Merge "Output PHP version before running PHPUnit tests"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 8 Feb 2016 02:09:34 +0000 (02:09 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 8 Feb 2016 02:09:34 +0000 (02:09 +0000)
795 files changed:
CREDITS
Gemfile
Gemfile.lock
RELEASE-NOTES-1.27
autoload.php
composer.json
docs/deferred.txt
docs/hooks.txt
images/.htaccess
includes/DefaultSettings.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/LinkTarget.php [new file with mode: 0644]
includes/MediaWiki.php
includes/Message.php
includes/OutputPage.php
includes/PrefixSearch.php
includes/Sanitizer.php
includes/Setup.php
includes/Title.php
includes/WatchedItem.php
includes/ZhConversion.php [deleted file]
includes/api/ApiBase.php
includes/api/ApiCheckToken.php
includes/api/ApiCreateAccount.php
includes/api/ApiDelete.php
includes/api/ApiEditPage.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatJson.php
includes/api/ApiFormatPhp.php
includes/api/ApiFormatXml.php
includes/api/ApiHelp.php
includes/api/ApiLogin.php
includes/api/ApiMain.php
includes/api/ApiOpenSearch.php
includes/api/ApiParamInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryPrefixSearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryTokens.php
includes/api/ApiRollback.php
includes/api/ApiStashEdit.php
includes/api/ApiTag.php
includes/api/ApiTokens.php
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ksh.json
includes/api/i18n/nl.json
includes/api/i18n/qqq.json
includes/api/i18n/sr-el.json
includes/api/i18n/tr.json
includes/api/i18n/zh-hans.json
includes/cache/MessageCache.php
includes/context/RequestContext.php
includes/db/DBConnRef.php
includes/db/Database.php
includes/db/DatabaseMysqlBase.php
includes/db/DatabasePostgres.php
includes/db/IDatabase.php
includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LoadBalancer.php
includes/debug/logger/monolog/AvroFormatter.php
includes/debug/logger/monolog/KafkaHandler.php
includes/debug/logger/monolog/WikiProcessor.php
includes/filerepo/ForeignAPIRepo.php
includes/htmlform/HTMLUserTextField.php
includes/installer/DatabaseUpdater.php
includes/installer/LocalSettingsGenerator.php
includes/installer/MysqlUpdater.php
includes/installer/i18n/ar.json
includes/installer/i18n/fa.json
includes/installer/i18n/is.json
includes/installer/i18n/ja.json
includes/installer/i18n/lb.json
includes/installer/i18n/mk.json
includes/installer/i18n/war.json
includes/installer/i18n/zh-hans.json
includes/jobqueue/JobRunner.php
includes/jobqueue/jobs/ActivityUpdateJob.php
includes/jobqueue/jobs/CategoryMembershipChangeJob.php
includes/jobqueue/jobs/HTMLCacheUpdateJob.php
includes/jobqueue/jobs/RecentChangesUpdateJob.php
includes/libs/CSSMin.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/CachedBagOStuff.php [new file with mode: 0644]
includes/logging/LogFormatter.php
includes/logging/TagLogFormatter.php
includes/mail/EmailNotification.php
includes/media/Bitmap.php
includes/media/TransformationalImageHandler.php
includes/media/XMPValidate.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/page/CategoryPage.php
includes/page/ImageHistoryList.php [new file with mode: 0644]
includes/page/ImageHistoryPseudoPager.php [new file with mode: 0644]
includes/page/ImagePage.php
includes/page/WikiPage.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/search/SearchEngine.php
includes/search/SearchSuggestion.php [new file with mode: 0644]
includes/search/SearchSuggestionSet.php [new file with mode: 0644]
includes/session/CookieSessionProvider.php
includes/session/PHPSessionHandler.php
includes/session/Session.php
includes/session/SessionBackend.php
includes/session/SessionManager.php
includes/session/Token.php [new file with mode: 0644]
includes/session/UserInfo.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialAllPages.php
includes/specials/SpecialApiSandbox.php [new file with mode: 0644]
includes/specials/SpecialChangeContentModel.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialContributions.php
includes/specials/SpecialExport.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/title/MediaWikiPageLinkRenderer.php
includes/title/MediaWikiTitleCodec.php
includes/title/PageLinkRenderer.php
includes/title/TitleFormatter.php
includes/title/TitleValue.php
includes/user/LoggedOutEditToken.php [new file with mode: 0644]
includes/user/User.php
includes/utils/BatchRowWriter.php
includes/utils/IP.php
jsduck.json
languages/Language.php
languages/Names.php [deleted file]
languages/classes/LanguageGan.php
languages/classes/LanguageIu.php
languages/classes/LanguageKk.php
languages/classes/LanguageKu.php
languages/classes/LanguageShi.php
languages/classes/LanguageSr.php
languages/classes/LanguageTg.php
languages/classes/LanguageUz.php
languages/classes/LanguageZh.php
languages/data/Names.php [new file with mode: 0644]
languages/data/ZhConversion.php [new file with mode: 0644]
languages/i18n/ar.json
languages/i18n/arq.json
languages/i18n/ast.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/cu.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/fur.json
languages/i18n/gl.json
languages/i18n/gom-deva.json
languages/i18n/gom-latn.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ilo.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jam.json
languages/i18n/ka.json
languages/i18n/kiu.json
languages/i18n/ko.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/la.json
languages/i18n/lb.json
languages/i18n/lki.json
languages/i18n/lt.json
languages/i18n/lzh.json
languages/i18n/mai.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/ms.json
languages/i18n/my.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/or.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/ps.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/scn.json
languages/i18n/sd.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/szl.json
languages/i18n/tg-cyrl.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/tyv.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vi.json
languages/i18n/vo.json
languages/i18n/war.json
languages/i18n/wuu.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesEn.php
maintenance/Maintenance.php
maintenance/attachLatest.php
maintenance/benchmarks/bench_HTTP_HTTPS.php
maintenance/benchmarks/bench_Wikimedia_base_convert.php
maintenance/benchmarks/bench_delete_truncate.php
maintenance/benchmarks/bench_if_switch.php
maintenance/benchmarks/bench_strtr_str_replace.php
maintenance/benchmarks/bench_utf8_title_check.php
maintenance/benchmarks/bench_wfIsWindows.php
maintenance/benchmarks/benchmarkHooks.php
maintenance/benchmarks/benchmarkPurge.php
maintenance/changePassword.php
maintenance/checkBadRedirects.php
maintenance/checkComposerLockUpToDate.php
maintenance/checkImages.php
maintenance/checkLess.php
maintenance/checkSyntax.php
maintenance/checkUsernames.php
maintenance/cleanupAncientTables.php
maintenance/cleanupBlocks.php
maintenance/cleanupCaps.php
maintenance/cleanupImages.php
maintenance/cleanupRemovedModules.php
maintenance/cleanupSpam.php
maintenance/cleanupTitles.php
maintenance/cleanupUploadStash.php
maintenance/cleanupWatchlist.php
maintenance/clearInterwikiCache.php
maintenance/compareParserCache.php
maintenance/compareParsers.php
maintenance/convertExtensionToRegistration.php
maintenance/convertLinks.php
maintenance/convertUserOptions.php
maintenance/copyFileBackend.php
maintenance/copyJobQueue.php
maintenance/createAndPromote.php
maintenance/createCommonPasswordCdb.php
maintenance/deleteArchivedFiles.php
maintenance/deleteArchivedRevisions.php
maintenance/deleteBatch.php
maintenance/deleteDefaultMessages.php
maintenance/deleteEqualMessages.php
maintenance/deleteOldRevisions.php
maintenance/deleteOrphanedRevisions.php
maintenance/deleteRevision.php
maintenance/deleteSelfExternals.php
maintenance/dumpBackup.php
maintenance/dumpIterator.php
maintenance/dumpLinks.php
maintenance/dumpTextPass.php
maintenance/dumpUploads.php
maintenance/edit.php
maintenance/eraseArchivedFile.php
maintenance/exportSites.php
maintenance/fetchText.php
maintenance/fileOpPerfTest.php
maintenance/findDeprecated.php
maintenance/findHooks.php
maintenance/findMissingFiles.php
maintenance/findOrphanedFiles.php
maintenance/fixDefaultJsonContentPages.php
maintenance/fixDoubleRedirects.php
maintenance/fixExtLinksProtocolRelative.php
maintenance/fixTimestamps.php
maintenance/fixUserRegistration.php
maintenance/generateJsonI18n.php
maintenance/generateSitemap.php
maintenance/getConfiguration.php
maintenance/getLagTimes.php
maintenance/getSlaveServer.php
maintenance/getText.php
maintenance/importDump.php
maintenance/importSiteScripts.php
maintenance/importSites.php
maintenance/importTextFiles.php
maintenance/initEditCount.php
maintenance/initSiteStats.php
maintenance/jsparse.php
maintenance/lag.php
maintenance/language/alltrans.php
maintenance/language/date-formats.php
maintenance/language/digit2html.php
maintenance/language/dumpMessages.php
maintenance/language/generateNormalizerDataAr.php
maintenance/language/generateNormalizerDataMl.php
maintenance/language/generateUtf8Case.php
maintenance/language/langmemusage.php
maintenance/language/listVariants.php
maintenance/language/zhtable/Makefile
maintenance/language/zhtable/Makefile.py
maintenance/makeTestEdits.php
maintenance/mctest.php
maintenance/mergeMessageFileList.php
maintenance/migrateFileRepoLayout.php
maintenance/migrateUserGroup.php
maintenance/minify.php
maintenance/moveBatch.php
maintenance/mwdocgen.php
maintenance/namespaceDupes.php
maintenance/nukeNS.php
maintenance/nukePage.php
maintenance/oracle/alterSharedConstraints.php
maintenance/orphans.php
maintenance/pageExists.php
maintenance/parse.php
maintenance/patchSql.php
maintenance/populateBacklinkNamespace.php
maintenance/populateCategory.php
maintenance/populateContentModel.php
maintenance/populateFilearchiveSha1.php
maintenance/populateImageSha1.php
maintenance/populateLogSearch.php
maintenance/populateLogUsertext.php
maintenance/populateParentId.php
maintenance/populateRecentChangesSource.php
maintenance/populateRevisionLength.php
maintenance/populateRevisionSha1.php
maintenance/protect.php
maintenance/pruneFileCache.php
maintenance/purgeChangedFiles.php
maintenance/purgeChangedPages.php
maintenance/purgeList.php
maintenance/purgeOldText.php
maintenance/reassignEdits.php
maintenance/rebuildFileCache.php
maintenance/rebuildImages.php
maintenance/rebuildLocalisationCache.php
maintenance/rebuildSitesCache.php
maintenance/rebuildall.php
maintenance/rebuildmessages.php
maintenance/rebuildrecentchanges.php
maintenance/rebuildtextindex.php
maintenance/refreshFileHeaders.php
maintenance/refreshImageMetadata.php
maintenance/refreshLinks.php
maintenance/renderDump.php
maintenance/resetUserEmail.php [new file with mode: 0644]
maintenance/resetUserTokens.php
maintenance/resources/update-oojs-ui.sh
maintenance/rollbackEdits.php
maintenance/runBatchedQuery.php
maintenance/runJobs.php
maintenance/showJobs.php
maintenance/showSiteStats.php
maintenance/sql.php
maintenance/sqlite.php
maintenance/storage/compressOld.php
maintenance/storage/fixBug20757.php
maintenance/storage/orphanStats.php
maintenance/syncFileBackend.php
maintenance/undelete.php
maintenance/update.php
maintenance/updateArticleCount.php
maintenance/updateCollation.php
maintenance/updateDoubleWidthSearch.php
maintenance/updateRestrictions.php
maintenance/updateSearchIndex.php
maintenance/wrapOldPasswords.php
resources/Resources.php
resources/ResourcesOOUI.php
resources/lib/oojs-ui/i18n/cdo.json [new file with mode: 0644]
resources/lib/oojs-ui/i18n/hy.json
resources/lib/oojs-ui/i18n/it.json
resources/lib/oojs-ui/i18n/sh.json
resources/lib/oojs-ui/i18n/xmf.json
resources/lib/oojs-ui/i18n/zh-hans.json
resources/lib/oojs-ui/oojs-ui-apex-noimages.css [deleted file]
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-core.js [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css [deleted file]
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-toolbars.js [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-widgets-apex.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-widgets.js [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-windows-apex.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-windows.js [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui.js [deleted file]
resources/lib/oojs-ui/themes/mediawiki/icons-accessibility.json
resources/lib/oojs-ui/themes/mediawiki/icons-alerts.json
resources/lib/oojs-ui/themes/mediawiki/icons-content.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-advanced.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-core.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-list.json
resources/lib/oojs-ui/themes/mediawiki/icons-editing-styling.json
resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json
resources/lib/oojs-ui/themes/mediawiki/icons-layout.json
resources/lib/oojs-ui/themes/mediawiki/icons-location.json
resources/lib/oojs-ui/themes/mediawiki/icons-media.json
resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json
resources/lib/oojs-ui/themes/mediawiki/icons-movement.json
resources/lib/oojs-ui/themes/mediawiki/icons-wikimedia.json
resources/lib/oojs-ui/themes/mediawiki/icons.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/add-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/add-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/advanced-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/alert-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/alert-warning.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/align-center-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/align-float-left-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/align-float-right-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/arched-arrow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/arched-arrow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/arrow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/arrow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/article-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/article-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleCheck-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleCheck-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleRedirect-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleRedirect-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleSearch-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/articleSearch-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bell-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bellOn-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bellOn-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/beta-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/block-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/block-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-a-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-arab-ain-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-arab-dad-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-armn-to-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-b-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-cyrl-be-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-cyrl-te-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-cyrl-zhe-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-f-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-g-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-geor-man-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-l-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-n-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bold-v-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/book-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/book-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bookmark-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bookmark-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bright-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/browser-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/browser-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/calendar-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/calendar-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/cancel-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/caret-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/caret-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/caretDown-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/caretUp-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/case-sensitive-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/check-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/circle-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/circle-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/citeArticle-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/citeArticle-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/clear-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/clock-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/close-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/close-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/code-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/collapse-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/comment-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/die-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/die-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/downTriangle-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/download-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/download-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/edit-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/edit-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/edit-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/edit-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/editLock-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/editLock-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/editUndo-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/editUndo-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ellipsis-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/expand-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/external-link-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/external-link-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/eye-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/eyeClosed-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/find-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/find-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flag-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/folderPlaceholder-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/folderPlaceholder-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/funnel-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/funnel-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/halfBright-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/heart-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/help-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/help-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/history-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/image-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/image-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageAdd-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageAdd-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageGallery-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageGallery-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageLock-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/imageLock-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/indent-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/indent-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/info-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-a-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-arab-keheh-jeem-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-arab-meem-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-armn-sha-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-c-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-d-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-e-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-geor-kan-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-i-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-k-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/italic-s-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/journal-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/journal-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/key-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/key-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/keyboard-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/keyboard-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/language-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/language-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/largerText-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/largerText-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/layout-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/layout-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/link-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/link-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/listBullet-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/listBullet-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/listNumbered-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/listNumbered-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/lock-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/logOut-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/logOut-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-cc-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaCommons-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikipedia-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/map-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/map-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapPin-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapPinAdd-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/mapPinAdd-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/menu-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/message-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/message-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/moon-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/move-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/move-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/move-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newWindow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newWindow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newline-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newline-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newspaper-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/newspaper-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/noWikiText-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/noWikiText-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/notBright-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/notice-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ongoingConversation-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/outdent-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/outdent-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/outline-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/outline-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/play-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/play-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/printer-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/printer-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/puzzle-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/puzzle-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/quotes-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/quotes-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/quotesAdd-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/quotesAdd-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/regular-expression-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/ribbonPrize-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/search-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/search-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/secure-link-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/settings-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/signature-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/signature-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smallerText-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smallerText-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/specialCharacter-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubble-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubble-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubbleAdd-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubbleAdd-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubbles-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/speechBubbles-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/star-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/star-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stop-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/strikethrough-a-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/strikethrough-s-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/strikethrough-y-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeFlow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeFlow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeSideMenu-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeSummary-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeSummary-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeToC-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeToC-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeToC-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/stripeToC-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/subscript-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/subscript-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/sun-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/sun-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/superscript-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/superscript-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-caption-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-insert-column-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-insert-column-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-insert-row-after-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-insert-row-before-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/table-merge-cells-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/tag-warning.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/templateAdd-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/templateAdd-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/text-dir-lefttoright-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/text-dir-righttoleft-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/text-style-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/trash-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-destructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unLock-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unStar-constructive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/unStar-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/underline-a-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/underline-u-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/upTriangle-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/upload-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/upload-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/viewCompact-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/viewDetails-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/viewDetails-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/visionSimulator-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/watchlist-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/watchlist-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikiText-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/wikitrail-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/window-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/alert-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-down-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/arrow-up-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/clear-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/required-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/indicators/search-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/indicators.json
resources/src/mediawiki.special/mediawiki.special.apisandbox.css [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.apisandbox.js [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js
resources/src/mediawiki/api/parse.js
resources/src/mediawiki/api/upload.js
resources/src/mediawiki/mediawiki.Upload.js
resources/src/mediawiki/mediawiki.apipretty.css
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.userSuggest.js
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/EditPageTest.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/api/ApiCreateAccountTest.php
tests/phpunit/includes/api/ApiLoginTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/content/WikitextContentHandlerTest.php
tests/phpunit/includes/context/RequestContextTest.php
tests/phpunit/includes/debug/logger/monolog/AvroFormatterTest.php
tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php [new file with mode: 0644]
tests/phpunit/includes/media/BitmapScalingTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/search/SearchEnginePrefixTest.php [new file with mode: 0644]
tests/phpunit/includes/search/SearchSuggestionSetTest.php [new file with mode: 0644]
tests/phpunit/includes/session/CookieSessionProviderTest.php
tests/phpunit/includes/session/ImmutableSessionProviderWithCookieTest.php
tests/phpunit/includes/session/PHPSessionHandlerTest.php
tests/phpunit/includes/session/SessionBackendTest.php
tests/phpunit/includes/session/SessionManagerTest.php
tests/phpunit/includes/session/SessionTest.php
tests/phpunit/includes/session/TestBagOStuff.php
tests/phpunit/includes/session/TokenTest.php [new file with mode: 0644]
tests/phpunit/includes/session/UserInfoTest.php
tests/phpunit/structure/ApiDocumentationTest.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js

diff --git a/CREDITS b/CREDITS
index fe7b81e..a54bd90 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -138,6 +138,7 @@ following names for their contribution to the product.
 * Erwin Dokter
 * Étienne Beaulé
 * Federico Leva
+* Florian Schmidt
 * fomafix
 * FunPika
 * Gabriel Wicke
diff --git a/Gemfile b/Gemfile
index ee09906..636d4ee 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,4 @@
 source 'https://rubygems.org'
 
-gem 'mediawiki_selenium', '~> 1.6.3'
+gem 'mediawiki_selenium', '~> 1.6.5'
 gem 'rubocop', '~> 0.32.1', require: false
index 4d0203a..8684be9 100644 (file)
@@ -5,7 +5,7 @@ GEM
     astrolabe (1.3.0)
       parser (>= 2.2.0.pre.3, < 3.0)
     builder (3.2.2)
-    childprocess (0.5.8)
+    childprocess (0.5.9)
       ffi (~> 1.0, >= 1.0.11)
     cucumber (1.3.20)
       builder (>= 2.1.2)
@@ -17,7 +17,7 @@ GEM
       faker (>= 1.1.2)
       yml_reader (>= 0.6)
     diff-lcs (1.2.5)
-    domain_name (0.5.25)
+    domain_name (0.5.20160128)
       unf (>= 0.0.5, < 1.0.0)
     faker (1.6.1)
       i18n (~> 0.5)
@@ -37,7 +37,7 @@ GEM
     mediawiki_api (0.5.0)
       faraday (~> 0.9, >= 0.9.0)
       faraday-cookie_jar (~> 0.0, >= 0.0.6)
-    mediawiki_selenium (1.6.3)
+    mediawiki_selenium (1.6.5)
       cucumber (~> 1.3, >= 1.3.20)
       headless (~> 2.0, >= 2.1.0)
       json (~> 1.8, >= 1.8.1)
@@ -53,7 +53,7 @@ GEM
     multi_test (0.1.2)
     multipart-post (2.0.0)
     netrc (0.11.0)
-    page-object (1.1.0)
+    page-object (1.1.1)
       page_navigation (>= 0.9)
       selenium-webdriver (>= 2.44.0)
       watir-webdriver (>= 0.6.11)
@@ -78,7 +78,7 @@ GEM
       ruby-progressbar (~> 1.4)
     ruby-progressbar (1.7.5)
     rubyzip (1.1.7)
-    selenium-webdriver (2.48.1)
+    selenium-webdriver (2.50.0)
       childprocess (~> 0.5)
       multi_json (~> 1.0)
       rubyzip (~> 1.0)
@@ -91,11 +91,11 @@ GEM
     watir-webdriver (0.9.1)
       selenium-webdriver (>= 2.46.2)
     websocket (1.2.2)
-    yml_reader (0.6)
+    yml_reader (0.7)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  mediawiki_selenium (~> 1.6.3)
+  mediawiki_selenium (~> 1.6.5)
   rubocop (~> 0.32.1)
index 50d40a6..5b9b2b8 100644 (file)
@@ -81,6 +81,8 @@ production.
    MediaWiki\Session\SessionProvider.
 ** The User cannot be loaded from session until after Setup.php completes.
    Attempts to do so will be ignored and the User will remain unloaded.
+** CSRF tokens may be fetched from the MediaWiki\Session\Session, which uses
+   the MediaWiki\Session\Token class.
 * MediaWiki will now auto-create users as necessary, removing the need for
   extensions to do so. An 'autocreateaccount' right is added to allow
   auto-creation when 'createaccount' is not granted to all users.
@@ -88,11 +90,17 @@ production.
 * Most cookie-handling methods in User are deprecated.
 * $wgAllowAsyncCopyUploads and $CopyUploadAsyncTimeout were removed. This was an
   experimental feature that has never worked.
+* Login and createaccount tokens now vary by timestamp.
+* LoginForm::getLoginToken() and LoginForm::getCreateaccountToken()
+  return a MediaWiki\Session\Token, and tokens must be checked using that
+  class's methods.
+* $wgEnotifUseJobQ was removed and the job queue is always used.
+* The functionality of the ApiSandbox extension has been merged into core. The
+  extension should no longer be used.
 
 === New features in 1.27 ===
-* $wgDataCenterId and $wgDataCenterRoles where added, which will serve as
-  basic configuration settings needed for multi-datacenter setups.
-  $wgDataCenterUpdateStickTTL was also added.
+* $wgDataCenterUpdateStickTTL was also added. This decides how long a user
+  sticks to the primary DC (via cookies) after they make changes to the site.
 * Added a new hook, 'UserMailerTransformContent', to transform the contents
   of an email. This is similar to the EmailUser hook but applies to all mail
   sent via UserMailer.
@@ -146,6 +154,10 @@ production.
 * Added MWRestrictions as a class to check restrictions on a WebRequest, e.g.
   to assert that the request comes from a particular IP range.
 * Added bot passwords, a rights-restricted login mechanism for API-using bots.
+* Whitelisted the following HTML attributes for all elements in wikitext:
+  aria-describedby, aria-flowto, aria-label, aria-labelledby, aria-owns.
+* Removed "presentation" restriction on the HTML role attribute in wikitext.
+  All values are now allowed for the role attribute.
 
 === External library changes in 1.27 ===
 
@@ -199,6 +211,7 @@ production.
 * ApiQueryBase::getDirectionDescription() was removed (deprecated since 1.25).
 * ApiQuery::getModules() was removed (deprecated since 1.21).
 * ApiMain::getModules() was removed (deprecated since 1.21).
+* ApiBase::getVersion() was removed (deprecated since 1.21).
 
 === Languages updated in 1.27 ===
 
@@ -294,6 +307,8 @@ changes to languages because of Phabricator reports.
   together but instead pick the final one, similar to image syntax.
 * XML-like parser tags (such as <gallery>), when unclosed, will be left unparsed
   rather than consume everything until the end of the page.
+* New maintenance script resetUserEmail.php allows sysadmins to reset user emails in case
+  a user forgot password/account was stolen.
 
 == Compatibility ==
 
index 2f23924..4d48de0 100644 (file)
@@ -190,6 +190,7 @@ $wgAutoloadLocalClasses = array(
        'CacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
        'CacheTime' => __DIR__ . '/includes/parser/CacheTime.php',
        'CachedAction' => __DIR__ . '/includes/actions/CachedAction.php',
+       'CachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/CachedBagOStuff.php',
        'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
        'CapsCleanup' => __DIR__ . '/maintenance/cleanupCaps.php',
        'Category' => __DIR__ . '/includes/Category.php',
@@ -560,6 +561,7 @@ $wgAutoloadLocalClasses = array(
        'IPSet' => __DIR__ . '/includes/compat/IPSetCompat.php',
        'IPTC' => __DIR__ . '/includes/media/IPTC.php',
        'IRCColourfulRCFeedFormatter' => __DIR__ . '/includes/rcfeed/IRCColourfulRCFeedFormatter.php',
+       'LinkTarget' => __DIR__ . '/includes/LinkTarget.php',
        'IcuCollation' => __DIR__ . '/includes/Collation.php',
        'IdentityCollation' => __DIR__ . '/includes/Collation.php',
        'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
@@ -567,8 +569,8 @@ $wgAutoloadLocalClasses = array(
        'ImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
        'ImageGalleryBase' => __DIR__ . '/includes/gallery/ImageGalleryBase.php',
        'ImageHandler' => __DIR__ . '/includes/media/ImageHandler.php',
-       'ImageHistoryList' => __DIR__ . '/includes/page/ImagePage.php',
-       'ImageHistoryPseudoPager' => __DIR__ . '/includes/page/ImagePage.php',
+       'ImageHistoryList' => __DIR__ . '/includes/page/ImageHistoryList.php',
+       'ImageHistoryPseudoPager' => __DIR__ . '/includes/page/ImageHistoryPseudoPager.php',
        'ImageListPager' => __DIR__ . '/includes/specials/SpecialListfiles.php',
        'ImagePage' => __DIR__ . '/includes/page/ImagePage.php',
        'ImageQueryPage' => __DIR__ . '/includes/specialpage/ImageQueryPage.php',
@@ -721,6 +723,7 @@ $wgAutoloadLocalClasses = array(
        'LogFormatter' => __DIR__ . '/includes/logging/LogFormatter.php',
        'LogPage' => __DIR__ . '/includes/logging/LogPage.php',
        'LogPager' => __DIR__ . '/includes/logging/LogPager.php',
+       'LoggedOutEditToken' => __DIR__ . '/includes/user/LoggedOutEditToken.php',
        'LoggedUpdateMaintenance' => __DIR__ . '/maintenance/Maintenance.php',
        'LoginForm' => __DIR__ . '/includes/specials/SpecialUserlogin.php',
        'LonelyPagesPage' => __DIR__ . '/includes/specials/SpecialLonelypages.php',
@@ -771,6 +774,8 @@ $wgAutoloadLocalClasses = array(
        'MediaWikiSite' => __DIR__ . '/includes/site/MediaWikiSite.php',
        'MediaWikiTitleCodec' => __DIR__ . '/includes/title/MediaWikiTitleCodec.php',
        'MediaWikiVersionFetcher' => __DIR__ . '/includes/MediaWikiVersionFetcher.php',
+       'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
+       'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
        'MediaWiki\\Logger\\LegacyLogger' => __DIR__ . '/includes/debug/logger/LegacyLogger.php',
        'MediaWiki\\Logger\\LegacySpi' => __DIR__ . '/includes/debug/logger/LegacySpi.php',
        'MediaWiki\\Logger\\LoggerFactory' => __DIR__ . '/includes/debug/logger/LoggerFactory.php',
@@ -797,6 +802,7 @@ $wgAutoloadLocalClasses = array(
        'MediaWiki\\Session\\SessionManagerInterface' => __DIR__ . '/includes/session/SessionManagerInterface.php',
        'MediaWiki\\Session\\SessionProvider' => __DIR__ . '/includes/session/SessionProvider.php',
        'MediaWiki\\Session\\SessionProviderInterface' => __DIR__ . '/includes/session/SessionProviderInterface.php',
+       'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
        'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
        'MediaWiki\\Tidy\\Html5Depurate' => __DIR__ . '/includes/tidy/Html5Depurate.php',
@@ -1048,6 +1054,7 @@ $wgAutoloadLocalClasses = array(
        'ReplicatedBagOStuff' => __DIR__ . '/includes/libs/objectcache/ReplicatedBagOStuff.php',
        'RepoGroup' => __DIR__ . '/includes/filerepo/RepoGroup.php',
        'RequestContext' => __DIR__ . '/includes/context/RequestContext.php',
+       'ResetUserEmail' => __DIR__ . '/maintenance/resetUserEmail.php',
        'ResetUserTokens' => __DIR__ . '/maintenance/resetUserTokens.php',
        'ResourceFileCache' => __DIR__ . '/includes/cache/ResourceFileCache.php',
        'ResourceLoader' => __DIR__ . '/includes/resourceloader/ResourceLoader.php',
@@ -1129,6 +1136,8 @@ $wgAutoloadLocalClasses = array(
        'SearchResult' => __DIR__ . '/includes/search/SearchResult.php',
        'SearchResultSet' => __DIR__ . '/includes/search/SearchResultSet.php',
        'SearchSqlite' => __DIR__ . '/includes/search/SearchSqlite.php',
+       'SearchSuggestion' => __DIR__ . '/includes/search/SearchSuggestion.php',
+       'SearchSuggestionSet' => __DIR__ . '/includes/search/SearchSuggestionSet.php',
        'SearchUpdate' => __DIR__ . '/includes/deferred/SearchUpdate.php',
        'SectionProfileCallback' => __DIR__ . '/includes/profiler/SectionProfiler.php',
        'SectionProfiler' => __DIR__ . '/includes/profiler/SectionProfiler.php',
@@ -1162,6 +1171,7 @@ $wgAutoloadLocalClasses = array(
        'SpecialAllMyUploads' => __DIR__ . '/includes/specials/SpecialMyRedirectPages.php',
        'SpecialAllPages' => __DIR__ . '/includes/specials/SpecialAllPages.php',
        'SpecialApiHelp' => __DIR__ . '/includes/specials/SpecialApiHelp.php',
+       'SpecialApiSandbox' => __DIR__ . '/includes/specials/SpecialApiSandbox.php',
        'SpecialBlankpage' => __DIR__ . '/includes/specials/SpecialBlankpage.php',
        'SpecialBlock' => __DIR__ . '/includes/specials/SpecialBlock.php',
        'SpecialBlockList' => __DIR__ . '/includes/specials/SpecialBlockList.php',
index da088d3..f326dcb 100644 (file)
@@ -21,8 +21,8 @@
                "ext-iconv": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.15.1",
-               "oyejorge/less.php": "1.7.0.9",
+               "oojs/oojs-ui": "0.15.2",
+               "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.3.3",
                "psr/log": "1.0.0",
                "wikimedia/assert": "0.2.2",
index 495e659..b8ec76b 100644 (file)
@@ -33,4 +33,4 @@ Currently there are a few different types of jobs:
     Each job clears $wgUpdateRowsPerJob pages (500 by default).
 
   enotifNotify
-    Used when $wgEnotifUseJobQ is true to send mail using the job queue.
+    Used to send mail using the job queue.
index 2b5e1e0..79bc5f5 100644 (file)
@@ -513,7 +513,8 @@ sites statistics information.
 'ApiQueryTokensRegisterTypes': Use this hook to add additional token types to
 action=query&meta=tokens. Note that most modules will probably be able to use
 the 'csrf' token instead of creating their own token types.
-&$salts: array( type => salt to pass to User::getEditToken() )
+&$salts: array( type => salt to pass to User::getEditToken() or array of salt
+  and key to pass to Session::getToken() )
 
 'APIQueryUsersTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead.
 Use this hook to add custom token to list=users. Every token has an action,
@@ -2346,6 +2347,11 @@ run. Use when page save hooks require the presence of custom tables to ensure
 that tests continue to run properly.
 &$tables: array of table names
 
+'ParserOutputStashForEdit': Called when an edit stash parse finishes, before the output is cached.
+$page: the WikiPage of the candidate edit
+$content: the Content object of the candidate edit
+$output: the ParserOutput result of the candidate edit
+
 'PasswordPoliciesForUser': Alter the effective password policy for a user.
 $user: User object whose policy you are modifying
 &$effectivePolicy: Array of policy statements that apply to this user
@@ -2793,6 +2799,11 @@ $id: User id number, only provided for backwards-compatibility
 $user: User object representing user contributions are being fetched for
 $sp: SpecialPage instance, providing context
 
+'SpecialContributions::getForm::filters': Called with a list of filters to render
+on Special:Contributions.
+$sp: SpecialContributions object, for context
+&$filters: List of filters rendered as HTML
+
 'SpecialListusersDefaultQuery': Called right before the end of
 UsersPager::getDefaultQuery().
 $pager: The UsersPager instance
index 3f3d41e..4e253b6 100644 (file)
@@ -1,4 +1,4 @@
-# Protect against bug 28235
+# Protect against bug T30235
 <IfModule rewrite_module>
        RewriteEngine On
        RewriteOptions inherit
index 00a5709..6a41152 100644 (file)
@@ -75,7 +75,7 @@ $wgConfigRegistry = array(
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.27alpha';
+$wgVersion = '1.27.0-alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -943,6 +943,12 @@ $wgUseImageMagick = false;
  */
 $wgImageMagickConvertCommand = '/usr/bin/convert';
 
+/**
+ * Array of max pixel areas for interlacing per MIME type
+ * @since 1.27
+ */
+$wgMaxInterlacingAreas = array();
+
 /**
  * Sharpening parameter to ImageMagick
  */
@@ -1622,12 +1628,6 @@ $wgEnotifImpersonal = false;
  */
 $wgEnotifMaxRecips = 500;
 
-/**
- * Send mails via the job queue. This can be useful to reduce the time it
- * takes to save a page that a lot of people are watching.
- */
-$wgEnotifUseJobQ = false;
-
 /**
  * Use real name instead of username in e-mail "from" field.
  */
@@ -1865,24 +1865,6 @@ $wgDBservers = false;
  */
 $wgLBFactoryConf = array( 'class' => 'LBFactorySimple' );
 
-/**
- * The ID of the current data center
- * @since 1.27
- */
-$wgDataCenterId = 'default';
-
-/**
- * Map of data center IDs to their role ("master" or "slave")
- *
- * Multiple data centers can be setup to handle MediaWiki, with HTTP
- * POSTs routed to the master data center and GET/HEAD/OPTION routed to
- * any data center (usually the closest to the end user). In such setups,
- * this setting should be set to the appropriate value in the site
- * config for each data center.
- * @since 1.27
- */
-$wgDataCenterRoles = array( 'default' => 'master' );
-
 /**
  * After a state-changing request is done by a client, this determines
  * how many seconds that client should keep using the master datacenter.
@@ -2720,7 +2702,7 @@ $wgUsePrivateIPs = false;
  */
 
 /**
- * Site language code. See languages/Names.php for languages supported by
+ * Site language code. See languages/data/Names.php for languages supported by
  * MediaWiki out of the box. Not all languages listed there have translations,
  * see languages/messages/ for the list of languages with some localisation.
  *
@@ -4650,6 +4632,18 @@ $wgUserrightsInterwikiDelimiter = '@';
  */
 $wgSecureLogin = false;
 
+/**
+ * Versioning for authentication tokens.
+ *
+ * If non-null, this is combined with the user's secret (the user_token field
+ * in the DB) to generate the token cookie. Changing this will invalidate all
+ * active sessions (i.e. it will log everyone out).
+ *
+ * @since 1.27
+ * @var string|null
+ */
+$wgAuthenticationTokenVersion = null;
+
 /**
  * MediaWiki\Session\SessionProvider configuration.
  *
@@ -6666,6 +6660,14 @@ $wgExportFromNamespaces = false;
  */
 $wgExportAllowAll = false;
 
+/**
+ * Maximum number of pages returned by the GetPagesFromCategory and
+ * GetPagesFromNamespace functions.
+ *
+ * @since 1.27
+ */
+$wgExportPagelistLimit = 5000;
+
 /** @} */ # end of import/export }
 
 /*************************************************************************//**
@@ -7684,7 +7686,6 @@ $wgHTTPConnectTimeout = 5e0;
 
 /************************************************************************//**
  * @name   Job queue
- * See also $wgEnotifUseJobQ.
  * @{
  */
 
index 47912cb..277a6cc 100644 (file)
@@ -3457,6 +3457,9 @@ HTML
                global $wgOut;
 
                if ( Hooks::run( 'EditPageBeforeConflictDiff', array( &$this, &$wgOut ) ) ) {
+                       $stats = $wgOut->getContext()->getStats();
+                       $stats->increment( 'edit.failures.conflict' );
+
                        $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
 
                        $content1 = $this->toEditContent( $this->textbox1 );
index 4d0ebf6..66201b5 100644 (file)
@@ -1475,7 +1475,7 @@ function wfMsgReplaceArgs( $message, $args ) {
        $message = str_replace( "\r", '', $message );
 
        // Replace arguments
-       if ( count( $args ) ) {
+       if ( is_array( $args ) && $args ) {
                if ( is_array( $args[0] ) ) {
                        $args = array_values( $args[0] );
                }
@@ -3082,7 +3082,6 @@ function wfSetupSession( $sessionId = false ) {
        if ( session_id() !== $session->getId() ) {
                session_id( $session->getId() );
        }
-       MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
        MediaWiki\quietCall( 'session_start' );
 }
 
diff --git a/includes/LinkTarget.php b/includes/LinkTarget.php
new file mode 100644 (file)
index 0000000..1ce5f32
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @author Addshore
+ *
+ * @since 1.27
+ */
+interface LinkTarget {
+
+       /**
+        * Get the namespace index
+        *
+        * @return int Namespace index
+        */
+       public function getNamespace();
+
+       /**
+        * Get the link fragment (i.e.\ the bit after the #) in text form
+        *
+        * @return string link fragment
+        */
+       public function getFragment();
+
+       /**
+        * Get the main part with underscores
+        *
+        * @return string Main part of the link, with underscores (for use in hrf attributes)
+        */
+       public function getDBkey();
+
+       /**
+        * Returns the link in text form,
+        * without namespace prefix or fragment.
+        *
+        * This is computed from the DB key by replacing any underscores with spaces.
+        *
+        * @return string
+        */
+       public function getText();
+
+}
index 6342d71..8385a06 100644 (file)
@@ -551,21 +551,12 @@ class MediaWiki {
                $config = $context->getConfig();
 
                $factory = wfGetLBFactory();
-               // Check if any transaction was too big
-               $limit = $config->get( 'MaxUserDBWriteDuration' );
-               $factory->forEachLB( function ( LoadBalancer $lb ) use ( $limit ) {
-                       $lb->forEachOpenConnection( function ( IDatabase $db ) use ( $limit ) {
-                               $time = $db->pendingWriteQueryDuration();
-                               if ( $limit > 0 && $time > $limit ) {
-                                       throw new DBTransactionError(
-                                               $db,
-                                               wfMessage( 'transaction-duration-limit-exceeded', $time, $limit )->text()
-                                       );
-                               }
-                       } );
-               } );
                // Commit all changes
-               $factory->commitMasterChanges( __METHOD__ );
+               $factory->commitMasterChanges(
+                       __METHOD__,
+                       // Abort if any transaction was too big
+                       array( 'maxWriteDuration' => $config->get( 'MaxUserDBWriteDuration' ) )
+               );
                // Record ChronologyProtector positions
                $factory->shutdown();
                wfDebug( __METHOD__ . ': all transactions committed' );
index 54efd26..c71a953 100644 (file)
@@ -271,7 +271,7 @@ class Message implements MessageSpecifier, Serializable {
        public function serialize() {
                return serialize( array(
                        'interface' => $this->interface,
-                       'language' => $this->language->getCode(),
+                       'language' => $this->language instanceof StubUserLang ? false : $this->language->getCode(),
                        'key' => $this->key,
                        'keysToTry' => $this->keysToTry,
                        'parameters' => $this->parameters,
@@ -287,6 +287,8 @@ class Message implements MessageSpecifier, Serializable {
         * @param string $serialized
         */
        public function unserialize( $serialized ) {
+               global $wgLang;
+
                $data = unserialize( $serialized );
                $this->interface = $data['interface'];
                $this->key = $data['key'];
@@ -294,7 +296,7 @@ class Message implements MessageSpecifier, Serializable {
                $this->parameters = $data['parameters'];
                $this->format = $data['format'];
                $this->useDatabase = $data['useDatabase'];
-               $this->language = Language::factory( $data['language'] );
+               $this->language = $data['language'] ? Language::factory( $data['language'] ) : $wgLang;
                $this->title = $data['title'];
        }
 
index 93ba702..3adef5b 100644 (file)
@@ -3815,6 +3815,58 @@ class OutputPage extends ContextSource {
                return $link;
        }
 
+       /**
+        * Transform path to web-accessible static resource.
+        *
+        * This is used to add a validation hash as query string.
+        * This aids various behaviors:
+        *
+        * - Put long Cache-Control max-age headers on responses for improved
+        *   cache performance.
+        * - Get the correct version of a file as expected by the current page.
+        * - Instantly get the updated version of a file after deployment.
+        *
+        * Avoid using this for urls included in HTML as otherwise clients may get different
+        * versions of a resource when navigating the site depending on when the page was cached.
+        * If changes to the url propagate, this is not a problem (e.g. if the url is in
+        * an external stylesheet).
+        *
+        * @since 1.27
+        * @param Config $config
+        * @param string $path Path-absolute URL to file (from document root, must start with "/")
+        * @return string URL
+        */
+       public static function transformResourcePath( Config $config, $path ) {
+               global $IP;
+               $remotePath = $config->get( 'ResourceBasePath' );
+               if ( strpos( $path, $remotePath ) !== 0 ) {
+                       // Path is outside wgResourceBasePath, ignore.
+                       return $path;
+               }
+               $path = RelPath\getRelativePath( $path, $remotePath );
+               return self::transformFilePath( $remotePath, $IP, $path );
+       }
+
+       /**
+        * Utility method for transformResourceFilePath().
+        *
+        * Caller is responsible for ensuring the file exists. Emits a PHP warning otherwise.
+        *
+        * @since 1.27
+        * @param string $remotePath URL path that points to $localPath
+        * @param string $localPath File directory exposed at $remotePath
+        * @param string $file Path to target file relative to $localPath
+        * @return string URL
+        */
+       public static function transformFilePath( $remotePath, $localPath, $file ) {
+               $hash = md5_file( "$localPath/$file" );
+               if ( $hash === false ) {
+                       wfLogWarning( __METHOD__ . ": Failed to hash $localPath/$file" );
+                       $hash = '';
+               }
+               return "$remotePath/$file?" . substr( $hash, 0, 5 );
+       }
+
        /**
         * Transform "media" attribute based on request parameters
         *
@@ -3999,7 +4051,7 @@ class OutputPage extends ContextSource {
                        $this->getLanguage()->getDir()
                );
                $this->addModuleStyles( array(
-                       'oojs-ui.styles',
+                       'oojs-ui-core.styles',
                        'oojs-ui.styles.icons',
                        'oojs-ui.styles.indicators',
                        'oojs-ui.styles.textures',
index c6f187d..5f36cf5 100644 (file)
@@ -23,6 +23,7 @@
 /**
  * Handles searching prefixes of titles and finding any page
  * names that match. Used largely by the OpenSearch implementation.
+ * @deprecated Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch
  *
  * @ingroup Search
  */
@@ -259,14 +260,17 @@ abstract class PrefixSearch {
         * @param int $offset Number of items to skip
         * @return array Array of Title objects
         */
-       protected function defaultSearchBackend( $namespaces, $search, $limit, $offset ) {
+       public function defaultSearchBackend( $namespaces, $search, $limit, $offset ) {
                $ns = array_shift( $namespaces ); // support only one namespace
-               if ( in_array( NS_MAIN, $namespaces ) ) {
+               if ( is_null( $ns ) || in_array( NS_MAIN, $namespaces ) ) {
                        $ns = NS_MAIN; // if searching on many always default to main
                }
 
-               $t = Title::newFromText( $search, $ns );
+               if ( $ns == NS_SPECIAL ) {
+                       return $this->specialSearch( $search, $limit, $offset );
+               }
 
+               $t = Title::newFromText( $search, $ns );
                $prefix = $t ? $t->getDBkey() : '';
                $dbr = wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'page',
@@ -318,6 +322,7 @@ abstract class PrefixSearch {
 
 /**
  * Performs prefix search, returning Title objects
+ * @deprecated Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch
  * @ingroup Search
  */
 class TitlePrefixSearch extends PrefixSearch {
@@ -337,6 +342,7 @@ class TitlePrefixSearch extends PrefixSearch {
 
 /**
  * Performs prefix search, returning strings
+ * @deprecated Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch
  * @ingroup Search
  */
 class StringPrefixSearch extends PrefixSearch {
index d41e559..60c9498 100644 (file)
@@ -721,7 +721,7 @@ class Sanitizer {
         * Take an array of attribute names and values and normalize or discard
         * illegal values for the given whitelist.
         *
-        * - Discards attributes not the given whitelist
+        * - Discards attributes not on the given whitelist
         * - Unsafe style attributes are discarded
         * - Invalid id attributes are re-encoded
         *
@@ -770,18 +770,18 @@ class Sanitizer {
                                $value = Sanitizer::checkCss( $value );
                        }
 
+                       # Escape HTML id attributes
                        if ( $attribute === 'id' ) {
                                $value = Sanitizer::escapeId( $value, 'noninitial' );
                        }
 
-                       # WAI-ARIA
-                       # http://www.w3.org/TR/wai-aria/
-                       # http://www.whatwg.org/html/elements.html#wai-aria
-                       # For now we only support role="presentation" until we work out what roles should be
-                       # usable by content and we ensure that our code explicitly rejects patterns that
-                       # violate HTML5's ARIA restrictions.
-                       if ( $attribute === 'role' && $value !== 'presentation' ) {
-                               continue;
+                       # Escape HTML id reference lists
+                       if ( $attribute === 'aria-describedby'
+                               || $attribute === 'aria-flowto'
+                               || $attribute === 'aria-labelledby'
+                               || $attribute === 'aria-owns'
+                       ) {
+                               $value = Sanitizer::escapeIdReferenceList( $value, 'noninitial' );
                        }
 
                        // RDFa and microdata properties allow URLs, URIs and/or CURIs.
@@ -1163,6 +1163,39 @@ class Sanitizer {
                return $id;
        }
 
+       /**
+        * Given a string containing a space delimited list of ids, escape each id
+        * to match ids escaped by the escapeId() function.
+        *
+        * @since 1.27
+        *
+        * @param string $referenceString Space delimited list of ids
+        * @param string|array $options String or array of strings (default is array()):
+        *   'noninitial': This is a non-initial fragment of an id, not a full id,
+        *       so don't pay attention if the first character isn't valid at the
+        *       beginning of an id.  Only matters if $wgExperimentalHtmlIds is
+        *       false.
+        *   'legacy': Behave the way the old HTML 4-based ID escaping worked even
+        *       if $wgExperimentalHtmlIds is used, so we can generate extra
+        *       anchors and links won't break.
+        * @return string
+        */
+       static function escapeIdReferenceList( $referenceString, $options = array() ) {
+               # Explode the space delimited list string into an array of tokens
+               $references = preg_split( '/\s+/', "{$referenceString}", -1, PREG_SPLIT_NO_EMPTY );
+
+               # Escape each token as an id
+               foreach ( $references as &$ref ) {
+                       $ref = Sanitizer::escapeId( $ref, $options );
+               }
+
+               # Merge the array back to a space delimited list string
+               # If the array is empty, the result will be an empty string ('')
+               $referenceString = implode( ' ', $references );
+
+               return $referenceString;
+       }
+
        /**
         * Given a value, escape it so that it can be used as a CSS class and
         * return it.
@@ -1208,7 +1241,7 @@ class Sanitizer {
 
        /**
         * Return an associative array of attribute names and values from
-        * a partial tag string. Attribute names are forces to lowercase,
+        * a partial tag string. Attribute names are forced to lowercase,
         * character references are decoded to UTF-8 text.
         *
         * @param string $text
@@ -1546,6 +1579,11 @@ class Sanitizer {
                        'title',
 
                        # WAI-ARIA
+                       'aria-describedby',
+                       'aria-flowto',
+                       'aria-label',
+                       'aria-labelledby',
+                       'aria-owns',
                        'role',
                );
 
index 9bf05e0..ba3d628 100644 (file)
@@ -357,7 +357,6 @@ if ( $wgEnableEmail ) {
        $wgEnotifMaxRecips = 0;
        $wgEnotifMinorEdits = false;
        $wgEnotifRevealEditorAddress = false;
-       $wgEnotifUseJobQ = false;
        $wgEnotifUseRealName = false;
        $wgEnotifUserTalk = false;
        $wgEnotifWatchlist = false;
@@ -505,6 +504,7 @@ if ( !$wgSessionsInObjectCache && !$wgSessionsInMemcached ) {
        }
        $cacheType = get_class( ObjectCache::getInstance( $wgSessionCacheType ) );
        wfDebugLog(
+               'caches',
                "Session data will be stored in \"$cacheType\" cache with " .
                        "expiry $wgObjectCacheSessionExpiry seconds"
        );
@@ -738,7 +738,6 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        ) {
                // Start the PHP-session for backwards compatibility
                session_id( $session->getId() );
-               MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
                MediaWiki\quietCall( 'session_start' );
        }
 }
index e549037..55c7179 100644 (file)
@@ -30,7 +30,7 @@
  * @note Consider using a TitleValue object instead. TitleValue is more lightweight
  *       and does not rely on global state or the database.
  */
-class Title {
+class Title implements LinkTarget {
        /** @var HashBagOStuff */
        static private $titleCache = null;
 
@@ -236,17 +236,28 @@ class Title {
         * @return Title
         */
        public static function newFromTitleValue( TitleValue $titleValue ) {
+               return self::newFromLinkTarget( $titleValue );
+       }
+
+       /**
+        * Create a new Title from a LinkTarget
+        *
+        * @param LinkTarget $linkTarget Assumed to be safe.
+        *
+        * @return Title
+        */
+       public static function newFromLinkTarget( LinkTarget $linkTarget ) {
                return self::makeTitle(
-                       $titleValue->getNamespace(),
-                       $titleValue->getText(),
-                       $titleValue->getFragment() );
+                       $linkTarget->getNamespace(),
+                       $linkTarget->getText(),
+                       $linkTarget->getFragment() );
        }
 
        /**
         * Create a new Title from text, such as what one would find in a link. De-
         * codes any HTML entities in the text.
         *
-        * @param string|null $text The link text; spaces, prefixes, and an
+        * @param string|int|null $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.  If you want to force a specific namespace even if
@@ -259,7 +270,8 @@ class Title {
                if ( is_object( $text ) ) {
                        throw new InvalidArgumentException( '$text must be a string.' );
                }
-               if ( $text !== null && !is_string( $text ) ) {
+               // DWIM: Integers can be passed in here when page titles are used as array keys.
+               if ( $text !== null && !is_string( $text ) && !is_int( $text ) ) {
                        wfDebugLog( 'T76305', wfGetAllCallers( 5 ) );
                        return null;
                }
@@ -268,7 +280,7 @@ class Title {
                }
 
                try {
-                       return Title::newFromTextThrow( $text, $defaultNamespace );
+                       return Title::newFromTextThrow( strval( $text ), $defaultNamespace );
                } catch ( MalformedTitleException $ex ) {
                        return null;
                }
index 0ef2373..49aca0c 100644 (file)
  */
 class WatchedItem {
        /** @var Title */
-       public $mTitle;
+       private $mTitle;
 
        /** @var User */
-       public $mUser;
+       private $mUser;
 
        /** @var int */
-       public $mCheckRights;
+       private $mCheckRights;
 
        /** @var bool */
        private $loaded = false;
@@ -59,17 +59,6 @@ class WatchedItem {
         */
        const CHECK_USER_RIGHTS = 1;
 
-       /**
-        * Do DB master updates right now
-        * @since 1.26
-        */
-       const IMMEDIATE = 0;
-       /**
-        * Do DB master updates via the job queue
-        * @since 1.26
-        */
-       const DEFERRED = 1;
-
        /**
         * Create a WatchedItem object with the given user and title
         * @since 1.22 $checkRights parameter added
@@ -219,10 +208,9 @@ class WatchedItem {
         * @param bool $force Whether to force the write query to be executed even if the
         *    page is not watched or the notification timestamp is already NULL.
         * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed.
-        * @mode int $mode WatchedItem::DEFERRED/IMMEDIATE
         */
        public function resetNotificationTimestamp(
-               $force = '', $oldid = 0, $mode = self::IMMEDIATE
+               $force = '', $oldid = 0
        ) {
                // Only loggedin user can have a watchlist
                if ( wfReadOnly() || $this->mUser->isAnon() || !$this->isAllowed( 'editmywatchlist' ) ) {
@@ -273,28 +261,19 @@ class WatchedItem {
                }
 
                // If the page is watched by the user (or may be watched), update the timestamp
-               if ( $mode === self::DEFERRED ) {
-                       $job = new ActivityUpdateJob(
-                               $title,
-                               array(
-                                       'type'      => 'updateWatchlistNotification',
-                                       'userid'    => $this->getUserId(),
-                                       'notifTime' => $notificationTimestamp,
-                                       'curTime'   => time()
-                               )
-                       );
-                       // Try to run this post-send
-                       DeferredUpdates::addCallableUpdate( function() use ( $job ) {
-                               $job->run();
-                       } );
-               } else {
-                       $dbw = wfGetDB( DB_MASTER );
-                       $dbw->update( 'watchlist',
-                               array( 'wl_notificationtimestamp' => $dbw->timestampOrNull( $notificationTimestamp ) ),
-                               $this->dbCond(),
-                               __METHOD__
-                       );
-               }
+               $job = new ActivityUpdateJob(
+                       $title,
+                       array(
+                               'type'      => 'updateWatchlistNotification',
+                               'userid'    => $this->getUserId(),
+                               'notifTime' => $notificationTimestamp,
+                               'curTime'   => time()
+                       )
+               );
+               // Try to run this post-send
+               DeferredUpdates::addCallableUpdate( function() use ( $job ) {
+                       $job->run();
+               } );
 
                $this->timestamp = null;
        }
diff --git a/includes/ZhConversion.php b/includes/ZhConversion.php
deleted file mode 100644 (file)
index 6c768ff..0000000
+++ /dev/null
@@ -1,20277 +0,0 @@
-<?php
-/**
- * Simplified / Traditional Chinese conversion tables
- *
- * Automatically generated using code and data in maintenance/language/zhtable/
- * Do not modify directly!
- *
- * @file
- */
-
-$zh2Hant = array(
-'㐷' => '傌',
-'㐹' => '㑶',
-'㐽' => '偑',
-'㑇' => '㑳',
-'㑈' => '倲',
-'㑔' => '㑯',
-'㑩' => '儸',
-'㓥' => '劏',
-'㔉' => '劚',
-'㖊' => '噚',
-'㖞' => '喎',
-'㘎' => '㘚',
-'㚯' => '㜄',
-'㛀' => '媰',
-'㛟' => '𡞵',
-'㛠' => '𡢃',
-'㛣' => '㜏',
-'㛤' => '孋',
-'㛿' => '𡠹',
-'㟆' => '㠏',
-'㟜' => '𡾱',
-'㤘' => '㥮',
-'㧏' => '掆',
-'㧐' => '㩳',
-'㧑' => '撝',
-'㧟' => '擓',
-'㧰' => '擽',
-'㨫' => '㩜',
-'㭎' => '棡',
-'㭏' => '椲',
-'㭣' => '𣙎',
-'㭤' => '樢',
-'㭴' => '樫',
-'㱩' => '殰',
-'㱮' => '殨',
-'㲿' => '瀇',
-'㳔' => '濧',
-'㳠' => '澾',
-'㳡' => '濄',
-'㳢' => '𣾷',
-'㳽' => '瀰',
-'㶉' => '鸂',
-'㶶' => '燶',
-'㶽' => '煱',
-'㺍' => '獱',
-'㻅' => '璯',
-'㻏' => '𤫩',
-'㻘' => '𤪺',
-'䀥' => '䁻',
-'䁖' => '瞜',
-'䂵' => '碽',
-'䅉' => '稏',
-'䅪' => '𥢢',
-'䇲' => '筴',
-'䉤' => '籔',
-'䌶' => '䊷',
-'䌷' => '紬',
-'䌸' => '縳',
-'䌹' => '絅',
-'䌺' => '䋙',
-'䌻' => '䋚',
-'䌼' => '綐',
-'䌽' => '綵',
-'䌾' => '䋻',
-'䌿' => '䋹',
-'䍀' => '繿',
-'䍁' => '繸',
-'䎬' => '䎱',
-'䏝' => '膞',
-'䓖' => '藭',
-'䗖' => '螮',
-'䘛' => '𧝞',
-'䘞' => '𧜗',
-'䙊' => '𧜵',
-'䙌' => '䙡',
-'䙓' => '襬',
-'䜣' => '訢',
-'䜥' => '𧩙',
-'䜧' => '䜀',
-'䜩' => '讌',
-'䝙' => '貙',
-'䞌' => '𧵳',
-'䞍' => '䝼',
-'䞎' => '𧶧',
-'䞐' => '賰',
-'䟢' => '躎',
-'䢀' => '𨊰',
-'䢁' => '𨊸',
-'䢂' => '𨋢',
-'䥺' => '釾',
-'䥽' => '鏺',
-'䥾' => '䥱',
-'䥿' => '𨯅',
-'䦀' => '𨦫',
-'䦁' => '𨧜',
-'䦂' => '䥇',
-'䦃' => '鐯',
-'䦅' => '鐥',
-'䦶' => '䦛',
-'䦷' => '䦟',
-'䭪' => '𩞯',
-'䯃' => '𩣑',
-'䯄' => '騧',
-'䯅' => '䯀',
-'䲝' => '䱽',
-'䲞' => '𩶘',
-'䲟' => '鮣',
-'䲠' => '鰆',
-'䲡' => '鰌',
-'䲢' => '鰧',
-'䲣' => '䱷',
-'䴓' => '鳾',
-'䴔' => '鵁',
-'䴕' => '鴷',
-'䴖' => '鶄',
-'䴗' => '鶪',
-'䴘' => '鷈',
-'䴙' => '鷿',
-'䶮' => '龑',
-'万' => '萬',
-'与' => '與',
-'专' => '專',
-'业' => '業',
-'丛' => '叢',
-'东' => '東',
-'丝' => '絲',
-'丢' => '丟',
-'两' => '兩',
-'严' => '嚴',
-'丧' => '喪',
-'个' => '個',
-'丰' => '豐',
-'临' => '臨',
-'为' => '為',
-'丽' => '麗',
-'举' => '舉',
-'么' => '麼',
-'义' => '義',
-'乌' => '烏',
-'乐' => '樂',
-'乔' => '喬',
-'习' => '習',
-'乡' => '鄉',
-'书' => '書',
-'买' => '買',
-'乱' => '亂',
-'争' => '爭',
-'于' => '於',
-'亏' => '虧',
-'云' => '雲',
-'亚' => '亞',
-'产' => '產',
-'亩' => '畝',
-'亲' => '親',
-'亵' => '褻',
-'亸' => '嚲',
-'亿' => '億',
-'仅' => '僅',
-'从' => '從',
-'仑' => '侖',
-'仓' => '倉',
-'仪' => '儀',
-'们' => '們',
-'价' => '價',
-'众' => '眾',
-'优' => '優',
-'会' => '會',
-'伛' => '傴',
-'伞' => '傘',
-'伟' => '偉',
-'传' => '傳',
-'伡' => '俥',
-'伣' => '俔',
-'伤' => '傷',
-'伥' => '倀',
-'伦' => '倫',
-'伧' => '傖',
-'伪' => '偽',
-'伫' => '佇',
-'体' => '體',
-'佣' => '傭',
-'佥' => '僉',
-'侠' => '俠',
-'侣' => '侶',
-'侥' => '僥',
-'侦' => '偵',
-'侧' => '側',
-'侨' => '僑',
-'侩' => '儈',
-'侪' => '儕',
-'侬' => '儂',
-'俣' => '俁',
-'俦' => '儔',
-'俨' => '儼',
-'俩' => '倆',
-'俪' => '儷',
-'俫' => '倈',
-'俭' => '儉',
-'债' => '債',
-'倾' => '傾',
-'偬' => '傯',
-'偻' => '僂',
-'偾' => '僨',
-'偿' => '償',
-'傥' => '儻',
-'傧' => '儐',
-'储' => '儲',
-'傩' => '儺',
-'儿' => '兒',
-'兑' => '兌',
-'兖' => '兗',
-'党' => '黨',
-'兰' => '蘭',
-'关' => '關',
-'兴' => '興',
-'兹' => '茲',
-'养' => '養',
-'兽' => '獸',
-'冁' => '囅',
-'内' => '內',
-'冈' => '岡',
-'册' => '冊',
-'写' => '寫',
-'军' => '軍',
-'农' => '農',
-'冯' => '馮',
-'冲' => '沖',
-'决' => '決',
-'况' => '況',
-'冻' => '凍',
-'净' => '淨',
-'凄' => '淒',
-'凉' => '涼',
-'减' => '減',
-'凑' => '湊',
-'凛' => '凜',
-'几' => '幾',
-'凤' => '鳳',
-'凫' => '鳧',
-'凭' => '憑',
-'凯' => '凱',
-'击' => '擊',
-'凿' => '鑿',
-'刍' => '芻',
-'划' => '劃',
-'刘' => '劉',
-'则' => '則',
-'刚' => '剛',
-'创' => '創',
-'删' => '刪',
-'别' => '別',
-'刬' => '剗',
-'刭' => '剄',
-'刹' => '剎',
-'刽' => '劊',
-'刾' => '㓨',
-'刿' => '劌',
-'剀' => '剴',
-'剂' => '劑',
-'剐' => '剮',
-'剑' => '劍',
-'剥' => '剝',
-'剧' => '劇',
-'劝' => '勸',
-'办' => '辦',
-'务' => '務',
-'劢' => '勱',
-'动' => '動',
-'励' => '勵',
-'劲' => '勁',
-'劳' => '勞',
-'势' => '勢',
-'勋' => '勛',
-'勚' => '勩',
-'匀' => '勻',
-'匦' => '匭',
-'匮' => '匱',
-'区' => '區',
-'医' => '醫',
-'华' => '華',
-'协' => '協',
-'单' => '單',
-'卖' => '賣',
-'卢' => '盧',
-'卤' => '鹵',
-'卧' => '臥',
-'卫' => '衛',
-'却' => '卻',
-'厂' => '廠',
-'厅' => '廳',
-'历' => '歷',
-'厉' => '厲',
-'压' => '壓',
-'厌' => '厭',
-'厍' => '厙',
-'厐' => '龎',
-'厕' => '廁',
-'厢' => '廂',
-'厣' => '厴',
-'厦' => '廈',
-'厨' => '廚',
-'厩' => '廄',
-'厮' => '廝',
-'县' => '縣',
-'叁' => '叄',
-'参' => '參',
-'叆' => '靉',
-'叇' => '靆',
-'双' => '雙',
-'发' => '發',
-'变' => '變',
-'叙' => '敘',
-'叠' => '疊',
-'叶' => '葉',
-'号' => '號',
-'叹' => '嘆',
-'叽' => '嘰',
-'后' => '後',
-'吓' => '嚇',
-'吕' => '呂',
-'吗' => '嗎',
-'吣' => '唚',
-'吨' => '噸',
-'听' => '聽',
-'启' => '啟',
-'吴' => '吳',
-'呐' => '吶',
-'呒' => '嘸',
-'呓' => '囈',
-'呕' => '嘔',
-'呖' => '嚦',
-'呗' => '唄',
-'员' => '員',
-'呙' => '咼',
-'呛' => '嗆',
-'呜' => '嗚',
-'咏' => '詠',
-'咙' => '嚨',
-'咛' => '嚀',
-'咝' => '噝',
-'响' => '響',
-'哑' => '啞',
-'哒' => '噠',
-'哓' => '嘵',
-'哔' => '嗶',
-'哕' => '噦',
-'哗' => '嘩',
-'哙' => '噲',
-'哜' => '嚌',
-'哝' => '噥',
-'哟' => '喲',
-'唛' => '嘜',
-'唝' => '嗊',
-'唠' => '嘮',
-'唡' => '啢',
-'唢' => '嗩',
-'唤' => '喚',
-'啧' => '嘖',
-'啬' => '嗇',
-'啭' => '囀',
-'啮' => '齧',
-'啯' => '嘓',
-'啰' => '囉',
-'啴' => '嘽',
-'啸' => '嘯',
-'喂' => '餵',
-'喷' => '噴',
-'喽' => '嘍',
-'喾' => '嚳',
-'嗫' => '囁',
-'嗳' => '噯',
-'嘘' => '噓',
-'嘤' => '嚶',
-'嘱' => '囑',
-'噜' => '嚕',
-'嚣' => '囂',
-'团' => '團',
-'园' => '園',
-'囱' => '囪',
-'围' => '圍',
-'囵' => '圇',
-'国' => '國',
-'图' => '圖',
-'圆' => '圓',
-'圣' => '聖',
-'圹' => '壙',
-'场' => '場',
-'坏' => '壞',
-'块' => '塊',
-'坚' => '堅',
-'坛' => '壇',
-'坜' => '壢',
-'坝' => '壩',
-'坞' => '塢',
-'坟' => '墳',
-'坠' => '墜',
-'垄' => '壟',
-'垅' => '壠',
-'垆' => '壚',
-'垒' => '壘',
-'垦' => '墾',
-'垩' => '堊',
-'垫' => '墊',
-'垭' => '埡',
-'垱' => '壋',
-'垲' => '塏',
-'埘' => '塒',
-'埙' => '塤',
-'埚' => '堝',
-'埯' => '垵',
-'堑' => '塹',
-'堕' => '墮',
-'墙' => '牆',
-'壮' => '壯',
-'声' => '聲',
-'壳' => '殼',
-'壶' => '壺',
-'壸' => '壼',
-'处' => '處',
-'备' => '備',
-'复' => '復',
-'够' => '夠',
-'头' => '頭',
-'夹' => '夾',
-'夺' => '奪',
-'奁' => '奩',
-'奂' => '奐',
-'奋' => '奮',
-'奖' => '獎',
-'奥' => '奧',
-'妆' => '妝',
-'妇' => '婦',
-'妈' => '媽',
-'妩' => '嫵',
-'妪' => '嫗',
-'妫' => '媯',
-'姗' => '姍',
-'姹' => '奼',
-'娄' => '婁',
-'娅' => '婭',
-'娆' => '嬈',
-'娇' => '嬌',
-'娈' => '孌',
-'娱' => '娛',
-'娲' => '媧',
-'娴' => '嫻',
-'婳' => '嫿',
-'婴' => '嬰',
-'婵' => '嬋',
-'婶' => '嬸',
-'媪' => '媼',
-'媭' => '嬃',
-'嫒' => '嬡',
-'嫔' => '嬪',
-'嫱' => '嬙',
-'嬷' => '嬤',
-'孙' => '孫',
-'学' => '學',
-'孪' => '孿',
-'宁' => '寧',
-'宝' => '寶',
-'实' => '實',
-'宠' => '寵',
-'审' => '審',
-'宪' => '憲',
-'宫' => '宮',
-'宽' => '寬',
-'宾' => '賓',
-'寝' => '寢',
-'对' => '對',
-'寻' => '尋',
-'导' => '導',
-'寿' => '壽',
-'将' => '將',
-'尔' => '爾',
-'尘' => '塵',
-'尝' => '嘗',
-'尧' => '堯',
-'尴' => '尷',
-'尸' => '屍',
-'尽' => '盡',
-'层' => '層',
-'屃' => '屓',
-'屉' => '屜',
-'届' => '屆',
-'属' => '屬',
-'屡' => '屢',
-'屦' => '屨',
-'屿' => '嶼',
-'岁' => '歲',
-'岂' => '豈',
-'岖' => '嶇',
-'岗' => '崗',
-'岘' => '峴',
-'岚' => '嵐',
-'岛' => '島',
-'岭' => '嶺',
-'岽' => '崬',
-'岿' => '巋',
-'峃' => '嶨',
-'峄' => '嶧',
-'峡' => '峽',
-'峣' => '嶢',
-'峤' => '嶠',
-'峥' => '崢',
-'峦' => '巒',
-'崂' => '嶗',
-'崃' => '崍',
-'崄' => '嶮',
-'崭' => '嶄',
-'嵘' => '嶸',
-'嵚' => '嶔',
-'嵝' => '嶁',
-'巅' => '巔',
-'巩' => '鞏',
-'巯' => '巰',
-'币' => '幣',
-'帅' => '帥',
-'师' => '師',
-'帏' => '幃',
-'帐' => '帳',
-'帘' => '簾',
-'帜' => '幟',
-'带' => '帶',
-'帧' => '幀',
-'帮' => '幫',
-'帱' => '幬',
-'帻' => '幘',
-'帼' => '幗',
-'幂' => '冪',
-'并' => '並',
-'幺' => '么',
-'广' => '廣',
-'庄' => '莊',
-'庆' => '慶',
-'庐' => '廬',
-'庑' => '廡',
-'库' => '庫',
-'应' => '應',
-'庙' => '廟',
-'庞' => '龐',
-'废' => '廢',
-'庼' => '廎',
-'廪' => '廩',
-'开' => '開',
-'异' => '異',
-'弃' => '棄',
-'弑' => '弒',
-'张' => '張',
-'弥' => '彌',
-'弪' => '弳',
-'弯' => '彎',
-'弹' => '彈',
-'强' => '強',
-'归' => '歸',
-'当' => '當',
-'录' => '錄',
-'彟' => '彠',
-'彦' => '彥',
-'彨' => '彲',
-'彻' => '徹',
-'径' => '徑',
-'徕' => '徠',
-'忆' => '憶',
-'忏' => '懺',
-'忧' => '憂',
-'忾' => '愾',
-'怀' => '懷',
-'态' => '態',
-'怂' => '慫',
-'怃' => '憮',
-'怄' => '慪',
-'怅' => '悵',
-'怆' => '愴',
-'怜' => '憐',
-'总' => '總',
-'怼' => '懟',
-'怿' => '懌',
-'恋' => '戀',
-'恒' => '恆',
-'恳' => '懇',
-'恶' => '惡',
-'恸' => '慟',
-'恹' => '懨',
-'恺' => '愷',
-'恻' => '惻',
-'恼' => '惱',
-'恽' => '惲',
-'悦' => '悅',
-'悫' => '愨',
-'悬' => '懸',
-'悭' => '慳',
-'悮' => '悞',
-'悯' => '憫',
-'惊' => '驚',
-'惧' => '懼',
-'惨' => '慘',
-'惩' => '懲',
-'惫' => '憊',
-'惬' => '愜',
-'惭' => '慚',
-'惮' => '憚',
-'惯' => '慣',
-'愠' => '慍',
-'愤' => '憤',
-'愦' => '憒',
-'愿' => '願',
-'慑' => '懾',
-'懑' => '懣',
-'懒' => '懶',
-'懔' => '懍',
-'戆' => '戇',
-'戋' => '戔',
-'戏' => '戲',
-'戗' => '戧',
-'战' => '戰',
-'戬' => '戩',
-'戯' => '戱',
-'户' => '戶',
-'扑' => '撲',
-'执' => '執',
-'扩' => '擴',
-'扪' => '捫',
-'扫' => '掃',
-'扬' => '揚',
-'扰' => '擾',
-'抚' => '撫',
-'抛' => '拋',
-'抟' => '摶',
-'抠' => '摳',
-'抡' => '掄',
-'抢' => '搶',
-'护' => '護',
-'报' => '報',
-'担' => '擔',
-'拟' => '擬',
-'拢' => '攏',
-'拣' => '揀',
-'拥' => '擁',
-'拦' => '攔',
-'拧' => '擰',
-'拨' => '撥',
-'择' => '擇',
-'挂' => '掛',
-'挚' => '摯',
-'挛' => '攣',
-'挜' => '掗',
-'挝' => '撾',
-'挞' => '撻',
-'挟' => '挾',
-'挠' => '撓',
-'挡' => '擋',
-'挢' => '撟',
-'挣' => '掙',
-'挤' => '擠',
-'挥' => '揮',
-'挦' => '撏',
-'捝' => '挩',
-'捞' => '撈',
-'损' => '損',
-'捡' => '撿',
-'换' => '換',
-'捣' => '搗',
-'据' => '據',
-'掳' => '擄',
-'掴' => '摑',
-'掷' => '擲',
-'掸' => '撣',
-'掺' => '摻',
-'掼' => '摜',
-'揽' => '攬',
-'揾' => '搵',
-'揿' => '撳',
-'搀' => '攙',
-'搁' => '擱',
-'搂' => '摟',
-'搅' => '攪',
-'携' => '攜',
-'摄' => '攝',
-'摅' => '攄',
-'摆' => '擺',
-'摇' => '搖',
-'摈' => '擯',
-'摊' => '攤',
-'撄' => '攖',
-'撑' => '撐',
-'撵' => '攆',
-'撷' => '擷',
-'撸' => '擼',
-'撺' => '攛',
-'擞' => '擻',
-'攒' => '攢',
-'敌' => '敵',
-'敛' => '斂',
-'敩' => '斆',
-'数' => '數',
-'斋' => '齋',
-'斓' => '斕',
-'斩' => '斬',
-'断' => '斷',
-'无' => '無',
-'旧' => '舊',
-'时' => '時',
-'旷' => '曠',
-'旸' => '暘',
-'昙' => '曇',
-'昼' => '晝',
-'昽' => '曨',
-'显' => '顯',
-'晋' => '晉',
-'晒' => '曬',
-'晓' => '曉',
-'晔' => '曄',
-'晕' => '暈',
-'晖' => '暉',
-'暂' => '暫',
-'暧' => '曖',
-'术' => '術',
-'机' => '機',
-'杀' => '殺',
-'杂' => '雜',
-'权' => '權',
-'杠' => '槓',
-'条' => '條',
-'来' => '來',
-'杨' => '楊',
-'杩' => '榪',
-'杰' => '傑',
-'极' => '極',
-'构' => '構',
-'枞' => '樅',
-'枢' => '樞',
-'枣' => '棗',
-'枥' => '櫪',
-'枧' => '梘',
-'枨' => '棖',
-'枪' => '槍',
-'枫' => '楓',
-'枭' => '梟',
-'柜' => '櫃',
-'柠' => '檸',
-'柽' => '檉',
-'栀' => '梔',
-'栅' => '柵',
-'标' => '標',
-'栈' => '棧',
-'栉' => '櫛',
-'栊' => '櫳',
-'栋' => '棟',
-'栌' => '櫨',
-'栎' => '櫟',
-'栏' => '欄',
-'树' => '樹',
-'栖' => '棲',
-'样' => '樣',
-'栾' => '欒',
-'桠' => '椏',
-'桡' => '橈',
-'桢' => '楨',
-'档' => '檔',
-'桤' => '榿',
-'桥' => '橋',
-'桦' => '樺',
-'桧' => '檜',
-'桨' => '槳',
-'桩' => '樁',
-'桪' => '樳',
-'梦' => '夢',
-'梼' => '檮',
-'梾' => '棶',
-'梿' => '槤',
-'检' => '檢',
-'棁' => '梲',
-'棂' => '欞',
-'椁' => '槨',
-'椝' => '槼',
-'椟' => '櫝',
-'椠' => '槧',
-'椢' => '槶',
-'椤' => '欏',
-'椫' => '樿',
-'椭' => '橢',
-'椮' => '槮',
-'楼' => '樓',
-'榄' => '欖',
-'榅' => '榲',
-'榇' => '櫬',
-'榈' => '櫚',
-'榉' => '櫸',
-'槚' => '檟',
-'槛' => '檻',
-'槟' => '檳',
-'槠' => '櫧',
-'横' => '橫',
-'樯' => '檣',
-'樱' => '櫻',
-'橥' => '櫫',
-'橱' => '櫥',
-'橹' => '櫓',
-'橼' => '櫞',
-'檩' => '檁',
-'欢' => '歡',
-'欤' => '歟',
-'欧' => '歐',
-'歼' => '殲',
-'殁' => '歿',
-'殇' => '殤',
-'残' => '殘',
-'殒' => '殞',
-'殓' => '殮',
-'殚' => '殫',
-'殡' => '殯',
-'殴' => '毆',
-'毁' => '毀',
-'毂' => '轂',
-'毕' => '畢',
-'毙' => '斃',
-'毡' => '氈',
-'毵' => '毿',
-'氇' => '氌',
-'气' => '氣',
-'氢' => '氫',
-'氩' => '氬',
-'氲' => '氳',
-'汇' => '匯',
-'汉' => '漢',
-'汤' => '湯',
-'汹' => '洶',
-'沟' => '溝',
-'没' => '沒',
-'沣' => '灃',
-'沤' => '漚',
-'沥' => '瀝',
-'沦' => '淪',
-'沧' => '滄',
-'沨' => '渢',
-'沩' => '溈',
-'沪' => '滬',
-'泞' => '濘',
-'泪' => '淚',
-'泶' => '澩',
-'泷' => '瀧',
-'泸' => '瀘',
-'泺' => '濼',
-'泻' => '瀉',
-'泼' => '潑',
-'泽' => '澤',
-'泾' => '涇',
-'洁' => '潔',
-'洒' => '灑',
-'洼' => '窪',
-'浃' => '浹',
-'浅' => '淺',
-'浆' => '漿',
-'浇' => '澆',
-'浈' => '湞',
-'浉' => '溮',
-'浊' => '濁',
-'测' => '測',
-'浍' => '澮',
-'济' => '濟',
-'浏' => '瀏',
-'浐' => '滻',
-'浑' => '渾',
-'浒' => '滸',
-'浓' => '濃',
-'浔' => '潯',
-'浕' => '濜',
-'涂' => '塗',
-'涛' => '濤',
-'涝' => '澇',
-'涞' => '淶',
-'涟' => '漣',
-'涠' => '潿',
-'涡' => '渦',
-'涢' => '溳',
-'涣' => '渙',
-'涤' => '滌',
-'润' => '潤',
-'涧' => '澗',
-'涨' => '漲',
-'涩' => '澀',
-'渊' => '淵',
-'渌' => '淥',
-'渍' => '漬',
-'渎' => '瀆',
-'渐' => '漸',
-'渑' => '澠',
-'渔' => '漁',
-'渖' => '瀋',
-'渗' => '滲',
-'温' => '溫',
-'湾' => '灣',
-'湿' => '濕',
-'溃' => '潰',
-'溅' => '濺',
-'溆' => '漵',
-'溇' => '漊',
-'滗' => '潷',
-'滚' => '滾',
-'滞' => '滯',
-'滟' => '灩',
-'滠' => '灄',
-'满' => '滿',
-'滢' => '瀅',
-'滤' => '濾',
-'滥' => '濫',
-'滦' => '灤',
-'滨' => '濱',
-'滩' => '灘',
-'滪' => '澦',
-'漤' => '灠',
-'潆' => '瀠',
-'潇' => '瀟',
-'潋' => '瀲',
-'潍' => '濰',
-'潜' => '潛',
-'潴' => '瀦',
-'澛' => '瀂',
-'澜' => '瀾',
-'濑' => '瀨',
-'濒' => '瀕',
-'灏' => '灝',
-'灭' => '滅',
-'灯' => '燈',
-'灵' => '靈',
-'灾' => '災',
-'灿' => '燦',
-'炀' => '煬',
-'炉' => '爐',
-'炖' => '燉',
-'炜' => '煒',
-'炝' => '熗',
-'点' => '點',
-'炼' => '煉',
-'炽' => '熾',
-'烁' => '爍',
-'烂' => '爛',
-'烃' => '烴',
-'烛' => '燭',
-'烟' => '煙',
-'烦' => '煩',
-'烧' => '燒',
-'烨' => '燁',
-'烩' => '燴',
-'烫' => '燙',
-'烬' => '燼',
-'热' => '熱',
-'焕' => '煥',
-'焖' => '燜',
-'焘' => '燾',
-'煴' => '熅',
-'爱' => '愛',
-'爷' => '爺',
-'牍' => '牘',
-'牦' => '氂',
-'牵' => '牽',
-'牺' => '犧',
-'犊' => '犢',
-'状' => '狀',
-'犷' => '獷',
-'犸' => '獁',
-'犹' => '猶',
-'狈' => '狽',
-'狝' => '獮',
-'狞' => '獰',
-'独' => '獨',
-'狭' => '狹',
-'狮' => '獅',
-'狯' => '獪',
-'狰' => '猙',
-'狱' => '獄',
-'狲' => '猻',
-'猃' => '獫',
-'猎' => '獵',
-'猕' => '獼',
-'猡' => '玀',
-'猪' => '豬',
-'猫' => '貓',
-'猬' => '蝟',
-'献' => '獻',
-'獭' => '獺',
-'玑' => '璣',
-'玙' => '璵',
-'玚' => '瑒',
-'玛' => '瑪',
-'玮' => '瑋',
-'环' => '環',
-'现' => '現',
-'玱' => '瑲',
-'玺' => '璽',
-'珐' => '琺',
-'珑' => '瓏',
-'珰' => '璫',
-'珲' => '琿',
-'琎' => '璡',
-'琏' => '璉',
-'琐' => '瑣',
-'琼' => '瓊',
-'瑶' => '瑤',
-'瑷' => '璦',
-'瑸' => '璸',
-'璎' => '瓔',
-'瓒' => '瓚',
-'瓯' => '甌',
-'电' => '電',
-'画' => '畫',
-'畅' => '暢',
-'畴' => '疇',
-'疖' => '癤',
-'疗' => '療',
-'疟' => '瘧',
-'疠' => '癘',
-'疡' => '瘍',
-'疬' => '癧',
-'疭' => '瘲',
-'疮' => '瘡',
-'疯' => '瘋',
-'疱' => '皰',
-'痈' => '癰',
-'痉' => '痙',
-'痒' => '癢',
-'痖' => '瘂',
-'痨' => '癆',
-'痪' => '瘓',
-'痫' => '癇',
-'痳' => '痲',
-'瘅' => '癉',
-'瘆' => '瘮',
-'瘗' => '瘞',
-'瘘' => '瘺',
-'瘪' => '癟',
-'瘫' => '癱',
-'瘾' => '癮',
-'瘿' => '癭',
-'癞' => '癩',
-'癣' => '癬',
-'癫' => '癲',
-'皑' => '皚',
-'皱' => '皺',
-'皲' => '皸',
-'盏' => '盞',
-'盐' => '鹽',
-'监' => '監',
-'盖' => '蓋',
-'盗' => '盜',
-'盘' => '盤',
-'眍' => '瞘',
-'眦' => '眥',
-'眬' => '矓',
-'睁' => '睜',
-'睐' => '睞',
-'睑' => '瞼',
-'瞆' => '瞶',
-'瞒' => '瞞',
-'瞩' => '矚',
-'矫' => '矯',
-'矶' => '磯',
-'矾' => '礬',
-'矿' => '礦',
-'砀' => '碭',
-'码' => '碼',
-'砖' => '磚',
-'砗' => '硨',
-'砚' => '硯',
-'砜' => '碸',
-'砺' => '礪',
-'砻' => '礱',
-'砾' => '礫',
-'础' => '礎',
-'硁' => '硜',
-'硕' => '碩',
-'硖' => '硤',
-'硗' => '磽',
-'硙' => '磑',
-'硚' => '礄',
-'确' => '確',
-'硵' => '磠',
-'硷' => '鹼',
-'碍' => '礙',
-'碛' => '磧',
-'碜' => '磣',
-'碱' => '鹼',
-'礼' => '禮',
-'祃' => '禡',
-'祎' => '禕',
-'祢' => '禰',
-'祯' => '禎',
-'祷' => '禱',
-'祸' => '禍',
-'禀' => '稟',
-'禄' => '祿',
-'禅' => '禪',
-'离' => '離',
-'秃' => '禿',
-'秆' => '稈',
-'种' => '種',
-'积' => '積',
-'称' => '稱',
-'秽' => '穢',
-'秾' => '穠',
-'稆' => '穭',
-'税' => '稅',
-'稣' => '穌',
-'稳' => '穩',
-'穑' => '穡',
-'穷' => '窮',
-'窃' => '竊',
-'窍' => '竅',
-'窎' => '窵',
-'窑' => '窯',
-'窜' => '竄',
-'窝' => '窩',
-'窥' => '窺',
-'窦' => '竇',
-'窭' => '窶',
-'竖' => '豎',
-'竞' => '競',
-'笃' => '篤',
-'笋' => '筍',
-'笔' => '筆',
-'笕' => '筧',
-'笺' => '箋',
-'笼' => '籠',
-'笾' => '籩',
-'筑' => '築',
-'筚' => '篳',
-'筛' => '篩',
-'筜' => '簹',
-'筝' => '箏',
-'筹' => '籌',
-'筼' => '篔',
-'签' => '簽',
-'简' => '簡',
-'箓' => '籙',
-'箦' => '簀',
-'箧' => '篋',
-'箨' => '籜',
-'箩' => '籮',
-'箪' => '簞',
-'箫' => '簫',
-'篑' => '簣',
-'篓' => '簍',
-'篮' => '籃',
-'篯' => '籛',
-'篱' => '籬',
-'簖' => '籪',
-'籁' => '籟',
-'籴' => '糴',
-'类' => '類',
-'籼' => '秈',
-'粜' => '糶',
-'粝' => '糲',
-'粤' => '粵',
-'粪' => '糞',
-'粮' => '糧',
-'糁' => '糝',
-'糇' => '餱',
-'紧' => '緊',
-'絷' => '縶',
-'纟' => '糹',
-'纠' => '糾',
-'纡' => '紆',
-'红' => '紅',
-'纣' => '紂',
-'纤' => '纖',
-'纥' => '紇',
-'约' => '約',
-'级' => '級',
-'纨' => '紈',
-'纩' => '纊',
-'纪' => '紀',
-'纫' => '紉',
-'纬' => '緯',
-'纭' => '紜',
-'纮' => '紘',
-'纯' => '純',
-'纰' => '紕',
-'纱' => '紗',
-'纲' => '綱',
-'纳' => '納',
-'纴' => '紝',
-'纵' => '縱',
-'纶' => '綸',
-'纷' => '紛',
-'纸' => '紙',
-'纹' => '紋',
-'纺' => '紡',
-'纻' => '紵',
-'纼' => '紖',
-'纽' => '紐',
-'纾' => '紓',
-'线' => '線',
-'绀' => '紺',
-'绁' => '紲',
-'绂' => '紱',
-'练' => '練',
-'组' => '組',
-'绅' => '紳',
-'细' => '細',
-'织' => '織',
-'终' => '終',
-'绉' => '縐',
-'绊' => '絆',
-'绋' => '紼',
-'绌' => '絀',
-'绍' => '紹',
-'绎' => '繹',
-'经' => '經',
-'绐' => '紿',
-'绑' => '綁',
-'绒' => '絨',
-'结' => '結',
-'绔' => '絝',
-'绕' => '繞',
-'绖' => '絰',
-'绗' => '絎',
-'绘' => '繪',
-'给' => '給',
-'绚' => '絢',
-'绛' => '絳',
-'络' => '絡',
-'绝' => '絕',
-'绞' => '絞',
-'统' => '統',
-'绠' => '綆',
-'绡' => '綃',
-'绢' => '絹',
-'绣' => '繡',
-'绤' => '綌',
-'绥' => '綏',
-'绦' => '絛',
-'继' => '繼',
-'绨' => '綈',
-'绩' => '績',
-'绪' => '緒',
-'绫' => '綾',
-'绬' => '緓',
-'续' => '續',
-'绮' => '綺',
-'绯' => '緋',
-'绰' => '綽',
-'绱' => '鞝',
-'绲' => '緄',
-'绳' => '繩',
-'维' => '維',
-'绵' => '綿',
-'绶' => '綬',
-'绷' => '繃',
-'绸' => '綢',
-'绹' => '綯',
-'绺' => '綹',
-'绻' => '綣',
-'综' => '綜',
-'绽' => '綻',
-'绾' => '綰',
-'绿' => '綠',
-'缀' => '綴',
-'缁' => '緇',
-'缂' => '緙',
-'缃' => '緗',
-'缄' => '緘',
-'缅' => '緬',
-'缆' => '纜',
-'缇' => '緹',
-'缈' => '緲',
-'缉' => '緝',
-'缊' => '縕',
-'缋' => '繢',
-'缌' => '緦',
-'缍' => '綞',
-'缎' => '緞',
-'缏' => '緶',
-'缐' => '線',
-'缑' => '緱',
-'缒' => '縋',
-'缓' => '緩',
-'缔' => '締',
-'缕' => '縷',
-'编' => '編',
-'缗' => '緡',
-'缘' => '緣',
-'缙' => '縉',
-'缚' => '縛',
-'缛' => '縟',
-'缜' => '縝',
-'缝' => '縫',
-'缞' => '縗',
-'缟' => '縞',
-'缠' => '纏',
-'缡' => '縭',
-'缢' => '縊',
-'缣' => '縑',
-'缤' => '繽',
-'缥' => '縹',
-'缦' => '縵',
-'缧' => '縲',
-'缨' => '纓',
-'缩' => '縮',
-'缪' => '繆',
-'缫' => '繅',
-'缬' => '纈',
-'缭' => '繚',
-'缮' => '繕',
-'缯' => '繒',
-'缰' => '韁',
-'缱' => '繾',
-'缲' => '繰',
-'缳' => '繯',
-'缴' => '繳',
-'缵' => '纘',
-'罂' => '罌',
-'网' => '網',
-'罗' => '羅',
-'罚' => '罰',
-'罢' => '罷',
-'罴' => '羆',
-'羁' => '羈',
-'羟' => '羥',
-'羡' => '羨',
-'翘' => '翹',
-'翙' => '翽',
-'翚' => '翬',
-'耢' => '耮',
-'耧' => '耬',
-'耸' => '聳',
-'耻' => '恥',
-'聂' => '聶',
-'聋' => '聾',
-'职' => '職',
-'聍' => '聹',
-'联' => '聯',
-'聩' => '聵',
-'聪' => '聰',
-'肃' => '肅',
-'肠' => '腸',
-'肤' => '膚',
-'肮' => '骯',
-'肴' => '餚',
-'肾' => '腎',
-'肿' => '腫',
-'胀' => '脹',
-'胁' => '脅',
-'胆' => '膽',
-'胜' => '勝',
-'胧' => '朧',
-'胨' => '腖',
-'胪' => '臚',
-'胫' => '脛',
-'胶' => '膠',
-'脉' => '脈',
-'脍' => '膾',
-'脏' => '髒',
-'脐' => '臍',
-'脑' => '腦',
-'脓' => '膿',
-'脔' => '臠',
-'脚' => '腳',
-'脱' => '脫',
-'脶' => '腡',
-'脸' => '臉',
-'腊' => '臘',
-'腌' => '醃',
-'腘' => '膕',
-'腭' => '齶',
-'腻' => '膩',
-'腼' => '靦',
-'腽' => '膃',
-'腾' => '騰',
-'膑' => '臏',
-'臜' => '臢',
-'舆' => '輿',
-'舣' => '艤',
-'舰' => '艦',
-'舱' => '艙',
-'舻' => '艫',
-'艰' => '艱',
-'艳' => '艷',
-'艺' => '藝',
-'节' => '節',
-'芈' => '羋',
-'芗' => '薌',
-'芜' => '蕪',
-'芦' => '蘆',
-'苁' => '蓯',
-'苇' => '葦',
-'苈' => '藶',
-'苋' => '莧',
-'苌' => '萇',
-'苍' => '蒼',
-'苎' => '苧',
-'苏' => '蘇',
-'苧' => '薴',
-'茎' => '莖',
-'茏' => '蘢',
-'茑' => '蔦',
-'茔' => '塋',
-'茕' => '煢',
-'茧' => '繭',
-'荆' => '荊',
-'荐' => '薦',
-'荙' => '薘',
-'荚' => '莢',
-'荛' => '蕘',
-'荜' => '蓽',
-'荝' => '萴',
-'荞' => '蕎',
-'荟' => '薈',
-'荠' => '薺',
-'荡' => '盪',
-'荣' => '榮',
-'荤' => '葷',
-'荥' => '滎',
-'荦' => '犖',
-'荧' => '熒',
-'荨' => '蕁',
-'荩' => '藎',
-'荪' => '蓀',
-'荫' => '蔭',
-'荬' => '蕒',
-'荭' => '葒',
-'荮' => '葤',
-'药' => '藥',
-'莅' => '蒞',
-'莱' => '萊',
-'莲' => '蓮',
-'莳' => '蒔',
-'莴' => '萵',
-'莶' => '薟',
-'获' => '獲',
-'莸' => '蕕',
-'莹' => '瑩',
-'莺' => '鶯',
-'莼' => '蓴',
-'萚' => '蘀',
-'萝' => '蘿',
-'萤' => '螢',
-'营' => '營',
-'萦' => '縈',
-'萧' => '蕭',
-'萨' => '薩',
-'葱' => '蔥',
-'蒇' => '蕆',
-'蒉' => '蕢',
-'蒋' => '蔣',
-'蒌' => '蔞',
-'蓝' => '藍',
-'蓟' => '薊',
-'蓠' => '蘺',
-'蓣' => '蕷',
-'蓥' => '鎣',
-'蓦' => '驀',
-'蔂' => '虆',
-'蔷' => '薔',
-'蔹' => '蘞',
-'蔺' => '藺',
-'蔼' => '藹',
-'蕰' => '薀',
-'蕲' => '蘄',
-'蕴' => '蘊',
-'薮' => '藪',
-'藓' => '蘚',
-'蘖' => '櫱',
-'虏' => '虜',
-'虑' => '慮',
-'虚' => '虛',
-'虫' => '蟲',
-'虮' => '蟣',
-'虽' => '雖',
-'虾' => '蝦',
-'虿' => '蠆',
-'蚀' => '蝕',
-'蚁' => '蟻',
-'蚂' => '螞',
-'蚃' => '蠁',
-'蚕' => '蠶',
-'蚬' => '蜆',
-'蛊' => '蠱',
-'蛎' => '蠣',
-'蛏' => '蟶',
-'蛮' => '蠻',
-'蛰' => '蟄',
-'蛱' => '蛺',
-'蛲' => '蟯',
-'蛳' => '螄',
-'蛴' => '蠐',
-'蜕' => '蛻',
-'蜗' => '蝸',
-'蜡' => '蠟',
-'蝇' => '蠅',
-'蝈' => '蟈',
-'蝉' => '蟬',
-'蝎' => '蠍',
-'蝼' => '螻',
-'蝾' => '蠑',
-'螀' => '螿',
-'螨' => '蟎',
-'蟏' => '蠨',
-'衅' => '釁',
-'衔' => '銜',
-'补' => '補',
-'衬' => '襯',
-'衮' => '袞',
-'袄' => '襖',
-'袅' => '裊',
-'袆' => '褘',
-'袜' => '襪',
-'袭' => '襲',
-'袯' => '襏',
-'装' => '裝',
-'裆' => '襠',
-'裈' => '褌',
-'裢' => '褳',
-'裣' => '襝',
-'裤' => '褲',
-'裥' => '襉',
-'褛' => '褸',
-'褴' => '襤',
-'襕' => '襴',
-'见' => '見',
-'观' => '觀',
-'觃' => '覎',
-'规' => '規',
-'觅' => '覓',
-'视' => '視',
-'觇' => '覘',
-'览' => '覽',
-'觉' => '覺',
-'觊' => '覬',
-'觋' => '覡',
-'觌' => '覿',
-'觍' => '覥',
-'觎' => '覦',
-'觏' => '覯',
-'觐' => '覲',
-'觑' => '覷',
-'觞' => '觴',
-'触' => '觸',
-'觯' => '觶',
-'訚' => '誾',
-'詟' => '讋',
-'誉' => '譽',
-'誊' => '謄',
-'讠' => '訁',
-'计' => '計',
-'订' => '訂',
-'讣' => '訃',
-'认' => '認',
-'讥' => '譏',
-'讦' => '訐',
-'讧' => '訌',
-'讨' => '討',
-'让' => '讓',
-'讪' => '訕',
-'讫' => '訖',
-'讬' => '託',
-'训' => '訓',
-'议' => '議',
-'讯' => '訊',
-'记' => '記',
-'讱' => '訒',
-'讲' => '講',
-'讳' => '諱',
-'讴' => '謳',
-'讵' => '詎',
-'讶' => '訝',
-'讷' => '訥',
-'许' => '許',
-'讹' => '訛',
-'论' => '論',
-'讻' => '訩',
-'讼' => '訟',
-'讽' => '諷',
-'设' => '設',
-'访' => '訪',
-'诀' => '訣',
-'证' => '證',
-'诂' => '詁',
-'诃' => '訶',
-'评' => '評',
-'诅' => '詛',
-'识' => '識',
-'诇' => '詗',
-'诈' => '詐',
-'诉' => '訴',
-'诊' => '診',
-'诋' => '詆',
-'诌' => '謅',
-'词' => '詞',
-'诎' => '詘',
-'诏' => '詔',
-'诐' => '詖',
-'译' => '譯',
-'诒' => '詒',
-'诓' => '誆',
-'诔' => '誄',
-'试' => '試',
-'诖' => '詿',
-'诗' => '詩',
-'诘' => '詰',
-'诙' => '詼',
-'诚' => '誠',
-'诛' => '誅',
-'诜' => '詵',
-'话' => '話',
-'诞' => '誕',
-'诟' => '詬',
-'诠' => '詮',
-'诡' => '詭',
-'询' => '詢',
-'诣' => '詣',
-'诤' => '諍',
-'该' => '該',
-'详' => '詳',
-'诧' => '詫',
-'诨' => '諢',
-'诩' => '詡',
-'诪' => '譸',
-'诫' => '誡',
-'诬' => '誣',
-'语' => '語',
-'诮' => '誚',
-'误' => '誤',
-'诰' => '誥',
-'诱' => '誘',
-'诲' => '誨',
-'诳' => '誑',
-'说' => '說',
-'诵' => '誦',
-'诶' => '誒',
-'请' => '請',
-'诸' => '諸',
-'诹' => '諏',
-'诺' => '諾',
-'读' => '讀',
-'诼' => '諑',
-'诽' => '誹',
-'课' => '課',
-'诿' => '諉',
-'谀' => '諛',
-'谁' => '誰',
-'谂' => '諗',
-'调' => '調',
-'谄' => '諂',
-'谅' => '諒',
-'谆' => '諄',
-'谇' => '誶',
-'谈' => '談',
-'谊' => '誼',
-'谋' => '謀',
-'谌' => '諶',
-'谍' => '諜',
-'谎' => '謊',
-'谏' => '諫',
-'谐' => '諧',
-'谑' => '謔',
-'谒' => '謁',
-'谓' => '謂',
-'谔' => '諤',
-'谕' => '諭',
-'谖' => '諼',
-'谗' => '讒',
-'谘' => '諮',
-'谙' => '諳',
-'谚' => '諺',
-'谛' => '諦',
-'谜' => '謎',
-'谝' => '諞',
-'谞' => '諝',
-'谟' => '謨',
-'谠' => '讜',
-'谡' => '謖',
-'谢' => '謝',
-'谣' => '謠',
-'谤' => '謗',
-'谥' => '諡',
-'谦' => '謙',
-'谧' => '謐',
-'谨' => '謹',
-'谩' => '謾',
-'谪' => '謫',
-'谫' => '譾',
-'谬' => '謬',
-'谭' => '譚',
-'谮' => '譖',
-'谯' => '譙',
-'谰' => '讕',
-'谱' => '譜',
-'谲' => '譎',
-'谳' => '讞',
-'谴' => '譴',
-'谵' => '譫',
-'谶' => '讖',
-'豮' => '豶',
-'贝' => '貝',
-'贞' => '貞',
-'负' => '負',
-'贠' => '貟',
-'贡' => '貢',
-'财' => '財',
-'责' => '責',
-'贤' => '賢',
-'败' => '敗',
-'账' => '賬',
-'货' => '貨',
-'质' => '質',
-'贩' => '販',
-'贪' => '貪',
-'贫' => '貧',
-'贬' => '貶',
-'购' => '購',
-'贮' => '貯',
-'贯' => '貫',
-'贰' => '貳',
-'贱' => '賤',
-'贲' => '賁',
-'贳' => '貰',
-'贴' => '貼',
-'贵' => '貴',
-'贶' => '貺',
-'贷' => '貸',
-'贸' => '貿',
-'费' => '費',
-'贺' => '賀',
-'贻' => '貽',
-'贼' => '賊',
-'贽' => '贄',
-'贾' => '賈',
-'贿' => '賄',
-'赀' => '貲',
-'赁' => '賃',
-'赂' => '賂',
-'赃' => '贓',
-'资' => '資',
-'赅' => '賅',
-'赆' => '贐',
-'赇' => '賕',
-'赈' => '賑',
-'赉' => '賚',
-'赊' => '賒',
-'赋' => '賦',
-'赌' => '賭',
-'赍' => '齎',
-'赎' => '贖',
-'赏' => '賞',
-'赐' => '賜',
-'赑' => '贔',
-'赒' => '賙',
-'赓' => '賡',
-'赔' => '賠',
-'赕' => '賧',
-'赖' => '賴',
-'赗' => '賵',
-'赘' => '贅',
-'赙' => '賻',
-'赚' => '賺',
-'赛' => '賽',
-'赜' => '賾',
-'赝' => '贗',
-'赞' => '贊',
-'赟' => '贇',
-'赠' => '贈',
-'赡' => '贍',
-'赢' => '贏',
-'赣' => '贛',
-'赪' => '赬',
-'赵' => '趙',
-'赶' => '趕',
-'趋' => '趨',
-'趱' => '趲',
-'趸' => '躉',
-'跃' => '躍',
-'跄' => '蹌',
-'跞' => '躒',
-'践' => '踐',
-'跶' => '躂',
-'跷' => '蹺',
-'跸' => '蹕',
-'跹' => '躚',
-'跻' => '躋',
-'踊' => '踴',
-'踌' => '躊',
-'踪' => '蹤',
-'踬' => '躓',
-'踯' => '躑',
-'蹑' => '躡',
-'蹒' => '蹣',
-'蹰' => '躕',
-'蹿' => '躥',
-'躏' => '躪',
-'躜' => '躦',
-'躯' => '軀',
-'车' => '車',
-'轧' => '軋',
-'轨' => '軌',
-'轩' => '軒',
-'轪' => '軑',
-'轫' => '軔',
-'转' => '轉',
-'轭' => '軛',
-'轮' => '輪',
-'软' => '軟',
-'轰' => '轟',
-'轱' => '軲',
-'轲' => '軻',
-'轳' => '轤',
-'轴' => '軸',
-'轵' => '軹',
-'轶' => '軼',
-'轷' => '軤',
-'轸' => '軫',
-'轹' => '轢',
-'轺' => '軺',
-'轻' => '輕',
-'轼' => '軾',
-'载' => '載',
-'轾' => '輊',
-'轿' => '轎',
-'辀' => '輈',
-'辁' => '輇',
-'辂' => '輅',
-'较' => '較',
-'辄' => '輒',
-'辅' => '輔',
-'辆' => '輛',
-'辇' => '輦',
-'辈' => '輩',
-'辉' => '輝',
-'辊' => '輥',
-'辋' => '輞',
-'辌' => '輬',
-'辍' => '輟',
-'辎' => '輜',
-'辏' => '輳',
-'辐' => '輻',
-'辑' => '輯',
-'辒' => '轀',
-'输' => '輸',
-'辔' => '轡',
-'辕' => '轅',
-'辖' => '轄',
-'辗' => '輾',
-'辘' => '轆',
-'辙' => '轍',
-'辚' => '轔',
-'辞' => '辭',
-'辩' => '辯',
-'辫' => '辮',
-'边' => '邊',
-'辽' => '遼',
-'达' => '達',
-'迁' => '遷',
-'过' => '過',
-'迈' => '邁',
-'运' => '運',
-'还' => '還',
-'这' => '這',
-'进' => '進',
-'远' => '遠',
-'违' => '違',
-'连' => '連',
-'迟' => '遲',
-'迩' => '邇',
-'迳' => '逕',
-'迹' => '跡',
-'适' => '適',
-'选' => '選',
-'逊' => '遜',
-'递' => '遞',
-'逦' => '邐',
-'逻' => '邏',
-'遗' => '遺',
-'遥' => '遙',
-'邓' => '鄧',
-'邝' => '鄺',
-'邬' => '鄔',
-'邮' => '郵',
-'邹' => '鄒',
-'邺' => '鄴',
-'邻' => '鄰',
-'郏' => '郟',
-'郐' => '鄶',
-'郑' => '鄭',
-'郓' => '鄆',
-'郦' => '酈',
-'郧' => '鄖',
-'郸' => '鄲',
-'酂' => '酇',
-'酝' => '醞',
-'酦' => '醱',
-'酱' => '醬',
-'酽' => '釅',
-'酾' => '釃',
-'酿' => '釀',
-'释' => '釋',
-'鉴' => '鑒',
-'銮' => '鑾',
-'錾' => '鏨',
-'钅' => '釒',
-'钆' => '釓',
-'钇' => '釔',
-'针' => '針',
-'钉' => '釘',
-'钊' => '釗',
-'钋' => '釙',
-'钌' => '釕',
-'钍' => '釷',
-'钎' => '釺',
-'钏' => '釧',
-'钐' => '釤',
-'钑' => '鈒',
-'钒' => '釩',
-'钓' => '釣',
-'钔' => '鍆',
-'钕' => '釹',
-'钖' => '鍚',
-'钗' => '釵',
-'钘' => '鈃',
-'钙' => '鈣',
-'钚' => '鈈',
-'钛' => '鈦',
-'钜' => '鉅',
-'钝' => '鈍',
-'钞' => '鈔',
-'钟' => '鍾',
-'钠' => '鈉',
-'钡' => '鋇',
-'钢' => '鋼',
-'钣' => '鈑',
-'钤' => '鈐',
-'钥' => '鑰',
-'钦' => '欽',
-'钧' => '鈞',
-'钨' => '鎢',
-'钩' => '鈎',
-'钪' => '鈧',
-'钫' => '鈁',
-'钬' => '鈥',
-'钭' => '鈄',
-'钮' => '鈕',
-'钯' => '鈀',
-'钰' => '鈺',
-'钱' => '錢',
-'钲' => '鉦',
-'钳' => '鉗',
-'钴' => '鈷',
-'钵' => '缽',
-'钶' => '鈳',
-'钷' => '鉕',
-'钸' => '鈽',
-'钹' => '鈸',
-'钺' => '鉞',
-'钻' => '鑽',
-'钼' => '鉬',
-'钽' => '鉭',
-'钾' => '鉀',
-'钿' => '鈿',
-'铀' => '鈾',
-'铁' => '鐵',
-'铂' => '鉑',
-'铃' => '鈴',
-'铄' => '鑠',
-'铅' => '鉛',
-'铆' => '鉚',
-'铇' => '鉋',
-'铈' => '鈰',
-'铉' => '鉉',
-'铊' => '鉈',
-'铋' => '鉍',
-'铌' => '鈮',
-'铍' => '鈹',
-'铎' => '鐸',
-'铏' => '鉶',
-'铐' => '銬',
-'铑' => '銠',
-'铒' => '鉺',
-'铓' => '鋩',
-'铔' => '錏',
-'铕' => '銪',
-'铖' => '鋮',
-'铗' => '鋏',
-'铘' => '鋣',
-'铙' => '鐃',
-'铚' => '銍',
-'铛' => '鐺',
-'铜' => '銅',
-'铝' => '鋁',
-'铞' => '銱',
-'铟' => '銦',
-'铠' => '鎧',
-'铡' => '鍘',
-'铢' => '銖',
-'铣' => '銑',
-'铤' => '鋌',
-'铥' => '銩',
-'铦' => '銛',
-'铧' => '鏵',
-'铨' => '銓',
-'铩' => '鎩',
-'铪' => '鉿',
-'铫' => '銚',
-'铬' => '鉻',
-'铭' => '銘',
-'铮' => '錚',
-'铯' => '銫',
-'铰' => '鉸',
-'铱' => '銥',
-'铲' => '鏟',
-'铳' => '銃',
-'铴' => '鐋',
-'铵' => '銨',
-'银' => '銀',
-'铷' => '銣',
-'铸' => '鑄',
-'铹' => '鐒',
-'铺' => '鋪',
-'铻' => '鋙',
-'铼' => '錸',
-'铽' => '鋱',
-'链' => '鏈',
-'铿' => '鏗',
-'销' => '銷',
-'锁' => '鎖',
-'锂' => '鋰',
-'锃' => '鋥',
-'锄' => '鋤',
-'锅' => '鍋',
-'锆' => '鋯',
-'锇' => '鋨',
-'锈' => '銹',
-'锉' => '銼',
-'锊' => '鋝',
-'锋' => '鋒',
-'锌' => '鋅',
-'锍' => '鋶',
-'锎' => '鐦',
-'锏' => '鐧',
-'锐' => '銳',
-'锑' => '銻',
-'锒' => '鋃',
-'锓' => '鋟',
-'锔' => '鋦',
-'锕' => '錒',
-'锖' => '錆',
-'锗' => '鍺',
-'锘' => '鍩',
-'错' => '錯',
-'锚' => '錨',
-'锛' => '錛',
-'锜' => '錡',
-'锝' => '鍀',
-'锞' => '錁',
-'锟' => '錕',
-'锠' => '錩',
-'锡' => '錫',
-'锢' => '錮',
-'锣' => '鑼',
-'锤' => '錘',
-'锥' => '錐',
-'锦' => '錦',
-'锧' => '鑕',
-'锨' => '杴',
-'锩' => '錈',
-'锪' => '鍃',
-'锫' => '錇',
-'锬' => '錟',
-'锭' => '錠',
-'键' => '鍵',
-'锯' => '鋸',
-'锰' => '錳',
-'锱' => '錙',
-'锲' => '鍥',
-'锳' => '鍈',
-'锴' => '鍇',
-'锵' => '鏘',
-'锶' => '鍶',
-'锷' => '鍔',
-'锸' => '鍤',
-'锹' => '鍬',
-'锺' => '鍾',
-'锻' => '鍛',
-'锼' => '鎪',
-'锽' => '鍠',
-'锾' => '鍰',
-'锿' => '鎄',
-'镀' => '鍍',
-'镁' => '鎂',
-'镂' => '鏤',
-'镃' => '鎡',
-'镄' => '鐨',
-'镅' => '鎇',
-'镆' => '鏌',
-'镇' => '鎮',
-'镈' => '鎛',
-'镉' => '鎘',
-'镊' => '鑷',
-'镋' => '钂',
-'镌' => '鐫',
-'镍' => '鎳',
-'镎' => '鎿',
-'镏' => '鎦',
-'镐' => '鎬',
-'镑' => '鎊',
-'镒' => '鎰',
-'镓' => '鎵',
-'镔' => '鑌',
-'镕' => '鎔',
-'镖' => '鏢',
-'镗' => '鏜',
-'镘' => '鏝',
-'镙' => '鏍',
-'镚' => '鏰',
-'镛' => '鏞',
-'镜' => '鏡',
-'镝' => '鏑',
-'镞' => '鏃',
-'镟' => '鏇',
-'镠' => '鏐',
-'镡' => '鐔',
-'镢' => '钁',
-'镣' => '鐐',
-'镤' => '鏷',
-'镥' => '鑥',
-'镦' => '鐓',
-'镧' => '鑭',
-'镨' => '鐠',
-'镩' => '鑹',
-'镪' => '鏹',
-'镫' => '鐙',
-'镬' => '鑊',
-'镭' => '鐳',
-'镮' => '鐶',
-'镯' => '鐲',
-'镰' => '鐮',
-'镱' => '鐿',
-'镲' => '鑔',
-'镳' => '鑣',
-'镴' => '鑞',
-'镵' => '鑱',
-'镶' => '鑲',
-'长' => '長',
-'门' => '門',
-'闩' => '閂',
-'闪' => '閃',
-'闫' => '閆',
-'闬' => '閈',
-'闭' => '閉',
-'问' => '問',
-'闯' => '闖',
-'闰' => '閏',
-'闱' => '闈',
-'闲' => '閒',
-'闳' => '閎',
-'间' => '間',
-'闵' => '閔',
-'闶' => '閌',
-'闷' => '悶',
-'闸' => '閘',
-'闹' => '鬧',
-'闺' => '閨',
-'闻' => '聞',
-'闼' => '闥',
-'闽' => '閩',
-'闾' => '閭',
-'闿' => '闓',
-'阀' => '閥',
-'阁' => '閣',
-'阂' => '閡',
-'阃' => '閫',
-'阄' => '鬮',
-'阅' => '閱',
-'阆' => '閬',
-'阇' => '闍',
-'阈' => '閾',
-'阉' => '閹',
-'阊' => '閶',
-'阋' => '鬩',
-'阌' => '閿',
-'阍' => '閽',
-'阎' => '閻',
-'阏' => '閼',
-'阐' => '闡',
-'阑' => '闌',
-'阒' => '闃',
-'阓' => '闠',
-'阔' => '闊',
-'阕' => '闋',
-'阖' => '闔',
-'阗' => '闐',
-'阘' => '闒',
-'阙' => '闕',
-'阚' => '闞',
-'阛' => '闤',
-'队' => '隊',
-'阳' => '陽',
-'阴' => '陰',
-'阵' => '陣',
-'阶' => '階',
-'际' => '際',
-'陆' => '陸',
-'陇' => '隴',
-'陈' => '陳',
-'陉' => '陘',
-'陕' => '陝',
-'陧' => '隉',
-'陨' => '隕',
-'险' => '險',
-'随' => '隨',
-'隐' => '隱',
-'隶' => '隸',
-'隽' => '雋',
-'难' => '難',
-'雏' => '雛',
-'雠' => '讎',
-'雳' => '靂',
-'雾' => '霧',
-'霁' => '霽',
-'霡' => '霢',
-'霭' => '靄',
-'靓' => '靚',
-'静' => '靜',
-'靥' => '靨',
-'鞑' => '韃',
-'鞒' => '鞽',
-'鞯' => '韉',
-'韦' => '韋',
-'韧' => '韌',
-'韨' => '韍',
-'韩' => '韓',
-'韪' => '韙',
-'韫' => '韞',
-'韬' => '韜',
-'韵' => '韻',
-'页' => '頁',
-'顶' => '頂',
-'顷' => '頃',
-'顸' => '頇',
-'项' => '項',
-'顺' => '順',
-'须' => '須',
-'顼' => '頊',
-'顽' => '頑',
-'顾' => '顧',
-'顿' => '頓',
-'颀' => '頎',
-'颁' => '頒',
-'颂' => '頌',
-'颃' => '頏',
-'预' => '預',
-'颅' => '顱',
-'领' => '領',
-'颇' => '頗',
-'颈' => '頸',
-'颉' => '頡',
-'颊' => '頰',
-'颋' => '頲',
-'颌' => '頜',
-'颍' => '潁',
-'颎' => '熲',
-'颏' => '頦',
-'颐' => '頤',
-'频' => '頻',
-'颒' => '頮',
-'颓' => '頹',
-'颔' => '頷',
-'颕' => '頴',
-'颖' => '穎',
-'颗' => '顆',
-'题' => '題',
-'颙' => '顒',
-'颚' => '顎',
-'颛' => '顓',
-'颜' => '顏',
-'额' => '額',
-'颞' => '顳',
-'颟' => '顢',
-'颠' => '顛',
-'颡' => '顙',
-'颢' => '顥',
-'颣' => '纇',
-'颤' => '顫',
-'颥' => '顬',
-'颦' => '顰',
-'颧' => '顴',
-'风' => '風',
-'飏' => '颺',
-'飐' => '颭',
-'飑' => '颮',
-'飒' => '颯',
-'飓' => '颶',
-'飔' => '颸',
-'飕' => '颼',
-'飖' => '颻',
-'飗' => '飀',
-'飘' => '飄',
-'飙' => '飆',
-'飚' => '飈',
-'飞' => '飛',
-'飨' => '饗',
-'餍' => '饜',
-'饣' => '飠',
-'饤' => '飣',
-'饥' => '飢',
-'饦' => '飥',
-'饧' => '餳',
-'饨' => '飩',
-'饩' => '餼',
-'饪' => '飪',
-'饫' => '飫',
-'饬' => '飭',
-'饭' => '飯',
-'饮' => '飲',
-'饯' => '餞',
-'饰' => '飾',
-'饱' => '飽',
-'饲' => '飼',
-'饳' => '飿',
-'饴' => '飴',
-'饵' => '餌',
-'饶' => '饒',
-'饷' => '餉',
-'饸' => '餄',
-'饹' => '餎',
-'饺' => '餃',
-'饻' => '餏',
-'饼' => '餅',
-'饽' => '餑',
-'饾' => '餖',
-'饿' => '餓',
-'馀' => '餘',
-'馁' => '餒',
-'馂' => '餕',
-'馃' => '餜',
-'馄' => '餛',
-'馅' => '餡',
-'馆' => '館',
-'馇' => '餷',
-'馈' => '饋',
-'馉' => '餶',
-'馊' => '餿',
-'馋' => '饞',
-'馌' => '饁',
-'馍' => '饃',
-'馎' => '餺',
-'馏' => '餾',
-'馐' => '饈',
-'馑' => '饉',
-'馒' => '饅',
-'馓' => '饊',
-'馔' => '饌',
-'馕' => '饢',
-'马' => '馬',
-'驭' => '馭',
-'驮' => '馱',
-'驯' => '馴',
-'驰' => '馳',
-'驱' => '驅',
-'驲' => '馹',
-'驳' => '駁',
-'驴' => '驢',
-'驵' => '駔',
-'驶' => '駛',
-'驷' => '駟',
-'驸' => '駙',
-'驹' => '駒',
-'驺' => '騶',
-'驻' => '駐',
-'驼' => '駝',
-'驽' => '駑',
-'驾' => '駕',
-'驿' => '驛',
-'骀' => '駘',
-'骁' => '驍',
-'骂' => '罵',
-'骃' => '駰',
-'骄' => '驕',
-'骅' => '驊',
-'骆' => '駱',
-'骇' => '駭',
-'骈' => '駢',
-'骉' => '驫',
-'骊' => '驪',
-'骋' => '騁',
-'验' => '驗',
-'骍' => '騂',
-'骎' => '駸',
-'骏' => '駿',
-'骐' => '騏',
-'骑' => '騎',
-'骒' => '騍',
-'骓' => '騅',
-'骔' => '騌',
-'骕' => '驌',
-'骖' => '驂',
-'骗' => '騙',
-'骘' => '騭',
-'骙' => '騤',
-'骚' => '騷',
-'骛' => '騖',
-'骜' => '驁',
-'骝' => '騮',
-'骞' => '騫',
-'骟' => '騸',
-'骠' => '驃',
-'骡' => '騾',
-'骢' => '驄',
-'骣' => '驏',
-'骤' => '驟',
-'骥' => '驥',
-'骦' => '驦',
-'骧' => '驤',
-'髅' => '髏',
-'髋' => '髖',
-'髌' => '髕',
-'鬓' => '鬢',
-'鬶' => '鬹',
-'魇' => '魘',
-'魉' => '魎',
-'鱼' => '魚',
-'鱽' => '魛',
-'鱾' => '魢',
-'鱿' => '魷',
-'鲀' => '魨',
-'鲁' => '魯',
-'鲂' => '魴',
-'鲃' => '䰾',
-'鲄' => '魺',
-'鲅' => '鮁',
-'鲆' => '鮃',
-'鲇' => '鯰',
-'鲈' => '鱸',
-'鲉' => '鮋',
-'鲊' => '鮓',
-'鲋' => '鮒',
-'鲌' => '鮊',
-'鲍' => '鮑',
-'鲎' => '鱟',
-'鲏' => '鮍',
-'鲐' => '鮐',
-'鲑' => '鮭',
-'鲒' => '鮚',
-'鲓' => '鮳',
-'鲔' => '鮪',
-'鲕' => '鮞',
-'鲖' => '鮦',
-'鲗' => '鰂',
-'鲘' => '鮜',
-'鲙' => '鱠',
-'鲚' => '鱭',
-'鲛' => '鮫',
-'鲜' => '鮮',
-'鲝' => '鮺',
-'鲞' => '鯗',
-'鲟' => '鱘',
-'鲠' => '鯁',
-'鲡' => '鱺',
-'鲢' => '鰱',
-'鲣' => '鰹',
-'鲤' => '鯉',
-'鲥' => '鰣',
-'鲦' => '鰷',
-'鲧' => '鯀',
-'鲨' => '鯊',
-'鲩' => '鯇',
-'鲪' => '鮶',
-'鲫' => '鯽',
-'鲬' => '鯒',
-'鲭' => '鯖',
-'鲮' => '鯪',
-'鲯' => '鯕',
-'鲰' => '鯫',
-'鲱' => '鯡',
-'鲲' => '鯤',
-'鲳' => '鯧',
-'鲴' => '鯝',
-'鲵' => '鯢',
-'鲷' => '鯛',
-'鲸' => '鯨',
-'鲹' => '鰺',
-'鲺' => '鯴',
-'鲻' => '鯔',
-'鲼' => '鱝',
-'鲽' => '鰈',
-'鲾' => '鰏',
-'鲿' => '鱨',
-'鳀' => '鯷',
-'鳁' => '鰮',
-'鳂' => '鰃',
-'鳃' => '鰓',
-'鳄' => '鱷',
-'鳅' => '鰍',
-'鳆' => '鰒',
-'鳇' => '鰉',
-'鳈' => '鰁',
-'鳉' => '鱂',
-'鳊' => '鯿',
-'鳋' => '鰠',
-'鳌' => '鰲',
-'鳍' => '鰭',
-'鳎' => '鰨',
-'鳏' => '鰥',
-'鳐' => '鰩',
-'鳑' => '鰟',
-'鳒' => '鰜',
-'鳓' => '鰳',
-'鳔' => '鰾',
-'鳕' => '鱈',
-'鳖' => '鱉',
-'鳗' => '鰻',
-'鳘' => '鰵',
-'鳙' => '鱅',
-'鳚' => '䲁',
-'鳛' => '鰼',
-'鳜' => '鱖',
-'鳝' => '鱔',
-'鳞' => '鱗',
-'鳟' => '鱒',
-'鳠' => '鱯',
-'鳡' => '鱤',
-'鳢' => '鱧',
-'鳣' => '鱣',
-'鳤' => '䲘',
-'鸟' => '鳥',
-'鸠' => '鳩',
-'鸡' => '雞',
-'鸢' => '鳶',
-'鸣' => '鳴',
-'鸤' => '鳲',
-'鸥' => '鷗',
-'鸦' => '鴉',
-'鸧' => '鶬',
-'鸨' => '鴇',
-'鸩' => '鴆',
-'鸪' => '鴣',
-'鸫' => '鶇',
-'鸬' => '鸕',
-'鸭' => '鴨',
-'鸮' => '鴞',
-'鸯' => '鴦',
-'鸰' => '鴒',
-'鸱' => '鴟',
-'鸲' => '鴝',
-'鸳' => '鴛',
-'鸴' => '鷽',
-'鸵' => '鴕',
-'鸶' => '鷥',
-'鸷' => '鷙',
-'鸸' => '鴯',
-'鸹' => '鴰',
-'鸺' => '鵂',
-'鸻' => '鴴',
-'鸼' => '鵃',
-'鸽' => '鴿',
-'鸾' => '鸞',
-'鸿' => '鴻',
-'鹀' => '鵐',
-'鹁' => '鵓',
-'鹂' => '鸝',
-'鹃' => '鵑',
-'鹄' => '鵠',
-'鹅' => '鵝',
-'鹆' => '鵒',
-'鹇' => '鷳',
-'鹈' => '鵜',
-'鹉' => '鵡',
-'鹊' => '鵲',
-'鹋' => '鶓',
-'鹌' => '鵪',
-'鹍' => '鵾',
-'鹎' => '鵯',
-'鹏' => '鵬',
-'鹐' => '鵮',
-'鹑' => '鶉',
-'鹒' => '鶊',
-'鹓' => '鵷',
-'鹔' => '鷫',
-'鹕' => '鶘',
-'鹖' => '鶡',
-'鹗' => '鶚',
-'鹘' => '鶻',
-'鹙' => '鶖',
-'鹚' => '鶿',
-'鹛' => '鶥',
-'鹜' => '鶩',
-'鹝' => '鷊',
-'鹞' => '鷂',
-'鹟' => '鶲',
-'鹠' => '鶹',
-'鹡' => '鶺',
-'鹢' => '鷁',
-'鹣' => '鶼',
-'鹤' => '鶴',
-'鹥' => '鷖',
-'鹦' => '鸚',
-'鹧' => '鷓',
-'鹨' => '鷚',
-'鹩' => '鷯',
-'鹪' => '鷦',
-'鹫' => '鷲',
-'鹬' => '鷸',
-'鹭' => '鷺',
-'鹮' => '䴉',
-'鹯' => '鸇',
-'鹰' => '鷹',
-'鹱' => '鸌',
-'鹲' => '鸏',
-'鹳' => '鸛',
-'鹴' => '鸘',
-'鹾' => '鹺',
-'麦' => '麥',
-'麸' => '麩',
-'麹' => '麴',
-'黄' => '黃',
-'黉' => '黌',
-'黡' => '黶',
-'黩' => '黷',
-'黪' => '黲',
-'黾' => '黽',
-'鼋' => '黿',
-'鼍' => '鼉',
-'鼗' => '鞀',
-'鼹' => '鼴',
-'齐' => '齊',
-'齑' => '齏',
-'齿' => '齒',
-'龀' => '齔',
-'龁' => '齕',
-'龂' => '齗',
-'龃' => '齟',
-'龄' => '齡',
-'龅' => '齙',
-'龆' => '齠',
-'龇' => '齜',
-'龈' => '齦',
-'龉' => '齬',
-'龊' => '齪',
-'龋' => '齲',
-'龌' => '齷',
-'龙' => '龍',
-'龚' => '龔',
-'龛' => '龕',
-'龟' => '龜',
-'𠆲' => '儣',
-'𠆿' => '𠌥',
-'𠉂' => '㒓',
-'𠉗' => '𠏢',
-'𠚳' => '𠠎',
-'𠛅' => '剾',
-'𠛆' => '𠞆',
-'𠯟' => '哯',
-'𠯠' => '噅',
-'𠲥' => '𡅏',
-'𠴢' => '𡄔',
-'𠵸' => '𡄣',
-'𠵾' => '㗲',
-'𡋀' => '𡓾',
-'𡋗' => '𡑭',
-'𡒄' => '壈',
-'𡝠' => '㜷',
-'𡞱' => '㜢',
-'𡭜' => '𡮉',
-'𡭬' => '𡮣',
-'𡶴' => '嵼',
-'𢋈' => '㢝',
-'𢘝' => '𢣚',
-'𢘞' => '𢣭',
-'𢙓' => '懀',
-'𢛯' => '㦎',
-'𢫊' => '𢷮',
-'𢫞' => '𢶫',
-'𢫬' => '摋',
-'𢬦' => '𢹿',
-'𢭏' => '擣',
-'𢽾' => '斅',
-'𣆐' => '曥',
-'𣍨' => '𦢈',
-'𣍯' => '腪',
-'𣍰' => '脥',
-'𣎑' => '臗',
-'𣐤' => '欍',
-'𣑶' => '𣠲',
-'𣗋' => '欓',
-'𣘓' => '𣞻',
-'𣘴' => '檭',
-'𣘷' => '𣝕',
-'𣭤' => '𣯴',
-'𣶩' => '澅',
-'𣶫' => '𣿉',
-'𣸣' => '濆',
-'𣺼' => '灙',
-'𣺽' => '𤁣',
-'𣽷' => '瀃',
-'𤆡' => '熓',
-'𤇃' => '爄',
-'𤇄' => '熌',
-'𤈶' => '熉',
-'𤈷' => '㷿',
-'𤊀' => '𤒎',
-'𤋏' => '熡',
-'𤞤' => '玁',
-'𤠋' => '㺏',
-'𤦀' => '瓕',
-'𤳄' => '𤳸',
-'𤶧' => '𤸫',
-'𤽯' => '㿧',
-'𤾀' => '皟',
-'𥅘' => '𥌃',
-'𥅴' => '䀹',
-'𥆧' => '瞤',
-'𥇢' => '䁪',
-'𥐟' => '礒',
-'𥐯' => '𥖅',
-'𥐰' => '𥕥',
-'𥐻' => '碙',
-'𥧂' => '𥨐',
-'𥬀' => '䉙',
-'𥬞' => '籋',
-'𥬠' => '篘',
-'𥭉' => '𥵊',
-'𥮋' => '𥸠',
-'𥮜' => '䉲',
-'𥱔' => '𥵃',
-'𥹥' => '𥼽',
-'𥺅' => '䊭',
-'𥺇' => '𥽖',
-'𦈈' => '𥿊',
-'𦈉' => '緷',
-'𦈋' => '綇',
-'𦈌' => '綀',
-'𦈎' => '繟',
-'𦈏' => '緍',
-'𦈐' => '縺',
-'𦈑' => '緸',
-'𦈒' => '𦂅',
-'𦈓' => '䋿',
-'𦈔' => '縎',
-'𦈕' => '緰',
-'𦈖' => '䌈',
-'𦈗' => '𦃄',
-'𦈘' => '䌋',
-'𦈙' => '䌰',
-'𦈚' => '縬',
-'𦈛' => '繓',
-'𦈜' => '䌖',
-'𦈝' => '繏',
-'𦈞' => '䌟',
-'𦈟' => '䌝',
-'𦈠' => '䌥',
-'𦈡' => '繻',
-'𦛨' => '朥',
-'𦝼' => '膢',
-'𦟗' => '𦣎',
-'𦨩' => '𦪽',
-'𦰴' => '䕳',
-'𧉞' => '䗿',
-'𧒭' => '𧔥',
-'𧮪' => '詀',
-'𧳕' => '𧳟',
-'𧹑' => '䞈',
-'𧹓' => '𧶔',
-'𧹕' => '䝻',
-'𧹖' => '賟',
-'𧹗' => '贃',
-'𧿈' => '𨇁',
-'𨀱' => '𨄣',
-'𨁴' => '𨅍',
-'𨂺' => '𨈊',
-'𨄄' => '𨈌',
-'𨅫' => '𨇞',
-'𨅬' => '躝',
-'𨉗' => '軉',
-'𨐅' => '軗',
-'𨐆' => '𨊻',
-'𨐇' => '𨏠',
-'𨐈' => '輄',
-'𨐉' => '𨎮',
-'𨐊' => '𨏥',
-'𨑹' => '䢨',
-'𨤰' => '𨤻',
-'𨰾' => '鎷',
-'𨰿' => '釳',
-'𨱀' => '𨥛',
-'𨱁' => '鈠',
-'𨱂' => '鈋',
-'𨱃' => '鈲',
-'𨱄' => '鈯',
-'𨱅' => '鉁',
-'𨱆' => '龯',
-'𨱇' => '銶',
-'𨱈' => '鋉',
-'𨱉' => '鍄',
-'𨱊' => '𨧱',
-'𨱋' => '錂',
-'𨱌' => '鏆',
-'𨱍' => '鎯',
-'𨱎' => '鍮',
-'𨱏' => '鎝',
-'𨱐' => '𨫒',
-'𨱑' => '鐄',
-'𨱒' => '鏉',
-'𨱓' => '鐎',
-'𨱔' => '鐏',
-'𨱕' => '𨮂',
-'𨱖' => '䥩',
-'𨷿' => '䦳',
-'𨸀' => '𨳕',
-'𨸁' => '𨳑',
-'𨸂' => '閍',
-'𨸃' => '閐',
-'𨸄' => '䦘',
-'𨸅' => '𨴗',
-'𨸆' => '𨵩',
-'𨸇' => '𨵸',
-'𨸉' => '𨶀',
-'𨸊' => '𨶏',
-'𨸋' => '𨶲',
-'𨸌' => '𨶮',
-'𨸎' => '𨷲',
-'𨸘' => '𨽏',
-'𨸟' => '䧢',
-'𩏼' => '䪏',
-'𩏽' => '𩏪',
-'𩏾' => '𩎢',
-'𩏿' => '䪘',
-'𩐀' => '䪗',
-'𩖕' => '𩓣',
-'𩖖' => '顃',
-'𩖗' => '䫴',
-'𩙥' => '颰',
-'𩙦' => '𩗀',
-'𩙧' => '𩗡',
-'𩙨' => '𩘹',
-'𩙩' => '𩘀',
-'𩙪' => '颷',
-'𩙫' => '颾',
-'𩙬' => '𩘺',
-'𩙭' => '𩘝',
-'𩙮' => '䬘',
-'𩙯' => '䬝',
-'𩙰' => '𩙈',
-'𩟿' => '𩚛',
-'𩠀' => '𩚥',
-'𩠁' => '𩚵',
-'𩠂' => '𩛆',
-'𩠃' => '𩛩',
-'𩠅' => '𩟐',
-'𩠆' => '𩜦',
-'𩠇' => '䭀',
-'𩠈' => '䭃',
-'𩠉' => '𩜇',
-'𩠊' => '𩜵',
-'𩠋' => '𩝔',
-'𩠌' => '餸',
-'𩠎' => '𩞄',
-'𩠏' => '𩞦',
-'𩠠' => '𩠴',
-'𩧦' => '𩡺',
-'𩧨' => '駎',
-'𩧩' => '𩤊',
-'𩧪' => '䮾',
-'𩧫' => '駚',
-'𩧬' => '𩢡',
-'𩧭' => '䭿',
-'𩧮' => '𩢾',
-'𩧯' => '驋',
-'𩧰' => '䮝',
-'𩧱' => '𩥉',
-'𩧲' => '駧',
-'𩧳' => '𩢸',
-'𩧴' => '駩',
-'𩧵' => '𩢴',
-'𩧶' => '𩣏',
-'𩧺' => '駶',
-'𩧻' => '𩣵',
-'𩧼' => '𩣺',
-'𩧿' => '䮠',
-'𩨀' => '騔',
-'𩨁' => '䮞',
-'𩨃' => '騝',
-'𩨄' => '騪',
-'𩨅' => '𩤸',
-'𩨆' => '𩤙',
-'𩨇' => '䮫',
-'𩨈' => '騟',
-'𩨉' => '𩤲',
-'𩨊' => '騚',
-'𩨋' => '𩥄',
-'𩨌' => '𩥑',
-'𩨍' => '𩥇',
-'𩨎' => '龭',
-'𩨏' => '䮳',
-'𩨐' => '𩧆',
-'𩬣' => '𩭙',
-'𩬤' => '𩰀',
-'𩯒' => '𩯳',
-'𩲒' => '𩳤',
-'𩽹' => '魥',
-'𩽺' => '𩵩',
-'𩽻' => '𩵹',
-'𩽼' => '鯶',
-'𩽽' => '𩶱',
-'𩽾' => '鮟',
-'𩽿' => '𩶰',
-'𩾁' => '鯄',
-'𩾂' => '䲖',
-'𩾃' => '鮸',
-'𩾄' => '𩷰',
-'𩾅' => '𩸃',
-'𩾆' => '𩸦',
-'𩾇' => '鯱',
-'𩾈' => '䱙',
-'𩾊' => '䱬',
-'𩾋' => '䱰',
-'𩾌' => '鱇',
-'𩾎' => '𩽇',
-'𪉂' => '䲰',
-'𪉃' => '鳼',
-'𪉄' => '𩿪',
-'𪉅' => '𪀦',
-'𪉆' => '鴲',
-'𪉈' => '鴜',
-'𪉉' => '𪁈',
-'𪉊' => '鷨',
-'𪉋' => '𪀾',
-'𪉌' => '𪁖',
-'𪉍' => '鵚',
-'𪉎' => '𪂆',
-'𪉏' => '𪃏',
-'𪉐' => '𪃍',
-'𪉑' => '鷔',
-'𪉒' => '𪄕',
-'𪉓' => '𪈼',
-'𪉔' => '𪄆',
-'𪉕' => '𪇳',
-'𪎈' => '䴬',
-'𪎉' => '麲',
-'𪎊' => '麨',
-'𪎋' => '䴴',
-'𪎌' => '麳',
-'𪎍' => '𪋿',
-'𪔭' => '𪔵',
-'𪚏' => '𪘀',
-'𪚐' => '𪘯',
-'𪞝' => '凙',
-'𪡏' => '嗹',
-'𪢮' => '圞',
-'𪨊' => '㞞',
-'𪨗' => '屩',
-'𪻐' => '瑽',
-'𪾢' => '睍',
-'𫁡' => '鴗',
-'𫂈' => '䉬',
-'𫄨' => '絺',
-'𫄸' => '纁',
-'𫌀' => '襀',
-'𫌨' => '覼',
-'𫍙' => '訑',
-'𫍢' => '譊',
-'𫍰' => '諰',
-'𫍲' => '謏',
-'𫏋' => '蹻',
-'𫐄' => '軏',
-'𫐆' => '轣',
-'𫐉' => '軨',
-'𫐐' => '輗',
-'𫐓' => '輮',
-'𫓧' => '鈇',
-'𫓩' => '鏦',
-'𫔎' => '鐍',
-'𫖸' => '願',
-'𫗠' => '餦',
-'𫗦' => '餔',
-'𫗧' => '餗',
-'𫗮' => '餭',
-'𫗴' => '饘',
-'𫘝' => '駃',
-'𫘣' => '駻',
-'𫘤' => '騃',
-'𫘨' => '騠',
-'𫚈' => '鱮',
-'𫚉' => '魟',
-'𫚒' => '鮄',
-'𫚔' => '鮰',
-'𫚕' => '鰤',
-'𫚙' => '鯆',
-'𫛛' => '鳷',
-'𫛞' => '鴃',
-'𫛢' => '鸋',
-'𫛶' => '鶒',
-'𫛸' => '鶗',
-'0出现' => '0出現',
-'0出現' => '0出現',
-'0出線' => '0出線',
-'0出线' => '0出線',
-'0只支持' => '0只支持',
-'0只支援' => '0只支援',
-'0周后' => '0周後',
-'0天后' => '0天後',
-'0年' => '0年',
-'0只' => '0隻',
-'0余' => '0餘',
-'0出' => '0齣',
-'1只支持' => '1只支持',
-'1只支援' => '1只支援',
-'1周后' => '1周後',
-'1天后' => '1天後',
-'1年' => '1年',
-'1只' => '1隻',
-'1余' => '1餘',
-'2只支持' => '2只支持',
-'2只支援' => '2只支援',
-'2周后' => '2周後',
-'2天后' => '2天後',
-'2年' => '2年',
-'2只' => '2隻',
-'2余' => '2餘',
-'3只支持' => '3只支持',
-'3只支援' => '3只支援',
-'3周后' => '3周後',
-'3天后' => '3天後',
-'3年' => '3年',
-'3只' => '3隻',
-'3余' => '3餘',
-'4只支持' => '4只支持',
-'4只支援' => '4只支援',
-'4周后' => '4周後',
-'4天后' => '4天後',
-'4年' => '4年',
-'4只' => '4隻',
-'4余' => '4餘',
-'5只支持' => '5只支持',
-'5只支援' => '5只支援',
-'5周后' => '5周後',
-'5天后' => '5天後',
-'5年' => '5年',
-'5只' => '5隻',
-'5余' => '5餘',
-'6只支持' => '6只支持',
-'6只支援' => '6只支援',
-'6周后' => '6周後',
-'6天后' => '6天後',
-'6年' => '6年',
-'6只' => '6隻',
-'6余' => '6餘',
-'7只支持' => '7只支持',
-'7只支援' => '7只支援',
-'7周后' => '7周後',
-'7天后' => '7天後',
-'7年' => '7年',
-'7只' => '7隻',
-'7余' => '7餘',
-'8只支持' => '8只支持',
-'8只支援' => '8只支援',
-'8周后' => '8周後',
-'8天后' => '8天後',
-'8年' => '8年',
-'8只' => '8隻',
-'8余' => '8餘',
-'9只支持' => '9只支持',
-'9只支援' => '9只支援',
-'9周后' => '9周後',
-'9天后' => '9天後',
-'9年' => '9年',
-'9只' => '9隻',
-'9余' => '9餘',
-'·范' => '·范',
-'’s' => '’s',
-'、面点' => '、麵點',
-'。个中' => '。箇中',
-'〇周后' => '〇周後',
-'〇年' => '〇年',
-'〇只' => '〇隻',
-'〇余' => '〇餘',
-'“' => '「',
-'”' => '」',
-'‘' => '『',
-'’' => '』',
-'一干二净' => '一乾二淨',
-'一伙人' => '一伙人',
-'一伙头' => '一伙頭',
-'一伙食' => '一伙食',
-'一并' => '一併',
-'一个' => '一個',
-'一个准' => '一個準',
-'一划' => '一划',
-'一半只' => '一半只',
-'一吊钱' => '一吊錢',
-'一周后' => '一周後',
-'一地里' => '一地裡',
-'一伙' => '一夥',
-'一天后' => '一天後',
-'一天钟' => '一天鐘',
-'一干人' => '一干人',
-'一干家中' => '一干家中',
-'一干弟兄' => '一干弟兄',
-'一干弟子' => '一干弟子',
-'一干部下' => '一干部下',
-'一年' => '一年',
-'一年里' => '一年裡',
-'一别头' => '一彆頭',
-'一斗斗' => '一斗斗',
-'一树百获' => '一樹百穫',
-'一准' => '一準',
-'一争两丑' => '一爭兩醜',
-'一物克一物' => '一物剋一物',
-'一目了然' => '一目了然',
-'一碗面' => '一碗麵',
-'一扎' => '一紮',
-'一冲' => '一衝',
-'一厘一毫' => '一釐一毫',
-'一锅面' => '一鍋麵',
-'一只' => '一隻',
-'一面食' => '一面食',
-'一余' => '一餘',
-'一发千钧' => '一髮千鈞',
-'一哄而散' => '一鬨而散',
-'一出剧' => '一齣劇',
-'一出喜剧' => '一齣喜劇',
-'一出好戏' => '一齣好戲',
-'一出子' => '一齣子',
-'一出悲剧' => '一齣悲劇',
-'一出戏' => '一齣戲',
-'一出电影' => '一齣電影',
-'丁丁当当' => '丁丁當當',
-'丁丑' => '丁丑',
-'七个' => '七個',
-'七周后' => '七周後',
-'七天后' => '七天後',
-'七年' => '七年',
-'七情六欲' => '七情六慾',
-'七扎' => '七紮',
-'七只' => '七隻',
-'七余' => '七餘',
-'万俟' => '万俟',
-'万旗' => '万旗',
-'三个' => '三個',
-'三周后' => '三周後',
-'三天后' => '三天後',
-'三年' => '三年',
-'三征七辟' => '三徵七辟',
-'三准' => '三準',
-'三扎' => '三紮',
-'三统历' => '三統曆',
-'三统历史' => '三統歷史',
-'三只' => '三隻',
-'三余' => '三餘',
-'三出戏' => '三齣戲',
-'上天里' => '上天里',
-'上梁山' => '上梁山',
-'上梁' => '上樑',
-'上台面' => '上檯面',
-'上签名' => '上簽名',
-'上签字' => '上簽字',
-'上签定' => '上簽定',
-'上签写' => '上簽寫',
-'上签收' => '上簽收',
-'上签发' => '上簽發',
-'上签约' => '上簽約',
-'上签署' => '上簽署',
-'上签订' => '上簽訂',
-'上签' => '上籤',
-'上系上' => '上繫上',
-'上课钟' => '上課鐘',
-'上面糊' => '上面糊',
-'下于' => '下於',
-'下梁' => '下樑',
-'下注解' => '下注解',
-'下签名' => '下簽名',
-'下签字' => '下簽字',
-'下签定' => '下簽定',
-'下签写' => '下簽寫',
-'下签收' => '下簽收',
-'下签发' => '下簽發',
-'下签约' => '下簽約',
-'下签署' => '下簽署',
-'下签订' => '下簽訂',
-'下签' => '下籤',
-'下课钟' => '下課鐘',
-'不干不净' => '不乾不淨',
-'不干胶' => '不乾膠',
-'不克自制' => '不克自制',
-'不加自制' => '不加自制',
-'不占凶吉' => '不占凶吉',
-'不占卜' => '不占卜',
-'不占吉凶' => '不占吉凶',
-'不占算' => '不占算',
-'不只' => '不只',
-'不太准' => '不太準',
-'不好干涉' => '不好干涉',
-'不好干預' => '不好干預',
-'不好干预' => '不好干預',
-'不嫌母丑' => '不嫌母醜',
-'不寒而栗' => '不寒而慄',
-'不吊' => '不弔',
-'不卷' => '不捲',
-'不采' => '不採',
-'不斗胆' => '不斗膽',
-'不斗膽' => '不斗膽',
-'不断发' => '不斷發',
-'不每只' => '不每只',
-'不谷' => '不穀',
-'不托' => '不託',
-'不负所托' => '不負所托',
-'不通吊庆' => '不通弔慶',
-'不丑' => '不醜',
-'不采声' => '不采聲',
-'不采聲' => '不采聲',
-'不锈钢' => '不鏽鋼',
-'不食干腊' => '不食乾腊',
-'不斗' => '不鬥',
-'丑三' => '丑三',
-'丑年' => '丑年',
-'丑日' => '丑日',
-'丑旦' => '丑旦',
-'丑时' => '丑時',
-'丑月' => '丑月',
-'丑表功' => '丑表功',
-'丑角' => '丑角',
-'且于' => '且於',
-'世田谷' => '世田谷',
-'世界杯' => '世界盃',
-'世纪里' => '世紀裡',
-'世纪钟' => '世紀鐘',
-'世纪钟表' => '世紀鐘錶',
-'丢丑' => '丟醜',
-'并曰入淀' => '並曰入澱',
-'并发动' => '並發動',
-'并发展' => '並發展',
-'并发布' => '並發布',
-'并发现' => '並發現',
-'并发表' => '並發表',
-'并行' => '並行',
-'中国国际信托投资公司' => '中國國際信托投資公司',
-'中型钟' => '中型鐘',
-'中型钟表面' => '中型鐘表面',
-'中型钟表' => '中型鐘錶',
-'中型钟面' => '中型鐘面',
-'中境里' => '中境里',
-'中岳' => '中嶽',
-'中庄子' => '中庄子',
-'中文里' => '中文裡',
-'中于' => '中於',
-'中签名' => '中簽名',
-'中签字' => '中簽字',
-'中签定' => '中簽定',
-'中签写' => '中簽寫',
-'中签收' => '中簽收',
-'中签发' => '中簽發',
-'中签约' => '中簽約',
-'中签署' => '中簽署',
-'中签订' => '中簽訂',
-'中签' => '中籤',
-'中风后' => '中風後',
-'丰仪' => '丰儀',
-'丰儀' => '丰儀',
-'丰南' => '丰南',
-'丰姿' => '丰姿',
-'丰容' => '丰容',
-'丰情' => '丰情',
-'丰标' => '丰標',
-'丰标不凡' => '丰標不凡',
-'丰標不凡' => '丰標不凡',
-'丰神' => '丰神',
-'丰茸' => '丰茸',
-'丰采' => '丰采',
-'丰韵' => '丰韻',
-'丰韻' => '丰韻',
-'丹棱' => '丹稜',
-'主仆' => '主僕',
-'主干' => '主幹',
-'主钟差' => '主鐘差',
-'主钟曲线' => '主鐘曲線',
-'乃系' => '乃係',
-'么么唱唱' => '么么唱唱',
-'么九' => '么九',
-'么儿' => '么兒',
-'么半' => '么半',
-'么喝' => '么喝',
-'么女' => '么女',
-'么妹' => '么妹',
-'么子' => '么子',
-'么弟' => '么弟',
-'么正' => '么正',
-'么爷' => '么爺',
-'么雞' => '么雞',
-'么么小丑' => '么麼小丑',
-'之一只' => '之一只',
-'之二只' => '之二只',
-'之八九只' => '之八九只',
-'之征' => '之徵',
-'之托' => '之託',
-'之钟' => '之鐘',
-'之鉴' => '之鑑',
-'之余' => '之餘',
-'乙丑' => '乙丑',
-'九世之仇' => '九世之讎',
-'九个' => '九個',
-'九周后' => '九周後',
-'九天后' => '九天後',
-'九年' => '九年',
-'九谷' => '九穀',
-'九扎' => '九紮',
-'九只' => '九隻',
-'九余' => '九餘',
-'干干' => '乾乾',
-'干干净净' => '乾乾淨淨',
-'干井' => '乾井',
-'干个够' => '乾個夠',
-'干儿' => '乾兒',
-'干冰' => '乾冰',
-'干冷' => '乾冷',
-'干刻版' => '乾刻版',
-'干剥剥' => '乾剝剝',
-'干卦' => '乾卦',
-'干和' => '乾和',
-'干咳' => '乾咳',
-'干咽' => '乾咽',
-'干哥' => '乾哥',
-'干哭' => '乾哭',
-'干唱' => '乾唱',
-'干啼' => '乾啼',
-'干乔' => '乾喬',
-'干呕' => '乾嘔',
-'干哕' => '乾噦',
-'干嚎' => '乾嚎',
-'干回付' => '乾回付',
-'干圆洁净' => '乾圓潔淨',
-'干地' => '乾地',
-'干坞' => '乾塢',
-'干女' => '乾女',
-'干奴才' => '乾奴才',
-'干妹' => '乾妹',
-'干姊' => '乾姊',
-'干姐' => '乾姐',
-'干娘' => '乾娘',
-'干妈' => '乾媽',
-'干子' => '乾子',
-'干季' => '乾季',
-'干尸' => '乾屍',
-'干屎橛' => '乾屎橛',
-'干巴' => '乾巴',
-'干式' => '乾式',
-'干弟' => '乾弟',
-'干急' => '乾急',
-'干性' => '乾性',
-'干打雷' => '乾打雷',
-'干折' => '乾折',
-'干撂台' => '乾撂台',
-'干撇下' => '乾撇下',
-'干擦' => '乾擦',
-'干支剌' => '乾支剌',
-'干支支' => '乾支支',
-'干料' => '乾料',
-'干旱' => '乾旱',
-'干暖' => '乾暖',
-'干材' => '乾材',
-'干村沙' => '乾村沙',
-'干杯' => '乾杯',
-'干果' => '乾果',
-'干枯' => '乾枯',
-'干柴' => '乾柴',
-'干柴烈火' => '乾柴烈火',
-'干梅' => '乾梅',
-'干死' => '乾死',
-'干池' => '乾池',
-'干没' => '乾沒',
-'干洗' => '乾洗',
-'干涸' => '乾涸',
-'干凉' => '乾涼',
-'干净' => '乾淨',
-'干渠' => '乾渠',
-'干渴' => '乾渴',
-'干沟' => '乾溝',
-'干漆' => '乾漆',
-'干涩' => '乾澀',
-'干湿' => '乾濕',
-'干熬' => '乾熬',
-'干热' => '乾熱',
-'干灯盏' => '乾燈盞',
-'干燥' => '乾燥',
-'干爸' => '乾爸',
-'干爹' => '乾爹',
-'干爽' => '乾爽',
-'干片' => '乾片',
-'干物' => '乾物',
-'干生受' => '乾生受',
-'干生子' => '乾生子',
-'干产' => '乾產',
-'干田' => '乾田',
-'干疥' => '乾疥',
-'干瘦' => '乾瘦',
-'干瘪' => '乾癟',
-'干癣' => '乾癬',
-'干瘾' => '乾癮',
-'干白儿' => '乾白兒',
-'干白葡萄酒' => '乾白葡萄酒',
-'干的' => '乾的',
-'干眼' => '乾眼',
-'干瞪眼' => '乾瞪眼',
-'干礼' => '乾禮',
-'干稿' => '乾稿',
-'干笑' => '乾笑',
-'干等' => '乾等',
-'干篾片' => '乾篾片',
-'干粉' => '乾粉',
-'干粮' => '乾糧',
-'干红葡萄酒' => '乾紅葡萄酒',
-'干结' => '乾結',
-'干丝' => '乾絲',
-'干纲' => '乾綱',
-'干绷' => '乾繃',
-'干耗' => '乾耗',
-'干肉片' => '乾肉片',
-'干股' => '乾股',
-'干肥' => '乾肥',
-'干脆' => '乾脆',
-'干脆面' => '乾脆麵',
-'干花' => '乾花',
-'干刍' => '乾芻',
-'干苔' => '乾苔',
-'干茨腊' => '乾茨臘',
-'干茶钱' => '乾茶錢',
-'干草' => '乾草',
-'干菜' => '乾菜',
-'干落' => '乾落',
-'干姜' => '乾薑',
-'干薪' => '乾薪',
-'干虔' => '乾虔',
-'干号' => '乾號',
-'干血浆' => '乾血漿',
-'干衣' => '乾衣',
-'干裂' => '乾裂',
-'干亲' => '乾親',
-'乾象历' => '乾象曆',
-'乾象曆' => '乾象曆',
-'干贝' => '乾貝',
-'干货' => '乾貨',
-'干躁' => '乾躁',
-'干逼' => '乾逼',
-'干酪' => '乾酪',
-'干酵母' => '乾酵母',
-'干醋' => '乾醋',
-'干重' => '乾重',
-'干量' => '乾量',
-'干锅' => '乾鍋',
-'干阿奶' => '乾阿奶',
-'干雷' => '乾雷',
-'干电' => '乾電',
-'干霍乱' => '乾霍亂',
-'干颡' => '乾顙',
-'干台' => '乾颱',
-'干食' => '乾食',
-'干饭' => '乾飯',
-'干馆' => '乾館',
-'干糇' => '乾餱',
-'干馏' => '乾餾',
-'干鱼' => '乾魚',
-'干鲜' => '乾鮮',
-'干面' => '乾麵',
-'乱发生' => '亂發生',
-'乱发脾气' => '亂發脾氣',
-'乱发' => '亂髮',
-'乱哄哄' => '亂鬨鬨',
-'了然后' => '了然後',
-'事有斗巧' => '事有鬥巧',
-'事里' => '事裡',
-'二不棱登' => '二不稜登',
-'二个' => '二個',
-'二只得' => '二只得',
-'二周后' => '二周後',
-'二天后' => '二天後',
-'二年' => '二年',
-'二缶钟惑' => '二缶鐘惑',
-'二老板' => '二老板',
-'二虎相斗' => '二虎相鬥',
-'二里头' => '二里頭',
-'二里頭' => '二里頭',
-'二只' => '二隻',
-'二余' => '二餘',
-'于丹' => '于丹',
-'于于' => '于于',
-'于仁泰' => '于仁泰',
-'于仲文' => '于仲文',
-'于佳卉' => '于佳卉',
-'于来山' => '于來山',
-'于伟国' => '于偉國',
-'于偉國' => '于偉國',
-'于光新' => '于光新',
-'于光远' => '于光遠',
-'于光遠' => '于光遠',
-'于克-兰多县' => '于克-蘭多縣',
-'于克-蘭多縣' => '于克-蘭多縣',
-'于克勒' => '于克勒',
-'于再清' => '于再清',
-'于冕' => '于冕',
-'于冠华' => '于冠華',
-'于凌奎' => '于凌奎',
-'于凌辰' => '于凌辰',
-'于勒' => '于勒',
-'于化虎' => '于化虎',
-'于占元' => '于占元',
-'于友泽' => '于友澤',
-'于台烟' => '于台煙',
-'于台煙' => '于台煙',
-'于右任' => '于右任',
-'于吉' => '于吉',
-'于和伟' => '于和偉',
-'于品海' => '于品海',
-'于国桢' => '于國楨',
-'于國楨' => '于國楨',
-'于国治' => '于國治',
-'于國治' => '于國治',
-'于坚' => '于堅',
-'于堅' => '于堅',
-'于大宝' => '于大寶',
-'于大寶' => '于大寶',
-'于天仁' => '于天仁',
-'于天龙' => '于天龍',
-'于奇库杜克' => '于奇庫杜克',
-'于奇庫杜克' => '于奇庫杜克',
-'于姓' => '于姓',
-'于娜' => '于娜',
-'于娟' => '于娟',
-'于子千' => '于子千',
-'于孔兼' => '于孔兼',
-'于学忠' => '于學忠',
-'于學忠' => '于學忠',
-'于家堡' => '于家堡',
-'于寘' => '于寘',
-'于宝轩' => '于寶軒',
-'于小伟' => '于小偉',
-'于小偉' => '于小偉',
-'于小彤' => '于小彤',
-'于小惠' => '于小惠',
-'于少保' => '于少保',
-'于山' => '于山',
-'于山国' => '于山國',
-'于山國' => '于山國',
-'于帅' => '于帥',
-'于帥' => '于帥',
-'于幼军' => '于幼軍',
-'于幼軍' => '于幼軍',
-'于康震' => '于康震',
-'于广洲' => '于廣洲',
-'于廣洲' => '于廣洲',
-'于式枚' => '于式枚',
-'于从濂' => '于從濂',
-'于從濂' => '于從濂',
-'于德海' => '于德海',
-'于志宁' => '于志寧',
-'于志寧' => '于志寧',
-'于忠肃集' => '于忠肅集',
-'于思' => '于思',
-'于慎行' => '于慎行',
-'于慧' => '于慧',
-'于成龍' => '于成龍',
-'于成龙' => '于成龍',
-'于承惠' => '于承惠',
-'于振' => '于振',
-'于振武' => '于振武',
-'于敏' => '于敏',
-'于敏中' => '于敏中',
-'于斌' => '于斌',
-'于斯塔德' => '于斯塔德',
-'于斯納爾斯貝里' => '于斯納爾斯貝里',
-'于斯纳尔斯贝里' => '于斯納爾斯貝里',
-'于斯达尔' => '于斯達爾',
-'于斯達爾' => '于斯達爾',
-'于明涛' => '于明濤',
-'于明濤' => '于明濤',
-'于是之' => '于是之',
-'于晨楠' => '于晨楠',
-'于晴' => '于晴',
-'于会泳' => '于會泳',
-'于會泳' => '于會泳',
-'于根伟' => '于根偉',
-'于根偉' => '于根偉',
-'于格' => '于格',
-'于枫' => '于楓',
-'于楓' => '于楓',
-'于荣光' => '于榮光',
-'于樂' => '于樂',
-'于树洁' => '于樹潔',
-'于樹潔' => '于樹潔',
-'于欣' => '于欣',
-'于欣源' => '于欣源',
-'于正昇' => '于正昇',
-'于正昌' => '于正昌',
-'于归' => '于歸',
-'于氏' => '于氏',
-'于永波' => '于永波',
-'于江震' => '于江震',
-'于波' => '于波',
-'于洋' => '于洋',
-'于洪区' => '于洪區',
-'于洪區' => '于洪區',
-'于浩威' => '于浩威',
-'于海' => '于海',
-'于海洋' => '于海洋',
-'于湘兰' => '于湘蘭',
-'于湘蘭' => '于湘蘭',
-'于汉超' => '于漢超',
-'于漢超' => '于漢超',
-'于澄' => '于澄',
-'于泽尔' => '于澤爾',
-'于澤爾' => '于澤爾',
-'于涛' => '于濤',
-'于濤' => '于濤',
-'于熙珍' => '于熙珍',
-'于尔岑' => '于爾岑',
-'于爾岑' => '于爾岑',
-'于尔根' => '于爾根',
-'于爾根' => '于爾根',
-'于尔里克' => '于爾里克',
-'于爾里克' => '于爾里克',
-'于特森' => '于特森',
-'于玉立' => '于玉立',
-'于田' => '于田',
-'于禁' => '于禁',
-'于秀敏' => '于秀敏',
-'于立成' => '于立成',
-'于素秋' => '于素秋',
-'于美人' => '于美人',
-'于耘婕' => '于耘婕',
-'于若木' => '于若木',
-'于荫霖' => '于蔭霖',
-'于蔭霖' => '于蔭霖',
-'于衡' => '于衡',
-'于西翰' => '于西翰',
-'于謙' => '于謙',
-'于谦' => '于謙',
-'于谨' => '于謹',
-'于貝爾' => '于貝爾',
-'于贝尔' => '于貝爾',
-'于贈' => '于贈',
-'于赠' => '于贈',
-'于越' => '于越',
-'于軍' => '于軍',
-'于逸堯' => '于逸堯',
-'于道泉' => '于道泉',
-'于远伟' => '于遠偉',
-'于遠偉' => '于遠偉',
-'于都县' => '于都縣',
-'于都縣' => '于都縣',
-'于里察' => '于里察',
-'于阗' => '于闐',
-'于双戈' => '于雙戈',
-'于雙戈' => '于雙戈',
-'于云鹤' => '于雲鶴',
-'于震' => '于震',
-'于震寰' => '于震寰',
-'于震环' => '于震環',
-'于震環' => '于震環',
-'于靖' => '于靖',
-'于非暗' => '于非闇',
-'于非闇' => '于非闇',
-'于韋斯屈萊' => '于韋斯屈萊',
-'于韦斯屈莱' => '于韋斯屈萊',
-'于風政' => '于風政',
-'于风政' => '于風政',
-'于飛' => '于飛',
-'于飞' => '于飛',
-'于余曲折' => '于餘曲折',
-'于鬯' => '于鬯',
-'于魁智' => '于魁智',
-'于凤桐' => '于鳳桐',
-'于鳳桐' => '于鳳桐',
-'于凤至' => '于鳳至',
-'于鳳至' => '于鳳至',
-'于默奥' => '于默奧',
-'于默奧' => '于默奧',
-'云乎' => '云乎',
-'云云' => '云云',
-'云何' => '云何',
-'云敞' => '云敞',
-'云为' => '云為',
-'云為' => '云為',
-'云然' => '云然',
-'云尔' => '云爾',
-'云:' => '云:',
-'五个' => '五個',
-'五周后' => '五周後',
-'五天后' => '五天後',
-'五峰县' => '五峯縣',
-'五岳' => '五嶽',
-'五年' => '五年',
-'五谷' => '五穀',
-'五扎' => '五紮',
-'五脏' => '五臟',
-'五行生克' => '五行生剋',
-'五谷王北街' => '五谷王北街',
-'五谷王南街' => '五谷王南街',
-'五只' => '五隻',
-'五余' => '五餘',
-'井干' => '井幹',
-'井里' => '井裡',
-'亚于' => '亞於',
-'亚美尼亚历' => '亞美尼亞曆',
-'交托' => '交託',
-'交游' => '交遊',
-'交哄' => '交鬨',
-'亦云' => '亦云',
-'京沈' => '京瀋',
-'亮丑' => '亮醜',
-'亮钟' => '亮鐘',
-'人云' => '人云',
-'人如风后入江云' => '人如風後入江雲',
-'人干的' => '人幹的',
-'人欲' => '人慾',
-'人数只' => '人數只',
-'人数里' => '人數裡',
-'人物志' => '人物誌',
-'人生天里' => '人生天里',
-'人发指' => '人髮指',
-'什锦面' => '什錦麵',
-'仁贵' => '仁貴',
-'介胄' => '介冑',
-'他干的' => '他幹的',
-'他钟' => '他鐘',
-'付托' => '付託',
-'仙后' => '仙后',
-'仙后座' => '仙后座',
-'仙游' => '仙遊',
-'代数里' => '代數裡',
-'代理发行' => '代理發行',
-'代码表' => '代碼表',
-'代表' => '代表',
-'以自制' => '以自制',
-'仲裁制' => '仲裁制',
-'件钟' => '件鐘',
-'价川' => '价川',
-'任何钟' => '任何鐘',
-'任何钟表' => '任何鐘錶',
-'任教于' => '任教於',
-'任于' => '任於',
-'仿制' => '仿製',
-'伊于湖底' => '伊于湖底',
-'伊府面' => '伊府麵',
-'伊斯兰教历' => '伊斯蘭教曆',
-'伊斯兰教历史' => '伊斯蘭教歷史',
-'伊斯兰历' => '伊斯蘭曆',
-'伊斯兰历史' => '伊斯蘭歷史',
-'伊东怜' => '伊東怜',
-'伊尔汗历表' => '伊爾汗曆表',
-'伊达里子' => '伊達里子',
-'伊适杰' => '伊適杰',
-'伊里布' => '伊里布',
-'伊郁' => '伊鬱',
-'伏几' => '伏几',
-'伐罪吊民' => '伐罪弔民',
-'休克期' => '休克期',
-'休征' => '休徵',
-'伙头' => '伙頭',
-'伴游' => '伴遊',
-'似于' => '似於',
-'但云' => '但云',
-'位于' => '位於',
-'位准' => '位準',
-'低洼' => '低洼',
-'住扎' => '住紮',
-'占毕' => '佔畢',
-'占头筹' => '佔頭籌',
-'占高枝儿' => '佔高枝兒',
-'何杰' => '何杰',
-'余三勝' => '余三勝',
-'余三胜' => '余三勝',
-'余光中' => '余光中',
-'余光生' => '余光生',
-'余力为' => '余力為',
-'余威德' => '余威德',
-'余子明' => '余子明',
-'余思敏' => '余思敏',
-'佛罗棱萨' => '佛羅稜薩',
-'佛钟' => '佛鐘',
-'作品里' => '作品裡',
-'作准' => '作準',
-'你夸' => '你誇',
-'佣金' => '佣金',
-'佣鈿' => '佣鈿',
-'佣钿' => '佣鈿',
-'佣錢' => '佣錢',
-'佣钱' => '佣錢',
-'佳肴' => '佳肴',
-'佳里鎮' => '佳里鎮',
-'并一不二' => '併一不二',
-'并入' => '併入',
-'并兼' => '併兼',
-'并到' => '併到',
-'并合' => '併合',
-'并名' => '併名',
-'并吞下' => '併吞下',
-'并拢' => '併攏',
-'并案' => '併案',
-'并流' => '併流',
-'并火' => '併火',
-'并为一家' => '併為一家',
-'并为一体' => '併為一體',
-'并叠' => '併疊',
-'并发型模式' => '併發型模式',
-'并发模式' => '併發模式',
-'并发症' => '併發症',
-'并发重症' => '併發重症',
-'并科' => '併科',
-'并网' => '併網',
-'并线' => '併線',
-'并肩子' => '併肩子',
-'并购' => '併購',
-'并骨' => '併骨',
-'使其斗' => '使其鬥',
-'来于' => '來於',
-'侍仆' => '侍僕',
-'供制' => '供製',
-'依依不舍' => '依依不捨',
-'依托' => '依託',
-'侵并' => '侵併',
-'局促' => '侷促',
-'便于' => '便於',
-'系数' => '係數',
-'系为' => '係為',
-'保险柜' => '保險柜',
-'信托贸易' => '信托貿易',
-'信托' => '信託',
-'修杰楷' => '修杰楷',
-'修杰麟' => '修杰麟',
-'修筑前' => '修築前',
-'修筑后' => '修築後',
-'修胡刀' => '修鬍刀',
-'俯冲' => '俯衝',
-'个月里' => '個月裡',
-'个里' => '個裡',
-'个钟' => '個鐘',
-'个钟表' => '個鐘錶',
-'们干的' => '們幹的',
-'幸免' => '倖免',
-'幸存' => '倖存',
-'幸幸' => '倖幸',
-'候复' => '候覆',
-'倚闲' => '倚閑',
-'倛丑' => '倛醜',
-'借鉴' => '借鑑',
-'倦游' => '倦遊',
-'假里' => '假裡',
-'假托' => '假託',
-'假发' => '假髮',
-'偎干' => '偎乾',
-'停停当当' => '停停當當',
-'停征' => '停徵',
-'停制' => '停製',
-'备注' => '備註',
-'家伙' => '傢伙',
-'催并' => '催併',
-'佣仆' => '傭僕',
-'傲游' => '傲遊',
-'傲霜斗雪' => '傲霜鬥雪',
-'传位于四太子' => '傳位于四太子',
-'傳位于四太子' => '傳位于四太子',
-'传于' => '傳於',
-'债累累' => '債纍纍',
-'傻里傻气' => '傻裡傻氣',
-'仅余' => '僅餘',
-'仆人' => '僕人',
-'仆使' => '僕使',
-'仆仆' => '僕僕',
-'仆僮' => '僕僮',
-'仆吏' => '僕吏',
-'仆固怀恩' => '僕固懷恩',
-'仆夫' => '僕夫',
-'仆姑' => '僕姑',
-'仆婢' => '僕婢',
-'仆妇' => '僕婦',
-'仆射' => '僕射',
-'仆少' => '僕少',
-'仆役' => '僕役',
-'仆从' => '僕從',
-'仆憎' => '僕憎',
-'仆欧' => '僕歐',
-'仆程' => '僕程',
-'仆虽罢驽' => '僕雖罷駑',
-'侥幸' => '僥倖',
-'僮仆' => '僮僕',
-'雇主' => '僱主',
-'雇人' => '僱人',
-'雇佣' => '僱傭',
-'雇到' => '僱到',
-'雇工' => '僱工',
-'雇船' => '僱船',
-'雇请' => '僱請',
-'雇车' => '僱車',
-'雇农' => '僱農',
-'仪范' => '儀範',
-'亿个' => '億個',
-'亿周后' => '億周後',
-'亿天后' => '億天後',
-'亿年' => '億年',
-'亿只' => '億隻',
-'亿余' => '億餘',
-'俭仆' => '儉僕',
-'俭朴' => '儉樸',
-'俭确之教' => '儉确之教',
-'儒略改革历' => '儒略改革曆',
-'儒略改革历史' => '儒略改革歷史',
-'儒略历' => '儒略曆',
-'儒略历史' => '儒略歷史',
-'尽尽' => '儘儘',
-'尽先' => '儘先',
-'尽其所有' => '儘其所有',
-'尽可能' => '儘可能',
-'尽快' => '儘快',
-'尽早' => '儘早',
-'尽是' => '儘是',
-'尽管' => '儘管',
-'尽自' => '儘自',
-'尽速' => '儘速',
-'尽量' => '儘量',
-'优于' => '優於',
-'优游' => '優遊',
-'兀术' => '兀朮',
-'元凶' => '元兇',
-'兆个' => '兆個',
-'兆余' => '兆餘',
-'凶刀' => '兇刀',
-'凶器' => '兇器',
-'凶嫌' => '兇嫌',
-'凶巴巴' => '兇巴巴',
-'凶徒' => '兇徒',
-'凶悍' => '兇悍',
-'凶恶' => '兇惡',
-'凶手' => '兇手',
-'凶案' => '兇案',
-'凶枪' => '兇槍',
-'凶横' => '兇橫',
-'凶残' => '兇殘',
-'凶杀' => '兇殺',
-'凶犯' => '兇犯',
-'凶狠' => '兇狠',
-'凶猛' => '兇猛',
-'凶疑' => '兇疑',
-'凶相' => '兇相',
-'凶险' => '兇險',
-'先采' => '先採',
-'光致致' => '光緻緻',
-'克期间' => '克期間',
-'免征' => '免徵',
-'党太尉' => '党太尉',
-'党姓' => '党姓',
-'党家' => '党家',
-'党怀英' => '党懷英',
-'党进' => '党進',
-'党項' => '党項',
-'党项' => '党項',
-'内脏' => '內臟',
-'内制' => '內製',
-'内面包' => '內面包',
-'内面包的' => '內面包的',
-'内斗' => '內鬥',
-'内哄' => '內鬨',
-'全干' => '全乾',
-'两个' => '兩個',
-'两周后' => '兩周後',
-'两天后' => '兩天後',
-'两年' => '兩年',
-'两杆' => '兩桿',
-'两扎' => '兩紮',
-'两虎共斗' => '兩虎共鬥',
-'两只' => '兩隻',
-'两余' => '兩餘',
-'两鼠斗穴' => '兩鼠鬥穴',
-'两出' => '兩齣',
-'八个' => '八個',
-'八周后' => '八周後',
-'八天后' => '八天後',
-'八字胡' => '八字鬍',
-'八年' => '八年',
-'八扎' => '八紮',
-'八蜡' => '八蜡',
-'八只' => '八隻',
-'八余' => '八餘',
-'公仔面' => '公仔麵',
-'公仆' => '公僕',
-'公孙丑' => '公孫丑',
-'公干' => '公幹',
-'公历' => '公曆',
-'公历史' => '公歷史',
-'公里海' => '公里海',
-'公余' => '公餘',
-'六么' => '六么',
-'六个' => '六個',
-'六周后' => '六周後',
-'六天后' => '六天後',
-'六年' => '六年',
-'六楼后座' => '六樓后座',
-'六谷' => '六穀',
-'六扎' => '六紮',
-'六冲' => '六衝',
-'六只' => '六隻',
-'六余' => '六餘',
-'共和历' => '共和曆',
-'共和历史' => '共和歷史',
-'其一只' => '其一只',
-'其二只' => '其二只',
-'其八九只' => '其八九只',
-'其次辟地' => '其次辟地',
-'其余' => '其餘',
-'典范' => '典範',
-'兼并' => '兼并',
-'冉有仆' => '冉有僕',
-'冗余' => '冗餘',
-'冤仇' => '冤讎',
-'冥蒙' => '冥濛',
-'冬山庄' => '冬山庄',
-'冬游' => '冬遊',
-'冰山里' => '冰山裡',
-'冶游' => '冶遊',
-'冷面相' => '冷面相',
-'冷面' => '冷麵',
-'准三后' => '准三后',
-'准保护' => '准保護',
-'准保護' => '准保護',
-'准保释' => '准保釋',
-'准保釋' => '准保釋',
-'凌蒙初' => '凌濛初',
-'凝炼' => '凝鍊',
-'几上' => '几上',
-'几几' => '几几',
-'几凳' => '几凳',
-'几子' => '几子',
-'几旁' => '几旁',
-'几杖' => '几杖',
-'几案' => '几案',
-'几椅' => '几椅',
-'几榻' => '几榻',
-'几净窗明' => '几淨窗明',
-'几筵' => '几筵',
-'几面上' => '几面上',
-'凶征' => '凶徵',
-'凶相毕露' => '凶相畢露',
-'出乖弄丑' => '出乖弄醜',
-'出乖露丑' => '出乖露醜',
-'出征收' => '出征收',
-'出于' => '出於',
-'出游' => '出遊',
-'出丑' => '出醜',
-'函数里' => '函數裡',
-'分别致' => '分别致',
-'分半钟' => '分半鐘',
-'分多钟' => '分多鐘',
-'分子钟' => '分子鐘',
-'分子云' => '分子雲',
-'分布于' => '分布於',
-'分钟' => '分鐘',
-'分钟里' => '分鐘裡',
-'刑余' => '刑餘',
-'划一桨' => '划一槳',
-'划上' => '划上',
-'划下' => '划下',
-'划不來' => '划不來',
-'划不来' => '划不來',
-'划了一会' => '划了一會',
-'划來划去' => '划來划去',
-'划来划去' => '划來划去',
-'划具' => '划具',
-'划到岸' => '划到岸',
-'划到江心' => '划到江心',
-'划动' => '划動',
-'划動' => '划動',
-'划去' => '划去',
-'划子' => '划子',
-'划得來' => '划得來',
-'划得来' => '划得來',
-'划拳' => '划拳',
-'划桨' => '划槳',
-'划槳' => '划槳',
-'划水' => '划水',
-'划着独木舟' => '划着獨木舟',
-'划着竹筏' => '划着竹筏',
-'划着船' => '划着船',
-'划算' => '划算',
-'划船' => '划船',
-'划艇' => '划艇',
-'划行' => '划行',
-'划走' => '划走',
-'划起' => '划起',
-'划进' => '划進',
-'划進' => '划進',
-'划过' => '划過',
-'划過' => '划過',
-'划龍舟' => '划龍舟',
-'划龙舟' => '划龍舟',
-'判断发' => '判斷發',
-'别辟' => '別闢',
-'利欲' => '利慾',
-'利于' => '利於',
-'刮来刮去' => '刮來刮去',
-'刮起来' => '刮起來',
-'刮胡' => '刮鬍',
-'到山里' => '到山裡',
-'制冷机' => '制冷機',
-'制签' => '制籤',
-'制钟' => '制鐘',
-'刻半钟' => '刻半鐘',
-'刻多钟' => '刻多鐘',
-'刻钟' => '刻鐘',
-'剃发' => '剃髮',
-'剃胡' => '剃鬍',
-'剃须' => '剃鬚',
-'削发' => '削髮',
-'削面' => '削麵',
-'克剥' => '剋剝',
-'克扣' => '剋扣',
-'克期' => '剋期',
-'克死' => '剋死',
-'克薄' => '剋薄',
-'前往' => '前往',
-'前面店' => '前面店',
-'剖厘' => '剖釐',
-'刚干' => '剛乾',
-'刚雇' => '剛僱',
-'剥制' => '剝製',
-'剩余' => '剩餘',
-'剪其发' => '剪其髮',
-'剪发' => '剪髮',
-'割舍' => '割捨',
-'创获' => '創穫',
-'创制' => '創製',
-'铲出' => '剷出',
-'铲刈' => '剷刈',
-'铲平' => '剷平',
-'铲除' => '剷除',
-'铲头' => '剷頭',
-'划入' => '劃入',
-'划为' => '劃為',
-'划著' => '劃著名',
-'刘佳怜' => '劉佳怜',
-'劉佳怜' => '劉佳怜',
-'刘芸后' => '劉芸后',
-'力拼' => '力拚',
-'力拼众敌' => '力拼眾敵',
-'力争上游' => '力爭上遊',
-'功勋' => '功勳',
-'加氢精制' => '加氫精制',
-'劣于' => '劣於',
-'助于' => '助於',
-'劫余' => '劫餘',
-'勃郁' => '勃鬱',
-'胜于' => '勝於',
-'勤仆' => '勤僕',
-'勤朴' => '勤樸',
-'勋劳' => '勳勞',
-'勋业' => '勳業',
-'勋爵' => '勳爵',
-'勋章' => '勳章',
-'勋绩' => '勳績',
-'勾干' => '勾幹',
-'勾心斗角' => '勾心鬥角',
-'勾魂荡魄' => '勾魂蕩魄',
-'包括' => '包括',
-'包准' => '包準',
-'包谷' => '包穀',
-'包扎' => '包紮',
-'匏系' => '匏繫',
-'北山索面' => '北山索麵',
-'北仑河' => '北崙河',
-'北岳' => '北嶽',
-'北回线' => '北迴線',
-'北回铁路' => '北迴鐵路',
-'匪干' => '匪幹',
-'匿于' => '匿於',
-'十个' => '十個',
-'十出家' => '十出家',
-'十出击' => '十出擊',
-'十出生' => '十出生',
-'十出祁山' => '十出祁山',
-'十出头' => '十出頭',
-'十周后' => '十周後',
-'十天后' => '十天後',
-'十年' => '十年',
-'十扎' => '十紮',
-'十只' => '十隻',
-'十余' => '十餘',
-'十出' => '十齣',
-'千个' => '千個',
-'千只可' => '千只可',
-'千只够' => '千只夠',
-'千只夠' => '千只夠',
-'千只怕' => '千只怕',
-'千只能' => '千只能',
-'千只足够' => '千只足夠',
-'千只足夠' => '千只足夠',
-'千周后' => '千周後',
-'千天后' => '千天後',
-'千年' => '千年',
-'千扎' => '千紮',
-'千回百折' => '千迴百折',
-'千回百转' => '千迴百轉',
-'千钧一发' => '千鈞一髮',
-'千只' => '千隻',
-'千余' => '千餘',
-'升高后' => '升高後',
-'半制品' => '半制品',
-'半只可' => '半只可',
-'半只够' => '半只夠',
-'半于' => '半於',
-'半只' => '半隻',
-'协防' => '協防',
-'南京钟' => '南京鐘',
-'南京钟表' => '南京鐘錶',
-'南宫适' => '南宮适',
-'南宮适' => '南宮适',
-'南屏晚钟' => '南屏晚鐘',
-'南岳' => '南嶽',
-'南筑' => '南筑',
-'南回线' => '南迴線',
-'南回铁路' => '南迴鐵路',
-'南游' => '南遊',
-'博采' => '博採',
-'博尔术' => '博爾朮',
-'卜云吉' => '卜云吉',
-'占了卜' => '占了卜',
-'印累绶若' => '印纍綬若',
-'印制' => '印製',
-'印鉴' => '印鑑',
-'危于' => '危於',
-'卵与石斗' => '卵與石鬥',
-'卷须' => '卷鬚',
-'厂部' => '厂部',
-'原子钟' => '原子鐘',
-'原钟' => '原鐘',
-'历物之意' => '厤物之意',
-'去山里' => '去山裡',
-'参数只' => '參數只',
-'参数里' => '參數裡',
-'反反复复' => '反反覆覆',
-'反应制得' => '反應製得',
-'反朴' => '反樸',
-'反冲' => '反衝',
-'反复制' => '反複製',
-'反复' => '反覆',
-'反覆' => '反覆',
-'取舍' => '取捨',
-'取决于' => '取決於',
-'受雇' => '受僱',
-'受托' => '受託',
-'丛林里' => '叢林裡',
-'口干' => '口乾',
-'口干冒' => '口干冒',
-'口干政' => '口干政',
-'口干涉' => '口干涉',
-'口干犯' => '口干犯',
-'口干预' => '口干預',
-'口燥唇干' => '口燥唇乾',
-'口腹之欲' => '口腹之慾',
-'口里' => '口裡',
-'口钟' => '口鐘',
-'古人有云' => '古人有云',
-'古书云' => '古書云',
-'古書云' => '古書云',
-'古柯咸' => '古柯鹹',
-'古朴' => '古樸',
-'古語云' => '古語云',
-'古语云' => '古語云',
-'古迹' => '古蹟',
-'古钟' => '古鐘',
-'古钟表' => '古鐘錶',
-'另辟' => '另闢',
-'叩钟' => '叩鐘',
-'只占卜' => '只占卜',
-'只占吉' => '只占吉',
-'只占神问卜' => '只占神問卜',
-'只占算' => '只占算',
-'只影响' => '只影響',
-'只影響' => '只影響',
-'只采' => '只採',
-'只冲' => '只衝',
-'只要功夫深,铁杵磨成锈花针' => '只要功夫深,鐵杵磨成鏽花針',
-'只身上已' => '只身上已',
-'只身上有' => '只身上有',
-'只身上沒' => '只身上沒',
-'只身上没' => '只身上沒',
-'只身上无' => '只身上無',
-'只身上無' => '只身上無',
-'只身上的' => '只身上的',
-'只身世' => '只身世',
-'只身份' => '只身份',
-'只身前' => '只身前',
-'只身受' => '只身受',
-'只身子' => '只身子',
-'只身形' => '只身形',
-'只身影' => '只身影',
-'只身后' => '只身後',
-'只身後' => '只身後',
-'只身心' => '只身心',
-'只身旁' => '只身旁',
-'只身材' => '只身材',
-'只身段' => '只身段',
-'只身为' => '只身為',
-'只身為' => '只身為',
-'只身边' => '只身邊',
-'只身邊' => '只身邊',
-'只身首' => '只身首',
-'只身体' => '只身體',
-'只身體' => '只身體',
-'只身高' => '只身高',
-'只采声' => '只采聲',
-'叮叮当当' => '叮叮噹噹',
-'叮当' => '叮噹',
-'可紧可松' => '可緊可鬆',
-'可自制' => '可自制',
-'可鉴' => '可鑑',
-'台子女' => '台子女',
-'台子孙' => '台子孫',
-'台州' => '台州',
-'台布景' => '台布景',
-'台历史' => '台歷史',
-'台钟' => '台鐘',
-'台风奖' => '台風獎',
-'台风稳健' => '台風穩健',
-'史鉴' => '史鑑',
-'叶不二子' => '叶不二子',
-'叶志穗' => '叶志穗',
-'叶恭弘' => '叶恭弘',
-'叶音' => '叶音',
-'叶韵' => '叶韻',
-'吃板刀面' => '吃板刀麵',
-'吃碗面' => '吃碗麵',
-'吃姜' => '吃薑',
-'吃里扒外' => '吃裡扒外',
-'吃里爬外' => '吃裡爬外',
-'吃面' => '吃麵',
-'各辟' => '各闢',
-'各类钟' => '各類鐘',
-'合伙人' => '合伙人',
-'合并' => '合併',
-'合伙' => '合夥',
-'合府上' => '合府上',
-'合采' => '合採',
-'合历' => '合曆',
-'合历史' => '合歷史',
-'合准' => '合準',
-'吉凶庆吊' => '吉凶慶弔',
-'吉征' => '吉徵',
-'吊钟' => '吊鐘',
-'同人志' => '同人誌',
-'同伙' => '同夥',
-'同于' => '同於',
-'同余' => '同餘',
-'名单于' => '名單於',
-'后冠' => '后冠',
-'后北街' => '后北街',
-'后土' => '后土',
-'后妃' => '后妃',
-'后姓' => '后姓',
-'后安路' => '后安路',
-'后平路' => '后平路',
-'后庄' => '后庄',
-'后座' => '后座',
-'后母戊' => '后母戊',
-'后海湾' => '后海灣',
-'后海灣' => '后海灣',
-'后瑞站' => '后瑞站',
-'后稷' => '后稷',
-'后綜' => '后綜',
-'后羿' => '后羿',
-'后街' => '后街',
-'后角' => '后角',
-'后丰' => '后豐',
-'后豐' => '后豐',
-'后里' => '后里',
-'后发FK型星' => '后髮FK型星',
-'后髮FK型星' => '后髮FK型星',
-'后发座' => '后髮座',
-'后髮座' => '后髮座',
-'后发星系团' => '后髮星系團',
-'后髮星系團' => '后髮星系團',
-'吐哺捉发' => '吐哺捉髮',
-'吐哺握发' => '吐哺握髮',
-'向往来' => '向往來',
-'向往常' => '向往常',
-'向往日' => '向往日',
-'向往时' => '向往時',
-'吞并' => '吞併',
-'吟游' => '吟遊',
-'吧台' => '吧檯',
-'含齿戴发' => '含齒戴髮',
-'吹干' => '吹乾',
-'吹发' => '吹髮',
-'吹胡' => '吹鬍',
-'吾为之范我驰驱' => '吾爲之範我馳驅',
-'吕后' => '呂后',
-'呂后' => '呂后',
-'呆致致' => '呆緻緻',
-'呆里呆气' => '呆裡呆氣',
-'告札' => '告劄',
-'呦喂' => '呦喂',
-'周后' => '周后',
-'周惠后' => '周惠后',
-'周历' => '周曆',
-'周杰' => '周杰',
-'周历史' => '周歷史',
-'周游列国' => '周遊列國',
-'呵喂' => '呵喂',
-'呼吁' => '呼籲',
-'命中注定' => '命中注定',
-'和奸' => '和姦',
-'和制汉' => '和製漢',
-'和制英语' => '和製英語',
-'咎征' => '咎徵',
-'咕咕钟' => '咕咕鐘',
-'咪表' => '咪錶',
-'咬姜呷醋' => '咬薑呷醋',
-'咯当' => '咯噹',
-'哀吊' => '哀弔',
-'哀挽' => '哀輓',
-'品鉴' => '品鑑',
-'哄堂大笑' => '哄堂大笑',
-'員山庄' => '員山庄',
-'哪里' => '哪裡',
-'唁吊' => '唁弔',
-'呗赞' => '唄讚',
-'唇干' => '唇乾',
-'唯一只' => '唯一只',
-'唱游' => '唱遊',
-'唾面自干' => '唾面自乾',
-'唾余' => '唾餘',
-'商历' => '商曆',
-'商标准许' => '商標准許',
-'商历史' => '商歷史',
-'啊喂' => '啊喂',
-'启发式' => '啟發式',
-'啷当' => '啷噹',
-'喂了一声' => '喂了一聲',
-'喂喂' => '喂喂',
-'喂哟' => '喂喲',
-'喂!' => '喂!',
-'喂,' => '喂,',
-'善于' => '善於',
-'喜向往' => '喜向往',
-'喜欢表' => '喜歡錶',
-'喜欢钟' => '喜歡鐘',
-'喜欢钟表' => '喜歡鐘錶',
-'喝干' => '喝乾',
-'喧哗' => '喧譁',
-'喧哄' => '喧鬨',
-'丧钟' => '喪鐘',
-'乔岳' => '喬嶽',
-'单于' => '單于',
-'單于' => '單于',
-'单单于' => '單單於',
-'单干' => '單幹',
-'单打独斗' => '單打獨鬥',
-'哟喂' => '喲喂',
-'喲喂' => '喲喂',
-'嘉谷' => '嘉穀',
-'嘉肴' => '嘉肴',
-'嘴里' => '嘴裡',
-'恶心' => '噁心',
-'噙齿戴发' => '噙齒戴髮',
-'喷洒' => '噴洒',
-'当啷' => '噹啷',
-'当当' => '噹噹',
-'噜苏' => '嚕囌',
-'啮合' => '嚙合',
-'啮齿类' => '嚙齒類',
-'向导' => '嚮導',
-'向往' => '嚮往',
-'向慕' => '嚮慕',
-'向迩' => '嚮邇',
-'严云农' => '嚴云農',
-'严于' => '嚴於',
-'嚼谷' => '嚼穀',
-'啰啰苏苏' => '囉囉囌囌',
-'啰苏' => '囉囌',
-'嘱托' => '囑託',
-'啮虫' => '囓蟲',
-'四个' => '四個',
-'四出征收' => '四出徵收',
-'四分历' => '四分曆',
-'四分历史' => '四分歷史',
-'四周后' => '四周後',
-'四天后' => '四天後',
-'四年' => '四年',
-'四舍五入' => '四捨五入',
-'四舍六入' => '四捨六入',
-'四杆铁笔' => '四桿鐵筆',
-'四扎' => '四紮',
-'四只' => '四隻',
-'四面包' => '四面包',
-'四面钟' => '四面鐘',
-'四余' => '四餘',
-'回佣' => '回佣',
-'回采' => '回採',
-'回旋加速' => '回旋加速',
-'回历' => '回曆',
-'回历史' => '回歷史',
-'回复中' => '回覆中',
-'回复你' => '回覆你',
-'回复帖子' => '回覆帖子',
-'回复意见' => '回覆意見',
-'回复说' => '回覆說',
-'回复邮件' => '回覆郵件',
-'回复:' => '回覆:',
-'回游' => '回遊',
-'因于' => '因於',
-'困倦起来' => '困倦起來',
-'困于' => '困於',
-'困兽之斗' => '困獸之鬥',
-'困兽犹斗' => '困獸猶鬥',
-'困斗' => '困鬥',
-'固定制' => '固定制',
-'固征' => '固徵',
-'囿于' => '囿於',
-'圈梁' => '圈樑',
-'圈里' => '圈裡',
-'国之桢干' => '國之楨榦',
-'国于' => '國於',
-'国历' => '國曆',
-'国历代' => '國歷代',
-'国历任' => '國歷任',
-'国历来' => '國歷來',
-'国历史' => '國歷史',
-'国历届' => '國歷屆',
-'国历经' => '國歷經',
-'国仇' => '國讎',
-'园里' => '園裡',
-'园游会' => '園遊會',
-'图里的' => '圖裡的',
-'图里,' => '圖裡,',
-'图鉴' => '圖鑑',
-'土索面' => '土索麵',
-'土里' => '土裡',
-'土制' => '土製',
-'在制品' => '在制品',
-'在山里' => '在山裡',
-'在于' => '在於',
-'地图里' => '地圖裡',
-'地心历表' => '地心曆表',
-'地方志' => '地方志',
-'地志' => '地誌',
-'地丑德齐' => '地醜德齊',
-'坏于' => '坏於',
-'坐如钟' => '坐如鐘',
-'坐台' => '坐檯',
-'坐钟' => '坐鐘',
-'坑里' => '坑裡',
-'坤范' => '坤範',
-'坦荡' => '坦蕩',
-'坦荡荡' => '坦蕩蕩',
-'坱郁' => '坱鬱',
-'垂于' => '垂於',
-'垂范' => '垂範',
-'垂发' => '垂髮',
-'型范' => '型範',
-'埃及历' => '埃及曆',
-'埃及历史' => '埃及歷史',
-'埃及艳后' => '埃及豔后',
-'埃荣冲' => '埃榮衝',
-'城市里' => '城市裡',
-'城里' => '城裡',
-'埔子里' => '埔子里',
-'埔里社' => '埔裏社',
-'域里' => '域裡',
-'基干' => '基幹',
-'基于' => '基於',
-'基准' => '基準',
-'坚致' => '堅緻',
-'堙淀' => '堙澱',
-'堡子里' => '堡子里',
-'场里' => '場裡',
-'塞耳盗钟' => '塞耳盜鐘',
-'境里' => '境裡',
-'境里程' => '境里程',
-'墓志铭' => '墓志銘',
-'墓志' => '墓誌',
-'增辟' => '增闢',
-'墨子里' => '墨子里',
-'墨斗' => '墨斗',
-'墨沈沈' => '墨沈沈',
-'墨沈' => '墨瀋',
-'垦辟' => '墾闢',
-'压制出' => '壓製出',
-'压制机' => '壓製機',
-'壮游' => '壯遊',
-'壮面' => '壯麵',
-'壹郁' => '壹鬱',
-'壶里' => '壺裡',
-'壸范' => '壼範',
-'壽天里' => '壽天里',
-'寿面' => '壽麵',
-'夏于乔' => '夏于喬',
-'夏于喬' => '夏于喬',
-'夏历' => '夏曆',
-'夏历史' => '夏歷史',
-'夏游' => '夏遊',
-'外强中干' => '外強中乾',
-'外制' => '外製',
-'多半只' => '多半只',
-'多只包括' => '多只包括',
-'多只可' => '多只可',
-'多只含' => '多只含',
-'多只在' => '多只在',
-'多只是' => '多只是',
-'多只会' => '多只會',
-'多只會' => '多只會',
-'多只有' => '多只有',
-'多只比' => '多只比',
-'多只用' => '多只用',
-'多只能' => '多只能',
-'多只限' => '多只限',
-'多只需' => '多只需',
-'多只須' => '多只須',
-'多只须' => '多只須',
-'多周后' => '多周後',
-'多天后' => '多天後',
-'多于' => '多於',
-'多冲' => '多衝',
-'多丑' => '多醜',
-'多只' => '多隻',
-'多余' => '多餘',
-'多出电影' => '多齣電影',
-'夜晚里' => '夜晚裡',
-'夜里' => '夜裡',
-'夜游' => '夜遊',
-'梦里' => '夢裡',
-'梦游' => '夢遊',
-'伙伴' => '夥伴',
-'伙友' => '夥友',
-'伙同' => '夥同',
-'伙众' => '夥眾',
-'伙计' => '夥計',
-'大伙儿' => '大伙兒',
-'大只可' => '大只可',
-'大只在' => '大只在',
-'大只是' => '大只是',
-'大只会' => '大只會',
-'大只有' => '大只有',
-'大只能' => '大只能',
-'大只需' => '大只需',
-'大周后' => '大周后',
-'大型钟' => '大型鐘',
-'大型钟表面' => '大型鐘表面',
-'大型钟表' => '大型鐘錶',
-'大型钟面' => '大型鐘面',
-'大多只' => '大多只',
-'大伙' => '大夥',
-'大干' => '大幹',
-'大批涌到' => '大批湧到',
-'大折儿' => '大摺兒',
-'大明历' => '大明曆',
-'大明历史' => '大明歷史',
-'大历' => '大曆',
-'大本钟' => '大本鐘',
-'大本钟敲' => '大本鐘敲',
-'大历史' => '大歷史',
-'大病初愈' => '大病初癒',
-'大目干连' => '大目乾連',
-'大笨钟' => '大笨鐘',
-'大笨钟敲' => '大笨鐘敲',
-'大蜡' => '大蜡',
-'大衍历' => '大衍曆',
-'大衍历史' => '大衍歷史',
-'大言非夸' => '大言非夸',
-'大夸' => '大誇',
-'大赞' => '大讚',
-'大周折' => '大週摺',
-'大丑' => '大醜',
-'大金发苔' => '大金髮苔',
-'大钟' => '大鐘',
-'大只' => '大隻',
-'大风后' => '大風後',
-'天克地冲' => '天克地衝',
-'天台' => '天台',
-'天后' => '天后',
-'天后宫' => '天后宮',
-'天地志狼' => '天地志狼',
-'天地为范' => '天地為範',
-'天干地支' => '天干地支',
-'天后来' => '天後來',
-'天后半' => '天後半',
-'天后天' => '天後天',
-'天文学钟' => '天文學鐘',
-'天文历表' => '天文曆表',
-'天文钟' => '天文鐘',
-'天历' => '天曆',
-'天历史' => '天歷史',
-'天神之后' => '天神之后',
-'天里' => '天裡',
-'天里昂' => '天里昂',
-'天里村' => '天里村',
-'太仆' => '太僕',
-'太凶' => '太兇',
-'太初历' => '太初曆',
-'太初历史' => '太初歷史',
-'太后' => '太后',
-'太丑' => '太醜',
-'太阁' => '太閤',
-'夸克' => '夸克',
-'夸父' => '夸父',
-'夸特' => '夸特',
-'夸脱' => '夸脫',
-'奇勋' => '奇勳',
-'奇迹' => '奇蹟',
-'奇丑' => '奇醜',
-'奏折' => '奏摺',
-'夺斗' => '奪鬥',
-'奋斗' => '奮鬥',
-'女丑' => '女丑',
-'女仆' => '女僕',
-'奴仆' => '奴僕',
-'奸淫掳掠' => '奸淫擄掠',
-'好家伙' => '好傢夥',
-'好凶' => '好兇',
-'好勇斗狠' => '好勇鬥狠',
-'好斗大' => '好斗大',
-'好斗室' => '好斗室',
-'好斗笠' => '好斗笠',
-'好斗篷' => '好斗篷',
-'好斗胆' => '好斗膽',
-'好斗膽' => '好斗膽',
-'好斗蓬' => '好斗蓬',
-'好于' => '好於',
-'好困' => '好睏',
-'好签' => '好籤',
-'好丑' => '好醜',
-'好斗' => '好鬥',
-'如果干' => '如果幹',
-'如饥似渴' => '如饑似渴',
-'妖后' => '妖后',
-'妖气冲天' => '妖氣衝天',
-'妆台' => '妝檯',
-'始于' => '始於',
-'委托' => '委託',
-'委托书' => '委託書',
-'奸夫' => '姦夫',
-'奸妇' => '姦婦',
-'奸情' => '姦情',
-'奸杀' => '姦殺',
-'奸污' => '姦污',
-'奸淫' => '姦淫',
-'威棱' => '威稜',
-'婢仆' => '婢僕',
-'嫁祸于' => '嫁禍於',
-'嫌凶' => '嫌兇',
-'嫌好道丑' => '嫌好道醜',
-'嫩姜' => '嫩薑',
-'嬉游' => '嬉遊',
-'嬖幸' => '嬖倖',
-'嬴余' => '嬴餘',
-'子之丰兮' => '子之丰兮',
-'子云' => '子云',
-'子里' => '子裡',
-'子里甲' => '子里甲',
-'字汇' => '字彙',
-'字母后' => '字母後',
-'字码表' => '字碼表',
-'字里行间' => '字裡行間',
-'存折' => '存摺',
-'存于' => '存於',
-'孛里海' => '孛里海',
-'孝惠后' => '孝惠后',
-'孙杰' => '孫杰',
-'孫杰' => '孫杰',
-'学家' => '學家',
-'学里' => '學裡',
-'宇宙志' => '宇宙誌',
-'安于' => '安於',
-'安沈铁路' => '安瀋鐵路',
-'宋王台' => '宋王臺',
-'宗周钟' => '宗周鐘',
-'官不怕大只怕管' => '官不怕大只怕管',
-'官地为采' => '官地為寀',
-'官历' => '官曆',
-'官历史' => '官歷史',
-'定于' => '定於',
-'定准' => '定準',
-'定制' => '定製',
-'宜云' => '宜云',
-'宣泄' => '宣洩',
-'宦游' => '宦遊',
-'宫里' => '宮裡',
-'害于' => '害於',
-'宴游' => '宴遊',
-'家仆' => '家僕',
-'家里' => '家裡',
-'家丑' => '家醜',
-'容于' => '容於',
-'容范' => '容範',
-'宿舍' => '宿舍',
-'寄托在' => '寄托在',
-'寄托' => '寄託',
-'密致' => '密緻',
-'寇准' => '寇準',
-'寇仇' => '寇讎',
-'富余' => '富餘',
-'寒栗' => '寒慄',
-'寒于' => '寒於',
-'寓于' => '寓於',
-'寡欲' => '寡慾',
-'实干' => '實幹',
-'实累累' => '實纍纍',
-'写字台' => '寫字檯',
-'宽于' => '寬於',
-'宽余' => '寬餘',
-'宽松' => '寬鬆',
-'宽松松' => '寬鬆鬆',
-'寮采' => '寮寀',
-'寶山庄' => '寶山庄',
-'宝历' => '寶曆',
-'寶曆' => '寶曆',
-'宝历史' => '寶歷史',
-'宝里宝气' => '寶裡寶氣',
-'宝鉴' => '寶鑑',
-'寸发千金' => '寸髮千金',
-'寺钟' => '寺鐘',
-'封后' => '封后',
-'封为后' => '封為后',
-'封面里' => '封面裡',
-'射雕' => '射鵰',
-'专向往' => '專向往',
-'专辑里' => '專輯裡',
-'尊后' => '尊后',
-'对不准' => '對不準',
-'对折' => '對摺',
-'对于' => '對於',
-'对准' => '對準',
-'对准表' => '對準錶',
-'对准钟' => '對準鐘',
-'对准钟表' => '對準鐘錶',
-'对着干' => '對着幹',
-'对华发' => '對華發',
-'对表中' => '對表中',
-'对表扬' => '對表揚',
-'对表明' => '對表明',
-'对表演' => '對表演',
-'对表现' => '對表現',
-'对表达' => '對表達',
-'导游' => '導遊',
-'小丑' => '小丑',
-'小井里' => '小井里',
-'小价' => '小价',
-'小仆' => '小僕',
-'小几' => '小几',
-'小只可' => '小只可',
-'小只在' => '小只在',
-'小只是' => '小只是',
-'小只会' => '小只會',
-'小只有' => '小只有',
-'小只能' => '小只能',
-'小只需' => '小只需',
-'小周后' => '小周后',
-'小型钟' => '小型鐘',
-'小型钟表面' => '小型鐘表面',
-'小型钟表' => '小型鐘錶',
-'小型钟面' => '小型鐘面',
-'小时里' => '小時裡',
-'小米面' => '小米麵',
-'小只' => '小隻',
-'少采' => '少採',
-'就范' => '就範',
-'就里' => '就裡',
-'尸位素餐' => '尸位素餐',
-'尸佼' => '尸佼',
-'尸利' => '尸利',
-'尸子' => '尸子',
-'尸居余气' => '尸居餘氣',
-'尸弃佛' => '尸棄佛',
-'尸祝' => '尸祝',
-'尸禄' => '尸祿',
-'尸罗精舍' => '尸羅精舍',
-'尸羅精舍' => '尸羅精舍',
-'尸臣' => '尸臣',
-'尸谏' => '尸諫',
-'尸魂界' => '尸魂界',
-'尸鸠' => '尸鳩',
-'局促不安' => '局促不安',
-'局里' => '局裡',
-'屋梁' => '屋樑',
-'屋里' => '屋裡',
-'屏风后' => '屏風後',
-'屑于' => '屑於',
-'屡顾尔仆' => '屢顧爾僕',
-'属于' => '屬於',
-'属托' => '屬託',
-'屯扎' => '屯紮',
-'屯里' => '屯裡',
-'山仔后' => '山仔后',
-'山崩钟应' => '山崩鐘應',
-'山岳' => '山嶽',
-'山梁' => '山樑',
-'山棱' => '山稜',
-'山羊胡' => '山羊鬍',
-'山里有' => '山裡有',
-'山里的' => '山裡的',
-'山谷' => '山谷',
-'山重水复' => '山重水複',
-'岫岩' => '岫巖',
-'岱岳' => '岱嶽',
-'峇里海' => '峇里海',
-'峰回' => '峰迴',
-'峻岭' => '峻岭',
-'崑剧' => '崑劇',
-'昆剧' => '崑劇',
-'崑山' => '崑山',
-'昆山' => '崑山',
-'昆冈' => '崑岡',
-'昆仑' => '崑崙',
-'昆嵛' => '崑嵛',
-'昆承湖' => '崑承湖',
-'崑曲' => '崑曲',
-'昆曲' => '崑曲',
-'崑腔' => '崑腔',
-'昆腔' => '崑腔',
-'崑苏' => '崑蘇',
-'昆苏' => '崑蘇',
-'崑调' => '崑調',
-'昆调' => '崑調',
-'崖广' => '崖广',
-'嶒棱' => '嶒稜',
-'岳岳' => '嶽嶽',
-'岳麓' => '嶽麓',
-'川谷' => '川穀',
-'巡回医疗' => '巡回醫療',
-'巡回' => '巡迴',
-'巡游' => '巡遊',
-'工作台' => '工作檯',
-'左冲右突' => '左衝右突',
-'巧干' => '巧幹',
-'巧历' => '巧曆',
-'巧历史' => '巧歷史',
-'巨制' => '巨製',
-'差之毫厘' => '差之毫厘',
-'差于' => '差於',
-'己丑' => '己丑',
-'已占卜' => '已占卜',
-'已占算' => '已占算',
-'巴尔干' => '巴爾幹',
-'巷里' => '巷裡',
-'市里的' => '市裡的',
-'布谷' => '布穀',
-'布谷鸟' => '布穀鳥',
-'布谷鸟钟' => '布穀鳥鐘',
-'布里海' => '布里海',
-'希伯来历' => '希伯來曆',
-'希伯来历史' => '希伯來歷史',
-'帘子' => '帘子',
-'帘布' => '帘布',
-'帝后台' => '帝后臺',
-'师范' => '師範',
-'席卷' => '席捲',
-'带征' => '帶徵',
-'带余' => '帶餘',
-'带发修行' => '帶髮修行',
-'幅图里' => '幅圖裡',
-'干系' => '干係',
-'平平当当' => '平平當當',
-'平准' => '平準',
-'年代里' => '年代裡',
-'年历' => '年曆',
-'年历史' => '年歷史',
-'年谷' => '年穀',
-'年里' => '年裡',
-'年鉴' => '年鑑',
-'并力' => '并力',
-'并吞' => '并吞',
-'并州' => '并州',
-'并日而食' => '并日而食',
-'并迭' => '并迭',
-'幸免于难' => '幸免於難',
-'幸于' => '幸於',
-'幸运胡' => '幸運鬍',
-'干上' => '幹上',
-'干下去' => '幹下去',
-'干不了' => '幹不了',
-'干不成' => '幹不成',
-'干了' => '幹了',
-'干事' => '幹事',
-'干些' => '幹些',
-'干什么' => '幹什麼',
-'干仗' => '幹仗',
-'干个' => '幹個',
-'干劲' => '幹勁',
-'干吏' => '幹吏',
-'干员' => '幹員',
-'干啥' => '幹啥',
-'干吗' => '幹嗎',
-'干嘛' => '幹嘛',
-'干坏事' => '幹壞事',
-'干大事' => '幹大事',
-'干完' => '幹完',
-'干家' => '幹家',
-'干得' => '幹得',
-'干性油' => '幹性油',
-'干才' => '幹才',
-'干掉' => '幹掉',
-'干探' => '幹探',
-'干校' => '幹校',
-'干活' => '幹活',
-'干流' => '幹流',
-'干济' => '幹濟',
-'干营生' => '幹營生',
-'干父之蛊' => '幹父之蠱',
-'干球温度' => '幹球溫度',
-'干甚么' => '幹甚麼',
-'干略' => '幹略',
-'干当' => '幹當',
-'干的事' => '幹的事',
-'干的好事' => '幹的好事',
-'干细胞' => '幹細胞',
-'干线' => '幹線',
-'干练' => '幹練',
-'干缺' => '幹缺',
-'干群关系' => '幹群關係',
-'干蛊' => '幹蠱',
-'干警' => '幹警',
-'干起来' => '幹起來',
-'干路' => '幹路',
-'干办' => '幹辦',
-'干这' => '幹這',
-'干道' => '幹道',
-'干部' => '幹部',
-'干革命' => '幹革命',
-'干头' => '幹頭',
-'干么' => '幹麼',
-'几个' => '幾個',
-'几周后' => '幾周後',
-'几天后' => '幾天後',
-'几进几出' => '幾進幾出',
-'几只' => '幾隻',
-'几出' => '幾齣',
-'广部' => '广部',
-'庄司' => '庄司',
-'床席' => '床蓆',
-'店里' => '店裡',
-'府干卿' => '府干卿',
-'府干扰' => '府干擾',
-'府干擾' => '府干擾',
-'府干政' => '府干政',
-'府干涉' => '府干涉',
-'府干犯' => '府干犯',
-'府干預' => '府干預',
-'府干预' => '府干預',
-'府干' => '府幹',
-'座钟' => '座鐘',
-'廍子里' => '廍子里',
-'廓子里' => '廓子里',
-'厨余' => '廚餘',
-'厮斗' => '廝鬥',
-'庙里' => '廟裡',
-'废后' => '廢后',
-'廢后' => '廢后',
-'广征' => '廣徵',
-'广舍' => '廣捨',
-'广播里' => '廣播裡',
-'延历' => '延曆',
-'建于' => '建於',
-'建筑前' => '建築前',
-'建筑后' => '建築後',
-'弄干' => '弄乾',
-'弄丑' => '弄醜',
-'弄脏胸' => '弄髒胸',
-'弄松' => '弄鬆',
-'弄鬼吊猴' => '弄鬼弔猴',
-'吊卷' => '弔卷',
-'吊取' => '弔取',
-'吊古' => '弔古',
-'吊唁' => '弔唁',
-'吊问' => '弔問',
-'吊喉' => '弔喉',
-'吊丧' => '弔喪',
-'吊喭' => '弔喭',
-'吊奠' => '弔奠',
-'吊孝' => '弔孝',
-'吊客' => '弔客',
-'吊宴' => '弔宴',
-'吊带' => '弔帶',
-'吊影' => '弔影',
-'吊恤' => '弔恤',
-'吊慰' => '弔慰',
-'吊扣' => '弔扣',
-'吊拷' => '弔拷',
-'吊挂' => '弔掛',
-'吊撒' => '弔撒',
-'吊文' => '弔文',
-'吊旗' => '弔旗',
-'吊死' => '弔死',
-'吊民' => '弔民',
-'吊祭' => '弔祭',
-'吊纸' => '弔紙',
-'吊者大悦' => '弔者大悅',
-'吊腰撒跨' => '弔腰撒跨',
-'吊脚儿事' => '弔腳兒事',
-'吊膀子' => '弔膀子',
-'吊词' => '弔詞',
-'吊诡' => '弔詭',
-'吊谎' => '弔謊',
-'吊贺迎送' => '弔賀迎送',
-'吊头' => '弔頭',
-'吊鹤' => '弔鶴',
-'引斗' => '引鬥',
-'弘历' => '弘曆',
-'弘历史' => '弘歷史',
-'弱于' => '弱於',
-'弱水三千只取一瓢' => '弱水三千只取一瓢',
-'张三丰' => '張三丰',
-'張三丰' => '張三丰',
-'张勋' => '張勳',
-'张杰' => '張杰',
-'張杰' => '張杰',
-'张乐于张徐' => '張樂于張徐',
-'强制作用' => '強制作用',
-'强奸' => '強姦',
-'强干' => '強幹',
-'强于' => '強於',
-'别口气' => '彆口氣',
-'别强' => '彆強',
-'别扭' => '彆扭',
-'别拗' => '彆拗',
-'别气' => '彆氣',
-'弹子台' => '彈子檯',
-'弹珠台' => '彈珠檯',
-'汇刊' => '彙刊',
-'汇算' => '彙算',
-'汇纂' => '彙纂',
-'汇辑' => '彙輯',
-'形单影只' => '形單影隻',
-'形于' => '形於',
-'彭于晏' => '彭于晏',
-'影后' => '影后',
-'影相吊' => '影相弔',
-'役于' => '役於',
-'往复式' => '往復式',
-'往日无仇' => '往日無讎',
-'往里' => '往裡',
-'待复' => '待覆',
-'很干' => '很乾',
-'很凶' => '很兇',
-'很准' => '很準',
-'很丑' => '很醜',
-'很松' => '很鬆',
-'律历志' => '律曆志',
-'后印' => '後印',
-'后台老板' => '後台老板',
-'后天' => '後天',
-'後庄' => '後庄',
-'后面店' => '後面店',
-'徐干' => '徐幹',
-'徒杠' => '徒杠',
-'徒托空言' => '徒託空言',
-'得到回复' => '得到回覆',
-'得力干将' => '得力幹將',
-'从仆' => '從僕',
-'从图里' => '從圖裡',
-'从山里' => '從山裡',
-'从于' => '從於',
-'从里到外' => '從裡到外',
-'从里向外' => '從裡向外',
-'御岳山' => '御嶽山',
-'御制' => '御製',
-'复始' => '復始',
-'复活节历表' => '復活節曆表',
-'复苏' => '復甦',
-'征人' => '徵人',
-'征令' => '徵令',
-'征信' => '徵信',
-'征候' => '徵候',
-'征兆' => '徵兆',
-'征兵' => '徵兵',
-'征到' => '徵到',
-'征募' => '徵募',
-'征友' => '徵友',
-'征召' => '徵召',
-'征名责实' => '徵名責實',
-'征吏' => '徵吏',
-'征咎' => '徵咎',
-'征启' => '徵啟',
-'征士' => '徵士',
-'征婚' => '徵婚',
-'征实' => '徵實',
-'征庸' => '徵庸',
-'征引' => '徵引',
-'征得' => '徵得',
-'征怪' => '徵怪',
-'征才' => '徵才',
-'征招' => '徵招',
-'征收' => '徵收',
-'征效' => '徵效',
-'征文' => '徵文',
-'征求' => '徵求',
-'征状' => '徵狀',
-'征用' => '徵用',
-'征发' => '徵發',
-'征税' => '徵稅',
-'征稿' => '徵稿',
-'征答' => '徵答',
-'征结' => '徵結',
-'征圣' => '徵聖',
-'征聘' => '徵聘',
-'征训' => '徵訓',
-'征询' => '徵詢',
-'征调' => '徵調',
-'征象' => '徵象',
-'征购' => '徵購',
-'征迹' => '徵跡',
-'征车' => '徵車',
-'征辟' => '徵辟',
-'征逐' => '徵逐',
-'征选' => '徵選',
-'征集' => '徵集',
-'征风召雨' => '徵風召雨',
-'征验' => '徵驗',
-'心愿' => '心愿',
-'心于' => '心於',
-'心理' => '心理',
-'心细如发' => '心細如髮',
-'心系一' => '心繫一',
-'心系世' => '心繫世',
-'心系中' => '心繫中',
-'心系乔' => '心繫乔',
-'心系五' => '心繫五',
-'心系京' => '心繫京',
-'心系人' => '心繫人',
-'心系他' => '心繫他',
-'心系伊' => '心繫伊',
-'心系何' => '心繫何',
-'心系你' => '心繫你',
-'心系健' => '心繫健',
-'心系传' => '心繫傳',
-'心系全' => '心繫全',
-'心系两' => '心繫兩',
-'心系农' => '心繫农',
-'心系功' => '心繫功',
-'心系动' => '心繫動',
-'心系募' => '心繫募',
-'心系北' => '心繫北',
-'心系十' => '心繫十',
-'心系千' => '心繫千',
-'心系南' => '心繫南',
-'心系台' => '心繫台',
-'心系和' => '心繫和',
-'心系哪' => '心繫哪',
-'心系唐' => '心繫唐',
-'心系嘱' => '心繫囑',
-'心系四' => '心繫四',
-'心系困' => '心繫困',
-'心系国' => '心繫國',
-'心系在' => '心繫在',
-'心系地' => '心繫地',
-'心系大' => '心繫大',
-'心系天' => '心繫天',
-'心系夫' => '心繫夫',
-'心系奥' => '心繫奧',
-'心系女' => '心繫女',
-'心系她' => '心繫她',
-'心系妻' => '心繫妻',
-'心系妇' => '心繫婦',
-'心系子' => '心繫子',
-'心系它' => '心繫它',
-'心系宣' => '心繫宣',
-'心系家' => '心繫家',
-'心系富' => '心繫富',
-'心系小' => '心繫小',
-'心系山' => '心繫山',
-'心系川' => '心繫川',
-'心系幼' => '心繫幼',
-'心系广' => '心繫廣',
-'心系彼' => '心繫彼',
-'心系德' => '心繫德',
-'心系您' => '心繫您',
-'心系慈' => '心繫慈',
-'心系我' => '心繫我',
-'心系摩' => '心繫摩',
-'心系故' => '心繫故',
-'心系新' => '心繫新',
-'心系日' => '心繫日',
-'心系昌' => '心繫昌',
-'心系晓' => '心繫曉',
-'心系曼' => '心繫曼',
-'心系东' => '心繫東',
-'心系林' => '心繫林',
-'心系母' => '心繫母',
-'心系民' => '心繫民',
-'心系江' => '心繫江',
-'心系汶' => '心繫汶',
-'心系沈' => '心繫沈',
-'心系沙' => '心繫沙',
-'心系泰' => '心繫泰',
-'心系浙' => '心繫浙',
-'心系港' => '心繫港',
-'心系湖' => '心繫湖',
-'心系澳' => '心繫澳',
-'心系灾' => '心繫災',
-'心系父' => '心繫父',
-'心系生' => '心繫生',
-'心系病' => '心繫病',
-'心系百' => '心繫百',
-'心系的' => '心繫的',
-'心系众' => '心繫眾',
-'心系社' => '心繫社',
-'心系祖' => '心繫祖',
-'心系神' => '心繫神',
-'心系红' => '心繫紅',
-'心系美' => '心繫美',
-'心系群' => '心繫群',
-'心系老' => '心繫老',
-'心系舞' => '心繫舞',
-'心系英' => '心繫英',
-'心系茶' => '心繫茶',
-'心系万' => '心繫萬',
-'心系兰' => '心繫蘭',
-'心系西' => '心繫西',
-'心系贫' => '心繫貧',
-'心系输' => '心繫輸',
-'心系近' => '心繫近',
-'心系远' => '心繫遠',
-'心系选' => '心繫選',
-'心系重' => '心繫重',
-'心系长' => '心繫長',
-'心系阮' => '心繫阮',
-'心系震' => '心繫震',
-'心系非' => '心繫非',
-'心系风' => '心繫風',
-'心系香' => '心繫香',
-'心系高' => '心繫高',
-'心系麦' => '心繫麥',
-'心系黄' => '心繫黃',
-'心脏' => '心臟',
-'心脏痳痹' => '心臟痲痺',
-'心荡' => '心蕩',
-'心里面' => '心裏面',
-'心里' => '心裡',
-'心长发短' => '心長髮短',
-'心余' => '心餘',
-'必须' => '必須',
-'忙里' => '忙裡',
-'忙里偷闲' => '忙裡偷閒',
-'忠人之托' => '忠人之托',
-'忠仆' => '忠僕',
-'忠于' => '忠於',
-'快快当当' => '快快當當',
-'快冲' => '快衝',
-'怎么干' => '怎麼幹',
-'怒于' => '怒於',
-'怒气冲天' => '怒氣衝天',
-'怒火冲天' => '怒火衝天',
-'怒发冲冠' => '怒髮衝冠',
-'思如泉涌' => '思如泉湧',
-'怠于' => '怠於',
-'急于' => '急於',
-'急冲而下' => '急衝而下',
-'性征' => '性徵',
-'性欲' => '性慾',
-'怨气冲天' => '怨氣衝天',
-'怪里怪气' => '怪裡怪氣',
-'怫郁' => '怫鬱',
-'恂栗' => '恂慄',
-'恒基' => '恒基',
-'恒生' => '恒生',
-'恒隆' => '恒隆',
-'恕乏价催' => '恕乏价催',
-'息交绝游' => '息交絕遊',
-'息谷' => '息穀',
-'悒郁' => '悒鬱',
-'悠悠荡荡' => '悠悠蕩蕩',
-'悠荡' => '悠蕩',
-'悠游' => '悠遊',
-'悲凄' => '悲悽',
-'悲筑' => '悲筑',
-'悲郁' => '悲鬱',
-'悸栗' => '悸慄',
-'凄厉' => '悽厲',
-'凄怨' => '悽怨',
-'凄惋' => '悽惋',
-'凄惶' => '悽惶',
-'凄恻' => '悽惻',
-'凄怆' => '悽愴',
-'凄惨' => '悽慘',
-'凄戾' => '悽戾',
-'凄然' => '悽然',
-'凄美' => '悽美',
-'凄苦' => '悽苦',
-'凄酸' => '悽酸',
-'情欲' => '情慾',
-'惇朴' => '惇樸',
-'惠文后' => '惠文后',
-'恶仆' => '惡僕',
-'恶直丑正' => '惡直醜正',
-'恶斗' => '惡鬥',
-'惴栗' => '惴慄',
-'意大利面' => '意大利麵',
-'爱困' => '愛睏',
-'感于' => '感於',
-'愿朴' => '愿樸',
-'愿樸' => '愿樸',
-'愿而恭' => '愿而恭',
-'栗冽' => '慄冽',
-'栗栗' => '慄慄',
-'慈溪' => '慈谿',
-'慌里慌张' => '慌裡慌張',
-'惨淡' => '慘澹',
-'庆吊' => '慶弔',
-'庆历' => '慶曆',
-'庆历史' => '慶歷史',
-'欲令智昏' => '慾令智昏',
-'欲壑难填' => '慾壑難填',
-'欲念' => '慾念',
-'欲海' => '慾海',
-'欲火' => '慾火',
-'欲障' => '慾障',
-'忧郁' => '憂鬱',
-'凭几' => '憑几',
-'凭吊' => '憑弔',
-'凭折' => '憑摺',
-'凭准' => '憑準',
-'凭借' => '憑藉',
-'凭闲' => '憑閑',
-'宪法里' => '憲法裡',
-'恳托' => '懇託',
-'懈松' => '懈鬆',
-'应制得' => '應制得',
-'應制得' => '應制得',
-'应征' => '應徵',
-'应钟' => '應鐘',
-'懔栗' => '懍慄',
-'懞懞懂懂' => '懞懞懂懂',
-'懞直' => '懞直',
-'惩忿窒欲' => '懲忿窒欲',
-'怀里' => '懷裡',
-'怀钟' => '懷鐘',
-'悬挂' => '懸掛',
-'悬梁' => '懸樑',
-'悬臂梁' => '懸臂樑',
-'悬钟' => '懸鐘',
-'懿范' => '懿範',
-'恋恋不舍' => '戀戀不捨',
-'成于' => '成於',
-'成于思' => '成於思',
-'戬谷' => '戩穀',
-'截发' => '截髮',
-'战天斗地' => '戰天鬥地',
-'战栗' => '戰慄',
-'战于' => '戰於',
-'战斗' => '戰鬥',
-'戏里' => '戲裡',
-'戲院里' => '戲院里',
-'戴表元' => '戴表元',
-'戴发含齿' => '戴髮含齒',
-'房里' => '房裡',
-'所云' => '所云',
-'所云云' => '所云云',
-'所占卜' => '所占卜',
-'所占星' => '所占星',
-'所占算' => '所占算',
-'所托' => '所託',
-'扁拟谷盗虫' => '扁擬穀盜蟲',
-'手塚治虫' => '手塚治虫',
-'手折' => '手摺',
-'手表态' => '手表態',
-'手表態' => '手表態',
-'手表明' => '手表明',
-'手表决' => '手表決',
-'手表決' => '手表決',
-'手表演' => '手表演',
-'手表现' => '手表現',
-'手表現' => '手表現',
-'手表示' => '手表示',
-'手表达' => '手表達',
-'手表達' => '手表達',
-'手表露' => '手表露',
-'手表面' => '手表面',
-'手里剑' => '手裏劍',
-'手里' => '手裡',
-'手游' => '手遊',
-'手表' => '手錶',
-'手链' => '手鍊',
-'手松' => '手鬆',
-'才干休' => '才干休',
-'才干戈' => '才干戈',
-'才干扰' => '才干擾',
-'才干政' => '才干政',
-'才干涉' => '才干涉',
-'才干预' => '才干預',
-'才干' => '才幹',
-'扎好底子' => '扎好底子',
-'扎好根' => '扎好根',
-'扑作教刑' => '扑作教刑',
-'扑打' => '扑打',
-'扑挞' => '扑撻',
-'打干哕' => '打乾噦',
-'打出吊入' => '打出弔入',
-'打卡钟' => '打卡鐘',
-'打吨' => '打吨',
-'打干' => '打幹',
-'打拼' => '打拚',
-'打断发' => '打斷發',
-'打卤' => '打滷',
-'打谷' => '打穀',
-'打钟' => '打鐘',
-'打风后' => '打風後',
-'打斗' => '打鬥',
-'托管国' => '托管國',
-'扛大梁' => '扛大樑',
-'扯面' => '扯麵',
-'扶余' => '扶餘',
-'批准的' => '批准的',
-'批准确定' => '批准確定',
-'批复' => '批覆',
-'批注' => '批註',
-'批斗' => '批鬥',
-'抑制' => '抑制',
-'抑郁' => '抑鬱',
-'抓奸' => '抓姦',
-'抓斗' => '抓鬥',
-'抗御' => '抗禦',
-'折向往' => '折向往',
-'折子戏' => '折子戲',
-'折子戲' => '折子戲',
-'折戟沈河' => '折戟沈河',
-'折冲' => '折衝',
-'披榛采兰' => '披榛採蘭',
-'披头散发' => '披頭散髮',
-'披发' => '披髮',
-'抱朴而长吟兮' => '抱朴而長吟兮',
-'抱素怀朴' => '抱素懷樸',
-'抵御' => '抵禦',
-'抹干' => '抹乾',
-'抽公签' => '抽公籤',
-'抽签' => '抽籤',
-'抿发' => '抿髮',
-'拂钟无声' => '拂鐘無聲',
-'拆伙' => '拆夥',
-'拈须' => '拈鬚',
-'拉克施尔德钟' => '拉克施爾德鐘',
-'拉纤' => '拉縴',
-'拉面上' => '拉面上',
-'拉面具' => '拉面具',
-'拉面前' => '拉面前',
-'拉面巾' => '拉面巾',
-'拉面无' => '拉面無',
-'拉面皮' => '拉面皮',
-'拉面罩' => '拉面罩',
-'拉面色' => '拉面色',
-'拉面部' => '拉面部',
-'拉面' => '拉麵',
-'拒人于' => '拒人於',
-'拒于' => '拒於',
-'拓朴' => '拓樸',
-'拔发' => '拔髮',
-'拔须' => '拔鬚',
-'拗别' => '拗彆',
-'拘于' => '拘於',
-'拙于' => '拙於',
-'拙朴' => '拙樸',
-'拼却' => '拚卻',
-'拼命' => '拚命',
-'拼舍' => '拚捨',
-'拼死' => '拚死',
-'拼生尽死' => '拚生盡死',
-'拼绝' => '拚絕',
-'拼老命' => '拚老命',
-'拼斗' => '拚鬥',
-'拜托' => '拜託',
-'括发' => '括髮',
-'拭干' => '拭乾',
-'拮据' => '拮据',
-'拳局' => '拳跼',
-'拼死拼活' => '拼死拼活',
-'拾沈' => '拾瀋',
-'拿下表' => '拿下錶',
-'拿下钟' => '拿下鐘',
-'拿准' => '拿準',
-'拿破仑' => '拿破崙',
-'挂图' => '挂圖',
-'挂帅' => '挂帥',
-'挂彩' => '挂彩',
-'挂念' => '挂念',
-'挂号' => '挂號',
-'挂车' => '挂車',
-'挌斗' => '挌鬥',
-'挑大梁' => '挑大樑',
-'挑斗' => '挑鬥',
-'振荡' => '振蕩',
-'捉奸徒' => '捉奸徒',
-'捉奸细' => '捉奸細',
-'捉奸贼' => '捉奸賊',
-'捉奸党' => '捉奸黨',
-'捉奸' => '捉姦',
-'捉发' => '捉髮',
-'捍御' => '捍禦',
-'捏面人' => '捏麵人',
-'舍不得' => '捨不得',
-'舍入' => '捨入',
-'舍出' => '捨出',
-'舍去' => '捨去',
-'舍命' => '捨命',
-'舍堕' => '捨墮',
-'舍安就危' => '捨安就危',
-'舍实' => '捨實',
-'舍己从人' => '捨己從人',
-'舍己救人' => '捨己救人',
-'舍己为人' => '捨己為人',
-'舍己为公' => '捨己為公',
-'舍己为国' => '捨己為國',
-'舍得' => '捨得',
-'舍我其谁' => '捨我其誰',
-'舍本逐末' => '捨本逐末',
-'舍弃' => '捨棄',
-'舍死忘生' => '捨死忘生',
-'舍生' => '捨生',
-'舍短取长' => '捨短取長',
-'舍身' => '捨身',
-'舍车保帅' => '捨車保帥',
-'舍近求远' => '捨近求遠',
-'卷住' => '捲住',
-'卷来' => '捲來',
-'卷儿' => '捲兒',
-'卷入' => '捲入',
-'卷动' => '捲動',
-'卷去' => '捲去',
-'卷图' => '捲圖',
-'卷土重来' => '捲土重來',
-'卷地' => '捲地',
-'卷尺' => '捲尺',
-'卷尾猴' => '捲尾猴',
-'卷心菜' => '捲心菜',
-'卷成' => '捲成',
-'卷曲' => '捲曲',
-'卷款' => '捲款',
-'卷毛' => '捲毛',
-'卷烟盒' => '捲煙盒',
-'卷积云' => '捲積雲',
-'卷筒' => '捲筒',
-'卷帘' => '捲簾',
-'卷纸' => '捲紙',
-'卷缩' => '捲縮',
-'卷舌' => '捲舌',
-'卷烟' => '捲菸',
-'卷叶蛾' => '捲葉蛾',
-'卷袖' => '捲袖',
-'卷走' => '捲走',
-'卷起' => '捲起',
-'卷轴' => '捲軸',
-'卷逃' => '捲逃',
-'卷铺盖' => '捲鋪蓋',
-'卷云' => '捲雲',
-'卷风' => '捲風',
-'卷发' => '捲髮',
-'捵面' => '捵麵',
-'捶炼' => '捶鍊',
-'扫荡' => '掃蕩',
-'授勋' => '授勳',
-'掌柜' => '掌柜',
-'排骨面' => '排骨麵',
-'挂名' => '掛名',
-'挂帘' => '掛帘',
-'挂历' => '掛曆',
-'挂钩' => '掛鈎',
-'挂钟' => '掛鐘',
-'挂面' => '掛麵',
-'采下' => '採下',
-'采伐' => '採伐',
-'采住' => '採住',
-'采信' => '採信',
-'采光' => '採光',
-'采到' => '採到',
-'采制' => '採制',
-'采区' => '採區',
-'采去' => '採去',
-'采取' => '採取',
-'采回' => '採回',
-'采在' => '採在',
-'采好' => '採好',
-'采得' => '採得',
-'采拾' => '採拾',
-'采挖' => '採挖',
-'采掘' => '採掘',
-'采摘' => '採摘',
-'采摭' => '採摭',
-'采择' => '採擇',
-'采撷' => '採擷',
-'采收' => '採收',
-'采料' => '採料',
-'采暖' => '採暖',
-'采桑' => '採桑',
-'采样' => '採樣',
-'采樵人' => '採樵人',
-'采树种' => '採樹種',
-'采气' => '採氣',
-'采油' => '採油',
-'采为' => '採為',
-'采煤' => '採煤',
-'采获' => '採獲',
-'采猎' => '採獵',
-'采珠' => '採珠',
-'采生折割' => '採生折割',
-'采用' => '採用',
-'采石' => '採石',
-'采砂场' => '採砂場',
-'采矿' => '採礦',
-'采种' => '採種',
-'采空区' => '採空區',
-'采空采穗' => '採空採穗',
-'采納' => '採納',
-'采纳' => '採納',
-'采给' => '採給',
-'采花' => '採花',
-'采芹人' => '採芹人',
-'采茶' => '採茶',
-'采菊' => '採菊',
-'采莲' => '採蓮',
-'采薇' => '採薇',
-'采薪' => '採薪',
-'采药' => '採藥',
-'采血' => '採血',
-'采行' => '採行',
-'采补' => '採補',
-'采访' => '採訪',
-'采证' => '採證',
-'采买' => '採買',
-'采购' => '採購',
-'采办' => '採辦',
-'采运' => '採運',
-'采过' => '採過',
-'采选' => '採選',
-'采金' => '採金',
-'采录' => '採錄',
-'采铁' => '採鐵',
-'采集' => '採集',
-'采风' => '採風',
-'采风问俗' => '採風問俗',
-'采食' => '採食',
-'采盐' => '採鹽',
-'掣签' => '掣籤',
-'控制' => '控制',
-'推情准理' => '推情準理',
-'推托之词' => '推托之詞',
-'推托' => '推託',
-'提子干' => '提子乾',
-'提心吊胆' => '提心弔膽',
-'提摩太后书' => '提摩太後書',
-'提高后' => '提高後',
-'插于' => '插於',
-'换签' => '換籤',
-'换只' => '換隻',
-'换发' => '換髮',
-'握发' => '握髮',
-'揩干' => '揩乾',
-'揪采' => '揪採',
-'揪发' => '揪髮',
-'揪须' => '揪鬚',
-'揭丑' => '揭醜',
-'挥手表' => '揮手表',
-'揮手表' => '揮手表',
-'搋面' => '搋麵',
-'损于' => '損於',
-'搏斗' => '搏鬥',
-'捣鬼吊白' => '搗鬼弔白',
-'扼肮' => '搤肮',
-'扼肮拊背' => '搤肮拊背',
-'搬斗' => '搬鬥',
-'搭干铺' => '搭乾鋪',
-'搭伙' => '搭夥',
-'摧坚获丑' => '摧堅獲醜',
-'摭采' => '摭採',
-'摸棱' => '摸稜',
-'摸钟' => '摸鐘',
-'折奏' => '摺奏',
-'折子' => '摺子',
-'折尺' => '摺尺',
-'折扇' => '摺扇',
-'折梯' => '摺梯',
-'折椅' => '摺椅',
-'折台' => '摺檯',
-'折叠' => '摺疊',
-'折痕' => '摺痕',
-'折篷' => '摺篷',
-'折纸' => '摺紙',
-'折裙' => '摺裙',
-'撇吊' => '撇弔',
-'捞干' => '撈乾',
-'捞面' => '撈麵',
-'撚须' => '撚鬚',
-'撞钟' => '撞鐘',
-'撞阵冲军' => '撞陣衝軍',
-'撤并' => '撤併',
-'拨谷' => '撥穀',
-'撩斗' => '撩鬥',
-'播于' => '播於',
-'扑冬' => '撲鼕',
-'扑咚' => '撲鼕',
-'扑咚咚' => '撲鼕鼕',
-'擀面' => '擀麵',
-'击扑' => '擊扑',
-'击钟' => '擊鐘',
-'操作钟' => '操作鐘',
-'担仔面' => '擔仔麵',
-'担担面' => '擔擔麵',
-'据云' => '據云',
-'擢发' => '擢髮',
-'擦干' => '擦乾',
-'拧干' => '擰乾',
-'摆钟' => '擺鐘',
-'摄制' => '攝製',
-'支干' => '支幹',
-'支配欲' => '支配慾',
-'收获' => '收穫',
-'改制成' => '改制成',
-'改征' => '改徵',
-'改采' => '改採',
-'放懞挣' => '放懞掙',
-'放荡' => '放蕩',
-'放松' => '放鬆',
-'政斗' => '政鬥',
-'故云' => '故云',
-'敏于' => '敏於',
-'败于' => '敗於',
-'教学钟' => '教學鐘',
-'教于' => '教於',
-'教范' => '教範',
-'敢干' => '敢幹',
-'敢情欲' => '敢情欲',
-'敢斗了胆' => '敢斗了膽',
-'散伙' => '散夥',
-'散于' => '散於',
-'散荡' => '散蕩',
-'敦朴' => '敦樸',
-'敬挽' => '敬輓',
-'敲扑' => '敲扑',
-'敲钟' => '敲鐘',
-'整只' => '整隻',
-'整风后' => '整風後',
-'整发用品' => '整髮用品',
-'整出剧' => '整齣劇',
-'整出戏' => '整齣戲',
-'整出电影' => '整齣電影',
-'敌忾同仇' => '敵愾同讎',
-'数只包括' => '數只包括',
-'数只可' => '數只可',
-'数只含' => '數只含',
-'数只在' => '數只在',
-'数只应' => '數只應',
-'数只是' => '數只是',
-'数只会' => '數只會',
-'数只有' => '數只有',
-'数只比' => '數只比',
-'数只能' => '數只能',
-'数只限' => '數只限',
-'数只需' => '數只需',
-'数只须' => '數只須',
-'数天后' => '數天後',
-'数字钟' => '數字鐘',
-'数字钟表' => '數字鐘錶',
-'数罪并罚' => '數罪併罰',
-'数与虏确' => '數與虜确',
-'数只' => '數隻',
-'文丑' => '文丑',
-'文学志' => '文學誌',
-'文征明' => '文徵明',
-'文思泉涌' => '文思泉湧',
-'文杰' => '文杰',
-'文采郁郁' => '文采郁郁',
-'斗牛星' => '斗牛星',
-'斫雕为朴' => '斫雕為樸',
-'新井里美' => '新井里美',
-'新干县' => '新幹縣',
-'新历' => '新曆',
-'新历史' => '新歷史',
-'新扎' => '新紮',
-'斲雕为朴' => '斲雕為樸',
-'断发' => '斷髮',
-'断发文身' => '斷髮文身',
-'方便面' => '方便麵',
-'方向往' => '方向往',
-'方志恒' => '方志恒',
-'方法里' => '方法裡',
-'方志' => '方誌',
-'于后' => '於後',
-'于征' => '於徵',
-'于海上' => '於海上',
-'于海边' => '於海邊',
-'于震中' => '於震中',
-'于震前' => '於震前',
-'于震后' => '於震後',
-'施舍' => '施捨',
-'施于' => '施於',
-'施舍之道' => '施舍之道',
-'旁征博引' => '旁徵博引',
-'旁注' => '旁註',
-'旅游' => '旅遊',
-'旋回' => '旋迴',
-'族里' => '族裡',
-'日心历表' => '日心曆表',
-'日历' => '日曆',
-'日历史' => '日歷史',
-'日里' => '日裡',
-'日志' => '日誌',
-'早于' => '早於',
-'旱干' => '旱乾',
-'升州' => '昇州',
-'升平' => '昇平',
-'升阳' => '昇陽',
-'昊天不吊' => '昊天不弔',
-'明征' => '明徵',
-'明目张胆' => '明目張胆',
-'明窗净几' => '明窗淨几',
-'明范' => '明範',
-'明鉴' => '明鑑',
-'易于' => '易於',
-'昔人有云' => '昔人有云',
-'星历' => '星曆',
-'星期后' => '星期後',
-'星历史' => '星歷史',
-'春游' => '春遊',
-'春香斗学' => '春香鬥學',
-'昭惠后' => '昭惠后',
-'是发小' => '是髮小',
-'时钟' => '時鐘',
-'时间不准' => '時間不準',
-'晃荡' => '晃蕩',
-'晚于' => '晚於',
-'晚钟' => '晚鐘',
-'晞发' => '晞髮',
-'晨钟' => '晨鐘',
-'普咚咚' => '普鼕鼕',
-'晾干' => '晾乾',
-'暗地里' => '暗地裡',
-'暗沟里' => '暗溝裡',
-'暗里' => '暗裡',
-'暗斗' => '暗鬥',
-'畅游' => '暢遊',
-'昵称' => '暱稱',
-'暴敛横征' => '暴斂橫徵',
-'历元' => '曆元',
-'历命' => '曆命',
-'历始' => '曆始',
-'历室' => '曆室',
-'历尾' => '曆尾',
-'历局' => '曆局',
-'历数书' => '曆數書',
-'历日' => '曆日',
-'历书' => '曆書',
-'历本' => '曆本',
-'历法' => '曆法',
-'历狱' => '曆獄',
-'历纪' => '曆紀',
-'历象' => '曆象',
-'晒干' => '曬乾',
-'晒谷' => '曬穀',
-'曰云' => '曰云',
-'更仆难数' => '更僕難數',
-'更签' => '更籤',
-'更钟' => '更鐘',
-'书签' => '書籤',
-'书面' => '書面',
-'曹子里' => '曹子里',
-'曼谷' => '曼谷',
-'曾朴' => '曾樸',
-'最多' => '最多',
-'最多只' => '最多只',
-'会干扰' => '會干擾',
-'會干擾' => '會干擾',
-'会干' => '會幹',
-'会吊' => '會弔',
-'会里' => '會裡',
-'月历' => '月曆',
-'月历史' => '月歷史',
-'月球历表' => '月球曆表',
-'月里来' => '月裡來',
-'月面' => '月面',
-'有事之无范' => '有事之無範',
-'有仆' => '有僕',
-'有只不' => '有只不',
-'有只允' => '有只允',
-'有只容' => '有只容',
-'有只採' => '有只採',
-'有只采' => '有只採',
-'有只是' => '有只是',
-'有只用' => '有只用',
-'有回复' => '有回覆',
-'有够赞' => '有夠讚',
-'有征伐' => '有征伐',
-'有征战' => '有征戰',
-'有征戰' => '有征戰',
-'有征服' => '有征服',
-'有征討' => '有征討',
-'有征讨' => '有征討',
-'有征' => '有徵',
-'有恒街' => '有恒街',
-'有栖川' => '有栖川',
-'有准' => '有準',
-'有棱有角' => '有稜有角',
-'有只' => '有隻',
-'有余' => '有餘',
-'有发头陀寺' => '有髮頭陀寺',
-'服于' => '服於',
-'望了望' => '望了望',
-'望后石' => '望后石',
-'朝乾夕惕' => '朝乾夕惕',
-'朝钟' => '朝鐘',
-'朝鲜于' => '朝鮮於',
-'朦胧' => '朦朧',
-'蒙胧' => '朦朧',
-'木偶戏扎' => '木偶戲紮',
-'木材干馏' => '木材乾餾',
-'木梁' => '木樑',
-'木签' => '木籤',
-'木制' => '木製',
-'木钟' => '木鐘',
-'未干' => '未乾',
-'未干涉' => '未干涉',
-'未干預' => '未干預',
-'未干预' => '未干預',
-'本庄' => '本庄',
-'本征' => '本徵',
-'本出戏' => '本齣戲',
-'术赤' => '朮赤',
-'朱庆余' => '朱慶餘',
-'朱理安历' => '朱理安曆',
-'朱理安历史' => '朱理安歷史',
-'朴子里' => '朴子里',
-'李志喜' => '李志喜',
-'李适' => '李适',
-'李连杰' => '李連杰',
-'李連杰' => '李連杰',
-'材干' => '材幹',
-'村落发' => '村落發',
-'村里' => '村裡',
-'村里長' => '村里長',
-'村里长' => '村里長',
-'杜老志道' => '杜老誌道',
-'杞宋无征' => '杞宋無徵',
-'束发' => '束髮',
-'杠人' => '杠人',
-'杠梁' => '杠梁',
-'杠毂' => '杠轂',
-'杠轂' => '杠轂',
-'杯干' => '杯乾',
-'杯面' => '杯麵',
-'杰伦' => '杰倫',
-'杰倫' => '杰倫',
-'杰威尔' => '杰威爾',
-'杰威爾' => '杰威爾',
-'东周钟' => '東周鐘',
-'东岳' => '東嶽',
-'東湖里' => '東湖里',
-'东冲西突' => '東衝西突',
-'东游' => '東遊',
-'松口镇' => '松口鎮',
-'松山庄' => '松山庄',
-'松溪县' => '松谿縣',
-'板荡' => '板蕩',
-'林宏岳' => '林宏嶽',
-'林杰樑' => '林杰樑',
-'林郁方' => '林郁方',
-'林钟' => '林鐘',
-'林鹅峰' => '林鵞峰',
-'果干' => '果乾',
-'果子干' => '果子乾',
-'果累累' => '果纍纍',
-'枝干' => '枝幹',
-'枯干' => '枯乾',
-'架钟' => '架鐘',
-'某只' => '某隻',
-'染指于' => '染指於',
-'染殿后' => '染殿后',
-'染发' => '染髮',
-'柜上' => '柜上',
-'柜子' => '柜子',
-'柜柳' => '柜柳',
-'查封后' => '查封後',
-'柱梁' => '柱樑',
-'柳斌杰' => '柳斌杰',
-'柳诒征' => '柳詒徵',
-'栖栖皇皇' => '栖栖皇皇',
-'栗栖溪' => '栗栖溪',
-'校准' => '校準',
-'校舍' => '校舍',
-'核准的' => '核准的',
-'格于' => '格於',
-'格范' => '格範',
-'格里历' => '格里曆',
-'格里高利历' => '格里高利曆',
-'格斗' => '格鬥',
-'桂圆干' => '桂圓乾',
-'框里' => '框裡',
-'桌几' => '桌几',
-'桌历' => '桌曆',
-'桌历史' => '桌歷史',
-'桌游' => '桌遊',
-'桑干' => '桑乾',
-'杆枪' => '桿槍',
-'杆秤' => '桿秤',
-'杆菌' => '桿菌',
-'梁上君子' => '梁上君子',
-'梁启超' => '梁啓超',
-'条干' => '條幹',
-'梨干' => '梨乾',
-'梯冲' => '梯衝',
-'械系' => '械繫',
-'械斗' => '械鬥',
-'弃舍' => '棄捨',
-'棉里' => '棉裡',
-'棉制' => '棉製',
-'棒子面' => '棒子麵',
-'栋梁' => '棟樑',
-'棫朴' => '棫樸',
-'森林里' => '森林裡',
-'棺材里' => '棺材裡',
-'植发' => '植髮',
-'椒面' => '椒麵',
-'椰枣干' => '椰棗乾',
-'杨雅筑' => '楊雅筑',
-'楊雅筑' => '楊雅筑',
-'桢干' => '楨幹',
-'业余' => '業餘',
-'榨干' => '榨乾',
-'枪杆' => '槍桿',
-'杠杆' => '槓桿',
-'乐器钟' => '樂器鐘',
-'乐游原' => '樂遊原',
-'樊于期' => '樊於期',
-'梁上' => '樑上',
-'梁柱' => '樑柱',
-'樗里子' => '樗里子',
-'标标致致' => '標標致致',
-'标准' => '標準',
-'标签' => '標籤',
-'标致' => '標緻',
-'标注' => '標註',
-'标志' => '標誌',
-'模棱' => '模稜',
-'模范' => '模範',
-'模范七棒' => '模范七棒',
-'模范三军' => '模范三軍',
-'模范三軍' => '模范三軍',
-'模范棒棒堂' => '模范棒棒堂',
-'模制' => '模製',
-'样范' => '樣範',
-'樵采' => '樵採',
-'朴修斯' => '樸修斯',
-'朴厚' => '樸厚',
-'朴学' => '樸學',
-'朴实' => '樸實',
-'朴念仁' => '樸念仁',
-'朴拙' => '樸拙',
-'朴樕' => '樸樕',
-'朴父' => '樸父',
-'朴直' => '樸直',
-'朴素' => '樸素',
-'朴讷' => '樸訥',
-'朴质' => '樸質',
-'朴鄙' => '樸鄙',
-'朴重' => '樸重',
-'朴野' => '樸野',
-'朴钝' => '樸鈍',
-'朴陋' => '樸陋',
-'朴马' => '樸馬',
-'朴鲁' => '樸魯',
-'树干' => '樹幹',
-'树林里' => '樹林裡',
-'树梁' => '樹樑',
-'桥梁' => '橋樑',
-'机械系' => '機械系',
-'機械系' => '機械系',
-'机械表' => '機械錶',
-'机械钟' => '機械鐘',
-'机械钟表' => '機械鐘錶',
-'横峰县' => '橫峯縣',
-'横征暴敛' => '橫徵暴斂',
-'横梁' => '橫樑',
-'横冲' => '橫衝',
-'台布' => '檯布',
-'台历' => '檯曆',
-'台灯' => '檯燈',
-'台球' => '檯球',
-'台面上' => '檯面上',
-'台面化' => '檯面化',
-'柜台' => '櫃檯',
-'柜里' => '櫃裡',
-'栉发工' => '櫛髮工',
-'欲海难填' => '欲海難填',
-'欺蒙' => '欺矇',
-'歌后' => '歌后',
-'歌钟' => '歌鐘',
-'欧游' => '歐遊',
-'止于' => '止於',
-'正官庄' => '正官庄',
-'正杰' => '正杰',
-'武丑' => '武丑',
-'武后' => '武后',
-'武斗' => '武鬥',
-'岁聿云暮' => '歲聿云暮',
-'历史里' => '歷史裡',
-'归并' => '歸併',
-'归于' => '歸於',
-'归余' => '歸餘',
-'歹斗' => '歹鬥',
-'死于' => '死於',
-'死里求生' => '死裡求生',
-'死里逃生' => '死裡逃生',
-'殖谷' => '殖穀',
-'残肴' => '殘肴',
-'残余' => '殘餘',
-'僵尸' => '殭屍',
-'殷师牛斗' => '殷師牛鬥',
-'殷鉴' => '殷鑑',
-'壳里' => '殼裡',
-'殿钟自鸣' => '殿鐘自鳴',
-'毁于' => '毀於',
-'毁钟为铎' => '毀鐘為鐸',
-'殴斗' => '毆鬥',
-'母后' => '母后',
-'母范' => '母範',
-'母丑' => '母醜',
-'每每只' => '每每只',
-'每只' => '每隻',
-'毗婆尸佛' => '毗婆尸佛',
-'毛坏' => '毛坏',
-'毛姜' => '毛薑',
-'毛发' => '毛髮',
-'毫厘' => '毫釐',
-'毫发' => '毫髮',
-'气冲斗牛' => '氣沖斗牛',
-'气郁' => '氣鬱',
-'氤郁' => '氤鬱',
-'水来汤里去' => '水來湯裡去',
-'水准' => '水準',
-'水无怜奈' => '水無怜奈',
-'水表示' => '水表示',
-'水表面' => '水表面',
-'水里' => '水裡',
-'水里商工' => '水里商工',
-'水里溪' => '水里溪',
-'水里濁水溪' => '水里濁水溪',
-'水里鄉' => '水里鄉',
-'水里高級商工' => '水里高級商工',
-'水里鳳林' => '水里鳳林',
-'水表' => '水錶',
-'永历' => '永曆',
-'永历史' => '永歷史',
-'永志不忘' => '永誌不忘',
-'求知欲' => '求知慾',
-'求签' => '求籤',
-'池里' => '池裡',
-'污蔑' => '污衊',
-'汤卤' => '汤滷',
-'汲于' => '汲於',
-'决斗' => '決鬥',
-'沈淀' => '沈澱',
-'沈郁' => '沈鬱',
-'沉淀' => '沉澱',
-'沉郁' => '沉鬱',
-'没干没净' => '沒乾沒淨',
-'没事干' => '沒事幹',
-'没干' => '沒幹',
-'没折至' => '沒摺至',
-'没样范' => '沒樣範',
-'没准' => '沒準',
-'冲冠发怒' => '沖冠髮怒',
-'冲天' => '沖天',
-'沙琅' => '沙瑯',
-'沙羡' => '沙羡',
-'沙里淘金' => '沙裡淘金',
-'河岳' => '河嶽',
-'河里' => '河裡',
-'油泼面' => '油潑麵',
-'油斗' => '油鬥',
-'油面' => '油麵',
-'治愈' => '治癒',
-'沿溯' => '沿泝',
-'法自制' => '法自制',
-'法里,' => '法裡,',
-'泛游' => '泛遊',
-'泡制' => '泡製',
-'泡面' => '泡麵',
-'波棱菜' => '波稜菜',
-'波发藻' => '波髮藻',
-'泥于' => '泥於',
-'注云' => '注云',
-'注释' => '注釋',
-'泰山梁木' => '泰山梁木',
-'泱郁' => '泱鬱',
-'泳气钟' => '泳氣鐘',
-'洄游' => '洄遊',
-'洋河大曲' => '洋河大麯',
-'洒家' => '洒家',
-'洒扫' => '洒掃',
-'洒水' => '洒水',
-'洒洒' => '洒洒',
-'洒淅' => '洒淅',
-'洒涤' => '洒滌',
-'洒濯' => '洒濯',
-'洒然' => '洒然',
-'洒脱' => '洒脫',
-'洗炼' => '洗鍊',
-'洗练' => '洗鍊',
-'洗发' => '洗髮',
-'洛钟东应' => '洛鐘東應',
-'洞里' => '洞裡',
-'洞里萨' => '洞里薩',
-'洞里薩' => '洞里薩',
-'泄欲' => '洩慾',
-'洪范' => '洪範',
-'洪谷子' => '洪谷子',
-'洪适' => '洪适',
-'洪钟' => '洪鐘',
-'汹涌' => '洶湧',
-'流征' => '流徵',
-'流于' => '流於',
-'流荡' => '流蕩',
-'流风余俗' => '流風餘俗',
-'流风余韵' => '流風餘韻',
-'浩浩荡荡' => '浩浩蕩蕩',
-'浩荡' => '浩蕩',
-'浪荡' => '浪蕩',
-'浪游' => '浪遊',
-'浮于' => '浮於',
-'浮荡' => '浮蕩',
-'浮夸' => '浮誇',
-'浮松' => '浮鬆',
-'海干' => '海乾',
-'海淀山后' => '海淀山後',
-'海淀山後' => '海淀山後',
-'浸卤' => '浸滷',
-'涂善妮' => '涂善妮',
-'涂坤' => '涂坤',
-'涂壮勋' => '涂壯勳',
-'涂壯勳' => '涂壯勳',
-'涂天相' => '涂天相',
-'涂姓' => '涂姓',
-'涂序瑄' => '涂序瑄',
-'涂敏恆' => '涂敏恆',
-'涂敏恒' => '涂敏恆',
-'涂泽民' => '涂澤民',
-'涂澤民' => '涂澤民',
-'涂绍煃' => '涂紹煃',
-'涂羽卿' => '涂羽卿',
-'涂謹申' => '涂謹申',
-'涂谨申' => '涂謹申',
-'涂逢年' => '涂逢年',
-'涂醒哲' => '涂醒哲',
-'涂長望' => '涂長望',
-'涂长望' => '涂長望',
-'涂鴻欽' => '涂鴻欽',
-'涂鸿钦' => '涂鴻欽',
-'涌水塘' => '涌水塘',
-'涳蒙' => '涳濛',
-'涸干' => '涸乾',
-'凉席' => '涼蓆',
-'凉面' => '涼麵',
-'淋余土' => '淋餘土',
-'淑范' => '淑範',
-'泪干' => '淚乾',
-'泪如泉涌' => '淚如泉湧',
-'淡于' => '淡於',
-'淡蒙蒙' => '淡濛濛',
-'净余' => '淨餘',
-'净发' => '淨髮',
-'淫欲' => '淫慾',
-'淫荡' => '淫蕩',
-'淬炼' => '淬鍊',
-'深山何处钟' => '深山何處鐘',
-'深山里' => '深山裡',
-'淳于' => '淳于',
-'淳朴' => '淳樸',
-'渊淳岳峙' => '淵淳嶽峙',
-'渊里' => '淵裡',
-'浅淀' => '淺澱',
-'清心寡欲' => '清心寡欲',
-'渠冲' => '渠衝',
-'测不准' => '測不準',
-'港制' => '港製',
-'游离' => '游離',
-'浑朴' => '渾樸',
-'浑个' => '渾箇',
-'湖里' => '湖裡',
-'湘累' => '湘纍',
-'涌上' => '湧上',
-'涌来' => '湧來',
-'涌入' => '湧入',
-'涌出' => '湧出',
-'涌向' => '湧向',
-'涌水' => '湧水',
-'涌泉' => '湧泉',
-'涌现' => '湧現',
-'涌起' => '湧起',
-'涌进' => '湧進',
-'湮郁' => '湮鬱',
-'汤下面' => '湯下麵',
-'汤团' => '湯糰',
-'汤面' => '湯麵',
-'源于' => '源於',
-'准不准' => '準不準',
-'准例' => '準例',
-'准保' => '準保',
-'准备' => '準備',
-'准儿' => '準兒',
-'准分子' => '準分子',
-'准则' => '準則',
-'准噶尔' => '準噶爾',
-'准定' => '準定',
-'准平原' => '準平原',
-'准度' => '準度',
-'准式' => '準式',
-'准拿督' => '準拿督',
-'准据' => '準據',
-'准拟' => '準擬',
-'准新娘' => '準新娘',
-'准新郎' => '準新郎',
-'准星' => '準星',
-'准是' => '準是',
-'准时' => '準時',
-'准会' => '準會',
-'准决赛' => '準決賽',
-'准的' => '準的',
-'准直' => '準直',
-'准确' => '準確',
-'准线' => '準線',
-'准绳' => '準繩',
-'准话' => '準話',
-'准谱' => '準譜',
-'准货币' => '準貨幣',
-'准军事' => '準軍事',
-'准头' => '準頭',
-'准点' => '準點',
-'沟大曲' => '溝大麯',
-'沟谷' => '溝谷',
-'溟蒙' => '溟濛',
-'溢于' => '溢於',
-'温洛克期' => '溫洛克期',
-'溲面' => '溲麵',
-'溺于' => '溺於',
-'滃郁' => '滃鬱',
-'滑借' => '滑藉',
-'汇丰' => '滙豐',
-'渗漓' => '滲灕',
-'卤了' => '滷了',
-'卤五花' => '滷五花',
-'卤味' => '滷味',
-'卤好' => '滷好',
-'卤子' => '滷子',
-'卤料' => '滷料',
-'卤水' => '滷水',
-'卤汁' => '滷汁',
-'卤湖' => '滷湖',
-'卤煮' => '滷煮',
-'卤牛' => '滷牛',
-'卤的' => '滷的',
-'卤肉' => '滷肉',
-'卤菜' => '滷菜',
-'卤蛋' => '滷蛋',
-'卤虾' => '滷蝦',
-'卤制' => '滷製',
-'卤豆' => '滷豆',
-'卤鸡' => '滷雞',
-'卤鸭' => '滷鴨',
-'卤鹅' => '滷鵝',
-'卤面' => '滷麵',
-'满拼自尽' => '滿拚自盡',
-'满满当当' => '滿滿當當',
-'满头洋发' => '滿頭洋髮',
-'漂荡' => '漂蕩',
-'漕挽' => '漕輓',
-'沤郁' => '漚鬱',
-'漠里' => '漠裡',
-'汉弥登钟' => '漢彌登鐘',
-'漫卷' => '漫捲',
-'漫游' => '漫遊',
-'潜意识里' => '潛意識裡',
-'潜水表' => '潛水錶',
-'潜水钟' => '潛水鐘',
-'潜水钟表' => '潛水鐘錶',
-'潭里' => '潭裡',
-'潮涌' => '潮湧',
-'溃于' => '潰於',
-'涩谷区' => '澀谷區',
-'澄江县' => '澂江縣',
-'澄澹精致' => '澄澹精致',
-'澒蒙' => '澒濛',
-'淀乃不耕之地' => '澱乃不耕之地',
-'淀北片' => '澱北片',
-'淀山' => '澱山',
-'淀淀' => '澱澱',
-'淀积' => '澱積',
-'淀粉' => '澱粉',
-'淀解物' => '澱解物',
-'淀谓之滓' => '澱謂之滓',
-'澹台' => '澹臺',
-'澹荡' => '澹蕩',
-'激斗' => '激鬥',
-'浓发' => '濃髮',
-'蒙汜' => '濛汜',
-'蒙蒙细雨' => '濛濛細雨',
-'蒙雾' => '濛霧',
-'蒙鸿' => '濛鴻',
-'浚州' => '濬州',
-'浚县' => '濬縣',
-'滨田里佳子' => '濱田里佳子',
-'沈丹客运' => '瀋丹客運',
-'沈丹线' => '瀋丹線',
-'沈丹铁路' => '瀋丹鐵路',
-'沈丹高' => '瀋丹高',
-'沈北' => '瀋北',
-'沈吉' => '瀋吉',
-'沈大线' => '瀋大線',
-'沈大铁路' => '瀋大鐵路',
-'沈大高速' => '瀋大高速',
-'沈山线' => '瀋山線',
-'沈山铁路' => '瀋山鐵路',
-'沈州' => '瀋州',
-'沈抚' => '瀋撫',
-'沈水' => '瀋水',
-'沈河' => '瀋河',
-'沈海铁路' => '瀋海鐵路',
-'沈海高速' => '瀋海高速',
-'沈阳' => '瀋陽',
-'泸州大曲' => '瀘州大麯',
-'沥干' => '瀝乾',
-'潇洒' => '瀟洒',
-'弥山遍野' => '瀰山遍野',
-'弥漫' => '瀰漫',
-'弥弥' => '瀰瀰',
-'漓水' => '灕水',
-'漓江' => '灕江',
-'漓湘' => '灕湘',
-'漓然' => '灕然',
-'滩涂' => '灘涂',
-'滩席' => '灘蓆',
-'火并非' => '火並非',
-'火并' => '火併',
-'火山里' => '火山裡',
-'火拼' => '火拚',
-'火折子' => '火摺子',
-'火签' => '火籤',
-'灰蒙' => '灰濛',
-'灰蒙蒙' => '灰濛濛',
-'炆面' => '炆麵',
-'炒面' => '炒麵',
-'炮制' => '炮製',
-'炸酱面' => '炸醬麵',
-'为准' => '為準',
-'为鉴' => '為鑑',
-'乌兹冲锋枪' => '烏茲衝鋒槍',
-'乌苏里' => '烏蘇里',
-'乌发' => '烏髮',
-'乌龙面' => '烏龍麵',
-'烘干' => '烘乾',
-'烘制' => '烘製',
-'烤干' => '烤乾',
-'烤卤' => '烤滷',
-'烹制' => '烹製',
-'焙干' => '焙乾',
-'无征不信' => '無徵不信',
-'无业游民' => '無業游民',
-'无梁楼盖' => '無樑樓蓋',
-'无余' => '無餘',
-'炼制' => '煉製',
-'煎面' => '煎麵',
-'烟卷' => '煙捲',
-'烟台' => '煙臺',
-'照入签' => '照入籤',
-'照相干片' => '照相乾片',
-'煨干' => '煨乾',
-'煮面' => '煮麵',
-'熊杰' => '熊杰',
-'荧郁' => '熒鬱',
-'燎发' => '燎髮',
-'烧干' => '燒乾',
-'燕几' => '燕几',
-'燕游' => '燕遊',
-'烫一个发' => '燙一個髮',
-'烫一次发' => '燙一次髮',
-'烫个发' => '燙個髮',
-'烫完发' => '燙完髮',
-'烫次发' => '燙次髮',
-'烫发' => '燙髮',
-'烫面' => '燙麵',
-'营干' => '營幹',
-'烩面' => '燴麵',
-'烬余' => '燼餘',
-'爆发指数' => '爆發指數',
-'争奇斗妍' => '爭奇鬥妍',
-'争奇斗异' => '爭奇鬥異',
-'争奇斗艳' => '爭奇鬥豔',
-'争妍斗奇' => '爭妍鬥奇',
-'争妍斗艳' => '爭妍鬥豔',
-'争红斗紫' => '爭紅鬥紫',
-'争斗' => '爭鬥',
-'爰定祥历' => '爰定祥厤',
-'爽荡' => '爽蕩',
-'尔冬陞' => '爾冬陞',
-'墙里' => '牆裡',
-'片里' => '片裡',
-'片言只语' => '片言隻語',
-'版图里' => '版圖裡',
-'牙签' => '牙籤',
-'牛只' => '牛隻',
-'物欲' => '物慾',
-'抵牾' => '牴牾',
-'抵触' => '牴觸',
-'特别致' => '特别致',
-'特制住' => '特制住',
-'特制定' => '特制定',
-'特制止' => '特制止',
-'特制订' => '特制訂',
-'特征' => '特徵',
-'特制' => '特製',
-'牵一发' => '牽一髮',
-'牵系' => '牽繫',
-'荦确' => '犖确',
-'狂并潮' => '狂併潮',
-'狃于' => '狃於',
-'狄志杰' => '狄志杰',
-'狐借虎威' => '狐藉虎威',
-'猛于' => '猛於',
-'猛冲' => '猛衝',
-'猜三划五' => '猜三划五',
-'犹如表' => '猶如錶',
-'犹如钟' => '猶如鐘',
-'犹如钟表' => '猶如鐘錶',
-'狱里' => '獄裡',
-'奖杯' => '獎盃',
-'独裁制' => '獨裁制',
-'独辟蹊径' => '獨闢蹊徑',
-'获匪其丑' => '獲匪其醜',
-'兽欲' => '獸慾',
-'献丑' => '獻醜',
-'玉历' => '玉曆',
-'玉历史' => '玉歷史',
-'玉米面' => '玉米面',
-'王侯后' => '王侯后',
-'王后' => '王后',
-'王添灯' => '王添灯',
-'王田里' => '王田里',
-'王鉴' => '王鑑',
-'王余鱼' => '王餘魚',
-'珍肴异馔' => '珍肴異饌',
-'班里' => '班裡',
-'现于' => '現於',
-'球台' => '球檯',
-'理一个发' => '理一個髮',
-'理一次发' => '理一次髮',
-'理个发' => '理個髮',
-'理完发' => '理完髮',
-'理次发' => '理次髮',
-'理发' => '理髮',
-'琴钟' => '琴鐘',
-'珐琅' => '琺瑯',
-'瑞城里' => '瑞城里',
-'瑞征' => '瑞徵',
-'瑶签' => '瑤籤',
-'环游' => '環遊',
-'瓷制' => '瓷製',
-'甄后' => '甄后',
-'瓮安' => '甕安',
-'甚于' => '甚於',
-'甜水面' => '甜水麵',
-'甜面酱' => '甜麵醬',
-'生力面' => '生力麵',
-'生于' => '生於',
-'生殖洄游' => '生殖洄游',
-'生物钟' => '生物鐘',
-'生发生' => '生發生',
-'生华发' => '生華髮',
-'生姜' => '生薑',
-'生锈' => '生鏽',
-'生发' => '生髮',
-'产卵洄游' => '產卵洄游',
-'苏醒' => '甦醒',
-'用于' => '用於',
-'用法里' => '用法裡',
-'甩发' => '甩髮',
-'田子里' => '田子里',
-'田庄英雄' => '田庄英雄',
-'田谷' => '田穀',
-'田里' => '田裡',
-'由余' => '由余',
-'由于' => '由於',
-'甲胄' => '甲冑',
-'甲后路' => '甲后路',
-'男仆' => '男僕',
-'界里' => '界裡',
-'畏于' => '畏於',
-'留长发' => '留長髮',
-'留发' => '留髮',
-'毕于' => '畢於',
-'毕业于' => '畢業於',
-'毕生发展' => '畢生發展',
-'当准' => '當準',
-'当当丁丁' => '當當丁丁',
-'当当网' => '當當網',
-'叠席' => '疊蓆',
-'疏松' => '疏鬆',
-'疑系' => '疑係',
-'疑凶' => '疑兇',
-'疲于' => '疲於',
-'疲困' => '疲睏',
-'病征' => '病徵',
-'病愈' => '病癒',
-'病余' => '病餘',
-'痊愈' => '痊癒',
-'痒疹' => '痒疹',
-'痒痒' => '痒痒',
-'痳木' => '痳木',
-'痳疹' => '痳疹',
-'痳病' => '痳病',
-'痳痹' => '痳痺',
-'痳疯' => '痳瘋',
-'愈合' => '癒合',
-'症结' => '癥結',
-'癸丑' => '癸丑',
-'发干' => '發乾',
-'发呆' => '發獃',
-'发签' => '發籤',
-'发松' => '發鬆',
-'发面' => '發麵',
-'白干儿' => '白乾兒',
-'白术' => '白朮',
-'白朴' => '白樸',
-'白净面皮' => '白淨面皮',
-'白发其事' => '白發其事',
-'白皮松' => '白皮松',
-'白粉面' => '白粉麵',
-'白里透红' => '白裡透紅',
-'白面包青天' => '白面包青天',
-'白发' => '白髮',
-'白胡' => '白鬍',
-'白霉' => '白黴',
-'百个' => '百個',
-'百只可' => '百只可',
-'百只够' => '百只夠',
-'百只夠' => '百只夠',
-'百只怕' => '百只怕',
-'百只足够' => '百只足夠',
-'百只足夠' => '百只足夠',
-'百周后' => '百周後',
-'百天后' => '百天後',
-'百子里' => '百子里',
-'百年' => '百年',
-'百拙千丑' => '百拙千醜',
-'百科里' => '百科裡',
-'百谷' => '百穀',
-'百扎' => '百紮',
-'百花历' => '百花曆',
-'百花历史' => '百花歷史',
-'百炼' => '百鍊',
-'百只' => '百隻',
-'百余' => '百餘',
-'的回复' => '的回覆',
-'的图里' => '的圖裡',
-'的山里' => '的山裡',
-'的干将' => '的幹將',
-'的个中' => '的箇中',
-'的钟' => '的鐘',
-'的长发' => '的長髮',
-'的发小' => '的髮小',
-'皆可作淀' => '皆可作澱',
-'皆准' => '皆準',
-'皇后' => '皇后',
-'皇历' => '皇曆',
-'皇极历' => '皇極曆',
-'皇极历史' => '皇極歷史',
-'皇历史' => '皇歷史',
-'皓发' => '皓髮',
-'皮制服' => '皮制服',
-'皮托管' => '皮托管',
-'皮肤' => '皮膚',
-'皮里春秋' => '皮裡春秋',
-'皮里阳秋' => '皮裡陽秋',
-'皮制' => '皮製',
-'皮松' => '皮鬆',
-'皱别' => '皺彆',
-'皱折' => '皺摺',
-'盆吊' => '盆弔',
-'盈余' => '盈餘',
-'益于' => '益於',
-'盒里' => '盒裡',
-'盛赞' => '盛讚',
-'盗采' => '盜採',
-'盗钟' => '盜鐘',
-'监制' => '監製',
-'盘里' => '盤裡',
-'盘回' => '盤迴',
-'卢棱伽' => '盧稜伽',
-'荡气回肠' => '盪氣迴腸',
-'盲干' => '盲幹',
-'直于' => '直於',
-'直冲' => '直衝',
-'相并' => '相併',
-'相克制' => '相克制',
-'相克服' => '相克服',
-'相克' => '相剋',
-'相干' => '相干',
-'相于' => '相於',
-'相冲' => '相衝',
-'相斗' => '相鬥',
-'看下表' => '看下錶',
-'看下钟' => '看下鐘',
-'看法里' => '看法裡',
-'看准' => '看準',
-'看表面' => '看表面',
-'看表' => '看錶',
-'看钟' => '看鐘',
-'真凶' => '真兇',
-'真个' => '真箇',
-'真丑' => '真醜',
-'眼干' => '眼乾',
-'眼帘' => '眼帘',
-'眼眶里' => '眼眶裡',
-'眼睛里' => '眼睛裡',
-'眼里' => '眼裡',
-'着眼于' => '着眼於',
-'困乏' => '睏乏',
-'困了' => '睏了',
-'困倦' => '睏倦',
-'困觉' => '睏覺',
-'睡游病' => '睡遊病',
-'瞄准' => '瞄準',
-'瞅下表' => '瞅下錶',
-'瞅下钟' => '瞅下鐘',
-'瞎蒙' => '瞎矇',
-'了望' => '瞭望',
-'了然' => '瞭然',
-'了若指掌' => '瞭若指掌',
-'瞳蒙' => '瞳矇',
-'蒙事' => '矇事',
-'蒙昧无知' => '矇昧無知',
-'蒙松雨' => '矇松雨',
-'蒙混' => '矇混',
-'蒙瞍' => '矇瞍',
-'蒙眬' => '矇矓',
-'蒙聩' => '矇聵',
-'蒙头转' => '矇頭轉',
-'蒙骗' => '矇騙',
-'瞩托' => '矚託',
-'矜夸' => '矜誇',
-'短几' => '短几',
-'短于' => '短於',
-'短发生' => '短發生',
-'短发' => '短髮',
-'矮几' => '矮几',
-'石几' => '石几',
-'石杠' => '石杠',
-'石梁' => '石樑',
-'石英钟' => '石英鐘',
-'石英钟表' => '石英鐘錶',
-'石钟' => '石鐘',
-'研制' => '研製',
-'砰当' => '砰噹',
-'破鉴' => '破鑑',
-'朱砂' => '硃砂',
-'硬干' => '硬幹',
-'确瘠' => '确瘠',
-'碑志' => '碑誌',
-'碗里' => '碗裡',
-'碰钟' => '碰鐘',
-'确系' => '確係',
-'码表' => '碼錶',
-'磁制' => '磁製',
-'磨蝎' => '磨蝎',
-'磨制' => '磨製',
-'磨炼' => '磨鍊',
-'磬钟' => '磬鐘',
-'硗确' => '磽确',
-'砻谷' => '礱穀',
-'示范' => '示範',
-'社里' => '社裡',
-'祝赞' => '祝讚',
-'祝发' => '祝髮',
-'神荼郁垒' => '神荼鬱壘',
-'神游' => '神遊',
-'神雕像' => '神雕像',
-'神雕' => '神鵰',
-'祭吊' => '祭弔',
-'禁欲' => '禁慾',
-'禁欲主义' => '禁欲主義',
-'祸于' => '禍於',
-'御侮' => '禦侮',
-'御寇' => '禦寇',
-'御寒' => '禦寒',
-'御敌' => '禦敵',
-'礼赞' => '禮讚',
-'禾谷' => '禾穀',
-'秃妃之发' => '禿妃之髮',
-'秃发' => '禿髮',
-'秀发动' => '秀發動',
-'秀发展' => '秀發展',
-'秀发布' => '秀發布',
-'秀发村' => '秀發村',
-'秀发现' => '秀發現',
-'秀发生' => '秀發生',
-'秀发表' => '秀發表',
-'秀发起' => '秀發起',
-'秀发' => '秀髮',
-'私下里' => '私下裡',
-'私欲' => '私慾',
-'私斗' => '私鬥',
-'秋游' => '秋遊',
-'种丹妮' => '种丹妮',
-'种师中' => '种師中',
-'种师道' => '种師道',
-'种放' => '种放',
-'科尼亚克期' => '科尼亞克期',
-'科斗' => '科斗',
-'科范' => '科範',
-'秒表明' => '秒表明',
-'秒表示' => '秒表示',
-'秒钟' => '秒鐘',
-'秤杆' => '秤桿',
-'秦沈客运' => '秦瀋客運',
-'移祸于' => '移禍於',
-'稀松' => '稀鬆',
-'棱台' => '稜台',
-'棱子' => '稜子',
-'棱层' => '稜層',
-'棱柱' => '稜柱',
-'棱登' => '稜登',
-'棱棱' => '稜稜',
-'棱等登' => '稜等登',
-'棱线' => '稜線',
-'棱缝' => '稜縫',
-'棱角' => '稜角',
-'棱锥' => '稜錐',
-'棱镜' => '稜鏡',
-'棱体' => '稜體',
-'种谷' => '種穀',
-'称赞' => '稱讚',
-'稻谷' => '稻穀',
-'稽征' => '稽徵',
-'谷人' => '穀人',
-'谷保家商' => '穀保家商',
-'谷仓' => '穀倉',
-'谷圭' => '穀圭',
-'谷场' => '穀場',
-'谷子' => '穀子',
-'谷日' => '穀日',
-'谷旦' => '穀旦',
-'谷梁' => '穀梁',
-'谷壳' => '穀殼',
-'谷物' => '穀物',
-'谷皮' => '穀皮',
-'谷神' => '穀神',
-'谷禄' => '穀祿',
-'谷谷' => '穀穀',
-'谷米' => '穀米',
-'谷粒' => '穀粒',
-'谷舱' => '穀艙',
-'谷苗' => '穀苗',
-'谷草' => '穀草',
-'谷贵饿农' => '穀貴餓農',
-'谷贱伤农' => '穀賤傷農',
-'谷雨' => '穀雨',
-'谷类' => '穀類',
-'谷食' => '穀食',
-'穆棱' => '穆稜',
-'穆罕默德历' => '穆罕默德曆',
-'穆罕默德历史' => '穆罕默德歷史',
-'积淀' => '積澱',
-'积谷' => '積穀',
-'积谷防饥' => '積穀防饑',
-'积郁' => '積鬱',
-'稳健的台风' => '穩健的台風',
-'稳扎' => '穩紮',
-'空蒙' => '空濛',
-'空荡' => '空蕩',
-'空荡荡' => '空蕩蕩',
-'空钟' => '空鐘',
-'空余' => '空餘',
-'窒欲' => '窒慾',
-'窗明几亮' => '窗明几亮',
-'窗明几净' => '窗明几淨',
-'窗帘' => '窗簾',
-'窝里' => '窩裡',
-'窝里斗' => '窩裡鬥',
-'穷于' => '窮於',
-'穷追不舍' => '窮追不捨',
-'穷发' => '窮髮',
-'窃钟掩耳' => '竊鐘掩耳',
-'立于' => '立於',
-'立范' => '立範',
-'童仆' => '童僕',
-'竞斗' => '競鬥',
-'竹几' => '竹几',
-'竹林之游' => '竹林之遊',
-'竹签' => '竹籤',
-'竹席' => '竹蓆',
-'竹制' => '竹製',
-'竹溪县' => '竹谿縣',
-'笑里藏刀' => '笑裡藏刀',
-'第一出现' => '第一出現',
-'第一出現' => '第一出現',
-'第一出線' => '第一出線',
-'第一出线' => '第一出線',
-'第一出' => '第一齣',
-'第七出' => '第七齣',
-'第三出局' => '第三出局',
-'第三出' => '第三齣',
-'第九出' => '第九齣',
-'第二出線' => '第二出線',
-'第二出线' => '第二出線',
-'第二出' => '第二齣',
-'第五出局' => '第五出局',
-'第五出' => '第五齣',
-'第八出' => '第八齣',
-'第六出' => '第六齣',
-'第四出局' => '第四出局',
-'第四出' => '第四齣',
-'笔杆' => '筆桿',
-'笔秃墨干' => '筆禿墨乾',
-'等于' => '等於',
-'笋干' => '筍乾',
-'筑前' => '筑前',
-'筑北' => '筑北',
-'筑州' => '筑州',
-'筑后' => '筑後',
-'筑後' => '筑後',
-'筑波' => '筑波',
-'筑紫' => '筑紫',
-'筑肥' => '筑肥',
-'筑西' => '筑西',
-'筑邦' => '筑邦',
-'筑阳' => '筑陽',
-'筑陽' => '筑陽',
-'答复' => '答覆',
-'筵几' => '筵几',
-'个中原因' => '箇中原因',
-'个中奥' => '箇中奧',
-'个中好手' => '箇中好手',
-'个中强手' => '箇中強手',
-'个中滋味' => '箇中滋味',
-'个中玄机' => '箇中玄機',
-'个中理由' => '箇中理由',
-'个中翘楚' => '箇中翹楚',
-'个中道理' => '箇中道理',
-'个中高手' => '箇中高手',
-'个旧' => '箇舊',
-'算历' => '算曆',
-'算历史' => '算歷史',
-'算准' => '算準',
-'管制' => '管制',
-'管干' => '管幹',
-'箱里' => '箱裡',
-'节欲' => '節慾',
-'节目里' => '節目裡',
-'节余' => '節餘',
-'范亭' => '範亭',
-'范例' => '範例',
-'范围' => '範圍',
-'范字' => '範字',
-'范式' => '範式',
-'范性形变' => '範性形變',
-'范数' => '範數',
-'范文' => '範文',
-'范本' => '範本',
-'范畴' => '範疇',
-'范金' => '範金',
-'简并' => '簡併',
-'简朴' => '簡樸',
-'简短发' => '簡短發',
-'简筑翎' => '簡筑翎',
-'簡筑翎' => '簡筑翎',
-'簸荡' => '簸蕩',
-'签幐' => '籤幐',
-'签押' => '籤押',
-'签条' => '籤條',
-'签诗' => '籤詩',
-'吁天' => '籲天',
-'吁求' => '籲求',
-'吁请' => '籲請',
-'米沈' => '米瀋',
-'米谷' => '米穀',
-'米团' => '米糰',
-'米余' => '米餘',
-'米面' => '米麵',
-'粉签子' => '粉籤子',
-'粗制' => '粗製',
-'精制伏' => '精制伏',
-'精制住' => '精制住',
-'精制服' => '精制服',
-'精干' => '精幹',
-'精于' => '精於',
-'精准' => '精準',
-'精致' => '精緻',
-'精制' => '精製',
-'精炼' => '精鍊',
-'精辟' => '精闢',
-'精松' => '精鬆',
-'糊里糊涂' => '糊裡糊塗',
-'糕干' => '糕乾',
-'粪秽蔑面' => '糞穢衊面',
-'团子' => '糰子',
-'系列里' => '系列裡',
-'系里' => '系裡',
-'纪历' => '紀曆',
-'纪历史' => '紀歷史',
-'红后假说' => '紅后假說',
-'红绳系足' => '紅繩繫足',
-'红钟' => '紅鐘',
-'红发' => '紅髮',
-'纡回' => '紆迴',
-'纡余' => '紆餘',
-'纡郁' => '紆鬱',
-'纳征' => '納徵',
-'纯朴' => '純樸',
-'纸扎' => '紙紮',
-'素数里' => '素數裡',
-'素朴' => '素樸',
-'素发' => '素髮',
-'素面' => '素麵',
-'索馬里' => '索馬里',
-'索马里' => '索馬里',
-'索面' => '索麵',
-'紫姜' => '紫薑',
-'扎上' => '紮上',
-'扎下' => '紮下',
-'扎囮' => '紮囮',
-'扎好' => '紮好',
-'扎实' => '紮實',
-'扎寨' => '紮寨',
-'扎带子' => '紮帶子',
-'扎成' => '紮成',
-'扎根' => '紮根',
-'扎营' => '紮營',
-'扎紧' => '紮緊',
-'扎脚' => '紮腳',
-'扎裹' => '紮裹',
-'扎诈' => '紮詐',
-'扎起' => '紮起',
-'扎铁' => '紮鐵',
-'细不容发' => '細不容髮',
-'细如发' => '細如髮',
-'细致' => '細緻',
-'细炼' => '細鍊',
-'终于' => '終於',
-'组里' => '組裡',
-'结伴同游' => '結伴同遊',
-'结伙' => '結夥',
-'结扎' => '結紮',
-'结余' => '結餘',
-'结发' => '結髮',
-'绝于' => '絕於',
-'绞干' => '絞乾',
-'络腮胡' => '絡腮鬍',
-'给于' => '給於',
-'丝恩发怨' => '絲恩髮怨',
-'丝制' => '絲製',
-'丝发' => '絲髮',
-'绑扎' => '綁紮',
-'绥棱' => '綏稜',
-'捆扎' => '綑紮',
-'經有云' => '經有云',
-'经有云' => '經有云',
-'综合征' => '綜合徵',
-'绿发' => '綠髮',
-'维系' => '維繫',
-'绾发' => '綰髮',
-'纲鉴' => '綱鑑',
-'網球台' => '網球台',
-'网球台' => '網球台',
-'网站里' => '網站裡',
-'网里' => '網裡',
-'网志' => '網誌',
-'网游' => '網遊',
-'紧致' => '緊緻',
-'紧追不舍' => '緊追不捨',
-'绪余' => '緒餘',
-'线图里' => '線圖裡',
-'缉凶' => '緝兇',
-'编制法' => '編制法',
-'编采' => '編採',
-'编码表' => '編碼表',
-'编钟' => '編鐘',
-'编余' => '編餘',
-'编发' => '編髮',
-'缓征' => '緩徵',
-'缓冲' => '緩衝',
-'致密' => '緻密',
-'萦回' => '縈迴',
-'缜致' => '縝緻',
-'县里' => '縣裡',
-'县志' => '縣誌',
-'缝里' => '縫裡',
-'缝制' => '縫製',
-'缩栗' => '縮慄',
-'缩短发' => '縮短發',
-'纵欲' => '縱慾',
-'纤夫' => '縴夫',
-'纤手' => '縴手',
-'纤绳' => '縴繩',
-'总数只' => '總數只',
-'总数里' => '總數裡',
-'总裁制' => '總裁制',
-'繁复' => '繁複',
-'繁钟' => '繁鐘',
-'绷扒吊拷' => '繃扒弔拷',
-'绕梁' => '繞樑',
-'绘制' => '繪製',
-'系上。' => '繫上。',
-'系上了' => '繫上了',
-'系上安全' => '繫上安全',
-'系上红' => '繫上紅',
-'系上丝' => '繫上絲',
-'系上绳' => '繫上繩',
-'系上头' => '繫上頭',
-'系上黑' => '繫上黑',
-'系上,' => '繫上,',
-'系世' => '繫世',
-'系到' => '繫到',
-'系囚' => '繫囚',
-'系心' => '繫心',
-'系念' => '繫念',
-'系怀' => '繫懷',
-'系恋' => '繫戀',
-'系于' => '繫於',
-'系于一发' => '繫於一髮',
-'系着' => '繫着',
-'系结' => '繫結',
-'系紧' => '繫緊',
-'系绳' => '繫繩',
-'系累' => '繫纍',
-'系舟' => '繫舟',
-'系船' => '繫船',
-'系辞' => '繫辭',
-'系鞋带' => '繫鞋帶',
-'系风捕影' => '繫風捕影',
-'累囚' => '纍囚',
-'累堆' => '纍堆',
-'累瓦结绳' => '纍瓦結繩',
-'累绁' => '纍紲',
-'累臣' => '纍臣',
-'缠斗' => '纏鬥',
-'坛子' => '罈子',
-'坛坛罐罐' => '罈罈罐罐',
-'坛騞' => '罈騞',
-'置于' => '置於',
-'置言成范' => '置言成範',
-'罢于' => '罷於',
-'罗马历' => '羅馬曆',
-'罗马历代' => '羅馬歷代',
-'罗马历史' => '羅馬歷史',
-'羁系' => '羈繫',
-'美容美发' => '美容美髮',
-'美于' => '美於',
-'美丑' => '美醜',
-'美发学' => '美髮學',
-'美发师' => '美髮師',
-'美发店' => '美髮店',
-'美发业' => '美髮業',
-'美发沙龙' => '美髮沙龍',
-'美发馆' => '美髮館',
-'群丑' => '群醜',
-'羡余' => '羨餘',
-'义仆' => '義僕',
-'義联' => '義联',
-'翁子里' => '翁子里',
-'翕辟' => '翕闢',
-'翱游' => '翱遊',
-'翻涌' => '翻湧',
-'翻松' => '翻鬆',
-'老么' => '老么',
-'老干' => '老乾',
-'老仆' => '老僕',
-'老干部' => '老幹部',
-'老懞' => '老懞',
-'老于' => '老於',
-'老爷钟' => '老爺鐘',
-'老白干' => '老白乾',
-'老姜' => '老薑',
-'老板' => '老闆',
-'老面皮' => '老面皮',
-'考征' => '考徵',
-'耍斗' => '耍鬥',
-'耕获' => '耕穫',
-'耳余' => '耳餘',
-'耿于' => '耿於',
-'聊斋志异' => '聊齋志異',
-'圣人历' => '聖人曆',
-'圣后' => '聖后',
-'圣马尔谷日' => '聖馬爾谷日',
-'聖馬爾谷日' => '聖馬爾谷日',
-'聘雇' => '聘僱',
-'聚药雄蕊' => '聚葯雄蕊',
-'闻风后' => '聞風後',
-'联系' => '聯繫',
-'声母后' => '聲母後',
-'听于' => '聽於',
-'肉干' => '肉乾',
-'肉欲' => '肉慾',
-'肉丝面' => '肉絲麵',
-'肉羹面' => '肉羹麵',
-'肉松' => '肉鬆',
-'肉面' => '肉麵',
-'肚里' => '肚裡',
-'肝脏' => '肝臟',
-'肝郁' => '肝鬱',
-'股栗' => '股慄',
-'肥筑方言' => '肥筑方言',
-'肴馔' => '肴饌',
-'肺脏' => '肺臟',
-'胃脏' => '胃臟',
-'胃里' => '胃裡',
-'背地里' => '背地裡',
-'胎发' => '胎髮',
-'胜肽' => '胜肽',
-'胜键' => '胜鍵',
-'胡云' => '胡云',
-'胡子婴' => '胡子嬰',
-'胡子昂' => '胡子昂',
-'胡杰' => '胡杰',
-'胡朴安' => '胡樸安',
-'胡里胡涂' => '胡裡胡塗',
-'胰脏' => '胰臟',
-'能干休' => '能干休',
-'能干戈' => '能干戈',
-'能干扰' => '能干擾',
-'能干政' => '能干政',
-'能干涉' => '能干涉',
-'能干预' => '能干預',
-'能干' => '能幹',
-'能自制' => '能自制',
-'脉冲' => '脈衝',
-'脊梁背' => '脊梁背',
-'脊梁骨' => '脊梁骨',
-'脊梁' => '脊樑',
-'脱谷机' => '脫穀機',
-'脱发' => '脫髮',
-'脺脏' => '脺臟',
-'脾脏' => '脾臟',
-'腊之以为饵' => '腊之以為餌',
-'腊味' => '腊味',
-'腊毒' => '腊毒',
-'腊笔' => '腊筆',
-'腌臜' => '腌臢',
-'肾脏' => '腎臟',
-'腐干' => '腐乾',
-'腐余' => '腐餘',
-'腑脏' => '腑臟',
-'腕表' => '腕錶',
-'脑干' => '腦幹',
-'腰里' => '腰裡',
-'脚注' => '腳註',
-'脚炼' => '腳鍊',
-'肠脏' => '腸臟',
-'胶卷' => '膠捲',
-'膨松' => '膨鬆',
-'膵脏' => '膵臟',
-'臊子面' => '臊子麵',
-'脏器' => '臟器',
-'脏胸' => '臟胸',
-'脏腑' => '臟腑',
-'臣仆' => '臣僕',
-'卧游' => '臥遊',
-'臧谷亡羊' => '臧穀亡羊',
-'临潼斗宝' => '臨潼鬥寶',
-'自干五' => '自乾五',
-'自制一下' => '自制一下',
-'自制下来' => '自制下來',
-'自制不' => '自制不',
-'自制之力' => '自制之力',
-'自制之能' => '自制之能',
-'自制他' => '自制他',
-'自制伏' => '自制伏',
-'自制你' => '自制你',
-'自制力' => '自制力',
-'自制地' => '自制地',
-'自制她' => '自制她',
-'自制情' => '自制情',
-'自制我' => '自制我',
-'自制服' => '自制服',
-'自制的能' => '自制的能',
-'自制能力' => '自制能力',
-'自于' => '自於',
-'自然数里' => '自然數裡',
-'自由钟' => '自由鐘',
-'自制' => '自製',
-'自觉自愿' => '自覺自愿',
-'自夸' => '自誇',
-'臭气冲天' => '臭氣衝天',
-'至多' => '至多',
-'至多只' => '至多只',
-'至于' => '至於',
-'致于' => '致於',
-'台佟' => '臺佟',
-'台静农' => '臺靜農',
-'臻于' => '臻於',
-'舂谷' => '舂穀',
-'举手表' => '舉手表',
-'舉手表' => '舉手表',
-'舊庄' => '舊庄',
-'旧历' => '舊曆',
-'旧历史' => '舊歷史',
-'旧游' => '舊遊',
-'旧表' => '舊錶',
-'旧钟' => '舊鐘',
-'旧钟表' => '舊鐘錶',
-'舌干唇焦' => '舌乾唇焦',
-'舍入口' => '舍入口',
-'舒卷' => '舒捲',
-'舞后' => '舞后',
-'航海历' => '航海曆',
-'航海历史' => '航海歷史',
-'船只得' => '船只得',
-'船只有' => '船只有',
-'船只能' => '船只能',
-'船钟' => '船鐘',
-'船只' => '船隻',
-'舰只' => '艦隻',
-'色欲' => '色慾',
-'色长发' => '色長髮',
-'艳后' => '艷后',
-'艷后' => '艷后',
-'艸木丰丰' => '艸木丰丰',
-'芒果干' => '芒果乾',
-'花不要采' => '花不要採',
-'花卷' => '花捲',
-'花盆里' => '花盆裡',
-'花菴词选' => '花菴詞選',
-'花药' => '花葯',
-'花钟' => '花鐘',
-'花马吊嘴' => '花馬弔嘴',
-'花哄' => '花鬨',
-'苑里' => '苑裡',
-'若干' => '若干',
-'苦干' => '苦幹',
-'苦于' => '苦於',
-'苦里' => '苦裡',
-'苦斗' => '苦鬥',
-'苧麻' => '苧麻',
-'茂都淀' => '茂都澱',
-'范文同' => '范文同',
-'范文正公' => '范文正公',
-'范文澜' => '范文瀾',
-'范文瀾' => '范文瀾',
-'范文照' => '范文照',
-'范文程' => '范文程',
-'范文芳' => '范文芳',
-'范文藤' => '范文藤',
-'范文虎' => '范文虎',
-'范登堡' => '范登堡',
-'范賢惠' => '范賢惠',
-'范贤惠' => '范賢惠',
-'茅于軾' => '茅于軾',
-'茅于轼' => '茅于軾',
-'茶几' => '茶几',
-'茶余' => '茶餘',
-'茶面' => '茶麵',
-'草丛里' => '草叢裡',
-'草荐' => '草荐',
-'草席' => '草蓆',
-'荐居' => '荐居',
-'荐臻' => '荐臻',
-'荐饥' => '荐饑',
-'荷花淀' => '荷花澱',
-'庄里' => '莊裡',
-'茎干' => '莖幹',
-'莜面' => '莜麵',
-'莽荡' => '莽蕩',
-'菜干' => '菜乾',
-'菜坛' => '菜罈',
-'菜肴' => '菜餚',
-'菠棱菜' => '菠稜菜',
-'菠萝干' => '菠蘿乾',
-'华严钟' => '華嚴鐘',
-'万一只' => '萬一只',
-'萬一只' => '萬一只',
-'万个' => '萬個',
-'万周后' => '萬周後',
-'万天后' => '萬天後',
-'万年' => '萬年',
-'万年历' => '萬年曆',
-'万年历表' => '萬年曆錶',
-'万历' => '萬曆',
-'万历史' => '萬歷史',
-'万签插架' => '萬籤插架',
-'万扎' => '萬紮',
-'万象' => '萬象',
-'万只' => '萬隻',
-'万余' => '萬餘',
-'落于' => '落於',
-'落腮胡' => '落腮鬍',
-'落发' => '落髮',
-'叶叶琴' => '葉叶琴',
-'叶叶琹' => '葉叶琹',
-'叶阳后' => '葉陽后',
-'葉陽后' => '葉陽后',
-'葡萄干' => '葡萄乾',
-'董氏封发' => '董氏封髮',
-'葫芦里卖甚么药' => '葫蘆裡賣甚麼藥',
-'葬于' => '葬於',
-'蒙雾露' => '蒙霧露',
-'蒜发' => '蒜髮',
-'蒲席' => '蒲蓆',
-'蒸干' => '蒸乾',
-'蒸制' => '蒸製',
-'苍术' => '蒼朮',
-'苍发' => '蒼髮',
-'苍郁' => '蒼鬱',
-'蓄发' => '蓄髮',
-'蓄胡' => '蓄鬍',
-'蓄须' => '蓄鬚',
-'席子' => '蓆子',
-'蓊郁' => '蓊鬱',
-'蓬发' => '蓬髮',
-'蓬松' => '蓬鬆',
-'蓬松松' => '蓬鬆鬆',
-'参绥' => '蔘綏',
-'葱郁' => '蔥鬱',
-'荞麦面' => '蕎麥麵',
-'芸薹' => '蕓薹',
-'荡来荡去' => '蕩來蕩去',
-'荡女' => '蕩女',
-'荡妇' => '蕩婦',
-'荡寇' => '蕩寇',
-'荡平' => '蕩平',
-'荡气' => '蕩氣',
-'荡涤' => '蕩滌',
-'荡漾' => '蕩漾',
-'荡然' => '蕩然',
-'荡产' => '蕩產',
-'荡舟' => '蕩舟',
-'荡船' => '蕩船',
-'荡荡' => '蕩蕩',
-'萧参' => '蕭蔘',
-'薄幸' => '薄倖',
-'薄干' => '薄幹',
-'姜啤' => '薑啤',
-'姜是老的辣' => '薑是老的辣',
-'姜末' => '薑末',
-'姜桂' => '薑桂',
-'姜母' => '薑母',
-'姜汁' => '薑汁',
-'姜汤' => '薑湯',
-'姜片' => '薑片',
-'姜糖' => '薑糖',
-'姜丝' => '薑絲',
-'姜老辣' => '薑老辣',
-'姜茶' => '薑茶',
-'姜蓉' => '薑蓉',
-'姜饼' => '薑餅',
-'姜黄' => '薑黃',
-'薙发' => '薙髮',
-'薝卜' => '薝蔔',
-'熏心' => '薰心',
-'熏染' => '薰染',
-'熏沐' => '薰沐',
-'熏习' => '薰習',
-'熏陶' => '薰陶',
-'熏风' => '薰風',
-'熏香' => '薰香',
-'苧悴' => '薴悴',
-'苧烯' => '薴烯',
-'薴烯' => '薴烯',
-'借以' => '藉以',
-'借助' => '藉助',
-'借口' => '藉口',
-'借寇兵' => '藉寇兵',
-'借手' => '藉手',
-'借故' => '藉故',
-'借机' => '藉機',
-'借此' => '藉此',
-'借由' => '藉由',
-'借箸代筹' => '藉箸代籌',
-'借资' => '藉資',
-'蓝淀' => '藍澱',
-'藏于' => '藏於',
-'藏历' => '藏曆',
-'藏历史' => '藏歷史',
-'藏蒙歌儿' => '藏矇歌兒',
-'藤席' => '藤蓆',
-'藤制' => '藤製',
-'药签' => '藥籤',
-'药面儿' => '藥麵兒',
-'苏崑' => '蘇崑',
-'苏昆' => '蘇崑',
-'苹果' => '蘋果',
-'苹果干' => '蘋果乾',
-'兰溪市' => '蘭谿市',
-'萝卜' => '蘿蔔',
-'萝卜干' => '蘿蔔乾',
-'虎须' => '虎鬚',
-'虎斗' => '虎鬥',
-'处于' => '處於',
-'虚夸' => '虛誇',
-'号志' => '號誌',
-'虫部' => '虫部',
-'蚊动牛斗' => '蚊動牛鬥',
-'蛇发女妖' => '蛇髮女妖',
-'蜂后' => '蜂后',
-'蜂涌' => '蜂湧',
-'蜂准' => '蜂準',
-'蜜里调油' => '蜜裡調油',
-'蜡月' => '蜡月',
-'蜡祭' => '蜡祭',
-'蝎虎' => '蝎虎',
-'蝎蝎螫螫' => '蝎蝎螫螫',
-'蝎谮' => '蝎譖',
-'虾面' => '蝦麵',
-'虮虱相吊' => '蟣蝨相弔',
-'蛏干' => '蟶乾',
-'蚁后' => '蟻后',
-'蟻后' => '蟻后',
-'蚃干' => '蠁幹',
-'蛮干' => '蠻幹',
-'血拼' => '血拚',
-'血余' => '血餘',
-'行事历' => '行事曆',
-'行事历史' => '行事歷史',
-'行凶' => '行兇',
-'行家里手' => '行家裡手',
-'行于' => '行於',
-'卫后庄公' => '衛後莊公',
-'卫星钟' => '衛星鐘',
-'冲上' => '衝上',
-'冲下' => '衝下',
-'冲来' => '衝來',
-'冲倒' => '衝倒',
-'冲冠' => '衝冠',
-'冲出' => '衝出',
-'冲到' => '衝到',
-'冲刺' => '衝刺',
-'冲克' => '衝剋',
-'冲力' => '衝力',
-'冲劲' => '衝勁',
-'冲动' => '衝動',
-'冲去' => '衝去',
-'冲口' => '衝口',
-'冲垮' => '衝垮',
-'冲堂' => '衝堂',
-'冲坚陷阵' => '衝堅陷陣',
-'冲压' => '衝壓',
-'冲天炮' => '衝天炮',
-'冲州撞府' => '衝州撞府',
-'冲心' => '衝心',
-'冲掉' => '衝掉',
-'冲撞' => '衝撞',
-'冲击' => '衝擊',
-'冲散' => '衝散',
-'冲杀' => '衝殺',
-'冲决' => '衝決',
-'冲波' => '衝波',
-'冲浪' => '衝浪',
-'冲激' => '衝激',
-'冲然' => '衝然',
-'冲盹' => '衝盹',
-'冲着' => '衝着',
-'冲破' => '衝破',
-'冲程' => '衝程',
-'冲突' => '衝突',
-'冲线' => '衝線',
-'冲要' => '衝要',
-'冲起' => '衝起',
-'冲车' => '衝車',
-'冲进' => '衝進',
-'冲过' => '衝過',
-'冲量' => '衝量',
-'冲锋' => '衝鋒',
-'冲锋枪' => '衝鋒鎗',
-'冲陷' => '衝陷',
-'冲头阵' => '衝頭陣',
-'冲风' => '衝風',
-'衡鉴' => '衡鑑',
-'表面包' => '表面包',
-'衷于' => '衷於',
-'袋杆' => '袋桿',
-'袋里' => '袋裡',
-'袋表' => '袋錶',
-'袖里' => '袖裡',
-'被废后' => '被廢後',
-'被系上' => '被繫上',
-'被里' => '被裡',
-'被夸' => '被誇',
-'被发佯狂' => '被髮佯狂',
-'被发入山' => '被髮入山',
-'被发左衽' => '被髮左衽',
-'被发缨冠' => '被髮纓冠',
-'被发阳狂' => '被髮陽狂',
-'夹衣' => '袷衣',
-'夹裙' => '袷裙',
-'裁并' => '裁併',
-'裁制' => '裁製',
-'里水镇' => '裏水鎮',
-'里海' => '裏海',
-'里白' => '裏白',
-'里运河' => '裏運河',
-'补于' => '補於',
-'补注' => '補註',
-'装折' => '裝摺',
-'里勾外连' => '裡勾外連',
-'里屋' => '裡屋',
-'里层' => '裡層',
-'里带' => '裡帶',
-'里弦' => '裡弦',
-'里应外合' => '裡應外合',
-'里脊' => '裡脊',
-'里衣' => '裡衣',
-'里通外国' => '裡通外國',
-'里通外敌' => '裡通外敵',
-'里边' => '裡邊',
-'里间' => '裡間',
-'里面' => '裡面',
-'里面包' => '裡面包',
-'里头' => '裡頭',
-'制件' => '製件',
-'制作' => '製作',
-'制做' => '製做',
-'制备' => '製備',
-'制冰' => '製冰',
-'制冷' => '製冷',
-'制剂' => '製劑',
-'制取' => '製取',
-'制品' => '製品',
-'制图' => '製圖',
-'制得' => '製得',
-'制成' => '製成',
-'制毒' => '製毒',
-'制法' => '製法',
-'制浆' => '製漿',
-'制片' => '製片',
-'制版' => '製版',
-'制程' => '製程',
-'制糖' => '製糖',
-'制纸' => '製紙',
-'制药' => '製藥',
-'制衣' => '製衣',
-'制表键' => '製表鍵',
-'制贩' => '製販',
-'制造' => '製造',
-'制革' => '製革',
-'制鞋' => '製鞋',
-'制盐' => '製鹽',
-'复元音' => '複元音',
-'复函数' => '複函數',
-'复分数' => '複分數',
-'复分析' => '複分析',
-'复分解' => '複分解',
-'复列' => '複列',
-'复利' => '複利',
-'复印' => '複印',
-'复句' => '複句',
-'复合' => '複合',
-'复壁' => '複壁',
-'复姓' => '複姓',
-'复字键' => '複字鍵',
-'复审' => '複審',
-'复写' => '複寫',
-'复对数' => '複對數',
-'复平面' => '複平面',
-'复式' => '複式',
-'复数' => '複數',
-'复方' => '複方',
-'复本' => '複本',
-'复查' => '複查',
-'复次' => '複次',
-'复比' => '複比',
-'复决' => '複決',
-'复流' => '複流',
-'复测' => '複測',
-'复目' => '複目',
-'复眼' => '複眼',
-'复种' => '複種',
-'复线' => '複線',
-'复习' => '複習',
-'复色' => '複色',
-'复叶' => '複葉',
-'复制' => '複製',
-'复诊' => '複診',
-'复评' => '複評',
-'复词' => '複詞',
-'复试' => '複試',
-'复课' => '複課',
-'复议' => '複議',
-'复变函数' => '複變函數',
-'复赛' => '複賽',
-'复辅音' => '複輔音',
-'复述' => '複述',
-'复选' => '複選',
-'复钱' => '複錢',
-'复阅' => '複閱',
-'复杂' => '複雜',
-'复音' => '複音',
-'复韵' => '複韻',
-'褒赞' => '褒讚',
-'衬里' => '襯裡',
-'西井里' => '西井里',
-'西周钟' => '西周鐘',
-'西昆' => '西崑',
-'西岳' => '西嶽',
-'西历' => '西曆',
-'西历史' => '西歷史',
-'西湖里' => '西湖里',
-'西米谷' => '西米谷',
-'西西里' => '西西里',
-'西谷米' => '西谷米',
-'西游' => '西遊',
-'要自制' => '要自制',
-'要冲' => '要衝',
-'复信' => '覆信',
-'复核' => '覆核',
-'见于' => '見於',
-'见棱见角' => '見稜見角',
-'见素抱朴' => '見素抱樸',
-'见钟不打' => '見鐘不打',
-'规范' => '規範',
-'视于' => '視於',
-'观采' => '觀採',
-'角抵' => '角牴',
-'角落发' => '角落發',
-'角落里' => '角落裡',
-'觚棱' => '觚稜',
-'解雇' => '解僱',
-'解封后' => '解封後',
-'解铃仍须系铃人' => '解鈴仍須繫鈴人',
-'解铃还须系铃人' => '解鈴還須繫鈴人',
-'解发佯狂' => '解髮佯狂',
-'触须' => '觸鬚',
-'言云' => '言云',
-'言大而夸' => '言大而夸',
-'言里' => '言裡',
-'言辩而确' => '言辯而确',
-'订制' => '訂製',
-'计划' => '計劃',
-'计时表' => '計時錶',
-'托了' => '託了',
-'托事' => '託事',
-'托交' => '託交',
-'托人' => '託人',
-'托付' => '託付',
-'托克逊' => '託克遜',
-'托儿' => '託兒',
-'托古讽今' => '託古諷今',
-'托名' => '託名',
-'托命' => '託命',
-'托咎' => '託咎',
-'托梦' => '託夢',
-'托孤' => '託孤',
-'托庇' => '託庇',
-'托故' => '託故',
-'托疾' => '託疾',
-'托病' => '託病',
-'托管' => '託管',
-'托言' => '託言',
-'托词' => '託詞',
-'托买' => '託買',
-'托卖' => '託賣',
-'托身' => '託身',
-'托辞' => '託辭',
-'托运' => '託運',
-'托过' => '託過',
-'托里县' => '託里縣',
-'托附' => '託附',
-'许愿起经' => '許愿起經',
-'許聖杰' => '許聖杰',
-'注上' => '註上',
-'注册' => '註冊',
-'注失' => '註失',
-'注定' => '註定',
-'注明' => '註明',
-'注标' => '註標',
-'注生娘娘' => '註生娘娘',
-'注疏' => '註疏',
-'注脚' => '註腳',
-'注解' => '註解',
-'注记' => '註記',
-'注译' => '註譯',
-'注销' => '註銷',
-'注:' => '註:',
-'证谏' => '証諫',
-'评断发' => '評斷發',
-'评注' => '評註',
-'评鉴' => '評鑑',
-'词干' => '詞幹',
-'词汇' => '詞彙',
-'词余' => '詞餘',
-'询于' => '詢於',
-'试制' => '試製',
-'詩云' => '詩云',
-'诗云' => '詩云',
-'诗赞' => '詩讚',
-'诗钟' => '詩鐘',
-'诗余' => '詩餘',
-'话里有话' => '話裡有話',
-'该钟' => '該鐘',
-'详征博引' => '詳徵博引',
-'详注' => '詳註',
-'诔赞' => '誄讚',
-'夸下海口' => '誇下海口',
-'夸了' => '誇了',
-'夸人' => '誇人',
-'夸他' => '誇他',
-'夸你' => '誇你',
-'夸来夸去' => '誇來誇去',
-'夸别' => '誇別',
-'夸功' => '誇功',
-'夸胜道强' => '誇勝道強',
-'夸口' => '誇口',
-'夸嘴' => '誇嘴',
-'夸多斗靡' => '誇多鬥靡',
-'夸大' => '誇大',
-'夸她' => '誇她',
-'夸姣' => '誇姣',
-'夸官' => '誇官',
-'夸容' => '誇容',
-'夸张' => '誇張',
-'夸强说会' => '誇強說會',
-'夸得' => '誇得',
-'夸成' => '誇成',
-'夸我' => '誇我',
-'夸才' => '誇才',
-'夸毗' => '誇毗',
-'夸海口' => '誇海口',
-'夸奖' => '誇獎',
-'夸示' => '誇示',
-'夸称' => '誇稱',
-'夸耀' => '誇耀',
-'夸能' => '誇能',
-'夸能斗智' => '誇能鬥智',
-'夸诩' => '誇詡',
-'夸夸' => '誇誇',
-'夸夸其谈' => '誇誇其談',
-'夸诞' => '誇誕',
-'夸说' => '誇說',
-'夸赞' => '誇讚',
-'夸起' => '誇起',
-'夸辩' => '誇辯',
-'夸过' => '誇過',
-'夸饰' => '誇飾',
-'夸丽' => '誇麗',
-'志哀' => '誌哀',
-'志喜' => '誌喜',
-'志庆' => '誌慶',
-'志异' => '誌異',
-'认准' => '認準',
-'诱奸' => '誘姦',
-'语云' => '語云',
-'语汇' => '語彙',
-'語有云' => '語有云',
-'语有云' => '語有云',
-'语法里' => '語法裡',
-'语里' => '語裡',
-'诚征' => '誠徵',
-'诚朴' => '誠樸',
-'诬蔑' => '誣衊',
-'说不准' => '說不準',
-'谁干的' => '誰幹的',
-'课征' => '課徵',
-'课余' => '課餘',
-'调准' => '調準',
-'调制' => '調製',
-'调表' => '調錶',
-'调钟表' => '調鐘錶',
-'谈征' => '談徵',
-'请君入瓮' => '請君入甕',
-'请托' => '請託',
-'咨询' => '諮詢',
-'诸余' => '諸餘',
-'谋干' => '謀幹',
-'謝杰' => '謝杰',
-'谢杰' => '謝杰',
-'谢华后' => '謝華后',
-'谬采虚声' => '謬採虛聲',
-'谬赞' => '謬讚',
-'謷丑' => '謷醜',
-'謹愿' => '謹愿',
-'谨愿' => '謹愿',
-'哗噪' => '譁噪',
-'哗嚣' => '譁囂',
-'哗然' => '譁然',
-'哗众' => '譁眾',
-'哗笑' => '譁笑',
-'哗变' => '譁變',
-'噪诈' => '譟詐',
-'警世钟' => '警世鐘',
-'警报钟' => '警報鐘',
-'警示钟' => '警示鐘',
-'警钟' => '警鐘',
-'译制' => '譯製',
-'译注' => '譯註',
-'护发' => '護髮',
-'变征' => '變徵',
-'变丑' => '變醜',
-'仇隙' => '讎隙',
-'赞一个' => '讚一個',
-'赞不绝口' => '讚不絕口',
-'赞佩' => '讚佩',
-'赞呗' => '讚唄',
-'赞叹' => '讚嘆',
-'赞扬' => '讚揚',
-'赞乐' => '讚樂',
-'赞歌' => '讚歌',
-'赞美' => '讚美',
-'赞羡' => '讚羨',
-'赞许' => '讚許',
-'赞词' => '讚詞',
-'赞誉' => '讚譽',
-'赞赏' => '讚賞',
-'赞辞' => '讚辭',
-'赞颂' => '讚頌',
-'谷子敬' => '谷子敬',
-'豆干' => '豆乾',
-'豆腐干' => '豆腐乾',
-'竖起脊梁' => '豎起脊梁',
-'丰度' => '豐度',
-'丰滨' => '豐濱',
-'丰滨乡' => '豐濱鄉',
-'丰台' => '豐臺',
-'豔后' => '豔后',
-'象征' => '象徵',
-'贪欲' => '貪慾',
-'贵价' => '貴价',
-'貴子里' => '貴子里',
-'贵干' => '貴幹',
-'贵征' => '貴徵',
-'买凶' => '買兇',
-'买断发' => '買斷發',
-'費米面' => '費米面',
-'费米面' => '費米面',
-'贻范' => '貽範',
-'賈后' => '賈后',
-'贾后' => '賈后',
-'赈饥' => '賑饑',
-'赏赞' => '賞讚',
-'賢后' => '賢后',
-'贤后' => '賢后',
-'卖断发' => '賣斷發',
-'賦范' => '賦范',
-'赋范' => '賦范',
-'质数里' => '質數裡',
-'质朴' => '質樸',
-'赌后' => '賭后',
-'赌台' => '賭檯',
-'赌斗' => '賭鬥',
-'购并' => '購併',
-'购买欲' => '購買慾',
-'赢余' => '贏餘',
-'赤术' => '赤朮',
-'赤绳系足' => '赤繩繫足',
-'走回路' => '走回路',
-'起哄' => '起鬨',
-'超级杯' => '超級盃',
-'超赞' => '超讚',
-'赶制' => '趕製',
-'赶面棍' => '趕麵棍',
-'赵威后' => '趙威后',
-'赵惠后' => '趙惠后',
-'赵治勋' => '趙治勳',
-'趱干' => '趲幹',
-'足于' => '足於',
-'足球台' => '足球台',
-'跌扑' => '跌扑',
-'路图里' => '路圖裡',
-'路签' => '路籤',
-'路面' => '路面',
-'跳梁小丑' => '跳樑小丑',
-'跳荡' => '跳蕩',
-'局蹐' => '跼蹐',
-'局躅' => '跼躅',
-'踡局' => '踡跼',
-'逾闲' => '踰閑',
-'蹒局' => '蹣跼',
-'蹪于' => '蹪於',
-'蹭棱子' => '蹭稜子',
-'躁郁' => '躁鬱',
-'身于' => '身於',
-'身体发肤' => '身體髮膚',
-'躯干' => '軀幹',
-'车库里' => '車庫裡',
-'车站里' => '車站裡',
-'车里' => '車裡',
-'车里雅宾斯克' => '車里雅賓斯克',
-'轨范' => '軌範',
-'轩辟' => '軒闢',
-'较于' => '較於',
-'挽曲' => '輓曲',
-'挽歌' => '輓歌',
-'挽联' => '輓聯',
-'挽词' => '輓詞',
-'挽诗' => '輓詩',
-'挽车' => '輓車',
-'挽输' => '輓輸',
-'挽辞' => '輓辭',
-'轻于' => '輕於',
-'轻松' => '輕鬆',
-'轻松松' => '輕鬆鬆',
-'轮奸' => '輪姦',
-'轮回' => '輪迴',
-'转向往' => '轉向往',
-'转托' => '轉託',
-'转斗千里' => '轉鬥千里',
-'辛丑' => '辛丑',
-'辟谷' => '辟穀',
-'辣面' => '辣麵',
-'办公台' => '辦公檯',
-'辞汇' => '辭彙',
-'辫发' => '辮髮',
-'辩斗' => '辯鬥',
-'辰溪县' => '辰谿縣',
-'农历' => '農曆',
-'农历史' => '農歷史',
-'农民历' => '農民曆',
-'农民历史' => '農民歷史',
-'迂回' => '迂迴',
-'近日无仇' => '近日無讎',
-'返朴' => '返樸',
-'迥然回异' => '迥然迴異',
-'迫于' => '迫於',
-'回光返照' => '迴光返照',
-'回圈' => '迴圈',
-'回廊' => '迴廊',
-'回形夹' => '迴形夾',
-'回文序列' => '迴文序列',
-'回文数' => '迴文數',
-'回文构词' => '迴文構詞',
-'回文结构' => '迴文結構',
-'回文联' => '迴文聯',
-'回文诗' => '迴文詩',
-'回文锦' => '迴文錦',
-'回旋' => '迴旋',
-'回环' => '迴環',
-'回纹针' => '迴紋針',
-'回绕' => '迴繞',
-'回翔' => '迴翔',
-'回肠' => '迴腸',
-'回肠荡气' => '迴腸盪氣',
-'回荡' => '迴蕩',
-'回诵' => '迴誦',
-'回路' => '迴路',
-'回转' => '迴轉',
-'回递性' => '迴遞性',
-'回避' => '迴避',
-'回銮' => '迴鑾',
-'回响' => '迴響',
-'回风' => '迴風',
-'迷于' => '迷於',
-'迷蒙' => '迷濛',
-'追凶' => '追兇',
-'退伙' => '退夥',
-'逆钟' => '逆鐘',
-'逆钟向' => '逆鐘向',
-'逆风后' => '逆風後',
-'逋发' => '逋髮',
-'逍遥游' => '逍遙遊',
-'透辟' => '透闢',
-'这出世' => '這出世',
-'这出乎' => '這出乎',
-'这出人' => '這出人',
-'这出版' => '這出版',
-'这出现' => '這出現',
-'这出生' => '這出生',
-'这出色' => '這出色',
-'这出身' => '這出身',
-'这出道' => '這出道',
-'这只不' => '這只不',
-'这只不过' => '這只不過',
-'这只允' => '這只允',
-'这只包括' => '這只包括',
-'这只可' => '這只可',
-'这只在' => '這只在',
-'这只容' => '這只容',
-'这只应' => '這只應',
-'这只采' => '這只採',
-'这只是' => '這只是',
-'这只会' => '這只會',
-'这只比' => '這只比',
-'这只用' => '這只用',
-'这只能' => '這只能',
-'这只限' => '這只限',
-'这只需' => '這只需',
-'这只须' => '這只須',
-'这伙人' => '這夥人',
-'这里' => '這裡',
-'这钟' => '這鐘',
-'这只' => '這隻',
-'这么干' => '這麼幹',
-'这出' => '這齣',
-'通奸' => '通姦',
-'通心面' => '通心麵',
-'通于' => '通於',
-'通历' => '通曆',
-'通历史' => '通歷史',
-'通鉴' => '通鑑',
-'逞凶斗狠' => '逞兇鬥狠',
-'造钟' => '造鐘',
-'连三并四' => '連三併四',
-'连采' => '連採',
-'连发式' => '連發式',
-'连系' => '連繫',
-'周游' => '週遊',
-'进两出' => '進兩出',
-'进制' => '進制',
-'進制' => '進制',
-'逼并' => '逼併',
-'遇风后' => '遇風後',
-'游了' => '遊了',
-'游人' => '遊人',
-'游仙' => '遊仙',
-'游伴' => '遊伴',
-'游侠' => '遊俠',
-'游冶' => '遊冶',
-'游刃' => '遊刃',
-'游动' => '遊動',
-'游园' => '遊園',
-'游子' => '遊子',
-'游学' => '遊學',
-'游客' => '遊客',
-'游宦' => '遊宦',
-'游山玩水' => '遊山玩水',
-'游必有方' => '遊必有方',
-'游憩' => '遊憩',
-'游戏' => '遊戲',
-'游戏里' => '遊戲裡',
-'游手好闲' => '遊手好閒',
-'游方' => '遊方',
-'游星' => '遊星',
-'游乐' => '遊樂',
-'游标卡尺' => '遊標卡尺',
-'游历' => '遊歷',
-'游民' => '遊民',
-'游河' => '遊河',
-'游牧' => '遊牧',
-'游猎' => '遊獵',
-'游玩' => '遊玩',
-'游目骋怀' => '遊目騁懷',
-'游程' => '遊程',
-'游丝' => '遊絲',
-'游美学务' => '遊美學務',
-'游兴' => '遊興',
-'游船' => '遊船',
-'游艇' => '遊艇',
-'游荡' => '遊蕩',
-'游艺' => '遊藝',
-'游行' => '遊行',
-'游街' => '遊街',
-'游览' => '遊覽',
-'游记' => '遊記',
-'游说' => '遊說',
-'游资' => '遊資',
-'游走' => '遊走',
-'游踪' => '遊蹤',
-'游轮' => '遊輪',
-'游逛' => '遊逛',
-'游错' => '遊錯',
-'游骑兵' => '遊騎兵',
-'游魂' => '遊魂',
-'过于' => '過於',
-'过水面' => '過水麵',
-'遏制' => '遏制',
-'道范' => '道範',
-'逊于' => '遜於',
-'递回' => '遞迴',
-'远游' => '遠遊',
-'遨游' => '遨遊',
-'适于' => '適於',
-'遮丑' => '遮醜',
-'迁于' => '遷於',
-'选手表明' => '選手表明',
-'选手表决' => '選手表決',
-'选手表现' => '選手表現',
-'选手表示' => '選手表示',
-'选手表达' => '選手表達',
-'遗传钟' => '遺傳鐘',
-'遗范' => '遺範',
-'遗迹' => '遺蹟',
-'辽沈' => '遼瀋',
-'邀天之幸' => '邀天之倖',
-'还采' => '還採',
-'还冲' => '還衝',
-'邋里邋遢' => '邋裡邋遢',
-'那只不过' => '那只不過',
-'那只包括' => '那只包括',
-'那只可' => '那只可',
-'那只在' => '那只在',
-'那只怕' => '那只怕',
-'那只应' => '那只應',
-'那只是' => '那只是',
-'那只会' => '那只會',
-'那只有' => '那只有',
-'那只比' => '那只比',
-'那只用' => '那只用',
-'那只能' => '那只能',
-'那只限' => '那只限',
-'那只需' => '那只需',
-'那只须' => '那只須',
-'那卷' => '那捲',
-'那里' => '那裡',
-'那只' => '那隻',
-'邱于庭' => '邱于庭',
-'郁朴' => '郁樸',
-'郁郁菲菲' => '郁郁菲菲',
-'郁郁青青' => '郁郁青青',
-'郊游' => '郊遊',
-'郘钟' => '郘鐘',
-'部子里' => '部子里',
-'部落发' => '部落發',
-'郭后' => '郭后',
-'都市里' => '都市裡',
-'都于' => '都於',
-'乡愿' => '鄉愿',
-'鄉愿' => '鄉愿',
-'郑凯云' => '鄭凱云',
-'鄭凱云' => '鄭凱云',
-'配制饲料' => '配制飼料',
-'配图里' => '配圖裡',
-'配制' => '配製',
-'酒帘' => '酒帘',
-'酒气冲天' => '酒氣衝天',
-'酒坛' => '酒罈',
-'酒肴' => '酒肴',
-'酒曲' => '酒麴',
-'酒麹' => '酒麴',
-'酥松' => '酥鬆',
-'酸姜' => '酸薑',
-'腌制' => '醃製',
-'醇朴' => '醇樸',
-'醉于' => '醉於',
-'醋坛' => '醋罈',
-'丑丫头' => '醜丫頭',
-'丑事' => '醜事',
-'丑人' => '醜人',
-'丑侪' => '醜儕',
-'丑八怪' => '醜八怪',
-'丑剌剌' => '醜剌剌',
-'丑剧' => '醜劇',
-'丑化' => '醜化',
-'丑史' => '醜史',
-'丑名' => '醜名',
-'丑吒' => '醜吒',
-'丑地' => '醜地',
-'丑夷' => '醜夷',
-'丑女' => '醜女',
-'丑女效颦' => '醜女效顰',
-'丑奴儿' => '醜奴兒',
-'丑妇' => '醜婦',
-'丑媳' => '醜媳',
-'丑媳妇' => '醜媳婦',
-'丑小鸭' => '醜小鴨',
-'丑巴怪' => '醜巴怪',
-'丑徒' => '醜徒',
-'丑恶' => '醜惡',
-'丑态' => '醜態',
-'丑毙了' => '醜斃了',
-'丑于' => '醜於',
-'丑末' => '醜末',
-'丑样' => '醜樣',
-'丑死' => '醜死',
-'丑比' => '醜比',
-'丑沮' => '醜沮',
-'丑男' => '醜男',
-'丑闻' => '醜聞',
-'丑声' => '醜聲',
-'丑声远播' => '醜聲遠播',
-'丑脸' => '醜臉',
-'丑虏' => '醜虜',
-'丑行' => '醜行',
-'丑言' => '醜言',
-'丑诋' => '醜詆',
-'丑话' => '醜話',
-'丑语' => '醜語',
-'丑贼生' => '醜賊生',
-'丑辞' => '醜辭',
-'丑辱' => '醜辱',
-'丑逆' => '醜逆',
-'丑丑' => '醜醜',
-'丑陋' => '醜陋',
-'丑杂' => '醜雜',
-'丑头怪脸' => '醜頭怪臉',
-'丑类' => '醜類',
-'酿制' => '釀製',
-'衅钟' => '釁鐘',
-'采石之役' => '采石之役',
-'采石之战' => '采石之戰',
-'采石之戰' => '采石之戰',
-'采石矶' => '采石磯',
-'采石磯' => '采石磯',
-'里海大学' => '里海大學',
-'里海大學' => '里海大學',
-'里海崖' => '里海崖',
-'里海茨' => '里海茨',
-'里铺' => '里舖',
-'重回' => '重回',
-'重折' => '重摺',
-'重于' => '重於',
-'重罗面' => '重羅麵',
-'重制' => '重製',
-'重复' => '重複',
-'重托' => '重託',
-'重游' => '重遊',
-'野姜' => '野薑',
-'野游' => '野遊',
-'量不准' => '量不準',
-'厘改' => '釐改',
-'厘整' => '釐整',
-'厘正' => '釐正',
-'厘毫' => '釐毫',
-'厘清' => '釐清',
-'厘订' => '釐訂',
-'厘革' => '釐革',
-'金仆姑' => '金僕姑',
-'金城里' => '金城里',
-'金范' => '金範',
-'金圣叹' => '金聖歎',
-'金表情' => '金表情',
-'金表态' => '金表態',
-'金表扬' => '金表揚',
-'金表明' => '金表明',
-'金表演' => '金表演',
-'金表现' => '金表現',
-'金表示' => '金表示',
-'金表达' => '金表達',
-'金表露' => '金表露',
-'金表面' => '金表面',
-'金装玉里' => '金裝玉裡',
-'金溪县' => '金谿縣',
-'金链' => '金鍊',
-'金钟' => '金鐘',
-'金发' => '金髮',
-'钩心斗角' => '鈎心鬥角',
-'银朱' => '銀硃',
-'银发' => '銀髮',
-'铜范' => '銅範',
-'铜制' => '銅製',
-'铜钟' => '銅鐘',
-'铯钟' => '銫鐘',
-'铝制' => '鋁製',
-'钢之炼金术师' => '鋼之鍊金術師',
-'钢梁' => '鋼樑',
-'钢制' => '鋼製',
-'录制' => '錄製',
-'锤炼' => '錘鍊',
-'钱谷' => '錢穀',
-'钱范' => '錢範',
-'锦卤' => '錦滷',
-'锦绣花园' => '錦綉花園',
-'表停' => '錶停',
-'表冠' => '錶冠',
-'表带' => '錶帶',
-'表快' => '錶快',
-'表慢' => '錶慢',
-'表板' => '錶板',
-'表王' => '錶王',
-'表盘' => '錶盤',
-'表蒙子' => '錶蒙子',
-'表转' => '錶轉',
-'表速' => '錶速',
-'表针' => '錶針',
-'炼冶' => '鍊冶',
-'炼句' => '鍊句',
-'炼字' => '鍊字',
-'炼师' => '鍊師',
-'炼度' => '鍊度',
-'炼形' => '鍊形',
-'炼气' => '鍊氣',
-'炼汞' => '鍊汞',
-'炼石' => '鍊石',
-'链表' => '鍊表',
-'炼贫' => '鍊貧',
-'炼金术' => '鍊金術',
-'锲而不舍' => '鍥而不捨',
-'镰仓' => '鎌倉',
-'镜图里' => '鏡圖裡',
-'锈病' => '鏽病',
-'锈菌' => '鏽菌',
-'锈蚀' => '鏽蝕',
-'钟上' => '鐘上',
-'钟下' => '鐘下',
-'钟不' => '鐘不',
-'钟不扣不鸣' => '鐘不扣不鳴',
-'钟不撞不鸣' => '鐘不撞不鳴',
-'钟不敲不响' => '鐘不敲不響',
-'钟不空则哑' => '鐘不空則啞',
-'钟乳洞' => '鐘乳洞',
-'钟乳石' => '鐘乳石',
-'钟停' => '鐘停',
-'钟匠' => '鐘匠',
-'钟口' => '鐘口',
-'钟在寺里' => '鐘在寺裡',
-'钟塔' => '鐘塔',
-'钟壁' => '鐘壁',
-'钟太' => '鐘太',
-'钟好' => '鐘好',
-'钟山' => '鐘山',
-'钟左右' => '鐘左右',
-'钟差' => '鐘差',
-'钟座' => '鐘座',
-'钟形' => '鐘形',
-'钟形虫' => '鐘形蟲',
-'钟律' => '鐘律',
-'钟快' => '鐘快',
-'钟慢' => '鐘慢',
-'钟摆' => '鐘擺',
-'钟敲' => '鐘敲',
-'钟有' => '鐘有',
-'钟楼' => '鐘樓',
-'钟模' => '鐘模',
-'钟没' => '鐘沒',
-'钟漏' => '鐘漏',
-'钟王' => '鐘王',
-'钟琴' => '鐘琴',
-'钟发音' => '鐘發音',
-'钟的' => '鐘的',
-'钟盘' => '鐘盤',
-'钟相' => '鐘相',
-'钟磬' => '鐘磬',
-'钟纽' => '鐘紐',
-'钟罩' => '鐘罩',
-'钟声' => '鐘聲',
-'钟腰' => '鐘腰',
-'钟花' => '鐘花',
-'钟螺' => '鐘螺',
-'钟行' => '鐘行',
-'钟表面' => '鐘表面',
-'钟被' => '鐘被',
-'钟调' => '鐘調',
-'钟身' => '鐘身',
-'钟速' => '鐘速',
-'钟表' => '鐘錶',
-'钟表停' => '鐘錶停',
-'钟表快' => '鐘錶快',
-'钟表慢' => '鐘錶慢',
-'钟表王' => '鐘錶王',
-'钟表盘' => '鐘錶盤',
-'钟表速' => '鐘錶速',
-'钟关' => '鐘關',
-'钟陈列' => '鐘陳列',
-'钟面' => '鐘面',
-'钟响' => '鐘響',
-'钟顶' => '鐘頂',
-'钟头' => '鐘頭',
-'钟体' => '鐘體',
-'钟鸣' => '鐘鳴',
-'钟点' => '鐘點',
-'钟鼎' => '鐘鼎',
-'钟鼓' => '鐘鼓',
-'铁锈' => '鐵鏽',
-'铁钟' => '鐵鐘',
-'铸钟' => '鑄鐘',
-'鉴别' => '鑑別',
-'鉴古' => '鑑古',
-'鉴定' => '鑑定',
-'鉴察' => '鑑察',
-'鉴往知来' => '鑑往知來',
-'鉴戒' => '鑑戒',
-'鉴湖' => '鑑湖',
-'鉴藏' => '鑑藏',
-'鉴谅' => '鑑諒',
-'鉴证' => '鑑證',
-'鉴识' => '鑑識',
-'鉴赏' => '鑑賞',
-'鉴于' => '鑒於',
-'长几' => '長几',
-'长于' => '長於',
-'长历' => '長曆',
-'长历史' => '長歷史',
-'长发公主' => '長髮公主',
-'长发妹' => '長髮妹',
-'长发姑娘' => '長髮姑娘',
-'长胡' => '長鬍',
-'门帘' => '門帘',
-'门吊儿' => '門弔兒',
-'门里' => '門裡',
-'闫怀礼' => '閆懷禮',
-'開山辟谷' => '開山辟谷',
-'开山辟谷' => '開山闢谷',
-'开吊' => '開弔',
-'开征' => '開徵',
-'开采' => '開採',
-'开发' => '開發',
-'开辟' => '開闢',
-'开哄' => '開鬨',
-'闲邪' => '閑邪',
-'闲情逸致' => '閒情逸緻',
-'闲荡' => '閒蕩',
-'闲游' => '閒遊',
-'间不容发' => '間不容髮',
-'间里' => '間裡',
-'闵采尔' => '閔採爾',
-'阁府' => '閤府',
-'闺范' => '閨範',
-'阃范' => '閫範',
-'闯荡' => '闖蕩',
-'闯炼' => '闖鍊',
-'关系' => '關係',
-'关弓与我确' => '關弓與我确',
-'关于' => '關於',
-'辟佛' => '闢佛',
-'辟作' => '闢作',
-'辟划' => '闢劃',
-'辟土' => '闢土',
-'辟地' => '闢地',
-'辟室' => '闢室',
-'辟建' => '闢建',
-'辟为' => '闢為',
-'辟田' => '闢田',
-'辟筑' => '闢築',
-'辟谣' => '闢謠',
-'辟辟' => '闢辟',
-'辟邪以律' => '闢邪以律',
-'防水表' => '防水錶',
-'防御' => '防禦',
-'防范' => '防範',
-'防锈' => '防鏽',
-'阻于' => '阻於',
-'阿里' => '阿里',
-'附于' => '附於',
-'附注' => '附註',
-'限制' => '限制',
-'院里' => '院裡',
-'陪吊' => '陪弔',
-'阴干' => '陰乾',
-'阴历' => '陰曆',
-'阴历史' => '陰歷史',
-'阴沟里翻船' => '陰溝裡翻船',
-'阴郁' => '陰鬱',
-'陳冲' => '陳冲',
-'陳士杰' => '陳士杰',
-'陈升' => '陳昇',
-'陈有后' => '陳有后',
-'陳有后' => '陳有后',
-'陈杰' => '陳杰',
-'陳杰' => '陳杰',
-'陈炼' => '陳鍊',
-'陆游' => '陸遊',
-'阳春面' => '陽春麵',
-'阳历' => '陽曆',
-'阳历史' => '陽歷史',
-'阳谷' => '陽穀',
-'隆准许' => '隆准許',
-'隆准' => '隆準',
-'随于' => '隨於',
-'隐占' => '隱佔',
-'隐几' => '隱几',
-'隐于' => '隱於',
-'只字' => '隻字',
-'只影' => '隻影',
-'只手遮天' => '隻手遮天',
-'只眼' => '隻眼',
-'只言片语' => '隻言片語',
-'只身' => '隻身',
-'雄斗斗' => '雄斗斗',
-'雅范' => '雅範',
-'集数里' => '集數裡',
-'集于' => '集於',
-'集里' => '集裡',
-'集游法' => '集遊法',
-'雕梁画栋' => '雕樑畫棟',
-'双折射' => '雙折射',
-'双折' => '雙摺',
-'双胜类' => '雙胜類',
-'双雕' => '雙鵰',
-'杂合面儿' => '雜合麵兒',
-'杂志' => '雜誌',
-'杂面' => '雜麵',
-'鸡吵鹅斗' => '雞吵鵝鬥',
-'鸡奸' => '雞姦',
-'鸡争鹅斗' => '雞爭鵝鬥',
-'鸡丝' => '雞絲',
-'鸡丝面' => '雞絲麵',
-'鸡腿面' => '雞腿麵',
-'鸡蛋里挑骨头' => '雞蛋裡挑骨頭',
-'鸡只' => '雞隻',
-'离于' => '離於',
-'难舍' => '難捨',
-'难于' => '難於',
-'雨蒙蒙' => '雨濛濛',
-'雪窗萤几' => '雪窗螢几',
-'雪里' => '雪裡',
-'雪里红' => '雪裡紅',
-'雪里蕻' => '雪裡蕻',
-'云吞' => '雲吞',
-'云笈七签' => '雲笈七籤',
-'云里雾里' => '雲裡霧裡',
-'云游' => '雲遊',
-'云须' => '雲鬚',
-'零个' => '零個',
-'零周后' => '零周後',
-'零天后' => '零天後',
-'零年' => '零年',
-'零只' => '零隻',
-'零余' => '零餘',
-'电子表格' => '電子表格',
-'电子制表' => '電子製表',
-'电子钟' => '電子鐘',
-'电子钟表' => '電子鐘錶',
-'电影后' => '電影後',
-'电影里' => '電影裡',
-'电梯里' => '電梯裡',
-'电波钟' => '電波鐘',
-'电码表' => '電碼表',
-'电冲' => '電衝',
-'电视台风' => '電視台風',
-'电视里' => '電視裡',
-'电表' => '電錶',
-'电钟' => '電鐘',
-'震栗' => '震慄',
-'霉气冲天' => '霉氣衝天',
-'沾化' => '霑化',
-'沾益' => '霑益',
-'雾里' => '霧裡',
-'露丑' => '露醜',
-'霁范' => '霽範',
-'灵昆' => '靈崑',
-'青山一发' => '青山一髮',
-'青霉' => '青黴',
-'非常准' => '非常準',
-'面包住' => '面包住',
-'面包含' => '面包含',
-'面包围' => '面包圍',
-'面包容' => '面包容',
-'面包庇' => '面包庇',
-'面包厢' => '面包廂',
-'面包抄' => '面包抄',
-'面包括' => '面包括',
-'面包揽' => '面包攬',
-'面包涵' => '面包涵',
-'面包管' => '面包管',
-'面包扎' => '面包紮',
-'面包罗' => '面包羅',
-'面包着' => '面包著',
-'面包藏' => '面包藏',
-'面包装' => '面包裝',
-'面包裹' => '面包裹',
-'面包起' => '面包起',
-'面包办' => '面包辦',
-'面店铺' => '面店鋪',
-'面条目' => '面條目',
-'面條目' => '面條目',
-'面粉碎' => '面粉碎',
-'面粉红' => '面粉紅',
-'面食饭' => '面食飯',
-'鞋里' => '鞋裡',
-'鞣制' => '鞣製',
-'秋千' => '鞦韆',
-'鞭辟入里' => '鞭辟入裡',
-'韦席' => '韋蓆',
-'韩国制' => '韓國製',
-'韩制' => '韓製',
-'音不准' => '音不準',
-'音准' => '音準',
-'音声如钟' => '音聲如鐘',
-'韶山冲' => '韶山沖',
-'响钟' => '響鐘',
-'頁面' => '頁面',
-'页面' => '頁面',
-'顶凶' => '頂兇',
-'頂多' => '頂多',
-'顶多' => '頂多',
-'项链' => '項鍊',
-'顺于' => '順於',
-'顺钟向' => '順鐘向',
-'顺风后' => '順風後',
-'须根据' => '須根據',
-'颂系' => '頌繫',
-'颂赞' => '頌讚',
-'预报不准' => '預報不準',
-'预制' => '預製',
-'领袖欲' => '領袖慾',
-'头里' => '頭裡',
-'头长发' => '頭長髮',
-'头发' => '頭髮',
-'颊须' => '頰鬚',
-'额征' => '額徵',
-'额我略历' => '額我略曆',
-'额我略历史' => '額我略歷史',
-'颜范' => '顏範',
-'颠干倒坤' => '顛乾倒坤',
-'顛顛仆仆' => '顛顛仆仆',
-'颠颠仆仆' => '顛顛仆仆',
-'颤栗' => '顫慄',
-'显示表明' => '顯示表明',
-'显示表格' => '顯示表格',
-'显示表现' => '顯示表現',
-'显示表示' => '顯示表示',
-'显示表达' => '顯示表達',
-'显示表面' => '顯示表面',
-'显示表头' => '顯示表頭',
-'显示表' => '顯示錶',
-'显示钟' => '顯示鐘',
-'显示钟表' => '顯示鐘錶',
-'风干' => '風乾',
-'风后' => '風后',
-'风土志' => '風土誌',
-'风后,' => '風後,',
-'风卷残云' => '風捲殘雲',
-'风物志' => '風物誌',
-'风范' => '風範',
-'风里' => '風裡',
-'风起云涌' => '風起雲湧',
-'風采' => '風采',
-'风采' => '風采',
-'风刮' => '風颳',
-'台风' => '颱風',
-'台风后' => '颱風後',
-'刮了' => '颳了',
-'刮倒' => '颳倒',
-'刮去' => '颳去',
-'刮大风' => '颳大風',
-'刮得' => '颳得',
-'刮走' => '颳走',
-'刮起' => '颳起',
-'刮雪' => '颳雪',
-'刮风' => '颳風',
-'刮风后' => '颳風後',
-'飘荡' => '飄蕩',
-'飘游' => '飄遊',
-'飘飘荡荡' => '飄飄蕩蕩',
-'飘发自由女神' => '飄髮自由女神',
-'飞扎' => '飛紮',
-'飞刍挽粟' => '飛芻輓粟',
-'飞行钟' => '飛行鐘',
-'食欲' => '食慾',
-'食欲不振' => '食欲不振',
-'食面' => '食麵',
-'饭后钟' => '飯後鐘',
-'饭团' => '飯糰',
-'饼干' => '餅乾',
-'养脏' => '養臟',
-'餐台' => '餐檯',
-'馂余' => '餕餘',
-'余0' => '餘0',
-'余1' => '餘1',
-'余2' => '餘2',
-'余3' => '餘3',
-'余4' => '餘4',
-'余5' => '餘5',
-'余6' => '餘6',
-'余7' => '餘7',
-'余8' => '餘8',
-'余9' => '餘9',
-'余〇' => '餘〇',
-'余一' => '餘一',
-'余七' => '餘七',
-'余三' => '餘三',
-'余下' => '餘下',
-'余九' => '餘九',
-'余事' => '餘事',
-'余二' => '餘二',
-'余五' => '餘五',
-'余人' => '餘人',
-'余俗' => '餘俗',
-'余倍' => '餘倍',
-'余僇' => '餘僇',
-'余光' => '餘光',
-'余八' => '餘八',
-'余六' => '餘六',
-'余刃' => '餘刃',
-'余切' => '餘切',
-'余利' => '餘利',
-'余割' => '餘割',
-'余力' => '餘力',
-'余勇' => '餘勇',
-'余十' => '餘十',
-'余味' => '餘味',
-'余喘' => '餘喘',
-'余四' => '餘四',
-'余地' => '餘地',
-'余墨' => '餘墨',
-'余外' => '餘外',
-'余妙' => '餘妙',
-'余姚' => '餘姚',
-'余威' => '餘威',
-'余子' => '餘子',
-'余存' => '餘存',
-'余孽' => '餘孽',
-'余干' => '餘干',
-'余年' => '餘年',
-'余式' => '餘式',
-'余弦' => '餘弦',
-'余思' => '餘思',
-'余悸' => '餘悸',
-'余庆' => '餘慶',
-'余数' => '餘數',
-'余明' => '餘明',
-'余映' => '餘映',
-'余暇' => '餘暇',
-'余晖' => '餘暉',
-'余杭' => '餘杭',
-'余杯' => '餘杯',
-'余桃' => '餘桃',
-'余桶' => '餘桶',
-'余业' => '餘業',
-'余款' => '餘款',
-'余欢' => '餘歡',
-'余步' => '餘步',
-'余殃' => '餘殃',
-'余毒' => '餘毒',
-'余气' => '餘氣',
-'余江' => '餘江',
-'余波' => '餘波',
-'余温' => '餘溫',
-'余泽' => '餘澤',
-'余沥' => '餘瀝',
-'余烈' => '餘烈',
-'余热' => '餘熱',
-'余烬' => '餘燼',
-'余珍' => '餘珍',
-'余生' => '餘生',
-'余留' => '餘留',
-'余众' => '餘眾',
-'余窍' => '餘竅',
-'余粮' => '餘糧',
-'余绪' => '餘緒',
-'余缺' => '餘缺',
-'余罪' => '餘罪',
-'余羡' => '餘羨',
-'余声' => '餘聲',
-'余膏' => '餘膏',
-'余兴' => '餘興',
-'余蓄' => '餘蓄',
-'余荫' => '餘蔭',
-'余裕' => '餘裕',
-'余角' => '餘角',
-'余论' => '餘論',
-'余责' => '餘責',
-'余貾' => '餘貾',
-'余辉' => '餘輝',
-'余辜' => '餘辜',
-'余部' => '餘部',
-'余酲' => '餘酲',
-'余量' => '餘量',
-'余闰' => '餘閏',
-'余闲' => '餘閒',
-'余零' => '餘零',
-'余震' => '餘震',
-'余霞' => '餘霞',
-'余音' => '餘音',
-'余韵' => '餘韻',
-'余响' => '餘響',
-'余项' => '餘項',
-'余额' => '餘額',
-'余风' => '餘風',
-'余食' => '餘食',
-'余党' => '餘黨',
-'馄饨面' => '餛飩麵',
-'馆谷' => '館穀',
-'馆里' => '館裡',
-'饥寒' => '饑寒',
-'饥民' => '饑民',
-'饥渴' => '饑渴',
-'饥溺' => '饑溺',
-'饥荒' => '饑荒',
-'饥饱' => '饑飽',
-'饥馑' => '饑饉',
-'首当其冲' => '首當其衝',
-'首发' => '首發',
-'首只' => '首隻',
-'首出电影' => '首齣電影',
-'香干' => '香乾',
-'香山庄' => '香山庄',
-'马干' => '馬乾',
-'馬占山' => '馬占山',
-'马德钟' => '馬德鐘',
-'马斯垂克期' => '馬斯垂克期',
-'馬格里布' => '馬格里布',
-'马格里布' => '馬格里布',
-'驻扎' => '駐紮',
-'骀荡' => '駘蕩',
-'腾格里' => '騰格里',
-'騰格里' => '騰格里',
-'腾涌' => '騰湧',
-'腾冲' => '騰衝',
-'惊栗' => '驚慄',
-'惊赞' => '驚讚',
-'惊钟' => '驚鐘',
-'骨干' => '骨幹',
-'骨灰坛' => '骨灰罈',
-'骨坛' => '骨罈',
-'体征' => '體徵',
-'体范' => '體範',
-'体系' => '體系',
-'体里' => '體裡',
-'高几' => '高几',
-'高后' => '高后',
-'高干扰' => '高干擾',
-'高干预' => '高干預',
-'高干' => '高幹',
-'高度自制' => '高度自制',
-'高涌泉' => '高涌泉',
-'高清愿' => '高清愿',
-'髡发' => '髡髮',
-'髭胡' => '髭鬍',
-'髭须' => '髭鬚',
-'发上指冠' => '髮上指冠',
-'发上冲冠' => '髮上沖冠',
-'发乳' => '髮乳',
-'发光可鉴' => '髮光可鑑',
-'发匪' => '髮匪',
-'发及腰' => '髮及腰',
-'发型' => '髮型',
-'发夹' => '髮夾',
-'发妻' => '髮妻',
-'发姐' => '髮姐',
-'发屋' => '髮屋',
-'发已霜白' => '髮已霜白',
-'发带' => '髮帶',
-'发廊' => '髮廊',
-'发式' => '髮式',
-'发引千钧' => '髮引千鈞',
-'发披肩' => '髮披肩',
-'发卷' => '髮捲',
-'发根' => '髮根',
-'发油' => '髮油',
-'发漂' => '髮漂',
-'发为血之本' => '髮為血之本',
-'发状' => '髮狀',
-'发癣' => '髮癬',
-'发短心长' => '髮短心長',
-'发禁' => '髮禁',
-'发笺' => '髮箋',
-'发纱' => '髮紗',
-'发结' => '髮結',
-'发丝' => '髮絲',
-'发网' => '髮網',
-'发脚' => '髮腳',
-'发肤' => '髮膚',
-'发胶' => '髮膠',
-'发菜' => '髮菜',
-'发蜡' => '髮蠟',
-'发踊冲冠' => '髮踴沖冠',
-'发辫' => '髮辮',
-'发针' => '髮針',
-'发钗' => '髮釵',
-'发长' => '髮長',
-'发际' => '髮際',
-'发雕' => '髮雕',
-'发霜' => '髮霜',
-'发饰' => '髮飾',
-'发髻' => '髮髻',
-'发鬓' => '髮鬢',
-'髯胡' => '髯鬍',
-'髼松' => '髼鬆',
-'鬅松' => '鬅鬆',
-'松一口气' => '鬆一口氣',
-'松了' => '鬆了',
-'松些' => '鬆些',
-'松元音' => '鬆元音',
-'松劲' => '鬆勁',
-'松动' => '鬆動',
-'松化' => '鬆化',
-'松口' => '鬆口',
-'松喉' => '鬆喉',
-'松土' => '鬆土',
-'松宽' => '鬆寬',
-'松弛' => '鬆弛',
-'松快' => '鬆快',
-'松懈' => '鬆懈',
-'松手' => '鬆手',
-'松掉' => '鬆掉',
-'松散' => '鬆散',
-'松柔' => '鬆柔',
-'松气' => '鬆氣',
-'松浮' => '鬆浮',
-'松绑' => '鬆綁',
-'松紧' => '鬆緊',
-'松缓' => '鬆緩',
-'松脆' => '鬆脆',
-'松脱' => '鬆脫',
-'松蛋' => '鬆蛋',
-'松起' => '鬆起',
-'松软' => '鬆軟',
-'松通' => '鬆通',
-'松开' => '鬆開',
-'松饼' => '鬆餅',
-'松松地' => '鬆鬆地',
-'鬈发' => '鬈髮',
-'胡子' => '鬍子',
-'胡梢' => '鬍梢',
-'胡渣' => '鬍渣',
-'胡髭' => '鬍髭',
-'胡髯' => '鬍髯',
-'胡须' => '鬍鬚',
-'鬒发' => '鬒髮',
-'须根' => '鬚根',
-'须毛' => '鬚毛',
-'须生' => '鬚生',
-'须眉' => '鬚眉',
-'须发' => '鬚髮',
-'须胡' => '鬚鬍',
-'须须' => '鬚鬚',
-'须鲨' => '鬚鯊',
-'须鲸' => '鬚鯨',
-'鬓发' => '鬢髮',
-'斗不过' => '鬥不過',
-'斗了' => '鬥了',
-'斗来斗去' => '鬥來鬥去',
-'斗倒' => '鬥倒',
-'斗分子' => '鬥分子',
-'斗剑' => '鬥劍',
-'斗力' => '鬥力',
-'斗劲' => '鬥勁',
-'斗勇' => '鬥勇',
-'斗胜' => '鬥勝',
-'斗口' => '鬥口',
-'斗合' => '鬥合',
-'斗嘴' => '鬥嘴',
-'斗地主' => '鬥地主',
-'斗垮' => '鬥垮',
-'斗士' => '鬥士',
-'斗富' => '鬥富',
-'斗巧' => '鬥巧',
-'斗幌子' => '鬥幌子',
-'斗弄' => '鬥弄',
-'斗引' => '鬥引',
-'斗别气' => '鬥彆氣',
-'斗彩' => '鬥彩',
-'斗心眼' => '鬥心眼',
-'斗志' => '鬥志',
-'斗闷' => '鬥悶',
-'斗成' => '鬥成',
-'斗战' => '鬥戰',
-'斗打' => '鬥打',
-'斗批改' => '鬥批改',
-'斗技' => '鬥技',
-'斗败' => '鬥敗',
-'斗文' => '鬥文',
-'斗智' => '鬥智',
-'斗暴' => '鬥暴',
-'斗武' => '鬥武',
-'斗殴' => '鬥毆',
-'斗气' => '鬥氣',
-'斗法' => '鬥法',
-'斗争' => '鬥爭',
-'斗争斗合' => '鬥爭鬥合',
-'斗牌' => '鬥牌',
-'斗牙拌齿' => '鬥牙拌齒',
-'斗牙斗齿' => '鬥牙鬥齒',
-'斗牛' => '鬥牛',
-'斗犀台' => '鬥犀臺',
-'斗犬' => '鬥犬',
-'斗狗' => '鬥狗',
-'斗狠' => '鬥狠',
-'斗兽' => '鬥獸',
-'斗叠' => '鬥疊',
-'斗百草' => '鬥百草',
-'斗眼' => '鬥眼',
-'斗私批修' => '鬥私批修',
-'斗而铸兵' => '鬥而鑄兵',
-'斗而铸锥' => '鬥而鑄錐',
-'斗脚' => '鬥腳',
-'斗舰' => '鬥艦',
-'斗茶' => '鬥茶',
-'斗草' => '鬥草',
-'斗叶儿' => '鬥葉兒',
-'斗叶子' => '鬥葉子',
-'斗蛐' => '鬥蛐',
-'斗蟋蟀' => '鬥蟋蟀',
-'斗话' => '鬥話',
-'斗艳' => '鬥豔',
-'斗起' => '鬥起',
-'斗趣' => '鬥趣',
-'斗闲气' => '鬥閒氣',
-'斗鸡' => '鬥雞',
-'斗雪红' => '鬥雪紅',
-'斗头' => '鬥頭',
-'斗风' => '鬥風',
-'斗饤' => '鬥飣',
-'斗斗' => '鬥鬥',
-'斗哄' => '鬥鬨',
-'斗鱼' => '鬥魚',
-'斗鸭' => '鬥鴨',
-'斗鹌鹑' => '鬥鵪鶉',
-'斗丽' => '鬥麗',
-'斗龙' => '鬥龍',
-'闹表' => '鬧錶',
-'闹钟' => '鬧鐘',
-'哄动' => '鬨動',
-'哄堂' => '鬨堂',
-'哄笑' => '鬨笑',
-'郁伊' => '鬱伊',
-'郁勃' => '鬱勃',
-'郁卒' => '鬱卒',
-'郁南' => '鬱南',
-'郁堙不偶' => '鬱堙不偶',
-'郁塞' => '鬱塞',
-'郁垒' => '鬱壘',
-'郁律' => '鬱律',
-'郁悒' => '鬱悒',
-'郁闷' => '鬱悶',
-'郁愤' => '鬱憤',
-'郁抑' => '鬱抑',
-'郁挹' => '鬱挹',
-'郁林' => '鬱林',
-'郁气' => '鬱氣',
-'郁江' => '鬱江',
-'郁沉沉' => '鬱沉沉',
-'郁泱' => '鬱泱',
-'郁火' => '鬱火',
-'郁热' => '鬱熱',
-'郁燠' => '鬱燠',
-'郁症' => '鬱症',
-'郁积' => '鬱積',
-'郁纡' => '鬱紆',
-'郁结' => '鬱結',
-'郁蒸' => '鬱蒸',
-'郁蓊' => '鬱蓊',
-'郁血' => '鬱血',
-'郁邑' => '鬱邑',
-'郁郁' => '鬱郁',
-'郁金' => '鬱金',
-'郁闭' => '鬱閉',
-'郁陶' => '鬱陶',
-'郁郁不平' => '鬱鬱不平',
-'郁郁不乐' => '鬱鬱不樂',
-'郁郁寡欢' => '鬱鬱寡歡',
-'郁郁而终' => '鬱鬱而終',
-'郁郁苍苍' => '鬱鬱蒼蒼',
-'郁郁葱葱' => '鬱鬱蔥蔥',
-'郁黑' => '鬱黑',
-'鬼气冲天' => '鬼氣衝天',
-'鬼谷子' => '鬼谷子',
-'魂牵梦系' => '魂牽夢繫',
-'魏征' => '魏徵',
-'魔表' => '魔錶',
-'鱼干' => '魚乾',
-'鱼松' => '魚鬆',
-'鮮于' => '鮮于',
-'鲜于' => '鮮于',
-'鲸须' => '鯨鬚',
-'鳥栖' => '鳥栖',
-'鸟栖市' => '鳥栖市',
-'凤梨干' => '鳳梨乾',
-'鸣钟' => '鳴鐘',
-'鸿范' => '鴻範',
-'鹅准' => '鵝準',
-'鹄发' => '鵠髮',
-'雕心雁爪' => '鵰心雁爪',
-'雕悍' => '鵰悍',
-'雕翎' => '鵰翎',
-'雕鹗' => '鵰鶚',
-'鹤峰县' => '鶴峯縣',
-'鹤吊' => '鶴弔',
-'鹤发' => '鶴髮',
-'鸾鉴' => '鸞鑑',
-'鹰雕' => '鹰鵰',
-'咸味' => '鹹味',
-'咸嘴淡舌' => '鹹嘴淡舌',
-'咸土' => '鹹土',
-'咸度' => '鹹度',
-'咸得' => '鹹得',
-'咸批' => '鹹批',
-'咸水' => '鹹水',
-'咸派' => '鹹派',
-'咸海' => '鹹海',
-'咸淡' => '鹹淡',
-'咸湖' => '鹹湖',
-'咸汤' => '鹹湯',
-'咸潟' => '鹹潟',
-'咸湿' => '鹹濕',
-'咸的' => '鹹的',
-'咸粥' => '鹹粥',
-'咸肉' => '鹹肉',
-'咸菜' => '鹹菜',
-'咸菜干' => '鹹菜乾',
-'咸蛋' => '鹹蛋',
-'咸猪' => '鹹豬',
-'咸类' => '鹹類',
-'咸食' => '鹹食',
-'咸鱼' => '鹹魚',
-'咸鸭蛋' => '鹹鴨蛋',
-'咸卤' => '鹹鹵',
-'咸咸' => '鹹鹹',
-'盐打怎么咸' => '鹽打怎麼鹹',
-'盐卤' => '鹽滷',
-'盐余' => '鹽餘',
-'鹿場里' => '鹿場里',
-'丽于' => '麗於',
-'麟游' => '麟遊',
-'曲酒' => '麯酒',
-'曲尘' => '麴塵',
-'曲櫱' => '麴櫱',
-'曲秀才' => '麴秀才',
-'曲车' => '麴車',
-'曲道士' => '麴道士',
-'曲钱' => '麴錢',
-'曲霉' => '麴黴',
-'麹霉' => '麴黴',
-'面人儿' => '麵人兒',
-'面包' => '麵包',
-'面坊' => '麵坊',
-'面坯儿' => '麵坯兒',
-'面塑' => '麵塑',
-'面店' => '麵店',
-'面厂' => '麵廠',
-'面摊' => '麵攤',
-'面杖' => '麵杖',
-'面条' => '麵條',
-'面汤' => '麵湯',
-'面浆' => '麵漿',
-'面疙瘩' => '麵疙瘩',
-'面皮' => '麵皮',
-'面码儿' => '麵碼兒',
-'面筋' => '麵筋',
-'面粉' => '麵粉',
-'面糊' => '麵糊',
-'面团' => '麵糰',
-'面缸' => '麵缸',
-'面茶' => '麵茶',
-'面制品' => '麵製品',
-'面食' => '麵食',
-'面饺' => '麵餃',
-'面饼' => '麵餅',
-'面馆' => '麵館',
-'面点、' => '麵點、',
-'面点师' => '麵點師',
-'麻将席' => '麻將蓆',
-'麻酱面' => '麻醬麵',
-'黄干黑瘦' => '黃乾黑瘦',
-'黄岩区' => '黃巖區',
-'黄岩县' => '黃巖縣',
-'黄历' => '黃曆',
-'黃杰' => '黃杰',
-'黄杰' => '黃杰',
-'黄历史' => '黃歷史',
-'黄白术' => '黃白術',
-'黃詩杰' => '黃詩杰',
-'黄诗杰' => '黃詩杰',
-'黄金表' => '黃金表',
-'黃鈺筑' => '黃鈺筑',
-'黄钰筑' => '黃鈺筑',
-'黄钟' => '黃鐘',
-'黄发' => '黃髮',
-'黄曲毒素' => '黃麴毒素',
-'黎克特制' => '黎克特制',
-'黎吉云' => '黎吉雲',
-'黎吉雲' => '黎吉雲',
-'黑奴吁天录' => '黑奴籲天錄',
-'黑干将' => '黑幹將',
-'黑长发' => '黑長髮',
-'黑发' => '黑髮',
-'点个赞' => '點個讚',
-'点札' => '點劄',
-'点半钟' => '點半鐘',
-'点多钟' => '點多鐘',
-'点里' => '點裡',
-'点赞' => '點讚',
-'点里程' => '點里程',
-'点钟' => '點鐘',
-'霉毒' => '黴毒',
-'霉素' => '黴素',
-'霉菌' => '黴菌',
-'霉黑' => '黴黑',
-'霉黧' => '黴黧',
-'鼓里' => '鼓裡',
-'鼓噪' => '鼓譟',
-'冬冬鼓' => '鼕鼕鼓',
-'咚咚鼓' => '鼕鼕鼓',
-'鼠曲草' => '鼠麴草',
-'鼻梁儿' => '鼻梁兒',
-'鼻梁' => '鼻樑',
-'鼻准' => '鼻準',
-'齐王舍牛' => '齊王捨牛',
-'齿危发秀' => '齒危髮秀',
-'齿落发白' => '齒落髮白',
-'齿发' => '齒髮',
-'龙岩' => '龍巖',
-'龙卷' => '龍捲',
-'龙眼干' => '龍眼乾',
-'龙须' => '龍鬚',
-'龙须面' => '龍鬚麵',
-'龙斗虎伤' => '龍鬥虎傷',
-'龜山庄' => '龜山庄',
-'龟鉴' => '龜鑑',
-',并力' => ',並力',
-',并力攻' => ',并力攻',
-',并力討' => ',并力討',
-',并力讨' => ',并力討',
-',个中' => ',箇中',
-);
-
-$zh2Hans = array(
-'㑯' => '㑔',
-'㑳' => '㑇',
-'㑶' => '㐹',
-'㒓' => '𠉂',
-'㒺' => '罔',
-'㓂' => '寇',
-'㓨' => '刾',
-'㕁' => '却',
-'㕑' => '厨',
-'㕘' => '参',
-'㕥' => '以',
-'㗲' => '𠵾',
-'㘚' => '㘎',
-'㘭' => '坳',
-'㜄' => '㚯',
-'㜏' => '㛣',
-'㜢' => '𡞱',
-'㜷' => '𡝠',
-'㝛' => '宿',
-'㝠' => '冥',
-'㞞' => '𪨊',
-'㠀' => '岛',
-'㠏' => '㟆',
-'㠯' => '以',
-'㠶' => '帆',
-'㡌' => '帽',
-'㢘' => '廉',
-'㢝' => '𢋈',
-'㤙' => '恩',
-'㥦' => '惬',
-'㥮' => '㤘',
-'㦎' => '𢛯',
-'㨗' => '捷',
-'㨪' => '晃',
-'㨿' => '据',
-'㩗' => '携',
-'㩜' => '㨫',
-'㩦' => '携',
-'㩳' => '㧐',
-'㪚' => '散',
-'㪟' => '敦',
-'㬉' => '暖',
-'㬪' => '叠',
-'㯭' => '橹',
-'㱃' => '饮',
-'㳒' => '法',
-'㴱' => '深',
-'㷿' => '𤈷',
-'㺏' => '𤠋',
-'㼝' => '碗',
-'㽞' => '留',
-'㿜' => '瘪',
-'㿧' => '𤽯',
-'䀹' => '𥅴',
-'䁪' => '𥇢',
-'䁻' => '䀥',
-'䈰' => '筲',
-'䉙' => '𥬀',
-'䉬' => '𫂈',
-'䉲' => '𥮜',
-'䊀' => '糊',
-'䊭' => '𥺅',
-'䊷' => '䌶',
-'䋙' => '䌺',
-'䋚' => '䌻',
-'䋹' => '䌿',
-'䋻' => '䌾',
-'䋿' => '𦈓',
-'䌈' => '𦈖',
-'䌋' => '𦈘',
-'䌖' => '𦈜',
-'䌝' => '𦈟',
-'䌟' => '𦈞',
-'䌥' => '𦈠',
-'䌰' => '𦈙',
-'䎱' => '䎬',
-'䕳' => '𦰴',
-'䗬' => '蜂',
-'䗿' => '𧉞',
-'䘏' => '恤',
-'䘑' => '脉',
-'䘚' => '卒',
-'䙡' => '䙌',
-'䛐' => '词',
-'䛡' => '话',
-'䜀' => '䜧',
-'䝔' => '獾',
-'䝻' => '𧹕',
-'䝼' => '䞍',
-'䞈' => '𧹑',
-'䠀' => '蹚',
-'䠶' => '射',
-'䢨' => '𨑹',
-'䥇' => '䦂',
-'䥥' => '镰',
-'䥩' => '𨱖',
-'䥱' => '䥾',
-'䦘' => '𨸄',
-'䦛' => '䦶',
-'䦟' => '䦷',
-'䦳' => '𨷿',
-'䧢' => '𨸟',
-'䪏' => '𩏼',
-'䪗' => '𩐀',
-'䪘' => '𩏿',
-'䫴' => '𩖗',
-'䬃' => '飒',
-'䬘' => '𩙮',
-'䬝' => '𩙯',
-'䬞' => '𩙧',
-'䭀' => '𩠇',
-'䭃' => '𩠈',
-'䭾' => '驮',
-'䭿' => '𩧭',
-'䮝' => '𩧰',
-'䮞' => '𩨁',
-'䮠' => '𩧿',
-'䮫' => '𩨇',
-'䮳' => '𩨏',
-'䮾' => '𩧪',
-'䯀' => '䯅',
-'䰟' => '魂',
-'䰾' => '鲃',
-'䱙' => '𩾈',
-'䱬' => '𩾊',
-'䱰' => '𩾋',
-'䱷' => '䲣',
-'䱽' => '䲝',
-'䲁' => '鳚',
-'䲖' => '𩾂',
-'䲘' => '鳤',
-'䲰' => '𪉂',
-'䳘' => '鹅',
-'䴉' => '鹮',
-'䴬' => '𪎈',
-'䴴' => '𪎋',
-'䶊' => '衄',
-'丟' => '丢',
-'丣' => '卯',
-'並' => '并',
-'乗' => '乘',
-'乹' => '干',
-'乾' => '干',
-'亁' => '干',
-'亂' => '乱',
-'亙' => '亘',
-'亝' => '斋',
-'亞' => '亚',
-'亱' => '夜',
-'亷' => '廉',
-'亾' => '亡',
-'佇' => '伫',
-'佈' => '布',
-'佔' => '占',
-'併' => '并',
-'來' => '来',
-'侖' => '仑',
-'侶' => '侣',
-'俁' => '俣',
-'係' => '系',
-'俔' => '伣',
-'俠' => '侠',
-'俥' => '伡',
-'俻' => '备',
-'倀' => '伥',
-'倆' => '俩',
-'倈' => '俫',
-'倉' => '仓',
-'個' => '个',
-'倐' => '倏',
-'們' => '们',
-'倖' => '幸',
-'倣' => '仿',
-'倫' => '伦',
-'倲' => '㑈',
-'倸' => '睬',
-'偉' => '伟',
-'偑' => '㐽',
-'側' => '侧',
-'偵' => '侦',
-'偽' => '伪',
-'傌' => '㐷',
-'傑' => '杰',
-'傖' => '伧',
-'傘' => '伞',
-'備' => '备',
-'傚' => '效',
-'傢' => '家',
-'傭' => '佣',
-'傯' => '偬',
-'傳' => '传',
-'傴' => '伛',
-'債' => '债',
-'傷' => '伤',
-'傾' => '倾',
-'僂' => '偻',
-'僅' => '仅',
-'僉' => '佥',
-'僊' => '仙',
-'働' => '动',
-'僑' => '侨',
-'僕' => '仆',
-'僞' => '伪',
-'僥' => '侥',
-'僨' => '偾',
-'僱' => '雇',
-'價' => '价',
-'儀' => '仪',
-'儂' => '侬',
-'億' => '亿',
-'儈' => '侩',
-'儉' => '俭',
-'儌' => '侥',
-'儐' => '傧',
-'儔' => '俦',
-'儕' => '侪',
-'儘' => '尽',
-'償' => '偿',
-'儣' => '𠆲',
-'優' => '优',
-'儲' => '储',
-'儷' => '俪',
-'儸' => '㑩',
-'儺' => '傩',
-'儻' => '傥',
-'儼' => '俨',
-'兇' => '凶',
-'兌' => '兑',
-'兎' => '兔',
-'兒' => '儿',
-'兗' => '兖',
-'兠' => '兜',
-'內' => '内',
-'兩' => '两',
-'冄' => '冉',
-'冊' => '册',
-'冐' => '冒',
-'冑' => '胄',
-'冪' => '幂',
-'冺' => '泯',
-'凈' => '净',
-'凍' => '冻',
-'凙' => '𪞝',
-'凜' => '凛',
-'凢' => '凡',
-'凱' => '凯',
-'凴' => '凭',
-'別' => '别',
-'刦' => '劫',
-'刧' => '劫',
-'刪' => '删',
-'刼' => '劫',
-'剄' => '刭',
-'則' => '则',
-'剉' => '锉',
-'剋' => '克',
-'剎' => '刹',
-'剏' => '创',
-'剗' => '刬',
-'剙' => '创',
-'剛' => '刚',
-'剝' => '剥',
-'剮' => '剐',
-'剳' => '札',
-'剴' => '剀',
-'創' => '创',
-'剷' => '铲',
-'剹' => '戮',
-'剾' => '𠛅',
-'劃' => '划',
-'劄' => '札',
-'劇' => '剧',
-'劉' => '刘',
-'劊' => '刽',
-'劌' => '刿',
-'劍' => '剑',
-'劏' => '㓥',
-'劑' => '剂',
-'劒' => '剑',
-'劚' => '㔉',
-'効' => '效',
-'勁' => '劲',
-'勅' => '敕',
-'勌' => '倦',
-'勑' => '敕',
-'動' => '动',
-'務' => '务',
-'勛' => '勋',
-'勝' => '胜',
-'勞' => '劳',
-'勢' => '势',
-'勦' => '剿',
-'勩' => '勚',
-'勱' => '劢',
-'勳' => '勋',
-'勵' => '励',
-'勸' => '劝',
-'勻' => '匀',
-'匟' => '炕',
-'匭' => '匦',
-'匯' => '汇',
-'匱' => '匮',
-'匲' => '奁',
-'匳' => '奁',
-'區' => '区',
-'協' => '协',
-'卹' => '恤',
-'卻' => '却',
-'卽' => '即',
-'厀' => '膝',
-'厙' => '厍',
-'厠' => '厕',
-'厤' => '历',
-'厭' => '厌',
-'厰' => '厂',
-'厲' => '厉',
-'厴' => '厣',
-'參' => '参',
-'叄' => '叁',
-'叢' => '丛',
-'吚' => '咿',
-'吳' => '吴',
-'吶' => '呐',
-'呂' => '吕',
-'呌' => '叫',
-'呪' => '咒',
-'咊' => '和',
-'咼' => '呙',
-'員' => '员',
-'哯' => '𠯟',
-'哶' => '咩',
-'唄' => '呗',
-'唕' => '唣',
-'唘' => '启',
-'唚' => '吣',
-'唸' => '念',
-'啎' => '忤',
-'問' => '问',
-'啑' => '喋',
-'啓' => '启',
-'啗' => '啖',
-'啞' => '哑',
-'啟' => '启',
-'啢' => '唡',
-'啣' => '衔',
-'喎' => '㖞',
-'喚' => '唤',
-'喪' => '丧',
-'喫' => '吃',
-'喬' => '乔',
-'單' => '单',
-'喲' => '哟',
-'嗁' => '啼',
-'嗆' => '呛',
-'嗇' => '啬',
-'嗊' => '唝',
-'嗎' => '吗',
-'嗚' => '呜',
-'嗩' => '唢',
-'嗶' => '哔',
-'嗹' => '𪡏',
-'嘅' => '慨',
-'嘆' => '叹',
-'嘍' => '喽',
-'嘑' => '呼',
-'嘓' => '啯',
-'嘔' => '呕',
-'嘖' => '啧',
-'嘗' => '尝',
-'嘜' => '唛',
-'嘠' => '嘎',
-'嘩' => '哗',
-'嘮' => '唠',
-'嘯' => '啸',
-'嘰' => '叽',
-'嘵' => '哓',
-'嘷' => '嗥',
-'嘸' => '呒',
-'嘽' => '啴',
-'噅' => '𠯠',
-'噉' => '啖',
-'噓' => '嘘',
-'噚' => '㖊',
-'噝' => '咝',
-'噠' => '哒',
-'噥' => '哝',
-'噦' => '哕',
-'噯' => '嗳',
-'噲' => '哙',
-'噴' => '喷',
-'噸' => '吨',
-'噹' => '当',
-'嚀' => '咛',
-'嚇' => '吓',
-'嚌' => '哜',
-'嚐' => '尝',
-'嚕' => '噜',
-'嚙' => '啮',
-'嚥' => '咽',
-'嚦' => '呖',
-'嚨' => '咙',
-'嚮' => '向',
-'嚲' => '亸',
-'嚳' => '喾',
-'嚴' => '严',
-'嚶' => '嘤',
-'囀' => '啭',
-'囁' => '嗫',
-'囂' => '嚣',
-'囅' => '冁',
-'囈' => '呓',
-'囉' => '啰',
-'囌' => '苏',
-'囑' => '嘱',
-'囓' => '啮',
-'囙' => '因',
-'囪' => '囱',
-'圅' => '函',
-'圇' => '囵',
-'國' => '国',
-'圍' => '围',
-'園' => '园',
-'圓' => '圆',
-'圖' => '图',
-'團' => '团',
-'圞' => '𪢮',
-'坿' => '附',
-'垜' => '垛',
-'垵' => '埯',
-'埡' => '垭',
-'埰' => '采',
-'執' => '执',
-'堅' => '坚',
-'堊' => '垩',
-'堝' => '埚',
-'堯' => '尧',
-'報' => '报',
-'場' => '场',
-'塊' => '块',
-'塋' => '茔',
-'塏' => '垲',
-'塒' => '埘',
-'塗' => '涂',
-'塟' => '葬',
-'塢' => '坞',
-'塤' => '埙',
-'塲' => '场',
-'塵' => '尘',
-'塹' => '堑',
-'墊' => '垫',
-'墖' => '塔',
-'墜' => '坠',
-'墮' => '堕',
-'墰' => '坛',
-'墳' => '坟',
-'墻' => '墙',
-'墾' => '垦',
-'壇' => '坛',
-'壈' => '𡒄',
-'壋' => '垱',
-'壎' => '埙',
-'壓' => '压',
-'壘' => '垒',
-'壙' => '圹',
-'壚' => '垆',
-'壜' => '坛',
-'壞' => '坏',
-'壟' => '垄',
-'壠' => '垅',
-'壢' => '坜',
-'壩' => '坝',
-'壯' => '壮',
-'壺' => '壶',
-'壻' => '婿',
-'壼' => '壸',
-'壽' => '寿',
-'夘' => '卯',
-'夠' => '够',
-'夢' => '梦',
-'夥' => '伙',
-'夾' => '夹',
-'奐' => '奂',
-'奧' => '奥',
-'奩' => '奁',
-'奪' => '夺',
-'奬' => '奖',
-'奮' => '奋',
-'奼' => '姹',
-'妝' => '妆',
-'妬' => '妒',
-'妳' => '你',
-'妷' => '侄',
-'姉' => '姊',
-'姍' => '姗',
-'姙' => '妊',
-'姦' => '奸',
-'姪' => '侄',
-'姸' => '妍',
-'娛' => '娱',
-'婁' => '娄',
-'婣' => '姻',
-'婦' => '妇',
-'婬' => '淫',
-'婭' => '娅',
-'媍' => '妇',
-'媧' => '娲',
-'媯' => '妫',
-'媰' => '㛀',
-'媼' => '媪',
-'媽' => '妈',
-'媿' => '愧',
-'嫋' => '袅',
-'嫗' => '妪',
-'嫰' => '嫩',
-'嫵' => '妩',
-'嫺' => '娴',
-'嫻' => '娴',
-'嫿' => '婳',
-'嬀' => '妫',
-'嬃' => '媭',
-'嬈' => '娆',
-'嬋' => '婵',
-'嬌' => '娇',
-'嬙' => '嫱',
-'嬝' => '袅',
-'嬡' => '嫒',
-'嬤' => '嬷',
-'嬪' => '嫔',
-'嬭' => '奶',
-'嬰' => '婴',
-'嬸' => '婶',
-'嬾' => '懒',
-'孃' => '娘',
-'孋' => '㛤',
-'孌' => '娈',
-'孫' => '孙',
-'學' => '学',
-'孼' => '孽',
-'孿' => '孪',
-'宂' => '冗',
-'宮' => '宫',
-'寀' => '采',
-'寃' => '冤',
-'寑' => '寝',
-'寢' => '寝',
-'實' => '实',
-'寧' => '宁',
-'審' => '审',
-'寫' => '写',
-'寬' => '宽',
-'寳' => '宝',
-'寵' => '宠',
-'寶' => '宝',
-'尅' => '克',
-'將' => '将',
-'專' => '专',
-'尋' => '寻',
-'對' => '对',
-'導' => '导',
-'尒' => '尔',
-'尙' => '尚',
-'尟' => '鲜',
-'尠' => '鲜',
-'尷' => '尴',
-'屆' => '届',
-'屍' => '尸',
-'屓' => '屃',
-'屛' => '屏',
-'屜' => '屉',
-'屢' => '屡',
-'層' => '层',
-'屨' => '屦',
-'屩' => '𪨗',
-'屬' => '属',
-'屭' => '屃',
-'岅' => '坂',
-'岡' => '冈',
-'峝' => '峒',
-'峴' => '岘',
-'島' => '岛',
-'峽' => '峡',
-'崍' => '崃',
-'崗' => '岗',
-'崢' => '峥',
-'崬' => '岽',
-'嵐' => '岚',
-'嵗' => '岁',
-'嵼' => '𡶴',
-'嶁' => '嵝',
-'嶃' => '崭',
-'嶄' => '崭',
-'嶇' => '岖',
-'嶔' => '嵚',
-'嶗' => '崂',
-'嶠' => '峤',
-'嶢' => '峣',
-'嶧' => '峄',
-'嶨' => '峃',
-'嶮' => '崄',
-'嶸' => '嵘',
-'嶺' => '岭',
-'嶼' => '屿',
-'嶽' => '岳',
-'巋' => '岿',
-'巒' => '峦',
-'巔' => '巅',
-'巖' => '岩',
-'巗' => '岩',
-'巰' => '巯',
-'巵' => '卮',
-'帀' => '匝',
-'帋' => '纸',
-'帥' => '帅',
-'師' => '师',
-'帬' => '裙',
-'帳' => '帐',
-'帶' => '带',
-'幀' => '帧',
-'幃' => '帏',
-'幇' => '帮',
-'幑' => '徽',
-'幗' => '帼',
-'幘' => '帻',
-'幙' => '幕',
-'幚' => '帮',
-'幟' => '帜',
-'幣' => '币',
-'幫' => '帮',
-'幬' => '帱',
-'幹' => '干',
-'幾' => '几',
-'庫' => '库',
-'庻' => '庶',
-'庽' => '寓',
-'廁' => '厕',
-'廂' => '厢',
-'廄' => '厩',
-'廈' => '厦',
-'廎' => '庼',
-'廐' => '厩',
-'廕' => '荫',
-'廚' => '厨',
-'廝' => '厮',
-'廟' => '庙',
-'廠' => '厂',
-'廡' => '庑',
-'廢' => '废',
-'廣' => '广',
-'廩' => '廪',
-'廬' => '庐',
-'廳' => '厅',
-'廵' => '巡',
-'廹' => '迫',
-'廻' => '回',
-'廼' => '乃',
-'弒' => '弑',
-'弔' => '吊',
-'弳' => '弪',
-'張' => '张',
-'強' => '强',
-'彆' => '别',
-'彈' => '弹',
-'彌' => '弥',
-'彎' => '弯',
-'彙' => '汇',
-'彞' => '彝',
-'彠' => '彟',
-'彥' => '彦',
-'彫' => '雕',
-'彲' => '彨',
-'徃' => '往',
-'後' => '后',
-'徑' => '径',
-'從' => '从',
-'徠' => '徕',
-'徧' => '遍',
-'復' => '复',
-'徵' => '征',
-'徹' => '彻',
-'怱' => '匆',
-'怳' => '恍',
-'恆' => '恒',
-'恠' => '怪',
-'恡' => '吝',
-'恥' => '耻',
-'悅' => '悦',
-'悞' => '悮',
-'悤' => '匆',
-'悵' => '怅',
-'悶' => '闷',
-'悽' => '凄',
-'惏' => '婪',
-'惡' => '恶',
-'惥' => '恿',
-'惱' => '恼',
-'惲' => '恽',
-'惷' => '蠢',
-'惻' => '恻',
-'愛' => '爱',
-'愜' => '惬',
-'愨' => '悫',
-'愴' => '怆',
-'愷' => '恺',
-'愽' => '博',
-'愾' => '忾',
-'慄' => '栗',
-'態' => '态',
-'慍' => '愠',
-'慘' => '惨',
-'慙' => '惭',
-'慚' => '惭',
-'慟' => '恸',
-'慣' => '惯',
-'慤' => '悫',
-'慪' => '怄',
-'慫' => '怂',
-'慮' => '虑',
-'慳' => '悭',
-'慴' => '慑',
-'慶' => '庆',
-'慼' => '戚',
-'慽' => '戚',
-'慾' => '欲',
-'憂' => '忧',
-'憇' => '憩',
-'憊' => '惫',
-'憐' => '怜',
-'憑' => '凭',
-'憒' => '愦',
-'憚' => '惮',
-'憤' => '愤',
-'憫' => '悯',
-'憮' => '怃',
-'憲' => '宪',
-'憶' => '忆',
-'懀' => '𢙓',
-'懇' => '恳',
-'應' => '应',
-'懌' => '怿',
-'懍' => '懔',
-'懟' => '怼',
-'懣' => '懑',
-'懨' => '恹',
-'懲' => '惩',
-'懶' => '懒',
-'懷' => '怀',
-'懸' => '悬',
-'懺' => '忏',
-'懼' => '惧',
-'懾' => '慑',
-'戀' => '恋',
-'戇' => '戆',
-'戔' => '戋',
-'戞' => '戛',
-'戧' => '戗',
-'戩' => '戬',
-'戯' => '戏',
-'戰' => '战',
-'戱' => '戯',
-'戲' => '戏',
-'戶' => '户',
-'戹' => '厄',
-'扞' => '捍',
-'抝' => '拗',
-'拋' => '抛',
-'拚' => '拼',
-'挩' => '捝',
-'挱' => '挲',
-'挵' => '弄',
-'挾' => '挟',
-'捄' => '救',
-'捨' => '舍',
-'捫' => '扪',
-'捲' => '卷',
-'掃' => '扫',
-'掄' => '抡',
-'掆' => '㧏',
-'掗' => '挜',
-'掙' => '挣',
-'掛' => '挂',
-'採' => '采',
-'掽' => '碰',
-'揀' => '拣',
-'揑' => '捏',
-'揚' => '扬',
-'換' => '换',
-'揫' => '揪',
-'揮' => '挥',
-'揷' => '插',
-'揹' => '背',
-'搆' => '构',
-'搇' => '揿',
-'搉' => '榷',
-'損' => '损',
-'搖' => '摇',
-'搗' => '捣',
-'搤' => '扼',
-'搥' => '捶',
-'搨' => '拓',
-'搯' => '掏',
-'搵' => '揾',
-'搶' => '抢',
-'搾' => '榨',
-'摃' => '扛',
-'摋' => '𢫬',
-'摑' => '掴',
-'摜' => '掼',
-'摟' => '搂',
-'摯' => '挚',
-'摳' => '抠',
-'摶' => '抟',
-'摺' => '折',
-'摻' => '掺',
-'撈' => '捞',
-'撏' => '挦',
-'撐' => '撑',
-'撓' => '挠',
-'撝' => '㧑',
-'撟' => '挢',
-'撡' => '操',
-'撣' => '掸',
-'撥' => '拨',
-'撦' => '扯',
-'撫' => '抚',
-'撲' => '扑',
-'撳' => '揿',
-'撻' => '挞',
-'撾' => '挝',
-'撿' => '捡',
-'擁' => '拥',
-'擄' => '掳',
-'擇' => '择',
-'擊' => '击',
-'擋' => '挡',
-'擓' => '㧟',
-'擔' => '担',
-'擕' => '携',
-'據' => '据',
-'擠' => '挤',
-'擣' => '𢭏',
-'擧' => '举',
-'擬' => '拟',
-'擯' => '摈',
-'擰' => '拧',
-'擱' => '搁',
-'擲' => '掷',
-'擴' => '扩',
-'擷' => '撷',
-'擺' => '摆',
-'擻' => '擞',
-'擼' => '撸',
-'擽' => '㧰',
-'擾' => '扰',
-'攄' => '摅',
-'攆' => '撵',
-'攏' => '拢',
-'攔' => '拦',
-'攖' => '撄',
-'攙' => '搀',
-'攛' => '撺',
-'攜' => '携',
-'攝' => '摄',
-'攢' => '攒',
-'攣' => '挛',
-'攤' => '摊',
-'攩' => '挡',
-'攪' => '搅',
-'攬' => '揽',
-'攷' => '考',
-'敂' => '叩',
-'敍' => '叙',
-'敗' => '败',
-'敘' => '叙',
-'敵' => '敌',
-'數' => '数',
-'敺' => '驱',
-'斂' => '敛',
-'斃' => '毙',
-'斅' => '𢽾',
-'斆' => '敩',
-'斕' => '斓',
-'斬' => '斩',
-'斷' => '断',
-'於' => '于',
-'旂' => '旗',
-'旣' => '既',
-'旤' => '祸',
-'旹' => '时',
-'旾' => '春',
-'昬' => '昏',
-'時' => '时',
-'晉' => '晋',
-'晝' => '昼',
-'暈' => '晕',
-'暉' => '晖',
-'暘' => '旸',
-'暢' => '畅',
-'暫' => '暂',
-'暱' => '昵',
-'曄' => '晔',
-'曆' => '历',
-'曇' => '昙',
-'曉' => '晓',
-'曖' => '暧',
-'曠' => '旷',
-'曡' => '叠',
-'曥' => '𣆐',
-'曨' => '昽',
-'曬' => '晒',
-'書' => '书',
-'會' => '会',
-'朞' => '期',
-'朢' => '望',
-'朥' => '𦛨',
-'朧' => '胧',
-'朮' => '术',
-'朶' => '朵',
-'東' => '东',
-'杴' => '锨',
-'枱' => '台',
-'柵' => '栅',
-'柺' => '拐',
-'査' => '查',
-'栁' => '柳',
-'栞' => '刊',
-'栢' => '柏',
-'栰' => '筏',
-'桒' => '桑',
-'桮' => '杯',
-'桺' => '柳',
-'桿' => '杆',
-'梔' => '栀',
-'梘' => '枧',
-'條' => '条',
-'梟' => '枭',
-'梲' => '棁',
-'棄' => '弃',
-'棊' => '棋',
-'棖' => '枨',
-'棗' => '枣',
-'棟' => '栋',
-'棡' => '㭎',
-'棧' => '栈',
-'棲' => '栖',
-'棶' => '梾',
-'椏' => '桠',
-'椗' => '碇',
-'椲' => '㭏',
-'椶' => '棕',
-'椷' => '缄',
-'椾' => '笺',
-'楊' => '杨',
-'楓' => '枫',
-'楥' => '楦',
-'楨' => '桢',
-'業' => '业',
-'極' => '极',
-'榦' => '干',
-'榪' => '杩',
-'榮' => '荣',
-'榲' => '榅',
-'榿' => '桤',
-'構' => '构',
-'槍' => '枪',
-'槓' => '杠',
-'槕' => '桌',
-'槤' => '梿',
-'槧' => '椠',
-'槨' => '椁',
-'槮' => '椮',
-'槳' => '桨',
-'槶' => '椢',
-'槼' => '椝',
-'樁' => '桩',
-'樂' => '乐',
-'樅' => '枞',
-'樑' => '梁',
-'樓' => '楼',
-'標' => '标',
-'樞' => '枢',
-'樢' => '㭤',
-'樣' => '样',
-'樫' => '㭴',
-'樳' => '桪',
-'樸' => '朴',
-'樹' => '树',
-'樺' => '桦',
-'樿' => '椫',
-'橈' => '桡',
-'橋' => '桥',
-'橜' => '橛',
-'機' => '机',
-'橢' => '椭',
-'橫' => '横',
-'檁' => '檩',
-'檉' => '柽',
-'檔' => '档',
-'檜' => '桧',
-'檟' => '槚',
-'檢' => '检',
-'檣' => '樯',
-'檭' => '𣘴',
-'檮' => '梼',
-'檯' => '台',
-'檳' => '槟',
-'檸' => '柠',
-'檻' => '槛',
-'櫃' => '柜',
-'櫈' => '凳',
-'櫓' => '橹',
-'櫚' => '榈',
-'櫛' => '栉',
-'櫝' => '椟',
-'櫞' => '橼',
-'櫟' => '栎',
-'櫥' => '橱',
-'櫧' => '槠',
-'櫨' => '栌',
-'櫪' => '枥',
-'櫫' => '橥',
-'櫬' => '榇',
-'櫱' => '蘖',
-'櫳' => '栊',
-'櫸' => '榉',
-'櫻' => '樱',
-'欄' => '栏',
-'欅' => '榉',
-'權' => '权',
-'欍' => '𣐤',
-'欏' => '椤',
-'欒' => '栾',
-'欓' => '𣗋',
-'欖' => '榄',
-'欝' => '郁',
-'欞' => '棂',
-'欵' => '款',
-'欽' => '钦',
-'歎' => '叹',
-'歐' => '欧',
-'歛' => '敛',
-'歟' => '欤',
-'歡' => '欢',
-'歲' => '岁',
-'歴' => '历',
-'歷' => '历',
-'歸' => '归',
-'歿' => '殁',
-'殀' => '夭',
-'殘' => '残',
-'殞' => '殒',
-'殤' => '殇',
-'殨' => '㱮',
-'殫' => '殚',
-'殭' => '僵',
-'殮' => '殓',
-'殯' => '殡',
-'殰' => '㱩',
-'殲' => '歼',
-'殺' => '杀',
-'殻' => '壳',
-'殼' => '壳',
-'毀' => '毁',
-'毆' => '殴',
-'毧' => '绒',
-'毬' => '球',
-'毿' => '毵',
-'氂' => '牦',
-'氈' => '毡',
-'氊' => '毡',
-'氌' => '氇',
-'氣' => '气',
-'氫' => '氢',
-'氬' => '氩',
-'氳' => '氲',
-'氷' => '冰',
-'汙' => '污',
-'汚' => '污',
-'決' => '决',
-'沒' => '没',
-'沖' => '冲',
-'況' => '况',
-'泝' => '溯',
-'洩' => '泄',
-'洶' => '汹',
-'浹' => '浃',
-'涇' => '泾',
-'涖' => '莅',
-'涼' => '凉',
-'淒' => '凄',
-'淚' => '泪',
-'淛' => '浙',
-'淥' => '渌',
-'淨' => '净',
-'淩' => '凌',
-'淪' => '沦',
-'淵' => '渊',
-'淶' => '涞',
-'淺' => '浅',
-'渙' => '涣',
-'減' => '减',
-'渢' => '沨',
-'渦' => '涡',
-'測' => '测',
-'渾' => '浑',
-'湊' => '凑',
-'湞' => '浈',
-'湧' => '涌',
-'湯' => '汤',
-'湼' => '涅',
-'溈' => '沩',
-'準' => '准',
-'溝' => '沟',
-'溫' => '温',
-'溮' => '浉',
-'溳' => '涢',
-'溼' => '湿',
-'滄' => '沧',
-'滅' => '灭',
-'滌' => '涤',
-'滎' => '荥',
-'滙' => '汇',
-'滛' => '淫',
-'滬' => '沪',
-'滯' => '滞',
-'滲' => '渗',
-'滷' => '卤',
-'滸' => '浒',
-'滻' => '浐',
-'滾' => '滚',
-'滿' => '满',
-'漁' => '渔',
-'漊' => '溇',
-'漚' => '沤',
-'漢' => '汉',
-'漣' => '涟',
-'漬' => '渍',
-'漲' => '涨',
-'漵' => '溆',
-'漸' => '渐',
-'漿' => '浆',
-'潁' => '颍',
-'潄' => '漱',
-'潑' => '泼',
-'潔' => '洁',
-'潙' => '沩',
-'潛' => '潜',
-'潤' => '润',
-'潯' => '浔',
-'潰' => '溃',
-'潷' => '滗',
-'潿' => '涠',
-'澀' => '涩',
-'澁' => '涩',
-'澅' => '𣶩',
-'澆' => '浇',
-'澇' => '涝',
-'澐' => '沄',
-'澗' => '涧',
-'澠' => '渑',
-'澤' => '泽',
-'澦' => '滪',
-'澩' => '泶',
-'澮' => '浍',
-'澱' => '淀',
-'澾' => '㳠',
-'濁' => '浊',
-'濃' => '浓',
-'濄' => '㳡',
-'濆' => '𣸣',
-'濇' => '涩',
-'濕' => '湿',
-'濘' => '泞',
-'濜' => '浕',
-'濟' => '济',
-'濤' => '涛',
-'濧' => '㳔',
-'濫' => '滥',
-'濰' => '潍',
-'濱' => '滨',
-'濶' => '阔',
-'濺' => '溅',
-'濼' => '泺',
-'濾' => '滤',
-'瀂' => '澛',
-'瀃' => '𣽷',
-'瀅' => '滢',
-'瀆' => '渎',
-'瀇' => '㲿',
-'瀉' => '泻',
-'瀋' => '沈',
-'瀏' => '浏',
-'瀕' => '濒',
-'瀘' => '泸',
-'瀝' => '沥',
-'瀟' => '潇',
-'瀠' => '潆',
-'瀦' => '潴',
-'瀧' => '泷',
-'瀨' => '濑',
-'瀰' => '弥',
-'瀲' => '潋',
-'瀾' => '澜',
-'灃' => '沣',
-'灄' => '滠',
-'灋' => '法',
-'灑' => '洒',
-'灕' => '漓',
-'灘' => '滩',
-'灙' => '𣺼',
-'灝' => '灏',
-'灠' => '漤',
-'灣' => '湾',
-'灤' => '滦',
-'灧' => '滟',
-'灩' => '滟',
-'災' => '灾',
-'為' => '为',
-'烏' => '乌',
-'烖' => '灾',
-'烴' => '烃',
-'無' => '无',
-'煉' => '炼',
-'煑' => '煮',
-'煒' => '炜',
-'煗' => '暖',
-'煙' => '烟',
-'煢' => '茕',
-'煥' => '焕',
-'煩' => '烦',
-'煬' => '炀',
-'煱' => '㶽',
-'熅' => '煴',
-'熈' => '熙',
-'熉' => '𤈶',
-'熌' => '𤇄',
-'熒' => '荧',
-'熓' => '𤆡',
-'熗' => '炝',
-'熡' => '𤋏',
-'熱' => '热',
-'熲' => '颎',
-'熾' => '炽',
-'燁' => '烨',
-'燄' => '焰',
-'燈' => '灯',
-'燉' => '炖',
-'燒' => '烧',
-'燙' => '烫',
-'燜' => '焖',
-'營' => '营',
-'燦' => '灿',
-'燬' => '毁',
-'燭' => '烛',
-'燴' => '烩',
-'燶' => '㶶',
-'燻' => '熏',
-'燼' => '烬',
-'燾' => '焘',
-'爄' => '𤇃',
-'爍' => '烁',
-'爐' => '炉',
-'爗' => '烨',
-'爛' => '烂',
-'爭' => '争',
-'爲' => '为',
-'爺' => '爷',
-'爾' => '尔',
-'牀' => '床',
-'牆' => '墙',
-'牋' => '笺',
-'牎' => '窗',
-'牐' => '闸',
-'牓' => '榜',
-'牕' => '窗',
-'牘' => '牍',
-'牠' => '它',
-'牴' => '抵',
-'牽' => '牵',
-'犖' => '荦',
-'犢' => '犊',
-'犧' => '牺',
-'狀' => '状',
-'狥' => '徇',
-'狹' => '狭',
-'狽' => '狈',
-'猂' => '悍',
-'猙' => '狰',
-'猨' => '猿',
-'猶' => '犹',
-'猻' => '狲',
-'獁' => '犸',
-'獃' => '呆',
-'獄' => '狱',
-'獅' => '狮',
-'獎' => '奖',
-'獘' => '毙',
-'獧' => '狷',
-'獨' => '独',
-'獪' => '狯',
-'獫' => '猃',
-'獮' => '狝',
-'獰' => '狞',
-'獱' => '㺍',
-'獲' => '获',
-'獵' => '猎',
-'獷' => '犷',
-'獸' => '兽',
-'獺' => '獭',
-'獻' => '献',
-'獼' => '猕',
-'玀' => '猡',
-'玁' => '𤞤',
-'玅' => '妙',
-'現' => '现',
-'琖' => '盏',
-'琱' => '雕',
-'琺' => '珐',
-'琿' => '珲',
-'瑇' => '玳',
-'瑋' => '玮',
-'瑒' => '玚',
-'瑣' => '琐',
-'瑤' => '瑶',
-'瑩' => '莹',
-'瑪' => '玛',
-'瑯' => '琅',
-'瑲' => '玱',
-'瑽' => '𪻐',
-'璉' => '琏',
-'璡' => '琎',
-'璢' => '瑠',
-'璣' => '玑',
-'璦' => '瑷',
-'璫' => '珰',
-'璯' => '㻅',
-'環' => '环',
-'璵' => '玙',
-'璸' => '瑸',
-'璽' => '玺',
-'瓊' => '琼',
-'瓏' => '珑',
-'瓔' => '璎',
-'瓕' => '𤦀',
-'瓚' => '瓒',
-'甌' => '瓯',
-'甎' => '砖',
-'甕' => '瓮',
-'甖' => '罂',
-'甞' => '尝',
-'產' => '产',
-'産' => '产',
-'畂' => '亩',
-'畆' => '亩',
-'畝' => '亩',
-'畢' => '毕',
-'畧' => '略',
-'畫' => '画',
-'畮' => '亩',
-'異' => '异',
-'畱' => '留',
-'畵' => '画',
-'當' => '当',
-'疇' => '畴',
-'疊' => '叠',
-'疎' => '疏',
-'疘' => '肛',
-'疿' => '痱',
-'痐' => '蛔',
-'痙' => '痉',
-'痠' => '酸',
-'痲' => '痳',
-'痺' => '痹',
-'瘂' => '痖',
-'瘉' => '愈',
-'瘋' => '疯',
-'瘍' => '疡',
-'瘓' => '痪',
-'瘖' => '喑',
-'瘞' => '瘗',
-'瘡' => '疮',
-'瘧' => '疟',
-'瘮' => '瘆',
-'瘲' => '疭',
-'瘺' => '瘘',
-'瘻' => '瘘',
-'療' => '疗',
-'癄' => '憔',
-'癅' => '瘤',
-'癆' => '痨',
-'癇' => '痫',
-'癈' => '废',
-'癉' => '瘅',
-'癒' => '愈',
-'癘' => '疠',
-'癟' => '瘪',
-'癡' => '痴',
-'癢' => '痒',
-'癤' => '疖',
-'癥' => '症',
-'癧' => '疬',
-'癩' => '癞',
-'癬' => '癣',
-'癭' => '瘿',
-'癮' => '瘾',
-'癰' => '痈',
-'癱' => '瘫',
-'癲' => '癫',
-'發' => '发',
-'皁' => '皂',
-'皐' => '皋',
-'皚' => '皑',
-'皜' => '皓',
-'皟' => '𤾀',
-'皰' => '疱',
-'皷' => '鼓',
-'皸' => '皲',
-'皺' => '皱',
-'盃' => '杯',
-'盇' => '盍',
-'盌' => '碗',
-'盜' => '盗',
-'盞' => '盏',
-'盡' => '尽',
-'監' => '监',
-'盤' => '盘',
-'盧' => '卢',
-'盪' => '荡',
-'眎' => '视',
-'眞' => '真',
-'眡' => '视',
-'眥' => '眦',
-'眾' => '众',
-'睍' => '𪾢',
-'睏' => '困',
-'睜' => '睁',
-'睞' => '睐',
-'睠' => '眷',
-'睪' => '睾',
-'瞇' => '眯',
-'瞖' => '翳',
-'瞘' => '眍',
-'瞜' => '䁖',
-'瞞' => '瞒',
-'瞤' => '𥆧',
-'瞭' => '了',
-'瞶' => '瞆',
-'瞼' => '睑',
-'矁' => '瞅',
-'矇' => '蒙',
-'矓' => '眬',
-'矙' => '瞰',
-'矚' => '瞩',
-'矯' => '矫',
-'砲' => '炮',
-'硜' => '硁',
-'硤' => '硖',
-'硨' => '砗',
-'硯' => '砚',
-'碙' => '𥐻',
-'碩' => '硕',
-'碪' => '砧',
-'碭' => '砀',
-'碸' => '砜',
-'確' => '确',
-'碼' => '码',
-'碽' => '䂵',
-'磑' => '硙',
-'磚' => '砖',
-'磟' => '碌',
-'磠' => '硵',
-'磣' => '碜',
-'磧' => '碛',
-'磯' => '矶',
-'磽' => '硗',
-'礄' => '硚',
-'礆' => '碱',
-'礎' => '础',
-'礒' => '𥐟',
-'礙' => '碍',
-'礦' => '矿',
-'礪' => '砺',
-'礫' => '砾',
-'礬' => '矾',
-'礮' => '炮',
-'礱' => '砻',
-'祕' => '秘',
-'祘' => '算',
-'祿' => '禄',
-'禍' => '祸',
-'禎' => '祯',
-'禕' => '祎',
-'禡' => '祃',
-'禦' => '御',
-'禪' => '禅',
-'禮' => '礼',
-'禰' => '祢',
-'禱' => '祷',
-'禿' => '秃',
-'秈' => '籼',
-'秊' => '年',
-'秌' => '秋',
-'秖' => '只',
-'稅' => '税',
-'稈' => '秆',
-'稉' => '粳',
-'稏' => '䅉',
-'稜' => '棱',
-'稟' => '禀',
-'稬' => '糯',
-'稭' => '秸',
-'種' => '种',
-'稱' => '称',
-'稾' => '稿',
-'穀' => '谷',
-'穌' => '稣',
-'積' => '积',
-'穎' => '颖',
-'穠' => '秾',
-'穡' => '穑',
-'穢' => '秽',
-'穤' => '糯',
-'穨' => '颓',
-'穩' => '稳',
-'穫' => '获',
-'穭' => '稆',
-'穽' => '阱',
-'窓' => '窗',
-'窩' => '窝',
-'窪' => '洼',
-'窮' => '穷',
-'窯' => '窑',
-'窰' => '窑',
-'窵' => '窎',
-'窶' => '窭',
-'窺' => '窥',
-'窻' => '窗',
-'竄' => '窜',
-'竅' => '窍',
-'竇' => '窦',
-'竈' => '灶',
-'竊' => '窃',
-'竚' => '伫',
-'竝' => '并',
-'竢' => '俟',
-'竪' => '竖',
-'競' => '竞',
-'筆' => '笔',
-'筍' => '笋',
-'筞' => '策',
-'筧' => '笕',
-'筩' => '筒',
-'筯' => '箸',
-'筴' => '䇲',
-'箇' => '个',
-'箋' => '笺',
-'箏' => '筝',
-'箒' => '帚',
-'箠' => '棰',
-'節' => '节',
-'範' => '范',
-'築' => '筑',
-'篋' => '箧',
-'篔' => '筼',
-'篘' => '𥬠',
-'篛' => '箬',
-'篤' => '笃',
-'篩' => '筛',
-'篳' => '筚',
-'簀' => '箦',
-'簍' => '篓',
-'簑' => '蓑',
-'簒' => '篡',
-'簞' => '箪',
-'簡' => '简',
-'簣' => '篑',
-'簫' => '箫',
-'簮' => '簪',
-'簷' => '檐',
-'簹' => '筜',
-'簽' => '签',
-'簾' => '帘',
-'籃' => '篮',
-'籋' => '𥬞',
-'籌' => '筹',
-'籐' => '藤',
-'籔' => '䉤',
-'籙' => '箓',
-'籛' => '篯',
-'籜' => '箨',
-'籟' => '籁',
-'籠' => '笼',
-'籤' => '签',
-'籩' => '笾',
-'籪' => '簖',
-'籬' => '篱',
-'籮' => '箩',
-'籲' => '吁',
-'粃' => '秕',
-'粧' => '妆',
-'粵' => '粤',
-'糉' => '粽',
-'糝' => '糁',
-'糞' => '粪',
-'糧' => '粮',
-'糰' => '团',
-'糲' => '粝',
-'糴' => '籴',
-'糶' => '粜',
-'糹' => '纟',
-'糾' => '纠',
-'紀' => '纪',
-'紂' => '纣',
-'約' => '约',
-'紅' => '红',
-'紆' => '纡',
-'紇' => '纥',
-'紈' => '纨',
-'紉' => '纫',
-'紋' => '纹',
-'納' => '纳',
-'紐' => '纽',
-'紓' => '纾',
-'純' => '纯',
-'紕' => '纰',
-'紖' => '纼',
-'紗' => '纱',
-'紘' => '纮',
-'紙' => '纸',
-'級' => '级',
-'紛' => '纷',
-'紜' => '纭',
-'紝' => '纴',
-'紡' => '纺',
-'紥' => '扎',
-'紬' => '䌷',
-'紮' => '扎',
-'細' => '细',
-'紱' => '绂',
-'紲' => '绁',
-'紳' => '绅',
-'紵' => '纻',
-'紹' => '绍',
-'紺' => '绀',
-'紼' => '绋',
-'紿' => '绐',
-'絀' => '绌',
-'終' => '终',
-'絃' => '弦',
-'組' => '组',
-'絅' => '䌹',
-'絆' => '绊',
-'絎' => '绗',
-'絏' => '绁',
-'結' => '结',
-'絕' => '绝',
-'絛' => '绦',
-'絝' => '绔',
-'絞' => '绞',
-'絡' => '络',
-'絢' => '绚',
-'給' => '给',
-'絨' => '绒',
-'絰' => '绖',
-'統' => '统',
-'絲' => '丝',
-'絳' => '绛',
-'絶' => '绝',
-'絹' => '绢',
-'絺' => '𫄨',
-'綀' => '𦈌',
-'綁' => '绑',
-'綃' => '绡',
-'綆' => '绠',
-'綇' => '𦈋',
-'綈' => '绨',
-'綉' => '绣',
-'綌' => '绤',
-'綏' => '绥',
-'綐' => '䌼',
-'綑' => '捆',
-'經' => '经',
-'綜' => '综',
-'綞' => '缍',
-'綠' => '绿',
-'綢' => '绸',
-'綣' => '绻',
-'綫' => '线',
-'綬' => '绶',
-'維' => '维',
-'綯' => '绹',
-'綰' => '绾',
-'綱' => '纲',
-'網' => '网',
-'綴' => '缀',
-'綵' => '彩',
-'綸' => '纶',
-'綹' => '绺',
-'綺' => '绮',
-'綻' => '绽',
-'綽' => '绰',
-'綾' => '绫',
-'綿' => '绵',
-'緄' => '绲',
-'緇' => '缁',
-'緊' => '紧',
-'緋' => '绯',
-'緍' => '𦈏',
-'緐' => '繁',
-'緑' => '绿',
-'緒' => '绪',
-'緓' => '绬',
-'緔' => '绱',
-'緗' => '缃',
-'緘' => '缄',
-'緙' => '缂',
-'線' => '线',
-'緜' => '绵',
-'緝' => '缉',
-'緞' => '缎',
-'締' => '缔',
-'緡' => '缗',
-'緣' => '缘',
-'緥' => '褓',
-'緦' => '缌',
-'編' => '编',
-'緩' => '缓',
-'緬' => '缅',
-'緯' => '纬',
-'緰' => '𦈕',
-'緱' => '缑',
-'緲' => '缈',
-'練' => '练',
-'緶' => '缏',
-'緷' => '𦈉',
-'緸' => '𦈑',
-'緹' => '缇',
-'緻' => '致',
-'緼' => '缊',
-'縈' => '萦',
-'縉' => '缙',
-'縊' => '缢',
-'縋' => '缒',
-'縎' => '𦈔',
-'縐' => '绉',
-'縑' => '缣',
-'縕' => '缊',
-'縗' => '缞',
-'縛' => '缚',
-'縝' => '缜',
-'縞' => '缟',
-'縟' => '缛',
-'縣' => '县',
-'縧' => '绦',
-'縫' => '缝',
-'縬' => '𦈚',
-'縭' => '缡',
-'縮' => '缩',
-'縱' => '纵',
-'縲' => '缧',
-'縳' => '䌸',
-'縴' => '纤',
-'縵' => '缦',
-'縶' => '絷',
-'縷' => '缕',
-'縹' => '缥',
-'縺' => '𦈐',
-'總' => '总',
-'績' => '绩',
-'繃' => '绷',
-'繅' => '缫',
-'繆' => '缪',
-'繏' => '𦈝',
-'繐' => '穗',
-'繒' => '缯',
-'繓' => '𦈛',
-'織' => '织',
-'繕' => '缮',
-'繖' => '伞',
-'繙' => '翻',
-'繚' => '缭',
-'繞' => '绕',
-'繟' => '𦈎',
-'繡' => '绣',
-'繢' => '缋',
-'繦' => '襁',
-'繩' => '绳',
-'繪' => '绘',
-'繫' => '系',
-'繭' => '茧',
-'繮' => '缰',
-'繯' => '缳',
-'繰' => '缲',
-'繳' => '缴',
-'繸' => '䍁',
-'繹' => '绎',
-'繻' => '𦈡',
-'繼' => '继',
-'繽' => '缤',
-'繾' => '缱',
-'繿' => '䍀',
-'纁' => '𫄸',
-'纇' => '颣',
-'纈' => '缬',
-'纊' => '纩',
-'續' => '续',
-'纍' => '累',
-'纏' => '缠',
-'纓' => '缨',
-'纔' => '才',
-'纖' => '纤',
-'纘' => '缵',
-'纜' => '缆',
-'缽' => '钵',
-'罇' => '樽',
-'罈' => '坛',
-'罋' => '瓮',
-'罌' => '罂',
-'罎' => '坛',
-'罰' => '罚',
-'罵' => '骂',
-'罷' => '罢',
-'罸' => '罚',
-'羅' => '罗',
-'羆' => '罴',
-'羈' => '羁',
-'羋' => '芈',
-'羗' => '羌',
-'羢' => '绒',
-'羣' => '群',
-'羥' => '羟',
-'羨' => '羡',
-'義' => '义',
-'羶' => '膻',
-'翄' => '翅',
-'習' => '习',
-'翫' => '玩',
-'翬' => '翚',
-'翶' => '翱',
-'翹' => '翘',
-'翽' => '翙',
-'耡' => '锄',
-'耬' => '耧',
-'耮' => '耢',
-'聖' => '圣',
-'聞' => '闻',
-'聯' => '联',
-'聰' => '聪',
-'聲' => '声',
-'聳' => '耸',
-'聵' => '聩',
-'聶' => '聂',
-'職' => '职',
-'聹' => '聍',
-'聽' => '听',
-'聾' => '聋',
-'肅' => '肃',
-'肎' => '肯',
-'肐' => '胳',
-'肧' => '胚',
-'胷' => '胸',
-'脃' => '脆',
-'脅' => '胁',
-'脇' => '胁',
-'脈' => '脉',
-'脗' => '吻',
-'脛' => '胫',
-'脣' => '唇',
-'脥' => '𣍰',
-'脫' => '脱',
-'脹' => '胀',
-'腁' => '胼',
-'腎' => '肾',
-'腖' => '胨',
-'腡' => '脶',
-'腦' => '脑',
-'腪' => '𣍯',
-'腫' => '肿',
-'腳' => '脚',
-'腸' => '肠',
-'膃' => '腽',
-'膓' => '肠',
-'膕' => '腘',
-'膚' => '肤',
-'膞' => '䏝',
-'膠' => '胶',
-'膢' => '𦝼',
-'膩' => '腻',
-'膽' => '胆',
-'膾' => '脍',
-'膿' => '脓',
-'臈' => '腊',
-'臉' => '脸',
-'臋' => '臀',
-'臍' => '脐',
-'臏' => '膑',
-'臕' => '膘',
-'臗' => '𣎑',
-'臘' => '腊',
-'臙' => '胭',
-'臚' => '胪',
-'臝' => '裸',
-'臟' => '脏',
-'臠' => '脔',
-'臢' => '臜',
-'臥' => '卧',
-'臨' => '临',
-'臯' => '皋',
-'臺' => '台',
-'與' => '与',
-'興' => '兴',
-'舉' => '举',
-'舊' => '旧',
-'舖' => '铺',
-'舘' => '馆',
-'舩' => '船',
-'艙' => '舱',
-'艢' => '樯',
-'艣' => '橹',
-'艤' => '舣',
-'艦' => '舰',
-'艪' => '橹',
-'艫' => '舻',
-'艱' => '艰',
-'艷' => '艳',
-'芲' => '花',
-'芻' => '刍',
-'苧' => '苎',
-'茘' => '荔',
-'茲' => '兹',
-'荊' => '荆',
-'荳' => '豆',
-'莊' => '庄',
-'莖' => '茎',
-'莢' => '荚',
-'莧' => '苋',
-'華' => '华',
-'菸' => '烟',
-'萇' => '苌',
-'萊' => '莱',
-'萬' => '万',
-'萲' => '萱',
-'萴' => '荝',
-'萵' => '莴',
-'葉' => '叶',
-'葒' => '荭',
-'葠' => '参',
-'葤' => '荮',
-'葦' => '苇',
-'葯' => '药',
-'葷' => '荤',
-'蒓' => '莼',
-'蒔' => '莳',
-'蒞' => '莅',
-'蒼' => '苍',
-'蓀' => '荪',
-'蓆' => '席',
-'蓋' => '盖',
-'蓡' => '参',
-'蓮' => '莲',
-'蓯' => '苁',
-'蓴' => '莼',
-'蓽' => '荜',
-'蔔' => '卜',
-'蔕' => '蒂',
-'蔘' => '参',
-'蔞' => '蒌',
-'蔣' => '蒋',
-'蔥' => '葱',
-'蔦' => '茑',
-'蔭' => '荫',
-'蕁' => '荨',
-'蕆' => '蒇',
-'蕎' => '荞',
-'蕒' => '荬',
-'蕓' => '芸',
-'蕕' => '莸',
-'蕘' => '荛',
-'蕚' => '萼',
-'蕢' => '蒉',
-'蕩' => '荡',
-'蕪' => '芜',
-'蕭' => '萧',
-'蕷' => '蓣',
-'蕿' => '萱',
-'薀' => '蕰',
-'薈' => '荟',
-'薊' => '蓟',
-'薌' => '芗',
-'薑' => '姜',
-'薔' => '蔷',
-'薘' => '荙',
-'薟' => '莶',
-'薦' => '荐',
-'薩' => '萨',
-'薴' => '苧',
-'薺' => '荠',
-'藍' => '蓝',
-'藎' => '荩',
-'藝' => '艺',
-'藥' => '药',
-'藪' => '薮',
-'藭' => '䓖',
-'藴' => '蕴',
-'藶' => '苈',
-'藷' => '薯',
-'藹' => '蔼',
-'藺' => '蔺',
-'藼' => '萱',
-'蘀' => '萚',
-'蘄' => '蕲',
-'蘆' => '芦',
-'蘇' => '苏',
-'蘊' => '蕴',
-'蘐' => '萱',
-'蘓' => '苏',
-'蘚' => '藓',
-'蘞' => '蔹',
-'蘢' => '茏',
-'蘤' => '花',
-'蘭' => '兰',
-'蘺' => '蓠',
-'蘿' => '萝',
-'虆' => '蔂',
-'處' => '处',
-'虛' => '虚',
-'虜' => '虏',
-'號' => '号',
-'虧' => '亏',
-'虯' => '虬',
-'蚘' => '蛔',
-'蛕' => '蛔',
-'蛺' => '蛱',
-'蛻' => '蜕',
-'蜆' => '蚬',
-'蜋' => '螂',
-'蜖' => '蛔',
-'蜨' => '蝶',
-'蝕' => '蚀',
-'蝟' => '猬',
-'蝦' => '虾',
-'蝨' => '虱',
-'蝯' => '猿',
-'蝱' => '虻',
-'蝸' => '蜗',
-'螄' => '蛳',
-'螎' => '融',
-'螞' => '蚂',
-'螡' => '蚊',
-'螢' => '萤',
-'螮' => '䗖',
-'螻' => '蝼',
-'螿' => '螀',
-'蟁' => '蚊',
-'蟄' => '蛰',
-'蟇' => '蟆',
-'蟈' => '蝈',
-'蟎' => '螨',
-'蟣' => '虮',
-'蟬' => '蝉',
-'蟯' => '蛲',
-'蟲' => '虫',
-'蟶' => '蛏',
-'蟻' => '蚁',
-'蠁' => '蚃',
-'蠅' => '蝇',
-'蠆' => '虿',
-'蠍' => '蝎',
-'蠏' => '蟹',
-'蠐' => '蛴',
-'蠑' => '蝾',
-'蠒' => '茧',
-'蠔' => '蚝',
-'蠟' => '蜡',
-'蠣' => '蛎',
-'蠨' => '蟏',
-'蠭' => '蜂',
-'蠱' => '蛊',
-'蠶' => '蚕',
-'蠻' => '蛮',
-'衂' => '衄',
-'衆' => '众',
-'衇' => '脉',
-'衊' => '蔑',
-'術' => '术',
-'衕' => '同',
-'衚' => '胡',
-'衛' => '卫',
-'衝' => '冲',
-'衞' => '卫',
-'衺' => '邪',
-'袞' => '衮',
-'袟' => '帙',
-'袵' => '衽',
-'裊' => '袅',
-'裌' => '袷',
-'裏' => '里',
-'補' => '补',
-'裝' => '装',
-'裠' => '裙',
-'裡' => '里',
-'製' => '制',
-'複' => '复',
-'褌' => '裈',
-'褘' => '袆',
-'褭' => '袅',
-'褲' => '裤',
-'褳' => '裢',
-'褸' => '褛',
-'褻' => '亵',
-'襀' => '𫌀',
-'襃' => '褒',
-'襉' => '裥',
-'襍' => '杂',
-'襏' => '袯',
-'襖' => '袄',
-'襝' => '裣',
-'襠' => '裆',
-'襤' => '褴',
-'襪' => '袜',
-'襬' => '䙓',
-'襯' => '衬',
-'襲' => '袭',
-'襴' => '襕',
-'覇' => '霸',
-'覈' => '核',
-'覊' => '羁',
-'見' => '见',
-'覎' => '觃',
-'規' => '规',
-'覓' => '觅',
-'覔' => '觅',
-'視' => '视',
-'覘' => '觇',
-'覡' => '觋',
-'覥' => '觍',
-'覦' => '觎',
-'覩' => '睹',
-'親' => '亲',
-'覬' => '觊',
-'覯' => '觏',
-'覲' => '觐',
-'覷' => '觑',
-'覺' => '觉',
-'覼' => '𫌨',
-'覽' => '览',
-'覿' => '觌',
-'觀' => '观',
-'觝' => '抵',
-'觴' => '觞',
-'觶' => '觯',
-'觸' => '触',
-'訁' => '讠',
-'訂' => '订',
-'訃' => '讣',
-'計' => '计',
-'訊' => '讯',
-'訌' => '讧',
-'討' => '讨',
-'訐' => '讦',
-'訑' => '𫍙',
-'訒' => '讱',
-'訓' => '训',
-'訕' => '讪',
-'訖' => '讫',
-'託' => '托',
-'記' => '记',
-'訛' => '讹',
-'訝' => '讶',
-'訟' => '讼',
-'訢' => '䜣',
-'訣' => '诀',
-'訥' => '讷',
-'訩' => '讻',
-'訪' => '访',
-'設' => '设',
-'許' => '许',
-'訴' => '诉',
-'訶' => '诃',
-'診' => '诊',
-'註' => '注',
-'証' => '证',
-'詀' => '𧮪',
-'詁' => '诂',
-'詆' => '诋',
-'詎' => '讵',
-'詐' => '诈',
-'詒' => '诒',
-'詔' => '诏',
-'評' => '评',
-'詖' => '诐',
-'詗' => '诇',
-'詘' => '诎',
-'詛' => '诅',
-'詞' => '词',
-'詠' => '咏',
-'詡' => '诩',
-'詢' => '询',
-'詣' => '诣',
-'試' => '试',
-'詩' => '诗',
-'詫' => '诧',
-'詬' => '诟',
-'詭' => '诡',
-'詮' => '诠',
-'詰' => '诘',
-'話' => '话',
-'該' => '该',
-'詳' => '详',
-'詵' => '诜',
-'詶' => '酬',
-'詼' => '诙',
-'詿' => '诖',
-'誄' => '诔',
-'誅' => '诛',
-'誆' => '诓',
-'誇' => '夸',
-'誌' => '志',
-'認' => '认',
-'誑' => '诳',
-'誒' => '诶',
-'誕' => '诞',
-'誖' => '悖',
-'誘' => '诱',
-'誚' => '诮',
-'語' => '语',
-'誠' => '诚',
-'誡' => '诫',
-'誣' => '诬',
-'誤' => '误',
-'誥' => '诰',
-'誦' => '诵',
-'誨' => '诲',
-'說' => '说',
-'説' => '说',
-'誰' => '谁',
-'課' => '课',
-'誶' => '谇',
-'誹' => '诽',
-'誼' => '谊',
-'誾' => '訚',
-'調' => '调',
-'諂' => '谄',
-'諄' => '谆',
-'談' => '谈',
-'諉' => '诿',
-'請' => '请',
-'諍' => '诤',
-'諏' => '诹',
-'諑' => '诼',
-'諒' => '谅',
-'論' => '论',
-'諗' => '谂',
-'諛' => '谀',
-'諜' => '谍',
-'諝' => '谞',
-'諞' => '谝',
-'諡' => '谥',
-'諢' => '诨',
-'諤' => '谔',
-'諦' => '谛',
-'諧' => '谐',
-'諫' => '谏',
-'諭' => '谕',
-'諮' => '谘',
-'諰' => '𫍰',
-'諱' => '讳',
-'諳' => '谙',
-'諶' => '谌',
-'諷' => '讽',
-'諸' => '诸',
-'諺' => '谚',
-'諼' => '谖',
-'諾' => '诺',
-'謀' => '谋',
-'謁' => '谒',
-'謂' => '谓',
-'謄' => '誊',
-'謅' => '诌',
-'謊' => '谎',
-'謌' => '歌',
-'謎' => '谜',
-'謏' => '𫍲',
-'謐' => '谧',
-'謔' => '谑',
-'謖' => '谡',
-'謗' => '谤',
-'謙' => '谦',
-'謚' => '谥',
-'講' => '讲',
-'謝' => '谢',
-'謠' => '谣',
-'謡' => '谣',
-'謨' => '谟',
-'謫' => '谪',
-'謬' => '谬',
-'謭' => '谫',
-'謳' => '讴',
-'謹' => '谨',
-'謾' => '谩',
-'譁' => '哗',
-'譆' => '嘻',
-'證' => '证',
-'譊' => '𫍢',
-'譌' => '讹',
-'譎' => '谲',
-'譏' => '讥',
-'譔' => '撰',
-'譖' => '谮',
-'識' => '识',
-'譙' => '谯',
-'譚' => '谭',
-'譜' => '谱',
-'譟' => '噪',
-'譫' => '谵',
-'譭' => '毁',
-'譯' => '译',
-'議' => '议',
-'譴' => '谴',
-'護' => '护',
-'譸' => '诪',
-'譽' => '誉',
-'譾' => '谫',
-'讀' => '读',
-'讁' => '谪',
-'變' => '变',
-'讋' => '詟',
-'讌' => '䜩',
-'讎' => '仇',
-'讐' => '雠',
-'讒' => '谗',
-'讓' => '让',
-'讕' => '谰',
-'讖' => '谶',
-'讚' => '赞',
-'讜' => '谠',
-'讞' => '谳',
-'豈' => '岂',
-'豎' => '竖',
-'豐' => '丰',
-'豓' => '艳',
-'豔' => '艳',
-'豬' => '猪',
-'豶' => '豮',
-'貍' => '狸',
-'貓' => '猫',
-'貙' => '䝙',
-'貛' => '獾',
-'貝' => '贝',
-'貞' => '贞',
-'貟' => '贠',
-'負' => '负',
-'財' => '财',
-'貢' => '贡',
-'貧' => '贫',
-'貨' => '货',
-'販' => '贩',
-'貪' => '贪',
-'貫' => '贯',
-'責' => '责',
-'貯' => '贮',
-'貰' => '贳',
-'貲' => '赀',
-'貳' => '贰',
-'貴' => '贵',
-'貶' => '贬',
-'買' => '买',
-'貸' => '贷',
-'貺' => '贶',
-'費' => '费',
-'貼' => '贴',
-'貽' => '贻',
-'貿' => '贸',
-'賀' => '贺',
-'賁' => '贲',
-'賂' => '赂',
-'賃' => '赁',
-'賄' => '贿',
-'賅' => '赅',
-'資' => '资',
-'賈' => '贾',
-'賉' => '恤',
-'賊' => '贼',
-'賑' => '赈',
-'賒' => '赊',
-'賓' => '宾',
-'賕' => '赇',
-'賙' => '赒',
-'賚' => '赉',
-'賛' => '赞',
-'賜' => '赐',
-'賞' => '赏',
-'賟' => '𧹖',
-'賠' => '赔',
-'賡' => '赓',
-'賢' => '贤',
-'賣' => '卖',
-'賤' => '贱',
-'賦' => '赋',
-'賧' => '赕',
-'質' => '质',
-'賫' => '赍',
-'賬' => '账',
-'賭' => '赌',
-'賰' => '䞐',
-'賴' => '赖',
-'賵' => '赗',
-'賷' => '赍',
-'賺' => '赚',
-'賻' => '赙',
-'購' => '购',
-'賽' => '赛',
-'賾' => '赜',
-'贃' => '𧹗',
-'贄' => '贽',
-'贅' => '赘',
-'贇' => '赟',
-'贈' => '赠',
-'贊' => '赞',
-'贋' => '赝',
-'贍' => '赡',
-'贏' => '赢',
-'贐' => '赆',
-'贑' => '赣',
-'贓' => '赃',
-'贔' => '赑',
-'贖' => '赎',
-'贗' => '赝',
-'贛' => '赣',
-'贜' => '赃',
-'赬' => '赪',
-'趂' => '趁',
-'趕' => '赶',
-'趙' => '赵',
-'趨' => '趋',
-'趲' => '趱',
-'跡' => '迹',
-'跥' => '跺',
-'跴' => '踩',
-'踁' => '胫',
-'踐' => '践',
-'踫' => '碰',
-'踰' => '逾',
-'踴' => '踊',
-'蹌' => '跄',
-'蹏' => '蹄',
-'蹔' => '暂',
-'蹕' => '跸',
-'蹟' => '迹',
-'蹠' => '跖',
-'蹣' => '蹒',
-'蹤' => '踪',
-'蹧' => '糟',
-'蹵' => '蹴',
-'蹺' => '跷',
-'蹻' => '𫏋',
-'躂' => '跶',
-'躉' => '趸',
-'躊' => '踌',
-'躋' => '跻',
-'躍' => '跃',
-'躎' => '䟢',
-'躑' => '踯',
-'躒' => '跞',
-'躓' => '踬',
-'躕' => '蹰',
-'躚' => '跹',
-'躝' => '𨅬',
-'躡' => '蹑',
-'躥' => '蹿',
-'躦' => '躜',
-'躪' => '躏',
-'躭' => '耽',
-'躳' => '躬',
-'躶' => '裸',
-'軀' => '躯',
-'軉' => '𨉗',
-'車' => '车',
-'軋' => '轧',
-'軌' => '轨',
-'軍' => '军',
-'軏' => '𫐄',
-'軑' => '轪',
-'軒' => '轩',
-'軔' => '轫',
-'軗' => '𨐅',
-'軛' => '轭',
-'軟' => '软',
-'軤' => '轷',
-'軨' => '𫐉',
-'軫' => '轸',
-'軲' => '轱',
-'軸' => '轴',
-'軹' => '轵',
-'軺' => '轺',
-'軻' => '轲',
-'軼' => '轶',
-'軾' => '轼',
-'較' => '较',
-'輄' => '𨐈',
-'輅' => '辂',
-'輇' => '辁',
-'輈' => '辀',
-'載' => '载',
-'輊' => '轾',
-'輒' => '辄',
-'輓' => '挽',
-'輔' => '辅',
-'輕' => '轻',
-'輗' => '𫐐',
-'輙' => '辄',
-'輛' => '辆',
-'輜' => '辎',
-'輝' => '辉',
-'輞' => '辋',
-'輟' => '辍',
-'輥' => '辊',
-'輦' => '辇',
-'輩' => '辈',
-'輪' => '轮',
-'輬' => '辌',
-'輭' => '软',
-'輮' => '𫐓',
-'輯' => '辑',
-'輳' => '辏',
-'輸' => '输',
-'輻' => '辐',
-'輼' => '辒',
-'輾' => '辗',
-'輿' => '舆',
-'轀' => '辒',
-'轂' => '毂',
-'轄' => '辖',
-'轅' => '辕',
-'轆' => '辘',
-'轉' => '转',
-'轍' => '辙',
-'轎' => '轿',
-'轔' => '辚',
-'轟' => '轰',
-'轡' => '辔',
-'轢' => '轹',
-'轣' => '𫐆',
-'轤' => '轳',
-'辠' => '罪',
-'辢' => '辣',
-'辤' => '辞',
-'辦' => '办',
-'辭' => '辞',
-'辮' => '辫',
-'辯' => '辩',
-'農' => '农',
-'辳' => '农',
-'迴' => '回',
-'迻' => '移',
-'逈' => '迥',
-'逕' => '迳',
-'這' => '这',
-'連' => '连',
-'逥' => '回',
-'逩' => '奔',
-'逬' => '迸',
-'週' => '周',
-'進' => '进',
-'遉' => '侦',
-'遊' => '游',
-'運' => '运',
-'過' => '过',
-'達' => '达',
-'違' => '违',
-'遙' => '遥',
-'遜' => '逊',
-'遞' => '递',
-'遠' => '远',
-'遡' => '溯',
-'適' => '适',
-'遯' => '遁',
-'遲' => '迟',
-'遷' => '迁',
-'選' => '选',
-'遺' => '遗',
-'遼' => '辽',
-'邁' => '迈',
-'還' => '还',
-'邇' => '迩',
-'邊' => '边',
-'邏' => '逻',
-'邐' => '逦',
-'郟' => '郏',
-'郵' => '邮',
-'鄆' => '郓',
-'鄉' => '乡',
-'鄒' => '邹',
-'鄔' => '邬',
-'鄖' => '郧',
-'鄧' => '邓',
-'鄭' => '郑',
-'鄰' => '邻',
-'鄲' => '郸',
-'鄴' => '邺',
-'鄶' => '郐',
-'鄺' => '邝',
-'酇' => '酂',
-'酈' => '郦',
-'酖' => '鸩',
-'酧' => '酬',
-'醃' => '腌',
-'醆' => '盏',
-'醕' => '醇',
-'醜' => '丑',
-'醞' => '酝',
-'醣' => '糖',
-'醫' => '医',
-'醬' => '酱',
-'醯' => '酰',
-'醱' => '酦',
-'醻' => '酬',
-'醼' => '宴',
-'釀' => '酿',
-'釁' => '衅',
-'釃' => '酾',
-'釅' => '酽',
-'釋' => '释',
-'釒' => '钅',
-'釓' => '钆',
-'釔' => '钇',
-'釕' => '钌',
-'釗' => '钊',
-'釘' => '钉',
-'釙' => '钋',
-'針' => '针',
-'釣' => '钓',
-'釤' => '钐',
-'釦' => '扣',
-'釧' => '钏',
-'釩' => '钒',
-'釬' => '焊',
-'釳' => '𨰿',
-'釵' => '钗',
-'釷' => '钍',
-'釹' => '钕',
-'釺' => '钎',
-'釾' => '䥺',
-'鈀' => '钯',
-'鈁' => '钫',
-'鈃' => '钘',
-'鈄' => '钭',
-'鈅' => '钥',
-'鈇' => '𫓧',
-'鈈' => '钚',
-'鈉' => '钠',
-'鈋' => '𨱂',
-'鈍' => '钝',
-'鈎' => '钩',
-'鈐' => '钤',
-'鈑' => '钣',
-'鈒' => '钑',
-'鈔' => '钞',
-'鈕' => '钮',
-'鈞' => '钧',
-'鈠' => '𨱁',
-'鈣' => '钙',
-'鈥' => '钬',
-'鈦' => '钛',
-'鈧' => '钪',
-'鈮' => '铌',
-'鈯' => '𨱄',
-'鈰' => '铈',
-'鈲' => '𨱃',
-'鈳' => '钶',
-'鈴' => '铃',
-'鈷' => '钴',
-'鈸' => '钹',
-'鈹' => '铍',
-'鈺' => '钰',
-'鈽' => '钸',
-'鈾' => '铀',
-'鈿' => '钿',
-'鉀' => '钾',
-'鉁' => '𨱅',
-'鉄' => '铁',
-'鉅' => '钜',
-'鉆' => '钻',
-'鉈' => '铊',
-'鉉' => '铉',
-'鉋' => '铇',
-'鉍' => '铋',
-'鉑' => '铂',
-'鉕' => '钷',
-'鉗' => '钳',
-'鉚' => '铆',
-'鉛' => '铅',
-'鉞' => '钺',
-'鉢' => '钵',
-'鉤' => '钩',
-'鉦' => '钲',
-'鉬' => '钼',
-'鉭' => '钽',
-'鉶' => '铏',
-'鉸' => '铰',
-'鉺' => '铒',
-'鉻' => '铬',
-'鉿' => '铪',
-'銀' => '银',
-'銃' => '铳',
-'銅' => '铜',
-'銍' => '铚',
-'銑' => '铣',
-'銓' => '铨',
-'銖' => '铢',
-'銘' => '铭',
-'銚' => '铫',
-'銛' => '铦',
-'銜' => '衔',
-'銠' => '铑',
-'銣' => '铷',
-'銥' => '铱',
-'銦' => '铟',
-'銨' => '铵',
-'銩' => '铥',
-'銪' => '铕',
-'銫' => '铯',
-'銬' => '铐',
-'銱' => '铞',
-'銲' => '焊',
-'銳' => '锐',
-'銶' => '𨱇',
-'銷' => '销',
-'銻' => '锑',
-'銼' => '锉',
-'鋁' => '铝',
-'鋃' => '锒',
-'鋅' => '锌',
-'鋇' => '钡',
-'鋉' => '𨱈',
-'鋌' => '铤',
-'鋏' => '铗',
-'鋒' => '锋',
-'鋙' => '铻',
-'鋝' => '锊',
-'鋟' => '锓',
-'鋣' => '铘',
-'鋤' => '锄',
-'鋥' => '锃',
-'鋦' => '锔',
-'鋨' => '锇',
-'鋩' => '铓',
-'鋪' => '铺',
-'鋭' => '锐',
-'鋮' => '铖',
-'鋯' => '锆',
-'鋰' => '锂',
-'鋱' => '铽',
-'鋶' => '锍',
-'鋸' => '锯',
-'鋼' => '钢',
-'錁' => '锞',
-'錂' => '𨱋',
-'錄' => '录',
-'錆' => '锖',
-'錇' => '锫',
-'錈' => '锩',
-'錏' => '铔',
-'錐' => '锥',
-'錒' => '锕',
-'錕' => '锟',
-'錘' => '锤',
-'錙' => '锱',
-'錚' => '铮',
-'錛' => '锛',
-'錟' => '锬',
-'錠' => '锭',
-'錡' => '锜',
-'錢' => '钱',
-'錦' => '锦',
-'錨' => '锚',
-'錩' => '锠',
-'錫' => '锡',
-'錮' => '锢',
-'錯' => '错',
-'録' => '录',
-'錳' => '锰',
-'錶' => '表',
-'錸' => '铼',
-'鍀' => '锝',
-'鍁' => '锨',
-'鍃' => '锪',
-'鍄' => '𨱉',
-'鍆' => '钔',
-'鍇' => '锴',
-'鍈' => '锳',
-'鍊' => '炼',
-'鍋' => '锅',
-'鍍' => '镀',
-'鍔' => '锷',
-'鍘' => '铡',
-'鍚' => '钖',
-'鍛' => '锻',
-'鍠' => '锽',
-'鍤' => '锸',
-'鍥' => '锲',
-'鍩' => '锘',
-'鍫' => '锹',
-'鍬' => '锹',
-'鍮' => '𨱎',
-'鍰' => '锾',
-'鍳' => '鉴',
-'鍵' => '键',
-'鍶' => '锶',
-'鍺' => '锗',
-'鍾' => '锺',
-'鎂' => '镁',
-'鎄' => '锿',
-'鎇' => '镅',
-'鎊' => '镑',
-'鎌' => '镰',
-'鎔' => '镕',
-'鎖' => '锁',
-'鎗' => '枪',
-'鎘' => '镉',
-'鎚' => '锤',
-'鎛' => '镈',
-'鎝' => '𨱏',
-'鎡' => '镃',
-'鎢' => '钨',
-'鎣' => '蓥',
-'鎦' => '镏',
-'鎧' => '铠',
-'鎩' => '铩',
-'鎪' => '锼',
-'鎬' => '镐',
-'鎭' => '镇',
-'鎮' => '镇',
-'鎯' => '𨱍',
-'鎰' => '镒',
-'鎲' => '镋',
-'鎳' => '镍',
-'鎵' => '镓',
-'鎷' => '𨰾',
-'鎸' => '镌',
-'鎻' => '锁',
-'鎿' => '镎',
-'鏃' => '镞',
-'鏆' => '𨱌',
-'鏇' => '镟',
-'鏈' => '链',
-'鏉' => '𨱒',
-'鏌' => '镆',
-'鏍' => '镙',
-'鏐' => '镠',
-'鏑' => '镝',
-'鏗' => '铿',
-'鏘' => '锵',
-'鏚' => '戚',
-'鏜' => '镗',
-'鏝' => '镘',
-'鏞' => '镛',
-'鏟' => '铲',
-'鏡' => '镜',
-'鏢' => '镖',
-'鏤' => '镂',
-'鏦' => '𫓩',
-'鏨' => '錾',
-'鏰' => '镚',
-'鏵' => '铧',
-'鏷' => '镤',
-'鏹' => '镪',
-'鏺' => '䥽',
-'鏽' => '锈',
-'鐃' => '铙',
-'鐄' => '𨱑',
-'鐋' => '铴',
-'鐍' => '𫔎',
-'鐎' => '𨱓',
-'鐏' => '𨱔',
-'鐐' => '镣',
-'鐒' => '铹',
-'鐓' => '镦',
-'鐔' => '镡',
-'鐘' => '钟',
-'鐙' => '镫',
-'鐝' => '镢',
-'鐠' => '镨',
-'鐥' => '䦅',
-'鐦' => '锎',
-'鐧' => '锏',
-'鐨' => '镄',
-'鐫' => '镌',
-'鐮' => '镰',
-'鐯' => '䦃',
-'鐲' => '镯',
-'鐳' => '镭',
-'鐵' => '铁',
-'鐶' => '镮',
-'鐸' => '铎',
-'鐺' => '铛',
-'鐿' => '镱',
-'鑄' => '铸',
-'鑊' => '镬',
-'鑌' => '镔',
-'鑑' => '鉴',
-'鑒' => '鉴',
-'鑔' => '镲',
-'鑕' => '锧',
-'鑚' => '钻',
-'鑛' => '矿',
-'鑞' => '镴',
-'鑠' => '铄',
-'鑣' => '镳',
-'鑤' => '刨',
-'鑥' => '镥',
-'鑭' => '镧',
-'鑰' => '钥',
-'鑱' => '镵',
-'鑲' => '镶',
-'鑵' => '罐',
-'鑷' => '镊',
-'鑹' => '镩',
-'鑼' => '锣',
-'鑽' => '钻',
-'鑾' => '銮',
-'鑿' => '凿',
-'钁' => '镢',
-'钂' => '镋',
-'長' => '长',
-'門' => '门',
-'閂' => '闩',
-'閃' => '闪',
-'閆' => '闫',
-'閈' => '闬',
-'閉' => '闭',
-'開' => '开',
-'閌' => '闶',
-'閍' => '𨸂',
-'閎' => '闳',
-'閏' => '闰',
-'閐' => '𨸃',
-'閑' => '闲',
-'閒' => '闲',
-'間' => '间',
-'閔' => '闵',
-'閘' => '闸',
-'閙' => '闹',
-'閡' => '阂',
-'閣' => '阁',
-'閤' => '阁',
-'閥' => '阀',
-'閧' => '哄',
-'閨' => '闺',
-'閩' => '闽',
-'閫' => '阃',
-'閬' => '阆',
-'閭' => '闾',
-'閱' => '阅',
-'閲' => '阅',
-'閶' => '阊',
-'閹' => '阉',
-'閻' => '阎',
-'閼' => '阏',
-'閽' => '阍',
-'閾' => '阈',
-'閿' => '阌',
-'闃' => '阒',
-'闆' => '板',
-'闇' => '暗',
-'闈' => '闱',
-'闊' => '阔',
-'闋' => '阕',
-'闌' => '阑',
-'闍' => '阇',
-'闐' => '阗',
-'闒' => '阘',
-'闓' => '闿',
-'闔' => '阖',
-'闕' => '阙',
-'闖' => '闯',
-'闚' => '窥',
-'關' => '关',
-'闞' => '阚',
-'闠' => '阓',
-'闡' => '阐',
-'闢' => '辟',
-'闤' => '阛',
-'闥' => '闼',
-'阨' => '厄',
-'阬' => '坑',
-'陗' => '峭',
-'陘' => '陉',
-'陜' => '陕',
-'陝' => '陕',
-'陣' => '阵',
-'陰' => '阴',
-'陳' => '陈',
-'陸' => '陆',
-'陻' => '堙',
-'陽' => '阳',
-'陿' => '狭',
-'隂' => '阴',
-'隄' => '堤',
-'隉' => '陧',
-'隊' => '队',
-'階' => '阶',
-'隕' => '陨',
-'隖' => '坞',
-'際' => '际',
-'隣' => '邻',
-'隨' => '随',
-'險' => '险',
-'隱' => '隐',
-'隴' => '陇',
-'隷' => '隶',
-'隸' => '隶',
-'隻' => '只',
-'雋' => '隽',
-'雖' => '虽',
-'雙' => '双',
-'雛' => '雏',
-'雜' => '杂',
-'雞' => '鸡',
-'離' => '离',
-'難' => '难',
-'雲' => '云',
-'電' => '电',
-'霢' => '霡',
-'霧' => '雾',
-'霽' => '霁',
-'靂' => '雳',
-'靄' => '霭',
-'靆' => '叇',
-'靈' => '灵',
-'靉' => '叆',
-'靚' => '靓',
-'靜' => '静',
-'靦' => '腼',
-'靨' => '靥',
-'靭' => '韧',
-'靱' => '韧',
-'鞀' => '鼗',
-'鞏' => '巩',
-'鞝' => '绱',
-'鞦' => '秋',
-'鞵' => '鞋',
-'鞽' => '鞒',
-'鞾' => '靴',
-'韁' => '缰',
-'韃' => '鞑',
-'韆' => '千',
-'韈' => '袜',
-'韉' => '鞯',
-'韋' => '韦',
-'韌' => '韧',
-'韍' => '韨',
-'韓' => '韩',
-'韙' => '韪',
-'韜' => '韬',
-'韞' => '韫',
-'韤' => '袜',
-'韮' => '韭',
-'韻' => '韵',
-'響' => '响',
-'頁' => '页',
-'頂' => '顶',
-'頃' => '顷',
-'項' => '项',
-'順' => '顺',
-'頇' => '顸',
-'須' => '须',
-'頊' => '顼',
-'頌' => '颂',
-'頎' => '颀',
-'頏' => '颃',
-'預' => '预',
-'頑' => '顽',
-'頒' => '颁',
-'頓' => '顿',
-'頗' => '颇',
-'領' => '领',
-'頜' => '颌',
-'頟' => '额',
-'頡' => '颉',
-'頤' => '颐',
-'頦' => '颏',
-'頭' => '头',
-'頮' => '颒',
-'頰' => '颊',
-'頲' => '颋',
-'頴' => '颕',
-'頷' => '颔',
-'頸' => '颈',
-'頹' => '颓',
-'頻' => '频',
-'頼' => '赖',
-'頽' => '颓',
-'顃' => '𩖖',
-'顆' => '颗',
-'顇' => '悴',
-'顋' => '腮',
-'題' => '题',
-'額' => '额',
-'顎' => '颚',
-'顏' => '颜',
-'顒' => '颙',
-'顓' => '颛',
-'顔' => '颜',
-'願' => '愿',
-'顙' => '颡',
-'顛' => '颠',
-'類' => '类',
-'顢' => '颟',
-'顥' => '颢',
-'顦' => '憔',
-'顧' => '顾',
-'顫' => '颤',
-'顬' => '颥',
-'顯' => '显',
-'顰' => '颦',
-'顱' => '颅',
-'顳' => '颞',
-'顴' => '颧',
-'風' => '风',
-'颭' => '飐',
-'颮' => '飑',
-'颯' => '飒',
-'颰' => '𩙥',
-'颱' => '台',
-'颳' => '刮',
-'颶' => '飓',
-'颷' => '𩙪',
-'颸' => '飔',
-'颺' => '飏',
-'颻' => '飖',
-'颼' => '飕',
-'颾' => '𩙫',
-'飀' => '飗',
-'飃' => '飘',
-'飄' => '飘',
-'飆' => '飙',
-'飈' => '飚',
-'飛' => '飞',
-'飜' => '翻',
-'飠' => '饣',
-'飢' => '饥',
-'飣' => '饤',
-'飤' => '饲',
-'飥' => '饦',
-'飩' => '饨',
-'飪' => '饪',
-'飫' => '饫',
-'飭' => '饬',
-'飯' => '饭',
-'飱' => '飧',
-'飲' => '饮',
-'飴' => '饴',
-'飼' => '饲',
-'飽' => '饱',
-'飾' => '饰',
-'飿' => '饳',
-'餁' => '饪',
-'餃' => '饺',
-'餄' => '饸',
-'餅' => '饼',
-'餈' => '糍',
-'餉' => '饷',
-'養' => '养',
-'餌' => '饵',
-'餎' => '饹',
-'餏' => '饻',
-'餑' => '饽',
-'餒' => '馁',
-'餓' => '饿',
-'餔' => '𫗦',
-'餕' => '馂',
-'餖' => '饾',
-'餗' => '𫗧',
-'餘' => '馀',
-'餚' => '肴',
-'餛' => '馄',
-'餜' => '馃',
-'餞' => '饯',
-'餡' => '馅',
-'餦' => '𫗠',
-'館' => '馆',
-'餭' => '𫗮',
-'餱' => '糇',
-'餳' => '饧',
-'餵' => '喂',
-'餶' => '馉',
-'餷' => '馇',
-'餸' => '𩠌',
-'餹' => '糖',
-'餺' => '馎',
-'餻' => '糕',
-'餼' => '饩',
-'餽' => '馈',
-'餾' => '馏',
-'餿' => '馊',
-'饁' => '馌',
-'饃' => '馍',
-'饅' => '馒',
-'饈' => '馐',
-'饉' => '馑',
-'饊' => '馓',
-'饋' => '馈',
-'饌' => '馔',
-'饍' => '膳',
-'饑' => '饥',
-'饒' => '饶',
-'饗' => '飨',
-'饘' => '𫗴',
-'饜' => '餍',
-'饝' => '馍',
-'饞' => '馋',
-'饢' => '馕',
-'馬' => '马',
-'馭' => '驭',
-'馮' => '冯',
-'馱' => '驮',
-'馳' => '驰',
-'馴' => '驯',
-'馹' => '驲',
-'駁' => '驳',
-'駃' => '𫘝',
-'駈' => '驱',
-'駎' => '𩧨',
-'駐' => '驻',
-'駑' => '驽',
-'駒' => '驹',
-'駔' => '驵',
-'駕' => '驾',
-'駘' => '骀',
-'駙' => '驸',
-'駚' => '𩧫',
-'駛' => '驶',
-'駝' => '驼',
-'駟' => '驷',
-'駡' => '骂',
-'駢' => '骈',
-'駧' => '𩧲',
-'駩' => '𩧴',
-'駭' => '骇',
-'駰' => '骃',
-'駱' => '骆',
-'駶' => '𩧺',
-'駸' => '骎',
-'駻' => '𫘣',
-'駿' => '骏',
-'騁' => '骋',
-'騂' => '骍',
-'騃' => '𫘤',
-'騅' => '骓',
-'騌' => '骔',
-'騍' => '骒',
-'騎' => '骑',
-'騏' => '骐',
-'騐' => '验',
-'騔' => '𩨀',
-'騖' => '骛',
-'騙' => '骗',
-'騚' => '𩨊',
-'騝' => '𩨃',
-'騟' => '𩨈',
-'騠' => '𫘨',
-'騣' => '鬃',
-'騤' => '骙',
-'騧' => '䯄',
-'騪' => '𩨄',
-'騫' => '骞',
-'騭' => '骘',
-'騮' => '骝',
-'騰' => '腾',
-'騶' => '驺',
-'騷' => '骚',
-'騸' => '骟',
-'騾' => '骡',
-'驀' => '蓦',
-'驁' => '骜',
-'驂' => '骖',
-'驃' => '骠',
-'驄' => '骢',
-'驅' => '驱',
-'驊' => '骅',
-'驋' => '𩧯',
-'驌' => '骕',
-'驍' => '骁',
-'驏' => '骣',
-'驕' => '骄',
-'驗' => '验',
-'驘' => '骡',
-'驚' => '惊',
-'驛' => '驿',
-'驟' => '骤',
-'驢' => '驴',
-'驤' => '骧',
-'驥' => '骥',
-'驦' => '骦',
-'驪' => '骊',
-'驫' => '骉',
-'骯' => '肮',
-'骽' => '腿',
-'骾' => '鲠',
-'髈' => '膀',
-'髏' => '髅',
-'髒' => '脏',
-'體' => '体',
-'髕' => '髌',
-'髖' => '髋',
-'髥' => '髯',
-'髮' => '发',
-'鬀' => '剃',
-'鬆' => '松',
-'鬉' => '鬃',
-'鬍' => '胡',
-'鬚' => '须',
-'鬢' => '鬓',
-'鬥' => '斗',
-'鬦' => '斗',
-'鬧' => '闹',
-'鬨' => '哄',
-'鬩' => '阋',
-'鬪' => '斗',
-'鬮' => '阄',
-'鬰' => '郁',
-'鬱' => '郁',
-'鬹' => '鬶',
-'魎' => '魉',
-'魘' => '魇',
-'魚' => '鱼',
-'魛' => '鱽',
-'魟' => '𫚉',
-'魢' => '鱾',
-'魥' => '𩽹',
-'魨' => '鲀',
-'魯' => '鲁',
-'魴' => '鲂',
-'魷' => '鱿',
-'魺' => '鲄',
-'鮁' => '鲅',
-'鮃' => '鲆',
-'鮄' => '𫚒',
-'鮊' => '鲌',
-'鮋' => '鲉',
-'鮍' => '鲏',
-'鮎' => '鲇',
-'鮐' => '鲐',
-'鮑' => '鲍',
-'鮒' => '鲋',
-'鮓' => '鲊',
-'鮚' => '鲒',
-'鮜' => '鲘',
-'鮝' => '鲞',
-'鮞' => '鲕',
-'鮟' => '𩽾',
-'鮣' => '䲟',
-'鮦' => '鲖',
-'鮪' => '鲔',
-'鮫' => '鲛',
-'鮭' => '鲑',
-'鮮' => '鲜',
-'鮰' => '𫚔',
-'鮳' => '鲓',
-'鮶' => '鲪',
-'鮸' => '𩾃',
-'鮺' => '鲝',
-'鯀' => '鲧',
-'鯁' => '鲠',
-'鯄' => '𩾁',
-'鯆' => '𫚙',
-'鯇' => '鲩',
-'鯉' => '鲤',
-'鯊' => '鲨',
-'鯒' => '鲬',
-'鯔' => '鲻',
-'鯕' => '鲯',
-'鯖' => '鲭',
-'鯗' => '鲞',
-'鯛' => '鲷',
-'鯝' => '鲴',
-'鯡' => '鲱',
-'鯢' => '鲵',
-'鯤' => '鲲',
-'鯧' => '鲳',
-'鯨' => '鲸',
-'鯪' => '鲮',
-'鯫' => '鲰',
-'鯰' => '鲶',
-'鯱' => '𩾇',
-'鯴' => '鲺',
-'鯶' => '𩽼',
-'鯷' => '鳀',
-'鯽' => '鲫',
-'鯿' => '鳊',
-'鰁' => '鳈',
-'鰂' => '鲗',
-'鰃' => '鳂',
-'鰆' => '䲠',
-'鰈' => '鲽',
-'鰉' => '鳇',
-'鰌' => '䲡',
-'鰍' => '鳅',
-'鰏' => '鲾',
-'鰐' => '鳄',
-'鰒' => '鳆',
-'鰓' => '鳃',
-'鰛' => '鳁',
-'鰜' => '鳒',
-'鰟' => '鳑',
-'鰠' => '鳋',
-'鰣' => '鲥',
-'鰤' => '𫚕',
-'鰥' => '鳏',
-'鰧' => '䲢',
-'鰨' => '鳎',
-'鰩' => '鳐',
-'鰭' => '鳍',
-'鰮' => '鳁',
-'鰱' => '鲢',
-'鰲' => '鳌',
-'鰳' => '鳓',
-'鰵' => '鳘',
-'鰷' => '鲦',
-'鰹' => '鲣',
-'鰺' => '鲹',
-'鰻' => '鳗',
-'鰼' => '鳛',
-'鰾' => '鳔',
-'鱂' => '鳉',
-'鱅' => '鳙',
-'鱇' => '𩾌',
-'鱈' => '鳕',
-'鱉' => '鳖',
-'鱒' => '鳟',
-'鱔' => '鳝',
-'鱖' => '鳜',
-'鱗' => '鳞',
-'鱘' => '鲟',
-'鱝' => '鲼',
-'鱟' => '鲎',
-'鱠' => '鲙',
-'鱣' => '鳣',
-'鱤' => '鳡',
-'鱧' => '鳢',
-'鱨' => '鲿',
-'鱭' => '鲚',
-'鱮' => '𫚈',
-'鱯' => '鳠',
-'鱷' => '鳄',
-'鱸' => '鲈',
-'鱺' => '鲡',
-'鳥' => '鸟',
-'鳧' => '凫',
-'鳩' => '鸠',
-'鳬' => '凫',
-'鳲' => '鸤',
-'鳳' => '凤',
-'鳴' => '鸣',
-'鳶' => '鸢',
-'鳷' => '𫛛',
-'鳼' => '𪉃',
-'鳾' => '䴓',
-'鴃' => '𫛞',
-'鴆' => '鸩',
-'鴇' => '鸨',
-'鴈' => '雁',
-'鴉' => '鸦',
-'鴒' => '鸰',
-'鴕' => '鸵',
-'鴗' => '𫁡',
-'鴛' => '鸳',
-'鴜' => '𪉈',
-'鴝' => '鸲',
-'鴞' => '鸮',
-'鴟' => '鸱',
-'鴣' => '鸪',
-'鴦' => '鸯',
-'鴨' => '鸭',
-'鴯' => '鸸',
-'鴰' => '鸹',
-'鴲' => '𪉆',
-'鴴' => '鸻',
-'鴷' => '䴕',
-'鴻' => '鸿',
-'鴿' => '鸽',
-'鵁' => '䴔',
-'鵂' => '鸺',
-'鵃' => '鸼',
-'鵐' => '鹀',
-'鵑' => '鹃',
-'鵒' => '鹆',
-'鵓' => '鹁',
-'鵚' => '𪉍',
-'鵜' => '鹈',
-'鵝' => '鹅',
-'鵞' => '鹅',
-'鵠' => '鹄',
-'鵡' => '鹉',
-'鵪' => '鹌',
-'鵬' => '鹏',
-'鵮' => '鹐',
-'鵯' => '鹎',
-'鵰' => '雕',
-'鵲' => '鹊',
-'鵶' => '鸦',
-'鵷' => '鹓',
-'鵾' => '鹍',
-'鶄' => '䴖',
-'鶇' => '鸫',
-'鶉' => '鹑',
-'鶊' => '鹒',
-'鶒' => '𫛶',
-'鶓' => '鹋',
-'鶖' => '鹙',
-'鶗' => '𫛸',
-'鶘' => '鹕',
-'鶚' => '鹗',
-'鶡' => '鹖',
-'鶥' => '鹛',
-'鶩' => '鹜',
-'鶪' => '䴗',
-'鶬' => '鸧',
-'鶯' => '莺',
-'鶲' => '鹟',
-'鶴' => '鹤',
-'鶹' => '鹠',
-'鶺' => '鹡',
-'鶻' => '鹘',
-'鶼' => '鹣',
-'鶿' => '鹚',
-'鷀' => '鹚',
-'鷁' => '鹢',
-'鷂' => '鹞',
-'鷄' => '鸡',
-'鷈' => '䴘',
-'鷊' => '鹝',
-'鷓' => '鹧',
-'鷔' => '𪉑',
-'鷖' => '鹥',
-'鷗' => '鸥',
-'鷙' => '鸷',
-'鷚' => '鹨',
-'鷥' => '鸶',
-'鷦' => '鹪',
-'鷨' => '𪉊',
-'鷫' => '鹔',
-'鷯' => '鹩',
-'鷰' => '燕',
-'鷲' => '鹫',
-'鷳' => '鹇',
-'鷴' => '鹇',
-'鷸' => '鹬',
-'鷹' => '鹰',
-'鷺' => '鹭',
-'鷽' => '鸴',
-'鷿' => '䴙',
-'鸂' => '㶉',
-'鸇' => '鹯',
-'鸋' => '𫛢',
-'鸌' => '鹱',
-'鸎' => '莺',
-'鸏' => '鹲',
-'鸕' => '鸬',
-'鸘' => '鹴',
-'鸚' => '鹦',
-'鸛' => '鹳',
-'鸝' => '鹂',
-'鸞' => '鸾',
-'鹵' => '卤',
-'鹹' => '咸',
-'鹺' => '鹾',
-'鹻' => '碱',
-'鹼' => '碱',
-'鹽' => '盐',
-'麗' => '丽',
-'麥' => '麦',
-'麨' => '𪎊',
-'麩' => '麸',
-'麪' => '面',
-'麫' => '面',
-'麯' => '曲',
-'麲' => '𪎉',
-'麳' => '𪎌',
-'麴' => '麹',
-'麵' => '面',
-'麼' => '么',
-'麽' => '么',
-'黃' => '黄',
-'黌' => '黉',
-'點' => '点',
-'黨' => '党',
-'黲' => '黪',
-'黴' => '霉',
-'黶' => '黡',
-'黷' => '黩',
-'黽' => '黾',
-'黿' => '鼋',
-'鼃' => '蛙',
-'鼇' => '鳌',
-'鼈' => '鳖',
-'鼉' => '鼍',
-'鼕' => '咚',
-'鼴' => '鼹',
-'齊' => '齐',
-'齋' => '斋',
-'齎' => '赍',
-'齏' => '齑',
-'齒' => '齿',
-'齔' => '龀',
-'齕' => '龁',
-'齗' => '龂',
-'齙' => '龅',
-'齜' => '龇',
-'齟' => '龃',
-'齠' => '龆',
-'齡' => '龄',
-'齣' => '出',
-'齦' => '龈',
-'齧' => '啮',
-'齩' => '咬',
-'齪' => '龊',
-'齬' => '龉',
-'齲' => '龋',
-'齶' => '腭',
-'齷' => '龌',
-'龍' => '龙',
-'龎' => '厐',
-'龐' => '庞',
-'龑' => '䶮',
-'龔' => '龚',
-'龕' => '龛',
-'龜' => '龟',
-'龭' => '𩨎',
-'龯' => '𨱆',
-'𠌥' => '𠆿',
-'𠏢' => '𠉗',
-'𠕂' => '再',
-'𠕅' => '再',
-'𠞆' => '𠛆',
-'𠞰' => '剿',
-'𠠎' => '𠚳',
-'𡄔' => '𠴢',
-'𡄣' => '𠵸',
-'𡅏' => '𠲥',
-'𡑭' => '𡋗',
-'𡓾' => '𡋀',
-'𡚁' => '弊',
-'𡞵' => '㛟',
-'𡠹' => '㛿',
-'𡢃' => '㛠',
-'𡨥' => '寇',
-'𡮉' => '𡭜',
-'𡮣' => '𡭬',
-'𡻕' => '岁',
-'𡾱' => '㟜',
-'𢣚' => '𢘝',
-'𢣭' => '𢘞',
-'𢶫' => '𢫞',
-'𢷮' => '𢫊',
-'𢹿' => '𢬦',
-'𣙎' => '㭣',
-'𣙜' => '榷',
-'𣝕' => '𣘷',
-'𣞻' => '𣘓',
-'𣠲' => '𣑶',
-'𣯴' => '𣭤',
-'𣾷' => '㳢',
-'𣿉' => '𣶫',
-'𤁣' => '𣺽',
-'𤋮' => '熙',
-'𤒎' => '𤊀',
-'𤨏' => '琐',
-'𤪺' => '㻘',
-'𤫩' => '㻏',
-'𤱈' => '亩',
-'𤳸' => '𤳄',
-'𤸫' => '𤶧',
-'𤺥' => '瘩',
-'𥌃' => '𥅘',
-'𥕥' => '𥐰',
-'𥖅' => '𥐯',
-'𥢢' => '䅪',
-'𥨐' => '𥧂',
-'𥵃' => '𥱔',
-'𥵊' => '𥭉',
-'𥸠' => '𥮋',
-'𥼽' => '𥹥',
-'𥽖' => '𥺇',
-'𥿊' => '𦈈',
-'𦂅' => '𦈒',
-'𦃄' => '𦈗',
-'𦊱' => '挂',
-'𦍑' => '羌',
-'𦕈' => '眇',
-'𦢈' => '𣍨',
-'𦣎' => '𦟗',
-'𦪽' => '𦨩',
-'𦵏' => '葬',
-'𧔥' => '𧒭',
-'𧜗' => '䘞',
-'𧜵' => '䙊',
-'𧝞' => '䘛',
-'𧩙' => '䜥',
-'𧳟' => '𧳕',
-'𧵳' => '䞌',
-'𧶔' => '𧹓',
-'𧶧' => '䞎',
-'𨄣' => '𨀱',
-'𨅍' => '𨁴',
-'𨇁' => '𧿈',
-'𨇞' => '𨅫',
-'𨈊' => '𨂺',
-'𨈌' => '𨄄',
-'𨊰' => '䢀',
-'𨊸' => '䢁',
-'𨊻' => '𨐆',
-'𨋢' => '䢂',
-'𨎮' => '𨐉',
-'𨏠' => '𨐇',
-'𨏥' => '𨐊',
-'𨤻' => '𨤰',
-'𨥛' => '𨱀',
-'𨦫' => '䦀',
-'𨧜' => '䦁',
-'𨧱' => '𨱊',
-'𨫒' => '𨱐',
-'𨮂' => '𨱕',
-'𨯅' => '䥿',
-'𨳑' => '𨸁',
-'𨳕' => '𨸀',
-'𨴗' => '𨸅',
-'𨵩' => '𨸆',
-'𨵸' => '𨸇',
-'𨶀' => '𨸉',
-'𨶏' => '𨸊',
-'𨶮' => '𨸌',
-'𨶲' => '𨸋',
-'𨷲' => '𨸎',
-'𨽏' => '𨸘',
-'𨽻' => '隶',
-'𩎢' => '𩏾',
-'𩏪' => '𩏽',
-'𩓐' => '脖',
-'𩓣' => '𩖕',
-'𩗀' => '𩙦',
-'𩗗' => '飓',
-'𩗡' => '𩙧',
-'𩘀' => '𩙩',
-'𩘝' => '𩙭',
-'𩘹' => '𩙨',
-'𩘺' => '𩙬',
-'𩙈' => '𩙰',
-'𩚛' => '𩟿',
-'𩚥' => '𩠀',
-'𩚵' => '𩠁',
-'𩛆' => '𩠂',
-'𩛩' => '𩠃',
-'𩜇' => '𩠉',
-'𩜦' => '𩠆',
-'𩜵' => '𩠊',
-'𩝔' => '𩠋',
-'𩞄' => '𩠎',
-'𩞦' => '𩠏',
-'𩞯' => '䭪',
-'𩟐' => '𩠅',
-'𩠴' => '𩠠',
-'𩡺' => '𩧦',
-'𩢡' => '𩧬',
-'𩢴' => '𩧵',
-'𩢸' => '𩧳',
-'𩢾' => '𩧮',
-'𩣏' => '𩧶',
-'𩣑' => '䯃',
-'𩣵' => '𩧻',
-'𩣺' => '𩧼',
-'𩤊' => '𩧩',
-'𩤙' => '𩨆',
-'𩤲' => '𩨉',
-'𩤸' => '𩨅',
-'𩥄' => '𩨋',
-'𩥇' => '𩨍',
-'𩥉' => '𩧱',
-'𩥑' => '𩨌',
-'𩧆' => '𩨐',
-'𩭙' => '𩬣',
-'𩯳' => '𩯒',
-'𩰀' => '𩬤',
-'𩳤' => '𩲒',
-'𩵩' => '𩽺',
-'𩵹' => '𩽻',
-'𩶘' => '䲞',
-'𩶰' => '𩽿',
-'𩶱' => '𩽽',
-'𩷰' => '𩾄',
-'𩸃' => '𩾅',
-'𩸦' => '𩾆',
-'𩽇' => '𩾎',
-'𩿪' => '𪉄',
-'𪀦' => '𪉅',
-'𪀾' => '𪉋',
-'𪁈' => '𪉉',
-'𪁖' => '𪉌',
-'𪂆' => '𪉎',
-'𪃍' => '𪉐',
-'𪃏' => '𪉏',
-'𪄆' => '𪉔',
-'𪄕' => '𪉒',
-'𪇳' => '𪉕',
-'𪈼' => '𪉓',
-'𪋿' => '𪎍',
-'𪔵' => '𪔭',
-'𪘀' => '𪚏',
-'𪘯' => '𪚐',
-'『' => '‘',
-'』' => '’',
-'「' => '“',
-'「' => '“',
-'」' => '”',
-'」' => '”',
-'。陞' => '。升',
-'《易乾' => '《易乾',
-'一釐' => '一厘',
-'上昇' => '上升',
-'不穀' => '不穀',
-'專著' => '专著',
-'乾一坛' => '乾一坛',
-'乾一壇' => '乾一坛',
-'乾一組' => '乾一组',
-'乾一组' => '乾一组',
-'乾上乾下' => '乾上乾下',
-'乾东' => '乾东',
-'乾東' => '乾东',
-'乾為天' => '乾为天',
-'乾為陽' => '乾为阳',
-'乾九' => '乾九',
-'乾乾' => '乾乾',
-'乾亨' => '乾亨',
-'乾仪' => '乾仪',
-'乾儀' => '乾仪',
-'乾位' => '乾位',
-'乾健' => '乾健',
-'乾健也' => '乾健也',
-'乾元' => '乾元',
-'乾光' => '乾光',
-'乾兴' => '乾兴',
-'乾興' => '乾兴',
-'乾冈' => '乾冈',
-'乾岡' => '乾冈',
-'乾刘' => '乾刘',
-'乾劉' => '乾刘',
-'乾刚' => '乾刚',
-'乾剛' => '乾刚',
-'乾务' => '乾务',
-'乾務' => '乾务',
-'乾化' => '乾化',
-'乾卦' => '乾卦',
-'乾县' => '乾县',
-'乾縣' => '乾县',
-'乾台' => '乾台',
-'乾吉' => '乾吉',
-'乾启' => '乾启',
-'乾啟' => '乾启',
-'乾命' => '乾命',
-'乾和' => '乾和',
-'乾嘉' => '乾嘉',
-'乾图' => '乾图',
-'乾圖' => '乾图',
-'乾坤' => '乾坤',
-'乾城' => '乾城',
-'乾基' => '乾基',
-'乾天也' => '乾天也',
-'乾始' => '乾始',
-'乾姓' => '乾姓',
-'乾宁' => '乾宁',
-'乾寧' => '乾宁',
-'乾宅' => '乾宅',
-'乾宇' => '乾宇',
-'乾安' => '乾安',
-'乾定' => '乾定',
-'乾封' => '乾封',
-'乾居' => '乾居',
-'乾岗' => '乾岗',
-'乾崗' => '乾岗',
-'乾巛' => '乾巛',
-'乾州' => '乾州',
-'乾录' => '乾录',
-'乾錄' => '乾录',
-'乾律' => '乾律',
-'乾德' => '乾德',
-'乾心' => '乾心',
-'乾忠' => '乾忠',
-'乾文' => '乾文',
-'乾断' => '乾断',
-'乾斷' => '乾断',
-'乾方' => '乾方',
-'乾施' => '乾施',
-'乾旦' => '乾旦',
-'乾明' => '乾明',
-'乾昧' => '乾昧',
-'乾晖' => '乾晖',
-'乾暉' => '乾晖',
-'乾景' => '乾景',
-'乾晷' => '乾晷',
-'乾曜' => '乾曜',
-'乾构' => '乾构',
-'乾構' => '乾构',
-'乾枢' => '乾枢',
-'乾樞' => '乾枢',
-'乾栋' => '乾栋',
-'乾棟' => '乾栋',
-'乾步' => '乾步',
-'乾氏' => '乾氏',
-'乾沓和' => '乾沓和',
-'乾沓婆' => '乾沓婆',
-'乾泉' => '乾泉',
-'乾淳' => '乾淳',
-'乾清' => '乾清',
-'乾渥' => '乾渥',
-'乾潭' => '乾潭',
-'乾灵' => '乾灵',
-'乾靈' => '乾灵',
-'乾生元' => '乾生元',
-'乾男' => '乾男',
-'乾皋' => '乾皋',
-'乾盛世' => '乾盛世',
-'乾矢' => '乾矢',
-'乾祐' => '乾祐',
-'乾神' => '乾神',
-'乾穹' => '乾穹',
-'乾窦' => '乾窦',
-'乾竇' => '乾窦',
-'乾竺' => '乾竺',
-'乾笃' => '乾笃',
-'乾篤' => '乾笃',
-'乾符' => '乾符',
-'乾策' => '乾策',
-'乾精' => '乾精',
-'乾紅' => '乾红',
-'乾红' => '乾红',
-'乾綱' => '乾纲',
-'乾纲' => '乾纲',
-'乾紐' => '乾纽',
-'乾纽' => '乾纽',
-'乾絡' => '乾络',
-'乾络' => '乾络',
-'乾統' => '乾统',
-'乾统' => '乾统',
-'乾維' => '乾维',
-'乾维' => '乾维',
-'乾罗' => '乾罗',
-'乾羅' => '乾罗',
-'乾花' => '乾花',
-'乾荫' => '乾荫',
-'乾蔭' => '乾荫',
-'乾行' => '乾行',
-'乾衡' => '乾衡',
-'乾西' => '乾西',
-'乾覆' => '乾覆',
-'乾象' => '乾象',
-'乾象历' => '乾象历',
-'乾象歷' => '乾象历',
-'乾貞' => '乾贞',
-'乾贞' => '乾贞',
-'乾貴士' => '乾贵士',
-'乾贵士' => '乾贵士',
-'乾貺' => '乾贶',
-'乾贶' => '乾贶',
-'乾車' => '乾车',
-'乾车' => '乾车',
-'乾軸' => '乾轴',
-'乾轴' => '乾轴',
-'乾通' => '乾通',
-'乾造' => '乾造',
-'乾道' => '乾道',
-'乾鉴' => '乾鉴',
-'乾鑒' => '乾鉴',
-'乾鈞' => '乾钧',
-'乾钧' => '乾钧',
-'乾闥' => '乾闼',
-'乾闼' => '乾闼',
-'乾陀' => '乾陀',
-'乾陵' => '乾陵',
-'乾隆' => '乾隆',
-'乾音' => '乾音',
-'乾顧' => '乾顾',
-'乾顾' => '乾顾',
-'乾風' => '乾风',
-'乾风' => '乾风',
-'乾首' => '乾首',
-'乾馬' => '乾马',
-'乾马' => '乾马',
-'乾鵠' => '乾鹄',
-'乾鹄' => '乾鹄',
-'乾鵲' => '乾鹊',
-'乾鹊' => '乾鹊',
-'乾龍' => '乾龙',
-'乾龙' => '乾龙',
-'乾,健也' => '乾,健也',
-'乾,天也' => '乾,天也',
-'五箇山' => '五箇山',
-'什么' => '什么',
-'仇讎' => '仇雠',
-'以微知著' => '以微知著',
-'仰屋著書' => '仰屋著书',
-'彷彿' => '仿佛',
-'夥計' => '伙计',
-'佛頭著糞' => '佛头著粪',
-'偵蒐' => '侦搜',
-'倖一郎' => '倖一郎',
-'倖田' => '倖田',
-'候覆' => '候复',
-'藉助' => '借助',
-'藉口' => '借口',
-'藉手' => '借手',
-'藉故' => '借故',
-'藉機' => '借机',
-'藉此' => '借此',
-'藉由' => '借由',
-'藉端' => '借端',
-'藉詞' => '借词',
-'傒倖' => '傒倖',
-'先名後姓' => '先名后姓',
-'兒寬' => '兒宽',
-'六么' => '六幺',
-'蘭質薰心' => '兰质薰心',
-'內聯陞' => '内联升',
-'憑藉' => '凭借',
-'初昇' => '初升',
-'利欲薰心' => '利欲薰心',
-'剋了' => '剋了',
-'剋架' => '剋架',
-'剖釐' => '剖厘',
-'陞為' => '升为',
-'陞了' => '升了',
-'昇仙' => '升仙',
-'陞任' => '升任',
-'昇華' => '升华',
-'昇天' => '升天',
-'陞官' => '升官',
-'昇平' => '升平',
-'昇汞' => '升汞',
-'陞用' => '升用',
-'陞補' => '升补',
-'陞遷' => '升迁',
-'昇降' => '升降',
-'卓著' => '卓著',
-'博和託' => '博和讬',
-'歷陞' => '历升',
-'釐改' => '厘改',
-'釐整' => '厘整',
-'釐正' => '厘正',
-'釐毫' => '厘毫',
-'釐清' => '厘清',
-'釐訂' => '厘订',
-'釐革' => '厘革',
-'原著' => '原著',
-'又陞' => '又升',
-'反反覆覆' => '反反复复',
-'反覆' => '反复',
-'可穿著' => '可穿著',
-'吃衣著飯' => '吃衣著饭',
-'合著' => '合著',
-'同陞和' => '同升和',
-'名著' => '名著',
-'吳克羣' => '吴克羣',
-'周易乾' => '周易乾',
-'諠譁' => '喧哗',
-'回覆' => '回复',
-'土著' => '土著',
-'坤乾' => '坤乾',
-'墨瀋' => '墨渖',
-'覆查' => '复查',
-'覆核' => '复核',
-'覆检' => '复检',
-'復甦' => '复苏',
-'多么' => '多么',
-'大麴' => '大曲',
-'天道为乾' => '天道为乾',
-'天道為乾' => '天道为乾',
-'奧區' => '奧区',
-'如瀋' => '如渖',
-'姓么' => '姓幺',
-'子餘' => '子馀',
-'字乾生' => '字乾生',
-'孙乾' => '孙乾',
-'孫乾' => '孙乾',
-'宏碁' => '宏碁',
-'官陞' => '官升',
-'將軍抽俥' => '将军抽俥',
-'將軍抽車' => '将军抽車',
-'爾冬陞' => '尔冬升',
-'尼乾陀' => '尼乾陀',
-'侷促' => '局促',
-'跼促' => '局促',
-'侷限' => '局限',
-'跼限' => '局限',
-'山崎闇齋' => '山崎闇斋',
-'岳託' => '岳讬',
-'巨著' => '巨著',
-'乾乾淨淨' => '干干净净',
-'乾乾脆脆' => '干干脆脆',
-'乾泉水' => '干泉水',
-'年陞' => '年升',
-'么九' => '幺九',
-'么二三' => '幺二三',
-'么元' => '幺元',
-'么鳳' => '幺凤',
-'么半' => '幺半',
-'么半群' => '幺半群',
-'么廝' => '幺厮',
-'幺厮' => '幺厮',
-'么叔' => '幺叔',
-'么女' => '幺女',
-'么媽' => '幺妈',
-'么妹' => '幺妹',
-'么姓' => '幺姓',
-'么姨' => '幺姨',
-'么娘' => '幺娘',
-'么孃' => '幺娘',
-'幺孃' => '幺娘',
-'么子' => '幺子',
-'么小' => '幺小',
-'么弟' => '幺弟',
-'么正' => '幺正',
-'么氏' => '幺氏',
-'么爸' => '幺爸',
-'么爹' => '幺爹',
-'么篇' => '幺篇',
-'么舅' => '幺舅',
-'么蛾子' => '幺蛾子',
-'么謙' => '幺谦',
-'么麼' => '幺麽',
-'么麽' => '幺麽',
-'么麽小丑' => '幺麽小丑',
-'慶餘' => '庆馀',
-'康乾' => '康乾',
-'张法乾' => '张法乾',
-'張法乾' => '张法乾',
-'彰明較著' => '彰明较著',
-'待覆' => '待复',
-'後姓' => '後姓',
-'慫慂' => '怂恿',
-'怎么' => '怎么',
-'恩威並著' => '恩威并著',
-'噁心' => '恶心',
-'情蒐' => '情搜',
-'情鍾' => '情钟',
-'惏悷' => '惏悷',
-'惏慄' => '惏慄',
-'慘澹' => '惨淡',
-'成效顯著' => '成效显著',
-'成績顯著' => '成绩显著',
-'所鍾' => '所钟',
-'手鍊' => '手链',
-'扞格' => '扞格',
-'執著' => '执著',
-'批覆' => '批复',
-'承乾' => '承乾',
-'拉鍊' => '拉链',
-'拙著' => '拙著',
-'拚命' => '拚命',
-'拚搏' => '拚搏',
-'拚死' => '拚死',
-'拾瀋' => '拾渖',
-'拿破崙' => '拿破仑',
-'挨剋' => '挨剋',
-'提昇' => '提升',
-'蒐錄' => '搜录',
-'蒐索' => '搜索',
-'蒐羅' => '搜罗',
-'蒐藏' => '搜藏',
-'蒐證' => '搜证',
-'蒐購' => '搜购',
-'蒐輯' => '搜辑',
-'蒐採' => '搜采',
-'蒐采' => '搜采',
-'蒐集' => '搜集',
-'搥打' => '搥打',
-'搥胸頓足' => '搥胸顿足',
-'撰著' => '撰著',
-'效果顯著' => '效果显著',
-'文徵明' => '文徵明',
-'觔斗' => '斤斗',
-'新著' => '新著',
-'於世成' => '於世成',
-'於之瑩' => '於之莹',
-'於之莹' => '於之莹',
-'於乎' => '於乎',
-'於乙于同' => '於乙于同',
-'於乙宇同' => '於乙宇同',
-'於于同' => '於于同',
-'於哲' => '於哲',
-'於夫罗' => '於夫罗',
-'於夫羅' => '於夫罗',
-'於姓' => '於姓',
-'於宇同' => '於宇同',
-'於崇文' => '於崇文',
-'於志賀' => '於志贺',
-'於志贺' => '於志贺',
-'於戲' => '於戏',
-'於梨华' => '於梨华',
-'於梨華' => '於梨华',
-'於氏' => '於氏',
-'於潜' => '於潜',
-'於潛縣' => '於潜县',
-'於祥玉' => '於祥玉',
-'於菟' => '於菟',
-'於賢德' => '於贤德',
-'於除鞬' => '於除鞬',
-'施讎' => '施雠',
-'旋乾轉坤' => '旋乾转坤',
-'旋乾转坤' => '旋乾转坤',
-'無言不讎' => '无言不雠',
-'曠若發矇' => '旷若发矇',
-'崑崙' => '昆仑',
-'崑劇' => '昆剧',
-'崑山' => '昆山',
-'崑曲' => '昆曲',
-'崑腔' => '昆腔',
-'崑蘇' => '昆苏',
-'崑調' => '昆调',
-'易·乾' => '易·乾',
-'易經·乾' => '易经·乾',
-'易经·乾' => '易经·乾',
-'易經乾' => '易经乾',
-'易经乾' => '易经乾',
-'昭著' => '昭著',
-'顯著' => '显著',
-'顯著地' => '显著地',
-'顯著地位' => '显著地位',
-'顯著性' => '显著性',
-'顯著成績' => '显著成绩',
-'顯著效果' => '显著效果',
-'顯著特點' => '显著特点',
-'晉陞' => '晋升',
-'暗闇' => '暗闇',
-'麴黴' => '曲霉',
-'曾运乾' => '曾运乾',
-'曾運乾' => '曾运乾',
-'月陞' => '月升',
-'朝乾夕惕' => '朝乾夕惕',
-'朱有燉' => '朱有燉',
-'朱淛' => '朱淛',
-'硃砂' => '朱砂',
-'硃紅' => '朱红',
-'硃色' => '朱色',
-'朴於宇同' => '朴於宇同',
-'李乾德' => '李乾德',
-'李乾順' => '李乾顺',
-'李乾顺' => '李乾顺',
-'李澤鉅' => '李泽钜',
-'李祕' => '李祕',
-'李譔' => '李譔',
-'柳詒徵' => '柳诒徵',
-'柳诒徵' => '柳诒徵',
-'校讎' => '校雠',
-'楈枒' => '楈枒',
-'樊於期' => '樊於期',
-'殘瀋' => '残渖',
-'慇勤' => '殷勤',
-'慇懃' => '殷勤',
-'比較顯著' => '比较显著',
-'毫釐' => '毫厘',
-'氆氌' => '氆氌',
-'沈沒' => '沉没',
-'沈澱' => '沉淀',
-'沈積' => '沉积',
-'沈船' => '沉船',
-'沈重' => '沉重',
-'沈默' => '沉默',
-'氾濫' => '泛滥',
-'洗鍊' => '洗练',
-'瀋液' => '渖液',
-'薰習' => '熏习',
-'薰心' => '熏心',
-'薰沐' => '熏沐',
-'薰陶' => '熏陶',
-'薰香' => '熏香',
-'爨翫' => '爨翫',
-'獨鍾' => '独钟',
-'王道乾' => '王道乾',
-'王餘魚' => '王馀鱼',
-'甚夥' => '甚夥',
-'男为乾' => '男为乾',
-'男為乾' => '男为乾',
-'男性为乾' => '男性为乾',
-'男性為乾' => '男性为乾',
-'療效顯著' => '疗效显著',
-'白瀋' => '白渖',
-'皁保' => '皁保',
-'目劄' => '目劄',
-'直昇' => '直升',
-'睹微知著' => '睹微知著',
-'瞭台' => '瞭台',
-'瞭臺' => '瞭台',
-'瞭望' => '瞭望',
-'矇眬' => '矇眬',
-'矇矓' => '矇眬',
-'石碁' => '石碁',
-'石碁鎮' => '石碁镇',
-'碩託' => '硕讬',
-'鹼菜' => '硷菜',
-'碁圣' => '碁圣',
-'碁聖' => '碁圣',
-'碁所' => '碁所',
-'祕宜' => '祕宜',
-'穀旦' => '穀旦',
-'穀梁' => '穀梁',
-'穀水' => '穀水',
-'穀阳' => '穀阳',
-'穀陽' => '穀阳',
-'穿著者' => '穿着者',
-'竹昇' => '竹升',
-'答覆' => '答复',
-'米泽瑠美' => '米泽瑠美',
-'米瀋' => '米渖',
-'餬口' => '糊口',
-'繙㠾' => '繙㠾',
-'遶境' => '绕境',
-'線國安' => '缐国安',
-'線姓' => '缐姓',
-'編著' => '编著',
-'老么' => '老幺',
-'肉乾乾' => '肉干干',
-'肘手鍊足' => '肘手链足',
-'甦醒' => '苏醒',
-'苧烯' => '苧烯',
-'薴烯' => '苧烯',
-'蘋果' => '苹果',
-'荠苧' => '荠苧',
-'榮陞' => '荣升',
-'萧乾' => '萧乾',
-'蕭乾' => '萧乾',
-'著書' => '著书',
-'著書立說' => '著书立说',
-'著作' => '著作',
-'著名' => '著名',
-'著錄' => '著录',
-'著錄規則' => '著录规则',
-'著文' => '著文',
-'著有' => '著有',
-'著稱' => '著称',
-'著者' => '著者',
-'著身' => '著身',
-'著述' => '著述',
-'蔡孝乾' => '蔡孝乾',
-'蔡絛' => '蔡絛',
-'行餘' => '行馀',
-'覆蓋' => '覆盖',
-'見微知著' => '见微知著',
-'見著' => '见著',
-'視微知著' => '视微知著',
-'言幾析理' => '言幾析理',
-'諲譔' => '諲譔',
-'譩譆' => '譩譆',
-'託庸' => '讬庸',
-'託恩多' => '讬恩多',
-'託麻' => '讬麻',
-'論著' => '论著',
-'譯著' => '译著',
-'謝肇淛' => '谢肇淛',
-'象乾' => '象乾',
-'躊躇滿志' => '踌躇滿志',
-'較著' => '较著',
-'近角聪信' => '近角聪信',
-'这么' => '这么',
-'造麴' => '造曲',
-'遺著' => '遗著',
-'那么' => '那么',
-'那麽' => '那麽',
-'郭子乾' => '郭子乾',
-'酒麴' => '酒曲',
-'醉瀋' => '醉渖',
-'醯壶' => '醯壶',
-'醯壺' => '醯壶',
-'醯酱' => '醯酱',
-'醯醬' => '醯酱',
-'醯醋' => '醯醋',
-'醯醢' => '醯醢',
-'醯雞' => '醯鸡',
-'醯鸡' => '醯鸡',
-'重覆' => '重复',
-'金鍊' => '金链',
-'鍾情' => '钟情',
-'鍾意' => '钟意',
-'鍾靈' => '钟灵',
-'鍾愛' => '钟爱',
-'鐵鍊' => '铁链',
-'鉸鍊' => '铰链',
-'銀硃' => '银朱',
-'銀鍊' => '银链',
-'鍊子' => '链子',
-'鍊條' => '链条',
-'鍊表' => '链表',
-'鍊鎖' => '链锁',
-'鍊錘' => '链锤',
-'鎖鍊' => '锁链',
-'闇公' => '闇公',
-'閻懷禮' => '闫怀礼',
-'阳为乾' => '阳为乾',
-'陽為乾' => '阳为乾',
-'阿部正瞭' => '阿部正瞭',
-'陆徵祥' => '陆徵祥',
-'陸徵祥' => '陆徵祥',
-'陈乾生' => '陈乾生',
-'陳乾生' => '陈乾生',
-'陈元扞' => '陈元扞',
-'陳元扞' => '陈元扞',
-'陈公乾生' => '陈公乾生',
-'陳公乾生' => '陈公乾生',
-'陈遇乾' => '陈遇乾',
-'陳遇乾' => '陈遇乾',
-'陳堵' => '陳堵',
-'陳禕' => '陳禕',
-'雍乾' => '雍乾',
-'讎夷' => '雠夷',
-'讎定' => '雠定',
-'讎校' => '雠校',
-'讎正' => '雠正',
-'讎問' => '雠问',
-'項鍊' => '项链',
-'飛昇' => '飞升',
-'飭令' => '飭令',
-'飽託' => '饱讬',
-'餘慶' => '馀庆',
-'餘瀋' => '馀渖',
-'馬鞌' => '马鞍',
-'高昇' => '高升',
-'高陞' => '高升',
-'鬱姓' => '鬱姓',
-'鬱氏' => '鬱氏',
-'魏徵' => '魏徵',
-'魚乾乾' => '鱼干干',
-'麽氏' => '麽氏',
-'麼麼' => '麽麽',
-'麽麽' => '麽麽',
-'黃麴毒素' => '黄曲毒素',
-'黃潤乾' => '黄润乾',
-'黄润乾' => '黄润乾',
-'龍鍾' => '龙钟',
-',陞' => ',升',
-);
-
-$zh2TW = array(
-'0字节' => '0位元組',
-'0杆' => '0桿',
-'1字节' => '1位元組',
-'1杆' => '1桿',
-'2字节' => '2位元組',
-'2杆' => '2桿',
-'3字节' => '3位元組',
-'3杆' => '3桿',
-'4字节' => '4位元組',
-'4杆' => '4桿',
-'5字节' => '5位元組',
-'5杆' => '5桿',
-'6字节' => '6位元組',
-'6杆' => '6桿',
-'7字节' => '7位元組',
-'7杆' => '7桿',
-'8字节' => '8位元組',
-'8杆' => '8桿',
-'9字节' => '9位元組',
-'9杆' => '9桿',
-'甲型肝炎' => 'A型肝炎',
-'甲肝' => 'A肝',
-'乙型肝炎' => 'B型肝炎',
-'乙肝' => 'B肝',
-'丙型肝炎' => 'C型肝炎',
-'丙肝' => 'C肝',
-'IP地址' => 'IP位址',
-'乔戈里峰' => 'K2',
-'·威尔士' => '·威爾士',
-'·威爾士' => '·威爾士',
-'一杆' => '一桿',
-'七杆' => '七桿',
-'三杆' => '三桿',
-'三极管' => '三極體',
-'三極管' => '三極體',
-'达累斯萨拉姆' => '三蘭港',
-'上落客' => '上下客',
-'落車' => '下車',
-'不來梅' => '不萊梅',
-'不来梅' => '不萊梅',
-'以太网' => '乙太網',
-'九杆' => '九桿',
-'了結他' => '了結他',
-'二手烟' => '二手菸',
-'二手煙' => '二手菸',
-'二杆' => '二桿',
-'二极管' => '二極體',
-'二極管' => '二極體',
-'交互设计' => '互動設計',
-'五杆' => '五桿',
-'阿塞拜疆' => '亞塞拜然',
-'阿斯旺' => '亞斯文',
-'人工智能' => '人工智慧',
-'人机交互' => '人機互動',
-'行人路' => '人行道',
-'石勒苏益格' => '什勒斯維希',
-'石勒蘇益格' => '什勒斯維希',
-'界面' => '介面',
-'伊利诺伊州' => '伊利諾州',
-'伊斯坦布尔' => '伊斯坦堡',
-'伊斯坦布爾' => '伊斯坦堡',
-'伊斯兰堡' => '伊斯蘭瑪巴德',
-'伊斯蘭堡' => '伊斯蘭瑪巴德',
-'埃博拉' => '伊波拉',
-'伊丽莎白' => '伊莉莎白',
-'俯卧撑' => '伏地挺身',
-'掌上壓' => '伏地挺身',
-'伯明翰' => '伯明罕',
-'服务器' => '伺服器',
-'佛罗伦萨' => '佛羅倫斯',
-'操作系统' => '作業系統',
-'系数' => '係數',
-'避孕套' => '保險套',
-'傅里叶' => '傅立葉',
-'光盘' => '光碟',
-'光驱' => '光碟機',
-'开普勒' => '克卜勒',
-'開普勒' => '克卜勒',
-'克罗地亚' => '克羅埃西亞',
-'克羅地亞' => '克羅埃西亞',
-'克里斯托弗' => '克里斯多福',
-'万维网' => '全球資訊網',
-'八杆' => '八桿',
-'公共交通' => '公共運輸',
-'六杆' => '六桿',
-'凯瑟琳' => '凱薩琳',
-'嘉芙蓮' => '凱薩琳',
-'划着独木舟' => '划著獨木舟',
-'划着竹筏' => '划著竹筏',
-'划着船' => '划著船',
-'打印' => '列印',
-'列支敦士登' => '列支敦斯登',
-'前波美拉尼亚' => '前波莫瑞',
-'前波美拉尼亞' => '前波莫瑞',
-'加蓬' => '加彭',
-'加沙地带' => '加薩走廊',
-'加沙地帶' => '加薩走廊',
-'包豪斯' => '包浩斯',
-'北朝鲜' => '北韓',
-'局域网' => '區域網',
-'局域网络' => '區域網路',
-'十杆' => '十桿',
-'特立尼达和托巴哥' => '千里達托貝哥',
-'特立尼達和多巴哥' => '千里達托貝哥',
-'南朝鲜' => '南韓',
-'卡斯特罗' => '卡斯楚',
-'卡塔尔' => '卡達',
-'卡塔爾' => '卡達',
-'铆足' => '卯足',
-'打印机' => '印表機',
-'打印機' => '印表機',
-'厄利垂亚' => '厄利垂亞',
-'厄立特里亚' => '厄利垂亞',
-'厄立特里亞' => '厄利垂亞',
-'厄瓜多' => '厄瓜多',
-'厄瓜多尔' => '厄瓜多',
-'厄瓜多爾' => '厄瓜多',
-'源代码' => '原始碼',
-'圆珠笔' => '原子筆',
-'反烟' => '反菸',
-'反煙' => '反菸',
-'可卡因' => '古柯鹼',
-'便携式' => '可攜式',
-'叱咤' => '叱吒',
-'叱咤9' => '叱咤9',
-'叱咤M' => '叱咤M',
-'叱咤叱' => '叱咤叱',
-'叱咤咤' => '叱咤咤',
-'叱咤樂壇' => '叱咤樂壇',
-'斯坦福大学' => '史丹福大學',
-'斯皮尔伯格' => '史匹柏',
-'斯特劳斯' => '史特勞斯',
-'斯威士兰' => '史瓦濟蘭',
-'斯威士蘭' => '史瓦濟蘭',
-'斯蒂芬' => '史蒂芬',
-'斯大林' => '史達林',
-'結他' => '吉他',
-'乞力馬札羅' => '吉力馬札羅',
-'乞力马扎罗' => '吉力馬札羅',
-'吉布堤' => '吉布地',
-'吉布提' => '吉布地',
-'基里巴斯' => '吉里巴斯',
-'图瓦卢' => '吐瓦魯',
-'圖瓦盧' => '吐瓦魯',
-'吸烟' => '吸菸',
-'吸煙' => '吸菸',
-'吕宋烟' => '呂宋菸',
-'呂宋煙' => '呂宋菸',
-'格丁根' => '哥廷根',
-'哥特式' => '哥德式',
-'哥斯达黎加' => '哥斯大黎加',
-'哥斯達黎加' => '哥斯大黎加',
-'卡拉奇' => '喀拉蚩',
-'乔治·奥威尔' => '喬治·歐威爾',
-'佐治亚' => '喬治亞',
-'佐治亞' => '喬治亞',
-'格魯吉亞' => '喬治亞',
-'格鲁吉亚' => '喬治亞',
-'单反相机' => '單眼相機',
-'單鏡反光機' => '單眼相機',
-'嘯咤' => '嘯吒',
-'四杆' => '四桿',
-'图卢兹' => '土魯斯',
-'圖盧茲' => '土魯斯',
-'戛纳' => '坎城',
-'堪培拉' => '坎培拉',
-'坦桑尼亚' => '坦尚尼亞',
-'坦桑尼亞' => '坦尚尼亞',
-'端口' => '埠',
-'首席执行官' => '執行長',
-'报道' => '報導',
-'塑料袋' => '塑膠袋',
-'塞舌尔' => '塞席爾',
-'塞舌爾' => '塞席爾',
-'萨拉热窝' => '塞拉耶佛',
-'薩拉熱窩' => '塞拉耶佛',
-'塞尔维亚和黑山' => '塞爾維亞與蒙特內哥羅',
-'塞爾維亞和黑山' => '塞爾維亞與蒙特內哥羅',
-'塞爾維亞與蒙特內哥羅' => '塞爾維亞與蒙特內哥羅',
-'塞维利亚' => '塞維亞',
-'西維爾' => '塞維亞',
-'塞黑' => '塞蒙',
-'共和联邦' => '大英國協',
-'英联邦' => '大英國協',
-'英聯邦' => '大英國協',
-'太空飛行員' => '太空人',
-'宇航员' => '太空人',
-'穿梭機' => '太空梭',
-'航天飞机' => '太空梭',
-'宇航服' => '太空衣',
-'航天器' => '太空飛行器',
-'尼日利亚' => '奈及利亞',
-'尼日利亞' => '奈及利亞',
-'忌廉' => '奶油',
-'荷里活' => '好萊塢',
-'威廉姆斯' => '威廉士',
-'威斯特法伦' => '威斯伐倫',
-'威斯特法倫' => '威斯伐倫',
-'威士顿康星' => '威斯康辛',
-'威尔士' => '威爾斯',
-'威爾士' => '威爾斯',
-'字库' => '字型檔',
-'存盘' => '存檔',
-'孟德爾遜' => '孟德爾頌',
-'门德尔松' => '孟德爾頌',
-'安哈尔特' => '安哈特',
-'安哈爾特' => '安哈特',
-'安提瓜和巴布达' => '安地卡及巴布達',
-'安提瓜和巴布達' => '安地卡及巴布達',
-'洪都拉斯' => '宏都拉斯',
-'密歇根' => '密西根',
-'宽带' => '寬頻',
-'老挝人民民主共和国' => '寮人民民主共和國',
-'老撾人民民主共和國' => '寮人民民主共和國',
-'老挝' => '寮國',
-'老撾' => '寮國',
-'老挝语' => '寮語',
-'老撾語' => '寮語',
-'波里活' => '寶萊塢',
-'对着干' => '對著幹',
-'高峰时段' => '尖峰時段',
-'高峰时间' => '尖峰時間',
-'贊比亞' => '尚比亞',
-'赞比亚' => '尚比亞',
-'尼克松' => '尼克森',
-'尼日尔' => '尼日',
-'尼日爾' => '尼日',
-'雅马哈' => '山葉',
-'机床' => '工具機',
-'機床' => '工具機',
-'珍寶客機' => '巨無霸客機',
-'发达国家' => '已開發國家',
-'巴塞罗那' => '巴塞隆納',
-'巴塞隆拿' => '巴塞隆納',
-'巴布亚新几内亚' => '巴布亞紐幾內亞',
-'巴布亞新畿內亞' => '巴布亞紐幾內亞',
-'巴士拉' => '巴斯拉',
-'巴巴多斯' => '巴貝多',
-'佈' => '布',
-'布基納法索' => '布吉納法索',
-'布基纳法索' => '布吉納法索',
-'布什' => '布希',
-'布殊' => '布希',
-'勃兰登堡' => '布蘭登堡',
-'勃蘭登堡' => '布蘭登堡',
-'布里斯托尔' => '布里斯托',
-'布隆方丹' => '布隆泉',
-'希拉莉' => '希拉蕊',
-'希拉里' => '希拉蕊',
-'希特拉' => '希特勒',
-'巴尔米拉环礁' => '帕邁拉環礁',
-'帕劳' => '帛琉',
-'希拉克' => '席哈克',
-'账' => '帳',
-'干着急' => '干著急',
-'干着' => '幹著',
-'畿內亞' => '幾內亞',
-'几内亚比绍' => '幾內亞比索',
-'幾內亞比紹' => '幾內亞比索',
-'比利牛斯' => '庇里牛斯',
-'库尔德人' => '庫德人',
-'库尔德族' => '庫德族',
-'康涅狄格' => '康乃狄克',
-'约翰斯顿岛' => '強斯頓環礁',
-'汇编' => '彙編',
-'形而上学' => '形上學',
-'形而上學' => '形上學',
-'得克萨斯' => '德克薩斯',
-'得克薩斯' => '德克薩斯',
-'德累斯頓' => '德勒斯登',
-'德累斯顿' => '德勒斯登',
-'德里达' => '德希達',
-'特拉华' => '德拉瓦',
-'特拉華' => '德拉瓦',
-'快闪存储器' => '快閃記憶體',
-'闪存' => '快閃記憶體',
-'想象' => '想像',
-'愛德文' => '愛德溫',
-'艾滋' => '愛滋',
-'艾奧瓦' => '愛荷華',
-'爱德华州' => '愛達荷州',
-'应用程序' => '應用程式',
-'戈尔巴乔夫' => '戈巴契夫',
-'戈爾巴喬夫' => '戈巴契夫',
-'戒烟' => '戒菸',
-'戒煙' => '戒菸',
-'戴克里先' => '戴克里先',
-'打印度' => '打印度',
-'抽烟' => '抽菸',
-'抽煙' => '抽菸',
-'拉普兰' => '拉布蘭',
-'拒烟' => '拒菸',
-'拒煙' => '拒菸',
-'卷烟' => '捲菸',
-'捲煙' => '捲菸',
-'積架' => '捷豹',
-'控件' => '控制項',
-'推杆' => '推桿',
-'第比利斯' => '提比里西',
-'挥杆' => '揮桿',
-'揮杆' => '揮桿',
-'搜索引擎' => '搜尋引擎',
-'摩根士丹利' => '摩根史坦利',
-'台球' => '撞球',
-'攻打' => '攻打',
-'数字化' => '數位化',
-'數碼化' => '數位化',
-'数字技术' => '數位技術',
-'數碼技術' => '數位技術',
-'数字照相机' => '數位照相機',
-'数码照相机' => '數位照相機',
-'數碼照相機' => '數位照相機',
-'数码相机' => '數位相機',
-'數碼相機' => '數位相機',
-'数字信号' => '數位訊號',
-'數碼訊號' => '數位訊號',
-'数字电视' => '數位電視',
-'數碼電視' => '數位電視',
-'調制解調器' => '數據機',
-'调制解调器' => '數據機',
-'斯洛文尼亚' => '斯洛維尼亞',
-'斯洛文尼亞' => '斯洛維尼亞',
-'新罕布什尔' => '新罕布夏',
-'施罗德' => '施洛德',
-'旱烟' => '旱菸',
-'旱煙' => '旱菸',
-'普利策' => '普利茲',
-'芯片' => '晶片',
-'智能卡' => '智慧卡',
-'智能手机' => '智慧型手機',
-'智能手機' => '智慧型手機',
-'智能电话' => '智慧型電話',
-'智能電話' => '智慧型電話',
-'知識產權' => '智慧財產權',
-'知识产权' => '智慧財產權',
-'萌島' => '曼島',
-'马恩岛' => '曼島',
-'木杆' => '木桿',
-'列奥纳多' => '李奧納多',
-'杜塞尔多夫' => '杜塞道夫',
-'杜塞爾多夫' => '杜塞道夫',
-'迪拜' => '杜拜',
-'东盟' => '東協',
-'亚细安' => '東協',
-'東盟' => '東協',
-'东南亚国家联盟' => '東南亞國家協會',
-'東南亞國家聯盟' => '東南亞國家協會',
-'柏林墙' => '柏林圍牆',
-'柏林牆' => '柏林圍牆',
-'乍得' => '查德',
-'查韦斯' => '查維茲',
-'克林頓' => '柯林頓',
-'克林顿' => '柯林頓',
-'戴卓爾' => '柴契爾',
-'撒切尔' => '柴契爾',
-'格林納達' => '格瑞那達',
-'格林纳达' => '格瑞那達',
-'桃金娘' => '桃金孃',
-'台式电脑' => '桌上型電腦',
-'乒乓' => '桌球',
-'乒乓球' => '桌球',
-'杆弟' => '桿弟',
-'杆身' => '桿身',
-'杆头' => '桿頭',
-'杆頭' => '桿頭',
-'梅尔·吉布森' => '梅爾·吉勃遜',
-'梵高' => '梵谷',
-'桑巴舞' => '森巴舞',
-'榴莲' => '榴槤',
-'榴蓮' => '榴槤',
-'枪支' => '槍枝',
-'标准杆' => '標準桿',
-'標準杆' => '標準桿',
-'毛里求斯' => '模里西斯',
-'毛里裘斯' => '模里西斯',
-'机器人' => '機器人',
-'機械人' => '機器人',
-'概率' => '機率',
-'電單車' => '機車',
-'枱' => '檯',
-'字段' => '欄位',
-'奥巴马' => '歐巴馬',
-'奧巴馬' => '歐巴馬',
-'正在叱咤' => '正在叱咤',
-'文莱' => '汶萊',
-'沙律' => '沙拉',
-'沙地阿拉伯' => '沙烏地阿拉伯',
-'沙特阿拉伯' => '沙烏地阿拉伯',
-'法属圭亚那' => '法屬蓋亞那',
-'波斯尼亚' => '波士尼亞',
-'波斯尼亞' => '波士尼亞',
-'波斯尼亚和黑塞哥维那' => '波士尼亞赫塞哥維納',
-'波斯尼亞黑塞哥維那' => '波士尼亞赫塞哥維納',
-'博茨瓦納' => '波札那',
-'博茨瓦纳' => '波札那',
-'波黑' => '波赫',
-'洋烟' => '洋菸',
-'洋煙' => '洋菸',
-'帕特里克' => '派屈克',
-'海洛英' => '海洛因',
-'侯賽因' => '海珊',
-'侯赛因' => '海珊',
-'鼠标' => '滑鼠',
-'汉诺威' => '漢諾瓦',
-'漢诺威' => '漢諾瓦',
-'烤烟' => '烤菸',
-'烤煙' => '烤菸',
-'无烟日' => '無菸日',
-'無煙日' => '無菸日',
-'无烟环境' => '無菸環境',
-'無煙環境' => '無菸環境',
-'烟熏' => '煙燻',
-'首席运营官' => '營運長',
-'熏烤' => '燻烤',
-'熏肉' => '燻肉',
-'熏黑' => '燻黑',
-'版权信息' => '版權資訊',
-'疯牛症' => '狂牛症',
-'鐵托' => '狄托',
-'铁托' => '狄托',
-'塞拉利昂' => '獅子山',
-'独联体' => '獨立國協',
-'獨聯體' => '獨立國協',
-'独立国家联合体' => '獨立國家國協',
-'獨立國家聯合體' => '獨立國家國協',
-'波利尼西亚' => '玻里尼西亞',
-'波利尼西亞' => '玻里尼西亞',
-'本傑明' => '班傑明',
-'本杰明' => '班傑明',
-'球杆' => '球桿',
-'理查德' => '理察',
-'卢塞恩' => '琉森',
-'危地馬拉' => '瓜地馬拉',
-'危地马拉' => '瓜地馬拉',
-'巴伦西亚' => '瓦倫西亞',
-'華倫西亞' => '瓦倫西亞',
-'冈比亚' => '甘比亞',
-'岡比亞' => '甘比亞',
-'肯尼迪' => '甘迺迪',
-'留尼汪' => '留尼旺',
-'毕加索' => '畢卡索',
-'迭代' => '疊代',
-'徵狀' => '症狀',
-'勃朗宁' => '白朗寧',
-'百慕大' => '百慕達',
-'卢旺达' => '盧安達',
-'盧旺達' => '盧安達',
-'睾' => '睪',
-'知识产权局' => '知識產權局',
-'知識產權局' => '知識產權署',
-'知識產權署' => '知識產權署',
-'知识产权署' => '知識產權署',
-'硅' => '矽',
-'硅藻' => '硅藻',
-'硬盘' => '硬碟',
-'硬件' => '硬體',
-'盘片' => '碟片',
-'磁盘' => '磁碟',
-'磁道' => '磁軌',
-'禁烟' => '禁菸',
-'禁煙' => '禁菸',
-'福尔马林' => '福馬林',
-'福爾馬林' => '福馬林',
-'私烟' => '私菸',
-'私煙' => '私菸',
-'程序员' => '程式設計師',
-'编程语言' => '程式語言',
-'空气质量' => '空氣品質',
-'空氣質素' => '空氣品質',
-'突尼斯' => '突尼西亞',
-'绑紧跳' => '笨豬跳',
-'蹦极跳' => '笨豬跳',
-'短信' => '簡訊',
-'纽黑文' => '紐哈芬',
-'新奥尔良' => '紐奧良',
-'新奧爾良' => '紐奧良',
-'新几内亚' => '紐幾內亞',
-'新西兰' => '紐西蘭',
-'新西蘭' => '紐西蘭',
-'紙煙' => '紙菸',
-'纸烟' => '紙菸',
-'索尔仁尼琴' => '索忍尼辛',
-'索贊尼辛' => '索忍尼辛',
-'所罗门群岛' => '索羅門群島',
-'所羅門群島' => '索羅門群島',
-'索馬里' => '索馬利亞',
-'索马里' => '索馬利亞',
-'索馬里蘭' => '索馬利蘭',
-'索马里兰' => '索馬利蘭',
-'維爾京群島' => '維京群島',
-'维尔京群岛' => '維京群島',
-'弗吉尼亚' => '維吉尼亞',
-'佛得角' => '維德角',
-'维特根斯坦' => '維根斯坦',
-'網絡遊戲' => '網路遊戲',
-'网络游戏' => '網路遊戲',
-'互联网' => '網際網路',
-'互联网络' => '網際網路',
-'互聯網' => '網際網路',
-'互聯網絡' => '網際網路',
-'因特网' => '網際網路',
-'系着' => '繫著',
-'卢瓦尔' => '羅亞爾',
-'盧瓦爾' => '羅亞爾',
-'卢浮宫' => '羅浮宮',
-'樂行童軍' => '羅浮童軍',
-'意大利' => '義大利',
-'昂山素姬' => '翁山蘇姬',
-'昂山素季' => '翁山蘇姬',
-'圣基茨和尼维斯' => '聖克里斯多福及尼維斯',
-'聖吉斯納域斯' => '聖克里斯多福及尼維斯',
-'圣文森特和格林纳丁斯' => '聖文森及格瑞那丁',
-'聖文森特和格林納丁斯' => '聖文森及格瑞那丁',
-'圣赫勒拿' => '聖赫倫那',
-'圣卢西亚' => '聖露西亞',
-'聖盧西亞' => '聖露西亞',
-'圣马力诺' => '聖馬利諾',
-'聖馬力諾' => '聖馬利諾',
-'肯尼亚' => '肯亞',
-'氨基酸' => '胺基酸',
-'自由泳' => '自由式',
-'三藩市' => '舊金山',
-'艾森豪威尔' => '艾森豪',
-'埃菲尔' => '艾菲爾',
-'阿里埃勒·沙龍' => '艾里爾·夏隆',
-'阿里埃勒·沙龙' => '艾里爾·夏隆',
-'帕塔亚' => '芭達亞',
-'黎克特制' => '芮氏',
-'里氏0' => '芮氏0',
-'里氏1' => '芮氏1',
-'里氏2' => '芮氏2',
-'里氏3' => '芮氏3',
-'里氏4' => '芮氏4',
-'里氏5' => '芮氏5',
-'里氏6' => '芮氏6',
-'里氏7' => '芮氏7',
-'里氏8' => '芮氏8',
-'里氏9' => '芮氏9',
-'里氏地震规模' => '芮氏地震規模',
-'里氏规模' => '芮氏規模',
-'里氏震级' => '芮氏規模',
-'当且仅当' => '若且唯若',
-'味美思' => '苦艾酒',
-'毛里塔尼亚' => '茅利塔尼亞',
-'毛里塔尼亞' => '茅利塔尼亞',
-'霍尔木兹' => '荷姆茲',
-'霍爾木茲' => '荷姆茲',
-'荷李活道' => '荷李活道',
-'莫桑比克' => '莫三比克',
-'瓦文萨' => '華勒沙',
-'華里沙' => '華勒沙',
-'瓦格纳' => '華格納',
-'烟具' => '菸具',
-'煙具' => '菸具',
-'烟品' => '菸品',
-'煙品' => '菸品',
-'烟嘴' => '菸嘴',
-'煙嘴' => '菸嘴',
-'烟卷' => '菸捲',
-'煙捲' => '菸捲',
-'烟斗' => '菸斗',
-'煙斗' => '菸斗',
-'烟民' => '菸民',
-'煙民' => '菸民',
-'烟灰' => '菸灰',
-'煙灰' => '菸灰',
-'烟瘾' => '菸癮',
-'煙癮' => '菸癮',
-'烟丝' => '菸絲',
-'煙絲' => '菸絲',
-'烟草' => '菸草',
-'煙草' => '菸草',
-'烟叶' => '菸葉',
-'煙葉' => '菸葉',
-'烟蒂' => '菸蒂',
-'煙蒂' => '菸蒂',
-'烟袋' => '菸袋',
-'煙袋' => '菸袋',
-'烟农' => '菸農',
-'煙農' => '菸農',
-'烟酒' => '菸酒',
-'煙酒' => '菸酒',
-'烟头' => '菸頭',
-'煙頭' => '菸頭',
-'烟鬼' => '菸鬼',
-'煙鬼' => '菸鬼',
-'烟碱' => '菸鹼',
-'煙鹼' => '菸鹼',
-'万历朝鲜战争' => '萬曆朝鮮戰爭',
-'瓦努阿图' => '萬那杜',
-'瓦努阿圖' => '萬那杜',
-'叶利钦' => '葉爾欽',
-'葉利欽' => '葉爾欽',
-'埃里温' => '葉里溫',
-'埃里溫' => '葉里溫',
-'也門' => '葉門',
-'也门' => '葉門',
-'着' => '著',
-'着眼于' => '著眼於',
-'科摩罗' => '葛摩',
-'科摩羅' => '葛摩',
-'格林美獎' => '葛萊美獎',
-'格莱美奖' => '葛萊美獎',
-'黑山共和国' => '蒙特內哥羅共和國',
-'黑山共和國' => '蒙特內哥羅共和國',
-'滿地可' => '蒙特婁',
-'蒙特利尔' => '蒙特婁',
-'蒙特利爾' => '蒙特婁',
-'普密蓬' => '蒲美蓬',
-'布隆迪' => '蒲隆地',
-'圭亚那' => '蓋亞那',
-'肖斯塔科维奇' => '蕭士塔高維奇',
-'蕭士達高維契' => '蕭士塔高維奇',
-'肖邦' => '蕭邦',
-'薛定谔' => '薛丁格',
-'扎伊尔' => '薩伊',
-'扎伊爾' => '薩伊',
-'素檀' => '蘇丹',
-'苏里南' => '蘇利南',
-'浮罗交怡' => '蘭卡威',
-'浮羅交怡' => '蘭卡威',
-'劳拉' => '蘿拉',
-'荧光' => '螢光',
-'荧屏' => '螢屏',
-'屏幕' => '螢幕',
-'行人路权' => '行人路權',
-'行人路權' => '行人路權',
-'流動網絡' => '行動網路',
-'移动网络' => '行動網路',
-'流動電話' => '行動電話',
-'移动电话' => '行動電話',
-'冲着' => '衝著',
-'埃塞俄比亚' => '衣索比亞',
-'埃塞俄比亞' => '衣索比亞',
-'克隆人' => '複製人',
-'国际象棋' => '西洋棋',
-'國際象棋' => '西洋棋',
-'赫梯' => '西臺',
-'分辨率' => '解析度',
-'解像度' => '解析度',
-'译码' => '解碼',
-'出租车' => '計程車',
-'约翰逊' => '詹森',
-'诺曼底' => '諾曼第',
-'瑙魯' => '諾魯',
-'瑙鲁' => '諾魯',
-'科特迪瓦' => '象牙海岸',
-'碧咸' => '貝克漢',
-'貝爾格萊德' => '貝爾格勒',
-'贝尔格莱德' => '貝爾格勒',
-'伯利兹' => '貝里斯',
-'伯利茲' => '貝里斯',
-'首席财务官' => '財務長',
-'集装箱' => '貨櫃',
-'数据库' => '資料庫',
-'數據庫' => '資料庫',
-'信息时代' => '資訊時代',
-'信息论' => '資訊理論',
-'乔布斯' => '賈伯斯',
-'本·拉登' => '賓·拉登',
-'宾西法尼亚' => '賓夕法尼亞',
-'本拉登' => '賓拉登',
-'利比里亚' => '賴比瑞亞',
-'利比里亞' => '賴比瑞亞',
-'莱索托' => '賴索托',
-'萊索托' => '賴索托',
-'塞浦路斯' => '賽普勒斯',
-'赫丘勒·波洛' => '赫丘勒·白羅',
-'赫鲁晓夫' => '赫魯雪夫',
-'切尔诺贝利' => '車諾比',
-'软驱' => '軟碟機',
-'軟件' => '軟體',
-'软件' => '軟體',
-'津巴布韋' => '辛巴威',
-'津巴布韦' => '辛巴威',
-'径入' => '逕入',
-'径到' => '逕到',
-'径取' => '逕取',
-'径启' => '逕啟',
-'径寄' => '逕寄',
-'径庭' => '逕庭',
-'径往' => '逕往',
-'径自' => '逕自',
-'径行' => '逕行',
-'径迎' => '逕迎',
-'链接' => '連結',
-'連結他' => '連結他',
-'进制' => '進位',
-'达·芬奇' => '達·文西',
-'达芬奇' => '達文西',
-'溫納圖萬' => '那杜',
-'丘吉尔' => '邱吉爾',
-'多普勒' => '都卜勒',
-'酰' => '醯',
-'里士满' => '里奇蒙',
-'金沙萨' => '金夏沙',
-'金沙薩' => '金夏沙',
-'健力士世界紀錄' => '金氏世界紀錄',
-'健力士世界纪录' => '金氏世界紀錄',
-'吉尼斯世界纪录' => '金氏世界紀錄',
-'钚' => '鈽',
-'鈎' => '鉤',
-'钩' => '鉤',
-'锎' => '鉲',
-'锫' => '鉳',
-'镅' => '鋂',
-'镎' => '錼',
-'钫' => '鍅',
-'炼金' => '鍊金',
-'锻炼' => '鍛鍊',
-'锝' => '鎝',
-'鐵杆' => '鐵桿',
-'铁杆' => '鐵桿',
-'泰坦尼克号' => '鐵達尼號',
-'锿' => '鑀',
-'关系着' => '關係著',
-'写保护' => '防寫',
-'阿布扎比' => '阿布達比',
-'阿拉伯联合酋长国' => '阿拉伯聯合大公國',
-'阿拉伯聯合酋長國' => '阿拉伯聯合大公國',
-'亚拉巴马' => '阿拉巴馬',
-'阿联酋' => '阿聯',
-'阿聯酋' => '阿聯',
-'罗纳德·里根' => '隆納·雷根',
-'私隱' => '隱私',
-'耶加達' => '雅加達',
-'雅尔塔' => '雅爾達',
-'雅爾塔' => '雅爾達',
-'雅穆苏克雷' => '雅穆索戈',
-'雅穆蘇克雷' => '雅穆索戈',
-'悉尼' => '雪梨',
-'雪茄烟' => '雪茄菸',
-'雪茄煙' => '雪茄菸',
-'莱特湾' => '雷伊泰灣',
-'萊特灣' => '雷伊泰灣',
-'激光' => '雷射',
-'雷诺阿' => '雷諾瓦',
-'电子烟' => '電子菸',
-'電子煙' => '電子菸',
-'晶体管' => '電晶體',
-'晶體管' => '電晶體',
-'电杆' => '電桿',
-'电线杆' => '電線桿',
-'电脑程序' => '電腦程式',
-'计算机程序' => '電腦程式',
-'荷尔斯泰因' => '霍爾斯坦',
-'荷爾斯泰因' => '霍爾斯坦',
-'面包着' => '面包著',
-'朝鲜战争' => '韓戰',
-'声卡' => '音效卡',
-'缺省' => '預設',
-'导弹' => '飛彈',
-'糊口' => '餬口',
-'香烟' => '香菸',
-'香煙' => '香菸',
-'馬里共和國' => '馬利共和國',
-'马里共和国' => '馬利共和國',
-'马拉维' => '馬拉威',
-'馬斯特里赫特' => '馬斯垂克',
-'马斯特里赫特' => '馬斯垂克',
-'马耳他' => '馬爾他',
-'馬爾代夫' => '馬爾地夫',
-'马尔代夫' => '馬爾地夫',
-'馬利蘭' => '馬里蘭',
-'高清电视' => '高畫質電視',
-'斗着' => '鬥著',
-'魯賓斯·巴里切羅' => '魯本·巴瑞切羅',
-'咪高峰' => '麥克風',
-'迈克尔' => '麥可',
-'麦克尔' => '麥可',
-'迈凯轮' => '麥拿輪',
-'邁凱輪' => '麥拿輪',
-'马萨诸塞' => '麻薩諸塞',
-'戴安娜' => '黛安娜',
-'狄安娜' => '黛安娜',
-'点烟' => '點菸',
-'點煙' => '點菸',
-'霉素' => '黴素',
-);
-
-$zh2HK = array(
-'0字节' => '0位元組',
-'1字节' => '1位元組',
-'2字节' => '2位元組',
-'3字节' => '3位元組',
-'4字节' => '4位元組',
-'5字节' => '5位元組',
-'6字节' => '6位元組',
-'7字节' => '7位元組',
-'8字节' => '8位元組',
-'9字节' => '9位元組',
-'IP地址' => 'IP位址',
-'·威尔士' => '·威爾士',
-'·威爾士' => '·威爾士',
-'一地里' => '一地裏',
-'一年里' => '一年裏',
-'三十六著' => '三十六着',
-'三極體' => '三極管',
-'旧金山' => '三藩市',
-'舊金山' => '三藩市',
-'上台面' => '上枱面',
-'下著' => '下着',
-'下著作' => '下著作',
-'下著名' => '下著名',
-'下著有' => '下著有',
-'下著称' => '下著稱',
-'下著稱' => '下著稱',
-'下著者' => '下著者',
-'下著述' => '下著述',
-'下著录' => '下著錄',
-'下著錄' => '下著錄',
-'不占' => '不佔',
-'不萊梅' => '不來梅',
-'不著痕跡' => '不着痕跡',
-'不著邊際' => '不着邊際',
-'世纪里' => '世紀裏',
-'C型肝炎' => '丙型肝炎',
-'C肝' => '丙肝',
-'并发布' => '並發佈',
-'中文里' => '中文裏',
-'乘著' => '乘着',
-'乘著作' => '乘著作',
-'乘著名' => '乘著名',
-'乘著書' => '乘著書',
-'乘著称' => '乘著稱',
-'乘著稱' => '乘著稱',
-'乘著者' => '乘著者',
-'乘著述' => '乘著述',
-'乘著錄' => '乘著錄',
-'B型肝炎' => '乙型肝炎',
-'B肝' => '乙肝',
-'吉力馬札羅' => '乞力馬札羅',
-'葉門' => '也門',
-'事里' => '事裏',
-'二極體' => '二極管',
-'因特网' => '互聯網',
-'網際網路' => '互聯網',
-'井里' => '井裏',
-'亮著' => '亮着',
-'亮著作' => '亮著作',
-'亮著名' => '亮著名',
-'亮著書' => '亮著書',
-'亮著称' => '亮著稱',
-'亮著稱' => '亮著稱',
-'亮著者' => '亮著者',
-'亮著述' => '亮著述',
-'亮著錄' => '亮著錄',
-'人工智慧' => '人工智能',
-'人数里' => '人數裏',
-'仗著' => '仗着',
-'仗著作' => '仗著作',
-'仗著名' => '仗著名',
-'仗著書' => '仗著書',
-'仗著稱' => '仗著稱',
-'仗著者' => '仗著者',
-'仗著述' => '仗著述',
-'仗著錄' => '仗著錄',
-'代表著' => '代表着',
-'代表著作' => '代表著作',
-'代表著名' => '代表著名',
-'代表著書' => '代表著書',
-'代表著稱' => '代表著稱',
-'代表著者' => '代表著者',
-'代表著述' => '代表著述',
-'代表著錄' => '代表著錄',
-'伊斯蘭瑪巴德' => '伊斯蘭堡',
-'埃博拉' => '伊波拉',
-'伏著' => '伏着',
-'貝里斯' => '伯利茲',
-'伯明罕' => '伯明翰',
-'伴著' => '伴着',
-'伴著作' => '伴著作',
-'伴著名' => '伴著名',
-'伴著書' => '伴著書',
-'伴著稱' => '伴著稱',
-'伴著者' => '伴著者',
-'伴著述' => '伴著述',
-'伴著錄' => '伴著錄',
-'布下了' => '佈下了',
-'布下的' => '佈下的',
-'布光' => '佈光',
-'布告' => '佈告',
-'布局' => '佈局',
-'布展' => '佈展',
-'布控' => '佈控',
-'布于' => '佈於',
-'布於' => '佈於',
-'布施' => '佈施',
-'布景' => '佈景',
-'布满' => '佈滿',
-'布滿' => '佈滿',
-'布置' => '佈置',
-'布設' => '佈設',
-'布设' => '佈設',
-'布警' => '佈警',
-'布道' => '佈道',
-'布防' => '佈防',
-'布阵' => '佈陣',
-'布陣' => '佈陣',
-'布雷、' => '佈雷、',
-'布雷。' => '佈雷。',
-'布雷封鎖' => '佈雷封鎖',
-'布雷封锁' => '佈雷封鎖',
-'布雷的' => '佈雷的',
-'布雷艇' => '佈雷艇',
-'布雷舰' => '佈雷艦',
-'布雷艦' => '佈雷艦',
-'布雷速度' => '佈雷速度',
-'布雷,' => '佈雷,',
-'布雷;' => '佈雷;',
-'布点' => '佈點',
-'布點' => '佈點',
-'低著' => '低着',
-'低著作' => '低著作',
-'低著名' => '低著名',
-'低著書' => '低著書',
-'低著称' => '低著稱',
-'低著稱' => '低著稱',
-'低著者' => '低著者',
-'低著述' => '低著述',
-'低著錄' => '低著錄',
-'住著' => '住着',
-'住著作' => '住著作',
-'住著名' => '住著名',
-'住著書' => '住著書',
-'住著稱' => '住著稱',
-'住著者' => '住著者',
-'住著述' => '住著述',
-'住著錄' => '住著錄',
-'占0' => '佔0',
-'占1' => '佔1',
-'占2' => '佔2',
-'占3' => '佔3',
-'占4' => '佔4',
-'占5' => '佔5',
-'占6' => '佔6',
-'占7' => '佔7',
-'占8' => '佔8',
-'占9' => '佔9',
-'占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',
-'占〇' => '佔〇',
-'占一' => '佔一',
-'占七' => '佔七',
-'占三' => '佔三',
-'占上風' => '佔上風',
-'占上风' => '佔上風',
-'占下' => '佔下',
-'占下風' => '佔下風',
-'占下风' => '佔下風',
-'占不占' => '佔不佔',
-'占不足' => '佔不足',
-'占世界' => '佔世界',
-'占中' => '佔中',
-'占主' => '佔主',
-'占主要' => '佔主要',
-'占九' => '佔九',
-'占了' => '佔了',
-'占二' => '佔二',
-'占五' => '佔五',
-'占人便宜' => '佔人便宜',
-'占位' => '佔位',
-'占住' => '佔住',
-'占占' => '佔佔',
-'占便宜' => '佔便宜',
-'占俄' => '佔俄',
-'占个' => '佔個',
-'占個' => '佔個',
-'占个位' => '佔個位',
-'占個位' => '佔個位',
-'占亿' => '佔億',
-'占億' => '佔億',
-'占优' => '佔優',
-'占優' => '佔優',
-'占先' => '佔先',
-'占光' => '佔光',
-'占全' => '佔全',
-'占两' => '佔兩',
-'占兩' => '佔兩',
-'占八' => '佔八',
-'占六' => '佔六',
-'占分' => '佔分',
-'占到' => '佔到',
-'占加' => '佔加',
-'占劣' => '佔劣',
-'占北' => '佔北',
-'占十' => '佔十',
-'占千' => '佔千',
-'占半' => '佔半',
-'占南' => '佔南',
-'占印' => '佔印',
-'占去' => '佔去',
-'占取' => '佔取',
-'占台' => '佔台',
-'占囁' => '佔囁',
-'占四' => '佔四',
-'占国' => '佔國',
-'占國' => '佔國',
-'占在' => '佔在',
-'占地' => '佔地',
-'占场' => '佔場',
-'占場' => '佔場',
-'占压' => '佔壓',
-'占壓' => '佔壓',
-'占多' => '佔多',
-'占大' => '佔大',
-'占好' => '佔好',
-'占小' => '佔小',
-'占少' => '佔少',
-'占局部' => '佔局部',
-'占屋' => '佔屋',
-'占山为' => '佔山為',
-'占山為' => '佔山為',
-'占市' => '佔市',
-'占平均' => '佔平均',
-'占床' => '佔床',
-'占座' => '佔座',
-'占後' => '佔後',
-'占得' => '佔得',
-'占德' => '佔德',
-'占所有' => '佔所有',
-'占掉' => '佔掉',
-'占据' => '佔據',
-'占據' => '佔據',
-'占整' => '佔整',
-'占新' => '佔新',
-'占有' => '佔有',
-'占东' => '佔東',
-'占東' => '佔東',
-'占查' => '佔查',
-'占次' => '佔次',
-'占比' => '佔比',
-'占法' => '佔法',
-'占满' => '佔滿',
-'占滿' => '佔滿',
-'占澳' => '佔澳',
-'占为' => '佔為',
-'占為' => '佔為',
-'占率' => '佔率',
-'占用' => '佔用',
-'占毕' => '佔畢',
-'占畢' => '佔畢',
-'占百' => '佔百',
-'占尽' => '佔盡',
-'占盡' => '佔盡',
-'占着' => '佔着',
-'占著' => '佔着',
-'占網' => '佔網',
-'占网' => '佔網',
-'占線' => '佔線',
-'占线' => '佔線',
-'占总' => '佔總',
-'占總' => '佔總',
-'占缺' => '佔缺',
-'占美国' => '佔美國',
-'占美國' => '佔美國',
-'占耕' => '佔耕',
-'占至多' => '佔至多',
-'占至少' => '佔至少',
-'占臺' => '佔臺',
-'占英' => '佔英',
-'占万' => '佔萬',
-'占萬' => '佔萬',
-'占著名' => '佔著名',
-'占著者' => '佔著者',
-'占葡' => '佔葡',
-'占苏' => '佔蘇',
-'占蘇' => '佔蘇',
-'占西' => '佔西',
-'占資' => '佔資',
-'占资' => '佔資',
-'占起' => '佔起',
-'占超过' => '佔超過',
-'占超過' => '佔超過',
-'占过' => '佔過',
-'占過' => '佔過',
-'占道' => '佔道',
-'占零' => '佔零',
-'占領' => '佔領',
-'占领' => '佔領',
-'占头' => '佔頭',
-'占頭' => '佔頭',
-'占头筹' => '佔頭籌',
-'占頭籌' => '佔頭籌',
-'占香' => '佔香',
-'占馬' => '佔馬',
-'占马' => '佔馬',
-'占高枝' => '佔高枝',
-'維德角' => '佛得角',
-'作品里' => '作品裏',
-'來著' => '來着',
-'來著作' => '來著作',
-'來著名' => '來著名',
-'來著書' => '來著書',
-'來著稱' => '來著稱',
-'來著者' => '來著者',
-'來著述' => '來著述',
-'來著錄' => '來著錄',
-'侵占' => '侵佔',
-'俄占' => '俄佔',
-'保障著' => '保障着',
-'保障著作' => '保障著作',
-'保障著名' => '保障著名',
-'保障著書' => '保障著書',
-'保障著稱' => '保障著稱',
-'保障著者' => '保障著者',
-'保障著述' => '保障著述',
-'保障著錄' => '保障著錄',
-'信著' => '信着',
-'信著作' => '信著作',
-'信著名' => '信著名',
-'信著書' => '信著書',
-'信著称' => '信著稱',
-'信著稱' => '信著稱',
-'信著者' => '信著者',
-'信著述' => '信著述',
-'信著錄' => '信著錄',
-'个月里' => '個月裏',
-'个里' => '個裏',
-'倒楣' => '倒霉',
-'候著' => '候着',
-'候著作' => '候著作',
-'候著名' => '候著名',
-'候著書' => '候著書',
-'候著稱' => '候著稱',
-'候著者' => '候著者',
-'候著述' => '候著述',
-'候著錄' => '候著錄',
-'借著' => '借着',
-'借著作' => '借著作',
-'借著名' => '借著名',
-'借著書' => '借著書',
-'借著稱' => '借著稱',
-'借著者' => '借著者',
-'借著述' => '借著述',
-'借著錄' => '借著錄',
-'假里' => '假裏',
-'做著' => '做着',
-'做著作' => '做著作',
-'做著名' => '做著名',
-'做著書' => '做著書',
-'做著稱' => '做著稱',
-'做著者' => '做著者',
-'做著述' => '做著述',
-'做著錄' => '做著錄',
-'吉尼斯世界纪录' => '健力士世界紀錄',
-'金氏世界紀錄' => '健力士世界紀錄',
-'側著' => '側着',
-'側著作' => '側著作',
-'側著名' => '側著名',
-'側著書' => '側著書',
-'側著稱' => '側著稱',
-'側著者' => '側著者',
-'側著述' => '側著述',
-'側著錄' => '側著錄',
-'偷著' => '偷着',
-'偷著作' => '偷著作',
-'偷著名' => '偷著名',
-'偷著書' => '偷著書',
-'偷著稱' => '偷著稱',
-'偷著者' => '偷著者',
-'偷著述' => '偷著述',
-'偷著錄' => '偷著錄',
-'備著' => '備着',
-'備著作' => '備著作',
-'備著名' => '備著名',
-'備著書' => '備著書',
-'備著稱' => '備著稱',
-'備著者' => '備著者',
-'備著述' => '備著述',
-'備著錄' => '備著錄',
-'傻里傻气' => '傻裏傻氣',
-'雇员' => '僱員',
-'雇用' => '僱用',
-'凶惡' => '兇惡',
-'凶殘' => '兇殘',
-'凶殺' => '兇殺',
-'先占' => '先佔',
-'雪鐵龍' => '先進',
-'雪铁龙' => '先進',
-'光著' => '光着',
-'光著作' => '光著作',
-'光著名' => '光著名',
-'光著書' => '光著書',
-'光著称' => '光著稱',
-'光著稱' => '光著稱',
-'光著者' => '光著者',
-'光著述' => '光著述',
-'光著錄' => '光著錄',
-'柯林頓' => '克林頓',
-'克羅埃西亞' => '克羅地亞',
-'公布' => '公佈',
-'冒著' => '冒着',
-'冒著作' => '冒著作',
-'冒著名' => '冒著名',
-'冒著書' => '冒著書',
-'冒著稱' => '冒著稱',
-'冒著者' => '冒著者',
-'冒著述' => '冒著述',
-'冒著錄' => '冒著錄',
-'冰山里' => '冰山裏',
-'恺撒' => '凱撒',
-'函数里' => '函數裏',
-'分布' => '分佈',
-'分布于' => '分佈於',
-'分佈著' => '分佈着',
-'分布著' => '分佈着',
-'分占' => '分佔',
-'分钟里' => '分鐘裏',
-'錢尼' => '切尼',
-'切尔诺贝利' => '切爾諾貝爾',
-'列支敦斯登' => '列支敦士登',
-'別著' => '別着',
-'賴比瑞亞' => '利比里亞',
-'刮著' => '刮着',
-'到山里' => '到山裏',
-'制著' => '制着',
-'制著作' => '制著作',
-'制著名' => '制著名',
-'制著書' => '制著書',
-'制著稱' => '制著稱',
-'制著者' => '制著者',
-'制著述' => '制著述',
-'制著錄' => '制著錄',
-'刻著' => '刻着',
-'刻著作' => '刻著作',
-'刻著名' => '刻著名',
-'刻著書' => '刻著書',
-'刻著称' => '刻著稱',
-'刻著稱' => '刻著稱',
-'刻著者' => '刻著者',
-'刻著述' => '刻著述',
-'刻著錄' => '刻著錄',
-'前波莫瑞' => '前波美拉尼亞',
-'剪彩' => '剪綵',
-'割占' => '割佔',
-'劃著' => '劃着',
-'击剑' => '劍擊',
-'擊劍' => '劍擊',
-'加薩走廊' => '加沙地帶',
-'迦納' => '加納',
-'加彭' => '加蓬',
-'努力著' => '努力着',
-'努力著作' => '努力著作',
-'努力著名' => '努力著名',
-'努力著書' => '努力著書',
-'努力著称' => '努力著稱',
-'努力著稱' => '努力著稱',
-'努力著者' => '努力著者',
-'努力著述' => '努力著述',
-'努力著錄' => '努力著錄',
-'布蘭登堡' => '勃蘭登堡',
-'動著' => '動着',
-'動著作' => '動著作',
-'動著名' => '動著名',
-'動著書' => '動著書',
-'動著稱' => '動著稱',
-'動著者' => '動著者',
-'動著述' => '動著述',
-'動著錄' => '動著錄',
-'包著' => '包着',
-'北朝鲜' => '北韓',
-'南朝鲜' => '南韓',
-'波札那' => '博茨瓦納',
-'占卜' => '占卜',
-'占国桥' => '占國橋',
-'占國橋' => '占國橋',
-'占有五不' => '占有五不',
-'占著作' => '占著作',
-'占著稱' => '占著稱',
-'占著述' => '占著述',
-'占著錄' => '占著錄',
-'卡普里亚蒂' => '卡佩雅蒂',
-'喀拉蚩' => '卡拉奇',
-'卡斯楚' => '卡斯特羅',
-'印著' => '印着',
-'印著作' => '印著作',
-'印著名' => '印著名',
-'印著書' => '印著書',
-'印著稱' => '印著稱',
-'印著者' => '印著者',
-'印著述' => '印著述',
-'印著錄' => '印著錄',
-'瓜地馬拉' => '危地馬拉',
-'厄瓜多' => '厄瓜多爾',
-'厄瓜多尔' => '厄瓜多爾',
-'厄瓜多爾' => '厄瓜多爾',
-'厄利垂亚' => '厄立特里亞',
-'厄利垂亞' => '厄立特里亞',
-'源代码' => '原始碼',
-'去山里' => '去山裏',
-'参数里' => '參數裏',
-'受著' => '受着',
-'受著作' => '受著作',
-'受著名' => '受著名',
-'受著書' => '受著書',
-'受著稱' => '受著稱',
-'受著者' => '受著者',
-'受著述' => '受著述',
-'受著錄' => '受著錄',
-'丛林里' => '叢林裏',
-'口里' => '口裏',
-'只占' => '只佔',
-'叫著' => '叫着',
-'叫著作' => '叫著作',
-'叫著名' => '叫著名',
-'叫著書' => '叫著書',
-'叫著稱' => '叫著稱',
-'叫著者' => '叫著者',
-'叫著述' => '叫著述',
-'叫著錄' => '叫著錄',
-'古柯鹼' => '可卡因',
-'叱吒' => '叱咤',
-'斯坦福大学' => '史丹福大學',
-'史匹柏' => '史匹堡',
-'斯皮尔伯格' => '史匹堡',
-'史蒂芬·史匹柏' => '史提芬·史匹堡',
-'斯蒂芬·斯皮尔伯格' => '史提芬·史匹堡',
-'吃不著' => '吃不着',
-'吃得著' => '吃得着',
-'吃著' => '吃着',
-'吃里扒外' => '吃裏扒外',
-'吃里爬外' => '吃裏爬外',
-'吉布地' => '吉布堤',
-'吊著' => '吊着',
-'向著' => '向着',
-'向著作' => '向著作',
-'向著名' => '向著名',
-'向著書' => '向著書',
-'向著稱' => '向著稱',
-'向著者' => '向著者',
-'向著述' => '向著述',
-'向著錄' => '向著錄',
-'吞占' => '吞佔',
-'吧台' => '吧枱',
-'含著' => '含着',
-'含著作' => '含著作',
-'含著名' => '含著名',
-'含著書' => '含著書',
-'含著稱' => '含著稱',
-'含著者' => '含著者',
-'含著述' => '含著述',
-'含著錄' => '含著錄',
-'吹著' => '吹着',
-'吹著作' => '吹著作',
-'吹著名' => '吹著名',
-'吹著書' => '吹著書',
-'吹著稱' => '吹著稱',
-'吹著者' => '吹著者',
-'吹著述' => '吹著述',
-'吹著錄' => '吹著錄',
-'呆著' => '呆着',
-'呆里呆气' => '呆裏呆氣',
-'味著' => '味着',
-'味著作' => '味著作',
-'味著名' => '味著名',
-'味著書' => '味著書',
-'味著称' => '味著稱',
-'味著稱' => '味著稱',
-'味著者' => '味著者',
-'味著述' => '味著述',
-'味著錄' => '味著錄',
-'咖哩' => '咖喱',
-'麥克風' => '咪高峰',
-'麦克风' => '咪高峰',
-'哥特式' => '哥德式',
-'哥斯大黎加' => '哥斯達黎加',
-'哪里' => '哪裏',
-'哭著' => '哭着',
-'哭著作' => '哭著作',
-'哭著名' => '哭著名',
-'哭著書' => '哭著書',
-'哭著稱' => '哭著稱',
-'哭著者' => '哭著者',
-'哭著述' => '哭著述',
-'哭著錄' => '哭著錄',
-'唱著' => '唱着',
-'唱著作' => '唱著作',
-'唱著名' => '唱著名',
-'唱著書' => '唱著書',
-'唱著稱' => '唱著稱',
-'唱著者' => '唱著者',
-'唱著述' => '唱著述',
-'唱著錄' => '唱著錄',
-'喝著' => '喝着',
-'喝著作' => '喝著作',
-'喝著名' => '喝著名',
-'喝著書' => '喝著書',
-'喝著稱' => '喝著稱',
-'喝著者' => '喝著者',
-'喝著述' => '喝著述',
-'喝著錄' => '喝著錄',
-'賈伯斯' => '喬布斯',
-'乔治·奥威尔' => '喬治·歐威爾',
-'单反相机' => '單鏡反光機',
-'單眼相機' => '單鏡反光機',
-'嗅不著' => '嗅不着',
-'嗅得著' => '嗅得着',
-'嗅著' => '嗅着',
-'凯瑟琳' => '嘉芙蓮',
-'凱薩琳' => '嘉芙蓮',
-'嘯吒' => '嘯咤',
-'嘴里' => '嘴裏',
-'嚷著' => '嚷着',
-'嚷著作' => '嚷著作',
-'嚷著名' => '嚷著名',
-'嚷著書' => '嚷著書',
-'嚷著稱' => '嚷著稱',
-'嚷著者' => '嚷著者',
-'嚷著述' => '嚷著述',
-'嚷著錄' => '嚷著錄',
-'回著' => '回着',
-'回著名' => '回著名',
-'因著' => '因着',
-'因著〈' => '因著〈',
-'因著《' => '因著《',
-'因著作' => '因著作',
-'因著名' => '因著名',
-'因著書' => '因著書',
-'因著稱' => '因著稱',
-'因著者' => '因著者',
-'因著述' => '因著述',
-'因著錄' => '因著錄',
-'困著' => '困着',
-'困著作' => '困著作',
-'困著名' => '困著名',
-'困著書' => '困著書',
-'困著稱' => '困著稱',
-'困著者' => '困著者',
-'困著述' => '困著述',
-'困著錄' => '困著錄',
-'固著' => '固着',
-'圈占' => '圈佔',
-'圈里' => '圈裏',
-'西洋棋' => '國際象棋',
-'圍著' => '圍着',
-'圍著作' => '圍著作',
-'圍著名' => '圍著名',
-'圍著書' => '圍著書',
-'圍著稱' => '圍著稱',
-'圍著者' => '圍著者',
-'圍著述' => '圍著述',
-'圍著錄' => '圍著錄',
-'园里' => '園裏',
-'吐瓦魯' => '圖瓦盧',
-'土魯斯' => '圖盧茲',
-'图里的' => '圖裏的',
-'图里,' => '圖裏,',
-'土里' => '土裏',
-'在山里' => '在山裏',
-'蓋亞那' => '圭亞那',
-'地占' => '地佔',
-'地图里' => '地圖裏',
-'堪培拉' => '坎培拉',
-'坐台' => '坐枱',
-'坐著' => '坐着',
-'坐著作' => '坐著作',
-'坐著名' => '坐著名',
-'坐著書' => '坐著書',
-'坐著稱' => '坐著稱',
-'坐著者' => '坐著者',
-'坐著述' => '坐著述',
-'坐著錄' => '坐著錄',
-'坑里' => '坑裏',
-'坦尚尼亞' => '坦桑尼亞',
-'衣索匹亞' => '埃塞俄比亚',
-'衣索比亞' => '埃塞俄比亞',
-'葉里溫' => '埃里溫',
-'城市里' => '城市裏',
-'城里' => '城裏',
-'域里' => '域裏',
-'吉里巴斯' => '基里巴斯',
-'堅貞著' => '堅貞着',
-'场里' => '場裏',
-'塗著' => '塗着',
-'塞普勒斯' => '塞浦路斯',
-'賽普勒斯' => '塞浦路斯',
-'塞爾維亞與蒙特內哥羅' => '塞爾維亞和黑山',
-'塞席爾' => '塞舌爾',
-'境里' => '境裏',
-'壓著' => '壓着',
-'壓著作' => '壓著作',
-'壓著名' => '壓著名',
-'壓著書' => '壓著書',
-'壓著稱' => '壓著稱',
-'壓著者' => '壓著者',
-'壓著述' => '壓著述',
-'壓著錄' => '壓著錄',
-'壶里' => '壺裏',
-'多占' => '多佔',
-'夜晚里' => '夜晚裏',
-'夜里' => '夜裏',
-'夢有五不占' => '夢有五不占',
-'梦有五不占' => '夢有五不占',
-'夢著' => '夢着',
-'夢著作' => '夢著作',
-'夢著名' => '夢著名',
-'夢著書' => '夢著書',
-'夢著稱' => '夢著稱',
-'夢著者' => '夢著者',
-'夢著述' => '夢著述',
-'夢著錄' => '夢著錄',
-'梦里' => '夢裏',
-'天里' => '天裏',
-'宇航员' => '太空人',
-'夾著' => '夾着',
-'夾著作' => '夾著作',
-'夾著名' => '夾著名',
-'夾著書' => '夾著書',
-'夾著稱' => '夾著稱',
-'夾著者' => '夾著者',
-'夾著述' => '夾著述',
-'夾著錄' => '夾著錄',
-'奥占' => '奧佔',
-'奧占' => '奧佔',
-'歐巴馬' => '奧巴馬',
-'妆台' => '妝枱',
-'威斯伐倫' => '威斯特法倫',
-'威尔士' => '威爾斯',
-'威爾士' => '威爾斯',
-'子里' => '子裏',
-'字里行间' => '字裏行間',
-'存在著' => '存在着',
-'存著' => '存着',
-'存著作' => '存著作',
-'存著名' => '存著名',
-'孟德爾頌' => '孟德爾遜',
-'门德尔松' => '孟德爾遜',
-'學著' => '學着',
-'學著作' => '學著作',
-'學著名' => '學著名',
-'學著書' => '學著書',
-'學著稱' => '學著稱',
-'學著者' => '學著者',
-'學著述' => '學著述',
-'學著錄' => '學著錄',
-'学里' => '學裏',
-'守著' => '守着',
-'守著作' => '守著作',
-'守著名' => '守著名',
-'守著書' => '守著書',
-'守著称' => '守著稱',
-'守著稱' => '守著稱',
-'守著者' => '守著者',
-'守著述' => '守著述',
-'守著錄' => '守著錄',
-'安哈特' => '安哈爾特',
-'安地卡及巴布達' => '安提瓜和巴布達',
-'定著' => '定着',
-'定著作' => '定著作',
-'定著名' => '定著名',
-'定著書' => '定著書',
-'定著称' => '定著稱',
-'定著稱' => '定著稱',
-'定著者' => '定著者',
-'定著述' => '定著述',
-'定著錄' => '定著錄',
-'宣布' => '宣佈',
-'宫里' => '宮裏',
-'家里' => '家裏',
-'密布' => '密佈',
-'密西根' => '密歇根',
-'沃尓沃' => '富豪',
-'寡占' => '寡佔',
-'写字台' => '寫字枱',
-'寫著' => '寫着',
-'寫著作' => '寫著作',
-'寫著名' => '寫著名',
-'寫著書' => '寫著書',
-'寫著稱' => '寫著稱',
-'寫著者' => '寫著者',
-'寫著述' => '寫著述',
-'寫著錄' => '寫著錄',
-'宝里宝气' => '寶裏寶氣',
-'封面里' => '封面裏',
-'将占' => '將佔',
-'將占' => '將佔',
-'将占卜' => '將占卜',
-'將占卜' => '將占卜',
-'专辑里' => '專輯裏',
-'尋著' => '尋着',
-'尋著作' => '尋著作',
-'尋著名' => '尋著名',
-'尋著書' => '尋著書',
-'尋著稱' => '尋著稱',
-'尋著者' => '尋著者',
-'尋著述' => '尋著述',
-'尋著錄' => '尋著錄',
-'對著' => '對着',
-'對著作' => '對著作',
-'對著名' => '對著名',
-'對著書' => '對著書',
-'對著稱' => '對著稱',
-'對著者' => '對著者',
-'對著述' => '對著述',
-'對著錄' => '對著錄',
-'小时里' => '小時裏',
-'少占' => '少佔',
-'就里' => '就裏',
-'尼克松' => '尼克遜',
-'奈及利亞' => '尼日利亞',
-'局里' => '局裏',
-'屋里' => '屋裏',
-'展著' => '展着',
-'展著作' => '展著作',
-'展著名' => '展著名',
-'展著書' => '展著書',
-'展著稱' => '展著稱',
-'展著者' => '展著者',
-'展著述' => '展著述',
-'展著錄' => '展著錄',
-'屯里' => '屯裏',
-'山里有' => '山裏有',
-'山里的' => '山裏的',
-'甘比亞' => '岡比亞',
-'岸裡' => '岸裡',
-'工作台' => '工作枱',
-'已占' => '已佔',
-'巴塞罗那' => '巴塞隆拿',
-'巴塞隆納' => '巴塞隆拿',
-'巴貝多' => '巴巴多斯',
-'巴布亞紐幾內亞' => '巴布亞新畿內亞',
-'巴士拉' => '巴斯拉',
-'巷里' => '巷裏',
-'市占' => '市佔',
-'市里的' => '市裏的',
-'布吉納法索' => '布基納法索',
-'布什' => '布殊',
-'布里斯托尔' => '布里斯托',
-'蒲隆地' => '布隆迪',
-'希冀著' => '希冀着',
-'席哈克' => '希拉克',
-'希拉蕊' => '希拉莉',
-'希特勒' => '希特拉',
-'帛琉' => '帕勞',
-'巴尔米拉环礁' => '帕邁拉環礁',
-'帕劳' => '帛琉',
-'帶著' => '帶着',
-'帶著作' => '帶著作',
-'帶著名' => '帶著名',
-'帶著書' => '帶著書',
-'帶著稱' => '帶著稱',
-'帶著者' => '帶著者',
-'帶著述' => '帶著述',
-'帶著錄' => '帶著錄',
-'幅图里' => '幅圖裏',
-'幫著' => '幫着',
-'幫著作' => '幫著作',
-'幫著名' => '幫著名',
-'幫著書' => '幫著書',
-'幫著稱' => '幫著稱',
-'幫著者' => '幫著者',
-'幫著述' => '幫著述',
-'幫著錄' => '幫著錄',
-'干着急' => '干着急',
-'賓士' => '平治',
-'年代里' => '年代裏',
-'年里' => '年裏',
-'干着' => '幹着',
-'幹著' => '幹着',
-'幹著名' => '幹著名',
-'幹著稱' => '幹著稱',
-'幾內亞比索' => '幾內亞比紹',
-'店里' => '店裏',
-'庫德人' => '庫爾德人',
-'庫德族' => '庫爾德族',
-'坎城' => '康城',
-'戛纳' => '康城',
-'庙里' => '廟裏',
-'广播里' => '廣播裏',
-'強占' => '強佔',
-'强占' => '強佔',
-'约翰斯顿岛' => '強斯頓環礁',
-'弹子台' => '彈子枱',
-'蹦床' => '彈床',
-'弹珠台' => '彈珠枱',
-'形上學' => '形而上學',
-'谢丽·布莱尔' => '彭雪玲',
-'往里' => '往裏',
-'待著' => '待着',
-'待著作' => '待著作',
-'待著名' => '待著名',
-'待著書' => '待著書',
-'待著稱' => '待著稱',
-'待著者' => '待著者',
-'待著述' => '待著述',
-'待著錄' => '待著錄',
-'得著' => '得着',
-'得著作' => '得著作',
-'得著名' => '得著名',
-'得著書' => '得著書',
-'得著稱' => '得著稱',
-'得著者' => '得著者',
-'得著述' => '得著述',
-'得著錄' => '得著錄',
-'从图里' => '從圖裏',
-'从山里' => '從山裏',
-'从里到外' => '從裏到外',
-'从里向外' => '從裏向外',
-'循著' => '循着',
-'循著作' => '循著作',
-'循著名' => '循著名',
-'循著書' => '循著書',
-'循著稱' => '循著稱',
-'循著者' => '循著者',
-'循著述' => '循著述',
-'循著錄' => '循著錄',
-'征占' => '徵佔',
-'徵占' => '徵佔',
-'德占' => '德佔',
-'得克萨斯' => '德克薩斯',
-'德勒斯登' => '德累斯頓',
-'澈底' => '徹底',
-'心著' => '心着',
-'心著作' => '心著作',
-'心著名' => '心著名',
-'心著書' => '心著書',
-'心著称' => '心著稱',
-'心著稱' => '心著稱',
-'心著者' => '心著者',
-'心著述' => '心著述',
-'心著錄' => '心著錄',
-'心里' => '心裏',
-'心里面' => '心裏面',
-'忍著' => '忍着',
-'忍著作' => '忍著作',
-'忍著名' => '忍著名',
-'忍著書' => '忍著書',
-'忍著稱' => '忍著稱',
-'忍著者' => '忍著者',
-'忍著述' => '忍著述',
-'忍著錄' => '忍著錄',
-'忙著' => '忙着',
-'忙著作' => '忙著作',
-'忙著名' => '忙著名',
-'忙著書' => '忙著書',
-'忙著稱' => '忙著稱',
-'忙著者' => '忙著者',
-'忙著述' => '忙著述',
-'忙著錄' => '忙著錄',
-'忙里' => '忙裏',
-'忠貞著' => '忠貞着',
-'急著' => '急着',
-'急著作' => '急著作',
-'急著名' => '急著名',
-'急著書' => '急著書',
-'急著稱' => '急著稱',
-'急著者' => '急著者',
-'急著述' => '急著述',
-'急著錄' => '急著錄',
-'怪里怪气' => '怪裏怪氣',
-'悠著' => '悠着',
-'悠著作' => '悠著作',
-'悠著名' => '悠著名',
-'悠著書' => '悠著書',
-'悠著稱' => '悠著稱',
-'悠著者' => '悠著者',
-'悠著述' => '悠著述',
-'悠著錄' => '悠著錄',
-'悶著' => '悶着',
-'想象' => '想像',
-'想著' => '想着',
-'想著作' => '想著作',
-'想著名' => '想著名',
-'想著書' => '想著書',
-'想著称' => '想著稱',
-'想著稱' => '想著稱',
-'想著者' => '想著者',
-'想著述' => '想著述',
-'想著錄' => '想著錄',
-'意占' => '意佔',
-'義占' => '意佔',
-'義大利' => '意大利',
-'艾滋' => '愛滋',
-'愛著' => '愛着',
-'愛著作' => '愛著作',
-'愛著名' => '愛著名',
-'愛著書' => '愛著書',
-'愛著稱' => '愛著稱',
-'愛著者' => '愛著者',
-'愛著述' => '愛著述',
-'愛著錄' => '愛著錄',
-'慌里慌张' => '慌裏慌張',
-'慣著' => '慣着',
-'慣著作' => '慣著作',
-'慣著名' => '慣著名',
-'慣著書' => '慣著書',
-'慣著稱' => '慣著稱',
-'慣著者' => '慣著者',
-'慣著述' => '慣著述',
-'慣著錄' => '慣著錄',
-'宪法里' => '憲法裏',
-'应用程序' => '應用程式',
-'應著' => '應着',
-'應著作' => '應著作',
-'應著名' => '應著名',
-'應著書' => '應著書',
-'應著稱' => '應著稱',
-'應著者' => '應著者',
-'應著述' => '應著述',
-'應著錄' => '應著錄',
-'懷著' => '懷着',
-'懷著作' => '懷著作',
-'懷著名' => '懷著名',
-'懷著書' => '懷著書',
-'懷著稱' => '懷著稱',
-'懷著者' => '懷著者',
-'懷著述' => '懷著述',
-'懷著錄' => '懷著錄',
-'怀里' => '懷裏',
-'戀著' => '戀着',
-'戀著作' => '戀著作',
-'戀著名' => '戀著名',
-'戀著書' => '戀著書',
-'戀著稱' => '戀著稱',
-'戀著者' => '戀著者',
-'戀著述' => '戀著述',
-'戀著錄' => '戀著錄',
-'戈巴契夫' => '戈爾巴喬夫',
-'戰著' => '戰着',
-'戰著作' => '戰著作',
-'戰著名' => '戰著名',
-'戰著書' => '戰著書',
-'戰著稱' => '戰著稱',
-'戰著者' => '戰著者',
-'戰著述' => '戰著述',
-'戰著錄' => '戰著錄',
-'戏彩娱亲' => '戲綵娛親',
-'戲彩娛親' => '戲綵娛親',
-'戏里' => '戲裏',
-'撒切尔' => '戴卓爾',
-'柴契爾' => '戴卓爾',
-'狄安娜' => '戴安娜',
-'黛安娜' => '戴安娜',
-'戴著' => '戴着',
-'戴著作' => '戴著作',
-'戴著名' => '戴著名',
-'戴著書' => '戴著書',
-'戴著稱' => '戴著稱',
-'戴著者' => '戴著者',
-'戴著述' => '戴著述',
-'戴著錄' => '戴著錄',
-'房里' => '房裏',
-'所占' => '所佔',
-'索羅門群島' => '所羅門群島',
-'手里' => '手裏',
-'手里剑' => '手裏劍',
-'列印' => '打印',
-'印表機' => '打印機',
-'打著' => '打着',
-'打著作' => '打著作',
-'打著名' => '打著名',
-'打著書' => '打著書',
-'打著稱' => '打著稱',
-'打著者' => '打著者',
-'打著述' => '打著述',
-'打著錄' => '打著錄',
-'扛著' => '扛着',
-'扛著作' => '扛著作',
-'扛著名' => '扛著名',
-'扛著書' => '扛著書',
-'扛著稱' => '扛著稱',
-'扛著者' => '扛著者',
-'扛著述' => '扛著述',
-'扛著錄' => '扛著錄',
-'找不著' => '找不着',
-'找得著' => '找得着',
-'承宣布政' => '承宣布政',
-'抓著' => '抓着',
-'抓著作' => '抓著作',
-'抓著名' => '抓著名',
-'抓著稱' => '抓著稱',
-'抓著者' => '抓著者',
-'抓著述' => '抓著述',
-'抓著錄' => '抓著錄',
-'披著' => '披着',
-'披著作' => '披著作',
-'披著名' => '披著名',
-'披著書' => '披著書',
-'披著稱' => '披著稱',
-'披著者' => '披著者',
-'披著述' => '披著述',
-'披著錄' => '披著錄',
-'抬著' => '抬着',
-'抬著作' => '抬著作',
-'抬著名' => '抬著名',
-'抬著稱' => '抬著稱',
-'抬著者' => '抬著者',
-'抬著述' => '抬著述',
-'抬著錄' => '抬著錄',
-'抱著' => '抱着',
-'抱著作' => '抱著作',
-'抱著名' => '抱著名',
-'抱著稱' => '抱著稱',
-'抱著者' => '抱著者',
-'抱著述' => '抱著述',
-'抱著錄' => '抱著錄',
-'拉著' => '拉着',
-'拉著作' => '拉著作',
-'拉著名' => '拉著名',
-'拉著書' => '拉著書',
-'拉著稱' => '拉著稱',
-'拉著者' => '拉著者',
-'拉著述' => '拉著述',
-'拉著錄' => '拉著錄',
-'拎著' => '拎着',
-'拎著作' => '拎著作',
-'拎著名' => '拎著名',
-'拎著稱' => '拎著稱',
-'拎著者' => '拎著者',
-'拎著述' => '拎著述',
-'拎著錄' => '拎著錄',
-'拖著' => '拖着',
-'拖著作' => '拖著作',
-'拖著名' => '拖著名',
-'拖著稱' => '拖著稱',
-'拖著者' => '拖著者',
-'拖著述' => '拖著述',
-'拖著錄' => '拖著錄',
-'拼著' => '拼着',
-'拼著作' => '拼著作',
-'拼著名' => '拼著名',
-'拼著稱' => '拼著稱',
-'拼著者' => '拼著者',
-'拼著述' => '拼著述',
-'拼著錄' => '拼著錄',
-'拿著' => '拿着',
-'拿著作' => '拿著作',
-'拿著名' => '拿著名',
-'拿著稱' => '拿著稱',
-'拿著者' => '拿著者',
-'拿著述' => '拿著述',
-'拿著錄' => '拿著錄',
-'持著' => '持着',
-'持著作' => '持著作',
-'持著名' => '持著名',
-'持著稱' => '持著稱',
-'持著者' => '持著者',
-'持著述' => '持著述',
-'持著錄' => '持著錄',
-'挑著' => '挑着',
-'挑著作' => '挑著作',
-'挑著名' => '挑著名',
-'挑著稱' => '挑著稱',
-'挑著者' => '挑著者',
-'挑著述' => '挑著述',
-'挑著錄' => '挑著錄',
-'挨著' => '挨着',
-'挨著作' => '挨著作',
-'挨著名' => '挨著名',
-'挨著稱' => '挨著稱',
-'挨著者' => '挨著者',
-'挨著述' => '挨著述',
-'挨著錄' => '挨著錄',
-'捆著' => '捆着',
-'捆著作' => '捆著作',
-'捆著名' => '捆著名',
-'捆著稱' => '捆著稱',
-'捆著者' => '捆著者',
-'捆著述' => '捆著述',
-'捆著錄' => '捆著錄',
-'伏地挺身' => '掌上壓',
-'俯卧撑' => '掌上壓',
-'掖著' => '掖着',
-'掖著作' => '掖著作',
-'掖著名' => '掖著名',
-'掖著稱' => '掖著稱',
-'掖著者' => '掖著者',
-'掖著述' => '掖著述',
-'掖著錄' => '掖著錄',
-'掙著' => '掙着',
-'掙著作' => '掙著作',
-'掙著名' => '掙著名',
-'掙著書' => '掙著書',
-'掙著稱' => '掙著稱',
-'掙著者' => '掙著者',
-'掙著述' => '掙著述',
-'掙著錄' => '掙著錄',
-'掛著' => '掛着',
-'接著' => '接着',
-'接著作' => '接著作',
-'接著名' => '接著名',
-'接著稱' => '接著稱',
-'接著者' => '接著者',
-'接著述' => '接著述',
-'接著錄' => '接著錄',
-'揉著' => '揉着',
-'揉著作' => '揉著作',
-'揉著名' => '揉著名',
-'揉著書' => '揉著書',
-'揉著稱' => '揉著稱',
-'揉著者' => '揉著者',
-'揉著述' => '揉著述',
-'揉著錄' => '揉著錄',
-'提著' => '提着',
-'提著作' => '提著作',
-'提著名' => '提著名',
-'提著稱' => '提著稱',
-'提著者' => '提著者',
-'提著述' => '提著述',
-'提著錄' => '提著錄',
-'揮著' => '揮着',
-'揮著作' => '揮著作',
-'揮著名' => '揮著名',
-'揮著稱' => '揮著稱',
-'揮著者' => '揮著者',
-'揮著述' => '揮著述',
-'揮著錄' => '揮著錄',
-'搜索引擎' => '搜尋引擎',
-'抢占' => '搶佔',
-'搶占' => '搶佔',
-'摟著' => '摟着',
-'摟著作' => '摟著作',
-'摟著名' => '摟著名',
-'摟著稱' => '摟著稱',
-'摟著者' => '摟著者',
-'摟著述' => '摟著述',
-'摟著錄' => '摟著錄',
-'折台' => '摺枱',
-'撒马尔罕' => '撒馬爾罕',
-'撼著' => '撼着',
-'撼著作' => '撼著作',
-'撼著名' => '撼著名',
-'撼著書' => '撼著書',
-'撼著稱' => '撼著稱',
-'撼著者' => '撼著者',
-'撼著述' => '撼著述',
-'撼著錄' => '撼著錄',
-'擋著' => '擋着',
-'擋著作' => '擋著作',
-'擋著名' => '擋著名',
-'擋著稱' => '擋著稱',
-'擋著者' => '擋著者',
-'擋著述' => '擋著述',
-'擋著錄' => '擋著錄',
-'擔著' => '擔着',
-'據著' => '據着',
-'據著作' => '據著作',
-'據著名' => '據著名',
-'據著書' => '據著書',
-'據著稱' => '據著稱',
-'據著者' => '據著者',
-'據著述' => '據著述',
-'據著錄' => '據著錄',
-'擡著' => '擡着',
-'摆布' => '擺佈',
-'擺布' => '擺佈',
-'擺著' => '擺着',
-'擺著作' => '擺著作',
-'擺著名' => '擺著名',
-'擺著稱' => '擺著稱',
-'擺著者' => '擺著者',
-'擺著述' => '擺著述',
-'擺著錄' => '擺著錄',
-'攻占' => '攻佔',
-'放著' => '放着',
-'放著作' => '放著作',
-'放著名' => '放著名',
-'放著称' => '放著稱',
-'放著稱' => '放著稱',
-'敞著' => '敞着',
-'敞著作' => '敞著作',
-'敞著名' => '敞著名',
-'敞著稱' => '敞著稱',
-'敞著者' => '敞著者',
-'敞著述' => '敞著述',
-'敞著錄' => '敞著錄',
-'散布' => '散佈',
-'散佈著' => '散佈着',
-'散布著' => '散佈着',
-'数字照相机' => '数碼照相機',
-'數位照相機' => '数碼照相機',
-'數著' => '數着',
-'数字化' => '數碼化',
-'數位化' => '數碼化',
-'数字技术' => '數碼技術',
-'數位技術' => '數碼技術',
-'數位相機' => '數碼相機',
-'数字信号' => '數碼訊號',
-'數碼訊號' => '數碼訊號',
-'数字电视' => '數碼電視',
-'數位電視' => '數碼電視',
-'數著作' => '數著作',
-'數著名' => '數著名',
-'數著稱' => '數著稱',
-'數著者' => '數著者',
-'數著述' => '數著述',
-'數著錄' => '數著錄',
-'斥著' => '斥着',
-'斥著作' => '斥著作',
-'斥著名' => '斥著名',
-'斥著書' => '斥著書',
-'斥著稱' => '斥著稱',
-'斥著者' => '斥著者',
-'斥著述' => '斥著述',
-'斥著錄' => '斥著錄',
-'史瓦濟蘭' => '斯威士蘭',
-'斯洛維尼亞' => '斯洛文尼亞',
-'紐澳良' => '新奧爾良',
-'紐西蘭' => '新西蘭',
-'方法里' => '方法裏',
-'族里' => '族裏',
-'日占' => '日佔',
-'日里' => '日裏',
-'昂山素季' => '昂山素姬',
-'翁山蘇姬' => '昂山素姬',
-'昂著' => '昂着',
-'昂著作' => '昂著作',
-'昂著名' => '昂著名',
-'昂著書' => '昂著書',
-'昂著稱' => '昂著稱',
-'昂著者' => '昂著者',
-'昂著述' => '昂著述',
-'昂著錄' => '昂著錄',
-'星罗棋布' => '星羅棋佈',
-'星羅棋布' => '星羅棋佈',
-'映著' => '映着',
-'映著作' => '映著作',
-'映著名' => '映著名',
-'映著書' => '映著書',
-'映著稱' => '映著稱',
-'映著者' => '映著者',
-'映著述' => '映著述',
-'映著錄' => '映著錄',
-'晃著' => '晃着',
-'晃著作' => '晃著作',
-'晃著名' => '晃著名',
-'晃著稱' => '晃著稱',
-'晃著者' => '晃著者',
-'晃著述' => '晃著述',
-'晃著錄' => '晃著錄',
-'晶元' => '晶片',
-'芯片' => '晶片',
-'智慧型' => '智能',
-'智慧卡' => '智能卡',
-'智慧手機' => '智能手機',
-'暗地里' => '暗地裏',
-'暗沟里' => '暗溝裏',
-'暗著' => '暗着',
-'暗著作' => '暗著作',
-'暗著名' => '暗著名',
-'暗著書' => '暗著書',
-'暗著稱' => '暗著稱',
-'暗著者' => '暗著者',
-'暗著述' => '暗著述',
-'暗著錄' => '暗著錄',
-'暗里' => '暗裏',
-'会占' => '會佔',
-'會占' => '會佔',
-'会占卜' => '會占卜',
-'會占卜' => '會占卜',
-'会里' => '會裏',
-'月裡来' => '月裏來',
-'有著' => '有着',
-'有著作' => '有著作',
-'有著名' => '有著名',
-'有著書' => '有著書',
-'有著稱' => '有著稱',
-'有著者' => '有著者',
-'有著述' => '有著述',
-'有著錄' => '有著錄',
-'罗纳德·里根' => '朗奴·列根',
-'罗纳尔多' => '朗拿度',
-'罗纳尔迪尼奥' => '朗拿甸奴',
-'望著' => '望着',
-'望著作' => '望著作',
-'望著名' => '望著名',
-'望著書' => '望著書',
-'望著稱' => '望著稱',
-'望著者' => '望著者',
-'望著述' => '望著述',
-'望著錄' => '望著錄',
-'朝著' => '朝着',
-'朝著作' => '朝著作',
-'朝著名' => '朝著名',
-'朝著稱' => '朝著稱',
-'朝著者' => '朝著者',
-'朝著述' => '朝著述',
-'朝著錄' => '朝著錄',
-'板球' => '木球',
-'賓·拉登' => '本·拉登',
-'班傑明' => '本傑明',
-'賓拉登' => '本拉登',
-'本著' => '本着',
-'本著作' => '本著作',
-'本著名' => '本著名',
-'本著書' => '本著書',
-'本著稱' => '本著稱',
-'本著者' => '本著者',
-'本著述' => '本著述',
-'本著錄' => '本著錄',
-'里瓦尔多' => '李華度',
-'村里' => '村裏',
-'杜塞道夫' => '杜塞爾多夫',
-'迪拜' => '杜拜',
-'東協助' => '東協助',
-'東協會' => '東協會',
-'東協議' => '東協議',
-'東南亞國家協會' => '東南亞國家聯盟',
-'亚细安' => '東盟',
-'東協' => '東盟',
-'板著臉' => '板着臉',
-'枕著' => '枕着',
-'枕著作' => '枕著作',
-'枕著名' => '枕著名',
-'枕著稱' => '枕著稱',
-'枕著者' => '枕著者',
-'枕著述' => '枕著述',
-'枕著錄' => '枕著錄',
-'檯' => '枱',
-'台布' => '枱布',
-'台历' => '枱曆',
-'台灯' => '枱燈',
-'台面上' => '枱面上',
-'台面化' => '枱面化',
-'柏林墙' => '柏林圍牆',
-'奧黛莉·朵杜' => '柯德莉·塔圖',
-'奥黛丽·赫本' => '柯德莉·夏萍',
-'奧黛麗·赫本' => '柯德莉·夏萍',
-'哥廷根' => '格丁根',
-'格瑞那達' => '格林納達',
-'格莱美奖' => '格林美獎',
-'葛萊美獎' => '格林美獎',
-'格鲁吉亚' => '格魯吉亞',
-'框里' => '框裏',
-'台式电脑' => '桌上型電腦',
-'台球' => '桌球',
-'撞球' => '桌球',
-'梅鐸' => '梅鐸',
-'默多克' => '梅鐸',
-'梳著' => '梳着',
-'梳著作' => '梳著作',
-'梳著名' => '梳著名',
-'梳著稱' => '梳著稱',
-'梳著者' => '梳著者',
-'梳著述' => '梳著述',
-'梳著錄' => '梳著錄',
-'棉里' => '棉裏',
-'桑巴舞' => '森巴舞',
-'森林里' => '森林裏',
-'棺材里' => '棺材裏',
-'榴莲' => '榴槤',
-'榴蓮' => '榴槤',
-'樂著' => '樂着',
-'樂著作' => '樂著作',
-'樂著名' => '樂著名',
-'樂著書' => '樂著書',
-'樂著稱' => '樂著稱',
-'樂著者' => '樂著者',
-'樂著述' => '樂著述',
-'樂著錄' => '樂著錄',
-'標志著' => '標志着',
-'寶獅' => '標致',
-'標誌著' => '標誌着',
-'树林里' => '樹林裏',
-'工具機' => '機床',
-'机器人' => '機械人',
-'機器人' => '機械人',
-'柜台' => '櫃枱',
-'柜里' => '櫃裏',
-'历史里' => '歷史裏',
-'死里求生' => '死裏求生',
-'死里逃生' => '死裏逃生',
-'殺著' => '殺着',
-'殺著作' => '殺著作',
-'殺著名' => '殺著名',
-'殺著書' => '殺著書',
-'殺著稱' => '殺著稱',
-'殺著者' => '殺著者',
-'殺著述' => '殺著述',
-'殺著錄' => '殺著錄',
-'壳里' => '殼裏',
-'茅利塔尼亞' => '毛里塔尼亞',
-'模里西斯' => '毛里裘斯',
-'毛里求斯' => '毛里裘斯',
-'公厘' => '毫米',
-'公釐' => '毫米',
-'水来汤里去' => '水來湯裏去',
-'水里' => '水裏',
-'求著' => '求着',
-'求著作' => '求著作',
-'求著名' => '求著名',
-'求著書' => '求著書',
-'求著稱' => '求著稱',
-'求著者' => '求著者',
-'求著述' => '求著述',
-'求著錄' => '求著錄',
-'池里' => '池裏',
-'汙' => '污',
-'文莱' => '汶萊',
-'沈著' => '沈着',
-'沉著' => '沉着',
-'沉著作' => '沉著作',
-'沉著名' => '沉著名',
-'沉著書' => '沉著書',
-'沉著稱' => '沉著稱',
-'沉著者' => '沉著者',
-'沉著述' => '沉著述',
-'沉著錄' => '沉著錄',
-'沖著' => '沖着',
-'沖著。' => '沖著。',
-'沖著《' => '沖著《',
-'沖著,' => '沖著,',
-'沙地阿拉伯' => '沙特阿拉伯',
-'沙烏地阿拉伯' => '沙特阿拉伯',
-'沙里淘金' => '沙裏淘金',
-'河里' => '河裏',
-'沿著' => '沿着',
-'沿著作' => '沿著作',
-'沿著名' => '沿著名',
-'沿著書' => '沿著書',
-'沿著稱' => '沿著稱',
-'沿著者' => '沿著者',
-'沿著述' => '沿著述',
-'沿著錄' => '沿著錄',
-'法占' => '法佔',
-'法里,' => '法裏,',
-'玻里尼西亞' => '波利尼西亞',
-'波士尼亞' => '波斯尼亞',
-'波士尼亞赫塞哥維納' => '波斯尼亞黑塞哥維那',
-'宝莱坞' => '波里活',
-'寶萊塢' => '波里活',
-'幫浦' => '泵',
-'洞里' => '洞裏',
-'辛巴威' => '津巴布韋',
-'宏都拉斯' => '洪都拉斯',
-'活著' => '活着',
-'活著作' => '活著作',
-'活著名' => '活著名',
-'活著書' => '活著書',
-'活著稱' => '活著稱',
-'活著者' => '活著者',
-'活著述' => '活著述',
-'活著錄' => '活著錄',
-'移动网络' => '流動網絡',
-'行動網路' => '流動網絡',
-'移动电话' => '流動電話',
-'行動電話' => '流動電話',
-'流著' => '流着',
-'流著作' => '流著作',
-'流著名' => '流著名',
-'流著書' => '流著書',
-'流著稱' => '流著稱',
-'流著者' => '流著者',
-'流著述' => '流著述',
-'流著錄' => '流著錄',
-'流露著' => '流露着',
-'浮著' => '浮着',
-'蘭卡威' => '浮羅交怡',
-'浮著作' => '浮著作',
-'浮著名' => '浮著名',
-'浮著書' => '浮著書',
-'浮著稱' => '浮著稱',
-'浮著者' => '浮著者',
-'浮著述' => '浮著述',
-'浮著錄' => '浮著錄',
-'海上布雷' => '海上佈雷',
-'海洛因' => '海洛英',
-'海湾布雷' => '海灣佈雷',
-'海灣布雷' => '海灣佈雷',
-'涼著' => '涼着',
-'涼著作' => '涼著作',
-'涼著名' => '涼著名',
-'涼著書' => '涼著書',
-'涼著稱' => '涼著稱',
-'涼著者' => '涼著者',
-'涼著述' => '涼著述',
-'涼著錄' => '涼著錄',
-'深山里' => '深山裏',
-'渊里' => '淵裏',
-'渴著' => '渴着',
-'渴著作' => '渴著作',
-'渴著名' => '渴著名',
-'渴著書' => '渴著書',
-'渴著稱' => '渴著稱',
-'渴著者' => '渴著者',
-'渴著述' => '渴著述',
-'渴著錄' => '渴著錄',
-'湊合著' => '湊合着',
-'湖里' => '湖裏',
-'准将' => '準將',
-'准將' => '準將',
-'准尉' => '準尉',
-'溢著' => '溢着',
-'溢著作' => '溢著作',
-'溢著名' => '溢著名',
-'溢著書' => '溢著書',
-'溢著稱' => '溢著稱',
-'溢著者' => '溢著者',
-'溢著述' => '溢著述',
-'溢著錄' => '溢著錄',
-'演著' => '演着',
-'演著作' => '演著作',
-'演著名' => '演著名',
-'演著書' => '演著書',
-'演著稱' => '演著稱',
-'演著者' => '演著者',
-'演著述' => '演著述',
-'演著錄' => '演著錄',
-'漠里' => '漠裏',
-'漢諾瓦' => '漢諾威',
-'漫著' => '漫着',
-'漫著作' => '漫著作',
-'漫著名' => '漫著名',
-'漫著書' => '漫著書',
-'漫著稱' => '漫著稱',
-'漫著者' => '漫著者',
-'漫著述' => '漫著述',
-'漫著錄' => '漫著錄',
-'潜意识里' => '潛意識裏',
-'潤著' => '潤着',
-'潤著作' => '潤著作',
-'潤著名' => '潤著名',
-'潤著書' => '潤著書',
-'潤著稱' => '潤著稱',
-'潤著者' => '潤著者',
-'潤著述' => '潤著述',
-'潤著錄' => '潤著錄',
-'潭里' => '潭裏',
-'溼' => '濕',
-'火山里' => '火山裏',
-'火箭布雷' => '火箭佈雷',
-'為著' => '為着',
-'為著《' => '為著《',
-'為著作' => '為著作',
-'為著名' => '為著名',
-'為著稱' => '為著稱',
-'為著者' => '為著者',
-'為著述' => '為著述',
-'為著錄' => '為著錄',
-'菸' => '煙',
-'照占' => '照佔',
-'照著' => '照着',
-'照著作' => '照著作',
-'照著名' => '照著名',
-'照著書' => '照著書',
-'照著稱' => '照著稱',
-'照著者' => '照著者',
-'照著述' => '照著述',
-'照著錄' => '照著錄',
-'燒著' => '燒着',
-'燒著作' => '燒著作',
-'燒著名' => '燒著名',
-'燒著書' => '燒著書',
-'燒著稱' => '燒著稱',
-'燒著者' => '燒著者',
-'燒著述' => '燒著述',
-'燒著錄' => '燒著錄',
-'爭著' => '爭着',
-'爭著作' => '爭著作',
-'爭著名' => '爭著名',
-'爭著書' => '爭著書',
-'爭著稱' => '爭著稱',
-'爭著者' => '爭著者',
-'爭著述' => '爭著述',
-'爭著錄' => '爭著錄',
-'墙里' => '牆裏',
-'版图里' => '版圖裏',
-'版权信息' => '版權資訊',
-'千里達托貝哥' => '特立尼達和多巴哥',
-'牽著' => '牽着',
-'牽著作' => '牽著作',
-'牽著名' => '牽著名',
-'牽著書' => '牽著書',
-'牽著稱' => '牽著稱',
-'牽著者' => '牽著者',
-'牽著述' => '牽著述',
-'牽著錄' => '牽著錄',
-'犯不著' => '犯不着',
-'犯不著作' => '犯不著作',
-'犯不著名' => '犯不著名',
-'犯不著書' => '犯不著書',
-'犯不著稱' => '犯不著稱',
-'犯不著者' => '犯不著者',
-'犯不著述' => '犯不著述',
-'犯不著錄' => '犯不著錄',
-'犯得著' => '犯得着',
-'狂占' => '狂佔',
-'猜著' => '猜着',
-'猜著作' => '猜著作',
-'猜著名' => '猜著名',
-'猜著書' => '猜著書',
-'猜著稱' => '猜著稱',
-'猜著者' => '猜著者',
-'猜著述' => '猜著述',
-'猜著錄' => '猜著錄',
-'猶豫著' => '猶豫着',
-'狱里' => '獄裏',
-'独占' => '獨佔',
-'獨占' => '獨佔',
-'獨立國家國協' => '獨立國家聯合體',
-'獨立國協' => '獨聯體',
-'獲著' => '獲着',
-'獲著作' => '獲著作',
-'獲著名' => '獲著名',
-'獲著書' => '獲著書',
-'獲著稱' => '獲著稱',
-'獲著者' => '獲著者',
-'獲著述' => '獲著述',
-'獲著錄' => '獲著錄',
-'班固著' => '班固著',
-'班里' => '班裏',
-'球台' => '球枱',
-'卢塞恩' => '琉森',
-'諾鲁' => '瑙魯',
-'萬那杜' => '瓦努阿圖',
-'肯尼迪' => '甘迺迪',
-'甜著' => '甜着',
-'甜著作' => '甜著作',
-'甜著名' => '甜著名',
-'甜著書' => '甜著書',
-'甜著稱' => '甜著稱',
-'甜著者' => '甜著者',
-'甜著述' => '甜著述',
-'甜著錄' => '甜著錄',
-'用不著' => '用不着',
-'用得著' => '用得着',
-'用法里' => '用法裏',
-'用著' => '用着',
-'用著作' => '用著作',
-'用著名' => '用著名',
-'用著書' => '用著書',
-'用著稱' => '用著稱',
-'用著者' => '用著者',
-'用著述' => '用著述',
-'用著錄' => '用著錄',
-'田里' => '田裏',
-'由表及里' => '由表及裏',
-'A型肝炎' => '甲型肝炎',
-'A肝' => '甲肝',
-'界里' => '界裏',
-'留著' => '留着',
-'留著作' => '留著作',
-'留著名' => '留著名',
-'留著書' => '留著書',
-'留著稱' => '留著稱',
-'留著者' => '留著者',
-'留著述' => '留著述',
-'留著錄' => '留著錄',
-'畫著' => '畫着',
-'畫著作' => '畫著作',
-'畫著名' => '畫著名',
-'畫著稱' => '畫著稱',
-'畫著者' => '畫著者',
-'當著' => '當着',
-'當著作' => '當著作',
-'過著作' => '當著作',
-'當著名' => '當著名',
-'過著名' => '當著名',
-'當著書' => '當著書',
-'過著書' => '當著書',
-'當著稱' => '當著稱',
-'過著稱' => '當著稱',
-'當著者' => '當著者',
-'過著者' => '當著者',
-'當著述' => '當著述',
-'過著述' => '當著述',
-'當著錄' => '當著錄',
-'過著錄' => '當著錄',
-'几内亚' => '畿內亞',
-'幾內亞' => '畿內亞',
-'迭代' => '疊代',
-'疑著' => '疑着',
-'疑著作' => '疑著作',
-'疑著名' => '疑著名',
-'疑著書' => '疑著書',
-'疑著稱' => '疑著稱',
-'疑著者' => '疑著者',
-'疑著述' => '疑著述',
-'疑著錄' => '疑著錄',
-'狂牛症' => '瘋牛症',
-'发布' => '發佈',
-'發布' => '發佈',
-'發著' => '發着',
-'發著《' => '發著《',
-'發著作' => '發著作',
-'發著名' => '發著名',
-'發著稱' => '發著稱',
-'發著者' => '發著者',
-'白里透红' => '白裏透紅',
-'戈登·布朗' => '白高敦',
-'百科里' => '百科裏',
-'的图里' => '的圖裏',
-'的山里' => '的山裏',
-'皮里春秋' => '皮裏春秋',
-'皮里阳秋' => '皮裏陽秋',
-'皺著' => '皺着',
-'皺著作' => '皺著作',
-'皺著名' => '皺著名',
-'皺著書' => '皺著書',
-'皺著稱' => '皺著稱',
-'皺著者' => '皺著者',
-'皺著述' => '皺著述',
-'皺著錄' => '皺著錄',
-'盒里' => '盒裏',
-'盛著' => '盛着',
-'盛著作' => '盛著作',
-'盛著名' => '盛著名',
-'盛著書' => '盛著書',
-'盛著稱' => '盛著稱',
-'盛著者' => '盛著者',
-'盛著述' => '盛著述',
-'盛著錄' => '盛著錄',
-'盘里' => '盤裏',
-'盧安達' => '盧旺達',
-'羅亞爾' => '盧瓦爾',
-'盯著' => '盯着',
-'盯著作' => '盯著作',
-'盯著名' => '盯著名',
-'盯著書' => '盯著書',
-'盯著稱' => '盯著稱',
-'盯著者' => '盯著者',
-'盯著述' => '盯著述',
-'盯著錄' => '盯著錄',
-'看不著' => '看不着',
-'看得著' => '看得着',
-'看法里' => '看法裏',
-'看著' => '看着',
-'看著作' => '看著作',
-'看著名' => '看著名',
-'看著書' => '看著書',
-'看著稱' => '看著稱',
-'看著者' => '看著者',
-'看著述' => '看著述',
-'看著錄' => '看著錄',
-'眼眶里' => '眼眶裏',
-'眼睛里' => '眼睛裏',
-'眼里' => '眼裏',
-'著什' => '着什',
-'著他' => '着他',
-'著你' => '着你',
-'著力' => '着力',
-'著地' => '着地',
-'著墨' => '着墨',
-'著她' => '着她',
-'著妳' => '着妳',
-'著它' => '着它',
-'著實' => '着實',
-'著忙' => '着忙',
-'著急' => '着急',
-'著想' => '着想',
-'著意' => '着意',
-'著我' => '着我',
-'著手' => '着手',
-'著數' => '着數',
-'著法' => '着法',
-'著涼' => '着涼',
-'著火' => '着火',
-'著甚麽' => '着甚麽',
-'著眼' => '着眼',
-'著祂' => '着祂',
-'著筆' => '着筆',
-'著絲' => '着絲',
-'著緊' => '着緊',
-'著腳' => '着腳',
-'著艦' => '着艦',
-'著色' => '着色',
-'著落' => '着落',
-'著衣' => '着衣',
-'著裝' => '着裝',
-'著迷' => '着迷',
-'著重' => '着重',
-'著錄' => '着錄',
-'著陸' => '着陸',
-'著鞭' => '着鞭',
-'睡不著' => '睡不着',
-'睡得著' => '睡得着',
-'睡著' => '睡着',
-'睡著作' => '睡著作',
-'睡著名' => '睡著名',
-'睡著書' => '睡著書',
-'睡著稱' => '睡著稱',
-'睡著者' => '睡著者',
-'睡著述' => '睡著述',
-'睡著錄' => '睡著錄',
-'瞞著' => '瞞着',
-'瞞著作' => '瞞著作',
-'瞞著名' => '瞞著名',
-'瞞著書' => '瞞著書',
-'瞞著稱' => '瞞著稱',
-'瞞著者' => '瞞著者',
-'瞞著述' => '瞞著述',
-'瞞著錄' => '瞞著錄',
-'瞪著' => '瞪着',
-'瞪著作' => '瞪著作',
-'瞪著名' => '瞪著名',
-'瞪著書' => '瞪著書',
-'瞪著稱' => '瞪著稱',
-'瞪著者' => '瞪著者',
-'瞪著述' => '瞪著述',
-'瞪著錄' => '瞪著錄',
-'矛盾著' => '矛盾着',
-'智慧財產權' => '知識產權',
-'智財權' => '知識產權',
-'短信' => '短訊',
-'簡訊' => '短訊',
-'什勒斯維希' => '石勒蘇益格',
-'硅' => '矽',
-'硅藻' => '硅藻',
-'硬件' => '硬件',
-'硬體' => '硬件',
-'碗里' => '碗裏',
-'貝克漢' => '碧咸',
-'贝克汉姆' => '碧咸',
-'社里' => '社裏',
-'福馬林' => '福爾馬林',
-'福著' => '福着',
-'福著作' => '福著作',
-'福著名' => '福著名',
-'福著書' => '福著書',
-'福著稱' => '福著稱',
-'福著者' => '福著者',
-'福著述' => '福著述',
-'福著錄' => '福著錄',
-'秀发布' => '秀發佈',
-'私下里' => '私下裏',
-'隐私' => '私隱',
-'隱私' => '私隱',
-'葛摩' => '科摩羅',
-'程序员' => '程式設計師',
-'捷豹' => '積架',
-'稳占' => '穩佔',
-'穩占' => '穩佔',
-'穫著' => '穫着',
-'空中布雷' => '空中佈雷',
-'空投布雷' => '空投佈雷',
-'空气质量' => '空氣質素',
-'空氣品質' => '空氣質素',
-'空著' => '空着',
-'空著作' => '空著作',
-'空著名' => '空著名',
-'空著書' => '空著書',
-'空著稱' => '空著稱',
-'空著者' => '空著者',
-'空著述' => '空著述',
-'空著錄' => '空著錄',
-'太空梭' => '穿梭機',
-'航天飞机' => '穿梭機',
-'穿著' => '穿着',
-'穿著作' => '穿著作',
-'穿著名' => '穿著名',
-'穿著書' => '穿著書',
-'穿著稱' => '穿著稱',
-'穿著者' => '穿著者',
-'穿著述' => '穿著述',
-'穿著錄' => '穿著錄',
-'窝里' => '窩裏',
-'窝里斗' => '窩裏鬥',
-'立著' => '立着',
-'立著《' => '立著《',
-'立著作' => '立著作',
-'立著名' => '立著名',
-'立著有' => '立著有',
-'立著称' => '立著稱',
-'立著稱' => '立著稱',
-'立著者' => '立著者',
-'立著(' => '立著(',
-'站著' => '站着',
-'站著作' => '站著作',
-'站著名' => '站著名',
-'站著書' => '站著書',
-'站著稱' => '站著稱',
-'站著者' => '站著者',
-'站著述' => '站著述',
-'站著錄' => '站著錄',
-'竪著' => '竪着',
-'笑著' => '笑着',
-'笑著作' => '笑著作',
-'笑著名' => '笑著名',
-'笑著書' => '笑著書',
-'笑著稱' => '笑著稱',
-'笑著者' => '笑著者',
-'笑著述' => '笑著述',
-'笑著錄' => '笑著錄',
-'笑里藏刀' => '笑裏藏刀',
-'提比里西' => '第比利斯',
-'管著' => '管着',
-'管著作' => '管著作',
-'管著名' => '管著名',
-'管著書' => '管著書',
-'管著稱' => '管著稱',
-'管著者' => '管著者',
-'管著述' => '管著述',
-'管著錄' => '管著錄',
-'箱里' => '箱裏',
-'节目里' => '節目裏',
-'簽著' => '簽着',
-'篮板球' => '籃板球',
-'籃板球' => '籃板球',
-'迈克尔' => '米高',
-'麦克尔' => '米高',
-'迈克尔·欧文' => '米高·奧雲',
-'糊里糊涂' => '糊裏糊塗',
-'系列里' => '系列裏',
-'係數' => '系數',
-'系里' => '系裏',
-'約占' => '約佔',
-'约占' => '約佔',
-'紐賓士域' => '紐賓士域',
-'索尔仁尼琴' => '索贊尼辛',
-'索忍尼辛' => '索贊尼辛',
-'索馬利亞' => '索馬里',
-'索馬利里' => '索馬里',
-'紮著' => '紮着',
-'紮著作' => '紮著作',
-'紮著名' => '紮著名',
-'紮著書' => '紮著書',
-'紮著稱' => '紮著稱',
-'紮著者' => '紮著者',
-'紮著述' => '紮著述',
-'紮著錄' => '紮著錄',
-'组里' => '組裏',
-'吉他' => '結他',
-'結彩' => '結綵',
-'结彩' => '結綵',
-'綁著' => '綁着',
-'綁著作' => '綁著作',
-'綁著名' => '綁著名',
-'綁著書' => '綁著書',
-'綁著稱' => '綁著稱',
-'綁著者' => '綁著者',
-'綁著述' => '綁著述',
-'綁著錄' => '綁著錄',
-'网站里' => '網站裏',
-'網路' => '網絡',
-'网里' => '網裏',
-'彩带' => '綵帶',
-'彩帶' => '綵帶',
-'彩排' => '綵排',
-'彩楼' => '綵樓',
-'彩樓' => '綵樓',
-'彩牌楼' => '綵牌樓',
-'彩牌樓' => '綵牌樓',
-'彩球' => '綵球',
-'彩綢' => '綵綢',
-'彩绸' => '綵綢',
-'彩线' => '綵綫',
-'彩線' => '綵線',
-'彩船' => '綵船',
-'彩衣' => '綵衣',
-'线图里' => '線圖裏',
-'緝凶' => '緝兇',
-'县里' => '縣裏',
-'缝里' => '縫裏',
-'縱著' => '縱着',
-'总数里' => '總數裏',
-'尖峰時段' => '繁忙時段',
-'尖峰時間' => '繁忙時間',
-'正體中文' => '繁體中文',
-'繃著' => '繃着',
-'繞著' => '繞着',
-'繞著作' => '繞著作',
-'繞著名' => '繞著名',
-'繞著書' => '繞著書',
-'繞著稱' => '繞著稱',
-'繞著者' => '繞著者',
-'繞著述' => '繞著述',
-'繞著錄' => '繞著錄',
-'系着' => '繫着',
-'繫著' => '繫着',
-'纏著' => '纏着',
-'纏著作' => '纏著作',
-'纏著名' => '纏著名',
-'纏著書' => '纏著書',
-'纏著稱' => '纏著稱',
-'纏著者' => '纏著者',
-'纏著述' => '纏著述',
-'纏著錄' => '纏著錄',
-'罩著' => '罩着',
-'罩著作' => '罩著作',
-'罩著名' => '罩著名',
-'罩著書' => '罩著書',
-'罩著稱' => '罩著稱',
-'罩著者' => '罩著者',
-'罩著述' => '罩著述',
-'罩著錄' => '罩著錄',
-'罵著' => '罵着',
-'罵著作' => '罵著作',
-'罵著名' => '罵著名',
-'罵著書' => '罵著書',
-'罵著稱' => '罵著稱',
-'罵著者' => '罵著者',
-'罵著述' => '罵著述',
-'罵著錄' => '罵著錄',
-'卢浮宫' => '羅浮宮',
-'美占' => '美佔',
-'美著' => '美着',
-'美著作' => '美著作',
-'美著名' => '美著名',
-'美著書' => '美著書',
-'美著称' => '美著稱',
-'美著稱' => '美著稱',
-'美著者' => '美著者',
-'美著述' => '美著述',
-'美著錄' => '美著錄',
-'耀著' => '耀着',
-'耀著作' => '耀著作',
-'耀著名' => '耀著名',
-'耀著書' => '耀著書',
-'耀著稱' => '耀著稱',
-'耀著者' => '耀著者',
-'耀著述' => '耀著述',
-'耀著錄' => '耀著錄',
-'寮國' => '老撾',
-'寮人民民主共和國' => '老撾人民民主共和國',
-'寮語' => '老撾語',
-'考著' => '考着',
-'考著作' => '考著作',
-'考著名' => '考著名',
-'考著書' => '考著書',
-'考著稱' => '考著稱',
-'考著者' => '考著者',
-'考著述' => '考著述',
-'考著錄' => '考著錄',
-'圣基茨和尼维斯' => '聖吉斯納域斯',
-'聖克里斯多福及尼維斯' => '聖吉斯納域斯',
-'聖文森及格瑞那丁' => '聖文森特和格林納丁斯',
-'聖露西亞' => '聖盧西亞',
-'聖馬利諾' => '聖馬力諾',
-'聽不著' => '聽不着',
-'聽得著' => '聽得着',
-'聽著' => '聽着',
-'聽著作' => '聽著作',
-'聽著名' => '聽著名',
-'聽著書' => '聽著書',
-'聽著稱' => '聽著稱',
-'聽著者' => '聽著者',
-'聽著述' => '聽著述',
-'聽著錄' => '聽著錄',
-'肚里' => '肚裏',
-'肯尼亚' => '肯雅',
-'胃里' => '胃裏',
-'背地里' => '背地裏',
-'背著' => '背着',
-'背著作' => '背著作',
-'背著名' => '背著名',
-'背著書' => '背著書',
-'背著稱' => '背著稱',
-'背著者' => '背著者',
-'背著述' => '背著述',
-'背著錄' => '背著錄',
-'胡里胡涂' => '胡裏胡塗',
-'腰里' => '腰裏',
-'膠著' => '膠着',
-'膠著作' => '膠著作',
-'膠著名' => '膠著名',
-'膠著書' => '膠著書',
-'膠著稱' => '膠著稱',
-'膠著者' => '膠著者',
-'膠著述' => '膠著述',
-'膠著錄' => '膠著錄',
-'塑料袋' => '膠袋',
-'臨著' => '臨着',
-'臨著作' => '臨著作',
-'臨著名' => '臨著名',
-'臨著書' => '臨著書',
-'臨著稱' => '臨著稱',
-'臨著者' => '臨著者',
-'臨著述' => '臨著述',
-'臨著錄' => '臨著錄',
-'自行火炮' => '自走炮',
-'與著' => '與着',
-'與著作' => '與著作',
-'與著名' => '與著名',
-'與著書' => '與著書',
-'與著稱' => '與著稱',
-'與著者' => '與著者',
-'與著述' => '與著述',
-'與著錄' => '與著錄',
-'舒马赫' => '舒麥加',
-'愛荷華' => '艾奧瓦',
-'爱荷华' => '艾奧瓦',
-'埃菲尔' => '艾菲爾',
-'帕塔亚' => '芭達亞',
-'花盆里' => '花盆裏',
-'苑里' => '苑裏',
-'苑裡' => '苑裡',
-'苦著' => '苦着',
-'苦著作' => '苦著作',
-'苦著名' => '苦著名',
-'苦著書' => '苦著書',
-'苦著稱' => '苦著稱',
-'苦著者' => '苦著者',
-'苦著述' => '苦著述',
-'苦著錄' => '苦著錄',
-'苦里' => '苦裏',
-'英占' => '英佔',
-'共和联邦' => '英聯邦',
-'大英國協' => '英聯邦',
-'草丛里' => '草叢裏',
-'霍爾斯坦' => '荷爾斯泰因',
-'好莱坞' => '荷里活',
-'好萊塢' => '荷里活',
-'庄里' => '莊裏',
-'莫三比克' => '莫桑比克',
-'巴伦西亚' => '華倫西亞',
-'巴倫西亞' => '華倫西亞',
-'瓦倫西亞' => '華倫西亞',
-'瓦文萨' => '華里沙',
-'華勒沙' => '華里沙',
-'菲利普亲王' => '菲臘親王',
-'菲利普親王' => '菲臘親王',
-'賴索托' => '萊索托',
-'马恩岛' => '萌島',
-'馬自達' => '萬事得',
-'马自达' => '萬事得',
-'万历朝鲜战争' => '萬曆朝鮮戰爭',
-'落著' => '落着',
-'落著作' => '落著作',
-'落著名' => '落著名',
-'落著書' => '落著書',
-'落著稱' => '落著稱',
-'落著者' => '落著者',
-'落著述' => '落著述',
-'落著錄' => '落著錄',
-'葉爾欽' => '葉利欽',
-'葡占' => '葡佔',
-'葫芦里卖甚么药' => '葫蘆裏賣甚麼藥',
-'滿地可' => '蒙特利爾',
-'蒙特婁' => '蒙特利爾',
-'蒙著' => '蒙着',
-'蒙著作' => '蒙著作',
-'蒙著名' => '蒙著名',
-'蒙著書' => '蒙著書',
-'蒙著稱' => '蒙著稱',
-'蒙著者' => '蒙著者',
-'蒙著述' => '蒙著述',
-'蒙著錄' => '蒙著錄',
-'蓋著' => '蓋着',
-'蓋著作' => '蓋著作',
-'蓋著名' => '蓋著名',
-'蓋著稱' => '蓋著稱',
-'肖斯塔科维奇' => '蕭士達高維契',
-'蕭士塔高維奇' => '蕭士達高維契',
-'肖邦' => '蕭邦',
-'薛丁格' => '薛定諤',
-'塞拉耶佛' => '薩拉熱窩',
-'萨达姆' => '薩達姆',
-'藉著' => '藉着',
-'藏著' => '藏着',
-'藏著作' => '藏著作',
-'藏著名' => '藏著名',
-'藏著書' => '藏著書',
-'藏著稱' => '藏著稱',
-'藏著者' => '藏著者',
-'藏著述' => '藏著述',
-'藏著錄' => '藏著錄',
-'蘊涵著' => '蘊涵着',
-'蘸著' => '蘸着',
-'蘸著作' => '蘸著作',
-'蘸著名' => '蘸著名',
-'蘸著書' => '蘸著書',
-'蘸著稱' => '蘸著稱',
-'蘸著者' => '蘸著者',
-'蘸著述' => '蘸著述',
-'蘸著錄' => '蘸著錄',
-'蜜里调油' => '蜜裏調油',
-'荧屏' => '螢屏',
-'屏幕' => '螢幕',
-'人行道' => '行人路',
-'行家里手' => '行家裏手',
-'首席执行官' => '行政總裁',
-'行著' => '行着',
-'行著作' => '行著作',
-'行著名' => '行著名',
-'行著書' => '行著書',
-'行著稱' => '行著稱',
-'行著者' => '行著者',
-'行著述' => '行著述',
-'行著錄' => '行著錄',
-'衝著' => '衝着',
-'衣著' => '衣着',
-'衣著作' => '衣著作',
-'衣著名' => '衣著名',
-'衣著書' => '衣著書',
-'衣著稱' => '衣著稱',
-'衣著者' => '衣著者',
-'衣著述' => '衣著述',
-'衣著錄' => '衣著錄',
-'表里' => '表裏',
-'表里一致' => '表裏一致',
-'表里不一' => '表裏不一',
-'表里如一' => '表裏如一',
-'表里山河' => '表裏山河',
-'袋里' => '袋裏',
-'袖里' => '袖裏',
-'被里' => '被裏',
-'裡' => '裏',
-'里勾外连' => '裏勾外連',
-'里屋' => '裏屋',
-'里层' => '裏層',
-'里带' => '裏帶',
-'里弦' => '裏弦',
-'里应外合' => '裏應外合',
-'里海' => '裏海',
-'里脊' => '裏脊',
-'里衣' => '裏衣',
-'里通外国' => '裏通外國',
-'里通外敌' => '裏通外敵',
-'里边' => '裏邊',
-'里间' => '裏間',
-'里面' => '裏面',
-'里头' => '裏頭',
-'裝著' => '裝着',
-'裝著作' => '裝著作',
-'裝著名' => '裝著名',
-'裝著書' => '裝著書',
-'裝著稱' => '裝著稱',
-'裝著者' => '裝著者',
-'裝著述' => '裝著述',
-'裝著錄' => '裝著錄',
-'裡冷' => '裡冷',
-'裹著' => '裹着',
-'裹著作' => '裹著作',
-'裹著名' => '裹著名',
-'裹著書' => '裹著書',
-'裹著稱' => '裹著稱',
-'裹著者' => '裹著者',
-'裹著述' => '裹著述',
-'裹著錄' => '裹著錄',
-'衬里' => '襯裏',
-'西占' => '西佔',
-'塞維亞' => '西維爾',
-'塞维利亚' => '西維爾',
-'要占' => '要佔',
-'要占卜' => '要占卜',
-'覆著' => '覆着',
-'覆蓋著' => '覆蓋着',
-'見著' => '見着',
-'見著作' => '見著作',
-'見著名' => '見著名',
-'見著書' => '見著書',
-'見著稱' => '見著稱',
-'見著者' => '見著者',
-'見著述' => '見著述',
-'見著錄' => '見著錄',
-'視著' => '視着',
-'視著名' => '視著名',
-'角落里' => '角落裏',
-'分辨率' => '解像度',
-'解析度' => '解像度',
-'言里' => '言裏',
-'計畫' => '計劃',
-'記著' => '記着',
-'記著作' => '記著作',
-'記著名' => '記著名',
-'記著書' => '記著書',
-'記著稱' => '記著稱',
-'記著者' => '記著者',
-'記著述' => '記著述',
-'記著錄' => '記著錄',
-'試著' => '試着',
-'試著作' => '試著作',
-'試著名' => '試著名',
-'試著書' => '試著書',
-'試著稱' => '試著稱',
-'試著者' => '試著者',
-'試著述' => '試著述',
-'試著錄' => '試著錄',
-'话里有话' => '話裏有話',
-'语法里' => '語法裏',
-'語著' => '語着',
-'語著作' => '語著作',
-'語著名' => '語著名',
-'語著書' => '語著書',
-'語著稱' => '語著稱',
-'語著者' => '語著者',
-'語著述' => '語著述',
-'語著錄' => '語著錄',
-'语里' => '語裏',
-'說著' => '說着',
-'說著作' => '說著作',
-'說著稱' => '說著稱',
-'說著者' => '說著者',
-'說著述' => '說著述',
-'數據機' => '調制解調器',
-'诺曼底' => '諾曼第',
-'警戒著' => '警戒着',
-'變著' => '變着',
-'變著作' => '變著作',
-'變著名' => '變著名',
-'變著書' => '變著書',
-'變著稱' => '變著稱',
-'變著者' => '變著者',
-'變著述' => '變著述',
-'變著錄' => '變著錄',
-'豎著' => '豎着',
-'豎著作' => '豎著作',
-'豎著名' => '豎著名',
-'豎著書' => '豎著書',
-'豎著稱' => '豎著稱',
-'豎著者' => '豎著者',
-'豎著述' => '豎著述',
-'豎著錄' => '豎著錄',
-'象徵著名' => '象徵著名',
-'象徵著' => '象著着',
-'貝爾格勒' => '貝爾格萊德',
-'布莱尔' => '貝理雅',
-'負著' => '負着',
-'貢寮' => '貢寮',
-'買凶' => '買兇',
-'費占' => '費佔',
-'费占' => '費佔',
-'信息时代' => '資訊時代',
-'赌台' => '賭枱',
-'尚比亞' => '贊比亞',
-'西臺人' => '赫梯人',
-'西臺國' => '赫梯國',
-'西臺帝' => '赫梯帝',
-'西臺文' => '赫梯文',
-'西臺族' => '赫梯族',
-'西臺王' => '赫梯王',
-'西臺語' => '赫梯語',
-'赫魯雪夫' => '赫魯曉夫',
-'走為上著' => '走為上着',
-'走著' => '走着',
-'走著作' => '走著作',
-'走著名' => '走著名',
-'走著書' => '走著書',
-'走著稱' => '走著稱',
-'走著者' => '走著者',
-'走著述' => '走著述',
-'走著錄' => '走著錄',
-'趕著' => '趕着',
-'趕著作' => '趕著作',
-'趕著名' => '趕著名',
-'趕著書' => '趕著書',
-'趕著稱' => '趕著稱',
-'趕著者' => '趕著者',
-'趕著述' => '趕著述',
-'趕著錄' => '趕著錄',
-'趴著' => '趴着',
-'趴著作' => '趴著作',
-'趴著名' => '趴著名',
-'趴著書' => '趴著書',
-'趴著稱' => '趴著稱',
-'趴著者' => '趴著者',
-'趴著述' => '趴著述',
-'趴著錄' => '趴著錄',
-'跑著' => '跑着',
-'跑著作' => '跑著作',
-'跑著名' => '跑著名',
-'跑著書' => '跑著書',
-'跑著稱' => '跑著稱',
-'跑著者' => '跑著者',
-'跑著述' => '跑著述',
-'跑著錄' => '跑著錄',
-'跟著' => '跟着',
-'跟著作' => '跟著作',
-'跟著名' => '跟著名',
-'跟著書' => '跟著書',
-'跟著稱' => '跟著稱',
-'跟著者' => '跟著者',
-'跟著述' => '跟著述',
-'跟著錄' => '跟著錄',
-'跪著' => '跪着',
-'跪著作' => '跪著作',
-'跪著名' => '跪著名',
-'跪著書' => '跪著書',
-'跪著稱' => '跪著稱',
-'跪著者' => '跪著者',
-'跪著述' => '跪著述',
-'跪著錄' => '跪著錄',
-'路图里' => '路圖裏',
-'跳著' => '跳着',
-'跳著作' => '跳著作',
-'跳著名' => '跳著名',
-'跳著書' => '跳著書',
-'跳著稱' => '跳著稱',
-'跳著者' => '跳著者',
-'跳著述' => '跳著述',
-'跳著錄' => '跳著錄',
-'踏著' => '踏着',
-'踏著作' => '踏著作',
-'踏著名' => '踏著名',
-'踏著稱' => '踏著稱',
-'踏著者' => '踏著者',
-'踏著述' => '踏著述',
-'踏著錄' => '踏著錄',
-'踩著' => '踩着',
-'踩著作' => '踩著作',
-'踩著名' => '踩著名',
-'踩著書' => '踩著書',
-'踩著稱' => '踩著稱',
-'踩著者' => '踩著者',
-'踩著述' => '踩著述',
-'踩著錄' => '踩著錄',
-'躍著' => '躍着',
-'躍著作' => '躍著作',
-'躍著名' => '躍著名',
-'躍著書' => '躍著書',
-'躍著稱' => '躍著稱',
-'躍著者' => '躍著者',
-'躍著述' => '躍著述',
-'躍著錄' => '躍著錄',
-'身著' => '身着',
-'身著作' => '身著作',
-'身著名' => '身著名',
-'身著書' => '身著書',
-'身著稱' => '身著稱',
-'身著者' => '身著者',
-'身著述' => '身著述',
-'身著錄' => '身著錄',
-'躺著' => '躺着',
-'躺著作' => '躺著作',
-'躺著名' => '躺著名',
-'躺著書' => '躺著書',
-'躺著稱' => '躺著稱',
-'躺著者' => '躺著者',
-'躺著述' => '躺著述',
-'躺著錄' => '躺著錄',
-'车库里' => '車庫裏',
-'车站里' => '車站裏',
-'车里' => '車裏',
-'车里雅宾斯克' => '車里雅賓斯克',
-'軟體' => '軟件',
-'軟體動物' => '軟體動物',
-'軟體家具' => '軟體家具',
-'載著' => '載着',
-'載著作' => '載著作',
-'載著名' => '載著名',
-'載著書' => '載著書',
-'載著稱' => '載著稱',
-'載著者' => '載著者',
-'載著述' => '載著述',
-'載著錄' => '載著錄',
-'轉著' => '轉着',
-'轉著作' => '轉著作',
-'轉著名' => '轉著名',
-'轉著書' => '轉著書',
-'轉著稱' => '轉著稱',
-'轉著者' => '轉著者',
-'轉著述' => '轉著述',
-'轉著錄' => '轉著錄',
-'办公台' => '辦公枱',
-'辦著' => '辦着',
-'辦著作' => '辦著作',
-'辦著名' => '辦著名',
-'辦著書' => '辦著書',
-'辦著稱' => '辦著稱',
-'辦著者' => '辦著者',
-'辦著述' => '辦著述',
-'辦著錄' => '辦著錄',
-'迫著' => '迫着',
-'追著' => '追着',
-'追著作' => '追著作',
-'追著名' => '追著名',
-'追著書' => '追著書',
-'追著稱' => '追著稱',
-'追著者' => '追著者',
-'追著述' => '追著述',
-'追著錄' => '追著錄',
-'逆著' => '逆着',
-'逆著作' => '逆著作',
-'逆著名' => '逆著名',
-'逆著書' => '逆著書',
-'逆著稱' => '逆著稱',
-'逆著者' => '逆著者',
-'逆著述' => '逆著述',
-'逆著錄' => '逆著錄',
-'径入' => '逕入',
-'径到' => '逕到',
-'径取' => '逕取',
-'径启' => '逕啟',
-'径寄' => '逕寄',
-'径庭' => '逕庭',
-'径往' => '逕往',
-'径自' => '逕自',
-'径行' => '逕行',
-'径迎' => '逕迎',
-'这里' => '這裏',
-'连占' => '連佔',
-'連占' => '連佔',
-'連著' => '連着',
-'链接' => '連結',
-'連著作' => '連著作',
-'連著名' => '連著名',
-'連著書' => '連著書',
-'連著稱' => '連著稱',
-'連著者' => '連著者',
-'連著述' => '連著述',
-'連著錄' => '連著錄',
-'进占' => '進佔',
-'進占' => '進佔',
-'演化論' => '進化論',
-'逼著' => '逼着',
-'逼著作' => '逼著作',
-'逼著名' => '逼著名',
-'逼著書' => '逼著書',
-'逼著稱' => '逼著稱',
-'逼著者' => '逼著者',
-'逼著述' => '逼著述',
-'逼著錄' => '逼著錄',
-'遇著' => '遇着',
-'遇著作' => '遇著作',
-'遇著名' => '遇著名',
-'遇著書' => '遇著書',
-'遇著称' => '遇著稱',
-'遇著稱' => '遇著稱',
-'遇著者' => '遇著者',
-'遇著述' => '遇著述',
-'遇著錄' => '遇著錄',
-'游戏里' => '遊戲裏',
-'遍布' => '遍佈',
-'遍佈著' => '遍佈着',
-'遍布著' => '遍佈着',
-'過著' => '過着',
-'达·芬奇' => '達·文西',
-'达芬奇' => '達文西',
-'達著' => '達着',
-'達著作' => '達著作',
-'達著名' => '達著名',
-'達著書' => '達著書',
-'達著稱' => '達著稱',
-'達著者' => '達著者',
-'達著述' => '達著述',
-'達著錄' => '達著錄',
-'还占' => '還佔',
-'還占' => '還佔',
-'邋里邋遢' => '邋裏邋遢',
-'那里' => '那裏',
-'都市里' => '都市裏',
-'配合著' => '配合着',
-'配合著名' => '配合著名',
-'配图里' => '配圖裏',
-'配著' => '配着',
-'配著作' => '配著作',
-'配著名' => '配著名',
-'配著書' => '配著書',
-'配著稱' => '配著稱',
-'配著者' => '配著者',
-'配著述' => '配著述',
-'配著錄' => '配著錄',
-'醯' => '酰',
-'醜著' => '醜着',
-'醜著作' => '醜著作',
-'醜著名' => '醜著名',
-'醜著書' => '醜著書',
-'醜著稱' => '醜著稱',
-'醜著者' => '醜著者',
-'醜著述' => '醜著述',
-'醜著錄' => '醜著錄',
-'醯壶' => '醯壺',
-'醯壺' => '醯壺',
-'醯醋' => '醯醋',
-'醯醢' => '醯醢',
-'醯酱' => '醯醬',
-'醯醬' => '醯醬',
-'醯雞' => '醯雞',
-'醯鸡' => '醯雞',
-'釀著' => '釀着',
-'釀著作' => '釀著作',
-'釀著名' => '釀著名',
-'釀著書' => '釀著書',
-'釀著稱' => '釀著稱',
-'釀著者' => '釀著者',
-'釀著述' => '釀著述',
-'釀著錄' => '釀著錄',
-'金装玉里' => '金裝玉裏',
-'鉤' => '鈎',
-'鋪著' => '鋪着',
-'鋪著作' => '鋪著作',
-'鋪著名' => '鋪著名',
-'鋪著書' => '鋪著書',
-'鋪著稱' => '鋪著稱',
-'鋪著者' => '鋪著者',
-'鋪著述' => '鋪著述',
-'鋪著錄' => '鋪著錄',
-'镜图里' => '鏡圖裏',
-'钟在寺里' => '鐘在寺裏',
-'狄托' => '鐵托',
-'泰坦尼克号' => '鐵達尼號',
-'门里' => '門裏',
-'閉著' => '閉着',
-'閉著作' => '閉著作',
-'閉著名' => '閉著名',
-'閉著書' => '閉著書',
-'閉著稱' => '閉著稱',
-'閉著者' => '閉著者',
-'閉著述' => '閉著述',
-'閉著錄' => '閉著錄',
-'克卜勒' => '開普勒',
-'開著' => '開着',
-'開著作' => '開著作',
-'開著名' => '開著名',
-'開著書' => '開著書',
-'開著稱' => '開著稱',
-'開著者' => '開著者',
-'開著述' => '開著述',
-'開著錄' => '開著錄',
-'开诚布公' => '開誠佈公',
-'開誠布公' => '開誠佈公',
-'閑著' => '閑着',
-'閑著作' => '閑著作',
-'閑著名' => '閑著名',
-'閑著書' => '閑著書',
-'閑著稱' => '閑著稱',
-'閑著者' => '閑著者',
-'閑著述' => '閑著述',
-'閑著錄' => '閑著錄',
-'閒著' => '閒着',
-'间里' => '間裏',
-'關係著' => '關係着',
-'關著' => '關着',
-'關著作' => '關著作',
-'關著名' => '關著名',
-'關著書' => '關著書',
-'關著稱' => '關著稱',
-'關著者' => '關著者',
-'關著述' => '關著述',
-'關著錄' => '關著錄',
-'聞不著' => '闻不着',
-'聞得著' => '闻得着',
-'聞著' => '闻着',
-'亞塞拜然' => '阿塞拜疆',
-'阿布達比' => '阿布扎比',
-'阿拉伯聯合大公國' => '阿拉伯聯合酋長國',
-'亞斯文' => '阿斯旺',
-'阿联酋' => '阿聯酋',
-'艾里爾·夏隆' => '阿里埃勒·沙龍',
-'附著' => '附着',
-'附著作' => '附著作',
-'附著名' => '附著名',
-'附著書' => '附著書',
-'附著稱' => '附著稱',
-'附著者' => '附著者',
-'附著述' => '附著述',
-'附著錄' => '附著錄',
-'陋著' => '陋着',
-'陋著作' => '陋著作',
-'陋著名' => '陋著名',
-'陋著書' => '陋著書',
-'陋著稱' => '陋著稱',
-'陋著者' => '陋著者',
-'陋著述' => '陋著述',
-'陋著錄' => '陋著錄',
-'院里' => '院裏',
-'陪著' => '陪着',
-'陪著作' => '陪著作',
-'陪著名' => '陪著名',
-'陪著書' => '陪著書',
-'陪著稱' => '陪著稱',
-'陪著者' => '陪著者',
-'陪著述' => '陪著述',
-'陪著錄' => '陪著錄',
-'阴沟里翻船' => '陰溝裏翻船',
-'隔著' => '隔着',
-'隔著作' => '隔著作',
-'隔著名' => '隔著名',
-'隔著書' => '隔著書',
-'隔著稱' => '隔著稱',
-'隔著者' => '隔著者',
-'隔著述' => '隔著述',
-'隔著錄' => '隔著錄',
-'隨著' => '隨着',
-'隨著作' => '隨著作',
-'隨著名' => '隨著名',
-'隨著書' => '隨著書',
-'隨著稱' => '隨著稱',
-'隨著者' => '隨著者',
-'隨著述' => '隨著述',
-'隨著錄' => '隨著錄',
-'隐占' => '隱佔',
-'隱占' => '隱佔',
-'雅爾達' => '雅爾塔',
-'雅著' => '雅着',
-'雅穆索戈' => '雅穆蘇克雷',
-'雅著作' => '雅著作',
-'雅著名' => '雅著名',
-'雅著書' => '雅著書',
-'雅著称' => '雅著稱',
-'雅著稱' => '雅著稱',
-'雅著者' => '雅著者',
-'雅著述' => '雅著述',
-'雅著錄' => '雅著錄',
-'集数里' => '集數裏',
-'集里' => '集裏',
-'雜著' => '雜着',
-'雜著作' => '雜著作',
-'雜著名' => '雜著名',
-'雜著書' => '雜著書',
-'雜著稱' => '雜著稱',
-'雜著者' => '雜著者',
-'雜著述' => '雜著述',
-'雜著錄' => '雜著錄',
-'鸡蛋里挑骨头' => '雞蛋裏挑骨頭',
-'冰淇淋' => '雪糕',
-'冰激凌' => '雪糕',
-'雪里' => '雪裏',
-'云里雾里' => '雲裏霧裏',
-'莱特湾' => '雷伊泰灣',
-'萊特灣' => '雷伊泰灣',
-'电影里' => '電影裏',
-'晶体管' => '電晶體',
-'晶體管' => '電晶體',
-'电梯里' => '電梯裏',
-'电脑程序' => '電腦程式',
-'计算机程序' => '電腦程式',
-'电视里' => '電視裏',
-'霄裡' => '霄裡',
-'荷姆茲' => '霍爾木茲',
-'雾里' => '霧裏',
-'霸占' => '霸佔',
-'非占不可' => '非佔不可',
-'靠著' => '靠着',
-'靠著作' => '靠著作',
-'靠著名' => '靠著名',
-'靠著称' => '靠著稱',
-'靠著稱' => '靠著稱',
-'靠著者' => '靠著者',
-'靠著述' => '靠著述',
-'靠著录' => '靠著錄',
-'靠著錄' => '靠著錄',
-'面包著' => '面包着',
-'鞋里' => '鞋裏',
-'鞭辟入里' => '鞭辟入裏',
-'朝鲜战争' => '韓戰',
-'響著' => '響着',
-'響著作' => '響著作',
-'響著名' => '響著名',
-'響著書' => '響著書',
-'響著稱' => '響著稱',
-'響著者' => '響著者',
-'響著述' => '響著述',
-'響著錄' => '響著錄',
-'頂著' => '頂着',
-'頂著作' => '頂著作',
-'頂著名' => '頂著名',
-'頂著書' => '頂著書',
-'頂著稱' => '頂著稱',
-'頂著者' => '頂著者',
-'頂著述' => '頂著述',
-'頂著錄' => '頂著錄',
-'順著' => '順着',
-'順著作' => '順著作',
-'順著名' => '順著名',
-'順著書' => '順著書',
-'順著稱' => '順著稱',
-'順著者' => '順著者',
-'順著述' => '順著述',
-'順著錄' => '順著錄',
-'頒布' => '頒佈',
-'颁布' => '頒佈',
-'領著' => '領着',
-'領著作' => '領著作',
-'領著名' => '領著名',
-'領著書' => '領著書',
-'領著稱' => '領著稱',
-'領著者' => '領著者',
-'領著述' => '領著述',
-'領著錄' => '領著錄',
-'头里' => '頭裏',
-'风里' => '風裏',
-'颳著' => '颳着',
-'飃著' => '飃着',
-'飄著' => '飄着',
-'飄著作' => '飄著作',
-'飄著名' => '飄著名',
-'飄著書' => '飄著書',
-'飄著稱' => '飄著稱',
-'飄著者' => '飄著者',
-'飄著述' => '飄著述',
-'飄著錄' => '飄著錄',
-'餐台' => '餐枱',
-'馆里' => '館裏',
-'糊口' => '餬口',
-'馬里蘭' => '馬利蘭',
-'马里兰' => '馬利蘭',
-'马拉特·萨芬' => '馬拉特·沙芬',
-'馬斯垂克' => '馬斯特里赫特',
-'馬爾地夫' => '馬爾代夫',
-'馬利共和國' => '馬里共和國',
-'駕著' => '駕着',
-'駕著作' => '駕著作',
-'駕著名' => '駕著名',
-'駕著書' => '駕著書',
-'駕著稱' => '駕著稱',
-'駕著者' => '駕著者',
-'駕著述' => '駕著述',
-'駕著錄' => '駕著錄',
-'騎著' => '騎着',
-'騎著作' => '騎著作',
-'騎著名' => '騎著名',
-'騎著書' => '騎著書',
-'騎著稱' => '騎著稱',
-'騎著者' => '騎著者',
-'騎著述' => '騎著述',
-'騎著錄' => '騎著錄',
-'騙著' => '騙着',
-'騙著作' => '騙著作',
-'騙著名' => '騙著名',
-'騙著書' => '騙著書',
-'騙著稱' => '騙著稱',
-'騙著者' => '騙著者',
-'騙著述' => '騙著述',
-'騙著錄' => '騙著錄',
-'驶著' => '驶着',
-'体里' => '體裏',
-'高畫質' => '高清',
-'高著' => '高着',
-'高著作' => '高著作',
-'高著名' => '高著名',
-'高著書' => '高著書',
-'高著称' => '高著稱',
-'高著稱' => '高著稱',
-'高著者' => '高著者',
-'高著述' => '高著述',
-'高著錄' => '高著錄',
-'斗着' => '鬥着',
-'鬥著' => '鬥着',
-'鬥著作' => '鬥著作',
-'鬥著名' => '鬥著名',
-'鬥著書' => '鬥著書',
-'鬥著稱' => '鬥著稱',
-'鬥著者' => '鬥著者',
-'鬥著述' => '鬥著述',
-'鬥著錄' => '鬥著錄',
-'鬧著' => '鬧着',
-'牛軋' => '鳥結',
-'牛轧' => '鳥結',
-'鳩占' => '鳩佔',
-'鸠占' => '鳩佔',
-'麗著' => '麗着',
-'麗著作' => '麗著作',
-'麗著名' => '麗著名',
-'麗著書' => '麗著書',
-'麗著稱' => '麗著稱',
-'麗著者' => '麗著者',
-'麗著述' => '麗著述',
-'麗著錄' => '麗著錄',
-'麼著' => '麼着',
-'芮氏0' => '黎克特制0',
-'里氏0' => '黎克特制0',
-'芮氏1' => '黎克特制1',
-'里氏1' => '黎克特制1',
-'芮氏2' => '黎克特制2',
-'里氏2' => '黎克特制2',
-'芮氏3' => '黎克特制3',
-'里氏3' => '黎克特制3',
-'芮氏4' => '黎克特制4',
-'里氏4' => '黎克特制4',
-'芮氏5' => '黎克特制5',
-'里氏5' => '黎克特制5',
-'芮氏6' => '黎克特制6',
-'里氏6' => '黎克特制6',
-'芮氏7' => '黎克特制7',
-'里氏7' => '黎克特制7',
-'芮氏8' => '黎克特制8',
-'里氏8' => '黎克特制8',
-'芮氏9' => '黎克特制9',
-'里氏9' => '黎克特制9',
-'芮氏地震規模' => '黎克特制地震震級',
-'里氏地震规模' => '黎克特制地震震級',
-'芮氏規模' => '黎克特制震級',
-'里氏规模' => '黎克特制震級',
-'里氏震级' => '黎克特制震級',
-'黏著' => '黏着',
-'黏著作' => '黏著作',
-'黏著名' => '黏著名',
-'黏著書' => '黏著書',
-'黏著稱' => '黏著稱',
-'黏著者' => '黏著者',
-'黏著述' => '黏著述',
-'黏著錄' => '黏著錄',
-'蒙特內哥羅' => '黑山',
-'點著' => '點着',
-'點著作' => '點著作',
-'點著名' => '點著名',
-'點著書' => '點著書',
-'點著稱' => '點著稱',
-'點著者' => '點著者',
-'點著述' => '點著述',
-'點著錄' => '點著錄',
-'点里' => '點裏',
-'点里程' => '點里程',
-'鼓里' => '鼓裏',
-);
-
-$zh2CN = array(
-'16進位制' => '16进位制',
-'16進位' => '16进制',
-'IP位址' => 'IP地址',
-'一份子' => '一分子',
-'全球資訊網' => '万维网',
-'三十六著' => '三十六着',
-'三極體' => '三极管',
-'下著' => '下着',
-'下著作' => '下著作',
-'下著名' => '下著名',
-'下著录' => '下著录',
-'下著錄' => '下著录',
-'下著有' => '下著有',
-'下著称' => '下著称',
-'下著稱' => '下著称',
-'下著者' => '下著者',
-'下著述' => '下著述',
-'不著' => '不着',
-'不著書' => '不著书',
-'不著名' => '不著名',
-'不著錄' => '不著录',
-'不著稱' => '不著称',
-'不著述' => '不著述',
-'與著' => '与着',
-'與著書' => '与著书',
-'與著作' => '与著作',
-'與著名' => '与著名',
-'與著錄' => '与著录',
-'與著稱' => '与著称',
-'與著者' => '与著者',
-'與著述' => '与著述',
-'醜著' => '丑着',
-'醜著書' => '丑著书',
-'醜著作' => '丑著作',
-'醜著名' => '丑著名',
-'醜著錄' => '丑著录',
-'醜著稱' => '丑著称',
-'醜著者' => '丑著者',
-'醜著述' => '丑著述',
-'邱吉爾' => '丘吉尔',
-'C型肝炎' => '丙型肝炎',
-'C肝' => '丙肝',
-'東協會' => '东协会',
-'東協助' => '东协助',
-'東協議' => '东协议',
-'東南亞國家協會' => '东南亚国家联盟',
-'亚细安' => '东盟',
-'東協' => '东盟',
-'仲介' => '中介',
-'臨著' => '临着',
-'臨著書' => '临著书',
-'臨著作' => '临著作',
-'臨著名' => '临著名',
-'臨著錄' => '临著录',
-'臨著稱' => '临著称',
-'臨著者' => '临著者',
-'臨著述' => '临著述',
-'為著' => '为着',
-'為著《' => '为著《',
-'為著作' => '为著作',
-'為著名' => '为著名',
-'為著錄' => '为著录',
-'為著稱' => '为著称',
-'為著者' => '为著者',
-'為著述' => '为著述',
-'主機板' => '主板',
-'麗著' => '丽着',
-'麗著書' => '丽著书',
-'麗著作' => '丽著作',
-'麗著名' => '丽著名',
-'麗著錄' => '丽著录',
-'麗著稱' => '丽著称',
-'麗著者' => '丽著者',
-'麗著述' => '丽著述',
-'麼著' => '么着',
-'樂著' => '乐着',
-'樂著書' => '乐著书',
-'樂著作' => '乐著作',
-'樂著名' => '乐著名',
-'樂著錄' => '乐著录',
-'樂著稱' => '乐著称',
-'樂著者' => '乐著者',
-'樂著述' => '乐著述',
-'賈伯斯' => '乔布斯',
-'喬治·歐威爾' => '乔治·奥威尔',
-'乘著' => '乘着',
-'乘著書' => '乘著书',
-'乘著作' => '乘著作',
-'乘著名' => '乘著名',
-'乘著錄' => '乘著录',
-'乘著称' => '乘著称',
-'乘著稱' => '乘著称',
-'乘著者' => '乘著者',
-'乘著述' => '乘著述',
-'B型肝炎' => '乙型肝炎',
-'B肝' => '乙肝',
-'吉力馬札羅' => '乞力马扎罗',
-'葉門' => '也门',
-'買帳' => '买账',
-'了結他' => '了结他',
-'爭著' => '争着',
-'爭著書' => '争著书',
-'爭著作' => '争著作',
-'爭著名' => '争著名',
-'爭著錄' => '争著录',
-'爭著稱' => '争著称',
-'爭著者' => '争著者',
-'爭著述' => '争著述',
-'二極體' => '二极管',
-'二進位制' => '二进位制',
-'二進位' => '二进制',
-'網際網絡' => '互联网',
-'網際網路' => '互联网',
-'亞歷山卓' => '亚历山大',
-'雅穆索戈' => '亚穆苏克罗',
-'交帳' => '交账',
-'亮著' => '亮着',
-'亮著書' => '亮著书',
-'亮著作' => '亮著作',
-'亮著名' => '亮著名',
-'亮著錄' => '亮著录',
-'亮著称' => '亮著称',
-'亮著稱' => '亮著称',
-'亮著者' => '亮著者',
-'亮著述' => '亮著述',
-'人工智慧' => '人工智能',
-'行人路' => '人行道',
-'甚麼' => '什么',
-'甚麽' => '什么',
-'仗著' => '仗着',
-'仗著書' => '仗著书',
-'仗著作' => '仗著作',
-'仗著名' => '仗著名',
-'仗著錄' => '仗著录',
-'仗著稱' => '仗著称',
-'仗著者' => '仗著者',
-'仗著述' => '仗著述',
-'付帳' => '付账',
-'代表著' => '代表着',
-'代表著書' => '代表著书',
-'代表著作' => '代表著作',
-'代表著名' => '代表著名',
-'代表著錄' => '代表著录',
-'代表著稱' => '代表著称',
-'代表著者' => '代表著者',
-'代表著述' => '代表著述',
-'乙太網' => '以太网',
-'伊莉莎白' => '伊丽莎白',
-'伊利諾' => '伊利诺伊',
-'伊利諾伊' => '伊利诺伊',
-'伊斯蘭瑪巴德' => '伊斯兰堡',
-'伊斯坦堡' => '伊斯坦布尔',
-'伏著' => '伏着',
-'優先順序' => '优先级',
-'傳著' => '传着',
-'傳著書' => '传著书',
-'傳著作' => '传著作',
-'傳著名' => '传著名',
-'傳著錄' => '传著录',
-'傳著稱' => '传著称',
-'傳著者' => '传著者',
-'傳著述' => '传著述',
-'貝里斯' => '伯利兹',
-'伯明罕' => '伯明翰',
-'伴著' => '伴着',
-'伴著書' => '伴著书',
-'伴著作' => '伴著作',
-'伴著名' => '伴著名',
-'伴著錄' => '伴著录',
-'伴著稱' => '伴著称',
-'伴著者' => '伴著者',
-'伴著述' => '伴著述',
-'點陣圖' => '位图',
-'低著' => '低着',
-'低著書' => '低著书',
-'低著作' => '低著作',
-'低著名' => '低著名',
-'低著錄' => '低著录',
-'低著称' => '低著称',
-'低著稱' => '低著称',
-'低著者' => '低著者',
-'低著述' => '低著述',
-'住著' => '住着',
-'住著書' => '住著书',
-'住著作' => '住著作',
-'住著名' => '住著名',
-'住著錄' => '住著录',
-'住著称' => '住著称',
-'住著稱' => '住著称',
-'住著者' => '住著者',
-'住著述' => '住著述',
-'餘' => '余',
-'維德角' => '佛得角',
-'侏儸紀' => '侏罗纪',
-'側著' => '侧着',
-'側著書' => '侧著书',
-'側著作' => '侧著作',
-'側著名' => '侧著名',
-'側著錄' => '侧著录',
-'側著稱' => '侧著称',
-'側著者' => '侧著者',
-'側著述' => '侧著述',
-'可攜式' => '便携式',
-'攜帶型' => '便携式',
-'保護著' => '保护着',
-'保障著' => '保障着',
-'保障著書' => '保障著书',
-'保障著作' => '保障著作',
-'保障著名' => '保障著名',
-'保障著錄' => '保障著录',
-'保障著称' => '保障著称',
-'保障著稱' => '保障著称',
-'保障著者' => '保障著者',
-'保障著述' => '保障著述',
-'資訊時代' => '信息时代',
-'資訊理論' => '信息论',
-'信著' => '信着',
-'信著書' => '信著书',
-'信著作' => '信著作',
-'信著名' => '信著名',
-'信著錄' => '信著录',
-'信著称' => '信著称',
-'信著稱' => '信著称',
-'信著者' => '信著者',
-'信著述' => '信著述',
-'伏地挺身' => '俯卧撑',
-'掌上壓' => '俯卧撑',
-'倒帳' => '倒账',
-'候著' => '候着',
-'候著書' => '候著书',
-'候著作' => '候著作',
-'候著名' => '候著名',
-'候著錄' => '候著录',
-'候著稱' => '候著称',
-'候著者' => '候著者',
-'候著述' => '候著述',
-'借著' => '借着',
-'藉著' => '借着',
-'借著書' => '借著书',
-'借著作' => '借著作',
-'借著名' => '借著名',
-'借著錄' => '借著录',
-'借著稱' => '借著称',
-'借著者' => '借著者',
-'借著述' => '借著述',
-'假帳' => '假账',
-'做著' => '做着',
-'做著書' => '做著书',
-'做著作' => '做著作',
-'做著名' => '做著名',
-'做著錄' => '做著录',
-'做著稱' => '做著称',
-'做著者' => '做著者',
-'做著述' => '做著述',
-'偷著' => '偷着',
-'偷著書' => '偷著书',
-'偷著作' => '偷著作',
-'偷著名' => '偷著名',
-'偷著錄' => '偷著录',
-'偷著稱' => '偷著称',
-'偷著者' => '偷著者',
-'偷著述' => '偷著述',
-'傅利葉' => '傅里叶',
-'母音' => '元音',
-'光著' => '光着',
-'光著書' => '光著书',
-'光著作' => '光著作',
-'光著名' => '光著名',
-'光著錄' => '光著录',
-'光著称' => '光著称',
-'光著稱' => '光著称',
-'光著者' => '光著者',
-'光著述' => '光著述',
-'光碟機' => '光驱',
-'柯林頓' => '克林顿',
-'克羅埃西亞' => '克罗地亚',
-'轉殖' => '克隆',
-'複製人' => '克隆人',
-'入帳' => '入账',
-'八進位制' => '八进位制',
-'八進位' => '八进制',
-'西元1' => '公元1',
-'西元2' => '公元2',
-'西元3' => '公元3',
-'西元4' => '公元4',
-'西元5' => '公元5',
-'西元6' => '公元6',
-'西元7' => '公元7',
-'西元8' => '公元8',
-'西元9' => '公元9',
-'西元前' => '公元前',
-'公帳' => '公账',
-'六進位制' => '六进位制',
-'六進位' => '六进制',
-'關著' => '关着',
-'關係著' => '关系着',
-'關著書' => '关著书',
-'關著作' => '关著作',
-'關著名' => '关著名',
-'關著錄' => '关著录',
-'關著稱' => '关著称',
-'關著者' => '关著者',
-'關著述' => '关著述',
-'關帳' => '关账',
-'記憶體' => '内存',
-'甘比亞' => '冈比亚',
-'冒著' => '冒着',
-'冒著書' => '冒著书',
-'冒著作' => '冒著作',
-'冒著名' => '冒著名',
-'冒著錄' => '冒著录',
-'冒著稱' => '冒著称',
-'冒著者' => '冒著者',
-'冒著述' => '冒著述',
-'寫著' => '写着',
-'寫著書' => '写著书',
-'寫著作' => '写著作',
-'寫著名' => '写著名',
-'寫著錄' => '写著录',
-'寫著稱' => '写著称',
-'寫著者' => '写著者',
-'寫著述' => '写著述',
-'沖著' => '冲着',
-'衝著' => '冲着',
-'沖著。' => '冲著。',
-'沖著《' => '冲著《',
-'沖著(' => '冲著(',
-'沖著,' => '冲著,',
-'沖帳' => '冲账',
-'涼著' => '凉着',
-'涼著書' => '凉著书',
-'涼著作' => '凉著作',
-'涼著名' => '凉著名',
-'涼著錄' => '凉著录',
-'涼著稱' => '凉著称',
-'涼著者' => '凉著者',
-'涼著述' => '凉著述',
-'湊合著' => '凑合着',
-'畿內亞' => '几内亚',
-'幾內亞比索' => '几内亚比绍',
-'凱薩琳' => '凯瑟琳',
-'嘉芙蓮' => '凯瑟琳',
-'份內' => '分内',
-'份外' => '分外',
-'分佈著' => '分布着',
-'分布著' => '分布着',
-'解像度' => '分辨率',
-'解析度' => '分辨率',
-'份量' => '分量',
-'車諾比' => '切尔诺贝利',
-'劃著' => '划着',
-'李奧納多' => '列奥那多',
-'列支敦斯登' => '列支敦士登',
-'賴比瑞亞' => '利比里亚',
-'別著' => '别着',
-'刮著' => '刮着',
-'颳著' => '刮着',
-'到帳' => '到账',
-'制著' => '制着',
-'制著書' => '制著书',
-'制著作' => '制著作',
-'制著名' => '制著名',
-'制著錄' => '制著录',
-'制著稱' => '制著称',
-'制著者' => '制著者',
-'制著述' => '制著述',
-'煞車' => '刹车',
-'刻著' => '刻着',
-'刻著書' => '刻著书',
-'刻著作' => '刻著作',
-'刻著名' => '刻著名',
-'刻著錄' => '刻著录',
-'刻著称' => '刻著称',
-'刻著稱' => '刻著称',
-'刻著者' => '刻著者',
-'刻著述' => '刻著述',
-'前波莫瑞' => '前波美拉尼亚',
-'辦著' => '办着',
-'辦著書' => '办著书',
-'辦著作' => '办著作',
-'辦著名' => '办著名',
-'辦著錄' => '办著录',
-'辦著稱' => '办著称',
-'辦著者' => '办著者',
-'辦著述' => '办著述',
-'加薩走廊' => '加沙地带',
-'迦納' => '加纳',
-'加彭' => '加蓬',
-'動著' => '动着',
-'動著書' => '动著书',
-'動著作' => '动著作',
-'動著名' => '动著名',
-'動著錄' => '动著录',
-'動著稱' => '动著称',
-'動著者' => '动著者',
-'動著述' => '动著述',
-'努力著' => '努力着',
-'努力著書' => '努力著书',
-'努力著作' => '努力著作',
-'努力著名' => '努力著名',
-'努力著錄' => '努力著录',
-'努力著称' => '努力著称',
-'努力著稱' => '努力著称',
-'努力著者' => '努力著者',
-'努力著述' => '努力著述',
-'蘿拉' => '劳拉',
-'布蘭登堡' => '勃兰登堡',
-'白朗寧' => '勃朗宁',
-'包著' => '包着',
-'北韓' => '北朝鲜',
-'十進位制' => '十进位制',
-'十進位' => '十进制',
-'公升' => '升',
-'單眼相機' => '单反相机',
-'單鏡反光機' => '单反相机',
-'波札那' => '博茨瓦纳',
-'占著' => '占着',
-'占著作' => '占著作',
-'占著名' => '占著名',
-'占著者' => '占著者',
-'喀拉蚩' => '卡拉奇',
-'卡斯楚' => '卡斯特罗',
-'卡佩雅蒂' => '卡普里亚蒂',
-'盧安達' => '卢旺达',
-'羅浮宮' => '卢浮宫',
-'羅亞爾' => '卢瓦尔',
-'印著' => '印着',
-'印著書' => '印著书',
-'印著作' => '印著作',
-'印著名' => '印著名',
-'印著錄' => '印著录',
-'印著稱' => '印著称',
-'印著者' => '印著者',
-'印著述' => '印著述',
-'瓜地馬拉' => '危地马拉',
-'厄瓜多' => '厄瓜多尔',
-'厄瓜多尔' => '厄瓜多尔',
-'厄瓜多爾' => '厄瓜多尔',
-'厄利垂亚' => '厄立特里亚',
-'厄利垂亞' => '厄立特里亚',
-'厄立特里亞' => '厄立特里亚',
-'壓著' => '压着',
-'壓著書' => '压著书',
-'壓著作' => '压著作',
-'壓著名' => '压著名',
-'壓著錄' => '压著录',
-'壓著稱' => '压著称',
-'壓著者' => '压著者',
-'壓著述' => '压著述',
-'發著' => '发着',
-'發著《' => '发著《',
-'發著作' => '发著作',
-'發著名' => '发著名',
-'發著稱' => '发著称',
-'發著者' => '发著者',
-'已開發國家' => '发达国家',
-'受著' => '受着',
-'受著書' => '受著书',
-'受著作' => '受著作',
-'受著名' => '受著名',
-'受著錄' => '受著录',
-'受著稱' => '受著称',
-'受著者' => '受著者',
-'受著述' => '受著述',
-'變著' => '变着',
-'變著書' => '变著书',
-'變著作' => '变著作',
-'變著名' => '变著名',
-'變著錄' => '变著录',
-'變著稱' => '变著称',
-'變著者' => '变著者',
-'變著述' => '变著述',
-'隻字片語' => '只字片语',
-'隻言片語' => '只言片语',
-'唯讀' => '只读',
-'叫著' => '叫着',
-'叫著書' => '叫著书',
-'叫著作' => '叫著作',
-'叫著名' => '叫著名',
-'叫著錄' => '叫著录',
-'叫著稱' => '叫著称',
-'叫著者' => '叫著者',
-'叫著述' => '叫著述',
-'桌上型電腦' => '台式电脑',
-'撞球' => '台球',
-'台帳' => '台账',
-'叱吒' => '叱咤',
-'吃著' => '吃着',
-'結他' => '吉他',
-'健力士世界紀錄' => '吉尼斯世界纪录',
-'金氏世界紀錄' => '吉尼斯世界纪录',
-'吉布地' => '吉布提',
-'吊著' => '吊着',
-'名份' => '名分',
-'向著' => '向着',
-'向著書' => '向著书',
-'向著作' => '向著作',
-'向著名' => '向著名',
-'向著錄' => '向著录',
-'向著稱' => '向著称',
-'向著者' => '向著者',
-'向著述' => '向著述',
-'含著' => '含着',
-'含著書' => '含著书',
-'含著作' => '含著作',
-'含著名' => '含著名',
-'含著錄' => '含著录',
-'含著稱' => '含著称',
-'含著者' => '含著者',
-'含著述' => '含著述',
-'聽著' => '听着',
-'聽著書' => '听著书',
-'聽著作' => '听著作',
-'聽著名' => '听著名',
-'聽著錄' => '听著录',
-'聽著稱' => '听著称',
-'聽著者' => '听著者',
-'聽著述' => '听著述',
-'吹著' => '吹着',
-'吹著書' => '吹著书',
-'吹著作' => '吹著作',
-'吹著名' => '吹著名',
-'吹著錄' => '吹著录',
-'吹著稱' => '吹著称',
-'吹著者' => '吹著者',
-'吹著述' => '吹著述',
-'呆著' => '呆着',
-'呆帳' => '呆账',
-'味著' => '味着',
-'味著書' => '味著书',
-'味著作' => '味著作',
-'味著名' => '味著名',
-'味著錄' => '味著录',
-'味著称' => '味著称',
-'味著稱' => '味著称',
-'味著者' => '味著者',
-'味著述' => '味著述',
-'咖哩' => '咖喱',
-'諮' => '咨',
-'響著' => '响着',
-'響著書' => '响著书',
-'響著作' => '响著作',
-'響著名' => '响著名',
-'響著錄' => '响著录',
-'響著稱' => '响著称',
-'響著者' => '响著者',
-'響著述' => '响著述',
-'哥斯大黎加' => '哥斯达黎加',
-'哥德式' => '哥特式',
-'哭著' => '哭着',
-'哭著書' => '哭著书',
-'哭著作' => '哭著作',
-'哭著名' => '哭著名',
-'哭著錄' => '哭著录',
-'哭著稱' => '哭著称',
-'哭著者' => '哭著者',
-'哭著述' => '哭著述',
-'唱著' => '唱着',
-'唱著書' => '唱著书',
-'唱著作' => '唱著作',
-'唱著名' => '唱著名',
-'唱著錄' => '唱著录',
-'唱著稱' => '唱著称',
-'唱著者' => '唱著者',
-'唱著述' => '唱著述',
-'啸吒' => '啸咤',
-'喝著' => '喝着',
-'喝著書' => '喝著书',
-'喝著作' => '喝著作',
-'喝著名' => '喝著名',
-'喝著錄' => '喝著录',
-'喝著稱' => '喝著称',
-'喝著者' => '喝著者',
-'喝著述' => '喝著述',
-'嗅著' => '嗅着',
-'雜訊' => '噪声',
-'嚷著' => '嚷着',
-'嚷著書' => '嚷著书',
-'嚷著作' => '嚷著作',
-'嚷著名' => '嚷著名',
-'嚷著錄' => '嚷著录',
-'嚷著稱' => '嚷著称',
-'嚷著者' => '嚷著者',
-'嚷著述' => '嚷著述',
-'回著' => '回着',
-'回著名' => '回著名',
-'因著' => '因着',
-'因著〈' => '因著〈',
-'因著《' => '因著《',
-'因著書' => '因著书',
-'因著作' => '因著作',
-'因著名' => '因著名',
-'因著录' => '因著录',
-'因著錄' => '因著录',
-'因著稱' => '因著称',
-'因著者' => '因著者',
-'因著述' => '因著述',
-'困著' => '困着',
-'困著書' => '困著书',
-'困著作' => '困著作',
-'困著名' => '困著名',
-'困著錄' => '困著录',
-'困著稱' => '困著称',
-'困著者' => '困著者',
-'困著述' => '困著述',
-'圍著' => '围着',
-'圍著書' => '围著书',
-'圍著作' => '围著作',
-'圍著名' => '围著名',
-'圍著錄' => '围著录',
-'圍著稱' => '围著称',
-'圍著者' => '围著者',
-'圍著述' => '围著述',
-'韌體' => '固件',
-'固著' => '固着',
-'西洋棋' => '国际象棋',
-'土魯斯' => '图卢兹',
-'吐瓦魯' => '图瓦卢',
-'原子筆' => '圆珠笔',
-'聖露西亞' => '圣卢西亚',
-'聖克里斯多福及尼維斯' => '圣基茨和尼维斯',
-'聖吉斯納域斯' => '圣基茨和尼维斯',
-'聖文森及格瑞那丁' => '圣文森特和格林纳丁斯',
-'聖馬利諾' => '圣马力诺',
-'蓋亞那' => '圭亚那',
-'坐著' => '坐着',
-'坐著書' => '坐著书',
-'坐著作' => '坐著作',
-'坐著名' => '坐著名',
-'坐著錄' => '坐著录',
-'坐著稱' => '坐著称',
-'坐著者' => '坐著者',
-'坐著述' => '坐著述',
-'堅貞著' => '坚贞着',
-'坦尚尼亞' => '坦桑尼亚',
-'伊波拉' => '埃博拉',
-'衣索匹亞' => '埃塞俄比亚',
-'衣索比亞' => '埃塞俄比亚',
-'艾菲爾' => '埃菲尔',
-'葉里溫' => '埃里温',
-'功能變數名稱' => '域名',
-'吉里巴斯' => '基里巴斯',
-'堂姊' => '堂姐',
-'坎培拉' => '堪培拉',
-'塑膠袋' => '塑料袋',
-'塞爾維亞與蒙特內哥羅' => '塞尔维亚和黑山',
-'塞拉利昂' => '塞拉利昂',
-'塞普勒斯' => '塞浦路斯',
-'賽普勒斯' => '塞浦路斯',
-'塞維亞' => '塞维利亚',
-'西維爾' => '塞维利亚',
-'塞席爾' => '塞舌尔',
-'音效卡' => '声卡',
-'備著' => '备着',
-'備著書' => '备著书',
-'備著作' => '备著作',
-'備著名' => '备著名',
-'備著錄' => '备著录',
-'備著稱' => '备著称',
-'備著者' => '备著者',
-'備著述' => '备著述',
-'外部連結' => '外部链接',
-'托巴哥' => '多巴哥',
-'都卜勒' => '多普勒',
-'多明尼加' => '多米尼加',
-'大姊' => '大姐',
-'天份' => '天分',
-'夾著' => '夹着',
-'夾著書' => '夹著书',
-'夾著作' => '夹著作',
-'夾著名' => '夹著名',
-'夾著錄' => '夹著录',
-'夾著稱' => '夹著称',
-'夾著者' => '夹著者',
-'夾著述' => '夹著述',
-'賓士' => '奔驰',
-'歐巴馬' => '奥巴马',
-'柯德莉·夏萍' => '奥黛丽·赫本',
-'忌廉' => '奶油',
-'荷里活' => '好莱坞',
-'姊夫' => '姐夫',
-'姊姊' => '姐姐',
-'姊弟' => '姐弟',
-'威爾斯' => '威尔士',
-'威斯伐倫' => '威斯特法伦',
-'字型大小' => '字号',
-'字型檔' => '字库',
-'欄位' => '字段',
-'位元組' => '字节',
-'存在著' => '存在着',
-'存著' => '存着',
-'存著作' => '存著作',
-'存著名' => '存著名',
-'學姊' => '学姐',
-'學著' => '学着',
-'學著書' => '学著书',
-'學著作' => '学著作',
-'學著名' => '学著名',
-'學著錄' => '学著录',
-'學著稱' => '学著称',
-'學著者' => '学著者',
-'學著述' => '学著述',
-'太空飛行員' => '宇航员',
-'太空衣' => '宇航服',
-'守著' => '守着',
-'守著書' => '守著书',
-'守著作' => '守著作',
-'守著名' => '守著名',
-'守著錄' => '守著录',
-'守著称' => '守著称',
-'守著稱' => '守著称',
-'守著者' => '守著者',
-'守著述' => '守著述',
-'安哈特' => '安哈尔特',
-'安地卡及巴布達' => '安提瓜和巴布达',
-'巨集' => '宏',
-'定著' => '定着',
-'定著書' => '定著书',
-'定著作' => '定著作',
-'定著名' => '定著名',
-'定著錄' => '定著录',
-'定著称' => '定著称',
-'定著稱' => '定著称',
-'定著者' => '定著者',
-'定著述' => '定著述',
-'波里活' => '宝莱坞',
-'寬頻' => '宽带',
-'密执安' => '密歇根',
-'密西根' => '密歇根',
-'對著' => '对着',
-'對著書' => '对著书',
-'對著作' => '对著作',
-'對著名' => '对著名',
-'對著錄' => '对著录',
-'對著稱' => '对著称',
-'對著者' => '对著者',
-'對著述' => '对著述',
-'對帳' => '对账',
-'尋著' => '寻着',
-'尋著書' => '寻著书',
-'尋著作' => '寻著作',
-'尋著名' => '寻著名',
-'尋著錄' => '寻著录',
-'尋著稱' => '寻著称',
-'尋著者' => '寻著者',
-'尋著述' => '寻著述',
-'飛彈' => '导弹',
-'祖雲達斯' => '尤文图斯',
-'奈及利亞' => '尼日利亚',
-'尼日爾' => '尼日尔',
-'區域網' => '局域网',
-'區域網路' => '局域网络',
-'螢幕' => '屏幕',
-'展著' => '展着',
-'展著書' => '展著书',
-'展著作' => '展著作',
-'展著名' => '展著名',
-'展著錄' => '展著录',
-'展著稱' => '展著称',
-'展著者' => '展著者',
-'展著述' => '展著述',
-'瓦倫西亞' => '巴伦西亚',
-'華倫西亞' => '巴伦西亚',
-'巴塞隆拿' => '巴塞罗那',
-'巴塞隆納' => '巴塞罗那',
-'巴斯拉' => '巴士拉',
-'帕邁拉環礁' => '巴尔米拉环礁',
-'巴貝多' => '巴巴多斯',
-'巴布亞紐幾內亞' => '巴布亚新几内亚',
-'布殊' => '布什',
-'布吉納法索' => '布基纳法索',
-'布隆泉' => '布隆方丹',
-'蒲隆地' => '布隆迪',
-'希冀著' => '希冀着',
-'席哈克' => '希拉克',
-'希拉莉' => '希拉里',
-'希拉蕊' => '希拉里',
-'希特拉' => '希特勒',
-'帛琉' => '帕劳',
-'派屈克' => '帕特里克',
-'頻寬' => '带宽',
-'帶著' => '带着',
-'帶著書' => '带著书',
-'帶著作' => '带著作',
-'帶著名' => '带著名',
-'帶著錄' => '带著录',
-'帶著稱' => '带著称',
-'帶著者' => '带著者',
-'帶著述' => '带著述',
-'幫著' => '帮着',
-'幫著書' => '帮著书',
-'幫著作' => '帮著作',
-'幫著名' => '帮著名',
-'幫著錄' => '帮著录',
-'幫著稱' => '帮著称',
-'幫著者' => '帮著者',
-'幫著述' => '帮著述',
-'乾姊' => '干姐',
-'幹著' => '干着',
-'幹著名' => '幹著名',
-'幹著稱' => '幹著称',
-'庇護著' => '庇护着',
-'庫德人' => '库尔德人',
-'庫德族' => '库尔德族',
-'應用程式' => '应用程序',
-'應著' => '应着',
-'應著書' => '应著书',
-'應著作' => '应著作',
-'應著名' => '应著名',
-'應著錄' => '应著录',
-'應著稱' => '应著称',
-'應著者' => '应著者',
-'應著述' => '应著述',
-'建帳' => '建账',
-'克卜勒' => '开普勒',
-'開著' => '开着',
-'開著書' => '开著书',
-'開著作' => '开著作',
-'開著名' => '开著名',
-'開著錄' => '开著录',
-'開著稱' => '开著称',
-'開著者' => '开著者',
-'開著述' => '开著述',
-'開帳' => '开账',
-'非同步' => '异步',
-'若且唯若' => '当且仅当',
-'當著' => '当着',
-'當著書' => '当著书',
-'當著作' => '当著作',
-'當著名' => '当著名',
-'當著錄' => '当著录',
-'當著稱' => '当著称',
-'當著者' => '当著者',
-'當著述' => '当著述',
-'錄影帶' => '录像带',
-'形上學' => '形而上学',
-'澈底' => '彻底',
-'逕入' => '径入',
-'逕到' => '径到',
-'逕取' => '径取',
-'逕啟' => '径启',
-'逕寄' => '径寄',
-'逕庭' => '径庭',
-'逕往' => '径往',
-'逕自' => '径自',
-'逕行' => '径行',
-'逕迎' => '径迎',
-'待著' => '待着',
-'待著書' => '待著书',
-'待著作' => '待著作',
-'待著名' => '待著名',
-'待著錄' => '待著录',
-'待著稱' => '待著称',
-'待著者' => '待著者',
-'待著述' => '待著述',
-'得著' => '得着',
-'得著書' => '得著书',
-'得著作' => '得著作',
-'得著名' => '得著名',
-'得著錄' => '得著录',
-'得著稱' => '得著称',
-'得著者' => '得著者',
-'得著述' => '得著述',
-'御姊' => '御姐',
-'迴圈' => '循环',
-'循著' => '循着',
-'循著書' => '循著书',
-'循著作' => '循著作',
-'循著名' => '循著名',
-'循著錄' => '循著录',
-'循著稱' => '循著称',
-'循著者' => '循著者',
-'循著述' => '循著述',
-'德勒斯登' => '德累斯顿',
-'德希達' => '德里达',
-'心著' => '心着',
-'心著書' => '心著书',
-'心著作' => '心著作',
-'心著名' => '心著名',
-'心著錄' => '心著录',
-'心著称' => '心著称',
-'心著稱' => '心著称',
-'心著者' => '心著者',
-'心著述' => '心著述',
-'忍著' => '忍着',
-'忍著書' => '忍著书',
-'忍著作' => '忍著作',
-'忍著名' => '忍著名',
-'忍著錄' => '忍著录',
-'忍著稱' => '忍著称',
-'忍著者' => '忍著者',
-'忍著述' => '忍著述',
-'忙著' => '忙着',
-'忙著書' => '忙著书',
-'忙著作' => '忙著作',
-'忙著名' => '忙著名',
-'忙著錄' => '忙著录',
-'忙著稱' => '忙著称',
-'忙著者' => '忙著者',
-'忙著述' => '忙著述',
-'忠貞著' => '忠贞着',
-'懷著' => '怀着',
-'懷著書' => '怀著书',
-'懷著作' => '怀著作',
-'懷著名' => '怀著名',
-'懷著錄' => '怀著录',
-'懷著稱' => '怀著称',
-'懷著者' => '怀著者',
-'懷著述' => '怀著述',
-'急著' => '急着',
-'急著書' => '急著书',
-'急著作' => '急著作',
-'急著名' => '急著名',
-'急著錄' => '急著录',
-'急著稱' => '急著称',
-'急著者' => '急著者',
-'急著述' => '急著述',
-'匯流排' => '总线',
-'總帳' => '总账',
-'戀著' => '恋着',
-'戀著書' => '恋著书',
-'戀著作' => '恋著作',
-'戀著名' => '恋著名',
-'戀著錄' => '恋著录',
-'戀著稱' => '恋著称',
-'戀著者' => '恋著者',
-'戀著述' => '恋著述',
-'恰如其份' => '恰如其分',
-'悠著' => '悠着',
-'悠著書' => '悠著书',
-'悠著作' => '悠著作',
-'悠著名' => '悠著名',
-'悠著錄' => '悠著录',
-'悠著稱' => '悠著称',
-'悠著者' => '悠著者',
-'悠著述' => '悠著述',
-'慣著' => '惯着',
-'慣著書' => '惯著书',
-'慣著作' => '惯著作',
-'慣著名' => '惯著名',
-'慣著錄' => '惯著录',
-'慣著稱' => '惯著称',
-'慣著者' => '惯著者',
-'慣著述' => '惯著述',
-'想著' => '想着',
-'想著書' => '想著书',
-'想著作' => '想著作',
-'想著名' => '想著名',
-'想著錄' => '想著录',
-'想著称' => '想著称',
-'想著稱' => '想著称',
-'想著者' => '想著者',
-'想著述' => '想著述',
-'義大利' => '意大利',
-'戈巴契夫' => '戈尔巴乔夫',
-'成份' => '成分',
-'戰著' => '战着',
-'戰著書' => '战著书',
-'戰著作' => '战著作',
-'戰著名' => '战著名',
-'戰著錄' => '战著录',
-'戰著稱' => '战著称',
-'戰著者' => '战著者',
-'戰著述' => '战著述',
-'坎城' => '戛纳',
-'黛安娜' => '戴安娜',
-'戴著' => '戴着',
-'戴著書' => '戴著书',
-'戴著作' => '戴著作',
-'戴著名' => '戴著名',
-'戴著錄' => '戴著录',
-'戴著稱' => '戴著称',
-'戴著者' => '戴著者',
-'戴著述' => '戴著述',
-'索羅門群島' => '所罗门群岛',
-'紮著' => '扎着',
-'紮著書' => '扎著书',
-'紮著作' => '扎著作',
-'紮著名' => '扎著名',
-'紮著錄' => '扎著录',
-'紮著稱' => '扎著称',
-'紮著者' => '扎著者',
-'紮著述' => '扎著述',
-'列印' => '打印',
-'印表機' => '打印机',
-'打著' => '打着',
-'打著書' => '打著书',
-'打著作' => '打著作',
-'打著名' => '打著名',
-'打著錄' => '打著录',
-'打著稱' => '打著称',
-'打著者' => '打著者',
-'打著述' => '打著述',
-'扛著' => '扛着',
-'扛著書' => '扛著书',
-'扛著作' => '扛著作',
-'扛著名' => '扛著名',
-'扛著錄' => '扛著录',
-'扛著稱' => '扛著称',
-'扛著者' => '扛著者',
-'扛著述' => '扛著述',
-'掃瞄' => '扫描',
-'掃瞄器' => '扫描仪',
-'抓著' => '抓着',
-'抓著作' => '抓著作',
-'抓著名' => '抓著名',
-'抓著錄' => '抓著录',
-'抓著稱' => '抓著称',
-'抓著者' => '抓著者',
-'抓著述' => '抓著述',
-'投機份子' => '投机分子',
-'護著' => '护着',
-'護著書' => '护著书',
-'護著作' => '护著作',
-'護著名' => '护著名',
-'護著錄' => '护著录',
-'護著稱' => '护著称',
-'護著者' => '护著者',
-'護著述' => '护著述',
-'報帳' => '报账',
-'披著' => '披着',
-'披著書' => '披著书',
-'披著作' => '披著作',
-'披著名' => '披著名',
-'披著錄' => '披著录',
-'披著稱' => '披著称',
-'披著者' => '披著者',
-'披著述' => '披著述',
-'抬著' => '抬着',
-'擡著' => '抬着',
-'抬著作' => '抬著作',
-'抬著名' => '抬著名',
-'抬著錄' => '抬著录',
-'抬著稱' => '抬著称',
-'抬著者' => '抬著者',
-'抬著述' => '抬著述',
-'抱著' => '抱着',
-'抱著作' => '抱著作',
-'抱著名' => '抱著名',
-'抱著錄' => '抱著录',
-'抱著稱' => '抱著称',
-'抱著者' => '抱著者',
-'抱著述' => '抱著述',
-'擔著' => '担着',
-'拉著' => '拉着',
-'拉著書' => '拉著书',
-'拉著作' => '拉著作',
-'拉著名' => '拉著名',
-'拉著錄' => '拉著录',
-'拉著稱' => '拉著称',
-'拉著者' => '拉著者',
-'拉著述' => '拉著述',
-'拎著' => '拎着',
-'拎著作' => '拎著作',
-'拎著名' => '拎著名',
-'拎著錄' => '拎著录',
-'拎著稱' => '拎著称',
-'拎著者' => '拎著者',
-'拎著述' => '拎著述',
-'拖著' => '拖着',
-'拖著作' => '拖著作',
-'拖著名' => '拖著名',
-'拖著錄' => '拖著录',
-'拖著稱' => '拖著称',
-'拖著者' => '拖著者',
-'拖著述' => '拖著述',
-'拼著' => '拼着',
-'拼著作' => '拼著作',
-'拼著名' => '拼著名',
-'拼著錄' => '拼著录',
-'拼著稱' => '拼著称',
-'拼著者' => '拼著者',
-'拼著述' => '拼著述',
-'拿著' => '拿着',
-'拿著作' => '拿著作',
-'拿著名' => '拿著名',
-'拿著錄' => '拿著录',
-'拿著稱' => '拿著称',
-'拿著者' => '拿著者',
-'拿著述' => '拿著述',
-'持著' => '持着',
-'持著作' => '持著作',
-'持著名' => '持著名',
-'持著錄' => '持著录',
-'持著稱' => '持著称',
-'持著者' => '持著者',
-'持著述' => '持著述',
-'掛著' => '挂着',
-'挑著' => '挑着',
-'挑著作' => '挑著作',
-'挑著名' => '挑著名',
-'挑著錄' => '挑著录',
-'挑著稱' => '挑著称',
-'挑著者' => '挑著者',
-'挑著述' => '挑著述',
-'擋著' => '挡着',
-'擋著作' => '挡著作',
-'擋著名' => '挡著名',
-'擋著錄' => '挡著录',
-'擋著稱' => '挡著称',
-'擋著者' => '挡著者',
-'擋著述' => '挡著述',
-'掙著' => '挣着',
-'掙著書' => '挣著书',
-'掙著作' => '挣著作',
-'掙著名' => '挣著名',
-'掙著錄' => '挣著录',
-'掙著稱' => '挣著称',
-'掙著者' => '挣著者',
-'掙著述' => '挣著述',
-'揮著' => '挥着',
-'揮著作' => '挥著作',
-'揮著名' => '挥著名',
-'揮著錄' => '挥著录',
-'揮著稱' => '挥著称',
-'揮著者' => '挥著者',
-'揮著述' => '挥著述',
-'挨著' => '挨着',
-'挨著作' => '挨著作',
-'挨著名' => '挨著名',
-'挨著錄' => '挨著录',
-'挨著稱' => '挨著称',
-'挨著者' => '挨著者',
-'挨著述' => '挨著述',
-'捆著' => '捆着',
-'捆著作' => '捆著作',
-'捆著名' => '捆著名',
-'捆著錄' => '捆著录',
-'捆著稱' => '捆著称',
-'捆著者' => '捆著者',
-'捆著述' => '捆著述',
-'據著' => '据着',
-'據著書' => '据著书',
-'據著作' => '据著作',
-'據著名' => '据著名',
-'據著錄' => '据著录',
-'據著稱' => '据著称',
-'據著者' => '据著者',
-'據著述' => '据著述',
-'積架' => '捷豹',
-'掖著' => '掖着',
-'掖著作' => '掖著作',
-'掖著名' => '掖著名',
-'掖著錄' => '掖著录',
-'掖著稱' => '掖著称',
-'掖著者' => '掖著者',
-'掖著述' => '掖著述',
-'接著' => '接着',
-'接著作' => '接著作',
-'接著名' => '接著名',
-'接著錄' => '接著录',
-'接著稱' => '接著称',
-'接著者' => '接著者',
-'接著述' => '接著述',
-'控制項' => '控件',
-'揉著' => '揉着',
-'揉著書' => '揉著书',
-'揉著作' => '揉著作',
-'揉著名' => '揉著名',
-'揉著錄' => '揉著录',
-'揉著稱' => '揉著称',
-'揉著者' => '揉著者',
-'揉著述' => '揉著述',
-'提著' => '提着',
-'提著作' => '提著作',
-'提著名' => '提著名',
-'提著錄' => '提著录',
-'提著稱' => '提著称',
-'提著者' => '提著者',
-'提著述' => '提著述',
-'外掛程式' => '插件',
-'摟著' => '搂着',
-'摟著作' => '搂著作',
-'摟著名' => '搂著名',
-'摟著錄' => '搂著录',
-'摟著稱' => '搂著称',
-'摟著者' => '搂著者',
-'摟著述' => '搂著述',
-'搜尋引擎' => '搜索引擎',
-'擺著' => '摆着',
-'擺著作' => '摆著作',
-'擺著名' => '摆著名',
-'擺著錄' => '摆著录',
-'擺著稱' => '摆著称',
-'擺著者' => '摆著者',
-'擺著述' => '摆著述',
-'電單車' => '摩托车',
-'戴卓爾' => '撒切尔',
-'柴契爾' => '撒切尔',
-'撼著' => '撼着',
-'撼著書' => '撼著书',
-'撼著作' => '撼著作',
-'撼著名' => '撼著名',
-'撼著錄' => '撼著录',
-'撼著稱' => '撼著称',
-'撼著者' => '撼著者',
-'撼著述' => '撼著述',
-'作業系統' => '操作系统',
-'收帳' => '收账',
-'放著' => '放着',
-'放著作' => '放著作',
-'放著名' => '放著名',
-'放著称' => '放著称',
-'放著稱' => '放著称',
-'放帳' => '放账',
-'敞著' => '敞着',
-'敞著作' => '敞著作',
-'敞著名' => '敞著名',
-'敞著錄' => '敞著录',
-'敞著稱' => '敞著称',
-'敞著者' => '敞著者',
-'敞著述' => '敞著述',
-'散佈著' => '散布着',
-'散布著' => '散布着',
-'數位訊號' => '数字信号',
-'數碼訊號' => '数字信号',
-'數位化' => '数字化',
-'數位技術' => '数字技术',
-'數位電視' => '数字电视',
-'數碼電視' => '数字电视',
-'資料庫' => '数据库',
-'數著' => '数着',
-'數位照相機' => '数码照相机',
-'數位相機' => '数码相机',
-'數著作' => '数著作',
-'數著名' => '数著名',
-'數著錄' => '数著录',
-'數著稱' => '数著称',
-'數著者' => '数著者',
-'數著述' => '数著述',
-'汶萊' => '文莱',
-'鬥著' => '斗着',
-'鬥著書' => '斗著书',
-'鬥著作' => '斗著作',
-'鬥著名' => '斗著名',
-'鬥著錄' => '斗著录',
-'鬥著稱' => '斗著称',
-'鬥著者' => '斗著者',
-'鬥著述' => '斗著述',
-'斥著' => '斥着',
-'斥著書' => '斥著书',
-'斥著作' => '斥著作',
-'斥著名' => '斥著名',
-'斥著錄' => '斥著录',
-'斥著稱' => '斥著称',
-'斥著者' => '斥著者',
-'斥著述' => '斥著述',
-'史丹福大學' => '斯坦福大学',
-'史達林' => '斯大林',
-'史瓦濟蘭' => '斯威士兰',
-'斯洛維尼亞' => '斯洛文尼亚',
-'史特勞斯' => '斯特劳斯',
-'紐幾內亞' => '新几内亚',
-'紐澤西' => '新泽西',
-'紐西蘭' => '新西兰',
-'舊帳' => '旧账',
-'三藩市' => '旧金山',
-'昂山素姬' => '昂山素季',
-'翁山蘇姬' => '昂山素季',
-'昂著' => '昂着',
-'昂著書' => '昂著书',
-'昂著作' => '昂著作',
-'昂著名' => '昂著名',
-'昂著錄' => '昂著录',
-'昂著稱' => '昂著称',
-'昂著者' => '昂著者',
-'昂著述' => '昂著述',
-'明白帳' => '明白账',
-'映著' => '映着',
-'映著書' => '映著书',
-'映著作' => '映著作',
-'映著名' => '映著名',
-'映著錄' => '映著录',
-'映著稱' => '映著称',
-'映著者' => '映著者',
-'映著述' => '映著述',
-'顯示卡' => '显卡',
-'显著' => '显著',
-'顯著' => '显著',
-'晃著' => '晃着',
-'晃著作' => '晃著作',
-'晃著名' => '晃著名',
-'晃著錄' => '晃著录',
-'晃著稱' => '晃著称',
-'晃著者' => '晃著者',
-'晃著述' => '晃著述',
-'普利茲' => '普利策',
-'蒲美蓬' => '普密蓬',
-'蒲朗克' => '普朗克',
-'電晶體' => '晶体管',
-'智慧型' => '智能',
-'智慧卡' => '智能卡',
-'智慧手機' => '智能手机',
-'暗著' => '暗着',
-'暗著書' => '暗著书',
-'暗著作' => '暗著作',
-'暗著名' => '暗著名',
-'暗著錄' => '暗著录',
-'暗著稱' => '暗著称',
-'暗著者' => '暗著者',
-'暗著述' => '暗著述',
-'有著' => '有着',
-'有著書' => '有著书',
-'有著作' => '有著作',
-'有著名' => '有著名',
-'有著錄' => '有著录',
-'有著稱' => '有著称',
-'有著者' => '有著者',
-'有著述' => '有著述',
-'伺服器' => '服务器',
-'望著' => '望着',
-'望著作' => '望著作',
-'望著名' => '望著名',
-'望著錄' => '望著录',
-'望著稱' => '望著称',
-'望著者' => '望著者',
-'望著述' => '望著述',
-'朝著' => '朝着',
-'朝著作' => '朝著作',
-'朝著名' => '朝著名',
-'朝著錄' => '朝著录',
-'朝著稱' => '朝著称',
-'朝著者' => '朝著者',
-'朝著述' => '朝著述',
-'賓·拉登' => '本·拉登',
-'本份' => '本分',
-'賓拉登' => '本拉登',
-'本本份份' => '本本分分',
-'班傑明' => '本杰明',
-'本著' => '本着',
-'本著書' => '本著书',
-'本著作' => '本著作',
-'本著名' => '本著名',
-'本著錄' => '本著录',
-'本著稱' => '本著称',
-'本著者' => '本著者',
-'本著述' => '本著述',
-'本帳' => '本账',
-'機械人' => '机器人',
-'工具機' => '机床',
-'殺著' => '杀着',
-'殺著書' => '杀著书',
-'殺著作' => '杀著作',
-'殺著名' => '杀著名',
-'殺著錄' => '杀著录',
-'殺著稱' => '杀著称',
-'殺著者' => '杀著者',
-'殺著述' => '杀著述',
-'雜著' => '杂着',
-'雜著書' => '杂著书',
-'雜著作' => '杂著作',
-'雜著名' => '杂著名',
-'雜著錄' => '杂著录',
-'雜著稱' => '杂著称',
-'雜著者' => '杂著者',
-'雜著述' => '杂著述',
-'杜塞道夫' => '杜塞尔多夫',
-'來著' => '来着',
-'來著書' => '来著书',
-'來著作' => '来著作',
-'來著名' => '来著名',
-'來著錄' => '来著录',
-'來著稱' => '来著称',
-'來著者' => '来著者',
-'來著述' => '来著述',
-'板著臉' => '板着脸',
-'枕著' => '枕着',
-'枕著作' => '枕著作',
-'枕著名' => '枕著名',
-'枕著錄' => '枕著录',
-'枕著稱' => '枕著称',
-'枕著者' => '枕著者',
-'枕著述' => '枕著述',
-'槍枝' => '枪支',
-'柏林圍牆' => '柏林墙',
-'查帳' => '查账',
-'查維茲' => '查韦斯',
-'標志著' => '标志着',
-'標誌著' => '标志着',
-'格瑞那達' => '格林纳达',
-'格林美獎' => '格莱美奖',
-'葛萊美獎' => '格莱美奖',
-'森巴舞' => '桑巴舞',
-'梅赫西迪' => '梅赛德斯',
-'夢著' => '梦着',
-'夢著書' => '梦著书',
-'夢著作' => '梦著作',
-'夢著名' => '梦著名',
-'夢著錄' => '梦著录',
-'夢著稱' => '梦著称',
-'夢著者' => '梦著者',
-'夢著述' => '梦著述',
-'梳著' => '梳着',
-'梳著作' => '梳著作',
-'梳著名' => '梳著名',
-'梳著錄' => '梳著录',
-'梳著稱' => '梳著称',
-'梳著者' => '梳著者',
-'梳著述' => '梳著述',
-'梵谷' => '梵高',
-'機率' => '概率',
-'欠帳' => '欠账',
-'死帳' => '死账',
-'庇里牛斯' => '比利牛斯',
-'畢卡索' => '毕加索',
-'茅利塔尼亞' => '毛里塔尼亚',
-'模里西斯' => '毛里求斯',
-'毛里裘斯' => '毛里求斯',
-'公厘' => '毫米',
-'公釐' => '毫米',
-'氧份' => '氧分',
-'胺基酸' => '氨基酸',
-'水份' => '水分',
-'水氣' => '水汽',
-'求著' => '求着',
-'求著書' => '求著书',
-'求著作' => '求著作',
-'求著名' => '求著名',
-'求著錄' => '求著录',
-'求著稱' => '求著称',
-'求著者' => '求著者',
-'求著述' => '求著述',
-'漢諾瓦' => '汉诺威',
-'沈著' => '沉着',
-'沉著' => '沉着',
-'沉著書' => '沉著书',
-'沉著作' => '沉著作',
-'沉著名' => '沉著名',
-'沉著錄' => '沉著录',
-'沉著稱' => '沉著称',
-'沉著者' => '沉著者',
-'沉著述' => '沉著述',
-'沙地阿拉伯' => '沙特阿拉伯',
-'沙烏地阿拉伯' => '沙特阿拉伯',
-'沿著' => '沿着',
-'沿著書' => '沿著书',
-'沿著作' => '沿著作',
-'沿著名' => '沿著名',
-'沿著錄' => '沿著录',
-'沿著稱' => '沿著称',
-'沿著者' => '沿著者',
-'沿著述' => '沿著述',
-'玻里尼西亞' => '波利尼西亚',
-'波士尼亞' => '波斯尼亚',
-'波士尼亞赫塞哥維納' => '波斯尼亚和黑塞哥维那',
-'鐵達尼號' => '泰坦尼克号',
-'幫浦' => '泵',
-'辛巴威' => '津巴布韦',
-'宏都拉斯' => '洪都拉斯',
-'活著' => '活着',
-'活著書' => '活著书',
-'活著作' => '活著作',
-'活著名' => '活著名',
-'活著錄' => '活著录',
-'活著稱' => '活著称',
-'活著者' => '活著者',
-'活著述' => '活著述',
-'流水帳' => '流水账',
-'流著' => '流着',
-'流著書' => '流著书',
-'流著作' => '流著作',
-'流著名' => '流著名',
-'流著錄' => '流著录',
-'流著稱' => '流著称',
-'流著者' => '流著者',
-'流著述' => '流著述',
-'流露著' => '流露着',
-'浮著' => '浮着',
-'蘭卡威' => '浮罗交怡',
-'浮著書' => '浮著书',
-'浮著作' => '浮著作',
-'浮著名' => '浮著名',
-'浮著錄' => '浮著录',
-'浮著稱' => '浮著称',
-'浮著者' => '浮著者',
-'浮著述' => '浮著述',
-'海洛英' => '海洛因',
-'海浬' => '海里',
-'塗著' => '涂着',
-'潤著' => '润着',
-'潤著書' => '润著书',
-'潤著作' => '润著作',
-'潤著名' => '润著名',
-'潤著錄' => '润著录',
-'潤著稱' => '润著称',
-'潤著者' => '润著者',
-'潤著述' => '润著述',
-'混帳' => '混账',
-'清澈' => '清澈',
-'清帳' => '清账',
-'渴著' => '渴着',
-'渴著書' => '渴著书',
-'渴著作' => '渴著作',
-'渴著名' => '渴著名',
-'渴著錄' => '渴著录',
-'渴著稱' => '渴著称',
-'渴著者' => '渴著者',
-'渴著述' => '渴著述',
-'原始碼' => '源代码',
-'溢著' => '溢着',
-'溢著書' => '溢著书',
-'溢著作' => '溢著作',
-'溢著名' => '溢著名',
-'溢著錄' => '溢著录',
-'溢著稱' => '溢著称',
-'溢著者' => '溢著者',
-'溢著述' => '溢著述',
-'滑鼠蛇' => '滑鼠蛇',
-'滿16進位' => '满16进位',
-'滿二進位' => '满二进位',
-'滿八進位' => '满八进位',
-'滿六進位' => '满六进位',
-'滿十六進位' => '满十六进位',
-'滿十進位' => '满十进位',
-'滿著' => '满着',
-'滿著作' => '满著作',
-'滿著名' => '满著名',
-'滿著者' => '满著者',
-'演著' => '演着',
-'演著書' => '演著书',
-'演著作' => '演著作',
-'演著名' => '演著名',
-'演著錄' => '演著录',
-'演著稱' => '演著称',
-'演著者' => '演著者',
-'演著述' => '演著述',
-'漫著' => '漫着',
-'漫著書' => '漫著书',
-'漫著作' => '漫著作',
-'漫著名' => '漫著名',
-'漫著錄' => '漫著录',
-'漫著稱' => '漫著称',
-'漫著者' => '漫著者',
-'漫著述' => '漫著述',
-'雷射' => '激光',
-'點著' => '点着',
-'點著作' => '点著作',
-'點著名' => '点著名',
-'點著錄' => '点著录',
-'點著稱' => '点著称',
-'點著者' => '点著者',
-'點著述' => '点著述',
-'爛帳' => '烂账',
-'燒著' => '烧着',
-'燒著作' => '烧著作',
-'燒著名' => '烧著名',
-'燒著錄' => '烧著录',
-'燒著稱' => '烧著称',
-'燒著者' => '烧著者',
-'燒著述' => '烧著述',
-'照著' => '照着',
-'照著書' => '照著书',
-'照著作' => '照著作',
-'照著名' => '照著名',
-'照著錄' => '照著录',
-'照著稱' => '照著称',
-'照著者' => '照著者',
-'照著述' => '照著述',
-'愛護著' => '爱护着',
-'愛著' => '爱着',
-'愛著書' => '爱著书',
-'愛著作' => '爱著作',
-'愛著名' => '爱著名',
-'愛著錄' => '爱著录',
-'愛著稱' => '爱著称',
-'愛著者' => '爱著者',
-'愛著述' => '爱著述',
-'牽著' => '牵着',
-'牽著書' => '牵著书',
-'牽著作' => '牵著作',
-'牽著名' => '牵著名',
-'牽著錄' => '牵著录',
-'牽著稱' => '牵著称',
-'牽著者' => '牵著者',
-'牽著述' => '牵著述',
-'千里達' => '特立尼达',
-'千里達及托巴哥' => '特立尼达和多巴哥',
-'千里達托貝哥' => '特立尼达和托巴哥',
-'狗隻' => '犬只',
-'猶豫著' => '犹豫着',
-'獨立國家國協' => '独立国家联合体',
-'獨立國協' => '独联体',
-'猜著' => '猜着',
-'猜著書' => '猜着书',
-'猜著作' => '猜著作',
-'猜著名' => '猜著名',
-'猜著錄' => '猜著录',
-'猜著稱' => '猜著称',
-'猜著者' => '猜著者',
-'猜著述' => '猜著述',
-'玩著' => '玩着',
-'班固著' => '班固著',
-'溫納圖' => '瓦努阿图',
-'萬那杜' => '瓦努阿图',
-'華勒沙' => '瓦文萨',
-'華里沙' => '瓦文萨',
-'甜著' => '甜着',
-'甜著書' => '甜著书',
-'甜著作' => '甜著作',
-'甜著名' => '甜著名',
-'甜著錄' => '甜著录',
-'甜著稱' => '甜著称',
-'甜著者' => '甜著者',
-'甜著述' => '甜著述',
-'用著' => '用着',
-'用著書' => '用著书',
-'用著作' => '用著作',
-'用著名' => '用著名',
-'用著錄' => '用著录',
-'用著稱' => '用著称',
-'用著者' => '用著者',
-'用著述' => '用著述',
-'A型肝炎' => '甲型肝炎',
-'A肝' => '甲肝',
-'電視劇集' => '电视剧',
-'電視影集' => '电视系列剧',
-'畫著' => '画着',
-'畫著作' => '画著作',
-'畫著名' => '画著名',
-'畫著稱' => '画著称',
-'畫著者' => '画著者',
-'介面' => '界面',
-'留著' => '留着',
-'留著書' => '留着书',
-'留著作' => '留著作',
-'留著名' => '留著名',
-'留著錄' => '留著录',
-'留著稱' => '留著称',
-'留著者' => '留著者',
-'留著述' => '留著述',
-'疑著' => '疑着',
-'疑著書' => '疑著书',
-'疑著作' => '疑著作',
-'疑著名' => '疑著名',
-'疑著錄' => '疑著录',
-'疑著稱' => '疑著称',
-'疑著者' => '疑著者',
-'疑著述' => '疑著述',
-'狂牛症' => '疯牛病',
-'徵狀' => '症状',
-'百慕達' => '百慕大',
-'皮雅斯·布士南' => '皮尔斯·布鲁斯南',
-'皺著' => '皱着',
-'皺著書' => '皱著书',
-'皺著作' => '皱著作',
-'皺著名' => '皱著名',
-'皺著錄' => '皱著录',
-'皺著稱' => '皱著称',
-'皺著者' => '皱著者',
-'皺著述' => '皱著述',
-'鹽份' => '盐分',
-'蓋著' => '盖着',
-'蓋著作' => '盖著作',
-'蓋著名' => '盖著名',
-'蓋著稱' => '盖著称',
-'盛著' => '盛着',
-'盛著書' => '盛著书',
-'盛著作' => '盛著作',
-'盛著名' => '盛著名',
-'盛著錄' => '盛著录',
-'盛著稱' => '盛著称',
-'盛著者' => '盛著者',
-'盛著述' => '盛著述',
-'盯著' => '盯着',
-'盯著書' => '盯着书',
-'盯著作' => '盯著作',
-'盯著名' => '盯著名',
-'盯著錄' => '盯著录',
-'盯著稱' => '盯著称',
-'盯著者' => '盯著者',
-'盯著述' => '盯著述',
-'看著' => '看着',
-'看著書' => '看着书',
-'看著作' => '看著作',
-'看著名' => '看著名',
-'看著錄' => '看著录',
-'看著稱' => '看著称',
-'看著者' => '看著者',
-'看著述' => '看著述',
-'著業' => '着业',
-'著絲' => '着丝',
-'著麼' => '着么',
-'著人' => '着人',
-'著什麼' => '着什么',
-'著甚麽' => '着什么',
-'著他' => '着他',
-'著令' => '着令',
-'著位' => '着位',
-'著體' => '着体',
-'著你' => '着你',
-'著便' => '着便',
-'著涼' => '着凉',
-'著力' => '着力',
-'著勁' => '着劲',
-'著號' => '着号',
-'著呢' => '着呢',
-'著哩' => '着哩',
-'著地' => '着地',
-'著墨' => '着墨',
-'著聲' => '着声',
-'著處' => '着处',
-'著她' => '着她',
-'著妳' => '着妳',
-'著姓' => '着姓',
-'著它' => '着它',
-'著定' => '着定',
-'著實' => '着实',
-'著己' => '着己',
-'著帳' => '着帐',
-'著床' => '着床',
-'著庸' => '着庸',
-'著式' => '着式',
-'著錄' => '着录',
-'著心' => '着心',
-'著志' => '着志',
-'著忙' => '着忙',
-'著急' => '着急',
-'著惱' => '着恼',
-'著驚' => '着惊',
-'著想' => '着想',
-'著意' => '着意',
-'著慌' => '着慌',
-'著我' => '着我',
-'著手' => '着手',
-'著抹' => '着抹',
-'著摸' => '着摸',
-'著撰' => '着撰',
-'著數' => '着数',
-'著明' => '着明',
-'著末' => '着末',
-'著極' => '着极',
-'著格' => '着格',
-'著棋' => '着棋',
-'著氣' => '着气',
-'著法' => '着法',
-'著淺' => '着浅',
-'著火' => '着火',
-'著然' => '着然',
-'著甚' => '着甚',
-'著生' => '着生',
-'著疑' => '着疑',
-'著白' => '着白',
-'著相' => '着相',
-'著眼' => '着眼',
-'著著' => '着着',
-'著祂' => '着祂',
-'著積' => '着积',
-'著稿' => '着稿',
-'著筆' => '着笔',
-'著籍' => '着籍',
-'著緊' => '着紧',
-'著緑' => '着緑',
-'著絆' => '着绊',
-'著績' => '着绩',
-'著緋' => '着绯',
-'著綠' => '着绿',
-'著肉' => '着肉',
-'著腳' => '着脚',
-'著艦' => '着舰',
-'著色' => '着色',
-'著節' => '着节',
-'著花' => '着花',
-'著莫' => '着莫',
-'著落' => '着落',
-'著槁' => '着藁',
-'著衣' => '着衣',
-'著裝' => '着装',
-'著要' => '着要',
-'著警' => '着警',
-'著趣' => '着趣',
-'著邊' => '着边',
-'著迷' => '着迷',
-'著跡' => '着迹',
-'著重' => '着重',
-'著録' => '着録',
-'著聞' => '着闻',
-'著陸' => '着陆',
-'著雝' => '着雝',
-'著鞭' => '着鞭',
-'著題' => '着题',
-'著魔' => '着魔',
-'睡著' => '睡着',
-'睡著書' => '睡著书',
-'睡著作' => '睡著作',
-'睡著名' => '睡著名',
-'睡著錄' => '睡著录',
-'睡著稱' => '睡著称',
-'睡著者' => '睡著者',
-'睡著述' => '睡著述',
-'瞞著' => '瞒着',
-'瞞著書' => '瞒著书',
-'瞞著作' => '瞒著作',
-'瞞著名' => '瞒著名',
-'瞞著錄' => '瞒著录',
-'瞞著稱' => '瞒著称',
-'瞞著者' => '瞒著者',
-'瞞著述' => '瞒著述',
-'瞧著' => '瞧着',
-'瞧著書' => '瞧着书',
-'瞧著作' => '瞧著作',
-'瞧著名' => '瞧著名',
-'瞧著錄' => '瞧著录',
-'瞧著稱' => '瞧著称',
-'瞧著者' => '瞧著者',
-'瞧著述' => '瞧著述',
-'瞪著' => '瞪着',
-'瞪著書' => '瞪著书',
-'瞪著作' => '瞪著作',
-'瞪著名' => '瞪著名',
-'瞪著錄' => '瞪著录',
-'瞪著稱' => '瞪著称',
-'瞪著者' => '瞪著者',
-'瞪著述' => '瞪著述',
-'矛盾著' => '矛盾着',
-'智慧財產權' => '知识产权',
-'智財權' => '知识产权',
-'知識份子' => '知识分子',
-'什勒斯維希' => '石勒苏益格',
-'矽塵' => '矽尘',
-'矽尘' => '矽尘',
-'矽肺' => '矽肺',
-'矽鋼' => '矽钢',
-'矽钢' => '矽钢',
-'矽' => '硅',
-'矽片' => '硅片',
-'矽谷' => '硅谷',
-'硬體' => '硬件',
-'硬碟' => '硬盘',
-'磁碟' => '磁盘',
-'磁軌' => '磁道',
-'福馬林' => '福尔马林',
-'福著' => '福着',
-'福著書' => '福著书',
-'福著作' => '福著作',
-'福著名' => '福著名',
-'福著錄' => '福著录',
-'福著稱' => '福著称',
-'福著者' => '福著者',
-'福著述' => '福著述',
-'私帳' => '私账',
-'葛摩' => '科摩罗',
-'象牙海岸' => '科特迪瓦',
-'積極份子' => '积极分子',
-'流動電話' => '移动电话',
-'行動電話' => '移动电话',
-'流動網絡' => '移动网络',
-'行動網路' => '移动网络',
-'程式設計師' => '程序员',
-'程式控制' => '程控',
-'空中巴士' => '空中客车',
-'空氣品質' => '空气质量',
-'空氣質素' => '空气质量',
-'空著' => '空着',
-'空著書' => '空著书',
-'空著作' => '空著作',
-'空著名' => '空著名',
-'空著錄' => '空著录',
-'空著稱' => '空著称',
-'空著者' => '空著者',
-'空著述' => '空著述',
-'穿著' => '穿着',
-'穿著書' => '穿著书',
-'穿著作' => '穿著作',
-'穿著名' => '穿著名',
-'穿著錄' => '穿著录',
-'穿著稱' => '穿著称',
-'穿著者' => '穿著者',
-'穿著述' => '穿著述',
-'突尼西亞' => '突尼斯',
-'立著' => '立着',
-'立著《' => '立著《',
-'立著作' => '立著作',
-'立著名' => '立著名',
-'立著有' => '立著有',
-'立著称' => '立著称',
-'立著稱' => '立著称',
-'立著者' => '立著者',
-'立著(' => '立著(',
-'豎著' => '竖着',
-'豎著書' => '竖著书',
-'豎著作' => '竖著作',
-'豎著名' => '竖著名',
-'豎著錄' => '竖著录',
-'豎著稱' => '竖著称',
-'豎著者' => '竖著者',
-'豎著述' => '竖著述',
-'站著' => '站着',
-'站著書' => '站著书',
-'站著作' => '站著作',
-'站著名' => '站著名',
-'站著錄' => '站著录',
-'站著稱' => '站著称',
-'站著者' => '站著者',
-'站著述' => '站著述',
-'笑著' => '笑着',
-'笑著書' => '笑著书',
-'笑著作' => '笑著作',
-'笑著名' => '笑著名',
-'笑著錄' => '笑著录',
-'笑著稱' => '笑著称',
-'笑著者' => '笑著者',
-'笑著述' => '笑著述',
-'筆帳' => '笔账',
-'提比里西' => '第比利斯',
-'簽著' => '签着',
-'簽帳' => '签账',
-'運算元' => '算子',
-'演算法' => '算法',
-'算帳' => '算账',
-'管著' => '管着',
-'管著書' => '管著书',
-'管著作' => '管著作',
-'管著名' => '管著名',
-'管著錄' => '管著录',
-'管著稱' => '管著称',
-'管著者' => '管著者',
-'管著述' => '管著述',
-'管帳' => '管账',
-'公尺' => '米',
-'糊塗帳' => '糊涂账',
-'糖份' => '糖分',
-'動畫影集' => '系列动画片',
-'繫著' => '系着',
-'索忍尼辛' => '索尔仁尼琴',
-'索贊尼辛' => '索尔仁尼琴',
-'蘇辛尼津' => '索尔仁尼琴',
-'索馬利亞' => '索马里',
-'索馬利蘭' => '索马里兰',
-'正體中文' => '繁体中文',
-'強斯頓環礁' => '约翰斯顿岛',
-'縱著' => '纵着',
-'組份' => '组分',
-'經常帳' => '经常账',
-'經濟帳' => '经济账',
-'綁著' => '绑着',
-'綁著書' => '绑著书',
-'綁著作' => '绑著作',
-'綁著名' => '绑著名',
-'綁著錄' => '绑著录',
-'綁著稱' => '绑著称',
-'綁著者' => '绑著者',
-'綁著述' => '绑著述',
-'結帳' => '结账',
-'繞著' => '绕着',
-'繞著書' => '绕著书',
-'繞著作' => '绕著作',
-'繞著名' => '绕著名',
-'繞著錄' => '绕著录',
-'繞著稱' => '绕著称',
-'繞著者' => '绕著者',
-'繞著述' => '绕著述',
-'維根斯坦' => '维特根斯坦',
-'繃著' => '绷着',
-'緣份' => '缘分',
-'纏著' => '缠着',
-'纏著書' => '缠著书',
-'纏著作' => '缠著作',
-'纏著名' => '缠著名',
-'纏著錄' => '缠著录',
-'纏著稱' => '缠著称',
-'纏著者' => '缠著者',
-'纏著述' => '缠著述',
-'網站連結' => '网站链接',
-'網路' => '网络',
-'網頁連結' => '网页链接',
-'罩著' => '罩着',
-'罩著書' => '罩著书',
-'罩著作' => '罩著作',
-'罩著名' => '罩著名',
-'罩著錄' => '罩著录',
-'罩著稱' => '罩著称',
-'罩著者' => '罩著者',
-'罩著述' => '罩著述',
-'美著' => '美着',
-'美著書' => '美著书',
-'美著作' => '美著作',
-'美著名' => '美著名',
-'美著錄' => '美著录',
-'美著称' => '美著称',
-'美著稱' => '美著称',
-'美著者' => '美著者',
-'美著述' => '美著述',
-'耀著' => '耀着',
-'耀著書' => '耀著书',
-'耀著作' => '耀著作',
-'耀著名' => '耀著名',
-'耀著錄' => '耀著录',
-'耀著稱' => '耀著称',
-'耀著者' => '耀著者',
-'耀著述' => '耀著述',
-'寮國' => '老挝',
-'寮人民民主共和國' => '老挝人民民主共和国',
-'寮語' => '老挝语',
-'考著' => '考着',
-'考著書' => '考著书',
-'考著作' => '考著作',
-'考著名' => '考著名',
-'考著錄' => '考著录',
-'考著稱' => '考著称',
-'考著者' => '考著者',
-'考著述' => '考著述',
-'職份' => '职分',
-'辛康納利' => '肖恩·康纳利',
-'蕭士塔高維奇' => '肖斯塔科维奇',
-'蕭士達高維契' => '肖斯塔科维奇',
-'甘迺迪' => '肯尼迪',
-'背著' => '背着',
-'背著書' => '背著书',
-'背著作' => '背著作',
-'背著名' => '背著名',
-'背著錄' => '背著录',
-'背著稱' => '背著称',
-'背著者' => '背著者',
-'背著述' => '背著述',
-'膠著' => '胶着',
-'膠著書' => '胶著书',
-'膠著作' => '胶著作',
-'膠著名' => '胶著名',
-'膠著錄' => '胶著录',
-'膠著稱' => '胶著称',
-'膠著者' => '胶著者',
-'膠著述' => '胶著述',
-'舒麥加' => '舒马赫',
-'太空梭' => '航天飞机',
-'穿梭機' => '航天飞机',
-'愛滋' => '艾滋',
-'晶元' => '芯片',
-'晶片' => '芯片',
-'蘇利南' => '苏里南',
-'苦著' => '苦着',
-'苦著書' => '苦著书',
-'苦著作' => '苦著作',
-'苦著名' => '苦著名',
-'苦著錄' => '苦著录',
-'苦著稱' => '苦著称',
-'苦著者' => '苦著者',
-'苦著述' => '苦著述',
-'英吋' => '英寸',
-'英呎' => '英尺',
-'共和联邦' => '英联邦',
-'大英國協' => '英联邦',
-'士多啤梨' => '草莓',
-'螢光棒' => '荧光棒',
-'螢屏' => '荧屏',
-'霍爾斯坦' => '荷尔斯泰因',
-'莫三比克' => '莫桑比克',
-'雷伊泰灣' => '莱特湾',
-'賴索托' => '莱索托',
-'獲著' => '获着',
-'穫著' => '获着',
-'獲著書' => '获著书',
-'獲著作' => '获著作',
-'獲著名' => '获著名',
-'獲著錄' => '获著录',
-'獲著稱' => '获著称',
-'獲著者' => '获著者',
-'獲著述' => '获著述',
-'塞拉耶佛' => '萨拉热窝',
-'落著' => '落着',
-'落著書' => '落著书',
-'落著作' => '落著作',
-'落著名' => '落著名',
-'落著錄' => '落著录',
-'落著稱' => '落著称',
-'落著者' => '落著者',
-'落著述' => '落著述',
-'滿地可' => '蒙特利尔',
-'蒙特婁' => '蒙特利尔',
-'蒙著' => '蒙着',
-'蒙著書' => '蒙著书',
-'蒙著作' => '蒙著作',
-'蒙著名' => '蒙著名',
-'蒙著錄' => '蒙著录',
-'蒙著稱' => '蒙著称',
-'蒙著者' => '蒙著者',
-'蒙著述' => '蒙著述',
-'藍芽' => '蓝牙',
-'蘊涵著' => '蕴涵着',
-'薛丁格' => '薛定谔',
-'藏著' => '藏着',
-'藏著書' => '藏著书',
-'藏著作' => '藏著作',
-'藏著名' => '藏著名',
-'藏著錄' => '藏著录',
-'藏著稱' => '藏著称',
-'藏著者' => '藏著者',
-'藏著述' => '藏著述',
-'蘸著' => '蘸着',
-'蘸著書' => '蘸著书',
-'蘸著作' => '蘸著作',
-'蘸著名' => '蘸著名',
-'蘸著錄' => '蘸著录',
-'蘸著稱' => '蘸著称',
-'蘸著者' => '蘸著者',
-'蘸著述' => '蘸著述',
-'行人路权' => '行人路权',
-'行人路權' => '行人路权',
-'行著' => '行着',
-'行著書' => '行著书',
-'行著作' => '行著作',
-'行著名' => '行著名',
-'行著錄' => '行著录',
-'行著稱' => '行著称',
-'行著者' => '行著者',
-'行著述' => '行著述',
-'衣著' => '衣着',
-'衣著書' => '衣著书',
-'衣著作' => '衣著作',
-'衣著名' => '衣著名',
-'衣著錄' => '衣著录',
-'衣著称' => '衣著称',
-'衣著稱' => '衣著称',
-'衣著者' => '衣著者',
-'衣著述' => '衣著述',
-'表姊' => '表姐',
-'裝著' => '装着',
-'裝著書' => '装著书',
-'裝著作' => '装著作',
-'裝著名' => '装著名',
-'裝著錄' => '装著录',
-'裝著稱' => '装著称',
-'裝著者' => '装著者',
-'裝著述' => '装著述',
-'裹著' => '裹着',
-'裹著書' => '裹著书',
-'裹著作' => '裹著作',
-'裹著名' => '裹著名',
-'裹著錄' => '裹著录',
-'裹著稱' => '裹著称',
-'裹著者' => '裹著者',
-'裹著述' => '裹著述',
-'要帳' => '要账',
-'覆蓋著' => '覆盖着',
-'覆著' => '覆着',
-'見著' => '见着',
-'見著書' => '见著书',
-'見著作' => '见著作',
-'見著名' => '见著名',
-'見著錄' => '见著录',
-'見著稱' => '见著称',
-'見著者' => '见著者',
-'見著述' => '见著述',
-'規畫' => '规划',
-'視著' => '视着',
-'視著名' => '视著名',
-'占士邦' => '詹姆斯·邦德',
-'警戒著' => '警戒着',
-'計畫' => '计划',
-'電腦程式' => '计算机程序',
-'認帳' => '认账',
-'記著' => '记着',
-'記著書' => '记著书',
-'記著作' => '记著作',
-'記著名' => '记著名',
-'記著錄' => '记著录',
-'記著稱' => '记著称',
-'記著者' => '记著者',
-'記著述' => '记著述',
-'記帳' => '记账',
-'片語' => '词组',
-'試著' => '试着',
-'試著書' => '试著书',
-'試著作' => '试著作',
-'試著名' => '试著名',
-'試著錄' => '试著录',
-'試著稱' => '试著称',
-'試著者' => '试著者',
-'試著述' => '试著述',
-'語著' => '语着',
-'語著書' => '语著书',
-'語著作' => '语著作',
-'語著名' => '语著名',
-'語著錄' => '语著录',
-'語著稱' => '语著称',
-'語著者' => '语著者',
-'語著述' => '语著述',
-'說著' => '说着',
-'說著作' => '说著作',
-'說著稱' => '说著称',
-'說著者' => '说著者',
-'說著述' => '说著述',
-'諾曼第' => '诺曼底',
-'數據機' => '调制解调器',
-'象徵著' => '象征着',
-'象徵著名' => '象征著名',
-'碧咸' => '贝克汉姆',
-'貝爾格勒' => '贝尔格莱德',
-'負著' => '负着',
-'貢寮' => '贡寮',
-'帳上' => '账上',
-'帳冊' => '账册',
-'帳務' => '账务',
-'帳單' => '账单',
-'帳號' => '账号',
-'帳外' => '账外',
-'帳戶' => '账户',
-'帳房' => '账房',
-'帳本' => '账本',
-'帳款' => '账款',
-'帳目' => '账目',
-'帳簿' => '账簿',
-'帳面' => '账面',
-'賒帳' => '赊账',
-'賴帳' => '赖账',
-'尚比亞' => '赞比亚',
-'西臺人' => '赫梯人',
-'西臺國' => '赫梯国',
-'西臺帝' => '赫梯帝',
-'西臺文' => '赫梯文',
-'西臺族' => '赫梯族',
-'西臺王' => '赫梯王',
-'西臺語' => '赫梯语',
-'赫魯雪夫' => '赫鲁晓夫',
-'走為上著' => '走为上着',
-'走著' => '走着',
-'走著書' => '走著书',
-'走著作' => '走著作',
-'走著名' => '走著名',
-'走著錄' => '走著录',
-'走著稱' => '走著称',
-'走著者' => '走著者',
-'走著述' => '走著述',
-'趕著' => '赶着',
-'趕著書' => '赶著书',
-'趕著作' => '赶著作',
-'趕著名' => '赶著名',
-'趕著錄' => '赶著录',
-'趕著稱' => '赶著称',
-'趕著者' => '赶著者',
-'趕著述' => '赶著述',
-'超連結' => '超链接',
-'趴著' => '趴着',
-'趴著書' => '趴著书',
-'趴著作' => '趴著作',
-'趴著名' => '趴著名',
-'趴著錄' => '趴著录',
-'趴著稱' => '趴著称',
-'趴著者' => '趴著者',
-'趴著述' => '趴著述',
-'躍著' => '跃着',
-'躍著書' => '跃著书',
-'躍著作' => '跃著作',
-'躍著名' => '跃著名',
-'躍著錄' => '跃著录',
-'躍著稱' => '跃著称',
-'躍著者' => '跃著者',
-'躍著述' => '跃著述',
-'跑著' => '跑着',
-'跑著書' => '跑著书',
-'跑著作' => '跑著作',
-'跑著名' => '跑著名',
-'跑著錄' => '跑著录',
-'跑著稱' => '跑著称',
-'跑著者' => '跑著者',
-'跑著述' => '跑著述',
-'跟著' => '跟着',
-'跟著書' => '跟著书',
-'跟著作' => '跟著作',
-'跟著名' => '跟著名',
-'跟著錄' => '跟著录',
-'跟著稱' => '跟著称',
-'跟著者' => '跟著者',
-'跟著述' => '跟著述',
-'跪著' => '跪着',
-'跪著書' => '跪著书',
-'跪著作' => '跪著作',
-'跪著名' => '跪著名',
-'跪著錄' => '跪著录',
-'跪著稱' => '跪著称',
-'跪著者' => '跪著者',
-'跪著述' => '跪著述',
-'跳著' => '跳着',
-'跳著書' => '跳著书',
-'跳著作' => '跳著作',
-'跳著名' => '跳著名',
-'跳著錄' => '跳著录',
-'跳著稱' => '跳著称',
-'跳著者' => '跳著者',
-'跳著述' => '跳著述',
-'踏著' => '踏着',
-'踏著書' => '踏著书',
-'踏著作' => '踏著作',
-'踏著名' => '踏著名',
-'踏著錄' => '踏著录',
-'踏著稱' => '踏著称',
-'踏著者' => '踏著者',
-'踏著述' => '踏著述',
-'踩著' => '踩着',
-'踩著書' => '踩著书',
-'踩著作' => '踩著作',
-'踩著名' => '踩著名',
-'踩著錄' => '踩著录',
-'踩著稱' => '踩著称',
-'踩著者' => '踩著者',
-'踩著述' => '踩著述',
-'笨豬跳' => '蹦极跳',
-'绑紧跳' => '蹦极跳',
-'身分' => '身份',
-'身著' => '身着',
-'身著書' => '身著书',
-'身著作' => '身著作',
-'身著名' => '身著名',
-'身著錄' => '身著录',
-'身著稱' => '身著称',
-'身著者' => '身著者',
-'身著述' => '身著述',
-'躺著' => '躺着',
-'躺著書' => '躺著书',
-'躺著作' => '躺著作',
-'躺著名' => '躺著名',
-'躺著錄' => '躺著录',
-'躺著稱' => '躺著称',
-'躺著者' => '躺著者',
-'躺著述' => '躺著述',
-'轉著' => '转着',
-'轉著書' => '转著书',
-'轉著作' => '转著作',
-'轉著名' => '转著名',
-'轉著錄' => '转著录',
-'轉著稱' => '转著称',
-'轉著者' => '转著者',
-'轉著述' => '转著述',
-'轉帳' => '转账',
-'軟體' => '软件',
-'軟體動物' => '软体动物',
-'軟體家具' => '软体家具',
-'軟碟機' => '软驱',
-'載著' => '载着',
-'載著書' => '载著书',
-'載著作' => '载著作',
-'載著名' => '载著名',
-'載著錄' => '载著录',
-'載著稱' => '载著称',
-'載著者' => '载著者',
-'載著述' => '载著述',
-'達·文西' => '达·芬奇',
-'達著' => '达着',
-'三蘭港' => '达累斯萨拉姆',
-'達文西' => '达芬奇',
-'達著書' => '达著书',
-'達著作' => '达著作',
-'達著名' => '达著名',
-'達著錄' => '达著录',
-'達著稱' => '达著称',
-'達著者' => '达著者',
-'達著述' => '达著述',
-'過份' => '过分',
-'過著' => '过着',
-'過著作' => '过著作',
-'過著名' => '过著名',
-'過著錄' => '过著录',
-'過著稱' => '过著称',
-'過著者' => '过著者',
-'過著述' => '过著述',
-'米高·奧雲' => '迈克尔·欧文',
-'還帳' => '还账',
-'演化論' => '进化论',
-'進帳' => '进账',
-'連著' => '连着',
-'連結他' => '连结他',
-'連著書' => '连著书',
-'連著作' => '连著作',
-'連著名' => '连著名',
-'連著錄' => '连著录',
-'連著稱' => '连著称',
-'連著者' => '连著者',
-'連著述' => '连著述',
-'杜拜' => '迪拜',
-'迫著' => '迫着',
-'疊代' => '迭代',
-'追著' => '追着',
-'追著書' => '追著书',
-'追著作' => '追著作',
-'追著名' => '追著名',
-'追著錄' => '追著录',
-'追著稱' => '追著称',
-'追著者' => '追著者',
-'追著述' => '追著述',
-'逆著' => '逆着',
-'逆著書' => '逆著书',
-'逆著作' => '逆著作',
-'逆著名' => '逆著名',
-'逆著錄' => '逆著录',
-'逆著稱' => '逆著称',
-'逆著者' => '逆著者',
-'逆著述' => '逆著述',
-'逼著' => '逼着',
-'逼著書' => '逼著书',
-'逼著作' => '逼著作',
-'逼著名' => '逼著名',
-'逼著錄' => '逼著录',
-'逼著稱' => '逼著称',
-'逼著者' => '逼著者',
-'逼著述' => '逼著述',
-'遇著' => '遇着',
-'遇著書' => '遇著书',
-'遇著作' => '遇著作',
-'遇著名' => '遇著名',
-'遇著錄' => '遇著录',
-'遇著称' => '遇著称',
-'遇著稱' => '遇著称',
-'遇著者' => '遇著者',
-'遇著述' => '遇著述',
-'遍佈著' => '遍布着',
-'遍布著' => '遍布着',
-'部份' => '部分',
-'配合著' => '配合着',
-'配合著名' => '配合著名',
-'配著' => '配着',
-'配著書' => '配著书',
-'配著作' => '配著作',
-'配著名' => '配著名',
-'配著錄' => '配著录',
-'配著稱' => '配著称',
-'配著者' => '配著者',
-'配著述' => '配著述',
-'釀著' => '酿着',
-'釀著書' => '酿著书',
-'釀著作' => '酿著作',
-'釀著名' => '酿著名',
-'釀著錄' => '酿著录',
-'釀著稱' => '酿著称',
-'釀著者' => '酿著者',
-'釀著述' => '酿著述',
-'黎克特制' => '里氏',
-'芮氏0' => '里氏0',
-'芮氏1' => '里氏1',
-'芮氏2' => '里氏2',
-'芮氏3' => '里氏3',
-'芮氏4' => '里氏4',
-'芮氏5' => '里氏5',
-'芮氏6' => '里氏6',
-'芮氏7' => '里氏7',
-'芮氏8' => '里氏8',
-'芮氏9' => '里氏9',
-'芮氏地震規模' => '里氏地震规模',
-'芮氏規模' => '里氏震级',
-'金夏沙' => '金沙萨',
-'鈽' => '钚',
-'鍅' => '钫',
-'狄托' => '铁托',
-'卯足' => '铆足',
-'鋪著' => '铺着',
-'鋪著書' => '铺著书',
-'鋪著作' => '铺著作',
-'鋪著名' => '铺著名',
-'鋪著錄' => '铺著录',
-'鋪著稱' => '铺著称',
-'鋪著者' => '铺著者',
-'鋪著述' => '铺著述',
-'鏈結' => '链接',
-'銷帳' => '销账',
-'鉲' => '锎',
-'鎝' => '锝',
-'鉳' => '锫',
-'鑀' => '锿',
-'鋂' => '镅',
-'錼' => '镎',
-'孟德爾遜' => '门德尔松',
-'孟德爾頌' => '门德尔松',
-'快閃記憶體' => '闪存',
-'閉著' => '闭着',
-'閉著書' => '闭著书',
-'閉著作' => '闭著作',
-'閉著名' => '闭著名',
-'閉著錄' => '闭著录',
-'閉著稱' => '闭著称',
-'閉著者' => '闭著者',
-'閉著述' => '闭著述',
-'閑著' => '闲着',
-'閒著' => '闲着',
-'閑著書' => '闲著书',
-'閑著作' => '闲著作',
-'閑著名' => '闲著名',
-'閑著錄' => '闲著录',
-'閑著稱' => '闲著称',
-'閑著者' => '闲著者',
-'閑著述' => '闲著述',
-'悶著' => '闷着',
-'鬧著' => '闹着',
-'聞著' => '闻着',
-'亞塞拜然' => '阿塞拜疆',
-'阿布達比' => '阿布扎比',
-'阿拉伯聯合大公國' => '阿拉伯联合酋长国',
-'亞斯文' => '阿斯旺',
-'附著' => '附着',
-'附著書' => '附著书',
-'附著作' => '附著作',
-'附著名' => '附著名',
-'附著錄' => '附著录',
-'附著稱' => '附著称',
-'附著者' => '附著者',
-'附著述' => '附著述',
-'陋著' => '陋着',
-'陋著書' => '陋著书',
-'陋著作' => '陋著作',
-'陋著名' => '陋著名',
-'陋著錄' => '陋著录',
-'陋著稱' => '陋著称',
-'陋著者' => '陋著者',
-'陋著述' => '陋著述',
-'陪著' => '陪着',
-'陪著書' => '陪著书',
-'陪著作' => '陪著作',
-'陪著名' => '陪著名',
-'陪著錄' => '陪著录',
-'陪著稱' => '陪著称',
-'陪著者' => '陪著者',
-'陪著述' => '陪著述',
-'隨著' => '随着',
-'隨著書' => '随著书',
-'隨著作' => '随著作',
-'隨著名' => '随著名',
-'隨著錄' => '随著录',
-'隨著稱' => '随著称',
-'隨著者' => '随著者',
-'隨著述' => '随著述',
-'私隱' => '隐私',
-'隔著' => '隔着',
-'隔著書' => '隔著书',
-'隔著作' => '隔著作',
-'隔著名' => '隔著名',
-'隔著錄' => '隔著录',
-'隔著稱' => '隔著称',
-'隔著者' => '隔著者',
-'隔著述' => '隔著述',
-'耶加達' => '雅加达',
-'雅爾達' => '雅尔塔',
-'雅著' => '雅着',
-'雅著書' => '雅著书',
-'雅著作' => '雅著作',
-'雅著名' => '雅著名',
-'雅著錄' => '雅著录',
-'雅著称' => '雅著称',
-'雅著稱' => '雅著称',
-'雅著者' => '雅著者',
-'雅著述' => '雅著述',
-'雷諾瓦' => '雷诺阿',
-'荷姆茲' => '霍尔木兹',
-'非份' => '非分',
-'靠著' => '靠着',
-'靠著作' => '靠著作',
-'靠著名' => '靠著名',
-'靠著錄' => '靠著录',
-'靠著稱' => '靠著称',
-'靠著者' => '靠著者',
-'靠著述' => '靠著述',
-'南韓' => '韩国',
-'音樂錄影帶' => '音乐录影带',
-'頂著' => '顶着',
-'頂著書' => '顶著书',
-'頂著作' => '顶著作',
-'頂著名' => '顶著名',
-'頂著錄' => '顶著录',
-'頂著稱' => '顶著称',
-'頂著者' => '顶著者',
-'頂著述' => '顶著述',
-'順著' => '顺着',
-'順著書' => '顺著书',
-'順著作' => '顺著作',
-'順著名' => '顺著名',
-'順著錄' => '顺著录',
-'順著稱' => '顺著称',
-'順著者' => '顺著者',
-'順著述' => '顺著述',
-'領著' => '领着',
-'領著書' => '领著书',
-'領著作' => '领著作',
-'領著名' => '领著名',
-'領著錄' => '领著录',
-'領著稱' => '领著称',
-'領著者' => '领著者',
-'領著述' => '领著述',
-'飃著' => '飘着',
-'飄著' => '飘着',
-'飄著書' => '飘著书',
-'飄著作' => '飘著作',
-'飄著名' => '飘著名',
-'飄著錄' => '飘著录',
-'飄著稱' => '飘著称',
-'飄著者' => '飘著者',
-'飄著述' => '飘著述',
-'行政總裁' => '首席执行官',
-'執行長、' => '首席执行官、',
-'執行長。' => '首席执行官。',
-'執行長,' => '首席执行官,',
-'財務長、' => '首席财务官、',
-'財務長。' => '首席财务官。',
-'財務長,' => '首席财务官,',
-'營運長、' => '首席运营官、',
-'營運長。' => '首席运营官。',
-'營運長,' => '首席运营官,',
-'馬爾地夫' => '马尔代夫',
-'萌島' => '马恩岛',
-'馬拉威' => '马拉维',
-'馬斯垂克' => '马斯特里赫特',
-'馬爾他' => '马耳他',
-'麻薩諸塞' => '马萨诸塞',
-'馬利共和國' => '马里共和国',
-'駛著' => '驶着',
-'駕著' => '驾着',
-'駕著書' => '驾著书',
-'駕著作' => '驾著作',
-'駕著名' => '驾著名',
-'駕著錄' => '驾著录',
-'駕著稱' => '驾著称',
-'駕著者' => '驾著者',
-'駕著述' => '驾著述',
-'罵著' => '骂着',
-'罵著書' => '骂著书',
-'罵著作' => '骂著作',
-'罵著名' => '骂著名',
-'罵著錄' => '骂著录',
-'罵著稱' => '骂著称',
-'罵著者' => '骂著者',
-'罵著述' => '骂著述',
-'騎著' => '骑着',
-'騎著書' => '骑著书',
-'騎著作' => '骑著作',
-'騎著名' => '骑著名',
-'騎著錄' => '骑著录',
-'騎著稱' => '骑著称',
-'騎著者' => '骑著者',
-'騎著述' => '骑著述',
-'騙著' => '骗着',
-'騙著書' => '骗著书',
-'騙著作' => '骗著作',
-'騙著名' => '骗著名',
-'騙著錄' => '骗著录',
-'騙著稱' => '骗著称',
-'騙著者' => '骗著者',
-'騙著述' => '骗著述',
-'尖峰時段' => '高峰时段',
-'尖峰時間' => '高峰时间',
-'高畫質' => '高清',
-'高著' => '高着',
-'高著書' => '高著书',
-'高著作' => '高著作',
-'高著名' => '高著名',
-'高著錄' => '高著录',
-'高著称' => '高著称',
-'高著稱' => '高著称',
-'高著者' => '高著者',
-'高著述' => '高著述',
-'魚雷' => '鱼雷',
-'鱼雷' => '鱼雷',
-'咪高峰' => '麦克风',
-'黏著' => '黏着',
-'黏著書' => '黏著书',
-'黏著作' => '黏著作',
-'黏著名' => '黏著名',
-'黏著錄' => '黏著录',
-'黏著稱' => '黏著称',
-'黏著者' => '黏著者',
-'黏著述' => '黏著述',
-'蒙特內哥羅' => '黑山',
-'滑鼠' => '鼠标',
-);
index 13d13a6..a6da823 100644 (file)
@@ -74,6 +74,8 @@ abstract class ApiBase extends ContextSource {
         * - string: Any non-empty string, not expected to be very long or contain newlines.
         *   <input type="text"> would be an appropriate HTML form field.
         * - submodule: The name of a submodule of this module, see PARAM_SUBMODULE_MAP.
+        * - tags: A string naming an existing, explicitly-defined tag. Should usually be
+        *   used with PARAM_ISMULTI.
         * - text: Any non-empty string, expected to be very long or contain newlines.
         *   <textarea> would be an appropriate HTML form field.
         * - timestamp: A timestamp in any format recognized by MWTimestamp, or the
@@ -1063,6 +1065,16 @@ abstract class ApiBase extends ContextSource {
                                                break;
                                        case 'upload': // nothing to do
                                                break;
+                                       case 'tags':
+                                               // If change tagging was requested, check that the tags are valid.
+                                               if ( !is_array( $value ) && !$multi ) {
+                                                       $value = array( $value );
+                                               }
+                                               $tagsStatus = ChangeTags::canAddTagsAccompanyingChange( $value );
+                                               if ( !$tagsStatus->isGood() ) {
+                                                       $this->dieStatus( $tagsStatus );
+                                               }
+                                               break;
                                        default:
                                                ApiBase::dieDebug( __METHOD__, "Param $encParamName's type is unknown - $type" );
                                }
@@ -1260,11 +1272,10 @@ abstract class ApiBase extends ContextSource {
                        );
                }
 
-               if ( $this->getUser()->matchEditToken(
-                       $token,
-                       $salts[$tokenType],
-                       $this->getRequest()
-               ) ) {
+               $tokenObj = ApiQueryTokens::getToken(
+                       $this->getUser(), $this->getRequest()->getSession(), $salts[$tokenType]
+               );
+               if ( $tokenObj->match( $token ) ) {
                        return true;
                }
 
@@ -2523,19 +2534,6 @@ abstract class ApiBase extends ContextSource {
        /// @deprecated since 1.24
        const PROP_NULLABLE = 1;
 
-       /**
-        * Formerly returned a string that identifies the version of the extending
-        * class. Typically included the class name, the svn revision, timestamp,
-        * and last author. Usually done with SVN's Id keyword
-        *
-        * @deprecated since 1.21, version string is no longer supported
-        * @return string
-        */
-       public function getVersion() {
-               wfDeprecated( __METHOD__, '1.21' );
-               return '';
-       }
-
        /**
         * Formerly used to fetch a list of possible properites in the result,
         * somehow organized with respect to the prop parameter that causes them to
index 28c6ece..dfcbaf8 100644 (file)
@@ -32,21 +32,22 @@ class ApiCheckToken extends ApiBase {
                $params = $this->extractRequestParams();
                $token = $params['token'];
                $maxage = $params['maxtokenage'];
-               $request = $this->getRequest();
                $salts = ApiQueryTokens::getTokenTypeSalts();
-               $salt = $salts[$params['type']];
 
                $res = array();
 
-               if ( $this->getUser()->matchEditToken( $token, $salt, $request, $maxage ) ) {
+               $tokenObj = ApiQueryTokens::getToken(
+                       $this->getUser(), $this->getRequest()->getSession(), $salts[$params['type']]
+               );
+               if ( $tokenObj->match( $token, $maxage ) ) {
                        $res['result'] = 'valid';
-               } elseif ( $maxage !== null && $this->getUser()->matchEditToken( $token, $salt, $request ) ) {
+               } elseif ( $maxage !== null && $tokenObj->match( $token ) ) {
                        $res['result'] = 'expired';
                } else {
                        $res['result'] = 'invalid';
                }
 
-               $ts = User::getEditTokenTimestamp( $token );
+               $ts = MediaWiki\Session\Token::getTimestamp( $token );
                if ( $ts !== null ) {
                        $mwts = new MWTimestamp();
                        $mwts->timestamp->setTimestamp( $ts );
index a044be2..d6baf34 100644 (file)
@@ -149,8 +149,11 @@ class ApiCreateAccount extends ApiBase {
                        // Token was incorrect, so add it to result, but don't throw an exception
                        // since not having the correct token is part of the normal
                        // flow of events.
-                       $result['token'] = LoginForm::getCreateaccountToken();
+                       $result['token'] = LoginForm::getCreateaccountToken()->toString();
                        $result['result'] = 'NeedToken';
+                       $this->setWarning( 'Fetching a token via action=createaccount is deprecated. ' .
+                               'Use action=query&meta=tokens&type=createaccount instead.' );
+                       $this->logFeatureUsage( 'action=createaccount&!token' );
                } elseif ( !$status->isOK() ) {
                        // There was an error. Die now.
                        $this->dieStatus( $status );
@@ -200,7 +203,11 @@ class ApiCreateAccount extends ApiBase {
                                ApiBase::PARAM_TYPE => 'password',
                        ),
                        'domain' => null,
-                       'token' => null,
+                       'token' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => false, // for BC
+                               ApiBase::PARAM_HELP_MSG => array( 'api-help-param-token', 'createaccount' ),
+                       ),
                        'email' => array(
                                ApiBase::PARAM_TYPE => 'string',
                                ApiBase::PARAM_REQUIRED => $this->getConfig()->get( 'EmailConfirmToEdit' ),
index edcee86..b0bf5dd 100644 (file)
@@ -188,7 +188,7 @@ class ApiDelete extends ApiBase {
                        ),
                        'reason' => null,
                        'tags' => array(
-                               ApiBase::PARAM_TYPE => ChangeTags::listExplicitlyDefinedTags(),
+                               ApiBase::PARAM_TYPE => 'tags',
                                ApiBase::PARAM_ISMULTI => true,
                        ),
                        'watch' => array(
index 59264e8..4a83129 100644 (file)
@@ -363,10 +363,11 @@ class ApiEditPage extends ApiBase {
 
                // Apply change tags
                if ( count( $params['tags'] ) ) {
-                       if ( $user->isAllowed( 'applychangetags' ) ) {
+                       $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
+                       if ( $tagStatus->isOk() ) {
                                $requestArray['wpChangeTags'] = implode( ',', $params['tags'] );
                        } else {
-                               $this->dieUsage( 'You don\'t have permission to set change tags.', 'taggingnotallowed' );
+                               $this->dieStatus( $tagStatus );
                        }
                }
 
@@ -579,7 +580,7 @@ class ApiEditPage extends ApiBase {
                        ),
                        'summary' => null,
                        'tags' => array(
-                               ApiBase::PARAM_TYPE => ChangeTags::listExplicitlyDefinedTags(),
+                               ApiBase::PARAM_TYPE => 'tags',
                                ApiBase::PARAM_ISMULTI => true,
                        ),
                        'minor' => false,
index be68310..69cedd7 100644 (file)
@@ -32,6 +32,7 @@
 abstract class ApiFormatBase extends ApiBase {
        private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp;
        private $mBuffer, $mDisabled = false;
+       private $mIsWrappedHtml = false;
        protected $mForceDefaultParams = false;
 
        /**
@@ -45,6 +46,7 @@ abstract class ApiFormatBase extends ApiBase {
                $this->mIsHtml = ( substr( $format, -2, 2 ) === 'fm' ); // ends with 'fm'
                if ( $this->mIsHtml ) {
                        $this->mFormat = substr( $format, 0, -2 ); // remove ending 'fm'
+                       $this->mIsWrappedHtml = $this->getMain()->getCheck( 'wrappedhtml' );
                } else {
                        $this->mFormat = $format;
                }
@@ -79,6 +81,15 @@ abstract class ApiFormatBase extends ApiBase {
                return $this->mIsHtml;
        }
 
+       /**
+        * Returns true when the special wrapped mode is enabled.
+        * @since 1.27
+        * @return bool
+        */
+       protected function getIsWrappedHtml() {
+               return $this->mIsWrappedHtml;
+       }
+
        /**
         * Disable the formatter.
         *
@@ -145,7 +156,9 @@ abstract class ApiFormatBase extends ApiBase {
                        return;
                }
 
-               $mime = $this->getIsHtml() ? 'text/html' : $this->getMimeType();
+               $mime = $this->getIsWrappedHtml()
+                       ? 'text/mediawiki-api-prettyprint-wrapped'
+                       : ( $this->getIsHtml() ? 'text/html' : $this->getMimeType() );
 
                // Some printers (ex. Feed) do their own header settings,
                // in which case $mime will be set to null
@@ -185,19 +198,21 @@ abstract class ApiFormatBase extends ApiBase {
                        $out->addModuleStyles( 'mediawiki.apipretty' );
                        $out->setPageTitle( $context->msg( 'api-format-title' ) );
 
-                       // When the format without suffix 'fm' is defined, there is a non-html version
-                       if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) {
-                               $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat );
-                       } else {
-                               $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format );
-                       }
+                       if ( !$this->getIsWrappedHtml() ) {
+                               // When the format without suffix 'fm' is defined, there is a non-html version
+                               if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) {
+                                       $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat );
+                               } else {
+                                       $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format );
+                               }
 
-                       $header = $msg->parseAsBlock();
-                       $out->addHTML(
-                               Html::rawElement( 'div', array( 'class' => 'api-pretty-header' ),
-                                       ApiHelp::fixHelpLinks( $header )
-                               )
-                       );
+                               $header = $msg->parseAsBlock();
+                               $out->addHTML(
+                                       Html::rawElement( 'div', array( 'class' => 'api-pretty-header' ),
+                                               ApiHelp::fixHelpLinks( $header )
+                                       )
+                               );
+                       }
 
                        if ( Hooks::run( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) {
                                $out->addHTML(
@@ -205,10 +220,38 @@ abstract class ApiFormatBase extends ApiBase {
                                );
                        }
 
-                       // API handles its own clickjacking protection.
-                       // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
-                       $out->allowClickjacking();
-                       $out->output();
+                       if ( $this->getIsWrappedHtml() ) {
+                               // This is a special output mode mainly intended for ApiSandbox use
+                               $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' );
+                               $json = FormatJson::encode(
+                                       array(
+                                               'html' => $out->getHTML(),
+                                               'modules' => array_values( array_unique( array_merge(
+                                                       $out->getModules(),
+                                                       $out->getModuleScripts(),
+                                                       $out->getModuleStyles()
+                                               ) ) ),
+                                               'time' => round( $time * 1000 ),
+                                       ),
+                                       false, FormatJson::ALL_OK
+                               );
+
+                               // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
+                               // Flash, but what it does isn't friendly for the API, so we need to
+                               // work around it.
+                               if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) {
+                                       $json = preg_replace(
+                                               '/\<(\s*cross-domain-policy\s*)\>/i', '\\u003C$1\\u003E', $json
+                                       );
+                               }
+
+                               echo $json;
+                       } else {
+                               // API handles its own clickjacking protection.
+                               // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
+                               $out->allowClickjacking();
+                               $out->output();
+                       }
                } else {
                        // For non-HTML output, clear all errors that might have been
                        // displayed if display_errors=On
@@ -234,6 +277,18 @@ abstract class ApiFormatBase extends ApiBase {
                return $this->mBuffer;
        }
 
+       public function getAllowedParams() {
+               $ret = array();
+               if ( $this->getIsHtml() ) {
+                       $ret['wrappedhtml'] = array(
+                               ApiBase::PARAM_DFLT => false,
+                               ApiBase::PARAM_HELP_MSG => 'apihelp-format-param-wrappedhtml',
+
+                       );
+               }
+               return $ret;
+       }
+
        protected function getExamplesMessages() {
                return array(
                        'action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName()
index a319be3..1566a0f 100644 (file)
@@ -121,10 +121,10 @@ class ApiFormatJson extends ApiFormatBase {
 
        public function getAllowedParams() {
                if ( $this->isRaw ) {
-                       return array();
+                       return parent::getAllowedParams();
                }
 
-               $ret = array(
+               $ret = parent::getAllowedParams() + array(
                        'callback' => array(
                                ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback',
                        ),
index df9d581..f5f2504 100644 (file)
@@ -78,7 +78,7 @@ class ApiFormatPhp extends ApiFormatBase {
        }
 
        public function getAllowedParams() {
-               $ret = array(
+               $ret = parent::getAllowedParams() + array(
                        'formatversion' => array(
                                ApiBase::PARAM_TYPE => array( 1, 2, 'latest' ),
                                ApiBase::PARAM_DFLT => 1,
index e8ad387..b4a478c 100644 (file)
@@ -288,7 +288,7 @@ class ApiFormatXml extends ApiFormatBase {
        }
 
        public function getAllowedParams() {
-               return array(
+               return parent::getAllowedParams() + array(
                        'xslt' => array(
                                ApiBase::PARAM_HELP_MSG => 'apihelp-xml-param-xslt',
                        ),
index bbea20b..092e3e6 100644 (file)
@@ -533,6 +533,17 @@ class ApiHelp extends ApiBase {
                                                                        $type = null;
                                                                        break;
 
+                                                               case 'tags':
+                                                                       $tags = ChangeTags::listExplicitlyDefinedTags();
+                                                                       $count = count( $tags );
+                                                                       $info[] = $context->msg( 'api-help-param-list' )
+                                                                               ->params( $multi ? 2 : 1 )
+                                                                               ->params( $context->getLanguage()->commaList( $tags ) )
+                                                                               ->parse();
+                                                                       $hintPipeSeparated = false;
+                                                                       $type = null;
+                                                                       break;
+
                                                                case 'limit':
                                                                        if ( isset( $settings[ApiBase::PARAM_MAX2] ) ) {
                                                                                $info[] = $context->msg( 'api-help-param-limit2' )
@@ -690,9 +701,12 @@ class ApiHelp extends ApiBase {
                                        ) );
 
                                        $link = wfAppendQuery( wfScript( 'api' ), $qs );
+                                       $sandbox = SpecialPage::getTitleFor( 'ApiSandbox' )->getLocalURL() . '#' . $qs;
                                        $help['examples'] .= Html::rawElement( 'dt', null, $msg->parse() );
                                        $help['examples'] .= Html::rawElement( 'dd', null,
-                                               Html::element( 'a', array( 'href' => $link ), "api.php?$qs" )
+                                               Html::element( 'a', array( 'href' => $link ), "api.php?$qs" ) . ' ' .
+                                               Html::rawElement( 'a', array( 'href' => $sandbox ),
+                                                       $context->msg( 'api-help-open-in-apisandbox' )->parse() )
                                        );
                                }
                                $help['examples'] .= Html::closeElement( 'dl' );
index 860e3b2..03cd666 100644 (file)
@@ -84,12 +84,9 @@ class ApiLogin extends ApiBase {
 
                // Check login token
                $token = LoginForm::getLoginToken();
-               if ( !$token ) {
-                       LoginForm::setLoginToken();
+               if ( $token->wasNew() || !$params['token'] ) {
                        $authRes = LoginForm::NEED_TOKEN;
-               } elseif ( !$params['token'] ) {
-                       $authRes = LoginForm::NEED_TOKEN;
-               } elseif ( $token !== $params['token'] ) {
+               } elseif ( !$token->match( $params['token'] ) ) {
                        $authRes = LoginForm::WRONG_TOKEN;
                }
 
@@ -159,7 +156,10 @@ class ApiLogin extends ApiBase {
 
                        case LoginForm::NEED_TOKEN:
                                $result['result'] = 'NeedToken';
-                               $result['token'] = LoginForm::getLoginToken();
+                               $result['token'] = LoginForm::getLoginToken()->toString();
+                               $this->setWarning( 'Fetching a token via action=login is deprecated. ' .
+                                  'Use action=query&meta=tokens&type=login instead.' );
+                               $this->logFeatureUsage( 'action=login&!lgtoken' );
 
                                // @todo: See above about deprecation
                                $result['cookieprefix'] = $this->getConfig()->get( 'CookiePrefix' );
@@ -254,7 +254,11 @@ class ApiLogin extends ApiBase {
                                ApiBase::PARAM_TYPE => 'password',
                        ),
                        'domain' => null,
-                       'token' => null,
+                       'token' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => false, // for BC
+                               ApiBase::PARAM_HELP_MSG => array( 'api-help-param-token', 'login' ),
+                       ),
                );
        }
 
index 6ddc28a..458fd18 100644 (file)
@@ -1231,7 +1231,8 @@ class ApiMain extends ApiBase {
         * @param array $params An array with the request parameters
         */
        protected function setupExternalResponse( $module, $params ) {
-               if ( !$this->getRequest()->wasPosted() && $module->mustBePosted() ) {
+               $request = $this->getRequest();
+               if ( !$request->wasPosted() && $module->mustBePosted() ) {
                        // Module requires POST. GET request might still be allowed
                        // if $wgDebugApi is true, otherwise fail.
                        $this->dieUsageMsgOrDebug( array( 'mustbeposted', $this->mAction ) );
@@ -1243,6 +1244,15 @@ class ApiMain extends ApiBase {
                        // Create an appropriate printer
                        $this->mPrinter = $this->createPrinterByName( $params['format'] );
                }
+
+               if ( $request->getProtocol() === 'http' && (
+                       $request->getSession()->shouldForceHTTPS() ||
+                       ( $this->getUser()->isLoggedIn() &&
+                               $this->getUser()->requiresHTTPS() )
+               ) ) {
+                       $this->logFeatureUsage( 'https-expected' );
+                       $this->setWarning( 'HTTP used when HTTPS was expected' );
+               }
        }
 
        /**
index 5ce43cc..ff5707e 100644 (file)
@@ -123,9 +123,12 @@ class ApiOpenSearch extends ApiBase {
         * @param array &$results Put results here. Keys have to be integers.
         */
        protected function search( $search, $limit, $namespaces, $resolveRedir, &$results ) {
-               // Find matching titles as Title objects
-               $searcher = new TitlePrefixSearch;
-               $titles = $searcher->searchWithVariants( $search, $limit, $namespaces );
+
+               $searchEngine = SearchEngine::create();
+               $searchEngine->setLimitOffset( $limit );
+               $searchEngine->setNamespaces( $namespaces );
+               $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
+
                if ( !$titles ) {
                        return;
                }
index 18ca0ab..a8e5629 100644 (file)
@@ -338,6 +338,8 @@ class ApiParamInfo extends ApiBase {
                                        if ( isset( $settings[ApiBase::PARAM_SUBMODULE_PARAM_PREFIX] ) ) {
                                                $item['submoduleparamprefix'] = $settings[ApiBase::PARAM_SUBMODULE_PARAM_PREFIX];
                                        }
+                               } elseif ( $settings[ApiBase::PARAM_TYPE] === 'tags' ) {
+                                       $item['type'] = ChangeTags::listExplicitlyDefinedTags();
                                } else {
                                        $item['type'] = $settings[ApiBase::PARAM_TYPE];
                                }
index 286c18e..27690ff 100644 (file)
@@ -38,7 +38,14 @@ class ApiQueryInfo extends ApiQueryBase {
                $fld_notificationtimestamp = false,
                $fld_preload = false, $fld_displaytitle = false;
 
-       private $params, $titles, $missing, $everything;
+       private $params;
+
+       /** @var Title[] */
+       private $titles;
+       /** @var Title[] */
+       private $missing;
+       /** @var Title[] */
+       private $everything;
 
        private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched,
                $pageLatest, $pageLength;
index 25ff07c..1dac740 100644 (file)
@@ -45,8 +45,11 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                $namespaces = $params['namespace'];
                $offset = $params['offset'];
 
-               $searcher = new TitlePrefixSearch;
-               $titles = $searcher->searchWithVariants( $search, $limit + 1, $namespaces, $offset );
+               $searchEngine = SearchEngine::create();
+               $searchEngine->setLimitOffset( $limit + 1, $offset );
+               $searchEngine->setNamespaces( $namespaces );
+               $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
+
                if ( $resultPageSet ) {
                        $resultPageSet->setRedirectMergePolicy( function( array $current, array $new ) {
                                if ( !isset( $current['index'] ) || $new['index'] < $current['index'] ) {
index ca9ceca..196c1fa 100644 (file)
@@ -184,11 +184,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                        $data['git-hash'] = $git;
                        $data['git-branch'] =
                                SpecialVersion::getGitCurrentBranch( $GLOBALS['IP'] );
-               } else {
-                       $svn = SpecialVersion::getSvnRevision( $IP );
-                       if ( $svn ) {
-                               $data['rev'] = $svn;
-                       }
                }
 
                // 'case-insensitive' option is reserved for future
@@ -602,11 +597,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                }
                                if ( isset( $ext['version'] ) ) {
                                        $ret['version'] = $ext['version'];
-                               } elseif ( isset( $ext['svn-revision'] ) &&
-                                       preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
-                                               $ext['svn-revision'], $m )
-                               ) {
-                                       $ret['version'] = 'r' . $m[1];
                                }
                                if ( isset( $ext['path'] ) ) {
                                        $extensionPath = dirname( $ext['path'] );
@@ -620,13 +610,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                                if ( $vcsDate !== false ) {
                                                        $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
                                                }
-                                       } else {
-                                               $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
-                                               if ( $svnInfo !== false ) {
-                                                       $ret['vcs-system'] = 'svn';
-                                                       $ret['vcs-version'] = $svnInfo['checkout-rev'];
-                                                       $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
-                                               }
                                        }
 
                                        if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
index f887664..3f3464b 100644 (file)
@@ -44,16 +44,24 @@ class ApiQueryTokens extends ApiQueryBase {
                        return;
                }
 
+               $user = $this->getUser();
+               $session = $this->getRequest()->getSession();
                $salts = self::getTokenTypeSalts();
                foreach ( $params['type'] as $type ) {
-                       $salt = $salts[$type];
-                       $val = $this->getUser()->getEditToken( $salt, $this->getRequest() );
-                       $res[$type . 'token'] = $val;
+                       $res[$type . 'token'] = self::getToken( $user, $session, $salts[$type] )->toString();
                }
 
                $this->getResult()->addValue( 'query', $this->getModuleName(), $res );
        }
 
+       /**
+        * Get the salts for known token types
+        * @return (string|array)[] Returning a string will use that as the salt
+        *  for User::getEditTokenObject() to fetch the token, which will give a
+        *  LoggedOutEditToken (always "+\\") for anonymous users. Returning an
+        *  array will use it as parameters to MediaWiki\\Session\\Session::getToken(),
+        *  which will always return a full token even for anonymous users.
+        */
        public static function getTokenTypeSalts() {
                static $salts = null;
                if ( !$salts ) {
@@ -63,6 +71,8 @@ class ApiQueryTokens extends ApiQueryBase {
                                'patrol' => 'patrol',
                                'rollback' => 'rollback',
                                'userrights' => 'userrights',
+                               'login' => array( '', 'login' ),
+                               'createaccount' => array( '', 'createaccount' ),
                        );
                        Hooks::run( 'ApiQueryTokensRegisterTypes', array( &$salts ) );
                        ksort( $salts );
@@ -71,6 +81,27 @@ class ApiQueryTokens extends ApiQueryBase {
                return $salts;
        }
 
+       /**
+        * Get a token from a salt
+        * @param User $user
+        * @param MediaWiki\\Session\\Session $session
+        * @param string|array $salt A string will be used as the salt for
+        *  User::getEditTokenObject() to fetch the token, which will give a
+        *  LoggedOutEditToken (always "+\\") for anonymous users. An array will
+        *  be used as parameters to MediaWiki\\Session\\Session::getToken(), which
+        *  will always return a full token even for anonymous users. An array will
+        *  also persist the session.
+        * @return MediaWiki\\Session\\Token
+        */
+       public static function getToken( User $user, MediaWiki\Session\Session $session, $salt ) {
+               if ( is_array( $salt ) ) {
+                       $session->persist();
+                       return call_user_func_array( array( $session, 'getToken' ), $salt );
+               } else {
+                       return $user->getEditTokenObject( $salt, $session->getRequest() );
+               }
+       }
+
        public function getAllowedParams() {
                return array(
                        'type' => array(
@@ -90,6 +121,11 @@ class ApiQueryTokens extends ApiQueryBase {
                );
        }
 
+       public function isReadMode() {
+               // So login tokens can be fetched on private wikis
+               return false;
+       }
+
        public function getCacheMode( $params ) {
                return 'private';
        }
index 0fa2e31..055c7fe 100644 (file)
@@ -122,7 +122,7 @@ class ApiRollback extends ApiBase {
                                ApiBase::PARAM_TYPE => 'integer'
                        ),
                        'tags' => array(
-                               ApiBase::PARAM_TYPE => ChangeTags::listExplicitlyDefinedTags(),
+                               ApiBase::PARAM_TYPE => 'tags',
                                ApiBase::PARAM_ISMULTI => true,
                        ),
                        'user' => array(
index 8822750..00675f4 100644 (file)
@@ -141,6 +141,9 @@ class ApiStashEdit extends ApiBase {
                if ( $editInfo && $editInfo->output ) {
                        $key = self::getStashKey( $page->getTitle(), $content, $user );
 
+                       // Let extensions add ParserOutput metadata or warm other caches
+                       Hooks::run( 'ParserOutputStashForEdit', array( $page, $content, $editInfo->output ) );
+
                        list( $stashInfo, $ttl ) = self::buildStashValue(
                                $editInfo->pstContent, $editInfo->output, $editInfo->timestamp
                        );
@@ -148,6 +151,7 @@ class ApiStashEdit extends ApiBase {
                        if ( $stashInfo ) {
                                $ok = $cache->set( $key, $stashInfo, $ttl );
                                if ( $ok ) {
+
                                        $logger->debug( "Cached parser output for key '$key'." );
                                        return self::ERROR_NONE;
                                } else {
index 4bf799e..c1a6810 100644 (file)
  */
 class ApiTag extends ApiBase {
 
-       protected function getAvailableTags() {
-               return ChangeTags::listExplicitlyDefinedTags();
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
                $user = $this->getUser();
@@ -150,7 +146,7 @@ class ApiTag extends ApiBase {
                                ApiBase::PARAM_ISMULTI => true,
                        ),
                        'add' => array(
-                               ApiBase::PARAM_TYPE => $this->getAvailableTags(),
+                               ApiBase::PARAM_TYPE => 'tags',
                                ApiBase::PARAM_ISMULTI => true,
                        ),
                        'remove' => array(
index f92526d..c10c938 100644 (file)
@@ -81,7 +81,7 @@ class ApiTokens extends ApiBase {
                foreach ( ApiQueryTokens::getTokenTypeSalts() as $name => $salt ) {
                        if ( !isset( $types[$name] ) ) {
                                $types[$name] = function () use ( $salt, $user, $request ) {
-                                       return $user->getEditToken( $salt, $request );
+                                       return ApiQueryTokens::getToken( $user, $request->getSession(), $salt )->toString();
                                };
                        }
                }
index 1680544..47e8e22 100644 (file)
@@ -19,7 +19,7 @@
                        "Luke081515"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page/de|Dokumentation]]\n* [[mw:API:FAQ/de|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:API:Errors_and_warnings|API: Fehler und Warnungen]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentation]]\n* [[mw:API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n<strong>Testen:</strong> Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Auszuführende Aktion.",
        "apihelp-main-param-format": "Format der Ausgabe.",
        "apihelp-main-param-maxlag": "maxlag kann verwendet werden, wenn MediaWiki auf einem datenbankreplizierten Cluster installiert ist. Um weitere Replikationsrückstände zu verhindern, lässt dieser Parameter den Client warten, bis der Replikationsrückstand kleiner als der angegebene Wert (in Sekunden) ist. Bei einem größerem Rückstand wird der Fehlercode <samp>maxlag</samp> zurückgegeben mit einer Nachricht wie <samp>Waiting for $host: $lag seconds lagged</samp>.<br />Siehe [[mw:Manual:Maxlag_parameter|Handbuch: Maxlag parameter]] für weitere Informationen.",
        "apihelp-unblock-param-id": "ID der Sperre zum Entsperren (über <kbd>list=blocks</kbd> erhalten). Darf nicht zusammen mit <var>$1user</var> verwendet werden.",
        "apihelp-unblock-param-reason": "Grund für die Freigabe.",
        "apihelp-unblock-example-id": "Sperrkennung #<kbd>105</kbd> freigeben.",
+       "apihelp-undelete-param-title": "Titel der wiederherzustellenden Seite.",
        "apihelp-undelete-param-reason": "Grund für die Wiederherstellung.",
        "apihelp-upload-param-filename": "Ziel-Dateiname.",
        "apihelp-upload-param-text": "Erster Seitentext für neue Dateien.",
        "api-help-permissions": "{{PLURAL:$1|Berechtigung|Berechtigungen}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Gewährt an}}: $2",
        "api-help-right-apihighlimits": "Höhere Beschränkungen in API-Anfragen verwenden (langsame Anfragen: $1; schnelle Anfragen: $2). Die Beschränkungen für langsame Anfragen werden auch auf Mehrwertparameter angewandt.",
+       "api-help-open-in-apisandbox": "<small>[in Spielwiese öffnen]</small>",
        "api-credits-header": "Danksagungen",
        "api-credits": "API-Entwickler:\n* Roan Kattouw (Hauptentwickler von September 2007 bis 2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (Autor, Hauptentwickler von September 2006 bis September 2007)\n* Brad Jorsch (Hauptentwickler seit 2013)\n\nBitte sende deine Kommentare, Vorschläge und Fragen an mediawiki-api@lists.wikimedia.org\noder reiche einen Fehlerbericht auf https://phabricator.wikimedia.org/ ein."
 }
index 1af53fa..a1b303f 100644 (file)
@@ -6,7 +6,7 @@
                ]
        },
 
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> All features shown on this page should be working, but the API is still in active development, and may change at any time. Subscribe to [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] for notice of updates.\n\n<strong>Erroneous requests:</strong> When erroneous requests are sent to the API, an HTTP header will be sent with the key \"MediaWiki-API-Error\" and then both the value of the header and the error code sent back will be set to the same value. For more information see [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> All features shown on this page should be working, but the API is still in active development, and may change at any time. Subscribe to [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] for notice of updates.\n\n<strong>Erroneous requests:</strong> When erroneous requests are sent to the API, an HTTP header will be sent with the key \"MediaWiki-API-Error\" and then both the value of the header and the error code sent back will be set to the same value. For more information see [[mw:API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Testing:</strong> For ease of testing API requests, see [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Which action to perform.",
        "apihelp-main-param-format": "The format of the output.",
        "apihelp-main-param-maxlag": "Maximum lag can be used when MediaWiki is installed on a database replicated cluster. To save actions causing any more site replication lag, this parameter can make the client wait until the replication lag is less than the specified value. In case of excessive lag, error code <samp>maxlag</samp> is returned with a message like <samp>Waiting for $host: $lag seconds lagged</samp>.<br />See [[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]] for more information.",
        "apihelp-watch-example-generator": "Watch the first few pages in the main namespace.",
 
        "apihelp-format-example-generic": "Return the query result in the $1 format.",
+       "apihelp-format-param-wrappedhtml": "Return the pretty-printed HTML and associated ResourceLoader modules as a JSON object.",
        "apihelp-json-description": "Output data in JSON format.",
        "apihelp-json-param-callback": "If specified, wraps the output into a given function call. For safety, all user-specific data will be restricted.",
        "apihelp-json-param-utf8": "If specified, encodes most (but not all) non-ASCII characters as UTF-8 instead of replacing them with hexadecimal escape sequences. Default when <var>formatversion</var> is not <kbd>1</kbd>.",
        "api-help-permissions": "{{PLURAL:$1|Permission|Permissions}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Granted to}}: $2",
        "api-help-right-apihighlimits": "Use higher limits in API queries (slow queries: $1; fast queries: $2). The limits for slow queries also apply to multivalue parameters.",
+       "api-help-open-in-apisandbox": "<small>[open in sandbox]</small>",
 
        "api-credits-header": "Credits",
        "api-credits": "API developers:\n* Yuri Astrakhan (creator, lead developer Sep 2006–Sep 2007)\n* Roan Kattouw (lead developer Sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Brad Jorsch (lead developer 2013–present)\n\nPlease send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org\nor file a bug report at https://phabricator.wikimedia.org/."
index 253edc9..f517aad 100644 (file)
@@ -12,7 +12,8 @@
                        "Csbotero",
                        "Chris TR",
                        "Ncontinanza",
-                       "Poco a poco"
+                       "Poco a poco",
+                       "YoViajo"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|Preguntas frecuentes]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de correos]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API de anuncios]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Errores y peticiones]\n</div>\n<strong>Estado:</strong> Todas las características que se muestran en esta página debería funcionar, pero la API aún está en desarrollo activo y puede cambiar en cualquier momento. Suscríbete a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la lista de correo de mediawiki-api-announce] para estar al día de las actualizaciones.\n\n<strong>Solicitudes erróneas:</strong> Cuando se envían solicitudes erróneas a la API, se envía un encabezado HTTP con la clave \"MediaWiki-API-Error\" y ambos valores, del encabezado y el código de error, se establecerán en el mismo valor. Para más información, véase [[mw:API:Errors_and_warnings|API: Errores y advertencias]].",
        "apihelp-query+allrevisions-param-namespace": "Listar solo las páginas en este espacio de nombres.",
        "apihelp-query+allrevisions-example-user": "Listar las últimas 50 contribuciones del usuario <kbd>Example</kbd>.",
        "apihelp-query+allrevisions-example-ns-main": "Listar las primeras 50 revisiones en el espacio de nombres principal.",
+       "apihelp-query+mystashedfiles-param-limit": "Cuántos archivos a obtener.",
        "apihelp-query+alltransclusions-param-prefix": "Buscar todos los títulos transcluidos que comiencen con este valor.",
        "apihelp-query+alltransclusions-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+alltransclusions-example-unique": "Listar títulos transcluidos de forma única.",
index 7c54805..a0af3b2 100644 (file)
                        "Ash Crow",
                        "L",
                        "Umherirrender",
-                       "Elfix"
+                       "Elfix",
+                       "Lbayle"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong> Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un en-tête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet en-tête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong> Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un en-tête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet en-tête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Test :</strong> Pour faciliter le test des requêtes de l’API, voyez [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Quelle action effectuer.",
        "apihelp-main-param-format": "Le format de sortie.",
        "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MédiaWiki est installé sur un cluster de base de données répliqué. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur <samp>maxlag</samp> est renvoyé avec un message tel que <samp>Attente de $host : $lag secondes de délai</samp>.<br />Voyez [[mw:Manual:Maxlag_parameter|Manuel: Maxlag parameter]] pour plus d’information.",
        "apihelp-query+info-paramvalue-prop-talkid": "L’ID de la page de discussion de chaque page qui n’est pas de discussion.",
        "apihelp-query+info-paramvalue-prop-watched": "Lister l’état de suivi de chaque page.",
        "apihelp-query+info-paramvalue-prop-watchers": "Le nombre d’observateurs, si c’est autorisé.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "Le nombre de personnes suivant chaque page qui ont regardé les modifications récentes de cette page, si c’est autorisé.",
        "apihelp-query+info-paramvalue-prop-notificationtimestamp": "L’horodatage de notification de la liste de suivi de chaque page.",
        "apihelp-query+info-paramvalue-prop-subjectid": "L’ID de page de la page parent de chaque page de discussion.",
        "apihelp-query+info-paramvalue-prop-url": "Fournit une URL complète, une URL de modification, et l’URL canonique de chaque page.",
        "apihelp-watch-example-unwatch": "Ne plus suivre la page <kbd>Page principale</kbd>.",
        "apihelp-watch-example-generator": "Suivre les quelques premières pages de l’espace de nom principal",
        "apihelp-format-example-generic": "Renvoyer le résultat de la requête dans le format $1.",
+       "apihelp-format-param-wrappedhtml": "Renvoyer le HTML avec une jolie mise en forme et les modules ResourceLoader associés comme un objet JSON.",
        "apihelp-json-description": "Extraire les données au format JSON.",
        "apihelp-json-param-callback": "Si spécifié, inclut la sortie dans l’appel d’une fonction fournie. Pour plus de sûreté, toutes les données spécifiques à l’utilisateur seront restreintes.",
        "apihelp-json-param-utf8": "Si spécifié, encode la plupart (mais pas tous) des caractères non ASCII en URF-8 au lieu de les remplacer par leur séquence d’échappement hexadécimale. Valeur par défaut quand <var>formatversion</var> ne vaut pas <kbd>1</kbd>.",
        "api-help-permissions": "{{PLURAL:$1|Droit|Droits}} :",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Accordé à}} : $2",
        "api-help-right-apihighlimits": "Utiliser des valeurs plus hautes dans les requêtes de l’API (requêtes lentes : $1 ; requêtes rapides : $2). Les limites pour les requêtes lentes s’appliquent aussi aux paramètres multivalués.",
+       "api-help-open-in-apisandbox": "<small>[ouvrir dans le bac à sable]</small>",
        "api-credits-header": "Remerciements",
        "api-credits": "Développeurs de l’API :\n* Roan Kattouw (développeur en chef Sept. 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (créateur, développeur en chef Sept. 2006–Sept. 2007)\n* Brad Jorsch (développeur en chef depuis 2013)\n\nVeuillez envoyer vos commentaires, suggestions et questions à mediawiki-api@lists.wikimedia.org\nou remplir un rapport de bogue sur https://phabricator.wikimedia.org/."
 }
index 9e881d8..751471d 100644 (file)
@@ -13,7 +13,7 @@
                        "Macofe"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte [[mw:API:Errors_and_warnings|API: Erros e avisos]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte [[mw:API:Errors_and_warnings|API: Erros e avisos]].\n\n<strong>Test:</strong> Para facilitar as probas das peticións da API, consulte [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Que acción se realizará.",
        "apihelp-main-param-format": "O formato de saída.",
        "apihelp-main-param-maxlag": "O retardo máximo pode usarse cando MediaWiki está instalada nun cluster de base de datos replicadas. Para gardar accións que causen calquera retardo máis de replicación do sitio, este parámetro pode facer que o cliente espere ata que o retardo de replicación sexa menor que o valor especificado. No caso de retardo excesivo, é devolto o código de erro <samp>maxlag</samp> cunha mensaxe como <samp>esperando por $host: $lag segundos de retardo</samp>.<br />Para máis información, ver [[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]].",
        "apihelp-query+allrevisions-param-generatetitles": "Usado como xenerador, xenera títulos no canto de IDs de revisión.",
        "apihelp-query+allrevisions-example-user": "Listar as últimas 50 contribucións do usuario <kbd>Example</kbd>.",
        "apihelp-query+allrevisions-example-ns-main": "Listar as 50 primeiras revisións do espazo de nomes principal.",
+       "apihelp-query+mystashedfiles-description": "Obter unha lista dos ficheiros da caché de carga do usuario actual.",
        "apihelp-query+mystashedfiles-param-prop": "Que propiedades obter para os ficheiros.",
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "Consultar o tamaño de ficheiro e as dimensións da imaxe.",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "Consultar o tipo MIME do ficheiro e tipo multimedia.",
        "apihelp-query+mystashedfiles-param-limit": "Cantos ficheiros devolver.",
+       "apihelp-query+mystashedfiles-example-simple": "Obter a clave de ficheiro, tamaño de ficheiro, e tamaño en pixels dos ficheiros na caché de carga do usuario actual.",
        "apihelp-query+alltransclusions-description": "Listar todas as transclusións (páxinas integradas usando &#123;&#123;x&#125;&#125;), incluíndo as eliminadas.",
        "apihelp-query+alltransclusions-param-from": "Título da transclusión na que comezar a enumerar.",
        "apihelp-query+alltransclusions-param-to": "Título da transclusión na que rematar de enumerar.",
        "apihelp-query+info-paramvalue-prop-talkid": "O ID de páxina da páxina de conversa para cada páxina que non é páxina de conversa.",
        "apihelp-query+info-paramvalue-prop-watched": "Listar o estado de vixiancia de cada páxina.",
        "apihelp-query+info-paramvalue-prop-watchers": "O número de vixiantes, se está permitido.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "O nome dos usuarios que vixían cada páxina e que teñen visitado os cambios recentes a esta páxina, se está autorizado.",
        "apihelp-query+info-paramvalue-prop-notificationtimestamp": "O selo de tempo de notificación da lista de vixiancia de cada páxina.",
        "apihelp-query+info-paramvalue-prop-subjectid": "O ID de páxina da páxina pai para cada páxina de conversa.",
        "apihelp-query+info-paramvalue-prop-url": "Devolve unha URL completa, unha URL de modificación, e a URL canónica de cada páxina.",
        "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Concedida a|Concedidas a}}: $2",
        "api-help-right-apihighlimits": "Usar os valores superiores das consultas da API (consultas lentas: $1; consultas rápidas: $2). Os límites para as consultas lentas tamén se aplican ós parámetros multivaluados.",
+       "api-help-open-in-apisandbox": "<small>[abrir en zona de probas]</small>",
        "api-credits-header": "Créditos",
        "api-credits": "Desenvolvedores da API:\n* Roan Kattouw (desenvolvedor principal, set. 2007-2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (creador e desenvolvedor principal, set. 2006-sep. 2007)\n* Brad Jorsch (desenvolvedor principal, 2013-actualidade)\n\nEnvía comentarios, suxerencias e preguntas a mediawiki-api@lists.wikimedia.org\nou informa dun erro en https://phabricator.wikimedia.org/."
 }
index 7651551..4da0430 100644 (file)
@@ -13,7 +13,7 @@
                        "Macofe"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|תיעוד]]\n* [[mw:API:FAQ|שו\"ת]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api רשימת דיוור]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce הודעות על API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R באגים ובקשות]\n</div>\n<strong>מצב:</strong> כל האפשרויות שמוצגות בדף הזה אמורות לעבוד, אבל ה־API עדיין בפיתוח פעיל, ויכול להשתנות בכל זמן. עשו מינוי ל [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ רשימת הדיוור mediawiki-api-announce] להודעות על עדכונים.\n\n<strong>בקשות שגויות:</strong> כשבקשות שגויות נשלחות ל־API, תישלח כותרת HTTP עם המפתח \"MediaWiki-API-Error\" ואז גם הערך של הכותרת וגם קוד השגיאה יוגדרו לאותו ערך. למידע נוסף ר' [[mw:API:Errors_and_warnings|API: שגיאות ואזהרות]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|תיעוד]]\n* [[mw:API:FAQ|שו\"ת]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api רשימת דיוור]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce הודעות על API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R באגים ובקשות]\n</div>\n<strong>מצב:</strong> כל האפשרויות שמוצגות בדף הזה אמורות לעבוד, אבל ה־API עדיין בפיתוח פעיל, ויכול להשתנות בכל זמן. עשו מינוי ל [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ רשימת הדיוור mediawiki-api-announce] להודעות על עדכונים.\n\n<strong>בקשות שגויות:</strong> כשבקשות שגויות נשלחות ל־API, תישלח כותרת HTTP עם המפתח \"MediaWiki-API-Error\" ואז גם הערך של הכותרת וגם קוד השגיאה יוגדרו לאותו ערך. למידע נוסף ר' [[mw:API:Errors_and_warnings|API: שגיאות ואזהרות]].\n\n<strong>בדיקה:</strong> לבדיקה קלה יותר של בקשות ר' [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "איזו פעולה לבצע.",
        "apihelp-main-param-format": "תסדיר הפלט.",
        "apihelp-main-param-maxlag": "שיהוי מרבי יכול לשמש כשמדיה־ויקי מותקנת בצביר עם מסד נתונים משוכפל. כדי לחסוך בפעולות שגורמות יותר שיהוי בשכפול אתר, הפרמטר הזה יכול לגרום ללקוח להמתין עד ששיהוי השכפול יורד מתחת לערך שצוין. במקרה של שיהוי מוגזם, קוד השגיאה <samp>maxlag</samp> מוחזר עם הודעה כמו <samp>Waiting for $host: $lag seconds lagged</samp>.<br />ר' [[mw:Manual:Maxlag_parameter|מדריך למשתמש: פרמטר maxlag]] למידע נוסף.",
        "apihelp-query+info-paramvalue-prop-talkid": "מזהה הדף של דף השיחה עבור כל דף שאינו דף שיחה.",
        "apihelp-query+info-paramvalue-prop-watched": "לרשום את מצב המעקב של כל דף.",
        "apihelp-query+info-paramvalue-prop-watchers": "מספר העוקבים, אם קיבלת הרשאה.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "מספר העוקבים אחרי כל דף שביקרו עריכות אחרונות לאותו הדף, אם זה מותר.",
        "apihelp-query+info-paramvalue-prop-notificationtimestamp": "חותם־זמן של הודעת רשימת מעקב של כל דף.",
        "apihelp-query+info-paramvalue-prop-subjectid": "מזהה הדף של הדף העיקרי של כל דף שיחה.",
        "apihelp-query+info-paramvalue-prop-url": "נותן URL מלא, URL לעריכה ו־URL קנוני לכל דף.",
        "apihelp-watch-example-unwatch": "להפסיק את המעקב אחרי הדף <kbd>Main Page</kbd>.",
        "apihelp-watch-example-generator": "לעקוב אחרי הדפים הראשונים במרחב הראשי.",
        "apihelp-format-example-generic": "להחזיר את תוצאות השאילתה בתסדיר $1.",
+       "apihelp-format-param-wrappedhtml": "החזרת HTML מעוצב ומודולי ResourceLoader משויכים בתור עצם JSON.",
        "apihelp-json-description": "לפלוט נתונים בתסדיר JSON.",
        "apihelp-json-param-callback": "אם זה צוין, עוטף את הפלט לתוך קריאת פונקציה נתונה. למען הבטיחות, כל הנתונים הייחודיים למשתמש יוגבלו.",
        "apihelp-json-param-utf8": "אם זה צוין, רוב התווים שאינם ASCII (אבל לא כולם) יקודדו בתור UTF-8 במקום להתחלף בסדרות חילוף הקסדצימליות. זאת בררת המחדל אם הערך של <var>formatversion</var> הוא לא <kbd>1</kbd>.",
        "api-help-permissions": "{{PLURAL:$1|הרשאה|הרשאות}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|הוענק ל|הוענקו ל}}: $2",
        "api-help-right-apihighlimits": "להשתמש במגבלות גבוהות יותר בשאילתות API (שאילתות אטיות: $1; שאילתות מהירות: $2). המגבלות לשאילתות אטיות חלות גם על פרמטרים מרובי־ערכים.",
+       "api-help-open-in-apisandbox": "<small>[פתיחה בארגז חול]</small>",
        "api-credits-header": "קרדיטים",
        "api-credits": "מפתחי ה־API:\n* רואן קטאו (מפתח מוביל 2007–2009)\n* ויקטור וסילייב\n* בריאן טונג מין\n* סאם ריד\n* יורי אסטרחן (יוצר, מפתח מוביל מספטמבר 2006 עד ספטמבר 2007)\n* בראד יורש (מפתח מוביל מאז 2013)\n\nאנא שלחו הערות, הצעות ושאלות לכתובת mediawiki-api@lists.wikimedia.org או כתבו דיווח באג באתר https://phabricator.wikimedia.org."
 }
index 5730655..bca4a43 100644 (file)
@@ -14,7 +14,7 @@
                        "JackLantern"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentazione (in inglese)]]\n* [[mw:API:FAQ|FAQ (in inglese)]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> Tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma l'API è ancora in fase d'attivo sviluppo, e potrebbe cambiare in qualsiasi momenento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite all'API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e sia al valore dell'intestazione sia al codice d'errore verrà impostato lo stesso valore. Per maggiori informazioni leggi [[mw:API:Errors_and_warnings|API:Errori ed avvertimenti (in inglese)]].",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentazione (in inglese)]]\n* [[mw:API:FAQ|FAQ (in inglese)]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> Tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma l'API è ancora in fase d'attivo sviluppo, e potrebbe cambiare in qualsiasi momenento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite all'API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e sia al valore dell'intestazione sia al codice d'errore verrà impostato lo stesso valore. Per maggiori informazioni leggi [[mw:API:Errors_and_warnings|API:Errori ed avvertimenti (in inglese)]].\n\n<strong>Test:</strong> per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Azione da compiere.",
        "apihelp-main-param-format": "Formato dell'output.",
        "apihelp-main-param-assert": "Verifica che l'utente sia loggato se si è impostato <kbd>utente</kbd>, o che abbia i permessi di bot se si è impostato <kbd>bot</kbd>.",
        "apihelp-query+allrevisions-example-ns-main": "Elenca solo le prime 50 versioni nel namespace principale.",
        "apihelp-query+mystashedfiles-param-prop": "Quali proprietà recuperare per il file.",
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "Recupera la dimensione del file e le dimensioni dell'immagine.",
+       "apihelp-query+mystashedfiles-paramvalue-prop-type": "Recupera il tipo MIME del file e il tipo media.",
        "apihelp-query+mystashedfiles-param-limit": "Quanti file restituire.",
        "apihelp-query+alltransclusions-paramvalue-prop-title": "Aggiunge il titolo dell'inclusione.",
        "apihelp-query+alltransclusions-param-limit": "Quanti elementi totali restituire.",
        "apihelp-query+imageusage-description": "Trova tutte le pagine che utilizzano il titolo dell'immagine specificato.",
        "apihelp-query+imageusage-param-dir": "La direzione in cui elencare.",
        "apihelp-query+imageusage-param-redirect": "Se la pagina collegata è un redirect, trova tutte le pagine che puntano al redirect. Il limite massimo è dimezzato.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "Il numero di osservatori di ogni pagina che hanno visitato le ultime modifiche alla pagina, se consentito.",
        "apihelp-query+iwbacklinks-param-prop": "Quali proprietà ottenere:",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Aggiunge il titolo dell'interwiki.",
        "apihelp-query+iwbacklinks-param-dir": "La direzione in cui elencare.",
        "apihelp-userrights-param-user": "Nome utente.",
        "apihelp-userrights-param-userid": "ID utente.",
        "apihelp-watch-description": "Aggiunge o rimuove pagine dagli osservati speciali dell'utente attuale.",
+       "apihelp-format-param-wrappedhtml": "Restituisce l'HTML ben formattato e i moduli ResourceLoader associati come un oggetto JSON.",
        "api-pageset-param-titles": "Un elenco di titoli su cui lavorare.",
        "api-pageset-param-pageids": "Un elenco di ID pagina su cui lavorare.",
        "api-pageset-param-revids": "Un elenco di ID versioni su cui lavorare.",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(nessuna descrizione)</span>",
        "api-help-examples": "{{PLURAL:$1|Esempio|Esempi}}:",
        "api-help-permissions": "{{PLURAL:$1|Permesso|Permessi}}:",
+       "api-help-open-in-apisandbox": "<small>[apri in una sandbox]</small>",
        "api-credits-header": "Crediti"
 }
index 949f4aa..4e94d58 100644 (file)
@@ -11,7 +11,7 @@
                        "Macofe"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api メーリングリスト]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 告知]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R バグの報告とリクエスト]\n</div>\n<strong>状態:</strong> このページに表示されている機能は全て動作するはずですが、この API は未だ活発に開発されており、変更される可能性があります。アップデートの通知を受け取るには、[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce メーリングリスト]に参加してください。\n\n<strong>誤ったリクエスト:</strong> 誤ったリクエストが API に贈られた場合、\"MediaWiki-API-Error\" HTTP ヘッダーが送信され、そのヘッダーの値と送り返されるエラーコードは同じ値にセットされます。より詳しい情報は [[mw:API:Errors_and_warnings|API: Errors and warnings]] を参照してください。",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api メーリングリスト]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 告知]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R バグの報告とリクエスト]\n</div>\n<strong>状態:</strong> このページに表示されている機能は全て動作するはずですが、この API は未だ活発に開発されており、変更される可能性があります。アップデートの通知を受け取るには、[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce メーリングリスト]に参加してください。\n\n<strong>誤ったリクエスト:</strong> 誤ったリクエストが API に送られた場合、\"MediaWiki-API-Error\" HTTP ヘッダーが送信され、そのヘッダーの値と送り返されるエラーコードは同じ値にセットされます。より詳しい情報は [[mw:API:Errors_and_warnings|API: Errors and warnings]] を参照してください。\n\n<strong>テスト:</strong> API のリクエストのテストは、[[Special:ApiSandbox]]で簡単に行えます。",
        "apihelp-main-param-action": "実行する操作です。",
        "apihelp-main-param-format": "出力する形式です。",
        "apihelp-main-param-smaxage": "<code>s-maxage</code> HTTP キャッシュ コントロール ヘッダー に、この秒数を設定します。エラーがキャッシュされることはありません。",
        "api-help-examples": "{{PLURAL:$1|例}}:",
        "api-help-permissions": "{{PLURAL:$1|権限}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|権限を持つグループ}}: $2",
+       "api-help-open-in-apisandbox": "<small>[サンドボックスで開く]</small>",
        "api-credits-header": "クレジット",
        "api-credits": "API の開発者:\n* Roan Kattouw (2007年9月-2009年の主任開発者)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (作成者、2006年9月-2007年9月の主任開発者)\n* Brad Jorsch (2013年-現在の主任開発者)\n\nコメント、提案、質問は mediawiki-api@lists.wikimedia.org にお送りください。\nバグはこちらへご報告ください: https://phabricator.wikimedia.org/"
 }
index c6b08c1..f7468b4 100644 (file)
        "apihelp-query+info-paramvalue-prop-talkid": "De Kännong för de Klaafsigg för jehde Nit-Klaafsigg.",
        "apihelp-query+info-paramvalue-prop-watched": "Donn der Zohschtand vum Oppaße för jehde Sigg opleßte.",
        "apihelp-query+info-paramvalue-prop-watchers": "De Aanzahl Oppaßer, wann zohjelohße.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "De Aanzahl Oppaßer pro Sigg, di woh zohjelohße, de neußte Änderonge aan dä Sigg belohrt hann.",
        "apihelp-query+info-paramvalue-prop-subjectid": "De Kännong för de övverje'odente Sigg för jehde Klaafsigg.",
        "apihelp-query+info-paramvalue-prop-url": "Jidd en kumplätte <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i>, en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> för et Beärbeide, un en kannohnesche <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> för jehde Sigg uß.",
        "apihelp-query+info-paramvalue-prop-readable": "Ov dä Metmaacher heh di Sigg lässe kann.",
        "apihelp-upload-param-url": "Der <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i>, öm di Dattei dervun ze holle.",
        "apihelp-upload-param-sessionkey": "Et sälve wi „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1filekey</code>“, wat mer emmer noch noch bruche kann, weil mer et fröhjer alld ens esu hatte.",
        "apihelp-upload-param-filesize": "De Datteijrühße vum jannze Huhlahde.",
-       "apihelp-upload-param-asyncdownload": "Maach dat Holle vun ene <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> zoh ene andere Zigg.",
        "apihelp-upload-example-url": "Vun enem <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Uniform Ressource Locator\">URL</i> huhlahde.",
        "apihelp-upload-example-filekey": "Don et Huhlahde fähdesch maace, wat wähje Warnonge nit johd jejange wohr.",
        "apihelp-userrights-param-user": "Metmaacher_Nahme.",
index 89dcaaa..e7b4421 100644 (file)
@@ -31,6 +31,8 @@
        "apihelp-block-param-nocreate": "Voorkom registeren van accounts.",
        "apihelp-block-param-autoblock": "Blokkeer automatisch het laatst gebruikte IP-adres en ieder volgend IP-adres van waaruit ze proberen aan te melden.",
        "apihelp-block-param-reblock": "De huidige blokkade aanpassen als de gebruiker al geblokkeerd is.",
+       "apihelp-block-param-watchuser": "De gebruikerspagina en overlegpagina van de gebruiker of het IP-adres volgen.",
+       "apihelp-block-example-ip-simple": "Het IP-adres <kbd>192.0.2.5</kbd> voor drie dagen blokkeren met <kbd>First strike</kbd> als opgegeven reden.",
        "apihelp-compare-param-fromtitle": "Eerste titel om te vergelijken.",
        "apihelp-compare-param-fromid": "Eerste pagina-ID om te vergelijken.",
        "apihelp-compare-param-fromrev": "Eerste versie om te vergelijken.",
index 4d4614c..e3354aa 100644 (file)
        "apihelp-watch-example-unwatch": "{{doc-apihelp-example|watch}}",
        "apihelp-watch-example-generator": "{{doc-apihelp-example|watch}}",
        "apihelp-format-example-generic": "{{doc-apihelp-example|format|params=* $1 - Format name|paramstart=2|noseealso=1}}",
+       "apihelp-format-param-wrappedhtml": "{{doc-apihelp-param|format|wrappedhtml|description=the \"wrappedhtml\" parameter in pretty-printing format modules}}",
        "apihelp-json-description": "{{doc-apihelp-description|json|seealso=* {{msg-mw|apihelp-jsonfm-description}}}}",
        "apihelp-json-param-callback": "{{doc-apihelp-param|json|callback}}",
        "apihelp-json-param-utf8": "{{doc-apihelp-param|json|utf8}}",
        "api-help-permissions": "Label for the \"permissions\" section in the main module's help output.\n\nParameters:\n* $1 - Number of permissions displayed\n{{Identical|Permission}}",
        "api-help-permissions-granted-to": "Used to introduce the list of groups each permission is assigned to.\n\nParameters:\n* $1 - Number of groups\n* $2 - List of group names, comma-separated",
        "api-help-right-apihighlimits": "{{technical}}{{doc-right|apihighlimits|prefix=api-help}}\nThis message is used instead of {{msg-mw|right-apihighlimits}} in the API help to display the actual limits.\n\nParameters:\n* $1 - Limit for slow queries\n* $2 - Limit for fast queries",
+       "api-help-open-in-apisandbox": "Text for the link to open an API example in [[Special:ApiSandbox]].",
        "api-credits-header": "Header for the API credits section in the API help output\n{{Identical|Credit}}",
        "api-credits": "API credits text, displayed in the API help output"
 }
index 55611f0..f6d1b62 100644 (file)
@@ -7,5 +7,6 @@
        "apihelp-block-description": "Blokiraj korisnika.",
        "apihelp-block-param-reason": "Razlog za blokiranje.",
        "apihelp-delete-description": "Obriši stranicu.",
-       "apihelp-edit-param-minor": "Manja izmena."
+       "apihelp-edit-param-minor": "Manja izmena.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Sakrij patrolirane izmene."
 }
index a10452d..f611160 100644 (file)
@@ -6,11 +6,13 @@
                        "Uğurkent",
                        "Gorizon",
                        "HakanIST",
-                       "Imabadplayer"
+                       "Imabadplayer",
+                       "İnternion"
                ]
        },
        "apihelp-block-description": "Bir kullanıcıyı engelle.",
        "apihelp-block-param-reason": "Engelleme sebebi.",
+       "apihelp-createaccount-description": "Yeni bir kullanıcı hesabı oluşturun.",
        "apihelp-createaccount-param-name": "Kullanıcı adı.",
        "apihelp-createaccount-param-password": "Parola (ignored if <var>$1mailpassword</var> is set).",
        "apihelp-createaccount-param-email": "Kullanıcının e-posta adresi (isteğe bağlı).",
index 6b36dd8..a2b2f73 100644 (file)
@@ -20,7 +20,7 @@
                        "Hzy980512"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文档]]\n* [[mw:API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:API:Errors_and_warnings|API: 错误与警告]]。",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文档]]\n* [[mw:API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:API:Errors_and_warnings|API: 错误与警告]]。\n\n<strong>测试中:</strong>测试API请求的易用性,请参见[[Special:ApiSandbox]]。",
        "apihelp-main-param-action": "要执行的操作。",
        "apihelp-main-param-format": "输出的格式。",
        "apihelp-main-param-maxlag": "最大延迟可被用于MediaWiki安装于数据库复制集中。要保存导致更多网站复制延迟的操作,此参数可使客户端等待直到复制延迟少于指定值时。万一发生过多延迟,错误代码<samp>maxlag</samp>会返回消息,例如<samp>等待$host中:延迟$lag秒</samp>。<br />参见[[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]]以获取更多信息。",
        "apihelp-query+allrevisions-example-ns-main": "列举主名字空间中的前50次修订。",
        "apihelp-query+mystashedfiles-description": "获取当前用户的上传藏匿中的文件列表。",
        "apihelp-query+mystashedfiles-param-prop": "要检索文件的属性。",
+       "apihelp-query+mystashedfiles-paramvalue-prop-size": "检索文件大小和图片尺寸。",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "检索文件的MIME类型和媒体类型。",
        "apihelp-query+mystashedfiles-param-limit": "获取多少文件。",
        "apihelp-query+alltransclusions-description": "列出所有嵌入页面(使用&#123;&#123;x&#125;&#125;嵌入的页面),包括不存在的。",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "添加用于非最新版本的存档版本的文件名。",
        "apihelp-query+filearchive-example-simple": "显示已删除文件列表。",
        "apihelp-query+filerepoinfo-description": "返回有关wiki配置的图片存储库的元信息。",
-       "apihelp-query+filerepoinfo-param-prop": "要获取的存储库属性(这在一些wiki上可能有更多可用选项):\n;apiurl:链接至API的URL - 对从主机获取图片信息有用。\n;name:The key of the repository - used in e.g. <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.\n;displayname:The human-readable name of the repository wiki.\n;rooturl:Root URL for image paths.\n;local:Whether that repository is the local one or not.",
+       "apihelp-query+filerepoinfo-param-prop": "要获取的存储库属性(这在一些wiki上可能有更多可用选项):\n;apiurl:链接至API的URL - 对从主机获取图片信息有用。\n;name:存储库关键词 - 用于例如<var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var>,并且[[Special:ApiHelp/query+imageinfo|imageinfo]]会返回值。\n;displayname:人类可读的存储库wiki名称。\n;rooturl:图片路径的根URL。\n;local:存储库是否在本地。",
        "apihelp-query+filerepoinfo-example-simple": "获得有关文件存储库的信息。",
        "apihelp-query+fileusage-description": "查找所有使用指定文件的页面。",
        "apihelp-query+fileusage-param-prop": "要获取的属性:",
        "apihelp-query+info-paramvalue-prop-talkid": "每个非讨论页面的讨论页的页面ID。",
        "apihelp-query+info-paramvalue-prop-watched": "列出每个页面的被监视状态。",
        "apihelp-query+info-paramvalue-prop-watchers": "监视人员数,如果允许。",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "访问了每个页面的最近编辑的监视者数量,如果允许。",
        "apihelp-query+info-paramvalue-prop-notificationtimestamp": "每个页面的监视列表通知时间戳。",
        "apihelp-query+info-paramvalue-prop-subjectid": "每个讨论页的母页面的页面ID。",
        "apihelp-query+info-paramvalue-prop-url": "为每个页面提供一个完整URL、一个编辑URL和规范URL。",
        "apihelp-query+pageswithprop-param-dir": "排序的方向。",
        "apihelp-query+pageswithprop-example-simple": "列出前10个使用<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>的页面。",
        "apihelp-query+pageswithprop-example-generator": "获取有关前10个使用<code>_&#95;NOTOC_&#95;</code>的页面的额外信息。",
+       "apihelp-query+prefixsearch-description": "为页面标题执行前缀搜索。\n\nDespite the similarity in names, this module is not intended to be equivalent to [[Special:PrefixIndex]]; for that, see <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> with the <kbd>apprefix</kbd> parameter. The purpose of this module is similar to <kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd>: to take user input and provide the best-matching titles. Depending on the search engine backend, this might include typo correction, redirect avoidance, or other heuristics.",
        "apihelp-query+prefixsearch-param-search": "搜索字符串。",
        "apihelp-query+prefixsearch-param-namespace": "搜索的名字空间。",
        "apihelp-query+prefixsearch-param-limit": "要返回的结果最大数。",
        "apihelp-query+protectedtitles-paramvalue-prop-level": "添加保护级别。",
        "apihelp-query+protectedtitles-example-simple": "受保护标题列表。",
        "apihelp-query+protectedtitles-example-generator": "找到主命名空间中已保护的标题的链接。",
+       "apihelp-query+querypage-description": "获取由基于QueryPage的特殊页面提供的列表。",
+       "apihelp-query+querypage-param-page": "特殊页面的名称。注意其区分大小写。",
        "apihelp-query+querypage-param-limit": "返回的结果数。",
        "apihelp-query+querypage-example-ancientpages": "返回[[Special:Ancientpages]]的结果。",
        "apihelp-query+random-description": "获取一组随机页面。\n\n页面列举在一个固定序列中,只有起始点是随机的。这意味着如果<samp>Main Page</samp>是列表中第一个随机页面的话,<samp>List of fictional monkeys</samp>将<em>总是</em>第二个,<samp>List of people on stamps of Vanuatu</samp>是第三个等。",
        "apihelp-query+recentchanges-param-excludeuser": "不要列出此用户的更改。",
        "apihelp-query+recentchanges-param-tag": "只列出带此标签的更改。",
        "apihelp-query+recentchanges-param-prop": "包含的额外信息束:",
-       "apihelp-query+recentchanges-paramvalue-prop-user": "Adds the user responsible for the edit and tags if they are an IP.",
+       "apihelp-query+recentchanges-paramvalue-prop-user": "为编辑和标签添加用户责任,如果它们是IP的话。",
        "apihelp-query+recentchanges-paramvalue-prop-userid": "为编辑添加用户ID责任。",
        "apihelp-query+recentchanges-paramvalue-prop-comment": "为编辑添加摘要。",
-       "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Adds the parsed comment for the edit.",
+       "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "为编辑添加解析的摘要。",
        "apihelp-query+recentchanges-paramvalue-prop-flags": "为编辑添加标记。",
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "添加编辑的时间戳。",
        "apihelp-query+recentchanges-paramvalue-prop-title": "添加编辑的页面标题。",
        "apihelp-query+recentchanges-paramvalue-prop-ids": "添加页面ID、最近更改ID和新旧修订的ID。",
-       "apihelp-query+recentchanges-paramvalue-prop-sizes": "Adds the new and old page length in bytes.",
+       "apihelp-query+recentchanges-paramvalue-prop-sizes": "添加新旧页面长度(字节)。",
        "apihelp-query+recentchanges-paramvalue-prop-redirect": "如果页面是重定向的话,标记编辑。",
        "apihelp-query+recentchanges-paramvalue-prop-patrolled": "Tags patrollable edits as being patrolled or unpatrolled.",
        "apihelp-query+recentchanges-paramvalue-prop-loginfo": "Adds log information (log ID, log type, etc) to log entries.",
        "apihelp-query+redirects-param-show": "只显示符合这些标准的项目:\n;fragment:只显示带碎片的重定向。\n;!fragment:只显示不带碎片的重定向。",
        "apihelp-query+redirects-example-simple": "获取至[[Main Page]]的重定向列表。",
        "apihelp-query+redirects-example-generator": "获取所有重定向至[[Main Page]]的信息。",
+       "apihelp-query+revisions-description": "获取修订版本信息。\n\n可用于以下几个方面:\n# Get data about a set of pages (last revision), by setting titles or pageids.\n# Get revisions for one given page, by using titles or pageids with start, end, or limit.\n# Get data about a set of revisions by setting their IDs with revids.",
        "apihelp-query+revisions-paraminfo-singlepageonly": "可能只能与单一页面使用(模式#2)。",
        "apihelp-query+revisions-param-startid": "从哪个修订版本ID开始列举。",
        "apihelp-query+revisions-param-endid": "在此修订版本ID停止修订列举。",
        "apihelp-query+revisions-param-user": "只包含由用户做出的修订。",
        "apihelp-query+revisions-param-excludeuser": "不包括由用户做出的修订。",
        "apihelp-query+revisions-param-tag": "只列出被此标签标记的修订。",
+       "apihelp-query+revisions-param-token": "要为每个修订版本获得的令牌。",
        "apihelp-query+revisions-example-content": "获取带内容的数据,用于标题<kbd>API</kbd>和<kbd>Main Page</kbd>的最近修订。",
        "apihelp-query+revisions-example-last5": "获取<kbd>Main Page</kbd>的最近5次修订。",
        "apihelp-query+revisions-example-first5": "获取<kbd>Main Page</kbd>的前5次修订。",
        "apihelp-query+search-param-info": "要返回的元数据。",
        "apihelp-query+search-param-prop": "要返回的属性:",
        "apihelp-query+search-paramvalue-prop-size": "添加页面大小,单位为字节。",
-       "apihelp-query+search-paramvalue-prop-wordcount": "Adds the word count of the page.",
-       "apihelp-query+search-paramvalue-prop-timestamp": "Adds the timestamp of when the page was last edited.",
+       "apihelp-query+search-paramvalue-prop-wordcount": "添加页面的字数。",
+       "apihelp-query+search-paramvalue-prop-timestamp": "添加页面上次编辑时的时间戳。",
        "apihelp-query+search-paramvalue-prop-snippet": "Adds a parsed snippet of the page.",
        "apihelp-query+search-paramvalue-prop-titlesnippet": "Adds a parsed snippet of the page title.",
        "apihelp-query+search-paramvalue-prop-redirectsnippet": "Adds a parsed snippet of the redirect title.",
        "apihelp-query+search-paramvalue-prop-sectiontitle": "Adds the title of the matching section.",
        "apihelp-query+search-paramvalue-prop-categorysnippet": "Adds a parsed snippet of the matching category.",
        "apihelp-query+search-paramvalue-prop-isfilematch": "Adds a boolean indicating if the search matched file content.",
-       "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">Deprecated and ignored.</span>",
+       "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">已弃用并已忽略。</span>",
        "apihelp-query+search-paramvalue-prop-hasrelated": "<span class=\"apihelp-deprecated\">Deprecated and ignored.</span>",
        "apihelp-query+search-param-limit": "返回的总计页面数。",
        "apihelp-query+search-param-interwiki": "搜索结果中包含跨wiki结果,如果可用。",
        "apihelp-query+search-param-backend": "要使用的搜索后端,如果没有则为默认。",
+       "apihelp-query+search-param-enablerewrites": "启用内部查询重写。一些搜索后端可以重写查询到它认为会给出更好结果的地方,例如纠正拼写错误。",
        "apihelp-query+search-example-simple": "搜索<kbd>meaning</kbd>。",
        "apihelp-query+search-example-text": "搜索文本<kbd>meaning</kbd>。",
        "apihelp-query+search-example-generator": "获得有关搜索<kbd>meaning</kbd>返回页面的页面信息。",
        "apihelp-query+stashimageinfo-param-filekey": "用于识别一次临时藏匿的早前上传的关键字。",
        "apihelp-query+stashimageinfo-param-sessionkey": "$1filekey的别名,用于向后兼容。",
        "apihelp-query+stashimageinfo-example-simple": "返回藏匿文件的信息。",
+       "apihelp-query+stashimageinfo-example-params": "返回两个藏匿文件的缩略图。",
        "apihelp-query+tags-description": "列出更改标签。",
        "apihelp-query+tags-param-limit": "列出标签的最大数量。",
        "apihelp-query+tags-param-prop": "要获取哪个属性:",
        "apihelp-query+userinfo-paramvalue-prop-blockinfo": "如果当前用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。",
        "apihelp-query+userinfo-paramvalue-prop-hasmsg": "如果当前用户有等待中的消息的话,添加标签<samp>messages</samp>。",
        "apihelp-query+userinfo-paramvalue-prop-groups": "列举当前用户隶属的所有群组。",
-       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "Lists all the groups the current user is automatically a member of.",
-       "apihelp-query+userinfo-paramvalue-prop-rights": "Lists all the rights the current user has.",
+       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "列举当前用户的所有自动成为成员的用户组。",
+       "apihelp-query+userinfo-paramvalue-prop-rights": "列举当前用户拥有的所有权限。",
        "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Lists the groups the current user can add to and remove from.",
        "apihelp-query+userinfo-paramvalue-prop-options": "Lists all preferences the current user has set.",
        "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "<span class=\"apihelp-deprecated\">已弃用。</span>获取令牌以更改当前用户的参数设置。",
        "apihelp-query+users-paramvalue-prop-blockinfo": "如果用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。",
        "apihelp-query+users-paramvalue-prop-groups": "列举每位用户属于的所有组。",
        "apihelp-query+users-paramvalue-prop-implicitgroups": "Lists all the groups a user is automatically a member of.",
-       "apihelp-query+users-paramvalue-prop-rights": "Lists all the rights each user has.",
+       "apihelp-query+users-paramvalue-prop-rights": "列举每位用户拥有的所有权限。",
        "apihelp-query+users-paramvalue-prop-editcount": "添加用户的编辑计数。",
        "apihelp-query+users-paramvalue-prop-registration": "添加用户的注册时间戳。",
        "apihelp-query+users-paramvalue-prop-emailable": "Tags if the user can and wants to receive email through [[Special:Emailuser]].",
-       "apihelp-query+users-paramvalue-prop-gender": "Tags the gender of the user. Returns \"male\", \"female\", or \"unknown\".",
+       "apihelp-query+users-paramvalue-prop-gender": "标记用户性别。返回“male”、“female”或“unknown”。",
        "apihelp-query+users-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+users-param-attachedwiki": "与<kbd>$1prop=centralids</kbd>一起使用,表明用户是否附加于此ID定义的wiki。",
        "apihelp-query+users-param-users": "要获取信息的用户列表。",
        "api-help-permissions": "{{PLURAL:$1|权限}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|授予}}:$2",
        "api-help-right-apihighlimits": "在API查询中使用更高的上限(慢查询:$1;快查询:$2)。慢查询的限制也适用于多值参数。",
+       "api-help-open-in-apisandbox": "<small>[在沙盒中打开]</small>",
        "api-credits-header": "制作人员",
        "api-credits": "API 开发人员:\n* Yuri Astrakhan(创建者,2006年9月~2007年9月的开发组领导)\n* Roan Kattouw(2007年9月~2009年的开发组领导)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Brad Jorsch(2013年至今的开发组领导)\n\n请将您的评论、建议和问题发送至mediawiki-api@lists.wikimedia.org,或提交错误请求至https://phabricator.wikimedia.org/。"
 }
index 24df574..2fae4e3 100644 (file)
@@ -168,7 +168,18 @@ class MessageCache {
         * @return ParserOptions
         */
        function getParserOptions() {
+               global $wgUser;
+
                if ( !$this->mParserOptions ) {
+                       if ( !$wgUser->isSafeToLoad() ) {
+                               // $wgUser isn't unstubbable yet, so don't try to get a
+                               // ParserOptions for it. And don't cache this ParserOptions
+                               // either.
+                               $po = ParserOptions::newFromAnon();
+                               $po->setEditSection( false );
+                               return $po;
+                       }
+
                        $this->mParserOptions = new ParserOptions;
                        $this->mParserOptions->setEditSection( false );
                }
index 3b868a1..8056b4d 100644 (file)
@@ -510,10 +510,11 @@ class RequestContext implements IContextSource, MutableContext {
         * @since 1.21
         */
        public function exportSession() {
+               $session = MediaWiki\Session\SessionManager::getGlobalSession();
                return array(
                        'ip' => $this->getRequest()->getIP(),
                        'headers' => $this->getRequest()->getAllHeaders(),
-                       'sessionId' => MediaWiki\Session\SessionManager::getGlobalSession()->getId(),
+                       'sessionId' => $session->isPersistent() ? $session->getId() : '',
                        'userId' => $this->getUser()->getId()
                );
        }
@@ -594,7 +595,6 @@ class RequestContext implements IContextSource, MutableContext {
                        $wgUser = $context->getUser(); // b/c
                        if ( $session && MediaWiki\Session\PHPSessionHandler::isEnabled() ) {
                                session_id( $session->getId() );
-                               MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
                                MediaWiki\quietCall( 'session_start' );
                        }
                        $request = new FauxRequest( array(), false, $session );
index f09de4f..264ee11 100644 (file)
@@ -505,6 +505,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function getScopedLockAndFlush( $lockKey, $fname, $timeout ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function namedLocksEnqueue() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
index 1835958..a4d0ad0 100644 (file)
@@ -155,6 +155,9 @@ abstract class DatabaseBase implements IDatabase {
         */
        private $mTrxWriteDuration = 0.0;
 
+       /** @var array Map of (name => 1) for locks obtained via lock() */
+       private $mNamedLocksHeld = array();
+
        /** @var IDatabase|null Lazy handle to the master DB this server replicates from */
        private $lazyMasterHandle;
 
@@ -871,7 +874,7 @@ abstract class DatabaseBase implements IDatabase {
                                $msg = __METHOD__ . ": lost connection to $server; reconnected";
                                wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
 
-                               if ( $hadTrx ) {
+                               if ( $hadTrx || $this->mNamedLocksHeld ) {
                                        # Leave $ret as false and let an error be reported.
                                        # Callers may catch the exception and continue to use the DB.
                                        $this->reportQueryError( $lastError, $lastErrno, $sql, $fname, $tempIgnore );
@@ -3160,13 +3163,33 @@ abstract class DatabaseBase implements IDatabase {
        }
 
        public function lock( $lockName, $method, $timeout = 5 ) {
+               $this->mNamedLocksHeld[$lockName] = 1;
+
                return true;
        }
 
        public function unlock( $lockName, $method ) {
+               unset( $this->mNamedLocksHeld[$lockName] );
+
                return true;
        }
 
+       public function getScopedLockAndFlush( $lockKey, $fname, $timeout ) {
+               if ( !$this->lock( $lockKey, $fname, $timeout ) ) {
+                       return null;
+               }
+
+               $that = $this;
+               $unlocker = new ScopedCallback( function () use ( $that, $lockKey, $fname ) {
+                       $that->commit( __METHOD__, 'flush' );
+                       $that->unlock( $lockKey, $fname );
+               } );
+
+               $this->commit( __METHOD__, 'flush' );
+
+               return $unlocker;
+       }
+
        public function namedLocksEnqueue() {
                return false;
        }
index 3a8f737..29106ab 100644 (file)
@@ -932,12 +932,13 @@ abstract class DatabaseMysqlBase extends Database {
                $row = $this->fetchObject( $result );
 
                if ( $row->lockstatus == 1 ) {
+                       parent::lock( $lockName, $method, $timeout ); // record
                        return true;
-               } else {
-                       wfDebug( __METHOD__ . " failed to acquire lock\n" );
-
-                       return false;
                }
+
+               wfDebug( __METHOD__ . " failed to acquire lock\n" );
+
+               return false;
        }
 
        /**
@@ -952,7 +953,14 @@ abstract class DatabaseMysqlBase extends Database {
                $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method );
                $row = $this->fetchObject( $result );
 
-               return ( $row->lockstatus == 1 );
+               if ( $row->lockstatus == 1 ) {
+                       parent::unlock( $lockName, $method ); // record
+                       return true;
+               }
+
+               wfDebug( __METHOD__ . " failed to release lock\n" );
+
+               return false;
        }
 
        private function makeLockName( $lockName ) {
index 4d9891e..e84f264 100644 (file)
@@ -1581,11 +1581,13 @@ SQL;
                                "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
                        $row = $this->fetchObject( $result );
                        if ( $row->lockstatus === 't' ) {
+                               parent::lock( $lockName, $method, $timeout ); // record
                                return true;
                        } else {
                                sleep( 1 );
                        }
                }
+
                wfDebug( __METHOD__ . " failed to acquire lock\n" );
 
                return false;
@@ -1603,7 +1605,14 @@ SQL;
                $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
                $row = $this->fetchObject( $result );
 
-               return ( $row->lockstatus === 't' );
+               if ( $row->lockstatus === 't' ) {
+                       parent::unlock( $lockName, $method ); // record
+                       return true;
+               }
+
+               wfDebug( __METHOD__ . " failed to release lock\n" );
+
+               return false;
        }
 
        /**
index cecb643..1e728d8 100644 (file)
@@ -1493,8 +1493,8 @@ interface IDatabase {
         * Named locks are not related to transactions
         *
         * @param string $lockName Name of lock to aquire
-        * @param string $method Name of method calling us
-        * @param int $timeout
+        * @param string $method Name of the calling method
+        * @param int $timeout Acquisition timeout in seconds
         * @return bool
         */
        public function lock( $lockName, $method, $timeout = 5 );
@@ -1505,7 +1505,7 @@ interface IDatabase {
         * Named locks are not related to transactions
         *
         * @param string $lockName Name of lock to release
-        * @param string $method Name of method calling us
+        * @param string $method Name of the calling method
         *
         * @return int Returns 1 if the lock was released, 0 if the lock was not established
         * by this thread (in which case the lock is not released), and NULL if the named
@@ -1513,6 +1513,25 @@ interface IDatabase {
         */
        public function unlock( $lockName, $method );
 
+       /**
+        * Acquire a named lock, flush any transaction, and return an RAII style unlocker object
+        *
+        * This is suitiable for transactions that need to be serialized using cooperative locks,
+        * where each transaction can see each others' changes. Any transaction is flushed to clear
+        * out stale REPEATABLE-READ snapshot data. Once the returned object falls out of PHP scope,
+        * any transaction will be committed and the lock will be released.
+        *
+        * If the lock acquisition failed, then no transaction flush happens, and null is returned.
+        *
+        * @param string $lockKey Name of lock to release
+        * @param string $fname Name of the calling method
+        * @param int $timeout Acquisition timeout in seconds
+        * @return ScopedCallback|null
+        * @throws DBUnexpectedError
+        * @since 1.27
+        */
+       public function getScopedLockAndFlush( $lockKey, $fname, $timeout );
+
        /**
         * Check to see if a named lock used by lock() use blocking queues
         *
index 25fdea9..606f4f4 100644 (file)
@@ -228,9 +228,24 @@ abstract class LBFactory {
        /**
         * Commit changes on all master connections
         * @param string $fname Caller name
+        * @param array $options Options map:
+        *   - maxWriteDuration: abort if more than this much time was spent in write queries
         */
-       public function commitMasterChanges( $fname = __METHOD__ ) {
+       public function commitMasterChanges( $fname = __METHOD__, array $options = array() ) {
+               $limit = isset( $options['maxWriteDuration'] ) ? $options['maxWriteDuration'] : 0;
+
                $this->logMultiDbTransaction();
+               $this->forEachLB( function ( LoadBalancer $lb ) use ( $limit ) {
+                       $lb->forEachOpenConnection( function ( IDatabase $db ) use ( $limit ) {
+                               $time = $db->pendingWriteQueryDuration();
+                               if ( $limit > 0 && $time > $limit ) {
+                                       throw new DBTransactionError(
+                                               $db,
+                                               wfMessage( 'transaction-duration-limit-exceeded', $time, $limit )->text()
+                                       );
+                               }
+                       } );
+               } );
 
                $start = microtime( true );
                $this->forEachLBCallMethod( 'commitMasterChanges', array( $fname ) );
index b5a79a9..32999f5 100644 (file)
@@ -1363,10 +1363,10 @@ class LoadBalancer {
         * function instead of Database::getLag() avoids a fatal error in this
         * case on many installations.
         *
-        * @param DatabaseBase $conn
-        * @return int
+        * @param IDatabase $conn
+        * @return int|bool Returns false on error
         */
-       public function safeGetLag( $conn ) {
+       public function safeGetLag( IDatabase $conn ) {
                if ( $this->getServerCount() == 1 ) {
                        return 0;
                } else {
@@ -1374,6 +1374,41 @@ class LoadBalancer {
                }
        }
 
+       /**
+        * Wait for a slave DB to reach a specified master position
+        *
+        * This will connect to the master to get an accurate position if $pos is not given
+        *
+        * @param IDatabase $conn Slave DB
+        * @param DBMasterPos|bool $pos Master position; default: current position
+        * @param integer $timeout Timeout in seconds
+        * @return bool Success
+        * @since 1.27
+        */
+       public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
+               if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'slave' ) ) {
+                       return true; // server is not a slave DB
+               }
+
+               $pos = $pos ?: $this->getConnection( DB_MASTER )->getMasterPos();
+               if ( !$pos ) {
+                       return false; // something is misconfigured
+               }
+
+               $result = $conn->masterPosWait( $pos, $timeout );
+               if ( $result == -1 || is_null( $result ) ) {
+                       $msg = __METHOD__ . ": Timed out waiting on {$conn->getServer()} pos {$pos}";
+                       wfDebugLog( 'replication', "$msg\n" );
+                       wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
+                       $ok = false;
+               } else {
+                       wfDebugLog( 'replication', __METHOD__ . ": Done\n" );
+                       $ok = true;
+               }
+
+               return $ok;
+       }
+
        /**
         * Clear the cache for slag lag delay times
         *
index fc24e82..eb1a0d0 100644 (file)
@@ -85,7 +85,7 @@ class AvroFormatter implements FormatterInterface {
                $this->io->truncate();
                $schema = $this->getSchema( $record['channel'] );
                $revId = $this->getSchemaRevisionId( $record['channel'] );
-               if ( $schema === null ) {
+               if ( $schema === null || $revId === null ) {
                        trigger_error( "The schema for channel '{$record['channel']}' is not available" );
                        return null;
                }
@@ -97,11 +97,7 @@ class AvroFormatter implements FormatterInterface {
                        trigger_error( "Avro failed to serialize record for {$record['channel']} : {$json}" );
                        return null;
                }
-               if ( $revId !== null ) {
-                       return chr( self::MAGIC ) . $this->encode_long( $revId ) . $this->io->string();
-               }
-               // @todo: remove backward compat code and do not send messages without rev id.
-               return $this->io->string();
+               return chr( self::MAGIC ) . $this->encodeLong( $revId ) . $this->io->string();
        }
 
        /**
@@ -132,27 +128,23 @@ class AvroFormatter implements FormatterInterface {
                if ( !isset( $this->schemas[$channel] ) ) {
                        return null;
                }
-               $schemaDetails = &$this->schemas[$channel];
-               $schema = null;
-               if ( isset( $schemaDetails['revision'] ) && isset( $schemaDetails['schema'] ) ) {
-                       $schema = &$schemaDetails['schema'];
-               } else {
-                       // @todo: Remove backward compat code
-                       $schema = &$schemaDetails;
+               if ( !isset( $this->schemas[$channel]['revision'], $this->schemas[$channel]['schema'] ) ) {
+                       return null;
                }
 
-               if ( !$schema instanceof AvroSchema ) {
+               if ( !$this->schemas[$channel]['schema'] instanceof AvroSchema ) {
+                       $schema = $this->schemas[$channel]['schema'];
                        if ( is_string( $schema ) ) {
-                               $schema = AvroSchema::parse( $schema );
+                               $this->schemas[$channel]['schema'] = AvroSchema::parse( $schema );
                        } else {
-                               $schema = AvroSchema::real_parse(
-                                       $this->schemas[$channel],
+                               $this->schemas[$channel]['schema'] = AvroSchema::real_parse(
+                                       $schema,
                                        null,
                                        new AvroNamedSchemata()
                                );
                        }
                }
-               return $schema;
+               return $this->schemas[$channel]['schema'];
        }
 
        /**
@@ -162,10 +154,7 @@ class AvroFormatter implements FormatterInterface {
         * @return int|null
         */
        public function getSchemaRevisionId( $channel ) {
-               // @todo: remove backward compat code
-               if ( isset( $this->schemas[$channel] )
-                               && is_array( $this->schemas[$channel] )
-                               && isset( $this->schemas[$channel]['revision'] ) ) {
+               if ( isset( $this->schemas[$channel]['revision'] ) ) {
                        return (int) $this->schemas[$channel]['revision'];
                }
                return null;
@@ -177,7 +166,7 @@ class AvroFormatter implements FormatterInterface {
         * @param int $id
         * @return string the binary representation of $id
         */
-       private function encode_long( $id ) {
+       private function encodeLong( $id ) {
                $high   = ( $id & 0xffffffff00000000 ) >> 32;
                $low    = $id & 0x00000000ffffffff;
                return pack( 'NN', $high, $low );
index 4e8e65b..2465918 100644 (file)
@@ -99,9 +99,25 @@ class KafkaHandler extends AbstractProcessingHandler {
        ) {
                $metadata = new MetaDataFromKafka( $kafkaServers );
                $produce = new Produce( $metadata );
+
+               if ( isset( $options['sendTimeout'] ) ) {
+                       $timeOut = $options['sendTimeout'];
+                       $produce->getClient()->setStreamOption( 'SendTimeoutSec', 0 );
+                       $produce->getClient()->setStreamOption( 'SendTimeoutUSec',
+                               intval( $timeOut * 1000000 )
+                       );
+               }
+               if ( isset( $options['recvTimeout'] ) ) {
+                       $timeOut = $options['recvTimeout'];
+                       $produce->getClient()->setStreamOption( 'RecvTimeoutSec', 0 );
+                       $produce->getClient()->setStreamOption( 'RecvTimeoutUSec',
+                               intval( $timeOut * 1000000 )
+                       );
+               }
                if ( isset( $options['logExceptions'] ) && is_string( $options['logExceptions'] ) ) {
                        $options['logExceptions'] = LoggerFactory::getInstance( $options['logExceptions'] );
                }
+
                return new self( $produce, $options, $level, $bubble );
        }
 
index a52f636..9a357ee 100644 (file)
@@ -21,7 +21,7 @@
 namespace MediaWiki\Logger\Monolog;
 
 /**
- * Injects `wfHostname()` and `wfWikiID()` in all records.
+ * Injects `wfHostname()`, `wfWikiID()` and `$wgVersion` in all records.
  *
  * @since 1.25
  * @author Bryan Davis <bd808@wikimedia.org>
@@ -34,11 +34,13 @@ class WikiProcessor {
         * @return array
         */
        public function __invoke( array $record ) {
+               global $wgVersion;
                $record['extra'] = array_merge(
                        $record['extra'],
                        array(
                                'host' => wfHostname(),
                                'wiki' => wfWikiID(),
+                               'mwversion' => $wgVersion,
                        )
                );
                return $record;
index a8d37a1..d7241e9 100644 (file)
@@ -50,7 +50,6 @@ class ForeignAPIRepo extends FileRepo {
         */
        protected static $imageInfoProps = array(
                'url',
-               'thumbnail',
                'timestamp',
        );
 
index 9617c0a..8816d37 100644 (file)
@@ -44,4 +44,13 @@ class HTMLUserTextField extends HTMLTextField {
 
                return new UserInputWidget( $params );
        }
+
+       public function getInputHtml( $value ) {
+               // add the required module and css class for user suggestions in non-OOUI mode
+               $this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' );
+               $this->mClass .= ' mw-autocomplete-user';
+
+               // return parent html
+               return parent::getInputHtml( $value );
+       }
 }
index 904fde8..61c3002 100644 (file)
@@ -456,7 +456,7 @@ abstract class DatabaseUpdater {
                        flush();
                        if ( $ret !== false ) {
                                $updatesDone[] = $origParams;
-                               wfWaitForSlaves();
+                               wfGetLBFactory()->waitForReplication();
                        } else {
                                $updatesSkipped[] = array( $func, $params, $origParams );
                        }
index b742074..3b6a37f 100644 (file)
@@ -391,7 +391,7 @@ ${serverSetting}
 ## be publically accessible from the web.
 #\$wgCacheDirectory = \"\$IP/cache\";
 
-# Site language code, should be one of the list in ./languages/Names.php
+# Site language code, should be one of the list in ./languages/data/Names.php
 \$wgLanguageCode = \"{$this->values['wgLanguageCode']}\";
 
 \$wgSecretKey = \"{$this->values['wgSecretKey']}\";
index 4813bea..10fed31 100644 (file)
@@ -836,7 +836,7 @@ class MysqlUpdater extends DatabaseUpdater {
                        foreach ( $res as $row ) {
                                $count = ( $count + 1 ) % 100;
                                if ( $count == 0 ) {
-                                       wfWaitForSlaves();
+                                       wfGetLBFactory()->waitForReplication( array( 'wiki' => wfWikiID() ) );
                                }
                                $this->db->insert( 'templatelinks',
                                        array(
index 2fadfce..838c953 100644 (file)
@@ -16,7 +16,7 @@
        "config-localsettings-upgrade": "<code>LocalSettings.php</code> قد تم كشف ملف.\nلترقية هذا التنصيب، رجاء أدخل قيمة <code>$wgUpgradeKey</code> في الصندوق أدناه.\nستجده في <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "<code>LocalSettings.php</code> قد تم كشف ملف.\nلترقية هذا التنصيب، رجاء قم بتفعيل <code>update.php</code> عوضًا عن ذلك",
        "config-localsettings-key": "مفتاح ترقية:",
-       "config-localsettings-badkey": "المفتاح الذي قدمته غير صحيح.",
+       "config-localsettings-badkey": "مفتاح الترقية الذي قدمته غير صحيح.",
        "config-upgrade-key-missing": "تنصيب موجود للميدياويكي قد تم اكتشافه.\nلترقية هذا التنصيب، الرجاء وضع السطر أسفل <code>LocalSettings.php</code> الخاصة بك:\n\n$1",
        "config-localsettings-incomplete": "صفحة <code>LocalSettings.php</code> يبدو أنها ناقصة.\nالمتغير $1 لم يتم تعيينه.\nالرجاء تغيير <code>LocalSettings.php</code> لكي يتم تعيين المتغير، ثم اضغط على \"{{int:Config-continue}}\".",
        "config-localsettings-connection-error": "تمت مصادفة خطأ أثناء الاتصال بقاعدة البيانات باستخدام الإعدادات المحددة في <code>LocalSettings.php</code> أو <code>AdminSettings.php</code>. الرجاء إصلاح هذه الإعدادات وحاول مجددًا.\n\n$1",
        "config-license-pd": "ملكية عامة",
        "config-license-cc-choose": "اختر ترخيص مشاع إبداعي مخصص",
        "config-email-settings": "إعدادات البريد الإلكتروني",
+       "config-email-user": "تفعيل البريد الإلكتروني من المستخدم إلى مستخدم آخر",
+       "config-email-user-help": "يتيح لكل المستخدمين إرسال رسائل بريد إلكتروني إلى بعضهم البعض إذا فعَّلوا هذا الخيار في تفضيلاتهم.",
        "config-email-usertalk": "فعل إخطارات صفحات نقاش المستخدمين",
        "config-email-watchlist": "تمكين إشعارات قائمة المراقبة",
        "config-email-sender": "يرجع عنوان البريد الإلكتروني:",
        "config-install-tables": "إنشاء الجداول",
        "config-install-stats": "بدء الإحصاءات",
        "config-install-keys": "توليد المفاتيح السرية",
+       "config-install-sysop": "إنشاء حساب مستخدم إداري",
        "config-install-mainpage": "إنشاء صفحة رئيسية بالمحتوى الافتراضي",
        "config-help": "مساعدة",
        "config-help-tooltip": "اضغط للتوسيع",
index fc99677..ee69d6a 100644 (file)
@@ -20,7 +20,7 @@
        "config-localsettings-upgrade": "یک پرونده <code>LocalSettings.php</code> شناسایی شده‌است.\nبرای ارتقاء این نصب لطفاً مقدار <code>$wgUpgradeKey</code> در جعبه زیر وارد کنید.\nشما می‌توانید آن را در <code>LocalSettings.php</code> پیدا کنید.",
        "config-localsettings-cli-upgrade": "یک پرونده <code>LocalSettings.php</code> شناسایی شده است.\nبرای ارتقاء این نصب، لطفاً <code>update.php</code> را اجرا کنید.",
        "config-localsettings-key": "کلید ارتقا:",
-       "config-localsettings-badkey": "کلیدی که شما ارائه کردید نادرست است.",
+       "config-localsettings-badkey": "کلید به‌روزرسانی‌ای که شما ارائه کردید نادرست است.",
        "config-upgrade-key-missing": "نصب موجود مدیاویکی شناسایی شده‌است.\nبرای بروزرسانی این نصب، لطفاً خط زیر را در آخر کد \nقرار دادن به نصب ارتقاء داده شده، به خط زیر لطفاً در پایین خود را <code>LocalSettings.php</code> قرار دهید:\n\n$1",
        "config-localsettings-incomplete": "وجود <code>LocalSettings.php</code> به نظر ناقص می‌رسد.\nمتغیر $1 تنظیم نشده‌است.\nبرای اینکه این متغیر تنظیم شود لطفاً <code>LocalSettings.php</code> را تغییر دهید، و \"{{int:Config-continue}}\" را کلیک کنید.",
        "config-localsettings-connection-error": "هنگام اتصال به پایگاه اطلاعاتی که ازتنظیمات مشخص شده در<code>LocalSettings.php</code> استفاده می‌کند، خطایی رخ داد. لطفاً این تنظیمات را نصب کنید و دوباره تلاش کنید.\n$1",
index 17b5658..f524b32 100644 (file)
@@ -1,9 +1,38 @@
 {
        "@metadata": {
                "authors": [
-                       "Snævar"
+                       "Snævar",
+                       "Sveinn í Felli"
                ]
        },
+       "config-information": "Upplýsingar",
+       "config-your-language": "Tungumálið þitt:",
+       "config-your-language-help": "Veldu tungumál að nota við uppsetninguna.",
+       "config-back": "← Til baka",
+       "config-continue": "Halda áfram →",
+       "config-page-language": "Tungumál",
+       "config-page-welcome": "Velkomin í MediaWiki!",
+       "config-page-dbconnect": "Tengjast gagnagrunni",
+       "config-page-name": "Heiti",
+       "config-page-options": "Valkostir",
+       "config-page-install": "Setja upp",
+       "config-page-complete": "Lokið!",
+       "config-page-restart": "Byrja uppsetningu aftur",
+       "config-page-readme": "Lesa meira",
+       "config-page-releasenotes": "Athugasemdir með útgáfu",
+       "config-page-copying": "Afritun",
+       "config-page-upgradedoc": "Uppfærsla",
+       "config-env-php": "PHP $1 er uppsett.",
+       "config-env-hhvm": "HHVM $1 er uppsett.",
+       "config-mysql-utf8": "UTF-8",
+       "config-ns-generic": "Verkefni",
+       "config-admin-name": "Notandanafnið þitt:",
+       "config-admin-password": "Lykilorð:",
+       "config-admin-password-confirm": "Lykilorðið aftur:",
+       "config-admin-email": "Tölvupóstfang:",
+       "config-license-pd": "Almenningseign",
+       "config-install-step-done": "lokið",
+       "config-install-step-failed": "mistókst",
        "mainpagetext": "'''Uppsetning á MediaWiki heppnaðist.'''",
        "mainpagedocfooter": "Ráðfærðu þig við [//meta.wikimedia.org/wiki/Help:Contents Notandahandbókina] fyrir frekari upplýsingar um notkun wiki-hugbúnaðarins.\n\n== Fyrir byrjendur ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Listi yfir uppsetningarstillingar]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki Algengar spurningar MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Póstlisti MediaWiki-útgáfa]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Læra hvernig á að berjast við amapóst á þínum wiki]"
 }
index e468b00..8c0ade9 100644 (file)
@@ -15,7 +15,8 @@
                        "Shield-9",
                        "Takot",
                        "Sujiniku",
-                       "Macofe"
+                       "Macofe",
+                       "2nd-player"
                ]
        },
        "config-desc": "MediaWiki のインストーラー",
        "config-instantcommons-help": "[//www.mediawiki.org/wiki/InstantCommons Instant Commons] は、[//commons.wikimedia.org/ ウィキメディア・コモンズ]のサイトにある画像、音声、その他のメディアをウィキ上で利用できるようにする機能です。\nこれを使用するには、MediaWiki がインターネットに接続できる必要があります。\n\nウィキメディア・コモンズ以外のウィキを同様に設定する手順など、この機能に関する詳細な情報は、[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos マニュアル]をご覧ください。",
        "config-cc-error": "クリエイティブ・コモンズ・ライセンスの選択器から結果が得られませんでした。\nライセンスの名前を手動で入力してください。",
        "config-cc-again": "もう一度選択してください...",
-       "config-cc-not-chosen": "希望するクリエイティブ・コモンズのライセンスを選択して、「続行」をクリックしてください。",
+       "config-cc-not-chosen": "希望するクリエイティブ・コモンズのライセンスを選択して、「proceed」をクリックしてください。",
        "config-advanced-settings": "高度な設定",
        "config-cache-options": "オブジェクトのキャッシュの設定:",
        "config-cache-help": "オブジェクトのキャッシュを使用すると、頻繁に使用するデータをキャッシュするため MediaWiki の動作速度を改善できます。\n中〜大規模サイトではこれを有効にすることを強くお勧めします。小規模サイトでも同様に効果があります。",
index bf7df55..fbbeb66 100644 (file)
@@ -12,7 +12,7 @@
        "config-localsettings-upgrade": "'''Opgepasst''': E Fichier <code>LocalSettings.php</code> gouf fonnt.\nÄr Software kann aktualiséiert ginn, setzt w.e.g. de Wäert vum <code>$wgUpgradeKey</code> an d'Këscht.\nDir fannt en am <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "E Fichier <code>LocalSettings.php</code> gouf fonnt.\nFir dës Installatioun z'aktuaéliséieren start w.e.g. <code>update.php</code>",
        "config-localsettings-key": "Aktualisatiounsschlëssel:",
-       "config-localsettings-badkey": "De Schlëssel deen Dir aginn hutt ass net korrekt",
+       "config-localsettings-badkey": "Den Aktualisatiouns-Schlëssel deen Dir aginn hutt ass net korrekt",
        "config-localsettings-incomplete": "De Fichier <code>LocalSettings.php</code> schéngt net komplett ze sinn.\nD'Variabel $1 ass net definéiert.\nÄnnert w.e.g. de Fichier <code>LocalSettings.php</code> sou datt déi Variabel definéiert ass a klickt op \"{{int:Config-continue}}\".",
        "config-session-error": "Feeler beim Starte vun der Sessioun: $1",
        "config-no-session": "D'Donnéeë vun ärer Sessioun si verluergaangen!\nKuckt Är php.ini no a vergewëssert Iech datt <code>session.save_path</code>  op adequate REpertoire agestallt ass.",
index 6a607b6..3377afb 100644 (file)
@@ -12,7 +12,7 @@
        "config-localsettings-upgrade": "Востановена е податотека <code>LocalSettings.php</code>.\nЗа да ја надградите инсталцијава, внесете ја вредноста на <code>$wgUpgradeKey</code> во полето подолу.\nТоа е го најдете во <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "Утврдено е присуството на податотеката „<code>LocalSettings.php</code>“.\nЗа да ја надградите воспоставката, пуштете ја „<code>update.php</code>“ наместо горенаведената.",
        "config-localsettings-key": "Надградбен клуч:",
-       "config-localsettings-badkey": "Ð\9aлÑ\83Ñ\87оÑ\82 Ñ\88Ñ\82о Ð³Ð¾ Ð½Ð°Ð²ÐµÐ´Ð¾Ð²Ñ\82е Ðµ Ð¿Ð¾Ð³Ñ\80еÑ\88ен",
+       "config-localsettings-badkey": "Ð\9dадгÑ\80адбениоÑ\82 ÐºÐ»Ñ\83Ñ\87 Ñ\88Ñ\82о Ð³Ð¾ Ð½Ð°Ð²ÐµÐ´Ð¾Ð²Ñ\82е Ðµ Ð¿Ð¾Ð³Ñ\80еÑ\88ен.",
        "config-upgrade-key-missing": "Востановена е постоечка воспоставка на МедијаВики.\nЗа да ја надградите, вметнете го следниов ред на дното од вашата страница <code>LocalSettings.php</code>:\n\n$1",
        "config-localsettings-incomplete": "Постоечката страница <code>LocalSettings.php</code> е нецелосна.\nНе е поставена променливата $1.\nИзменете ја страницата <code>LocalSettings.php</code> така што ќе ѝ зададете вредност на променливата, па стиснете на „{{int:Config-continue}}“.",
        "config-localsettings-connection-error": "Се појави грешка при поврзувањето со базата користејќи ги поставките назначени во <code>LocalSettings.php</code>. Исправете ги овие поставки и обидете се повторно.\n\n$1",
index 71c6c17..bbecf18 100644 (file)
        "config-page-copying": "Nagkokopya",
        "config-restart": "Oo, utroha patikanga",
        "config-welcome": "=== Mga pagpanginano panlibong ===\nMagkakamay-ada yano nga panginano para masabtan kun ini nga libong in naaangay para hiton pagtataod hiton MediaWiki. Hinumdomi iton paglakip hinin nga impormasyon kun karuyag mo mangaro hin suporta kun paunan-on humanon an pagtataod.",
+       "config-env-php": "Gin-install an PHP $1.",
+       "config-env-hhvm": "Gin-install an HHVM $1.",
+       "config-unicode-using-intl": "Gamita an [http://pecl.php.net/intl intl PECL extension] para han normalisasyon han Unicode.",
+       "config-unicode-pure-php-warning": "<strong>Pahimatngon:</strong> An [http://pecl.php.net/intl intl PECL extension] in waray akos kumapot hin Unicode normalization, tungod hini mabalik ha mahinay nga puro-PHP nga implementasyon.\nKun nagpapadalagan ka hin high-traffic site, alayon pagbasa hin guti han [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
        "config-no-db": "Diri nakakabiling hin naaangay nga database driver! Kinahanglan mo magtaod hin uska database driver para han PHP. An masunod nga mga klase hin database in ginsusuporatahan: $1.\n\nKun ikaw mismo an nag-compile han PHP, kinahanglan ma-reconfigure iton nga para maapandar an database client, pananglitan, han paggamit han <code>./configure --with-mysqli</code>.\nKun gintaod mo an PHP tikang ha uska Debian o Ubuntu nga pakete, kinahanglan nimo magtaod liwat, pananglitan, hiton an <code>php5-mysql</code> nga pakete.",
        "config-pcre-old": "<strong>Nangangarat-an:</strong> Nagkikinahanglan hin PCRE $1 o mas urhi pa.\nAn imo PHP nga binaryo in nakasumpay hin PCRE $2. [https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE More information].",
        "config-db-name": "Ngaran han database:",
index dcfd69a..b57bc78 100644 (file)
        "config-unicode-pure-php-warning": "<strong>警告:</strong>因为尚未安装 [http://pecl.php.net/intl intl PECL 扩展]以处理 Unicode 正常化,故只能退而采用运行较慢的纯 PHP 实现的方法。\n如果您运行着一个高流量的网站,请参阅 [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode标准化]一文。",
        "config-unicode-update-warning": "'''警告''':Unicode正常化封装器的已安装版本使用了旧版本的[http://site.icu-project.org/ ICU项目]库。如果您需要使用Unicode,请将其[//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 升级]。",
        "config-no-db": "无法找到合适的数据库驱动!您需要为PHP安装数据库驱动。目前支持以下数据库{{PLURAL:$2|类型}}:$1。\n\n如果您自己编译了PHP,请通过启用数据库客户端重新配置它,例如使用 <code>./configure --with-mysqli</code>。如果您从 Debian 或 Ubuntu 安装包安装了PHP,那么您也需要安装,例如 <code>php5-mysql</code> 安装包。",
-       "config-outdated-sqlite": "'''警告''':您已安装SQLite $1,但是它的版本低于最低要求版本$2。因此您无法选择SQLite。",
-       "config-no-fts3": "'''警告''':已编译的SQLite不包含[//sqlite.org/fts3.html FTS3模块],后台搜索功能将不可用。",
+       "config-outdated-sqlite": "<strong>警告:</strong>您已安装SQLite $1,但是它的版本低于最低要求版本$2。因此您无法选择SQLite。",
+       "config-no-fts3": "<strong>警告:</strong>已编译的SQLite不包含[//sqlite.org/fts3.html FTS3模块],后台搜索功能将不可用。",
        "config-register-globals-error": "<strong>错误:PHP<code>[http://php.net/register_globals register_globals]</code>选项被启用。必须禁用它才能继续安装。</strong>关于如何禁用,参见[https://www.mediawiki.org/wiki/register_globals mediawiki.org此页]。",
        "config-magic-quotes-gpc": "<strong>致命错误:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc]已启用!</strong>此选项会无法挽回的破坏输入数据。除非此选项被禁用否则您不能安装或使用MediaWiki。",
-       "config-magic-quotes-runtime": "'''毁灭性错误:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime]已启用!'''\n此选项会无法预测地破坏输入的数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
-       "config-magic-quotes-sybase": "'''毁灭性错误:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_sybase]已启用!'''\n此选项会无法预测地破坏输入的数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
-       "config-mbstring": "'''毁灭性错误:[http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload]已启用!'''\n此选项会导致错误并不可预测地破坏数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
-       "config-safe-mode": "'''警告:'''PHP的[http://www.php.net/features.safe-mode 安全模式]已启用。它可能会导致一些问题,尤其在对文件上传和数学公式<code>math</code>的支持方面。",
+       "config-magic-quotes-runtime": "<strong>致命错误:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime]已启用!</strong>\n此选项会无法预测地破坏输入的数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
+       "config-magic-quotes-sybase": "<strong>致命错误:[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase]已启用!</strong>\n此选项会无法预测地破坏输入的数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
+       "config-mbstring": "<strong>致命错误:[http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload]已启用!</strong>\n此选项会导致错误并不可预测地破坏数据,请将其禁用,否则您将不能安装或使用MediaWiki。",
+       "config-safe-mode": "<strong>警告:</strong>PHP的[http://www.php.net/features.safe-mode 安全模式]已启用。\n它可能会导致一些问题,尤其在对文件上传和数学公式<code>math</code>的支持方面。",
        "config-xml-bad": "缺少PHP的XML模块。MediaWiki需要使用该模块提供的函数,在当前配置下将无法工作。您可能需要安装php-xml RPM包。",
-       "config-pcre-old": "'' 致命错误: ''需要PCRE $1 或更高版本。\n您的 PHP 二进制文件与 PCRE $2 链接。\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 详细信息]。",
-       "config-pcre-no-utf8": "'''毁灭性错误''':PHP的PCRE模块在编译时可能没有包含PCRE_UTF8支持。MediaWiki需要UTF-8支持才能正常工作。",
+       "config-pcre-old": "<strong>致命错误:</strong>需要PCRE $1 或更高版本。\n您的 PHP 二进制文件与 PCRE $2 链接。\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 详细信息]。",
+       "config-pcre-no-utf8": "<strong>致命错误:</strong>PHP的PCRE模块在编译时可能没有包含PCRE_UTF8支持。\nMediaWiki需要UTF-8支持才能正常工作。",
        "config-memory-raised": "PHP的内存使用上限<code>memory_limit</code>为$1,自动提升到$2。",
-       "config-memory-bad": "'''警告:'''PHP的内存使用上限<code>memory_limit</code>为$1。该设定可能过低,并导致安装失败!",
-       "config-ctype": "'''毁灭性错误''':PHP必须有[http://www.php.net/manual/en/ctype.installation.php Ctype 扩展]来支持编译。",
+       "config-memory-bad": "<strong>警告:</strong>PHP的内存使用上限<code>memory_limit</code>为$1。\n该设定可能过低,并导致安装失败!",
+       "config-ctype": "<strong>致命错误:</strong>PHP必须有[http://www.php.net/manual/en/ctype.installation.php Ctype 扩展]来支持编译。",
        "config-iconv": "<strong>致命错误:</strong>PHP必须编译支持[http://www.php.net/manual/en/iconv.installation.php iconv拓展]。",
-       "config-json": "'''致命问题:''' PHP编译没有附带JSON支持。\n在安装MediaWiki前,你必须安装PHP JSON扩展或者[http://pecl.php.net/package/jsonc PECL jsonc]扩展。\n* PHP扩展已包含在Red Hat Enterprise Linux (CentOS) 5和6中,但必须在<code>/etc/php.ini</code>或<code>/etc/php.d/json.ini</code>中启用。\n* 部分在2013年5月后发行的Linux发行版省略了PHP扩展,而将PECL扩展打包成了<code>php5-json</code>或<code>php-pecl-jsonc</code>。",
+       "config-json": "<strong>致命错误:</strong>PHP编译没有附带JSON支持。\n在安装MediaWiki前,你必须安装PHP JSON扩展或者[http://pecl.php.net/package/jsonc PECL jsonc]扩展。\n* PHP扩展已包含在Red Hat Enterprise Linux (CentOS) 5和6中,但必须在<code>/etc/php.ini</code>或<code>/etc/php.d/json.ini</code>中启用。\n* 部分在2013年5月后发行的Linux发行版省略了PHP扩展,而将PECL扩展打包成了<code>php5-json</code>或<code>php-pecl-jsonc</code>。",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache]已安装",
        "config-apc": "[http://www.php.net/apc APC]已安装",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache]已安装",
-       "config-no-cache": "'''警告:'''找不到[http://www.php.net/apc APC]、[http://xcache.lighttpd.net/ XCache]或[http://www.iis.net/download/WinCacheForPhp WinCache],无法启用对象缓存。\nObject caching is not enabled.",
+       "config-no-cache": "<strong>警告:</strong>找不到[http://www.php.net/apc APC]、[http://xcache.lighttpd.net/ XCache]或[http://www.iis.net/download/WinCacheForPhp WinCache]。\n对象缓冲未启用。",
        "config-no-cache-apcu": "<strong>警告:</strong>找不到[http://www.php.net/apcu APCu]、[http://xcache.lighttpd.net/ XCache]或[http://www.iis.net/download/WinCacheForPhp WinCache]。\n对象缓存未启用。",
-       "config-mod-security": "'''警告''':您的服务器已启动[http://modsecurity.org/ mod_security]。若其配置错误, 会导致MediaWiki和其他软件的错误并允许用户任意发布内容。如果您遇到任何错误,请查阅[http://modsecurity.org/documentation/ mod_security文档]或联系您的客服。",
+       "config-mod-security": "<strong>警告:</strong>您的web服务器已启用[http://modsecurity.org/ mod_security]/mod_security2。它的很多常见配置可能导致MediaWiki及其他软件允许用户发布任意内容的问题。如果可能,这应当被禁用。否则,当您遭遇随机错误时,请参考[http://modsecurity.org/documentation/ mod_security 文档]或联络您的主机支持。",
        "config-diff3-bad": "找不到GNU diff3。",
        "config-git": "发现Git版本控制软件:<code>$1</code>",
        "config-git-bad": "Git版本控制软件未找到。",
        "config-imagemagick": "已找到ImageMagick:<code>$1</code>。如果你启用了上传功能,缩略图功能也将被启用。",
        "config-gd": "已找到内建的GD图形库。如果你启用了上传功能,缩略图功能也将被启用。",
        "config-no-scaling": "找不到GD库或ImageMagick。缩略图功能将不可用。",
-       "config-no-uri": "'''错误:'''无法确定当前的URI。安装已中断。",
+       "config-no-uri": "<strong>错误:</strong>无法确定当前的URI。\n安装已中断。",
        "config-no-cli-uri": "<strong>警告:</strong>未指定<code>--scriptpath</code>参数,使用默认值:<code>$1</code>。",
        "config-using-server": "使用服务器名“<nowiki>$1</nowiki>”。",
        "config-using-uri": "使用服务器URL“<nowiki>$1$2</nowiki>”。",
-       "config-uploads-not-safe": "'''警告:'''您的默认上传目录<code>$1</code>存在允许执行任意脚本的漏洞。尽管MediaWiki会对所有已上传的文件进行安全检查,但我们仍然强烈建议您在启用上传功能前[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security 关闭该安全漏洞]。",
-       "config-no-cli-uploads-check": "'''警告''':在CLI安装过程中,没有对您的默认上传目录(<code>$1</code>)进行执行任意脚本的漏洞检查。",
+       "config-uploads-not-safe": "<strong>警告:</strong>您的默认上传目录<code>$1</code>存在允许执行任意脚本的漏洞。\n尽管MediaWiki会对所有已上传的文件进行安全检查,但我们仍然强烈建议您在启用上传功能前[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security 关闭该安全漏洞]。",
+       "config-no-cli-uploads-check": "<strong>警告:</strong>在CLI安装过程中,没有对您的默认上传目录(<code>$1</code>)进行执行任意脚本的漏洞检查。",
        "config-brokenlibxml": "您的系统安装的PHP和libxml2版本组合存在故障,并可能在MediaWiki和其他web应用程序中造成隐藏的数据损坏。请将libxml2升级到2.7.3或以上([https://bugs.php.net/bug.php?id=45996 PHP的故障报告])。安装已中断。",
        "config-suhosin-max-value-length": "Suhosin已经安装并将GET请求的参数长度限制在$1字节。MediaWiki的ResourceLoader部件可以在此限制下正常工作,但其性能会被降低。如果可能,请在<code>php.ini</code>中将<code>suhosin.get.max_value_length</code>设为1024或更高值,并在LocalSettings.php中将<code>$wgResourceLoaderMaxQueryLength</code>设为同一值。",
        "config-db-type": "数据库类型:",
        "config-charset-mysql5-binary": "MySQL 4.1/5.0 二进制",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
        "config-charset-mysql4": "MySQL 4.0 UTF-8(向后兼容)",
-       "config-charset-help": "'''警告:'''如果您在MySQL 4.1+中使用'''向后兼容的UTF-8'''字符集,并在之后使用<code>mysqldump</code>备份了数据库,则可能损坏所有的非ASCII字符,从而不可逆地破坏您的备份!\n\n在'''二进制模式'''下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在'''UTF-8模式'''下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[//zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
+       "config-charset-help": "<strong>警告:</strong>如果您在MySQL 4.1+中使用<strong>向后兼容的UTF-8</strong>字符集,并在之后使用<code>mysqldump</code>备份了数据库,则可能损坏所有的非ASCII字符,从而不可逆地破坏您的备份!\n\n在<strong>二进制模式</strong>下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在<strong>UTF-8模式</strong>下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[//zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
        "config-mysql-old": "需要MySQL $1或更新的版本,您的版本为$2。",
        "config-db-port": "数据库端口:",
        "config-db-schema": "MediaWiki的数据库模式",
        "config-db-schema-help": "此数据库模式通常是正确的,请在有明确需求时才改动之。",
-       "config-pg-test-error": "无法连接到数据库'''$1''':$2",
+       "config-pg-test-error": "无法连接到数据库<strong>$1</strong>:$2",
        "config-sqlite-dir": "SQLite数据目录:",
-       "config-sqlite-dir-help": "SQLite会将所有的数据存储于单一文件中。\n\n您所提供的目录必须在安装过程中对网页服务器可写。\n\n该目录'''不应'''允许通过web访问,因此我们不会将数据文件和PHP文件放在一起。\n\n安装程序在创建数据文件时,亦会在相同目录下创建<code>.htaccess</code>以控制权限。假若此等控制失效,则可能会将您的数据文件暴露于公共空间,让他人可以获取用户数据(电子邮件地址、杂凑后的密码)、被删除的版本以及其他在wiki上被限制访问的数据。\n\n请考虑将数据库统一放置在某处,如<code>/var/lib/mediawiki/yourwiki</code>下。",
+       "config-sqlite-dir-help": "SQLite会将所有的数据存储于单一文件中。\n\n您所提供的目录必须在安装过程中对网页服务器可写。\n\n该目录<strong>不应</strong>允许通过web访问,因此我们不会将数据文件和PHP文件放在一起。\n\n安装程序在创建数据文件时,亦会在相同目录下创建<code>.htaccess</code>以控制权限。假若此等控制失效,则可能会将您的数据文件暴露于公共空间,让他人可以获取用户数据(电子邮件地址、杂凑后的密码)、被删除的版本以及其他在wiki上被限制访问的数据。\n\n请考虑将数据库统一放置在某处,如<code>/var/lib/mediawiki/yourwiki</code>下。",
        "config-oracle-def-ts": "默认表空间:",
        "config-oracle-temp-ts": "临时表空间:",
        "config-type-mysql": "MySQL(或兼容程序)",
        "config-sqlite-readonly": "文件<code>$1</code>不可写。",
        "config-sqlite-cant-create-db": "无法创建数据文件<code>$1</code>。",
        "config-sqlite-fts3-downgrade": "PHP缺少FTS3支持,正在降级数据表",
-       "config-can-upgrade": "在数据库中发现了MediaWiki的数据表。要将它们升级至MediaWiki $1,请点击'''继续'''。",
-       "config-upgrade-done": "升级完成。\n\n现在您可以[$1 开始使用您的wiki]了。\n\n如果您需要重新生成<code>LocalSettings.php</code>文件,请点击下面的按钮。除非您的wiki出现了问题,我们'''不推荐'''您执行此操作。",
+       "config-can-upgrade": "在数据库中发现了MediaWiki的数据表。要将它们升级至MediaWiki $1,请点击<strong>继续</strong>。",
+       "config-upgrade-done": "升级完成。\n\n现在您可以[$1 开始使用您的wiki]了。\n\n如果您需要重新生成<code>LocalSettings.php</code>文件,请点击下面的按钮。除非您的wiki出现了问题,我们<strong>不推荐</strong>您执行此操作。",
        "config-upgrade-done-no-regenerate": "升级完成。\n\n现在您可以[$1 开始使用您的wiki]了。",
        "config-regenerate": "重新生成LocalSettings.php →",
        "config-show-table-status": "<code>SHOW TABLE STATUS</code>语句执行失败!",
-       "config-unknown-collation": "'''警告:'''数据库使用了无法识别的整理。",
+       "config-unknown-collation": "<strong>警告:</strong>数据库使用了无法识别的整理。",
        "config-db-web-account": "供网页访问使用的数据库帐号",
        "config-db-web-help": "请指定在wiki执行普通操作时,网页服务器用于连接数据库服务器的用户名和密码。",
        "config-db-web-account-same": "使用和安装程序相同的帐号",
        "config-mysql-engine": "存储引擎:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''警告''':您选择了MyISAM作为MySQL的存储引擎,MediaWiki并不推荐您这么做,因为:\n* 它仅能通过表锁定来勉强支持并发\n* 与其他引擎相比,它更容易被损坏\n* MediaWiki代码库并不总会去处理MyISAM\n\n如果您的MySQL程序支持InnoDB,我们高度推荐您使用该引擎替代MyISAM。\n如果您的MySQL程序不支持InnoDB,请考虑升级。",
+       "config-mysql-myisam-dep": "<strong>警告:</strong>您选择了MyISAM作为MySQL的存储引擎,MediaWiki并不推荐您这么做,因为:\n* 它仅能通过表锁定来勉强支持并发\n* 与其他引擎相比,它更容易被损坏\n* MediaWiki代码库并不总会去处理MyISAM\n\n如果您的MySQL程序支持InnoDB,我们高度推荐您使用该引擎替代MyISAM。\n如果您的MySQL程序不支持InnoDB,请考虑升级。",
        "config-mysql-only-myisam-dep": "<strong>警告:</strong>MyISAM是MySQL在此机器上唯一可用的存储引擎,但它不适合用于MediaWiki,因为:\n*因为表级锁定,它几乎不支持并发。\n*它相比其他引擎更容易损坏。\n*MediaWiki代码不能总是按照预期操作MyISAM。\n\n你的MySQL不支持InnoDB,是时候升级了。",
-       "config-mysql-engine-help": "'''InnoDB'''通常是最佳选项,因为它对并发操作有着良好的支持。\n\n'''MyISAM'''在单用户或只读环境下可能会有更快的性能表现。但MyISAM数据库出错的概率一般要大于InnoDB数据库。",
+       "config-mysql-engine-help": "<strong>InnoDB</strong>通常是最佳选项,因为它对并发操作有着良好的支持。\n\n<strong>MyISAM</strong>在单用户或只读环境下可能会有更快的性能表现。但MyISAM数据库出错的概率一般要大于InnoDB数据库。",
        "config-mysql-charset": "数据库字符集:",
        "config-mysql-binary": "二进制",
        "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "在'''二进制模式'''下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在'''UTF-8模式'''下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[//zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
+       "config-mysql-charset-help": "在<strong>二进制模式</strong>下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在<strong>UTF-8模式</strong>下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[//zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
        "config-mssql-auth": "身份验证类型:",
        "config-mssql-install-auth": "选择安装过程中链接数据库时将采用的身份验证方式。\n如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行服务器的用户的身份凭据。",
        "config-mssql-web-auth": "选择Web服务器在通常wiki操作期间用来连接数据库服务器的身份验证方式。\n如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行Web服务器的用户的凭据。",
index 4ab9f5a..3919318 100644 (file)
@@ -208,7 +208,12 @@ class JobRunner implements LoggerAwareInterface {
                                // other wikis in the farm (on different masters) get a chance.
                                $timePassed = microtime( true ) - $lastCheckTime;
                                if ( $timePassed >= self::LAG_CHECK_PERIOD || $timePassed < 0 ) {
-                                       if ( !wfWaitForSlaves( $lastCheckTime, false, '*', self::MAX_ALLOWED_LAG ) ) {
+                                       try {
+                                               wfGetLBFactory()->waitForReplication( array(
+                                                       'ifWritesSince' => $lastCheckTime,
+                                                       'timeout' => self::MAX_ALLOWED_LAG
+                                               ) );
+                                       } catch ( DBReplicationWaitError $e ) {
                                                $response['reached'] = 'slave-lag-limit';
                                                break;
                                        }
index f146e6e..13e36d8 100644 (file)
@@ -41,7 +41,8 @@ class ActivityUpdateJob extends Job {
                if ( $this->params['type'] === 'updateWatchlistNotification' ) {
                        $this->updateWatchlistNotification();
                } else {
-                       throw new Exception( "Invalid 'type' parameter '{$this->params['type']}'." );
+                       throw new InvalidArgumentException(
+                               "Invalid 'type' parameter '{$this->params['type']}'." );
                }
 
                return true;
index c9e20a9..5dc2acb 100644 (file)
@@ -49,21 +49,22 @@ class CategoryMembershipChangeJob extends Job {
                }
 
                $dbw = wfGetDB( DB_MASTER );
-
                // Use a named lock so that jobs for this page see each others' changes
-               $fname = __METHOD__;
                $lockKey = "CategoryMembershipUpdates:{$page->getId()}";
-               if ( !$dbw->lock( $lockKey, $fname, 10 ) ) {
+               $scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 10 );
+               if ( !$scopedLock ) {
                        $this->setLastError( "Could not acquire lock '$lockKey'" );
                        return false;
                }
 
-               $unlocker = new ScopedCallback( function () use ( $dbw, $lockKey, $fname ) {
-                       $dbw->unlock( $lockKey, $fname );
-               } );
-
-               // Sanity: clear any DB transaction snapshot
-               $dbw->commit( __METHOD__, 'flush' );
+               $dbr = wfGetDB( DB_SLAVE, array( 'recentchanges' ) );
+               // Wait till the slave is caught up so that jobs for this page see each others' changes
+               if ( !wfGetLB()->safeWaitForMasterPos( $dbr ) ) {
+                       $this->setLastError( "Timed out while waiting for slave to catch up" );
+                       return false;
+               }
+               // Clear any stale REPEATABLE-READ snapshot
+               $dbr->commit( __METHOD__, 'flush' );
 
                $cutoffUnix = wfTimestamp( TS_UNIX, $this->params['revTimestamp'] );
                // Using ENQUEUE_FUDGE_SEC handles jobs inserted out of revision order due to the delay
@@ -71,12 +72,12 @@ class CategoryMembershipChangeJob extends Job {
                $cutoffUnix -= self::ENQUEUE_FUDGE_SEC;
 
                // Get the newest revision that has a SRC_CATEGORIZE row...
-               $row = $dbw->selectRow(
+               $row = $dbr->selectRow(
                        array( 'revision', 'recentchanges' ),
                        array( 'rev_timestamp', 'rev_id' ),
                        array(
                                'rev_page' => $page->getId(),
-                               'rev_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $cutoffUnix ) )
+                               'rev_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) )
                        ),
                        __METHOD__,
                        array( 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ),
@@ -103,8 +104,8 @@ class CategoryMembershipChangeJob extends Job {
 
                // Find revisions to this page made around and after this revision which lack category
                // notifications in recent changes. This lets jobs pick up were the last one left off.
-               $encCutoff = $dbw->addQuotes( $dbw->timestamp( $cutoffUnix ) );
-               $res = $dbw->select(
+               $encCutoff = $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) );
+               $res = $dbr->select(
                        'revision',
                        Revision::selectFields(),
                        array(
@@ -121,8 +122,6 @@ class CategoryMembershipChangeJob extends Job {
                        $this->notifyUpdatesForRevision( $page, Revision::newFromRow( $row ) );
                }
 
-               ScopedCallback::consume( $unlocker );
-
                return true;
        }
 
@@ -169,7 +168,7 @@ class CategoryMembershipChangeJob extends Job {
                        $catMembChange->triggerCategoryAddedNotification( $categoryTitle );
                        if ( $insertCount++ && ( $insertCount % $batchSize ) == 0 ) {
                                $dbw->commit( __METHOD__, 'flush' );
-                               wfWaitForSlaves();
+                               wfGetLBFactory()->waitForReplication();
                        }
                }
 
@@ -178,7 +177,7 @@ class CategoryMembershipChangeJob extends Job {
                        $catMembChange->triggerCategoryRemovedNotification( $categoryTitle );
                        if ( $insertCount++ && ( $insertCount++ % $batchSize ) == 0 ) {
                                $dbw->commit( __METHOD__, 'flush' );
-                               wfWaitForSlaves();
+                               wfGetLBFactory()->waitForReplication();
                        }
                }
        }
index df0a66e..0d48cb3 100644 (file)
@@ -120,7 +120,7 @@ class HTMLCacheUpdateJob extends Job {
                // Check $wgUpdateRowsPerQuery for sanity; batch jobs are sized by that already.
                foreach ( array_chunk( $pageIds, $wgUpdateRowsPerQuery ) as $batch ) {
                        $dbw->commit( __METHOD__, 'flush' );
-                       wfWaitForSlaves();
+                       wfGetLBFactory()->waitForReplication();
 
                        $dbw->update( 'page',
                                array( 'page_touched' => $dbw->timestamp( $touchTimestamp ) ),
index d6fa26b..0685299 100644 (file)
@@ -98,7 +98,9 @@ class RecentChangesUpdateJob extends Job {
 
                        if ( count( $rcIds ) === $batchSize ) {
                                // There might be more, so try waiting for slaves
-                               if ( !wfWaitForSlaves( null, false, false, /* $timeout = */ 3 ) ) {
+                               try {
+                                       wfGetLBFactory()->waitForReplication( array( 'timeout' => 3 ) );
+                               } catch ( DBReplicationWaitError $e ) {
                                        // Another job will continue anyway
                                        break;
                                }
@@ -125,7 +127,7 @@ class RecentChangesUpdateJob extends Job {
 
                        $lockKey = wfWikiID() . '-activeusers';
                        if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
-                               return false; // exclusive update (avoids duplicate entries)
+                               return; // exclusive update (avoids duplicate entries)
                        }
 
                        $nowUnix = time();
@@ -203,7 +205,7 @@ class RecentChangesUpdateJob extends Job {
                                }
                                foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
                                        $dbw->insert( 'querycachetwo', $rowBatch, __METHOD__ );
-                                       wfWaitForSlaves();
+                                       wfGetLBFactory()->waitForReplication();
                                }
                        }
 
index 6ca0fed..246de75 100644 (file)
@@ -451,15 +451,19 @@ class CSSMin {
                        // Path to the actual file on the filesystem
                        $localFile = "{$local}/{$file}";
                        if ( file_exists( $localFile ) ) {
-                               // Add version parameter as the first five hex digits
-                               // of the MD5 hash of the file's contents.
-                               $url .= '?' . substr( md5_file( $localFile ), 0, 5 );
                                if ( $embed ) {
                                        $data = self::encodeImageAsDataURI( $localFile );
                                        if ( $data !== false ) {
                                                return $data;
                                        }
                                }
+                               if ( method_exists( 'OutputPage', 'transformFilePath' ) ) {
+                                       $url = OutputPage::transformFilePath( $remote, $local, $file );
+                               } else {
+                                       // Add version parameter as the first five hex digits
+                                       // of the MD5 hash of the file's contents.
+                                       $url .= '?' . substr( md5_file( $localFile ), 0, 5 );
+                               }
                        }
                        // If any of these conditions failed (file missing, we don't want to embed it
                        // or it's not embeddable), return the URL (possibly with ?timestamp part)
index b9be43d..3736103 100644 (file)
@@ -69,6 +69,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        const READ_VERIFIED = 2; // promise that caller can tell when keys are stale
        /** Bitfield constants for set()/merge() */
        const WRITE_SYNC = 1; // synchronously write to all locations for replicated stores
+       const WRITE_CACHE_ONLY = 2; // Only change state of the in-memory cache
 
        public function __construct( array $params = array() ) {
                if ( isset( $params['logger'] ) ) {
diff --git a/includes/libs/objectcache/CachedBagOStuff.php b/includes/libs/objectcache/CachedBagOStuff.php
new file mode 100644 (file)
index 0000000..fc15618
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Wrapper around a BagOStuff that caches data in memory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Wrapper around a BagOStuff that caches data in memory
+ *
+ * The differences between CachedBagOStuff and MultiWriteBagOStuff are:
+ * * CachedBagOStuff supports only one "backend".
+ * * There's a flag for writes to only go to the in-memory cache.
+ * * The in-memory cache is always updated.
+ * * Locks go to the backend cache (with MultiWriteBagOStuff, it would wind
+ *   up going to the HashBagOStuff used for the in-memory cache).
+ *
+ * @ingroup Cache
+ */
+class CachedBagOStuff extends HashBagOStuff {
+       /** @var BagOStuff */
+       protected $backend;
+
+       /**
+        * @param BagOStuff $backend Permanent backend to use
+        * @param array $params Parameters for HashBagOStuff
+        */
+       function __construct( BagOStuff $backend, $params = array() ) {
+               $this->backend = $backend;
+               parent::__construct( $params );
+       }
+
+       protected function doGet( $key, $flags = 0 ) {
+               $ret = parent::doGet( $key, $flags );
+               if ( $ret === false ) {
+                       $ret = $this->backend->doGet( $key, $flags );
+                       if ( $ret !== false ) {
+                               $this->set( $key, $ret, 0, self::WRITE_CACHE_ONLY );
+                       }
+               }
+               return $ret;
+       }
+
+       public function set( $key, $value, $exptime = 0, $flags = 0 ) {
+               parent::set( $key, $value, $exptime, $flags );
+               if ( !( $flags & self::WRITE_CACHE_ONLY ) ) {
+                       $this->backend->set( $key, $value, $exptime, $flags & ~self::WRITE_CACHE_ONLY );
+               }
+               return true;
+       }
+
+       public function delete( $key, $flags = 0 ) {
+               unset( $this->bag[$key] );
+               if ( !( $flags & self::WRITE_CACHE_ONLY ) ) {
+                       $this->backend->delete( $key );
+               }
+
+               return true;
+       }
+
+       public function setLogger( LoggerInterface $logger ) {
+               parent::setLogger( $logger );
+               $this->backend->setLogger( $logger );
+       }
+
+       public function setDebug( $bool ) {
+               parent::setDebug( $bool );
+               $this->backend->setDebug( $bool );
+       }
+
+       public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) {
+               return $this->backend->lock( $key, $timeout, $expiry, $rclass );
+       }
+
+       public function unlock( $key ) {
+               return $this->backend->unlock( $key );
+       }
+
+       public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
+               parent::deleteObjectsExpiringBefore( $date, $progressCallback );
+               return $this->backend->deleteObjectsExpiringBefore( $date, $progressCallback );
+       }
+
+       public function getLastError() {
+               return $this->backend->getLastError();
+       }
+
+       public function clearLastError() {
+               $this->backend->clearLastError();
+       }
+
+       public function modifySimpleRelayEvent( array $event ) {
+               return $this->backend->modifySimpleRelayEvent( $event );
+       }
+
+}
index e2d9946..b99cb41 100644 (file)
@@ -67,7 +67,7 @@ class LogFormatter {
        /**
         * Handy shortcut for constructing a formatter directly from
         * database row.
-        * @param object $row
+        * @param stdClass|array $row
         * @see DatabaseLogEntry::getSelectQueryData
         * @return LogFormatter
         */
@@ -237,7 +237,7 @@ class LogFormatter {
                                        // @codingStandardsIgnoreStart Long line
                                        //case 'revision': // Revision deletion
                                        //case 'event': // Log deletion
-                                       // see https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/LogPage.php?&pathrev=97044&r1=97043&r2=97044
+                                       // see https://github.com/wikimedia/mediawiki/commit/a9c243b7b5289dad204278dbe7ed571fd914e395
                                        //default:
                                        // @codingStandardsIgnoreEnd
                                }
@@ -245,7 +245,7 @@ class LogFormatter {
 
                        case 'patrol':
                                // @codingStandardsIgnoreStart Long line
-                               // https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/PatrolLog.php?&pathrev=97495&r1=97494&r2=97495
+                               // https://github.com/wikimedia/mediawiki/commit/1a05f8faf78675dc85984f27f355b8825b43efff
                                // @codingStandardsIgnoreEnd
                                // Create a diff link to the patrolled revision
                                if ( $entry->getSubtype() === 'patrol' ) {
index 5a58c33..b62bcb4 100644 (file)
@@ -38,10 +38,10 @@ class TagLogFormatter extends LogFormatter {
                $remove = ( isset( $params[8] ) && isset( $params[8]['num'] ) && $params[8]['num'] );
                $key .= ( $remove ? ( $add ? '' : '-remove' ) : '-add' );
 
-               if ( isset( $params[4] ) && $params[4] ) {
-                       $key .= '-logentry';
-               } else {
+               if ( isset( $params[3] ) && $params[3] ) {
                        $key .= '-revision';
+               } else {
+                       $key .= '-logentry';
                }
 
                return $key;
index f557c1a..8bac6b8 100644 (file)
@@ -138,7 +138,7 @@ class EmailNotification {
        public function notifyOnPageChange( $editor, $title, $timestamp, $summary,
                $minorEdit, $oldid = false, $pageStatus = 'changed'
        ) {
-               global $wgEnotifUseJobQ, $wgEnotifMinorEdits, $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
+               global $wgEnotifMinorEdits, $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
 
                if ( $title->getNamespace() < 0 ) {
                        return;
@@ -166,34 +166,20 @@ class EmailNotification {
                        }
                }
 
-               if ( !$sendEmail ) {
-                       return;
-               }
-
-               if ( $wgEnotifUseJobQ ) {
-                       $params = array(
-                               'editor' => $editor->getName(),
-                               'editorID' => $editor->getID(),
-                               'timestamp' => $timestamp,
-                               'summary' => $summary,
-                               'minorEdit' => $minorEdit,
-                               'oldid' => $oldid,
-                               'watchers' => $watchers,
-                               'pageStatus' => $pageStatus
-                       );
-                       $job = new EnotifNotifyJob( $title, $params );
-                       JobQueueGroup::singleton()->lazyPush( $job );
-               } else {
-                       $this->actuallyNotifyOnPageChange(
-                               $editor,
+               if ( $sendEmail ) {
+                       JobQueueGroup::singleton()->lazyPush( new EnotifNotifyJob(
                                $title,
-                               $timestamp,
-                               $summary,
-                               $minorEdit,
-                               $oldid,
-                               $watchers,
-                               $pageStatus
-                       );
+                               array(
+                                       'editor' => $editor->getName(),
+                                       'editorID' => $editor->getID(),
+                                       'timestamp' => $timestamp,
+                                       'summary' => $summary,
+                                       'minorEdit' => $minorEdit,
+                                       'oldid' => $oldid,
+                                       'watchers' => $watchers,
+                                       'pageStatus' => $pageStatus
+                               )
+                       ) );
                }
        }
 
index faf40b3..c2b82d8 100644 (file)
@@ -59,6 +59,51 @@ class BitmapHandler extends TransformationalImageHandler {
                return $scaler;
        }
 
+       function makeParamString( $params ) {
+               $res = parent::makeParamString( $params );
+               if ( isset( $params['interlace'] ) && $params['interlace'] ) {
+                       return "interlaced-{$res}";
+               } else {
+                       return $res;
+               }
+       }
+
+       function parseParamString( $str ) {
+               $remainder = preg_replace( '/^interlaced-/', '', $str );
+               $params = parent::parseParamString( $remainder );
+               if ( $params === false ) {
+                       return false;
+               }
+               $params['interlace'] = $str !== $remainder;
+               return $params;
+       }
+
+       function validateParam( $name, $value ) {
+               if ( $name === 'interlace' ) {
+                       return $value === false || $value === true;
+               } else {
+                       return parent::validateParam( $name, $value );
+               }
+       }
+
+       /**
+        * @param File $image
+        * @param array $params
+        * @return bool
+        */
+       function normaliseParams( $image, &$params ) {
+               global $wgMaxInterlacingAreas;
+               if ( !parent::normaliseParams( $image, $params ) ) {
+                       return false;
+               }
+               $mimeType = $image->getMimeType();
+               $interlace = isset( $params['interlace'] ) && $params['interlace']
+                       && isset( $wgMaxInterlacingAreas[$mimeType] )
+                       && $this->getImageArea( $image ) <= $wgMaxInterlacingAreas[$mimeType];
+               $params['interlace'] = $interlace;
+               return true;
+       }
+
        /**
         * Transform an image using ImageMagick
         *
@@ -70,7 +115,7 @@ class BitmapHandler extends TransformationalImageHandler {
        protected function transformImageMagick( $image, $params ) {
                # use ImageMagick
                global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
-                       $wgImageMagickTempDir, $wgImageMagickConvertCommand;
+                       $wgImageMagickTempDir, $wgImageMagickConvertCommand, $wgMaxInterlacingAreas;
 
                $quality = array();
                $sharpen = array();
@@ -78,9 +123,13 @@ class BitmapHandler extends TransformationalImageHandler {
                $animation_pre = array();
                $animation_post = array();
                $decoderHint = array();
+
                if ( $params['mimeType'] == 'image/jpeg' ) {
                        $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
                        $quality = array( '-quality', $qualityVal ?: '80' ); // 80%
+                       if ( $params['interlace'] ) {
+                               $animation_post = array( '-interlace', 'JPEG' );
+                       }
                        # Sharpening, see bug 6193
                        if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
                                / ( $params['srcWidth'] + $params['srcHeight'] )
@@ -92,7 +141,12 @@ class BitmapHandler extends TransformationalImageHandler {
                                // JPEG decoder hint to reduce memory, available since IM 6.5.6-2
                                $decoderHint = array( '-define', "jpeg:size={$params['physicalDimensions']}" );
                        }
-               } elseif ( $params['mimeType'] == 'image/png' || $params['mimeType'] == 'image/webp' ) {
+               } elseif ( $params['mimeType'] == 'image/png' ) {
+                       $quality = array( '-quality', '95' ); // zlib 9, adaptive filtering
+                       if ( $params['interlace'] ) {
+                               $animation_post = array( '-interlace', 'PNG' );
+                       }
+               } elseif ( $params['mimeType'] == 'image/webp' ) {
                        $quality = array( '-quality', '95' ); // zlib 9, adaptive filtering
                } elseif ( $params['mimeType'] == 'image/gif' ) {
                        if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
@@ -108,6 +162,11 @@ class BitmapHandler extends TransformationalImageHandler {
                                        $animation_post = array( '-fuzz', '5%', '-layers', 'optimizeTransparency' );
                                }
                        }
+                       if ( $params['interlace'] && version_compare( $this->getMagickVersion(), "6.3.4" ) >= 0
+                               && !$this->isAnimatedImage( $image ) ) { // interlacing animated GIFs is a bad idea
+                               $animation_post[] = '-interlace';
+                               $animation_post[] = 'GIF';
+                       }
                } elseif ( $params['mimeType'] == 'image/x-xcf' ) {
                        // Before merging layers, we need to set the background
                        // to be transparent to preserve alpha, as -layers merge
@@ -191,7 +250,8 @@ class BitmapHandler extends TransformationalImageHandler {
         * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
         */
        protected function transformImageMagickExt( $image, $params ) {
-               global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea;
+               global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
+                       $wgMaxInterlacingAreas;
 
                try {
                        $im = new Imagick();
@@ -209,8 +269,14 @@ class BitmapHandler extends TransformationalImageHandler {
                                }
                                $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
                                $im->setCompressionQuality( $qualityVal ?: 80 );
+                               if ( $params['interlace'] ) {
+                                       $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
+                               }
                        } elseif ( $params['mimeType'] == 'image/png' ) {
                                $im->setCompressionQuality( 95 );
+                               if ( $params['interlace'] ) {
+                                       $im->setInterlaceScheme( Imagick::INTERLACE_PNG );
+                               }
                        } elseif ( $params['mimeType'] == 'image/gif' ) {
                                if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
                                        // Extract initial frame only; we're so big it'll
@@ -220,6 +286,13 @@ class BitmapHandler extends TransformationalImageHandler {
                                        // Coalesce is needed to scale animated GIFs properly (bug 1017).
                                        $im = $im->coalesceImages();
                                }
+                               // GIF interlacing is only available since 6.3.4
+                               $v = Imagick::getVersion();
+                               preg_match( '/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $v );
+
+                               if ( $params['interlace'] && version_compare( $v[1], '6.3.4' ) >= 0 ) {
+                                       $im->setInterlaceScheme( Imagick::INTERLACE_GIF );
+                               }
                        }
 
                        $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
index f72df19..597ac26 100644 (file)
@@ -126,6 +126,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
                        'mimeType' => $image->getMimeType(),
                        'dstPath' => $dstPath,
                        'dstUrl' => $dstUrl,
+                       'interlace' => isset( $params['interlace'] ) ? $params['interlace'] : false,
                );
 
                if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) {
index 519c420..e1f69db 100644 (file)
@@ -70,7 +70,7 @@ class XMPValidate implements LoggerAwareInterface {
                        return;
                }
                if ( $val !== 'True' && $val !== 'False' ) {
-                       $this->debug->info( __METHOD__ . " Expected True or False but got $val" );
+                       $this->logger->info( __METHOD__ . " Expected True or False but got $val" );
                        $val = null;
                }
        }
index 5776519..0e3c9eb 100644 (file)
@@ -735,7 +735,12 @@ class SqlBagOStuff extends BagOStuff {
        protected function waitForSlaves() {
                if ( !$this->serverInfos ) {
                        // Main LB is used; wait for any slaves to catch up
-                       return wfWaitForSlaves( null, false, false, $this->syncTimeout );
+                       try {
+                               wfGetLBFactory()->waitForReplication( array( 'wiki' => wfWikiID() ) );
+                               return true;
+                       } catch ( DBReplicationWaitError $e ) {
+                               return false;
+                       }
                } else {
                        // Custom DB server list; probably doesn't use replication
                        return true;
index f16158b..e81fd96 100644 (file)
@@ -521,7 +521,7 @@ class Article implements Page {
                # Try client and file cache
                if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
                        if ( $wgUseETag ) {
-                               $outputPage->setETag( $parserCache->getETag( $this, $parserOptions ) );
+                               $outputPage->setETag( $parserCache->getETag( $this->mPage, $parserOptions ) );
                        }
 
                        # Use the greatest of the page's timestamp or the timestamp of any
@@ -595,7 +595,7 @@ class Article implements Page {
 
                                        # Try the parser cache
                                        if ( $useParserCache ) {
-                                               $this->mParserOutput = $parserCache->get( $this, $parserOptions );
+                                               $this->mParserOutput = $parserCache->get( $this->mPage, $parserOptions );
 
                                                if ( $this->mParserOutput !== false ) {
                                                        if ( $oldid ) {
@@ -2084,22 +2084,575 @@ class Article implements Page {
        }
 
        /**
-        * Use PHP's magic __call handler to transform instance calls to
-        * WikiPage functions for backwards compatibility.
-        *
-        * @param string $fname Name of called method
-        * @param array $args Arguments to the method
-        * @return mixed
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::checkFlags
         */
-       public function __call( $fname, $args ) {
-               if ( is_callable( array( $this->mPage, $fname ) ) ) {
-                       # wfWarn( "Call to " . __CLASS__ . "::$fname; please use WikiPage instead" );
-                       return call_user_func_array( array( $this->mPage, $fname ), $args );
-               }
-               trigger_error( 'Inaccessible function via __call(): ' . $fname, E_USER_ERROR );
+       public function checkFlags( $flags ) {
+               return $this->mPage->checkFlags( $flags );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::checkTouched
+        */
+       public function checkTouched() {
+               return $this->mPage->checkTouched();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::clearPreparedEdit
+        */
+       public function clearPreparedEdit() {
+               $this->mPage->clearPreparedEdit();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doDeleteArticleReal
+        */
+       public function doDeleteArticleReal(
+               $reason, $suppress = false, $u1 = null, $u2 = null, &$error = '', User $user = null
+       ) {
+               return $this->mPage->doDeleteArticleReal(
+                       $reason, $suppress, $u1, $u2, $error, $user
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doDeleteUpdates
+        */
+       public function doDeleteUpdates( $id, Content $content = null ) {
+               return $this->mPage->doDeleteUpdates( $id, $content );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEdit
+        */
+       public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->doEdit( $text, $summary, $flags, $baseRevId, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEditContent
+        */
+       public function doEditContent( Content $content, $summary, $flags = 0, $baseRevId = false,
+               User $user = null, $serialFormat = null
+       ) {
+               return $this->mPage->doEditContent( $content, $summary, $flags, $baseRevId,
+                       $user, $serialFormat
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doEditUpdates
+        */
+       public function doEditUpdates( Revision $revision, User $user, array $options = array() ) {
+               return $this->mPage->doEditUpdates( $revision, $user, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doPurge
+        */
+       public function doPurge() {
+               return $this->mPage->doPurge();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doQuickEditContent
+        */
+       public function doQuickEditContent(
+               Content $content, User $user, $comment = '', $minor = false, $serialFormat = null
+       ) {
+               return $this->mPage->doQuickEditContent(
+                       $content, $user, $comment, $minor, $serialFormat
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::doViewUpdates
+        */
+       public function doViewUpdates( User $user, $oldid = 0 ) {
+               $this->mPage->doViewUpdates( $user, $oldid );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::exists
+        */
+       public function exists() {
+               return $this->mPage->exists();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::followRedirect
+        */
+       public function followRedirect() {
+               return $this->mPage->followRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getActionOverrides
+        */
+       public function getActionOverrides() {
+               return $this->mPage->getActionOverrides();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getAutoDeleteReason
+        */
+       public function getAutoDeleteReason( &$hasHistory ) {
+               return $this->mPage->getAutoDeleteReason( $hasHistory );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getCategories
+        */
+       public function getCategories() {
+               return $this->mPage->getCategories();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getComment
+        */
+       public function getComment( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getComment( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContentHandler
+        */
+       public function getContentHandler() {
+               return $this->mPage->getContentHandler();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContentModel
+        */
+       public function getContentModel() {
+               return $this->mPage->getContentModel();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getContributors
+        */
+       public function getContributors() {
+               return $this->mPage->getContributors();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getCreator
+        */
+       public function getCreator( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getCreator( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getDeletionUpdates
+        */
+       public function getDeletionUpdates( Content $content = null ) {
+               return $this->mPage->getDeletionUpdates( $content );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getHiddenCategories
+        */
+       public function getHiddenCategories() {
+               return $this->mPage->getHiddenCategories();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getId
+        */
+       public function getId() {
+               return $this->mPage->getId();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getLatest
+        */
+       public function getLatest() {
+               return $this->mPage->getLatest();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getLinksTimestamp
+        */
+       public function getLinksTimestamp() {
+               return $this->mPage->getLinksTimestamp();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getMinorEdit
+        */
+       public function getMinorEdit() {
+               return $this->mPage->getMinorEdit();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getOldestRevision
+        */
+       public function getOldestRevision() {
+               return $this->mPage->getOldestRevision();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRedirectTarget
+        */
+       public function getRedirectTarget() {
+               return $this->mPage->getRedirectTarget();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRedirectURL
+        */
+       public function getRedirectURL( $rt ) {
+               return $this->mPage->getRedirectURL( $rt );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getRevision
+        */
+       public function getRevision() {
+               return $this->mPage->getRevision();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getText
+        */
+       public function getText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->getText( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getTimestamp
+        */
+       public function getTimestamp() {
+               return $this->mPage->getTimestamp();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getTouched
+        */
+       public function getTouched() {
+               return $this->mPage->getTouched();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUndoContent
+        */
+       public function getUndoContent( Revision $undo, Revision $undoafter = null ) {
+               return $this->mPage->getUndoContent( $undo, $undoafter );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUndoText
+        */
+       public function getUndoText( Revision $undo, Revision $undoafter = null ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->getUndoText( $undo, $undoafter );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUser
+        */
+       public function getUser( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getUser( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::getUserText
+        */
+       public function getUserText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+               return $this->mPage->getUserText( $audience, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::hasViewableContent
+        */
+       public function hasViewableContent() {
+               return $this->mPage->hasViewableContent();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertOn
+        */
+       public function insertOn( $dbw, $pageId = null ) {
+               return $this->mPage->insertOn( $dbw, $pageId );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertProtectNullRevision
+        */
+       public function insertProtectNullRevision( $revCommentMsg, array $limit,
+               array $expiry, $cascade, $reason, $user = null
+       ) {
+               return $this->mPage->insertProtectNullRevision( $revCommentMsg, $limit,
+                       $expiry, $cascade, $reason, $user
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertRedirect
+        */
+       public function insertRedirect() {
+               return $this->mPage->insertRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::insertRedirectEntry
+        */
+       public function insertRedirectEntry( Title $rt, $oldLatest = null ) {
+               return $this->mPage->insertRedirectEntry( $rt, $oldLatest );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::isCountable
+        */
+       public function isCountable( $editInfo = false ) {
+               return $this->mPage->isCountable( $editInfo );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::isRedirect
+        */
+       public function isRedirect() {
+               return $this->mPage->isRedirect();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::loadFromRow
+        */
+       public function loadFromRow( $data, $from ) {
+               return $this->mPage->loadFromRow( $data, $from );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::loadPageData
+        */
+       public function loadPageData( $from = 'fromdb' ) {
+               $this->mPage->loadPageData( $from );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::lockAndGetLatest
+        */
+       public function lockAndGetLatest() {
+               return $this->mPage->lockAndGetLatest();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::makeParserOptions
+        */
+       public function makeParserOptions( $context ) {
+               return $this->mPage->makeParserOptions( $context );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::pageDataFromId
+        */
+       public function pageDataFromId( $dbr, $id, $options = array() ) {
+               return $this->mPage->pageDataFromId( $dbr, $id, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::pageDataFromTitle
+        */
+       public function pageDataFromTitle( $dbr, $title, $options = array() ) {
+               return $this->mPage->pageDataFromTitle( $dbr, $title, $options );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::prepareContentForEdit
+        */
+       public function prepareContentForEdit(
+               Content $content, $revision = null, User $user = null,
+               $serialFormat = null, $useCache = true
+       ) {
+               return $this->mPage->prepareContentForEdit(
+                       $content, $revision, $user,
+                       $serialFormat, $useCache
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::prepareTextForEdit
+        */
+       public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
+               return $this->mPage->prepareTextForEdit( $text, $revid, $user );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::protectDescription
+        */
+       public function protectDescription( array $limit, array $expiry ) {
+               return $this->mPage->protectDescription( $limit, $expiry );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::protectDescriptionLog
+        */
+       public function protectDescriptionLog( array $limit, array $expiry ) {
+               return $this->mPage->protectDescriptionLog( $limit, $expiry );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSection
+        */
+       public function replaceSection( $sectionId, $text, $sectionTitle = '',
+               $edittime = null
+       ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+               return $this->mPage->replaceSection( $sectionId, $text, $sectionTitle,
+                       $edittime
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSectionAtRev
+        */
+       public function replaceSectionAtRev( $sectionId, Content $sectionContent,
+               $sectionTitle = '', $baseRevId = null
+       ) {
+               return $this->mPage->replaceSectionAtRev( $sectionId, $sectionContent,
+                       $sectionTitle, $baseRevId
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::replaceSectionContent
+        */
+       public function replaceSectionContent(
+               $sectionId, Content $sectionContent, $sectionTitle = '', $edittime = null
+       ) {
+               return $this->mPage->replaceSectionContent(
+                       $sectionId, $sectionContent, $sectionTitle, $edittime
+               );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::setTimestamp
+        */
+       public function setTimestamp( $ts ) {
+               return $this->mPage->setTimestamp( $ts );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::shouldCheckParserCache
+        */
+       public function shouldCheckParserCache( ParserOptions $parserOptions, $oldId ) {
+               return $this->mPage->shouldCheckParserCache( $parserOptions, $oldId );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::supportsSections
+        */
+       public function supportsSections() {
+               return $this->mPage->supportsSections();
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::triggerOpportunisticLinksUpdate
+        */
+       public function triggerOpportunisticLinksUpdate( ParserOutput $parserOutput ) {
+               return $this->mPage->triggerOpportunisticLinksUpdate( $parserOutput );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateCategoryCounts
+        */
+       public function updateCategoryCounts( array $added, array $deleted ) {
+               return $this->mPage->updateCategoryCounts( $added, $deleted );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateIfNewerOn
+        */
+       public function updateIfNewerOn( $dbw, $revision ) {
+               return $this->mPage->updateIfNewerOn( $dbw, $revision );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateRedirectOn
+        */
+       public function updateRedirectOn( $dbw, $redirectTitle, $lastRevIsRedirect = null ) {
+               return $this->mPage->updateRedirectOn( $dbw, $redirectTitle, $lastRevIsRedirect = null );
+       }
+
+       /**
+        * Call to WikiPage function for backwards compatibility.
+        * @see WikiPage::updateRevisionOn
+        */
+       public function updateRevisionOn( $dbw, $revision, $lastRevision = null,
+               $lastRevIsRedirect = null
+       ) {
+               return $this->mPage->updateRevisionOn( $dbw, $revision, $lastRevision,
+                       $lastRevIsRedirect
+               );
        }
 
-       // ****** B/C functions to work-around PHP silliness with __call and references ****** //
 
        /**
         * @param array $limit
@@ -2185,8 +2738,6 @@ class Article implements Page {
                return $handler->getAutoDeleteReason( $title, $hasHistory );
        }
 
-       // ****** B/C functions for static methods ( __callStatic is PHP>=5.3 ) ****** //
-
        /**
         * @return array
         *
index caebcd7..50cb96c 100644 (file)
@@ -29,6 +29,11 @@ class CategoryPage extends Article {
        # Subclasses can change this to override the viewer class.
        protected $mCategoryViewerClass = 'CategoryViewer';
 
+       /**
+        * @var WikiCategoryPage
+        */
+       protected $mPage;
+
        /**
         * @param Title $title
         * @return WikiCategoryPage
diff --git a/includes/page/ImageHistoryList.php b/includes/page/ImageHistoryList.php
new file mode 100644 (file)
index 0000000..32638a5
--- /dev/null
@@ -0,0 +1,327 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Builds the image revision log shown on image pages
+ *
+ * @ingroup Media
+ */
+class ImageHistoryList extends ContextSource {
+
+       /**
+        * @var Title
+        */
+       protected $title;
+
+       /**
+        * @var File
+        */
+       protected $img;
+
+       /**
+        * @var ImagePage
+        */
+       protected $imagePage;
+
+       /**
+        * @var File
+        */
+       protected $current;
+
+       protected $repo, $showThumb;
+       protected $preventClickjacking = false;
+
+       /**
+        * @param ImagePage $imagePage
+        */
+       public function __construct( $imagePage ) {
+               global $wgShowArchiveThumbnails;
+               $this->current = $imagePage->getFile();
+               $this->img = $imagePage->getDisplayedFile();
+               $this->title = $imagePage->getTitle();
+               $this->imagePage = $imagePage;
+               $this->showThumb = $wgShowArchiveThumbnails && $this->img->canRender();
+               $this->setContext( $imagePage->getContext() );
+       }
+
+       /**
+        * @return ImagePage
+        */
+       public function getImagePage() {
+               return $this->imagePage;
+       }
+
+       /**
+        * @return File
+        */
+       public function getFile() {
+               return $this->img;
+       }
+
+       /**
+        * @param string $navLinks
+        * @return string
+        */
+       public function beginImageHistoryList( $navLinks = '' ) {
+               return Xml::element( 'h2', array( 'id' => 'filehistory' ), $this->msg( 'filehist' )->text() )
+               . "\n"
+               . "<div id=\"mw-imagepage-section-filehistory\">\n"
+               . $this->msg( 'filehist-help' )->parseAsBlock()
+               . $navLinks . "\n"
+               . Xml::openElement( 'table', array( 'class' => 'wikitable filehistory' ) ) . "\n"
+               . '<tr><th></th>'
+               . ( $this->current->isLocal()
+               && ( $this->getUser()->isAllowedAny( 'delete', 'deletedhistory' ) ) ? '<th></th>' : '' )
+               . '<th>' . $this->msg( 'filehist-datetime' )->escaped() . '</th>'
+               . ( $this->showThumb ? '<th>' . $this->msg( 'filehist-thumb' )->escaped() . '</th>' : '' )
+               . '<th>' . $this->msg( 'filehist-dimensions' )->escaped() . '</th>'
+               . '<th>' . $this->msg( 'filehist-user' )->escaped() . '</th>'
+               . '<th>' . $this->msg( 'filehist-comment' )->escaped() . '</th>'
+               . "</tr>\n";
+       }
+
+       /**
+        * @param string $navLinks
+        * @return string
+        */
+       public function endImageHistoryList( $navLinks = '' ) {
+               return "</table>\n$navLinks\n</div>\n";
+       }
+
+       /**
+        * @param bool $iscur
+        * @param File $file
+        * @return string
+        */
+       public function imageHistoryLine( $iscur, $file ) {
+               global $wgContLang;
+
+               $user = $this->getUser();
+               $lang = $this->getLanguage();
+               $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
+               $img = $iscur ? $file->getName() : $file->getArchiveName();
+               $userId = $file->getUser( 'id' );
+               $userText = $file->getUser( 'text' );
+               $description = $file->getDescription( File::FOR_THIS_USER, $user );
+
+               $local = $this->current->isLocal();
+               $row = $selected = '';
+
+               // Deletion link
+               if ( $local && ( $user->isAllowedAny( 'delete', 'deletedhistory' ) ) ) {
+                       $row .= '<td>';
+                       # Link to remove from history
+                       if ( $user->isAllowed( 'delete' ) ) {
+                               $q = array( 'action' => 'delete' );
+                               if ( !$iscur ) {
+                                       $q['oldimage'] = $img;
+                               }
+                               $row .= Linker::linkKnown(
+                                       $this->title,
+                                       $this->msg( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' )->escaped(),
+                                       array(), $q
+                               );
+                       }
+                       # Link to hide content. Don't show useless link to people who cannot hide revisions.
+                       $canHide = $user->isAllowed( 'deleterevision' );
+                       if ( $canHide || ( $user->isAllowed( 'deletedhistory' ) && $file->getVisibility() ) ) {
+                               if ( $user->isAllowed( 'delete' ) ) {
+                                       $row .= '<br />';
+                               }
+                               // If file is top revision or locked from this user, don't link
+                               if ( $iscur || !$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
+                                       $del = Linker::revDeleteLinkDisabled( $canHide );
+                               } else {
+                                       list( $ts, ) = explode( '!', $img, 2 );
+                                       $query = array(
+                                               'type' => 'oldimage',
+                                               'target' => $this->title->getPrefixedText(),
+                                               'ids' => $ts,
+                                       );
+                                       $del = Linker::revDeleteLink( $query,
+                                               $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
+                               }
+                               $row .= $del;
+                       }
+                       $row .= '</td>';
+               }
+
+               // Reversion link/current indicator
+               $row .= '<td>';
+               if ( $iscur ) {
+                       $row .= $this->msg( 'filehist-current' )->escaped();
+               } elseif ( $local && $this->title->quickUserCan( 'edit', $user )
+                       && $this->title->quickUserCan( 'upload', $user )
+               ) {
+                       if ( $file->isDeleted( File::DELETED_FILE ) ) {
+                               $row .= $this->msg( 'filehist-revert' )->escaped();
+                       } else {
+                               $row .= Linker::linkKnown(
+                                       $this->title,
+                                       $this->msg( 'filehist-revert' )->escaped(),
+                                       array(),
+                                       array(
+                                               'action' => 'revert',
+                                               'oldimage' => $img,
+                                               'wpEditToken' => $user->getEditToken( $img )
+                                       )
+                               );
+                       }
+               }
+               $row .= '</td>';
+
+               // Date/time and image link
+               if ( $file->getTimestamp() === $this->img->getTimestamp() ) {
+                       $selected = "class='filehistory-selected'";
+               }
+               $row .= "<td $selected style='white-space: nowrap;'>";
+               if ( !$file->userCan( File::DELETED_FILE, $user ) ) {
+                       # Don't link to unviewable files
+                       $row .= '<span class="history-deleted">'
+                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
+               } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
+                       if ( $local ) {
+                               $this->preventClickjacking();
+                               $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
+                               # Make a link to review the image
+                               $url = Linker::linkKnown(
+                                       $revdel,
+                                       $lang->userTimeAndDate( $timestamp, $user ),
+                                       array(),
+                                       array(
+                                               'target' => $this->title->getPrefixedText(),
+                                               'file' => $img,
+                                               'token' => $user->getEditToken( $img )
+                                       )
+                               );
+                       } else {
+                               $url = $lang->userTimeAndDate( $timestamp, $user );
+                       }
+                       $row .= '<span class="history-deleted">' . $url . '</span>';
+               } elseif ( !$file->exists() ) {
+                       $row .= '<span class="mw-file-missing">'
+                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
+               } else {
+                       $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
+                       $row .= Xml::element(
+                               'a',
+                               array( 'href' => $url ),
+                               $lang->userTimeAndDate( $timestamp, $user )
+                       );
+               }
+               $row .= "</td>";
+
+               // Thumbnail
+               if ( $this->showThumb ) {
+                       $row .= '<td>' . $this->getThumbForLine( $file ) . '</td>';
+               }
+
+               // Image dimensions + size
+               $row .= '<td>';
+               $row .= htmlspecialchars( $file->getDimensionsString() );
+               $row .= $this->msg( 'word-separator' )->escaped();
+               $row .= '<span style="white-space: nowrap;">';
+               $row .= $this->msg( 'parentheses' )->sizeParams( $file->getSize() )->escaped();
+               $row .= '</span>';
+               $row .= '</td>';
+
+               // Uploading user
+               $row .= '<td>';
+               // Hide deleted usernames
+               if ( $file->isDeleted( File::DELETED_USER ) ) {
+                       $row .= '<span class="history-deleted">'
+                               . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
+               } else {
+                       if ( $local ) {
+                               $row .= Linker::userLink( $userId, $userText );
+                               $row .= '<span style="white-space: nowrap;">';
+                               $row .= Linker::userToolLinks( $userId, $userText );
+                               $row .= '</span>';
+                       } else {
+                               $row .= htmlspecialchars( $userText );
+                       }
+               }
+               $row .= '</td>';
+
+               // Don't show deleted descriptions
+               if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
+                       $row .= '<td><span class="history-deleted">' .
+                               $this->msg( 'rev-deleted-comment' )->escaped() . '</span></td>';
+               } else {
+                       $row .= '<td dir="' . $wgContLang->getDir() . '">' .
+                               Linker::formatComment( $description, $this->title ) . '</td>';
+               }
+
+               $rowClass = null;
+               Hooks::run( 'ImagePageFileHistoryLine', array( $this, $file, &$row, &$rowClass ) );
+               $classAttr = $rowClass ? " class='$rowClass'" : '';
+
+               return "<tr{$classAttr}>{$row}</tr>\n";
+       }
+
+       /**
+        * @param File $file
+        * @return string
+        */
+       protected function getThumbForLine( $file ) {
+               $lang = $this->getLanguage();
+               $user = $this->getUser();
+               if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user )
+                       && !$file->isDeleted( File::DELETED_FILE )
+               ) {
+                       $params = array(
+                               'width' => '120',
+                               'height' => '120',
+                       );
+                       $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
+
+                       $thumbnail = $file->transform( $params );
+                       $options = array(
+                               'alt' => $this->msg( 'filehist-thumbtext',
+                                       $lang->userTimeAndDate( $timestamp, $user ),
+                                       $lang->userDate( $timestamp, $user ),
+                                       $lang->userTime( $timestamp, $user ) )->text(),
+                               'file-link' => true,
+                       );
+
+                       if ( !$thumbnail ) {
+                               return $this->msg( 'filehist-nothumb' )->escaped();
+                       }
+
+                       return $thumbnail->toHtml( $options );
+               } else {
+                       return $this->msg( 'filehist-nothumb' )->escaped();
+               }
+       }
+
+       /**
+        * @param bool $enable
+        */
+       protected function preventClickjacking( $enable = true ) {
+               $this->preventClickjacking = $enable;
+       }
+
+       /**
+        * @return bool
+        */
+       public function getPreventClickjacking() {
+               return $this->preventClickjacking;
+       }
+}
diff --git a/includes/page/ImageHistoryPseudoPager.php b/includes/page/ImageHistoryPseudoPager.php
new file mode 100644 (file)
index 0000000..e421d23
--- /dev/null
@@ -0,0 +1,205 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class ImageHistoryPseudoPager extends ReverseChronologicalPager {
+       protected $preventClickjacking = false;
+
+       /**
+        * @var File
+        */
+       protected $mImg;
+
+       /**
+        * @var Title
+        */
+       protected $mTitle;
+
+       /**
+        * @param ImagePage $imagePage
+        */
+       function __construct( $imagePage ) {
+               parent::__construct( $imagePage->getContext() );
+               $this->mImagePage = $imagePage;
+               $this->mTitle = clone $imagePage->getTitle();
+               $this->mTitle->setFragment( '#filehistory' );
+               $this->mImg = null;
+               $this->mHist = array();
+               $this->mRange = array( 0, 0 ); // display range
+       }
+
+       /**
+        * @return Title
+        */
+       function getTitle() {
+               return $this->mTitle;
+       }
+
+       function getQueryInfo() {
+               return false;
+       }
+
+       /**
+        * @return string
+        */
+       function getIndexField() {
+               return '';
+       }
+
+       /**
+        * @param object $row
+        * @return string
+        */
+       function formatRow( $row ) {
+               return '';
+       }
+
+       /**
+        * @return string
+        */
+       function getBody() {
+               $s = '';
+               $this->doQuery();
+               if ( count( $this->mHist ) ) {
+                       if ( $this->mImg->isLocal() ) {
+                               // Do a batch existence check for user pages and talkpages
+                               $linkBatch = new LinkBatch();
+                               for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
+                                       $file = $this->mHist[$i];
+                                       $user = $file->getUser( 'text' );
+                                       $linkBatch->add( NS_USER, $user );
+                                       $linkBatch->add( NS_USER_TALK, $user );
+                               }
+                               $linkBatch->execute();
+                       }
+
+                       $list = new ImageHistoryList( $this->mImagePage );
+                       # Generate prev/next links
+                       $navLink = $this->getNavigationBar();
+                       $s = $list->beginImageHistoryList( $navLink );
+                       // Skip rows there just for paging links
+                       for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
+                               $file = $this->mHist[$i];
+                               $s .= $list->imageHistoryLine( !$file->isOld(), $file );
+                       }
+                       $s .= $list->endImageHistoryList( $navLink );
+
+                       if ( $list->getPreventClickjacking() ) {
+                               $this->preventClickjacking();
+                       }
+               }
+               return $s;
+       }
+
+       function doQuery() {
+               if ( $this->mQueryDone ) {
+                       return;
+               }
+               $this->mImg = $this->mImagePage->getFile(); // ensure loading
+               if ( !$this->mImg->exists() ) {
+                       return;
+               }
+               $queryLimit = $this->mLimit + 1; // limit plus extra row
+               if ( $this->mIsBackwards ) {
+                       // Fetch the file history
+                       $this->mHist = $this->mImg->getHistory( $queryLimit, null, $this->mOffset, false );
+                       // The current rev may not meet the offset/limit
+                       $numRows = count( $this->mHist );
+                       if ( $numRows <= $this->mLimit && $this->mImg->getTimestamp() > $this->mOffset ) {
+                               $this->mHist = array_merge( array( $this->mImg ), $this->mHist );
+                       }
+               } else {
+                       // The current rev may not meet the offset
+                       if ( !$this->mOffset || $this->mImg->getTimestamp() < $this->mOffset ) {
+                               $this->mHist[] = $this->mImg;
+                       }
+                       // Old image versions (fetch extra row for nav links)
+                       $oiLimit = count( $this->mHist ) ? $this->mLimit : $this->mLimit + 1;
+                       // Fetch the file history
+                       $this->mHist = array_merge( $this->mHist,
+                               $this->mImg->getHistory( $oiLimit, $this->mOffset, null, false ) );
+               }
+               $numRows = count( $this->mHist ); // Total number of query results
+               if ( $numRows ) {
+                       # Index value of top item in the list
+                       $firstIndex = $this->mIsBackwards ?
+                               $this->mHist[$numRows - 1]->getTimestamp() : $this->mHist[0]->getTimestamp();
+                       # Discard the extra result row if there is one
+                       if ( $numRows > $this->mLimit && $numRows > 1 ) {
+                               if ( $this->mIsBackwards ) {
+                                       # Index value of item past the index
+                                       $this->mPastTheEndIndex = $this->mHist[0]->getTimestamp();
+                                       # Index value of bottom item in the list
+                                       $lastIndex = $this->mHist[1]->getTimestamp();
+                                       # Display range
+                                       $this->mRange = array( 1, $numRows - 1 );
+                               } else {
+                                       # Index value of item past the index
+                                       $this->mPastTheEndIndex = $this->mHist[$numRows - 1]->getTimestamp();
+                                       # Index value of bottom item in the list
+                                       $lastIndex = $this->mHist[$numRows - 2]->getTimestamp();
+                                       # Display range
+                                       $this->mRange = array( 0, $numRows - 2 );
+                               }
+                       } else {
+                               # 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 = '';
+                               # Index value of bottom item in the list
+                               $lastIndex = $this->mIsBackwards ?
+                                       $this->mHist[0]->getTimestamp() : $this->mHist[$numRows - 1]->getTimestamp();
+                               # Display range
+                               $this->mRange = array( 0, $numRows - 1 );
+                       }
+               } else {
+                       $firstIndex = '';
+                       $lastIndex = '';
+                       $this->mPastTheEndIndex = '';
+               }
+               if ( $this->mIsBackwards ) {
+                       $this->mIsFirst = ( $numRows < $queryLimit );
+                       $this->mIsLast = ( $this->mOffset == '' );
+                       $this->mLastShown = $firstIndex;
+                       $this->mFirstShown = $lastIndex;
+               } else {
+                       $this->mIsFirst = ( $this->mOffset == '' );
+                       $this->mIsLast = ( $numRows < $queryLimit );
+                       $this->mLastShown = $lastIndex;
+                       $this->mFirstShown = $firstIndex;
+               }
+               $this->mQueryDone = true;
+       }
+
+       /**
+        * @param bool $enable
+        */
+       protected function preventClickjacking( $enable = true ) {
+               $this->preventClickjacking = $enable;
+       }
+
+       /**
+        * @return bool
+        */
+       public function getPreventClickjacking() {
+               return $this->preventClickjacking;
+       }
+
+}
index 3638aed..d171e89 100644 (file)
@@ -38,6 +38,11 @@ class ImagePage extends Article {
        /** @var bool */
        protected $mExtraDescription = false;
 
+       /**
+        * @var WikiFilePage
+        */
+       protected $mPage;
+
        /**
         * @param Title $title
         * @return WikiFilePage
@@ -1204,498 +1209,36 @@ EOT
                return $thumbSizes;
        }
 
-}
-
-/**
- * Builds the image revision log shown on image pages
- *
- * @ingroup Media
- */
-class ImageHistoryList extends ContextSource {
-
        /**
-        * @var Title
-        */
-       protected $title;
-
-       /**
-        * @var File
-        */
-       protected $img;
-
-       /**
-        * @var ImagePage
-        */
-       protected $imagePage;
-
-       /**
-        * @var File
-        */
-       protected $current;
-
-       protected $repo, $showThumb;
-       protected $preventClickjacking = false;
-
-       /**
-        * @param ImagePage $imagePage
-        */
-       public function __construct( $imagePage ) {
-               global $wgShowArchiveThumbnails;
-               $this->current = $imagePage->getFile();
-               $this->img = $imagePage->getDisplayedFile();
-               $this->title = $imagePage->getTitle();
-               $this->imagePage = $imagePage;
-               $this->showThumb = $wgShowArchiveThumbnails && $this->img->canRender();
-               $this->setContext( $imagePage->getContext() );
-       }
-
-       /**
-        * @return ImagePage
-        */
-       public function getImagePage() {
-               return $this->imagePage;
-       }
-
-       /**
-        * @return File
+        * @see WikiFilePage::getFile
+        * @return bool|File
         */
        public function getFile() {
-               return $this->img;
-       }
-
-       /**
-        * @param string $navLinks
-        * @return string
-        */
-       public function beginImageHistoryList( $navLinks = '' ) {
-               return Xml::element( 'h2', array( 'id' => 'filehistory' ), $this->msg( 'filehist' )->text() )
-                       . "\n"
-                       . "<div id=\"mw-imagepage-section-filehistory\">\n"
-                       . $this->msg( 'filehist-help' )->parseAsBlock()
-                       . $navLinks . "\n"
-                       . Xml::openElement( 'table', array( 'class' => 'wikitable filehistory' ) ) . "\n"
-                       . '<tr><th></th>'
-                       . ( $this->current->isLocal()
-                               && ( $this->getUser()->isAllowedAny( 'delete', 'deletedhistory' ) ) ? '<th></th>' : '' )
-                       . '<th>' . $this->msg( 'filehist-datetime' )->escaped() . '</th>'
-                       . ( $this->showThumb ? '<th>' . $this->msg( 'filehist-thumb' )->escaped() . '</th>' : '' )
-                       . '<th>' . $this->msg( 'filehist-dimensions' )->escaped() . '</th>'
-                       . '<th>' . $this->msg( 'filehist-user' )->escaped() . '</th>'
-                       . '<th>' . $this->msg( 'filehist-comment' )->escaped() . '</th>'
-                       . "</tr>\n";
-       }
-
-       /**
-        * @param string $navLinks
-        * @return string
-        */
-       public function endImageHistoryList( $navLinks = '' ) {
-               return "</table>\n$navLinks\n</div>\n";
-       }
-
-       /**
-        * @param bool $iscur
-        * @param File $file
-        * @return string
-        */
-       public function imageHistoryLine( $iscur, $file ) {
-               global $wgContLang;
-
-               $user = $this->getUser();
-               $lang = $this->getLanguage();
-               $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
-               $img = $iscur ? $file->getName() : $file->getArchiveName();
-               $userId = $file->getUser( 'id' );
-               $userText = $file->getUser( 'text' );
-               $description = $file->getDescription( File::FOR_THIS_USER, $user );
-
-               $local = $this->current->isLocal();
-               $row = $selected = '';
-
-               // Deletion link
-               if ( $local && ( $user->isAllowedAny( 'delete', 'deletedhistory' ) ) ) {
-                       $row .= '<td>';
-                       # Link to remove from history
-                       if ( $user->isAllowed( 'delete' ) ) {
-                               $q = array( 'action' => 'delete' );
-                               if ( !$iscur ) {
-                                       $q['oldimage'] = $img;
-                               }
-                               $row .= Linker::linkKnown(
-                                       $this->title,
-                                       $this->msg( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' )->escaped(),
-                                       array(), $q
-                               );
-                       }
-                       # Link to hide content. Don't show useless link to people who cannot hide revisions.
-                       $canHide = $user->isAllowed( 'deleterevision' );
-                       if ( $canHide || ( $user->isAllowed( 'deletedhistory' ) && $file->getVisibility() ) ) {
-                               if ( $user->isAllowed( 'delete' ) ) {
-                                       $row .= '<br />';
-                               }
-                               // If file is top revision or locked from this user, don't link
-                               if ( $iscur || !$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
-                                       $del = Linker::revDeleteLinkDisabled( $canHide );
-                               } else {
-                                       list( $ts, ) = explode( '!', $img, 2 );
-                                       $query = array(
-                                               'type' => 'oldimage',
-                                               'target' => $this->title->getPrefixedText(),
-                                               'ids' => $ts,
-                                       );
-                                       $del = Linker::revDeleteLink( $query,
-                                               $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
-                               }
-                               $row .= $del;
-                       }
-                       $row .= '</td>';
-               }
-
-               // Reversion link/current indicator
-               $row .= '<td>';
-               if ( $iscur ) {
-                       $row .= $this->msg( 'filehist-current' )->escaped();
-               } elseif ( $local && $this->title->quickUserCan( 'edit', $user )
-                       && $this->title->quickUserCan( 'upload', $user )
-               ) {
-                       if ( $file->isDeleted( File::DELETED_FILE ) ) {
-                               $row .= $this->msg( 'filehist-revert' )->escaped();
-                       } else {
-                               $row .= Linker::linkKnown(
-                                       $this->title,
-                                       $this->msg( 'filehist-revert' )->escaped(),
-                                       array(),
-                                       array(
-                                               'action' => 'revert',
-                                               'oldimage' => $img,
-                                               'wpEditToken' => $user->getEditToken( $img )
-                                       )
-                               );
-                       }
-               }
-               $row .= '</td>';
-
-               // Date/time and image link
-               if ( $file->getTimestamp() === $this->img->getTimestamp() ) {
-                       $selected = "class='filehistory-selected'";
-               }
-               $row .= "<td $selected style='white-space: nowrap;'>";
-               if ( !$file->userCan( File::DELETED_FILE, $user ) ) {
-                       # Don't link to unviewable files
-                       $row .= '<span class="history-deleted">'
-                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
-               } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
-                       if ( $local ) {
-                               $this->preventClickjacking();
-                               $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
-                               # Make a link to review the image
-                               $url = Linker::linkKnown(
-                                       $revdel,
-                                       $lang->userTimeAndDate( $timestamp, $user ),
-                                       array(),
-                                       array(
-                                               'target' => $this->title->getPrefixedText(),
-                                               'file' => $img,
-                                               'token' => $user->getEditToken( $img )
-                                       )
-                               );
-                       } else {
-                               $url = $lang->userTimeAndDate( $timestamp, $user );
-                       }
-                       $row .= '<span class="history-deleted">' . $url . '</span>';
-               } elseif ( !$file->exists() ) {
-                       $row .= '<span class="mw-file-missing">'
-                               . $lang->userTimeAndDate( $timestamp, $user ) . '</span>';
-               } else {
-                       $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img );
-                       $row .= Xml::element(
-                               'a',
-                               array( 'href' => $url ),
-                               $lang->userTimeAndDate( $timestamp, $user )
-                       );
-               }
-               $row .= "</td>";
-
-               // Thumbnail
-               if ( $this->showThumb ) {
-                       $row .= '<td>' . $this->getThumbForLine( $file ) . '</td>';
-               }
-
-               // Image dimensions + size
-               $row .= '<td>';
-               $row .= htmlspecialchars( $file->getDimensionsString() );
-               $row .= $this->msg( 'word-separator' )->escaped();
-               $row .= '<span style="white-space: nowrap;">';
-               $row .= $this->msg( 'parentheses' )->sizeParams( $file->getSize() )->escaped();
-               $row .= '</span>';
-               $row .= '</td>';
-
-               // Uploading user
-               $row .= '<td>';
-               // Hide deleted usernames
-               if ( $file->isDeleted( File::DELETED_USER ) ) {
-                       $row .= '<span class="history-deleted">'
-                               . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
-               } else {
-                       if ( $local ) {
-                               $row .= Linker::userLink( $userId, $userText );
-                               $row .= '<span style="white-space: nowrap;">';
-                               $row .= Linker::userToolLinks( $userId, $userText );
-                               $row .= '</span>';
-                       } else {
-                               $row .= htmlspecialchars( $userText );
-                       }
-               }
-               $row .= '</td>';
-
-               // Don't show deleted descriptions
-               if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
-                       $row .= '<td><span class="history-deleted">' .
-                               $this->msg( 'rev-deleted-comment' )->escaped() . '</span></td>';
-               } else {
-                       $row .= '<td dir="' . $wgContLang->getDir() . '">' .
-                               Linker::formatComment( $description, $this->title ) . '</td>';
-               }
-
-               $rowClass = null;
-               Hooks::run( 'ImagePageFileHistoryLine', array( $this, $file, &$row, &$rowClass ) );
-               $classAttr = $rowClass ? " class='$rowClass'" : '';
-
-               return "<tr{$classAttr}>{$row}</tr>\n";
-       }
-
-       /**
-        * @param File $file
-        * @return string
-        */
-       protected function getThumbForLine( $file ) {
-               $lang = $this->getLanguage();
-               $user = $this->getUser();
-               if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user )
-                       && !$file->isDeleted( File::DELETED_FILE )
-               ) {
-                       $params = array(
-                               'width' => '120',
-                               'height' => '120',
-                       );
-                       $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() );
-
-                       $thumbnail = $file->transform( $params );
-                       $options = array(
-                               'alt' => $this->msg( 'filehist-thumbtext',
-                                       $lang->userTimeAndDate( $timestamp, $user ),
-                                       $lang->userDate( $timestamp, $user ),
-                                       $lang->userTime( $timestamp, $user ) )->text(),
-                               'file-link' => true,
-                       );
-
-                       if ( !$thumbnail ) {
-                               return $this->msg( 'filehist-nothumb' )->escaped();
-                       }
-
-                       return $thumbnail->toHtml( $options );
-               } else {
-                       return $this->msg( 'filehist-nothumb' )->escaped();
-               }
-       }
-
-       /**
-        * @param bool $enable
-        */
-       protected function preventClickjacking( $enable = true ) {
-               $this->preventClickjacking = $enable;
+               return $this->mPage->getFile();
        }
 
        /**
+        * @see WikiFilePage::isLocal
         * @return bool
         */
-       public function getPreventClickjacking() {
-               return $this->preventClickjacking;
-       }
-}
-
-class ImageHistoryPseudoPager extends ReverseChronologicalPager {
-       protected $preventClickjacking = false;
-
-       /**
-        * @var File
-        */
-       protected $mImg;
-
-       /**
-        * @var Title
-        */
-       protected $mTitle;
-
-       /**
-        * @param ImagePage $imagePage
-        */
-       function __construct( $imagePage ) {
-               parent::__construct( $imagePage->getContext() );
-               $this->mImagePage = $imagePage;
-               $this->mTitle = clone $imagePage->getTitle();
-               $this->mTitle->setFragment( '#filehistory' );
-               $this->mImg = null;
-               $this->mHist = array();
-               $this->mRange = array( 0, 0 ); // display range
-       }
-
-       /**
-        * @return Title
-        */
-       function getTitle() {
-               return $this->mTitle;
-       }
-
-       function getQueryInfo() {
-               return false;
+       public function isLocal() {
+               return $this->mPage->isLocal();
        }
 
        /**
-        * @return string
+        * @see WikiFilePage::getDuplicates
+        * @return array|null
         */
-       function getIndexField() {
-               return '';
+       public function getDuplicates() {
+               return $this->mPage->getDuplicates();
        }
 
        /**
-        * @param object $row
-        * @return string
-        */
-       function formatRow( $row ) {
-               return '';
-       }
-
-       /**
-        * @return string
-        */
-       function getBody() {
-               $s = '';
-               $this->doQuery();
-               if ( count( $this->mHist ) ) {
-                       if ( $this->mImg->isLocal() ) {
-                               // Do a batch existence check for user pages and talkpages
-                               $linkBatch = new LinkBatch();
-                               for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
-                                       $file = $this->mHist[$i];
-                                       $user = $file->getUser( 'text' );
-                                       $linkBatch->add( NS_USER, $user );
-                                       $linkBatch->add( NS_USER_TALK, $user );
-                               }
-                               $linkBatch->execute();
-                       }
-
-                       $list = new ImageHistoryList( $this->mImagePage );
-                       # Generate prev/next links
-                       $navLink = $this->getNavigationBar();
-                       $s = $list->beginImageHistoryList( $navLink );
-                       // Skip rows there just for paging links
-                       for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) {
-                               $file = $this->mHist[$i];
-                               $s .= $list->imageHistoryLine( !$file->isOld(), $file );
-                       }
-                       $s .= $list->endImageHistoryList( $navLink );
-
-                       if ( $list->getPreventClickjacking() ) {
-                               $this->preventClickjacking();
-                       }
-               }
-               return $s;
-       }
-
-       function doQuery() {
-               if ( $this->mQueryDone ) {
-                       return;
-               }
-               $this->mImg = $this->mImagePage->getFile(); // ensure loading
-               if ( !$this->mImg->exists() ) {
-                       return;
-               }
-               $queryLimit = $this->mLimit + 1; // limit plus extra row
-               if ( $this->mIsBackwards ) {
-                       // Fetch the file history
-                       $this->mHist = $this->mImg->getHistory( $queryLimit, null, $this->mOffset, false );
-                       // The current rev may not meet the offset/limit
-                       $numRows = count( $this->mHist );
-                       if ( $numRows <= $this->mLimit && $this->mImg->getTimestamp() > $this->mOffset ) {
-                               $this->mHist = array_merge( array( $this->mImg ), $this->mHist );
-                       }
-               } else {
-                       // The current rev may not meet the offset
-                       if ( !$this->mOffset || $this->mImg->getTimestamp() < $this->mOffset ) {
-                               $this->mHist[] = $this->mImg;
-                       }
-                       // Old image versions (fetch extra row for nav links)
-                       $oiLimit = count( $this->mHist ) ? $this->mLimit : $this->mLimit + 1;
-                       // Fetch the file history
-                       $this->mHist = array_merge( $this->mHist,
-                               $this->mImg->getHistory( $oiLimit, $this->mOffset, null, false ) );
-               }
-               $numRows = count( $this->mHist ); // Total number of query results
-               if ( $numRows ) {
-                       # Index value of top item in the list
-                       $firstIndex = $this->mIsBackwards ?
-                               $this->mHist[$numRows - 1]->getTimestamp() : $this->mHist[0]->getTimestamp();
-                       # Discard the extra result row if there is one
-                       if ( $numRows > $this->mLimit && $numRows > 1 ) {
-                               if ( $this->mIsBackwards ) {
-                                       # Index value of item past the index
-                                       $this->mPastTheEndIndex = $this->mHist[0]->getTimestamp();
-                                       # Index value of bottom item in the list
-                                       $lastIndex = $this->mHist[1]->getTimestamp();
-                                       # Display range
-                                       $this->mRange = array( 1, $numRows - 1 );
-                               } else {
-                                       # Index value of item past the index
-                                       $this->mPastTheEndIndex = $this->mHist[$numRows - 1]->getTimestamp();
-                                       # Index value of bottom item in the list
-                                       $lastIndex = $this->mHist[$numRows - 2]->getTimestamp();
-                                       # Display range
-                                       $this->mRange = array( 0, $numRows - 2 );
-                               }
-                       } else {
-                               # 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 = '';
-                               # Index value of bottom item in the list
-                               $lastIndex = $this->mIsBackwards ?
-                                       $this->mHist[0]->getTimestamp() : $this->mHist[$numRows - 1]->getTimestamp();
-                               # Display range
-                               $this->mRange = array( 0, $numRows - 1 );
-                       }
-               } else {
-                       $firstIndex = '';
-                       $lastIndex = '';
-                       $this->mPastTheEndIndex = '';
-               }
-               if ( $this->mIsBackwards ) {
-                       $this->mIsFirst = ( $numRows < $queryLimit );
-                       $this->mIsLast = ( $this->mOffset == '' );
-                       $this->mLastShown = $firstIndex;
-                       $this->mFirstShown = $lastIndex;
-               } else {
-                       $this->mIsFirst = ( $this->mOffset == '' );
-                       $this->mIsLast = ( $numRows < $queryLimit );
-                       $this->mLastShown = $lastIndex;
-                       $this->mFirstShown = $firstIndex;
-               }
-               $this->mQueryDone = true;
-       }
-
-       /**
-        * @param bool $enable
-        */
-       protected function preventClickjacking( $enable = true ) {
-               $this->preventClickjacking = $enable;
-       }
-
-       /**
-        * @return bool
+        * @see WikiFilePage::getForeignCategories
+        * @return TitleArray|Title[]
         */
-       public function getPreventClickjacking() {
-               return $this->preventClickjacking;
+       public function getForeignCategories() {
+               $this->mPage->getForeignCategories();
        }
 
 }
index c02f975..b7eef8f 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /**
- * Abstract class for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
+ * Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
  */
 interface Page {
 }
index 5f7e89c..f947285 100644 (file)
@@ -1113,15 +1113,15 @@ class Parser {
                                        $line = substr( $line, 1 );
                                }
 
+                               // Implies both are valid for table headings.
                                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 );
+                               # by earlier parser steps.
+                               $cells = explode( '||', $line );
 
                                $outLine = '';
 
index e6d5274..0e8d76d 100644 (file)
@@ -599,6 +599,15 @@ class ParserOptions {
                $this->initialiseFromUser( $user, $lang );
        }
 
+       /**
+        * Get a ParserOptions object for an anonymous user
+        * @return ParserOptions
+        */
+       public static function newFromAnon() {
+               global $wgContLang;
+               return new ParserOptions( new User, $wgContLang );
+       }
+
        /**
         * Get a ParserOptions object from a given user.
         * Language will be taken from $wgLang.
index 817f153..4ca3a87 100644 (file)
@@ -237,8 +237,6 @@ class Preprocessor_DOM extends Preprocessor {
                $inHeading = false;
                // True if there are no more greater-than (>) signs right of $i
                $noMoreGT = false;
-               // Map of tag name => true if there are no more closing tags of given type right of $i
-               $noMoreClosingTag = array();
                // True to ignore all input up to the next <onlyinclude>
                $findOnlyinclude = $enableOnlyinclude;
                // Do a line-start run without outputting an LF character
@@ -459,21 +457,17 @@ class Preprocessor_DOM extends Preprocessor {
                                } else {
                                        $attrEnd = $tagEndPos;
                                        // Find closing tag
-                                       if (
-                                               !isset( $noMoreClosingTag[$name] ) &&
-                                               preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
+                                       if ( preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
                                                        $text, $matches, PREG_OFFSET_CAPTURE, $tagEndPos + 1 )
                                        ) {
                                                $inner = substr( $text, $tagEndPos + 1, $matches[0][1] - $tagEndPos - 1 );
                                                $i = $matches[0][1] + strlen( $matches[0][0] );
                                                $close = '<close>' . htmlspecialchars( $matches[0][0] ) . '</close>';
                                        } else {
-                                               // No end tag -- don't match the tag, treat opening tag as literal and resume parsing.
-                                               $i = $tagEndPos + 1;
-                                               $accum .= htmlspecialchars( substr( $text, $tagStartPos, $tagEndPos + 1 - $tagStartPos ) );
-                                               // Cache results, otherwise we have O(N^2) performance for input like <foo><foo><foo>...
-                                               $noMoreClosingTag[$name] = true;
-                                               continue;
+                                               // No end tag -- let it run out to the end of the text.
+                                               $inner = substr( $text, $tagEndPos + 1 );
+                                               $i = $lengthText;
+                                               $close = '';
                                        }
                                }
                                // <includeonly> and <noinclude> just become <ignore> tags
index 28c49fd..50eaefb 100644 (file)
@@ -160,8 +160,6 @@ class Preprocessor_Hash extends Preprocessor {
                $inHeading = false;
                // True if there are no more greater-than (>) signs right of $i
                $noMoreGT = false;
-               // Map of tag name => true if there are no more closing tags of given type right of $i
-               $noMoreClosingTag = array();
                // True to ignore all input up to the next <onlyinclude>
                $findOnlyinclude = $enableOnlyinclude;
                // Do a line-start run without outputting an LF character
@@ -382,21 +380,17 @@ class Preprocessor_Hash extends Preprocessor {
                                } else {
                                        $attrEnd = $tagEndPos;
                                        // Find closing tag
-                                       if (
-                                               !isset( $noMoreClosingTag[$name] ) &&
-                                               preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
+                                       if ( preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
                                                        $text, $matches, PREG_OFFSET_CAPTURE, $tagEndPos + 1 )
                                        ) {
                                                $inner = substr( $text, $tagEndPos + 1, $matches[0][1] - $tagEndPos - 1 );
                                                $i = $matches[0][1] + strlen( $matches[0][0] );
                                                $close = $matches[0][0];
                                        } else {
-                                               // No end tag -- don't match the tag, treat opening tag as literal and resume parsing.
-                                               $i = $tagEndPos + 1;
-                                               $accum->addLiteral( substr( $text, $tagStartPos, $tagEndPos + 1 - $tagStartPos ) );
-                                               // Cache results, otherwise we have O(N^2) performance for input like <foo><foo><foo>...
-                                               $noMoreClosingTag[$name] = true;
-                                               continue;
+                                               // No end tag -- let it run out to the end of the text.
+                                               $inner = substr( $text, $tagEndPos + 1 );
+                                               $i = $lengthText;
+                                               $close = null;
                                        }
                                }
                                // <includeonly> and <noinclude> just become <ignore> tags
index 9d5fe38..1f35e1f 100644 (file)
@@ -272,7 +272,7 @@ class ResourceLoaderImage {
         */
        protected function variantize( $variantConf, ResourceLoaderContext $context ) {
                $dom = new DomDocument;
-               $dom->load( $this->getPath( $context ) );
+               $dom->loadXml( file_get_contents( $this->getPath( $context ) ) );
                $root = $dom->documentElement;
                $wrapper = $dom->createElement( 'g' );
                while ( $root->firstChild ) {
index 113fc84..bcd159f 100644 (file)
@@ -180,6 +180,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        /**
         * @since 1.27
         * @param LoggerInterface $logger
+        * @return null
         */
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
@@ -410,8 +411,8 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         * This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
         * To save the data, use saveFileDependencies().
         *
-        * @param string $skin Skin name
-        * @param array $deps Array of file names
+        * @param ResourceLoaderContext $context
+        * @param string[] $files Array of file names
         */
        public function setFileDependencies( ResourceLoaderContext $context, $files ) {
                $vary = $context->getSkin() . '|' . $context->getLanguage();
index e1df6d9..490a4ab 100644 (file)
@@ -30,11 +30,17 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
         * @return array
         */
        public function getStyles( ResourceLoaderContext $context ) {
-               $logo = $this->getConfig()->get( 'Logo' );
-               $logoHD = $this->getConfig()->get( 'LogoHD' );
+               $conf = $this->getConfig();
+               $logo = $conf->get( 'Logo' );
+               $logoHD = $conf->get( 'LogoHD' );
+
+               $logo1 = OutputPage::transformResourcePath( $conf, $logo );
+               $logo15 = OutputPage::transformResourcePath( $conf, $logoHD['1.5x'] );
+               $logo2 = OutputPage::transformResourcePath( $conf, $logoHD['2x'] );
+
                $styles = parent::getStyles( $context );
                $styles['all'][] = '.mw-wiki-logo { background-image: ' .
-                       CSSMin::buildUrlValue( $logo ) .
+                       CSSMin::buildUrlValue( $logo1 ) .
                        '; }';
                if ( $logoHD ) {
                        if ( isset( $logoHD['1.5x'] ) ) {
@@ -44,7 +50,7 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                                        '(min-resolution: 1.5dppx), ' .
                                        '(min-resolution: 144dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
-                               CSSMin::buildUrlValue( $logoHD['1.5x'] ) . ';' .
+                               CSSMin::buildUrlValue( $logo15 ) . ';' .
                                'background-size: 135px auto; }';
                        }
                        if ( isset( $logoHD['2x'] ) ) {
@@ -54,7 +60,7 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
                                        '(min-resolution: 2dppx), ' .
                                        '(min-resolution: 192dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
-                               CSSMin::buildUrlValue( $logoHD['2x'] ) . ';' .
+                               CSSMin::buildUrlValue( $logo2 ) . ';' .
                                'background-size: 135px auto; }';
                        }
                }
index 3c8d56e..81b850a 100644 (file)
@@ -296,6 +296,15 @@ class SearchEngine {
         * @param int[]|null $namespaces
         */
        function setNamespaces( $namespaces ) {
+               if ( $namespaces ) {
+                       // Filter namespaces to only keep valid ones
+                       $validNs = $this->searchableNamespaces();
+                       $namespaces = array_filter( $namespaces, function( $ns ) use( $validNs ) {
+                               return $ns < 0 || isset( $validNs[$ns] );
+                       } );
+               } else {
+                       $namespaces = array();
+               }
                $this->namespaces = $namespaces;
        }
 
@@ -570,6 +579,201 @@ class SearchEngine {
        public function textAlreadyUpdatedForIndex() {
                return false;
        }
+
+       /**
+        * Makes search simple string if it was namespaced.
+        * Sets namespaces of the search to namespaces extracted from string.
+        * @param string $search
+        * @return $string Simplified search string
+        */
+       protected function normalizeNamespaces( $search ) {
+               // Find a Title which is not an interwiki and is in NS_MAIN
+               $title = Title::newFromText( $search );
+               $ns = $this->namespaces;
+               if ( $title && !$title->isExternal() ) {
+                       $ns = array( $title->getNamespace() );
+                       $search = $title->getText();
+                       if ( $ns[0] == NS_MAIN ) {
+                               $ns = $this->namespaces; // no explicit prefix, use default namespaces
+                               Hooks::run( 'PrefixSearchExtractNamespace', array( &$ns, &$search ) );
+                       }
+               } else {
+                       $title = Title::newFromText( $search . 'Dummy' );
+                       if ( $title && $title->getText() == 'Dummy'
+                                       && $title->getNamespace() != NS_MAIN
+                                       && !$title->isExternal() )
+                       {
+                               $ns = array( $title->getNamespace() );
+                               $search = '';
+                       } else {
+                               Hooks::run( 'PrefixSearchExtractNamespace', array( &$ns, &$search ) );
+                       }
+               }
+
+               $ns = array_map( function( $space ) {
+                       return $space == NS_MEDIA ? NS_FILE : $space;
+               }, $ns );
+
+               $this->setNamespaces( $ns );
+               return $search;
+       }
+
+       /**
+        * Perform a completion search.
+        * Does not resolve namespaces and does not check variants.
+        * Search engine implementations may want to override this function.
+        * @param string $search
+        * @return SearchSuggestionSet
+        */
+       protected function completionSearchBackend( $search ) {
+               $results = array();
+
+               $search = trim( $search );
+
+               if ( !in_array( NS_SPECIAL, $this->namespaces ) && // We do not run hook on Special: search
+                        !Hooks::run( 'PrefixSearchBackend',
+                               array( $this->namespaces, $search, $this->limit, &$results, $this->offset )
+               ) ) {
+                       // False means hook worked.
+                       // FIXME: Yes, the API is weird. That's why it is going to be deprecated.
+
+                       return SearchSuggestionSet::fromStrings( $results );
+               } else {
+                       // Hook did not do the job, use default simple search
+                       $results = $this->simplePrefixSearch( $search );
+                       return SearchSuggestionSet::fromTitles( $results );
+               }
+       }
+
+       /**
+        * Perform a completion search.
+        * @param string $search
+        * @return SearchSuggestionSet
+        */
+       public function completionSearch( $search ) {
+               if ( trim( $search ) === '' ) {
+                       return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
+               }
+               $search = $this->normalizeNamespaces( $search );
+               return $this->processCompletionResults( $search, $this->completionSearchBackend( $search ) );
+       }
+
+       /**
+        * Perform a completion search with variants.
+        * @param string $search
+        * @return SearchSuggestionSet
+        */
+       public function completionSearchWithVariants( $search ) {
+               if ( trim( $search ) === '' ) {
+                       return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
+               }
+               $search = $this->normalizeNamespaces( $search );
+
+               $results = $this->completionSearchBackend( $search );
+               $fallbackLimit = $this->limit - $results->getSize();
+               if ( $fallbackLimit > 0 ) {
+                       global $wgContLang;
+
+                       $fallbackSearches = $wgContLang->autoConvertToAllVariants( $search );
+                       $fallbackSearches = array_diff( array_unique( $fallbackSearches ), array( $search ) );
+
+                       foreach ( $fallbackSearches as $fbs ) {
+                               $this->setLimitOffset( $fallbackLimit );
+                               $fallbackSearchResult = $this->completionSearch( $fbs );
+                               $results->appendAll( $fallbackSearchResult );
+                               $fallbackLimit -= count( $fallbackSearchResult );
+                               if ( $fallbackLimit <= 0 ) {
+                                       break;
+                               }
+                       }
+               }
+               return $this->processCompletionResults( $search, $results );
+       }
+
+       /**
+        * Extract titles from completion results
+        * @param SearchSuggestionSet $completionResults
+        * @return Title[]
+        */
+       public function extractTitles( SearchSuggestionSet $completionResults ) {
+               return $completionResults->map( function( SearchSuggestion $sugg ) {
+                       return $sugg->getSuggestedTitle();
+               } );
+       }
+
+       /**
+        * Process completion search results.
+        * Resolves the titles and rescores.
+        * @param SearchSuggestionSet $suggestions
+        * @return SearchSuggestionSet
+        */
+       protected function processCompletionResults( $search, SearchSuggestionSet $suggestions ) {
+               if ( $suggestions->getSize() == 0 ) {
+                       // If we don't have anything, don't bother
+                       return $suggestions;
+               }
+               $search = trim( $search );
+               // preload the titles with LinkBatch
+               $titles = $suggestions->map( function( SearchSuggestion $sugg ) {
+                       return $sugg->getSuggestedTitle();
+               } );
+               $lb = new LinkBatch( $titles );
+               $lb->setCaller( __METHOD__ );
+               $lb->execute();
+
+               $results = $suggestions->map( function( SearchSuggestion $sugg ) {
+                       return $sugg->getSuggestedTitle()->getPrefixedText();
+               } );
+
+               // Rescore results with an exact title match
+               $rescorer = new SearchExactMatchRescorer();
+               $rescoredResults = $rescorer->rescore( $search, $this->namespaces, $results, $this->limit );
+
+               if ( count( $rescoredResults ) > 0 ) {
+                       $found = array_search( $rescoredResults[0], $results );
+                       if ( $found === false ) {
+                               // If the first result is not in the previous array it
+                               // means that we found a new exact match
+                               $exactMatch = SearchSuggestion::fromTitle( 0, Title::newFromText( $rescoredResults[0] ) );
+                               $suggestions->prepend( $exactMatch );
+                               $suggestions->shrink( $this->limit );
+                       } else {
+                               // if the first result is not the same we need to rescore
+                               if ( $found > 0 ) {
+                                       $suggestions->rescore( $found );
+                               }
+                       }
+               }
+
+               return $suggestions;
+       }
+
+       /**
+        * Simple prefix search for subpages.
+        * @param string $search
+        * @return Title[]
+        */
+       public function defaultPrefixSearch( $search ) {
+               if ( trim( $search ) === '' ) {
+                       return array();
+               }
+
+               $search = $this->normalizeNamespaces( $search );
+               return $this->simplePrefixSearch( $search );
+       }
+
+       /**
+        * Call out to simple search backend.
+        * Defaults to TitlePrefixSearch.
+        * @param string $search
+        * @return Title[]
+        */
+       protected function simplePrefixSearch( $search ) {
+               // Use default database prefix search
+               $backend = new TitlePrefixSearch;
+               return $backend->defaultSearchBackend( $this->namespaces, $search, $this->limit, $this->offset );
+       }
+
 }
 
 /**
diff --git a/includes/search/SearchSuggestion.php b/includes/search/SearchSuggestion.php
new file mode 100644 (file)
index 0000000..cd9062b
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * Search suggestion
+ *
+ * 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
+ *
+ */
+
+/**
+ * A search suggestion
+ *
+ */
+class SearchSuggestion {
+       /**
+        * @var string the suggestion
+        */
+       private $text;
+
+       /**
+        * @var string the suggestion URL
+        */
+       private $url;
+
+       /**
+        * @var Title|null the suggested title
+        */
+       private $suggestedTitle;
+
+       /**
+        * NOTE: even if suggestedTitle is a redirect suggestedTitleID
+        * is the ID of the target page.
+        * @var int|null the suggested title ID
+        */
+       private $suggestedTitleID;
+
+       /**
+        * @var float|null The suggestion score
+        */
+       private $score;
+
+       /**
+        * Construct a new suggestion
+        * @param float $score the suggestion score
+        * @param string $text|null the suggestion text
+        * @param Title|null $suggestedTitle the suggested title
+        * @param int|null $suggestedTitleID the suggested title ID
+        */
+       public function __construct( $score, $text = null, Title $suggestedTitle = null,
+                       $suggestedTitleID = null ) {
+               $this->score = $score;
+               $this->text = $text;
+               if ( $suggestedTitle ) {
+                       $this->setSuggestedTitle( $suggestedTitle );
+               }
+               $this->suggestedTitleID = $suggestedTitleID;
+       }
+
+       /**
+        * The suggestion text
+        * @return string
+        */
+       public function getText() {
+               return $this->text;
+       }
+
+       /**
+        * Set the suggestion text.
+        * @param string $text
+        * @param bool $setTitle Should we also update the title?
+        */
+       public function setText( $text, $setTitle = true ) {
+               $this->text = $text;
+               if ( $setTitle && $text ) {
+                       $this->setSuggestedTitle( Title::makeTitle( 0, $text ) );
+               }
+       }
+
+       /**
+        * Title object in the case this suggestion is based on a title.
+        * May return null if the suggestion is not a Title.
+        * @return Title|null
+        */
+       public function getSuggestedTitle() {
+               return $this->suggestedTitle;
+       }
+
+       /**
+        * Set the suggested title
+        * @param Title|null $title
+        */
+       public function setSuggestedTitle( Title $title = null ) {
+               $this->suggestedTitle = $title;
+               if ( $title !== null ) {
+                       $this->url = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
+               }
+       }
+
+       /**
+        * Title ID in the case this suggestion is based on a title.
+        * May return null if the suggestion is not a Title.
+        * @return int|null
+        */
+       public function getSuggestedTitleID() {
+               return $this->suggestedTitleID;
+       }
+
+       /**
+        * Set the suggested title ID
+        * @param int|null $suggestedTitleID
+        */
+       public function setSuggestedTitleID( $suggestedTitleID = null ) {
+               $this->suggestedTitleID = $suggestedTitleID;
+       }
+
+       /**
+        * Suggestion score
+        * @return float Suggestion score
+        */
+       public function getScore() {
+               return $this->score;
+       }
+
+       /**
+        * Set the suggestion score
+        * @param float $score
+        */
+       public function setScore( $score ) {
+               $this->score = $score;
+       }
+
+       /**
+        * Suggestion URL, can be the link to the Title or maybe in the
+        * future a link to the search results for this search suggestion.
+        * @return string Suggestion URL
+        */
+       public function getURL() {
+               return $this->url;
+       }
+
+       /**
+        * Set the suggestion URL
+        * @param string $url
+        */
+       public function setURL( $url ) {
+               $this->url = $url;
+       }
+
+       /**
+        * Create suggestion from Title
+        * @param float $score Suggestions score
+        * @param Title $title
+        * @return SearchSuggestion
+        */
+       public static function fromTitle( $score, Title $title ) {
+               return new self( $score, $title->getPrefixedText(), $title, $title->getArticleID() );
+       }
+
+       /**
+        * Create suggestion from text
+        * Will also create a title if text if not empty.
+        * @param float $score Suggestions score
+        * @param string $text
+        * @return SearchSuggestion
+        */
+       public static function fromText( $score, $text ) {
+               $suggestion = new self( $score, $text );
+               if ( $text ) {
+                       $suggestion->setSuggestedTitle( Title::makeTitle( 0, $text ) );
+               }
+               return $suggestion;
+       }
+
+}
diff --git a/includes/search/SearchSuggestionSet.php b/includes/search/SearchSuggestionSet.php
new file mode 100644 (file)
index 0000000..a1f9a04
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+
+/**
+ * Search suggestion sets
+ *
+ * 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
+ *
+ */
+
+/**
+ * A set of search suggestions.
+ * The set is always ordered by score, with the best match first.
+ */
+class SearchSuggestionSet {
+       /**
+        * @var SearchSuggestion[]
+        */
+       private $suggestions = array();
+
+       /**
+        *
+        * @var array
+        */
+       private $pageMap = array();
+
+       /**
+        * Builds a new set of suggestions.
+        *
+        * NOTE: the array should be sorted by score (higher is better),
+        * in descending order.
+        * SearchSuggestionSet will not try to re-order this input array.
+        * Providing an unsorted input array is a mistake and will lead to
+        * unexpected behaviors.
+        *
+        * @param SearchSuggestion[] $suggestions (must be sorted by score)
+        */
+       public function __construct( array $suggestions ) {
+               foreach ( $suggestions as $suggestion ) {
+                       $pageID = $suggestion->getSuggestedTitleID();
+                       if ( $pageID && empty( $this->pageMap[$pageID] ) ) {
+                               $this->pageMap[$pageID] = true;
+                       }
+                       $this->suggestions[] = $suggestion;
+               }
+       }
+
+       /**
+        * Get the list of suggestions.
+        * @return SearchSuggestion[]
+        */
+       public function getSuggestions() {
+               return $this->suggestions;
+       }
+
+       /**
+        * Call array_map on the suggestions array
+        * @param callback $callback
+        * @return array
+        */
+       public function map( $callback ) {
+               return array_map( $callback, $this->suggestions );
+       }
+
+       /**
+        * Add a new suggestion at the end.
+        * If the score of the new suggestion is greater than the worst one,
+        * the new suggestion score will be updated (worst - 1).
+        *
+        * @param SearchSuggestion $suggestion
+        */
+       public function append( SearchSuggestion $suggestion ) {
+               $pageID = $suggestion->getSuggestedTitleID();
+               if ( $pageID && isset( $this->pageMap[$pageID] ) ) {
+                       return;
+               }
+               if ( $this->getSize() > 0 && $suggestion->getScore() >= $this->getWorstScore() ) {
+                       $suggestion->setScore( $this->getWorstScore() - 1 );
+               }
+               $this->suggestions[] = $suggestion;
+               if ( $pageID ) {
+                       $this->pageMap[$pageID] = true;
+               }
+       }
+
+       /**
+        * Add suggestion set to the end of the current one.
+        * @param SearchSuggestionSet $set
+        */
+       public function appendAll( SearchSuggestionSet $set ) {
+               foreach ( $set->getSuggestions() as $sugg ) {
+                       $this->append( $sugg );
+               }
+       }
+
+       /**
+        * Move the suggestion at index $key to the first position
+        */
+       public function rescore( $key ) {
+               $removed = array_splice( $this->suggestions, $key, 1 );
+               unset( $this->pageMap[$removed[0]->getSuggestedTitleID()] );
+               $this->prepend( $removed[0] );
+       }
+
+       /**
+        * Add a new suggestion at the top. If the new suggestion score
+        * is lower than the best one its score will be updated (best + 1)
+        * @param SearchSuggestion $suggestion
+        */
+       public function prepend( SearchSuggestion $suggestion ) {
+               $pageID = $suggestion->getSuggestedTitleID();
+               if ( $pageID && isset( $this->pageMap[$pageID] ) ) {
+                       return;
+               }
+               if ( $this->getSize() > 0 && $suggestion->getScore() <= $this->getBestScore() ) {
+                       $suggestion->setScore( $this->getBestScore() + 1 );
+               }
+               array_unshift( $this->suggestions,  $suggestion );
+               if ( $pageID ) {
+                       $this->pageMap[$pageID] = true;
+               }
+       }
+
+       /**
+        * @return float the best score in this suggestion set
+        */
+       public function getBestScore() {
+               if ( empty( $this->suggestions ) ) {
+                       return 0;
+               }
+               return $this->suggestions[0]->getScore();
+       }
+
+       /**
+        * @return float the worst score in this set
+        */
+       public function getWorstScore() {
+               if ( empty( $this->suggestions ) ) {
+                       return 0;
+               }
+               return end( $this->suggestions )->getScore();
+       }
+
+       /**
+        * @return int the number of suggestion in this set
+        */
+       public function getSize() {
+               return count( $this->suggestions );
+       }
+
+       /**
+        * Remove any extra elements in the suggestions set
+        * @param int $limit the max size of this set.
+        */
+       public function shrink( $limit ) {
+               if ( count( $this->suggestions ) > $limit ) {
+                       $this->suggestions = array_slice( $this->suggestions, 0, $limit );
+               }
+       }
+
+       /**
+        * Builds a new set of suggestion based on a title array.
+        * Useful when using a backend that supports only Titles.
+        *
+        * NOTE: Suggestion scores will be generated.
+        *
+        * @param Title[] $titles
+        * @return SearchSuggestionSet
+        */
+       public static function fromTitles( array $titles ) {
+               $score = count( $titles );
+               $suggestions = array_map( function( $title ) use ( &$score ) {
+                       return SearchSuggestion::fromTitle( $score--, $title );
+               }, $titles );
+               return new SearchSuggestionSet( $suggestions );
+       }
+
+       /**
+        * Builds a new set of suggestion based on a string array.
+        *
+        * NOTE: Suggestion scores will be generated.
+        *
+        * @param string[] $titles
+        * @return SearchSuggestionSet
+        */
+       public static function fromStrings( array $titles ) {
+               $score = count( $titles );
+               $suggestions = array_map( function( $title ) use ( &$score ) {
+                       return SearchSuggestion::fromText( $score--, $title );
+               }, $titles );
+               return new SearchSuggestionSet( $suggestions );
+       }
+
+
+       /**
+        * @return SearchSuggestionSet an empty suggestion set
+        */
+       public static function emptySuggestionSet() {
+               return new SearchSuggestionSet( array() );
+       }
+}
index 2d01d1d..f989cbc 100644 (file)
@@ -104,11 +104,14 @@ class CookieSessionProvider extends SessionProvider {
 
        public function provideSessionInfo( WebRequest $request ) {
                $info = array(
-                       'id' => $this->getCookie( $request, $this->params['sessionName'], '' )
+                       'id' => $this->getCookie( $request, $this->params['sessionName'], '' ),
+                       'provider' => $this,
+                       'forceHTTPS' => $this->getCookie( $request, 'forceHTTPS', '', false )
                );
                if ( !SessionManager::validateSessionId( $info['id'] ) ) {
                        unset( $info['id'] );
                }
+               $info['persisted'] = isset( $info['id'] );
 
                list( $userId, $userName, $token ) = $this->getUserInfoFromCookies( $request );
                if ( $userId !== null ) {
@@ -128,21 +131,22 @@ class CookieSessionProvider extends SessionProvider {
                                        return null;
                                }
                                $info['userInfo'] = $userInfo->verified();
-                       } elseif ( isset( $info['id'] ) ) { // No point if no session ID
+                       } elseif ( isset( $info['id'] ) ) {
                                $info['userInfo'] = $userInfo;
+                       } else {
+                               // No point in returning, loadSessionInfoFromStore() will
+                               // reject it anyway.
+                               return null;
                        }
-               }
-
-               if ( !$info ) {
+               } elseif ( isset( $info['id'] ) ) {
+                       // No UserID cookie, so insist that the session is anonymous.
+                       $info['userInfo'] = UserInfo::newAnonymous();
+               } else {
+                       // No session ID and no user is the same as an empty session, so
+                       // there's no point.
                        return null;
                }
 
-               $info += array(
-                       'provider' => $this,
-                       'persisted' => isset( $info['id'] ),
-                       'forceHTTPS' => $this->getCookie( $request, 'forceHTTPS', '', false )
-               );
-
                return new SessionInfo( $this->priority, $info );
        }
 
index d21bea9..4dea274 100644 (file)
@@ -123,6 +123,12 @@ class PHPSessionHandler {
                ini_set( 'session.use_cookies', 0 );
                ini_set( 'session.use_trans_sid', 0 );
 
+               // T124510: Disable automatic PHP session related cache headers.
+               // MediaWiki adds it's own headers and the default PHP behavior may
+               // set headers such as 'Pragma: no-cache' that cause problems with
+               // some user agents.
+               session_cache_limiter( '' );
+
                // Also set a sane serialization handler
                \Wikimedia\PhpSessionSerializer::setSerializeHandler();
 
index 840baa7..4ad69ae 100644 (file)
@@ -314,6 +314,58 @@ final class Session implements \Countable, \Iterator {
                }
        }
 
+       /**
+        * Fetch a CSRF token from the session
+        *
+        * Note that this does not persist the session, which you'll probably want
+        * to do if you want the token to actually be useful.
+        *
+        * @param string|string[] $salt Token salt
+        * @param string $key Token key
+        * @return MediaWiki\\Session\\SessionToken
+        */
+       public function getToken( $salt = '', $key = 'default' ) {
+               $new = false;
+               $secrets = $this->get( 'wsTokenSecrets' );
+               if ( !is_array( $secrets ) ) {
+                       $secrets = array();
+               }
+               if ( isset( $secrets[$key] ) && is_string( $secrets[$key] ) ) {
+                       $secret = $secrets[$key];
+               } else {
+                       $secret = \MWCryptRand::generateHex( 32 );
+                       $secrets[$key] = $secret;
+                       $this->set( 'wsTokenSecrets', $secrets );
+                       $new = true;
+               }
+               if ( is_array( $salt ) ) {
+                       $salt = join( '|', $salt );
+               }
+               return new Token( $secret, (string)$salt, $new );
+       }
+
+       /**
+        * Remove a CSRF token from the session
+        *
+        * The next call to self::getToken() with $key will generate a new secret.
+        *
+        * @param string $key Token key
+        */
+       public function resetToken( $key = 'default' ) {
+               $secrets = $this->get( 'wsTokenSecrets' );
+               if ( is_array( $secrets ) && isset( $secrets[$key] ) ) {
+                       unset( $secrets[$key] );
+                       $this->set( 'wsTokenSecrets', $secrets );
+               }
+       }
+
+       /**
+        * Remove all CSRF tokens from the session
+        */
+       public function resetAllTokens() {
+               $this->remove( 'wsTokenSecrets' );
+       }
+
        /**
         * Delay automatic saving while multiple updates are being made
         *
index 95c6f0c..2bff173 100644 (file)
@@ -23,7 +23,7 @@
 
 namespace MediaWiki\Session;
 
-use BagOStuff;
+use CachedBagOStuff;
 use Psr\Log\LoggerInterface;
 use User;
 use WebRequest;
@@ -64,7 +64,7 @@ final class SessionBackend {
        /** @var string Used to detect subarray modifications */
        private $dataHash = null;
 
-       /** @var BagOStuff */
+       /** @var CachedBagOStuff */
        private $store;
 
        /** @var LoggerInterface */
@@ -97,12 +97,12 @@ final class SessionBackend {
        /**
         * @param SessionId $id Session ID object
         * @param SessionInfo $info Session info to populate from
-        * @param BagOStuff $store Backend data store
+        * @param CachedBagOStuff $store Backend data store
         * @param LoggerInterface $logger
         * @param int $lifetime Session data lifetime in seconds
         */
        public function __construct(
-               SessionId $id, SessionInfo $info, BagOStuff $store, LoggerInterface $logger, $lifetime
+               SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger, $lifetime
        ) {
                $phpSessionHandling = \RequestContext::getMain()->getConfig()->get( 'PHPSessionHandling' );
                $this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
@@ -262,6 +262,7 @@ final class SessionBackend {
                if ( !$this->persist ) {
                        $this->persist = true;
                        $this->forcePersist = true;
+                       $this->metaDirty = true;
                        $this->logger->debug( "SessionBackend $this->id force-persist due to persist()" );
                        $this->autosave();
                } else {
@@ -543,7 +544,7 @@ final class SessionBackend {
                // Ensure the user has a token
                // @codeCoverageIgnoreStart
                $anon = $this->user->isAnon();
-               if ( !$anon && !$this->user->getToken() ) {
+               if ( !$anon && !$this->user->getToken( false ) ) {
                        $this->logger->debug(
                                "SessionBackend $this->id creating token for user {$this->user} on save"
                        );
@@ -595,12 +596,13 @@ final class SessionBackend {
                        'provider' => (string)$this->provider,
                        'providerMetadata' => $this->providerMetadata,
                        'userId' => $anon ? 0 : $this->user->getId(),
-                       'userName' => $anon ? null : $this->user->getName(),
+                       'userName' => User::isValidUserName( $this->user->getName() ) ? $this->user->getName() : null,
                        'userToken' => $anon ? null : $this->user->getToken(),
                        'remember' => !$anon && $this->remember,
                        'forceHTTPS' => $this->forceHTTPS,
                        'expires' => time() + $this->lifetime,
                        'loggedOut' => $this->loggedOut,
+                       'persisted' => $this->persist,
                );
 
                \Hooks::run( 'SessionMetadata', array( $this, &$metadata, $this->requests ) );
@@ -617,7 +619,8 @@ final class SessionBackend {
                                'data' => $this->data,
                                'metadata' => $metadata,
                        ),
-                       $metadata['expires']
+                       $metadata['expires'],
+                       $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY
                );
 
                $this->metaDirty = false;
@@ -643,7 +646,6 @@ final class SessionBackend {
                        ) {
                                $this->logger->debug( "SessionBackend $this->id: Taking over PHP session" );
                                session_id( (string)$this->id );
-                               \MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
                                \MediaWiki\quietCall( 'session_start' );
                        }
                }
index ecc4e54..f03260f 100644 (file)
@@ -25,6 +25,7 @@ namespace MediaWiki\Session;
 
 use Psr\Log\LoggerInterface;
 use BagOStuff;
+use CachedBagOStuff;
 use Config;
 use FauxRequest;
 use Language;
@@ -54,7 +55,7 @@ final class SessionManager implements SessionManagerInterface {
        /** @var Config */
        private $config;
 
-       /** @var BagOStuff|null */
+       /** @var CachedBagOStuff|null */
        private $store;
 
        /** @var SessionProvider[] */
@@ -165,11 +166,12 @@ final class SessionManager implements SessionManagerInterface {
                                        '$options[\'store\'] must be an instance of BagOStuff'
                                );
                        }
-                       $this->store = $options['store'];
+                       $store = $options['store'];
                } else {
-                       $this->store = \ObjectCache::getInstance( $this->config->get( 'SessionCacheType' ) );
-                       $this->store->setLogger( $this->logger );
+                       $store = \ObjectCache::getInstance( $this->config->get( 'SessionCacheType' ) );
+                       $store->setLogger( $this->logger );
                }
+               $this->store = $store instanceof CachedBagOStuff ? $store : new CachedBagOStuff( $store );
 
                register_shutdown_function( array( $this, 'shutdown' ) );
        }
@@ -483,11 +485,7 @@ final class SessionManager implements SessionManagerInterface {
                        // @codeCoverageIgnoreEnd
                }
 
-               # Notify hooks (e.g. Newuserlog)
-               \Hooks::run( 'AuthPluginAutoCreate', array( $user ) );
-               \Hooks::run( 'LocalUserCreated', array( $user, true ) );
-
-               # Notify AuthPlugin too
+               # Notify AuthPlugin
                $tmpUser = $user;
                $wgAuth->initUser( $tmpUser, true );
                if ( $tmpUser !== $user ) {
@@ -495,6 +493,10 @@ final class SessionManager implements SessionManagerInterface {
                                get_class( $wgAuth ) . '::initUser() replaced the user object' );
                }
 
+               # Notify hooks (e.g. Newuserlog)
+               \Hooks::run( 'AuthPluginAutoCreate', array( $user ) );
+               \Hooks::run( 'LocalUserCreated', array( $user, true ) );
+
                $user->saveSettings();
 
                # Update user count
@@ -518,13 +520,6 @@ final class SessionManager implements SessionManagerInterface {
        public function preventSessionsForUser( $username ) {
                $this->preventUsers[$username] = true;
 
-               // Reset the user's token to kill existing sessions
-               $user = User::newFromName( $username );
-               if ( $user && $user->getToken() ) {
-                       $user->setToken( true );
-                       $user->saveSettings();
-               }
-
                // Instruct the session providers to kill any other sessions too.
                foreach ( $this->getProviders() as $provider ) {
                        $provider->preventSessionsForUser( $username );
@@ -801,6 +796,9 @@ final class SessionManager implements SessionManagerInterface {
                        if ( !empty( $metadata['forceHTTPS'] ) && !$info->forceHTTPS() ) {
                                $newParams['forceHTTPS'] = true;
                        }
+                       if ( !empty( $metadata['persisted'] ) && !$info->wasPersisted() ) {
+                               $newParams['persisted'] = true;
+                       }
 
                        if ( !$info->isIdSafe() ) {
                                $newParams['idIsSafe'] = true;
diff --git a/includes/session/Token.php b/includes/session/Token.php
new file mode 100644 (file)
index 0000000..9b4a73c
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+/**
+ * MediaWiki session token
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Session
+ */
+
+namespace MediaWiki\Session;
+
+/**
+ * Value object representing a CSRF token
+ *
+ * @ingroup Session
+ * @since 1.27
+ */
+class Token {
+       /** CSRF token suffix. Plus and terminal backslash are included to stop
+        * editing from certain broken proxies. */
+       const SUFFIX = '+\\';
+
+       private $secret = '';
+       private $salt = '';
+       private $new = false;
+
+       /**
+        * @param string $secret Token secret
+        * @param string $salt Token salt
+        * @param bool $new Whether the secret was newly-created
+        */
+       public function __construct( $secret, $salt, $new = false ) {
+               $this->secret = $secret;
+               $this->salt = $salt;
+               $this->new = $new;
+       }
+
+       /**
+        * Decode the timestamp from a token string
+        *
+        * Does not validate the token beyond the syntactic checks necessary to
+        * be able to extract the timestamp.
+        *
+        * @param string $token
+        * @param int|null
+        */
+       public static function getTimestamp( $token ) {
+               $suffixLen = strlen( self::SUFFIX );
+               $len = strlen( $token );
+               if ( $len <= 32 + $suffixLen ||
+                       substr( $token, -$suffixLen ) !== self::SUFFIX ||
+                       strspn( $token, '0123456789abcdef' ) + $suffixLen !== $len
+               ) {
+                       return null;
+               }
+
+               return hexdec( substr( $token, 32, -$suffixLen ) );
+       }
+
+       /**
+        * Get the string representation of the token at a timestamp
+        * @param int timestamp
+        * @return string
+        */
+       protected function toStringAtTimestamp( $timestamp ) {
+               return hash_hmac( 'md5', $timestamp . $this->salt, $this->secret, false ) .
+                       dechex( $timestamp ) .
+                       self::SUFFIX;
+       }
+
+       /**
+        * Get the string representation of the token
+        * @return string
+        */
+       public function toString() {
+               return $this->toStringAtTimestamp( wfTimestamp() );
+       }
+
+       public function __toString() {
+               return $this->toString();
+       }
+
+       /**
+        * Test if the token-string matches this token
+        * @param string $userToken
+        * @param int|null $maxAge Return false if $userToken is older than this many seconds
+        * @return bool
+        */
+       public function match( $userToken, $maxAge = null ) {
+               $timestamp = self::getTimestamp( $userToken );
+               if ( $timestamp === null ) {
+                       return false;
+               }
+               if ( $maxAge !== null && $timestamp < wfTimestamp() - $maxAge ) {
+                       // Expired token
+                       return false;
+               }
+
+               $sessionToken = $this->toStringAtTimestamp( $timestamp );
+               return hash_equals( $sessionToken, $userToken );
+       }
+
+       /**
+        * Indicate whether this token was just created
+        * @return bool
+        */
+       public function wasNew() {
+               return $this->new;
+       }
+
+}
index e844bb6..c01b9ec 100644 (file)
@@ -152,10 +152,10 @@ final class UserInfo {
 
        /**
         * Return the user token
-        * @return string|null
+        * @return string
         */
        public function getToken() {
-               return $this->user === null || $this->user->getId() === 0 ? null : $this->user->getToken( true );
+               return $this->user === null || $this->user->getId() === 0 ? '' : $this->user->getToken( false );
        }
 
        /**
index 0417146..6158df2 100644 (file)
@@ -328,6 +328,29 @@ class SpecialPage {
                return array();
        }
 
+       /**
+        * Perform a regular substring search for prefixSearchSubpages
+        * @param string $search Prefix to search for
+        * @param int $limit Maximum number of results to return (usually 10)
+        * @param int $offset Number of results to skip (usually 0)
+        * @return string[] Matching subpages
+        */
+       protected function prefixSearchString( $search, $limit, $offset ) {
+               $title = Title::newFromText( $search );
+               if ( !$title || !$title->canExist() ) {
+                       // No prefix suggestion in special and media namespace
+                       return array();
+               }
+
+               $search = SearchEngine::create();
+               $search->setLimitOffset( $limit, $offset );
+               $search->setNamespaces( array() );
+               $result = $search->defaultPrefixSearch( $search );
+               return array_map( function( Title $t ) {
+                       return $t->getPrefixedText();
+               }, $result );
+       }
+
        /**
         * Helper function for implementations of prefixSearchSubpages() that
         * filter the values in memory (as opposed to making a query).
index 2e764ba..030e7e5 100644 (file)
@@ -124,6 +124,7 @@ class SpecialPageFactory {
                'ListDuplicatedFiles' => 'ListDuplicatedFilesPage',
 
                // Data and tools
+               'ApiSandbox' => 'SpecialApiSandbox',
                'Statistics' => 'SpecialStatistics',
                'Allmessages' => 'SpecialAllMessages',
                'Version' => 'SpecialVersion',
index 1f369d8..cbe61bc 100644 (file)
@@ -279,11 +279,12 @@ class SpecialActiveUsers extends SpecialPage {
 
                // Mention the level of cache staleness...
                $dbr = wfGetDB( DB_SLAVE, 'recentchanges' );
-               $rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)' );
+               $rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
                if ( $rcMax ) {
                        $cTime = $dbr->selectField( 'querycache_info',
                                'qci_timestamp',
-                               array( 'qci_type' => 'activeusers' )
+                               array( 'qci_type' => 'activeusers' ),
+                               __METHOD__
                        );
                        if ( $cTime ) {
                                $secondsOld = wfTimestamp( TS_UNIX, $rcMax ) - wfTimestamp( TS_UNIX, $cTime );
index 9e75522..0bf93be 100644 (file)
@@ -365,15 +365,7 @@ class SpecialAllPages extends IncludableSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
diff --git a/includes/specials/SpecialApiSandbox.php b/includes/specials/SpecialApiSandbox.php
new file mode 100644 (file)
index 0000000..42101ba
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Implements Special:ApiSandbox
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * @ingroup SpecialPage
+ * @since 1.27
+ */
+class SpecialApiSandbox extends SpecialPage {
+       public function __construct() {
+               parent::__construct( 'ApiSandbox' );
+       }
+
+       public function execute( $par ) {
+               $this->setHeaders();
+               $out = $this->getOutput();
+
+               if ( !$this->getConfig()->get( 'EnableAPI' ) ) {
+                       $out->showErrorPage( 'error', 'apisandbox-api-disabled' );
+               }
+
+               $out->addJsConfigVars( 'apihighlimits', $this->getUser()->isAllowed( 'apihighlimits' ) );
+               $out->addModuleStyles( array(
+                       'mediawiki.special.apisandbox.styles',
+               ) );
+               $out->addModules( array(
+                       'mediawiki.special.apisandbox',
+                       'mediawiki.apipretty',
+               ) );
+               $out->wrapWikiMsg(
+                       "<div id='mw-apisandbox'><div class='mw-apisandbox-nojs error'>\n$1\n</div></div>",
+                       'apisandbox-jsonly'
+               );
+       }
+
+       protected function getGroupName() {
+               return 'wiki';
+       }
+}
index a9a7f97..1f32e3f 100644 (file)
@@ -234,15 +234,7 @@ class SpecialChangeContentModel extends FormSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index 8656798..3e5a936 100644 (file)
@@ -111,13 +111,10 @@ class SpecialChangePassword extends FormSpecialPage {
                );
 
                if ( !$this->getUser()->isLoggedIn() ) {
-                       if ( !LoginForm::getLoginToken() ) {
-                               LoginForm::setLoginToken();
-                       }
                        $fields['LoginOnChangeToken'] = array(
                                'type' => 'hidden',
                                'label' => 'Change Password Token',
-                               'default' => LoginForm::getLoginToken(),
+                               'default' => LoginForm::getLoginToken()->toString(),
                        );
                }
 
@@ -179,7 +176,7 @@ class SpecialChangePassword extends FormSpecialPage {
                }
 
                if ( !$this->getUser()->isLoggedIn()
-                       && $request->getVal( 'wpLoginOnChangeToken' ) !== LoginForm::getLoginToken()
+                       && !LoginForm::getLoginToken()->match( $request->getVal( 'wpLoginOnChangeToken' ) )
                ) {
                        // Potential CSRF (bug 62497)
                        return false;
@@ -218,8 +215,8 @@ class SpecialChangePassword extends FormSpecialPage {
                        $this->getOutput()->returnToMain();
                } else {
                        $request = $this->getRequest();
-                       LoginForm::setLoginToken();
-                       $token = LoginForm::getLoginToken();
+                       LoginForm::clearLoginToken();
+                       $token = LoginForm::getLoginToken()->toString();
                        $data = array(
                                'action' => 'submitlogin',
                                'wpName' => $this->mUserName,
index ab6614b..1a1b490 100644 (file)
@@ -571,8 +571,10 @@ class SpecialContributions extends IncludableSpecialPage {
                                )
                );
 
+               $filters = array();
+
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
-                       $deletedOnlyCheck = Html::rawElement(
+                       $filters[] = Html::rawElement(
                                'span',
                                array( 'class' => 'mw-input-with-label' ),
                                Xml::checkLabel(
@@ -583,11 +585,9 @@ class SpecialContributions extends IncludableSpecialPage {
                                        array( 'class' => 'mw-input' )
                                )
                        );
-               } else {
-                       $deletedOnlyCheck = '';
                }
 
-               $checkLabelTopOnly = Html::rawElement(
+               $filters[] = Html::rawElement(
                        'span',
                        array( 'class' => 'mw-input-with-label' ),
                        Xml::checkLabel(
@@ -598,7 +598,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                array( 'class' => 'mw-input' )
                        )
                );
-               $checkLabelNewOnly = Html::rawElement(
+               $filters[] = Html::rawElement(
                        'span',
                        array( 'class' => 'mw-input-with-label' ),
                        Xml::checkLabel(
@@ -609,10 +609,16 @@ class SpecialContributions extends IncludableSpecialPage {
                                array( 'class' => 'mw-input' )
                        )
                );
+
+               Hooks::run(
+                       'SpecialContributions::getForm::filters',
+                       array( $this, &$filters )
+               );
+
                $extraOptions = Html::rawElement(
                        'td',
                        array( 'colspan' => 2 ),
-                       $deletedOnlyCheck . $checkLabelTopOnly . $checkLabelNewOnly
+                       implode( '', $filters )
                );
 
                $dateSelectionAndSubmit = Xml::tags( 'td', array( 'colspan' => 2 ),
index 3ce9c76..f9b5050 100644 (file)
@@ -418,6 +418,8 @@ class SpecialExport extends SpecialPage {
        private function getPagesFromCategory( $title ) {
                global $wgContLang;
 
+               $maxPages = $this->getConfig()->get( 'ExportPagelistLimit' );
+
                $name = $title->getDBkey();
 
                $dbr = wfGetDB( DB_SLAVE );
@@ -426,7 +428,7 @@ class SpecialExport extends SpecialPage {
                        array( 'page_namespace', 'page_title' ),
                        array( 'cl_from=page_id', 'cl_to' => $name ),
                        __METHOD__,
-                       array( 'LIMIT' => '5000' )
+                       array( 'LIMIT' => $maxPages )
                );
 
                $pages = array();
@@ -451,13 +453,15 @@ class SpecialExport extends SpecialPage {
        private function getPagesFromNamespace( $nsindex ) {
                global $wgContLang;
 
+               $maxPages = $this->getConfig()->get( 'ExportPagelistLimit' );
+
                $dbr = wfGetDB( DB_SLAVE );
                $res = $dbr->select(
                        'page',
                        array( 'page_namespace', 'page_title' ),
                        array( 'page_namespace' => $nsindex ),
                        __METHOD__,
-                       array( 'LIMIT' => '5000' )
+                       array( 'LIMIT' => $maxPages )
                );
 
                $pages = array();
index 323903e..9970dfa 100644 (file)
@@ -246,9 +246,11 @@ class FileDuplicateSearchPage extends QueryPage {
                        // No prefix suggestion outside of file namespace
                        return array();
                }
+               $search = SearchEngine::create();
+               $search->setLimitOffset( $limit, $offset );
                // Autocomplete subpage the same as a normal search, but just for files
-               $prefixSearcher = new TitlePrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array( NS_FILE ), $offset );
+               $search->setNamespaces( array( NS_FILE ) );
+               $result = $search->defaultPrefixSearch( $search );
 
                return array_map( function ( Title $t ) {
                        // Remove namespace in search suggestion
index 27d2304..339c1d9 100644 (file)
@@ -117,9 +117,9 @@ class MovePageForm extends UnlistedSpecialPage {
                $this->moveTalk = $request->getBool( 'wpMovetalk', $def );
                $this->fixRedirects = $request->getBool( 'wpFixRedirects', $def );
                $this->leaveRedirect = $request->getBool( 'wpLeaveRedirect', $def );
-               $this->moveSubpages = $request->getBool( 'wpMovesubpages', false );
-               $this->deleteAndMove = $request->getBool( 'wpDeleteAndMove' ) && $request->getBool( 'wpConfirm' );
-               $this->moveOverShared = $request->getBool( 'wpMoveOverSharedFile', false );
+               $this->moveSubpages = $request->getBool( 'wpMovesubpages' );
+               $this->deleteAndMove = $request->getBool( 'wpDeleteAndMove' );
+               $this->moveOverShared = $request->getBool( 'wpMoveOverSharedFile' );
                $this->watch = $request->getCheck( 'wpWatch' ) && $user->isLoggedIn();
 
                if ( 'submit' == $request->getVal( 'action' ) && $request->wasPosted()
@@ -166,8 +166,8 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                }
 
-               $submitVar = 'wpMove';
-               $confirm = false;
+               $deleteAndMove = false;
+               $moveOverShared = false;
 
                $newTitle = $this->newTitle;
 
@@ -194,8 +194,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                "<div class='warningbox'>\n$1\n</div>\n",
                                array( 'delete_and_move_text', $newTitle->getPrefixedText() )
                        );
-                       $submitVar = 'wpDeleteAndMove';
-                       $confirm = true;
+                       $deleteAndMove = true;
                        $err = array();
                }
 
@@ -209,7 +208,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                        $newTitle->getPrefixedText()
                                )
                        );
-                       $submitVar = 'wpMoveOverSharedFile';
+                       $moveOverShared = true;
                        $err = array();
                }
 
@@ -440,11 +439,16 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                }
 
-               if ( $confirm ) {
+               $hiddenFields = '';
+               if ( $moveOverShared ) {
+                       $hiddenFields .= Html::hidden( 'wpMoveOverSharedFile', '1' );
+               }
+
+               if ( $deleteAndMove ) {
                        $fields[] = new OOUI\FieldLayout(
                                new OOUI\CheckboxInputWidget( array(
-                                       'name' => 'wpConfirm',
-                                       'id' => 'wpConfirm',
+                                       'name' => 'wpDeleteAndMove',
+                                       'id' => 'wpDeleteAndMove',
                                        'value' => '1',
                                ) ),
                                array(
@@ -456,7 +460,7 @@ class MovePageForm extends UnlistedSpecialPage {
 
                $fields[] = new OOUI\FieldLayout(
                        new OOUI\ButtonInputWidget( array(
-                               'name' => $submitVar,
+                               'name' => 'wpMove',
                                'value' => $this->msg( 'movepagebtn' )->text(),
                                'label' => $this->msg( 'movepagebtn' )->text(),
                                'flags' => array( 'constructive', 'primary' ),
@@ -481,6 +485,7 @@ class MovePageForm extends UnlistedSpecialPage {
                $form->appendContent(
                        $fieldset,
                        new OOUI\HtmlSnippet(
+                               $hiddenFields .
                                Html::hidden( 'wpOldTitle', $this->oldTitle->getPrefixedText() ) .
                                Html::hidden( 'wpEditToken', $user->getEditToken() )
                        )
@@ -815,15 +820,7 @@ class MovePageForm extends UnlistedSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index 69a9d48..38093be 100644 (file)
@@ -214,15 +214,7 @@ class SpecialPageLanguage extends FormSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index a6c0423..6401063 100644 (file)
@@ -303,15 +303,7 @@ class SpecialPrefixindex extends SpecialAllPages {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index f030231..0bf2485 100644 (file)
@@ -84,10 +84,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $opts->add( 'hideliu', false );
                $opts->add( 'hidepatrolled', $user->getBoolOption( 'hidepatrolled' ) );
                $opts->add( 'hidemyself', false );
-
-               if ( $config->get( 'RCWatchCategoryMembership' ) ) {
-                       $opts->add( 'hidecategorization', $user->getBoolOption( 'hidecategorization' ) );
-               }
+               $opts->add( 'hidecategorization', $user->getBoolOption( 'hidecategorization' ) );
 
                $opts->add( 'categories', '' );
                $opts->add( 'categories_any', false );
index 8db8f24..dc210db 100644 (file)
@@ -273,14 +273,6 @@ class SpecialRecentChangesLinked extends SpecialRecentChanges {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 }
index f99a52d..078f032 100644 (file)
@@ -1709,15 +1709,7 @@ class SpecialUndelete extends SpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index 9473dff..05e5229 100644 (file)
@@ -531,9 +531,8 @@ class LoginForm extends SpecialPage {
                }
 
                # Request forgery checks.
-               if ( !self::getCreateaccountToken() ) {
-                       self::setCreateaccountToken();
-
+               $token = self::getCreateaccountToken();
+               if ( $token->wasNew() ) {
                        return Status::newFatal( 'nocookiesfornew' );
                }
 
@@ -543,7 +542,7 @@ class LoginForm extends SpecialPage {
                }
 
                # Validate the createaccount token
-               if ( $this->mToken !== self::getCreateaccountToken() ) {
+               if ( !$token->match( $this->mToken ) ) {
                        return Status::newFatal( 'sessionfailure' );
                }
 
@@ -737,9 +736,8 @@ class LoginForm extends SpecialPage {
                // but wrong-token attempts do.
 
                // If the user doesn't have a login token yet, set one.
-               if ( !self::getLoginToken() ) {
-                       self::setLoginToken();
-
+               $token = self::getLoginToken();
+               if ( $token->wasNew() ) {
                        return self::NEED_TOKEN;
                }
                // If the user didn't pass a login token, tell them we need one
@@ -753,7 +751,7 @@ class LoginForm extends SpecialPage {
                }
 
                // Validate the login token
-               if ( $this->mToken !== self::getLoginToken() ) {
+               if ( !$token->match( $this->mToken ) ) {
                        return self::WRONG_TOKEN;
                }
 
@@ -1492,15 +1490,9 @@ class LoginForm extends SpecialPage {
                $template->set( 'loggedinuser', $user->getName() );
 
                if ( $this->mType == 'signup' ) {
-                       if ( !self::getCreateaccountToken() ) {
-                               self::setCreateaccountToken();
-                       }
-                       $template->set( 'token', self::getCreateaccountToken() );
+                       $template->set( 'token', self::getCreateaccountToken()->toString() );
                } else {
-                       if ( !self::getLoginToken() ) {
-                               self::setLoginToken();
-                       }
-                       $template->set( 'token', self::getLoginToken() );
+                       $template->set( 'token', self::getLoginToken()->toString() );
                }
 
                # Prepare language selection links as needed
@@ -1576,22 +1568,25 @@ class LoginForm extends SpecialPage {
 
        /**
         * Get the login token from the current session
-        * @return mixed
+        * @since 1.27 returns a MediaWiki\\Session\\Token instead of a string
+        * @return MediaWiki\\Session\\Token
         */
        public static function getLoginToken() {
                global $wgRequest;
-
-               return $wgRequest->getSessionData( 'wsLoginToken' );
+               return $wgRequest->getSession()->getToken( '', 'login' );
        }
 
        /**
-        * Randomly generate a new login token and attach it to the current session
+        * Formerly randomly generated a login token that would be returned by
+        * $this->getLoginToken().
+        *
+        * Since 1.27, this is a no-op. The token is generated as necessary by
+        * $this->getLoginToken().
+        *
+        * @deprecated since 1.27
         */
        public static function setLoginToken() {
-               global $wgRequest;
-               // Generate a token directly instead of using $user->getEditToken()
-               // because the latter reuses wsEditToken in the session
-               $wgRequest->setSessionData( 'wsLoginToken', MWCryptRand::generateHex( 32 ) );
+               wfDeprecated( __METHOD__, '1.27' );
        }
 
        /**
@@ -1599,24 +1594,30 @@ class LoginForm extends SpecialPage {
         */
        public static function clearLoginToken() {
                global $wgRequest;
-               $wgRequest->setSessionData( 'wsLoginToken', null );
+               $wgRequest->getSession()->resetToken( 'login' );
        }
 
        /**
         * Get the createaccount token from the current session
-        * @return mixed
+        * @since 1.27 returns a MediaWiki\\Session\\Token instead of a string
+        * @return MediaWiki\\Session\\Token
         */
        public static function getCreateaccountToken() {
                global $wgRequest;
-               return $wgRequest->getSessionData( 'wsCreateaccountToken' );
+               return $wgRequest->getSession()->getToken( '', 'createaccount' );
        }
 
        /**
-        * Randomly generate a new createaccount token and attach it to the current session
+        * Formerly randomly generated a createaccount token that would be returned
+        * by $this->getCreateaccountToken().
+        *
+        * Since 1.27, this is a no-op. The token is generated as necessary by
+        * $this->getCreateaccountToken().
+        *
+        * @deprecated since 1.27
         */
        public static function setCreateaccountToken() {
-               global $wgRequest;
-               $wgRequest->setSessionData( 'wsCreateaccountToken', MWCryptRand::generateHex( 32 ) );
+               wfDeprecated( __METHOD__, '1.27' );
        }
 
        /**
@@ -1624,7 +1625,7 @@ class LoginForm extends SpecialPage {
         */
        public static function clearCreateaccountToken() {
                global $wgRequest;
-               $wgRequest->setSessionData( 'wsCreateaccountToken', null );
+               $wgRequest->getSession()->resetToken( 'createaccount' );
        }
 
        /**
@@ -1757,4 +1758,7 @@ class LoginForm extends SpecialPage {
                return $expired;
        }
 
+       protected function getSubpagesForPrefixSearch() {
+               return array( 'signup' );
+       }
 }
index 43228fa..17442be 100644 (file)
@@ -38,12 +38,6 @@ class SpecialVersion extends SpecialPage {
 
        protected static $extensionTypes = false;
 
-       protected static $viewvcUrls = array(
-               'svn+ssh://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
-               'http://svn.wikimedia.org/svnroot/mediawiki' => 'http://svn.wikimedia.org/viewvc/mediawiki',
-               'https://svn.wikimedia.org/svnroot/mediawiki' => 'https://svn.wikimedia.org/viewvc/mediawiki',
-       );
-
        public function __construct() {
                parent::__construct( 'Version' );
        }
@@ -132,7 +126,7 @@ class SpecialVersion extends SpecialPage {
                                break;
 
                        default:
-                               $out->addModules( 'mediawiki.special.version' );
+                               $out->addModuleStyles( 'mediawiki.special.version' );
                                $out->addWikiText(
                                        $this->getMediaWikiCredits() .
                                        $this->softwareInformation() .
@@ -258,7 +252,7 @@ class SpecialVersion extends SpecialPage {
        }
 
        /**
-        * Return a string of the MediaWiki version with SVN revision if available.
+        * Return a string of the MediaWiki version with Git revision if available.
         *
         * @param string $flags
         * @return mixed
@@ -267,25 +261,15 @@ class SpecialVersion extends SpecialPage {
                global $wgVersion, $IP;
 
                $gitInfo = self::getGitHeadSha1( $IP );
-               $svnInfo = self::getSvnInfo( $IP );
-               if ( !$svnInfo && !$gitInfo ) {
+               if ( !$gitInfo ) {
                        $version = $wgVersion;
-               } elseif ( $gitInfo && $flags === 'nodb' ) {
+               } elseif ( $flags === 'nodb' ) {
                        $shortSha1 = substr( $gitInfo, 0, 7 );
                        $version = "$wgVersion ($shortSha1)";
-               } elseif ( $gitInfo ) {
+               } else {
                        $shortSha1 = substr( $gitInfo, 0, 7 );
                        $shortSha1 = wfMessage( 'parentheses' )->params( $shortSha1 )->escaped();
                        $version = "$wgVersion $shortSha1";
-               } elseif ( $flags === 'nodb' ) {
-                       $version = "$wgVersion (r{$svnInfo['checkout-rev']})";
-               } else {
-                       $version = $wgVersion . ' ' .
-                               wfMessage(
-                                       'version-svn-revision',
-                                       isset( $svnInfo['directory-rev'] ) ? $svnInfo['directory-rev'] : '',
-                                       isset( $svnInfo['checkout-rev'] ) ? $svnInfo['checkout-rev'] : ''
-                               )->text();
                }
 
                return $version;
@@ -293,8 +277,7 @@ class SpecialVersion extends SpecialPage {
 
        /**
         * Return a wikitext-formatted string of the MediaWiki version with a link to
-        * the SVN revision or the git SHA1 of head if available.
-        * Git is prefered over Svn
+        * the Git SHA1 of head if available.
         * The fallback is just $wgVersion
         *
         * @return mixed
@@ -306,43 +289,12 @@ class SpecialVersion extends SpecialPage {
                if ( $gitVersion ) {
                        $v = $gitVersion;
                } else {
-                       $svnVersion = self::getVersionLinkedSvn();
-                       if ( $svnVersion ) {
-                               $v = $svnVersion;
-                       } else {
-                               $v = $wgVersion; // fallback
-                       }
+                       $v = $wgVersion; // fallback
                }
 
                return $v;
        }
 
-       /**
-        * @return string Global wgVersion + a link to subversion revision of svn BASE
-        */
-       private static function getVersionLinkedSvn() {
-               global $IP;
-
-               $info = self::getSvnInfo( $IP );
-               if ( !isset( $info['checkout-rev'] ) ) {
-                       return false;
-               }
-
-               $linkText = wfMessage(
-                       'version-svn-revision',
-                       isset( $info['directory-rev'] ) ? $info['directory-rev'] : '',
-                       $info['checkout-rev']
-               )->text();
-
-               if ( isset( $info['viewvc-url'] ) ) {
-                       $version = "[{$info['viewvc-url']} $linkText]";
-               } else {
-                       $version = $linkText;
-               }
-
-               return self::getwgVersionLinked() . " $version";
-       }
-
        /**
         * @return string
         */
@@ -744,7 +696,7 @@ class SpecialVersion extends SpecialPage {
                }
 
                // ... and the version information
-               // If the extension path is set we will check that directory for GIT and SVN
+               // If the extension path is set we will check that directory for GIT
                // metadata in an attempt to extract date and vcs commit metadata.
                $canonicalVersion = '&ndash;';
                $extensionPath = null;
@@ -764,11 +716,6 @@ class SpecialVersion extends SpecialPage {
                                $coreHeadSHA1 = self::getGitHeadSha1( $IP );
                                if ( $coreHeadSHA1 ) {
                                        $this->coreId = $coreHeadSHA1;
-                               } else {
-                                       $svnInfo = self::getSvnInfo( $IP );
-                                       if ( $svnInfo !== false ) {
-                                               $this->coreId = $svnInfo['checkout-rev'];
-                                       }
                                }
                        }
                        $cache = wfGetCache( CACHE_ANYTHING );
@@ -783,12 +730,6 @@ class SpecialVersion extends SpecialPage {
                                        $vcsVersion = substr( $vcsVersion, 0, 7 );
                                        $vcsLink = $gitInfo->getHeadViewUrl();
                                        $vcsDate = $gitInfo->getHeadCommitDate();
-                               } else {
-                                       $svnInfo = self::getSvnInfo( $extensionPath );
-                                       if ( $svnInfo !== false ) {
-                                               $vcsVersion = $this->msg( 'version-svn-revision', $svnInfo['checkout-rev'] )->text();
-                                               $vcsLink = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
-                                       }
                                }
                                $cache->set( $memcKey, array( $vcsVersion, $vcsLink, $vcsDate ), 60 * 60 * 24 );
                        } else {
@@ -1154,108 +1095,6 @@ class SpecialVersion extends SpecialPage {
                }
        }
 
-       /**
-        * Get an associative array of information about a given path, from its .svn
-        * subdirectory. Returns false on error, such as if the directory was not
-        * checked out with subversion.
-        *
-        * Returned keys are:
-        *    Required:
-        *        checkout-rev          The revision which was checked out
-        *    Optional:
-        *        directory-rev         The revision when the directory was last modified
-        *        url                   The subversion URL of the directory
-        *        repo-url              The base URL of the repository
-        *        viewvc-url            A ViewVC URL pointing to the checked-out revision
-        * @param string $dir
-        * @return array|bool
-        */
-       public static function getSvnInfo( $dir ) {
-               // http://svnbook.red-bean.com/nightly/en/svn.developer.insidewc.html
-               $entries = $dir . '/.svn/entries';
-
-               if ( !file_exists( $entries ) ) {
-                       return false;
-               }
-
-               $lines = file( $entries );
-               if ( !count( $lines ) ) {
-                       return false;
-               }
-
-               // check if file is xml (subversion release <= 1.3) or not (subversion release = 1.4)
-               if ( preg_match( '/^<\?xml/', $lines[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...
-                       MediaWiki\suppressWarnings();
-                       $xml = simplexml_load_file( $entries );
-                       MediaWiki\restoreWarnings();
-
-                       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 array( 'checkout-rev' => intval( $entry['revision'] ) );
-                                               }
-                                       }
-                               }
-                       }
-
-                       return false;
-               }
-
-               // Subversion is release 1.4 or above.
-               if ( count( $lines ) < 11 ) {
-                       return false;
-               }
-
-               $info = array(
-                       'checkout-rev' => intval( trim( $lines[3] ) ),
-                       'url' => trim( $lines[4] ),
-                       'repo-url' => trim( $lines[5] ),
-                       'directory-rev' => intval( trim( $lines[10] ) )
-               );
-
-               if ( isset( self::$viewvcUrls[$info['repo-url']] ) ) {
-                       $viewvc = str_replace(
-                               $info['repo-url'],
-                               self::$viewvcUrls[$info['repo-url']],
-                               $info['url']
-                       );
-
-                       $viewvc .= '/?pathrev=';
-                       $viewvc .= urlencode( $info['checkout-rev'] );
-                       $info['viewvc-url'] = $viewvc;
-               }
-
-               return $info;
-       }
-
-       /**
-        * Retrieve the revision number of a Subversion working directory.
-        *
-        * @param string $dir Directory of the svn checkout
-        *
-        * @return int Revision number
-        */
-       public static function getSvnRevision( $dir ) {
-               $info = self::getSvnInfo( $dir );
-
-               if ( $info === false ) {
-                       return false;
-               } elseif ( isset( $info['checkout-rev'] ) ) {
-                       return $info['checkout-rev'];
-               } else {
-                       return false;
-               }
-       }
-
        /**
         * @param string $dir Directory of the git checkout
         * @return bool|string Sha1 of commit HEAD points to
index 6ebe9a8..cc5c150 100644 (file)
@@ -118,10 +118,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                $opts->add( 'hideliu', $user->getBoolOption( 'watchlisthideliu' ) );
                $opts->add( 'hidepatrolled', $user->getBoolOption( 'watchlisthidepatrolled' ) );
                $opts->add( 'hidemyself', $user->getBoolOption( 'watchlisthideown' ) );
-
-               if ( $this->getConfig()->get( 'RCWatchCategoryMembership' ) ) {
-                       $opts->add( 'hidecategorization', $user->getBoolOption( 'watchlisthidecategorization' ) );
-               }
+               $opts->add( 'hidecategorization', $user->getBoolOption( 'watchlisthidecategorization' ) );
 
                return $opts;
        }
index 47fd972..45ef9a2 100644 (file)
@@ -548,15 +548,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
         * @return string[] Matching subpages
         */
        public function prefixSearchSubpages( $search, $limit, $offset ) {
-               $title = Title::newFromText( $search );
-               if ( !$title || !$title->canExist() ) {
-                       // No prefix suggestion in special and media namespace
-                       return array();
-               }
-               // Autocomplete subpage the same as a normal search
-               $prefixSearcher = new StringPrefixSearch;
-               $result = $prefixSearcher->search( $search, $limit, array(), $offset );
-               return $result;
+               return $this->prefixSearchString( $search, $limit, $offset );
        }
 
        protected function getGroupName() {
index 27574fa..07060b2 100644 (file)
@@ -62,12 +62,12 @@ class MediaWikiPageLinkRenderer implements PageLinkRenderer {
        /**
         * Returns the (partial) URL for the given page (including any section identifier).
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $page The link's target
         * @param array $params Any additional URL parameters.
         *
         * @return string
         */
-       public function getPageUrl( TitleValue $page, $params = array() ) {
+       public function getPageUrl( LinkTarget $page, $params = array() ) {
                // TODO: move the code from Linker::linkUrl here!
                // The below is just a rough estimation!
 
@@ -93,20 +93,24 @@ class MediaWikiPageLinkRenderer implements PageLinkRenderer {
        /**
         * Returns an HTML link to the given page, using the given surface text.
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $linkTarget The link's target
         * @param string $text The link's surface text (will be derived from $page if not given).
         *
         * @return string
         */
-       public function renderHtmlLink( TitleValue $page, $text = null ) {
+       public function renderHtmlLink( LinkTarget $linkTarget, $text = null ) {
                if ( $text === null ) {
-                       $text = $this->formatter->getFullText( $page );
+                       $text = $this->formatter->getFullText( $linkTarget );
                }
 
                // TODO: move the logic implemented by Linker here,
                // using $this->formatter and $this->baseUrl, and
                // re-implement Linker to use a HtmlPageLinkRenderer.
-               $title = Title::newFromTitleValue( $page );
+               if ( $linkTarget instanceof Title ) {
+                       $title = $linkTarget;
+               } else {
+                       $title = Title::newFromLinkTarget( $linkTarget );
+               }
                $link = Linker::link( $title, htmlspecialchars( $text ) );
 
                return $link;
@@ -115,12 +119,12 @@ class MediaWikiPageLinkRenderer implements PageLinkRenderer {
        /**
         * Returns a wikitext link to the given page, using the given surface text.
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $page The link's target
         * @param string $text The link's surface text (will be derived from $page if not given).
         *
         * @return string
         */
-       public function renderWikitextLink( TitleValue $page, $text = null ) {
+       public function renderWikitextLink( LinkTarget $page, $text = null ) {
                if ( $text === null ) {
                        $text = $this->formatter->getFullText( $page );
                }
index c497865..1de4247 100644 (file)
@@ -151,33 +151,33 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
        /**
         * @see TitleFormatter::getText()
         *
-        * @param TitleValue $title
+        * @param LinkTarget $title
         *
         * @return string $title->getText()
         */
-       public function getText( TitleValue $title ) {
+       public function getText( LinkTarget $title ) {
                return $this->formatTitle( false, $title->getText(), '' );
        }
 
        /**
         * @see TitleFormatter::getText()
         *
-        * @param TitleValue $title
+        * @param LinkTarget $title
         *
         * @return string
         */
-       public function getPrefixedText( TitleValue $title ) {
+       public function getPrefixedText( LinkTarget $title ) {
                return $this->formatTitle( $title->getNamespace(), $title->getText(), '' );
        }
 
        /**
         * @see TitleFormatter::getText()
         *
-        * @param TitleValue $title
+        * @param LinkTarget $title
         *
         * @return string
         */
-       public function getFullText( TitleValue $title ) {
+       public function getFullText( LinkTarget $title ) {
                return $this->formatTitle( $title->getNamespace(), $title->getText(), $title->getFragment() );
        }
 
index ca91f58..2ca5707 100644 (file)
@@ -37,32 +37,32 @@ interface PageLinkRenderer {
         *
         * @todo expand this to cover the functionality of Linker::linkUrl
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $page The link's target
         * @param array $params Any additional URL parameters.
         *
         * @return string
         */
-       public function getPageUrl( TitleValue $page, $params = array() );
+       public function getPageUrl( LinkTarget $page, $params = array() );
 
        /**
         * Returns an HTML link to the given page, using the given surface text.
         *
         * @todo expand this to cover the functionality of Linker::link
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $page The link's target
         * @param string $text The link's surface text (will be derived from $page if not given).
         *
         * @return string
         */
-       public function renderHtmlLink( TitleValue $page, $text = null );
+       public function renderHtmlLink( LinkTarget $page, $text = null );
 
        /**
         * Returns a wikitext link to the given page, using the given surface text.
         *
-        * @param TitleValue $page The link's target
+        * @param LinkTarget $page The link's target
         * @param string $text The link's surface text (will be derived from $page if not given).
         *
         * @return string
         */
-       public function renderWikitextLink( TitleValue $page, $text = null );
+       public function renderWikitextLink( LinkTarget $page, $text = null );
 }
index aad8376..4edc5db 100644 (file)
@@ -51,29 +51,29 @@ interface TitleFormatter {
         *
         * @note Only minimal normalization is applied. Consider using TitleValue::getText() directly.
         *
-        * @param TitleValue $title The title to format
+        * @param LinkTarget $title The title to format
         *
         * @return string
         */
-       public function getText( TitleValue $title );
+       public function getText( LinkTarget $title );
 
        /**
         * Returns the title formatted for display, including the namespace name.
         *
-        * @param TitleValue $title The title to format
+        * @param LinkTarget $title The title to format
         *
         * @return string
         */
-       public function getPrefixedText( TitleValue $title );
+       public function getPrefixedText( LinkTarget $title );
 
        /**
         * Returns the title formatted for display, with namespace and fragment.
         *
-        * @param TitleValue $title The title to format
+        * @param LinkTarget $title The title to format
         *
         * @return string
         */
-       public function getFullText( TitleValue $title );
+       public function getFullText( LinkTarget $title );
 
        /**
         * Returns the name of the namespace for the given title.
index a0f3b6f..c8ebc2a 100644 (file)
@@ -35,7 +35,7 @@ use Wikimedia\Assert\Assert;
  * @see https://www.mediawiki.org/wiki/Requests_for_comment/TitleValue
  * @since 1.23
  */
-class TitleValue {
+class TitleValue implements LinkTarget {
        /**
         * @var int
         */
diff --git a/includes/user/LoggedOutEditToken.php b/includes/user/LoggedOutEditToken.php
new file mode 100644 (file)
index 0000000..14548f4
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+/**
+ * MediaWiki edit token
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Session
+ */
+
+use MediaWiki\Session\Token;
+
+/**
+ * Value object representing a logged-out user's edit token
+ *
+ * This exists so that code generically dealing with MediaWiki\\Session\\Token
+ * (i.e. the API) doesn't have to have so many special cases for anon edit
+ * tokens.
+ *
+ * @since 1.27
+ */
+class LoggedOutEditToken extends MediaWiki\Session\Token {
+       public function __construct() {
+               parent::__construct( '', '', false );
+       }
+
+       protected function toStringAtTimestamp( $timestamp ) {
+               return self::SUFFIX;
+       }
+
+       public function match( $userToken, $maxAge = null ) {
+               return $userToken === self::SUFFIX;
+       }
+}
index 2fadd6b..da63075 100644 (file)
@@ -24,9 +24,10 @@ use MediaWiki\Session\SessionManager;
 
 /**
  * String Some punctuation to prevent editing from broken text-mangling proxies.
+ * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::SUFFIX
  * @ingroup Constants
  */
-define( 'EDIT_TOKEN_SUFFIX', '+\\' );
+define( 'EDIT_TOKEN_SUFFIX', MediaWiki\Session\Token::SUFFIX );
 
 /**
  * The User object encapsulates all of the user-specific settings (user_id,
@@ -44,9 +45,15 @@ class User implements IDBAccessObject {
         */
        const TOKEN_LENGTH = 32;
 
+       /**
+        * @const string An invalid value for user_token
+        */
+       const INVALID_TOKEN = '*** INVALID ***';
+
        /**
         * Global constant made accessible as class constants so that autoloader
         * magic can be used.
+        * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::SUFFIX
         */
        const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
 
@@ -307,6 +314,22 @@ class User implements IDBAccessObject {
                return $this->getName();
        }
 
+       /**
+        * Test if it's safe to load this User object. You should typically check this before using
+        * $wgUser or RequestContext::getUser in a method that might be called before the system has
+        * been fully initialized. If the object is unsafe, you should use an anonymous user:
+        * \code
+        * $user = $wgUser->isSafeToLoad() ? $wgUser : new User;
+        * \endcode
+        *
+        * @since 1.27
+        * @return bool
+        */
+       public function isSafeToLoad() {
+               global $wgFullyInitialised;
+               return $wgFullyInitialised || $this->mLoadedItems === true || $this->mFrom !== 'session';
+       }
+
        /**
         * Load the user table data for this object from the source given by mFrom.
         *
@@ -325,7 +348,7 @@ class User implements IDBAccessObject {
                $this->queryFlagsUsed = $flags;
 
                // If this is called too early, things are likely to break.
-               if ( $this->mFrom === 'session' && empty( $wgFullyInitialised ) ) {
+               if ( !$wgFullyInitialised && $this->mFrom === 'session' ) {
                        \MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
                                ->warning( 'User::loadFromSession called before the end of Setup.php', array(
                                        'exception' => new Exception( 'User::loadFromSession called before the end of Setup.php' ),
@@ -639,7 +662,8 @@ class User implements IDBAccessObject {
                $user = self::newFromRow( $row );
 
                // A user is considered to exist as a non-system user if it has a
-               // password set, or a temporary password set, or an email set.
+               // password set, or a temporary password set, or an email set, or a
+               // non-invalid token.
                $passwordFactory = new PasswordFactory();
                $passwordFactory->init( RequestContext::getMain()->getConfig() );
                try {
@@ -655,7 +679,7 @@ class User implements IDBAccessObject {
                        $newpassword = PasswordFactory::newInvalidPassword();
                }
                if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
-                       || $user->mEmail
+                       || $user->mEmail || $user->mToken !== self::INVALID_TOKEN
                ) {
                        // User exists. Steal it?
                        if ( !$options['steal'] ) {
@@ -675,11 +699,11 @@ class User implements IDBAccessObject {
                                __METHOD__
                        );
                        $user->invalidateEmail();
+                       $user->mToken = self::INVALID_TOKEN;
                        $user->saveSettings();
+                       SessionManager::singleton()->preventSessionsForUser( $user->getName() );
                }
 
-               SessionManager::singleton()->preventSessionsForUser( $user->getName() );
-
                return $user;
        }
 
@@ -1154,7 +1178,7 @@ class User implements IDBAccessObject {
                        // Other code expects these to be set in the session, so set them.
                        $session->set( 'wsUserID', $this->getId() );
                        $session->set( 'wsUserName', $this->getName() );
-                       $session->set( 'wsToken', $this->mToken );
+                       $session->set( 'wsToken', $this->getToken() );
                        return true;
                }
 
@@ -1259,12 +1283,20 @@ class User implements IDBAccessObject {
                        $all = false;
                }
 
-               if ( isset( $row->user_email ) ) {
-                       $this->mEmail = $row->user_email;
-                       $this->mToken = $row->user_token;
-                       if ( $this->mToken == '' ) {
+               if ( isset( $row->user_token ) ) {
+                       // The definition for the column is binary(32), so trim the NULs
+                       // that appends. The previous definition was char(32), so trim
+                       // spaces too.
+                       $this->mToken = rtrim( $row->user_token, " \0" );
+                       if ( $this->mToken === '' ) {
                                $this->mToken = null;
                        }
+               } else {
+                       $all = false;
+               }
+
+               if ( isset( $row->user_email ) ) {
+                       $this->mEmail = $row->user_email;
                        $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
                        $this->mEmailToken = $row->user_email_token;
                        $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
@@ -1516,10 +1548,16 @@ class User implements IDBAccessObject {
                # We only need to worry about passing the IP address to the Block generator if the
                # user is not immune to autoblocks/hardblocks, and they are the current user so we
                # know which IP address they're actually coming from
-               if ( !$this->isAllowed( 'ipblock-exempt' ) && $this->equals( $wgUser ) ) {
-                       $ip = $this->getRequest()->getIP();
-               } else {
-                       $ip = null;
+               $ip = null;
+               if ( !$this->isAllowed( 'ipblock-exempt' ) ) {
+                       // $wgUser->getName() only works after the end of Setup.php. Until
+                       // then, assume it's a logged-out user.
+                       $globalUserName = $wgUser->isSafeToLoad()
+                               ? $wgUser->getName()
+                               : IP::sanitizeIP( $wgUser->getRequest()->getIP() );
+                       if ( $this->getName() === $globalUserName ) {
+                               $ip = $this->getRequest()->getIP();
+                       }
                }
 
                // User/IP blocking
@@ -1728,40 +1766,43 @@ class User implements IDBAccessObject {
                $keys = array();
                $id = $this->getId();
                $userLimit = false;
+               $isNewbie = $this->isNewbie();
 
-               if ( isset( $limits['anon'] ) && $id == 0 ) {
-                       $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
-               }
-
-               if ( isset( $limits['user'] ) && $id != 0 ) {
-                       $userLimit = $limits['user'];
-               }
-               if ( $this->isNewbie() ) {
-                       if ( isset( $limits['newbie'] ) && $id != 0 ) {
+               if ( $id == 0 ) {
+                       // limits for anons
+                       if ( isset( $limits['anon'] ) ) {
+                               $keys[wfMemcKey( 'limiter', $action, 'anon' )] = $limits['anon'];
+                       }
+               } else {
+                       // limits for logged-in users
+                       if ( isset( $limits['user'] ) ) {
+                               $userLimit = $limits['user'];
+                       }
+                       // limits for newbie logged-in users
+                       if ( $isNewbie && isset( $limits['newbie'] ) ) {
                                $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $limits['newbie'];
                        }
+               }
+
+               // limits for anons and for newbie logged-in users
+               if ( $isNewbie ) {
+                       // ip-based limits
                        if ( isset( $limits['ip'] ) ) {
                                $ip = $this->getRequest()->getIP();
                                $keys["mediawiki:limiter:$action:ip:$ip"] = $limits['ip'];
                        }
+                       // subnet-based limits
                        if ( isset( $limits['subnet'] ) ) {
                                $ip = $this->getRequest()->getIP();
-                               $matches = array();
-                               $subnet = false;
-                               if ( IP::isIPv6( $ip ) ) {
-                                       $parts = IP::parseRange( "$ip/64" );
-                                       $subnet = $parts[0];
-                               } elseif ( preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
-                                       // IPv4
-                                       $subnet = $matches[1];
-                               }
+                               $subnet = IP::getSubnet( $ip );
                                if ( $subnet !== false ) {
                                        $keys["mediawiki:limiter:$action:subnet:$subnet"] = $limits['subnet'];
                                }
                        }
                }
+
                // Check for group-specific permissions
-               // If more than one group applies, use the group with the highest limit
+               // If more than one group applies, use the group with the highest limit ratio (max/period)
                foreach ( $this->getGroups() as $group ) {
                        if ( isset( $limits[$group] ) ) {
                                if ( $userLimit === false
@@ -1771,6 +1812,7 @@ class User implements IDBAccessObject {
                                }
                        }
                }
+
                // Set the user limit key
                if ( $userLimit !== false ) {
                        list( $max, $period ) = $userLimit;
@@ -1778,6 +1820,30 @@ class User implements IDBAccessObject {
                        $keys[wfMemcKey( 'limiter', $action, 'user', $id )] = $userLimit;
                }
 
+               // ip-based limits for all ping-limitable users
+               if ( isset( $limits['ip-all'] ) ) {
+                       $ip = $this->getRequest()->getIP();
+                       // ignore if user limit is more permissive
+                       if ( $isNewbie || $userLimit === false
+                               || $limits['ip-all'][0] / $limits['ip-all'][1] > $userLimit[0] / $userLimit[1] ) {
+                               $keys["mediawiki:limiter:$action:ip-all:$ip"] = $limits['ip-all'];
+                       }
+               }
+
+               // subnet-based limits for all ping-limitable users
+               if ( isset( $limits['subnet-all'] ) ) {
+                       $ip = $this->getRequest()->getIP();
+                       $subnet = IP::getSubnet( $ip );
+                       if ( $subnet !== false ) {
+                               // ignore if user limit is more permissive
+                               if ( $isNewbie || $userLimit === false
+                                       || $limits['ip-all'][0] / $limits['ip-all'][1]
+                                       > $userLimit[0] / $userLimit[1] ) {
+                                       $keys["mediawiki:limiter:$action:subnet-all:$subnet"] = $limits['subnet-all'];
+                               }
+                       }
+               }
+
                $cache = ObjectCache::getLocalClusterInstance();
 
                $triggered = false;
@@ -2419,14 +2485,38 @@ class User implements IDBAccessObject {
         * Get the user's current token.
         * @param bool $forceCreation Force the generation of a new token if the
         *   user doesn't have one (default=true for backwards compatibility).
-        * @return string Token
+        * @return string|null Token
         */
        public function getToken( $forceCreation = true ) {
+               global $wgAuthenticationTokenVersion;
+
                $this->load();
                if ( !$this->mToken && $forceCreation ) {
                        $this->setToken();
                }
-               return $this->mToken;
+
+               if ( !$this->mToken ) {
+                       // The user doesn't have a token, return null to indicate that.
+                       return null;
+               } elseif ( $this->mToken === self::INVALID_TOKEN ) {
+                       // We return a random value here so existing token checks are very
+                       // likely to fail.
+                       return MWCryptRand::generateHex( self::TOKEN_LENGTH );
+               } elseif ( $wgAuthenticationTokenVersion === null ) {
+                       // $wgAuthenticationTokenVersion not in use, so return the raw secret
+                       return $this->mToken;
+               } else {
+                       // $wgAuthenticationTokenVersion in use, so hmac it.
+                       $ret = MWCryptHash::hmac( $wgAuthenticationTokenVersion, $this->mToken, false );
+
+                       // The raw hash can be overly long. Shorten it up.
+                       $len = max( 32, self::TOKEN_LENGTH );
+                       if ( strlen( $ret ) < $len ) {
+                               // Should never happen, even md5 is 128 bits
+                               throw new \UnexpectedValueException( 'Hmac returned less than 128 bits' );
+                       }
+                       return substr( $ret, -$len );
+               }
        }
 
        /**
@@ -2437,7 +2527,10 @@ class User implements IDBAccessObject {
         */
        public function setToken( $token = false ) {
                $this->load();
-               if ( !$token ) {
+               if ( $this->mToken === self::INVALID_TOKEN ) {
+                       \MediaWiki\Logger\LoggerFactory::getInstance( 'session' )
+                               ->debug( __METHOD__ . ": Ignoring attempt to set token for system user \"$this\"" );
+               } elseif ( !$token ) {
                        $this->mToken = MWCryptRand::generateHex( self::TOKEN_LENGTH );
                } else {
                        $this->mToken = $token;
@@ -3431,7 +3524,7 @@ class User implements IDBAccessObject {
                }
 
                $this->getWatchedItem( $title )->resetNotificationTimestamp(
-                       $force, $oldid, WatchedItem::DEFERRED
+                       $force, $oldid
                );
        }
 
@@ -4066,30 +4159,25 @@ class User implements IDBAccessObject {
        }
 
        /**
-        * Internal implementation for self::getEditToken() and
-        * self::matchEditToken().
+        * 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 string|array $salt
-        * @param WebRequest $request
-        * @param string|int $timestamp
-        * @return string
+        * @since 1.27
+        * @param string|array $salt Array of Strings Optional function-specific data for hashing
+        * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
+        * @return MediaWiki\\Session\\Token The new edit token
         */
-       private function getEditTokenAtTimestamp( $salt, $request, $timestamp ) {
+       public function getEditTokenObject( $salt = '', $request = null ) {
                if ( $this->isAnon() ) {
-                       return self::EDIT_TOKEN_SUFFIX;
-               } else {
-                       $token = $request->getSessionData( 'wsEditToken' );
-                       if ( $token === null ) {
-                               $token = MWCryptRand::generateHex( 32 );
-                               $request->setSessionData( 'wsEditToken', $token );
-                       }
-                       if ( is_array( $salt ) ) {
-                               $salt = implode( '|', $salt );
-                       }
-                       return hash_hmac( 'md5', $timestamp . $salt, $token, false ) .
-                               dechex( $timestamp ) .
-                               self::EDIT_TOKEN_SUFFIX;
+                       return new LoggedOutEditToken();
                }
+
+               if ( !$request ) {
+                       $request = $this->getRequest();
+               }
+               return $request->getSession()->getToken( $salt );
        }
 
        /**
@@ -4099,29 +4187,23 @@ class User implements IDBAccessObject {
         * submission.
         *
         * @since 1.19
-        *
         * @param string|array $salt Array of Strings Optional function-specific data for hashing
         * @param WebRequest|null $request WebRequest object to use or null to use $wgRequest
         * @return string The new edit token
         */
        public function getEditToken( $salt = '', $request = null ) {
-               return $this->getEditTokenAtTimestamp(
-                       $salt, $request ?: $this->getRequest(), wfTimestamp()
-               );
+               return $this->getEditTokenObject( $salt, $request )->toString();
        }
 
        /**
         * Get the embedded timestamp from a token.
+        * @deprecated since 1.27, use \\MediaWiki\\Session\\Token::getTimestamp instead.
         * @param string $val Input token
         * @return int|null
         */
        public static function getEditTokenTimestamp( $val ) {
-               $suffixLen = strlen( self::EDIT_TOKEN_SUFFIX );
-               if ( strlen( $val ) <= 32 + $suffixLen ) {
-                       return null;
-               }
-
-               return hexdec( substr( $val, 32, -$suffixLen ) );
+               wfDeprecated( __METHOD__, '1.27' );
+               return MediaWiki\Session\Token::getTimestamp( $val );
        }
 
        /**
@@ -4137,28 +4219,7 @@ class User implements IDBAccessObject {
         * @return bool Whether the token matches
         */
        public function matchEditToken( $val, $salt = '', $request = null, $maxage = null ) {
-               if ( $this->isAnon() ) {
-                       return $val === self::EDIT_TOKEN_SUFFIX;
-               }
-
-               $timestamp = self::getEditTokenTimestamp( $val );
-               if ( $timestamp === null ) {
-                       return false;
-               }
-               if ( $maxage !== null && $timestamp < wfTimestamp() - $maxage ) {
-                       // Expired token
-                       return false;
-               }
-
-               $sessionToken = $this->getEditTokenAtTimestamp(
-                       $salt, $request ?: $this->getRequest(), $timestamp
-               );
-
-               if ( !hash_equals( $sessionToken, $val ) ) {
-                       wfDebug( "User::matchEditToken: broken session data\n" );
-               }
-
-               return hash_equals( $sessionToken, $val );
+               return $this->getEditTokenObject( $salt, $request )->match( $val, $maxage );
        }
 
        /**
index 13cab5b..ffb7053 100644 (file)
@@ -66,6 +66,6 @@ class BatchRowWriter {
                }
 
                $this->db->commit();
-               wfWaitForSlaves( false, false, $this->clusterName );
+               wfGetLBFactory()->waitForReplication();
        }
 }
index 8abca5b..b352ecc 100644 (file)
@@ -766,4 +766,23 @@ class IP {
        public static function clearCaches() {
                self::$proxyIpSet = null;
        }
+
+       /**
+        * Returns the subnet of a given IP
+        *
+        * @param string $ip
+        * @return string|false
+        */
+       public static function getSubnet( $ip ) {
+               $matches = array();
+               $subnet = false;
+               if ( IP::isIPv6( $ip ) ) {
+                       $parts = IP::parseRange( "$ip/64" );
+                       $subnet = $parts[0];
+               } elseif ( preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
+                       // IPv4
+                       $subnet = $matches[1];
+               }
+               return $subnet;
+       }
 }
index aac76c5..53300c5 100644 (file)
@@ -7,7 +7,7 @@
        "--builtin-classes": true,
        "--processes": "0",
        "--warnings-exit-nonzero": true,
-       "--external": "HTMLElement,HTMLDocument,Window,File,MouseEvent,KeyboardEvent,HTMLIframeElement,HTMLInputElement,XMLDocument",
+       "--external": "HTMLElement,HTMLDocument,Window,Blob,File,MouseEvent,KeyboardEvent,HTMLIframeElement,HTMLInputElement,XMLDocument",
        "--output": "docs/js",
        "--": [
                "maintenance/jsduck/external.js",
index cb2d24f..42c5a57 100644 (file)
@@ -383,20 +383,13 @@ class Language {
         * @return bool
         */
        public static function isKnownLanguageTag( $tag ) {
-               static $coreLanguageNames;
-
                // Quick escape for invalid input to avoid exceptions down the line
                // when code tries to process tags which are not valid at all.
                if ( !self::isValidBuiltInCode( $tag ) ) {
                        return false;
                }
 
-               if ( $coreLanguageNames === null ) {
-                       global $IP;
-                       include "$IP/languages/Names.php";
-               }
-
-               if ( isset( $coreLanguageNames[$tag] )
+               if ( isset( MediaWiki\Languages\Data\Names::$names[$tag] )
                        || self::fetchLanguageName( $tag, $tag ) !== ''
                ) {
                        return true;
@@ -874,12 +867,6 @@ class Language {
         */
        private static function fetchLanguageNamesUncached( $inLanguage = null, $include = 'mw' ) {
                global $wgExtraLanguageNames;
-               static $coreLanguageNames;
-
-               if ( $coreLanguageNames === null ) {
-                       global $IP;
-                       include "$IP/languages/Names.php";
-               }
 
                // If passed an invalid language code to use, fallback to en
                if ( $inLanguage !== null && !Language::isValidCode( $inLanguage ) ) {
@@ -893,7 +880,7 @@ class Language {
                        Hooks::run( 'LanguageGetTranslatedLanguageNames', array( &$names, $inLanguage ) );
                }
 
-               $mwNames = $wgExtraLanguageNames + $coreLanguageNames;
+               $mwNames = $wgExtraLanguageNames + MediaWiki\Languages\Data\Names::$names;
                foreach ( $mwNames as $mwCode => $mwName ) {
                        # - Prefer own MediaWiki native name when not using the hook
                        # - For other names just add if not added through the hook
diff --git a/languages/Names.php b/languages/Names.php
deleted file mode 100644 (file)
index c27755e..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-<?php
-/**
- * Language names.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Language
- */
-
-/**
- * These determine things like interwikis, language selectors, and so on.
- * Safe to change without running scripts on the respective sites.
- *
- * \xE2\x80\x8E is the left-to-right marker and
- * \xE2\x80\x8F is the right-to-left marker.
- * They are required for ensuring the correct display of brackets in
- * mixed rtl/ltr environment.
- *
- * Some writing systems require some line-height fixes. This includes
- * most Indic scripts, like Devanagari.
- * If you are adding support for such a language, add it also to
- * the relevant section in shared.css.
- *
- * @ingroup Language
- */
-/* private */ $coreLanguageNames = array(
-       'aa' => 'Qafár af',    # Afar
-       'ab' => 'Аҧсшәа', # Abkhaz
-       'ace' => 'Acèh',       # Aceh
-       'ady' => 'адыгабзэ',    # Adyghe
-       'ady-cyrl' => 'адыгабзэ',       # Adyghe
-       'aeb' => 'تونسي/Tûnsî',  # Tunisian Arabic (multiple scripts - defaults to Arabic)
-       'aeb-arab' => 'تونسي',     # Tunisian Arabic (Arabic Script)
-       'aeb-latn' => 'Tûnsî',        # Tunisian Arabic (Latin Script)
-       'af' => 'Afrikaans',    # Afrikaans
-       'ak' => 'Akan',         # Akan
-       'aln' => 'Gegë',       # Gheg Albanian
-       'als' => 'Alemannisch', # Alemannic -- not a valid code, for compatibility. See gsw.
-       'am' => 'አማርኛ', # Amharic
-       'an' => 'aragonés',    # Aragonese
-       'ang' => 'Ænglisc',    # Old English, bug 23283
-       'anp' => 'अङ्गिका',       # Angika
-       'ar' => 'العربية',       # Arabic
-       'arc' => 'ܐܪܡܝܐ',  # Aramaic
-       'arn' => 'mapudungun',  # Mapuche, Mapudungu, Araucanian (Araucano)
-       'arq' => 'جازايرية', # Algerian Spoken Arabic
-       'ary' => 'Maġribi',    # Moroccan Spoken Arabic
-       'arz' => 'مصرى',    # Egyptian Spoken Arabic
-       'as' => 'অসমীয়া',        # Assamese
-       'ase' => 'American sign language',      # American sign language
-       'ast' => 'asturianu',   # Asturian
-       'av' => 'авар',     # Avar
-       'avk' => 'Kotava', # Kotava
-       'awa' => 'अवधी',        # Awadhi
-       'ay' => 'Aymar aru',    # Aymara
-       'az' => 'azərbaycanca',        # Azerbaijani
-       'azb' => 'تۆرکجه',        # South Azerbaijani
-       'ba' => 'башҡортса',   # Bashkir
-       'bar' => 'Boarisch',    # Bavarian (Austro-Bavarian and South Tyrolean)
-       'bat-smg' => 'žemaitėška', # Samogitian (deprecated code, 'sgs' in ISO 693-3 since 2010-06-30 )
-       'bbc' => 'Batak Toba', # Batak Toba (falls back to bbc-latn)
-       'bbc-latn' => 'Batak Toba', # Batak Toba
-       'bcc' => 'جهلسری بلوچی', # Southern Balochi
-       'bcl' => 'Bikol Central', # Bikol: Central Bicolano language
-       'be' => 'беларуская', #  Belarusian normative
-       'be-tarask' => "беларуская (тарашкевіца)\xE2\x80\x8E",     # Belarusian in Taraskievica orthography
-       'be-x-old' => "беларуская (тарашкевіца)\xE2\x80\x8E",      # (be-tarask compat)
-       'bg' => 'български',   # Bulgarian
-       'bgn' => 'روچ کپتین بلوچی', # Western Balochi
-       'bh' => 'भोजपुरी',        # Bihari macro language. Falls back to Bhojpuri (bho)
-       'bho' => 'भोजपुरी',       # Bhojpuri
-       'bi' => 'Bislama',              # Bislama
-       'bjn' => 'Bahasa Banjar',       # Banjarese
-       'bm' => 'bamanankan',   # Bambara
-       'bn' => 'বাংলা',      # Bengali
-       'bo' => 'བོད་ཡིག',        # Tibetan
-       'bpy' => 'বিষ্ণুপ্রিয়া মণিপুরী',       # Bishnupriya Manipuri
-       'bqi' => 'بختیاری',      # Bakthiari
-       'br' => 'brezhoneg',    # Breton
-       'brh' => 'Bráhuí',    # Brahui
-       'bs' => 'bosanski',             # Bosnian
-       'bto' => 'Iriga Bicolano',      # Rinconada Bikol
-       'bug' => 'ᨅᨔ ᨕᨘᨁᨗ', # Buginese
-       'bxr' => 'буряад',        # Buryat (Russia)
-       'ca' => 'català',      # Catalan
-       'cbk-zam' => 'Chavacano de Zamboanga',  # 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
-       'ckb' => 'کوردیی ناوەندی', # Central Kurdish
-       'co' => 'corsu',                # Corsican
-       'cps' => 'Capiceño', # Capiznon
-       'cr' => 'Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ',                # Cree
-       'crh' => 'qırımtatarca',   # Crimean Tatar (multiple scripts - defaults to Latin)
-       'crh-latn' => "qırımtatarca (Latin)\xE2\x80\x8E",       # Crimean Tatar (Latin)
-       'crh-cyrl' => "къырымтатарджа (Кирилл)\xE2\x80\x8E",       # Crimean Tatar (Cyrillic)
-       'cs' => 'čeština',    # Czech
-       'csb' => 'kaszëbsczi', # Cassubian
-       'cu' => 'словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ',        # Old Church Slavonic (ancient language)
-       'cv' => 'Чӑвашла',       # Chuvash
-       'cy' => 'Cymraeg',              # Welsh
-       'da' => 'dansk',                # Danish
-       'de' => 'Deutsch',              # German ("Du")
-       'de-at' => 'Österreichisches Deutsch',         # Austrian German
-       'de-ch' => 'Schweizer Hochdeutsch',             # Swiss Standard German
-       'de-formal' => "Deutsch (Sie-Form)\xE2\x80\x8E",                # German - formal address ("Sie")
-       'diq' => 'Zazaki',              # Zazaki
-       'dsb' => 'dolnoserbski', # Lower Sorbian
-       'dtp' => 'Dusun Bundu-liwan', # Central Dusun
-       'dty' => 'डोटेली', # Doteli
-       'dv' => 'ދިވެހިބަސް',         # Dhivehi
-       'dz' => 'ཇོང་ཁ',              # Dzongkha (Bhutan)
-       'ee' => 'eʋegbe',      # Éwé
-       'egl' => 'Emiliàn',    # Emilian
-       'el' => 'Ελληνικά',     # Greek
-       'eml' => 'emiliàn e rumagnòl',        # Emiliano-Romagnolo / Sammarinese
-       'en' => 'English',              # English
-       'en-ca' => 'Canadian English',  # Canadian English
-       'en-gb' => 'British English',   # British English
-       'eo' => 'Esperanto',    # Esperanto
-       'es' => 'español',     # Spanish
-       'et' => 'eesti',                # Estonian
-       'eu' => 'euskara',              # Basque
-       'ext' => 'estremeñu', # Extremaduran
-       'fa' => 'فارسی',   # Persian
-       'ff' => 'Fulfulde',             # Fulfulde, Maasina
-       'fi' => 'suomi',                # Finnish
-       'fit' => 'meänkieli', # Tornedalen Finnish
-       'fiu-vro' => 'Võro',    # Võro (deprecated code, 'vro' in ISO 639-3 since 2009-01-16)
-       'fj' => 'Na Vosa Vakaviti',     # Fijian
-       'fo' => 'føroyskt',    # Faroese
-       'fr' => 'français',    # French
-       'frc' => 'français cadien', # Cajun French
-       'frp' => 'arpetan',     # Franco-Provençal/Arpitan
-       'frr' => 'Nordfriisk',  # North Frisian
-       'fur' => 'furlan',              # Friulian
-       'fy' => 'Frysk',                # Frisian
-       'ga' => 'Gaeilge',              # Irish
-       'gag' => 'Gagauz',              # Gagauz
-       'gan' => '贛語',              # Gan (multiple scripts - defaults to Traditional)
-       'gan-hans' => "赣语(简体)\xE2\x80\x8E", # Gan (Simplified Han)
-       'gan-hant' => "贛語(繁體)\xE2\x80\x8E", # Gan (Traditional Han)
-       'gd' => 'Gàidhlig',    # Scots Gaelic
-       'gl' => 'galego',               # Galician
-       'glk' => 'گیلکی',  # Gilaki
-       'gn' => 'Avañe\'ẽ',  # Guaraní, Paraguayan
-       'gom' => 'गोवा कोंकणी / Gova Konknni',      # Goan Konkani
-       'gom-deva' => 'गोवा कोंकणी',        # Goan Konkani (Devanagari script)
-       'gom-latn' => 'Gova Konknni',   # Goan Konkani (Latin script)
-       'got' => '𐌲𐌿𐍄𐌹𐍃𐌺',    # Gothic
-       'grc' => 'Ἀρχαία ἑλληνικὴ', # Ancient Greek
-       'gsw' => 'Alemannisch', # Alemannic
-       'gu' => 'ગુજરાતી',        # Gujarati
-       'gv' => 'Gaelg',                # Manx
-       'ha' => 'Hausa',        # Hausa
-       'hak' => '客家語/Hak-kâ-ngî',      # Hakka
-       'haw' => 'Hawai`i',             # Hawaiian
-       'he' => 'עברית',   # Hebrew
-       'hi' => 'हिन्दी',   # Hindi
-       'hif' => 'Fiji Hindi',  # Fijian Hindi (multiple scripts - defaults to Latin)
-       'hif-latn' => 'Fiji Hindi',     # Fiji Hindi (latin)
-       'hil' => 'Ilonggo',     # Hiligaynon
-       'ho' => 'Hiri Motu',    # Hiri Motu
-       'hr' => 'hrvatski',             # Croatian
-       'hrx' => 'Hunsrik', # Riograndenser Hunsrückisch
-       'hsb' => 'hornjoserbsce',       # Upper Sorbian
-       'ht' => 'Kreyòl ayisyen',              # Haitian Creole French
-       '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 (Inupiatun, Northwest Alaska / Inupiatun, North Alaskan)
-       'ike-cans' => 'ᐃᓄᒃᑎᑐᑦ',     # Inuktitut, Eastern Canadian (Unified Canadian Aboriginal Syllabics)
-       'ike-latn' => 'inuktitut',      # Inuktitut, Eastern Canadian (Latin script)
-       'ilo' => 'Ilokano',     # Ilokano
-       'inh' => 'ГӀалгӀай',    # Ingush
-       'io' => 'Ido',                  # Ido
-       'is' => 'íslenska',    # Icelandic
-       'it' => 'italiano',             # Italian
-       'iu' => 'ᐃᓄᒃᑎᑐᑦ/inuktitut', # Inuktitut (macro language, see ike/ikt, falls back to ike-cans)
-       'ja' => '日本語',    # Japanese
-       'jam' => 'Patois',      # Jamaican Creole English
-       'jbo' => 'la .lojban.',         # Lojban
-       'jut' => 'jysk',        # Jutish / Jutlandic
-       'jv' => 'Basa Jawa',    # Javanese
-       'ka' => 'ქართული',        # Georgian
-       'kaa' => 'Qaraqalpaqsha',       # Karakalpak
-       'kab' => 'Taqbaylit',   # Kabyle
-       'kbd' => 'Адыгэбзэ',    # Kabardian
-       'kbd-cyrl' => 'Адыгэбзэ',       # Kabardian (Cyrillic)
-       'kg' => 'Kongo',        # Kongo, (FIXME!) should probaly be KiKongo or KiKoongo
-       'khw' => 'کھوار',  # Khowar
-       'ki' => 'Gĩkũyũ',    # Gikuyu
-       'kiu' => 'Kırmancki',  # Kirmanjki
-       'kj' => 'Kwanyama',     # Kwanyama
-       'kk' => 'қазақша',       # Kazakh (multiple scripts - defaults to Cyrillic)
-       'kk-arab' => "قازاقشا (تٴوتە)\xE2\x80\x8F", # Kazakh Arabic
-       'kk-cyrl' => "қазақша (кирил)\xE2\x80\x8E", # Kazakh Cyrillic
-       'kk-latn' => "qazaqşa (latın)\xE2\x80\x8E",   # Kazakh Latin
-       'kk-cn' => "قازاقشا (جۇنگو)\xE2\x80\x8F",   # Kazakh (China)
-       'kk-kz' => "қазақша (Қазақстан)\xE2\x80\x8E",   # Kazakh (Kazakhstan)
-       'kk-tr' => "qazaqşa (Türkïya)\xE2\x80\x8E",  # Kazakh (Turkey)
-       'kl' => 'kalaallisut',  # Inuktitut, Greenlandic/Greenlandic/Kalaallisut (kal)
-       'km' => 'ភាសាខ្មែរ',  # Khmer, Central
-       'kn' => 'ಕನ್ನಡ',      # Kannada
-       'ko' => '한국어',    # Korean
-       'ko-kp' => '한국어 (조선)',        # Korean (DPRK)
-       'koi' => 'Перем Коми', # Komi-Permyak
-       'kr' => 'Kanuri',               # Kanuri, Central
-       'krc' => 'къарачай-малкъар', # Karachay-Balkar
-       'kri' => 'Krio', # Krio
-       'krj' => 'Kinaray-a', # Kinaray-a
-       'ks' => 'कॉशुर / کٲشُر', # Kashmiri (multiple scripts - defaults to Perso-Arabic)
-       'ks-arab' => 'کٲشُر',      # Kashmiri (Perso-Arabic script)
-       'ks-deva' => 'कॉशुर', # Kashmiri (Devanagari script)
-       'ksh' => 'Ripoarisch',  # Ripuarian
-       'ku' => 'Kurdî',       # Kurdish (multiple scripts - defaults to Latin)
-       'ku-latn' => "Kurdî (latînî)\xE2\x80\x8E",   # Northern Kurdish (Latin script)
-       'ku-arab' => "كوردي (عەرەبی)\xE2\x80\x8F",   # Northern Kurdish (Arabic script) (falls back to ckb)
-       'kv' => 'коми',     # Komi-Zyrian (Cyrillic is common script but also written in Latin script)
-       'kw' => 'kernowek',             # Cornish
-       'ky' => 'Кыргызча',     # Kirghiz
-       'la' => 'Latina',               # Latin
-       'lad' => 'Ladino',      # Ladino
-       'lb' => 'Lëtzebuergesch',      # Luxemburguish
-       'lbe' => 'лакку',  # Lak
-       'lez' => 'лезги',  # Lezgi
-       'lfn' => 'Lingua Franca Nova',  # Lingua Franca Nova
-       'lg' => 'Luganda',              # Ganda
-       'li' => 'Limburgs',     # Limburgian
-       'lij' => 'Ligure',      # Ligurian
-       'liv' => 'Līvõ kēļ',        # Livonian
-       'lmo' => 'lumbaart',    # Lombard
-       'ln' => 'lingála',             # Lingala
-       'lo' => 'ລາວ',    # Laotian
-       'lrc' => 'لۊری شومالی',       # Northern Luri
-       'loz' => 'Silozi', # Lozi
-       'lt' => 'lietuvių',    # Lithuanian
-       'ltg' => 'latgaļu',    # Latgalian
-       'lus' => 'Mizo ţawng', # Mizo/Lushai
-       'luz' => 'لئری دوٙمینی', # Southern Luri
-       'lv' => 'latviešu',    # Latvian
-       'lzh' => '文言',      # Literary Chinese, bug 8217
-       'lzz' => 'Lazuri',      # Laz
-       'mai' => 'मैथिली', # Maithili
-       'map-bms' => 'Basa Banyumasan', # Banyumasan
-       'mdf' => 'мокшень',              # Moksha
-       'mg' => 'Malagasy',             # Malagasy
-       'mh' => 'Ebon',                 # Marshallese
-       'mhr' => 'олык марий', # Eastern Mari
-       'mi' => 'Māori',       # Maori
-       'min' => 'Baso Minangkabau',    # Minangkabau
-       'mk' => 'македонски', # Macedonian
-       'ml' => 'മലയാളം',   # Malayalam
-       'mn' => 'монгол', # Halh Mongolian (Cyrillic) (ISO 639-3: khk)
-       'mo' => 'молдовеняскэ',     # Moldovan, deprecated
-       'mr' => 'मराठी',      # Marathi
-       'mrj' => 'кырык мары', # Hill Mari
-       'ms' => 'Bahasa Melayu',        # Malay
-       'mt' => 'Malti',        # Maltese
-       'mus' => 'Mvskoke',     # Muskogee/Creek
-       'mwl' => 'Mirandés',   # Mirandese
-       'my' => 'မြန်မာဘာသာ',               # Burmese
-       'myv' => 'эрзянь',        # Erzya
-       'mzn' => 'مازِرونی',            # Mazanderani
-       'na' => 'Dorerin Naoero',               # Nauruan
-       'nah' => 'Nāhuatl',            # Nahuatl (not in ISO 639-3)
-       'nan' => 'Bân-lâm-gú', # Min-nan, bug 8217
-       'nap' => 'Napulitano',  # Neapolitan, bug 43793
-       'nb' => "norsk bokmål",                # Norwegian (Bokmal)
-       'nds' => 'Plattdüütsch',      # Low German ''or'' Low Saxon
-       'nds-nl' => 'Nedersaksies',     # aka Nedersaksisch: Dutch Low Saxon
-       'ne' => 'नेपाली',   # Nepali
-       'new' => 'नेपाल भाषा',                # Newar / Nepal Bhasha
-       'ng' => 'Oshiwambo',            # Ndonga
-       'niu' => 'Niuē',       # Niuean
-       'nl' => 'Nederlands',   # Dutch
-       'nl-informal' => "Nederlands (informeel)\xE2\x80\x8E",  # Dutch (informal address ("je"))
-       'nn' => "norsk nynorsk",        # Norwegian (Nynorsk)
-       'no' => "norsk bokmål",                # Norwegian (falls back to nb).
-       'nov' => 'Novial',              # Novial
-       'nrm' => 'Nouormand',   # Norman
-       'nso' => 'Sesotho sa Leboa',    # Northern Sotho
-       'nv' => 'Diné bizaad', # Navajo
-       'ny' => 'Chi-Chewa',    # Chichewa
-       'oc' => 'occitan',              # Occitan
-       'olo' => 'Livvinкarjala',              # Livvi-Karelian
-       'om' => 'Oromoo',               # Oromo
-       'or' => 'ଓଡ଼ିଆ',              # Oriya
-       'os' => 'Ирон', # Ossetic, bug 29091
-       'pa' => 'ਪੰਜਾਬੀ', # Eastern Punjabi (Gurmukhi script) (pan)
-       'pag' => 'Pangasinan',  # Pangasinan
-       'pam' => 'Kapampangan',   # Pampanga
-       'pap' => 'Papiamentu',  # Papiamentu
-       'pcd' => 'Picard',      # Picard
-       'pdc' => 'Deitsch',     # Pennsylvania German
-       'pdt' => 'Plautdietsch',        # Plautdietsch/Mennonite Low German
-       'pfl' => 'Pälzisch',   # Palatinate German
-       'pi' => 'पालि', # Pali
-       'pih' => 'Norfuk / Pitkern', # Norfuk/Pitcairn/Norfolk
-       'pl' => 'polski',               # Polish
-       'pms' => 'Piemontèis', # Piedmontese
-       'pnb' => 'پنجابی',        # Western Punjabi
-       'pnt' => 'Ποντιακά',    # Pontic/Pontic Greek
-       'prg' => 'Prūsiskan',  # Prussian
-       'ps' => 'پښتو',     # Pashto, Northern/Paktu/Pakhtu/Pakhtoo/Afghan/Pakhto/Pashtu/Pushto/Yusufzai Pashto
-       'pt' => 'português',   # Portuguese
-       'pt-br' => 'português do Brasil',      # Brazilian Portuguese
-       'qu' => 'Runa Simi',    # Southern Quechua
-       'qug' => 'Runa shimi',  # Kichwa/Northern Quechua (temporarily used until Kichwa has its own)
-       'rgn' => 'Rumagnôl',   # Romagnol
-       'rif' => 'Tarifit',     # Tarifit
-       'rm' => 'rumantsch',    # Raeto-Romance
-       'rmy' => 'Romani',      # Vlax Romany
-       'rn' => 'Kirundi',              # Rundi/Kirundi/Urundi
-       'ro' => 'română',     # Romanian
-       'roa-rup' => 'armãneashti', # Aromanian (deprecated code, 'rup' exists in ISO 693-3)
-       'roa-tara' => 'tarandíne',     # Tarantino
-       'ru' => 'русский',       # Russian
-       'rue' => 'русиньскый',        # Rusyn
-       'rup' => 'armãneashti', # Aromanian
-       'ruq' => 'Vlăheşte',  # Megleno-Romanian (multiple scripts - defaults to Latin)
-       'ruq-cyrl' => 'Влахесте',       # Megleno-Romanian (Cyrillic script)
-       # 'ruq-grek' => 'Βλαεστε',       # Megleno-Romanian (Greek script)
-       'ruq-latn' => 'Vlăheşte',     # Megleno-Romanian (Latin script)
-       'rw' => 'Kinyarwanda',  # Kinyarwanda, should possibly be Kinyarwandi
-       'sa' => 'संस्कृतम्',  # Sanskrit
-       'sah' => 'саха тыла', # Sakha
-       'sat' => 'Santali',     # Santali
-       'sc' => 'sardu',                # Sardinian
-       'scn' => 'sicilianu',   # Sicilian
-       'sco' => 'Scots',       # Scots
-       'sd' => 'سنڌي',     # Sindhi
-       'sdc' => 'Sassaresu',   # Sassarese
-       'sdh' => 'کوردی خوارگ',       # Southern Kurdish
-       'se' => 'sámegiella',  # Northern Sami
-       'sei' => 'Cmique Itom', # Seri
-       'ses' => 'Koyraboro Senni',     # Koyraboro Senni
-       'sg' => 'Sängö',              # Sango/Sangho
-       'sgs' => 'žemaitėška', # Samogitian
-       'sh' => 'srpskohrvatski / српскохрватски', # Serbocroatian
-       'shi' => 'Tašlḥiyt/ⵜⴰⵛⵍⵃⵉⵜ',    # Tachelhit (multiple scripts - defaults to Latin)
-       'shi-tfng' => 'ⵜⴰⵛⵍⵃⵉⵜ',    # Tachelhit (Tifinagh script)
-       'shi-latn' => 'Tašlḥiyt',    # Tachelhit (Latin script)
-       'si' => 'සිංහල',      # Sinhalese
-       'simple' => 'Simple English',   # Simple English
-       'sk' => 'slovenčina',  # Slovak
-       'sl' => 'slovenščina',        # Slovenian
-       'sli' => 'Schläsch',   # Lower Selisian
-       'sm' => 'Gagana Samoa', # Samoan
-       'sma' => 'Åarjelsaemien',      # Southern Sami
-       'sn' => 'chiShona',             # Shona
-       'so' => 'Soomaaliga',   # Somali
-       'sq' => 'shqip',                # Albanian
-       'sr' => 'српски / srpski',        # Serbian (multiple scripts - defaults to Cyrillic)
-       'sr-ec' => "српски (ћирилица)\xE2\x80\x8E",       # Serbian Cyrillic ekavian
-       'sr-el' => "srpski (latinica)\xE2\x80\x8E",     # Serbian Latin ekavian
-       'srn' => 'Sranantongo',         # Sranan Tongo
-       'ss' => 'SiSwati',              # Swati
-       'st' => 'Sesotho',              # Southern Sotho
-       'stq' => 'Seeltersk',           # Saterland Frisian
-       'su' => 'Basa Sunda',   # Sundanese
-       'sv' => 'svenska',              # Swedish
-       'sw' => 'Kiswahili',    # Swahili
-       'szl' => 'ślůnski',   # Silesian
-       'ta' => 'தமிழ்',      # Tamil
-       'tcy' => 'ತುಳು', # Tulu
-       'te' => 'తెలుగు',   # Telugu
-       'tet' => 'tetun',       # Tetun
-       'tg' => 'тоҷикӣ', # Tajiki (falls back to tg-cyrl)
-       'tg-cyrl' => 'тоҷикӣ',    # Tajiki (Cyrllic script) (default)
-       'tg-latn' => 'tojikī', # Tajiki (Latin script)
-       'th' => 'ไทย',    # Thai
-       'ti' => 'ትግርኛ',         # Tigrinya
-       'tk' => 'Türkmençe',  # Turkmen
-       'tl' => 'Tagalog',              # Tagalog
-       'tly' => 'толышә зывон',     # Talysh
-       'tn' => 'Setswana',             # Setswana
-       'to' => 'lea faka-Tonga',               # Tonga (Tonga Islands)
-       'tokipona' => 'Toki Pona',      # Toki Pona
-       'tpi' => 'Tok Pisin',   # Tok Pisin
-       'tr' => 'Türkçe',     # Turkish
-       'tru' => 'Ṫuroyo', # Turoyo
-       'ts' => 'Xitsonga',             # Tsonga
-       'tt' => 'татарча/tatarça',      # Tatar (multiple scripts - defaults to Cyrillic)
-       'tt-cyrl' => 'татарча',  # Tatar (Cyrillic script) (default)
-       'tt-latn' => 'tatarça',        # Tatar (Latin script)
-       'tum' => 'chiTumbuka',  # Tumbuka
-       'tw' => 'Twi',                  # Twi, (FIXME!)
-       'ty' => 'reo tahiti',   # Tahitian
-       'tyv' => 'тыва дыл',     # Tyvan
-       'tzm' => 'ⵜⴰⵎⴰⵣⵉⵖⵜ',    # Tamazight
-       'udm' => 'удмурт',        # Udmurt
-       'ug' => 'ئۇيغۇرچە / Uyghurche', # Uyghur (multiple scripts - defaults to Arabic)
-       'ug-arab' => 'ئۇيغۇرچە', # Uyghur (Arabic script) (default)
-       'ug-latn' => 'Uyghurche', # Uyghur (Latin script)
-       'uk' => 'українська', # Ukrainian
-       'ur' => 'اردو',     # Urdu
-       'uz' => "oʻzbekcha/ўзбекча",    # Uzbek (multiple scripts - defaults to Latin)
-       'uz-cyrl' => "ўзбекча",  # Uzbek Cyrillic
-       'uz-latn' => "oʻzbekcha",      # Uzbek Latin (default)
-       've' => 'Tshivenda',            # Venda
-       'vec' => 'vèneto',     # Venetian
-       'vep' => 'vepsän kel’',      # Veps
-       'vi' => 'Tiếng Việt',       # Vietnamese
-       'vls' => 'West-Vlams', # West Flemish
-       'vmf' => 'Mainfränkisch', # Upper Franconian, Main-Franconian
-       'vo' => 'Volapük',     # Volapük
-       'vot' => 'Vaďďa',     # Vod/Votian
-       'vro' => 'Võro',    # Võro
-       'wa' => 'walon',                # Walloon
-       'war' => 'Winaray', # Waray-Waray
-       'wo' => 'Wolof',                # Wolof
-       'wuu' => '吴语',              # Wu Chinese
-       'xal' => 'хальмг',                # Kalmyk-Oirat
-       'xh' => 'isiXhosa',             # Xhosan
-       'xmf' => 'მარგალური', # Mingrelian
-       'yi' => 'ייִדיש', # Yiddish
-       'yo' => 'Yorùbá',     # Yoruba
-       'yue' => '粵語',      # Cantonese
-       'za' => 'Vahcuengh',    # Zhuang
-       'zea' => 'Zeêuws',     # Zeeuws/Zeaws
-       'zh' => '中文',                                               # (Zhōng Wén) - Chinese
-       'zh-classical' => '文言',                     # Classical Chinese/Literary Chinese -- (see bug 8217)
-       'zh-cn' => "中文(中国大陆)\xE2\x80\x8E",      # Chinese (PRC)
-       'zh-hans' => "中文(简体)\xE2\x80\x8E",  # Mandarin Chinese (Simplified Chinese script) (cmn-hans)
-       'zh-hant' => "中文(繁體)\xE2\x80\x8E",  # Mandarin Chinese (Traditional Chinese script) (cmn-hant)
-       'zh-hk' => "中文(香港)\xE2\x80\x8E",    # Chinese (Hong Kong)
-       'zh-min-nan' => 'Bân-lâm-gú',                                # Min-nan -- (see bug 8217)
-       'zh-mo' => "中文(澳門)\xE2\x80\x8E",    # Chinese (Macau)
-       'zh-my' => "中文(马来西亚)\xE2\x80\x8E",      # Chinese (Malaysia)
-       'zh-sg' => "中文(新加坡)\xE2\x80\x8E", # Chinese (Singapore)
-       'zh-tw' => "中文(台灣)\xE2\x80\x8E",    # Chinese (Taiwan)
-       'zh-yue' => '粵語',                                   # Cantonese -- (see bug 8217)
-       'zu' => 'isiZulu'               # Zulu
-);
index a012f59..9dc3a86 100644 (file)
@@ -21,9 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-require_once __DIR__ . '/LanguageZh.php';
-
 /**
  * @ingroup Language
  */
@@ -57,10 +54,9 @@ class GanConverter extends LanguageConverter {
        }
 
        function loadDefaultTables() {
-               require __DIR__ . '/../../includes/ZhConversion.php';
                $this->mTables = array(
-                       'gan-hans' => new ReplacementArray( $zh2Hans ),
-                       'gan-hant' => new ReplacementArray( $zh2Hant ),
+                       'gan-hans' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2Hans ),
+                       'gan-hant' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2Hant ),
                        'gan' => new ReplacementArray
                );
        }
index db3a22c..af0431f 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-
 /**
  * Conversion script between Latin and Syllabics for Inuktitut.
  * - Syllabics -> lowercase Latin
index 0f60889..0357730 100644 (file)
@@ -21,9 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-require_once __DIR__ . '/LanguageKk_cyrl.php';
-
 define( 'KK_C_UC', 'АӘБВГҒДЕЁЖЗИЙКҚЛМНҢОӨПРСТУҰҮФХҺЦЧШЩЪЫІЬЭЮЯ' ); # Kazakh Cyrillic uppercase
 define( 'KK_C_LC', 'аәбвгғдеёжзийкқлмнңоөпрстуұүфхһцчшщъыіьэюя' ); # Kazakh Cyrillic lowercase
 define( 'KK_L_UC', 'AÄBCÇDEÉFGĞHIİÏJKLMNÑOÖPQRSŞTUÜVWXYÝZ' ); # Kazakh Latin uppercase
index 1fdebc2..c14f468 100644 (file)
@@ -21,9 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-require_once __DIR__ . '/LanguageKu_ku.php';
-
 /**
  * Kurdish converter routines
  *
index 105a3af..afd7283 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-
 /**
  * Conversion script between Latin and Tifinagh for Tachelhit.
  * - Tifinagh -> lowercase Latin
index bdf1ec4..ece50e8 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-
 /**
  * There are two levels of conversion for Serbian: the script level
  * (Cyrillics <-> Latin), and the variant level (ekavian
index 10755b4..6518e65 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-
 /**
  * Converts Tajiki to latin orthography
  *
index 985de68..6910d9c 100644 (file)
@@ -21,8 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-
 /**
  * @ingroup Language
  */
index 0f47c38..51b09f6 100644 (file)
@@ -21,9 +21,6 @@
  * @ingroup Language
  */
 
-require_once __DIR__ . '/../LanguageConverter.php';
-require_once __DIR__ . '/LanguageZh_hans.php';
-
 /**
  * @ingroup Language
  */
@@ -63,16 +60,15 @@ class ZhConverter extends LanguageConverter {
        }
 
        function loadDefaultTables() {
-               require __DIR__ . "/../../includes/ZhConversion.php";
                $this->mTables = array(
-                       'zh-hans' => new ReplacementArray( $zh2Hans ),
-                       'zh-hant' => new ReplacementArray( $zh2Hant ),
-                       'zh-cn' => new ReplacementArray( $zh2CN ),
-                       'zh-hk' => new ReplacementArray( $zh2HK ),
-                       'zh-mo' => new ReplacementArray( $zh2HK ),
-                       'zh-my' => new ReplacementArray( $zh2CN ),
-                       'zh-sg' => new ReplacementArray( $zh2CN ),
-                       'zh-tw' => new ReplacementArray( $zh2TW ),
+                       'zh-hans' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2Hans ),
+                       'zh-hant' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2Hant ),
+                       'zh-cn' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2CN ),
+                       'zh-hk' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2HK ),
+                       'zh-mo' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2HK ),
+                       'zh-my' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2CN ),
+                       'zh-sg' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2CN ),
+                       'zh-tw' => new ReplacementArray( MediaWiki\Languages\Data\ZhConversion::$zh2TW ),
                        'zh' => new ReplacementArray
                );
        }
diff --git a/languages/data/Names.php b/languages/data/Names.php
new file mode 100644 (file)
index 0000000..7711d8f
--- /dev/null
@@ -0,0 +1,467 @@
+<?php
+/**
+ * Language names.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Language
+ */
+
+namespace MediaWiki\Languages\Data;
+
+/**
+ * Language names in their own languages (language autonyms).
+ *
+ * These determine things like interwikis, language selectors, and so on.
+ * Safe to change without running scripts on the respective sites.
+ *
+ * \xE2\x80\x8E is the left-to-right marker and
+ * \xE2\x80\x8F is the right-to-left marker.
+ * They are required for ensuring the correct display of brackets in
+ * mixed rtl/ltr environment.
+ *
+ * Some writing systems require some line-height fixes. This includes
+ * most Indic scripts, like Devanagari.
+ * If you are adding support for such a language, add it also to
+ * the relevant section in shared.css.
+ *
+ * Do not use this class directly. Use Language::fetchLanguageNames(), which
+ * includes support for the CLDR extension.
+ *
+ * @ingroup Language
+ */
+class Names {
+       public static $names = array(
+               'aa' => 'Qafár af',    # Afar
+               'ab' => 'Аҧсшәа', # Abkhaz
+               'ace' => 'Acèh',       # Aceh
+               'ady' => 'адыгабзэ',    # Adyghe
+               'ady-cyrl' => 'адыгабзэ',       # Adyghe
+               'aeb' => 'تونسي/Tûnsî',  # Tunisian Arabic (multiple scripts - defaults to Arabic)
+               'aeb-arab' => 'تونسي',     # Tunisian Arabic (Arabic Script)
+               'aeb-latn' => 'Tûnsî',        # Tunisian Arabic (Latin Script)
+               'af' => 'Afrikaans',    # Afrikaans
+               'ak' => 'Akan',         # Akan
+               'aln' => 'Gegë',       # Gheg Albanian
+               'als' => 'Alemannisch', # Alemannic -- not a valid code, for compatibility. See gsw.
+               'am' => 'አማርኛ', # Amharic
+               'an' => 'aragonés',    # Aragonese
+               'ang' => 'Ænglisc',    # Old English, bug 23283
+               'anp' => 'अङ्गिका',       # Angika
+               'ar' => 'العربية',       # Arabic
+               'arc' => 'ܐܪܡܝܐ',  # Aramaic
+               'arn' => 'mapudungun',  # Mapuche, Mapudungu, Araucanian (Araucano)
+               'arq' => 'جازايرية', # Algerian Spoken Arabic
+               'ary' => 'Maġribi',    # Moroccan Spoken Arabic
+               'arz' => 'مصرى',    # Egyptian Spoken Arabic
+               'as' => 'অসমীয়া',        # Assamese
+               'ase' => 'American sign language',      # American sign language
+               'ast' => 'asturianu',   # Asturian
+               'av' => 'авар',     # Avar
+               'avk' => 'Kotava', # Kotava
+               'awa' => 'अवधी',        # Awadhi
+               'ay' => 'Aymar aru',    # Aymara
+               'az' => 'azərbaycanca',        # Azerbaijani
+               'azb' => 'تۆرکجه',        # South Azerbaijani
+               'ba' => 'башҡортса',   # Bashkir
+               'bar' => 'Boarisch',    # Bavarian (Austro-Bavarian and South Tyrolean)
+               'bat-smg' => 'žemaitėška', # Samogitian (deprecated code, 'sgs' in ISO 693-3 since 2010-06-30 )
+               'bbc' => 'Batak Toba', # Batak Toba (falls back to bbc-latn)
+               'bbc-latn' => 'Batak Toba', # Batak Toba
+               'bcc' => 'جهلسری بلوچی', # Southern Balochi
+               'bcl' => 'Bikol Central', # Bikol: Central Bicolano language
+               'be' => 'беларуская', #  Belarusian normative
+               'be-tarask' => "беларуская (тарашкевіца)\xE2\x80\x8E",     # Belarusian in Taraskievica orthography
+               'be-x-old' => "беларуская (тарашкевіца)\xE2\x80\x8E",      # (be-tarask compat)
+               'bg' => 'български',   # Bulgarian
+               'bgn' => 'روچ کپتین بلوچی', # Western Balochi
+               'bh' => 'भोजपुरी',        # Bihari macro language. Falls back to Bhojpuri (bho)
+               'bho' => 'भोजपुरी',       # Bhojpuri
+               'bi' => 'Bislama',              # Bislama
+               'bjn' => 'Bahasa Banjar',       # Banjarese
+               'bm' => 'bamanankan',   # Bambara
+               'bn' => 'বাংলা',      # Bengali
+               'bo' => 'བོད་ཡིག',        # Tibetan
+               'bpy' => 'বিষ্ণুপ্রিয়া মণিপুরী',       # Bishnupriya Manipuri
+               'bqi' => 'بختیاری',      # Bakthiari
+               'br' => 'brezhoneg',    # Breton
+               'brh' => 'Bráhuí',    # Brahui
+               'bs' => 'bosanski',             # Bosnian
+               'bto' => 'Iriga Bicolano',      # Rinconada Bikol
+               'bug' => 'ᨅᨔ ᨕᨘᨁᨗ', # Buginese
+               'bxr' => 'буряад',        # Buryat (Russia)
+               'ca' => 'català',      # Catalan
+               'cbk-zam' => 'Chavacano de Zamboanga',  # 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
+               'ckb' => 'کوردیی ناوەندی', # Central Kurdish
+               'co' => 'corsu',                # Corsican
+               'cps' => 'Capiceño', # Capiznon
+               'cr' => 'Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ',                # Cree
+               'crh' => 'qırımtatarca',   # Crimean Tatar (multiple scripts - defaults to Latin)
+               'crh-latn' => "qırımtatarca (Latin)\xE2\x80\x8E",       # Crimean Tatar (Latin)
+               'crh-cyrl' => "къырымтатарджа (Кирилл)\xE2\x80\x8E",       # Crimean Tatar (Cyrillic)
+               'cs' => 'čeština',    # Czech
+               'csb' => 'kaszëbsczi', # Cassubian
+               'cu' => 'словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ',        # Old Church Slavonic (ancient language)
+               'cv' => 'Чӑвашла',       # Chuvash
+               'cy' => 'Cymraeg',              # Welsh
+               'da' => 'dansk',                # Danish
+               'de' => 'Deutsch',              # German ("Du")
+               'de-at' => 'Österreichisches Deutsch',         # Austrian German
+               'de-ch' => 'Schweizer Hochdeutsch',             # Swiss Standard German
+               'de-formal' => "Deutsch (Sie-Form)\xE2\x80\x8E",                # German - formal address ("Sie")
+               'diq' => 'Zazaki',              # Zazaki
+               'dsb' => 'dolnoserbski', # Lower Sorbian
+               'dtp' => 'Dusun Bundu-liwan', # Central Dusun
+               'dty' => 'डोटेली', # Doteli
+               'dv' => 'ދިވެހިބަސް',         # Dhivehi
+               'dz' => 'ཇོང་ཁ',              # Dzongkha (Bhutan)
+               'ee' => 'eʋegbe',      # Éwé
+               'egl' => 'Emiliàn',    # Emilian
+               'el' => 'Ελληνικά',     # Greek
+               'eml' => 'emiliàn e rumagnòl',        # Emiliano-Romagnolo / Sammarinese
+               'en' => 'English',              # English
+               'en-ca' => 'Canadian English',  # Canadian English
+               'en-gb' => 'British English',   # British English
+               'eo' => 'Esperanto',    # Esperanto
+               'es' => 'español',     # Spanish
+               'et' => 'eesti',                # Estonian
+               'eu' => 'euskara',              # Basque
+               'ext' => 'estremeñu', # Extremaduran
+               'fa' => 'فارسی',   # Persian
+               'ff' => 'Fulfulde',             # Fulfulde, Maasina
+               'fi' => 'suomi',                # Finnish
+               'fit' => 'meänkieli', # Tornedalen Finnish
+               'fiu-vro' => 'Võro',    # Võro (deprecated code, 'vro' in ISO 639-3 since 2009-01-16)
+               'fj' => 'Na Vosa Vakaviti',     # Fijian
+               'fo' => 'føroyskt',    # Faroese
+               'fr' => 'français',    # French
+               'frc' => 'français cadien', # Cajun French
+               'frp' => 'arpetan',     # Franco-Provençal/Arpitan
+               'frr' => 'Nordfriisk',  # North Frisian
+               'fur' => 'furlan',              # Friulian
+               'fy' => 'Frysk',                # Frisian
+               'ga' => 'Gaeilge',              # Irish
+               'gag' => 'Gagauz',              # Gagauz
+               'gan' => '贛語',              # Gan (multiple scripts - defaults to Traditional)
+               'gan-hans' => "赣语(简体)\xE2\x80\x8E", # Gan (Simplified Han)
+               'gan-hant' => "贛語(繁體)\xE2\x80\x8E", # Gan (Traditional Han)
+               'gd' => 'Gàidhlig',    # Scots Gaelic
+               'gl' => 'galego',               # Galician
+               'glk' => 'گیلکی',  # Gilaki
+               'gn' => 'Avañe\'ẽ',  # Guaraní, Paraguayan
+               'gom' => 'गोवा कोंकणी / Gova Konknni',      # Goan Konkani
+               'gom-deva' => 'गोवा कोंकणी',        # Goan Konkani (Devanagari script)
+               'gom-latn' => 'Gova Konknni',   # Goan Konkani (Latin script)
+               'got' => '𐌲𐌿𐍄𐌹𐍃𐌺',    # Gothic
+               'grc' => 'Ἀρχαία ἑλληνικὴ', # Ancient Greek
+               'gsw' => 'Alemannisch', # Alemannic
+               'gu' => 'ગુજરાતી',        # Gujarati
+               'gv' => 'Gaelg',                # Manx
+               'ha' => 'Hausa',        # Hausa
+               'hak' => '客家語/Hak-kâ-ngî',      # Hakka
+               'haw' => 'Hawai`i',             # Hawaiian
+               'he' => 'עברית',   # Hebrew
+               'hi' => 'हिन्दी',   # Hindi
+               'hif' => 'Fiji Hindi',  # Fijian Hindi (multiple scripts - defaults to Latin)
+               'hif-latn' => 'Fiji Hindi',     # Fiji Hindi (latin)
+               'hil' => 'Ilonggo',     # Hiligaynon
+               'ho' => 'Hiri Motu',    # Hiri Motu
+               'hr' => 'hrvatski',             # Croatian
+               'hrx' => 'Hunsrik', # Riograndenser Hunsrückisch
+               'hsb' => 'hornjoserbsce',       # Upper Sorbian
+               'ht' => 'Kreyòl ayisyen',              # Haitian Creole French
+               '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 (Inupiatun, Northwest Alaska / Inupiatun, North Alaskan)
+               'ike-cans' => 'ᐃᓄᒃᑎᑐᑦ',     # Inuktitut, Eastern Canadian (Unified Canadian Aboriginal Syllabics)
+               'ike-latn' => 'inuktitut',      # Inuktitut, Eastern Canadian (Latin script)
+               'ilo' => 'Ilokano',     # Ilokano
+               'inh' => 'ГӀалгӀай',    # Ingush
+               'io' => 'Ido',                  # Ido
+               'is' => 'íslenska',    # Icelandic
+               'it' => 'italiano',             # Italian
+               'iu' => 'ᐃᓄᒃᑎᑐᑦ/inuktitut', # Inuktitut (macro language, see ike/ikt, falls back to ike-cans)
+               'ja' => '日本語',    # Japanese
+               'jam' => 'Patois',      # Jamaican Creole English
+               'jbo' => 'la .lojban.',         # Lojban
+               'jut' => 'jysk',        # Jutish / Jutlandic
+               'jv' => 'Basa Jawa',    # Javanese
+               'ka' => 'ქართული',        # Georgian
+               'kaa' => 'Qaraqalpaqsha',       # Karakalpak
+               'kab' => 'Taqbaylit',   # Kabyle
+               'kbd' => 'Адыгэбзэ',    # Kabardian
+               'kbd-cyrl' => 'Адыгэбзэ',       # Kabardian (Cyrillic)
+               'kg' => 'Kongo',        # Kongo, (FIXME!) should probaly be KiKongo or KiKoongo
+               'khw' => 'کھوار',  # Khowar
+               'ki' => 'Gĩkũyũ',    # Gikuyu
+               'kiu' => 'Kırmancki',  # Kirmanjki
+               'kj' => 'Kwanyama',     # Kwanyama
+               'kk' => 'қазақша',       # Kazakh (multiple scripts - defaults to Cyrillic)
+               'kk-arab' => "قازاقشا (تٴوتە)\xE2\x80\x8F", # Kazakh Arabic
+               'kk-cyrl' => "қазақша (кирил)\xE2\x80\x8E", # Kazakh Cyrillic
+               'kk-latn' => "qazaqşa (latın)\xE2\x80\x8E",   # Kazakh Latin
+               'kk-cn' => "قازاقشا (جۇنگو)\xE2\x80\x8F",   # Kazakh (China)
+               'kk-kz' => "қазақша (Қазақстан)\xE2\x80\x8E",   # Kazakh (Kazakhstan)
+               'kk-tr' => "qazaqşa (Türkïya)\xE2\x80\x8E",  # Kazakh (Turkey)
+               'kl' => 'kalaallisut',  # Inuktitut, Greenlandic/Greenlandic/Kalaallisut (kal)
+               'km' => 'ភាសាខ្មែរ',  # Khmer, Central
+               'kn' => 'ಕನ್ನಡ',      # Kannada
+               'ko' => '한국어',    # Korean
+               'ko-kp' => '한국어 (조선)',        # Korean (DPRK)
+               'koi' => 'Перем Коми', # Komi-Permyak
+               'kr' => 'Kanuri',               # Kanuri, Central
+               'krc' => 'къарачай-малкъар', # Karachay-Balkar
+               'kri' => 'Krio', # Krio
+               'krj' => 'Kinaray-a', # Kinaray-a
+               'ks' => 'कॉशुर / کٲشُر', # Kashmiri (multiple scripts - defaults to Perso-Arabic)
+               'ks-arab' => 'کٲشُر',      # Kashmiri (Perso-Arabic script)
+               'ks-deva' => 'कॉशुर', # Kashmiri (Devanagari script)
+               'ksh' => 'Ripoarisch',  # Ripuarian
+               'ku' => 'Kurdî',       # Kurdish (multiple scripts - defaults to Latin)
+               'ku-latn' => "Kurdî (latînî)\xE2\x80\x8E",   # Northern Kurdish (Latin script)
+               'ku-arab' => "كوردي (عەرەبی)\xE2\x80\x8F",   # Northern Kurdish (Arabic script) (falls back to ckb)
+               'kv' => 'коми',     # Komi-Zyrian (Cyrillic is common script but also written in Latin script)
+               'kw' => 'kernowek',             # Cornish
+               'ky' => 'Кыргызча',     # Kirghiz
+               'la' => 'Latina',               # Latin
+               'lad' => 'Ladino',      # Ladino
+               'lb' => 'Lëtzebuergesch',      # Luxemburguish
+               'lbe' => 'лакку',  # Lak
+               'lez' => 'лезги',  # Lezgi
+               'lfn' => 'Lingua Franca Nova',  # Lingua Franca Nova
+               'lg' => 'Luganda',              # Ganda
+               'li' => 'Limburgs',     # Limburgian
+               'lij' => 'Ligure',      # Ligurian
+               'liv' => 'Līvõ kēļ',        # Livonian
+               'lmo' => 'lumbaart',    # Lombard
+               'ln' => 'lingála',             # Lingala
+               'lo' => 'ລາວ',    # Laotian
+               'lrc' => 'لۊری شومالی',       # Northern Luri
+               'loz' => 'Silozi', # Lozi
+               'lt' => 'lietuvių',    # Lithuanian
+               'ltg' => 'latgaļu',    # Latgalian
+               'lus' => 'Mizo ţawng', # Mizo/Lushai
+               'luz' => 'لئری دوٙمینی', # Southern Luri
+               'lv' => 'latviešu',    # Latvian
+               'lzh' => '文言',      # Literary Chinese, bug 8217
+               'lzz' => 'Lazuri',      # Laz
+               'mai' => 'मैथिली', # Maithili
+               'map-bms' => 'Basa Banyumasan', # Banyumasan
+               'mdf' => 'мокшень',              # Moksha
+               'mg' => 'Malagasy',             # Malagasy
+               'mh' => 'Ebon',                 # Marshallese
+               'mhr' => 'олык марий', # Eastern Mari
+               'mi' => 'Māori',       # Maori
+               'min' => 'Baso Minangkabau',    # Minangkabau
+               'mk' => 'македонски', # Macedonian
+               'ml' => 'മലയാളം',   # Malayalam
+               'mn' => 'монгол', # Halh Mongolian (Cyrillic) (ISO 639-3: khk)
+               'mo' => 'молдовеняскэ',     # Moldovan, deprecated
+               'mr' => 'मराठी',      # Marathi
+               'mrj' => 'кырык мары', # Hill Mari
+               'ms' => 'Bahasa Melayu',        # Malay
+               'mt' => 'Malti',        # Maltese
+               'mus' => 'Mvskoke',     # Muskogee/Creek
+               'mwl' => 'Mirandés',   # Mirandese
+               'my' => 'မြန်မာဘာသာ',               # Burmese
+               'myv' => 'эрзянь',        # Erzya
+               'mzn' => 'مازِرونی',            # Mazanderani
+               'na' => 'Dorerin Naoero',               # Nauruan
+               'nah' => 'Nāhuatl',            # Nahuatl (not in ISO 639-3)
+               'nan' => 'Bân-lâm-gú', # Min-nan, bug 8217
+               'nap' => 'Napulitano',  # Neapolitan, bug 43793
+               'nb' => "norsk bokmål",                # Norwegian (Bokmal)
+               'nds' => 'Plattdüütsch',      # Low German ''or'' Low Saxon
+               'nds-nl' => 'Nedersaksies',     # aka Nedersaksisch: Dutch Low Saxon
+               'ne' => 'नेपाली',   # Nepali
+               'new' => 'नेपाल भाषा',                # Newar / Nepal Bhasha
+               'ng' => 'Oshiwambo',            # Ndonga
+               'niu' => 'Niuē',       # Niuean
+               'nl' => 'Nederlands',   # Dutch
+               'nl-informal' => "Nederlands (informeel)\xE2\x80\x8E",  # Dutch (informal address ("je"))
+               'nn' => "norsk nynorsk",        # Norwegian (Nynorsk)
+               'no' => "norsk bokmål",                # Norwegian (falls back to nb).
+               'nov' => 'Novial',              # Novial
+               'nrm' => 'Nouormand',   # Norman
+               'nso' => 'Sesotho sa Leboa',    # Northern Sotho
+               'nv' => 'Diné bizaad', # Navajo
+               'ny' => 'Chi-Chewa',    # Chichewa
+               'oc' => 'occitan',              # Occitan
+               'olo' => 'Livvinкarjala',              # Livvi-Karelian
+               'om' => 'Oromoo',               # Oromo
+               'or' => 'ଓଡ଼ିଆ',              # Oriya
+               'os' => 'Ирон', # Ossetic, bug 29091
+               'pa' => 'ਪੰਜਾਬੀ', # Eastern Punjabi (Gurmukhi script) (pan)
+               'pag' => 'Pangasinan',  # Pangasinan
+               'pam' => 'Kapampangan',   # Pampanga
+               'pap' => 'Papiamentu',  # Papiamentu
+               'pcd' => 'Picard',      # Picard
+               'pdc' => 'Deitsch',     # Pennsylvania German
+               'pdt' => 'Plautdietsch',        # Plautdietsch/Mennonite Low German
+               'pfl' => 'Pälzisch',   # Palatinate German
+               'pi' => 'पालि', # Pali
+               'pih' => 'Norfuk / Pitkern', # Norfuk/Pitcairn/Norfolk
+               'pl' => 'polski',               # Polish
+               'pms' => 'Piemontèis', # Piedmontese
+               'pnb' => 'پنجابی',        # Western Punjabi
+               'pnt' => 'Ποντιακά',    # Pontic/Pontic Greek
+               'prg' => 'Prūsiskan',  # Prussian
+               'ps' => 'پښتو',     # Pashto
+               'pt' => 'português',   # Portuguese
+               'pt-br' => 'português do Brasil',      # Brazilian Portuguese
+               'qu' => 'Runa Simi',    # Southern Quechua
+               'qug' => 'Runa shimi',  # Kichwa/Northern Quechua (temporarily used until Kichwa has its own)
+               'rgn' => 'Rumagnôl',   # Romagnol
+               'rif' => 'Tarifit',     # Tarifit
+               'rm' => 'rumantsch',    # Raeto-Romance
+               'rmy' => 'Romani',      # Vlax Romany
+               'rn' => 'Kirundi',              # Rundi/Kirundi/Urundi
+               'ro' => 'română',     # Romanian
+               'roa-rup' => 'armãneashti', # Aromanian (deprecated code, 'rup' exists in ISO 693-3)
+               'roa-tara' => 'tarandíne',     # Tarantino
+               'ru' => 'русский',       # Russian
+               'rue' => 'русиньскый',        # Rusyn
+               'rup' => 'armãneashti', # Aromanian
+               'ruq' => 'Vlăheşte',  # Megleno-Romanian (multiple scripts - defaults to Latin)
+               'ruq-cyrl' => 'Влахесте',       # Megleno-Romanian (Cyrillic script)
+               # 'ruq-grek' => 'Βλαεστε',       # Megleno-Romanian (Greek script)
+               'ruq-latn' => 'Vlăheşte',     # Megleno-Romanian (Latin script)
+               'rw' => 'Kinyarwanda',  # Kinyarwanda, should possibly be Kinyarwandi
+               'sa' => 'संस्कृतम्',  # Sanskrit
+               'sah' => 'саха тыла', # Sakha
+               'sat' => 'Santali',     # Santali
+               'sc' => 'sardu',                # Sardinian
+               'scn' => 'sicilianu',   # Sicilian
+               'sco' => 'Scots',       # Scots
+               'sd' => 'سنڌي',     # Sindhi
+               'sdc' => 'Sassaresu',   # Sassarese
+               'sdh' => 'کوردی خوارگ',       # Southern Kurdish
+               'se' => 'sámegiella',  # Northern Sami
+               'sei' => 'Cmique Itom', # Seri
+               'ses' => 'Koyraboro Senni',     # Koyraboro Senni
+               'sg' => 'Sängö',              # Sango/Sangho
+               'sgs' => 'žemaitėška', # Samogitian
+               'sh' => 'srpskohrvatski / српскохрватски', # Serbocroatian
+               'shi' => 'Tašlḥiyt/ⵜⴰⵛⵍⵃⵉⵜ',    # Tachelhit (multiple scripts - defaults to Latin)
+               'shi-tfng' => 'ⵜⴰⵛⵍⵃⵉⵜ',    # Tachelhit (Tifinagh script)
+               'shi-latn' => 'Tašlḥiyt',    # Tachelhit (Latin script)
+               'si' => 'සිංහල',      # Sinhalese
+               'simple' => 'Simple English',   # Simple English
+               'sk' => 'slovenčina',  # Slovak
+               'sl' => 'slovenščina',        # Slovenian
+               'sli' => 'Schläsch',   # Lower Selisian
+               'sm' => 'Gagana Samoa', # Samoan
+               'sma' => 'Åarjelsaemien',      # Southern Sami
+               'sn' => 'chiShona',             # Shona
+               'so' => 'Soomaaliga',   # Somali
+               'sq' => 'shqip',                # Albanian
+               'sr' => 'српски / srpski',        # Serbian (multiple scripts - defaults to Cyrillic)
+               'sr-ec' => "српски (ћирилица)\xE2\x80\x8E",       # Serbian Cyrillic ekavian
+               'sr-el' => "srpski (latinica)\xE2\x80\x8E",     # Serbian Latin ekavian
+               'srn' => 'Sranantongo',         # Sranan Tongo
+               'ss' => 'SiSwati',              # Swati
+               'st' => 'Sesotho',              # Southern Sotho
+               'stq' => 'Seeltersk',           # Saterland Frisian
+               'su' => 'Basa Sunda',   # Sundanese
+               'sv' => 'svenska',              # Swedish
+               'sw' => 'Kiswahili',    # Swahili
+               'szl' => 'ślůnski',   # Silesian
+               'ta' => 'தமிழ்',      # Tamil
+               'tcy' => 'ತುಳು', # Tulu
+               'te' => 'తెలుగు',   # Telugu
+               'tet' => 'tetun',       # Tetun
+               'tg' => 'тоҷикӣ', # Tajiki (falls back to tg-cyrl)
+               'tg-cyrl' => 'тоҷикӣ',    # Tajiki (Cyrllic script) (default)
+               'tg-latn' => 'tojikī', # Tajiki (Latin script)
+               'th' => 'ไทย',    # Thai
+               'ti' => 'ትግርኛ',         # Tigrinya
+               'tk' => 'Türkmençe',  # Turkmen
+               'tl' => 'Tagalog',              # Tagalog
+               'tly' => 'толышә зывон',     # Talysh
+               'tn' => 'Setswana',             # Setswana
+               'to' => 'lea faka-Tonga',               # Tonga (Tonga Islands)
+               'tokipona' => 'Toki Pona',      # Toki Pona
+               'tpi' => 'Tok Pisin',   # Tok Pisin
+               'tr' => 'Türkçe',     # Turkish
+               'tru' => 'Ṫuroyo', # Turoyo
+               'ts' => 'Xitsonga',             # Tsonga
+               'tt' => 'татарча/tatarça',      # Tatar (multiple scripts - defaults to Cyrillic)
+               'tt-cyrl' => 'татарча',  # Tatar (Cyrillic script) (default)
+               'tt-latn' => 'tatarça',        # Tatar (Latin script)
+               'tum' => 'chiTumbuka',  # Tumbuka
+               'tw' => 'Twi',                  # Twi, (FIXME!)
+               'ty' => 'reo tahiti',   # Tahitian
+               'tyv' => 'тыва дыл',     # Tyvan
+               'tzm' => 'ⵜⴰⵎⴰⵣⵉⵖⵜ',    # Tamazight
+               'udm' => 'удмурт',        # Udmurt
+               'ug' => 'ئۇيغۇرچە / Uyghurche', # Uyghur (multiple scripts - defaults to Arabic)
+               'ug-arab' => 'ئۇيغۇرچە', # Uyghur (Arabic script) (default)
+               'ug-latn' => 'Uyghurche', # Uyghur (Latin script)
+               'uk' => 'українська', # Ukrainian
+               'ur' => 'اردو',     # Urdu
+               'uz' => "oʻzbekcha/ўзбекча",    # Uzbek (multiple scripts - defaults to Latin)
+               'uz-cyrl' => "ўзбекча",  # Uzbek Cyrillic
+               'uz-latn' => "oʻzbekcha",      # Uzbek Latin (default)
+               've' => 'Tshivenda',            # Venda
+               'vec' => 'vèneto',     # Venetian
+               'vep' => 'vepsän kel’',      # Veps
+               'vi' => 'Tiếng Việt',       # Vietnamese
+               'vls' => 'West-Vlams', # West Flemish
+               'vmf' => 'Mainfränkisch', # Upper Franconian, Main-Franconian
+               'vo' => 'Volapük',     # Volapük
+               'vot' => 'Vaďďa',     # Vod/Votian
+               'vro' => 'Võro',    # Võro
+               'wa' => 'walon',                # Walloon
+               'war' => 'Winaray', # Waray-Waray
+               'wo' => 'Wolof',                # Wolof
+               'wuu' => '吴语',              # Wu Chinese
+               'xal' => 'хальмг',                # Kalmyk-Oirat
+               'xh' => 'isiXhosa',             # Xhosan
+               'xmf' => 'მარგალური', # Mingrelian
+               'yi' => 'ייִדיש', # Yiddish
+               'yo' => 'Yorùbá',     # Yoruba
+               'yue' => '粵語',      # Cantonese
+               'za' => 'Vahcuengh',    # Zhuang
+               'zea' => 'Zeêuws',     # Zeeuws/Zeaws
+               'zh' => '中文',                                               # (Zhōng Wén) - Chinese
+               'zh-classical' => '文言',                     # Classical Chinese/Literary Chinese -- (see bug 8217)
+               'zh-cn' => "中文(中国大陆)\xE2\x80\x8E",      # Chinese (PRC)
+               'zh-hans' => "中文(简体)\xE2\x80\x8E",  # Mandarin Chinese (Simplified Chinese script) (cmn-hans)
+               'zh-hant' => "中文(繁體)\xE2\x80\x8E",  # Mandarin Chinese (Traditional Chinese script) (cmn-hant)
+               'zh-hk' => "中文(香港)\xE2\x80\x8E",    # Chinese (Hong Kong)
+               'zh-min-nan' => 'Bân-lâm-gú',                                # Min-nan -- (see bug 8217)
+               'zh-mo' => "中文(澳門)\xE2\x80\x8E",    # Chinese (Macau)
+               'zh-my' => "中文(马来西亚)\xE2\x80\x8E",      # Chinese (Malaysia)
+               'zh-sg' => "中文(新加坡)\xE2\x80\x8E", # Chinese (Singapore)
+               'zh-tw' => "中文(台灣)\xE2\x80\x8E",    # Chinese (Taiwan)
+               'zh-yue' => '粵語',                                   # Cantonese -- (see bug 8217)
+               'zu' => 'isiZulu'               # Zulu
+       );
+}
diff --git a/languages/data/ZhConversion.php b/languages/data/ZhConversion.php
new file mode 100644 (file)
index 0000000..8652975
--- /dev/null
@@ -0,0 +1,20281 @@
+<?php
+/**
+ * Simplified / Traditional Chinese conversion tables
+ *
+ * Automatically generated using code and data in maintenance/language/zhtable/
+ * Do not modify directly!
+ *
+ * @file
+ */
+
+namespace MediaWiki\Languages\Data;
+
+class ZhConversion {
+public static $zh2Hant = array(
+'㐷' => '傌',
+'㐹' => '㑶',
+'㐽' => '偑',
+'㑇' => '㑳',
+'㑈' => '倲',
+'㑔' => '㑯',
+'㑩' => '儸',
+'㓥' => '劏',
+'㔉' => '劚',
+'㖊' => '噚',
+'㖞' => '喎',
+'㘎' => '㘚',
+'㚯' => '㜄',
+'㛀' => '媰',
+'㛟' => '𡞵',
+'㛠' => '𡢃',
+'㛣' => '㜏',
+'㛤' => '孋',
+'㛿' => '𡠹',
+'㟆' => '㠏',
+'㟜' => '𡾱',
+'㤘' => '㥮',
+'㧏' => '掆',
+'㧐' => '㩳',
+'㧑' => '撝',
+'㧟' => '擓',
+'㧰' => '擽',
+'㨫' => '㩜',
+'㭎' => '棡',
+'㭏' => '椲',
+'㭣' => '𣙎',
+'㭤' => '樢',
+'㭴' => '樫',
+'㱩' => '殰',
+'㱮' => '殨',
+'㲿' => '瀇',
+'㳔' => '濧',
+'㳠' => '澾',
+'㳡' => '濄',
+'㳢' => '𣾷',
+'㳽' => '瀰',
+'㶉' => '鸂',
+'㶶' => '燶',
+'㶽' => '煱',
+'㺍' => '獱',
+'㻅' => '璯',
+'㻏' => '𤫩',
+'㻘' => '𤪺',
+'䀥' => '䁻',
+'䁖' => '瞜',
+'䂵' => '碽',
+'䅉' => '稏',
+'䅪' => '𥢢',
+'䇲' => '筴',
+'䉤' => '籔',
+'䌶' => '䊷',
+'䌷' => '紬',
+'䌸' => '縳',
+'䌹' => '絅',
+'䌺' => '䋙',
+'䌻' => '䋚',
+'䌼' => '綐',
+'䌽' => '綵',
+'䌾' => '䋻',
+'䌿' => '䋹',
+'䍀' => '繿',
+'䍁' => '繸',
+'䎬' => '䎱',
+'䏝' => '膞',
+'䓖' => '藭',
+'䗖' => '螮',
+'䘛' => '𧝞',
+'䘞' => '𧜗',
+'䙊' => '𧜵',
+'䙌' => '䙡',
+'䙓' => '襬',
+'䜣' => '訢',
+'䜥' => '𧩙',
+'䜧' => '䜀',
+'䜩' => '讌',
+'䝙' => '貙',
+'䞌' => '𧵳',
+'䞍' => '䝼',
+'䞎' => '𧶧',
+'䞐' => '賰',
+'䟢' => '躎',
+'䢀' => '𨊰',
+'䢁' => '𨊸',
+'䢂' => '𨋢',
+'䥺' => '釾',
+'䥽' => '鏺',
+'䥾' => '䥱',
+'䥿' => '𨯅',
+'䦀' => '𨦫',
+'䦁' => '𨧜',
+'䦂' => '䥇',
+'䦃' => '鐯',
+'䦅' => '鐥',
+'䦶' => '䦛',
+'䦷' => '䦟',
+'䭪' => '𩞯',
+'䯃' => '𩣑',
+'䯄' => '騧',
+'䯅' => '䯀',
+'䲝' => '䱽',
+'䲞' => '𩶘',
+'䲟' => '鮣',
+'䲠' => '鰆',
+'䲡' => '鰌',
+'䲢' => '鰧',
+'䲣' => '䱷',
+'䴓' => '鳾',
+'䴔' => '鵁',
+'䴕' => '鴷',
+'䴖' => '鶄',
+'䴗' => '鶪',
+'䴘' => '鷈',
+'䴙' => '鷿',
+'䶮' => '龑',
+'万' => '萬',
+'与' => '與',
+'专' => '專',
+'业' => '業',
+'丛' => '叢',
+'东' => '東',
+'丝' => '絲',
+'丢' => '丟',
+'两' => '兩',
+'严' => '嚴',
+'丧' => '喪',
+'个' => '個',
+'丰' => '豐',
+'临' => '臨',
+'为' => '為',
+'丽' => '麗',
+'举' => '舉',
+'么' => '麼',
+'义' => '義',
+'乌' => '烏',
+'乐' => '樂',
+'乔' => '喬',
+'习' => '習',
+'乡' => '鄉',
+'书' => '書',
+'买' => '買',
+'乱' => '亂',
+'争' => '爭',
+'于' => '於',
+'亏' => '虧',
+'云' => '雲',
+'亚' => '亞',
+'产' => '產',
+'亩' => '畝',
+'亲' => '親',
+'亵' => '褻',
+'亸' => '嚲',
+'亿' => '億',
+'仅' => '僅',
+'从' => '從',
+'仑' => '侖',
+'仓' => '倉',
+'仪' => '儀',
+'们' => '們',
+'价' => '價',
+'众' => '眾',
+'优' => '優',
+'会' => '會',
+'伛' => '傴',
+'伞' => '傘',
+'伟' => '偉',
+'传' => '傳',
+'伡' => '俥',
+'伣' => '俔',
+'伤' => '傷',
+'伥' => '倀',
+'伦' => '倫',
+'伧' => '傖',
+'伪' => '偽',
+'伫' => '佇',
+'体' => '體',
+'佣' => '傭',
+'佥' => '僉',
+'侠' => '俠',
+'侣' => '侶',
+'侥' => '僥',
+'侦' => '偵',
+'侧' => '側',
+'侨' => '僑',
+'侩' => '儈',
+'侪' => '儕',
+'侬' => '儂',
+'俣' => '俁',
+'俦' => '儔',
+'俨' => '儼',
+'俩' => '倆',
+'俪' => '儷',
+'俫' => '倈',
+'俭' => '儉',
+'债' => '債',
+'倾' => '傾',
+'偬' => '傯',
+'偻' => '僂',
+'偾' => '僨',
+'偿' => '償',
+'傥' => '儻',
+'傧' => '儐',
+'储' => '儲',
+'傩' => '儺',
+'儿' => '兒',
+'兑' => '兌',
+'兖' => '兗',
+'党' => '黨',
+'兰' => '蘭',
+'关' => '關',
+'兴' => '興',
+'兹' => '茲',
+'养' => '養',
+'兽' => '獸',
+'冁' => '囅',
+'内' => '內',
+'冈' => '岡',
+'册' => '冊',
+'写' => '寫',
+'军' => '軍',
+'农' => '農',
+'冯' => '馮',
+'冲' => '沖',
+'决' => '決',
+'况' => '況',
+'冻' => '凍',
+'净' => '淨',
+'凄' => '淒',
+'凉' => '涼',
+'减' => '減',
+'凑' => '湊',
+'凛' => '凜',
+'几' => '幾',
+'凤' => '鳳',
+'凫' => '鳧',
+'凭' => '憑',
+'凯' => '凱',
+'击' => '擊',
+'凿' => '鑿',
+'刍' => '芻',
+'划' => '劃',
+'刘' => '劉',
+'则' => '則',
+'刚' => '剛',
+'创' => '創',
+'删' => '刪',
+'别' => '別',
+'刬' => '剗',
+'刭' => '剄',
+'刹' => '剎',
+'刽' => '劊',
+'刾' => '㓨',
+'刿' => '劌',
+'剀' => '剴',
+'剂' => '劑',
+'剐' => '剮',
+'剑' => '劍',
+'剥' => '剝',
+'剧' => '劇',
+'劝' => '勸',
+'办' => '辦',
+'务' => '務',
+'劢' => '勱',
+'动' => '動',
+'励' => '勵',
+'劲' => '勁',
+'劳' => '勞',
+'势' => '勢',
+'勋' => '勛',
+'勚' => '勩',
+'匀' => '勻',
+'匦' => '匭',
+'匮' => '匱',
+'区' => '區',
+'医' => '醫',
+'华' => '華',
+'协' => '協',
+'单' => '單',
+'卖' => '賣',
+'卢' => '盧',
+'卤' => '鹵',
+'卧' => '臥',
+'卫' => '衛',
+'却' => '卻',
+'厂' => '廠',
+'厅' => '廳',
+'历' => '歷',
+'厉' => '厲',
+'压' => '壓',
+'厌' => '厭',
+'厍' => '厙',
+'厐' => '龎',
+'厕' => '廁',
+'厢' => '廂',
+'厣' => '厴',
+'厦' => '廈',
+'厨' => '廚',
+'厩' => '廄',
+'厮' => '廝',
+'县' => '縣',
+'叁' => '叄',
+'参' => '參',
+'叆' => '靉',
+'叇' => '靆',
+'双' => '雙',
+'发' => '發',
+'变' => '變',
+'叙' => '敘',
+'叠' => '疊',
+'叶' => '葉',
+'号' => '號',
+'叹' => '嘆',
+'叽' => '嘰',
+'后' => '後',
+'吓' => '嚇',
+'吕' => '呂',
+'吗' => '嗎',
+'吣' => '唚',
+'吨' => '噸',
+'听' => '聽',
+'启' => '啟',
+'吴' => '吳',
+'呐' => '吶',
+'呒' => '嘸',
+'呓' => '囈',
+'呕' => '嘔',
+'呖' => '嚦',
+'呗' => '唄',
+'员' => '員',
+'呙' => '咼',
+'呛' => '嗆',
+'呜' => '嗚',
+'咏' => '詠',
+'咙' => '嚨',
+'咛' => '嚀',
+'咝' => '噝',
+'响' => '響',
+'哑' => '啞',
+'哒' => '噠',
+'哓' => '嘵',
+'哔' => '嗶',
+'哕' => '噦',
+'哗' => '嘩',
+'哙' => '噲',
+'哜' => '嚌',
+'哝' => '噥',
+'哟' => '喲',
+'唛' => '嘜',
+'唝' => '嗊',
+'唠' => '嘮',
+'唡' => '啢',
+'唢' => '嗩',
+'唤' => '喚',
+'啧' => '嘖',
+'啬' => '嗇',
+'啭' => '囀',
+'啮' => '齧',
+'啯' => '嘓',
+'啰' => '囉',
+'啴' => '嘽',
+'啸' => '嘯',
+'喂' => '餵',
+'喷' => '噴',
+'喽' => '嘍',
+'喾' => '嚳',
+'嗫' => '囁',
+'嗳' => '噯',
+'嘘' => '噓',
+'嘤' => '嚶',
+'嘱' => '囑',
+'噜' => '嚕',
+'嚣' => '囂',
+'团' => '團',
+'园' => '園',
+'囱' => '囪',
+'围' => '圍',
+'囵' => '圇',
+'国' => '國',
+'图' => '圖',
+'圆' => '圓',
+'圣' => '聖',
+'圹' => '壙',
+'场' => '場',
+'坏' => '壞',
+'块' => '塊',
+'坚' => '堅',
+'坛' => '壇',
+'坜' => '壢',
+'坝' => '壩',
+'坞' => '塢',
+'坟' => '墳',
+'坠' => '墜',
+'垄' => '壟',
+'垅' => '壠',
+'垆' => '壚',
+'垒' => '壘',
+'垦' => '墾',
+'垩' => '堊',
+'垫' => '墊',
+'垭' => '埡',
+'垱' => '壋',
+'垲' => '塏',
+'埘' => '塒',
+'埙' => '塤',
+'埚' => '堝',
+'埯' => '垵',
+'堑' => '塹',
+'堕' => '墮',
+'墙' => '牆',
+'壮' => '壯',
+'声' => '聲',
+'壳' => '殼',
+'壶' => '壺',
+'壸' => '壼',
+'处' => '處',
+'备' => '備',
+'复' => '復',
+'够' => '夠',
+'头' => '頭',
+'夹' => '夾',
+'夺' => '奪',
+'奁' => '奩',
+'奂' => '奐',
+'奋' => '奮',
+'奖' => '獎',
+'奥' => '奧',
+'妆' => '妝',
+'妇' => '婦',
+'妈' => '媽',
+'妩' => '嫵',
+'妪' => '嫗',
+'妫' => '媯',
+'姗' => '姍',
+'姹' => '奼',
+'娄' => '婁',
+'娅' => '婭',
+'娆' => '嬈',
+'娇' => '嬌',
+'娈' => '孌',
+'娱' => '娛',
+'娲' => '媧',
+'娴' => '嫻',
+'婳' => '嫿',
+'婴' => '嬰',
+'婵' => '嬋',
+'婶' => '嬸',
+'媪' => '媼',
+'媭' => '嬃',
+'嫒' => '嬡',
+'嫔' => '嬪',
+'嫱' => '嬙',
+'嬷' => '嬤',
+'孙' => '孫',
+'学' => '學',
+'孪' => '孿',
+'宁' => '寧',
+'宝' => '寶',
+'实' => '實',
+'宠' => '寵',
+'审' => '審',
+'宪' => '憲',
+'宫' => '宮',
+'宽' => '寬',
+'宾' => '賓',
+'寝' => '寢',
+'对' => '對',
+'寻' => '尋',
+'导' => '導',
+'寿' => '壽',
+'将' => '將',
+'尔' => '爾',
+'尘' => '塵',
+'尝' => '嘗',
+'尧' => '堯',
+'尴' => '尷',
+'尸' => '屍',
+'尽' => '盡',
+'层' => '層',
+'屃' => '屓',
+'屉' => '屜',
+'届' => '屆',
+'属' => '屬',
+'屡' => '屢',
+'屦' => '屨',
+'屿' => '嶼',
+'岁' => '歲',
+'岂' => '豈',
+'岖' => '嶇',
+'岗' => '崗',
+'岘' => '峴',
+'岚' => '嵐',
+'岛' => '島',
+'岭' => '嶺',
+'岽' => '崬',
+'岿' => '巋',
+'峃' => '嶨',
+'峄' => '嶧',
+'峡' => '峽',
+'峣' => '嶢',
+'峤' => '嶠',
+'峥' => '崢',
+'峦' => '巒',
+'崂' => '嶗',
+'崃' => '崍',
+'崄' => '嶮',
+'崭' => '嶄',
+'嵘' => '嶸',
+'嵚' => '嶔',
+'嵝' => '嶁',
+'巅' => '巔',
+'巩' => '鞏',
+'巯' => '巰',
+'币' => '幣',
+'帅' => '帥',
+'师' => '師',
+'帏' => '幃',
+'帐' => '帳',
+'帘' => '簾',
+'帜' => '幟',
+'带' => '帶',
+'帧' => '幀',
+'帮' => '幫',
+'帱' => '幬',
+'帻' => '幘',
+'帼' => '幗',
+'幂' => '冪',
+'并' => '並',
+'幺' => '么',
+'广' => '廣',
+'庄' => '莊',
+'庆' => '慶',
+'庐' => '廬',
+'庑' => '廡',
+'库' => '庫',
+'应' => '應',
+'庙' => '廟',
+'庞' => '龐',
+'废' => '廢',
+'庼' => '廎',
+'廪' => '廩',
+'开' => '開',
+'异' => '異',
+'弃' => '棄',
+'弑' => '弒',
+'张' => '張',
+'弥' => '彌',
+'弪' => '弳',
+'弯' => '彎',
+'弹' => '彈',
+'强' => '強',
+'归' => '歸',
+'当' => '當',
+'录' => '錄',
+'彟' => '彠',
+'彦' => '彥',
+'彨' => '彲',
+'彻' => '徹',
+'径' => '徑',
+'徕' => '徠',
+'忆' => '憶',
+'忏' => '懺',
+'忧' => '憂',
+'忾' => '愾',
+'怀' => '懷',
+'态' => '態',
+'怂' => '慫',
+'怃' => '憮',
+'怄' => '慪',
+'怅' => '悵',
+'怆' => '愴',
+'怜' => '憐',
+'总' => '總',
+'怼' => '懟',
+'怿' => '懌',
+'恋' => '戀',
+'恒' => '恆',
+'恳' => '懇',
+'恶' => '惡',
+'恸' => '慟',
+'恹' => '懨',
+'恺' => '愷',
+'恻' => '惻',
+'恼' => '惱',
+'恽' => '惲',
+'悦' => '悅',
+'悫' => '愨',
+'悬' => '懸',
+'悭' => '慳',
+'悮' => '悞',
+'悯' => '憫',
+'惊' => '驚',
+'惧' => '懼',
+'惨' => '慘',
+'惩' => '懲',
+'惫' => '憊',
+'惬' => '愜',
+'惭' => '慚',
+'惮' => '憚',
+'惯' => '慣',
+'愠' => '慍',
+'愤' => '憤',
+'愦' => '憒',
+'愿' => '願',
+'慑' => '懾',
+'懑' => '懣',
+'懒' => '懶',
+'懔' => '懍',
+'戆' => '戇',
+'戋' => '戔',
+'戏' => '戲',
+'戗' => '戧',
+'战' => '戰',
+'戬' => '戩',
+'戯' => '戱',
+'户' => '戶',
+'扑' => '撲',
+'执' => '執',
+'扩' => '擴',
+'扪' => '捫',
+'扫' => '掃',
+'扬' => '揚',
+'扰' => '擾',
+'抚' => '撫',
+'抛' => '拋',
+'抟' => '摶',
+'抠' => '摳',
+'抡' => '掄',
+'抢' => '搶',
+'护' => '護',
+'报' => '報',
+'担' => '擔',
+'拟' => '擬',
+'拢' => '攏',
+'拣' => '揀',
+'拥' => '擁',
+'拦' => '攔',
+'拧' => '擰',
+'拨' => '撥',
+'择' => '擇',
+'挂' => '掛',
+'挚' => '摯',
+'挛' => '攣',
+'挜' => '掗',
+'挝' => '撾',
+'挞' => '撻',
+'挟' => '挾',
+'挠' => '撓',
+'挡' => '擋',
+'挢' => '撟',
+'挣' => '掙',
+'挤' => '擠',
+'挥' => '揮',
+'挦' => '撏',
+'捝' => '挩',
+'捞' => '撈',
+'损' => '損',
+'捡' => '撿',
+'换' => '換',
+'捣' => '搗',
+'据' => '據',
+'掳' => '擄',
+'掴' => '摑',
+'掷' => '擲',
+'掸' => '撣',
+'掺' => '摻',
+'掼' => '摜',
+'揽' => '攬',
+'揾' => '搵',
+'揿' => '撳',
+'搀' => '攙',
+'搁' => '擱',
+'搂' => '摟',
+'搅' => '攪',
+'携' => '攜',
+'摄' => '攝',
+'摅' => '攄',
+'摆' => '擺',
+'摇' => '搖',
+'摈' => '擯',
+'摊' => '攤',
+'撄' => '攖',
+'撑' => '撐',
+'撵' => '攆',
+'撷' => '擷',
+'撸' => '擼',
+'撺' => '攛',
+'擞' => '擻',
+'攒' => '攢',
+'敌' => '敵',
+'敛' => '斂',
+'敩' => '斆',
+'数' => '數',
+'斋' => '齋',
+'斓' => '斕',
+'斩' => '斬',
+'断' => '斷',
+'无' => '無',
+'旧' => '舊',
+'时' => '時',
+'旷' => '曠',
+'旸' => '暘',
+'昙' => '曇',
+'昼' => '晝',
+'昽' => '曨',
+'显' => '顯',
+'晋' => '晉',
+'晒' => '曬',
+'晓' => '曉',
+'晔' => '曄',
+'晕' => '暈',
+'晖' => '暉',
+'暂' => '暫',
+'暧' => '曖',
+'术' => '術',
+'机' => '機',
+'杀' => '殺',
+'杂' => '雜',
+'权' => '權',
+'杠' => '槓',
+'条' => '條',
+'来' => '來',
+'杨' => '楊',
+'杩' => '榪',
+'杰' => '傑',
+'极' => '極',
+'构' => '構',
+'枞' => '樅',
+'枢' => '樞',
+'枣' => '棗',
+'枥' => '櫪',
+'枧' => '梘',
+'枨' => '棖',
+'枪' => '槍',
+'枫' => '楓',
+'枭' => '梟',
+'柜' => '櫃',
+'柠' => '檸',
+'柽' => '檉',
+'栀' => '梔',
+'栅' => '柵',
+'标' => '標',
+'栈' => '棧',
+'栉' => '櫛',
+'栊' => '櫳',
+'栋' => '棟',
+'栌' => '櫨',
+'栎' => '櫟',
+'栏' => '欄',
+'树' => '樹',
+'栖' => '棲',
+'样' => '樣',
+'栾' => '欒',
+'桠' => '椏',
+'桡' => '橈',
+'桢' => '楨',
+'档' => '檔',
+'桤' => '榿',
+'桥' => '橋',
+'桦' => '樺',
+'桧' => '檜',
+'桨' => '槳',
+'桩' => '樁',
+'桪' => '樳',
+'梦' => '夢',
+'梼' => '檮',
+'梾' => '棶',
+'梿' => '槤',
+'检' => '檢',
+'棁' => '梲',
+'棂' => '欞',
+'椁' => '槨',
+'椝' => '槼',
+'椟' => '櫝',
+'椠' => '槧',
+'椢' => '槶',
+'椤' => '欏',
+'椫' => '樿',
+'椭' => '橢',
+'椮' => '槮',
+'楼' => '樓',
+'榄' => '欖',
+'榅' => '榲',
+'榇' => '櫬',
+'榈' => '櫚',
+'榉' => '櫸',
+'槚' => '檟',
+'槛' => '檻',
+'槟' => '檳',
+'槠' => '櫧',
+'横' => '橫',
+'樯' => '檣',
+'樱' => '櫻',
+'橥' => '櫫',
+'橱' => '櫥',
+'橹' => '櫓',
+'橼' => '櫞',
+'檩' => '檁',
+'欢' => '歡',
+'欤' => '歟',
+'欧' => '歐',
+'歼' => '殲',
+'殁' => '歿',
+'殇' => '殤',
+'残' => '殘',
+'殒' => '殞',
+'殓' => '殮',
+'殚' => '殫',
+'殡' => '殯',
+'殴' => '毆',
+'毁' => '毀',
+'毂' => '轂',
+'毕' => '畢',
+'毙' => '斃',
+'毡' => '氈',
+'毵' => '毿',
+'氇' => '氌',
+'气' => '氣',
+'氢' => '氫',
+'氩' => '氬',
+'氲' => '氳',
+'汇' => '匯',
+'汉' => '漢',
+'汤' => '湯',
+'汹' => '洶',
+'沟' => '溝',
+'没' => '沒',
+'沣' => '灃',
+'沤' => '漚',
+'沥' => '瀝',
+'沦' => '淪',
+'沧' => '滄',
+'沨' => '渢',
+'沩' => '溈',
+'沪' => '滬',
+'泞' => '濘',
+'泪' => '淚',
+'泶' => '澩',
+'泷' => '瀧',
+'泸' => '瀘',
+'泺' => '濼',
+'泻' => '瀉',
+'泼' => '潑',
+'泽' => '澤',
+'泾' => '涇',
+'洁' => '潔',
+'洒' => '灑',
+'洼' => '窪',
+'浃' => '浹',
+'浅' => '淺',
+'浆' => '漿',
+'浇' => '澆',
+'浈' => '湞',
+'浉' => '溮',
+'浊' => '濁',
+'测' => '測',
+'浍' => '澮',
+'济' => '濟',
+'浏' => '瀏',
+'浐' => '滻',
+'浑' => '渾',
+'浒' => '滸',
+'浓' => '濃',
+'浔' => '潯',
+'浕' => '濜',
+'涂' => '塗',
+'涛' => '濤',
+'涝' => '澇',
+'涞' => '淶',
+'涟' => '漣',
+'涠' => '潿',
+'涡' => '渦',
+'涢' => '溳',
+'涣' => '渙',
+'涤' => '滌',
+'润' => '潤',
+'涧' => '澗',
+'涨' => '漲',
+'涩' => '澀',
+'渊' => '淵',
+'渌' => '淥',
+'渍' => '漬',
+'渎' => '瀆',
+'渐' => '漸',
+'渑' => '澠',
+'渔' => '漁',
+'渖' => '瀋',
+'渗' => '滲',
+'温' => '溫',
+'湾' => '灣',
+'湿' => '濕',
+'溃' => '潰',
+'溅' => '濺',
+'溆' => '漵',
+'溇' => '漊',
+'滗' => '潷',
+'滚' => '滾',
+'滞' => '滯',
+'滟' => '灩',
+'滠' => '灄',
+'满' => '滿',
+'滢' => '瀅',
+'滤' => '濾',
+'滥' => '濫',
+'滦' => '灤',
+'滨' => '濱',
+'滩' => '灘',
+'滪' => '澦',
+'漤' => '灠',
+'潆' => '瀠',
+'潇' => '瀟',
+'潋' => '瀲',
+'潍' => '濰',
+'潜' => '潛',
+'潴' => '瀦',
+'澛' => '瀂',
+'澜' => '瀾',
+'濑' => '瀨',
+'濒' => '瀕',
+'灏' => '灝',
+'灭' => '滅',
+'灯' => '燈',
+'灵' => '靈',
+'灾' => '災',
+'灿' => '燦',
+'炀' => '煬',
+'炉' => '爐',
+'炖' => '燉',
+'炜' => '煒',
+'炝' => '熗',
+'点' => '點',
+'炼' => '煉',
+'炽' => '熾',
+'烁' => '爍',
+'烂' => '爛',
+'烃' => '烴',
+'烛' => '燭',
+'烟' => '煙',
+'烦' => '煩',
+'烧' => '燒',
+'烨' => '燁',
+'烩' => '燴',
+'烫' => '燙',
+'烬' => '燼',
+'热' => '熱',
+'焕' => '煥',
+'焖' => '燜',
+'焘' => '燾',
+'煴' => '熅',
+'爱' => '愛',
+'爷' => '爺',
+'牍' => '牘',
+'牦' => '氂',
+'牵' => '牽',
+'牺' => '犧',
+'犊' => '犢',
+'状' => '狀',
+'犷' => '獷',
+'犸' => '獁',
+'犹' => '猶',
+'狈' => '狽',
+'狝' => '獮',
+'狞' => '獰',
+'独' => '獨',
+'狭' => '狹',
+'狮' => '獅',
+'狯' => '獪',
+'狰' => '猙',
+'狱' => '獄',
+'狲' => '猻',
+'猃' => '獫',
+'猎' => '獵',
+'猕' => '獼',
+'猡' => '玀',
+'猪' => '豬',
+'猫' => '貓',
+'猬' => '蝟',
+'献' => '獻',
+'獭' => '獺',
+'玑' => '璣',
+'玙' => '璵',
+'玚' => '瑒',
+'玛' => '瑪',
+'玮' => '瑋',
+'环' => '環',
+'现' => '現',
+'玱' => '瑲',
+'玺' => '璽',
+'珐' => '琺',
+'珑' => '瓏',
+'珰' => '璫',
+'珲' => '琿',
+'琎' => '璡',
+'琏' => '璉',
+'琐' => '瑣',
+'琼' => '瓊',
+'瑶' => '瑤',
+'瑷' => '璦',
+'瑸' => '璸',
+'璎' => '瓔',
+'瓒' => '瓚',
+'瓯' => '甌',
+'电' => '電',
+'画' => '畫',
+'畅' => '暢',
+'畴' => '疇',
+'疖' => '癤',
+'疗' => '療',
+'疟' => '瘧',
+'疠' => '癘',
+'疡' => '瘍',
+'疬' => '癧',
+'疭' => '瘲',
+'疮' => '瘡',
+'疯' => '瘋',
+'疱' => '皰',
+'痈' => '癰',
+'痉' => '痙',
+'痒' => '癢',
+'痖' => '瘂',
+'痨' => '癆',
+'痪' => '瘓',
+'痫' => '癇',
+'痳' => '痲',
+'瘅' => '癉',
+'瘆' => '瘮',
+'瘗' => '瘞',
+'瘘' => '瘺',
+'瘪' => '癟',
+'瘫' => '癱',
+'瘾' => '癮',
+'瘿' => '癭',
+'癞' => '癩',
+'癣' => '癬',
+'癫' => '癲',
+'皑' => '皚',
+'皱' => '皺',
+'皲' => '皸',
+'盏' => '盞',
+'盐' => '鹽',
+'监' => '監',
+'盖' => '蓋',
+'盗' => '盜',
+'盘' => '盤',
+'眍' => '瞘',
+'眦' => '眥',
+'眬' => '矓',
+'睁' => '睜',
+'睐' => '睞',
+'睑' => '瞼',
+'瞆' => '瞶',
+'瞒' => '瞞',
+'瞩' => '矚',
+'矫' => '矯',
+'矶' => '磯',
+'矾' => '礬',
+'矿' => '礦',
+'砀' => '碭',
+'码' => '碼',
+'砖' => '磚',
+'砗' => '硨',
+'砚' => '硯',
+'砜' => '碸',
+'砺' => '礪',
+'砻' => '礱',
+'砾' => '礫',
+'础' => '礎',
+'硁' => '硜',
+'硕' => '碩',
+'硖' => '硤',
+'硗' => '磽',
+'硙' => '磑',
+'硚' => '礄',
+'确' => '確',
+'硵' => '磠',
+'硷' => '鹼',
+'碍' => '礙',
+'碛' => '磧',
+'碜' => '磣',
+'碱' => '鹼',
+'礼' => '禮',
+'祃' => '禡',
+'祎' => '禕',
+'祢' => '禰',
+'祯' => '禎',
+'祷' => '禱',
+'祸' => '禍',
+'禀' => '稟',
+'禄' => '祿',
+'禅' => '禪',
+'离' => '離',
+'秃' => '禿',
+'秆' => '稈',
+'种' => '種',
+'积' => '積',
+'称' => '稱',
+'秽' => '穢',
+'秾' => '穠',
+'稆' => '穭',
+'税' => '稅',
+'稣' => '穌',
+'稳' => '穩',
+'穑' => '穡',
+'穷' => '窮',
+'窃' => '竊',
+'窍' => '竅',
+'窎' => '窵',
+'窑' => '窯',
+'窜' => '竄',
+'窝' => '窩',
+'窥' => '窺',
+'窦' => '竇',
+'窭' => '窶',
+'竖' => '豎',
+'竞' => '競',
+'笃' => '篤',
+'笋' => '筍',
+'笔' => '筆',
+'笕' => '筧',
+'笺' => '箋',
+'笼' => '籠',
+'笾' => '籩',
+'筑' => '築',
+'筚' => '篳',
+'筛' => '篩',
+'筜' => '簹',
+'筝' => '箏',
+'筹' => '籌',
+'筼' => '篔',
+'签' => '簽',
+'简' => '簡',
+'箓' => '籙',
+'箦' => '簀',
+'箧' => '篋',
+'箨' => '籜',
+'箩' => '籮',
+'箪' => '簞',
+'箫' => '簫',
+'篑' => '簣',
+'篓' => '簍',
+'篮' => '籃',
+'篯' => '籛',
+'篱' => '籬',
+'簖' => '籪',
+'籁' => '籟',
+'籴' => '糴',
+'类' => '類',
+'籼' => '秈',
+'粜' => '糶',
+'粝' => '糲',
+'粤' => '粵',
+'粪' => '糞',
+'粮' => '糧',
+'糁' => '糝',
+'糇' => '餱',
+'紧' => '緊',
+'絷' => '縶',
+'纟' => '糹',
+'纠' => '糾',
+'纡' => '紆',
+'红' => '紅',
+'纣' => '紂',
+'纤' => '纖',
+'纥' => '紇',
+'约' => '約',
+'级' => '級',
+'纨' => '紈',
+'纩' => '纊',
+'纪' => '紀',
+'纫' => '紉',
+'纬' => '緯',
+'纭' => '紜',
+'纮' => '紘',
+'纯' => '純',
+'纰' => '紕',
+'纱' => '紗',
+'纲' => '綱',
+'纳' => '納',
+'纴' => '紝',
+'纵' => '縱',
+'纶' => '綸',
+'纷' => '紛',
+'纸' => '紙',
+'纹' => '紋',
+'纺' => '紡',
+'纻' => '紵',
+'纼' => '紖',
+'纽' => '紐',
+'纾' => '紓',
+'线' => '線',
+'绀' => '紺',
+'绁' => '紲',
+'绂' => '紱',
+'练' => '練',
+'组' => '組',
+'绅' => '紳',
+'细' => '細',
+'织' => '織',
+'终' => '終',
+'绉' => '縐',
+'绊' => '絆',
+'绋' => '紼',
+'绌' => '絀',
+'绍' => '紹',
+'绎' => '繹',
+'经' => '經',
+'绐' => '紿',
+'绑' => '綁',
+'绒' => '絨',
+'结' => '結',
+'绔' => '絝',
+'绕' => '繞',
+'绖' => '絰',
+'绗' => '絎',
+'绘' => '繪',
+'给' => '給',
+'绚' => '絢',
+'绛' => '絳',
+'络' => '絡',
+'绝' => '絕',
+'绞' => '絞',
+'统' => '統',
+'绠' => '綆',
+'绡' => '綃',
+'绢' => '絹',
+'绣' => '繡',
+'绤' => '綌',
+'绥' => '綏',
+'绦' => '絛',
+'继' => '繼',
+'绨' => '綈',
+'绩' => '績',
+'绪' => '緒',
+'绫' => '綾',
+'绬' => '緓',
+'续' => '續',
+'绮' => '綺',
+'绯' => '緋',
+'绰' => '綽',
+'绱' => '鞝',
+'绲' => '緄',
+'绳' => '繩',
+'维' => '維',
+'绵' => '綿',
+'绶' => '綬',
+'绷' => '繃',
+'绸' => '綢',
+'绹' => '綯',
+'绺' => '綹',
+'绻' => '綣',
+'综' => '綜',
+'绽' => '綻',
+'绾' => '綰',
+'绿' => '綠',
+'缀' => '綴',
+'缁' => '緇',
+'缂' => '緙',
+'缃' => '緗',
+'缄' => '緘',
+'缅' => '緬',
+'缆' => '纜',
+'缇' => '緹',
+'缈' => '緲',
+'缉' => '緝',
+'缊' => '縕',
+'缋' => '繢',
+'缌' => '緦',
+'缍' => '綞',
+'缎' => '緞',
+'缏' => '緶',
+'缐' => '線',
+'缑' => '緱',
+'缒' => '縋',
+'缓' => '緩',
+'缔' => '締',
+'缕' => '縷',
+'编' => '編',
+'缗' => '緡',
+'缘' => '緣',
+'缙' => '縉',
+'缚' => '縛',
+'缛' => '縟',
+'缜' => '縝',
+'缝' => '縫',
+'缞' => '縗',
+'缟' => '縞',
+'缠' => '纏',
+'缡' => '縭',
+'缢' => '縊',
+'缣' => '縑',
+'缤' => '繽',
+'缥' => '縹',
+'缦' => '縵',
+'缧' => '縲',
+'缨' => '纓',
+'缩' => '縮',
+'缪' => '繆',
+'缫' => '繅',
+'缬' => '纈',
+'缭' => '繚',
+'缮' => '繕',
+'缯' => '繒',
+'缰' => '韁',
+'缱' => '繾',
+'缲' => '繰',
+'缳' => '繯',
+'缴' => '繳',
+'缵' => '纘',
+'罂' => '罌',
+'网' => '網',
+'罗' => '羅',
+'罚' => '罰',
+'罢' => '罷',
+'罴' => '羆',
+'羁' => '羈',
+'羟' => '羥',
+'羡' => '羨',
+'翘' => '翹',
+'翙' => '翽',
+'翚' => '翬',
+'耢' => '耮',
+'耧' => '耬',
+'耸' => '聳',
+'耻' => '恥',
+'聂' => '聶',
+'聋' => '聾',
+'职' => '職',
+'聍' => '聹',
+'联' => '聯',
+'聩' => '聵',
+'聪' => '聰',
+'肃' => '肅',
+'肠' => '腸',
+'肤' => '膚',
+'肮' => '骯',
+'肴' => '餚',
+'肾' => '腎',
+'肿' => '腫',
+'胀' => '脹',
+'胁' => '脅',
+'胆' => '膽',
+'胜' => '勝',
+'胧' => '朧',
+'胨' => '腖',
+'胪' => '臚',
+'胫' => '脛',
+'胶' => '膠',
+'脉' => '脈',
+'脍' => '膾',
+'脏' => '髒',
+'脐' => '臍',
+'脑' => '腦',
+'脓' => '膿',
+'脔' => '臠',
+'脚' => '腳',
+'脱' => '脫',
+'脶' => '腡',
+'脸' => '臉',
+'腊' => '臘',
+'腌' => '醃',
+'腘' => '膕',
+'腭' => '齶',
+'腻' => '膩',
+'腼' => '靦',
+'腽' => '膃',
+'腾' => '騰',
+'膑' => '臏',
+'臜' => '臢',
+'舆' => '輿',
+'舣' => '艤',
+'舰' => '艦',
+'舱' => '艙',
+'舻' => '艫',
+'艰' => '艱',
+'艳' => '艷',
+'艺' => '藝',
+'节' => '節',
+'芈' => '羋',
+'芗' => '薌',
+'芜' => '蕪',
+'芦' => '蘆',
+'苁' => '蓯',
+'苇' => '葦',
+'苈' => '藶',
+'苋' => '莧',
+'苌' => '萇',
+'苍' => '蒼',
+'苎' => '苧',
+'苏' => '蘇',
+'苧' => '薴',
+'茎' => '莖',
+'茏' => '蘢',
+'茑' => '蔦',
+'茔' => '塋',
+'茕' => '煢',
+'茧' => '繭',
+'荆' => '荊',
+'荐' => '薦',
+'荙' => '薘',
+'荚' => '莢',
+'荛' => '蕘',
+'荜' => '蓽',
+'荝' => '萴',
+'荞' => '蕎',
+'荟' => '薈',
+'荠' => '薺',
+'荡' => '盪',
+'荣' => '榮',
+'荤' => '葷',
+'荥' => '滎',
+'荦' => '犖',
+'荧' => '熒',
+'荨' => '蕁',
+'荩' => '藎',
+'荪' => '蓀',
+'荫' => '蔭',
+'荬' => '蕒',
+'荭' => '葒',
+'荮' => '葤',
+'药' => '藥',
+'莅' => '蒞',
+'莱' => '萊',
+'莲' => '蓮',
+'莳' => '蒔',
+'莴' => '萵',
+'莶' => '薟',
+'获' => '獲',
+'莸' => '蕕',
+'莹' => '瑩',
+'莺' => '鶯',
+'莼' => '蓴',
+'萚' => '蘀',
+'萝' => '蘿',
+'萤' => '螢',
+'营' => '營',
+'萦' => '縈',
+'萧' => '蕭',
+'萨' => '薩',
+'葱' => '蔥',
+'蒇' => '蕆',
+'蒉' => '蕢',
+'蒋' => '蔣',
+'蒌' => '蔞',
+'蓝' => '藍',
+'蓟' => '薊',
+'蓠' => '蘺',
+'蓣' => '蕷',
+'蓥' => '鎣',
+'蓦' => '驀',
+'蔂' => '虆',
+'蔷' => '薔',
+'蔹' => '蘞',
+'蔺' => '藺',
+'蔼' => '藹',
+'蕰' => '薀',
+'蕲' => '蘄',
+'蕴' => '蘊',
+'薮' => '藪',
+'藓' => '蘚',
+'蘖' => '櫱',
+'虏' => '虜',
+'虑' => '慮',
+'虚' => '虛',
+'虫' => '蟲',
+'虮' => '蟣',
+'虽' => '雖',
+'虾' => '蝦',
+'虿' => '蠆',
+'蚀' => '蝕',
+'蚁' => '蟻',
+'蚂' => '螞',
+'蚃' => '蠁',
+'蚕' => '蠶',
+'蚬' => '蜆',
+'蛊' => '蠱',
+'蛎' => '蠣',
+'蛏' => '蟶',
+'蛮' => '蠻',
+'蛰' => '蟄',
+'蛱' => '蛺',
+'蛲' => '蟯',
+'蛳' => '螄',
+'蛴' => '蠐',
+'蜕' => '蛻',
+'蜗' => '蝸',
+'蜡' => '蠟',
+'蝇' => '蠅',
+'蝈' => '蟈',
+'蝉' => '蟬',
+'蝎' => '蠍',
+'蝼' => '螻',
+'蝾' => '蠑',
+'螀' => '螿',
+'螨' => '蟎',
+'蟏' => '蠨',
+'衅' => '釁',
+'衔' => '銜',
+'补' => '補',
+'衬' => '襯',
+'衮' => '袞',
+'袄' => '襖',
+'袅' => '裊',
+'袆' => '褘',
+'袜' => '襪',
+'袭' => '襲',
+'袯' => '襏',
+'装' => '裝',
+'裆' => '襠',
+'裈' => '褌',
+'裢' => '褳',
+'裣' => '襝',
+'裤' => '褲',
+'裥' => '襉',
+'褛' => '褸',
+'褴' => '襤',
+'襕' => '襴',
+'见' => '見',
+'观' => '觀',
+'觃' => '覎',
+'规' => '規',
+'觅' => '覓',
+'视' => '視',
+'觇' => '覘',
+'览' => '覽',
+'觉' => '覺',
+'觊' => '覬',
+'觋' => '覡',
+'觌' => '覿',
+'觍' => '覥',
+'觎' => '覦',
+'觏' => '覯',
+'觐' => '覲',
+'觑' => '覷',
+'觞' => '觴',
+'触' => '觸',
+'觯' => '觶',
+'訚' => '誾',
+'詟' => '讋',
+'誉' => '譽',
+'誊' => '謄',
+'讠' => '訁',
+'计' => '計',
+'订' => '訂',
+'讣' => '訃',
+'认' => '認',
+'讥' => '譏',
+'讦' => '訐',
+'讧' => '訌',
+'讨' => '討',
+'让' => '讓',
+'讪' => '訕',
+'讫' => '訖',
+'讬' => '託',
+'训' => '訓',
+'议' => '議',
+'讯' => '訊',
+'记' => '記',
+'讱' => '訒',
+'讲' => '講',
+'讳' => '諱',
+'讴' => '謳',
+'讵' => '詎',
+'讶' => '訝',
+'讷' => '訥',
+'许' => '許',
+'讹' => '訛',
+'论' => '論',
+'讻' => '訩',
+'讼' => '訟',
+'讽' => '諷',
+'设' => '設',
+'访' => '訪',
+'诀' => '訣',
+'证' => '證',
+'诂' => '詁',
+'诃' => '訶',
+'评' => '評',
+'诅' => '詛',
+'识' => '識',
+'诇' => '詗',
+'诈' => '詐',
+'诉' => '訴',
+'诊' => '診',
+'诋' => '詆',
+'诌' => '謅',
+'词' => '詞',
+'诎' => '詘',
+'诏' => '詔',
+'诐' => '詖',
+'译' => '譯',
+'诒' => '詒',
+'诓' => '誆',
+'诔' => '誄',
+'试' => '試',
+'诖' => '詿',
+'诗' => '詩',
+'诘' => '詰',
+'诙' => '詼',
+'诚' => '誠',
+'诛' => '誅',
+'诜' => '詵',
+'话' => '話',
+'诞' => '誕',
+'诟' => '詬',
+'诠' => '詮',
+'诡' => '詭',
+'询' => '詢',
+'诣' => '詣',
+'诤' => '諍',
+'该' => '該',
+'详' => '詳',
+'诧' => '詫',
+'诨' => '諢',
+'诩' => '詡',
+'诪' => '譸',
+'诫' => '誡',
+'诬' => '誣',
+'语' => '語',
+'诮' => '誚',
+'误' => '誤',
+'诰' => '誥',
+'诱' => '誘',
+'诲' => '誨',
+'诳' => '誑',
+'说' => '說',
+'诵' => '誦',
+'诶' => '誒',
+'请' => '請',
+'诸' => '諸',
+'诹' => '諏',
+'诺' => '諾',
+'读' => '讀',
+'诼' => '諑',
+'诽' => '誹',
+'课' => '課',
+'诿' => '諉',
+'谀' => '諛',
+'谁' => '誰',
+'谂' => '諗',
+'调' => '調',
+'谄' => '諂',
+'谅' => '諒',
+'谆' => '諄',
+'谇' => '誶',
+'谈' => '談',
+'谊' => '誼',
+'谋' => '謀',
+'谌' => '諶',
+'谍' => '諜',
+'谎' => '謊',
+'谏' => '諫',
+'谐' => '諧',
+'谑' => '謔',
+'谒' => '謁',
+'谓' => '謂',
+'谔' => '諤',
+'谕' => '諭',
+'谖' => '諼',
+'谗' => '讒',
+'谘' => '諮',
+'谙' => '諳',
+'谚' => '諺',
+'谛' => '諦',
+'谜' => '謎',
+'谝' => '諞',
+'谞' => '諝',
+'谟' => '謨',
+'谠' => '讜',
+'谡' => '謖',
+'谢' => '謝',
+'谣' => '謠',
+'谤' => '謗',
+'谥' => '諡',
+'谦' => '謙',
+'谧' => '謐',
+'谨' => '謹',
+'谩' => '謾',
+'谪' => '謫',
+'谫' => '譾',
+'谬' => '謬',
+'谭' => '譚',
+'谮' => '譖',
+'谯' => '譙',
+'谰' => '讕',
+'谱' => '譜',
+'谲' => '譎',
+'谳' => '讞',
+'谴' => '譴',
+'谵' => '譫',
+'谶' => '讖',
+'豮' => '豶',
+'贝' => '貝',
+'贞' => '貞',
+'负' => '負',
+'贠' => '貟',
+'贡' => '貢',
+'财' => '財',
+'责' => '責',
+'贤' => '賢',
+'败' => '敗',
+'账' => '賬',
+'货' => '貨',
+'质' => '質',
+'贩' => '販',
+'贪' => '貪',
+'贫' => '貧',
+'贬' => '貶',
+'购' => '購',
+'贮' => '貯',
+'贯' => '貫',
+'贰' => '貳',
+'贱' => '賤',
+'贲' => '賁',
+'贳' => '貰',
+'贴' => '貼',
+'贵' => '貴',
+'贶' => '貺',
+'贷' => '貸',
+'贸' => '貿',
+'费' => '費',
+'贺' => '賀',
+'贻' => '貽',
+'贼' => '賊',
+'贽' => '贄',
+'贾' => '賈',
+'贿' => '賄',
+'赀' => '貲',
+'赁' => '賃',
+'赂' => '賂',
+'赃' => '贓',
+'资' => '資',
+'赅' => '賅',
+'赆' => '贐',
+'赇' => '賕',
+'赈' => '賑',
+'赉' => '賚',
+'赊' => '賒',
+'赋' => '賦',
+'赌' => '賭',
+'赍' => '齎',
+'赎' => '贖',
+'赏' => '賞',
+'赐' => '賜',
+'赑' => '贔',
+'赒' => '賙',
+'赓' => '賡',
+'赔' => '賠',
+'赕' => '賧',
+'赖' => '賴',
+'赗' => '賵',
+'赘' => '贅',
+'赙' => '賻',
+'赚' => '賺',
+'赛' => '賽',
+'赜' => '賾',
+'赝' => '贗',
+'赞' => '贊',
+'赟' => '贇',
+'赠' => '贈',
+'赡' => '贍',
+'赢' => '贏',
+'赣' => '贛',
+'赪' => '赬',
+'赵' => '趙',
+'赶' => '趕',
+'趋' => '趨',
+'趱' => '趲',
+'趸' => '躉',
+'跃' => '躍',
+'跄' => '蹌',
+'跞' => '躒',
+'践' => '踐',
+'跶' => '躂',
+'跷' => '蹺',
+'跸' => '蹕',
+'跹' => '躚',
+'跻' => '躋',
+'踊' => '踴',
+'踌' => '躊',
+'踪' => '蹤',
+'踬' => '躓',
+'踯' => '躑',
+'蹑' => '躡',
+'蹒' => '蹣',
+'蹰' => '躕',
+'蹿' => '躥',
+'躏' => '躪',
+'躜' => '躦',
+'躯' => '軀',
+'车' => '車',
+'轧' => '軋',
+'轨' => '軌',
+'轩' => '軒',
+'轪' => '軑',
+'轫' => '軔',
+'转' => '轉',
+'轭' => '軛',
+'轮' => '輪',
+'软' => '軟',
+'轰' => '轟',
+'轱' => '軲',
+'轲' => '軻',
+'轳' => '轤',
+'轴' => '軸',
+'轵' => '軹',
+'轶' => '軼',
+'轷' => '軤',
+'轸' => '軫',
+'轹' => '轢',
+'轺' => '軺',
+'轻' => '輕',
+'轼' => '軾',
+'载' => '載',
+'轾' => '輊',
+'轿' => '轎',
+'辀' => '輈',
+'辁' => '輇',
+'辂' => '輅',
+'较' => '較',
+'辄' => '輒',
+'辅' => '輔',
+'辆' => '輛',
+'辇' => '輦',
+'辈' => '輩',
+'辉' => '輝',
+'辊' => '輥',
+'辋' => '輞',
+'辌' => '輬',
+'辍' => '輟',
+'辎' => '輜',
+'辏' => '輳',
+'辐' => '輻',
+'辑' => '輯',
+'辒' => '轀',
+'输' => '輸',
+'辔' => '轡',
+'辕' => '轅',
+'辖' => '轄',
+'辗' => '輾',
+'辘' => '轆',
+'辙' => '轍',
+'辚' => '轔',
+'辞' => '辭',
+'辩' => '辯',
+'辫' => '辮',
+'边' => '邊',
+'辽' => '遼',
+'达' => '達',
+'迁' => '遷',
+'过' => '過',
+'迈' => '邁',
+'运' => '運',
+'还' => '還',
+'这' => '這',
+'进' => '進',
+'远' => '遠',
+'违' => '違',
+'连' => '連',
+'迟' => '遲',
+'迩' => '邇',
+'迳' => '逕',
+'迹' => '跡',
+'适' => '適',
+'选' => '選',
+'逊' => '遜',
+'递' => '遞',
+'逦' => '邐',
+'逻' => '邏',
+'遗' => '遺',
+'遥' => '遙',
+'邓' => '鄧',
+'邝' => '鄺',
+'邬' => '鄔',
+'邮' => '郵',
+'邹' => '鄒',
+'邺' => '鄴',
+'邻' => '鄰',
+'郏' => '郟',
+'郐' => '鄶',
+'郑' => '鄭',
+'郓' => '鄆',
+'郦' => '酈',
+'郧' => '鄖',
+'郸' => '鄲',
+'酂' => '酇',
+'酝' => '醞',
+'酦' => '醱',
+'酱' => '醬',
+'酽' => '釅',
+'酾' => '釃',
+'酿' => '釀',
+'释' => '釋',
+'鉴' => '鑒',
+'銮' => '鑾',
+'錾' => '鏨',
+'钅' => '釒',
+'钆' => '釓',
+'钇' => '釔',
+'针' => '針',
+'钉' => '釘',
+'钊' => '釗',
+'钋' => '釙',
+'钌' => '釕',
+'钍' => '釷',
+'钎' => '釺',
+'钏' => '釧',
+'钐' => '釤',
+'钑' => '鈒',
+'钒' => '釩',
+'钓' => '釣',
+'钔' => '鍆',
+'钕' => '釹',
+'钖' => '鍚',
+'钗' => '釵',
+'钘' => '鈃',
+'钙' => '鈣',
+'钚' => '鈈',
+'钛' => '鈦',
+'钜' => '鉅',
+'钝' => '鈍',
+'钞' => '鈔',
+'钟' => '鍾',
+'钠' => '鈉',
+'钡' => '鋇',
+'钢' => '鋼',
+'钣' => '鈑',
+'钤' => '鈐',
+'钥' => '鑰',
+'钦' => '欽',
+'钧' => '鈞',
+'钨' => '鎢',
+'钩' => '鈎',
+'钪' => '鈧',
+'钫' => '鈁',
+'钬' => '鈥',
+'钭' => '鈄',
+'钮' => '鈕',
+'钯' => '鈀',
+'钰' => '鈺',
+'钱' => '錢',
+'钲' => '鉦',
+'钳' => '鉗',
+'钴' => '鈷',
+'钵' => '缽',
+'钶' => '鈳',
+'钷' => '鉕',
+'钸' => '鈽',
+'钹' => '鈸',
+'钺' => '鉞',
+'钻' => '鑽',
+'钼' => '鉬',
+'钽' => '鉭',
+'钾' => '鉀',
+'钿' => '鈿',
+'铀' => '鈾',
+'铁' => '鐵',
+'铂' => '鉑',
+'铃' => '鈴',
+'铄' => '鑠',
+'铅' => '鉛',
+'铆' => '鉚',
+'铇' => '鉋',
+'铈' => '鈰',
+'铉' => '鉉',
+'铊' => '鉈',
+'铋' => '鉍',
+'铌' => '鈮',
+'铍' => '鈹',
+'铎' => '鐸',
+'铏' => '鉶',
+'铐' => '銬',
+'铑' => '銠',
+'铒' => '鉺',
+'铓' => '鋩',
+'铔' => '錏',
+'铕' => '銪',
+'铖' => '鋮',
+'铗' => '鋏',
+'铘' => '鋣',
+'铙' => '鐃',
+'铚' => '銍',
+'铛' => '鐺',
+'铜' => '銅',
+'铝' => '鋁',
+'铞' => '銱',
+'铟' => '銦',
+'铠' => '鎧',
+'铡' => '鍘',
+'铢' => '銖',
+'铣' => '銑',
+'铤' => '鋌',
+'铥' => '銩',
+'铦' => '銛',
+'铧' => '鏵',
+'铨' => '銓',
+'铩' => '鎩',
+'铪' => '鉿',
+'铫' => '銚',
+'铬' => '鉻',
+'铭' => '銘',
+'铮' => '錚',
+'铯' => '銫',
+'铰' => '鉸',
+'铱' => '銥',
+'铲' => '鏟',
+'铳' => '銃',
+'铴' => '鐋',
+'铵' => '銨',
+'银' => '銀',
+'铷' => '銣',
+'铸' => '鑄',
+'铹' => '鐒',
+'铺' => '鋪',
+'铻' => '鋙',
+'铼' => '錸',
+'铽' => '鋱',
+'链' => '鏈',
+'铿' => '鏗',
+'销' => '銷',
+'锁' => '鎖',
+'锂' => '鋰',
+'锃' => '鋥',
+'锄' => '鋤',
+'锅' => '鍋',
+'锆' => '鋯',
+'锇' => '鋨',
+'锈' => '銹',
+'锉' => '銼',
+'锊' => '鋝',
+'锋' => '鋒',
+'锌' => '鋅',
+'锍' => '鋶',
+'锎' => '鐦',
+'锏' => '鐧',
+'锐' => '銳',
+'锑' => '銻',
+'锒' => '鋃',
+'锓' => '鋟',
+'锔' => '鋦',
+'锕' => '錒',
+'锖' => '錆',
+'锗' => '鍺',
+'锘' => '鍩',
+'错' => '錯',
+'锚' => '錨',
+'锛' => '錛',
+'锜' => '錡',
+'锝' => '鍀',
+'锞' => '錁',
+'锟' => '錕',
+'锠' => '錩',
+'锡' => '錫',
+'锢' => '錮',
+'锣' => '鑼',
+'锤' => '錘',
+'锥' => '錐',
+'锦' => '錦',
+'锧' => '鑕',
+'锨' => '杴',
+'锩' => '錈',
+'锪' => '鍃',
+'锫' => '錇',
+'锬' => '錟',
+'锭' => '錠',
+'键' => '鍵',
+'锯' => '鋸',
+'锰' => '錳',
+'锱' => '錙',
+'锲' => '鍥',
+'锳' => '鍈',
+'锴' => '鍇',
+'锵' => '鏘',
+'锶' => '鍶',
+'锷' => '鍔',
+'锸' => '鍤',
+'锹' => '鍬',
+'锺' => '鍾',
+'锻' => '鍛',
+'锼' => '鎪',
+'锽' => '鍠',
+'锾' => '鍰',
+'锿' => '鎄',
+'镀' => '鍍',
+'镁' => '鎂',
+'镂' => '鏤',
+'镃' => '鎡',
+'镄' => '鐨',
+'镅' => '鎇',
+'镆' => '鏌',
+'镇' => '鎮',
+'镈' => '鎛',
+'镉' => '鎘',
+'镊' => '鑷',
+'镋' => '钂',
+'镌' => '鐫',
+'镍' => '鎳',
+'镎' => '鎿',
+'镏' => '鎦',
+'镐' => '鎬',
+'镑' => '鎊',
+'镒' => '鎰',
+'镓' => '鎵',
+'镔' => '鑌',
+'镕' => '鎔',
+'镖' => '鏢',
+'镗' => '鏜',
+'镘' => '鏝',
+'镙' => '鏍',
+'镚' => '鏰',
+'镛' => '鏞',
+'镜' => '鏡',
+'镝' => '鏑',
+'镞' => '鏃',
+'镟' => '鏇',
+'镠' => '鏐',
+'镡' => '鐔',
+'镢' => '钁',
+'镣' => '鐐',
+'镤' => '鏷',
+'镥' => '鑥',
+'镦' => '鐓',
+'镧' => '鑭',
+'镨' => '鐠',
+'镩' => '鑹',
+'镪' => '鏹',
+'镫' => '鐙',
+'镬' => '鑊',
+'镭' => '鐳',
+'镮' => '鐶',
+'镯' => '鐲',
+'镰' => '鐮',
+'镱' => '鐿',
+'镲' => '鑔',
+'镳' => '鑣',
+'镴' => '鑞',
+'镵' => '鑱',
+'镶' => '鑲',
+'长' => '長',
+'门' => '門',
+'闩' => '閂',
+'闪' => '閃',
+'闫' => '閆',
+'闬' => '閈',
+'闭' => '閉',
+'问' => '問',
+'闯' => '闖',
+'闰' => '閏',
+'闱' => '闈',
+'闲' => '閒',
+'闳' => '閎',
+'间' => '間',
+'闵' => '閔',
+'闶' => '閌',
+'闷' => '悶',
+'闸' => '閘',
+'闹' => '鬧',
+'闺' => '閨',
+'闻' => '聞',
+'闼' => '闥',
+'闽' => '閩',
+'闾' => '閭',
+'闿' => '闓',
+'阀' => '閥',
+'阁' => '閣',
+'阂' => '閡',
+'阃' => '閫',
+'阄' => '鬮',
+'阅' => '閱',
+'阆' => '閬',
+'阇' => '闍',
+'阈' => '閾',
+'阉' => '閹',
+'阊' => '閶',
+'阋' => '鬩',
+'阌' => '閿',
+'阍' => '閽',
+'阎' => '閻',
+'阏' => '閼',
+'阐' => '闡',
+'阑' => '闌',
+'阒' => '闃',
+'阓' => '闠',
+'阔' => '闊',
+'阕' => '闋',
+'阖' => '闔',
+'阗' => '闐',
+'阘' => '闒',
+'阙' => '闕',
+'阚' => '闞',
+'阛' => '闤',
+'队' => '隊',
+'阳' => '陽',
+'阴' => '陰',
+'阵' => '陣',
+'阶' => '階',
+'际' => '際',
+'陆' => '陸',
+'陇' => '隴',
+'陈' => '陳',
+'陉' => '陘',
+'陕' => '陝',
+'陧' => '隉',
+'陨' => '隕',
+'险' => '險',
+'随' => '隨',
+'隐' => '隱',
+'隶' => '隸',
+'隽' => '雋',
+'难' => '難',
+'雏' => '雛',
+'雠' => '讎',
+'雳' => '靂',
+'雾' => '霧',
+'霁' => '霽',
+'霡' => '霢',
+'霭' => '靄',
+'靓' => '靚',
+'静' => '靜',
+'靥' => '靨',
+'鞑' => '韃',
+'鞒' => '鞽',
+'鞯' => '韉',
+'韦' => '韋',
+'韧' => '韌',
+'韨' => '韍',
+'韩' => '韓',
+'韪' => '韙',
+'韫' => '韞',
+'韬' => '韜',
+'韵' => '韻',
+'页' => '頁',
+'顶' => '頂',
+'顷' => '頃',
+'顸' => '頇',
+'项' => '項',
+'顺' => '順',
+'须' => '須',
+'顼' => '頊',
+'顽' => '頑',
+'顾' => '顧',
+'顿' => '頓',
+'颀' => '頎',
+'颁' => '頒',
+'颂' => '頌',
+'颃' => '頏',
+'预' => '預',
+'颅' => '顱',
+'领' => '領',
+'颇' => '頗',
+'颈' => '頸',
+'颉' => '頡',
+'颊' => '頰',
+'颋' => '頲',
+'颌' => '頜',
+'颍' => '潁',
+'颎' => '熲',
+'颏' => '頦',
+'颐' => '頤',
+'频' => '頻',
+'颒' => '頮',
+'颓' => '頹',
+'颔' => '頷',
+'颕' => '頴',
+'颖' => '穎',
+'颗' => '顆',
+'题' => '題',
+'颙' => '顒',
+'颚' => '顎',
+'颛' => '顓',
+'颜' => '顏',
+'额' => '額',
+'颞' => '顳',
+'颟' => '顢',
+'颠' => '顛',
+'颡' => '顙',
+'颢' => '顥',
+'颣' => '纇',
+'颤' => '顫',
+'颥' => '顬',
+'颦' => '顰',
+'颧' => '顴',
+'风' => '風',
+'飏' => '颺',
+'飐' => '颭',
+'飑' => '颮',
+'飒' => '颯',
+'飓' => '颶',
+'飔' => '颸',
+'飕' => '颼',
+'飖' => '颻',
+'飗' => '飀',
+'飘' => '飄',
+'飙' => '飆',
+'飚' => '飈',
+'飞' => '飛',
+'飨' => '饗',
+'餍' => '饜',
+'饣' => '飠',
+'饤' => '飣',
+'饥' => '飢',
+'饦' => '飥',
+'饧' => '餳',
+'饨' => '飩',
+'饩' => '餼',
+'饪' => '飪',
+'饫' => '飫',
+'饬' => '飭',
+'饭' => '飯',
+'饮' => '飲',
+'饯' => '餞',
+'饰' => '飾',
+'饱' => '飽',
+'饲' => '飼',
+'饳' => '飿',
+'饴' => '飴',
+'饵' => '餌',
+'饶' => '饒',
+'饷' => '餉',
+'饸' => '餄',
+'饹' => '餎',
+'饺' => '餃',
+'饻' => '餏',
+'饼' => '餅',
+'饽' => '餑',
+'饾' => '餖',
+'饿' => '餓',
+'馀' => '餘',
+'馁' => '餒',
+'馂' => '餕',
+'馃' => '餜',
+'馄' => '餛',
+'馅' => '餡',
+'馆' => '館',
+'馇' => '餷',
+'馈' => '饋',
+'馉' => '餶',
+'馊' => '餿',
+'馋' => '饞',
+'馌' => '饁',
+'馍' => '饃',
+'馎' => '餺',
+'馏' => '餾',
+'馐' => '饈',
+'馑' => '饉',
+'馒' => '饅',
+'馓' => '饊',
+'馔' => '饌',
+'馕' => '饢',
+'马' => '馬',
+'驭' => '馭',
+'驮' => '馱',
+'驯' => '馴',
+'驰' => '馳',
+'驱' => '驅',
+'驲' => '馹',
+'驳' => '駁',
+'驴' => '驢',
+'驵' => '駔',
+'驶' => '駛',
+'驷' => '駟',
+'驸' => '駙',
+'驹' => '駒',
+'驺' => '騶',
+'驻' => '駐',
+'驼' => '駝',
+'驽' => '駑',
+'驾' => '駕',
+'驿' => '驛',
+'骀' => '駘',
+'骁' => '驍',
+'骂' => '罵',
+'骃' => '駰',
+'骄' => '驕',
+'骅' => '驊',
+'骆' => '駱',
+'骇' => '駭',
+'骈' => '駢',
+'骉' => '驫',
+'骊' => '驪',
+'骋' => '騁',
+'验' => '驗',
+'骍' => '騂',
+'骎' => '駸',
+'骏' => '駿',
+'骐' => '騏',
+'骑' => '騎',
+'骒' => '騍',
+'骓' => '騅',
+'骔' => '騌',
+'骕' => '驌',
+'骖' => '驂',
+'骗' => '騙',
+'骘' => '騭',
+'骙' => '騤',
+'骚' => '騷',
+'骛' => '騖',
+'骜' => '驁',
+'骝' => '騮',
+'骞' => '騫',
+'骟' => '騸',
+'骠' => '驃',
+'骡' => '騾',
+'骢' => '驄',
+'骣' => '驏',
+'骤' => '驟',
+'骥' => '驥',
+'骦' => '驦',
+'骧' => '驤',
+'髅' => '髏',
+'髋' => '髖',
+'髌' => '髕',
+'鬓' => '鬢',
+'鬶' => '鬹',
+'魇' => '魘',
+'魉' => '魎',
+'鱼' => '魚',
+'鱽' => '魛',
+'鱾' => '魢',
+'鱿' => '魷',
+'鲀' => '魨',
+'鲁' => '魯',
+'鲂' => '魴',
+'鲃' => '䰾',
+'鲄' => '魺',
+'鲅' => '鮁',
+'鲆' => '鮃',
+'鲇' => '鯰',
+'鲈' => '鱸',
+'鲉' => '鮋',
+'鲊' => '鮓',
+'鲋' => '鮒',
+'鲌' => '鮊',
+'鲍' => '鮑',
+'鲎' => '鱟',
+'鲏' => '鮍',
+'鲐' => '鮐',
+'鲑' => '鮭',
+'鲒' => '鮚',
+'鲓' => '鮳',
+'鲔' => '鮪',
+'鲕' => '鮞',
+'鲖' => '鮦',
+'鲗' => '鰂',
+'鲘' => '鮜',
+'鲙' => '鱠',
+'鲚' => '鱭',
+'鲛' => '鮫',
+'鲜' => '鮮',
+'鲝' => '鮺',
+'鲞' => '鯗',
+'鲟' => '鱘',
+'鲠' => '鯁',
+'鲡' => '鱺',
+'鲢' => '鰱',
+'鲣' => '鰹',
+'鲤' => '鯉',
+'鲥' => '鰣',
+'鲦' => '鰷',
+'鲧' => '鯀',
+'鲨' => '鯊',
+'鲩' => '鯇',
+'鲪' => '鮶',
+'鲫' => '鯽',
+'鲬' => '鯒',
+'鲭' => '鯖',
+'鲮' => '鯪',
+'鲯' => '鯕',
+'鲰' => '鯫',
+'鲱' => '鯡',
+'鲲' => '鯤',
+'鲳' => '鯧',
+'鲴' => '鯝',
+'鲵' => '鯢',
+'鲷' => '鯛',
+'鲸' => '鯨',
+'鲹' => '鰺',
+'鲺' => '鯴',
+'鲻' => '鯔',
+'鲼' => '鱝',
+'鲽' => '鰈',
+'鲾' => '鰏',
+'鲿' => '鱨',
+'鳀' => '鯷',
+'鳁' => '鰮',
+'鳂' => '鰃',
+'鳃' => '鰓',
+'鳄' => '鱷',
+'鳅' => '鰍',
+'鳆' => '鰒',
+'鳇' => '鰉',
+'鳈' => '鰁',
+'鳉' => '鱂',
+'鳊' => '鯿',
+'鳋' => '鰠',
+'鳌' => '鰲',
+'鳍' => '鰭',
+'鳎' => '鰨',
+'鳏' => '鰥',
+'鳐' => '鰩',
+'鳑' => '鰟',
+'鳒' => '鰜',
+'鳓' => '鰳',
+'鳔' => '鰾',
+'鳕' => '鱈',
+'鳖' => '鱉',
+'鳗' => '鰻',
+'鳘' => '鰵',
+'鳙' => '鱅',
+'鳚' => '䲁',
+'鳛' => '鰼',
+'鳜' => '鱖',
+'鳝' => '鱔',
+'鳞' => '鱗',
+'鳟' => '鱒',
+'鳠' => '鱯',
+'鳡' => '鱤',
+'鳢' => '鱧',
+'鳣' => '鱣',
+'鳤' => '䲘',
+'鸟' => '鳥',
+'鸠' => '鳩',
+'鸡' => '雞',
+'鸢' => '鳶',
+'鸣' => '鳴',
+'鸤' => '鳲',
+'鸥' => '鷗',
+'鸦' => '鴉',
+'鸧' => '鶬',
+'鸨' => '鴇',
+'鸩' => '鴆',
+'鸪' => '鴣',
+'鸫' => '鶇',
+'鸬' => '鸕',
+'鸭' => '鴨',
+'鸮' => '鴞',
+'鸯' => '鴦',
+'鸰' => '鴒',
+'鸱' => '鴟',
+'鸲' => '鴝',
+'鸳' => '鴛',
+'鸴' => '鷽',
+'鸵' => '鴕',
+'鸶' => '鷥',
+'鸷' => '鷙',
+'鸸' => '鴯',
+'鸹' => '鴰',
+'鸺' => '鵂',
+'鸻' => '鴴',
+'鸼' => '鵃',
+'鸽' => '鴿',
+'鸾' => '鸞',
+'鸿' => '鴻',
+'鹀' => '鵐',
+'鹁' => '鵓',
+'鹂' => '鸝',
+'鹃' => '鵑',
+'鹄' => '鵠',
+'鹅' => '鵝',
+'鹆' => '鵒',
+'鹇' => '鷳',
+'鹈' => '鵜',
+'鹉' => '鵡',
+'鹊' => '鵲',
+'鹋' => '鶓',
+'鹌' => '鵪',
+'鹍' => '鵾',
+'鹎' => '鵯',
+'鹏' => '鵬',
+'鹐' => '鵮',
+'鹑' => '鶉',
+'鹒' => '鶊',
+'鹓' => '鵷',
+'鹔' => '鷫',
+'鹕' => '鶘',
+'鹖' => '鶡',
+'鹗' => '鶚',
+'鹘' => '鶻',
+'鹙' => '鶖',
+'鹚' => '鶿',
+'鹛' => '鶥',
+'鹜' => '鶩',
+'鹝' => '鷊',
+'鹞' => '鷂',
+'鹟' => '鶲',
+'鹠' => '鶹',
+'鹡' => '鶺',
+'鹢' => '鷁',
+'鹣' => '鶼',
+'鹤' => '鶴',
+'鹥' => '鷖',
+'鹦' => '鸚',
+'鹧' => '鷓',
+'鹨' => '鷚',
+'鹩' => '鷯',
+'鹪' => '鷦',
+'鹫' => '鷲',
+'鹬' => '鷸',
+'鹭' => '鷺',
+'鹮' => '䴉',
+'鹯' => '鸇',
+'鹰' => '鷹',
+'鹱' => '鸌',
+'鹲' => '鸏',
+'鹳' => '鸛',
+'鹴' => '鸘',
+'鹾' => '鹺',
+'麦' => '麥',
+'麸' => '麩',
+'麹' => '麴',
+'黄' => '黃',
+'黉' => '黌',
+'黡' => '黶',
+'黩' => '黷',
+'黪' => '黲',
+'黾' => '黽',
+'鼋' => '黿',
+'鼍' => '鼉',
+'鼗' => '鞀',
+'鼹' => '鼴',
+'齐' => '齊',
+'齑' => '齏',
+'齿' => '齒',
+'龀' => '齔',
+'龁' => '齕',
+'龂' => '齗',
+'龃' => '齟',
+'龄' => '齡',
+'龅' => '齙',
+'龆' => '齠',
+'龇' => '齜',
+'龈' => '齦',
+'龉' => '齬',
+'龊' => '齪',
+'龋' => '齲',
+'龌' => '齷',
+'龙' => '龍',
+'龚' => '龔',
+'龛' => '龕',
+'龟' => '龜',
+'𠆲' => '儣',
+'𠆿' => '𠌥',
+'𠉂' => '㒓',
+'𠉗' => '𠏢',
+'𠚳' => '𠠎',
+'𠛅' => '剾',
+'𠛆' => '𠞆',
+'𠯟' => '哯',
+'𠯠' => '噅',
+'𠲥' => '𡅏',
+'𠴢' => '𡄔',
+'𠵸' => '𡄣',
+'𠵾' => '㗲',
+'𡋀' => '𡓾',
+'𡋗' => '𡑭',
+'𡒄' => '壈',
+'𡝠' => '㜷',
+'𡞱' => '㜢',
+'𡭜' => '𡮉',
+'𡭬' => '𡮣',
+'𡶴' => '嵼',
+'𢋈' => '㢝',
+'𢘝' => '𢣚',
+'𢘞' => '𢣭',
+'𢙓' => '懀',
+'𢛯' => '㦎',
+'𢫊' => '𢷮',
+'𢫞' => '𢶫',
+'𢫬' => '摋',
+'𢬦' => '𢹿',
+'𢭏' => '擣',
+'𢽾' => '斅',
+'𣆐' => '曥',
+'𣍨' => '𦢈',
+'𣍯' => '腪',
+'𣍰' => '脥',
+'𣎑' => '臗',
+'𣐤' => '欍',
+'𣑶' => '𣠲',
+'𣗋' => '欓',
+'𣘓' => '𣞻',
+'𣘴' => '檭',
+'𣘷' => '𣝕',
+'𣭤' => '𣯴',
+'𣶩' => '澅',
+'𣶫' => '𣿉',
+'𣸣' => '濆',
+'𣺼' => '灙',
+'𣺽' => '𤁣',
+'𣽷' => '瀃',
+'𤆡' => '熓',
+'𤇃' => '爄',
+'𤇄' => '熌',
+'𤈶' => '熉',
+'𤈷' => '㷿',
+'𤊀' => '𤒎',
+'𤋏' => '熡',
+'𤞤' => '玁',
+'𤠋' => '㺏',
+'𤦀' => '瓕',
+'𤳄' => '𤳸',
+'𤶧' => '𤸫',
+'𤽯' => '㿧',
+'𤾀' => '皟',
+'𥅘' => '𥌃',
+'𥅴' => '䀹',
+'𥆧' => '瞤',
+'𥇢' => '䁪',
+'𥐟' => '礒',
+'𥐯' => '𥖅',
+'𥐰' => '𥕥',
+'𥐻' => '碙',
+'𥧂' => '𥨐',
+'𥬀' => '䉙',
+'𥬞' => '籋',
+'𥬠' => '篘',
+'𥭉' => '𥵊',
+'𥮋' => '𥸠',
+'𥮜' => '䉲',
+'𥱔' => '𥵃',
+'𥹥' => '𥼽',
+'𥺅' => '䊭',
+'𥺇' => '𥽖',
+'𦈈' => '𥿊',
+'𦈉' => '緷',
+'𦈋' => '綇',
+'𦈌' => '綀',
+'𦈎' => '繟',
+'𦈏' => '緍',
+'𦈐' => '縺',
+'𦈑' => '緸',
+'𦈒' => '𦂅',
+'𦈓' => '䋿',
+'𦈔' => '縎',
+'𦈕' => '緰',
+'𦈖' => '䌈',
+'𦈗' => '𦃄',
+'𦈘' => '䌋',
+'𦈙' => '䌰',
+'𦈚' => '縬',
+'𦈛' => '繓',
+'𦈜' => '䌖',
+'𦈝' => '繏',
+'𦈞' => '䌟',
+'𦈟' => '䌝',
+'𦈠' => '䌥',
+'𦈡' => '繻',
+'𦛨' => '朥',
+'𦝼' => '膢',
+'𦟗' => '𦣎',
+'𦨩' => '𦪽',
+'𦰴' => '䕳',
+'𧉞' => '䗿',
+'𧒭' => '𧔥',
+'𧮪' => '詀',
+'𧳕' => '𧳟',
+'𧹑' => '䞈',
+'𧹓' => '𧶔',
+'𧹕' => '䝻',
+'𧹖' => '賟',
+'𧹗' => '贃',
+'𧿈' => '𨇁',
+'𨀱' => '𨄣',
+'𨁴' => '𨅍',
+'𨂺' => '𨈊',
+'𨄄' => '𨈌',
+'𨅫' => '𨇞',
+'𨅬' => '躝',
+'𨉗' => '軉',
+'𨐅' => '軗',
+'𨐆' => '𨊻',
+'𨐇' => '𨏠',
+'𨐈' => '輄',
+'𨐉' => '𨎮',
+'𨐊' => '𨏥',
+'𨑹' => '䢨',
+'𨤰' => '𨤻',
+'𨰾' => '鎷',
+'𨰿' => '釳',
+'𨱀' => '𨥛',
+'𨱁' => '鈠',
+'𨱂' => '鈋',
+'𨱃' => '鈲',
+'𨱄' => '鈯',
+'𨱅' => '鉁',
+'𨱆' => '龯',
+'𨱇' => '銶',
+'𨱈' => '鋉',
+'𨱉' => '鍄',
+'𨱊' => '𨧱',
+'𨱋' => '錂',
+'𨱌' => '鏆',
+'𨱍' => '鎯',
+'𨱎' => '鍮',
+'𨱏' => '鎝',
+'𨱐' => '𨫒',
+'𨱑' => '鐄',
+'𨱒' => '鏉',
+'𨱓' => '鐎',
+'𨱔' => '鐏',
+'𨱕' => '𨮂',
+'𨱖' => '䥩',
+'𨷿' => '䦳',
+'𨸀' => '𨳕',
+'𨸁' => '𨳑',
+'𨸂' => '閍',
+'𨸃' => '閐',
+'𨸄' => '䦘',
+'𨸅' => '𨴗',
+'𨸆' => '𨵩',
+'𨸇' => '𨵸',
+'𨸉' => '𨶀',
+'𨸊' => '𨶏',
+'𨸋' => '𨶲',
+'𨸌' => '𨶮',
+'𨸎' => '𨷲',
+'𨸘' => '𨽏',
+'𨸟' => '䧢',
+'𩏼' => '䪏',
+'𩏽' => '𩏪',
+'𩏾' => '𩎢',
+'𩏿' => '䪘',
+'𩐀' => '䪗',
+'𩖕' => '𩓣',
+'𩖖' => '顃',
+'𩖗' => '䫴',
+'𩙥' => '颰',
+'𩙦' => '𩗀',
+'𩙧' => '𩗡',
+'𩙨' => '𩘹',
+'𩙩' => '𩘀',
+'𩙪' => '颷',
+'𩙫' => '颾',
+'𩙬' => '𩘺',
+'𩙭' => '𩘝',
+'𩙮' => '䬘',
+'𩙯' => '䬝',
+'𩙰' => '𩙈',
+'𩟿' => '𩚛',
+'𩠀' => '𩚥',
+'𩠁' => '𩚵',
+'𩠂' => '𩛆',
+'𩠃' => '𩛩',
+'𩠅' => '𩟐',
+'𩠆' => '𩜦',
+'𩠇' => '䭀',
+'𩠈' => '䭃',
+'𩠉' => '𩜇',
+'𩠊' => '𩜵',
+'𩠋' => '𩝔',
+'𩠌' => '餸',
+'𩠎' => '𩞄',
+'𩠏' => '𩞦',
+'𩠠' => '𩠴',
+'𩧦' => '𩡺',
+'𩧨' => '駎',
+'𩧩' => '𩤊',
+'𩧪' => '䮾',
+'𩧫' => '駚',
+'𩧬' => '𩢡',
+'𩧭' => '䭿',
+'𩧮' => '𩢾',
+'𩧯' => '驋',
+'𩧰' => '䮝',
+'𩧱' => '𩥉',
+'𩧲' => '駧',
+'𩧳' => '𩢸',
+'𩧴' => '駩',
+'𩧵' => '𩢴',
+'𩧶' => '𩣏',
+'𩧺' => '駶',
+'𩧻' => '𩣵',
+'𩧼' => '𩣺',
+'𩧿' => '䮠',
+'𩨀' => '騔',
+'𩨁' => '䮞',
+'𩨃' => '騝',
+'𩨄' => '騪',
+'𩨅' => '𩤸',
+'𩨆' => '𩤙',
+'𩨇' => '䮫',
+'𩨈' => '騟',
+'𩨉' => '𩤲',
+'𩨊' => '騚',
+'𩨋' => '𩥄',
+'𩨌' => '𩥑',
+'𩨍' => '𩥇',
+'𩨎' => '龭',
+'𩨏' => '䮳',
+'𩨐' => '𩧆',
+'𩬣' => '𩭙',
+'𩬤' => '𩰀',
+'𩯒' => '𩯳',
+'𩲒' => '𩳤',
+'𩽹' => '魥',
+'𩽺' => '𩵩',
+'𩽻' => '𩵹',
+'𩽼' => '鯶',
+'𩽽' => '𩶱',
+'𩽾' => '鮟',
+'𩽿' => '𩶰',
+'𩾁' => '鯄',
+'𩾂' => '䲖',
+'𩾃' => '鮸',
+'𩾄' => '𩷰',
+'𩾅' => '𩸃',
+'𩾆' => '𩸦',
+'𩾇' => '鯱',
+'𩾈' => '䱙',
+'𩾊' => '䱬',
+'𩾋' => '䱰',
+'𩾌' => '鱇',
+'𩾎' => '𩽇',
+'𪉂' => '䲰',
+'𪉃' => '鳼',
+'𪉄' => '𩿪',
+'𪉅' => '𪀦',
+'𪉆' => '鴲',
+'𪉈' => '鴜',
+'𪉉' => '𪁈',
+'𪉊' => '鷨',
+'𪉋' => '𪀾',
+'𪉌' => '𪁖',
+'𪉍' => '鵚',
+'𪉎' => '𪂆',
+'𪉏' => '𪃏',
+'𪉐' => '𪃍',
+'𪉑' => '鷔',
+'𪉒' => '𪄕',
+'𪉓' => '𪈼',
+'𪉔' => '𪄆',
+'𪉕' => '𪇳',
+'𪎈' => '䴬',
+'𪎉' => '麲',
+'𪎊' => '麨',
+'𪎋' => '䴴',
+'𪎌' => '麳',
+'𪎍' => '𪋿',
+'𪔭' => '𪔵',
+'𪚏' => '𪘀',
+'𪚐' => '𪘯',
+'𪞝' => '凙',
+'𪡏' => '嗹',
+'𪢮' => '圞',
+'𪨊' => '㞞',
+'𪨗' => '屩',
+'𪻐' => '瑽',
+'𪾢' => '睍',
+'𫁡' => '鴗',
+'𫂈' => '䉬',
+'𫄨' => '絺',
+'𫄸' => '纁',
+'𫌀' => '襀',
+'𫌨' => '覼',
+'𫍙' => '訑',
+'𫍢' => '譊',
+'𫍰' => '諰',
+'𫍲' => '謏',
+'𫏋' => '蹻',
+'𫐄' => '軏',
+'𫐆' => '轣',
+'𫐉' => '軨',
+'𫐐' => '輗',
+'𫐓' => '輮',
+'𫓧' => '鈇',
+'𫓩' => '鏦',
+'𫔎' => '鐍',
+'𫖸' => '願',
+'𫗠' => '餦',
+'𫗦' => '餔',
+'𫗧' => '餗',
+'𫗮' => '餭',
+'𫗴' => '饘',
+'𫘝' => '駃',
+'𫘣' => '駻',
+'𫘤' => '騃',
+'𫘨' => '騠',
+'𫚈' => '鱮',
+'𫚉' => '魟',
+'𫚒' => '鮄',
+'𫚔' => '鮰',
+'𫚕' => '鰤',
+'𫚙' => '鯆',
+'𫛛' => '鳷',
+'𫛞' => '鴃',
+'𫛢' => '鸋',
+'𫛶' => '鶒',
+'𫛸' => '鶗',
+'0出现' => '0出現',
+'0出現' => '0出現',
+'0出線' => '0出線',
+'0出线' => '0出線',
+'0只支持' => '0只支持',
+'0只支援' => '0只支援',
+'0周后' => '0周後',
+'0天后' => '0天後',
+'0年' => '0年',
+'0只' => '0隻',
+'0余' => '0餘',
+'0出' => '0齣',
+'1只支持' => '1只支持',
+'1只支援' => '1只支援',
+'1周后' => '1周後',
+'1天后' => '1天後',
+'1年' => '1年',
+'1只' => '1隻',
+'1余' => '1餘',
+'2只支持' => '2只支持',
+'2只支援' => '2只支援',
+'2周后' => '2周後',
+'2天后' => '2天後',
+'2年' => '2年',
+'2只' => '2隻',
+'2余' => '2餘',
+'3只支持' => '3只支持',
+'3只支援' => '3只支援',
+'3周后' => '3周後',
+'3天后' => '3天後',
+'3年' => '3年',
+'3只' => '3隻',
+'3余' => '3餘',
+'4只支持' => '4只支持',
+'4只支援' => '4只支援',
+'4周后' => '4周後',
+'4天后' => '4天後',
+'4年' => '4年',
+'4只' => '4隻',
+'4余' => '4餘',
+'5只支持' => '5只支持',
+'5只支援' => '5只支援',
+'5周后' => '5周後',
+'5天后' => '5天後',
+'5年' => '5年',
+'5只' => '5隻',
+'5余' => '5餘',
+'6只支持' => '6只支持',
+'6只支援' => '6只支援',
+'6周后' => '6周後',
+'6天后' => '6天後',
+'6年' => '6年',
+'6只' => '6隻',
+'6余' => '6餘',
+'7只支持' => '7只支持',
+'7只支援' => '7只支援',
+'7周后' => '7周後',
+'7天后' => '7天後',
+'7年' => '7年',
+'7只' => '7隻',
+'7余' => '7餘',
+'8只支持' => '8只支持',
+'8只支援' => '8只支援',
+'8周后' => '8周後',
+'8天后' => '8天後',
+'8年' => '8年',
+'8只' => '8隻',
+'8余' => '8餘',
+'9只支持' => '9只支持',
+'9只支援' => '9只支援',
+'9周后' => '9周後',
+'9天后' => '9天後',
+'9年' => '9年',
+'9只' => '9隻',
+'9余' => '9餘',
+'·范' => '·范',
+'’s' => '’s',
+'、面点' => '、麵點',
+'。个中' => '。箇中',
+'〇周后' => '〇周後',
+'〇年' => '〇年',
+'〇只' => '〇隻',
+'〇余' => '〇餘',
+'“' => '「',
+'”' => '」',
+'‘' => '『',
+'’' => '』',
+'一干二净' => '一乾二淨',
+'一伙人' => '一伙人',
+'一伙头' => '一伙頭',
+'一伙食' => '一伙食',
+'一并' => '一併',
+'一个' => '一個',
+'一个准' => '一個準',
+'一划' => '一划',
+'一半只' => '一半只',
+'一吊钱' => '一吊錢',
+'一周后' => '一周後',
+'一地里' => '一地裡',
+'一伙' => '一夥',
+'一天后' => '一天後',
+'一天钟' => '一天鐘',
+'一干人' => '一干人',
+'一干家中' => '一干家中',
+'一干弟兄' => '一干弟兄',
+'一干弟子' => '一干弟子',
+'一干部下' => '一干部下',
+'一年' => '一年',
+'一年里' => '一年裡',
+'一别头' => '一彆頭',
+'一斗斗' => '一斗斗',
+'一树百获' => '一樹百穫',
+'一准' => '一準',
+'一争两丑' => '一爭兩醜',
+'一物克一物' => '一物剋一物',
+'一目了然' => '一目了然',
+'一碗面' => '一碗麵',
+'一扎' => '一紮',
+'一冲' => '一衝',
+'一厘一毫' => '一釐一毫',
+'一锅面' => '一鍋麵',
+'一只' => '一隻',
+'一面食' => '一面食',
+'一余' => '一餘',
+'一发千钧' => '一髮千鈞',
+'一哄而散' => '一鬨而散',
+'一出剧' => '一齣劇',
+'一出喜剧' => '一齣喜劇',
+'一出好戏' => '一齣好戲',
+'一出子' => '一齣子',
+'一出悲剧' => '一齣悲劇',
+'一出戏' => '一齣戲',
+'一出电影' => '一齣電影',
+'丁丁当当' => '丁丁當當',
+'丁丑' => '丁丑',
+'七个' => '七個',
+'七周后' => '七周後',
+'七天后' => '七天後',
+'七年' => '七年',
+'七情六欲' => '七情六慾',
+'七扎' => '七紮',
+'七只' => '七隻',
+'七余' => '七餘',
+'万俟' => '万俟',
+'万旗' => '万旗',
+'三个' => '三個',
+'三周后' => '三周後',
+'三天后' => '三天後',
+'三年' => '三年',
+'三征七辟' => '三徵七辟',
+'三准' => '三準',
+'三扎' => '三紮',
+'三统历' => '三統曆',
+'三统历史' => '三統歷史',
+'三只' => '三隻',
+'三余' => '三餘',
+'三出戏' => '三齣戲',
+'上天里' => '上天里',
+'上梁山' => '上梁山',
+'上梁' => '上樑',
+'上台面' => '上檯面',
+'上签名' => '上簽名',
+'上签字' => '上簽字',
+'上签定' => '上簽定',
+'上签写' => '上簽寫',
+'上签收' => '上簽收',
+'上签发' => '上簽發',
+'上签约' => '上簽約',
+'上签署' => '上簽署',
+'上签订' => '上簽訂',
+'上签' => '上籤',
+'上系上' => '上繫上',
+'上课钟' => '上課鐘',
+'上面糊' => '上面糊',
+'下于' => '下於',
+'下梁' => '下樑',
+'下注解' => '下注解',
+'下签名' => '下簽名',
+'下签字' => '下簽字',
+'下签定' => '下簽定',
+'下签写' => '下簽寫',
+'下签收' => '下簽收',
+'下签发' => '下簽發',
+'下签约' => '下簽約',
+'下签署' => '下簽署',
+'下签订' => '下簽訂',
+'下签' => '下籤',
+'下课钟' => '下課鐘',
+'不干不净' => '不乾不淨',
+'不干胶' => '不乾膠',
+'不克自制' => '不克自制',
+'不加自制' => '不加自制',
+'不占凶吉' => '不占凶吉',
+'不占卜' => '不占卜',
+'不占吉凶' => '不占吉凶',
+'不占算' => '不占算',
+'不只' => '不只',
+'不太准' => '不太準',
+'不好干涉' => '不好干涉',
+'不好干預' => '不好干預',
+'不好干预' => '不好干預',
+'不嫌母丑' => '不嫌母醜',
+'不寒而栗' => '不寒而慄',
+'不吊' => '不弔',
+'不卷' => '不捲',
+'不采' => '不採',
+'不斗胆' => '不斗膽',
+'不斗膽' => '不斗膽',
+'不断发' => '不斷發',
+'不每只' => '不每只',
+'不谷' => '不穀',
+'不托' => '不託',
+'不负所托' => '不負所托',
+'不通吊庆' => '不通弔慶',
+'不丑' => '不醜',
+'不采声' => '不采聲',
+'不采聲' => '不采聲',
+'不锈钢' => '不鏽鋼',
+'不食干腊' => '不食乾腊',
+'不斗' => '不鬥',
+'丑三' => '丑三',
+'丑年' => '丑年',
+'丑日' => '丑日',
+'丑旦' => '丑旦',
+'丑时' => '丑時',
+'丑月' => '丑月',
+'丑表功' => '丑表功',
+'丑角' => '丑角',
+'且于' => '且於',
+'世田谷' => '世田谷',
+'世界杯' => '世界盃',
+'世纪里' => '世紀裡',
+'世纪钟' => '世紀鐘',
+'世纪钟表' => '世紀鐘錶',
+'丢丑' => '丟醜',
+'并曰入淀' => '並曰入澱',
+'并发动' => '並發動',
+'并发展' => '並發展',
+'并发布' => '並發布',
+'并发现' => '並發現',
+'并发表' => '並發表',
+'并行' => '並行',
+'中国国际信托投资公司' => '中國國際信托投資公司',
+'中型钟' => '中型鐘',
+'中型钟表面' => '中型鐘表面',
+'中型钟表' => '中型鐘錶',
+'中型钟面' => '中型鐘面',
+'中境里' => '中境里',
+'中岳' => '中嶽',
+'中庄子' => '中庄子',
+'中文里' => '中文裡',
+'中于' => '中於',
+'中签名' => '中簽名',
+'中签字' => '中簽字',
+'中签定' => '中簽定',
+'中签写' => '中簽寫',
+'中签收' => '中簽收',
+'中签发' => '中簽發',
+'中签约' => '中簽約',
+'中签署' => '中簽署',
+'中签订' => '中簽訂',
+'中签' => '中籤',
+'中风后' => '中風後',
+'丰仪' => '丰儀',
+'丰儀' => '丰儀',
+'丰南' => '丰南',
+'丰姿' => '丰姿',
+'丰容' => '丰容',
+'丰情' => '丰情',
+'丰标' => '丰標',
+'丰标不凡' => '丰標不凡',
+'丰標不凡' => '丰標不凡',
+'丰神' => '丰神',
+'丰茸' => '丰茸',
+'丰采' => '丰采',
+'丰韵' => '丰韻',
+'丰韻' => '丰韻',
+'丹棱' => '丹稜',
+'主仆' => '主僕',
+'主干' => '主幹',
+'主钟差' => '主鐘差',
+'主钟曲线' => '主鐘曲線',
+'乃系' => '乃係',
+'么么唱唱' => '么么唱唱',
+'么九' => '么九',
+'么儿' => '么兒',
+'么半' => '么半',
+'么喝' => '么喝',
+'么女' => '么女',
+'么妹' => '么妹',
+'么子' => '么子',
+'么弟' => '么弟',
+'么正' => '么正',
+'么爷' => '么爺',
+'么雞' => '么雞',
+'么么小丑' => '么麼小丑',
+'之一只' => '之一只',
+'之二只' => '之二只',
+'之八九只' => '之八九只',
+'之征' => '之徵',
+'之托' => '之託',
+'之钟' => '之鐘',
+'之鉴' => '之鑑',
+'之余' => '之餘',
+'乙丑' => '乙丑',
+'九世之仇' => '九世之讎',
+'九个' => '九個',
+'九周后' => '九周後',
+'九天后' => '九天後',
+'九年' => '九年',
+'九谷' => '九穀',
+'九扎' => '九紮',
+'九只' => '九隻',
+'九余' => '九餘',
+'干干' => '乾乾',
+'干干净净' => '乾乾淨淨',
+'干井' => '乾井',
+'干个够' => '乾個夠',
+'干儿' => '乾兒',
+'干冰' => '乾冰',
+'干冷' => '乾冷',
+'干刻版' => '乾刻版',
+'干剥剥' => '乾剝剝',
+'干卦' => '乾卦',
+'干和' => '乾和',
+'干咳' => '乾咳',
+'干咽' => '乾咽',
+'干哥' => '乾哥',
+'干哭' => '乾哭',
+'干唱' => '乾唱',
+'干啼' => '乾啼',
+'干乔' => '乾喬',
+'干呕' => '乾嘔',
+'干哕' => '乾噦',
+'干嚎' => '乾嚎',
+'干回付' => '乾回付',
+'干圆洁净' => '乾圓潔淨',
+'干地' => '乾地',
+'干坞' => '乾塢',
+'干女' => '乾女',
+'干奴才' => '乾奴才',
+'干妹' => '乾妹',
+'干姊' => '乾姊',
+'干姐' => '乾姐',
+'干娘' => '乾娘',
+'干妈' => '乾媽',
+'干子' => '乾子',
+'干季' => '乾季',
+'干尸' => '乾屍',
+'干屎橛' => '乾屎橛',
+'干巴' => '乾巴',
+'干式' => '乾式',
+'干弟' => '乾弟',
+'干急' => '乾急',
+'干性' => '乾性',
+'干打雷' => '乾打雷',
+'干折' => '乾折',
+'干撂台' => '乾撂台',
+'干撇下' => '乾撇下',
+'干擦' => '乾擦',
+'干支剌' => '乾支剌',
+'干支支' => '乾支支',
+'干料' => '乾料',
+'干旱' => '乾旱',
+'干暖' => '乾暖',
+'干材' => '乾材',
+'干村沙' => '乾村沙',
+'干杯' => '乾杯',
+'干果' => '乾果',
+'干枯' => '乾枯',
+'干柴' => '乾柴',
+'干柴烈火' => '乾柴烈火',
+'干梅' => '乾梅',
+'干死' => '乾死',
+'干池' => '乾池',
+'干没' => '乾沒',
+'干洗' => '乾洗',
+'干涸' => '乾涸',
+'干凉' => '乾涼',
+'干净' => '乾淨',
+'干渠' => '乾渠',
+'干渴' => '乾渴',
+'干沟' => '乾溝',
+'干漆' => '乾漆',
+'干涩' => '乾澀',
+'干湿' => '乾濕',
+'干熬' => '乾熬',
+'干热' => '乾熱',
+'干灯盏' => '乾燈盞',
+'干燥' => '乾燥',
+'干爸' => '乾爸',
+'干爹' => '乾爹',
+'干爽' => '乾爽',
+'干片' => '乾片',
+'干物' => '乾物',
+'干生受' => '乾生受',
+'干生子' => '乾生子',
+'干产' => '乾產',
+'干田' => '乾田',
+'干疥' => '乾疥',
+'干瘦' => '乾瘦',
+'干瘪' => '乾癟',
+'干癣' => '乾癬',
+'干瘾' => '乾癮',
+'干白儿' => '乾白兒',
+'干白葡萄酒' => '乾白葡萄酒',
+'干的' => '乾的',
+'干眼' => '乾眼',
+'干瞪眼' => '乾瞪眼',
+'干礼' => '乾禮',
+'干稿' => '乾稿',
+'干笑' => '乾笑',
+'干等' => '乾等',
+'干篾片' => '乾篾片',
+'干粉' => '乾粉',
+'干粮' => '乾糧',
+'干红葡萄酒' => '乾紅葡萄酒',
+'干结' => '乾結',
+'干丝' => '乾絲',
+'干纲' => '乾綱',
+'干绷' => '乾繃',
+'干耗' => '乾耗',
+'干肉片' => '乾肉片',
+'干股' => '乾股',
+'干肥' => '乾肥',
+'干脆' => '乾脆',
+'干脆面' => '乾脆麵',
+'干花' => '乾花',
+'干刍' => '乾芻',
+'干苔' => '乾苔',
+'干茨腊' => '乾茨臘',
+'干茶钱' => '乾茶錢',
+'干草' => '乾草',
+'干菜' => '乾菜',
+'干落' => '乾落',
+'干姜' => '乾薑',
+'干薪' => '乾薪',
+'干虔' => '乾虔',
+'干号' => '乾號',
+'干血浆' => '乾血漿',
+'干衣' => '乾衣',
+'干裂' => '乾裂',
+'干亲' => '乾親',
+'乾象历' => '乾象曆',
+'乾象曆' => '乾象曆',
+'干贝' => '乾貝',
+'干货' => '乾貨',
+'干躁' => '乾躁',
+'干逼' => '乾逼',
+'干酪' => '乾酪',
+'干酵母' => '乾酵母',
+'干醋' => '乾醋',
+'干重' => '乾重',
+'干量' => '乾量',
+'干锅' => '乾鍋',
+'干阿奶' => '乾阿奶',
+'干雷' => '乾雷',
+'干电' => '乾電',
+'干霍乱' => '乾霍亂',
+'干颡' => '乾顙',
+'干台' => '乾颱',
+'干食' => '乾食',
+'干饭' => '乾飯',
+'干馆' => '乾館',
+'干糇' => '乾餱',
+'干馏' => '乾餾',
+'干鱼' => '乾魚',
+'干鲜' => '乾鮮',
+'干面' => '乾麵',
+'乱发生' => '亂發生',
+'乱发脾气' => '亂發脾氣',
+'乱发' => '亂髮',
+'乱哄哄' => '亂鬨鬨',
+'了然后' => '了然後',
+'事有斗巧' => '事有鬥巧',
+'事里' => '事裡',
+'二不棱登' => '二不稜登',
+'二个' => '二個',
+'二只得' => '二只得',
+'二周后' => '二周後',
+'二天后' => '二天後',
+'二年' => '二年',
+'二缶钟惑' => '二缶鐘惑',
+'二老板' => '二老板',
+'二虎相斗' => '二虎相鬥',
+'二里头' => '二里頭',
+'二里頭' => '二里頭',
+'二只' => '二隻',
+'二余' => '二餘',
+'于丹' => '于丹',
+'于于' => '于于',
+'于仁泰' => '于仁泰',
+'于仲文' => '于仲文',
+'于佳卉' => '于佳卉',
+'于来山' => '于來山',
+'于伟国' => '于偉國',
+'于偉國' => '于偉國',
+'于光新' => '于光新',
+'于光远' => '于光遠',
+'于光遠' => '于光遠',
+'于克-兰多县' => '于克-蘭多縣',
+'于克-蘭多縣' => '于克-蘭多縣',
+'于克勒' => '于克勒',
+'于再清' => '于再清',
+'于冕' => '于冕',
+'于冠华' => '于冠華',
+'于凌奎' => '于凌奎',
+'于凌辰' => '于凌辰',
+'于勒' => '于勒',
+'于化虎' => '于化虎',
+'于占元' => '于占元',
+'于友泽' => '于友澤',
+'于台烟' => '于台煙',
+'于台煙' => '于台煙',
+'于右任' => '于右任',
+'于吉' => '于吉',
+'于和伟' => '于和偉',
+'于品海' => '于品海',
+'于国桢' => '于國楨',
+'于國楨' => '于國楨',
+'于国治' => '于國治',
+'于國治' => '于國治',
+'于坚' => '于堅',
+'于堅' => '于堅',
+'于大宝' => '于大寶',
+'于大寶' => '于大寶',
+'于天仁' => '于天仁',
+'于天龙' => '于天龍',
+'于奇库杜克' => '于奇庫杜克',
+'于奇庫杜克' => '于奇庫杜克',
+'于姓' => '于姓',
+'于娜' => '于娜',
+'于娟' => '于娟',
+'于子千' => '于子千',
+'于孔兼' => '于孔兼',
+'于学忠' => '于學忠',
+'于學忠' => '于學忠',
+'于家堡' => '于家堡',
+'于寘' => '于寘',
+'于宝轩' => '于寶軒',
+'于小伟' => '于小偉',
+'于小偉' => '于小偉',
+'于小彤' => '于小彤',
+'于小惠' => '于小惠',
+'于少保' => '于少保',
+'于山' => '于山',
+'于山国' => '于山國',
+'于山國' => '于山國',
+'于帅' => '于帥',
+'于帥' => '于帥',
+'于幼军' => '于幼軍',
+'于幼軍' => '于幼軍',
+'于康震' => '于康震',
+'于广洲' => '于廣洲',
+'于廣洲' => '于廣洲',
+'于式枚' => '于式枚',
+'于从濂' => '于從濂',
+'于從濂' => '于從濂',
+'于德海' => '于德海',
+'于志宁' => '于志寧',
+'于志寧' => '于志寧',
+'于忠肃集' => '于忠肅集',
+'于思' => '于思',
+'于慎行' => '于慎行',
+'于慧' => '于慧',
+'于成龍' => '于成龍',
+'于成龙' => '于成龍',
+'于承惠' => '于承惠',
+'于振' => '于振',
+'于振武' => '于振武',
+'于敏' => '于敏',
+'于敏中' => '于敏中',
+'于斌' => '于斌',
+'于斯塔德' => '于斯塔德',
+'于斯納爾斯貝里' => '于斯納爾斯貝里',
+'于斯纳尔斯贝里' => '于斯納爾斯貝里',
+'于斯达尔' => '于斯達爾',
+'于斯達爾' => '于斯達爾',
+'于明涛' => '于明濤',
+'于明濤' => '于明濤',
+'于是之' => '于是之',
+'于晨楠' => '于晨楠',
+'于晴' => '于晴',
+'于会泳' => '于會泳',
+'于會泳' => '于會泳',
+'于根伟' => '于根偉',
+'于根偉' => '于根偉',
+'于格' => '于格',
+'于枫' => '于楓',
+'于楓' => '于楓',
+'于荣光' => '于榮光',
+'于樂' => '于樂',
+'于树洁' => '于樹潔',
+'于樹潔' => '于樹潔',
+'于欣' => '于欣',
+'于欣源' => '于欣源',
+'于正昇' => '于正昇',
+'于正昌' => '于正昌',
+'于归' => '于歸',
+'于氏' => '于氏',
+'于永波' => '于永波',
+'于江震' => '于江震',
+'于波' => '于波',
+'于洋' => '于洋',
+'于洪区' => '于洪區',
+'于洪區' => '于洪區',
+'于浩威' => '于浩威',
+'于海' => '于海',
+'于海洋' => '于海洋',
+'于湘兰' => '于湘蘭',
+'于湘蘭' => '于湘蘭',
+'于汉超' => '于漢超',
+'于漢超' => '于漢超',
+'于澄' => '于澄',
+'于泽尔' => '于澤爾',
+'于澤爾' => '于澤爾',
+'于涛' => '于濤',
+'于濤' => '于濤',
+'于熙珍' => '于熙珍',
+'于尔岑' => '于爾岑',
+'于爾岑' => '于爾岑',
+'于尔根' => '于爾根',
+'于爾根' => '于爾根',
+'于尔里克' => '于爾里克',
+'于爾里克' => '于爾里克',
+'于特森' => '于特森',
+'于玉立' => '于玉立',
+'于田' => '于田',
+'于禁' => '于禁',
+'于秀敏' => '于秀敏',
+'于立成' => '于立成',
+'于素秋' => '于素秋',
+'于美人' => '于美人',
+'于耘婕' => '于耘婕',
+'于若木' => '于若木',
+'于荫霖' => '于蔭霖',
+'于蔭霖' => '于蔭霖',
+'于衡' => '于衡',
+'于西翰' => '于西翰',
+'于謙' => '于謙',
+'于谦' => '于謙',
+'于谨' => '于謹',
+'于貝爾' => '于貝爾',
+'于贝尔' => '于貝爾',
+'于贈' => '于贈',
+'于赠' => '于贈',
+'于越' => '于越',
+'于軍' => '于軍',
+'于逸堯' => '于逸堯',
+'于道泉' => '于道泉',
+'于远伟' => '于遠偉',
+'于遠偉' => '于遠偉',
+'于都县' => '于都縣',
+'于都縣' => '于都縣',
+'于里察' => '于里察',
+'于阗' => '于闐',
+'于双戈' => '于雙戈',
+'于雙戈' => '于雙戈',
+'于云鹤' => '于雲鶴',
+'于震' => '于震',
+'于震寰' => '于震寰',
+'于震环' => '于震環',
+'于震環' => '于震環',
+'于靖' => '于靖',
+'于非暗' => '于非闇',
+'于非闇' => '于非闇',
+'于韋斯屈萊' => '于韋斯屈萊',
+'于韦斯屈莱' => '于韋斯屈萊',
+'于風政' => '于風政',
+'于风政' => '于風政',
+'于飛' => '于飛',
+'于飞' => '于飛',
+'于余曲折' => '于餘曲折',
+'于鬯' => '于鬯',
+'于魁智' => '于魁智',
+'于凤桐' => '于鳳桐',
+'于鳳桐' => '于鳳桐',
+'于凤至' => '于鳳至',
+'于鳳至' => '于鳳至',
+'于默奥' => '于默奧',
+'于默奧' => '于默奧',
+'云乎' => '云乎',
+'云云' => '云云',
+'云何' => '云何',
+'云敞' => '云敞',
+'云为' => '云為',
+'云為' => '云為',
+'云然' => '云然',
+'云尔' => '云爾',
+'云:' => '云:',
+'五个' => '五個',
+'五周后' => '五周後',
+'五天后' => '五天後',
+'五峰县' => '五峯縣',
+'五岳' => '五嶽',
+'五年' => '五年',
+'五谷' => '五穀',
+'五扎' => '五紮',
+'五脏' => '五臟',
+'五行生克' => '五行生剋',
+'五谷王北街' => '五谷王北街',
+'五谷王南街' => '五谷王南街',
+'五只' => '五隻',
+'五余' => '五餘',
+'井干' => '井幹',
+'井里' => '井裡',
+'亚于' => '亞於',
+'亚美尼亚历' => '亞美尼亞曆',
+'交托' => '交託',
+'交游' => '交遊',
+'交哄' => '交鬨',
+'亦云' => '亦云',
+'京沈' => '京瀋',
+'亮丑' => '亮醜',
+'亮钟' => '亮鐘',
+'人云' => '人云',
+'人如风后入江云' => '人如風後入江雲',
+'人干的' => '人幹的',
+'人欲' => '人慾',
+'人数只' => '人數只',
+'人数里' => '人數裡',
+'人物志' => '人物誌',
+'人生天里' => '人生天里',
+'人发指' => '人髮指',
+'什锦面' => '什錦麵',
+'仁贵' => '仁貴',
+'介胄' => '介冑',
+'他干的' => '他幹的',
+'他钟' => '他鐘',
+'付托' => '付託',
+'仙后' => '仙后',
+'仙后座' => '仙后座',
+'仙游' => '仙遊',
+'代数里' => '代數裡',
+'代理发行' => '代理發行',
+'代码表' => '代碼表',
+'代表' => '代表',
+'以自制' => '以自制',
+'仲裁制' => '仲裁制',
+'件钟' => '件鐘',
+'价川' => '价川',
+'任何钟' => '任何鐘',
+'任何钟表' => '任何鐘錶',
+'任教于' => '任教於',
+'任于' => '任於',
+'仿制' => '仿製',
+'伊于湖底' => '伊于湖底',
+'伊府面' => '伊府麵',
+'伊斯兰教历' => '伊斯蘭教曆',
+'伊斯兰教历史' => '伊斯蘭教歷史',
+'伊斯兰历' => '伊斯蘭曆',
+'伊斯兰历史' => '伊斯蘭歷史',
+'伊东怜' => '伊東怜',
+'伊尔汗历表' => '伊爾汗曆表',
+'伊达里子' => '伊達里子',
+'伊适杰' => '伊適杰',
+'伊里布' => '伊里布',
+'伊郁' => '伊鬱',
+'伏几' => '伏几',
+'伐罪吊民' => '伐罪弔民',
+'休克期' => '休克期',
+'休征' => '休徵',
+'伙头' => '伙頭',
+'伴游' => '伴遊',
+'似于' => '似於',
+'但云' => '但云',
+'位于' => '位於',
+'位准' => '位準',
+'低洼' => '低洼',
+'住扎' => '住紮',
+'占毕' => '佔畢',
+'占头筹' => '佔頭籌',
+'占高枝儿' => '佔高枝兒',
+'何杰' => '何杰',
+'余三勝' => '余三勝',
+'余三胜' => '余三勝',
+'余光中' => '余光中',
+'余光生' => '余光生',
+'余力为' => '余力為',
+'余威德' => '余威德',
+'余子明' => '余子明',
+'余思敏' => '余思敏',
+'佛罗棱萨' => '佛羅稜薩',
+'佛钟' => '佛鐘',
+'作品里' => '作品裡',
+'作准' => '作準',
+'你夸' => '你誇',
+'佣金' => '佣金',
+'佣鈿' => '佣鈿',
+'佣钿' => '佣鈿',
+'佣錢' => '佣錢',
+'佣钱' => '佣錢',
+'佳肴' => '佳肴',
+'佳里鎮' => '佳里鎮',
+'并一不二' => '併一不二',
+'并入' => '併入',
+'并兼' => '併兼',
+'并到' => '併到',
+'并合' => '併合',
+'并名' => '併名',
+'并吞下' => '併吞下',
+'并拢' => '併攏',
+'并案' => '併案',
+'并流' => '併流',
+'并火' => '併火',
+'并为一家' => '併為一家',
+'并为一体' => '併為一體',
+'并叠' => '併疊',
+'并发型模式' => '併發型模式',
+'并发模式' => '併發模式',
+'并发症' => '併發症',
+'并发重症' => '併發重症',
+'并科' => '併科',
+'并网' => '併網',
+'并线' => '併線',
+'并肩子' => '併肩子',
+'并购' => '併購',
+'并骨' => '併骨',
+'使其斗' => '使其鬥',
+'来于' => '來於',
+'侍仆' => '侍僕',
+'供制' => '供製',
+'依依不舍' => '依依不捨',
+'依托' => '依託',
+'侵并' => '侵併',
+'局促' => '侷促',
+'便于' => '便於',
+'系数' => '係數',
+'系为' => '係為',
+'保险柜' => '保險柜',
+'信托贸易' => '信托貿易',
+'信托' => '信託',
+'修杰楷' => '修杰楷',
+'修杰麟' => '修杰麟',
+'修筑前' => '修築前',
+'修筑后' => '修築後',
+'修胡刀' => '修鬍刀',
+'俯冲' => '俯衝',
+'个月里' => '個月裡',
+'个里' => '個裡',
+'个钟' => '個鐘',
+'个钟表' => '個鐘錶',
+'们干的' => '們幹的',
+'幸免' => '倖免',
+'幸存' => '倖存',
+'幸幸' => '倖幸',
+'候复' => '候覆',
+'倚闲' => '倚閑',
+'倛丑' => '倛醜',
+'借鉴' => '借鑑',
+'倦游' => '倦遊',
+'假里' => '假裡',
+'假托' => '假託',
+'假发' => '假髮',
+'偎干' => '偎乾',
+'停停当当' => '停停當當',
+'停征' => '停徵',
+'停制' => '停製',
+'备注' => '備註',
+'家伙' => '傢伙',
+'催并' => '催併',
+'佣仆' => '傭僕',
+'傲游' => '傲遊',
+'傲霜斗雪' => '傲霜鬥雪',
+'传位于四太子' => '傳位于四太子',
+'傳位于四太子' => '傳位于四太子',
+'传于' => '傳於',
+'债累累' => '債纍纍',
+'傻里傻气' => '傻裡傻氣',
+'仅余' => '僅餘',
+'仆人' => '僕人',
+'仆使' => '僕使',
+'仆仆' => '僕僕',
+'仆僮' => '僕僮',
+'仆吏' => '僕吏',
+'仆固怀恩' => '僕固懷恩',
+'仆夫' => '僕夫',
+'仆姑' => '僕姑',
+'仆婢' => '僕婢',
+'仆妇' => '僕婦',
+'仆射' => '僕射',
+'仆少' => '僕少',
+'仆役' => '僕役',
+'仆从' => '僕從',
+'仆憎' => '僕憎',
+'仆欧' => '僕歐',
+'仆程' => '僕程',
+'仆虽罢驽' => '僕雖罷駑',
+'侥幸' => '僥倖',
+'僮仆' => '僮僕',
+'雇主' => '僱主',
+'雇人' => '僱人',
+'雇佣' => '僱傭',
+'雇到' => '僱到',
+'雇工' => '僱工',
+'雇船' => '僱船',
+'雇请' => '僱請',
+'雇车' => '僱車',
+'雇农' => '僱農',
+'仪范' => '儀範',
+'亿个' => '億個',
+'亿周后' => '億周後',
+'亿天后' => '億天後',
+'亿年' => '億年',
+'亿只' => '億隻',
+'亿余' => '億餘',
+'俭仆' => '儉僕',
+'俭朴' => '儉樸',
+'俭确之教' => '儉确之教',
+'儒略改革历' => '儒略改革曆',
+'儒略改革历史' => '儒略改革歷史',
+'儒略历' => '儒略曆',
+'儒略历史' => '儒略歷史',
+'尽尽' => '儘儘',
+'尽先' => '儘先',
+'尽其所有' => '儘其所有',
+'尽可能' => '儘可能',
+'尽快' => '儘快',
+'尽早' => '儘早',
+'尽是' => '儘是',
+'尽管' => '儘管',
+'尽自' => '儘自',
+'尽速' => '儘速',
+'尽量' => '儘量',
+'优于' => '優於',
+'优游' => '優遊',
+'兀术' => '兀朮',
+'元凶' => '元兇',
+'兆个' => '兆個',
+'兆余' => '兆餘',
+'凶刀' => '兇刀',
+'凶器' => '兇器',
+'凶嫌' => '兇嫌',
+'凶巴巴' => '兇巴巴',
+'凶徒' => '兇徒',
+'凶悍' => '兇悍',
+'凶恶' => '兇惡',
+'凶手' => '兇手',
+'凶案' => '兇案',
+'凶枪' => '兇槍',
+'凶横' => '兇橫',
+'凶残' => '兇殘',
+'凶杀' => '兇殺',
+'凶犯' => '兇犯',
+'凶狠' => '兇狠',
+'凶猛' => '兇猛',
+'凶疑' => '兇疑',
+'凶相' => '兇相',
+'凶险' => '兇險',
+'先采' => '先採',
+'光致致' => '光緻緻',
+'克期间' => '克期間',
+'免征' => '免徵',
+'党太尉' => '党太尉',
+'党姓' => '党姓',
+'党家' => '党家',
+'党怀英' => '党懷英',
+'党进' => '党進',
+'党項' => '党項',
+'党项' => '党項',
+'内脏' => '內臟',
+'内制' => '內製',
+'内面包' => '內面包',
+'内面包的' => '內面包的',
+'内斗' => '內鬥',
+'内哄' => '內鬨',
+'全干' => '全乾',
+'两个' => '兩個',
+'两周后' => '兩周後',
+'两天后' => '兩天後',
+'两年' => '兩年',
+'两杆' => '兩桿',
+'两扎' => '兩紮',
+'两虎共斗' => '兩虎共鬥',
+'两只' => '兩隻',
+'两余' => '兩餘',
+'两鼠斗穴' => '兩鼠鬥穴',
+'两出' => '兩齣',
+'八个' => '八個',
+'八周后' => '八周後',
+'八天后' => '八天後',
+'八字胡' => '八字鬍',
+'八年' => '八年',
+'八扎' => '八紮',
+'八蜡' => '八蜡',
+'八只' => '八隻',
+'八余' => '八餘',
+'公仔面' => '公仔麵',
+'公仆' => '公僕',
+'公孙丑' => '公孫丑',
+'公干' => '公幹',
+'公历' => '公曆',
+'公历史' => '公歷史',
+'公里海' => '公里海',
+'公余' => '公餘',
+'六么' => '六么',
+'六个' => '六個',
+'六周后' => '六周後',
+'六天后' => '六天後',
+'六年' => '六年',
+'六楼后座' => '六樓后座',
+'六谷' => '六穀',
+'六扎' => '六紮',
+'六冲' => '六衝',
+'六只' => '六隻',
+'六余' => '六餘',
+'共和历' => '共和曆',
+'共和历史' => '共和歷史',
+'其一只' => '其一只',
+'其二只' => '其二只',
+'其八九只' => '其八九只',
+'其次辟地' => '其次辟地',
+'其余' => '其餘',
+'典范' => '典範',
+'兼并' => '兼并',
+'冉有仆' => '冉有僕',
+'冗余' => '冗餘',
+'冤仇' => '冤讎',
+'冥蒙' => '冥濛',
+'冬山庄' => '冬山庄',
+'冬游' => '冬遊',
+'冰山里' => '冰山裡',
+'冶游' => '冶遊',
+'冷面相' => '冷面相',
+'冷面' => '冷麵',
+'准三后' => '准三后',
+'准保护' => '准保護',
+'准保護' => '准保護',
+'准保释' => '准保釋',
+'准保釋' => '准保釋',
+'凌蒙初' => '凌濛初',
+'凝炼' => '凝鍊',
+'几上' => '几上',
+'几几' => '几几',
+'几凳' => '几凳',
+'几子' => '几子',
+'几旁' => '几旁',
+'几杖' => '几杖',
+'几案' => '几案',
+'几椅' => '几椅',
+'几榻' => '几榻',
+'几净窗明' => '几淨窗明',
+'几筵' => '几筵',
+'几面上' => '几面上',
+'凶征' => '凶徵',
+'凶相毕露' => '凶相畢露',
+'出乖弄丑' => '出乖弄醜',
+'出乖露丑' => '出乖露醜',
+'出征收' => '出征收',
+'出于' => '出於',
+'出游' => '出遊',
+'出丑' => '出醜',
+'函数里' => '函數裡',
+'分别致' => '分别致',
+'分半钟' => '分半鐘',
+'分多钟' => '分多鐘',
+'分子钟' => '分子鐘',
+'分子云' => '分子雲',
+'分布于' => '分布於',
+'分钟' => '分鐘',
+'分钟里' => '分鐘裡',
+'刑余' => '刑餘',
+'划一桨' => '划一槳',
+'划上' => '划上',
+'划下' => '划下',
+'划不來' => '划不來',
+'划不来' => '划不來',
+'划了一会' => '划了一會',
+'划來划去' => '划來划去',
+'划来划去' => '划來划去',
+'划具' => '划具',
+'划到岸' => '划到岸',
+'划到江心' => '划到江心',
+'划动' => '划動',
+'划動' => '划動',
+'划去' => '划去',
+'划子' => '划子',
+'划得來' => '划得來',
+'划得来' => '划得來',
+'划拳' => '划拳',
+'划桨' => '划槳',
+'划槳' => '划槳',
+'划水' => '划水',
+'划着独木舟' => '划着獨木舟',
+'划着竹筏' => '划着竹筏',
+'划着船' => '划着船',
+'划算' => '划算',
+'划船' => '划船',
+'划艇' => '划艇',
+'划行' => '划行',
+'划走' => '划走',
+'划起' => '划起',
+'划进' => '划進',
+'划進' => '划進',
+'划过' => '划過',
+'划過' => '划過',
+'划龍舟' => '划龍舟',
+'划龙舟' => '划龍舟',
+'判断发' => '判斷發',
+'别辟' => '別闢',
+'利欲' => '利慾',
+'利于' => '利於',
+'刮来刮去' => '刮來刮去',
+'刮起来' => '刮起來',
+'刮胡' => '刮鬍',
+'到山里' => '到山裡',
+'制冷机' => '制冷機',
+'制签' => '制籤',
+'制钟' => '制鐘',
+'刻半钟' => '刻半鐘',
+'刻多钟' => '刻多鐘',
+'刻钟' => '刻鐘',
+'剃发' => '剃髮',
+'剃胡' => '剃鬍',
+'剃须' => '剃鬚',
+'削发' => '削髮',
+'削面' => '削麵',
+'克剥' => '剋剝',
+'克扣' => '剋扣',
+'克期' => '剋期',
+'克死' => '剋死',
+'克薄' => '剋薄',
+'前往' => '前往',
+'前面店' => '前面店',
+'剖厘' => '剖釐',
+'刚干' => '剛乾',
+'刚雇' => '剛僱',
+'剥制' => '剝製',
+'剩余' => '剩餘',
+'剪其发' => '剪其髮',
+'剪发' => '剪髮',
+'割舍' => '割捨',
+'创获' => '創穫',
+'创制' => '創製',
+'铲出' => '剷出',
+'铲刈' => '剷刈',
+'铲平' => '剷平',
+'铲除' => '剷除',
+'铲头' => '剷頭',
+'划入' => '劃入',
+'划为' => '劃為',
+'划著' => '劃著名',
+'刘佳怜' => '劉佳怜',
+'劉佳怜' => '劉佳怜',
+'刘芸后' => '劉芸后',
+'力拼' => '力拚',
+'力拼众敌' => '力拼眾敵',
+'力争上游' => '力爭上遊',
+'功勋' => '功勳',
+'加氢精制' => '加氫精制',
+'劣于' => '劣於',
+'助于' => '助於',
+'劫余' => '劫餘',
+'勃郁' => '勃鬱',
+'胜于' => '勝於',
+'勤仆' => '勤僕',
+'勤朴' => '勤樸',
+'勋劳' => '勳勞',
+'勋业' => '勳業',
+'勋爵' => '勳爵',
+'勋章' => '勳章',
+'勋绩' => '勳績',
+'勾干' => '勾幹',
+'勾心斗角' => '勾心鬥角',
+'勾魂荡魄' => '勾魂蕩魄',
+'包括' => '包括',
+'包准' => '包準',
+'包谷' => '包穀',
+'包扎' => '包紮',
+'匏系' => '匏繫',
+'北山索面' => '北山索麵',
+'北仑河' => '北崙河',
+'北岳' => '北嶽',
+'北回线' => '北迴線',
+'北回铁路' => '北迴鐵路',
+'匪干' => '匪幹',
+'匿于' => '匿於',
+'十个' => '十個',
+'十出家' => '十出家',
+'十出击' => '十出擊',
+'十出生' => '十出生',
+'十出祁山' => '十出祁山',
+'十出头' => '十出頭',
+'十周后' => '十周後',
+'十天后' => '十天後',
+'十年' => '十年',
+'十扎' => '十紮',
+'十只' => '十隻',
+'十余' => '十餘',
+'十出' => '十齣',
+'千个' => '千個',
+'千只可' => '千只可',
+'千只够' => '千只夠',
+'千只夠' => '千只夠',
+'千只怕' => '千只怕',
+'千只能' => '千只能',
+'千只足够' => '千只足夠',
+'千只足夠' => '千只足夠',
+'千周后' => '千周後',
+'千天后' => '千天後',
+'千年' => '千年',
+'千扎' => '千紮',
+'千回百折' => '千迴百折',
+'千回百转' => '千迴百轉',
+'千钧一发' => '千鈞一髮',
+'千只' => '千隻',
+'千余' => '千餘',
+'升高后' => '升高後',
+'半制品' => '半制品',
+'半只可' => '半只可',
+'半只够' => '半只夠',
+'半于' => '半於',
+'半只' => '半隻',
+'协防' => '協防',
+'南京钟' => '南京鐘',
+'南京钟表' => '南京鐘錶',
+'南宫适' => '南宮适',
+'南宮适' => '南宮适',
+'南屏晚钟' => '南屏晚鐘',
+'南岳' => '南嶽',
+'南筑' => '南筑',
+'南回线' => '南迴線',
+'南回铁路' => '南迴鐵路',
+'南游' => '南遊',
+'博采' => '博採',
+'博尔术' => '博爾朮',
+'卜云吉' => '卜云吉',
+'占了卜' => '占了卜',
+'印累绶若' => '印纍綬若',
+'印制' => '印製',
+'印鉴' => '印鑑',
+'危于' => '危於',
+'卵与石斗' => '卵與石鬥',
+'卷须' => '卷鬚',
+'厂部' => '厂部',
+'原子钟' => '原子鐘',
+'原钟' => '原鐘',
+'历物之意' => '厤物之意',
+'去山里' => '去山裡',
+'参数只' => '參數只',
+'参数里' => '參數裡',
+'反反复复' => '反反覆覆',
+'反应制得' => '反應製得',
+'反朴' => '反樸',
+'反冲' => '反衝',
+'反复制' => '反複製',
+'反复' => '反覆',
+'反覆' => '反覆',
+'取舍' => '取捨',
+'取决于' => '取決於',
+'受雇' => '受僱',
+'受托' => '受託',
+'丛林里' => '叢林裡',
+'口干' => '口乾',
+'口干冒' => '口干冒',
+'口干政' => '口干政',
+'口干涉' => '口干涉',
+'口干犯' => '口干犯',
+'口干预' => '口干預',
+'口燥唇干' => '口燥唇乾',
+'口腹之欲' => '口腹之慾',
+'口里' => '口裡',
+'口钟' => '口鐘',
+'古人有云' => '古人有云',
+'古书云' => '古書云',
+'古書云' => '古書云',
+'古柯咸' => '古柯鹹',
+'古朴' => '古樸',
+'古語云' => '古語云',
+'古语云' => '古語云',
+'古迹' => '古蹟',
+'古钟' => '古鐘',
+'古钟表' => '古鐘錶',
+'另辟' => '另闢',
+'叩钟' => '叩鐘',
+'只占卜' => '只占卜',
+'只占吉' => '只占吉',
+'只占神问卜' => '只占神問卜',
+'只占算' => '只占算',
+'只影响' => '只影響',
+'只影響' => '只影響',
+'只采' => '只採',
+'只冲' => '只衝',
+'只要功夫深,铁杵磨成锈花针' => '只要功夫深,鐵杵磨成鏽花針',
+'只身上已' => '只身上已',
+'只身上有' => '只身上有',
+'只身上沒' => '只身上沒',
+'只身上没' => '只身上沒',
+'只身上无' => '只身上無',
+'只身上無' => '只身上無',
+'只身上的' => '只身上的',
+'只身世' => '只身世',
+'只身份' => '只身份',
+'只身前' => '只身前',
+'只身受' => '只身受',
+'只身子' => '只身子',
+'只身形' => '只身形',
+'只身影' => '只身影',
+'只身后' => '只身後',
+'只身後' => '只身後',
+'只身心' => '只身心',
+'只身旁' => '只身旁',
+'只身材' => '只身材',
+'只身段' => '只身段',
+'只身为' => '只身為',
+'只身為' => '只身為',
+'只身边' => '只身邊',
+'只身邊' => '只身邊',
+'只身首' => '只身首',
+'只身体' => '只身體',
+'只身體' => '只身體',
+'只身高' => '只身高',
+'只采声' => '只采聲',
+'叮叮当当' => '叮叮噹噹',
+'叮当' => '叮噹',
+'可紧可松' => '可緊可鬆',
+'可自制' => '可自制',
+'可鉴' => '可鑑',
+'台子女' => '台子女',
+'台子孙' => '台子孫',
+'台州' => '台州',
+'台布景' => '台布景',
+'台历史' => '台歷史',
+'台钟' => '台鐘',
+'台风奖' => '台風獎',
+'台风稳健' => '台風穩健',
+'史鉴' => '史鑑',
+'叶不二子' => '叶不二子',
+'叶志穗' => '叶志穗',
+'叶恭弘' => '叶恭弘',
+'叶音' => '叶音',
+'叶韵' => '叶韻',
+'吃板刀面' => '吃板刀麵',
+'吃碗面' => '吃碗麵',
+'吃姜' => '吃薑',
+'吃里扒外' => '吃裡扒外',
+'吃里爬外' => '吃裡爬外',
+'吃面' => '吃麵',
+'各辟' => '各闢',
+'各类钟' => '各類鐘',
+'合伙人' => '合伙人',
+'合并' => '合併',
+'合伙' => '合夥',
+'合府上' => '合府上',
+'合采' => '合採',
+'合历' => '合曆',
+'合历史' => '合歷史',
+'合准' => '合準',
+'吉凶庆吊' => '吉凶慶弔',
+'吉征' => '吉徵',
+'吊钟' => '吊鐘',
+'同人志' => '同人誌',
+'同伙' => '同夥',
+'同于' => '同於',
+'同余' => '同餘',
+'名单于' => '名單於',
+'后冠' => '后冠',
+'后北街' => '后北街',
+'后土' => '后土',
+'后妃' => '后妃',
+'后姓' => '后姓',
+'后安路' => '后安路',
+'后平路' => '后平路',
+'后庄' => '后庄',
+'后座' => '后座',
+'后母戊' => '后母戊',
+'后海湾' => '后海灣',
+'后海灣' => '后海灣',
+'后瑞站' => '后瑞站',
+'后稷' => '后稷',
+'后綜' => '后綜',
+'后羿' => '后羿',
+'后街' => '后街',
+'后角' => '后角',
+'后丰' => '后豐',
+'后豐' => '后豐',
+'后里' => '后里',
+'后发FK型星' => '后髮FK型星',
+'后髮FK型星' => '后髮FK型星',
+'后发座' => '后髮座',
+'后髮座' => '后髮座',
+'后发星系团' => '后髮星系團',
+'后髮星系團' => '后髮星系團',
+'吐哺捉发' => '吐哺捉髮',
+'吐哺握发' => '吐哺握髮',
+'向往来' => '向往來',
+'向往常' => '向往常',
+'向往日' => '向往日',
+'向往时' => '向往時',
+'吞并' => '吞併',
+'吟游' => '吟遊',
+'吧台' => '吧檯',
+'含齿戴发' => '含齒戴髮',
+'吹干' => '吹乾',
+'吹发' => '吹髮',
+'吹胡' => '吹鬍',
+'吾为之范我驰驱' => '吾爲之範我馳驅',
+'吕后' => '呂后',
+'呂后' => '呂后',
+'呆致致' => '呆緻緻',
+'呆里呆气' => '呆裡呆氣',
+'告札' => '告劄',
+'呦喂' => '呦喂',
+'周后' => '周后',
+'周惠后' => '周惠后',
+'周历' => '周曆',
+'周杰' => '周杰',
+'周历史' => '周歷史',
+'周游列国' => '周遊列國',
+'呵喂' => '呵喂',
+'呼吁' => '呼籲',
+'命中注定' => '命中注定',
+'和奸' => '和姦',
+'和制汉' => '和製漢',
+'和制英语' => '和製英語',
+'咎征' => '咎徵',
+'咕咕钟' => '咕咕鐘',
+'咪表' => '咪錶',
+'咬姜呷醋' => '咬薑呷醋',
+'咯当' => '咯噹',
+'哀吊' => '哀弔',
+'哀挽' => '哀輓',
+'品鉴' => '品鑑',
+'哄堂大笑' => '哄堂大笑',
+'員山庄' => '員山庄',
+'哪里' => '哪裡',
+'唁吊' => '唁弔',
+'呗赞' => '唄讚',
+'唇干' => '唇乾',
+'唯一只' => '唯一只',
+'唱游' => '唱遊',
+'唾面自干' => '唾面自乾',
+'唾余' => '唾餘',
+'商历' => '商曆',
+'商标准许' => '商標准許',
+'商历史' => '商歷史',
+'啊喂' => '啊喂',
+'启发式' => '啟發式',
+'啷当' => '啷噹',
+'喂了一声' => '喂了一聲',
+'喂喂' => '喂喂',
+'喂哟' => '喂喲',
+'喂!' => '喂!',
+'喂,' => '喂,',
+'善于' => '善於',
+'喜向往' => '喜向往',
+'喜欢表' => '喜歡錶',
+'喜欢钟' => '喜歡鐘',
+'喜欢钟表' => '喜歡鐘錶',
+'喝干' => '喝乾',
+'喧哗' => '喧譁',
+'喧哄' => '喧鬨',
+'丧钟' => '喪鐘',
+'乔岳' => '喬嶽',
+'单于' => '單于',
+'單于' => '單于',
+'单单于' => '單單於',
+'单干' => '單幹',
+'单打独斗' => '單打獨鬥',
+'哟喂' => '喲喂',
+'喲喂' => '喲喂',
+'嘉谷' => '嘉穀',
+'嘉肴' => '嘉肴',
+'嘴里' => '嘴裡',
+'恶心' => '噁心',
+'噙齿戴发' => '噙齒戴髮',
+'喷洒' => '噴洒',
+'当啷' => '噹啷',
+'当当' => '噹噹',
+'噜苏' => '嚕囌',
+'啮合' => '嚙合',
+'啮齿类' => '嚙齒類',
+'向导' => '嚮導',
+'向往' => '嚮往',
+'向慕' => '嚮慕',
+'向迩' => '嚮邇',
+'严云农' => '嚴云農',
+'严于' => '嚴於',
+'嚼谷' => '嚼穀',
+'啰啰苏苏' => '囉囉囌囌',
+'啰苏' => '囉囌',
+'嘱托' => '囑託',
+'啮虫' => '囓蟲',
+'四个' => '四個',
+'四出征收' => '四出徵收',
+'四分历' => '四分曆',
+'四分历史' => '四分歷史',
+'四周后' => '四周後',
+'四天后' => '四天後',
+'四年' => '四年',
+'四舍五入' => '四捨五入',
+'四舍六入' => '四捨六入',
+'四杆铁笔' => '四桿鐵筆',
+'四扎' => '四紮',
+'四只' => '四隻',
+'四面包' => '四面包',
+'四面钟' => '四面鐘',
+'四余' => '四餘',
+'回佣' => '回佣',
+'回采' => '回採',
+'回旋加速' => '回旋加速',
+'回历' => '回曆',
+'回历史' => '回歷史',
+'回复中' => '回覆中',
+'回复你' => '回覆你',
+'回复帖子' => '回覆帖子',
+'回复意见' => '回覆意見',
+'回复说' => '回覆說',
+'回复邮件' => '回覆郵件',
+'回复:' => '回覆:',
+'回游' => '回遊',
+'因于' => '因於',
+'困倦起来' => '困倦起來',
+'困于' => '困於',
+'困兽之斗' => '困獸之鬥',
+'困兽犹斗' => '困獸猶鬥',
+'困斗' => '困鬥',
+'固定制' => '固定制',
+'固征' => '固徵',
+'囿于' => '囿於',
+'圈梁' => '圈樑',
+'圈里' => '圈裡',
+'国之桢干' => '國之楨榦',
+'国于' => '國於',
+'国历' => '國曆',
+'国历代' => '國歷代',
+'国历任' => '國歷任',
+'国历来' => '國歷來',
+'国历史' => '國歷史',
+'国历届' => '國歷屆',
+'国历经' => '國歷經',
+'国仇' => '國讎',
+'园里' => '園裡',
+'园游会' => '園遊會',
+'图里的' => '圖裡的',
+'图里,' => '圖裡,',
+'图鉴' => '圖鑑',
+'土索面' => '土索麵',
+'土里' => '土裡',
+'土制' => '土製',
+'在制品' => '在制品',
+'在山里' => '在山裡',
+'在于' => '在於',
+'地图里' => '地圖裡',
+'地心历表' => '地心曆表',
+'地方志' => '地方志',
+'地志' => '地誌',
+'地丑德齐' => '地醜德齊',
+'坏于' => '坏於',
+'坐如钟' => '坐如鐘',
+'坐台' => '坐檯',
+'坐钟' => '坐鐘',
+'坑里' => '坑裡',
+'坤范' => '坤範',
+'坦荡' => '坦蕩',
+'坦荡荡' => '坦蕩蕩',
+'坱郁' => '坱鬱',
+'垂于' => '垂於',
+'垂范' => '垂範',
+'垂发' => '垂髮',
+'型范' => '型範',
+'埃及历' => '埃及曆',
+'埃及历史' => '埃及歷史',
+'埃及艳后' => '埃及豔后',
+'埃荣冲' => '埃榮衝',
+'城市里' => '城市裡',
+'城里' => '城裡',
+'埔子里' => '埔子里',
+'埔里社' => '埔裏社',
+'域里' => '域裡',
+'基干' => '基幹',
+'基于' => '基於',
+'基准' => '基準',
+'坚致' => '堅緻',
+'堙淀' => '堙澱',
+'堡子里' => '堡子里',
+'场里' => '場裡',
+'塞耳盗钟' => '塞耳盜鐘',
+'境里' => '境裡',
+'境里程' => '境里程',
+'墓志铭' => '墓志銘',
+'墓志' => '墓誌',
+'增辟' => '增闢',
+'墨子里' => '墨子里',
+'墨斗' => '墨斗',
+'墨沈沈' => '墨沈沈',
+'墨沈' => '墨瀋',
+'垦辟' => '墾闢',
+'压制出' => '壓製出',
+'压制机' => '壓製機',
+'壮游' => '壯遊',
+'壮面' => '壯麵',
+'壹郁' => '壹鬱',
+'壶里' => '壺裡',
+'壸范' => '壼範',
+'壽天里' => '壽天里',
+'寿面' => '壽麵',
+'夏于乔' => '夏于喬',
+'夏于喬' => '夏于喬',
+'夏历' => '夏曆',
+'夏历史' => '夏歷史',
+'夏游' => '夏遊',
+'外强中干' => '外強中乾',
+'外制' => '外製',
+'多半只' => '多半只',
+'多只包括' => '多只包括',
+'多只可' => '多只可',
+'多只含' => '多只含',
+'多只在' => '多只在',
+'多只是' => '多只是',
+'多只会' => '多只會',
+'多只會' => '多只會',
+'多只有' => '多只有',
+'多只比' => '多只比',
+'多只用' => '多只用',
+'多只能' => '多只能',
+'多只限' => '多只限',
+'多只需' => '多只需',
+'多只須' => '多只須',
+'多只须' => '多只須',
+'多周后' => '多周後',
+'多天后' => '多天後',
+'多于' => '多於',
+'多冲' => '多衝',
+'多丑' => '多醜',
+'多只' => '多隻',
+'多余' => '多餘',
+'多出电影' => '多齣電影',
+'夜晚里' => '夜晚裡',
+'夜里' => '夜裡',
+'夜游' => '夜遊',
+'梦里' => '夢裡',
+'梦游' => '夢遊',
+'伙伴' => '夥伴',
+'伙友' => '夥友',
+'伙同' => '夥同',
+'伙众' => '夥眾',
+'伙计' => '夥計',
+'大伙儿' => '大伙兒',
+'大只可' => '大只可',
+'大只在' => '大只在',
+'大只是' => '大只是',
+'大只会' => '大只會',
+'大只有' => '大只有',
+'大只能' => '大只能',
+'大只需' => '大只需',
+'大周后' => '大周后',
+'大型钟' => '大型鐘',
+'大型钟表面' => '大型鐘表面',
+'大型钟表' => '大型鐘錶',
+'大型钟面' => '大型鐘面',
+'大多只' => '大多只',
+'大伙' => '大夥',
+'大干' => '大幹',
+'大批涌到' => '大批湧到',
+'大折儿' => '大摺兒',
+'大明历' => '大明曆',
+'大明历史' => '大明歷史',
+'大历' => '大曆',
+'大本钟' => '大本鐘',
+'大本钟敲' => '大本鐘敲',
+'大历史' => '大歷史',
+'大病初愈' => '大病初癒',
+'大目干连' => '大目乾連',
+'大笨钟' => '大笨鐘',
+'大笨钟敲' => '大笨鐘敲',
+'大蜡' => '大蜡',
+'大衍历' => '大衍曆',
+'大衍历史' => '大衍歷史',
+'大言非夸' => '大言非夸',
+'大夸' => '大誇',
+'大赞' => '大讚',
+'大周折' => '大週摺',
+'大丑' => '大醜',
+'大金发苔' => '大金髮苔',
+'大钟' => '大鐘',
+'大只' => '大隻',
+'大风后' => '大風後',
+'天克地冲' => '天克地衝',
+'天台' => '天台',
+'天后' => '天后',
+'天后宫' => '天后宮',
+'天地志狼' => '天地志狼',
+'天地为范' => '天地為範',
+'天干地支' => '天干地支',
+'天后来' => '天後來',
+'天后半' => '天後半',
+'天后天' => '天後天',
+'天文学钟' => '天文學鐘',
+'天文历表' => '天文曆表',
+'天文钟' => '天文鐘',
+'天历' => '天曆',
+'天历史' => '天歷史',
+'天神之后' => '天神之后',
+'天里' => '天裡',
+'天里昂' => '天里昂',
+'天里村' => '天里村',
+'太仆' => '太僕',
+'太凶' => '太兇',
+'太初历' => '太初曆',
+'太初历史' => '太初歷史',
+'太后' => '太后',
+'太丑' => '太醜',
+'太阁' => '太閤',
+'夸克' => '夸克',
+'夸父' => '夸父',
+'夸特' => '夸特',
+'夸脱' => '夸脫',
+'奇勋' => '奇勳',
+'奇迹' => '奇蹟',
+'奇丑' => '奇醜',
+'奏折' => '奏摺',
+'夺斗' => '奪鬥',
+'奋斗' => '奮鬥',
+'女丑' => '女丑',
+'女仆' => '女僕',
+'奴仆' => '奴僕',
+'奸淫掳掠' => '奸淫擄掠',
+'好家伙' => '好傢夥',
+'好凶' => '好兇',
+'好勇斗狠' => '好勇鬥狠',
+'好斗大' => '好斗大',
+'好斗室' => '好斗室',
+'好斗笠' => '好斗笠',
+'好斗篷' => '好斗篷',
+'好斗胆' => '好斗膽',
+'好斗膽' => '好斗膽',
+'好斗蓬' => '好斗蓬',
+'好于' => '好於',
+'好困' => '好睏',
+'好签' => '好籤',
+'好丑' => '好醜',
+'好斗' => '好鬥',
+'如果干' => '如果幹',
+'如饥似渴' => '如饑似渴',
+'妖后' => '妖后',
+'妖气冲天' => '妖氣衝天',
+'妆台' => '妝檯',
+'始于' => '始於',
+'委托' => '委託',
+'委托书' => '委託書',
+'奸夫' => '姦夫',
+'奸妇' => '姦婦',
+'奸情' => '姦情',
+'奸杀' => '姦殺',
+'奸污' => '姦污',
+'奸淫' => '姦淫',
+'威棱' => '威稜',
+'婢仆' => '婢僕',
+'嫁祸于' => '嫁禍於',
+'嫌凶' => '嫌兇',
+'嫌好道丑' => '嫌好道醜',
+'嫩姜' => '嫩薑',
+'嬉游' => '嬉遊',
+'嬖幸' => '嬖倖',
+'嬴余' => '嬴餘',
+'子之丰兮' => '子之丰兮',
+'子云' => '子云',
+'子里' => '子裡',
+'子里甲' => '子里甲',
+'字汇' => '字彙',
+'字母后' => '字母後',
+'字码表' => '字碼表',
+'字里行间' => '字裡行間',
+'存折' => '存摺',
+'存于' => '存於',
+'孛里海' => '孛里海',
+'孝惠后' => '孝惠后',
+'孙杰' => '孫杰',
+'孫杰' => '孫杰',
+'学家' => '學家',
+'学里' => '學裡',
+'宇宙志' => '宇宙誌',
+'安于' => '安於',
+'安沈铁路' => '安瀋鐵路',
+'宋王台' => '宋王臺',
+'宗周钟' => '宗周鐘',
+'官不怕大只怕管' => '官不怕大只怕管',
+'官地为采' => '官地為寀',
+'官历' => '官曆',
+'官历史' => '官歷史',
+'定于' => '定於',
+'定准' => '定準',
+'定制' => '定製',
+'宜云' => '宜云',
+'宣泄' => '宣洩',
+'宦游' => '宦遊',
+'宫里' => '宮裡',
+'害于' => '害於',
+'宴游' => '宴遊',
+'家仆' => '家僕',
+'家里' => '家裡',
+'家丑' => '家醜',
+'容于' => '容於',
+'容范' => '容範',
+'宿舍' => '宿舍',
+'寄托在' => '寄托在',
+'寄托' => '寄託',
+'密致' => '密緻',
+'寇准' => '寇準',
+'寇仇' => '寇讎',
+'富余' => '富餘',
+'寒栗' => '寒慄',
+'寒于' => '寒於',
+'寓于' => '寓於',
+'寡欲' => '寡慾',
+'实干' => '實幹',
+'实累累' => '實纍纍',
+'写字台' => '寫字檯',
+'宽于' => '寬於',
+'宽余' => '寬餘',
+'宽松' => '寬鬆',
+'宽松松' => '寬鬆鬆',
+'寮采' => '寮寀',
+'寶山庄' => '寶山庄',
+'宝历' => '寶曆',
+'寶曆' => '寶曆',
+'宝历史' => '寶歷史',
+'宝里宝气' => '寶裡寶氣',
+'宝鉴' => '寶鑑',
+'寸发千金' => '寸髮千金',
+'寺钟' => '寺鐘',
+'封后' => '封后',
+'封为后' => '封為后',
+'封面里' => '封面裡',
+'射雕' => '射鵰',
+'专向往' => '專向往',
+'专辑里' => '專輯裡',
+'尊后' => '尊后',
+'对不准' => '對不準',
+'对折' => '對摺',
+'对于' => '對於',
+'对准' => '對準',
+'对准表' => '對準錶',
+'对准钟' => '對準鐘',
+'对准钟表' => '對準鐘錶',
+'对着干' => '對着幹',
+'对华发' => '對華發',
+'对表中' => '對表中',
+'对表扬' => '對表揚',
+'对表明' => '對表明',
+'对表演' => '對表演',
+'对表现' => '對表現',
+'对表达' => '對表達',
+'导游' => '導遊',
+'小丑' => '小丑',
+'小井里' => '小井里',
+'小价' => '小价',
+'小仆' => '小僕',
+'小几' => '小几',
+'小只可' => '小只可',
+'小只在' => '小只在',
+'小只是' => '小只是',
+'小只会' => '小只會',
+'小只有' => '小只有',
+'小只能' => '小只能',
+'小只需' => '小只需',
+'小周后' => '小周后',
+'小型钟' => '小型鐘',
+'小型钟表面' => '小型鐘表面',
+'小型钟表' => '小型鐘錶',
+'小型钟面' => '小型鐘面',
+'小时里' => '小時裡',
+'小米面' => '小米麵',
+'小只' => '小隻',
+'少采' => '少採',
+'就范' => '就範',
+'就里' => '就裡',
+'尸位素餐' => '尸位素餐',
+'尸佼' => '尸佼',
+'尸利' => '尸利',
+'尸子' => '尸子',
+'尸居余气' => '尸居餘氣',
+'尸弃佛' => '尸棄佛',
+'尸祝' => '尸祝',
+'尸禄' => '尸祿',
+'尸罗精舍' => '尸羅精舍',
+'尸羅精舍' => '尸羅精舍',
+'尸臣' => '尸臣',
+'尸谏' => '尸諫',
+'尸魂界' => '尸魂界',
+'尸鸠' => '尸鳩',
+'局促不安' => '局促不安',
+'局里' => '局裡',
+'屋梁' => '屋樑',
+'屋里' => '屋裡',
+'屏风后' => '屏風後',
+'屑于' => '屑於',
+'屡顾尔仆' => '屢顧爾僕',
+'属于' => '屬於',
+'属托' => '屬託',
+'屯扎' => '屯紮',
+'屯里' => '屯裡',
+'山仔后' => '山仔后',
+'山崩钟应' => '山崩鐘應',
+'山岳' => '山嶽',
+'山梁' => '山樑',
+'山棱' => '山稜',
+'山羊胡' => '山羊鬍',
+'山里有' => '山裡有',
+'山里的' => '山裡的',
+'山谷' => '山谷',
+'山重水复' => '山重水複',
+'岫岩' => '岫巖',
+'岱岳' => '岱嶽',
+'峇里海' => '峇里海',
+'峰回' => '峰迴',
+'峻岭' => '峻岭',
+'崑剧' => '崑劇',
+'昆剧' => '崑劇',
+'崑山' => '崑山',
+'昆山' => '崑山',
+'昆冈' => '崑岡',
+'昆仑' => '崑崙',
+'昆嵛' => '崑嵛',
+'昆承湖' => '崑承湖',
+'崑曲' => '崑曲',
+'昆曲' => '崑曲',
+'崑腔' => '崑腔',
+'昆腔' => '崑腔',
+'崑苏' => '崑蘇',
+'昆苏' => '崑蘇',
+'崑调' => '崑調',
+'昆调' => '崑調',
+'崖广' => '崖广',
+'嶒棱' => '嶒稜',
+'岳岳' => '嶽嶽',
+'岳麓' => '嶽麓',
+'川谷' => '川穀',
+'巡回医疗' => '巡回醫療',
+'巡回' => '巡迴',
+'巡游' => '巡遊',
+'工作台' => '工作檯',
+'左冲右突' => '左衝右突',
+'巧干' => '巧幹',
+'巧历' => '巧曆',
+'巧历史' => '巧歷史',
+'巨制' => '巨製',
+'差之毫厘' => '差之毫厘',
+'差于' => '差於',
+'己丑' => '己丑',
+'已占卜' => '已占卜',
+'已占算' => '已占算',
+'巴尔干' => '巴爾幹',
+'巷里' => '巷裡',
+'市里的' => '市裡的',
+'布谷' => '布穀',
+'布谷鸟' => '布穀鳥',
+'布谷鸟钟' => '布穀鳥鐘',
+'布里海' => '布里海',
+'希伯来历' => '希伯來曆',
+'希伯来历史' => '希伯來歷史',
+'帘子' => '帘子',
+'帘布' => '帘布',
+'帝后台' => '帝后臺',
+'师范' => '師範',
+'席卷' => '席捲',
+'带征' => '帶徵',
+'带余' => '帶餘',
+'带发修行' => '帶髮修行',
+'幅图里' => '幅圖裡',
+'干系' => '干係',
+'平平当当' => '平平當當',
+'平准' => '平準',
+'年代里' => '年代裡',
+'年历' => '年曆',
+'年历史' => '年歷史',
+'年谷' => '年穀',
+'年里' => '年裡',
+'年鉴' => '年鑑',
+'并力' => '并力',
+'并吞' => '并吞',
+'并州' => '并州',
+'并日而食' => '并日而食',
+'并迭' => '并迭',
+'幸免于难' => '幸免於難',
+'幸于' => '幸於',
+'幸运胡' => '幸運鬍',
+'干上' => '幹上',
+'干下去' => '幹下去',
+'干不了' => '幹不了',
+'干不成' => '幹不成',
+'干了' => '幹了',
+'干事' => '幹事',
+'干些' => '幹些',
+'干什么' => '幹什麼',
+'干仗' => '幹仗',
+'干个' => '幹個',
+'干劲' => '幹勁',
+'干吏' => '幹吏',
+'干员' => '幹員',
+'干啥' => '幹啥',
+'干吗' => '幹嗎',
+'干嘛' => '幹嘛',
+'干坏事' => '幹壞事',
+'干大事' => '幹大事',
+'干完' => '幹完',
+'干家' => '幹家',
+'干得' => '幹得',
+'干性油' => '幹性油',
+'干才' => '幹才',
+'干掉' => '幹掉',
+'干探' => '幹探',
+'干校' => '幹校',
+'干活' => '幹活',
+'干流' => '幹流',
+'干济' => '幹濟',
+'干营生' => '幹營生',
+'干父之蛊' => '幹父之蠱',
+'干球温度' => '幹球溫度',
+'干甚么' => '幹甚麼',
+'干略' => '幹略',
+'干当' => '幹當',
+'干的事' => '幹的事',
+'干的好事' => '幹的好事',
+'干细胞' => '幹細胞',
+'干线' => '幹線',
+'干练' => '幹練',
+'干缺' => '幹缺',
+'干群关系' => '幹群關係',
+'干蛊' => '幹蠱',
+'干警' => '幹警',
+'干起来' => '幹起來',
+'干路' => '幹路',
+'干办' => '幹辦',
+'干这' => '幹這',
+'干道' => '幹道',
+'干部' => '幹部',
+'干革命' => '幹革命',
+'干头' => '幹頭',
+'干么' => '幹麼',
+'几个' => '幾個',
+'几周后' => '幾周後',
+'几天后' => '幾天後',
+'几进几出' => '幾進幾出',
+'几只' => '幾隻',
+'几出' => '幾齣',
+'广部' => '广部',
+'庄司' => '庄司',
+'床席' => '床蓆',
+'店里' => '店裡',
+'府干卿' => '府干卿',
+'府干扰' => '府干擾',
+'府干擾' => '府干擾',
+'府干政' => '府干政',
+'府干涉' => '府干涉',
+'府干犯' => '府干犯',
+'府干預' => '府干預',
+'府干预' => '府干預',
+'府干' => '府幹',
+'座钟' => '座鐘',
+'廍子里' => '廍子里',
+'廓子里' => '廓子里',
+'厨余' => '廚餘',
+'厮斗' => '廝鬥',
+'庙里' => '廟裡',
+'废后' => '廢后',
+'廢后' => '廢后',
+'广征' => '廣徵',
+'广舍' => '廣捨',
+'广播里' => '廣播裡',
+'延历' => '延曆',
+'建于' => '建於',
+'建筑前' => '建築前',
+'建筑后' => '建築後',
+'弄干' => '弄乾',
+'弄丑' => '弄醜',
+'弄脏胸' => '弄髒胸',
+'弄松' => '弄鬆',
+'弄鬼吊猴' => '弄鬼弔猴',
+'吊卷' => '弔卷',
+'吊取' => '弔取',
+'吊古' => '弔古',
+'吊唁' => '弔唁',
+'吊问' => '弔問',
+'吊喉' => '弔喉',
+'吊丧' => '弔喪',
+'吊喭' => '弔喭',
+'吊奠' => '弔奠',
+'吊孝' => '弔孝',
+'吊客' => '弔客',
+'吊宴' => '弔宴',
+'吊带' => '弔帶',
+'吊影' => '弔影',
+'吊恤' => '弔恤',
+'吊慰' => '弔慰',
+'吊扣' => '弔扣',
+'吊拷' => '弔拷',
+'吊挂' => '弔掛',
+'吊撒' => '弔撒',
+'吊文' => '弔文',
+'吊旗' => '弔旗',
+'吊死' => '弔死',
+'吊民' => '弔民',
+'吊祭' => '弔祭',
+'吊纸' => '弔紙',
+'吊者大悦' => '弔者大悅',
+'吊腰撒跨' => '弔腰撒跨',
+'吊脚儿事' => '弔腳兒事',
+'吊膀子' => '弔膀子',
+'吊词' => '弔詞',
+'吊诡' => '弔詭',
+'吊谎' => '弔謊',
+'吊贺迎送' => '弔賀迎送',
+'吊头' => '弔頭',
+'吊鹤' => '弔鶴',
+'引斗' => '引鬥',
+'弘历' => '弘曆',
+'弘历史' => '弘歷史',
+'弱于' => '弱於',
+'弱水三千只取一瓢' => '弱水三千只取一瓢',
+'张三丰' => '張三丰',
+'張三丰' => '張三丰',
+'张勋' => '張勳',
+'张杰' => '張杰',
+'張杰' => '張杰',
+'张乐于张徐' => '張樂于張徐',
+'强制作用' => '強制作用',
+'强奸' => '強姦',
+'强干' => '強幹',
+'强于' => '強於',
+'别口气' => '彆口氣',
+'别强' => '彆強',
+'别扭' => '彆扭',
+'别拗' => '彆拗',
+'别气' => '彆氣',
+'弹子台' => '彈子檯',
+'弹珠台' => '彈珠檯',
+'汇刊' => '彙刊',
+'汇算' => '彙算',
+'汇纂' => '彙纂',
+'汇辑' => '彙輯',
+'形单影只' => '形單影隻',
+'形于' => '形於',
+'彭于晏' => '彭于晏',
+'影后' => '影后',
+'影相吊' => '影相弔',
+'役于' => '役於',
+'往复式' => '往復式',
+'往日无仇' => '往日無讎',
+'往里' => '往裡',
+'待复' => '待覆',
+'很干' => '很乾',
+'很凶' => '很兇',
+'很准' => '很準',
+'很丑' => '很醜',
+'很松' => '很鬆',
+'律历志' => '律曆志',
+'后印' => '後印',
+'后台老板' => '後台老板',
+'后天' => '後天',
+'後庄' => '後庄',
+'后面店' => '後面店',
+'徐干' => '徐幹',
+'徒杠' => '徒杠',
+'徒托空言' => '徒託空言',
+'得到回复' => '得到回覆',
+'得力干将' => '得力幹將',
+'从仆' => '從僕',
+'从图里' => '從圖裡',
+'从山里' => '從山裡',
+'从于' => '從於',
+'从里到外' => '從裡到外',
+'从里向外' => '從裡向外',
+'御岳山' => '御嶽山',
+'御制' => '御製',
+'复始' => '復始',
+'复活节历表' => '復活節曆表',
+'复苏' => '復甦',
+'征人' => '徵人',
+'征令' => '徵令',
+'征信' => '徵信',
+'征候' => '徵候',
+'征兆' => '徵兆',
+'征兵' => '徵兵',
+'征到' => '徵到',
+'征募' => '徵募',
+'征友' => '徵友',
+'征召' => '徵召',
+'征名责实' => '徵名責實',
+'征吏' => '徵吏',
+'征咎' => '徵咎',
+'征启' => '徵啟',
+'征士' => '徵士',
+'征婚' => '徵婚',
+'征实' => '徵實',
+'征庸' => '徵庸',
+'征引' => '徵引',
+'征得' => '徵得',
+'征怪' => '徵怪',
+'征才' => '徵才',
+'征招' => '徵招',
+'征收' => '徵收',
+'征效' => '徵效',
+'征文' => '徵文',
+'征求' => '徵求',
+'征状' => '徵狀',
+'征用' => '徵用',
+'征发' => '徵發',
+'征税' => '徵稅',
+'征稿' => '徵稿',
+'征答' => '徵答',
+'征结' => '徵結',
+'征圣' => '徵聖',
+'征聘' => '徵聘',
+'征训' => '徵訓',
+'征询' => '徵詢',
+'征调' => '徵調',
+'征象' => '徵象',
+'征购' => '徵購',
+'征迹' => '徵跡',
+'征车' => '徵車',
+'征辟' => '徵辟',
+'征逐' => '徵逐',
+'征选' => '徵選',
+'征集' => '徵集',
+'征风召雨' => '徵風召雨',
+'征验' => '徵驗',
+'心愿' => '心愿',
+'心于' => '心於',
+'心理' => '心理',
+'心细如发' => '心細如髮',
+'心系一' => '心繫一',
+'心系世' => '心繫世',
+'心系中' => '心繫中',
+'心系乔' => '心繫乔',
+'心系五' => '心繫五',
+'心系京' => '心繫京',
+'心系人' => '心繫人',
+'心系他' => '心繫他',
+'心系伊' => '心繫伊',
+'心系何' => '心繫何',
+'心系你' => '心繫你',
+'心系健' => '心繫健',
+'心系传' => '心繫傳',
+'心系全' => '心繫全',
+'心系两' => '心繫兩',
+'心系农' => '心繫农',
+'心系功' => '心繫功',
+'心系动' => '心繫動',
+'心系募' => '心繫募',
+'心系北' => '心繫北',
+'心系十' => '心繫十',
+'心系千' => '心繫千',
+'心系南' => '心繫南',
+'心系台' => '心繫台',
+'心系和' => '心繫和',
+'心系哪' => '心繫哪',
+'心系唐' => '心繫唐',
+'心系嘱' => '心繫囑',
+'心系四' => '心繫四',
+'心系困' => '心繫困',
+'心系国' => '心繫國',
+'心系在' => '心繫在',
+'心系地' => '心繫地',
+'心系大' => '心繫大',
+'心系天' => '心繫天',
+'心系夫' => '心繫夫',
+'心系奥' => '心繫奧',
+'心系女' => '心繫女',
+'心系她' => '心繫她',
+'心系妻' => '心繫妻',
+'心系妇' => '心繫婦',
+'心系子' => '心繫子',
+'心系它' => '心繫它',
+'心系宣' => '心繫宣',
+'心系家' => '心繫家',
+'心系富' => '心繫富',
+'心系小' => '心繫小',
+'心系山' => '心繫山',
+'心系川' => '心繫川',
+'心系幼' => '心繫幼',
+'心系广' => '心繫廣',
+'心系彼' => '心繫彼',
+'心系德' => '心繫德',
+'心系您' => '心繫您',
+'心系慈' => '心繫慈',
+'心系我' => '心繫我',
+'心系摩' => '心繫摩',
+'心系故' => '心繫故',
+'心系新' => '心繫新',
+'心系日' => '心繫日',
+'心系昌' => '心繫昌',
+'心系晓' => '心繫曉',
+'心系曼' => '心繫曼',
+'心系东' => '心繫東',
+'心系林' => '心繫林',
+'心系母' => '心繫母',
+'心系民' => '心繫民',
+'心系江' => '心繫江',
+'心系汶' => '心繫汶',
+'心系沈' => '心繫沈',
+'心系沙' => '心繫沙',
+'心系泰' => '心繫泰',
+'心系浙' => '心繫浙',
+'心系港' => '心繫港',
+'心系湖' => '心繫湖',
+'心系澳' => '心繫澳',
+'心系灾' => '心繫災',
+'心系父' => '心繫父',
+'心系生' => '心繫生',
+'心系病' => '心繫病',
+'心系百' => '心繫百',
+'心系的' => '心繫的',
+'心系众' => '心繫眾',
+'心系社' => '心繫社',
+'心系祖' => '心繫祖',
+'心系神' => '心繫神',
+'心系红' => '心繫紅',
+'心系美' => '心繫美',
+'心系群' => '心繫群',
+'心系老' => '心繫老',
+'心系舞' => '心繫舞',
+'心系英' => '心繫英',
+'心系茶' => '心繫茶',
+'心系万' => '心繫萬',
+'心系兰' => '心繫蘭',
+'心系西' => '心繫西',
+'心系贫' => '心繫貧',
+'心系输' => '心繫輸',
+'心系近' => '心繫近',
+'心系远' => '心繫遠',
+'心系选' => '心繫選',
+'心系重' => '心繫重',
+'心系长' => '心繫長',
+'心系阮' => '心繫阮',
+'心系震' => '心繫震',
+'心系非' => '心繫非',
+'心系风' => '心繫風',
+'心系香' => '心繫香',
+'心系高' => '心繫高',
+'心系麦' => '心繫麥',
+'心系黄' => '心繫黃',
+'心脏' => '心臟',
+'心脏痳痹' => '心臟痲痺',
+'心荡' => '心蕩',
+'心里面' => '心裏面',
+'心里' => '心裡',
+'心长发短' => '心長髮短',
+'心余' => '心餘',
+'必须' => '必須',
+'忙里' => '忙裡',
+'忙里偷闲' => '忙裡偷閒',
+'忠人之托' => '忠人之托',
+'忠仆' => '忠僕',
+'忠于' => '忠於',
+'快快当当' => '快快當當',
+'快冲' => '快衝',
+'怎么干' => '怎麼幹',
+'怒于' => '怒於',
+'怒气冲天' => '怒氣衝天',
+'怒火冲天' => '怒火衝天',
+'怒发冲冠' => '怒髮衝冠',
+'思如泉涌' => '思如泉湧',
+'怠于' => '怠於',
+'急于' => '急於',
+'急冲而下' => '急衝而下',
+'性征' => '性徵',
+'性欲' => '性慾',
+'怨气冲天' => '怨氣衝天',
+'怪里怪气' => '怪裡怪氣',
+'怫郁' => '怫鬱',
+'恂栗' => '恂慄',
+'恒基' => '恒基',
+'恒生' => '恒生',
+'恒隆' => '恒隆',
+'恕乏价催' => '恕乏价催',
+'息交绝游' => '息交絕遊',
+'息谷' => '息穀',
+'悒郁' => '悒鬱',
+'悠悠荡荡' => '悠悠蕩蕩',
+'悠荡' => '悠蕩',
+'悠游' => '悠遊',
+'悲凄' => '悲悽',
+'悲筑' => '悲筑',
+'悲郁' => '悲鬱',
+'悸栗' => '悸慄',
+'凄厉' => '悽厲',
+'凄怨' => '悽怨',
+'凄惋' => '悽惋',
+'凄惶' => '悽惶',
+'凄恻' => '悽惻',
+'凄怆' => '悽愴',
+'凄惨' => '悽慘',
+'凄戾' => '悽戾',
+'凄然' => '悽然',
+'凄美' => '悽美',
+'凄苦' => '悽苦',
+'凄酸' => '悽酸',
+'情欲' => '情慾',
+'惇朴' => '惇樸',
+'惠文后' => '惠文后',
+'恶仆' => '惡僕',
+'恶直丑正' => '惡直醜正',
+'恶斗' => '惡鬥',
+'惴栗' => '惴慄',
+'意大利面' => '意大利麵',
+'爱困' => '愛睏',
+'感于' => '感於',
+'愿朴' => '愿樸',
+'愿樸' => '愿樸',
+'愿而恭' => '愿而恭',
+'栗冽' => '慄冽',
+'栗栗' => '慄慄',
+'慈溪' => '慈谿',
+'慌里慌张' => '慌裡慌張',
+'惨淡' => '慘澹',
+'庆吊' => '慶弔',
+'庆历' => '慶曆',
+'庆历史' => '慶歷史',
+'欲令智昏' => '慾令智昏',
+'欲壑难填' => '慾壑難填',
+'欲念' => '慾念',
+'欲海' => '慾海',
+'欲火' => '慾火',
+'欲障' => '慾障',
+'忧郁' => '憂鬱',
+'凭几' => '憑几',
+'凭吊' => '憑弔',
+'凭折' => '憑摺',
+'凭准' => '憑準',
+'凭借' => '憑藉',
+'凭闲' => '憑閑',
+'宪法里' => '憲法裡',
+'恳托' => '懇託',
+'懈松' => '懈鬆',
+'应制得' => '應制得',
+'應制得' => '應制得',
+'应征' => '應徵',
+'应钟' => '應鐘',
+'懔栗' => '懍慄',
+'懞懞懂懂' => '懞懞懂懂',
+'懞直' => '懞直',
+'惩忿窒欲' => '懲忿窒欲',
+'怀里' => '懷裡',
+'怀钟' => '懷鐘',
+'悬挂' => '懸掛',
+'悬梁' => '懸樑',
+'悬臂梁' => '懸臂樑',
+'悬钟' => '懸鐘',
+'懿范' => '懿範',
+'恋恋不舍' => '戀戀不捨',
+'成于' => '成於',
+'成于思' => '成於思',
+'戬谷' => '戩穀',
+'截发' => '截髮',
+'战天斗地' => '戰天鬥地',
+'战栗' => '戰慄',
+'战于' => '戰於',
+'战斗' => '戰鬥',
+'戏里' => '戲裡',
+'戲院里' => '戲院里',
+'戴表元' => '戴表元',
+'戴发含齿' => '戴髮含齒',
+'房里' => '房裡',
+'所云' => '所云',
+'所云云' => '所云云',
+'所占卜' => '所占卜',
+'所占星' => '所占星',
+'所占算' => '所占算',
+'所托' => '所託',
+'扁拟谷盗虫' => '扁擬穀盜蟲',
+'手塚治虫' => '手塚治虫',
+'手折' => '手摺',
+'手表态' => '手表態',
+'手表態' => '手表態',
+'手表明' => '手表明',
+'手表决' => '手表決',
+'手表決' => '手表決',
+'手表演' => '手表演',
+'手表现' => '手表現',
+'手表現' => '手表現',
+'手表示' => '手表示',
+'手表达' => '手表達',
+'手表達' => '手表達',
+'手表露' => '手表露',
+'手表面' => '手表面',
+'手里剑' => '手裏劍',
+'手里' => '手裡',
+'手游' => '手遊',
+'手表' => '手錶',
+'手链' => '手鍊',
+'手松' => '手鬆',
+'才干休' => '才干休',
+'才干戈' => '才干戈',
+'才干扰' => '才干擾',
+'才干政' => '才干政',
+'才干涉' => '才干涉',
+'才干预' => '才干預',
+'才干' => '才幹',
+'扎好底子' => '扎好底子',
+'扎好根' => '扎好根',
+'扑作教刑' => '扑作教刑',
+'扑打' => '扑打',
+'扑挞' => '扑撻',
+'打干哕' => '打乾噦',
+'打出吊入' => '打出弔入',
+'打卡钟' => '打卡鐘',
+'打吨' => '打吨',
+'打干' => '打幹',
+'打拼' => '打拚',
+'打断发' => '打斷發',
+'打卤' => '打滷',
+'打谷' => '打穀',
+'打钟' => '打鐘',
+'打风后' => '打風後',
+'打斗' => '打鬥',
+'托管国' => '托管國',
+'扛大梁' => '扛大樑',
+'扯面' => '扯麵',
+'扶余' => '扶餘',
+'批准的' => '批准的',
+'批准确定' => '批准確定',
+'批复' => '批覆',
+'批注' => '批註',
+'批斗' => '批鬥',
+'抑制' => '抑制',
+'抑郁' => '抑鬱',
+'抓奸' => '抓姦',
+'抓斗' => '抓鬥',
+'抗御' => '抗禦',
+'折向往' => '折向往',
+'折子戏' => '折子戲',
+'折子戲' => '折子戲',
+'折戟沈河' => '折戟沈河',
+'折冲' => '折衝',
+'披榛采兰' => '披榛採蘭',
+'披头散发' => '披頭散髮',
+'披发' => '披髮',
+'抱朴而长吟兮' => '抱朴而長吟兮',
+'抱素怀朴' => '抱素懷樸',
+'抵御' => '抵禦',
+'抹干' => '抹乾',
+'抽公签' => '抽公籤',
+'抽签' => '抽籤',
+'抿发' => '抿髮',
+'拂钟无声' => '拂鐘無聲',
+'拆伙' => '拆夥',
+'拈须' => '拈鬚',
+'拉克施尔德钟' => '拉克施爾德鐘',
+'拉纤' => '拉縴',
+'拉面上' => '拉面上',
+'拉面具' => '拉面具',
+'拉面前' => '拉面前',
+'拉面巾' => '拉面巾',
+'拉面无' => '拉面無',
+'拉面皮' => '拉面皮',
+'拉面罩' => '拉面罩',
+'拉面色' => '拉面色',
+'拉面部' => '拉面部',
+'拉面' => '拉麵',
+'拒人于' => '拒人於',
+'拒于' => '拒於',
+'拓朴' => '拓樸',
+'拔发' => '拔髮',
+'拔须' => '拔鬚',
+'拗别' => '拗彆',
+'拘于' => '拘於',
+'拙于' => '拙於',
+'拙朴' => '拙樸',
+'拼却' => '拚卻',
+'拼命' => '拚命',
+'拼舍' => '拚捨',
+'拼死' => '拚死',
+'拼生尽死' => '拚生盡死',
+'拼绝' => '拚絕',
+'拼老命' => '拚老命',
+'拼斗' => '拚鬥',
+'拜托' => '拜託',
+'括发' => '括髮',
+'拭干' => '拭乾',
+'拮据' => '拮据',
+'拳局' => '拳跼',
+'拼死拼活' => '拼死拼活',
+'拾沈' => '拾瀋',
+'拿下表' => '拿下錶',
+'拿下钟' => '拿下鐘',
+'拿准' => '拿準',
+'拿破仑' => '拿破崙',
+'挂图' => '挂圖',
+'挂帅' => '挂帥',
+'挂彩' => '挂彩',
+'挂念' => '挂念',
+'挂号' => '挂號',
+'挂车' => '挂車',
+'挌斗' => '挌鬥',
+'挑大梁' => '挑大樑',
+'挑斗' => '挑鬥',
+'振荡' => '振蕩',
+'捉奸徒' => '捉奸徒',
+'捉奸细' => '捉奸細',
+'捉奸贼' => '捉奸賊',
+'捉奸党' => '捉奸黨',
+'捉奸' => '捉姦',
+'捉发' => '捉髮',
+'捍御' => '捍禦',
+'捏面人' => '捏麵人',
+'舍不得' => '捨不得',
+'舍入' => '捨入',
+'舍出' => '捨出',
+'舍去' => '捨去',
+'舍命' => '捨命',
+'舍堕' => '捨墮',
+'舍安就危' => '捨安就危',
+'舍实' => '捨實',
+'舍己从人' => '捨己從人',
+'舍己救人' => '捨己救人',
+'舍己为人' => '捨己為人',
+'舍己为公' => '捨己為公',
+'舍己为国' => '捨己為國',
+'舍得' => '捨得',
+'舍我其谁' => '捨我其誰',
+'舍本逐末' => '捨本逐末',
+'舍弃' => '捨棄',
+'舍死忘生' => '捨死忘生',
+'舍生' => '捨生',
+'舍短取长' => '捨短取長',
+'舍身' => '捨身',
+'舍车保帅' => '捨車保帥',
+'舍近求远' => '捨近求遠',
+'卷住' => '捲住',
+'卷来' => '捲來',
+'卷儿' => '捲兒',
+'卷入' => '捲入',
+'卷动' => '捲動',
+'卷去' => '捲去',
+'卷图' => '捲圖',
+'卷土重来' => '捲土重來',
+'卷地' => '捲地',
+'卷尺' => '捲尺',
+'卷尾猴' => '捲尾猴',
+'卷心菜' => '捲心菜',
+'卷成' => '捲成',
+'卷曲' => '捲曲',
+'卷款' => '捲款',
+'卷毛' => '捲毛',
+'卷烟盒' => '捲煙盒',
+'卷积云' => '捲積雲',
+'卷筒' => '捲筒',
+'卷帘' => '捲簾',
+'卷纸' => '捲紙',
+'卷缩' => '捲縮',
+'卷舌' => '捲舌',
+'卷烟' => '捲菸',
+'卷叶蛾' => '捲葉蛾',
+'卷袖' => '捲袖',
+'卷走' => '捲走',
+'卷起' => '捲起',
+'卷轴' => '捲軸',
+'卷逃' => '捲逃',
+'卷铺盖' => '捲鋪蓋',
+'卷云' => '捲雲',
+'卷风' => '捲風',
+'卷发' => '捲髮',
+'捵面' => '捵麵',
+'捶炼' => '捶鍊',
+'扫荡' => '掃蕩',
+'授勋' => '授勳',
+'掌柜' => '掌柜',
+'排骨面' => '排骨麵',
+'挂名' => '掛名',
+'挂帘' => '掛帘',
+'挂历' => '掛曆',
+'挂钩' => '掛鈎',
+'挂钟' => '掛鐘',
+'挂面' => '掛麵',
+'采下' => '採下',
+'采伐' => '採伐',
+'采住' => '採住',
+'采信' => '採信',
+'采光' => '採光',
+'采到' => '採到',
+'采制' => '採制',
+'采区' => '採區',
+'采去' => '採去',
+'采取' => '採取',
+'采回' => '採回',
+'采在' => '採在',
+'采好' => '採好',
+'采得' => '採得',
+'采拾' => '採拾',
+'采挖' => '採挖',
+'采掘' => '採掘',
+'采摘' => '採摘',
+'采摭' => '採摭',
+'采择' => '採擇',
+'采撷' => '採擷',
+'采收' => '採收',
+'采料' => '採料',
+'采暖' => '採暖',
+'采桑' => '採桑',
+'采样' => '採樣',
+'采樵人' => '採樵人',
+'采树种' => '採樹種',
+'采气' => '採氣',
+'采油' => '採油',
+'采为' => '採為',
+'采煤' => '採煤',
+'采获' => '採獲',
+'采猎' => '採獵',
+'采珠' => '採珠',
+'采生折割' => '採生折割',
+'采用' => '採用',
+'采石' => '採石',
+'采砂场' => '採砂場',
+'采矿' => '採礦',
+'采种' => '採種',
+'采空区' => '採空區',
+'采空采穗' => '採空採穗',
+'采納' => '採納',
+'采纳' => '採納',
+'采给' => '採給',
+'采花' => '採花',
+'采芹人' => '採芹人',
+'采茶' => '採茶',
+'采菊' => '採菊',
+'采莲' => '採蓮',
+'采薇' => '採薇',
+'采薪' => '採薪',
+'采药' => '採藥',
+'采血' => '採血',
+'采行' => '採行',
+'采补' => '採補',
+'采访' => '採訪',
+'采证' => '採證',
+'采买' => '採買',
+'采购' => '採購',
+'采办' => '採辦',
+'采运' => '採運',
+'采过' => '採過',
+'采选' => '採選',
+'采金' => '採金',
+'采录' => '採錄',
+'采铁' => '採鐵',
+'采集' => '採集',
+'采风' => '採風',
+'采风问俗' => '採風問俗',
+'采食' => '採食',
+'采盐' => '採鹽',
+'掣签' => '掣籤',
+'控制' => '控制',
+'推情准理' => '推情準理',
+'推托之词' => '推托之詞',
+'推托' => '推託',
+'提子干' => '提子乾',
+'提心吊胆' => '提心弔膽',
+'提摩太后书' => '提摩太後書',
+'提高后' => '提高後',
+'插于' => '插於',
+'换签' => '換籤',
+'换只' => '換隻',
+'换发' => '換髮',
+'握发' => '握髮',
+'揩干' => '揩乾',
+'揪采' => '揪採',
+'揪发' => '揪髮',
+'揪须' => '揪鬚',
+'揭丑' => '揭醜',
+'挥手表' => '揮手表',
+'揮手表' => '揮手表',
+'搋面' => '搋麵',
+'损于' => '損於',
+'搏斗' => '搏鬥',
+'捣鬼吊白' => '搗鬼弔白',
+'扼肮' => '搤肮',
+'扼肮拊背' => '搤肮拊背',
+'搬斗' => '搬鬥',
+'搭干铺' => '搭乾鋪',
+'搭伙' => '搭夥',
+'摧坚获丑' => '摧堅獲醜',
+'摭采' => '摭採',
+'摸棱' => '摸稜',
+'摸钟' => '摸鐘',
+'折奏' => '摺奏',
+'折子' => '摺子',
+'折尺' => '摺尺',
+'折扇' => '摺扇',
+'折梯' => '摺梯',
+'折椅' => '摺椅',
+'折台' => '摺檯',
+'折叠' => '摺疊',
+'折痕' => '摺痕',
+'折篷' => '摺篷',
+'折纸' => '摺紙',
+'折裙' => '摺裙',
+'撇吊' => '撇弔',
+'捞干' => '撈乾',
+'捞面' => '撈麵',
+'撚须' => '撚鬚',
+'撞钟' => '撞鐘',
+'撞阵冲军' => '撞陣衝軍',
+'撤并' => '撤併',
+'拨谷' => '撥穀',
+'撩斗' => '撩鬥',
+'播于' => '播於',
+'扑冬' => '撲鼕',
+'扑咚' => '撲鼕',
+'扑咚咚' => '撲鼕鼕',
+'擀面' => '擀麵',
+'击扑' => '擊扑',
+'击钟' => '擊鐘',
+'操作钟' => '操作鐘',
+'担仔面' => '擔仔麵',
+'担担面' => '擔擔麵',
+'据云' => '據云',
+'擢发' => '擢髮',
+'擦干' => '擦乾',
+'拧干' => '擰乾',
+'摆钟' => '擺鐘',
+'摄制' => '攝製',
+'支干' => '支幹',
+'支配欲' => '支配慾',
+'收获' => '收穫',
+'改制成' => '改制成',
+'改征' => '改徵',
+'改采' => '改採',
+'放懞挣' => '放懞掙',
+'放荡' => '放蕩',
+'放松' => '放鬆',
+'政斗' => '政鬥',
+'故云' => '故云',
+'敏于' => '敏於',
+'败于' => '敗於',
+'教学钟' => '教學鐘',
+'教于' => '教於',
+'教范' => '教範',
+'敢干' => '敢幹',
+'敢情欲' => '敢情欲',
+'敢斗了胆' => '敢斗了膽',
+'散伙' => '散夥',
+'散于' => '散於',
+'散荡' => '散蕩',
+'敦朴' => '敦樸',
+'敬挽' => '敬輓',
+'敲扑' => '敲扑',
+'敲钟' => '敲鐘',
+'整只' => '整隻',
+'整风后' => '整風後',
+'整发用品' => '整髮用品',
+'整出剧' => '整齣劇',
+'整出戏' => '整齣戲',
+'整出电影' => '整齣電影',
+'敌忾同仇' => '敵愾同讎',
+'数只包括' => '數只包括',
+'数只可' => '數只可',
+'数只含' => '數只含',
+'数只在' => '數只在',
+'数只应' => '數只應',
+'数只是' => '數只是',
+'数只会' => '數只會',
+'数只有' => '數只有',
+'数只比' => '數只比',
+'数只能' => '數只能',
+'数只限' => '數只限',
+'数只需' => '數只需',
+'数只须' => '數只須',
+'数天后' => '數天後',
+'数字钟' => '數字鐘',
+'数字钟表' => '數字鐘錶',
+'数罪并罚' => '數罪併罰',
+'数与虏确' => '數與虜确',
+'数只' => '數隻',
+'文丑' => '文丑',
+'文学志' => '文學誌',
+'文征明' => '文徵明',
+'文思泉涌' => '文思泉湧',
+'文杰' => '文杰',
+'文采郁郁' => '文采郁郁',
+'斗牛星' => '斗牛星',
+'斫雕为朴' => '斫雕為樸',
+'新井里美' => '新井里美',
+'新干县' => '新幹縣',
+'新历' => '新曆',
+'新历史' => '新歷史',
+'新扎' => '新紮',
+'斲雕为朴' => '斲雕為樸',
+'断发' => '斷髮',
+'断发文身' => '斷髮文身',
+'方便面' => '方便麵',
+'方向往' => '方向往',
+'方志恒' => '方志恒',
+'方法里' => '方法裡',
+'方志' => '方誌',
+'于后' => '於後',
+'于征' => '於徵',
+'于海上' => '於海上',
+'于海边' => '於海邊',
+'于震中' => '於震中',
+'于震前' => '於震前',
+'于震后' => '於震後',
+'施舍' => '施捨',
+'施于' => '施於',
+'施舍之道' => '施舍之道',
+'旁征博引' => '旁徵博引',
+'旁注' => '旁註',
+'旅游' => '旅遊',
+'旋回' => '旋迴',
+'族里' => '族裡',
+'日心历表' => '日心曆表',
+'日历' => '日曆',
+'日历史' => '日歷史',
+'日里' => '日裡',
+'日志' => '日誌',
+'早于' => '早於',
+'旱干' => '旱乾',
+'升州' => '昇州',
+'升平' => '昇平',
+'升阳' => '昇陽',
+'昊天不吊' => '昊天不弔',
+'明征' => '明徵',
+'明目张胆' => '明目張胆',
+'明窗净几' => '明窗淨几',
+'明范' => '明範',
+'明鉴' => '明鑑',
+'易于' => '易於',
+'昔人有云' => '昔人有云',
+'星历' => '星曆',
+'星期后' => '星期後',
+'星历史' => '星歷史',
+'春游' => '春遊',
+'春香斗学' => '春香鬥學',
+'昭惠后' => '昭惠后',
+'是发小' => '是髮小',
+'时钟' => '時鐘',
+'时间不准' => '時間不準',
+'晃荡' => '晃蕩',
+'晚于' => '晚於',
+'晚钟' => '晚鐘',
+'晞发' => '晞髮',
+'晨钟' => '晨鐘',
+'普咚咚' => '普鼕鼕',
+'晾干' => '晾乾',
+'暗地里' => '暗地裡',
+'暗沟里' => '暗溝裡',
+'暗里' => '暗裡',
+'暗斗' => '暗鬥',
+'畅游' => '暢遊',
+'昵称' => '暱稱',
+'暴敛横征' => '暴斂橫徵',
+'历元' => '曆元',
+'历命' => '曆命',
+'历始' => '曆始',
+'历室' => '曆室',
+'历尾' => '曆尾',
+'历局' => '曆局',
+'历数书' => '曆數書',
+'历日' => '曆日',
+'历书' => '曆書',
+'历本' => '曆本',
+'历法' => '曆法',
+'历狱' => '曆獄',
+'历纪' => '曆紀',
+'历象' => '曆象',
+'晒干' => '曬乾',
+'晒谷' => '曬穀',
+'曰云' => '曰云',
+'更仆难数' => '更僕難數',
+'更签' => '更籤',
+'更钟' => '更鐘',
+'书签' => '書籤',
+'书面' => '書面',
+'曹子里' => '曹子里',
+'曼谷' => '曼谷',
+'曾朴' => '曾樸',
+'最多' => '最多',
+'最多只' => '最多只',
+'会干扰' => '會干擾',
+'會干擾' => '會干擾',
+'会干' => '會幹',
+'会吊' => '會弔',
+'会里' => '會裡',
+'月历' => '月曆',
+'月历史' => '月歷史',
+'月球历表' => '月球曆表',
+'月里来' => '月裡來',
+'月面' => '月面',
+'有事之无范' => '有事之無範',
+'有仆' => '有僕',
+'有只不' => '有只不',
+'有只允' => '有只允',
+'有只容' => '有只容',
+'有只採' => '有只採',
+'有只采' => '有只採',
+'有只是' => '有只是',
+'有只用' => '有只用',
+'有回复' => '有回覆',
+'有够赞' => '有夠讚',
+'有征伐' => '有征伐',
+'有征战' => '有征戰',
+'有征戰' => '有征戰',
+'有征服' => '有征服',
+'有征討' => '有征討',
+'有征讨' => '有征討',
+'有征' => '有徵',
+'有恒街' => '有恒街',
+'有栖川' => '有栖川',
+'有准' => '有準',
+'有棱有角' => '有稜有角',
+'有只' => '有隻',
+'有余' => '有餘',
+'有发头陀寺' => '有髮頭陀寺',
+'服于' => '服於',
+'望了望' => '望了望',
+'望后石' => '望后石',
+'朝乾夕惕' => '朝乾夕惕',
+'朝钟' => '朝鐘',
+'朝鲜于' => '朝鮮於',
+'朦胧' => '朦朧',
+'蒙胧' => '朦朧',
+'木偶戏扎' => '木偶戲紮',
+'木材干馏' => '木材乾餾',
+'木梁' => '木樑',
+'木签' => '木籤',
+'木制' => '木製',
+'木钟' => '木鐘',
+'未干' => '未乾',
+'未干涉' => '未干涉',
+'未干預' => '未干預',
+'未干预' => '未干預',
+'本庄' => '本庄',
+'本征' => '本徵',
+'本出戏' => '本齣戲',
+'术赤' => '朮赤',
+'朱庆余' => '朱慶餘',
+'朱理安历' => '朱理安曆',
+'朱理安历史' => '朱理安歷史',
+'朴子里' => '朴子里',
+'李志喜' => '李志喜',
+'李适' => '李适',
+'李连杰' => '李連杰',
+'李連杰' => '李連杰',
+'材干' => '材幹',
+'村落发' => '村落發',
+'村里' => '村裡',
+'村里長' => '村里長',
+'村里长' => '村里長',
+'杜老志道' => '杜老誌道',
+'杞宋无征' => '杞宋無徵',
+'束发' => '束髮',
+'杠人' => '杠人',
+'杠梁' => '杠梁',
+'杠毂' => '杠轂',
+'杠轂' => '杠轂',
+'杯干' => '杯乾',
+'杯面' => '杯麵',
+'杰伦' => '杰倫',
+'杰倫' => '杰倫',
+'杰威尔' => '杰威爾',
+'杰威爾' => '杰威爾',
+'东周钟' => '東周鐘',
+'东岳' => '東嶽',
+'東湖里' => '東湖里',
+'东冲西突' => '東衝西突',
+'东游' => '東遊',
+'松口镇' => '松口鎮',
+'松山庄' => '松山庄',
+'松溪县' => '松谿縣',
+'板荡' => '板蕩',
+'林宏岳' => '林宏嶽',
+'林杰樑' => '林杰樑',
+'林郁方' => '林郁方',
+'林钟' => '林鐘',
+'林鹅峰' => '林鵞峰',
+'果干' => '果乾',
+'果子干' => '果子乾',
+'果累累' => '果纍纍',
+'枝干' => '枝幹',
+'枯干' => '枯乾',
+'架钟' => '架鐘',
+'某只' => '某隻',
+'染指于' => '染指於',
+'染殿后' => '染殿后',
+'染发' => '染髮',
+'柜上' => '柜上',
+'柜子' => '柜子',
+'柜柳' => '柜柳',
+'查封后' => '查封後',
+'柱梁' => '柱樑',
+'柳斌杰' => '柳斌杰',
+'柳诒征' => '柳詒徵',
+'栖栖皇皇' => '栖栖皇皇',
+'栗栖溪' => '栗栖溪',
+'校准' => '校準',
+'校舍' => '校舍',
+'核准的' => '核准的',
+'格于' => '格於',
+'格范' => '格範',
+'格里历' => '格里曆',
+'格里高利历' => '格里高利曆',
+'格斗' => '格鬥',
+'桂圆干' => '桂圓乾',
+'框里' => '框裡',
+'桌几' => '桌几',
+'桌历' => '桌曆',
+'桌历史' => '桌歷史',
+'桌游' => '桌遊',
+'桑干' => '桑乾',
+'杆枪' => '桿槍',
+'杆秤' => '桿秤',
+'杆菌' => '桿菌',
+'梁上君子' => '梁上君子',
+'梁启超' => '梁啓超',
+'条干' => '條幹',
+'梨干' => '梨乾',
+'梯冲' => '梯衝',
+'械系' => '械繫',
+'械斗' => '械鬥',
+'弃舍' => '棄捨',
+'棉里' => '棉裡',
+'棉制' => '棉製',
+'棒子面' => '棒子麵',
+'栋梁' => '棟樑',
+'棫朴' => '棫樸',
+'森林里' => '森林裡',
+'棺材里' => '棺材裡',
+'植发' => '植髮',
+'椒面' => '椒麵',
+'椰枣干' => '椰棗乾',
+'杨雅筑' => '楊雅筑',
+'楊雅筑' => '楊雅筑',
+'桢干' => '楨幹',
+'业余' => '業餘',
+'榨干' => '榨乾',
+'枪杆' => '槍桿',
+'杠杆' => '槓桿',
+'乐器钟' => '樂器鐘',
+'乐游原' => '樂遊原',
+'樊于期' => '樊於期',
+'梁上' => '樑上',
+'梁柱' => '樑柱',
+'樗里子' => '樗里子',
+'标标致致' => '標標致致',
+'标准' => '標準',
+'标签' => '標籤',
+'标致' => '標緻',
+'标注' => '標註',
+'标志' => '標誌',
+'模棱' => '模稜',
+'模范' => '模範',
+'模范七棒' => '模范七棒',
+'模范三军' => '模范三軍',
+'模范三軍' => '模范三軍',
+'模范棒棒堂' => '模范棒棒堂',
+'模制' => '模製',
+'样范' => '樣範',
+'樵采' => '樵採',
+'朴修斯' => '樸修斯',
+'朴厚' => '樸厚',
+'朴学' => '樸學',
+'朴实' => '樸實',
+'朴念仁' => '樸念仁',
+'朴拙' => '樸拙',
+'朴樕' => '樸樕',
+'朴父' => '樸父',
+'朴直' => '樸直',
+'朴素' => '樸素',
+'朴讷' => '樸訥',
+'朴质' => '樸質',
+'朴鄙' => '樸鄙',
+'朴重' => '樸重',
+'朴野' => '樸野',
+'朴钝' => '樸鈍',
+'朴陋' => '樸陋',
+'朴马' => '樸馬',
+'朴鲁' => '樸魯',
+'树干' => '樹幹',
+'树林里' => '樹林裡',
+'树梁' => '樹樑',
+'桥梁' => '橋樑',
+'机械系' => '機械系',
+'機械系' => '機械系',
+'机械表' => '機械錶',
+'机械钟' => '機械鐘',
+'机械钟表' => '機械鐘錶',
+'横峰县' => '橫峯縣',
+'横征暴敛' => '橫徵暴斂',
+'横梁' => '橫樑',
+'横冲' => '橫衝',
+'台布' => '檯布',
+'台历' => '檯曆',
+'台灯' => '檯燈',
+'台球' => '檯球',
+'台面上' => '檯面上',
+'台面化' => '檯面化',
+'柜台' => '櫃檯',
+'柜里' => '櫃裡',
+'栉发工' => '櫛髮工',
+'欲海难填' => '欲海難填',
+'欺蒙' => '欺矇',
+'歌后' => '歌后',
+'歌钟' => '歌鐘',
+'欧游' => '歐遊',
+'止于' => '止於',
+'正官庄' => '正官庄',
+'正杰' => '正杰',
+'武丑' => '武丑',
+'武后' => '武后',
+'武斗' => '武鬥',
+'岁聿云暮' => '歲聿云暮',
+'历史里' => '歷史裡',
+'归并' => '歸併',
+'归于' => '歸於',
+'归余' => '歸餘',
+'歹斗' => '歹鬥',
+'死于' => '死於',
+'死里求生' => '死裡求生',
+'死里逃生' => '死裡逃生',
+'殖谷' => '殖穀',
+'残肴' => '殘肴',
+'残余' => '殘餘',
+'僵尸' => '殭屍',
+'殷师牛斗' => '殷師牛鬥',
+'殷鉴' => '殷鑑',
+'壳里' => '殼裡',
+'殿钟自鸣' => '殿鐘自鳴',
+'毁于' => '毀於',
+'毁钟为铎' => '毀鐘為鐸',
+'殴斗' => '毆鬥',
+'母后' => '母后',
+'母范' => '母範',
+'母丑' => '母醜',
+'每每只' => '每每只',
+'每只' => '每隻',
+'毗婆尸佛' => '毗婆尸佛',
+'毛坏' => '毛坏',
+'毛姜' => '毛薑',
+'毛发' => '毛髮',
+'毫厘' => '毫釐',
+'毫发' => '毫髮',
+'气冲斗牛' => '氣沖斗牛',
+'气郁' => '氣鬱',
+'氤郁' => '氤鬱',
+'水来汤里去' => '水來湯裡去',
+'水准' => '水準',
+'水无怜奈' => '水無怜奈',
+'水表示' => '水表示',
+'水表面' => '水表面',
+'水里' => '水裡',
+'水里商工' => '水里商工',
+'水里溪' => '水里溪',
+'水里濁水溪' => '水里濁水溪',
+'水里鄉' => '水里鄉',
+'水里高級商工' => '水里高級商工',
+'水里鳳林' => '水里鳳林',
+'水表' => '水錶',
+'永历' => '永曆',
+'永历史' => '永歷史',
+'永志不忘' => '永誌不忘',
+'求知欲' => '求知慾',
+'求签' => '求籤',
+'池里' => '池裡',
+'污蔑' => '污衊',
+'汤卤' => '汤滷',
+'汲于' => '汲於',
+'决斗' => '決鬥',
+'沈淀' => '沈澱',
+'沈郁' => '沈鬱',
+'沉淀' => '沉澱',
+'沉郁' => '沉鬱',
+'没干没净' => '沒乾沒淨',
+'没事干' => '沒事幹',
+'没干' => '沒幹',
+'没折至' => '沒摺至',
+'没样范' => '沒樣範',
+'没准' => '沒準',
+'冲冠发怒' => '沖冠髮怒',
+'冲天' => '沖天',
+'沙琅' => '沙瑯',
+'沙羡' => '沙羡',
+'沙里淘金' => '沙裡淘金',
+'河岳' => '河嶽',
+'河里' => '河裡',
+'油泼面' => '油潑麵',
+'油斗' => '油鬥',
+'油面' => '油麵',
+'治愈' => '治癒',
+'沿溯' => '沿泝',
+'法自制' => '法自制',
+'法里,' => '法裡,',
+'泛游' => '泛遊',
+'泡制' => '泡製',
+'泡面' => '泡麵',
+'波棱菜' => '波稜菜',
+'波发藻' => '波髮藻',
+'泥于' => '泥於',
+'注云' => '注云',
+'注释' => '注釋',
+'泰山梁木' => '泰山梁木',
+'泱郁' => '泱鬱',
+'泳气钟' => '泳氣鐘',
+'洄游' => '洄遊',
+'洋河大曲' => '洋河大麯',
+'洒家' => '洒家',
+'洒扫' => '洒掃',
+'洒水' => '洒水',
+'洒洒' => '洒洒',
+'洒淅' => '洒淅',
+'洒涤' => '洒滌',
+'洒濯' => '洒濯',
+'洒然' => '洒然',
+'洒脱' => '洒脫',
+'洗炼' => '洗鍊',
+'洗练' => '洗鍊',
+'洗发' => '洗髮',
+'洛钟东应' => '洛鐘東應',
+'洞里' => '洞裡',
+'洞里萨' => '洞里薩',
+'洞里薩' => '洞里薩',
+'泄欲' => '洩慾',
+'洪范' => '洪範',
+'洪谷子' => '洪谷子',
+'洪适' => '洪适',
+'洪钟' => '洪鐘',
+'汹涌' => '洶湧',
+'流征' => '流徵',
+'流于' => '流於',
+'流荡' => '流蕩',
+'流风余俗' => '流風餘俗',
+'流风余韵' => '流風餘韻',
+'浩浩荡荡' => '浩浩蕩蕩',
+'浩荡' => '浩蕩',
+'浪荡' => '浪蕩',
+'浪游' => '浪遊',
+'浮于' => '浮於',
+'浮荡' => '浮蕩',
+'浮夸' => '浮誇',
+'浮松' => '浮鬆',
+'海干' => '海乾',
+'海淀山后' => '海淀山後',
+'海淀山後' => '海淀山後',
+'浸卤' => '浸滷',
+'涂善妮' => '涂善妮',
+'涂坤' => '涂坤',
+'涂壮勋' => '涂壯勳',
+'涂壯勳' => '涂壯勳',
+'涂天相' => '涂天相',
+'涂姓' => '涂姓',
+'涂序瑄' => '涂序瑄',
+'涂敏恆' => '涂敏恆',
+'涂敏恒' => '涂敏恆',
+'涂泽民' => '涂澤民',
+'涂澤民' => '涂澤民',
+'涂绍煃' => '涂紹煃',
+'涂羽卿' => '涂羽卿',
+'涂謹申' => '涂謹申',
+'涂谨申' => '涂謹申',
+'涂逢年' => '涂逢年',
+'涂醒哲' => '涂醒哲',
+'涂長望' => '涂長望',
+'涂长望' => '涂長望',
+'涂鴻欽' => '涂鴻欽',
+'涂鸿钦' => '涂鴻欽',
+'涌水塘' => '涌水塘',
+'涳蒙' => '涳濛',
+'涸干' => '涸乾',
+'凉席' => '涼蓆',
+'凉面' => '涼麵',
+'淋余土' => '淋餘土',
+'淑范' => '淑範',
+'泪干' => '淚乾',
+'泪如泉涌' => '淚如泉湧',
+'淡于' => '淡於',
+'淡蒙蒙' => '淡濛濛',
+'净余' => '淨餘',
+'净发' => '淨髮',
+'淫欲' => '淫慾',
+'淫荡' => '淫蕩',
+'淬炼' => '淬鍊',
+'深山何处钟' => '深山何處鐘',
+'深山里' => '深山裡',
+'淳于' => '淳于',
+'淳朴' => '淳樸',
+'渊淳岳峙' => '淵淳嶽峙',
+'渊里' => '淵裡',
+'浅淀' => '淺澱',
+'清心寡欲' => '清心寡欲',
+'渠冲' => '渠衝',
+'测不准' => '測不準',
+'港制' => '港製',
+'游离' => '游離',
+'浑朴' => '渾樸',
+'浑个' => '渾箇',
+'湖里' => '湖裡',
+'湘累' => '湘纍',
+'涌上' => '湧上',
+'涌来' => '湧來',
+'涌入' => '湧入',
+'涌出' => '湧出',
+'涌向' => '湧向',
+'涌水' => '湧水',
+'涌泉' => '湧泉',
+'涌现' => '湧現',
+'涌起' => '湧起',
+'涌进' => '湧進',
+'湮郁' => '湮鬱',
+'汤下面' => '湯下麵',
+'汤团' => '湯糰',
+'汤面' => '湯麵',
+'源于' => '源於',
+'准不准' => '準不準',
+'准例' => '準例',
+'准保' => '準保',
+'准备' => '準備',
+'准儿' => '準兒',
+'准分子' => '準分子',
+'准则' => '準則',
+'准噶尔' => '準噶爾',
+'准定' => '準定',
+'准平原' => '準平原',
+'准度' => '準度',
+'准式' => '準式',
+'准拿督' => '準拿督',
+'准据' => '準據',
+'准拟' => '準擬',
+'准新娘' => '準新娘',
+'准新郎' => '準新郎',
+'准星' => '準星',
+'准是' => '準是',
+'准时' => '準時',
+'准会' => '準會',
+'准决赛' => '準決賽',
+'准的' => '準的',
+'准直' => '準直',
+'准确' => '準確',
+'准线' => '準線',
+'准绳' => '準繩',
+'准话' => '準話',
+'准谱' => '準譜',
+'准货币' => '準貨幣',
+'准军事' => '準軍事',
+'准头' => '準頭',
+'准点' => '準點',
+'沟大曲' => '溝大麯',
+'沟谷' => '溝谷',
+'溟蒙' => '溟濛',
+'溢于' => '溢於',
+'温洛克期' => '溫洛克期',
+'溲面' => '溲麵',
+'溺于' => '溺於',
+'滃郁' => '滃鬱',
+'滑借' => '滑藉',
+'汇丰' => '滙豐',
+'渗漓' => '滲灕',
+'卤了' => '滷了',
+'卤五花' => '滷五花',
+'卤味' => '滷味',
+'卤好' => '滷好',
+'卤子' => '滷子',
+'卤料' => '滷料',
+'卤水' => '滷水',
+'卤汁' => '滷汁',
+'卤湖' => '滷湖',
+'卤煮' => '滷煮',
+'卤牛' => '滷牛',
+'卤的' => '滷的',
+'卤肉' => '滷肉',
+'卤菜' => '滷菜',
+'卤蛋' => '滷蛋',
+'卤虾' => '滷蝦',
+'卤制' => '滷製',
+'卤豆' => '滷豆',
+'卤鸡' => '滷雞',
+'卤鸭' => '滷鴨',
+'卤鹅' => '滷鵝',
+'卤面' => '滷麵',
+'满拼自尽' => '滿拚自盡',
+'满满当当' => '滿滿當當',
+'满头洋发' => '滿頭洋髮',
+'漂荡' => '漂蕩',
+'漕挽' => '漕輓',
+'沤郁' => '漚鬱',
+'漠里' => '漠裡',
+'汉弥登钟' => '漢彌登鐘',
+'漫卷' => '漫捲',
+'漫游' => '漫遊',
+'潜意识里' => '潛意識裡',
+'潜水表' => '潛水錶',
+'潜水钟' => '潛水鐘',
+'潜水钟表' => '潛水鐘錶',
+'潭里' => '潭裡',
+'潮涌' => '潮湧',
+'溃于' => '潰於',
+'涩谷区' => '澀谷區',
+'澄江县' => '澂江縣',
+'澄澹精致' => '澄澹精致',
+'澒蒙' => '澒濛',
+'淀乃不耕之地' => '澱乃不耕之地',
+'淀北片' => '澱北片',
+'淀山' => '澱山',
+'淀淀' => '澱澱',
+'淀积' => '澱積',
+'淀粉' => '澱粉',
+'淀解物' => '澱解物',
+'淀谓之滓' => '澱謂之滓',
+'澹台' => '澹臺',
+'澹荡' => '澹蕩',
+'激斗' => '激鬥',
+'浓发' => '濃髮',
+'蒙汜' => '濛汜',
+'蒙蒙细雨' => '濛濛細雨',
+'蒙雾' => '濛霧',
+'蒙鸿' => '濛鴻',
+'浚州' => '濬州',
+'浚县' => '濬縣',
+'滨田里佳子' => '濱田里佳子',
+'沈丹客运' => '瀋丹客運',
+'沈丹线' => '瀋丹線',
+'沈丹铁路' => '瀋丹鐵路',
+'沈丹高' => '瀋丹高',
+'沈北' => '瀋北',
+'沈吉' => '瀋吉',
+'沈大线' => '瀋大線',
+'沈大铁路' => '瀋大鐵路',
+'沈大高速' => '瀋大高速',
+'沈山线' => '瀋山線',
+'沈山铁路' => '瀋山鐵路',
+'沈州' => '瀋州',
+'沈抚' => '瀋撫',
+'沈水' => '瀋水',
+'沈河' => '瀋河',
+'沈海铁路' => '瀋海鐵路',
+'沈海高速' => '瀋海高速',
+'沈阳' => '瀋陽',
+'泸州大曲' => '瀘州大麯',
+'沥干' => '瀝乾',
+'潇洒' => '瀟洒',
+'弥山遍野' => '瀰山遍野',
+'弥漫' => '瀰漫',
+'弥弥' => '瀰瀰',
+'漓水' => '灕水',
+'漓江' => '灕江',
+'漓湘' => '灕湘',
+'漓然' => '灕然',
+'滩涂' => '灘涂',
+'滩席' => '灘蓆',
+'火并非' => '火並非',
+'火并' => '火併',
+'火山里' => '火山裡',
+'火拼' => '火拚',
+'火折子' => '火摺子',
+'火签' => '火籤',
+'灰蒙' => '灰濛',
+'灰蒙蒙' => '灰濛濛',
+'炆面' => '炆麵',
+'炒面' => '炒麵',
+'炮制' => '炮製',
+'炸酱面' => '炸醬麵',
+'为准' => '為準',
+'为鉴' => '為鑑',
+'乌兹冲锋枪' => '烏茲衝鋒槍',
+'乌苏里' => '烏蘇里',
+'乌发' => '烏髮',
+'乌龙面' => '烏龍麵',
+'烘干' => '烘乾',
+'烘制' => '烘製',
+'烤干' => '烤乾',
+'烤卤' => '烤滷',
+'烹制' => '烹製',
+'焙干' => '焙乾',
+'无征不信' => '無徵不信',
+'无业游民' => '無業游民',
+'无梁楼盖' => '無樑樓蓋',
+'无余' => '無餘',
+'炼制' => '煉製',
+'煎面' => '煎麵',
+'烟卷' => '煙捲',
+'烟台' => '煙臺',
+'照入签' => '照入籤',
+'照相干片' => '照相乾片',
+'煨干' => '煨乾',
+'煮面' => '煮麵',
+'熊杰' => '熊杰',
+'荧郁' => '熒鬱',
+'燎发' => '燎髮',
+'烧干' => '燒乾',
+'燕几' => '燕几',
+'燕游' => '燕遊',
+'烫一个发' => '燙一個髮',
+'烫一次发' => '燙一次髮',
+'烫个发' => '燙個髮',
+'烫完发' => '燙完髮',
+'烫次发' => '燙次髮',
+'烫发' => '燙髮',
+'烫面' => '燙麵',
+'营干' => '營幹',
+'烩面' => '燴麵',
+'烬余' => '燼餘',
+'爆发指数' => '爆發指數',
+'争奇斗妍' => '爭奇鬥妍',
+'争奇斗异' => '爭奇鬥異',
+'争奇斗艳' => '爭奇鬥豔',
+'争妍斗奇' => '爭妍鬥奇',
+'争妍斗艳' => '爭妍鬥豔',
+'争红斗紫' => '爭紅鬥紫',
+'争斗' => '爭鬥',
+'爰定祥历' => '爰定祥厤',
+'爽荡' => '爽蕩',
+'尔冬陞' => '爾冬陞',
+'墙里' => '牆裡',
+'片里' => '片裡',
+'片言只语' => '片言隻語',
+'版图里' => '版圖裡',
+'牙签' => '牙籤',
+'牛只' => '牛隻',
+'物欲' => '物慾',
+'抵牾' => '牴牾',
+'抵触' => '牴觸',
+'特别致' => '特别致',
+'特制住' => '特制住',
+'特制定' => '特制定',
+'特制止' => '特制止',
+'特制订' => '特制訂',
+'特征' => '特徵',
+'特制' => '特製',
+'牵一发' => '牽一髮',
+'牵系' => '牽繫',
+'荦确' => '犖确',
+'狂并潮' => '狂併潮',
+'狃于' => '狃於',
+'狄志杰' => '狄志杰',
+'狐借虎威' => '狐藉虎威',
+'猛于' => '猛於',
+'猛冲' => '猛衝',
+'猜三划五' => '猜三划五',
+'犹如表' => '猶如錶',
+'犹如钟' => '猶如鐘',
+'犹如钟表' => '猶如鐘錶',
+'狱里' => '獄裡',
+'奖杯' => '獎盃',
+'独裁制' => '獨裁制',
+'独辟蹊径' => '獨闢蹊徑',
+'获匪其丑' => '獲匪其醜',
+'兽欲' => '獸慾',
+'献丑' => '獻醜',
+'玉历' => '玉曆',
+'玉历史' => '玉歷史',
+'玉米面' => '玉米面',
+'王侯后' => '王侯后',
+'王后' => '王后',
+'王添灯' => '王添灯',
+'王田里' => '王田里',
+'王鉴' => '王鑑',
+'王余鱼' => '王餘魚',
+'珍肴异馔' => '珍肴異饌',
+'班里' => '班裡',
+'现于' => '現於',
+'球台' => '球檯',
+'理一个发' => '理一個髮',
+'理一次发' => '理一次髮',
+'理个发' => '理個髮',
+'理完发' => '理完髮',
+'理次发' => '理次髮',
+'理发' => '理髮',
+'琴钟' => '琴鐘',
+'珐琅' => '琺瑯',
+'瑞城里' => '瑞城里',
+'瑞征' => '瑞徵',
+'瑶签' => '瑤籤',
+'环游' => '環遊',
+'瓷制' => '瓷製',
+'甄后' => '甄后',
+'瓮安' => '甕安',
+'甚于' => '甚於',
+'甜水面' => '甜水麵',
+'甜面酱' => '甜麵醬',
+'生力面' => '生力麵',
+'生于' => '生於',
+'生殖洄游' => '生殖洄游',
+'生物钟' => '生物鐘',
+'生发生' => '生發生',
+'生华发' => '生華髮',
+'生姜' => '生薑',
+'生锈' => '生鏽',
+'生发' => '生髮',
+'产卵洄游' => '產卵洄游',
+'苏醒' => '甦醒',
+'用于' => '用於',
+'用法里' => '用法裡',
+'甩发' => '甩髮',
+'田子里' => '田子里',
+'田庄英雄' => '田庄英雄',
+'田谷' => '田穀',
+'田里' => '田裡',
+'由余' => '由余',
+'由于' => '由於',
+'甲胄' => '甲冑',
+'甲后路' => '甲后路',
+'男仆' => '男僕',
+'界里' => '界裡',
+'畏于' => '畏於',
+'留长发' => '留長髮',
+'留发' => '留髮',
+'毕于' => '畢於',
+'毕业于' => '畢業於',
+'毕生发展' => '畢生發展',
+'当准' => '當準',
+'当当丁丁' => '當當丁丁',
+'当当网' => '當當網',
+'叠席' => '疊蓆',
+'疏松' => '疏鬆',
+'疑系' => '疑係',
+'疑凶' => '疑兇',
+'疲于' => '疲於',
+'疲困' => '疲睏',
+'病征' => '病徵',
+'病愈' => '病癒',
+'病余' => '病餘',
+'痊愈' => '痊癒',
+'痒疹' => '痒疹',
+'痒痒' => '痒痒',
+'痳木' => '痳木',
+'痳疹' => '痳疹',
+'痳病' => '痳病',
+'痳痹' => '痳痺',
+'痳疯' => '痳瘋',
+'愈合' => '癒合',
+'症结' => '癥結',
+'癸丑' => '癸丑',
+'发干' => '發乾',
+'发呆' => '發獃',
+'发签' => '發籤',
+'发松' => '發鬆',
+'发面' => '發麵',
+'白干儿' => '白乾兒',
+'白术' => '白朮',
+'白朴' => '白樸',
+'白净面皮' => '白淨面皮',
+'白发其事' => '白發其事',
+'白皮松' => '白皮松',
+'白粉面' => '白粉麵',
+'白里透红' => '白裡透紅',
+'白面包青天' => '白面包青天',
+'白发' => '白髮',
+'白胡' => '白鬍',
+'白霉' => '白黴',
+'百个' => '百個',
+'百只可' => '百只可',
+'百只够' => '百只夠',
+'百只夠' => '百只夠',
+'百只怕' => '百只怕',
+'百只足够' => '百只足夠',
+'百只足夠' => '百只足夠',
+'百周后' => '百周後',
+'百天后' => '百天後',
+'百子里' => '百子里',
+'百年' => '百年',
+'百拙千丑' => '百拙千醜',
+'百科里' => '百科裡',
+'百谷' => '百穀',
+'百扎' => '百紮',
+'百花历' => '百花曆',
+'百花历史' => '百花歷史',
+'百炼' => '百鍊',
+'百只' => '百隻',
+'百余' => '百餘',
+'的回复' => '的回覆',
+'的图里' => '的圖裡',
+'的山里' => '的山裡',
+'的干将' => '的幹將',
+'的个中' => '的箇中',
+'的钟' => '的鐘',
+'的长发' => '的長髮',
+'的发小' => '的髮小',
+'皆可作淀' => '皆可作澱',
+'皆准' => '皆準',
+'皇后' => '皇后',
+'皇历' => '皇曆',
+'皇极历' => '皇極曆',
+'皇极历史' => '皇極歷史',
+'皇历史' => '皇歷史',
+'皓发' => '皓髮',
+'皮制服' => '皮制服',
+'皮托管' => '皮托管',
+'皮肤' => '皮膚',
+'皮里春秋' => '皮裡春秋',
+'皮里阳秋' => '皮裡陽秋',
+'皮制' => '皮製',
+'皮松' => '皮鬆',
+'皱别' => '皺彆',
+'皱折' => '皺摺',
+'盆吊' => '盆弔',
+'盈余' => '盈餘',
+'益于' => '益於',
+'盒里' => '盒裡',
+'盛赞' => '盛讚',
+'盗采' => '盜採',
+'盗钟' => '盜鐘',
+'监制' => '監製',
+'盘里' => '盤裡',
+'盘回' => '盤迴',
+'卢棱伽' => '盧稜伽',
+'荡气回肠' => '盪氣迴腸',
+'盲干' => '盲幹',
+'直于' => '直於',
+'直冲' => '直衝',
+'相并' => '相併',
+'相克制' => '相克制',
+'相克服' => '相克服',
+'相克' => '相剋',
+'相干' => '相干',
+'相于' => '相於',
+'相冲' => '相衝',
+'相斗' => '相鬥',
+'看下表' => '看下錶',
+'看下钟' => '看下鐘',
+'看法里' => '看法裡',
+'看准' => '看準',
+'看表面' => '看表面',
+'看表' => '看錶',
+'看钟' => '看鐘',
+'真凶' => '真兇',
+'真个' => '真箇',
+'真丑' => '真醜',
+'眼干' => '眼乾',
+'眼帘' => '眼帘',
+'眼眶里' => '眼眶裡',
+'眼睛里' => '眼睛裡',
+'眼里' => '眼裡',
+'着眼于' => '着眼於',
+'困乏' => '睏乏',
+'困了' => '睏了',
+'困倦' => '睏倦',
+'困觉' => '睏覺',
+'睡游病' => '睡遊病',
+'瞄准' => '瞄準',
+'瞅下表' => '瞅下錶',
+'瞅下钟' => '瞅下鐘',
+'瞎蒙' => '瞎矇',
+'了望' => '瞭望',
+'了然' => '瞭然',
+'了若指掌' => '瞭若指掌',
+'瞳蒙' => '瞳矇',
+'蒙事' => '矇事',
+'蒙昧无知' => '矇昧無知',
+'蒙松雨' => '矇松雨',
+'蒙混' => '矇混',
+'蒙瞍' => '矇瞍',
+'蒙眬' => '矇矓',
+'蒙聩' => '矇聵',
+'蒙头转' => '矇頭轉',
+'蒙骗' => '矇騙',
+'瞩托' => '矚託',
+'矜夸' => '矜誇',
+'短几' => '短几',
+'短于' => '短於',
+'短发生' => '短發生',
+'短发' => '短髮',
+'矮几' => '矮几',
+'石几' => '石几',
+'石杠' => '石杠',
+'石梁' => '石樑',
+'石英钟' => '石英鐘',
+'石英钟表' => '石英鐘錶',
+'石钟' => '石鐘',
+'研制' => '研製',
+'砰当' => '砰噹',
+'破鉴' => '破鑑',
+'朱砂' => '硃砂',
+'硬干' => '硬幹',
+'确瘠' => '确瘠',
+'碑志' => '碑誌',
+'碗里' => '碗裡',
+'碰钟' => '碰鐘',
+'确系' => '確係',
+'码表' => '碼錶',
+'磁制' => '磁製',
+'磨蝎' => '磨蝎',
+'磨制' => '磨製',
+'磨炼' => '磨鍊',
+'磬钟' => '磬鐘',
+'硗确' => '磽确',
+'砻谷' => '礱穀',
+'示范' => '示範',
+'社里' => '社裡',
+'祝赞' => '祝讚',
+'祝发' => '祝髮',
+'神荼郁垒' => '神荼鬱壘',
+'神游' => '神遊',
+'神雕像' => '神雕像',
+'神雕' => '神鵰',
+'祭吊' => '祭弔',
+'禁欲' => '禁慾',
+'禁欲主义' => '禁欲主義',
+'祸于' => '禍於',
+'御侮' => '禦侮',
+'御寇' => '禦寇',
+'御寒' => '禦寒',
+'御敌' => '禦敵',
+'礼赞' => '禮讚',
+'禾谷' => '禾穀',
+'秃妃之发' => '禿妃之髮',
+'秃发' => '禿髮',
+'秀发动' => '秀發動',
+'秀发展' => '秀發展',
+'秀发布' => '秀發布',
+'秀发村' => '秀發村',
+'秀发现' => '秀發現',
+'秀发生' => '秀發生',
+'秀发表' => '秀發表',
+'秀发起' => '秀發起',
+'秀发' => '秀髮',
+'私下里' => '私下裡',
+'私欲' => '私慾',
+'私斗' => '私鬥',
+'秋游' => '秋遊',
+'种丹妮' => '种丹妮',
+'种师中' => '种師中',
+'种师道' => '种師道',
+'种放' => '种放',
+'科尼亚克期' => '科尼亞克期',
+'科斗' => '科斗',
+'科范' => '科範',
+'秒表明' => '秒表明',
+'秒表示' => '秒表示',
+'秒钟' => '秒鐘',
+'秤杆' => '秤桿',
+'秦沈客运' => '秦瀋客運',
+'移祸于' => '移禍於',
+'稀松' => '稀鬆',
+'棱台' => '稜台',
+'棱子' => '稜子',
+'棱层' => '稜層',
+'棱柱' => '稜柱',
+'棱登' => '稜登',
+'棱棱' => '稜稜',
+'棱等登' => '稜等登',
+'棱线' => '稜線',
+'棱缝' => '稜縫',
+'棱角' => '稜角',
+'棱锥' => '稜錐',
+'棱镜' => '稜鏡',
+'棱体' => '稜體',
+'种谷' => '種穀',
+'称赞' => '稱讚',
+'稻谷' => '稻穀',
+'稽征' => '稽徵',
+'谷人' => '穀人',
+'谷保家商' => '穀保家商',
+'谷仓' => '穀倉',
+'谷圭' => '穀圭',
+'谷场' => '穀場',
+'谷子' => '穀子',
+'谷日' => '穀日',
+'谷旦' => '穀旦',
+'谷梁' => '穀梁',
+'谷壳' => '穀殼',
+'谷物' => '穀物',
+'谷皮' => '穀皮',
+'谷神' => '穀神',
+'谷禄' => '穀祿',
+'谷谷' => '穀穀',
+'谷米' => '穀米',
+'谷粒' => '穀粒',
+'谷舱' => '穀艙',
+'谷苗' => '穀苗',
+'谷草' => '穀草',
+'谷贵饿农' => '穀貴餓農',
+'谷贱伤农' => '穀賤傷農',
+'谷雨' => '穀雨',
+'谷类' => '穀類',
+'谷食' => '穀食',
+'穆棱' => '穆稜',
+'穆罕默德历' => '穆罕默德曆',
+'穆罕默德历史' => '穆罕默德歷史',
+'积淀' => '積澱',
+'积谷' => '積穀',
+'积谷防饥' => '積穀防饑',
+'积郁' => '積鬱',
+'稳健的台风' => '穩健的台風',
+'稳扎' => '穩紮',
+'空蒙' => '空濛',
+'空荡' => '空蕩',
+'空荡荡' => '空蕩蕩',
+'空钟' => '空鐘',
+'空余' => '空餘',
+'窒欲' => '窒慾',
+'窗明几亮' => '窗明几亮',
+'窗明几净' => '窗明几淨',
+'窗帘' => '窗簾',
+'窝里' => '窩裡',
+'窝里斗' => '窩裡鬥',
+'穷于' => '窮於',
+'穷追不舍' => '窮追不捨',
+'穷发' => '窮髮',
+'窃钟掩耳' => '竊鐘掩耳',
+'立于' => '立於',
+'立范' => '立範',
+'童仆' => '童僕',
+'竞斗' => '競鬥',
+'竹几' => '竹几',
+'竹林之游' => '竹林之遊',
+'竹签' => '竹籤',
+'竹席' => '竹蓆',
+'竹制' => '竹製',
+'竹溪县' => '竹谿縣',
+'笑里藏刀' => '笑裡藏刀',
+'第一出现' => '第一出現',
+'第一出現' => '第一出現',
+'第一出線' => '第一出線',
+'第一出线' => '第一出線',
+'第一出' => '第一齣',
+'第七出' => '第七齣',
+'第三出局' => '第三出局',
+'第三出' => '第三齣',
+'第九出' => '第九齣',
+'第二出線' => '第二出線',
+'第二出线' => '第二出線',
+'第二出' => '第二齣',
+'第五出局' => '第五出局',
+'第五出' => '第五齣',
+'第八出' => '第八齣',
+'第六出' => '第六齣',
+'第四出局' => '第四出局',
+'第四出' => '第四齣',
+'笔杆' => '筆桿',
+'笔秃墨干' => '筆禿墨乾',
+'等于' => '等於',
+'笋干' => '筍乾',
+'筑前' => '筑前',
+'筑北' => '筑北',
+'筑州' => '筑州',
+'筑后' => '筑後',
+'筑後' => '筑後',
+'筑波' => '筑波',
+'筑紫' => '筑紫',
+'筑肥' => '筑肥',
+'筑西' => '筑西',
+'筑邦' => '筑邦',
+'筑阳' => '筑陽',
+'筑陽' => '筑陽',
+'答复' => '答覆',
+'筵几' => '筵几',
+'个中原因' => '箇中原因',
+'个中奥' => '箇中奧',
+'个中好手' => '箇中好手',
+'个中强手' => '箇中強手',
+'个中滋味' => '箇中滋味',
+'个中玄机' => '箇中玄機',
+'个中理由' => '箇中理由',
+'个中翘楚' => '箇中翹楚',
+'个中道理' => '箇中道理',
+'个中高手' => '箇中高手',
+'个旧' => '箇舊',
+'算历' => '算曆',
+'算历史' => '算歷史',
+'算准' => '算準',
+'管制' => '管制',
+'管干' => '管幹',
+'箱里' => '箱裡',
+'节欲' => '節慾',
+'节目里' => '節目裡',
+'节余' => '節餘',
+'范亭' => '範亭',
+'范例' => '範例',
+'范围' => '範圍',
+'范字' => '範字',
+'范式' => '範式',
+'范性形变' => '範性形變',
+'范数' => '範數',
+'范文' => '範文',
+'范本' => '範本',
+'范畴' => '範疇',
+'范金' => '範金',
+'简并' => '簡併',
+'简朴' => '簡樸',
+'简短发' => '簡短發',
+'简筑翎' => '簡筑翎',
+'簡筑翎' => '簡筑翎',
+'簸荡' => '簸蕩',
+'签幐' => '籤幐',
+'签押' => '籤押',
+'签条' => '籤條',
+'签诗' => '籤詩',
+'吁天' => '籲天',
+'吁求' => '籲求',
+'吁请' => '籲請',
+'米沈' => '米瀋',
+'米谷' => '米穀',
+'米团' => '米糰',
+'米余' => '米餘',
+'米面' => '米麵',
+'粉签子' => '粉籤子',
+'粗制' => '粗製',
+'精制伏' => '精制伏',
+'精制住' => '精制住',
+'精制服' => '精制服',
+'精干' => '精幹',
+'精于' => '精於',
+'精准' => '精準',
+'精致' => '精緻',
+'精制' => '精製',
+'精炼' => '精鍊',
+'精辟' => '精闢',
+'精松' => '精鬆',
+'糊里糊涂' => '糊裡糊塗',
+'糕干' => '糕乾',
+'粪秽蔑面' => '糞穢衊面',
+'团子' => '糰子',
+'系列里' => '系列裡',
+'系里' => '系裡',
+'纪历' => '紀曆',
+'纪历史' => '紀歷史',
+'红后假说' => '紅后假說',
+'红绳系足' => '紅繩繫足',
+'红钟' => '紅鐘',
+'红发' => '紅髮',
+'纡回' => '紆迴',
+'纡余' => '紆餘',
+'纡郁' => '紆鬱',
+'纳征' => '納徵',
+'纯朴' => '純樸',
+'纸扎' => '紙紮',
+'素数里' => '素數裡',
+'素朴' => '素樸',
+'素发' => '素髮',
+'素面' => '素麵',
+'索馬里' => '索馬里',
+'索马里' => '索馬里',
+'索面' => '索麵',
+'紫姜' => '紫薑',
+'扎上' => '紮上',
+'扎下' => '紮下',
+'扎囮' => '紮囮',
+'扎好' => '紮好',
+'扎实' => '紮實',
+'扎寨' => '紮寨',
+'扎带子' => '紮帶子',
+'扎成' => '紮成',
+'扎根' => '紮根',
+'扎营' => '紮營',
+'扎紧' => '紮緊',
+'扎脚' => '紮腳',
+'扎裹' => '紮裹',
+'扎诈' => '紮詐',
+'扎起' => '紮起',
+'扎铁' => '紮鐵',
+'细不容发' => '細不容髮',
+'细如发' => '細如髮',
+'细致' => '細緻',
+'细炼' => '細鍊',
+'终于' => '終於',
+'组里' => '組裡',
+'结伴同游' => '結伴同遊',
+'结伙' => '結夥',
+'结扎' => '結紮',
+'结余' => '結餘',
+'结发' => '結髮',
+'绝于' => '絕於',
+'绞干' => '絞乾',
+'络腮胡' => '絡腮鬍',
+'给于' => '給於',
+'丝恩发怨' => '絲恩髮怨',
+'丝制' => '絲製',
+'丝发' => '絲髮',
+'绑扎' => '綁紮',
+'绥棱' => '綏稜',
+'捆扎' => '綑紮',
+'經有云' => '經有云',
+'经有云' => '經有云',
+'综合征' => '綜合徵',
+'绿发' => '綠髮',
+'维系' => '維繫',
+'绾发' => '綰髮',
+'纲鉴' => '綱鑑',
+'網球台' => '網球台',
+'网球台' => '網球台',
+'网站里' => '網站裡',
+'网里' => '網裡',
+'网志' => '網誌',
+'网游' => '網遊',
+'紧致' => '緊緻',
+'紧追不舍' => '緊追不捨',
+'绪余' => '緒餘',
+'线图里' => '線圖裡',
+'缉凶' => '緝兇',
+'编制法' => '編制法',
+'编采' => '編採',
+'编码表' => '編碼表',
+'编钟' => '編鐘',
+'编余' => '編餘',
+'编发' => '編髮',
+'缓征' => '緩徵',
+'缓冲' => '緩衝',
+'致密' => '緻密',
+'萦回' => '縈迴',
+'缜致' => '縝緻',
+'县里' => '縣裡',
+'县志' => '縣誌',
+'缝里' => '縫裡',
+'缝制' => '縫製',
+'缩栗' => '縮慄',
+'缩短发' => '縮短發',
+'纵欲' => '縱慾',
+'纤夫' => '縴夫',
+'纤手' => '縴手',
+'纤绳' => '縴繩',
+'总数只' => '總數只',
+'总数里' => '總數裡',
+'总裁制' => '總裁制',
+'繁复' => '繁複',
+'繁钟' => '繁鐘',
+'绷扒吊拷' => '繃扒弔拷',
+'绕梁' => '繞樑',
+'绘制' => '繪製',
+'系上。' => '繫上。',
+'系上了' => '繫上了',
+'系上安全' => '繫上安全',
+'系上红' => '繫上紅',
+'系上丝' => '繫上絲',
+'系上绳' => '繫上繩',
+'系上头' => '繫上頭',
+'系上黑' => '繫上黑',
+'系上,' => '繫上,',
+'系世' => '繫世',
+'系到' => '繫到',
+'系囚' => '繫囚',
+'系心' => '繫心',
+'系念' => '繫念',
+'系怀' => '繫懷',
+'系恋' => '繫戀',
+'系于' => '繫於',
+'系于一发' => '繫於一髮',
+'系着' => '繫着',
+'系结' => '繫結',
+'系紧' => '繫緊',
+'系绳' => '繫繩',
+'系累' => '繫纍',
+'系舟' => '繫舟',
+'系船' => '繫船',
+'系辞' => '繫辭',
+'系鞋带' => '繫鞋帶',
+'系风捕影' => '繫風捕影',
+'累囚' => '纍囚',
+'累堆' => '纍堆',
+'累瓦结绳' => '纍瓦結繩',
+'累绁' => '纍紲',
+'累臣' => '纍臣',
+'缠斗' => '纏鬥',
+'坛子' => '罈子',
+'坛坛罐罐' => '罈罈罐罐',
+'坛騞' => '罈騞',
+'置于' => '置於',
+'置言成范' => '置言成範',
+'罢于' => '罷於',
+'罗马历' => '羅馬曆',
+'罗马历代' => '羅馬歷代',
+'罗马历史' => '羅馬歷史',
+'羁系' => '羈繫',
+'美容美发' => '美容美髮',
+'美于' => '美於',
+'美丑' => '美醜',
+'美发学' => '美髮學',
+'美发师' => '美髮師',
+'美发店' => '美髮店',
+'美发业' => '美髮業',
+'美发沙龙' => '美髮沙龍',
+'美发馆' => '美髮館',
+'群丑' => '群醜',
+'羡余' => '羨餘',
+'义仆' => '義僕',
+'義联' => '義联',
+'翁子里' => '翁子里',
+'翕辟' => '翕闢',
+'翱游' => '翱遊',
+'翻涌' => '翻湧',
+'翻松' => '翻鬆',
+'老么' => '老么',
+'老干' => '老乾',
+'老仆' => '老僕',
+'老干部' => '老幹部',
+'老懞' => '老懞',
+'老于' => '老於',
+'老爷钟' => '老爺鐘',
+'老白干' => '老白乾',
+'老姜' => '老薑',
+'老板' => '老闆',
+'老面皮' => '老面皮',
+'考征' => '考徵',
+'耍斗' => '耍鬥',
+'耕获' => '耕穫',
+'耳余' => '耳餘',
+'耿于' => '耿於',
+'聊斋志异' => '聊齋志異',
+'圣人历' => '聖人曆',
+'圣后' => '聖后',
+'圣马尔谷日' => '聖馬爾谷日',
+'聖馬爾谷日' => '聖馬爾谷日',
+'聘雇' => '聘僱',
+'聚药雄蕊' => '聚葯雄蕊',
+'闻风后' => '聞風後',
+'联系' => '聯繫',
+'声母后' => '聲母後',
+'听于' => '聽於',
+'肉干' => '肉乾',
+'肉欲' => '肉慾',
+'肉丝面' => '肉絲麵',
+'肉羹面' => '肉羹麵',
+'肉松' => '肉鬆',
+'肉面' => '肉麵',
+'肚里' => '肚裡',
+'肝脏' => '肝臟',
+'肝郁' => '肝鬱',
+'股栗' => '股慄',
+'肥筑方言' => '肥筑方言',
+'肴馔' => '肴饌',
+'肺脏' => '肺臟',
+'胃脏' => '胃臟',
+'胃里' => '胃裡',
+'背地里' => '背地裡',
+'胎发' => '胎髮',
+'胜肽' => '胜肽',
+'胜键' => '胜鍵',
+'胡云' => '胡云',
+'胡子婴' => '胡子嬰',
+'胡子昂' => '胡子昂',
+'胡杰' => '胡杰',
+'胡朴安' => '胡樸安',
+'胡里胡涂' => '胡裡胡塗',
+'胰脏' => '胰臟',
+'能干休' => '能干休',
+'能干戈' => '能干戈',
+'能干扰' => '能干擾',
+'能干政' => '能干政',
+'能干涉' => '能干涉',
+'能干预' => '能干預',
+'能干' => '能幹',
+'能自制' => '能自制',
+'脉冲' => '脈衝',
+'脊梁背' => '脊梁背',
+'脊梁骨' => '脊梁骨',
+'脊梁' => '脊樑',
+'脱谷机' => '脫穀機',
+'脱发' => '脫髮',
+'脺脏' => '脺臟',
+'脾脏' => '脾臟',
+'腊之以为饵' => '腊之以為餌',
+'腊味' => '腊味',
+'腊毒' => '腊毒',
+'腊笔' => '腊筆',
+'腌臜' => '腌臢',
+'肾脏' => '腎臟',
+'腐干' => '腐乾',
+'腐余' => '腐餘',
+'腑脏' => '腑臟',
+'腕表' => '腕錶',
+'脑干' => '腦幹',
+'腰里' => '腰裡',
+'脚注' => '腳註',
+'脚炼' => '腳鍊',
+'肠脏' => '腸臟',
+'胶卷' => '膠捲',
+'膨松' => '膨鬆',
+'膵脏' => '膵臟',
+'臊子面' => '臊子麵',
+'脏器' => '臟器',
+'脏胸' => '臟胸',
+'脏腑' => '臟腑',
+'臣仆' => '臣僕',
+'卧游' => '臥遊',
+'臧谷亡羊' => '臧穀亡羊',
+'临潼斗宝' => '臨潼鬥寶',
+'自干五' => '自乾五',
+'自制一下' => '自制一下',
+'自制下来' => '自制下來',
+'自制不' => '自制不',
+'自制之力' => '自制之力',
+'自制之能' => '自制之能',
+'自制他' => '自制他',
+'自制伏' => '自制伏',
+'自制你' => '自制你',
+'自制力' => '自制力',
+'自制地' => '自制地',
+'自制她' => '自制她',
+'自制情' => '自制情',
+'自制我' => '自制我',
+'自制服' => '自制服',
+'自制的能' => '自制的能',
+'自制能力' => '自制能力',
+'自于' => '自於',
+'自然数里' => '自然數裡',
+'自由钟' => '自由鐘',
+'自制' => '自製',
+'自觉自愿' => '自覺自愿',
+'自夸' => '自誇',
+'臭气冲天' => '臭氣衝天',
+'至多' => '至多',
+'至多只' => '至多只',
+'至于' => '至於',
+'致于' => '致於',
+'台佟' => '臺佟',
+'台静农' => '臺靜農',
+'臻于' => '臻於',
+'舂谷' => '舂穀',
+'举手表' => '舉手表',
+'舉手表' => '舉手表',
+'舊庄' => '舊庄',
+'旧历' => '舊曆',
+'旧历史' => '舊歷史',
+'旧游' => '舊遊',
+'旧表' => '舊錶',
+'旧钟' => '舊鐘',
+'旧钟表' => '舊鐘錶',
+'舌干唇焦' => '舌乾唇焦',
+'舍入口' => '舍入口',
+'舒卷' => '舒捲',
+'舞后' => '舞后',
+'航海历' => '航海曆',
+'航海历史' => '航海歷史',
+'船只得' => '船只得',
+'船只有' => '船只有',
+'船只能' => '船只能',
+'船钟' => '船鐘',
+'船只' => '船隻',
+'舰只' => '艦隻',
+'色欲' => '色慾',
+'色长发' => '色長髮',
+'艳后' => '艷后',
+'艷后' => '艷后',
+'艸木丰丰' => '艸木丰丰',
+'芒果干' => '芒果乾',
+'花不要采' => '花不要採',
+'花卷' => '花捲',
+'花盆里' => '花盆裡',
+'花菴词选' => '花菴詞選',
+'花药' => '花葯',
+'花钟' => '花鐘',
+'花马吊嘴' => '花馬弔嘴',
+'花哄' => '花鬨',
+'苑里' => '苑裡',
+'若干' => '若干',
+'苦干' => '苦幹',
+'苦于' => '苦於',
+'苦里' => '苦裡',
+'苦斗' => '苦鬥',
+'苧麻' => '苧麻',
+'茂都淀' => '茂都澱',
+'范文同' => '范文同',
+'范文正公' => '范文正公',
+'范文澜' => '范文瀾',
+'范文瀾' => '范文瀾',
+'范文照' => '范文照',
+'范文程' => '范文程',
+'范文芳' => '范文芳',
+'范文藤' => '范文藤',
+'范文虎' => '范文虎',
+'范登堡' => '范登堡',
+'范賢惠' => '范賢惠',
+'范贤惠' => '范賢惠',
+'茅于軾' => '茅于軾',
+'茅于轼' => '茅于軾',
+'茶几' => '茶几',
+'茶余' => '茶餘',
+'茶面' => '茶麵',
+'草丛里' => '草叢裡',
+'草荐' => '草荐',
+'草席' => '草蓆',
+'荐居' => '荐居',
+'荐臻' => '荐臻',
+'荐饥' => '荐饑',
+'荷花淀' => '荷花澱',
+'庄里' => '莊裡',
+'茎干' => '莖幹',
+'莜面' => '莜麵',
+'莽荡' => '莽蕩',
+'菜干' => '菜乾',
+'菜坛' => '菜罈',
+'菜肴' => '菜餚',
+'菠棱菜' => '菠稜菜',
+'菠萝干' => '菠蘿乾',
+'华严钟' => '華嚴鐘',
+'万一只' => '萬一只',
+'萬一只' => '萬一只',
+'万个' => '萬個',
+'万周后' => '萬周後',
+'万天后' => '萬天後',
+'万年' => '萬年',
+'万年历' => '萬年曆',
+'万年历表' => '萬年曆錶',
+'万历' => '萬曆',
+'万历史' => '萬歷史',
+'万签插架' => '萬籤插架',
+'万扎' => '萬紮',
+'万象' => '萬象',
+'万只' => '萬隻',
+'万余' => '萬餘',
+'落于' => '落於',
+'落腮胡' => '落腮鬍',
+'落发' => '落髮',
+'叶叶琴' => '葉叶琴',
+'叶叶琹' => '葉叶琹',
+'叶阳后' => '葉陽后',
+'葉陽后' => '葉陽后',
+'葡萄干' => '葡萄乾',
+'董氏封发' => '董氏封髮',
+'葫芦里卖甚么药' => '葫蘆裡賣甚麼藥',
+'葬于' => '葬於',
+'蒙雾露' => '蒙霧露',
+'蒜发' => '蒜髮',
+'蒲席' => '蒲蓆',
+'蒸干' => '蒸乾',
+'蒸制' => '蒸製',
+'苍术' => '蒼朮',
+'苍发' => '蒼髮',
+'苍郁' => '蒼鬱',
+'蓄发' => '蓄髮',
+'蓄胡' => '蓄鬍',
+'蓄须' => '蓄鬚',
+'席子' => '蓆子',
+'蓊郁' => '蓊鬱',
+'蓬发' => '蓬髮',
+'蓬松' => '蓬鬆',
+'蓬松松' => '蓬鬆鬆',
+'参绥' => '蔘綏',
+'葱郁' => '蔥鬱',
+'荞麦面' => '蕎麥麵',
+'芸薹' => '蕓薹',
+'荡来荡去' => '蕩來蕩去',
+'荡女' => '蕩女',
+'荡妇' => '蕩婦',
+'荡寇' => '蕩寇',
+'荡平' => '蕩平',
+'荡气' => '蕩氣',
+'荡涤' => '蕩滌',
+'荡漾' => '蕩漾',
+'荡然' => '蕩然',
+'荡产' => '蕩產',
+'荡舟' => '蕩舟',
+'荡船' => '蕩船',
+'荡荡' => '蕩蕩',
+'萧参' => '蕭蔘',
+'薄幸' => '薄倖',
+'薄干' => '薄幹',
+'姜啤' => '薑啤',
+'姜是老的辣' => '薑是老的辣',
+'姜末' => '薑末',
+'姜桂' => '薑桂',
+'姜母' => '薑母',
+'姜汁' => '薑汁',
+'姜汤' => '薑湯',
+'姜片' => '薑片',
+'姜糖' => '薑糖',
+'姜丝' => '薑絲',
+'姜老辣' => '薑老辣',
+'姜茶' => '薑茶',
+'姜蓉' => '薑蓉',
+'姜饼' => '薑餅',
+'姜黄' => '薑黃',
+'薙发' => '薙髮',
+'薝卜' => '薝蔔',
+'熏心' => '薰心',
+'熏染' => '薰染',
+'熏沐' => '薰沐',
+'熏习' => '薰習',
+'熏陶' => '薰陶',
+'熏风' => '薰風',
+'熏香' => '薰香',
+'苧悴' => '薴悴',
+'苧烯' => '薴烯',
+'薴烯' => '薴烯',
+'借以' => '藉以',
+'借助' => '藉助',
+'借口' => '藉口',
+'借寇兵' => '藉寇兵',
+'借手' => '藉手',
+'借故' => '藉故',
+'借机' => '藉機',
+'借此' => '藉此',
+'借由' => '藉由',
+'借箸代筹' => '藉箸代籌',
+'借资' => '藉資',
+'蓝淀' => '藍澱',
+'藏于' => '藏於',
+'藏历' => '藏曆',
+'藏历史' => '藏歷史',
+'藏蒙歌儿' => '藏矇歌兒',
+'藤席' => '藤蓆',
+'藤制' => '藤製',
+'药签' => '藥籤',
+'药面儿' => '藥麵兒',
+'苏崑' => '蘇崑',
+'苏昆' => '蘇崑',
+'苹果' => '蘋果',
+'苹果干' => '蘋果乾',
+'兰溪市' => '蘭谿市',
+'萝卜' => '蘿蔔',
+'萝卜干' => '蘿蔔乾',
+'虎须' => '虎鬚',
+'虎斗' => '虎鬥',
+'处于' => '處於',
+'虚夸' => '虛誇',
+'号志' => '號誌',
+'虫部' => '虫部',
+'蚊动牛斗' => '蚊動牛鬥',
+'蛇发女妖' => '蛇髮女妖',
+'蜂后' => '蜂后',
+'蜂涌' => '蜂湧',
+'蜂准' => '蜂準',
+'蜜里调油' => '蜜裡調油',
+'蜡月' => '蜡月',
+'蜡祭' => '蜡祭',
+'蝎虎' => '蝎虎',
+'蝎蝎螫螫' => '蝎蝎螫螫',
+'蝎谮' => '蝎譖',
+'虾面' => '蝦麵',
+'虮虱相吊' => '蟣蝨相弔',
+'蛏干' => '蟶乾',
+'蚁后' => '蟻后',
+'蟻后' => '蟻后',
+'蚃干' => '蠁幹',
+'蛮干' => '蠻幹',
+'血拼' => '血拚',
+'血余' => '血餘',
+'行事历' => '行事曆',
+'行事历史' => '行事歷史',
+'行凶' => '行兇',
+'行家里手' => '行家裡手',
+'行于' => '行於',
+'卫后庄公' => '衛後莊公',
+'卫星钟' => '衛星鐘',
+'冲上' => '衝上',
+'冲下' => '衝下',
+'冲来' => '衝來',
+'冲倒' => '衝倒',
+'冲冠' => '衝冠',
+'冲出' => '衝出',
+'冲到' => '衝到',
+'冲刺' => '衝刺',
+'冲克' => '衝剋',
+'冲力' => '衝力',
+'冲劲' => '衝勁',
+'冲动' => '衝動',
+'冲去' => '衝去',
+'冲口' => '衝口',
+'冲垮' => '衝垮',
+'冲堂' => '衝堂',
+'冲坚陷阵' => '衝堅陷陣',
+'冲压' => '衝壓',
+'冲天炮' => '衝天炮',
+'冲州撞府' => '衝州撞府',
+'冲心' => '衝心',
+'冲掉' => '衝掉',
+'冲撞' => '衝撞',
+'冲击' => '衝擊',
+'冲散' => '衝散',
+'冲杀' => '衝殺',
+'冲决' => '衝決',
+'冲波' => '衝波',
+'冲浪' => '衝浪',
+'冲激' => '衝激',
+'冲然' => '衝然',
+'冲盹' => '衝盹',
+'冲着' => '衝着',
+'冲破' => '衝破',
+'冲程' => '衝程',
+'冲突' => '衝突',
+'冲线' => '衝線',
+'冲要' => '衝要',
+'冲起' => '衝起',
+'冲车' => '衝車',
+'冲进' => '衝進',
+'冲过' => '衝過',
+'冲量' => '衝量',
+'冲锋' => '衝鋒',
+'冲锋枪' => '衝鋒鎗',
+'冲陷' => '衝陷',
+'冲头阵' => '衝頭陣',
+'冲风' => '衝風',
+'衡鉴' => '衡鑑',
+'表面包' => '表面包',
+'衷于' => '衷於',
+'袋杆' => '袋桿',
+'袋里' => '袋裡',
+'袋表' => '袋錶',
+'袖里' => '袖裡',
+'被废后' => '被廢後',
+'被系上' => '被繫上',
+'被里' => '被裡',
+'被夸' => '被誇',
+'被发佯狂' => '被髮佯狂',
+'被发入山' => '被髮入山',
+'被发左衽' => '被髮左衽',
+'被发缨冠' => '被髮纓冠',
+'被发阳狂' => '被髮陽狂',
+'夹衣' => '袷衣',
+'夹裙' => '袷裙',
+'裁并' => '裁併',
+'裁制' => '裁製',
+'里水镇' => '裏水鎮',
+'里海' => '裏海',
+'里白' => '裏白',
+'里运河' => '裏運河',
+'补于' => '補於',
+'补注' => '補註',
+'装折' => '裝摺',
+'里勾外连' => '裡勾外連',
+'里屋' => '裡屋',
+'里层' => '裡層',
+'里带' => '裡帶',
+'里弦' => '裡弦',
+'里应外合' => '裡應外合',
+'里脊' => '裡脊',
+'里衣' => '裡衣',
+'里通外国' => '裡通外國',
+'里通外敌' => '裡通外敵',
+'里边' => '裡邊',
+'里间' => '裡間',
+'里面' => '裡面',
+'里面包' => '裡面包',
+'里头' => '裡頭',
+'制件' => '製件',
+'制作' => '製作',
+'制做' => '製做',
+'制备' => '製備',
+'制冰' => '製冰',
+'制冷' => '製冷',
+'制剂' => '製劑',
+'制取' => '製取',
+'制品' => '製品',
+'制图' => '製圖',
+'制得' => '製得',
+'制成' => '製成',
+'制毒' => '製毒',
+'制法' => '製法',
+'制浆' => '製漿',
+'制片' => '製片',
+'制版' => '製版',
+'制程' => '製程',
+'制糖' => '製糖',
+'制纸' => '製紙',
+'制药' => '製藥',
+'制衣' => '製衣',
+'制表键' => '製表鍵',
+'制贩' => '製販',
+'制造' => '製造',
+'制革' => '製革',
+'制鞋' => '製鞋',
+'制盐' => '製鹽',
+'复元音' => '複元音',
+'复函数' => '複函數',
+'复分数' => '複分數',
+'复分析' => '複分析',
+'复分解' => '複分解',
+'复列' => '複列',
+'复利' => '複利',
+'复印' => '複印',
+'复句' => '複句',
+'复合' => '複合',
+'复壁' => '複壁',
+'复姓' => '複姓',
+'复字键' => '複字鍵',
+'复审' => '複審',
+'复写' => '複寫',
+'复对数' => '複對數',
+'复平面' => '複平面',
+'复式' => '複式',
+'复数' => '複數',
+'复方' => '複方',
+'复本' => '複本',
+'复查' => '複查',
+'复次' => '複次',
+'复比' => '複比',
+'复决' => '複決',
+'复流' => '複流',
+'复测' => '複測',
+'复目' => '複目',
+'复眼' => '複眼',
+'复种' => '複種',
+'复线' => '複線',
+'复习' => '複習',
+'复色' => '複色',
+'复叶' => '複葉',
+'复制' => '複製',
+'复诊' => '複診',
+'复评' => '複評',
+'复词' => '複詞',
+'复试' => '複試',
+'复课' => '複課',
+'复议' => '複議',
+'复变函数' => '複變函數',
+'复赛' => '複賽',
+'复辅音' => '複輔音',
+'复述' => '複述',
+'复选' => '複選',
+'复钱' => '複錢',
+'复阅' => '複閱',
+'复杂' => '複雜',
+'复音' => '複音',
+'复韵' => '複韻',
+'褒赞' => '褒讚',
+'衬里' => '襯裡',
+'西井里' => '西井里',
+'西周钟' => '西周鐘',
+'西昆' => '西崑',
+'西岳' => '西嶽',
+'西历' => '西曆',
+'西历史' => '西歷史',
+'西湖里' => '西湖里',
+'西米谷' => '西米谷',
+'西西里' => '西西里',
+'西谷米' => '西谷米',
+'西游' => '西遊',
+'要自制' => '要自制',
+'要冲' => '要衝',
+'复信' => '覆信',
+'复核' => '覆核',
+'见于' => '見於',
+'见棱见角' => '見稜見角',
+'见素抱朴' => '見素抱樸',
+'见钟不打' => '見鐘不打',
+'规范' => '規範',
+'视于' => '視於',
+'观采' => '觀採',
+'角抵' => '角牴',
+'角落发' => '角落發',
+'角落里' => '角落裡',
+'觚棱' => '觚稜',
+'解雇' => '解僱',
+'解封后' => '解封後',
+'解铃仍须系铃人' => '解鈴仍須繫鈴人',
+'解铃还须系铃人' => '解鈴還須繫鈴人',
+'解发佯狂' => '解髮佯狂',
+'触须' => '觸鬚',
+'言云' => '言云',
+'言大而夸' => '言大而夸',
+'言里' => '言裡',
+'言辩而确' => '言辯而确',
+'订制' => '訂製',
+'计划' => '計劃',
+'计时表' => '計時錶',
+'托了' => '託了',
+'托事' => '託事',
+'托交' => '託交',
+'托人' => '託人',
+'托付' => '託付',
+'托克逊' => '託克遜',
+'托儿' => '託兒',
+'托古讽今' => '託古諷今',
+'托名' => '託名',
+'托命' => '託命',
+'托咎' => '託咎',
+'托梦' => '託夢',
+'托孤' => '託孤',
+'托庇' => '託庇',
+'托故' => '託故',
+'托疾' => '託疾',
+'托病' => '託病',
+'托管' => '託管',
+'托言' => '託言',
+'托词' => '託詞',
+'托买' => '託買',
+'托卖' => '託賣',
+'托身' => '託身',
+'托辞' => '託辭',
+'托运' => '託運',
+'托过' => '託過',
+'托里县' => '託里縣',
+'托附' => '託附',
+'许愿起经' => '許愿起經',
+'許聖杰' => '許聖杰',
+'注上' => '註上',
+'注册' => '註冊',
+'注失' => '註失',
+'注定' => '註定',
+'注明' => '註明',
+'注标' => '註標',
+'注生娘娘' => '註生娘娘',
+'注疏' => '註疏',
+'注脚' => '註腳',
+'注解' => '註解',
+'注记' => '註記',
+'注译' => '註譯',
+'注销' => '註銷',
+'注:' => '註:',
+'证谏' => '証諫',
+'评断发' => '評斷發',
+'评注' => '評註',
+'评鉴' => '評鑑',
+'词干' => '詞幹',
+'词汇' => '詞彙',
+'词余' => '詞餘',
+'询于' => '詢於',
+'试制' => '試製',
+'詩云' => '詩云',
+'诗云' => '詩云',
+'诗赞' => '詩讚',
+'诗钟' => '詩鐘',
+'诗余' => '詩餘',
+'话里有话' => '話裡有話',
+'该钟' => '該鐘',
+'详征博引' => '詳徵博引',
+'详注' => '詳註',
+'诔赞' => '誄讚',
+'夸下海口' => '誇下海口',
+'夸了' => '誇了',
+'夸人' => '誇人',
+'夸他' => '誇他',
+'夸你' => '誇你',
+'夸来夸去' => '誇來誇去',
+'夸别' => '誇別',
+'夸功' => '誇功',
+'夸胜道强' => '誇勝道強',
+'夸口' => '誇口',
+'夸嘴' => '誇嘴',
+'夸多斗靡' => '誇多鬥靡',
+'夸大' => '誇大',
+'夸她' => '誇她',
+'夸姣' => '誇姣',
+'夸官' => '誇官',
+'夸容' => '誇容',
+'夸张' => '誇張',
+'夸强说会' => '誇強說會',
+'夸得' => '誇得',
+'夸成' => '誇成',
+'夸我' => '誇我',
+'夸才' => '誇才',
+'夸毗' => '誇毗',
+'夸海口' => '誇海口',
+'夸奖' => '誇獎',
+'夸示' => '誇示',
+'夸称' => '誇稱',
+'夸耀' => '誇耀',
+'夸能' => '誇能',
+'夸能斗智' => '誇能鬥智',
+'夸诩' => '誇詡',
+'夸夸' => '誇誇',
+'夸夸其谈' => '誇誇其談',
+'夸诞' => '誇誕',
+'夸说' => '誇說',
+'夸赞' => '誇讚',
+'夸起' => '誇起',
+'夸辩' => '誇辯',
+'夸过' => '誇過',
+'夸饰' => '誇飾',
+'夸丽' => '誇麗',
+'志哀' => '誌哀',
+'志喜' => '誌喜',
+'志庆' => '誌慶',
+'志异' => '誌異',
+'认准' => '認準',
+'诱奸' => '誘姦',
+'语云' => '語云',
+'语汇' => '語彙',
+'語有云' => '語有云',
+'语有云' => '語有云',
+'语法里' => '語法裡',
+'语里' => '語裡',
+'诚征' => '誠徵',
+'诚朴' => '誠樸',
+'诬蔑' => '誣衊',
+'说不准' => '說不準',
+'谁干的' => '誰幹的',
+'课征' => '課徵',
+'课余' => '課餘',
+'调准' => '調準',
+'调制' => '調製',
+'调表' => '調錶',
+'调钟表' => '調鐘錶',
+'谈征' => '談徵',
+'请君入瓮' => '請君入甕',
+'请托' => '請託',
+'咨询' => '諮詢',
+'诸余' => '諸餘',
+'谋干' => '謀幹',
+'謝杰' => '謝杰',
+'谢杰' => '謝杰',
+'谢华后' => '謝華后',
+'谬采虚声' => '謬採虛聲',
+'谬赞' => '謬讚',
+'謷丑' => '謷醜',
+'謹愿' => '謹愿',
+'谨愿' => '謹愿',
+'哗噪' => '譁噪',
+'哗嚣' => '譁囂',
+'哗然' => '譁然',
+'哗众' => '譁眾',
+'哗笑' => '譁笑',
+'哗变' => '譁變',
+'噪诈' => '譟詐',
+'警世钟' => '警世鐘',
+'警报钟' => '警報鐘',
+'警示钟' => '警示鐘',
+'警钟' => '警鐘',
+'译制' => '譯製',
+'译注' => '譯註',
+'护发' => '護髮',
+'变征' => '變徵',
+'变丑' => '變醜',
+'仇隙' => '讎隙',
+'赞一个' => '讚一個',
+'赞不绝口' => '讚不絕口',
+'赞佩' => '讚佩',
+'赞呗' => '讚唄',
+'赞叹' => '讚嘆',
+'赞扬' => '讚揚',
+'赞乐' => '讚樂',
+'赞歌' => '讚歌',
+'赞美' => '讚美',
+'赞羡' => '讚羨',
+'赞许' => '讚許',
+'赞词' => '讚詞',
+'赞誉' => '讚譽',
+'赞赏' => '讚賞',
+'赞辞' => '讚辭',
+'赞颂' => '讚頌',
+'谷子敬' => '谷子敬',
+'豆干' => '豆乾',
+'豆腐干' => '豆腐乾',
+'竖起脊梁' => '豎起脊梁',
+'丰度' => '豐度',
+'丰滨' => '豐濱',
+'丰滨乡' => '豐濱鄉',
+'丰台' => '豐臺',
+'豔后' => '豔后',
+'象征' => '象徵',
+'贪欲' => '貪慾',
+'贵价' => '貴价',
+'貴子里' => '貴子里',
+'贵干' => '貴幹',
+'贵征' => '貴徵',
+'买凶' => '買兇',
+'买断发' => '買斷發',
+'費米面' => '費米面',
+'费米面' => '費米面',
+'贻范' => '貽範',
+'賈后' => '賈后',
+'贾后' => '賈后',
+'赈饥' => '賑饑',
+'赏赞' => '賞讚',
+'賢后' => '賢后',
+'贤后' => '賢后',
+'卖断发' => '賣斷發',
+'賦范' => '賦范',
+'赋范' => '賦范',
+'质数里' => '質數裡',
+'质朴' => '質樸',
+'赌后' => '賭后',
+'赌台' => '賭檯',
+'赌斗' => '賭鬥',
+'购并' => '購併',
+'购买欲' => '購買慾',
+'赢余' => '贏餘',
+'赤术' => '赤朮',
+'赤绳系足' => '赤繩繫足',
+'走回路' => '走回路',
+'起哄' => '起鬨',
+'超级杯' => '超級盃',
+'超赞' => '超讚',
+'赶制' => '趕製',
+'赶面棍' => '趕麵棍',
+'赵威后' => '趙威后',
+'赵惠后' => '趙惠后',
+'赵治勋' => '趙治勳',
+'趱干' => '趲幹',
+'足于' => '足於',
+'足球台' => '足球台',
+'跌扑' => '跌扑',
+'路图里' => '路圖裡',
+'路签' => '路籤',
+'路面' => '路面',
+'跳梁小丑' => '跳樑小丑',
+'跳荡' => '跳蕩',
+'局蹐' => '跼蹐',
+'局躅' => '跼躅',
+'踡局' => '踡跼',
+'逾闲' => '踰閑',
+'蹒局' => '蹣跼',
+'蹪于' => '蹪於',
+'蹭棱子' => '蹭稜子',
+'躁郁' => '躁鬱',
+'身于' => '身於',
+'身体发肤' => '身體髮膚',
+'躯干' => '軀幹',
+'车库里' => '車庫裡',
+'车站里' => '車站裡',
+'车里' => '車裡',
+'车里雅宾斯克' => '車里雅賓斯克',
+'轨范' => '軌範',
+'轩辟' => '軒闢',
+'较于' => '較於',
+'挽曲' => '輓曲',
+'挽歌' => '輓歌',
+'挽联' => '輓聯',
+'挽词' => '輓詞',
+'挽诗' => '輓詩',
+'挽车' => '輓車',
+'挽输' => '輓輸',
+'挽辞' => '輓辭',
+'轻于' => '輕於',
+'轻松' => '輕鬆',
+'轻松松' => '輕鬆鬆',
+'轮奸' => '輪姦',
+'轮回' => '輪迴',
+'转向往' => '轉向往',
+'转托' => '轉託',
+'转斗千里' => '轉鬥千里',
+'辛丑' => '辛丑',
+'辟谷' => '辟穀',
+'辣面' => '辣麵',
+'办公台' => '辦公檯',
+'辞汇' => '辭彙',
+'辫发' => '辮髮',
+'辩斗' => '辯鬥',
+'辰溪县' => '辰谿縣',
+'农历' => '農曆',
+'农历史' => '農歷史',
+'农民历' => '農民曆',
+'农民历史' => '農民歷史',
+'迂回' => '迂迴',
+'近日无仇' => '近日無讎',
+'返朴' => '返樸',
+'迥然回异' => '迥然迴異',
+'迫于' => '迫於',
+'回光返照' => '迴光返照',
+'回圈' => '迴圈',
+'回廊' => '迴廊',
+'回形夹' => '迴形夾',
+'回文序列' => '迴文序列',
+'回文数' => '迴文數',
+'回文构词' => '迴文構詞',
+'回文结构' => '迴文結構',
+'回文联' => '迴文聯',
+'回文诗' => '迴文詩',
+'回文锦' => '迴文錦',
+'回旋' => '迴旋',
+'回环' => '迴環',
+'回纹针' => '迴紋針',
+'回绕' => '迴繞',
+'回翔' => '迴翔',
+'回肠' => '迴腸',
+'回肠荡气' => '迴腸盪氣',
+'回荡' => '迴蕩',
+'回诵' => '迴誦',
+'回路' => '迴路',
+'回转' => '迴轉',
+'回递性' => '迴遞性',
+'回避' => '迴避',
+'回銮' => '迴鑾',
+'回响' => '迴響',
+'回风' => '迴風',
+'迷于' => '迷於',
+'迷蒙' => '迷濛',
+'追凶' => '追兇',
+'退伙' => '退夥',
+'逆钟' => '逆鐘',
+'逆钟向' => '逆鐘向',
+'逆风后' => '逆風後',
+'逋发' => '逋髮',
+'逍遥游' => '逍遙遊',
+'透辟' => '透闢',
+'这出世' => '這出世',
+'这出乎' => '這出乎',
+'这出人' => '這出人',
+'这出版' => '這出版',
+'这出现' => '這出現',
+'这出生' => '這出生',
+'这出色' => '這出色',
+'这出身' => '這出身',
+'这出道' => '這出道',
+'这只不' => '這只不',
+'这只不过' => '這只不過',
+'这只允' => '這只允',
+'这只包括' => '這只包括',
+'这只可' => '這只可',
+'这只在' => '這只在',
+'这只容' => '這只容',
+'这只应' => '這只應',
+'这只采' => '這只採',
+'这只是' => '這只是',
+'这只会' => '這只會',
+'这只比' => '這只比',
+'这只用' => '這只用',
+'这只能' => '這只能',
+'这只限' => '這只限',
+'这只需' => '這只需',
+'这只须' => '這只須',
+'这伙人' => '這夥人',
+'这里' => '這裡',
+'这钟' => '這鐘',
+'这只' => '這隻',
+'这么干' => '這麼幹',
+'这出' => '這齣',
+'通奸' => '通姦',
+'通心面' => '通心麵',
+'通于' => '通於',
+'通历' => '通曆',
+'通历史' => '通歷史',
+'通鉴' => '通鑑',
+'逞凶斗狠' => '逞兇鬥狠',
+'造钟' => '造鐘',
+'连三并四' => '連三併四',
+'连采' => '連採',
+'连发式' => '連發式',
+'连系' => '連繫',
+'周游' => '週遊',
+'进两出' => '進兩出',
+'进制' => '進制',
+'進制' => '進制',
+'逼并' => '逼併',
+'遇风后' => '遇風後',
+'游了' => '遊了',
+'游人' => '遊人',
+'游仙' => '遊仙',
+'游伴' => '遊伴',
+'游侠' => '遊俠',
+'游冶' => '遊冶',
+'游刃' => '遊刃',
+'游动' => '遊動',
+'游园' => '遊園',
+'游子' => '遊子',
+'游学' => '遊學',
+'游客' => '遊客',
+'游宦' => '遊宦',
+'游山玩水' => '遊山玩水',
+'游必有方' => '遊必有方',
+'游憩' => '遊憩',
+'游戏' => '遊戲',
+'游戏里' => '遊戲裡',
+'游手好闲' => '遊手好閒',
+'游方' => '遊方',
+'游星' => '遊星',
+'游乐' => '遊樂',
+'游标卡尺' => '遊標卡尺',
+'游历' => '遊歷',
+'游民' => '遊民',
+'游河' => '遊河',
+'游牧' => '遊牧',
+'游猎' => '遊獵',
+'游玩' => '遊玩',
+'游目骋怀' => '遊目騁懷',
+'游程' => '遊程',
+'游丝' => '遊絲',
+'游美学务' => '遊美學務',
+'游兴' => '遊興',
+'游船' => '遊船',
+'游艇' => '遊艇',
+'游荡' => '遊蕩',
+'游艺' => '遊藝',
+'游行' => '遊行',
+'游街' => '遊街',
+'游览' => '遊覽',
+'游记' => '遊記',
+'游说' => '遊說',
+'游资' => '遊資',
+'游走' => '遊走',
+'游踪' => '遊蹤',
+'游轮' => '遊輪',
+'游逛' => '遊逛',
+'游错' => '遊錯',
+'游骑兵' => '遊騎兵',
+'游魂' => '遊魂',
+'过于' => '過於',
+'过水面' => '過水麵',
+'遏制' => '遏制',
+'道范' => '道範',
+'逊于' => '遜於',
+'递回' => '遞迴',
+'远游' => '遠遊',
+'遨游' => '遨遊',
+'适于' => '適於',
+'遮丑' => '遮醜',
+'迁于' => '遷於',
+'选手表明' => '選手表明',
+'选手表决' => '選手表決',
+'选手表现' => '選手表現',
+'选手表示' => '選手表示',
+'选手表达' => '選手表達',
+'遗传钟' => '遺傳鐘',
+'遗范' => '遺範',
+'遗迹' => '遺蹟',
+'辽沈' => '遼瀋',
+'邀天之幸' => '邀天之倖',
+'还采' => '還採',
+'还冲' => '還衝',
+'邋里邋遢' => '邋裡邋遢',
+'那只不过' => '那只不過',
+'那只包括' => '那只包括',
+'那只可' => '那只可',
+'那只在' => '那只在',
+'那只怕' => '那只怕',
+'那只应' => '那只應',
+'那只是' => '那只是',
+'那只会' => '那只會',
+'那只有' => '那只有',
+'那只比' => '那只比',
+'那只用' => '那只用',
+'那只能' => '那只能',
+'那只限' => '那只限',
+'那只需' => '那只需',
+'那只须' => '那只須',
+'那卷' => '那捲',
+'那里' => '那裡',
+'那只' => '那隻',
+'邱于庭' => '邱于庭',
+'郁朴' => '郁樸',
+'郁郁菲菲' => '郁郁菲菲',
+'郁郁青青' => '郁郁青青',
+'郊游' => '郊遊',
+'郘钟' => '郘鐘',
+'部子里' => '部子里',
+'部落发' => '部落發',
+'郭后' => '郭后',
+'都市里' => '都市裡',
+'都于' => '都於',
+'乡愿' => '鄉愿',
+'鄉愿' => '鄉愿',
+'郑凯云' => '鄭凱云',
+'鄭凱云' => '鄭凱云',
+'配制饲料' => '配制飼料',
+'配图里' => '配圖裡',
+'配制' => '配製',
+'酒帘' => '酒帘',
+'酒气冲天' => '酒氣衝天',
+'酒坛' => '酒罈',
+'酒肴' => '酒肴',
+'酒曲' => '酒麴',
+'酒麹' => '酒麴',
+'酥松' => '酥鬆',
+'酸姜' => '酸薑',
+'腌制' => '醃製',
+'醇朴' => '醇樸',
+'醉于' => '醉於',
+'醋坛' => '醋罈',
+'丑丫头' => '醜丫頭',
+'丑事' => '醜事',
+'丑人' => '醜人',
+'丑侪' => '醜儕',
+'丑八怪' => '醜八怪',
+'丑剌剌' => '醜剌剌',
+'丑剧' => '醜劇',
+'丑化' => '醜化',
+'丑史' => '醜史',
+'丑名' => '醜名',
+'丑吒' => '醜吒',
+'丑地' => '醜地',
+'丑夷' => '醜夷',
+'丑女' => '醜女',
+'丑女效颦' => '醜女效顰',
+'丑奴儿' => '醜奴兒',
+'丑妇' => '醜婦',
+'丑媳' => '醜媳',
+'丑媳妇' => '醜媳婦',
+'丑小鸭' => '醜小鴨',
+'丑巴怪' => '醜巴怪',
+'丑徒' => '醜徒',
+'丑恶' => '醜惡',
+'丑态' => '醜態',
+'丑毙了' => '醜斃了',
+'丑于' => '醜於',
+'丑末' => '醜末',
+'丑样' => '醜樣',
+'丑死' => '醜死',
+'丑比' => '醜比',
+'丑沮' => '醜沮',
+'丑男' => '醜男',
+'丑闻' => '醜聞',
+'丑声' => '醜聲',
+'丑声远播' => '醜聲遠播',
+'丑脸' => '醜臉',
+'丑虏' => '醜虜',
+'丑行' => '醜行',
+'丑言' => '醜言',
+'丑诋' => '醜詆',
+'丑话' => '醜話',
+'丑语' => '醜語',
+'丑贼生' => '醜賊生',
+'丑辞' => '醜辭',
+'丑辱' => '醜辱',
+'丑逆' => '醜逆',
+'丑丑' => '醜醜',
+'丑陋' => '醜陋',
+'丑杂' => '醜雜',
+'丑头怪脸' => '醜頭怪臉',
+'丑类' => '醜類',
+'酿制' => '釀製',
+'衅钟' => '釁鐘',
+'采石之役' => '采石之役',
+'采石之战' => '采石之戰',
+'采石之戰' => '采石之戰',
+'采石矶' => '采石磯',
+'采石磯' => '采石磯',
+'里海大学' => '里海大學',
+'里海大學' => '里海大學',
+'里海崖' => '里海崖',
+'里海茨' => '里海茨',
+'里铺' => '里舖',
+'重回' => '重回',
+'重折' => '重摺',
+'重于' => '重於',
+'重罗面' => '重羅麵',
+'重制' => '重製',
+'重复' => '重複',
+'重托' => '重託',
+'重游' => '重遊',
+'野姜' => '野薑',
+'野游' => '野遊',
+'量不准' => '量不準',
+'厘改' => '釐改',
+'厘整' => '釐整',
+'厘正' => '釐正',
+'厘毫' => '釐毫',
+'厘清' => '釐清',
+'厘订' => '釐訂',
+'厘革' => '釐革',
+'金仆姑' => '金僕姑',
+'金城里' => '金城里',
+'金范' => '金範',
+'金圣叹' => '金聖歎',
+'金表情' => '金表情',
+'金表态' => '金表態',
+'金表扬' => '金表揚',
+'金表明' => '金表明',
+'金表演' => '金表演',
+'金表现' => '金表現',
+'金表示' => '金表示',
+'金表达' => '金表達',
+'金表露' => '金表露',
+'金表面' => '金表面',
+'金装玉里' => '金裝玉裡',
+'金溪县' => '金谿縣',
+'金链' => '金鍊',
+'金钟' => '金鐘',
+'金发' => '金髮',
+'钩心斗角' => '鈎心鬥角',
+'银朱' => '銀硃',
+'银发' => '銀髮',
+'铜范' => '銅範',
+'铜制' => '銅製',
+'铜钟' => '銅鐘',
+'铯钟' => '銫鐘',
+'铝制' => '鋁製',
+'钢之炼金术师' => '鋼之鍊金術師',
+'钢梁' => '鋼樑',
+'钢制' => '鋼製',
+'录制' => '錄製',
+'锤炼' => '錘鍊',
+'钱谷' => '錢穀',
+'钱范' => '錢範',
+'锦卤' => '錦滷',
+'锦绣花园' => '錦綉花園',
+'表停' => '錶停',
+'表冠' => '錶冠',
+'表带' => '錶帶',
+'表快' => '錶快',
+'表慢' => '錶慢',
+'表板' => '錶板',
+'表王' => '錶王',
+'表盘' => '錶盤',
+'表蒙子' => '錶蒙子',
+'表转' => '錶轉',
+'表速' => '錶速',
+'表针' => '錶針',
+'炼冶' => '鍊冶',
+'炼句' => '鍊句',
+'炼字' => '鍊字',
+'炼师' => '鍊師',
+'炼度' => '鍊度',
+'炼形' => '鍊形',
+'炼气' => '鍊氣',
+'炼汞' => '鍊汞',
+'炼石' => '鍊石',
+'链表' => '鍊表',
+'炼贫' => '鍊貧',
+'炼金术' => '鍊金術',
+'锲而不舍' => '鍥而不捨',
+'镰仓' => '鎌倉',
+'镜图里' => '鏡圖裡',
+'锈病' => '鏽病',
+'锈菌' => '鏽菌',
+'锈蚀' => '鏽蝕',
+'钟上' => '鐘上',
+'钟下' => '鐘下',
+'钟不' => '鐘不',
+'钟不扣不鸣' => '鐘不扣不鳴',
+'钟不撞不鸣' => '鐘不撞不鳴',
+'钟不敲不响' => '鐘不敲不響',
+'钟不空则哑' => '鐘不空則啞',
+'钟乳洞' => '鐘乳洞',
+'钟乳石' => '鐘乳石',
+'钟停' => '鐘停',
+'钟匠' => '鐘匠',
+'钟口' => '鐘口',
+'钟在寺里' => '鐘在寺裡',
+'钟塔' => '鐘塔',
+'钟壁' => '鐘壁',
+'钟太' => '鐘太',
+'钟好' => '鐘好',
+'钟山' => '鐘山',
+'钟左右' => '鐘左右',
+'钟差' => '鐘差',
+'钟座' => '鐘座',
+'钟形' => '鐘形',
+'钟形虫' => '鐘形蟲',
+'钟律' => '鐘律',
+'钟快' => '鐘快',
+'钟慢' => '鐘慢',
+'钟摆' => '鐘擺',
+'钟敲' => '鐘敲',
+'钟有' => '鐘有',
+'钟楼' => '鐘樓',
+'钟模' => '鐘模',
+'钟没' => '鐘沒',
+'钟漏' => '鐘漏',
+'钟王' => '鐘王',
+'钟琴' => '鐘琴',
+'钟发音' => '鐘發音',
+'钟的' => '鐘的',
+'钟盘' => '鐘盤',
+'钟相' => '鐘相',
+'钟磬' => '鐘磬',
+'钟纽' => '鐘紐',
+'钟罩' => '鐘罩',
+'钟声' => '鐘聲',
+'钟腰' => '鐘腰',
+'钟花' => '鐘花',
+'钟螺' => '鐘螺',
+'钟行' => '鐘行',
+'钟表面' => '鐘表面',
+'钟被' => '鐘被',
+'钟调' => '鐘調',
+'钟身' => '鐘身',
+'钟速' => '鐘速',
+'钟表' => '鐘錶',
+'钟表停' => '鐘錶停',
+'钟表快' => '鐘錶快',
+'钟表慢' => '鐘錶慢',
+'钟表王' => '鐘錶王',
+'钟表盘' => '鐘錶盤',
+'钟表速' => '鐘錶速',
+'钟关' => '鐘關',
+'钟陈列' => '鐘陳列',
+'钟面' => '鐘面',
+'钟响' => '鐘響',
+'钟顶' => '鐘頂',
+'钟头' => '鐘頭',
+'钟体' => '鐘體',
+'钟鸣' => '鐘鳴',
+'钟点' => '鐘點',
+'钟鼎' => '鐘鼎',
+'钟鼓' => '鐘鼓',
+'铁锈' => '鐵鏽',
+'铁钟' => '鐵鐘',
+'铸钟' => '鑄鐘',
+'鉴别' => '鑑別',
+'鉴古' => '鑑古',
+'鉴定' => '鑑定',
+'鉴察' => '鑑察',
+'鉴往知来' => '鑑往知來',
+'鉴戒' => '鑑戒',
+'鉴湖' => '鑑湖',
+'鉴藏' => '鑑藏',
+'鉴谅' => '鑑諒',
+'鉴证' => '鑑證',
+'鉴识' => '鑑識',
+'鉴赏' => '鑑賞',
+'鉴于' => '鑒於',
+'长几' => '長几',
+'长于' => '長於',
+'长历' => '長曆',
+'长历史' => '長歷史',
+'长发公主' => '長髮公主',
+'长发妹' => '長髮妹',
+'长发姑娘' => '長髮姑娘',
+'长胡' => '長鬍',
+'门帘' => '門帘',
+'门吊儿' => '門弔兒',
+'门里' => '門裡',
+'闫怀礼' => '閆懷禮',
+'開山辟谷' => '開山辟谷',
+'开山辟谷' => '開山闢谷',
+'开吊' => '開弔',
+'开征' => '開徵',
+'开采' => '開採',
+'开发' => '開發',
+'开辟' => '開闢',
+'开哄' => '開鬨',
+'闲邪' => '閑邪',
+'闲情逸致' => '閒情逸緻',
+'闲荡' => '閒蕩',
+'闲游' => '閒遊',
+'间不容发' => '間不容髮',
+'间里' => '間裡',
+'闵采尔' => '閔採爾',
+'阁府' => '閤府',
+'闺范' => '閨範',
+'阃范' => '閫範',
+'闯荡' => '闖蕩',
+'闯炼' => '闖鍊',
+'关系' => '關係',
+'关弓与我确' => '關弓與我确',
+'关于' => '關於',
+'辟佛' => '闢佛',
+'辟作' => '闢作',
+'辟划' => '闢劃',
+'辟土' => '闢土',
+'辟地' => '闢地',
+'辟室' => '闢室',
+'辟建' => '闢建',
+'辟为' => '闢為',
+'辟田' => '闢田',
+'辟筑' => '闢築',
+'辟谣' => '闢謠',
+'辟辟' => '闢辟',
+'辟邪以律' => '闢邪以律',
+'防水表' => '防水錶',
+'防御' => '防禦',
+'防范' => '防範',
+'防锈' => '防鏽',
+'阻于' => '阻於',
+'阿里' => '阿里',
+'附于' => '附於',
+'附注' => '附註',
+'限制' => '限制',
+'院里' => '院裡',
+'陪吊' => '陪弔',
+'阴干' => '陰乾',
+'阴历' => '陰曆',
+'阴历史' => '陰歷史',
+'阴沟里翻船' => '陰溝裡翻船',
+'阴郁' => '陰鬱',
+'陳冲' => '陳冲',
+'陳士杰' => '陳士杰',
+'陈升' => '陳昇',
+'陈有后' => '陳有后',
+'陳有后' => '陳有后',
+'陈杰' => '陳杰',
+'陳杰' => '陳杰',
+'陈炼' => '陳鍊',
+'陆游' => '陸遊',
+'阳春面' => '陽春麵',
+'阳历' => '陽曆',
+'阳历史' => '陽歷史',
+'阳谷' => '陽穀',
+'隆准许' => '隆准許',
+'隆准' => '隆準',
+'随于' => '隨於',
+'隐占' => '隱佔',
+'隐几' => '隱几',
+'隐于' => '隱於',
+'只字' => '隻字',
+'只影' => '隻影',
+'只手遮天' => '隻手遮天',
+'只眼' => '隻眼',
+'只言片语' => '隻言片語',
+'只身' => '隻身',
+'雄斗斗' => '雄斗斗',
+'雅范' => '雅範',
+'集数里' => '集數裡',
+'集于' => '集於',
+'集里' => '集裡',
+'集游法' => '集遊法',
+'雕梁画栋' => '雕樑畫棟',
+'双折射' => '雙折射',
+'双折' => '雙摺',
+'双胜类' => '雙胜類',
+'双雕' => '雙鵰',
+'杂合面儿' => '雜合麵兒',
+'杂志' => '雜誌',
+'杂面' => '雜麵',
+'鸡吵鹅斗' => '雞吵鵝鬥',
+'鸡奸' => '雞姦',
+'鸡争鹅斗' => '雞爭鵝鬥',
+'鸡丝' => '雞絲',
+'鸡丝面' => '雞絲麵',
+'鸡腿面' => '雞腿麵',
+'鸡蛋里挑骨头' => '雞蛋裡挑骨頭',
+'鸡只' => '雞隻',
+'离于' => '離於',
+'难舍' => '難捨',
+'难于' => '難於',
+'雨蒙蒙' => '雨濛濛',
+'雪窗萤几' => '雪窗螢几',
+'雪里' => '雪裡',
+'雪里红' => '雪裡紅',
+'雪里蕻' => '雪裡蕻',
+'云吞' => '雲吞',
+'云笈七签' => '雲笈七籤',
+'云里雾里' => '雲裡霧裡',
+'云游' => '雲遊',
+'云须' => '雲鬚',
+'零个' => '零個',
+'零周后' => '零周後',
+'零天后' => '零天後',
+'零年' => '零年',
+'零只' => '零隻',
+'零余' => '零餘',
+'电子表格' => '電子表格',
+'电子制表' => '電子製表',
+'电子钟' => '電子鐘',
+'电子钟表' => '電子鐘錶',
+'电影后' => '電影後',
+'电影里' => '電影裡',
+'电梯里' => '電梯裡',
+'电波钟' => '電波鐘',
+'电码表' => '電碼表',
+'电冲' => '電衝',
+'电视台风' => '電視台風',
+'电视里' => '電視裡',
+'电表' => '電錶',
+'电钟' => '電鐘',
+'震栗' => '震慄',
+'霉气冲天' => '霉氣衝天',
+'沾化' => '霑化',
+'沾益' => '霑益',
+'雾里' => '霧裡',
+'露丑' => '露醜',
+'霁范' => '霽範',
+'灵昆' => '靈崑',
+'青山一发' => '青山一髮',
+'青霉' => '青黴',
+'非常准' => '非常準',
+'面包住' => '面包住',
+'面包含' => '面包含',
+'面包围' => '面包圍',
+'面包容' => '面包容',
+'面包庇' => '面包庇',
+'面包厢' => '面包廂',
+'面包抄' => '面包抄',
+'面包括' => '面包括',
+'面包揽' => '面包攬',
+'面包涵' => '面包涵',
+'面包管' => '面包管',
+'面包扎' => '面包紮',
+'面包罗' => '面包羅',
+'面包着' => '面包著',
+'面包藏' => '面包藏',
+'面包装' => '面包裝',
+'面包裹' => '面包裹',
+'面包起' => '面包起',
+'面包办' => '面包辦',
+'面店铺' => '面店鋪',
+'面条目' => '面條目',
+'面條目' => '面條目',
+'面粉碎' => '面粉碎',
+'面粉红' => '面粉紅',
+'面食饭' => '面食飯',
+'鞋里' => '鞋裡',
+'鞣制' => '鞣製',
+'秋千' => '鞦韆',
+'鞭辟入里' => '鞭辟入裡',
+'韦席' => '韋蓆',
+'韩国制' => '韓國製',
+'韩制' => '韓製',
+'音不准' => '音不準',
+'音准' => '音準',
+'音声如钟' => '音聲如鐘',
+'韶山冲' => '韶山沖',
+'响钟' => '響鐘',
+'頁面' => '頁面',
+'页面' => '頁面',
+'顶凶' => '頂兇',
+'頂多' => '頂多',
+'顶多' => '頂多',
+'项链' => '項鍊',
+'顺于' => '順於',
+'顺钟向' => '順鐘向',
+'顺风后' => '順風後',
+'须根据' => '須根據',
+'颂系' => '頌繫',
+'颂赞' => '頌讚',
+'预报不准' => '預報不準',
+'预制' => '預製',
+'领袖欲' => '領袖慾',
+'头里' => '頭裡',
+'头长发' => '頭長髮',
+'头发' => '頭髮',
+'颊须' => '頰鬚',
+'额征' => '額徵',
+'额我略历' => '額我略曆',
+'额我略历史' => '額我略歷史',
+'颜范' => '顏範',
+'颠干倒坤' => '顛乾倒坤',
+'顛顛仆仆' => '顛顛仆仆',
+'颠颠仆仆' => '顛顛仆仆',
+'颤栗' => '顫慄',
+'显示表明' => '顯示表明',
+'显示表格' => '顯示表格',
+'显示表现' => '顯示表現',
+'显示表示' => '顯示表示',
+'显示表达' => '顯示表達',
+'显示表面' => '顯示表面',
+'显示表头' => '顯示表頭',
+'显示表' => '顯示錶',
+'显示钟' => '顯示鐘',
+'显示钟表' => '顯示鐘錶',
+'风干' => '風乾',
+'风后' => '風后',
+'风土志' => '風土誌',
+'风后,' => '風後,',
+'风卷残云' => '風捲殘雲',
+'风物志' => '風物誌',
+'风范' => '風範',
+'风里' => '風裡',
+'风起云涌' => '風起雲湧',
+'風采' => '風采',
+'风采' => '風采',
+'风刮' => '風颳',
+'台风' => '颱風',
+'台风后' => '颱風後',
+'刮了' => '颳了',
+'刮倒' => '颳倒',
+'刮去' => '颳去',
+'刮大风' => '颳大風',
+'刮得' => '颳得',
+'刮走' => '颳走',
+'刮起' => '颳起',
+'刮雪' => '颳雪',
+'刮风' => '颳風',
+'刮风后' => '颳風後',
+'飘荡' => '飄蕩',
+'飘游' => '飄遊',
+'飘飘荡荡' => '飄飄蕩蕩',
+'飘发自由女神' => '飄髮自由女神',
+'飞扎' => '飛紮',
+'飞刍挽粟' => '飛芻輓粟',
+'飞行钟' => '飛行鐘',
+'食欲' => '食慾',
+'食欲不振' => '食欲不振',
+'食面' => '食麵',
+'饭后钟' => '飯後鐘',
+'饭团' => '飯糰',
+'饼干' => '餅乾',
+'养脏' => '養臟',
+'餐台' => '餐檯',
+'馂余' => '餕餘',
+'余0' => '餘0',
+'余1' => '餘1',
+'余2' => '餘2',
+'余3' => '餘3',
+'余4' => '餘4',
+'余5' => '餘5',
+'余6' => '餘6',
+'余7' => '餘7',
+'余8' => '餘8',
+'余9' => '餘9',
+'余〇' => '餘〇',
+'余一' => '餘一',
+'余七' => '餘七',
+'余三' => '餘三',
+'余下' => '餘下',
+'余九' => '餘九',
+'余事' => '餘事',
+'余二' => '餘二',
+'余五' => '餘五',
+'余人' => '餘人',
+'余俗' => '餘俗',
+'余倍' => '餘倍',
+'余僇' => '餘僇',
+'余光' => '餘光',
+'余八' => '餘八',
+'余六' => '餘六',
+'余刃' => '餘刃',
+'余切' => '餘切',
+'余利' => '餘利',
+'余割' => '餘割',
+'余力' => '餘力',
+'余勇' => '餘勇',
+'余十' => '餘十',
+'余味' => '餘味',
+'余喘' => '餘喘',
+'余四' => '餘四',
+'余地' => '餘地',
+'余墨' => '餘墨',
+'余外' => '餘外',
+'余妙' => '餘妙',
+'余姚' => '餘姚',
+'余威' => '餘威',
+'余子' => '餘子',
+'余存' => '餘存',
+'余孽' => '餘孽',
+'余干' => '餘干',
+'余年' => '餘年',
+'余式' => '餘式',
+'余弦' => '餘弦',
+'余思' => '餘思',
+'余悸' => '餘悸',
+'余庆' => '餘慶',
+'余数' => '餘數',
+'余明' => '餘明',
+'余映' => '餘映',
+'余暇' => '餘暇',
+'余晖' => '餘暉',
+'余杭' => '餘杭',
+'余杯' => '餘杯',
+'余桃' => '餘桃',
+'余桶' => '餘桶',
+'余业' => '餘業',
+'余款' => '餘款',
+'余欢' => '餘歡',
+'余步' => '餘步',
+'余殃' => '餘殃',
+'余毒' => '餘毒',
+'余气' => '餘氣',
+'余江' => '餘江',
+'余波' => '餘波',
+'余温' => '餘溫',
+'余泽' => '餘澤',
+'余沥' => '餘瀝',
+'余烈' => '餘烈',
+'余热' => '餘熱',
+'余烬' => '餘燼',
+'余珍' => '餘珍',
+'余生' => '餘生',
+'余留' => '餘留',
+'余众' => '餘眾',
+'余窍' => '餘竅',
+'余粮' => '餘糧',
+'余绪' => '餘緒',
+'余缺' => '餘缺',
+'余罪' => '餘罪',
+'余羡' => '餘羨',
+'余声' => '餘聲',
+'余膏' => '餘膏',
+'余兴' => '餘興',
+'余蓄' => '餘蓄',
+'余荫' => '餘蔭',
+'余裕' => '餘裕',
+'余角' => '餘角',
+'余论' => '餘論',
+'余责' => '餘責',
+'余貾' => '餘貾',
+'余辉' => '餘輝',
+'余辜' => '餘辜',
+'余部' => '餘部',
+'余酲' => '餘酲',
+'余量' => '餘量',
+'余闰' => '餘閏',
+'余闲' => '餘閒',
+'余零' => '餘零',
+'余震' => '餘震',
+'余霞' => '餘霞',
+'余音' => '餘音',
+'余韵' => '餘韻',
+'余响' => '餘響',
+'余项' => '餘項',
+'余额' => '餘額',
+'余风' => '餘風',
+'余食' => '餘食',
+'余党' => '餘黨',
+'馄饨面' => '餛飩麵',
+'馆谷' => '館穀',
+'馆里' => '館裡',
+'饥寒' => '饑寒',
+'饥民' => '饑民',
+'饥渴' => '饑渴',
+'饥溺' => '饑溺',
+'饥荒' => '饑荒',
+'饥饱' => '饑飽',
+'饥馑' => '饑饉',
+'首当其冲' => '首當其衝',
+'首发' => '首發',
+'首只' => '首隻',
+'首出电影' => '首齣電影',
+'香干' => '香乾',
+'香山庄' => '香山庄',
+'马干' => '馬乾',
+'馬占山' => '馬占山',
+'马德钟' => '馬德鐘',
+'马斯垂克期' => '馬斯垂克期',
+'馬格里布' => '馬格里布',
+'马格里布' => '馬格里布',
+'驻扎' => '駐紮',
+'骀荡' => '駘蕩',
+'腾格里' => '騰格里',
+'騰格里' => '騰格里',
+'腾涌' => '騰湧',
+'腾冲' => '騰衝',
+'惊栗' => '驚慄',
+'惊赞' => '驚讚',
+'惊钟' => '驚鐘',
+'骨干' => '骨幹',
+'骨灰坛' => '骨灰罈',
+'骨坛' => '骨罈',
+'体征' => '體徵',
+'体范' => '體範',
+'体系' => '體系',
+'体里' => '體裡',
+'高几' => '高几',
+'高后' => '高后',
+'高干扰' => '高干擾',
+'高干预' => '高干預',
+'高干' => '高幹',
+'高度自制' => '高度自制',
+'高涌泉' => '高涌泉',
+'高清愿' => '高清愿',
+'髡发' => '髡髮',
+'髭胡' => '髭鬍',
+'髭须' => '髭鬚',
+'发上指冠' => '髮上指冠',
+'发上冲冠' => '髮上沖冠',
+'发乳' => '髮乳',
+'发光可鉴' => '髮光可鑑',
+'发匪' => '髮匪',
+'发及腰' => '髮及腰',
+'发型' => '髮型',
+'发夹' => '髮夾',
+'发妻' => '髮妻',
+'发姐' => '髮姐',
+'发屋' => '髮屋',
+'发已霜白' => '髮已霜白',
+'发带' => '髮帶',
+'发廊' => '髮廊',
+'发式' => '髮式',
+'发引千钧' => '髮引千鈞',
+'发披肩' => '髮披肩',
+'发卷' => '髮捲',
+'发根' => '髮根',
+'发油' => '髮油',
+'发漂' => '髮漂',
+'发为血之本' => '髮為血之本',
+'发状' => '髮狀',
+'发癣' => '髮癬',
+'发短心长' => '髮短心長',
+'发禁' => '髮禁',
+'发笺' => '髮箋',
+'发纱' => '髮紗',
+'发结' => '髮結',
+'发丝' => '髮絲',
+'发网' => '髮網',
+'发脚' => '髮腳',
+'发肤' => '髮膚',
+'发胶' => '髮膠',
+'发菜' => '髮菜',
+'发蜡' => '髮蠟',
+'发踊冲冠' => '髮踴沖冠',
+'发辫' => '髮辮',
+'发针' => '髮針',
+'发钗' => '髮釵',
+'发长' => '髮長',
+'发际' => '髮際',
+'发雕' => '髮雕',
+'发霜' => '髮霜',
+'发饰' => '髮飾',
+'发髻' => '髮髻',
+'发鬓' => '髮鬢',
+'髯胡' => '髯鬍',
+'髼松' => '髼鬆',
+'鬅松' => '鬅鬆',
+'松一口气' => '鬆一口氣',
+'松了' => '鬆了',
+'松些' => '鬆些',
+'松元音' => '鬆元音',
+'松劲' => '鬆勁',
+'松动' => '鬆動',
+'松化' => '鬆化',
+'松口' => '鬆口',
+'松喉' => '鬆喉',
+'松土' => '鬆土',
+'松宽' => '鬆寬',
+'松弛' => '鬆弛',
+'松快' => '鬆快',
+'松懈' => '鬆懈',
+'松手' => '鬆手',
+'松掉' => '鬆掉',
+'松散' => '鬆散',
+'松柔' => '鬆柔',
+'松气' => '鬆氣',
+'松浮' => '鬆浮',
+'松绑' => '鬆綁',
+'松紧' => '鬆緊',
+'松缓' => '鬆緩',
+'松脆' => '鬆脆',
+'松脱' => '鬆脫',
+'松蛋' => '鬆蛋',
+'松起' => '鬆起',
+'松软' => '鬆軟',
+'松通' => '鬆通',
+'松开' => '鬆開',
+'松饼' => '鬆餅',
+'松松地' => '鬆鬆地',
+'鬈发' => '鬈髮',
+'胡子' => '鬍子',
+'胡梢' => '鬍梢',
+'胡渣' => '鬍渣',
+'胡髭' => '鬍髭',
+'胡髯' => '鬍髯',
+'胡须' => '鬍鬚',
+'鬒发' => '鬒髮',
+'须根' => '鬚根',
+'须毛' => '鬚毛',
+'须生' => '鬚生',
+'须眉' => '鬚眉',
+'须发' => '鬚髮',
+'须胡' => '鬚鬍',
+'须须' => '鬚鬚',
+'须鲨' => '鬚鯊',
+'须鲸' => '鬚鯨',
+'鬓发' => '鬢髮',
+'斗不过' => '鬥不過',
+'斗了' => '鬥了',
+'斗来斗去' => '鬥來鬥去',
+'斗倒' => '鬥倒',
+'斗分子' => '鬥分子',
+'斗剑' => '鬥劍',
+'斗力' => '鬥力',
+'斗劲' => '鬥勁',
+'斗勇' => '鬥勇',
+'斗胜' => '鬥勝',
+'斗口' => '鬥口',
+'斗合' => '鬥合',
+'斗嘴' => '鬥嘴',
+'斗地主' => '鬥地主',
+'斗垮' => '鬥垮',
+'斗士' => '鬥士',
+'斗富' => '鬥富',
+'斗巧' => '鬥巧',
+'斗幌子' => '鬥幌子',
+'斗弄' => '鬥弄',
+'斗引' => '鬥引',
+'斗别气' => '鬥彆氣',
+'斗彩' => '鬥彩',
+'斗心眼' => '鬥心眼',
+'斗志' => '鬥志',
+'斗闷' => '鬥悶',
+'斗成' => '鬥成',
+'斗战' => '鬥戰',
+'斗打' => '鬥打',
+'斗批改' => '鬥批改',
+'斗技' => '鬥技',
+'斗败' => '鬥敗',
+'斗文' => '鬥文',
+'斗智' => '鬥智',
+'斗暴' => '鬥暴',
+'斗武' => '鬥武',
+'斗殴' => '鬥毆',
+'斗气' => '鬥氣',
+'斗法' => '鬥法',
+'斗争' => '鬥爭',
+'斗争斗合' => '鬥爭鬥合',
+'斗牌' => '鬥牌',
+'斗牙拌齿' => '鬥牙拌齒',
+'斗牙斗齿' => '鬥牙鬥齒',
+'斗牛' => '鬥牛',
+'斗犀台' => '鬥犀臺',
+'斗犬' => '鬥犬',
+'斗狗' => '鬥狗',
+'斗狠' => '鬥狠',
+'斗兽' => '鬥獸',
+'斗叠' => '鬥疊',
+'斗百草' => '鬥百草',
+'斗眼' => '鬥眼',
+'斗私批修' => '鬥私批修',
+'斗而铸兵' => '鬥而鑄兵',
+'斗而铸锥' => '鬥而鑄錐',
+'斗脚' => '鬥腳',
+'斗舰' => '鬥艦',
+'斗茶' => '鬥茶',
+'斗草' => '鬥草',
+'斗叶儿' => '鬥葉兒',
+'斗叶子' => '鬥葉子',
+'斗蛐' => '鬥蛐',
+'斗蟋蟀' => '鬥蟋蟀',
+'斗话' => '鬥話',
+'斗艳' => '鬥豔',
+'斗起' => '鬥起',
+'斗趣' => '鬥趣',
+'斗闲气' => '鬥閒氣',
+'斗鸡' => '鬥雞',
+'斗雪红' => '鬥雪紅',
+'斗头' => '鬥頭',
+'斗风' => '鬥風',
+'斗饤' => '鬥飣',
+'斗斗' => '鬥鬥',
+'斗哄' => '鬥鬨',
+'斗鱼' => '鬥魚',
+'斗鸭' => '鬥鴨',
+'斗鹌鹑' => '鬥鵪鶉',
+'斗丽' => '鬥麗',
+'斗龙' => '鬥龍',
+'闹表' => '鬧錶',
+'闹钟' => '鬧鐘',
+'哄动' => '鬨動',
+'哄堂' => '鬨堂',
+'哄笑' => '鬨笑',
+'郁伊' => '鬱伊',
+'郁勃' => '鬱勃',
+'郁卒' => '鬱卒',
+'郁南' => '鬱南',
+'郁堙不偶' => '鬱堙不偶',
+'郁塞' => '鬱塞',
+'郁垒' => '鬱壘',
+'郁律' => '鬱律',
+'郁悒' => '鬱悒',
+'郁闷' => '鬱悶',
+'郁愤' => '鬱憤',
+'郁抑' => '鬱抑',
+'郁挹' => '鬱挹',
+'郁林' => '鬱林',
+'郁气' => '鬱氣',
+'郁江' => '鬱江',
+'郁沉沉' => '鬱沉沉',
+'郁泱' => '鬱泱',
+'郁火' => '鬱火',
+'郁热' => '鬱熱',
+'郁燠' => '鬱燠',
+'郁症' => '鬱症',
+'郁积' => '鬱積',
+'郁纡' => '鬱紆',
+'郁结' => '鬱結',
+'郁蒸' => '鬱蒸',
+'郁蓊' => '鬱蓊',
+'郁血' => '鬱血',
+'郁邑' => '鬱邑',
+'郁郁' => '鬱郁',
+'郁金' => '鬱金',
+'郁闭' => '鬱閉',
+'郁陶' => '鬱陶',
+'郁郁不平' => '鬱鬱不平',
+'郁郁不乐' => '鬱鬱不樂',
+'郁郁寡欢' => '鬱鬱寡歡',
+'郁郁而终' => '鬱鬱而終',
+'郁郁苍苍' => '鬱鬱蒼蒼',
+'郁郁葱葱' => '鬱鬱蔥蔥',
+'郁黑' => '鬱黑',
+'鬼气冲天' => '鬼氣衝天',
+'鬼谷子' => '鬼谷子',
+'魂牵梦系' => '魂牽夢繫',
+'魏征' => '魏徵',
+'魔表' => '魔錶',
+'鱼干' => '魚乾',
+'鱼松' => '魚鬆',
+'鮮于' => '鮮于',
+'鲜于' => '鮮于',
+'鲸须' => '鯨鬚',
+'鳥栖' => '鳥栖',
+'鸟栖市' => '鳥栖市',
+'凤梨干' => '鳳梨乾',
+'鸣钟' => '鳴鐘',
+'鸿范' => '鴻範',
+'鹅准' => '鵝準',
+'鹄发' => '鵠髮',
+'雕心雁爪' => '鵰心雁爪',
+'雕悍' => '鵰悍',
+'雕翎' => '鵰翎',
+'雕鹗' => '鵰鶚',
+'鹤峰县' => '鶴峯縣',
+'鹤吊' => '鶴弔',
+'鹤发' => '鶴髮',
+'鸾鉴' => '鸞鑑',
+'鹰雕' => '鹰鵰',
+'咸味' => '鹹味',
+'咸嘴淡舌' => '鹹嘴淡舌',
+'咸土' => '鹹土',
+'咸度' => '鹹度',
+'咸得' => '鹹得',
+'咸批' => '鹹批',
+'咸水' => '鹹水',
+'咸派' => '鹹派',
+'咸海' => '鹹海',
+'咸淡' => '鹹淡',
+'咸湖' => '鹹湖',
+'咸汤' => '鹹湯',
+'咸潟' => '鹹潟',
+'咸湿' => '鹹濕',
+'咸的' => '鹹的',
+'咸粥' => '鹹粥',
+'咸肉' => '鹹肉',
+'咸菜' => '鹹菜',
+'咸菜干' => '鹹菜乾',
+'咸蛋' => '鹹蛋',
+'咸猪' => '鹹豬',
+'咸类' => '鹹類',
+'咸食' => '鹹食',
+'咸鱼' => '鹹魚',
+'咸鸭蛋' => '鹹鴨蛋',
+'咸卤' => '鹹鹵',
+'咸咸' => '鹹鹹',
+'盐打怎么咸' => '鹽打怎麼鹹',
+'盐卤' => '鹽滷',
+'盐余' => '鹽餘',
+'鹿場里' => '鹿場里',
+'丽于' => '麗於',
+'麟游' => '麟遊',
+'曲酒' => '麯酒',
+'曲尘' => '麴塵',
+'曲櫱' => '麴櫱',
+'曲秀才' => '麴秀才',
+'曲车' => '麴車',
+'曲道士' => '麴道士',
+'曲钱' => '麴錢',
+'曲霉' => '麴黴',
+'麹霉' => '麴黴',
+'面人儿' => '麵人兒',
+'面包' => '麵包',
+'面坊' => '麵坊',
+'面坯儿' => '麵坯兒',
+'面塑' => '麵塑',
+'面店' => '麵店',
+'面厂' => '麵廠',
+'面摊' => '麵攤',
+'面杖' => '麵杖',
+'面条' => '麵條',
+'面汤' => '麵湯',
+'面浆' => '麵漿',
+'面疙瘩' => '麵疙瘩',
+'面皮' => '麵皮',
+'面码儿' => '麵碼兒',
+'面筋' => '麵筋',
+'面粉' => '麵粉',
+'面糊' => '麵糊',
+'面团' => '麵糰',
+'面缸' => '麵缸',
+'面茶' => '麵茶',
+'面制品' => '麵製品',
+'面食' => '麵食',
+'面饺' => '麵餃',
+'面饼' => '麵餅',
+'面馆' => '麵館',
+'面点、' => '麵點、',
+'面点师' => '麵點師',
+'麻将席' => '麻將蓆',
+'麻酱面' => '麻醬麵',
+'黄干黑瘦' => '黃乾黑瘦',
+'黄岩区' => '黃巖區',
+'黄岩县' => '黃巖縣',
+'黄历' => '黃曆',
+'黃杰' => '黃杰',
+'黄杰' => '黃杰',
+'黄历史' => '黃歷史',
+'黄白术' => '黃白術',
+'黃詩杰' => '黃詩杰',
+'黄诗杰' => '黃詩杰',
+'黄金表' => '黃金表',
+'黃鈺筑' => '黃鈺筑',
+'黄钰筑' => '黃鈺筑',
+'黄钟' => '黃鐘',
+'黄发' => '黃髮',
+'黄曲毒素' => '黃麴毒素',
+'黎克特制' => '黎克特制',
+'黎吉云' => '黎吉雲',
+'黎吉雲' => '黎吉雲',
+'黑奴吁天录' => '黑奴籲天錄',
+'黑干将' => '黑幹將',
+'黑长发' => '黑長髮',
+'黑发' => '黑髮',
+'点个赞' => '點個讚',
+'点札' => '點劄',
+'点半钟' => '點半鐘',
+'点多钟' => '點多鐘',
+'点里' => '點裡',
+'点赞' => '點讚',
+'点里程' => '點里程',
+'点钟' => '點鐘',
+'霉毒' => '黴毒',
+'霉素' => '黴素',
+'霉菌' => '黴菌',
+'霉黑' => '黴黑',
+'霉黧' => '黴黧',
+'鼓里' => '鼓裡',
+'鼓噪' => '鼓譟',
+'冬冬鼓' => '鼕鼕鼓',
+'咚咚鼓' => '鼕鼕鼓',
+'鼠曲草' => '鼠麴草',
+'鼻梁儿' => '鼻梁兒',
+'鼻梁' => '鼻樑',
+'鼻准' => '鼻準',
+'齐王舍牛' => '齊王捨牛',
+'齿危发秀' => '齒危髮秀',
+'齿落发白' => '齒落髮白',
+'齿发' => '齒髮',
+'龙岩' => '龍巖',
+'龙卷' => '龍捲',
+'龙眼干' => '龍眼乾',
+'龙须' => '龍鬚',
+'龙须面' => '龍鬚麵',
+'龙斗虎伤' => '龍鬥虎傷',
+'龜山庄' => '龜山庄',
+'龟鉴' => '龜鑑',
+',并力' => ',並力',
+',并力攻' => ',并力攻',
+',并力討' => ',并力討',
+',并力讨' => ',并力討',
+',个中' => ',箇中',
+);
+
+public static $zh2Hans = array(
+'㑯' => '㑔',
+'㑳' => '㑇',
+'㑶' => '㐹',
+'㒓' => '𠉂',
+'㒺' => '罔',
+'㓂' => '寇',
+'㓨' => '刾',
+'㕁' => '却',
+'㕑' => '厨',
+'㕘' => '参',
+'㕥' => '以',
+'㗲' => '𠵾',
+'㘚' => '㘎',
+'㘭' => '坳',
+'㜄' => '㚯',
+'㜏' => '㛣',
+'㜢' => '𡞱',
+'㜷' => '𡝠',
+'㝛' => '宿',
+'㝠' => '冥',
+'㞞' => '𪨊',
+'㠀' => '岛',
+'㠏' => '㟆',
+'㠯' => '以',
+'㠶' => '帆',
+'㡌' => '帽',
+'㢘' => '廉',
+'㢝' => '𢋈',
+'㤙' => '恩',
+'㥦' => '惬',
+'㥮' => '㤘',
+'㦎' => '𢛯',
+'㨗' => '捷',
+'㨪' => '晃',
+'㨿' => '据',
+'㩗' => '携',
+'㩜' => '㨫',
+'㩦' => '携',
+'㩳' => '㧐',
+'㪚' => '散',
+'㪟' => '敦',
+'㬉' => '暖',
+'㬪' => '叠',
+'㯭' => '橹',
+'㱃' => '饮',
+'㳒' => '法',
+'㴱' => '深',
+'㷿' => '𤈷',
+'㺏' => '𤠋',
+'㼝' => '碗',
+'㽞' => '留',
+'㿜' => '瘪',
+'㿧' => '𤽯',
+'䀹' => '𥅴',
+'䁪' => '𥇢',
+'䁻' => '䀥',
+'䈰' => '筲',
+'䉙' => '𥬀',
+'䉬' => '𫂈',
+'䉲' => '𥮜',
+'䊀' => '糊',
+'䊭' => '𥺅',
+'䊷' => '䌶',
+'䋙' => '䌺',
+'䋚' => '䌻',
+'䋹' => '䌿',
+'䋻' => '䌾',
+'䋿' => '𦈓',
+'䌈' => '𦈖',
+'䌋' => '𦈘',
+'䌖' => '𦈜',
+'䌝' => '𦈟',
+'䌟' => '𦈞',
+'䌥' => '𦈠',
+'䌰' => '𦈙',
+'䎱' => '䎬',
+'䕳' => '𦰴',
+'䗬' => '蜂',
+'䗿' => '𧉞',
+'䘏' => '恤',
+'䘑' => '脉',
+'䘚' => '卒',
+'䙡' => '䙌',
+'䛐' => '词',
+'䛡' => '话',
+'䜀' => '䜧',
+'䝔' => '獾',
+'䝻' => '𧹕',
+'䝼' => '䞍',
+'䞈' => '𧹑',
+'䠀' => '蹚',
+'䠶' => '射',
+'䢨' => '𨑹',
+'䥇' => '䦂',
+'䥥' => '镰',
+'䥩' => '𨱖',
+'䥱' => '䥾',
+'䦘' => '𨸄',
+'䦛' => '䦶',
+'䦟' => '䦷',
+'䦳' => '𨷿',
+'䧢' => '𨸟',
+'䪏' => '𩏼',
+'䪗' => '𩐀',
+'䪘' => '𩏿',
+'䫴' => '𩖗',
+'䬃' => '飒',
+'䬘' => '𩙮',
+'䬝' => '𩙯',
+'䬞' => '𩙧',
+'䭀' => '𩠇',
+'䭃' => '𩠈',
+'䭾' => '驮',
+'䭿' => '𩧭',
+'䮝' => '𩧰',
+'䮞' => '𩨁',
+'䮠' => '𩧿',
+'䮫' => '𩨇',
+'䮳' => '𩨏',
+'䮾' => '𩧪',
+'䯀' => '䯅',
+'䰟' => '魂',
+'䰾' => '鲃',
+'䱙' => '𩾈',
+'䱬' => '𩾊',
+'䱰' => '𩾋',
+'䱷' => '䲣',
+'䱽' => '䲝',
+'䲁' => '鳚',
+'䲖' => '𩾂',
+'䲘' => '鳤',
+'䲰' => '𪉂',
+'䳘' => '鹅',
+'䴉' => '鹮',
+'䴬' => '𪎈',
+'䴴' => '𪎋',
+'䶊' => '衄',
+'丟' => '丢',
+'丣' => '卯',
+'並' => '并',
+'乗' => '乘',
+'乹' => '干',
+'乾' => '干',
+'亁' => '干',
+'亂' => '乱',
+'亙' => '亘',
+'亝' => '斋',
+'亞' => '亚',
+'亱' => '夜',
+'亷' => '廉',
+'亾' => '亡',
+'佇' => '伫',
+'佈' => '布',
+'佔' => '占',
+'併' => '并',
+'來' => '来',
+'侖' => '仑',
+'侶' => '侣',
+'俁' => '俣',
+'係' => '系',
+'俔' => '伣',
+'俠' => '侠',
+'俥' => '伡',
+'俻' => '备',
+'倀' => '伥',
+'倆' => '俩',
+'倈' => '俫',
+'倉' => '仓',
+'個' => '个',
+'倐' => '倏',
+'們' => '们',
+'倖' => '幸',
+'倣' => '仿',
+'倫' => '伦',
+'倲' => '㑈',
+'倸' => '睬',
+'偉' => '伟',
+'偑' => '㐽',
+'側' => '侧',
+'偵' => '侦',
+'偽' => '伪',
+'傌' => '㐷',
+'傑' => '杰',
+'傖' => '伧',
+'傘' => '伞',
+'備' => '备',
+'傚' => '效',
+'傢' => '家',
+'傭' => '佣',
+'傯' => '偬',
+'傳' => '传',
+'傴' => '伛',
+'債' => '债',
+'傷' => '伤',
+'傾' => '倾',
+'僂' => '偻',
+'僅' => '仅',
+'僉' => '佥',
+'僊' => '仙',
+'働' => '动',
+'僑' => '侨',
+'僕' => '仆',
+'僞' => '伪',
+'僥' => '侥',
+'僨' => '偾',
+'僱' => '雇',
+'價' => '价',
+'儀' => '仪',
+'儂' => '侬',
+'億' => '亿',
+'儈' => '侩',
+'儉' => '俭',
+'儌' => '侥',
+'儐' => '傧',
+'儔' => '俦',
+'儕' => '侪',
+'儘' => '尽',
+'償' => '偿',
+'儣' => '𠆲',
+'優' => '优',
+'儲' => '储',
+'儷' => '俪',
+'儸' => '㑩',
+'儺' => '傩',
+'儻' => '傥',
+'儼' => '俨',
+'兇' => '凶',
+'兌' => '兑',
+'兎' => '兔',
+'兒' => '儿',
+'兗' => '兖',
+'兠' => '兜',
+'內' => '内',
+'兩' => '两',
+'冄' => '冉',
+'冊' => '册',
+'冐' => '冒',
+'冑' => '胄',
+'冪' => '幂',
+'冺' => '泯',
+'凈' => '净',
+'凍' => '冻',
+'凙' => '𪞝',
+'凜' => '凛',
+'凢' => '凡',
+'凱' => '凯',
+'凴' => '凭',
+'別' => '别',
+'刦' => '劫',
+'刧' => '劫',
+'刪' => '删',
+'刼' => '劫',
+'剄' => '刭',
+'則' => '则',
+'剉' => '锉',
+'剋' => '克',
+'剎' => '刹',
+'剏' => '创',
+'剗' => '刬',
+'剙' => '创',
+'剛' => '刚',
+'剝' => '剥',
+'剮' => '剐',
+'剳' => '札',
+'剴' => '剀',
+'創' => '创',
+'剷' => '铲',
+'剹' => '戮',
+'剾' => '𠛅',
+'劃' => '划',
+'劄' => '札',
+'劇' => '剧',
+'劉' => '刘',
+'劊' => '刽',
+'劌' => '刿',
+'劍' => '剑',
+'劏' => '㓥',
+'劑' => '剂',
+'劒' => '剑',
+'劚' => '㔉',
+'効' => '效',
+'勁' => '劲',
+'勅' => '敕',
+'勌' => '倦',
+'勑' => '敕',
+'動' => '动',
+'務' => '务',
+'勛' => '勋',
+'勝' => '胜',
+'勞' => '劳',
+'勢' => '势',
+'勦' => '剿',
+'勩' => '勚',
+'勱' => '劢',
+'勳' => '勋',
+'勵' => '励',
+'勸' => '劝',
+'勻' => '匀',
+'匟' => '炕',
+'匭' => '匦',
+'匯' => '汇',
+'匱' => '匮',
+'匲' => '奁',
+'匳' => '奁',
+'區' => '区',
+'協' => '协',
+'卹' => '恤',
+'卻' => '却',
+'卽' => '即',
+'厀' => '膝',
+'厙' => '厍',
+'厠' => '厕',
+'厤' => '历',
+'厭' => '厌',
+'厰' => '厂',
+'厲' => '厉',
+'厴' => '厣',
+'參' => '参',
+'叄' => '叁',
+'叢' => '丛',
+'吚' => '咿',
+'吳' => '吴',
+'吶' => '呐',
+'呂' => '吕',
+'呌' => '叫',
+'呪' => '咒',
+'咊' => '和',
+'咼' => '呙',
+'員' => '员',
+'哯' => '𠯟',
+'哶' => '咩',
+'唄' => '呗',
+'唕' => '唣',
+'唘' => '启',
+'唚' => '吣',
+'唸' => '念',
+'啎' => '忤',
+'問' => '问',
+'啑' => '喋',
+'啓' => '启',
+'啗' => '啖',
+'啞' => '哑',
+'啟' => '启',
+'啢' => '唡',
+'啣' => '衔',
+'喎' => '㖞',
+'喚' => '唤',
+'喪' => '丧',
+'喫' => '吃',
+'喬' => '乔',
+'單' => '单',
+'喲' => '哟',
+'嗁' => '啼',
+'嗆' => '呛',
+'嗇' => '啬',
+'嗊' => '唝',
+'嗎' => '吗',
+'嗚' => '呜',
+'嗩' => '唢',
+'嗶' => '哔',
+'嗹' => '𪡏',
+'嘅' => '慨',
+'嘆' => '叹',
+'嘍' => '喽',
+'嘑' => '呼',
+'嘓' => '啯',
+'嘔' => '呕',
+'嘖' => '啧',
+'嘗' => '尝',
+'嘜' => '唛',
+'嘠' => '嘎',
+'嘩' => '哗',
+'嘮' => '唠',
+'嘯' => '啸',
+'嘰' => '叽',
+'嘵' => '哓',
+'嘷' => '嗥',
+'嘸' => '呒',
+'嘽' => '啴',
+'噅' => '𠯠',
+'噉' => '啖',
+'噓' => '嘘',
+'噚' => '㖊',
+'噝' => '咝',
+'噠' => '哒',
+'噥' => '哝',
+'噦' => '哕',
+'噯' => '嗳',
+'噲' => '哙',
+'噴' => '喷',
+'噸' => '吨',
+'噹' => '当',
+'嚀' => '咛',
+'嚇' => '吓',
+'嚌' => '哜',
+'嚐' => '尝',
+'嚕' => '噜',
+'嚙' => '啮',
+'嚥' => '咽',
+'嚦' => '呖',
+'嚨' => '咙',
+'嚮' => '向',
+'嚲' => '亸',
+'嚳' => '喾',
+'嚴' => '严',
+'嚶' => '嘤',
+'囀' => '啭',
+'囁' => '嗫',
+'囂' => '嚣',
+'囅' => '冁',
+'囈' => '呓',
+'囉' => '啰',
+'囌' => '苏',
+'囑' => '嘱',
+'囓' => '啮',
+'囙' => '因',
+'囪' => '囱',
+'圅' => '函',
+'圇' => '囵',
+'國' => '国',
+'圍' => '围',
+'園' => '园',
+'圓' => '圆',
+'圖' => '图',
+'團' => '团',
+'圞' => '𪢮',
+'坿' => '附',
+'垜' => '垛',
+'垵' => '埯',
+'埡' => '垭',
+'埰' => '采',
+'執' => '执',
+'堅' => '坚',
+'堊' => '垩',
+'堝' => '埚',
+'堯' => '尧',
+'報' => '报',
+'場' => '场',
+'塊' => '块',
+'塋' => '茔',
+'塏' => '垲',
+'塒' => '埘',
+'塗' => '涂',
+'塟' => '葬',
+'塢' => '坞',
+'塤' => '埙',
+'塲' => '场',
+'塵' => '尘',
+'塹' => '堑',
+'墊' => '垫',
+'墖' => '塔',
+'墜' => '坠',
+'墮' => '堕',
+'墰' => '坛',
+'墳' => '坟',
+'墻' => '墙',
+'墾' => '垦',
+'壇' => '坛',
+'壈' => '𡒄',
+'壋' => '垱',
+'壎' => '埙',
+'壓' => '压',
+'壘' => '垒',
+'壙' => '圹',
+'壚' => '垆',
+'壜' => '坛',
+'壞' => '坏',
+'壟' => '垄',
+'壠' => '垅',
+'壢' => '坜',
+'壩' => '坝',
+'壯' => '壮',
+'壺' => '壶',
+'壻' => '婿',
+'壼' => '壸',
+'壽' => '寿',
+'夘' => '卯',
+'夠' => '够',
+'夢' => '梦',
+'夥' => '伙',
+'夾' => '夹',
+'奐' => '奂',
+'奧' => '奥',
+'奩' => '奁',
+'奪' => '夺',
+'奬' => '奖',
+'奮' => '奋',
+'奼' => '姹',
+'妝' => '妆',
+'妬' => '妒',
+'妳' => '你',
+'妷' => '侄',
+'姉' => '姊',
+'姍' => '姗',
+'姙' => '妊',
+'姦' => '奸',
+'姪' => '侄',
+'姸' => '妍',
+'娛' => '娱',
+'婁' => '娄',
+'婣' => '姻',
+'婦' => '妇',
+'婬' => '淫',
+'婭' => '娅',
+'媍' => '妇',
+'媧' => '娲',
+'媯' => '妫',
+'媰' => '㛀',
+'媼' => '媪',
+'媽' => '妈',
+'媿' => '愧',
+'嫋' => '袅',
+'嫗' => '妪',
+'嫰' => '嫩',
+'嫵' => '妩',
+'嫺' => '娴',
+'嫻' => '娴',
+'嫿' => '婳',
+'嬀' => '妫',
+'嬃' => '媭',
+'嬈' => '娆',
+'嬋' => '婵',
+'嬌' => '娇',
+'嬙' => '嫱',
+'嬝' => '袅',
+'嬡' => '嫒',
+'嬤' => '嬷',
+'嬪' => '嫔',
+'嬭' => '奶',
+'嬰' => '婴',
+'嬸' => '婶',
+'嬾' => '懒',
+'孃' => '娘',
+'孋' => '㛤',
+'孌' => '娈',
+'孫' => '孙',
+'學' => '学',
+'孼' => '孽',
+'孿' => '孪',
+'宂' => '冗',
+'宮' => '宫',
+'寀' => '采',
+'寃' => '冤',
+'寑' => '寝',
+'寢' => '寝',
+'實' => '实',
+'寧' => '宁',
+'審' => '审',
+'寫' => '写',
+'寬' => '宽',
+'寳' => '宝',
+'寵' => '宠',
+'寶' => '宝',
+'尅' => '克',
+'將' => '将',
+'專' => '专',
+'尋' => '寻',
+'對' => '对',
+'導' => '导',
+'尒' => '尔',
+'尙' => '尚',
+'尟' => '鲜',
+'尠' => '鲜',
+'尷' => '尴',
+'屆' => '届',
+'屍' => '尸',
+'屓' => '屃',
+'屛' => '屏',
+'屜' => '屉',
+'屢' => '屡',
+'層' => '层',
+'屨' => '屦',
+'屩' => '𪨗',
+'屬' => '属',
+'屭' => '屃',
+'岅' => '坂',
+'岡' => '冈',
+'峝' => '峒',
+'峴' => '岘',
+'島' => '岛',
+'峽' => '峡',
+'崍' => '崃',
+'崗' => '岗',
+'崢' => '峥',
+'崬' => '岽',
+'嵐' => '岚',
+'嵗' => '岁',
+'嵼' => '𡶴',
+'嶁' => '嵝',
+'嶃' => '崭',
+'嶄' => '崭',
+'嶇' => '岖',
+'嶔' => '嵚',
+'嶗' => '崂',
+'嶠' => '峤',
+'嶢' => '峣',
+'嶧' => '峄',
+'嶨' => '峃',
+'嶮' => '崄',
+'嶸' => '嵘',
+'嶺' => '岭',
+'嶼' => '屿',
+'嶽' => '岳',
+'巋' => '岿',
+'巒' => '峦',
+'巔' => '巅',
+'巖' => '岩',
+'巗' => '岩',
+'巰' => '巯',
+'巵' => '卮',
+'帀' => '匝',
+'帋' => '纸',
+'帥' => '帅',
+'師' => '师',
+'帬' => '裙',
+'帳' => '帐',
+'帶' => '带',
+'幀' => '帧',
+'幃' => '帏',
+'幇' => '帮',
+'幑' => '徽',
+'幗' => '帼',
+'幘' => '帻',
+'幙' => '幕',
+'幚' => '帮',
+'幟' => '帜',
+'幣' => '币',
+'幫' => '帮',
+'幬' => '帱',
+'幹' => '干',
+'幾' => '几',
+'庫' => '库',
+'庻' => '庶',
+'庽' => '寓',
+'廁' => '厕',
+'廂' => '厢',
+'廄' => '厩',
+'廈' => '厦',
+'廎' => '庼',
+'廐' => '厩',
+'廕' => '荫',
+'廚' => '厨',
+'廝' => '厮',
+'廟' => '庙',
+'廠' => '厂',
+'廡' => '庑',
+'廢' => '废',
+'廣' => '广',
+'廩' => '廪',
+'廬' => '庐',
+'廳' => '厅',
+'廵' => '巡',
+'廹' => '迫',
+'廻' => '回',
+'廼' => '乃',
+'弒' => '弑',
+'弔' => '吊',
+'弳' => '弪',
+'張' => '张',
+'強' => '强',
+'彆' => '别',
+'彈' => '弹',
+'彌' => '弥',
+'彎' => '弯',
+'彙' => '汇',
+'彞' => '彝',
+'彠' => '彟',
+'彥' => '彦',
+'彫' => '雕',
+'彲' => '彨',
+'徃' => '往',
+'後' => '后',
+'徑' => '径',
+'從' => '从',
+'徠' => '徕',
+'徧' => '遍',
+'復' => '复',
+'徵' => '征',
+'徹' => '彻',
+'怱' => '匆',
+'怳' => '恍',
+'恆' => '恒',
+'恠' => '怪',
+'恡' => '吝',
+'恥' => '耻',
+'悅' => '悦',
+'悞' => '悮',
+'悤' => '匆',
+'悵' => '怅',
+'悶' => '闷',
+'悽' => '凄',
+'惏' => '婪',
+'惡' => '恶',
+'惥' => '恿',
+'惱' => '恼',
+'惲' => '恽',
+'惷' => '蠢',
+'惻' => '恻',
+'愛' => '爱',
+'愜' => '惬',
+'愨' => '悫',
+'愴' => '怆',
+'愷' => '恺',
+'愽' => '博',
+'愾' => '忾',
+'慄' => '栗',
+'態' => '态',
+'慍' => '愠',
+'慘' => '惨',
+'慙' => '惭',
+'慚' => '惭',
+'慟' => '恸',
+'慣' => '惯',
+'慤' => '悫',
+'慪' => '怄',
+'慫' => '怂',
+'慮' => '虑',
+'慳' => '悭',
+'慴' => '慑',
+'慶' => '庆',
+'慼' => '戚',
+'慽' => '戚',
+'慾' => '欲',
+'憂' => '忧',
+'憇' => '憩',
+'憊' => '惫',
+'憐' => '怜',
+'憑' => '凭',
+'憒' => '愦',
+'憚' => '惮',
+'憤' => '愤',
+'憫' => '悯',
+'憮' => '怃',
+'憲' => '宪',
+'憶' => '忆',
+'懀' => '𢙓',
+'懇' => '恳',
+'應' => '应',
+'懌' => '怿',
+'懍' => '懔',
+'懟' => '怼',
+'懣' => '懑',
+'懨' => '恹',
+'懲' => '惩',
+'懶' => '懒',
+'懷' => '怀',
+'懸' => '悬',
+'懺' => '忏',
+'懼' => '惧',
+'懾' => '慑',
+'戀' => '恋',
+'戇' => '戆',
+'戔' => '戋',
+'戞' => '戛',
+'戧' => '戗',
+'戩' => '戬',
+'戯' => '戏',
+'戰' => '战',
+'戱' => '戯',
+'戲' => '戏',
+'戶' => '户',
+'戹' => '厄',
+'扞' => '捍',
+'抝' => '拗',
+'拋' => '抛',
+'拚' => '拼',
+'挩' => '捝',
+'挱' => '挲',
+'挵' => '弄',
+'挾' => '挟',
+'捄' => '救',
+'捨' => '舍',
+'捫' => '扪',
+'捲' => '卷',
+'掃' => '扫',
+'掄' => '抡',
+'掆' => '㧏',
+'掗' => '挜',
+'掙' => '挣',
+'掛' => '挂',
+'採' => '采',
+'掽' => '碰',
+'揀' => '拣',
+'揑' => '捏',
+'揚' => '扬',
+'換' => '换',
+'揫' => '揪',
+'揮' => '挥',
+'揷' => '插',
+'揹' => '背',
+'搆' => '构',
+'搇' => '揿',
+'搉' => '榷',
+'損' => '损',
+'搖' => '摇',
+'搗' => '捣',
+'搤' => '扼',
+'搥' => '捶',
+'搨' => '拓',
+'搯' => '掏',
+'搵' => '揾',
+'搶' => '抢',
+'搾' => '榨',
+'摃' => '扛',
+'摋' => '𢫬',
+'摑' => '掴',
+'摜' => '掼',
+'摟' => '搂',
+'摯' => '挚',
+'摳' => '抠',
+'摶' => '抟',
+'摺' => '折',
+'摻' => '掺',
+'撈' => '捞',
+'撏' => '挦',
+'撐' => '撑',
+'撓' => '挠',
+'撝' => '㧑',
+'撟' => '挢',
+'撡' => '操',
+'撣' => '掸',
+'撥' => '拨',
+'撦' => '扯',
+'撫' => '抚',
+'撲' => '扑',
+'撳' => '揿',
+'撻' => '挞',
+'撾' => '挝',
+'撿' => '捡',
+'擁' => '拥',
+'擄' => '掳',
+'擇' => '择',
+'擊' => '击',
+'擋' => '挡',
+'擓' => '㧟',
+'擔' => '担',
+'擕' => '携',
+'據' => '据',
+'擠' => '挤',
+'擣' => '𢭏',
+'擧' => '举',
+'擬' => '拟',
+'擯' => '摈',
+'擰' => '拧',
+'擱' => '搁',
+'擲' => '掷',
+'擴' => '扩',
+'擷' => '撷',
+'擺' => '摆',
+'擻' => '擞',
+'擼' => '撸',
+'擽' => '㧰',
+'擾' => '扰',
+'攄' => '摅',
+'攆' => '撵',
+'攏' => '拢',
+'攔' => '拦',
+'攖' => '撄',
+'攙' => '搀',
+'攛' => '撺',
+'攜' => '携',
+'攝' => '摄',
+'攢' => '攒',
+'攣' => '挛',
+'攤' => '摊',
+'攩' => '挡',
+'攪' => '搅',
+'攬' => '揽',
+'攷' => '考',
+'敂' => '叩',
+'敍' => '叙',
+'敗' => '败',
+'敘' => '叙',
+'敵' => '敌',
+'數' => '数',
+'敺' => '驱',
+'斂' => '敛',
+'斃' => '毙',
+'斅' => '𢽾',
+'斆' => '敩',
+'斕' => '斓',
+'斬' => '斩',
+'斷' => '断',
+'於' => '于',
+'旂' => '旗',
+'旣' => '既',
+'旤' => '祸',
+'旹' => '时',
+'旾' => '春',
+'昬' => '昏',
+'時' => '时',
+'晉' => '晋',
+'晝' => '昼',
+'暈' => '晕',
+'暉' => '晖',
+'暘' => '旸',
+'暢' => '畅',
+'暫' => '暂',
+'暱' => '昵',
+'曄' => '晔',
+'曆' => '历',
+'曇' => '昙',
+'曉' => '晓',
+'曖' => '暧',
+'曠' => '旷',
+'曡' => '叠',
+'曥' => '𣆐',
+'曨' => '昽',
+'曬' => '晒',
+'書' => '书',
+'會' => '会',
+'朞' => '期',
+'朢' => '望',
+'朥' => '𦛨',
+'朧' => '胧',
+'朮' => '术',
+'朶' => '朵',
+'東' => '东',
+'杴' => '锨',
+'枱' => '台',
+'柵' => '栅',
+'柺' => '拐',
+'査' => '查',
+'栁' => '柳',
+'栞' => '刊',
+'栢' => '柏',
+'栰' => '筏',
+'桒' => '桑',
+'桮' => '杯',
+'桺' => '柳',
+'桿' => '杆',
+'梔' => '栀',
+'梘' => '枧',
+'條' => '条',
+'梟' => '枭',
+'梲' => '棁',
+'棄' => '弃',
+'棊' => '棋',
+'棖' => '枨',
+'棗' => '枣',
+'棟' => '栋',
+'棡' => '㭎',
+'棧' => '栈',
+'棲' => '栖',
+'棶' => '梾',
+'椏' => '桠',
+'椗' => '碇',
+'椲' => '㭏',
+'椶' => '棕',
+'椷' => '缄',
+'椾' => '笺',
+'楊' => '杨',
+'楓' => '枫',
+'楥' => '楦',
+'楨' => '桢',
+'業' => '业',
+'極' => '极',
+'榦' => '干',
+'榪' => '杩',
+'榮' => '荣',
+'榲' => '榅',
+'榿' => '桤',
+'構' => '构',
+'槍' => '枪',
+'槓' => '杠',
+'槕' => '桌',
+'槤' => '梿',
+'槧' => '椠',
+'槨' => '椁',
+'槮' => '椮',
+'槳' => '桨',
+'槶' => '椢',
+'槼' => '椝',
+'樁' => '桩',
+'樂' => '乐',
+'樅' => '枞',
+'樑' => '梁',
+'樓' => '楼',
+'標' => '标',
+'樞' => '枢',
+'樢' => '㭤',
+'樣' => '样',
+'樫' => '㭴',
+'樳' => '桪',
+'樸' => '朴',
+'樹' => '树',
+'樺' => '桦',
+'樿' => '椫',
+'橈' => '桡',
+'橋' => '桥',
+'橜' => '橛',
+'機' => '机',
+'橢' => '椭',
+'橫' => '横',
+'檁' => '檩',
+'檉' => '柽',
+'檔' => '档',
+'檜' => '桧',
+'檟' => '槚',
+'檢' => '检',
+'檣' => '樯',
+'檭' => '𣘴',
+'檮' => '梼',
+'檯' => '台',
+'檳' => '槟',
+'檸' => '柠',
+'檻' => '槛',
+'櫃' => '柜',
+'櫈' => '凳',
+'櫓' => '橹',
+'櫚' => '榈',
+'櫛' => '栉',
+'櫝' => '椟',
+'櫞' => '橼',
+'櫟' => '栎',
+'櫥' => '橱',
+'櫧' => '槠',
+'櫨' => '栌',
+'櫪' => '枥',
+'櫫' => '橥',
+'櫬' => '榇',
+'櫱' => '蘖',
+'櫳' => '栊',
+'櫸' => '榉',
+'櫻' => '樱',
+'欄' => '栏',
+'欅' => '榉',
+'權' => '权',
+'欍' => '𣐤',
+'欏' => '椤',
+'欒' => '栾',
+'欓' => '𣗋',
+'欖' => '榄',
+'欝' => '郁',
+'欞' => '棂',
+'欵' => '款',
+'欽' => '钦',
+'歎' => '叹',
+'歐' => '欧',
+'歛' => '敛',
+'歟' => '欤',
+'歡' => '欢',
+'歲' => '岁',
+'歴' => '历',
+'歷' => '历',
+'歸' => '归',
+'歿' => '殁',
+'殀' => '夭',
+'殘' => '残',
+'殞' => '殒',
+'殤' => '殇',
+'殨' => '㱮',
+'殫' => '殚',
+'殭' => '僵',
+'殮' => '殓',
+'殯' => '殡',
+'殰' => '㱩',
+'殲' => '歼',
+'殺' => '杀',
+'殻' => '壳',
+'殼' => '壳',
+'毀' => '毁',
+'毆' => '殴',
+'毧' => '绒',
+'毬' => '球',
+'毿' => '毵',
+'氂' => '牦',
+'氈' => '毡',
+'氊' => '毡',
+'氌' => '氇',
+'氣' => '气',
+'氫' => '氢',
+'氬' => '氩',
+'氳' => '氲',
+'氷' => '冰',
+'汙' => '污',
+'汚' => '污',
+'決' => '决',
+'沒' => '没',
+'沖' => '冲',
+'況' => '况',
+'泝' => '溯',
+'洩' => '泄',
+'洶' => '汹',
+'浹' => '浃',
+'涇' => '泾',
+'涖' => '莅',
+'涼' => '凉',
+'淒' => '凄',
+'淚' => '泪',
+'淛' => '浙',
+'淥' => '渌',
+'淨' => '净',
+'淩' => '凌',
+'淪' => '沦',
+'淵' => '渊',
+'淶' => '涞',
+'淺' => '浅',
+'渙' => '涣',
+'減' => '减',
+'渢' => '沨',
+'渦' => '涡',
+'測' => '测',
+'渾' => '浑',
+'湊' => '凑',
+'湞' => '浈',
+'湧' => '涌',
+'湯' => '汤',
+'湼' => '涅',
+'溈' => '沩',
+'準' => '准',
+'溝' => '沟',
+'溫' => '温',
+'溮' => '浉',
+'溳' => '涢',
+'溼' => '湿',
+'滄' => '沧',
+'滅' => '灭',
+'滌' => '涤',
+'滎' => '荥',
+'滙' => '汇',
+'滛' => '淫',
+'滬' => '沪',
+'滯' => '滞',
+'滲' => '渗',
+'滷' => '卤',
+'滸' => '浒',
+'滻' => '浐',
+'滾' => '滚',
+'滿' => '满',
+'漁' => '渔',
+'漊' => '溇',
+'漚' => '沤',
+'漢' => '汉',
+'漣' => '涟',
+'漬' => '渍',
+'漲' => '涨',
+'漵' => '溆',
+'漸' => '渐',
+'漿' => '浆',
+'潁' => '颍',
+'潄' => '漱',
+'潑' => '泼',
+'潔' => '洁',
+'潙' => '沩',
+'潛' => '潜',
+'潤' => '润',
+'潯' => '浔',
+'潰' => '溃',
+'潷' => '滗',
+'潿' => '涠',
+'澀' => '涩',
+'澁' => '涩',
+'澅' => '𣶩',
+'澆' => '浇',
+'澇' => '涝',
+'澐' => '沄',
+'澗' => '涧',
+'澠' => '渑',
+'澤' => '泽',
+'澦' => '滪',
+'澩' => '泶',
+'澮' => '浍',
+'澱' => '淀',
+'澾' => '㳠',
+'濁' => '浊',
+'濃' => '浓',
+'濄' => '㳡',
+'濆' => '𣸣',
+'濇' => '涩',
+'濕' => '湿',
+'濘' => '泞',
+'濜' => '浕',
+'濟' => '济',
+'濤' => '涛',
+'濧' => '㳔',
+'濫' => '滥',
+'濰' => '潍',
+'濱' => '滨',
+'濶' => '阔',
+'濺' => '溅',
+'濼' => '泺',
+'濾' => '滤',
+'瀂' => '澛',
+'瀃' => '𣽷',
+'瀅' => '滢',
+'瀆' => '渎',
+'瀇' => '㲿',
+'瀉' => '泻',
+'瀋' => '沈',
+'瀏' => '浏',
+'瀕' => '濒',
+'瀘' => '泸',
+'瀝' => '沥',
+'瀟' => '潇',
+'瀠' => '潆',
+'瀦' => '潴',
+'瀧' => '泷',
+'瀨' => '濑',
+'瀰' => '弥',
+'瀲' => '潋',
+'瀾' => '澜',
+'灃' => '沣',
+'灄' => '滠',
+'灋' => '法',
+'灑' => '洒',
+'灕' => '漓',
+'灘' => '滩',
+'灙' => '𣺼',
+'灝' => '灏',
+'灠' => '漤',
+'灣' => '湾',
+'灤' => '滦',
+'灧' => '滟',
+'灩' => '滟',
+'災' => '灾',
+'為' => '为',
+'烏' => '乌',
+'烖' => '灾',
+'烴' => '烃',
+'無' => '无',
+'煉' => '炼',
+'煑' => '煮',
+'煒' => '炜',
+'煗' => '暖',
+'煙' => '烟',
+'煢' => '茕',
+'煥' => '焕',
+'煩' => '烦',
+'煬' => '炀',
+'煱' => '㶽',
+'熅' => '煴',
+'熈' => '熙',
+'熉' => '𤈶',
+'熌' => '𤇄',
+'熒' => '荧',
+'熓' => '𤆡',
+'熗' => '炝',
+'熡' => '𤋏',
+'熱' => '热',
+'熲' => '颎',
+'熾' => '炽',
+'燁' => '烨',
+'燄' => '焰',
+'燈' => '灯',
+'燉' => '炖',
+'燒' => '烧',
+'燙' => '烫',
+'燜' => '焖',
+'營' => '营',
+'燦' => '灿',
+'燬' => '毁',
+'燭' => '烛',
+'燴' => '烩',
+'燶' => '㶶',
+'燻' => '熏',
+'燼' => '烬',
+'燾' => '焘',
+'爄' => '𤇃',
+'爍' => '烁',
+'爐' => '炉',
+'爗' => '烨',
+'爛' => '烂',
+'爭' => '争',
+'爲' => '为',
+'爺' => '爷',
+'爾' => '尔',
+'牀' => '床',
+'牆' => '墙',
+'牋' => '笺',
+'牎' => '窗',
+'牐' => '闸',
+'牓' => '榜',
+'牕' => '窗',
+'牘' => '牍',
+'牠' => '它',
+'牴' => '抵',
+'牽' => '牵',
+'犖' => '荦',
+'犢' => '犊',
+'犧' => '牺',
+'狀' => '状',
+'狥' => '徇',
+'狹' => '狭',
+'狽' => '狈',
+'猂' => '悍',
+'猙' => '狰',
+'猨' => '猿',
+'猶' => '犹',
+'猻' => '狲',
+'獁' => '犸',
+'獃' => '呆',
+'獄' => '狱',
+'獅' => '狮',
+'獎' => '奖',
+'獘' => '毙',
+'獧' => '狷',
+'獨' => '独',
+'獪' => '狯',
+'獫' => '猃',
+'獮' => '狝',
+'獰' => '狞',
+'獱' => '㺍',
+'獲' => '获',
+'獵' => '猎',
+'獷' => '犷',
+'獸' => '兽',
+'獺' => '獭',
+'獻' => '献',
+'獼' => '猕',
+'玀' => '猡',
+'玁' => '𤞤',
+'玅' => '妙',
+'現' => '现',
+'琖' => '盏',
+'琱' => '雕',
+'琺' => '珐',
+'琿' => '珲',
+'瑇' => '玳',
+'瑋' => '玮',
+'瑒' => '玚',
+'瑣' => '琐',
+'瑤' => '瑶',
+'瑩' => '莹',
+'瑪' => '玛',
+'瑯' => '琅',
+'瑲' => '玱',
+'瑽' => '𪻐',
+'璉' => '琏',
+'璡' => '琎',
+'璢' => '瑠',
+'璣' => '玑',
+'璦' => '瑷',
+'璫' => '珰',
+'璯' => '㻅',
+'環' => '环',
+'璵' => '玙',
+'璸' => '瑸',
+'璽' => '玺',
+'瓊' => '琼',
+'瓏' => '珑',
+'瓔' => '璎',
+'瓕' => '𤦀',
+'瓚' => '瓒',
+'甌' => '瓯',
+'甎' => '砖',
+'甕' => '瓮',
+'甖' => '罂',
+'甞' => '尝',
+'產' => '产',
+'産' => '产',
+'畂' => '亩',
+'畆' => '亩',
+'畝' => '亩',
+'畢' => '毕',
+'畧' => '略',
+'畫' => '画',
+'畮' => '亩',
+'異' => '异',
+'畱' => '留',
+'畵' => '画',
+'當' => '当',
+'疇' => '畴',
+'疊' => '叠',
+'疎' => '疏',
+'疘' => '肛',
+'疿' => '痱',
+'痐' => '蛔',
+'痙' => '痉',
+'痠' => '酸',
+'痲' => '痳',
+'痺' => '痹',
+'瘂' => '痖',
+'瘉' => '愈',
+'瘋' => '疯',
+'瘍' => '疡',
+'瘓' => '痪',
+'瘖' => '喑',
+'瘞' => '瘗',
+'瘡' => '疮',
+'瘧' => '疟',
+'瘮' => '瘆',
+'瘲' => '疭',
+'瘺' => '瘘',
+'瘻' => '瘘',
+'療' => '疗',
+'癄' => '憔',
+'癅' => '瘤',
+'癆' => '痨',
+'癇' => '痫',
+'癈' => '废',
+'癉' => '瘅',
+'癒' => '愈',
+'癘' => '疠',
+'癟' => '瘪',
+'癡' => '痴',
+'癢' => '痒',
+'癤' => '疖',
+'癥' => '症',
+'癧' => '疬',
+'癩' => '癞',
+'癬' => '癣',
+'癭' => '瘿',
+'癮' => '瘾',
+'癰' => '痈',
+'癱' => '瘫',
+'癲' => '癫',
+'發' => '发',
+'皁' => '皂',
+'皐' => '皋',
+'皚' => '皑',
+'皜' => '皓',
+'皟' => '𤾀',
+'皰' => '疱',
+'皷' => '鼓',
+'皸' => '皲',
+'皺' => '皱',
+'盃' => '杯',
+'盇' => '盍',
+'盌' => '碗',
+'盜' => '盗',
+'盞' => '盏',
+'盡' => '尽',
+'監' => '监',
+'盤' => '盘',
+'盧' => '卢',
+'盪' => '荡',
+'眎' => '视',
+'眞' => '真',
+'眡' => '视',
+'眥' => '眦',
+'眾' => '众',
+'睍' => '𪾢',
+'睏' => '困',
+'睜' => '睁',
+'睞' => '睐',
+'睠' => '眷',
+'睪' => '睾',
+'瞇' => '眯',
+'瞖' => '翳',
+'瞘' => '眍',
+'瞜' => '䁖',
+'瞞' => '瞒',
+'瞤' => '𥆧',
+'瞭' => '了',
+'瞶' => '瞆',
+'瞼' => '睑',
+'矁' => '瞅',
+'矇' => '蒙',
+'矓' => '眬',
+'矙' => '瞰',
+'矚' => '瞩',
+'矯' => '矫',
+'砲' => '炮',
+'硜' => '硁',
+'硤' => '硖',
+'硨' => '砗',
+'硯' => '砚',
+'碙' => '𥐻',
+'碩' => '硕',
+'碪' => '砧',
+'碭' => '砀',
+'碸' => '砜',
+'確' => '确',
+'碼' => '码',
+'碽' => '䂵',
+'磑' => '硙',
+'磚' => '砖',
+'磟' => '碌',
+'磠' => '硵',
+'磣' => '碜',
+'磧' => '碛',
+'磯' => '矶',
+'磽' => '硗',
+'礄' => '硚',
+'礆' => '碱',
+'礎' => '础',
+'礒' => '𥐟',
+'礙' => '碍',
+'礦' => '矿',
+'礪' => '砺',
+'礫' => '砾',
+'礬' => '矾',
+'礮' => '炮',
+'礱' => '砻',
+'祕' => '秘',
+'祘' => '算',
+'祿' => '禄',
+'禍' => '祸',
+'禎' => '祯',
+'禕' => '祎',
+'禡' => '祃',
+'禦' => '御',
+'禪' => '禅',
+'禮' => '礼',
+'禰' => '祢',
+'禱' => '祷',
+'禿' => '秃',
+'秈' => '籼',
+'秊' => '年',
+'秌' => '秋',
+'秖' => '只',
+'稅' => '税',
+'稈' => '秆',
+'稉' => '粳',
+'稏' => '䅉',
+'稜' => '棱',
+'稟' => '禀',
+'稬' => '糯',
+'稭' => '秸',
+'種' => '种',
+'稱' => '称',
+'稾' => '稿',
+'穀' => '谷',
+'穌' => '稣',
+'積' => '积',
+'穎' => '颖',
+'穠' => '秾',
+'穡' => '穑',
+'穢' => '秽',
+'穤' => '糯',
+'穨' => '颓',
+'穩' => '稳',
+'穫' => '获',
+'穭' => '稆',
+'穽' => '阱',
+'窓' => '窗',
+'窩' => '窝',
+'窪' => '洼',
+'窮' => '穷',
+'窯' => '窑',
+'窰' => '窑',
+'窵' => '窎',
+'窶' => '窭',
+'窺' => '窥',
+'窻' => '窗',
+'竄' => '窜',
+'竅' => '窍',
+'竇' => '窦',
+'竈' => '灶',
+'竊' => '窃',
+'竚' => '伫',
+'竝' => '并',
+'竢' => '俟',
+'竪' => '竖',
+'競' => '竞',
+'筆' => '笔',
+'筍' => '笋',
+'筞' => '策',
+'筧' => '笕',
+'筩' => '筒',
+'筯' => '箸',
+'筴' => '䇲',
+'箇' => '个',
+'箋' => '笺',
+'箏' => '筝',
+'箒' => '帚',
+'箠' => '棰',
+'節' => '节',
+'範' => '范',
+'築' => '筑',
+'篋' => '箧',
+'篔' => '筼',
+'篘' => '𥬠',
+'篛' => '箬',
+'篤' => '笃',
+'篩' => '筛',
+'篳' => '筚',
+'簀' => '箦',
+'簍' => '篓',
+'簑' => '蓑',
+'簒' => '篡',
+'簞' => '箪',
+'簡' => '简',
+'簣' => '篑',
+'簫' => '箫',
+'簮' => '簪',
+'簷' => '檐',
+'簹' => '筜',
+'簽' => '签',
+'簾' => '帘',
+'籃' => '篮',
+'籋' => '𥬞',
+'籌' => '筹',
+'籐' => '藤',
+'籔' => '䉤',
+'籙' => '箓',
+'籛' => '篯',
+'籜' => '箨',
+'籟' => '籁',
+'籠' => '笼',
+'籤' => '签',
+'籩' => '笾',
+'籪' => '簖',
+'籬' => '篱',
+'籮' => '箩',
+'籲' => '吁',
+'粃' => '秕',
+'粧' => '妆',
+'粵' => '粤',
+'糉' => '粽',
+'糝' => '糁',
+'糞' => '粪',
+'糧' => '粮',
+'糰' => '团',
+'糲' => '粝',
+'糴' => '籴',
+'糶' => '粜',
+'糹' => '纟',
+'糾' => '纠',
+'紀' => '纪',
+'紂' => '纣',
+'約' => '约',
+'紅' => '红',
+'紆' => '纡',
+'紇' => '纥',
+'紈' => '纨',
+'紉' => '纫',
+'紋' => '纹',
+'納' => '纳',
+'紐' => '纽',
+'紓' => '纾',
+'純' => '纯',
+'紕' => '纰',
+'紖' => '纼',
+'紗' => '纱',
+'紘' => '纮',
+'紙' => '纸',
+'級' => '级',
+'紛' => '纷',
+'紜' => '纭',
+'紝' => '纴',
+'紡' => '纺',
+'紥' => '扎',
+'紬' => '䌷',
+'紮' => '扎',
+'細' => '细',
+'紱' => '绂',
+'紲' => '绁',
+'紳' => '绅',
+'紵' => '纻',
+'紹' => '绍',
+'紺' => '绀',
+'紼' => '绋',
+'紿' => '绐',
+'絀' => '绌',
+'終' => '终',
+'絃' => '弦',
+'組' => '组',
+'絅' => '䌹',
+'絆' => '绊',
+'絎' => '绗',
+'絏' => '绁',
+'結' => '结',
+'絕' => '绝',
+'絛' => '绦',
+'絝' => '绔',
+'絞' => '绞',
+'絡' => '络',
+'絢' => '绚',
+'給' => '给',
+'絨' => '绒',
+'絰' => '绖',
+'統' => '统',
+'絲' => '丝',
+'絳' => '绛',
+'絶' => '绝',
+'絹' => '绢',
+'絺' => '𫄨',
+'綀' => '𦈌',
+'綁' => '绑',
+'綃' => '绡',
+'綆' => '绠',
+'綇' => '𦈋',
+'綈' => '绨',
+'綉' => '绣',
+'綌' => '绤',
+'綏' => '绥',
+'綐' => '䌼',
+'綑' => '捆',
+'經' => '经',
+'綜' => '综',
+'綞' => '缍',
+'綠' => '绿',
+'綢' => '绸',
+'綣' => '绻',
+'綫' => '线',
+'綬' => '绶',
+'維' => '维',
+'綯' => '绹',
+'綰' => '绾',
+'綱' => '纲',
+'網' => '网',
+'綴' => '缀',
+'綵' => '彩',
+'綸' => '纶',
+'綹' => '绺',
+'綺' => '绮',
+'綻' => '绽',
+'綽' => '绰',
+'綾' => '绫',
+'綿' => '绵',
+'緄' => '绲',
+'緇' => '缁',
+'緊' => '紧',
+'緋' => '绯',
+'緍' => '𦈏',
+'緐' => '繁',
+'緑' => '绿',
+'緒' => '绪',
+'緓' => '绬',
+'緔' => '绱',
+'緗' => '缃',
+'緘' => '缄',
+'緙' => '缂',
+'線' => '线',
+'緜' => '绵',
+'緝' => '缉',
+'緞' => '缎',
+'締' => '缔',
+'緡' => '缗',
+'緣' => '缘',
+'緥' => '褓',
+'緦' => '缌',
+'編' => '编',
+'緩' => '缓',
+'緬' => '缅',
+'緯' => '纬',
+'緰' => '𦈕',
+'緱' => '缑',
+'緲' => '缈',
+'練' => '练',
+'緶' => '缏',
+'緷' => '𦈉',
+'緸' => '𦈑',
+'緹' => '缇',
+'緻' => '致',
+'緼' => '缊',
+'縈' => '萦',
+'縉' => '缙',
+'縊' => '缢',
+'縋' => '缒',
+'縎' => '𦈔',
+'縐' => '绉',
+'縑' => '缣',
+'縕' => '缊',
+'縗' => '缞',
+'縛' => '缚',
+'縝' => '缜',
+'縞' => '缟',
+'縟' => '缛',
+'縣' => '县',
+'縧' => '绦',
+'縫' => '缝',
+'縬' => '𦈚',
+'縭' => '缡',
+'縮' => '缩',
+'縱' => '纵',
+'縲' => '缧',
+'縳' => '䌸',
+'縴' => '纤',
+'縵' => '缦',
+'縶' => '絷',
+'縷' => '缕',
+'縹' => '缥',
+'縺' => '𦈐',
+'總' => '总',
+'績' => '绩',
+'繃' => '绷',
+'繅' => '缫',
+'繆' => '缪',
+'繏' => '𦈝',
+'繐' => '穗',
+'繒' => '缯',
+'繓' => '𦈛',
+'織' => '织',
+'繕' => '缮',
+'繖' => '伞',
+'繙' => '翻',
+'繚' => '缭',
+'繞' => '绕',
+'繟' => '𦈎',
+'繡' => '绣',
+'繢' => '缋',
+'繦' => '襁',
+'繩' => '绳',
+'繪' => '绘',
+'繫' => '系',
+'繭' => '茧',
+'繮' => '缰',
+'繯' => '缳',
+'繰' => '缲',
+'繳' => '缴',
+'繸' => '䍁',
+'繹' => '绎',
+'繻' => '𦈡',
+'繼' => '继',
+'繽' => '缤',
+'繾' => '缱',
+'繿' => '䍀',
+'纁' => '𫄸',
+'纇' => '颣',
+'纈' => '缬',
+'纊' => '纩',
+'續' => '续',
+'纍' => '累',
+'纏' => '缠',
+'纓' => '缨',
+'纔' => '才',
+'纖' => '纤',
+'纘' => '缵',
+'纜' => '缆',
+'缽' => '钵',
+'罇' => '樽',
+'罈' => '坛',
+'罋' => '瓮',
+'罌' => '罂',
+'罎' => '坛',
+'罰' => '罚',
+'罵' => '骂',
+'罷' => '罢',
+'罸' => '罚',
+'羅' => '罗',
+'羆' => '罴',
+'羈' => '羁',
+'羋' => '芈',
+'羗' => '羌',
+'羢' => '绒',
+'羣' => '群',
+'羥' => '羟',
+'羨' => '羡',
+'義' => '义',
+'羶' => '膻',
+'翄' => '翅',
+'習' => '习',
+'翫' => '玩',
+'翬' => '翚',
+'翶' => '翱',
+'翹' => '翘',
+'翽' => '翙',
+'耡' => '锄',
+'耬' => '耧',
+'耮' => '耢',
+'聖' => '圣',
+'聞' => '闻',
+'聯' => '联',
+'聰' => '聪',
+'聲' => '声',
+'聳' => '耸',
+'聵' => '聩',
+'聶' => '聂',
+'職' => '职',
+'聹' => '聍',
+'聽' => '听',
+'聾' => '聋',
+'肅' => '肃',
+'肎' => '肯',
+'肐' => '胳',
+'肧' => '胚',
+'胷' => '胸',
+'脃' => '脆',
+'脅' => '胁',
+'脇' => '胁',
+'脈' => '脉',
+'脗' => '吻',
+'脛' => '胫',
+'脣' => '唇',
+'脥' => '𣍰',
+'脫' => '脱',
+'脹' => '胀',
+'腁' => '胼',
+'腎' => '肾',
+'腖' => '胨',
+'腡' => '脶',
+'腦' => '脑',
+'腪' => '𣍯',
+'腫' => '肿',
+'腳' => '脚',
+'腸' => '肠',
+'膃' => '腽',
+'膓' => '肠',
+'膕' => '腘',
+'膚' => '肤',
+'膞' => '䏝',
+'膠' => '胶',
+'膢' => '𦝼',
+'膩' => '腻',
+'膽' => '胆',
+'膾' => '脍',
+'膿' => '脓',
+'臈' => '腊',
+'臉' => '脸',
+'臋' => '臀',
+'臍' => '脐',
+'臏' => '膑',
+'臕' => '膘',
+'臗' => '𣎑',
+'臘' => '腊',
+'臙' => '胭',
+'臚' => '胪',
+'臝' => '裸',
+'臟' => '脏',
+'臠' => '脔',
+'臢' => '臜',
+'臥' => '卧',
+'臨' => '临',
+'臯' => '皋',
+'臺' => '台',
+'與' => '与',
+'興' => '兴',
+'舉' => '举',
+'舊' => '旧',
+'舖' => '铺',
+'舘' => '馆',
+'舩' => '船',
+'艙' => '舱',
+'艢' => '樯',
+'艣' => '橹',
+'艤' => '舣',
+'艦' => '舰',
+'艪' => '橹',
+'艫' => '舻',
+'艱' => '艰',
+'艷' => '艳',
+'芲' => '花',
+'芻' => '刍',
+'苧' => '苎',
+'茘' => '荔',
+'茲' => '兹',
+'荊' => '荆',
+'荳' => '豆',
+'莊' => '庄',
+'莖' => '茎',
+'莢' => '荚',
+'莧' => '苋',
+'華' => '华',
+'菸' => '烟',
+'萇' => '苌',
+'萊' => '莱',
+'萬' => '万',
+'萲' => '萱',
+'萴' => '荝',
+'萵' => '莴',
+'葉' => '叶',
+'葒' => '荭',
+'葠' => '参',
+'葤' => '荮',
+'葦' => '苇',
+'葯' => '药',
+'葷' => '荤',
+'蒓' => '莼',
+'蒔' => '莳',
+'蒞' => '莅',
+'蒼' => '苍',
+'蓀' => '荪',
+'蓆' => '席',
+'蓋' => '盖',
+'蓡' => '参',
+'蓮' => '莲',
+'蓯' => '苁',
+'蓴' => '莼',
+'蓽' => '荜',
+'蔔' => '卜',
+'蔕' => '蒂',
+'蔘' => '参',
+'蔞' => '蒌',
+'蔣' => '蒋',
+'蔥' => '葱',
+'蔦' => '茑',
+'蔭' => '荫',
+'蕁' => '荨',
+'蕆' => '蒇',
+'蕎' => '荞',
+'蕒' => '荬',
+'蕓' => '芸',
+'蕕' => '莸',
+'蕘' => '荛',
+'蕚' => '萼',
+'蕢' => '蒉',
+'蕩' => '荡',
+'蕪' => '芜',
+'蕭' => '萧',
+'蕷' => '蓣',
+'蕿' => '萱',
+'薀' => '蕰',
+'薈' => '荟',
+'薊' => '蓟',
+'薌' => '芗',
+'薑' => '姜',
+'薔' => '蔷',
+'薘' => '荙',
+'薟' => '莶',
+'薦' => '荐',
+'薩' => '萨',
+'薴' => '苧',
+'薺' => '荠',
+'藍' => '蓝',
+'藎' => '荩',
+'藝' => '艺',
+'藥' => '药',
+'藪' => '薮',
+'藭' => '䓖',
+'藴' => '蕴',
+'藶' => '苈',
+'藷' => '薯',
+'藹' => '蔼',
+'藺' => '蔺',
+'藼' => '萱',
+'蘀' => '萚',
+'蘄' => '蕲',
+'蘆' => '芦',
+'蘇' => '苏',
+'蘊' => '蕴',
+'蘐' => '萱',
+'蘓' => '苏',
+'蘚' => '藓',
+'蘞' => '蔹',
+'蘢' => '茏',
+'蘤' => '花',
+'蘭' => '兰',
+'蘺' => '蓠',
+'蘿' => '萝',
+'虆' => '蔂',
+'處' => '处',
+'虛' => '虚',
+'虜' => '虏',
+'號' => '号',
+'虧' => '亏',
+'虯' => '虬',
+'蚘' => '蛔',
+'蛕' => '蛔',
+'蛺' => '蛱',
+'蛻' => '蜕',
+'蜆' => '蚬',
+'蜋' => '螂',
+'蜖' => '蛔',
+'蜨' => '蝶',
+'蝕' => '蚀',
+'蝟' => '猬',
+'蝦' => '虾',
+'蝨' => '虱',
+'蝯' => '猿',
+'蝱' => '虻',
+'蝸' => '蜗',
+'螄' => '蛳',
+'螎' => '融',
+'螞' => '蚂',
+'螡' => '蚊',
+'螢' => '萤',
+'螮' => '䗖',
+'螻' => '蝼',
+'螿' => '螀',
+'蟁' => '蚊',
+'蟄' => '蛰',
+'蟇' => '蟆',
+'蟈' => '蝈',
+'蟎' => '螨',
+'蟣' => '虮',
+'蟬' => '蝉',
+'蟯' => '蛲',
+'蟲' => '虫',
+'蟶' => '蛏',
+'蟻' => '蚁',
+'蠁' => '蚃',
+'蠅' => '蝇',
+'蠆' => '虿',
+'蠍' => '蝎',
+'蠏' => '蟹',
+'蠐' => '蛴',
+'蠑' => '蝾',
+'蠒' => '茧',
+'蠔' => '蚝',
+'蠟' => '蜡',
+'蠣' => '蛎',
+'蠨' => '蟏',
+'蠭' => '蜂',
+'蠱' => '蛊',
+'蠶' => '蚕',
+'蠻' => '蛮',
+'衂' => '衄',
+'衆' => '众',
+'衇' => '脉',
+'衊' => '蔑',
+'術' => '术',
+'衕' => '同',
+'衚' => '胡',
+'衛' => '卫',
+'衝' => '冲',
+'衞' => '卫',
+'衺' => '邪',
+'袞' => '衮',
+'袟' => '帙',
+'袵' => '衽',
+'裊' => '袅',
+'裌' => '袷',
+'裏' => '里',
+'補' => '补',
+'裝' => '装',
+'裠' => '裙',
+'裡' => '里',
+'製' => '制',
+'複' => '复',
+'褌' => '裈',
+'褘' => '袆',
+'褭' => '袅',
+'褲' => '裤',
+'褳' => '裢',
+'褸' => '褛',
+'褻' => '亵',
+'襀' => '𫌀',
+'襃' => '褒',
+'襉' => '裥',
+'襍' => '杂',
+'襏' => '袯',
+'襖' => '袄',
+'襝' => '裣',
+'襠' => '裆',
+'襤' => '褴',
+'襪' => '袜',
+'襬' => '䙓',
+'襯' => '衬',
+'襲' => '袭',
+'襴' => '襕',
+'覇' => '霸',
+'覈' => '核',
+'覊' => '羁',
+'見' => '见',
+'覎' => '觃',
+'規' => '规',
+'覓' => '觅',
+'覔' => '觅',
+'視' => '视',
+'覘' => '觇',
+'覡' => '觋',
+'覥' => '觍',
+'覦' => '觎',
+'覩' => '睹',
+'親' => '亲',
+'覬' => '觊',
+'覯' => '觏',
+'覲' => '觐',
+'覷' => '觑',
+'覺' => '觉',
+'覼' => '𫌨',
+'覽' => '览',
+'覿' => '觌',
+'觀' => '观',
+'觝' => '抵',
+'觴' => '觞',
+'觶' => '觯',
+'觸' => '触',
+'訁' => '讠',
+'訂' => '订',
+'訃' => '讣',
+'計' => '计',
+'訊' => '讯',
+'訌' => '讧',
+'討' => '讨',
+'訐' => '讦',
+'訑' => '𫍙',
+'訒' => '讱',
+'訓' => '训',
+'訕' => '讪',
+'訖' => '讫',
+'託' => '托',
+'記' => '记',
+'訛' => '讹',
+'訝' => '讶',
+'訟' => '讼',
+'訢' => '䜣',
+'訣' => '诀',
+'訥' => '讷',
+'訩' => '讻',
+'訪' => '访',
+'設' => '设',
+'許' => '许',
+'訴' => '诉',
+'訶' => '诃',
+'診' => '诊',
+'註' => '注',
+'証' => '证',
+'詀' => '𧮪',
+'詁' => '诂',
+'詆' => '诋',
+'詎' => '讵',
+'詐' => '诈',
+'詒' => '诒',
+'詔' => '诏',
+'評' => '评',
+'詖' => '诐',
+'詗' => '诇',
+'詘' => '诎',
+'詛' => '诅',
+'詞' => '词',
+'詠' => '咏',
+'詡' => '诩',
+'詢' => '询',
+'詣' => '诣',
+'試' => '试',
+'詩' => '诗',
+'詫' => '诧',
+'詬' => '诟',
+'詭' => '诡',
+'詮' => '诠',
+'詰' => '诘',
+'話' => '话',
+'該' => '该',
+'詳' => '详',
+'詵' => '诜',
+'詶' => '酬',
+'詼' => '诙',
+'詿' => '诖',
+'誄' => '诔',
+'誅' => '诛',
+'誆' => '诓',
+'誇' => '夸',
+'誌' => '志',
+'認' => '认',
+'誑' => '诳',
+'誒' => '诶',
+'誕' => '诞',
+'誖' => '悖',
+'誘' => '诱',
+'誚' => '诮',
+'語' => '语',
+'誠' => '诚',
+'誡' => '诫',
+'誣' => '诬',
+'誤' => '误',
+'誥' => '诰',
+'誦' => '诵',
+'誨' => '诲',
+'說' => '说',
+'説' => '说',
+'誰' => '谁',
+'課' => '课',
+'誶' => '谇',
+'誹' => '诽',
+'誼' => '谊',
+'誾' => '訚',
+'調' => '调',
+'諂' => '谄',
+'諄' => '谆',
+'談' => '谈',
+'諉' => '诿',
+'請' => '请',
+'諍' => '诤',
+'諏' => '诹',
+'諑' => '诼',
+'諒' => '谅',
+'論' => '论',
+'諗' => '谂',
+'諛' => '谀',
+'諜' => '谍',
+'諝' => '谞',
+'諞' => '谝',
+'諡' => '谥',
+'諢' => '诨',
+'諤' => '谔',
+'諦' => '谛',
+'諧' => '谐',
+'諫' => '谏',
+'諭' => '谕',
+'諮' => '谘',
+'諰' => '𫍰',
+'諱' => '讳',
+'諳' => '谙',
+'諶' => '谌',
+'諷' => '讽',
+'諸' => '诸',
+'諺' => '谚',
+'諼' => '谖',
+'諾' => '诺',
+'謀' => '谋',
+'謁' => '谒',
+'謂' => '谓',
+'謄' => '誊',
+'謅' => '诌',
+'謊' => '谎',
+'謌' => '歌',
+'謎' => '谜',
+'謏' => '𫍲',
+'謐' => '谧',
+'謔' => '谑',
+'謖' => '谡',
+'謗' => '谤',
+'謙' => '谦',
+'謚' => '谥',
+'講' => '讲',
+'謝' => '谢',
+'謠' => '谣',
+'謡' => '谣',
+'謨' => '谟',
+'謫' => '谪',
+'謬' => '谬',
+'謭' => '谫',
+'謳' => '讴',
+'謹' => '谨',
+'謾' => '谩',
+'譁' => '哗',
+'譆' => '嘻',
+'證' => '证',
+'譊' => '𫍢',
+'譌' => '讹',
+'譎' => '谲',
+'譏' => '讥',
+'譔' => '撰',
+'譖' => '谮',
+'識' => '识',
+'譙' => '谯',
+'譚' => '谭',
+'譜' => '谱',
+'譟' => '噪',
+'譫' => '谵',
+'譭' => '毁',
+'譯' => '译',
+'議' => '议',
+'譴' => '谴',
+'護' => '护',
+'譸' => '诪',
+'譽' => '誉',
+'譾' => '谫',
+'讀' => '读',
+'讁' => '谪',
+'變' => '变',
+'讋' => '詟',
+'讌' => '䜩',
+'讎' => '仇',
+'讐' => '雠',
+'讒' => '谗',
+'讓' => '让',
+'讕' => '谰',
+'讖' => '谶',
+'讚' => '赞',
+'讜' => '谠',
+'讞' => '谳',
+'豈' => '岂',
+'豎' => '竖',
+'豐' => '丰',
+'豓' => '艳',
+'豔' => '艳',
+'豬' => '猪',
+'豶' => '豮',
+'貍' => '狸',
+'貓' => '猫',
+'貙' => '䝙',
+'貛' => '獾',
+'貝' => '贝',
+'貞' => '贞',
+'貟' => '贠',
+'負' => '负',
+'財' => '财',
+'貢' => '贡',
+'貧' => '贫',
+'貨' => '货',
+'販' => '贩',
+'貪' => '贪',
+'貫' => '贯',
+'責' => '责',
+'貯' => '贮',
+'貰' => '贳',
+'貲' => '赀',
+'貳' => '贰',
+'貴' => '贵',
+'貶' => '贬',
+'買' => '买',
+'貸' => '贷',
+'貺' => '贶',
+'費' => '费',
+'貼' => '贴',
+'貽' => '贻',
+'貿' => '贸',
+'賀' => '贺',
+'賁' => '贲',
+'賂' => '赂',
+'賃' => '赁',
+'賄' => '贿',
+'賅' => '赅',
+'資' => '资',
+'賈' => '贾',
+'賉' => '恤',
+'賊' => '贼',
+'賑' => '赈',
+'賒' => '赊',
+'賓' => '宾',
+'賕' => '赇',
+'賙' => '赒',
+'賚' => '赉',
+'賛' => '赞',
+'賜' => '赐',
+'賞' => '赏',
+'賟' => '𧹖',
+'賠' => '赔',
+'賡' => '赓',
+'賢' => '贤',
+'賣' => '卖',
+'賤' => '贱',
+'賦' => '赋',
+'賧' => '赕',
+'質' => '质',
+'賫' => '赍',
+'賬' => '账',
+'賭' => '赌',
+'賰' => '䞐',
+'賴' => '赖',
+'賵' => '赗',
+'賷' => '赍',
+'賺' => '赚',
+'賻' => '赙',
+'購' => '购',
+'賽' => '赛',
+'賾' => '赜',
+'贃' => '𧹗',
+'贄' => '贽',
+'贅' => '赘',
+'贇' => '赟',
+'贈' => '赠',
+'贊' => '赞',
+'贋' => '赝',
+'贍' => '赡',
+'贏' => '赢',
+'贐' => '赆',
+'贑' => '赣',
+'贓' => '赃',
+'贔' => '赑',
+'贖' => '赎',
+'贗' => '赝',
+'贛' => '赣',
+'贜' => '赃',
+'赬' => '赪',
+'趂' => '趁',
+'趕' => '赶',
+'趙' => '赵',
+'趨' => '趋',
+'趲' => '趱',
+'跡' => '迹',
+'跥' => '跺',
+'跴' => '踩',
+'踁' => '胫',
+'踐' => '践',
+'踫' => '碰',
+'踰' => '逾',
+'踴' => '踊',
+'蹌' => '跄',
+'蹏' => '蹄',
+'蹔' => '暂',
+'蹕' => '跸',
+'蹟' => '迹',
+'蹠' => '跖',
+'蹣' => '蹒',
+'蹤' => '踪',
+'蹧' => '糟',
+'蹵' => '蹴',
+'蹺' => '跷',
+'蹻' => '𫏋',
+'躂' => '跶',
+'躉' => '趸',
+'躊' => '踌',
+'躋' => '跻',
+'躍' => '跃',
+'躎' => '䟢',
+'躑' => '踯',
+'躒' => '跞',
+'躓' => '踬',
+'躕' => '蹰',
+'躚' => '跹',
+'躝' => '𨅬',
+'躡' => '蹑',
+'躥' => '蹿',
+'躦' => '躜',
+'躪' => '躏',
+'躭' => '耽',
+'躳' => '躬',
+'躶' => '裸',
+'軀' => '躯',
+'軉' => '𨉗',
+'車' => '车',
+'軋' => '轧',
+'軌' => '轨',
+'軍' => '军',
+'軏' => '𫐄',
+'軑' => '轪',
+'軒' => '轩',
+'軔' => '轫',
+'軗' => '𨐅',
+'軛' => '轭',
+'軟' => '软',
+'軤' => '轷',
+'軨' => '𫐉',
+'軫' => '轸',
+'軲' => '轱',
+'軸' => '轴',
+'軹' => '轵',
+'軺' => '轺',
+'軻' => '轲',
+'軼' => '轶',
+'軾' => '轼',
+'較' => '较',
+'輄' => '𨐈',
+'輅' => '辂',
+'輇' => '辁',
+'輈' => '辀',
+'載' => '载',
+'輊' => '轾',
+'輒' => '辄',
+'輓' => '挽',
+'輔' => '辅',
+'輕' => '轻',
+'輗' => '𫐐',
+'輙' => '辄',
+'輛' => '辆',
+'輜' => '辎',
+'輝' => '辉',
+'輞' => '辋',
+'輟' => '辍',
+'輥' => '辊',
+'輦' => '辇',
+'輩' => '辈',
+'輪' => '轮',
+'輬' => '辌',
+'輭' => '软',
+'輮' => '𫐓',
+'輯' => '辑',
+'輳' => '辏',
+'輸' => '输',
+'輻' => '辐',
+'輼' => '辒',
+'輾' => '辗',
+'輿' => '舆',
+'轀' => '辒',
+'轂' => '毂',
+'轄' => '辖',
+'轅' => '辕',
+'轆' => '辘',
+'轉' => '转',
+'轍' => '辙',
+'轎' => '轿',
+'轔' => '辚',
+'轟' => '轰',
+'轡' => '辔',
+'轢' => '轹',
+'轣' => '𫐆',
+'轤' => '轳',
+'辠' => '罪',
+'辢' => '辣',
+'辤' => '辞',
+'辦' => '办',
+'辭' => '辞',
+'辮' => '辫',
+'辯' => '辩',
+'農' => '农',
+'辳' => '农',
+'迴' => '回',
+'迻' => '移',
+'逈' => '迥',
+'逕' => '迳',
+'這' => '这',
+'連' => '连',
+'逥' => '回',
+'逩' => '奔',
+'逬' => '迸',
+'週' => '周',
+'進' => '进',
+'遉' => '侦',
+'遊' => '游',
+'運' => '运',
+'過' => '过',
+'達' => '达',
+'違' => '违',
+'遙' => '遥',
+'遜' => '逊',
+'遞' => '递',
+'遠' => '远',
+'遡' => '溯',
+'適' => '适',
+'遯' => '遁',
+'遲' => '迟',
+'遷' => '迁',
+'選' => '选',
+'遺' => '遗',
+'遼' => '辽',
+'邁' => '迈',
+'還' => '还',
+'邇' => '迩',
+'邊' => '边',
+'邏' => '逻',
+'邐' => '逦',
+'郟' => '郏',
+'郵' => '邮',
+'鄆' => '郓',
+'鄉' => '乡',
+'鄒' => '邹',
+'鄔' => '邬',
+'鄖' => '郧',
+'鄧' => '邓',
+'鄭' => '郑',
+'鄰' => '邻',
+'鄲' => '郸',
+'鄴' => '邺',
+'鄶' => '郐',
+'鄺' => '邝',
+'酇' => '酂',
+'酈' => '郦',
+'酖' => '鸩',
+'酧' => '酬',
+'醃' => '腌',
+'醆' => '盏',
+'醕' => '醇',
+'醜' => '丑',
+'醞' => '酝',
+'醣' => '糖',
+'醫' => '医',
+'醬' => '酱',
+'醯' => '酰',
+'醱' => '酦',
+'醻' => '酬',
+'醼' => '宴',
+'釀' => '酿',
+'釁' => '衅',
+'釃' => '酾',
+'釅' => '酽',
+'釋' => '释',
+'釒' => '钅',
+'釓' => '钆',
+'釔' => '钇',
+'釕' => '钌',
+'釗' => '钊',
+'釘' => '钉',
+'釙' => '钋',
+'針' => '针',
+'釣' => '钓',
+'釤' => '钐',
+'釦' => '扣',
+'釧' => '钏',
+'釩' => '钒',
+'釬' => '焊',
+'釳' => '𨰿',
+'釵' => '钗',
+'釷' => '钍',
+'釹' => '钕',
+'釺' => '钎',
+'釾' => '䥺',
+'鈀' => '钯',
+'鈁' => '钫',
+'鈃' => '钘',
+'鈄' => '钭',
+'鈅' => '钥',
+'鈇' => '𫓧',
+'鈈' => '钚',
+'鈉' => '钠',
+'鈋' => '𨱂',
+'鈍' => '钝',
+'鈎' => '钩',
+'鈐' => '钤',
+'鈑' => '钣',
+'鈒' => '钑',
+'鈔' => '钞',
+'鈕' => '钮',
+'鈞' => '钧',
+'鈠' => '𨱁',
+'鈣' => '钙',
+'鈥' => '钬',
+'鈦' => '钛',
+'鈧' => '钪',
+'鈮' => '铌',
+'鈯' => '𨱄',
+'鈰' => '铈',
+'鈲' => '𨱃',
+'鈳' => '钶',
+'鈴' => '铃',
+'鈷' => '钴',
+'鈸' => '钹',
+'鈹' => '铍',
+'鈺' => '钰',
+'鈽' => '钸',
+'鈾' => '铀',
+'鈿' => '钿',
+'鉀' => '钾',
+'鉁' => '𨱅',
+'鉄' => '铁',
+'鉅' => '钜',
+'鉆' => '钻',
+'鉈' => '铊',
+'鉉' => '铉',
+'鉋' => '铇',
+'鉍' => '铋',
+'鉑' => '铂',
+'鉕' => '钷',
+'鉗' => '钳',
+'鉚' => '铆',
+'鉛' => '铅',
+'鉞' => '钺',
+'鉢' => '钵',
+'鉤' => '钩',
+'鉦' => '钲',
+'鉬' => '钼',
+'鉭' => '钽',
+'鉶' => '铏',
+'鉸' => '铰',
+'鉺' => '铒',
+'鉻' => '铬',
+'鉿' => '铪',
+'銀' => '银',
+'銃' => '铳',
+'銅' => '铜',
+'銍' => '铚',
+'銑' => '铣',
+'銓' => '铨',
+'銖' => '铢',
+'銘' => '铭',
+'銚' => '铫',
+'銛' => '铦',
+'銜' => '衔',
+'銠' => '铑',
+'銣' => '铷',
+'銥' => '铱',
+'銦' => '铟',
+'銨' => '铵',
+'銩' => '铥',
+'銪' => '铕',
+'銫' => '铯',
+'銬' => '铐',
+'銱' => '铞',
+'銲' => '焊',
+'銳' => '锐',
+'銶' => '𨱇',
+'銷' => '销',
+'銻' => '锑',
+'銼' => '锉',
+'鋁' => '铝',
+'鋃' => '锒',
+'鋅' => '锌',
+'鋇' => '钡',
+'鋉' => '𨱈',
+'鋌' => '铤',
+'鋏' => '铗',
+'鋒' => '锋',
+'鋙' => '铻',
+'鋝' => '锊',
+'鋟' => '锓',
+'鋣' => '铘',
+'鋤' => '锄',
+'鋥' => '锃',
+'鋦' => '锔',
+'鋨' => '锇',
+'鋩' => '铓',
+'鋪' => '铺',
+'鋭' => '锐',
+'鋮' => '铖',
+'鋯' => '锆',
+'鋰' => '锂',
+'鋱' => '铽',
+'鋶' => '锍',
+'鋸' => '锯',
+'鋼' => '钢',
+'錁' => '锞',
+'錂' => '𨱋',
+'錄' => '录',
+'錆' => '锖',
+'錇' => '锫',
+'錈' => '锩',
+'錏' => '铔',
+'錐' => '锥',
+'錒' => '锕',
+'錕' => '锟',
+'錘' => '锤',
+'錙' => '锱',
+'錚' => '铮',
+'錛' => '锛',
+'錟' => '锬',
+'錠' => '锭',
+'錡' => '锜',
+'錢' => '钱',
+'錦' => '锦',
+'錨' => '锚',
+'錩' => '锠',
+'錫' => '锡',
+'錮' => '锢',
+'錯' => '错',
+'録' => '录',
+'錳' => '锰',
+'錶' => '表',
+'錸' => '铼',
+'鍀' => '锝',
+'鍁' => '锨',
+'鍃' => '锪',
+'鍄' => '𨱉',
+'鍆' => '钔',
+'鍇' => '锴',
+'鍈' => '锳',
+'鍊' => '炼',
+'鍋' => '锅',
+'鍍' => '镀',
+'鍔' => '锷',
+'鍘' => '铡',
+'鍚' => '钖',
+'鍛' => '锻',
+'鍠' => '锽',
+'鍤' => '锸',
+'鍥' => '锲',
+'鍩' => '锘',
+'鍫' => '锹',
+'鍬' => '锹',
+'鍮' => '𨱎',
+'鍰' => '锾',
+'鍳' => '鉴',
+'鍵' => '键',
+'鍶' => '锶',
+'鍺' => '锗',
+'鍾' => '锺',
+'鎂' => '镁',
+'鎄' => '锿',
+'鎇' => '镅',
+'鎊' => '镑',
+'鎌' => '镰',
+'鎔' => '镕',
+'鎖' => '锁',
+'鎗' => '枪',
+'鎘' => '镉',
+'鎚' => '锤',
+'鎛' => '镈',
+'鎝' => '𨱏',
+'鎡' => '镃',
+'鎢' => '钨',
+'鎣' => '蓥',
+'鎦' => '镏',
+'鎧' => '铠',
+'鎩' => '铩',
+'鎪' => '锼',
+'鎬' => '镐',
+'鎭' => '镇',
+'鎮' => '镇',
+'鎯' => '𨱍',
+'鎰' => '镒',
+'鎲' => '镋',
+'鎳' => '镍',
+'鎵' => '镓',
+'鎷' => '𨰾',
+'鎸' => '镌',
+'鎻' => '锁',
+'鎿' => '镎',
+'鏃' => '镞',
+'鏆' => '𨱌',
+'鏇' => '镟',
+'鏈' => '链',
+'鏉' => '𨱒',
+'鏌' => '镆',
+'鏍' => '镙',
+'鏐' => '镠',
+'鏑' => '镝',
+'鏗' => '铿',
+'鏘' => '锵',
+'鏚' => '戚',
+'鏜' => '镗',
+'鏝' => '镘',
+'鏞' => '镛',
+'鏟' => '铲',
+'鏡' => '镜',
+'鏢' => '镖',
+'鏤' => '镂',
+'鏦' => '𫓩',
+'鏨' => '錾',
+'鏰' => '镚',
+'鏵' => '铧',
+'鏷' => '镤',
+'鏹' => '镪',
+'鏺' => '䥽',
+'鏽' => '锈',
+'鐃' => '铙',
+'鐄' => '𨱑',
+'鐋' => '铴',
+'鐍' => '𫔎',
+'鐎' => '𨱓',
+'鐏' => '𨱔',
+'鐐' => '镣',
+'鐒' => '铹',
+'鐓' => '镦',
+'鐔' => '镡',
+'鐘' => '钟',
+'鐙' => '镫',
+'鐝' => '镢',
+'鐠' => '镨',
+'鐥' => '䦅',
+'鐦' => '锎',
+'鐧' => '锏',
+'鐨' => '镄',
+'鐫' => '镌',
+'鐮' => '镰',
+'鐯' => '䦃',
+'鐲' => '镯',
+'鐳' => '镭',
+'鐵' => '铁',
+'鐶' => '镮',
+'鐸' => '铎',
+'鐺' => '铛',
+'鐿' => '镱',
+'鑄' => '铸',
+'鑊' => '镬',
+'鑌' => '镔',
+'鑑' => '鉴',
+'鑒' => '鉴',
+'鑔' => '镲',
+'鑕' => '锧',
+'鑚' => '钻',
+'鑛' => '矿',
+'鑞' => '镴',
+'鑠' => '铄',
+'鑣' => '镳',
+'鑤' => '刨',
+'鑥' => '镥',
+'鑭' => '镧',
+'鑰' => '钥',
+'鑱' => '镵',
+'鑲' => '镶',
+'鑵' => '罐',
+'鑷' => '镊',
+'鑹' => '镩',
+'鑼' => '锣',
+'鑽' => '钻',
+'鑾' => '銮',
+'鑿' => '凿',
+'钁' => '镢',
+'钂' => '镋',
+'長' => '长',
+'門' => '门',
+'閂' => '闩',
+'閃' => '闪',
+'閆' => '闫',
+'閈' => '闬',
+'閉' => '闭',
+'開' => '开',
+'閌' => '闶',
+'閍' => '𨸂',
+'閎' => '闳',
+'閏' => '闰',
+'閐' => '𨸃',
+'閑' => '闲',
+'閒' => '闲',
+'間' => '间',
+'閔' => '闵',
+'閘' => '闸',
+'閙' => '闹',
+'閡' => '阂',
+'閣' => '阁',
+'閤' => '阁',
+'閥' => '阀',
+'閧' => '哄',
+'閨' => '闺',
+'閩' => '闽',
+'閫' => '阃',
+'閬' => '阆',
+'閭' => '闾',
+'閱' => '阅',
+'閲' => '阅',
+'閶' => '阊',
+'閹' => '阉',
+'閻' => '阎',
+'閼' => '阏',
+'閽' => '阍',
+'閾' => '阈',
+'閿' => '阌',
+'闃' => '阒',
+'闆' => '板',
+'闇' => '暗',
+'闈' => '闱',
+'闊' => '阔',
+'闋' => '阕',
+'闌' => '阑',
+'闍' => '阇',
+'闐' => '阗',
+'闒' => '阘',
+'闓' => '闿',
+'闔' => '阖',
+'闕' => '阙',
+'闖' => '闯',
+'闚' => '窥',
+'關' => '关',
+'闞' => '阚',
+'闠' => '阓',
+'闡' => '阐',
+'闢' => '辟',
+'闤' => '阛',
+'闥' => '闼',
+'阨' => '厄',
+'阬' => '坑',
+'陗' => '峭',
+'陘' => '陉',
+'陜' => '陕',
+'陝' => '陕',
+'陣' => '阵',
+'陰' => '阴',
+'陳' => '陈',
+'陸' => '陆',
+'陻' => '堙',
+'陽' => '阳',
+'陿' => '狭',
+'隂' => '阴',
+'隄' => '堤',
+'隉' => '陧',
+'隊' => '队',
+'階' => '阶',
+'隕' => '陨',
+'隖' => '坞',
+'際' => '际',
+'隣' => '邻',
+'隨' => '随',
+'險' => '险',
+'隱' => '隐',
+'隴' => '陇',
+'隷' => '隶',
+'隸' => '隶',
+'隻' => '只',
+'雋' => '隽',
+'雖' => '虽',
+'雙' => '双',
+'雛' => '雏',
+'雜' => '杂',
+'雞' => '鸡',
+'離' => '离',
+'難' => '难',
+'雲' => '云',
+'電' => '电',
+'霢' => '霡',
+'霧' => '雾',
+'霽' => '霁',
+'靂' => '雳',
+'靄' => '霭',
+'靆' => '叇',
+'靈' => '灵',
+'靉' => '叆',
+'靚' => '靓',
+'靜' => '静',
+'靦' => '腼',
+'靨' => '靥',
+'靭' => '韧',
+'靱' => '韧',
+'鞀' => '鼗',
+'鞏' => '巩',
+'鞝' => '绱',
+'鞦' => '秋',
+'鞵' => '鞋',
+'鞽' => '鞒',
+'鞾' => '靴',
+'韁' => '缰',
+'韃' => '鞑',
+'韆' => '千',
+'韈' => '袜',
+'韉' => '鞯',
+'韋' => '韦',
+'韌' => '韧',
+'韍' => '韨',
+'韓' => '韩',
+'韙' => '韪',
+'韜' => '韬',
+'韞' => '韫',
+'韤' => '袜',
+'韮' => '韭',
+'韻' => '韵',
+'響' => '响',
+'頁' => '页',
+'頂' => '顶',
+'頃' => '顷',
+'項' => '项',
+'順' => '顺',
+'頇' => '顸',
+'須' => '须',
+'頊' => '顼',
+'頌' => '颂',
+'頎' => '颀',
+'頏' => '颃',
+'預' => '预',
+'頑' => '顽',
+'頒' => '颁',
+'頓' => '顿',
+'頗' => '颇',
+'領' => '领',
+'頜' => '颌',
+'頟' => '额',
+'頡' => '颉',
+'頤' => '颐',
+'頦' => '颏',
+'頭' => '头',
+'頮' => '颒',
+'頰' => '颊',
+'頲' => '颋',
+'頴' => '颕',
+'頷' => '颔',
+'頸' => '颈',
+'頹' => '颓',
+'頻' => '频',
+'頼' => '赖',
+'頽' => '颓',
+'顃' => '𩖖',
+'顆' => '颗',
+'顇' => '悴',
+'顋' => '腮',
+'題' => '题',
+'額' => '额',
+'顎' => '颚',
+'顏' => '颜',
+'顒' => '颙',
+'顓' => '颛',
+'顔' => '颜',
+'願' => '愿',
+'顙' => '颡',
+'顛' => '颠',
+'類' => '类',
+'顢' => '颟',
+'顥' => '颢',
+'顦' => '憔',
+'顧' => '顾',
+'顫' => '颤',
+'顬' => '颥',
+'顯' => '显',
+'顰' => '颦',
+'顱' => '颅',
+'顳' => '颞',
+'顴' => '颧',
+'風' => '风',
+'颭' => '飐',
+'颮' => '飑',
+'颯' => '飒',
+'颰' => '𩙥',
+'颱' => '台',
+'颳' => '刮',
+'颶' => '飓',
+'颷' => '𩙪',
+'颸' => '飔',
+'颺' => '飏',
+'颻' => '飖',
+'颼' => '飕',
+'颾' => '𩙫',
+'飀' => '飗',
+'飃' => '飘',
+'飄' => '飘',
+'飆' => '飙',
+'飈' => '飚',
+'飛' => '飞',
+'飜' => '翻',
+'飠' => '饣',
+'飢' => '饥',
+'飣' => '饤',
+'飤' => '饲',
+'飥' => '饦',
+'飩' => '饨',
+'飪' => '饪',
+'飫' => '饫',
+'飭' => '饬',
+'飯' => '饭',
+'飱' => '飧',
+'飲' => '饮',
+'飴' => '饴',
+'飼' => '饲',
+'飽' => '饱',
+'飾' => '饰',
+'飿' => '饳',
+'餁' => '饪',
+'餃' => '饺',
+'餄' => '饸',
+'餅' => '饼',
+'餈' => '糍',
+'餉' => '饷',
+'養' => '养',
+'餌' => '饵',
+'餎' => '饹',
+'餏' => '饻',
+'餑' => '饽',
+'餒' => '馁',
+'餓' => '饿',
+'餔' => '𫗦',
+'餕' => '馂',
+'餖' => '饾',
+'餗' => '𫗧',
+'餘' => '馀',
+'餚' => '肴',
+'餛' => '馄',
+'餜' => '馃',
+'餞' => '饯',
+'餡' => '馅',
+'餦' => '𫗠',
+'館' => '馆',
+'餭' => '𫗮',
+'餱' => '糇',
+'餳' => '饧',
+'餵' => '喂',
+'餶' => '馉',
+'餷' => '馇',
+'餸' => '𩠌',
+'餹' => '糖',
+'餺' => '馎',
+'餻' => '糕',
+'餼' => '饩',
+'餽' => '馈',
+'餾' => '馏',
+'餿' => '馊',
+'饁' => '馌',
+'饃' => '馍',
+'饅' => '馒',
+'饈' => '馐',
+'饉' => '馑',
+'饊' => '馓',
+'饋' => '馈',
+'饌' => '馔',
+'饍' => '膳',
+'饑' => '饥',
+'饒' => '饶',
+'饗' => '飨',
+'饘' => '𫗴',
+'饜' => '餍',
+'饝' => '馍',
+'饞' => '馋',
+'饢' => '馕',
+'馬' => '马',
+'馭' => '驭',
+'馮' => '冯',
+'馱' => '驮',
+'馳' => '驰',
+'馴' => '驯',
+'馹' => '驲',
+'駁' => '驳',
+'駃' => '𫘝',
+'駈' => '驱',
+'駎' => '𩧨',
+'駐' => '驻',
+'駑' => '驽',
+'駒' => '驹',
+'駔' => '驵',
+'駕' => '驾',
+'駘' => '骀',
+'駙' => '驸',
+'駚' => '𩧫',
+'駛' => '驶',
+'駝' => '驼',
+'駟' => '驷',
+'駡' => '骂',
+'駢' => '骈',
+'駧' => '𩧲',
+'駩' => '𩧴',
+'駭' => '骇',
+'駰' => '骃',
+'駱' => '骆',
+'駶' => '𩧺',
+'駸' => '骎',
+'駻' => '𫘣',
+'駿' => '骏',
+'騁' => '骋',
+'騂' => '骍',
+'騃' => '𫘤',
+'騅' => '骓',
+'騌' => '骔',
+'騍' => '骒',
+'騎' => '骑',
+'騏' => '骐',
+'騐' => '验',
+'騔' => '𩨀',
+'騖' => '骛',
+'騙' => '骗',
+'騚' => '𩨊',
+'騝' => '𩨃',
+'騟' => '𩨈',
+'騠' => '𫘨',
+'騣' => '鬃',
+'騤' => '骙',
+'騧' => '䯄',
+'騪' => '𩨄',
+'騫' => '骞',
+'騭' => '骘',
+'騮' => '骝',
+'騰' => '腾',
+'騶' => '驺',
+'騷' => '骚',
+'騸' => '骟',
+'騾' => '骡',
+'驀' => '蓦',
+'驁' => '骜',
+'驂' => '骖',
+'驃' => '骠',
+'驄' => '骢',
+'驅' => '驱',
+'驊' => '骅',
+'驋' => '𩧯',
+'驌' => '骕',
+'驍' => '骁',
+'驏' => '骣',
+'驕' => '骄',
+'驗' => '验',
+'驘' => '骡',
+'驚' => '惊',
+'驛' => '驿',
+'驟' => '骤',
+'驢' => '驴',
+'驤' => '骧',
+'驥' => '骥',
+'驦' => '骦',
+'驪' => '骊',
+'驫' => '骉',
+'骯' => '肮',
+'骽' => '腿',
+'骾' => '鲠',
+'髈' => '膀',
+'髏' => '髅',
+'髒' => '脏',
+'體' => '体',
+'髕' => '髌',
+'髖' => '髋',
+'髥' => '髯',
+'髮' => '发',
+'鬀' => '剃',
+'鬆' => '松',
+'鬉' => '鬃',
+'鬍' => '胡',
+'鬚' => '须',
+'鬢' => '鬓',
+'鬥' => '斗',
+'鬦' => '斗',
+'鬧' => '闹',
+'鬨' => '哄',
+'鬩' => '阋',
+'鬪' => '斗',
+'鬮' => '阄',
+'鬰' => '郁',
+'鬱' => '郁',
+'鬹' => '鬶',
+'魎' => '魉',
+'魘' => '魇',
+'魚' => '鱼',
+'魛' => '鱽',
+'魟' => '𫚉',
+'魢' => '鱾',
+'魥' => '𩽹',
+'魨' => '鲀',
+'魯' => '鲁',
+'魴' => '鲂',
+'魷' => '鱿',
+'魺' => '鲄',
+'鮁' => '鲅',
+'鮃' => '鲆',
+'鮄' => '𫚒',
+'鮊' => '鲌',
+'鮋' => '鲉',
+'鮍' => '鲏',
+'鮎' => '鲇',
+'鮐' => '鲐',
+'鮑' => '鲍',
+'鮒' => '鲋',
+'鮓' => '鲊',
+'鮚' => '鲒',
+'鮜' => '鲘',
+'鮝' => '鲞',
+'鮞' => '鲕',
+'鮟' => '𩽾',
+'鮣' => '䲟',
+'鮦' => '鲖',
+'鮪' => '鲔',
+'鮫' => '鲛',
+'鮭' => '鲑',
+'鮮' => '鲜',
+'鮰' => '𫚔',
+'鮳' => '鲓',
+'鮶' => '鲪',
+'鮸' => '𩾃',
+'鮺' => '鲝',
+'鯀' => '鲧',
+'鯁' => '鲠',
+'鯄' => '𩾁',
+'鯆' => '𫚙',
+'鯇' => '鲩',
+'鯉' => '鲤',
+'鯊' => '鲨',
+'鯒' => '鲬',
+'鯔' => '鲻',
+'鯕' => '鲯',
+'鯖' => '鲭',
+'鯗' => '鲞',
+'鯛' => '鲷',
+'鯝' => '鲴',
+'鯡' => '鲱',
+'鯢' => '鲵',
+'鯤' => '鲲',
+'鯧' => '鲳',
+'鯨' => '鲸',
+'鯪' => '鲮',
+'鯫' => '鲰',
+'鯰' => '鲶',
+'鯱' => '𩾇',
+'鯴' => '鲺',
+'鯶' => '𩽼',
+'鯷' => '鳀',
+'鯽' => '鲫',
+'鯿' => '鳊',
+'鰁' => '鳈',
+'鰂' => '鲗',
+'鰃' => '鳂',
+'鰆' => '䲠',
+'鰈' => '鲽',
+'鰉' => '鳇',
+'鰌' => '䲡',
+'鰍' => '鳅',
+'鰏' => '鲾',
+'鰐' => '鳄',
+'鰒' => '鳆',
+'鰓' => '鳃',
+'鰛' => '鳁',
+'鰜' => '鳒',
+'鰟' => '鳑',
+'鰠' => '鳋',
+'鰣' => '鲥',
+'鰤' => '𫚕',
+'鰥' => '鳏',
+'鰧' => '䲢',
+'鰨' => '鳎',
+'鰩' => '鳐',
+'鰭' => '鳍',
+'鰮' => '鳁',
+'鰱' => '鲢',
+'鰲' => '鳌',
+'鰳' => '鳓',
+'鰵' => '鳘',
+'鰷' => '鲦',
+'鰹' => '鲣',
+'鰺' => '鲹',
+'鰻' => '鳗',
+'鰼' => '鳛',
+'鰾' => '鳔',
+'鱂' => '鳉',
+'鱅' => '鳙',
+'鱇' => '𩾌',
+'鱈' => '鳕',
+'鱉' => '鳖',
+'鱒' => '鳟',
+'鱔' => '鳝',
+'鱖' => '鳜',
+'鱗' => '鳞',
+'鱘' => '鲟',
+'鱝' => '鲼',
+'鱟' => '鲎',
+'鱠' => '鲙',
+'鱣' => '鳣',
+'鱤' => '鳡',
+'鱧' => '鳢',
+'鱨' => '鲿',
+'鱭' => '鲚',
+'鱮' => '𫚈',
+'鱯' => '鳠',
+'鱷' => '鳄',
+'鱸' => '鲈',
+'鱺' => '鲡',
+'鳥' => '鸟',
+'鳧' => '凫',
+'鳩' => '鸠',
+'鳬' => '凫',
+'鳲' => '鸤',
+'鳳' => '凤',
+'鳴' => '鸣',
+'鳶' => '鸢',
+'鳷' => '𫛛',
+'鳼' => '𪉃',
+'鳾' => '䴓',
+'鴃' => '𫛞',
+'鴆' => '鸩',
+'鴇' => '鸨',
+'鴈' => '雁',
+'鴉' => '鸦',
+'鴒' => '鸰',
+'鴕' => '鸵',
+'鴗' => '𫁡',
+'鴛' => '鸳',
+'鴜' => '𪉈',
+'鴝' => '鸲',
+'鴞' => '鸮',
+'鴟' => '鸱',
+'鴣' => '鸪',
+'鴦' => '鸯',
+'鴨' => '鸭',
+'鴯' => '鸸',
+'鴰' => '鸹',
+'鴲' => '𪉆',
+'鴴' => '鸻',
+'鴷' => '䴕',
+'鴻' => '鸿',
+'鴿' => '鸽',
+'鵁' => '䴔',
+'鵂' => '鸺',
+'鵃' => '鸼',
+'鵐' => '鹀',
+'鵑' => '鹃',
+'鵒' => '鹆',
+'鵓' => '鹁',
+'鵚' => '𪉍',
+'鵜' => '鹈',
+'鵝' => '鹅',
+'鵞' => '鹅',
+'鵠' => '鹄',
+'鵡' => '鹉',
+'鵪' => '鹌',
+'鵬' => '鹏',
+'鵮' => '鹐',
+'鵯' => '鹎',
+'鵰' => '雕',
+'鵲' => '鹊',
+'鵶' => '鸦',
+'鵷' => '鹓',
+'鵾' => '鹍',
+'鶄' => '䴖',
+'鶇' => '鸫',
+'鶉' => '鹑',
+'鶊' => '鹒',
+'鶒' => '𫛶',
+'鶓' => '鹋',
+'鶖' => '鹙',
+'鶗' => '𫛸',
+'鶘' => '鹕',
+'鶚' => '鹗',
+'鶡' => '鹖',
+'鶥' => '鹛',
+'鶩' => '鹜',
+'鶪' => '䴗',
+'鶬' => '鸧',
+'鶯' => '莺',
+'鶲' => '鹟',
+'鶴' => '鹤',
+'鶹' => '鹠',
+'鶺' => '鹡',
+'鶻' => '鹘',
+'鶼' => '鹣',
+'鶿' => '鹚',
+'鷀' => '鹚',
+'鷁' => '鹢',
+'鷂' => '鹞',
+'鷄' => '鸡',
+'鷈' => '䴘',
+'鷊' => '鹝',
+'鷓' => '鹧',
+'鷔' => '𪉑',
+'鷖' => '鹥',
+'鷗' => '鸥',
+'鷙' => '鸷',
+'鷚' => '鹨',
+'鷥' => '鸶',
+'鷦' => '鹪',
+'鷨' => '𪉊',
+'鷫' => '鹔',
+'鷯' => '鹩',
+'鷰' => '燕',
+'鷲' => '鹫',
+'鷳' => '鹇',
+'鷴' => '鹇',
+'鷸' => '鹬',
+'鷹' => '鹰',
+'鷺' => '鹭',
+'鷽' => '鸴',
+'鷿' => '䴙',
+'鸂' => '㶉',
+'鸇' => '鹯',
+'鸋' => '𫛢',
+'鸌' => '鹱',
+'鸎' => '莺',
+'鸏' => '鹲',
+'鸕' => '鸬',
+'鸘' => '鹴',
+'鸚' => '鹦',
+'鸛' => '鹳',
+'鸝' => '鹂',
+'鸞' => '鸾',
+'鹵' => '卤',
+'鹹' => '咸',
+'鹺' => '鹾',
+'鹻' => '碱',
+'鹼' => '碱',
+'鹽' => '盐',
+'麗' => '丽',
+'麥' => '麦',
+'麨' => '𪎊',
+'麩' => '麸',
+'麪' => '面',
+'麫' => '面',
+'麯' => '曲',
+'麲' => '𪎉',
+'麳' => '𪎌',
+'麴' => '麹',
+'麵' => '面',
+'麼' => '么',
+'麽' => '么',
+'黃' => '黄',
+'黌' => '黉',
+'點' => '点',
+'黨' => '党',
+'黲' => '黪',
+'黴' => '霉',
+'黶' => '黡',
+'黷' => '黩',
+'黽' => '黾',
+'黿' => '鼋',
+'鼃' => '蛙',
+'鼇' => '鳌',
+'鼈' => '鳖',
+'鼉' => '鼍',
+'鼕' => '咚',
+'鼴' => '鼹',
+'齊' => '齐',
+'齋' => '斋',
+'齎' => '赍',
+'齏' => '齑',
+'齒' => '齿',
+'齔' => '龀',
+'齕' => '龁',
+'齗' => '龂',
+'齙' => '龅',
+'齜' => '龇',
+'齟' => '龃',
+'齠' => '龆',
+'齡' => '龄',
+'齣' => '出',
+'齦' => '龈',
+'齧' => '啮',
+'齩' => '咬',
+'齪' => '龊',
+'齬' => '龉',
+'齲' => '龋',
+'齶' => '腭',
+'齷' => '龌',
+'龍' => '龙',
+'龎' => '厐',
+'龐' => '庞',
+'龑' => '䶮',
+'龔' => '龚',
+'龕' => '龛',
+'龜' => '龟',
+'龭' => '𩨎',
+'龯' => '𨱆',
+'𠌥' => '𠆿',
+'𠏢' => '𠉗',
+'𠕂' => '再',
+'𠕅' => '再',
+'𠞆' => '𠛆',
+'𠞰' => '剿',
+'𠠎' => '𠚳',
+'𡄔' => '𠴢',
+'𡄣' => '𠵸',
+'𡅏' => '𠲥',
+'𡑭' => '𡋗',
+'𡓾' => '𡋀',
+'𡚁' => '弊',
+'𡞵' => '㛟',
+'𡠹' => '㛿',
+'𡢃' => '㛠',
+'𡨥' => '寇',
+'𡮉' => '𡭜',
+'𡮣' => '𡭬',
+'𡻕' => '岁',
+'𡾱' => '㟜',
+'𢣚' => '𢘝',
+'𢣭' => '𢘞',
+'𢶫' => '𢫞',
+'𢷮' => '𢫊',
+'𢹿' => '𢬦',
+'𣙎' => '㭣',
+'𣙜' => '榷',
+'𣝕' => '𣘷',
+'𣞻' => '𣘓',
+'𣠲' => '𣑶',
+'𣯴' => '𣭤',
+'𣾷' => '㳢',
+'𣿉' => '𣶫',
+'𤁣' => '𣺽',
+'𤋮' => '熙',
+'𤒎' => '𤊀',
+'𤨏' => '琐',
+'𤪺' => '㻘',
+'𤫩' => '㻏',
+'𤱈' => '亩',
+'𤳸' => '𤳄',
+'𤸫' => '𤶧',
+'𤺥' => '瘩',
+'𥌃' => '𥅘',
+'𥕥' => '𥐰',
+'𥖅' => '𥐯',
+'𥢢' => '䅪',
+'𥨐' => '𥧂',
+'𥵃' => '𥱔',
+'𥵊' => '𥭉',
+'𥸠' => '𥮋',
+'𥼽' => '𥹥',
+'𥽖' => '𥺇',
+'𥿊' => '𦈈',
+'𦂅' => '𦈒',
+'𦃄' => '𦈗',
+'𦊱' => '挂',
+'𦍑' => '羌',
+'𦕈' => '眇',
+'𦢈' => '𣍨',
+'𦣎' => '𦟗',
+'𦪽' => '𦨩',
+'𦵏' => '葬',
+'𧔥' => '𧒭',
+'𧜗' => '䘞',
+'𧜵' => '䙊',
+'𧝞' => '䘛',
+'𧩙' => '䜥',
+'𧳟' => '𧳕',
+'𧵳' => '䞌',
+'𧶔' => '𧹓',
+'𧶧' => '䞎',
+'𨄣' => '𨀱',
+'𨅍' => '𨁴',
+'𨇁' => '𧿈',
+'𨇞' => '𨅫',
+'𨈊' => '𨂺',
+'𨈌' => '𨄄',
+'𨊰' => '䢀',
+'𨊸' => '䢁',
+'𨊻' => '𨐆',
+'𨋢' => '䢂',
+'𨎮' => '𨐉',
+'𨏠' => '𨐇',
+'𨏥' => '𨐊',
+'𨤻' => '𨤰',
+'𨥛' => '𨱀',
+'𨦫' => '䦀',
+'𨧜' => '䦁',
+'𨧱' => '𨱊',
+'𨫒' => '𨱐',
+'𨮂' => '𨱕',
+'𨯅' => '䥿',
+'𨳑' => '𨸁',
+'𨳕' => '𨸀',
+'𨴗' => '𨸅',
+'𨵩' => '𨸆',
+'𨵸' => '𨸇',
+'𨶀' => '𨸉',
+'𨶏' => '𨸊',
+'𨶮' => '𨸌',
+'𨶲' => '𨸋',
+'𨷲' => '𨸎',
+'𨽏' => '𨸘',
+'𨽻' => '隶',
+'𩎢' => '𩏾',
+'𩏪' => '𩏽',
+'𩓐' => '脖',
+'𩓣' => '𩖕',
+'𩗀' => '𩙦',
+'𩗗' => '飓',
+'𩗡' => '𩙧',
+'𩘀' => '𩙩',
+'𩘝' => '𩙭',
+'𩘹' => '𩙨',
+'𩘺' => '𩙬',
+'𩙈' => '𩙰',
+'𩚛' => '𩟿',
+'𩚥' => '𩠀',
+'𩚵' => '𩠁',
+'𩛆' => '𩠂',
+'𩛩' => '𩠃',
+'𩜇' => '𩠉',
+'𩜦' => '𩠆',
+'𩜵' => '𩠊',
+'𩝔' => '𩠋',
+'𩞄' => '𩠎',
+'𩞦' => '𩠏',
+'𩞯' => '䭪',
+'𩟐' => '𩠅',
+'𩠴' => '𩠠',
+'𩡺' => '𩧦',
+'𩢡' => '𩧬',
+'𩢴' => '𩧵',
+'𩢸' => '𩧳',
+'𩢾' => '𩧮',
+'𩣏' => '𩧶',
+'𩣑' => '䯃',
+'𩣵' => '𩧻',
+'𩣺' => '𩧼',
+'𩤊' => '𩧩',
+'𩤙' => '𩨆',
+'𩤲' => '𩨉',
+'𩤸' => '𩨅',
+'𩥄' => '𩨋',
+'𩥇' => '𩨍',
+'𩥉' => '𩧱',
+'𩥑' => '𩨌',
+'𩧆' => '𩨐',
+'𩭙' => '𩬣',
+'𩯳' => '𩯒',
+'𩰀' => '𩬤',
+'𩳤' => '𩲒',
+'𩵩' => '𩽺',
+'𩵹' => '𩽻',
+'𩶘' => '䲞',
+'𩶰' => '𩽿',
+'𩶱' => '𩽽',
+'𩷰' => '𩾄',
+'𩸃' => '𩾅',
+'𩸦' => '𩾆',
+'𩽇' => '𩾎',
+'𩿪' => '𪉄',
+'𪀦' => '𪉅',
+'𪀾' => '𪉋',
+'𪁈' => '𪉉',
+'𪁖' => '𪉌',
+'𪂆' => '𪉎',
+'𪃍' => '𪉐',
+'𪃏' => '𪉏',
+'𪄆' => '𪉔',
+'𪄕' => '𪉒',
+'𪇳' => '𪉕',
+'𪈼' => '𪉓',
+'𪋿' => '𪎍',
+'𪔵' => '𪔭',
+'𪘀' => '𪚏',
+'𪘯' => '𪚐',
+'『' => '‘',
+'』' => '’',
+'「' => '“',
+'「' => '“',
+'」' => '”',
+'」' => '”',
+'。陞' => '。升',
+'《易乾' => '《易乾',
+'一釐' => '一厘',
+'上昇' => '上升',
+'不穀' => '不穀',
+'專著' => '专著',
+'乾一坛' => '乾一坛',
+'乾一壇' => '乾一坛',
+'乾一組' => '乾一组',
+'乾一组' => '乾一组',
+'乾上乾下' => '乾上乾下',
+'乾东' => '乾东',
+'乾東' => '乾东',
+'乾為天' => '乾为天',
+'乾為陽' => '乾为阳',
+'乾九' => '乾九',
+'乾乾' => '乾乾',
+'乾亨' => '乾亨',
+'乾仪' => '乾仪',
+'乾儀' => '乾仪',
+'乾位' => '乾位',
+'乾健' => '乾健',
+'乾健也' => '乾健也',
+'乾元' => '乾元',
+'乾光' => '乾光',
+'乾兴' => '乾兴',
+'乾興' => '乾兴',
+'乾冈' => '乾冈',
+'乾岡' => '乾冈',
+'乾刘' => '乾刘',
+'乾劉' => '乾刘',
+'乾刚' => '乾刚',
+'乾剛' => '乾刚',
+'乾务' => '乾务',
+'乾務' => '乾务',
+'乾化' => '乾化',
+'乾卦' => '乾卦',
+'乾县' => '乾县',
+'乾縣' => '乾县',
+'乾台' => '乾台',
+'乾吉' => '乾吉',
+'乾启' => '乾启',
+'乾啟' => '乾启',
+'乾命' => '乾命',
+'乾和' => '乾和',
+'乾嘉' => '乾嘉',
+'乾图' => '乾图',
+'乾圖' => '乾图',
+'乾坤' => '乾坤',
+'乾城' => '乾城',
+'乾基' => '乾基',
+'乾天也' => '乾天也',
+'乾始' => '乾始',
+'乾姓' => '乾姓',
+'乾宁' => '乾宁',
+'乾寧' => '乾宁',
+'乾宅' => '乾宅',
+'乾宇' => '乾宇',
+'乾安' => '乾安',
+'乾定' => '乾定',
+'乾封' => '乾封',
+'乾居' => '乾居',
+'乾岗' => '乾岗',
+'乾崗' => '乾岗',
+'乾巛' => '乾巛',
+'乾州' => '乾州',
+'乾录' => '乾录',
+'乾錄' => '乾录',
+'乾律' => '乾律',
+'乾德' => '乾德',
+'乾心' => '乾心',
+'乾忠' => '乾忠',
+'乾文' => '乾文',
+'乾断' => '乾断',
+'乾斷' => '乾断',
+'乾方' => '乾方',
+'乾施' => '乾施',
+'乾旦' => '乾旦',
+'乾明' => '乾明',
+'乾昧' => '乾昧',
+'乾晖' => '乾晖',
+'乾暉' => '乾晖',
+'乾景' => '乾景',
+'乾晷' => '乾晷',
+'乾曜' => '乾曜',
+'乾构' => '乾构',
+'乾構' => '乾构',
+'乾枢' => '乾枢',
+'乾樞' => '乾枢',
+'乾栋' => '乾栋',
+'乾棟' => '乾栋',
+'乾步' => '乾步',
+'乾氏' => '乾氏',
+'乾沓和' => '乾沓和',
+'乾沓婆' => '乾沓婆',
+'乾泉' => '乾泉',
+'乾淳' => '乾淳',
+'乾清' => '乾清',
+'乾渥' => '乾渥',
+'乾潭' => '乾潭',
+'乾灵' => '乾灵',
+'乾靈' => '乾灵',
+'乾生元' => '乾生元',
+'乾男' => '乾男',
+'乾皋' => '乾皋',
+'乾盛世' => '乾盛世',
+'乾矢' => '乾矢',
+'乾祐' => '乾祐',
+'乾神' => '乾神',
+'乾穹' => '乾穹',
+'乾窦' => '乾窦',
+'乾竇' => '乾窦',
+'乾竺' => '乾竺',
+'乾笃' => '乾笃',
+'乾篤' => '乾笃',
+'乾符' => '乾符',
+'乾策' => '乾策',
+'乾精' => '乾精',
+'乾紅' => '乾红',
+'乾红' => '乾红',
+'乾綱' => '乾纲',
+'乾纲' => '乾纲',
+'乾紐' => '乾纽',
+'乾纽' => '乾纽',
+'乾絡' => '乾络',
+'乾络' => '乾络',
+'乾統' => '乾统',
+'乾统' => '乾统',
+'乾維' => '乾维',
+'乾维' => '乾维',
+'乾罗' => '乾罗',
+'乾羅' => '乾罗',
+'乾花' => '乾花',
+'乾荫' => '乾荫',
+'乾蔭' => '乾荫',
+'乾行' => '乾行',
+'乾衡' => '乾衡',
+'乾西' => '乾西',
+'乾覆' => '乾覆',
+'乾象' => '乾象',
+'乾象历' => '乾象历',
+'乾象歷' => '乾象历',
+'乾貞' => '乾贞',
+'乾贞' => '乾贞',
+'乾貴士' => '乾贵士',
+'乾贵士' => '乾贵士',
+'乾貺' => '乾贶',
+'乾贶' => '乾贶',
+'乾車' => '乾车',
+'乾车' => '乾车',
+'乾軸' => '乾轴',
+'乾轴' => '乾轴',
+'乾通' => '乾通',
+'乾造' => '乾造',
+'乾道' => '乾道',
+'乾鉴' => '乾鉴',
+'乾鑒' => '乾鉴',
+'乾鈞' => '乾钧',
+'乾钧' => '乾钧',
+'乾闥' => '乾闼',
+'乾闼' => '乾闼',
+'乾陀' => '乾陀',
+'乾陵' => '乾陵',
+'乾隆' => '乾隆',
+'乾音' => '乾音',
+'乾顧' => '乾顾',
+'乾顾' => '乾顾',
+'乾風' => '乾风',
+'乾风' => '乾风',
+'乾首' => '乾首',
+'乾馬' => '乾马',
+'乾马' => '乾马',
+'乾鵠' => '乾鹄',
+'乾鹄' => '乾鹄',
+'乾鵲' => '乾鹊',
+'乾鹊' => '乾鹊',
+'乾龍' => '乾龙',
+'乾龙' => '乾龙',
+'乾,健也' => '乾,健也',
+'乾,天也' => '乾,天也',
+'五箇山' => '五箇山',
+'什么' => '什么',
+'仇讎' => '仇雠',
+'以微知著' => '以微知著',
+'仰屋著書' => '仰屋著书',
+'彷彿' => '仿佛',
+'夥計' => '伙计',
+'佛頭著糞' => '佛头著粪',
+'偵蒐' => '侦搜',
+'倖一郎' => '倖一郎',
+'倖田' => '倖田',
+'候覆' => '候复',
+'藉助' => '借助',
+'藉口' => '借口',
+'藉手' => '借手',
+'藉故' => '借故',
+'藉機' => '借机',
+'藉此' => '借此',
+'藉由' => '借由',
+'藉端' => '借端',
+'藉詞' => '借词',
+'傒倖' => '傒倖',
+'先名後姓' => '先名后姓',
+'兒寬' => '兒宽',
+'六么' => '六幺',
+'蘭質薰心' => '兰质薰心',
+'內聯陞' => '内联升',
+'憑藉' => '凭借',
+'初昇' => '初升',
+'利欲薰心' => '利欲薰心',
+'剋了' => '剋了',
+'剋架' => '剋架',
+'剖釐' => '剖厘',
+'陞為' => '升为',
+'陞了' => '升了',
+'昇仙' => '升仙',
+'陞任' => '升任',
+'昇華' => '升华',
+'昇天' => '升天',
+'陞官' => '升官',
+'昇平' => '升平',
+'昇汞' => '升汞',
+'陞用' => '升用',
+'陞補' => '升补',
+'陞遷' => '升迁',
+'昇降' => '升降',
+'卓著' => '卓著',
+'博和託' => '博和讬',
+'歷陞' => '历升',
+'釐改' => '厘改',
+'釐整' => '厘整',
+'釐正' => '厘正',
+'釐毫' => '厘毫',
+'釐清' => '厘清',
+'釐訂' => '厘订',
+'釐革' => '厘革',
+'原著' => '原著',
+'又陞' => '又升',
+'反反覆覆' => '反反复复',
+'反覆' => '反复',
+'可穿著' => '可穿著',
+'吃衣著飯' => '吃衣著饭',
+'合著' => '合著',
+'同陞和' => '同升和',
+'名著' => '名著',
+'吳克羣' => '吴克羣',
+'周易乾' => '周易乾',
+'諠譁' => '喧哗',
+'回覆' => '回复',
+'土著' => '土著',
+'坤乾' => '坤乾',
+'墨瀋' => '墨渖',
+'覆查' => '复查',
+'覆核' => '复核',
+'覆检' => '复检',
+'復甦' => '复苏',
+'多么' => '多么',
+'大麴' => '大曲',
+'天道为乾' => '天道为乾',
+'天道為乾' => '天道为乾',
+'奧區' => '奧区',
+'如瀋' => '如渖',
+'姓么' => '姓幺',
+'子餘' => '子馀',
+'字乾生' => '字乾生',
+'孙乾' => '孙乾',
+'孫乾' => '孙乾',
+'宏碁' => '宏碁',
+'官陞' => '官升',
+'將軍抽俥' => '将军抽俥',
+'將軍抽車' => '将军抽車',
+'爾冬陞' => '尔冬升',
+'尼乾陀' => '尼乾陀',
+'侷促' => '局促',
+'跼促' => '局促',
+'侷限' => '局限',
+'跼限' => '局限',
+'山崎闇齋' => '山崎闇斋',
+'岳託' => '岳讬',
+'巨著' => '巨著',
+'乾乾淨淨' => '干干净净',
+'乾乾脆脆' => '干干脆脆',
+'乾泉水' => '干泉水',
+'年陞' => '年升',
+'么九' => '幺九',
+'么二三' => '幺二三',
+'么元' => '幺元',
+'么鳳' => '幺凤',
+'么半' => '幺半',
+'么半群' => '幺半群',
+'么廝' => '幺厮',
+'幺厮' => '幺厮',
+'么叔' => '幺叔',
+'么女' => '幺女',
+'么媽' => '幺妈',
+'么妹' => '幺妹',
+'么姓' => '幺姓',
+'么姨' => '幺姨',
+'么娘' => '幺娘',
+'么孃' => '幺娘',
+'幺孃' => '幺娘',
+'么子' => '幺子',
+'么小' => '幺小',
+'么弟' => '幺弟',
+'么正' => '幺正',
+'么氏' => '幺氏',
+'么爸' => '幺爸',
+'么爹' => '幺爹',
+'么篇' => '幺篇',
+'么舅' => '幺舅',
+'么蛾子' => '幺蛾子',
+'么謙' => '幺谦',
+'么麼' => '幺麽',
+'么麽' => '幺麽',
+'么麽小丑' => '幺麽小丑',
+'慶餘' => '庆馀',
+'康乾' => '康乾',
+'张法乾' => '张法乾',
+'張法乾' => '张法乾',
+'彰明較著' => '彰明较著',
+'待覆' => '待复',
+'後姓' => '後姓',
+'慫慂' => '怂恿',
+'怎么' => '怎么',
+'恩威並著' => '恩威并著',
+'噁心' => '恶心',
+'情蒐' => '情搜',
+'情鍾' => '情钟',
+'惏悷' => '惏悷',
+'惏慄' => '惏慄',
+'慘澹' => '惨淡',
+'成效顯著' => '成效显著',
+'成績顯著' => '成绩显著',
+'所鍾' => '所钟',
+'手鍊' => '手链',
+'扞格' => '扞格',
+'執著' => '执著',
+'批覆' => '批复',
+'承乾' => '承乾',
+'拉鍊' => '拉链',
+'拙著' => '拙著',
+'拚命' => '拚命',
+'拚搏' => '拚搏',
+'拚死' => '拚死',
+'拾瀋' => '拾渖',
+'拿破崙' => '拿破仑',
+'挨剋' => '挨剋',
+'提昇' => '提升',
+'蒐錄' => '搜录',
+'蒐索' => '搜索',
+'蒐羅' => '搜罗',
+'蒐藏' => '搜藏',
+'蒐證' => '搜证',
+'蒐購' => '搜购',
+'蒐輯' => '搜辑',
+'蒐採' => '搜采',
+'蒐采' => '搜采',
+'蒐集' => '搜集',
+'搥打' => '搥打',
+'搥胸頓足' => '搥胸顿足',
+'撰著' => '撰著',
+'效果顯著' => '效果显著',
+'文徵明' => '文徵明',
+'觔斗' => '斤斗',
+'新著' => '新著',
+'於世成' => '於世成',
+'於之瑩' => '於之莹',
+'於之莹' => '於之莹',
+'於乎' => '於乎',
+'於乙于同' => '於乙于同',
+'於乙宇同' => '於乙宇同',
+'於于同' => '於于同',
+'於哲' => '於哲',
+'於夫罗' => '於夫罗',
+'於夫羅' => '於夫罗',
+'於姓' => '於姓',
+'於宇同' => '於宇同',
+'於崇文' => '於崇文',
+'於志賀' => '於志贺',
+'於志贺' => '於志贺',
+'於戲' => '於戏',
+'於梨华' => '於梨华',
+'於梨華' => '於梨华',
+'於氏' => '於氏',
+'於潜' => '於潜',
+'於潛縣' => '於潜县',
+'於祥玉' => '於祥玉',
+'於菟' => '於菟',
+'於賢德' => '於贤德',
+'於除鞬' => '於除鞬',
+'施讎' => '施雠',
+'旋乾轉坤' => '旋乾转坤',
+'旋乾转坤' => '旋乾转坤',
+'無言不讎' => '无言不雠',
+'曠若發矇' => '旷若发矇',
+'崑崙' => '昆仑',
+'崑劇' => '昆剧',
+'崑山' => '昆山',
+'崑曲' => '昆曲',
+'崑腔' => '昆腔',
+'崑蘇' => '昆苏',
+'崑調' => '昆调',
+'易·乾' => '易·乾',
+'易經·乾' => '易经·乾',
+'易经·乾' => '易经·乾',
+'易經乾' => '易经乾',
+'易经乾' => '易经乾',
+'昭著' => '昭著',
+'顯著' => '显著',
+'顯著地' => '显著地',
+'顯著地位' => '显著地位',
+'顯著性' => '显著性',
+'顯著成績' => '显著成绩',
+'顯著效果' => '显著效果',
+'顯著特點' => '显著特点',
+'晉陞' => '晋升',
+'暗闇' => '暗闇',
+'麴黴' => '曲霉',
+'曾运乾' => '曾运乾',
+'曾運乾' => '曾运乾',
+'月陞' => '月升',
+'朝乾夕惕' => '朝乾夕惕',
+'朱有燉' => '朱有燉',
+'朱淛' => '朱淛',
+'硃砂' => '朱砂',
+'硃紅' => '朱红',
+'硃色' => '朱色',
+'朴於宇同' => '朴於宇同',
+'李乾德' => '李乾德',
+'李乾順' => '李乾顺',
+'李乾顺' => '李乾顺',
+'李澤鉅' => '李泽钜',
+'李祕' => '李祕',
+'李譔' => '李譔',
+'柳詒徵' => '柳诒徵',
+'柳诒徵' => '柳诒徵',
+'校讎' => '校雠',
+'楈枒' => '楈枒',
+'樊於期' => '樊於期',
+'殘瀋' => '残渖',
+'慇勤' => '殷勤',
+'慇懃' => '殷勤',
+'比較顯著' => '比较显著',
+'毫釐' => '毫厘',
+'氆氌' => '氆氌',
+'沈沒' => '沉没',
+'沈澱' => '沉淀',
+'沈積' => '沉积',
+'沈船' => '沉船',
+'沈重' => '沉重',
+'沈默' => '沉默',
+'氾濫' => '泛滥',
+'洗鍊' => '洗练',
+'瀋液' => '渖液',
+'薰習' => '熏习',
+'薰心' => '熏心',
+'薰沐' => '熏沐',
+'薰陶' => '熏陶',
+'薰香' => '熏香',
+'爨翫' => '爨翫',
+'獨鍾' => '独钟',
+'王道乾' => '王道乾',
+'王餘魚' => '王馀鱼',
+'甚夥' => '甚夥',
+'男为乾' => '男为乾',
+'男為乾' => '男为乾',
+'男性为乾' => '男性为乾',
+'男性為乾' => '男性为乾',
+'療效顯著' => '疗效显著',
+'白瀋' => '白渖',
+'皁保' => '皁保',
+'目劄' => '目劄',
+'直昇' => '直升',
+'睹微知著' => '睹微知著',
+'瞭台' => '瞭台',
+'瞭臺' => '瞭台',
+'瞭望' => '瞭望',
+'矇眬' => '矇眬',
+'矇矓' => '矇眬',
+'石碁' => '石碁',
+'石碁鎮' => '石碁镇',
+'碩託' => '硕讬',
+'鹼菜' => '硷菜',
+'碁圣' => '碁圣',
+'碁聖' => '碁圣',
+'碁所' => '碁所',
+'祕宜' => '祕宜',
+'穀旦' => '穀旦',
+'穀梁' => '穀梁',
+'穀水' => '穀水',
+'穀阳' => '穀阳',
+'穀陽' => '穀阳',
+'穿著者' => '穿着者',
+'竹昇' => '竹升',
+'答覆' => '答复',
+'米泽瑠美' => '米泽瑠美',
+'米瀋' => '米渖',
+'餬口' => '糊口',
+'繙㠾' => '繙㠾',
+'遶境' => '绕境',
+'線國安' => '缐国安',
+'線姓' => '缐姓',
+'編著' => '编著',
+'老么' => '老幺',
+'肉乾乾' => '肉干干',
+'肘手鍊足' => '肘手链足',
+'甦醒' => '苏醒',
+'苧烯' => '苧烯',
+'薴烯' => '苧烯',
+'蘋果' => '苹果',
+'荠苧' => '荠苧',
+'榮陞' => '荣升',
+'萧乾' => '萧乾',
+'蕭乾' => '萧乾',
+'著書' => '著书',
+'著書立說' => '著书立说',
+'著作' => '著作',
+'著名' => '著名',
+'著錄' => '著录',
+'著錄規則' => '著录规则',
+'著文' => '著文',
+'著有' => '著有',
+'著稱' => '著称',
+'著者' => '著者',
+'著身' => '著身',
+'著述' => '著述',
+'蔡孝乾' => '蔡孝乾',
+'蔡絛' => '蔡絛',
+'行餘' => '行馀',
+'覆蓋' => '覆盖',
+'見微知著' => '见微知著',
+'見著' => '见著',
+'視微知著' => '视微知著',
+'言幾析理' => '言幾析理',
+'諲譔' => '諲譔',
+'譩譆' => '譩譆',
+'託庸' => '讬庸',
+'託恩多' => '讬恩多',
+'託麻' => '讬麻',
+'論著' => '论著',
+'譯著' => '译著',
+'謝肇淛' => '谢肇淛',
+'象乾' => '象乾',
+'躊躇滿志' => '踌躇滿志',
+'較著' => '较著',
+'近角聪信' => '近角聪信',
+'这么' => '这么',
+'造麴' => '造曲',
+'遺著' => '遗著',
+'那么' => '那么',
+'那麽' => '那麽',
+'郭子乾' => '郭子乾',
+'酒麴' => '酒曲',
+'醉瀋' => '醉渖',
+'醯壶' => '醯壶',
+'醯壺' => '醯壶',
+'醯酱' => '醯酱',
+'醯醬' => '醯酱',
+'醯醋' => '醯醋',
+'醯醢' => '醯醢',
+'醯雞' => '醯鸡',
+'醯鸡' => '醯鸡',
+'重覆' => '重复',
+'金鍊' => '金链',
+'鍾情' => '钟情',
+'鍾意' => '钟意',
+'鍾靈' => '钟灵',
+'鍾愛' => '钟爱',
+'鐵鍊' => '铁链',
+'鉸鍊' => '铰链',
+'銀硃' => '银朱',
+'銀鍊' => '银链',
+'鍊子' => '链子',
+'鍊條' => '链条',
+'鍊表' => '链表',
+'鍊鎖' => '链锁',
+'鍊錘' => '链锤',
+'鎖鍊' => '锁链',
+'闇公' => '闇公',
+'閻懷禮' => '闫怀礼',
+'阳为乾' => '阳为乾',
+'陽為乾' => '阳为乾',
+'阿部正瞭' => '阿部正瞭',
+'陆徵祥' => '陆徵祥',
+'陸徵祥' => '陆徵祥',
+'陈乾生' => '陈乾生',
+'陳乾生' => '陈乾生',
+'陈元扞' => '陈元扞',
+'陳元扞' => '陈元扞',
+'陈公乾生' => '陈公乾生',
+'陳公乾生' => '陈公乾生',
+'陈遇乾' => '陈遇乾',
+'陳遇乾' => '陈遇乾',
+'陳堵' => '陳堵',
+'陳禕' => '陳禕',
+'雍乾' => '雍乾',
+'讎夷' => '雠夷',
+'讎定' => '雠定',
+'讎校' => '雠校',
+'讎正' => '雠正',
+'讎問' => '雠问',
+'項鍊' => '项链',
+'飛昇' => '飞升',
+'飭令' => '飭令',
+'飽託' => '饱讬',
+'餘慶' => '馀庆',
+'餘瀋' => '馀渖',
+'馬鞌' => '马鞍',
+'高昇' => '高升',
+'高陞' => '高升',
+'鬱姓' => '鬱姓',
+'鬱氏' => '鬱氏',
+'魏徵' => '魏徵',
+'魚乾乾' => '鱼干干',
+'麽氏' => '麽氏',
+'麼麼' => '麽麽',
+'麽麽' => '麽麽',
+'黃麴毒素' => '黄曲毒素',
+'黃潤乾' => '黄润乾',
+'黄润乾' => '黄润乾',
+'龍鍾' => '龙钟',
+',陞' => ',升',
+);
+
+public static $zh2TW = array(
+'0字节' => '0位元組',
+'0杆' => '0桿',
+'1字节' => '1位元組',
+'1杆' => '1桿',
+'2字节' => '2位元組',
+'2杆' => '2桿',
+'3字节' => '3位元組',
+'3杆' => '3桿',
+'4字节' => '4位元組',
+'4杆' => '4桿',
+'5字节' => '5位元組',
+'5杆' => '5桿',
+'6字节' => '6位元組',
+'6杆' => '6桿',
+'7字节' => '7位元組',
+'7杆' => '7桿',
+'8字节' => '8位元組',
+'8杆' => '8桿',
+'9字节' => '9位元組',
+'9杆' => '9桿',
+'甲型肝炎' => 'A型肝炎',
+'甲肝' => 'A肝',
+'乙型肝炎' => 'B型肝炎',
+'乙肝' => 'B肝',
+'丙型肝炎' => 'C型肝炎',
+'丙肝' => 'C肝',
+'IP地址' => 'IP位址',
+'乔戈里峰' => 'K2',
+'·威尔士' => '·威爾士',
+'·威爾士' => '·威爾士',
+'一杆' => '一桿',
+'七杆' => '七桿',
+'三杆' => '三桿',
+'三极管' => '三極體',
+'三極管' => '三極體',
+'达累斯萨拉姆' => '三蘭港',
+'上落客' => '上下客',
+'落車' => '下車',
+'不來梅' => '不萊梅',
+'不来梅' => '不萊梅',
+'以太网' => '乙太網',
+'九杆' => '九桿',
+'了結他' => '了結他',
+'二手烟' => '二手菸',
+'二手煙' => '二手菸',
+'二杆' => '二桿',
+'二极管' => '二極體',
+'二極管' => '二極體',
+'交互设计' => '互動設計',
+'五杆' => '五桿',
+'阿塞拜疆' => '亞塞拜然',
+'阿斯旺' => '亞斯文',
+'人工智能' => '人工智慧',
+'人机交互' => '人機互動',
+'行人路' => '人行道',
+'石勒苏益格' => '什勒斯維希',
+'石勒蘇益格' => '什勒斯維希',
+'界面' => '介面',
+'伊利诺伊州' => '伊利諾州',
+'伊斯坦布尔' => '伊斯坦堡',
+'伊斯坦布爾' => '伊斯坦堡',
+'伊斯兰堡' => '伊斯蘭瑪巴德',
+'伊斯蘭堡' => '伊斯蘭瑪巴德',
+'埃博拉' => '伊波拉',
+'伊丽莎白' => '伊莉莎白',
+'俯卧撑' => '伏地挺身',
+'掌上壓' => '伏地挺身',
+'伯明翰' => '伯明罕',
+'服务器' => '伺服器',
+'佛罗伦萨' => '佛羅倫斯',
+'操作系统' => '作業系統',
+'系数' => '係數',
+'避孕套' => '保險套',
+'傅里叶' => '傅立葉',
+'光盘' => '光碟',
+'光驱' => '光碟機',
+'开普勒' => '克卜勒',
+'開普勒' => '克卜勒',
+'克罗地亚' => '克羅埃西亞',
+'克羅地亞' => '克羅埃西亞',
+'克里斯托弗' => '克里斯多福',
+'万维网' => '全球資訊網',
+'八杆' => '八桿',
+'公共交通' => '公共運輸',
+'六杆' => '六桿',
+'凯瑟琳' => '凱薩琳',
+'嘉芙蓮' => '凱薩琳',
+'划着独木舟' => '划著獨木舟',
+'划着竹筏' => '划著竹筏',
+'划着船' => '划著船',
+'打印' => '列印',
+'列支敦士登' => '列支敦斯登',
+'前波美拉尼亚' => '前波莫瑞',
+'前波美拉尼亞' => '前波莫瑞',
+'加蓬' => '加彭',
+'加沙地带' => '加薩走廊',
+'加沙地帶' => '加薩走廊',
+'包豪斯' => '包浩斯',
+'北朝鲜' => '北韓',
+'局域网' => '區域網',
+'局域网络' => '區域網路',
+'十杆' => '十桿',
+'特立尼达和托巴哥' => '千里達托貝哥',
+'特立尼達和多巴哥' => '千里達托貝哥',
+'南朝鲜' => '南韓',
+'卡斯特罗' => '卡斯楚',
+'卡塔尔' => '卡達',
+'卡塔爾' => '卡達',
+'铆足' => '卯足',
+'打印机' => '印表機',
+'打印機' => '印表機',
+'厄利垂亚' => '厄利垂亞',
+'厄立特里亚' => '厄利垂亞',
+'厄立特里亞' => '厄利垂亞',
+'厄瓜多' => '厄瓜多',
+'厄瓜多尔' => '厄瓜多',
+'厄瓜多爾' => '厄瓜多',
+'源代码' => '原始碼',
+'圆珠笔' => '原子筆',
+'反烟' => '反菸',
+'反煙' => '反菸',
+'可卡因' => '古柯鹼',
+'便携式' => '可攜式',
+'叱咤' => '叱吒',
+'叱咤9' => '叱咤9',
+'叱咤M' => '叱咤M',
+'叱咤叱' => '叱咤叱',
+'叱咤咤' => '叱咤咤',
+'叱咤樂壇' => '叱咤樂壇',
+'斯坦福大学' => '史丹福大學',
+'斯皮尔伯格' => '史匹柏',
+'斯特劳斯' => '史特勞斯',
+'斯威士兰' => '史瓦濟蘭',
+'斯威士蘭' => '史瓦濟蘭',
+'斯蒂芬' => '史蒂芬',
+'斯大林' => '史達林',
+'結他' => '吉他',
+'乞力馬札羅' => '吉力馬札羅',
+'乞力马扎罗' => '吉力馬札羅',
+'吉布堤' => '吉布地',
+'吉布提' => '吉布地',
+'基里巴斯' => '吉里巴斯',
+'图瓦卢' => '吐瓦魯',
+'圖瓦盧' => '吐瓦魯',
+'吸烟' => '吸菸',
+'吸煙' => '吸菸',
+'吕宋烟' => '呂宋菸',
+'呂宋煙' => '呂宋菸',
+'格丁根' => '哥廷根',
+'哥特式' => '哥德式',
+'哥斯达黎加' => '哥斯大黎加',
+'哥斯達黎加' => '哥斯大黎加',
+'卡拉奇' => '喀拉蚩',
+'乔治·奥威尔' => '喬治·歐威爾',
+'佐治亚' => '喬治亞',
+'佐治亞' => '喬治亞',
+'格魯吉亞' => '喬治亞',
+'格鲁吉亚' => '喬治亞',
+'单反相机' => '單眼相機',
+'單鏡反光機' => '單眼相機',
+'嘯咤' => '嘯吒',
+'四杆' => '四桿',
+'图卢兹' => '土魯斯',
+'圖盧茲' => '土魯斯',
+'戛纳' => '坎城',
+'堪培拉' => '坎培拉',
+'坦桑尼亚' => '坦尚尼亞',
+'坦桑尼亞' => '坦尚尼亞',
+'端口' => '埠',
+'首席执行官' => '執行長',
+'报道' => '報導',
+'塑料袋' => '塑膠袋',
+'塞舌尔' => '塞席爾',
+'塞舌爾' => '塞席爾',
+'萨拉热窝' => '塞拉耶佛',
+'薩拉熱窩' => '塞拉耶佛',
+'塞尔维亚和黑山' => '塞爾維亞與蒙特內哥羅',
+'塞爾維亞和黑山' => '塞爾維亞與蒙特內哥羅',
+'塞爾維亞與蒙特內哥羅' => '塞爾維亞與蒙特內哥羅',
+'塞维利亚' => '塞維亞',
+'西維爾' => '塞維亞',
+'塞黑' => '塞蒙',
+'共和联邦' => '大英國協',
+'英联邦' => '大英國協',
+'英聯邦' => '大英國協',
+'太空飛行員' => '太空人',
+'宇航员' => '太空人',
+'穿梭機' => '太空梭',
+'航天飞机' => '太空梭',
+'宇航服' => '太空衣',
+'航天器' => '太空飛行器',
+'尼日利亚' => '奈及利亞',
+'尼日利亞' => '奈及利亞',
+'忌廉' => '奶油',
+'荷里活' => '好萊塢',
+'威廉姆斯' => '威廉士',
+'威斯特法伦' => '威斯伐倫',
+'威斯特法倫' => '威斯伐倫',
+'威士顿康星' => '威斯康辛',
+'威尔士' => '威爾斯',
+'威爾士' => '威爾斯',
+'字库' => '字型檔',
+'存盘' => '存檔',
+'孟德爾遜' => '孟德爾頌',
+'门德尔松' => '孟德爾頌',
+'安哈尔特' => '安哈特',
+'安哈爾特' => '安哈特',
+'安提瓜和巴布达' => '安地卡及巴布達',
+'安提瓜和巴布達' => '安地卡及巴布達',
+'洪都拉斯' => '宏都拉斯',
+'密歇根' => '密西根',
+'宽带' => '寬頻',
+'老挝人民民主共和国' => '寮人民民主共和國',
+'老撾人民民主共和國' => '寮人民民主共和國',
+'老挝' => '寮國',
+'老撾' => '寮國',
+'老挝语' => '寮語',
+'老撾語' => '寮語',
+'波里活' => '寶萊塢',
+'对着干' => '對著幹',
+'高峰时段' => '尖峰時段',
+'高峰时间' => '尖峰時間',
+'贊比亞' => '尚比亞',
+'赞比亚' => '尚比亞',
+'尼克松' => '尼克森',
+'尼日尔' => '尼日',
+'尼日爾' => '尼日',
+'雅马哈' => '山葉',
+'机床' => '工具機',
+'機床' => '工具機',
+'珍寶客機' => '巨無霸客機',
+'发达国家' => '已開發國家',
+'巴塞罗那' => '巴塞隆納',
+'巴塞隆拿' => '巴塞隆納',
+'巴布亚新几内亚' => '巴布亞紐幾內亞',
+'巴布亞新畿內亞' => '巴布亞紐幾內亞',
+'巴士拉' => '巴斯拉',
+'巴巴多斯' => '巴貝多',
+'佈' => '布',
+'布基納法索' => '布吉納法索',
+'布基纳法索' => '布吉納法索',
+'布什' => '布希',
+'布殊' => '布希',
+'勃兰登堡' => '布蘭登堡',
+'勃蘭登堡' => '布蘭登堡',
+'布里斯托尔' => '布里斯托',
+'布隆方丹' => '布隆泉',
+'希拉莉' => '希拉蕊',
+'希拉里' => '希拉蕊',
+'希特拉' => '希特勒',
+'巴尔米拉环礁' => '帕邁拉環礁',
+'帕劳' => '帛琉',
+'希拉克' => '席哈克',
+'账' => '帳',
+'干着急' => '干著急',
+'干着' => '幹著',
+'畿內亞' => '幾內亞',
+'几内亚比绍' => '幾內亞比索',
+'幾內亞比紹' => '幾內亞比索',
+'比利牛斯' => '庇里牛斯',
+'库尔德人' => '庫德人',
+'库尔德族' => '庫德族',
+'康涅狄格' => '康乃狄克',
+'约翰斯顿岛' => '強斯頓環礁',
+'汇编' => '彙編',
+'形而上学' => '形上學',
+'形而上學' => '形上學',
+'得克萨斯' => '德克薩斯',
+'得克薩斯' => '德克薩斯',
+'德累斯頓' => '德勒斯登',
+'德累斯顿' => '德勒斯登',
+'德里达' => '德希達',
+'特拉华' => '德拉瓦',
+'特拉華' => '德拉瓦',
+'快闪存储器' => '快閃記憶體',
+'闪存' => '快閃記憶體',
+'想象' => '想像',
+'愛德文' => '愛德溫',
+'艾滋' => '愛滋',
+'艾奧瓦' => '愛荷華',
+'爱德华州' => '愛達荷州',
+'应用程序' => '應用程式',
+'戈尔巴乔夫' => '戈巴契夫',
+'戈爾巴喬夫' => '戈巴契夫',
+'戒烟' => '戒菸',
+'戒煙' => '戒菸',
+'戴克里先' => '戴克里先',
+'打印度' => '打印度',
+'抽烟' => '抽菸',
+'抽煙' => '抽菸',
+'拉普兰' => '拉布蘭',
+'拒烟' => '拒菸',
+'拒煙' => '拒菸',
+'卷烟' => '捲菸',
+'捲煙' => '捲菸',
+'積架' => '捷豹',
+'控件' => '控制項',
+'推杆' => '推桿',
+'第比利斯' => '提比里西',
+'挥杆' => '揮桿',
+'揮杆' => '揮桿',
+'搜索引擎' => '搜尋引擎',
+'摩根士丹利' => '摩根史坦利',
+'台球' => '撞球',
+'攻打' => '攻打',
+'数字化' => '數位化',
+'數碼化' => '數位化',
+'数字技术' => '數位技術',
+'數碼技術' => '數位技術',
+'数字照相机' => '數位照相機',
+'数码照相机' => '數位照相機',
+'數碼照相機' => '數位照相機',
+'数码相机' => '數位相機',
+'數碼相機' => '數位相機',
+'数字信号' => '數位訊號',
+'數碼訊號' => '數位訊號',
+'数字电视' => '數位電視',
+'數碼電視' => '數位電視',
+'調制解調器' => '數據機',
+'调制解调器' => '數據機',
+'斯洛文尼亚' => '斯洛維尼亞',
+'斯洛文尼亞' => '斯洛維尼亞',
+'新罕布什尔' => '新罕布夏',
+'施罗德' => '施洛德',
+'旱烟' => '旱菸',
+'旱煙' => '旱菸',
+'普利策' => '普利茲',
+'芯片' => '晶片',
+'智能卡' => '智慧卡',
+'智能手机' => '智慧型手機',
+'智能手機' => '智慧型手機',
+'智能电话' => '智慧型電話',
+'智能電話' => '智慧型電話',
+'知識產權' => '智慧財產權',
+'知识产权' => '智慧財產權',
+'萌島' => '曼島',
+'马恩岛' => '曼島',
+'木杆' => '木桿',
+'列奥纳多' => '李奧納多',
+'杜塞尔多夫' => '杜塞道夫',
+'杜塞爾多夫' => '杜塞道夫',
+'迪拜' => '杜拜',
+'东盟' => '東協',
+'亚细安' => '東協',
+'東盟' => '東協',
+'东南亚国家联盟' => '東南亞國家協會',
+'東南亞國家聯盟' => '東南亞國家協會',
+'柏林墙' => '柏林圍牆',
+'柏林牆' => '柏林圍牆',
+'乍得' => '查德',
+'查韦斯' => '查維茲',
+'克林頓' => '柯林頓',
+'克林顿' => '柯林頓',
+'戴卓爾' => '柴契爾',
+'撒切尔' => '柴契爾',
+'格林納達' => '格瑞那達',
+'格林纳达' => '格瑞那達',
+'桃金娘' => '桃金孃',
+'台式电脑' => '桌上型電腦',
+'乒乓' => '桌球',
+'乒乓球' => '桌球',
+'杆弟' => '桿弟',
+'杆身' => '桿身',
+'杆头' => '桿頭',
+'杆頭' => '桿頭',
+'梅尔·吉布森' => '梅爾·吉勃遜',
+'梵高' => '梵谷',
+'桑巴舞' => '森巴舞',
+'榴莲' => '榴槤',
+'榴蓮' => '榴槤',
+'枪支' => '槍枝',
+'标准杆' => '標準桿',
+'標準杆' => '標準桿',
+'毛里求斯' => '模里西斯',
+'毛里裘斯' => '模里西斯',
+'机器人' => '機器人',
+'機械人' => '機器人',
+'概率' => '機率',
+'電單車' => '機車',
+'枱' => '檯',
+'字段' => '欄位',
+'奥巴马' => '歐巴馬',
+'奧巴馬' => '歐巴馬',
+'正在叱咤' => '正在叱咤',
+'文莱' => '汶萊',
+'沙律' => '沙拉',
+'沙地阿拉伯' => '沙烏地阿拉伯',
+'沙特阿拉伯' => '沙烏地阿拉伯',
+'法属圭亚那' => '法屬蓋亞那',
+'波斯尼亚' => '波士尼亞',
+'波斯尼亞' => '波士尼亞',
+'波斯尼亚和黑塞哥维那' => '波士尼亞赫塞哥維納',
+'波斯尼亞黑塞哥維那' => '波士尼亞赫塞哥維納',
+'博茨瓦納' => '波札那',
+'博茨瓦纳' => '波札那',
+'波黑' => '波赫',
+'洋烟' => '洋菸',
+'洋煙' => '洋菸',
+'帕特里克' => '派屈克',
+'海洛英' => '海洛因',
+'侯賽因' => '海珊',
+'侯赛因' => '海珊',
+'鼠标' => '滑鼠',
+'汉诺威' => '漢諾瓦',
+'漢诺威' => '漢諾瓦',
+'烤烟' => '烤菸',
+'烤煙' => '烤菸',
+'无烟日' => '無菸日',
+'無煙日' => '無菸日',
+'无烟环境' => '無菸環境',
+'無煙環境' => '無菸環境',
+'烟熏' => '煙燻',
+'首席运营官' => '營運長',
+'熏烤' => '燻烤',
+'熏肉' => '燻肉',
+'熏黑' => '燻黑',
+'版权信息' => '版權資訊',
+'疯牛症' => '狂牛症',
+'鐵托' => '狄托',
+'铁托' => '狄托',
+'塞拉利昂' => '獅子山',
+'独联体' => '獨立國協',
+'獨聯體' => '獨立國協',
+'独立国家联合体' => '獨立國家國協',
+'獨立國家聯合體' => '獨立國家國協',
+'波利尼西亚' => '玻里尼西亞',
+'波利尼西亞' => '玻里尼西亞',
+'本傑明' => '班傑明',
+'本杰明' => '班傑明',
+'球杆' => '球桿',
+'理查德' => '理察',
+'卢塞恩' => '琉森',
+'危地馬拉' => '瓜地馬拉',
+'危地马拉' => '瓜地馬拉',
+'巴伦西亚' => '瓦倫西亞',
+'華倫西亞' => '瓦倫西亞',
+'冈比亚' => '甘比亞',
+'岡比亞' => '甘比亞',
+'肯尼迪' => '甘迺迪',
+'留尼汪' => '留尼旺',
+'毕加索' => '畢卡索',
+'迭代' => '疊代',
+'徵狀' => '症狀',
+'勃朗宁' => '白朗寧',
+'百慕大' => '百慕達',
+'卢旺达' => '盧安達',
+'盧旺達' => '盧安達',
+'睾' => '睪',
+'知识产权局' => '知識產權局',
+'知識產權局' => '知識產權署',
+'知識產權署' => '知識產權署',
+'知识产权署' => '知識產權署',
+'硅' => '矽',
+'硅藻' => '硅藻',
+'硬盘' => '硬碟',
+'硬件' => '硬體',
+'盘片' => '碟片',
+'磁盘' => '磁碟',
+'磁道' => '磁軌',
+'禁烟' => '禁菸',
+'禁煙' => '禁菸',
+'福尔马林' => '福馬林',
+'福爾馬林' => '福馬林',
+'私烟' => '私菸',
+'私煙' => '私菸',
+'程序员' => '程式設計師',
+'编程语言' => '程式語言',
+'空气质量' => '空氣品質',
+'空氣質素' => '空氣品質',
+'突尼斯' => '突尼西亞',
+'绑紧跳' => '笨豬跳',
+'蹦极跳' => '笨豬跳',
+'短信' => '簡訊',
+'纽黑文' => '紐哈芬',
+'新奥尔良' => '紐奧良',
+'新奧爾良' => '紐奧良',
+'新几内亚' => '紐幾內亞',
+'新西兰' => '紐西蘭',
+'新西蘭' => '紐西蘭',
+'紙煙' => '紙菸',
+'纸烟' => '紙菸',
+'索尔仁尼琴' => '索忍尼辛',
+'索贊尼辛' => '索忍尼辛',
+'所罗门群岛' => '索羅門群島',
+'所羅門群島' => '索羅門群島',
+'索馬里' => '索馬利亞',
+'索马里' => '索馬利亞',
+'索馬里蘭' => '索馬利蘭',
+'索马里兰' => '索馬利蘭',
+'維爾京群島' => '維京群島',
+'维尔京群岛' => '維京群島',
+'弗吉尼亚' => '維吉尼亞',
+'佛得角' => '維德角',
+'维特根斯坦' => '維根斯坦',
+'網絡遊戲' => '網路遊戲',
+'网络游戏' => '網路遊戲',
+'互联网' => '網際網路',
+'互联网络' => '網際網路',
+'互聯網' => '網際網路',
+'互聯網絡' => '網際網路',
+'因特网' => '網際網路',
+'系着' => '繫著',
+'卢瓦尔' => '羅亞爾',
+'盧瓦爾' => '羅亞爾',
+'卢浮宫' => '羅浮宮',
+'樂行童軍' => '羅浮童軍',
+'意大利' => '義大利',
+'昂山素姬' => '翁山蘇姬',
+'昂山素季' => '翁山蘇姬',
+'圣基茨和尼维斯' => '聖克里斯多福及尼維斯',
+'聖吉斯納域斯' => '聖克里斯多福及尼維斯',
+'圣文森特和格林纳丁斯' => '聖文森及格瑞那丁',
+'聖文森特和格林納丁斯' => '聖文森及格瑞那丁',
+'圣赫勒拿' => '聖赫倫那',
+'圣卢西亚' => '聖露西亞',
+'聖盧西亞' => '聖露西亞',
+'圣马力诺' => '聖馬利諾',
+'聖馬力諾' => '聖馬利諾',
+'肯尼亚' => '肯亞',
+'氨基酸' => '胺基酸',
+'自由泳' => '自由式',
+'三藩市' => '舊金山',
+'艾森豪威尔' => '艾森豪',
+'埃菲尔' => '艾菲爾',
+'阿里埃勒·沙龍' => '艾里爾·夏隆',
+'阿里埃勒·沙龙' => '艾里爾·夏隆',
+'帕塔亚' => '芭達亞',
+'黎克特制' => '芮氏',
+'里氏0' => '芮氏0',
+'里氏1' => '芮氏1',
+'里氏2' => '芮氏2',
+'里氏3' => '芮氏3',
+'里氏4' => '芮氏4',
+'里氏5' => '芮氏5',
+'里氏6' => '芮氏6',
+'里氏7' => '芮氏7',
+'里氏8' => '芮氏8',
+'里氏9' => '芮氏9',
+'里氏地震规模' => '芮氏地震規模',
+'里氏规模' => '芮氏規模',
+'里氏震级' => '芮氏規模',
+'当且仅当' => '若且唯若',
+'味美思' => '苦艾酒',
+'毛里塔尼亚' => '茅利塔尼亞',
+'毛里塔尼亞' => '茅利塔尼亞',
+'霍尔木兹' => '荷姆茲',
+'霍爾木茲' => '荷姆茲',
+'荷李活道' => '荷李活道',
+'莫桑比克' => '莫三比克',
+'瓦文萨' => '華勒沙',
+'華里沙' => '華勒沙',
+'瓦格纳' => '華格納',
+'烟具' => '菸具',
+'煙具' => '菸具',
+'烟品' => '菸品',
+'煙品' => '菸品',
+'烟嘴' => '菸嘴',
+'煙嘴' => '菸嘴',
+'烟卷' => '菸捲',
+'煙捲' => '菸捲',
+'烟斗' => '菸斗',
+'煙斗' => '菸斗',
+'烟民' => '菸民',
+'煙民' => '菸民',
+'烟灰' => '菸灰',
+'煙灰' => '菸灰',
+'烟瘾' => '菸癮',
+'煙癮' => '菸癮',
+'烟丝' => '菸絲',
+'煙絲' => '菸絲',
+'烟草' => '菸草',
+'煙草' => '菸草',
+'烟叶' => '菸葉',
+'煙葉' => '菸葉',
+'烟蒂' => '菸蒂',
+'煙蒂' => '菸蒂',
+'烟袋' => '菸袋',
+'煙袋' => '菸袋',
+'烟农' => '菸農',
+'煙農' => '菸農',
+'烟酒' => '菸酒',
+'煙酒' => '菸酒',
+'烟头' => '菸頭',
+'煙頭' => '菸頭',
+'烟鬼' => '菸鬼',
+'煙鬼' => '菸鬼',
+'烟碱' => '菸鹼',
+'煙鹼' => '菸鹼',
+'万历朝鲜战争' => '萬曆朝鮮戰爭',
+'瓦努阿图' => '萬那杜',
+'瓦努阿圖' => '萬那杜',
+'叶利钦' => '葉爾欽',
+'葉利欽' => '葉爾欽',
+'埃里温' => '葉里溫',
+'埃里溫' => '葉里溫',
+'也門' => '葉門',
+'也门' => '葉門',
+'着' => '著',
+'着眼于' => '著眼於',
+'科摩罗' => '葛摩',
+'科摩羅' => '葛摩',
+'格林美獎' => '葛萊美獎',
+'格莱美奖' => '葛萊美獎',
+'黑山共和国' => '蒙特內哥羅共和國',
+'黑山共和國' => '蒙特內哥羅共和國',
+'滿地可' => '蒙特婁',
+'蒙特利尔' => '蒙特婁',
+'蒙特利爾' => '蒙特婁',
+'普密蓬' => '蒲美蓬',
+'布隆迪' => '蒲隆地',
+'圭亚那' => '蓋亞那',
+'肖斯塔科维奇' => '蕭士塔高維奇',
+'蕭士達高維契' => '蕭士塔高維奇',
+'肖邦' => '蕭邦',
+'薛定谔' => '薛丁格',
+'扎伊尔' => '薩伊',
+'扎伊爾' => '薩伊',
+'素檀' => '蘇丹',
+'苏里南' => '蘇利南',
+'浮罗交怡' => '蘭卡威',
+'浮羅交怡' => '蘭卡威',
+'劳拉' => '蘿拉',
+'荧光' => '螢光',
+'荧屏' => '螢屏',
+'屏幕' => '螢幕',
+'行人路权' => '行人路權',
+'行人路權' => '行人路權',
+'流動網絡' => '行動網路',
+'移动网络' => '行動網路',
+'流動電話' => '行動電話',
+'移动电话' => '行動電話',
+'冲着' => '衝著',
+'埃塞俄比亚' => '衣索比亞',
+'埃塞俄比亞' => '衣索比亞',
+'克隆人' => '複製人',
+'国际象棋' => '西洋棋',
+'國際象棋' => '西洋棋',
+'赫梯' => '西臺',
+'分辨率' => '解析度',
+'解像度' => '解析度',
+'译码' => '解碼',
+'出租车' => '計程車',
+'约翰逊' => '詹森',
+'诺曼底' => '諾曼第',
+'瑙魯' => '諾魯',
+'瑙鲁' => '諾魯',
+'科特迪瓦' => '象牙海岸',
+'碧咸' => '貝克漢',
+'貝爾格萊德' => '貝爾格勒',
+'贝尔格莱德' => '貝爾格勒',
+'伯利兹' => '貝里斯',
+'伯利茲' => '貝里斯',
+'首席财务官' => '財務長',
+'集装箱' => '貨櫃',
+'数据库' => '資料庫',
+'數據庫' => '資料庫',
+'信息时代' => '資訊時代',
+'信息论' => '資訊理論',
+'乔布斯' => '賈伯斯',
+'本·拉登' => '賓·拉登',
+'宾西法尼亚' => '賓夕法尼亞',
+'本拉登' => '賓拉登',
+'利比里亚' => '賴比瑞亞',
+'利比里亞' => '賴比瑞亞',
+'莱索托' => '賴索托',
+'萊索托' => '賴索托',
+'塞浦路斯' => '賽普勒斯',
+'赫丘勒·波洛' => '赫丘勒·白羅',
+'赫鲁晓夫' => '赫魯雪夫',
+'切尔诺贝利' => '車諾比',
+'软驱' => '軟碟機',
+'軟件' => '軟體',
+'软件' => '軟體',
+'津巴布韋' => '辛巴威',
+'津巴布韦' => '辛巴威',
+'径入' => '逕入',
+'径到' => '逕到',
+'径取' => '逕取',
+'径启' => '逕啟',
+'径寄' => '逕寄',
+'径庭' => '逕庭',
+'径往' => '逕往',
+'径自' => '逕自',
+'径行' => '逕行',
+'径迎' => '逕迎',
+'链接' => '連結',
+'連結他' => '連結他',
+'进制' => '進位',
+'达·芬奇' => '達·文西',
+'达芬奇' => '達文西',
+'溫納圖萬' => '那杜',
+'丘吉尔' => '邱吉爾',
+'多普勒' => '都卜勒',
+'酰' => '醯',
+'里士满' => '里奇蒙',
+'金沙萨' => '金夏沙',
+'金沙薩' => '金夏沙',
+'健力士世界紀錄' => '金氏世界紀錄',
+'健力士世界纪录' => '金氏世界紀錄',
+'吉尼斯世界纪录' => '金氏世界紀錄',
+'钚' => '鈽',
+'鈎' => '鉤',
+'钩' => '鉤',
+'锎' => '鉲',
+'锫' => '鉳',
+'镅' => '鋂',
+'镎' => '錼',
+'钫' => '鍅',
+'炼金' => '鍊金',
+'锻炼' => '鍛鍊',
+'锝' => '鎝',
+'鐵杆' => '鐵桿',
+'铁杆' => '鐵桿',
+'泰坦尼克号' => '鐵達尼號',
+'锿' => '鑀',
+'关系着' => '關係著',
+'写保护' => '防寫',
+'阿布扎比' => '阿布達比',
+'阿拉伯联合酋长国' => '阿拉伯聯合大公國',
+'阿拉伯聯合酋長國' => '阿拉伯聯合大公國',
+'亚拉巴马' => '阿拉巴馬',
+'阿联酋' => '阿聯',
+'阿聯酋' => '阿聯',
+'罗纳德·里根' => '隆納·雷根',
+'私隱' => '隱私',
+'耶加達' => '雅加達',
+'雅尔塔' => '雅爾達',
+'雅爾塔' => '雅爾達',
+'雅穆苏克雷' => '雅穆索戈',
+'雅穆蘇克雷' => '雅穆索戈',
+'悉尼' => '雪梨',
+'雪茄烟' => '雪茄菸',
+'雪茄煙' => '雪茄菸',
+'莱特湾' => '雷伊泰灣',
+'萊特灣' => '雷伊泰灣',
+'激光' => '雷射',
+'雷诺阿' => '雷諾瓦',
+'电子烟' => '電子菸',
+'電子煙' => '電子菸',
+'晶体管' => '電晶體',
+'晶體管' => '電晶體',
+'电杆' => '電桿',
+'电线杆' => '電線桿',
+'电脑程序' => '電腦程式',
+'计算机程序' => '電腦程式',
+'荷尔斯泰因' => '霍爾斯坦',
+'荷爾斯泰因' => '霍爾斯坦',
+'面包着' => '面包著',
+'朝鲜战争' => '韓戰',
+'声卡' => '音效卡',
+'缺省' => '預設',
+'导弹' => '飛彈',
+'糊口' => '餬口',
+'香烟' => '香菸',
+'香煙' => '香菸',
+'馬里共和國' => '馬利共和國',
+'马里共和国' => '馬利共和國',
+'马拉维' => '馬拉威',
+'馬斯特里赫特' => '馬斯垂克',
+'马斯特里赫特' => '馬斯垂克',
+'马耳他' => '馬爾他',
+'馬爾代夫' => '馬爾地夫',
+'马尔代夫' => '馬爾地夫',
+'馬利蘭' => '馬里蘭',
+'高清电视' => '高畫質電視',
+'斗着' => '鬥著',
+'魯賓斯·巴里切羅' => '魯本·巴瑞切羅',
+'咪高峰' => '麥克風',
+'迈克尔' => '麥可',
+'麦克尔' => '麥可',
+'迈凯轮' => '麥拿輪',
+'邁凱輪' => '麥拿輪',
+'马萨诸塞' => '麻薩諸塞',
+'戴安娜' => '黛安娜',
+'狄安娜' => '黛安娜',
+'点烟' => '點菸',
+'點煙' => '點菸',
+'霉素' => '黴素',
+);
+
+public static $zh2HK = array(
+'0字节' => '0位元組',
+'1字节' => '1位元組',
+'2字节' => '2位元組',
+'3字节' => '3位元組',
+'4字节' => '4位元組',
+'5字节' => '5位元組',
+'6字节' => '6位元組',
+'7字节' => '7位元組',
+'8字节' => '8位元組',
+'9字节' => '9位元組',
+'IP地址' => 'IP位址',
+'·威尔士' => '·威爾士',
+'·威爾士' => '·威爾士',
+'一地里' => '一地裏',
+'一年里' => '一年裏',
+'三十六著' => '三十六着',
+'三極體' => '三極管',
+'旧金山' => '三藩市',
+'舊金山' => '三藩市',
+'上台面' => '上枱面',
+'下著' => '下着',
+'下著作' => '下著作',
+'下著名' => '下著名',
+'下著有' => '下著有',
+'下著称' => '下著稱',
+'下著稱' => '下著稱',
+'下著者' => '下著者',
+'下著述' => '下著述',
+'下著录' => '下著錄',
+'下著錄' => '下著錄',
+'不占' => '不佔',
+'不萊梅' => '不來梅',
+'不著痕跡' => '不着痕跡',
+'不著邊際' => '不着邊際',
+'世纪里' => '世紀裏',
+'C型肝炎' => '丙型肝炎',
+'C肝' => '丙肝',
+'并发布' => '並發佈',
+'中文里' => '中文裏',
+'乘著' => '乘着',
+'乘著作' => '乘著作',
+'乘著名' => '乘著名',
+'乘著書' => '乘著書',
+'乘著称' => '乘著稱',
+'乘著稱' => '乘著稱',
+'乘著者' => '乘著者',
+'乘著述' => '乘著述',
+'乘著錄' => '乘著錄',
+'B型肝炎' => '乙型肝炎',
+'B肝' => '乙肝',
+'吉力馬札羅' => '乞力馬札羅',
+'葉門' => '也門',
+'事里' => '事裏',
+'二極體' => '二極管',
+'因特网' => '互聯網',
+'網際網路' => '互聯網',
+'井里' => '井裏',
+'亮著' => '亮着',
+'亮著作' => '亮著作',
+'亮著名' => '亮著名',
+'亮著書' => '亮著書',
+'亮著称' => '亮著稱',
+'亮著稱' => '亮著稱',
+'亮著者' => '亮著者',
+'亮著述' => '亮著述',
+'亮著錄' => '亮著錄',
+'人工智慧' => '人工智能',
+'人数里' => '人數裏',
+'仗著' => '仗着',
+'仗著作' => '仗著作',
+'仗著名' => '仗著名',
+'仗著書' => '仗著書',
+'仗著稱' => '仗著稱',
+'仗著者' => '仗著者',
+'仗著述' => '仗著述',
+'仗著錄' => '仗著錄',
+'代表著' => '代表着',
+'代表著作' => '代表著作',
+'代表著名' => '代表著名',
+'代表著書' => '代表著書',
+'代表著稱' => '代表著稱',
+'代表著者' => '代表著者',
+'代表著述' => '代表著述',
+'代表著錄' => '代表著錄',
+'伊斯蘭瑪巴德' => '伊斯蘭堡',
+'埃博拉' => '伊波拉',
+'伏著' => '伏着',
+'貝里斯' => '伯利茲',
+'伯明罕' => '伯明翰',
+'伴著' => '伴着',
+'伴著作' => '伴著作',
+'伴著名' => '伴著名',
+'伴著書' => '伴著書',
+'伴著稱' => '伴著稱',
+'伴著者' => '伴著者',
+'伴著述' => '伴著述',
+'伴著錄' => '伴著錄',
+'布下了' => '佈下了',
+'布下的' => '佈下的',
+'布光' => '佈光',
+'布告' => '佈告',
+'布局' => '佈局',
+'布展' => '佈展',
+'布控' => '佈控',
+'布于' => '佈於',
+'布於' => '佈於',
+'布施' => '佈施',
+'布景' => '佈景',
+'布满' => '佈滿',
+'布滿' => '佈滿',
+'布置' => '佈置',
+'布設' => '佈設',
+'布设' => '佈設',
+'布警' => '佈警',
+'布道' => '佈道',
+'布防' => '佈防',
+'布阵' => '佈陣',
+'布陣' => '佈陣',
+'布雷、' => '佈雷、',
+'布雷。' => '佈雷。',
+'布雷封鎖' => '佈雷封鎖',
+'布雷封锁' => '佈雷封鎖',
+'布雷的' => '佈雷的',
+'布雷艇' => '佈雷艇',
+'布雷舰' => '佈雷艦',
+'布雷艦' => '佈雷艦',
+'布雷速度' => '佈雷速度',
+'布雷,' => '佈雷,',
+'布雷;' => '佈雷;',
+'布点' => '佈點',
+'布點' => '佈點',
+'低著' => '低着',
+'低著作' => '低著作',
+'低著名' => '低著名',
+'低著書' => '低著書',
+'低著称' => '低著稱',
+'低著稱' => '低著稱',
+'低著者' => '低著者',
+'低著述' => '低著述',
+'低著錄' => '低著錄',
+'住著' => '住着',
+'住著作' => '住著作',
+'住著名' => '住著名',
+'住著書' => '住著書',
+'住著稱' => '住著稱',
+'住著者' => '住著者',
+'住著述' => '住著述',
+'住著錄' => '住著錄',
+'占0' => '佔0',
+'占1' => '佔1',
+'占2' => '佔2',
+'占3' => '佔3',
+'占4' => '佔4',
+'占5' => '佔5',
+'占6' => '佔6',
+'占7' => '佔7',
+'占8' => '佔8',
+'占9' => '佔9',
+'占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',
+'占〇' => '佔〇',
+'占一' => '佔一',
+'占七' => '佔七',
+'占三' => '佔三',
+'占上風' => '佔上風',
+'占上风' => '佔上風',
+'占下' => '佔下',
+'占下風' => '佔下風',
+'占下风' => '佔下風',
+'占不占' => '佔不佔',
+'占不足' => '佔不足',
+'占世界' => '佔世界',
+'占中' => '佔中',
+'占主' => '佔主',
+'占主要' => '佔主要',
+'占九' => '佔九',
+'占了' => '佔了',
+'占二' => '佔二',
+'占五' => '佔五',
+'占人便宜' => '佔人便宜',
+'占位' => '佔位',
+'占住' => '佔住',
+'占占' => '佔佔',
+'占便宜' => '佔便宜',
+'占俄' => '佔俄',
+'占个' => '佔個',
+'占個' => '佔個',
+'占个位' => '佔個位',
+'占個位' => '佔個位',
+'占亿' => '佔億',
+'占億' => '佔億',
+'占优' => '佔優',
+'占優' => '佔優',
+'占先' => '佔先',
+'占光' => '佔光',
+'占全' => '佔全',
+'占两' => '佔兩',
+'占兩' => '佔兩',
+'占八' => '佔八',
+'占六' => '佔六',
+'占分' => '佔分',
+'占到' => '佔到',
+'占加' => '佔加',
+'占劣' => '佔劣',
+'占北' => '佔北',
+'占十' => '佔十',
+'占千' => '佔千',
+'占半' => '佔半',
+'占南' => '佔南',
+'占印' => '佔印',
+'占去' => '佔去',
+'占取' => '佔取',
+'占台' => '佔台',
+'占囁' => '佔囁',
+'占四' => '佔四',
+'占国' => '佔國',
+'占國' => '佔國',
+'占在' => '佔在',
+'占地' => '佔地',
+'占场' => '佔場',
+'占場' => '佔場',
+'占压' => '佔壓',
+'占壓' => '佔壓',
+'占多' => '佔多',
+'占大' => '佔大',
+'占好' => '佔好',
+'占小' => '佔小',
+'占少' => '佔少',
+'占局部' => '佔局部',
+'占屋' => '佔屋',
+'占山为' => '佔山為',
+'占山為' => '佔山為',
+'占市' => '佔市',
+'占平均' => '佔平均',
+'占床' => '佔床',
+'占座' => '佔座',
+'占後' => '佔後',
+'占得' => '佔得',
+'占德' => '佔德',
+'占所有' => '佔所有',
+'占掉' => '佔掉',
+'占据' => '佔據',
+'占據' => '佔據',
+'占整' => '佔整',
+'占新' => '佔新',
+'占有' => '佔有',
+'占东' => '佔東',
+'占東' => '佔東',
+'占查' => '佔查',
+'占次' => '佔次',
+'占比' => '佔比',
+'占法' => '佔法',
+'占满' => '佔滿',
+'占滿' => '佔滿',
+'占澳' => '佔澳',
+'占为' => '佔為',
+'占為' => '佔為',
+'占率' => '佔率',
+'占用' => '佔用',
+'占毕' => '佔畢',
+'占畢' => '佔畢',
+'占百' => '佔百',
+'占尽' => '佔盡',
+'占盡' => '佔盡',
+'占着' => '佔着',
+'占著' => '佔着',
+'占網' => '佔網',
+'占网' => '佔網',
+'占線' => '佔線',
+'占线' => '佔線',
+'占总' => '佔總',
+'占總' => '佔總',
+'占缺' => '佔缺',
+'占美国' => '佔美國',
+'占美國' => '佔美國',
+'占耕' => '佔耕',
+'占至多' => '佔至多',
+'占至少' => '佔至少',
+'占臺' => '佔臺',
+'占英' => '佔英',
+'占万' => '佔萬',
+'占萬' => '佔萬',
+'占著名' => '佔著名',
+'占著者' => '佔著者',
+'占葡' => '佔葡',
+'占苏' => '佔蘇',
+'占蘇' => '佔蘇',
+'占西' => '佔西',
+'占資' => '佔資',
+'占资' => '佔資',
+'占起' => '佔起',
+'占超过' => '佔超過',
+'占超過' => '佔超過',
+'占过' => '佔過',
+'占過' => '佔過',
+'占道' => '佔道',
+'占零' => '佔零',
+'占領' => '佔領',
+'占领' => '佔領',
+'占头' => '佔頭',
+'占頭' => '佔頭',
+'占头筹' => '佔頭籌',
+'占頭籌' => '佔頭籌',
+'占香' => '佔香',
+'占馬' => '佔馬',
+'占马' => '佔馬',
+'占高枝' => '佔高枝',
+'維德角' => '佛得角',
+'作品里' => '作品裏',
+'來著' => '來着',
+'來著作' => '來著作',
+'來著名' => '來著名',
+'來著書' => '來著書',
+'來著稱' => '來著稱',
+'來著者' => '來著者',
+'來著述' => '來著述',
+'來著錄' => '來著錄',
+'侵占' => '侵佔',
+'俄占' => '俄佔',
+'保障著' => '保障着',
+'保障著作' => '保障著作',
+'保障著名' => '保障著名',
+'保障著書' => '保障著書',
+'保障著稱' => '保障著稱',
+'保障著者' => '保障著者',
+'保障著述' => '保障著述',
+'保障著錄' => '保障著錄',
+'信著' => '信着',
+'信著作' => '信著作',
+'信著名' => '信著名',
+'信著書' => '信著書',
+'信著称' => '信著稱',
+'信著稱' => '信著稱',
+'信著者' => '信著者',
+'信著述' => '信著述',
+'信著錄' => '信著錄',
+'个月里' => '個月裏',
+'个里' => '個裏',
+'倒楣' => '倒霉',
+'候著' => '候着',
+'候著作' => '候著作',
+'候著名' => '候著名',
+'候著書' => '候著書',
+'候著稱' => '候著稱',
+'候著者' => '候著者',
+'候著述' => '候著述',
+'候著錄' => '候著錄',
+'借著' => '借着',
+'借著作' => '借著作',
+'借著名' => '借著名',
+'借著書' => '借著書',
+'借著稱' => '借著稱',
+'借著者' => '借著者',
+'借著述' => '借著述',
+'借著錄' => '借著錄',
+'假里' => '假裏',
+'做著' => '做着',
+'做著作' => '做著作',
+'做著名' => '做著名',
+'做著書' => '做著書',
+'做著稱' => '做著稱',
+'做著者' => '做著者',
+'做著述' => '做著述',
+'做著錄' => '做著錄',
+'吉尼斯世界纪录' => '健力士世界紀錄',
+'金氏世界紀錄' => '健力士世界紀錄',
+'側著' => '側着',
+'側著作' => '側著作',
+'側著名' => '側著名',
+'側著書' => '側著書',
+'側著稱' => '側著稱',
+'側著者' => '側著者',
+'側著述' => '側著述',
+'側著錄' => '側著錄',
+'偷著' => '偷着',
+'偷著作' => '偷著作',
+'偷著名' => '偷著名',
+'偷著書' => '偷著書',
+'偷著稱' => '偷著稱',
+'偷著者' => '偷著者',
+'偷著述' => '偷著述',
+'偷著錄' => '偷著錄',
+'備著' => '備着',
+'備著作' => '備著作',
+'備著名' => '備著名',
+'備著書' => '備著書',
+'備著稱' => '備著稱',
+'備著者' => '備著者',
+'備著述' => '備著述',
+'備著錄' => '備著錄',
+'傻里傻气' => '傻裏傻氣',
+'雇员' => '僱員',
+'雇用' => '僱用',
+'凶惡' => '兇惡',
+'凶殘' => '兇殘',
+'凶殺' => '兇殺',
+'先占' => '先佔',
+'雪鐵龍' => '先進',
+'雪铁龙' => '先進',
+'光著' => '光着',
+'光著作' => '光著作',
+'光著名' => '光著名',
+'光著書' => '光著書',
+'光著称' => '光著稱',
+'光著稱' => '光著稱',
+'光著者' => '光著者',
+'光著述' => '光著述',
+'光著錄' => '光著錄',
+'柯林頓' => '克林頓',
+'克羅埃西亞' => '克羅地亞',
+'公布' => '公佈',
+'冒著' => '冒着',
+'冒著作' => '冒著作',
+'冒著名' => '冒著名',
+'冒著書' => '冒著書',
+'冒著稱' => '冒著稱',
+'冒著者' => '冒著者',
+'冒著述' => '冒著述',
+'冒著錄' => '冒著錄',
+'冰山里' => '冰山裏',
+'恺撒' => '凱撒',
+'函数里' => '函數裏',
+'分布' => '分佈',
+'分布于' => '分佈於',
+'分佈著' => '分佈着',
+'分布著' => '分佈着',
+'分占' => '分佔',
+'分钟里' => '分鐘裏',
+'錢尼' => '切尼',
+'切尔诺贝利' => '切爾諾貝爾',
+'列支敦斯登' => '列支敦士登',
+'別著' => '別着',
+'賴比瑞亞' => '利比里亞',
+'刮著' => '刮着',
+'到山里' => '到山裏',
+'制著' => '制着',
+'制著作' => '制著作',
+'制著名' => '制著名',
+'制著書' => '制著書',
+'制著稱' => '制著稱',
+'制著者' => '制著者',
+'制著述' => '制著述',
+'制著錄' => '制著錄',
+'刻著' => '刻着',
+'刻著作' => '刻著作',
+'刻著名' => '刻著名',
+'刻著書' => '刻著書',
+'刻著称' => '刻著稱',
+'刻著稱' => '刻著稱',
+'刻著者' => '刻著者',
+'刻著述' => '刻著述',
+'刻著錄' => '刻著錄',
+'前波莫瑞' => '前波美拉尼亞',
+'剪彩' => '剪綵',
+'割占' => '割佔',
+'劃著' => '劃着',
+'击剑' => '劍擊',
+'擊劍' => '劍擊',
+'加薩走廊' => '加沙地帶',
+'迦納' => '加納',
+'加彭' => '加蓬',
+'努力著' => '努力着',
+'努力著作' => '努力著作',
+'努力著名' => '努力著名',
+'努力著書' => '努力著書',
+'努力著称' => '努力著稱',
+'努力著稱' => '努力著稱',
+'努力著者' => '努力著者',
+'努力著述' => '努力著述',
+'努力著錄' => '努力著錄',
+'布蘭登堡' => '勃蘭登堡',
+'動著' => '動着',
+'動著作' => '動著作',
+'動著名' => '動著名',
+'動著書' => '動著書',
+'動著稱' => '動著稱',
+'動著者' => '動著者',
+'動著述' => '動著述',
+'動著錄' => '動著錄',
+'包著' => '包着',
+'北朝鲜' => '北韓',
+'南朝鲜' => '南韓',
+'波札那' => '博茨瓦納',
+'占卜' => '占卜',
+'占国桥' => '占國橋',
+'占國橋' => '占國橋',
+'占有五不' => '占有五不',
+'占著作' => '占著作',
+'占著稱' => '占著稱',
+'占著述' => '占著述',
+'占著錄' => '占著錄',
+'卡普里亚蒂' => '卡佩雅蒂',
+'喀拉蚩' => '卡拉奇',
+'卡斯楚' => '卡斯特羅',
+'印著' => '印着',
+'印著作' => '印著作',
+'印著名' => '印著名',
+'印著書' => '印著書',
+'印著稱' => '印著稱',
+'印著者' => '印著者',
+'印著述' => '印著述',
+'印著錄' => '印著錄',
+'瓜地馬拉' => '危地馬拉',
+'厄瓜多' => '厄瓜多爾',
+'厄瓜多尔' => '厄瓜多爾',
+'厄瓜多爾' => '厄瓜多爾',
+'厄利垂亚' => '厄立特里亞',
+'厄利垂亞' => '厄立特里亞',
+'源代码' => '原始碼',
+'去山里' => '去山裏',
+'参数里' => '參數裏',
+'受著' => '受着',
+'受著作' => '受著作',
+'受著名' => '受著名',
+'受著書' => '受著書',
+'受著稱' => '受著稱',
+'受著者' => '受著者',
+'受著述' => '受著述',
+'受著錄' => '受著錄',
+'丛林里' => '叢林裏',
+'口里' => '口裏',
+'只占' => '只佔',
+'叫著' => '叫着',
+'叫著作' => '叫著作',
+'叫著名' => '叫著名',
+'叫著書' => '叫著書',
+'叫著稱' => '叫著稱',
+'叫著者' => '叫著者',
+'叫著述' => '叫著述',
+'叫著錄' => '叫著錄',
+'古柯鹼' => '可卡因',
+'叱吒' => '叱咤',
+'斯坦福大学' => '史丹福大學',
+'史匹柏' => '史匹堡',
+'斯皮尔伯格' => '史匹堡',
+'史蒂芬·史匹柏' => '史提芬·史匹堡',
+'斯蒂芬·斯皮尔伯格' => '史提芬·史匹堡',
+'吃不著' => '吃不着',
+'吃得著' => '吃得着',
+'吃著' => '吃着',
+'吃里扒外' => '吃裏扒外',
+'吃里爬外' => '吃裏爬外',
+'吉布地' => '吉布堤',
+'吊著' => '吊着',
+'向著' => '向着',
+'向著作' => '向著作',
+'向著名' => '向著名',
+'向著書' => '向著書',
+'向著稱' => '向著稱',
+'向著者' => '向著者',
+'向著述' => '向著述',
+'向著錄' => '向著錄',
+'吞占' => '吞佔',
+'吧台' => '吧枱',
+'含著' => '含着',
+'含著作' => '含著作',
+'含著名' => '含著名',
+'含著書' => '含著書',
+'含著稱' => '含著稱',
+'含著者' => '含著者',
+'含著述' => '含著述',
+'含著錄' => '含著錄',
+'吹著' => '吹着',
+'吹著作' => '吹著作',
+'吹著名' => '吹著名',
+'吹著書' => '吹著書',
+'吹著稱' => '吹著稱',
+'吹著者' => '吹著者',
+'吹著述' => '吹著述',
+'吹著錄' => '吹著錄',
+'呆著' => '呆着',
+'呆里呆气' => '呆裏呆氣',
+'味著' => '味着',
+'味著作' => '味著作',
+'味著名' => '味著名',
+'味著書' => '味著書',
+'味著称' => '味著稱',
+'味著稱' => '味著稱',
+'味著者' => '味著者',
+'味著述' => '味著述',
+'味著錄' => '味著錄',
+'咖哩' => '咖喱',
+'麥克風' => '咪高峰',
+'麦克风' => '咪高峰',
+'哥特式' => '哥德式',
+'哥斯大黎加' => '哥斯達黎加',
+'哪里' => '哪裏',
+'哭著' => '哭着',
+'哭著作' => '哭著作',
+'哭著名' => '哭著名',
+'哭著書' => '哭著書',
+'哭著稱' => '哭著稱',
+'哭著者' => '哭著者',
+'哭著述' => '哭著述',
+'哭著錄' => '哭著錄',
+'唱著' => '唱着',
+'唱著作' => '唱著作',
+'唱著名' => '唱著名',
+'唱著書' => '唱著書',
+'唱著稱' => '唱著稱',
+'唱著者' => '唱著者',
+'唱著述' => '唱著述',
+'唱著錄' => '唱著錄',
+'喝著' => '喝着',
+'喝著作' => '喝著作',
+'喝著名' => '喝著名',
+'喝著書' => '喝著書',
+'喝著稱' => '喝著稱',
+'喝著者' => '喝著者',
+'喝著述' => '喝著述',
+'喝著錄' => '喝著錄',
+'賈伯斯' => '喬布斯',
+'乔治·奥威尔' => '喬治·歐威爾',
+'单反相机' => '單鏡反光機',
+'單眼相機' => '單鏡反光機',
+'嗅不著' => '嗅不着',
+'嗅得著' => '嗅得着',
+'嗅著' => '嗅着',
+'凯瑟琳' => '嘉芙蓮',
+'凱薩琳' => '嘉芙蓮',
+'嘯吒' => '嘯咤',
+'嘴里' => '嘴裏',
+'嚷著' => '嚷着',
+'嚷著作' => '嚷著作',
+'嚷著名' => '嚷著名',
+'嚷著書' => '嚷著書',
+'嚷著稱' => '嚷著稱',
+'嚷著者' => '嚷著者',
+'嚷著述' => '嚷著述',
+'嚷著錄' => '嚷著錄',
+'回著' => '回着',
+'回著名' => '回著名',
+'因著' => '因着',
+'因著〈' => '因著〈',
+'因著《' => '因著《',
+'因著作' => '因著作',
+'因著名' => '因著名',
+'因著書' => '因著書',
+'因著稱' => '因著稱',
+'因著者' => '因著者',
+'因著述' => '因著述',
+'因著錄' => '因著錄',
+'困著' => '困着',
+'困著作' => '困著作',
+'困著名' => '困著名',
+'困著書' => '困著書',
+'困著稱' => '困著稱',
+'困著者' => '困著者',
+'困著述' => '困著述',
+'困著錄' => '困著錄',
+'固著' => '固着',
+'圈占' => '圈佔',
+'圈里' => '圈裏',
+'西洋棋' => '國際象棋',
+'圍著' => '圍着',
+'圍著作' => '圍著作',
+'圍著名' => '圍著名',
+'圍著書' => '圍著書',
+'圍著稱' => '圍著稱',
+'圍著者' => '圍著者',
+'圍著述' => '圍著述',
+'圍著錄' => '圍著錄',
+'园里' => '園裏',
+'吐瓦魯' => '圖瓦盧',
+'土魯斯' => '圖盧茲',
+'图里的' => '圖裏的',
+'图里,' => '圖裏,',
+'土里' => '土裏',
+'在山里' => '在山裏',
+'蓋亞那' => '圭亞那',
+'地占' => '地佔',
+'地图里' => '地圖裏',
+'堪培拉' => '坎培拉',
+'坐台' => '坐枱',
+'坐著' => '坐着',
+'坐著作' => '坐著作',
+'坐著名' => '坐著名',
+'坐著書' => '坐著書',
+'坐著稱' => '坐著稱',
+'坐著者' => '坐著者',
+'坐著述' => '坐著述',
+'坐著錄' => '坐著錄',
+'坑里' => '坑裏',
+'坦尚尼亞' => '坦桑尼亞',
+'衣索匹亞' => '埃塞俄比亚',
+'衣索比亞' => '埃塞俄比亞',
+'葉里溫' => '埃里溫',
+'城市里' => '城市裏',
+'城里' => '城裏',
+'域里' => '域裏',
+'吉里巴斯' => '基里巴斯',
+'堅貞著' => '堅貞着',
+'场里' => '場裏',
+'塗著' => '塗着',
+'塞普勒斯' => '塞浦路斯',
+'賽普勒斯' => '塞浦路斯',
+'塞爾維亞與蒙特內哥羅' => '塞爾維亞和黑山',
+'塞席爾' => '塞舌爾',
+'境里' => '境裏',
+'壓著' => '壓着',
+'壓著作' => '壓著作',
+'壓著名' => '壓著名',
+'壓著書' => '壓著書',
+'壓著稱' => '壓著稱',
+'壓著者' => '壓著者',
+'壓著述' => '壓著述',
+'壓著錄' => '壓著錄',
+'壶里' => '壺裏',
+'多占' => '多佔',
+'夜晚里' => '夜晚裏',
+'夜里' => '夜裏',
+'夢有五不占' => '夢有五不占',
+'梦有五不占' => '夢有五不占',
+'夢著' => '夢着',
+'夢著作' => '夢著作',
+'夢著名' => '夢著名',
+'夢著書' => '夢著書',
+'夢著稱' => '夢著稱',
+'夢著者' => '夢著者',
+'夢著述' => '夢著述',
+'夢著錄' => '夢著錄',
+'梦里' => '夢裏',
+'天里' => '天裏',
+'宇航员' => '太空人',
+'夾著' => '夾着',
+'夾著作' => '夾著作',
+'夾著名' => '夾著名',
+'夾著書' => '夾著書',
+'夾著稱' => '夾著稱',
+'夾著者' => '夾著者',
+'夾著述' => '夾著述',
+'夾著錄' => '夾著錄',
+'奥占' => '奧佔',
+'奧占' => '奧佔',
+'歐巴馬' => '奧巴馬',
+'妆台' => '妝枱',
+'威斯伐倫' => '威斯特法倫',
+'威尔士' => '威爾斯',
+'威爾士' => '威爾斯',
+'子里' => '子裏',
+'字里行间' => '字裏行間',
+'存在著' => '存在着',
+'存著' => '存着',
+'存著作' => '存著作',
+'存著名' => '存著名',
+'孟德爾頌' => '孟德爾遜',
+'门德尔松' => '孟德爾遜',
+'學著' => '學着',
+'學著作' => '學著作',
+'學著名' => '學著名',
+'學著書' => '學著書',
+'學著稱' => '學著稱',
+'學著者' => '學著者',
+'學著述' => '學著述',
+'學著錄' => '學著錄',
+'学里' => '學裏',
+'守著' => '守着',
+'守著作' => '守著作',
+'守著名' => '守著名',
+'守著書' => '守著書',
+'守著称' => '守著稱',
+'守著稱' => '守著稱',
+'守著者' => '守著者',
+'守著述' => '守著述',
+'守著錄' => '守著錄',
+'安哈特' => '安哈爾特',
+'安地卡及巴布達' => '安提瓜和巴布達',
+'定著' => '定着',
+'定著作' => '定著作',
+'定著名' => '定著名',
+'定著書' => '定著書',
+'定著称' => '定著稱',
+'定著稱' => '定著稱',
+'定著者' => '定著者',
+'定著述' => '定著述',
+'定著錄' => '定著錄',
+'宣布' => '宣佈',
+'宫里' => '宮裏',
+'家里' => '家裏',
+'密布' => '密佈',
+'密西根' => '密歇根',
+'沃尓沃' => '富豪',
+'寡占' => '寡佔',
+'写字台' => '寫字枱',
+'寫著' => '寫着',
+'寫著作' => '寫著作',
+'寫著名' => '寫著名',
+'寫著書' => '寫著書',
+'寫著稱' => '寫著稱',
+'寫著者' => '寫著者',
+'寫著述' => '寫著述',
+'寫著錄' => '寫著錄',
+'宝里宝气' => '寶裏寶氣',
+'封面里' => '封面裏',
+'将占' => '將佔',
+'將占' => '將佔',
+'将占卜' => '將占卜',
+'將占卜' => '將占卜',
+'专辑里' => '專輯裏',
+'尋著' => '尋着',
+'尋著作' => '尋著作',
+'尋著名' => '尋著名',
+'尋著書' => '尋著書',
+'尋著稱' => '尋著稱',
+'尋著者' => '尋著者',
+'尋著述' => '尋著述',
+'尋著錄' => '尋著錄',
+'對著' => '對着',
+'對著作' => '對著作',
+'對著名' => '對著名',
+'對著書' => '對著書',
+'對著稱' => '對著稱',
+'對著者' => '對著者',
+'對著述' => '對著述',
+'對著錄' => '對著錄',
+'小时里' => '小時裏',
+'少占' => '少佔',
+'就里' => '就裏',
+'尼克松' => '尼克遜',
+'奈及利亞' => '尼日利亞',
+'局里' => '局裏',
+'屋里' => '屋裏',
+'展著' => '展着',
+'展著作' => '展著作',
+'展著名' => '展著名',
+'展著書' => '展著書',
+'展著稱' => '展著稱',
+'展著者' => '展著者',
+'展著述' => '展著述',
+'展著錄' => '展著錄',
+'屯里' => '屯裏',
+'山里有' => '山裏有',
+'山里的' => '山裏的',
+'甘比亞' => '岡比亞',
+'岸裡' => '岸裡',
+'工作台' => '工作枱',
+'已占' => '已佔',
+'巴塞罗那' => '巴塞隆拿',
+'巴塞隆納' => '巴塞隆拿',
+'巴貝多' => '巴巴多斯',
+'巴布亞紐幾內亞' => '巴布亞新畿內亞',
+'巴士拉' => '巴斯拉',
+'巷里' => '巷裏',
+'市占' => '市佔',
+'市里的' => '市裏的',
+'布吉納法索' => '布基納法索',
+'布什' => '布殊',
+'布里斯托尔' => '布里斯托',
+'蒲隆地' => '布隆迪',
+'希冀著' => '希冀着',
+'席哈克' => '希拉克',
+'希拉蕊' => '希拉莉',
+'希特勒' => '希特拉',
+'帛琉' => '帕勞',
+'巴尔米拉环礁' => '帕邁拉環礁',
+'帕劳' => '帛琉',
+'帶著' => '帶着',
+'帶著作' => '帶著作',
+'帶著名' => '帶著名',
+'帶著書' => '帶著書',
+'帶著稱' => '帶著稱',
+'帶著者' => '帶著者',
+'帶著述' => '帶著述',
+'帶著錄' => '帶著錄',
+'幅图里' => '幅圖裏',
+'幫著' => '幫着',
+'幫著作' => '幫著作',
+'幫著名' => '幫著名',
+'幫著書' => '幫著書',
+'幫著稱' => '幫著稱',
+'幫著者' => '幫著者',
+'幫著述' => '幫著述',
+'幫著錄' => '幫著錄',
+'干着急' => '干着急',
+'賓士' => '平治',
+'年代里' => '年代裏',
+'年里' => '年裏',
+'干着' => '幹着',
+'幹著' => '幹着',
+'幹著名' => '幹著名',
+'幹著稱' => '幹著稱',
+'幾內亞比索' => '幾內亞比紹',
+'店里' => '店裏',
+'庫德人' => '庫爾德人',
+'庫德族' => '庫爾德族',
+'坎城' => '康城',
+'戛纳' => '康城',
+'庙里' => '廟裏',
+'广播里' => '廣播裏',
+'強占' => '強佔',
+'强占' => '強佔',
+'约翰斯顿岛' => '強斯頓環礁',
+'弹子台' => '彈子枱',
+'蹦床' => '彈床',
+'弹珠台' => '彈珠枱',
+'形上學' => '形而上學',
+'谢丽·布莱尔' => '彭雪玲',
+'往里' => '往裏',
+'待著' => '待着',
+'待著作' => '待著作',
+'待著名' => '待著名',
+'待著書' => '待著書',
+'待著稱' => '待著稱',
+'待著者' => '待著者',
+'待著述' => '待著述',
+'待著錄' => '待著錄',
+'得著' => '得着',
+'得著作' => '得著作',
+'得著名' => '得著名',
+'得著書' => '得著書',
+'得著稱' => '得著稱',
+'得著者' => '得著者',
+'得著述' => '得著述',
+'得著錄' => '得著錄',
+'从图里' => '從圖裏',
+'从山里' => '從山裏',
+'从里到外' => '從裏到外',
+'从里向外' => '從裏向外',
+'循著' => '循着',
+'循著作' => '循著作',
+'循著名' => '循著名',
+'循著書' => '循著書',
+'循著稱' => '循著稱',
+'循著者' => '循著者',
+'循著述' => '循著述',
+'循著錄' => '循著錄',
+'征占' => '徵佔',
+'徵占' => '徵佔',
+'德占' => '德佔',
+'得克萨斯' => '德克薩斯',
+'德勒斯登' => '德累斯頓',
+'澈底' => '徹底',
+'心著' => '心着',
+'心著作' => '心著作',
+'心著名' => '心著名',
+'心著書' => '心著書',
+'心著称' => '心著稱',
+'心著稱' => '心著稱',
+'心著者' => '心著者',
+'心著述' => '心著述',
+'心著錄' => '心著錄',
+'心里' => '心裏',
+'心里面' => '心裏面',
+'忍著' => '忍着',
+'忍著作' => '忍著作',
+'忍著名' => '忍著名',
+'忍著書' => '忍著書',
+'忍著稱' => '忍著稱',
+'忍著者' => '忍著者',
+'忍著述' => '忍著述',
+'忍著錄' => '忍著錄',
+'忙著' => '忙着',
+'忙著作' => '忙著作',
+'忙著名' => '忙著名',
+'忙著書' => '忙著書',
+'忙著稱' => '忙著稱',
+'忙著者' => '忙著者',
+'忙著述' => '忙著述',
+'忙著錄' => '忙著錄',
+'忙里' => '忙裏',
+'忠貞著' => '忠貞着',
+'急著' => '急着',
+'急著作' => '急著作',
+'急著名' => '急著名',
+'急著書' => '急著書',
+'急著稱' => '急著稱',
+'急著者' => '急著者',
+'急著述' => '急著述',
+'急著錄' => '急著錄',
+'怪里怪气' => '怪裏怪氣',
+'悠著' => '悠着',
+'悠著作' => '悠著作',
+'悠著名' => '悠著名',
+'悠著書' => '悠著書',
+'悠著稱' => '悠著稱',
+'悠著者' => '悠著者',
+'悠著述' => '悠著述',
+'悠著錄' => '悠著錄',
+'悶著' => '悶着',
+'想象' => '想像',
+'想著' => '想着',
+'想著作' => '想著作',
+'想著名' => '想著名',
+'想著書' => '想著書',
+'想著称' => '想著稱',
+'想著稱' => '想著稱',
+'想著者' => '想著者',
+'想著述' => '想著述',
+'想著錄' => '想著錄',
+'意占' => '意佔',
+'義占' => '意佔',
+'義大利' => '意大利',
+'艾滋' => '愛滋',
+'愛著' => '愛着',
+'愛著作' => '愛著作',
+'愛著名' => '愛著名',
+'愛著書' => '愛著書',
+'愛著稱' => '愛著稱',
+'愛著者' => '愛著者',
+'愛著述' => '愛著述',
+'愛著錄' => '愛著錄',
+'慌里慌张' => '慌裏慌張',
+'慣著' => '慣着',
+'慣著作' => '慣著作',
+'慣著名' => '慣著名',
+'慣著書' => '慣著書',
+'慣著稱' => '慣著稱',
+'慣著者' => '慣著者',
+'慣著述' => '慣著述',
+'慣著錄' => '慣著錄',
+'宪法里' => '憲法裏',
+'应用程序' => '應用程式',
+'應著' => '應着',
+'應著作' => '應著作',
+'應著名' => '應著名',
+'應著書' => '應著書',
+'應著稱' => '應著稱',
+'應著者' => '應著者',
+'應著述' => '應著述',
+'應著錄' => '應著錄',
+'懷著' => '懷着',
+'懷著作' => '懷著作',
+'懷著名' => '懷著名',
+'懷著書' => '懷著書',
+'懷著稱' => '懷著稱',
+'懷著者' => '懷著者',
+'懷著述' => '懷著述',
+'懷著錄' => '懷著錄',
+'怀里' => '懷裏',
+'戀著' => '戀着',
+'戀著作' => '戀著作',
+'戀著名' => '戀著名',
+'戀著書' => '戀著書',
+'戀著稱' => '戀著稱',
+'戀著者' => '戀著者',
+'戀著述' => '戀著述',
+'戀著錄' => '戀著錄',
+'戈巴契夫' => '戈爾巴喬夫',
+'戰著' => '戰着',
+'戰著作' => '戰著作',
+'戰著名' => '戰著名',
+'戰著書' => '戰著書',
+'戰著稱' => '戰著稱',
+'戰著者' => '戰著者',
+'戰著述' => '戰著述',
+'戰著錄' => '戰著錄',
+'戏彩娱亲' => '戲綵娛親',
+'戲彩娛親' => '戲綵娛親',
+'戏里' => '戲裏',
+'撒切尔' => '戴卓爾',
+'柴契爾' => '戴卓爾',
+'狄安娜' => '戴安娜',
+'黛安娜' => '戴安娜',
+'戴著' => '戴着',
+'戴著作' => '戴著作',
+'戴著名' => '戴著名',
+'戴著書' => '戴著書',
+'戴著稱' => '戴著稱',
+'戴著者' => '戴著者',
+'戴著述' => '戴著述',
+'戴著錄' => '戴著錄',
+'房里' => '房裏',
+'所占' => '所佔',
+'索羅門群島' => '所羅門群島',
+'手里' => '手裏',
+'手里剑' => '手裏劍',
+'列印' => '打印',
+'印表機' => '打印機',
+'打著' => '打着',
+'打著作' => '打著作',
+'打著名' => '打著名',
+'打著書' => '打著書',
+'打著稱' => '打著稱',
+'打著者' => '打著者',
+'打著述' => '打著述',
+'打著錄' => '打著錄',
+'扛著' => '扛着',
+'扛著作' => '扛著作',
+'扛著名' => '扛著名',
+'扛著書' => '扛著書',
+'扛著稱' => '扛著稱',
+'扛著者' => '扛著者',
+'扛著述' => '扛著述',
+'扛著錄' => '扛著錄',
+'找不著' => '找不着',
+'找得著' => '找得着',
+'承宣布政' => '承宣布政',
+'抓著' => '抓着',
+'抓著作' => '抓著作',
+'抓著名' => '抓著名',
+'抓著稱' => '抓著稱',
+'抓著者' => '抓著者',
+'抓著述' => '抓著述',
+'抓著錄' => '抓著錄',
+'披著' => '披着',
+'披著作' => '披著作',
+'披著名' => '披著名',
+'披著書' => '披著書',
+'披著稱' => '披著稱',
+'披著者' => '披著者',
+'披著述' => '披著述',
+'披著錄' => '披著錄',
+'抬著' => '抬着',
+'抬著作' => '抬著作',
+'抬著名' => '抬著名',
+'抬著稱' => '抬著稱',
+'抬著者' => '抬著者',
+'抬著述' => '抬著述',
+'抬著錄' => '抬著錄',
+'抱著' => '抱着',
+'抱著作' => '抱著作',
+'抱著名' => '抱著名',
+'抱著稱' => '抱著稱',
+'抱著者' => '抱著者',
+'抱著述' => '抱著述',
+'抱著錄' => '抱著錄',
+'拉著' => '拉着',
+'拉著作' => '拉著作',
+'拉著名' => '拉著名',
+'拉著書' => '拉著書',
+'拉著稱' => '拉著稱',
+'拉著者' => '拉著者',
+'拉著述' => '拉著述',
+'拉著錄' => '拉著錄',
+'拎著' => '拎着',
+'拎著作' => '拎著作',
+'拎著名' => '拎著名',
+'拎著稱' => '拎著稱',
+'拎著者' => '拎著者',
+'拎著述' => '拎著述',
+'拎著錄' => '拎著錄',
+'拖著' => '拖着',
+'拖著作' => '拖著作',
+'拖著名' => '拖著名',
+'拖著稱' => '拖著稱',
+'拖著者' => '拖著者',
+'拖著述' => '拖著述',
+'拖著錄' => '拖著錄',
+'拼著' => '拼着',
+'拼著作' => '拼著作',
+'拼著名' => '拼著名',
+'拼著稱' => '拼著稱',
+'拼著者' => '拼著者',
+'拼著述' => '拼著述',
+'拼著錄' => '拼著錄',
+'拿著' => '拿着',
+'拿著作' => '拿著作',
+'拿著名' => '拿著名',
+'拿著稱' => '拿著稱',
+'拿著者' => '拿著者',
+'拿著述' => '拿著述',
+'拿著錄' => '拿著錄',
+'持著' => '持着',
+'持著作' => '持著作',
+'持著名' => '持著名',
+'持著稱' => '持著稱',
+'持著者' => '持著者',
+'持著述' => '持著述',
+'持著錄' => '持著錄',
+'挑著' => '挑着',
+'挑著作' => '挑著作',
+'挑著名' => '挑著名',
+'挑著稱' => '挑著稱',
+'挑著者' => '挑著者',
+'挑著述' => '挑著述',
+'挑著錄' => '挑著錄',
+'挨著' => '挨着',
+'挨著作' => '挨著作',
+'挨著名' => '挨著名',
+'挨著稱' => '挨著稱',
+'挨著者' => '挨著者',
+'挨著述' => '挨著述',
+'挨著錄' => '挨著錄',
+'捆著' => '捆着',
+'捆著作' => '捆著作',
+'捆著名' => '捆著名',
+'捆著稱' => '捆著稱',
+'捆著者' => '捆著者',
+'捆著述' => '捆著述',
+'捆著錄' => '捆著錄',
+'伏地挺身' => '掌上壓',
+'俯卧撑' => '掌上壓',
+'掖著' => '掖着',
+'掖著作' => '掖著作',
+'掖著名' => '掖著名',
+'掖著稱' => '掖著稱',
+'掖著者' => '掖著者',
+'掖著述' => '掖著述',
+'掖著錄' => '掖著錄',
+'掙著' => '掙着',
+'掙著作' => '掙著作',
+'掙著名' => '掙著名',
+'掙著書' => '掙著書',
+'掙著稱' => '掙著稱',
+'掙著者' => '掙著者',
+'掙著述' => '掙著述',
+'掙著錄' => '掙著錄',
+'掛著' => '掛着',
+'接著' => '接着',
+'接著作' => '接著作',
+'接著名' => '接著名',
+'接著稱' => '接著稱',
+'接著者' => '接著者',
+'接著述' => '接著述',
+'接著錄' => '接著錄',
+'揉著' => '揉着',
+'揉著作' => '揉著作',
+'揉著名' => '揉著名',
+'揉著書' => '揉著書',
+'揉著稱' => '揉著稱',
+'揉著者' => '揉著者',
+'揉著述' => '揉著述',
+'揉著錄' => '揉著錄',
+'提著' => '提着',
+'提著作' => '提著作',
+'提著名' => '提著名',
+'提著稱' => '提著稱',
+'提著者' => '提著者',
+'提著述' => '提著述',
+'提著錄' => '提著錄',
+'揮著' => '揮着',
+'揮著作' => '揮著作',
+'揮著名' => '揮著名',
+'揮著稱' => '揮著稱',
+'揮著者' => '揮著者',
+'揮著述' => '揮著述',
+'揮著錄' => '揮著錄',
+'搜索引擎' => '搜尋引擎',
+'抢占' => '搶佔',
+'搶占' => '搶佔',
+'摟著' => '摟着',
+'摟著作' => '摟著作',
+'摟著名' => '摟著名',
+'摟著稱' => '摟著稱',
+'摟著者' => '摟著者',
+'摟著述' => '摟著述',
+'摟著錄' => '摟著錄',
+'折台' => '摺枱',
+'撒马尔罕' => '撒馬爾罕',
+'撼著' => '撼着',
+'撼著作' => '撼著作',
+'撼著名' => '撼著名',
+'撼著書' => '撼著書',
+'撼著稱' => '撼著稱',
+'撼著者' => '撼著者',
+'撼著述' => '撼著述',
+'撼著錄' => '撼著錄',
+'擋著' => '擋着',
+'擋著作' => '擋著作',
+'擋著名' => '擋著名',
+'擋著稱' => '擋著稱',
+'擋著者' => '擋著者',
+'擋著述' => '擋著述',
+'擋著錄' => '擋著錄',
+'擔著' => '擔着',
+'據著' => '據着',
+'據著作' => '據著作',
+'據著名' => '據著名',
+'據著書' => '據著書',
+'據著稱' => '據著稱',
+'據著者' => '據著者',
+'據著述' => '據著述',
+'據著錄' => '據著錄',
+'擡著' => '擡着',
+'摆布' => '擺佈',
+'擺布' => '擺佈',
+'擺著' => '擺着',
+'擺著作' => '擺著作',
+'擺著名' => '擺著名',
+'擺著稱' => '擺著稱',
+'擺著者' => '擺著者',
+'擺著述' => '擺著述',
+'擺著錄' => '擺著錄',
+'攻占' => '攻佔',
+'放著' => '放着',
+'放著作' => '放著作',
+'放著名' => '放著名',
+'放著称' => '放著稱',
+'放著稱' => '放著稱',
+'敞著' => '敞着',
+'敞著作' => '敞著作',
+'敞著名' => '敞著名',
+'敞著稱' => '敞著稱',
+'敞著者' => '敞著者',
+'敞著述' => '敞著述',
+'敞著錄' => '敞著錄',
+'散布' => '散佈',
+'散佈著' => '散佈着',
+'散布著' => '散佈着',
+'数字照相机' => '数碼照相機',
+'數位照相機' => '数碼照相機',
+'數著' => '數着',
+'数字化' => '數碼化',
+'數位化' => '數碼化',
+'数字技术' => '數碼技術',
+'數位技術' => '數碼技術',
+'數位相機' => '數碼相機',
+'数字信号' => '數碼訊號',
+'數碼訊號' => '數碼訊號',
+'数字电视' => '數碼電視',
+'數位電視' => '數碼電視',
+'數著作' => '數著作',
+'數著名' => '數著名',
+'數著稱' => '數著稱',
+'數著者' => '數著者',
+'數著述' => '數著述',
+'數著錄' => '數著錄',
+'斥著' => '斥着',
+'斥著作' => '斥著作',
+'斥著名' => '斥著名',
+'斥著書' => '斥著書',
+'斥著稱' => '斥著稱',
+'斥著者' => '斥著者',
+'斥著述' => '斥著述',
+'斥著錄' => '斥著錄',
+'史瓦濟蘭' => '斯威士蘭',
+'斯洛維尼亞' => '斯洛文尼亞',
+'紐澳良' => '新奧爾良',
+'紐西蘭' => '新西蘭',
+'方法里' => '方法裏',
+'族里' => '族裏',
+'日占' => '日佔',
+'日里' => '日裏',
+'昂山素季' => '昂山素姬',
+'翁山蘇姬' => '昂山素姬',
+'昂著' => '昂着',
+'昂著作' => '昂著作',
+'昂著名' => '昂著名',
+'昂著書' => '昂著書',
+'昂著稱' => '昂著稱',
+'昂著者' => '昂著者',
+'昂著述' => '昂著述',
+'昂著錄' => '昂著錄',
+'星罗棋布' => '星羅棋佈',
+'星羅棋布' => '星羅棋佈',
+'映著' => '映着',
+'映著作' => '映著作',
+'映著名' => '映著名',
+'映著書' => '映著書',
+'映著稱' => '映著稱',
+'映著者' => '映著者',
+'映著述' => '映著述',
+'映著錄' => '映著錄',
+'晃著' => '晃着',
+'晃著作' => '晃著作',
+'晃著名' => '晃著名',
+'晃著稱' => '晃著稱',
+'晃著者' => '晃著者',
+'晃著述' => '晃著述',
+'晃著錄' => '晃著錄',
+'晶元' => '晶片',
+'芯片' => '晶片',
+'智慧型' => '智能',
+'智慧卡' => '智能卡',
+'智慧手機' => '智能手機',
+'暗地里' => '暗地裏',
+'暗沟里' => '暗溝裏',
+'暗著' => '暗着',
+'暗著作' => '暗著作',
+'暗著名' => '暗著名',
+'暗著書' => '暗著書',
+'暗著稱' => '暗著稱',
+'暗著者' => '暗著者',
+'暗著述' => '暗著述',
+'暗著錄' => '暗著錄',
+'暗里' => '暗裏',
+'会占' => '會佔',
+'會占' => '會佔',
+'会占卜' => '會占卜',
+'會占卜' => '會占卜',
+'会里' => '會裏',
+'月裡来' => '月裏來',
+'有著' => '有着',
+'有著作' => '有著作',
+'有著名' => '有著名',
+'有著書' => '有著書',
+'有著稱' => '有著稱',
+'有著者' => '有著者',
+'有著述' => '有著述',
+'有著錄' => '有著錄',
+'罗纳德·里根' => '朗奴·列根',
+'罗纳尔多' => '朗拿度',
+'罗纳尔迪尼奥' => '朗拿甸奴',
+'望著' => '望着',
+'望著作' => '望著作',
+'望著名' => '望著名',
+'望著書' => '望著書',
+'望著稱' => '望著稱',
+'望著者' => '望著者',
+'望著述' => '望著述',
+'望著錄' => '望著錄',
+'朝著' => '朝着',
+'朝著作' => '朝著作',
+'朝著名' => '朝著名',
+'朝著稱' => '朝著稱',
+'朝著者' => '朝著者',
+'朝著述' => '朝著述',
+'朝著錄' => '朝著錄',
+'板球' => '木球',
+'賓·拉登' => '本·拉登',
+'班傑明' => '本傑明',
+'賓拉登' => '本拉登',
+'本著' => '本着',
+'本著作' => '本著作',
+'本著名' => '本著名',
+'本著書' => '本著書',
+'本著稱' => '本著稱',
+'本著者' => '本著者',
+'本著述' => '本著述',
+'本著錄' => '本著錄',
+'里瓦尔多' => '李華度',
+'村里' => '村裏',
+'杜塞道夫' => '杜塞爾多夫',
+'迪拜' => '杜拜',
+'東協助' => '東協助',
+'東協會' => '東協會',
+'東協議' => '東協議',
+'東南亞國家協會' => '東南亞國家聯盟',
+'亚细安' => '東盟',
+'東協' => '東盟',
+'板著臉' => '板着臉',
+'枕著' => '枕着',
+'枕著作' => '枕著作',
+'枕著名' => '枕著名',
+'枕著稱' => '枕著稱',
+'枕著者' => '枕著者',
+'枕著述' => '枕著述',
+'枕著錄' => '枕著錄',
+'檯' => '枱',
+'台布' => '枱布',
+'台历' => '枱曆',
+'台灯' => '枱燈',
+'台面上' => '枱面上',
+'台面化' => '枱面化',
+'柏林墙' => '柏林圍牆',
+'奧黛莉·朵杜' => '柯德莉·塔圖',
+'奥黛丽·赫本' => '柯德莉·夏萍',
+'奧黛麗·赫本' => '柯德莉·夏萍',
+'哥廷根' => '格丁根',
+'格瑞那達' => '格林納達',
+'格莱美奖' => '格林美獎',
+'葛萊美獎' => '格林美獎',
+'格鲁吉亚' => '格魯吉亞',
+'框里' => '框裏',
+'台式电脑' => '桌上型電腦',
+'台球' => '桌球',
+'撞球' => '桌球',
+'梅鐸' => '梅鐸',
+'默多克' => '梅鐸',
+'梳著' => '梳着',
+'梳著作' => '梳著作',
+'梳著名' => '梳著名',
+'梳著稱' => '梳著稱',
+'梳著者' => '梳著者',
+'梳著述' => '梳著述',
+'梳著錄' => '梳著錄',
+'棉里' => '棉裏',
+'桑巴舞' => '森巴舞',
+'森林里' => '森林裏',
+'棺材里' => '棺材裏',
+'榴莲' => '榴槤',
+'榴蓮' => '榴槤',
+'樂著' => '樂着',
+'樂著作' => '樂著作',
+'樂著名' => '樂著名',
+'樂著書' => '樂著書',
+'樂著稱' => '樂著稱',
+'樂著者' => '樂著者',
+'樂著述' => '樂著述',
+'樂著錄' => '樂著錄',
+'標志著' => '標志着',
+'寶獅' => '標致',
+'標誌著' => '標誌着',
+'树林里' => '樹林裏',
+'工具機' => '機床',
+'机器人' => '機械人',
+'機器人' => '機械人',
+'柜台' => '櫃枱',
+'柜里' => '櫃裏',
+'历史里' => '歷史裏',
+'死里求生' => '死裏求生',
+'死里逃生' => '死裏逃生',
+'殺著' => '殺着',
+'殺著作' => '殺著作',
+'殺著名' => '殺著名',
+'殺著書' => '殺著書',
+'殺著稱' => '殺著稱',
+'殺著者' => '殺著者',
+'殺著述' => '殺著述',
+'殺著錄' => '殺著錄',
+'壳里' => '殼裏',
+'茅利塔尼亞' => '毛里塔尼亞',
+'模里西斯' => '毛里裘斯',
+'毛里求斯' => '毛里裘斯',
+'公厘' => '毫米',
+'公釐' => '毫米',
+'水来汤里去' => '水來湯裏去',
+'水里' => '水裏',
+'求著' => '求着',
+'求著作' => '求著作',
+'求著名' => '求著名',
+'求著書' => '求著書',
+'求著稱' => '求著稱',
+'求著者' => '求著者',
+'求著述' => '求著述',
+'求著錄' => '求著錄',
+'池里' => '池裏',
+'汙' => '污',
+'文莱' => '汶萊',
+'沈著' => '沈着',
+'沉著' => '沉着',
+'沉著作' => '沉著作',
+'沉著名' => '沉著名',
+'沉著書' => '沉著書',
+'沉著稱' => '沉著稱',
+'沉著者' => '沉著者',
+'沉著述' => '沉著述',
+'沉著錄' => '沉著錄',
+'沖著' => '沖着',
+'沖著。' => '沖著。',
+'沖著《' => '沖著《',
+'沖著,' => '沖著,',
+'沙地阿拉伯' => '沙特阿拉伯',
+'沙烏地阿拉伯' => '沙特阿拉伯',
+'沙里淘金' => '沙裏淘金',
+'河里' => '河裏',
+'沿著' => '沿着',
+'沿著作' => '沿著作',
+'沿著名' => '沿著名',
+'沿著書' => '沿著書',
+'沿著稱' => '沿著稱',
+'沿著者' => '沿著者',
+'沿著述' => '沿著述',
+'沿著錄' => '沿著錄',
+'法占' => '法佔',
+'法里,' => '法裏,',
+'玻里尼西亞' => '波利尼西亞',
+'波士尼亞' => '波斯尼亞',
+'波士尼亞赫塞哥維納' => '波斯尼亞黑塞哥維那',
+'宝莱坞' => '波里活',
+'寶萊塢' => '波里活',
+'幫浦' => '泵',
+'洞里' => '洞裏',
+'辛巴威' => '津巴布韋',
+'宏都拉斯' => '洪都拉斯',
+'活著' => '活着',
+'活著作' => '活著作',
+'活著名' => '活著名',
+'活著書' => '活著書',
+'活著稱' => '活著稱',
+'活著者' => '活著者',
+'活著述' => '活著述',
+'活著錄' => '活著錄',
+'移动网络' => '流動網絡',
+'行動網路' => '流動網絡',
+'移动电话' => '流動電話',
+'行動電話' => '流動電話',
+'流著' => '流着',
+'流著作' => '流著作',
+'流著名' => '流著名',
+'流著書' => '流著書',
+'流著稱' => '流著稱',
+'流著者' => '流著者',
+'流著述' => '流著述',
+'流著錄' => '流著錄',
+'流露著' => '流露着',
+'浮著' => '浮着',
+'蘭卡威' => '浮羅交怡',
+'浮著作' => '浮著作',
+'浮著名' => '浮著名',
+'浮著書' => '浮著書',
+'浮著稱' => '浮著稱',
+'浮著者' => '浮著者',
+'浮著述' => '浮著述',
+'浮著錄' => '浮著錄',
+'海上布雷' => '海上佈雷',
+'海洛因' => '海洛英',
+'海湾布雷' => '海灣佈雷',
+'海灣布雷' => '海灣佈雷',
+'涼著' => '涼着',
+'涼著作' => '涼著作',
+'涼著名' => '涼著名',
+'涼著書' => '涼著書',
+'涼著稱' => '涼著稱',
+'涼著者' => '涼著者',
+'涼著述' => '涼著述',
+'涼著錄' => '涼著錄',
+'深山里' => '深山裏',
+'渊里' => '淵裏',
+'渴著' => '渴着',
+'渴著作' => '渴著作',
+'渴著名' => '渴著名',
+'渴著書' => '渴著書',
+'渴著稱' => '渴著稱',
+'渴著者' => '渴著者',
+'渴著述' => '渴著述',
+'渴著錄' => '渴著錄',
+'湊合著' => '湊合着',
+'湖里' => '湖裏',
+'准将' => '準將',
+'准將' => '準將',
+'准尉' => '準尉',
+'溢著' => '溢着',
+'溢著作' => '溢著作',
+'溢著名' => '溢著名',
+'溢著書' => '溢著書',
+'溢著稱' => '溢著稱',
+'溢著者' => '溢著者',
+'溢著述' => '溢著述',
+'溢著錄' => '溢著錄',
+'演著' => '演着',
+'演著作' => '演著作',
+'演著名' => '演著名',
+'演著書' => '演著書',
+'演著稱' => '演著稱',
+'演著者' => '演著者',
+'演著述' => '演著述',
+'演著錄' => '演著錄',
+'漠里' => '漠裏',
+'漢諾瓦' => '漢諾威',
+'漫著' => '漫着',
+'漫著作' => '漫著作',
+'漫著名' => '漫著名',
+'漫著書' => '漫著書',
+'漫著稱' => '漫著稱',
+'漫著者' => '漫著者',
+'漫著述' => '漫著述',
+'漫著錄' => '漫著錄',
+'潜意识里' => '潛意識裏',
+'潤著' => '潤着',
+'潤著作' => '潤著作',
+'潤著名' => '潤著名',
+'潤著書' => '潤著書',
+'潤著稱' => '潤著稱',
+'潤著者' => '潤著者',
+'潤著述' => '潤著述',
+'潤著錄' => '潤著錄',
+'潭里' => '潭裏',
+'溼' => '濕',
+'火山里' => '火山裏',
+'火箭布雷' => '火箭佈雷',
+'為著' => '為着',
+'為著《' => '為著《',
+'為著作' => '為著作',
+'為著名' => '為著名',
+'為著稱' => '為著稱',
+'為著者' => '為著者',
+'為著述' => '為著述',
+'為著錄' => '為著錄',
+'菸' => '煙',
+'照占' => '照佔',
+'照著' => '照着',
+'照著作' => '照著作',
+'照著名' => '照著名',
+'照著書' => '照著書',
+'照著稱' => '照著稱',
+'照著者' => '照著者',
+'照著述' => '照著述',
+'照著錄' => '照著錄',
+'燒著' => '燒着',
+'燒著作' => '燒著作',
+'燒著名' => '燒著名',
+'燒著書' => '燒著書',
+'燒著稱' => '燒著稱',
+'燒著者' => '燒著者',
+'燒著述' => '燒著述',
+'燒著錄' => '燒著錄',
+'爭著' => '爭着',
+'爭著作' => '爭著作',
+'爭著名' => '爭著名',
+'爭著書' => '爭著書',
+'爭著稱' => '爭著稱',
+'爭著者' => '爭著者',
+'爭著述' => '爭著述',
+'爭著錄' => '爭著錄',
+'墙里' => '牆裏',
+'版图里' => '版圖裏',
+'版权信息' => '版權資訊',
+'千里達托貝哥' => '特立尼達和多巴哥',
+'牽著' => '牽着',
+'牽著作' => '牽著作',
+'牽著名' => '牽著名',
+'牽著書' => '牽著書',
+'牽著稱' => '牽著稱',
+'牽著者' => '牽著者',
+'牽著述' => '牽著述',
+'牽著錄' => '牽著錄',
+'犯不著' => '犯不着',
+'犯不著作' => '犯不著作',
+'犯不著名' => '犯不著名',
+'犯不著書' => '犯不著書',
+'犯不著稱' => '犯不著稱',
+'犯不著者' => '犯不著者',
+'犯不著述' => '犯不著述',
+'犯不著錄' => '犯不著錄',
+'犯得著' => '犯得着',
+'狂占' => '狂佔',
+'猜著' => '猜着',
+'猜著作' => '猜著作',
+'猜著名' => '猜著名',
+'猜著書' => '猜著書',
+'猜著稱' => '猜著稱',
+'猜著者' => '猜著者',
+'猜著述' => '猜著述',
+'猜著錄' => '猜著錄',
+'猶豫著' => '猶豫着',
+'狱里' => '獄裏',
+'独占' => '獨佔',
+'獨占' => '獨佔',
+'獨立國家國協' => '獨立國家聯合體',
+'獨立國協' => '獨聯體',
+'獲著' => '獲着',
+'獲著作' => '獲著作',
+'獲著名' => '獲著名',
+'獲著書' => '獲著書',
+'獲著稱' => '獲著稱',
+'獲著者' => '獲著者',
+'獲著述' => '獲著述',
+'獲著錄' => '獲著錄',
+'班固著' => '班固著',
+'班里' => '班裏',
+'球台' => '球枱',
+'卢塞恩' => '琉森',
+'諾鲁' => '瑙魯',
+'萬那杜' => '瓦努阿圖',
+'肯尼迪' => '甘迺迪',
+'甜著' => '甜着',
+'甜著作' => '甜著作',
+'甜著名' => '甜著名',
+'甜著書' => '甜著書',
+'甜著稱' => '甜著稱',
+'甜著者' => '甜著者',
+'甜著述' => '甜著述',
+'甜著錄' => '甜著錄',
+'用不著' => '用不着',
+'用得著' => '用得着',
+'用法里' => '用法裏',
+'用著' => '用着',
+'用著作' => '用著作',
+'用著名' => '用著名',
+'用著書' => '用著書',
+'用著稱' => '用著稱',
+'用著者' => '用著者',
+'用著述' => '用著述',
+'用著錄' => '用著錄',
+'田里' => '田裏',
+'由表及里' => '由表及裏',
+'A型肝炎' => '甲型肝炎',
+'A肝' => '甲肝',
+'界里' => '界裏',
+'留著' => '留着',
+'留著作' => '留著作',
+'留著名' => '留著名',
+'留著書' => '留著書',
+'留著稱' => '留著稱',
+'留著者' => '留著者',
+'留著述' => '留著述',
+'留著錄' => '留著錄',
+'畫著' => '畫着',
+'畫著作' => '畫著作',
+'畫著名' => '畫著名',
+'畫著稱' => '畫著稱',
+'畫著者' => '畫著者',
+'當著' => '當着',
+'當著作' => '當著作',
+'過著作' => '當著作',
+'當著名' => '當著名',
+'過著名' => '當著名',
+'當著書' => '當著書',
+'過著書' => '當著書',
+'當著稱' => '當著稱',
+'過著稱' => '當著稱',
+'當著者' => '當著者',
+'過著者' => '當著者',
+'當著述' => '當著述',
+'過著述' => '當著述',
+'當著錄' => '當著錄',
+'過著錄' => '當著錄',
+'几内亚' => '畿內亞',
+'幾內亞' => '畿內亞',
+'迭代' => '疊代',
+'疑著' => '疑着',
+'疑著作' => '疑著作',
+'疑著名' => '疑著名',
+'疑著書' => '疑著書',
+'疑著稱' => '疑著稱',
+'疑著者' => '疑著者',
+'疑著述' => '疑著述',
+'疑著錄' => '疑著錄',
+'狂牛症' => '瘋牛症',
+'发布' => '發佈',
+'發布' => '發佈',
+'發著' => '發着',
+'發著《' => '發著《',
+'發著作' => '發著作',
+'發著名' => '發著名',
+'發著稱' => '發著稱',
+'發著者' => '發著者',
+'白里透红' => '白裏透紅',
+'戈登·布朗' => '白高敦',
+'百科里' => '百科裏',
+'的图里' => '的圖裏',
+'的山里' => '的山裏',
+'皮里春秋' => '皮裏春秋',
+'皮里阳秋' => '皮裏陽秋',
+'皺著' => '皺着',
+'皺著作' => '皺著作',
+'皺著名' => '皺著名',
+'皺著書' => '皺著書',
+'皺著稱' => '皺著稱',
+'皺著者' => '皺著者',
+'皺著述' => '皺著述',
+'皺著錄' => '皺著錄',
+'盒里' => '盒裏',
+'盛著' => '盛着',
+'盛著作' => '盛著作',
+'盛著名' => '盛著名',
+'盛著書' => '盛著書',
+'盛著稱' => '盛著稱',
+'盛著者' => '盛著者',
+'盛著述' => '盛著述',
+'盛著錄' => '盛著錄',
+'盘里' => '盤裏',
+'盧安達' => '盧旺達',
+'羅亞爾' => '盧瓦爾',
+'盯著' => '盯着',
+'盯著作' => '盯著作',
+'盯著名' => '盯著名',
+'盯著書' => '盯著書',
+'盯著稱' => '盯著稱',
+'盯著者' => '盯著者',
+'盯著述' => '盯著述',
+'盯著錄' => '盯著錄',
+'看不著' => '看不着',
+'看得著' => '看得着',
+'看法里' => '看法裏',
+'看著' => '看着',
+'看著作' => '看著作',
+'看著名' => '看著名',
+'看著書' => '看著書',
+'看著稱' => '看著稱',
+'看著者' => '看著者',
+'看著述' => '看著述',
+'看著錄' => '看著錄',
+'眼眶里' => '眼眶裏',
+'眼睛里' => '眼睛裏',
+'眼里' => '眼裏',
+'著什' => '着什',
+'著他' => '着他',
+'著你' => '着你',
+'著力' => '着力',
+'著地' => '着地',
+'著墨' => '着墨',
+'著她' => '着她',
+'著妳' => '着妳',
+'著它' => '着它',
+'著實' => '着實',
+'著忙' => '着忙',
+'著急' => '着急',
+'著想' => '着想',
+'著意' => '着意',
+'著我' => '着我',
+'著手' => '着手',
+'著數' => '着數',
+'著法' => '着法',
+'著涼' => '着涼',
+'著火' => '着火',
+'著甚麽' => '着甚麽',
+'著眼' => '着眼',
+'著祂' => '着祂',
+'著筆' => '着筆',
+'著絲' => '着絲',
+'著緊' => '着緊',
+'著腳' => '着腳',
+'著艦' => '着艦',
+'著色' => '着色',
+'著落' => '着落',
+'著衣' => '着衣',
+'著裝' => '着裝',
+'著迷' => '着迷',
+'著重' => '着重',
+'著錄' => '着錄',
+'著陸' => '着陸',
+'著鞭' => '着鞭',
+'睡不著' => '睡不着',
+'睡得著' => '睡得着',
+'睡著' => '睡着',
+'睡著作' => '睡著作',
+'睡著名' => '睡著名',
+'睡著書' => '睡著書',
+'睡著稱' => '睡著稱',
+'睡著者' => '睡著者',
+'睡著述' => '睡著述',
+'睡著錄' => '睡著錄',
+'瞞著' => '瞞着',
+'瞞著作' => '瞞著作',
+'瞞著名' => '瞞著名',
+'瞞著書' => '瞞著書',
+'瞞著稱' => '瞞著稱',
+'瞞著者' => '瞞著者',
+'瞞著述' => '瞞著述',
+'瞞著錄' => '瞞著錄',
+'瞪著' => '瞪着',
+'瞪著作' => '瞪著作',
+'瞪著名' => '瞪著名',
+'瞪著書' => '瞪著書',
+'瞪著稱' => '瞪著稱',
+'瞪著者' => '瞪著者',
+'瞪著述' => '瞪著述',
+'瞪著錄' => '瞪著錄',
+'矛盾著' => '矛盾着',
+'智慧財產權' => '知識產權',
+'智財權' => '知識產權',
+'短信' => '短訊',
+'簡訊' => '短訊',
+'什勒斯維希' => '石勒蘇益格',
+'硅' => '矽',
+'硅藻' => '硅藻',
+'硬件' => '硬件',
+'硬體' => '硬件',
+'碗里' => '碗裏',
+'貝克漢' => '碧咸',
+'贝克汉姆' => '碧咸',
+'社里' => '社裏',
+'福馬林' => '福爾馬林',
+'福著' => '福着',
+'福著作' => '福著作',
+'福著名' => '福著名',
+'福著書' => '福著書',
+'福著稱' => '福著稱',
+'福著者' => '福著者',
+'福著述' => '福著述',
+'福著錄' => '福著錄',
+'秀发布' => '秀發佈',
+'私下里' => '私下裏',
+'隐私' => '私隱',
+'隱私' => '私隱',
+'葛摩' => '科摩羅',
+'程序员' => '程式設計師',
+'捷豹' => '積架',
+'稳占' => '穩佔',
+'穩占' => '穩佔',
+'穫著' => '穫着',
+'空中布雷' => '空中佈雷',
+'空投布雷' => '空投佈雷',
+'空气质量' => '空氣質素',
+'空氣品質' => '空氣質素',
+'空著' => '空着',
+'空著作' => '空著作',
+'空著名' => '空著名',
+'空著書' => '空著書',
+'空著稱' => '空著稱',
+'空著者' => '空著者',
+'空著述' => '空著述',
+'空著錄' => '空著錄',
+'太空梭' => '穿梭機',
+'航天飞机' => '穿梭機',
+'穿著' => '穿着',
+'穿著作' => '穿著作',
+'穿著名' => '穿著名',
+'穿著書' => '穿著書',
+'穿著稱' => '穿著稱',
+'穿著者' => '穿著者',
+'穿著述' => '穿著述',
+'穿著錄' => '穿著錄',
+'窝里' => '窩裏',
+'窝里斗' => '窩裏鬥',
+'立著' => '立着',
+'立著《' => '立著《',
+'立著作' => '立著作',
+'立著名' => '立著名',
+'立著有' => '立著有',
+'立著称' => '立著稱',
+'立著稱' => '立著稱',
+'立著者' => '立著者',
+'立著(' => '立著(',
+'站著' => '站着',
+'站著作' => '站著作',
+'站著名' => '站著名',
+'站著書' => '站著書',
+'站著稱' => '站著稱',
+'站著者' => '站著者',
+'站著述' => '站著述',
+'站著錄' => '站著錄',
+'竪著' => '竪着',
+'笑著' => '笑着',
+'笑著作' => '笑著作',
+'笑著名' => '笑著名',
+'笑著書' => '笑著書',
+'笑著稱' => '笑著稱',
+'笑著者' => '笑著者',
+'笑著述' => '笑著述',
+'笑著錄' => '笑著錄',
+'笑里藏刀' => '笑裏藏刀',
+'提比里西' => '第比利斯',
+'管著' => '管着',
+'管著作' => '管著作',
+'管著名' => '管著名',
+'管著書' => '管著書',
+'管著稱' => '管著稱',
+'管著者' => '管著者',
+'管著述' => '管著述',
+'管著錄' => '管著錄',
+'箱里' => '箱裏',
+'节目里' => '節目裏',
+'簽著' => '簽着',
+'篮板球' => '籃板球',
+'籃板球' => '籃板球',
+'迈克尔' => '米高',
+'麦克尔' => '米高',
+'迈克尔·欧文' => '米高·奧雲',
+'糊里糊涂' => '糊裏糊塗',
+'系列里' => '系列裏',
+'係數' => '系數',
+'系里' => '系裏',
+'約占' => '約佔',
+'约占' => '約佔',
+'紐賓士域' => '紐賓士域',
+'索尔仁尼琴' => '索贊尼辛',
+'索忍尼辛' => '索贊尼辛',
+'索馬利亞' => '索馬里',
+'索馬利里' => '索馬里',
+'紮著' => '紮着',
+'紮著作' => '紮著作',
+'紮著名' => '紮著名',
+'紮著書' => '紮著書',
+'紮著稱' => '紮著稱',
+'紮著者' => '紮著者',
+'紮著述' => '紮著述',
+'紮著錄' => '紮著錄',
+'组里' => '組裏',
+'吉他' => '結他',
+'結彩' => '結綵',
+'结彩' => '結綵',
+'綁著' => '綁着',
+'綁著作' => '綁著作',
+'綁著名' => '綁著名',
+'綁著書' => '綁著書',
+'綁著稱' => '綁著稱',
+'綁著者' => '綁著者',
+'綁著述' => '綁著述',
+'綁著錄' => '綁著錄',
+'网站里' => '網站裏',
+'網路' => '網絡',
+'网里' => '網裏',
+'彩带' => '綵帶',
+'彩帶' => '綵帶',
+'彩排' => '綵排',
+'彩楼' => '綵樓',
+'彩樓' => '綵樓',
+'彩牌楼' => '綵牌樓',
+'彩牌樓' => '綵牌樓',
+'彩球' => '綵球',
+'彩綢' => '綵綢',
+'彩绸' => '綵綢',
+'彩线' => '綵綫',
+'彩線' => '綵線',
+'彩船' => '綵船',
+'彩衣' => '綵衣',
+'线图里' => '線圖裏',
+'緝凶' => '緝兇',
+'县里' => '縣裏',
+'缝里' => '縫裏',
+'縱著' => '縱着',
+'总数里' => '總數裏',
+'尖峰時段' => '繁忙時段',
+'尖峰時間' => '繁忙時間',
+'正體中文' => '繁體中文',
+'繃著' => '繃着',
+'繞著' => '繞着',
+'繞著作' => '繞著作',
+'繞著名' => '繞著名',
+'繞著書' => '繞著書',
+'繞著稱' => '繞著稱',
+'繞著者' => '繞著者',
+'繞著述' => '繞著述',
+'繞著錄' => '繞著錄',
+'系着' => '繫着',
+'繫著' => '繫着',
+'纏著' => '纏着',
+'纏著作' => '纏著作',
+'纏著名' => '纏著名',
+'纏著書' => '纏著書',
+'纏著稱' => '纏著稱',
+'纏著者' => '纏著者',
+'纏著述' => '纏著述',
+'纏著錄' => '纏著錄',
+'罩著' => '罩着',
+'罩著作' => '罩著作',
+'罩著名' => '罩著名',
+'罩著書' => '罩著書',
+'罩著稱' => '罩著稱',
+'罩著者' => '罩著者',
+'罩著述' => '罩著述',
+'罩著錄' => '罩著錄',
+'罵著' => '罵着',
+'罵著作' => '罵著作',
+'罵著名' => '罵著名',
+'罵著書' => '罵著書',
+'罵著稱' => '罵著稱',
+'罵著者' => '罵著者',
+'罵著述' => '罵著述',
+'罵著錄' => '罵著錄',
+'卢浮宫' => '羅浮宮',
+'美占' => '美佔',
+'美著' => '美着',
+'美著作' => '美著作',
+'美著名' => '美著名',
+'美著書' => '美著書',
+'美著称' => '美著稱',
+'美著稱' => '美著稱',
+'美著者' => '美著者',
+'美著述' => '美著述',
+'美著錄' => '美著錄',
+'耀著' => '耀着',
+'耀著作' => '耀著作',
+'耀著名' => '耀著名',
+'耀著書' => '耀著書',
+'耀著稱' => '耀著稱',
+'耀著者' => '耀著者',
+'耀著述' => '耀著述',
+'耀著錄' => '耀著錄',
+'寮國' => '老撾',
+'寮人民民主共和國' => '老撾人民民主共和國',
+'寮語' => '老撾語',
+'考著' => '考着',
+'考著作' => '考著作',
+'考著名' => '考著名',
+'考著書' => '考著書',
+'考著稱' => '考著稱',
+'考著者' => '考著者',
+'考著述' => '考著述',
+'考著錄' => '考著錄',
+'圣基茨和尼维斯' => '聖吉斯納域斯',
+'聖克里斯多福及尼維斯' => '聖吉斯納域斯',
+'聖文森及格瑞那丁' => '聖文森特和格林納丁斯',
+'聖露西亞' => '聖盧西亞',
+'聖馬利諾' => '聖馬力諾',
+'聽不著' => '聽不着',
+'聽得著' => '聽得着',
+'聽著' => '聽着',
+'聽著作' => '聽著作',
+'聽著名' => '聽著名',
+'聽著書' => '聽著書',
+'聽著稱' => '聽著稱',
+'聽著者' => '聽著者',
+'聽著述' => '聽著述',
+'聽著錄' => '聽著錄',
+'肚里' => '肚裏',
+'肯尼亚' => '肯雅',
+'胃里' => '胃裏',
+'背地里' => '背地裏',
+'背著' => '背着',
+'背著作' => '背著作',
+'背著名' => '背著名',
+'背著書' => '背著書',
+'背著稱' => '背著稱',
+'背著者' => '背著者',
+'背著述' => '背著述',
+'背著錄' => '背著錄',
+'胡里胡涂' => '胡裏胡塗',
+'腰里' => '腰裏',
+'膠著' => '膠着',
+'膠著作' => '膠著作',
+'膠著名' => '膠著名',
+'膠著書' => '膠著書',
+'膠著稱' => '膠著稱',
+'膠著者' => '膠著者',
+'膠著述' => '膠著述',
+'膠著錄' => '膠著錄',
+'塑料袋' => '膠袋',
+'臨著' => '臨着',
+'臨著作' => '臨著作',
+'臨著名' => '臨著名',
+'臨著書' => '臨著書',
+'臨著稱' => '臨著稱',
+'臨著者' => '臨著者',
+'臨著述' => '臨著述',
+'臨著錄' => '臨著錄',
+'自行火炮' => '自走炮',
+'與著' => '與着',
+'與著作' => '與著作',
+'與著名' => '與著名',
+'與著書' => '與著書',
+'與著稱' => '與著稱',
+'與著者' => '與著者',
+'與著述' => '與著述',
+'與著錄' => '與著錄',
+'舒马赫' => '舒麥加',
+'愛荷華' => '艾奧瓦',
+'爱荷华' => '艾奧瓦',
+'埃菲尔' => '艾菲爾',
+'帕塔亚' => '芭達亞',
+'花盆里' => '花盆裏',
+'苑里' => '苑裏',
+'苑裡' => '苑裡',
+'苦著' => '苦着',
+'苦著作' => '苦著作',
+'苦著名' => '苦著名',
+'苦著書' => '苦著書',
+'苦著稱' => '苦著稱',
+'苦著者' => '苦著者',
+'苦著述' => '苦著述',
+'苦著錄' => '苦著錄',
+'苦里' => '苦裏',
+'英占' => '英佔',
+'共和联邦' => '英聯邦',
+'大英國協' => '英聯邦',
+'草丛里' => '草叢裏',
+'霍爾斯坦' => '荷爾斯泰因',
+'好莱坞' => '荷里活',
+'好萊塢' => '荷里活',
+'庄里' => '莊裏',
+'莫三比克' => '莫桑比克',
+'巴伦西亚' => '華倫西亞',
+'巴倫西亞' => '華倫西亞',
+'瓦倫西亞' => '華倫西亞',
+'瓦文萨' => '華里沙',
+'華勒沙' => '華里沙',
+'菲利普亲王' => '菲臘親王',
+'菲利普親王' => '菲臘親王',
+'賴索托' => '萊索托',
+'马恩岛' => '萌島',
+'馬自達' => '萬事得',
+'马自达' => '萬事得',
+'万历朝鲜战争' => '萬曆朝鮮戰爭',
+'落著' => '落着',
+'落著作' => '落著作',
+'落著名' => '落著名',
+'落著書' => '落著書',
+'落著稱' => '落著稱',
+'落著者' => '落著者',
+'落著述' => '落著述',
+'落著錄' => '落著錄',
+'葉爾欽' => '葉利欽',
+'葡占' => '葡佔',
+'葫芦里卖甚么药' => '葫蘆裏賣甚麼藥',
+'滿地可' => '蒙特利爾',
+'蒙特婁' => '蒙特利爾',
+'蒙著' => '蒙着',
+'蒙著作' => '蒙著作',
+'蒙著名' => '蒙著名',
+'蒙著書' => '蒙著書',
+'蒙著稱' => '蒙著稱',
+'蒙著者' => '蒙著者',
+'蒙著述' => '蒙著述',
+'蒙著錄' => '蒙著錄',
+'蓋著' => '蓋着',
+'蓋著作' => '蓋著作',
+'蓋著名' => '蓋著名',
+'蓋著稱' => '蓋著稱',
+'肖斯塔科维奇' => '蕭士達高維契',
+'蕭士塔高維奇' => '蕭士達高維契',
+'肖邦' => '蕭邦',
+'薛丁格' => '薛定諤',
+'塞拉耶佛' => '薩拉熱窩',
+'萨达姆' => '薩達姆',
+'藉著' => '藉着',
+'藏著' => '藏着',
+'藏著作' => '藏著作',
+'藏著名' => '藏著名',
+'藏著書' => '藏著書',
+'藏著稱' => '藏著稱',
+'藏著者' => '藏著者',
+'藏著述' => '藏著述',
+'藏著錄' => '藏著錄',
+'蘊涵著' => '蘊涵着',
+'蘸著' => '蘸着',
+'蘸著作' => '蘸著作',
+'蘸著名' => '蘸著名',
+'蘸著書' => '蘸著書',
+'蘸著稱' => '蘸著稱',
+'蘸著者' => '蘸著者',
+'蘸著述' => '蘸著述',
+'蘸著錄' => '蘸著錄',
+'蜜里调油' => '蜜裏調油',
+'荧屏' => '螢屏',
+'屏幕' => '螢幕',
+'人行道' => '行人路',
+'行家里手' => '行家裏手',
+'首席执行官' => '行政總裁',
+'行著' => '行着',
+'行著作' => '行著作',
+'行著名' => '行著名',
+'行著書' => '行著書',
+'行著稱' => '行著稱',
+'行著者' => '行著者',
+'行著述' => '行著述',
+'行著錄' => '行著錄',
+'衝著' => '衝着',
+'衣著' => '衣着',
+'衣著作' => '衣著作',
+'衣著名' => '衣著名',
+'衣著書' => '衣著書',
+'衣著稱' => '衣著稱',
+'衣著者' => '衣著者',
+'衣著述' => '衣著述',
+'衣著錄' => '衣著錄',
+'表里' => '表裏',
+'表里一致' => '表裏一致',
+'表里不一' => '表裏不一',
+'表里如一' => '表裏如一',
+'表里山河' => '表裏山河',
+'袋里' => '袋裏',
+'袖里' => '袖裏',
+'被里' => '被裏',
+'裡' => '裏',
+'里勾外连' => '裏勾外連',
+'里屋' => '裏屋',
+'里层' => '裏層',
+'里带' => '裏帶',
+'里弦' => '裏弦',
+'里应外合' => '裏應外合',
+'里海' => '裏海',
+'里脊' => '裏脊',
+'里衣' => '裏衣',
+'里通外国' => '裏通外國',
+'里通外敌' => '裏通外敵',
+'里边' => '裏邊',
+'里间' => '裏間',
+'里面' => '裏面',
+'里头' => '裏頭',
+'裝著' => '裝着',
+'裝著作' => '裝著作',
+'裝著名' => '裝著名',
+'裝著書' => '裝著書',
+'裝著稱' => '裝著稱',
+'裝著者' => '裝著者',
+'裝著述' => '裝著述',
+'裝著錄' => '裝著錄',
+'裡冷' => '裡冷',
+'裹著' => '裹着',
+'裹著作' => '裹著作',
+'裹著名' => '裹著名',
+'裹著書' => '裹著書',
+'裹著稱' => '裹著稱',
+'裹著者' => '裹著者',
+'裹著述' => '裹著述',
+'裹著錄' => '裹著錄',
+'衬里' => '襯裏',
+'西占' => '西佔',
+'塞維亞' => '西維爾',
+'塞维利亚' => '西維爾',
+'要占' => '要佔',
+'要占卜' => '要占卜',
+'覆著' => '覆着',
+'覆蓋著' => '覆蓋着',
+'見著' => '見着',
+'見著作' => '見著作',
+'見著名' => '見著名',
+'見著書' => '見著書',
+'見著稱' => '見著稱',
+'見著者' => '見著者',
+'見著述' => '見著述',
+'見著錄' => '見著錄',
+'視著' => '視着',
+'視著名' => '視著名',
+'角落里' => '角落裏',
+'分辨率' => '解像度',
+'解析度' => '解像度',
+'言里' => '言裏',
+'計畫' => '計劃',
+'記著' => '記着',
+'記著作' => '記著作',
+'記著名' => '記著名',
+'記著書' => '記著書',
+'記著稱' => '記著稱',
+'記著者' => '記著者',
+'記著述' => '記著述',
+'記著錄' => '記著錄',
+'試著' => '試着',
+'試著作' => '試著作',
+'試著名' => '試著名',
+'試著書' => '試著書',
+'試著稱' => '試著稱',
+'試著者' => '試著者',
+'試著述' => '試著述',
+'試著錄' => '試著錄',
+'话里有话' => '話裏有話',
+'语法里' => '語法裏',
+'語著' => '語着',
+'語著作' => '語著作',
+'語著名' => '語著名',
+'語著書' => '語著書',
+'語著稱' => '語著稱',
+'語著者' => '語著者',
+'語著述' => '語著述',
+'語著錄' => '語著錄',
+'语里' => '語裏',
+'說著' => '說着',
+'說著作' => '說著作',
+'說著稱' => '說著稱',
+'說著者' => '說著者',
+'說著述' => '說著述',
+'數據機' => '調制解調器',
+'诺曼底' => '諾曼第',
+'警戒著' => '警戒着',
+'變著' => '變着',
+'變著作' => '變著作',
+'變著名' => '變著名',
+'變著書' => '變著書',
+'變著稱' => '變著稱',
+'變著者' => '變著者',
+'變著述' => '變著述',
+'變著錄' => '變著錄',
+'豎著' => '豎着',
+'豎著作' => '豎著作',
+'豎著名' => '豎著名',
+'豎著書' => '豎著書',
+'豎著稱' => '豎著稱',
+'豎著者' => '豎著者',
+'豎著述' => '豎著述',
+'豎著錄' => '豎著錄',
+'象徵著名' => '象徵著名',
+'象徵著' => '象著着',
+'貝爾格勒' => '貝爾格萊德',
+'布莱尔' => '貝理雅',
+'負著' => '負着',
+'貢寮' => '貢寮',
+'買凶' => '買兇',
+'費占' => '費佔',
+'费占' => '費佔',
+'信息时代' => '資訊時代',
+'赌台' => '賭枱',
+'尚比亞' => '贊比亞',
+'西臺人' => '赫梯人',
+'西臺國' => '赫梯國',
+'西臺帝' => '赫梯帝',
+'西臺文' => '赫梯文',
+'西臺族' => '赫梯族',
+'西臺王' => '赫梯王',
+'西臺語' => '赫梯語',
+'赫魯雪夫' => '赫魯曉夫',
+'走為上著' => '走為上着',
+'走著' => '走着',
+'走著作' => '走著作',
+'走著名' => '走著名',
+'走著書' => '走著書',
+'走著稱' => '走著稱',
+'走著者' => '走著者',
+'走著述' => '走著述',
+'走著錄' => '走著錄',
+'趕著' => '趕着',
+'趕著作' => '趕著作',
+'趕著名' => '趕著名',
+'趕著書' => '趕著書',
+'趕著稱' => '趕著稱',
+'趕著者' => '趕著者',
+'趕著述' => '趕著述',
+'趕著錄' => '趕著錄',
+'趴著' => '趴着',
+'趴著作' => '趴著作',
+'趴著名' => '趴著名',
+'趴著書' => '趴著書',
+'趴著稱' => '趴著稱',
+'趴著者' => '趴著者',
+'趴著述' => '趴著述',
+'趴著錄' => '趴著錄',
+'跑著' => '跑着',
+'跑著作' => '跑著作',
+'跑著名' => '跑著名',
+'跑著書' => '跑著書',
+'跑著稱' => '跑著稱',
+'跑著者' => '跑著者',
+'跑著述' => '跑著述',
+'跑著錄' => '跑著錄',
+'跟著' => '跟着',
+'跟著作' => '跟著作',
+'跟著名' => '跟著名',
+'跟著書' => '跟著書',
+'跟著稱' => '跟著稱',
+'跟著者' => '跟著者',
+'跟著述' => '跟著述',
+'跟著錄' => '跟著錄',
+'跪著' => '跪着',
+'跪著作' => '跪著作',
+'跪著名' => '跪著名',
+'跪著書' => '跪著書',
+'跪著稱' => '跪著稱',
+'跪著者' => '跪著者',
+'跪著述' => '跪著述',
+'跪著錄' => '跪著錄',
+'路图里' => '路圖裏',
+'跳著' => '跳着',
+'跳著作' => '跳著作',
+'跳著名' => '跳著名',
+'跳著書' => '跳著書',
+'跳著稱' => '跳著稱',
+'跳著者' => '跳著者',
+'跳著述' => '跳著述',
+'跳著錄' => '跳著錄',
+'踏著' => '踏着',
+'踏著作' => '踏著作',
+'踏著名' => '踏著名',
+'踏著稱' => '踏著稱',
+'踏著者' => '踏著者',
+'踏著述' => '踏著述',
+'踏著錄' => '踏著錄',
+'踩著' => '踩着',
+'踩著作' => '踩著作',
+'踩著名' => '踩著名',
+'踩著書' => '踩著書',
+'踩著稱' => '踩著稱',
+'踩著者' => '踩著者',
+'踩著述' => '踩著述',
+'踩著錄' => '踩著錄',
+'躍著' => '躍着',
+'躍著作' => '躍著作',
+'躍著名' => '躍著名',
+'躍著書' => '躍著書',
+'躍著稱' => '躍著稱',
+'躍著者' => '躍著者',
+'躍著述' => '躍著述',
+'躍著錄' => '躍著錄',
+'身著' => '身着',
+'身著作' => '身著作',
+'身著名' => '身著名',
+'身著書' => '身著書',
+'身著稱' => '身著稱',
+'身著者' => '身著者',
+'身著述' => '身著述',
+'身著錄' => '身著錄',
+'躺著' => '躺着',
+'躺著作' => '躺著作',
+'躺著名' => '躺著名',
+'躺著書' => '躺著書',
+'躺著稱' => '躺著稱',
+'躺著者' => '躺著者',
+'躺著述' => '躺著述',
+'躺著錄' => '躺著錄',
+'车库里' => '車庫裏',
+'车站里' => '車站裏',
+'车里' => '車裏',
+'车里雅宾斯克' => '車里雅賓斯克',
+'軟體' => '軟件',
+'軟體動物' => '軟體動物',
+'軟體家具' => '軟體家具',
+'載著' => '載着',
+'載著作' => '載著作',
+'載著名' => '載著名',
+'載著書' => '載著書',
+'載著稱' => '載著稱',
+'載著者' => '載著者',
+'載著述' => '載著述',
+'載著錄' => '載著錄',
+'轉著' => '轉着',
+'轉著作' => '轉著作',
+'轉著名' => '轉著名',
+'轉著書' => '轉著書',
+'轉著稱' => '轉著稱',
+'轉著者' => '轉著者',
+'轉著述' => '轉著述',
+'轉著錄' => '轉著錄',
+'办公台' => '辦公枱',
+'辦著' => '辦着',
+'辦著作' => '辦著作',
+'辦著名' => '辦著名',
+'辦著書' => '辦著書',
+'辦著稱' => '辦著稱',
+'辦著者' => '辦著者',
+'辦著述' => '辦著述',
+'辦著錄' => '辦著錄',
+'迫著' => '迫着',
+'追著' => '追着',
+'追著作' => '追著作',
+'追著名' => '追著名',
+'追著書' => '追著書',
+'追著稱' => '追著稱',
+'追著者' => '追著者',
+'追著述' => '追著述',
+'追著錄' => '追著錄',
+'逆著' => '逆着',
+'逆著作' => '逆著作',
+'逆著名' => '逆著名',
+'逆著書' => '逆著書',
+'逆著稱' => '逆著稱',
+'逆著者' => '逆著者',
+'逆著述' => '逆著述',
+'逆著錄' => '逆著錄',
+'径入' => '逕入',
+'径到' => '逕到',
+'径取' => '逕取',
+'径启' => '逕啟',
+'径寄' => '逕寄',
+'径庭' => '逕庭',
+'径往' => '逕往',
+'径自' => '逕自',
+'径行' => '逕行',
+'径迎' => '逕迎',
+'这里' => '這裏',
+'连占' => '連佔',
+'連占' => '連佔',
+'連著' => '連着',
+'链接' => '連結',
+'連著作' => '連著作',
+'連著名' => '連著名',
+'連著書' => '連著書',
+'連著稱' => '連著稱',
+'連著者' => '連著者',
+'連著述' => '連著述',
+'連著錄' => '連著錄',
+'进占' => '進佔',
+'進占' => '進佔',
+'演化論' => '進化論',
+'逼著' => '逼着',
+'逼著作' => '逼著作',
+'逼著名' => '逼著名',
+'逼著書' => '逼著書',
+'逼著稱' => '逼著稱',
+'逼著者' => '逼著者',
+'逼著述' => '逼著述',
+'逼著錄' => '逼著錄',
+'遇著' => '遇着',
+'遇著作' => '遇著作',
+'遇著名' => '遇著名',
+'遇著書' => '遇著書',
+'遇著称' => '遇著稱',
+'遇著稱' => '遇著稱',
+'遇著者' => '遇著者',
+'遇著述' => '遇著述',
+'遇著錄' => '遇著錄',
+'游戏里' => '遊戲裏',
+'遍布' => '遍佈',
+'遍佈著' => '遍佈着',
+'遍布著' => '遍佈着',
+'過著' => '過着',
+'达·芬奇' => '達·文西',
+'达芬奇' => '達文西',
+'達著' => '達着',
+'達著作' => '達著作',
+'達著名' => '達著名',
+'達著書' => '達著書',
+'達著稱' => '達著稱',
+'達著者' => '達著者',
+'達著述' => '達著述',
+'達著錄' => '達著錄',
+'还占' => '還佔',
+'還占' => '還佔',
+'邋里邋遢' => '邋裏邋遢',
+'那里' => '那裏',
+'都市里' => '都市裏',
+'配合著' => '配合着',
+'配合著名' => '配合著名',
+'配图里' => '配圖裏',
+'配著' => '配着',
+'配著作' => '配著作',
+'配著名' => '配著名',
+'配著書' => '配著書',
+'配著稱' => '配著稱',
+'配著者' => '配著者',
+'配著述' => '配著述',
+'配著錄' => '配著錄',
+'醯' => '酰',
+'醜著' => '醜着',
+'醜著作' => '醜著作',
+'醜著名' => '醜著名',
+'醜著書' => '醜著書',
+'醜著稱' => '醜著稱',
+'醜著者' => '醜著者',
+'醜著述' => '醜著述',
+'醜著錄' => '醜著錄',
+'醯壶' => '醯壺',
+'醯壺' => '醯壺',
+'醯醋' => '醯醋',
+'醯醢' => '醯醢',
+'醯酱' => '醯醬',
+'醯醬' => '醯醬',
+'醯雞' => '醯雞',
+'醯鸡' => '醯雞',
+'釀著' => '釀着',
+'釀著作' => '釀著作',
+'釀著名' => '釀著名',
+'釀著書' => '釀著書',
+'釀著稱' => '釀著稱',
+'釀著者' => '釀著者',
+'釀著述' => '釀著述',
+'釀著錄' => '釀著錄',
+'金装玉里' => '金裝玉裏',
+'鉤' => '鈎',
+'鋪著' => '鋪着',
+'鋪著作' => '鋪著作',
+'鋪著名' => '鋪著名',
+'鋪著書' => '鋪著書',
+'鋪著稱' => '鋪著稱',
+'鋪著者' => '鋪著者',
+'鋪著述' => '鋪著述',
+'鋪著錄' => '鋪著錄',
+'镜图里' => '鏡圖裏',
+'钟在寺里' => '鐘在寺裏',
+'狄托' => '鐵托',
+'泰坦尼克号' => '鐵達尼號',
+'门里' => '門裏',
+'閉著' => '閉着',
+'閉著作' => '閉著作',
+'閉著名' => '閉著名',
+'閉著書' => '閉著書',
+'閉著稱' => '閉著稱',
+'閉著者' => '閉著者',
+'閉著述' => '閉著述',
+'閉著錄' => '閉著錄',
+'克卜勒' => '開普勒',
+'開著' => '開着',
+'開著作' => '開著作',
+'開著名' => '開著名',
+'開著書' => '開著書',
+'開著稱' => '開著稱',
+'開著者' => '開著者',
+'開著述' => '開著述',
+'開著錄' => '開著錄',
+'开诚布公' => '開誠佈公',
+'開誠布公' => '開誠佈公',
+'閑著' => '閑着',
+'閑著作' => '閑著作',
+'閑著名' => '閑著名',
+'閑著書' => '閑著書',
+'閑著稱' => '閑著稱',
+'閑著者' => '閑著者',
+'閑著述' => '閑著述',
+'閑著錄' => '閑著錄',
+'閒著' => '閒着',
+'间里' => '間裏',
+'關係著' => '關係着',
+'關著' => '關着',
+'關著作' => '關著作',
+'關著名' => '關著名',
+'關著書' => '關著書',
+'關著稱' => '關著稱',
+'關著者' => '關著者',
+'關著述' => '關著述',
+'關著錄' => '關著錄',
+'聞不著' => '闻不着',
+'聞得著' => '闻得着',
+'聞著' => '闻着',
+'亞塞拜然' => '阿塞拜疆',
+'阿布達比' => '阿布扎比',
+'阿拉伯聯合大公國' => '阿拉伯聯合酋長國',
+'亞斯文' => '阿斯旺',
+'阿联酋' => '阿聯酋',
+'艾里爾·夏隆' => '阿里埃勒·沙龍',
+'附著' => '附着',
+'附著作' => '附著作',
+'附著名' => '附著名',
+'附著書' => '附著書',
+'附著稱' => '附著稱',
+'附著者' => '附著者',
+'附著述' => '附著述',
+'附著錄' => '附著錄',
+'陋著' => '陋着',
+'陋著作' => '陋著作',
+'陋著名' => '陋著名',
+'陋著書' => '陋著書',
+'陋著稱' => '陋著稱',
+'陋著者' => '陋著者',
+'陋著述' => '陋著述',
+'陋著錄' => '陋著錄',
+'院里' => '院裏',
+'陪著' => '陪着',
+'陪著作' => '陪著作',
+'陪著名' => '陪著名',
+'陪著書' => '陪著書',
+'陪著稱' => '陪著稱',
+'陪著者' => '陪著者',
+'陪著述' => '陪著述',
+'陪著錄' => '陪著錄',
+'阴沟里翻船' => '陰溝裏翻船',
+'隔著' => '隔着',
+'隔著作' => '隔著作',
+'隔著名' => '隔著名',
+'隔著書' => '隔著書',
+'隔著稱' => '隔著稱',
+'隔著者' => '隔著者',
+'隔著述' => '隔著述',
+'隔著錄' => '隔著錄',
+'隨著' => '隨着',
+'隨著作' => '隨著作',
+'隨著名' => '隨著名',
+'隨著書' => '隨著書',
+'隨著稱' => '隨著稱',
+'隨著者' => '隨著者',
+'隨著述' => '隨著述',
+'隨著錄' => '隨著錄',
+'隐占' => '隱佔',
+'隱占' => '隱佔',
+'雅爾達' => '雅爾塔',
+'雅著' => '雅着',
+'雅穆索戈' => '雅穆蘇克雷',
+'雅著作' => '雅著作',
+'雅著名' => '雅著名',
+'雅著書' => '雅著書',
+'雅著称' => '雅著稱',
+'雅著稱' => '雅著稱',
+'雅著者' => '雅著者',
+'雅著述' => '雅著述',
+'雅著錄' => '雅著錄',
+'集数里' => '集數裏',
+'集里' => '集裏',
+'雜著' => '雜着',
+'雜著作' => '雜著作',
+'雜著名' => '雜著名',
+'雜著書' => '雜著書',
+'雜著稱' => '雜著稱',
+'雜著者' => '雜著者',
+'雜著述' => '雜著述',
+'雜著錄' => '雜著錄',
+'鸡蛋里挑骨头' => '雞蛋裏挑骨頭',
+'冰淇淋' => '雪糕',
+'冰激凌' => '雪糕',
+'雪里' => '雪裏',
+'云里雾里' => '雲裏霧裏',
+'莱特湾' => '雷伊泰灣',
+'萊特灣' => '雷伊泰灣',
+'电影里' => '電影裏',
+'晶体管' => '電晶體',
+'晶體管' => '電晶體',
+'电梯里' => '電梯裏',
+'电脑程序' => '電腦程式',
+'计算机程序' => '電腦程式',
+'电视里' => '電視裏',
+'霄裡' => '霄裡',
+'荷姆茲' => '霍爾木茲',
+'雾里' => '霧裏',
+'霸占' => '霸佔',
+'非占不可' => '非佔不可',
+'靠著' => '靠着',
+'靠著作' => '靠著作',
+'靠著名' => '靠著名',
+'靠著称' => '靠著稱',
+'靠著稱' => '靠著稱',
+'靠著者' => '靠著者',
+'靠著述' => '靠著述',
+'靠著录' => '靠著錄',
+'靠著錄' => '靠著錄',
+'面包著' => '面包着',
+'鞋里' => '鞋裏',
+'鞭辟入里' => '鞭辟入裏',
+'朝鲜战争' => '韓戰',
+'響著' => '響着',
+'響著作' => '響著作',
+'響著名' => '響著名',
+'響著書' => '響著書',
+'響著稱' => '響著稱',
+'響著者' => '響著者',
+'響著述' => '響著述',
+'響著錄' => '響著錄',
+'頂著' => '頂着',
+'頂著作' => '頂著作',
+'頂著名' => '頂著名',
+'頂著書' => '頂著書',
+'頂著稱' => '頂著稱',
+'頂著者' => '頂著者',
+'頂著述' => '頂著述',
+'頂著錄' => '頂著錄',
+'順著' => '順着',
+'順著作' => '順著作',
+'順著名' => '順著名',
+'順著書' => '順著書',
+'順著稱' => '順著稱',
+'順著者' => '順著者',
+'順著述' => '順著述',
+'順著錄' => '順著錄',
+'頒布' => '頒佈',
+'颁布' => '頒佈',
+'領著' => '領着',
+'領著作' => '領著作',
+'領著名' => '領著名',
+'領著書' => '領著書',
+'領著稱' => '領著稱',
+'領著者' => '領著者',
+'領著述' => '領著述',
+'領著錄' => '領著錄',
+'头里' => '頭裏',
+'风里' => '風裏',
+'颳著' => '颳着',
+'飃著' => '飃着',
+'飄著' => '飄着',
+'飄著作' => '飄著作',
+'飄著名' => '飄著名',
+'飄著書' => '飄著書',
+'飄著稱' => '飄著稱',
+'飄著者' => '飄著者',
+'飄著述' => '飄著述',
+'飄著錄' => '飄著錄',
+'餐台' => '餐枱',
+'馆里' => '館裏',
+'糊口' => '餬口',
+'馬里蘭' => '馬利蘭',
+'马里兰' => '馬利蘭',
+'马拉特·萨芬' => '馬拉特·沙芬',
+'馬斯垂克' => '馬斯特里赫特',
+'馬爾地夫' => '馬爾代夫',
+'馬利共和國' => '馬里共和國',
+'駕著' => '駕着',
+'駕著作' => '駕著作',
+'駕著名' => '駕著名',
+'駕著書' => '駕著書',
+'駕著稱' => '駕著稱',
+'駕著者' => '駕著者',
+'駕著述' => '駕著述',
+'駕著錄' => '駕著錄',
+'騎著' => '騎着',
+'騎著作' => '騎著作',
+'騎著名' => '騎著名',
+'騎著書' => '騎著書',
+'騎著稱' => '騎著稱',
+'騎著者' => '騎著者',
+'騎著述' => '騎著述',
+'騎著錄' => '騎著錄',
+'騙著' => '騙着',
+'騙著作' => '騙著作',
+'騙著名' => '騙著名',
+'騙著書' => '騙著書',
+'騙著稱' => '騙著稱',
+'騙著者' => '騙著者',
+'騙著述' => '騙著述',
+'騙著錄' => '騙著錄',
+'驶著' => '驶着',
+'体里' => '體裏',
+'高畫質' => '高清',
+'高著' => '高着',
+'高著作' => '高著作',
+'高著名' => '高著名',
+'高著書' => '高著書',
+'高著称' => '高著稱',
+'高著稱' => '高著稱',
+'高著者' => '高著者',
+'高著述' => '高著述',
+'高著錄' => '高著錄',
+'斗着' => '鬥着',
+'鬥著' => '鬥着',
+'鬥著作' => '鬥著作',
+'鬥著名' => '鬥著名',
+'鬥著書' => '鬥著書',
+'鬥著稱' => '鬥著稱',
+'鬥著者' => '鬥著者',
+'鬥著述' => '鬥著述',
+'鬥著錄' => '鬥著錄',
+'鬧著' => '鬧着',
+'牛軋' => '鳥結',
+'牛轧' => '鳥結',
+'鳩占' => '鳩佔',
+'鸠占' => '鳩佔',
+'麗著' => '麗着',
+'麗著作' => '麗著作',
+'麗著名' => '麗著名',
+'麗著書' => '麗著書',
+'麗著稱' => '麗著稱',
+'麗著者' => '麗著者',
+'麗著述' => '麗著述',
+'麗著錄' => '麗著錄',
+'麼著' => '麼着',
+'芮氏0' => '黎克特制0',
+'里氏0' => '黎克特制0',
+'芮氏1' => '黎克特制1',
+'里氏1' => '黎克特制1',
+'芮氏2' => '黎克特制2',
+'里氏2' => '黎克特制2',
+'芮氏3' => '黎克特制3',
+'里氏3' => '黎克特制3',
+'芮氏4' => '黎克特制4',
+'里氏4' => '黎克特制4',
+'芮氏5' => '黎克特制5',
+'里氏5' => '黎克特制5',
+'芮氏6' => '黎克特制6',
+'里氏6' => '黎克特制6',
+'芮氏7' => '黎克特制7',
+'里氏7' => '黎克特制7',
+'芮氏8' => '黎克特制8',
+'里氏8' => '黎克特制8',
+'芮氏9' => '黎克特制9',
+'里氏9' => '黎克特制9',
+'芮氏地震規模' => '黎克特制地震震級',
+'里氏地震规模' => '黎克特制地震震級',
+'芮氏規模' => '黎克特制震級',
+'里氏规模' => '黎克特制震級',
+'里氏震级' => '黎克特制震級',
+'黏著' => '黏着',
+'黏著作' => '黏著作',
+'黏著名' => '黏著名',
+'黏著書' => '黏著書',
+'黏著稱' => '黏著稱',
+'黏著者' => '黏著者',
+'黏著述' => '黏著述',
+'黏著錄' => '黏著錄',
+'蒙特內哥羅' => '黑山',
+'點著' => '點着',
+'點著作' => '點著作',
+'點著名' => '點著名',
+'點著書' => '點著書',
+'點著稱' => '點著稱',
+'點著者' => '點著者',
+'點著述' => '點著述',
+'點著錄' => '點著錄',
+'点里' => '點裏',
+'点里程' => '點里程',
+'鼓里' => '鼓裏',
+);
+
+public static $zh2CN = array(
+'16進位制' => '16进位制',
+'16進位' => '16进制',
+'IP位址' => 'IP地址',
+'一份子' => '一分子',
+'全球資訊網' => '万维网',
+'三十六著' => '三十六着',
+'三極體' => '三极管',
+'下著' => '下着',
+'下著作' => '下著作',
+'下著名' => '下著名',
+'下著录' => '下著录',
+'下著錄' => '下著录',
+'下著有' => '下著有',
+'下著称' => '下著称',
+'下著稱' => '下著称',
+'下著者' => '下著者',
+'下著述' => '下著述',
+'不著' => '不着',
+'不著書' => '不著书',
+'不著名' => '不著名',
+'不著錄' => '不著录',
+'不著稱' => '不著称',
+'不著述' => '不著述',
+'與著' => '与着',
+'與著書' => '与著书',
+'與著作' => '与著作',
+'與著名' => '与著名',
+'與著錄' => '与著录',
+'與著稱' => '与著称',
+'與著者' => '与著者',
+'與著述' => '与著述',
+'醜著' => '丑着',
+'醜著書' => '丑著书',
+'醜著作' => '丑著作',
+'醜著名' => '丑著名',
+'醜著錄' => '丑著录',
+'醜著稱' => '丑著称',
+'醜著者' => '丑著者',
+'醜著述' => '丑著述',
+'邱吉爾' => '丘吉尔',
+'C型肝炎' => '丙型肝炎',
+'C肝' => '丙肝',
+'東協會' => '东协会',
+'東協助' => '东协助',
+'東協議' => '东协议',
+'東南亞國家協會' => '东南亚国家联盟',
+'亚细安' => '东盟',
+'東協' => '东盟',
+'仲介' => '中介',
+'臨著' => '临着',
+'臨著書' => '临著书',
+'臨著作' => '临著作',
+'臨著名' => '临著名',
+'臨著錄' => '临著录',
+'臨著稱' => '临著称',
+'臨著者' => '临著者',
+'臨著述' => '临著述',
+'為著' => '为着',
+'為著《' => '为著《',
+'為著作' => '为著作',
+'為著名' => '为著名',
+'為著錄' => '为著录',
+'為著稱' => '为著称',
+'為著者' => '为著者',
+'為著述' => '为著述',
+'主機板' => '主板',
+'麗著' => '丽着',
+'麗著書' => '丽著书',
+'麗著作' => '丽著作',
+'麗著名' => '丽著名',
+'麗著錄' => '丽著录',
+'麗著稱' => '丽著称',
+'麗著者' => '丽著者',
+'麗著述' => '丽著述',
+'麼著' => '么着',
+'樂著' => '乐着',
+'樂著書' => '乐著书',
+'樂著作' => '乐著作',
+'樂著名' => '乐著名',
+'樂著錄' => '乐著录',
+'樂著稱' => '乐著称',
+'樂著者' => '乐著者',
+'樂著述' => '乐著述',
+'賈伯斯' => '乔布斯',
+'喬治·歐威爾' => '乔治·奥威尔',
+'乘著' => '乘着',
+'乘著書' => '乘著书',
+'乘著作' => '乘著作',
+'乘著名' => '乘著名',
+'乘著錄' => '乘著录',
+'乘著称' => '乘著称',
+'乘著稱' => '乘著称',
+'乘著者' => '乘著者',
+'乘著述' => '乘著述',
+'B型肝炎' => '乙型肝炎',
+'B肝' => '乙肝',
+'吉力馬札羅' => '乞力马扎罗',
+'葉門' => '也门',
+'買帳' => '买账',
+'了結他' => '了结他',
+'爭著' => '争着',
+'爭著書' => '争著书',
+'爭著作' => '争著作',
+'爭著名' => '争著名',
+'爭著錄' => '争著录',
+'爭著稱' => '争著称',
+'爭著者' => '争著者',
+'爭著述' => '争著述',
+'二極體' => '二极管',
+'二進位制' => '二进位制',
+'二進位' => '二进制',
+'網際網絡' => '互联网',
+'網際網路' => '互联网',
+'亞歷山卓' => '亚历山大',
+'雅穆索戈' => '亚穆苏克罗',
+'交帳' => '交账',
+'亮著' => '亮着',
+'亮著書' => '亮著书',
+'亮著作' => '亮著作',
+'亮著名' => '亮著名',
+'亮著錄' => '亮著录',
+'亮著称' => '亮著称',
+'亮著稱' => '亮著称',
+'亮著者' => '亮著者',
+'亮著述' => '亮著述',
+'人工智慧' => '人工智能',
+'行人路' => '人行道',
+'甚麼' => '什么',
+'甚麽' => '什么',
+'仗著' => '仗着',
+'仗著書' => '仗著书',
+'仗著作' => '仗著作',
+'仗著名' => '仗著名',
+'仗著錄' => '仗著录',
+'仗著稱' => '仗著称',
+'仗著者' => '仗著者',
+'仗著述' => '仗著述',
+'付帳' => '付账',
+'代表著' => '代表着',
+'代表著書' => '代表著书',
+'代表著作' => '代表著作',
+'代表著名' => '代表著名',
+'代表著錄' => '代表著录',
+'代表著稱' => '代表著称',
+'代表著者' => '代表著者',
+'代表著述' => '代表著述',
+'乙太網' => '以太网',
+'伊莉莎白' => '伊丽莎白',
+'伊利諾' => '伊利诺伊',
+'伊利諾伊' => '伊利诺伊',
+'伊斯蘭瑪巴德' => '伊斯兰堡',
+'伊斯坦堡' => '伊斯坦布尔',
+'伏著' => '伏着',
+'優先順序' => '优先级',
+'傳著' => '传着',
+'傳著書' => '传著书',
+'傳著作' => '传著作',
+'傳著名' => '传著名',
+'傳著錄' => '传著录',
+'傳著稱' => '传著称',
+'傳著者' => '传著者',
+'傳著述' => '传著述',
+'貝里斯' => '伯利兹',
+'伯明罕' => '伯明翰',
+'伴著' => '伴着',
+'伴著書' => '伴著书',
+'伴著作' => '伴著作',
+'伴著名' => '伴著名',
+'伴著錄' => '伴著录',
+'伴著稱' => '伴著称',
+'伴著者' => '伴著者',
+'伴著述' => '伴著述',
+'點陣圖' => '位图',
+'低著' => '低着',
+'低著書' => '低著书',
+'低著作' => '低著作',
+'低著名' => '低著名',
+'低著錄' => '低著录',
+'低著称' => '低著称',
+'低著稱' => '低著称',
+'低著者' => '低著者',
+'低著述' => '低著述',
+'住著' => '住着',
+'住著書' => '住著书',
+'住著作' => '住著作',
+'住著名' => '住著名',
+'住著錄' => '住著录',
+'住著称' => '住著称',
+'住著稱' => '住著称',
+'住著者' => '住著者',
+'住著述' => '住著述',
+'餘' => '余',
+'維德角' => '佛得角',
+'侏儸紀' => '侏罗纪',
+'側著' => '侧着',
+'側著書' => '侧著书',
+'側著作' => '侧著作',
+'側著名' => '侧著名',
+'側著錄' => '侧著录',
+'側著稱' => '侧著称',
+'側著者' => '侧著者',
+'側著述' => '侧著述',
+'可攜式' => '便携式',
+'攜帶型' => '便携式',
+'保護著' => '保护着',
+'保障著' => '保障着',
+'保障著書' => '保障著书',
+'保障著作' => '保障著作',
+'保障著名' => '保障著名',
+'保障著錄' => '保障著录',
+'保障著称' => '保障著称',
+'保障著稱' => '保障著称',
+'保障著者' => '保障著者',
+'保障著述' => '保障著述',
+'資訊時代' => '信息时代',
+'資訊理論' => '信息论',
+'信著' => '信着',
+'信著書' => '信著书',
+'信著作' => '信著作',
+'信著名' => '信著名',
+'信著錄' => '信著录',
+'信著称' => '信著称',
+'信著稱' => '信著称',
+'信著者' => '信著者',
+'信著述' => '信著述',
+'伏地挺身' => '俯卧撑',
+'掌上壓' => '俯卧撑',
+'倒帳' => '倒账',
+'候著' => '候着',
+'候著書' => '候著书',
+'候著作' => '候著作',
+'候著名' => '候著名',
+'候著錄' => '候著录',
+'候著稱' => '候著称',
+'候著者' => '候著者',
+'候著述' => '候著述',
+'借著' => '借着',
+'藉著' => '借着',
+'借著書' => '借著书',
+'借著作' => '借著作',
+'借著名' => '借著名',
+'借著錄' => '借著录',
+'借著稱' => '借著称',
+'借著者' => '借著者',
+'借著述' => '借著述',
+'假帳' => '假账',
+'做著' => '做着',
+'做著書' => '做著书',
+'做著作' => '做著作',
+'做著名' => '做著名',
+'做著錄' => '做著录',
+'做著稱' => '做著称',
+'做著者' => '做著者',
+'做著述' => '做著述',
+'偷著' => '偷着',
+'偷著書' => '偷著书',
+'偷著作' => '偷著作',
+'偷著名' => '偷著名',
+'偷著錄' => '偷著录',
+'偷著稱' => '偷著称',
+'偷著者' => '偷著者',
+'偷著述' => '偷著述',
+'傅利葉' => '傅里叶',
+'母音' => '元音',
+'光著' => '光着',
+'光著書' => '光著书',
+'光著作' => '光著作',
+'光著名' => '光著名',
+'光著錄' => '光著录',
+'光著称' => '光著称',
+'光著稱' => '光著称',
+'光著者' => '光著者',
+'光著述' => '光著述',
+'光碟機' => '光驱',
+'柯林頓' => '克林顿',
+'克羅埃西亞' => '克罗地亚',
+'轉殖' => '克隆',
+'複製人' => '克隆人',
+'入帳' => '入账',
+'八進位制' => '八进位制',
+'八進位' => '八进制',
+'西元1' => '公元1',
+'西元2' => '公元2',
+'西元3' => '公元3',
+'西元4' => '公元4',
+'西元5' => '公元5',
+'西元6' => '公元6',
+'西元7' => '公元7',
+'西元8' => '公元8',
+'西元9' => '公元9',
+'西元前' => '公元前',
+'公帳' => '公账',
+'六進位制' => '六进位制',
+'六進位' => '六进制',
+'關著' => '关着',
+'關係著' => '关系着',
+'關著書' => '关著书',
+'關著作' => '关著作',
+'關著名' => '关著名',
+'關著錄' => '关著录',
+'關著稱' => '关著称',
+'關著者' => '关著者',
+'關著述' => '关著述',
+'關帳' => '关账',
+'記憶體' => '内存',
+'甘比亞' => '冈比亚',
+'冒著' => '冒着',
+'冒著書' => '冒著书',
+'冒著作' => '冒著作',
+'冒著名' => '冒著名',
+'冒著錄' => '冒著录',
+'冒著稱' => '冒著称',
+'冒著者' => '冒著者',
+'冒著述' => '冒著述',
+'寫著' => '写着',
+'寫著書' => '写著书',
+'寫著作' => '写著作',
+'寫著名' => '写著名',
+'寫著錄' => '写著录',
+'寫著稱' => '写著称',
+'寫著者' => '写著者',
+'寫著述' => '写著述',
+'沖著' => '冲着',
+'衝著' => '冲着',
+'沖著。' => '冲著。',
+'沖著《' => '冲著《',
+'沖著(' => '冲著(',
+'沖著,' => '冲著,',
+'沖帳' => '冲账',
+'涼著' => '凉着',
+'涼著書' => '凉著书',
+'涼著作' => '凉著作',
+'涼著名' => '凉著名',
+'涼著錄' => '凉著录',
+'涼著稱' => '凉著称',
+'涼著者' => '凉著者',
+'涼著述' => '凉著述',
+'湊合著' => '凑合着',
+'畿內亞' => '几内亚',
+'幾內亞比索' => '几内亚比绍',
+'凱薩琳' => '凯瑟琳',
+'嘉芙蓮' => '凯瑟琳',
+'份內' => '分内',
+'份外' => '分外',
+'分佈著' => '分布着',
+'分布著' => '分布着',
+'解像度' => '分辨率',
+'解析度' => '分辨率',
+'份量' => '分量',
+'車諾比' => '切尔诺贝利',
+'劃著' => '划着',
+'李奧納多' => '列奥那多',
+'列支敦斯登' => '列支敦士登',
+'賴比瑞亞' => '利比里亚',
+'別著' => '别着',
+'刮著' => '刮着',
+'颳著' => '刮着',
+'到帳' => '到账',
+'制著' => '制着',
+'制著書' => '制著书',
+'制著作' => '制著作',
+'制著名' => '制著名',
+'制著錄' => '制著录',
+'制著稱' => '制著称',
+'制著者' => '制著者',
+'制著述' => '制著述',
+'煞車' => '刹车',
+'刻著' => '刻着',
+'刻著書' => '刻著书',
+'刻著作' => '刻著作',
+'刻著名' => '刻著名',
+'刻著錄' => '刻著录',
+'刻著称' => '刻著称',
+'刻著稱' => '刻著称',
+'刻著者' => '刻著者',
+'刻著述' => '刻著述',
+'前波莫瑞' => '前波美拉尼亚',
+'辦著' => '办着',
+'辦著書' => '办著书',
+'辦著作' => '办著作',
+'辦著名' => '办著名',
+'辦著錄' => '办著录',
+'辦著稱' => '办著称',
+'辦著者' => '办著者',
+'辦著述' => '办著述',
+'加薩走廊' => '加沙地带',
+'迦納' => '加纳',
+'加彭' => '加蓬',
+'動著' => '动着',
+'動著書' => '动著书',
+'動著作' => '动著作',
+'動著名' => '动著名',
+'動著錄' => '动著录',
+'動著稱' => '动著称',
+'動著者' => '动著者',
+'動著述' => '动著述',
+'努力著' => '努力着',
+'努力著書' => '努力著书',
+'努力著作' => '努力著作',
+'努力著名' => '努力著名',
+'努力著錄' => '努力著录',
+'努力著称' => '努力著称',
+'努力著稱' => '努力著称',
+'努力著者' => '努力著者',
+'努力著述' => '努力著述',
+'蘿拉' => '劳拉',
+'布蘭登堡' => '勃兰登堡',
+'白朗寧' => '勃朗宁',
+'包著' => '包着',
+'北韓' => '北朝鲜',
+'十進位制' => '十进位制',
+'十進位' => '十进制',
+'公升' => '升',
+'單眼相機' => '单反相机',
+'單鏡反光機' => '单反相机',
+'波札那' => '博茨瓦纳',
+'占著' => '占着',
+'占著作' => '占著作',
+'占著名' => '占著名',
+'占著者' => '占著者',
+'喀拉蚩' => '卡拉奇',
+'卡斯楚' => '卡斯特罗',
+'卡佩雅蒂' => '卡普里亚蒂',
+'盧安達' => '卢旺达',
+'羅浮宮' => '卢浮宫',
+'羅亞爾' => '卢瓦尔',
+'印著' => '印着',
+'印著書' => '印著书',
+'印著作' => '印著作',
+'印著名' => '印著名',
+'印著錄' => '印著录',
+'印著稱' => '印著称',
+'印著者' => '印著者',
+'印著述' => '印著述',
+'瓜地馬拉' => '危地马拉',
+'厄瓜多' => '厄瓜多尔',
+'厄瓜多尔' => '厄瓜多尔',
+'厄瓜多爾' => '厄瓜多尔',
+'厄利垂亚' => '厄立特里亚',
+'厄利垂亞' => '厄立特里亚',
+'厄立特里亞' => '厄立特里亚',
+'壓著' => '压着',
+'壓著書' => '压著书',
+'壓著作' => '压著作',
+'壓著名' => '压著名',
+'壓著錄' => '压著录',
+'壓著稱' => '压著称',
+'壓著者' => '压著者',
+'壓著述' => '压著述',
+'發著' => '发着',
+'發著《' => '发著《',
+'發著作' => '发著作',
+'發著名' => '发著名',
+'發著稱' => '发著称',
+'發著者' => '发著者',
+'已開發國家' => '发达国家',
+'受著' => '受着',
+'受著書' => '受著书',
+'受著作' => '受著作',
+'受著名' => '受著名',
+'受著錄' => '受著录',
+'受著稱' => '受著称',
+'受著者' => '受著者',
+'受著述' => '受著述',
+'變著' => '变着',
+'變著書' => '变著书',
+'變著作' => '变著作',
+'變著名' => '变著名',
+'變著錄' => '变著录',
+'變著稱' => '变著称',
+'變著者' => '变著者',
+'變著述' => '变著述',
+'隻字片語' => '只字片语',
+'隻言片語' => '只言片语',
+'唯讀' => '只读',
+'叫著' => '叫着',
+'叫著書' => '叫著书',
+'叫著作' => '叫著作',
+'叫著名' => '叫著名',
+'叫著錄' => '叫著录',
+'叫著稱' => '叫著称',
+'叫著者' => '叫著者',
+'叫著述' => '叫著述',
+'桌上型電腦' => '台式电脑',
+'撞球' => '台球',
+'台帳' => '台账',
+'叱吒' => '叱咤',
+'吃著' => '吃着',
+'結他' => '吉他',
+'健力士世界紀錄' => '吉尼斯世界纪录',
+'金氏世界紀錄' => '吉尼斯世界纪录',
+'吉布地' => '吉布提',
+'吊著' => '吊着',
+'名份' => '名分',
+'向著' => '向着',
+'向著書' => '向著书',
+'向著作' => '向著作',
+'向著名' => '向著名',
+'向著錄' => '向著录',
+'向著稱' => '向著称',
+'向著者' => '向著者',
+'向著述' => '向著述',
+'含著' => '含着',
+'含著書' => '含著书',
+'含著作' => '含著作',
+'含著名' => '含著名',
+'含著錄' => '含著录',
+'含著稱' => '含著称',
+'含著者' => '含著者',
+'含著述' => '含著述',
+'聽著' => '听着',
+'聽著書' => '听著书',
+'聽著作' => '听著作',
+'聽著名' => '听著名',
+'聽著錄' => '听著录',
+'聽著稱' => '听著称',
+'聽著者' => '听著者',
+'聽著述' => '听著述',
+'吹著' => '吹着',
+'吹著書' => '吹著书',
+'吹著作' => '吹著作',
+'吹著名' => '吹著名',
+'吹著錄' => '吹著录',
+'吹著稱' => '吹著称',
+'吹著者' => '吹著者',
+'吹著述' => '吹著述',
+'呆著' => '呆着',
+'呆帳' => '呆账',
+'味著' => '味着',
+'味著書' => '味著书',
+'味著作' => '味著作',
+'味著名' => '味著名',
+'味著錄' => '味著录',
+'味著称' => '味著称',
+'味著稱' => '味著称',
+'味著者' => '味著者',
+'味著述' => '味著述',
+'咖哩' => '咖喱',
+'諮' => '咨',
+'響著' => '响着',
+'響著書' => '响著书',
+'響著作' => '响著作',
+'響著名' => '响著名',
+'響著錄' => '响著录',
+'響著稱' => '响著称',
+'響著者' => '响著者',
+'響著述' => '响著述',
+'哥斯大黎加' => '哥斯达黎加',
+'哥德式' => '哥特式',
+'哭著' => '哭着',
+'哭著書' => '哭著书',
+'哭著作' => '哭著作',
+'哭著名' => '哭著名',
+'哭著錄' => '哭著录',
+'哭著稱' => '哭著称',
+'哭著者' => '哭著者',
+'哭著述' => '哭著述',
+'唱著' => '唱着',
+'唱著書' => '唱著书',
+'唱著作' => '唱著作',
+'唱著名' => '唱著名',
+'唱著錄' => '唱著录',
+'唱著稱' => '唱著称',
+'唱著者' => '唱著者',
+'唱著述' => '唱著述',
+'啸吒' => '啸咤',
+'喝著' => '喝着',
+'喝著書' => '喝著书',
+'喝著作' => '喝著作',
+'喝著名' => '喝著名',
+'喝著錄' => '喝著录',
+'喝著稱' => '喝著称',
+'喝著者' => '喝著者',
+'喝著述' => '喝著述',
+'嗅著' => '嗅着',
+'雜訊' => '噪声',
+'嚷著' => '嚷着',
+'嚷著書' => '嚷著书',
+'嚷著作' => '嚷著作',
+'嚷著名' => '嚷著名',
+'嚷著錄' => '嚷著录',
+'嚷著稱' => '嚷著称',
+'嚷著者' => '嚷著者',
+'嚷著述' => '嚷著述',
+'回著' => '回着',
+'回著名' => '回著名',
+'因著' => '因着',
+'因著〈' => '因著〈',
+'因著《' => '因著《',
+'因著書' => '因著书',
+'因著作' => '因著作',
+'因著名' => '因著名',
+'因著录' => '因著录',
+'因著錄' => '因著录',
+'因著稱' => '因著称',
+'因著者' => '因著者',
+'因著述' => '因著述',
+'困著' => '困着',
+'困著書' => '困著书',
+'困著作' => '困著作',
+'困著名' => '困著名',
+'困著錄' => '困著录',
+'困著稱' => '困著称',
+'困著者' => '困著者',
+'困著述' => '困著述',
+'圍著' => '围着',
+'圍著書' => '围著书',
+'圍著作' => '围著作',
+'圍著名' => '围著名',
+'圍著錄' => '围著录',
+'圍著稱' => '围著称',
+'圍著者' => '围著者',
+'圍著述' => '围著述',
+'韌體' => '固件',
+'固著' => '固着',
+'西洋棋' => '国际象棋',
+'土魯斯' => '图卢兹',
+'吐瓦魯' => '图瓦卢',
+'原子筆' => '圆珠笔',
+'聖露西亞' => '圣卢西亚',
+'聖克里斯多福及尼維斯' => '圣基茨和尼维斯',
+'聖吉斯納域斯' => '圣基茨和尼维斯',
+'聖文森及格瑞那丁' => '圣文森特和格林纳丁斯',
+'聖馬利諾' => '圣马力诺',
+'蓋亞那' => '圭亚那',
+'坐著' => '坐着',
+'坐著書' => '坐著书',
+'坐著作' => '坐著作',
+'坐著名' => '坐著名',
+'坐著錄' => '坐著录',
+'坐著稱' => '坐著称',
+'坐著者' => '坐著者',
+'坐著述' => '坐著述',
+'堅貞著' => '坚贞着',
+'坦尚尼亞' => '坦桑尼亚',
+'伊波拉' => '埃博拉',
+'衣索匹亞' => '埃塞俄比亚',
+'衣索比亞' => '埃塞俄比亚',
+'艾菲爾' => '埃菲尔',
+'葉里溫' => '埃里温',
+'功能變數名稱' => '域名',
+'吉里巴斯' => '基里巴斯',
+'堂姊' => '堂姐',
+'坎培拉' => '堪培拉',
+'塑膠袋' => '塑料袋',
+'塞爾維亞與蒙特內哥羅' => '塞尔维亚和黑山',
+'塞拉利昂' => '塞拉利昂',
+'塞普勒斯' => '塞浦路斯',
+'賽普勒斯' => '塞浦路斯',
+'塞維亞' => '塞维利亚',
+'西維爾' => '塞维利亚',
+'塞席爾' => '塞舌尔',
+'音效卡' => '声卡',
+'備著' => '备着',
+'備著書' => '备著书',
+'備著作' => '备著作',
+'備著名' => '备著名',
+'備著錄' => '备著录',
+'備著稱' => '备著称',
+'備著者' => '备著者',
+'備著述' => '备著述',
+'外部連結' => '外部链接',
+'托巴哥' => '多巴哥',
+'都卜勒' => '多普勒',
+'多明尼加' => '多米尼加',
+'大姊' => '大姐',
+'天份' => '天分',
+'夾著' => '夹着',
+'夾著書' => '夹著书',
+'夾著作' => '夹著作',
+'夾著名' => '夹著名',
+'夾著錄' => '夹著录',
+'夾著稱' => '夹著称',
+'夾著者' => '夹著者',
+'夾著述' => '夹著述',
+'賓士' => '奔驰',
+'歐巴馬' => '奥巴马',
+'柯德莉·夏萍' => '奥黛丽·赫本',
+'忌廉' => '奶油',
+'荷里活' => '好莱坞',
+'姊夫' => '姐夫',
+'姊姊' => '姐姐',
+'姊弟' => '姐弟',
+'威爾斯' => '威尔士',
+'威斯伐倫' => '威斯特法伦',
+'字型大小' => '字号',
+'字型檔' => '字库',
+'欄位' => '字段',
+'位元組' => '字节',
+'存在著' => '存在着',
+'存著' => '存着',
+'存著作' => '存著作',
+'存著名' => '存著名',
+'學姊' => '学姐',
+'學著' => '学着',
+'學著書' => '学著书',
+'學著作' => '学著作',
+'學著名' => '学著名',
+'學著錄' => '学著录',
+'學著稱' => '学著称',
+'學著者' => '学著者',
+'學著述' => '学著述',
+'太空飛行員' => '宇航员',
+'太空衣' => '宇航服',
+'守著' => '守着',
+'守著書' => '守著书',
+'守著作' => '守著作',
+'守著名' => '守著名',
+'守著錄' => '守著录',
+'守著称' => '守著称',
+'守著稱' => '守著称',
+'守著者' => '守著者',
+'守著述' => '守著述',
+'安哈特' => '安哈尔特',
+'安地卡及巴布達' => '安提瓜和巴布达',
+'巨集' => '宏',
+'定著' => '定着',
+'定著書' => '定著书',
+'定著作' => '定著作',
+'定著名' => '定著名',
+'定著錄' => '定著录',
+'定著称' => '定著称',
+'定著稱' => '定著称',
+'定著者' => '定著者',
+'定著述' => '定著述',
+'波里活' => '宝莱坞',
+'寬頻' => '宽带',
+'密执安' => '密歇根',
+'密西根' => '密歇根',
+'對著' => '对着',
+'對著書' => '对著书',
+'對著作' => '对著作',
+'對著名' => '对著名',
+'對著錄' => '对著录',
+'對著稱' => '对著称',
+'對著者' => '对著者',
+'對著述' => '对著述',
+'對帳' => '对账',
+'尋著' => '寻着',
+'尋著書' => '寻著书',
+'尋著作' => '寻著作',
+'尋著名' => '寻著名',
+'尋著錄' => '寻著录',
+'尋著稱' => '寻著称',
+'尋著者' => '寻著者',
+'尋著述' => '寻著述',
+'飛彈' => '导弹',
+'祖雲達斯' => '尤文图斯',
+'奈及利亞' => '尼日利亚',
+'尼日爾' => '尼日尔',
+'區域網' => '局域网',
+'區域網路' => '局域网络',
+'螢幕' => '屏幕',
+'展著' => '展着',
+'展著書' => '展著书',
+'展著作' => '展著作',
+'展著名' => '展著名',
+'展著錄' => '展著录',
+'展著稱' => '展著称',
+'展著者' => '展著者',
+'展著述' => '展著述',
+'瓦倫西亞' => '巴伦西亚',
+'華倫西亞' => '巴伦西亚',
+'巴塞隆拿' => '巴塞罗那',
+'巴塞隆納' => '巴塞罗那',
+'巴斯拉' => '巴士拉',
+'帕邁拉環礁' => '巴尔米拉环礁',
+'巴貝多' => '巴巴多斯',
+'巴布亞紐幾內亞' => '巴布亚新几内亚',
+'布殊' => '布什',
+'布吉納法索' => '布基纳法索',
+'布隆泉' => '布隆方丹',
+'蒲隆地' => '布隆迪',
+'希冀著' => '希冀着',
+'席哈克' => '希拉克',
+'希拉莉' => '希拉里',
+'希拉蕊' => '希拉里',
+'希特拉' => '希特勒',
+'帛琉' => '帕劳',
+'派屈克' => '帕特里克',
+'頻寬' => '带宽',
+'帶著' => '带着',
+'帶著書' => '带著书',
+'帶著作' => '带著作',
+'帶著名' => '带著名',
+'帶著錄' => '带著录',
+'帶著稱' => '带著称',
+'帶著者' => '带著者',
+'帶著述' => '带著述',
+'幫著' => '帮着',
+'幫著書' => '帮著书',
+'幫著作' => '帮著作',
+'幫著名' => '帮著名',
+'幫著錄' => '帮著录',
+'幫著稱' => '帮著称',
+'幫著者' => '帮著者',
+'幫著述' => '帮著述',
+'乾姊' => '干姐',
+'幹著' => '干着',
+'幹著名' => '幹著名',
+'幹著稱' => '幹著称',
+'庇護著' => '庇护着',
+'庫德人' => '库尔德人',
+'庫德族' => '库尔德族',
+'應用程式' => '应用程序',
+'應著' => '应着',
+'應著書' => '应著书',
+'應著作' => '应著作',
+'應著名' => '应著名',
+'應著錄' => '应著录',
+'應著稱' => '应著称',
+'應著者' => '应著者',
+'應著述' => '应著述',
+'建帳' => '建账',
+'克卜勒' => '开普勒',
+'開著' => '开着',
+'開著書' => '开著书',
+'開著作' => '开著作',
+'開著名' => '开著名',
+'開著錄' => '开著录',
+'開著稱' => '开著称',
+'開著者' => '开著者',
+'開著述' => '开著述',
+'開帳' => '开账',
+'非同步' => '异步',
+'若且唯若' => '当且仅当',
+'當著' => '当着',
+'當著書' => '当著书',
+'當著作' => '当著作',
+'當著名' => '当著名',
+'當著錄' => '当著录',
+'當著稱' => '当著称',
+'當著者' => '当著者',
+'當著述' => '当著述',
+'錄影帶' => '录像带',
+'形上學' => '形而上学',
+'澈底' => '彻底',
+'逕入' => '径入',
+'逕到' => '径到',
+'逕取' => '径取',
+'逕啟' => '径启',
+'逕寄' => '径寄',
+'逕庭' => '径庭',
+'逕往' => '径往',
+'逕自' => '径自',
+'逕行' => '径行',
+'逕迎' => '径迎',
+'待著' => '待着',
+'待著書' => '待著书',
+'待著作' => '待著作',
+'待著名' => '待著名',
+'待著錄' => '待著录',
+'待著稱' => '待著称',
+'待著者' => '待著者',
+'待著述' => '待著述',
+'得著' => '得着',
+'得著書' => '得著书',
+'得著作' => '得著作',
+'得著名' => '得著名',
+'得著錄' => '得著录',
+'得著稱' => '得著称',
+'得著者' => '得著者',
+'得著述' => '得著述',
+'御姊' => '御姐',
+'迴圈' => '循环',
+'循著' => '循着',
+'循著書' => '循著书',
+'循著作' => '循著作',
+'循著名' => '循著名',
+'循著錄' => '循著录',
+'循著稱' => '循著称',
+'循著者' => '循著者',
+'循著述' => '循著述',
+'德勒斯登' => '德累斯顿',
+'德希達' => '德里达',
+'心著' => '心着',
+'心著書' => '心著书',
+'心著作' => '心著作',
+'心著名' => '心著名',
+'心著錄' => '心著录',
+'心著称' => '心著称',
+'心著稱' => '心著称',
+'心著者' => '心著者',
+'心著述' => '心著述',
+'忍著' => '忍着',
+'忍著書' => '忍著书',
+'忍著作' => '忍著作',
+'忍著名' => '忍著名',
+'忍著錄' => '忍著录',
+'忍著稱' => '忍著称',
+'忍著者' => '忍著者',
+'忍著述' => '忍著述',
+'忙著' => '忙着',
+'忙著書' => '忙著书',
+'忙著作' => '忙著作',
+'忙著名' => '忙著名',
+'忙著錄' => '忙著录',
+'忙著稱' => '忙著称',
+'忙著者' => '忙著者',
+'忙著述' => '忙著述',
+'忠貞著' => '忠贞着',
+'懷著' => '怀着',
+'懷著書' => '怀著书',
+'懷著作' => '怀著作',
+'懷著名' => '怀著名',
+'懷著錄' => '怀著录',
+'懷著稱' => '怀著称',
+'懷著者' => '怀著者',
+'懷著述' => '怀著述',
+'急著' => '急着',
+'急著書' => '急著书',
+'急著作' => '急著作',
+'急著名' => '急著名',
+'急著錄' => '急著录',
+'急著稱' => '急著称',
+'急著者' => '急著者',
+'急著述' => '急著述',
+'匯流排' => '总线',
+'總帳' => '总账',
+'戀著' => '恋着',
+'戀著書' => '恋著书',
+'戀著作' => '恋著作',
+'戀著名' => '恋著名',
+'戀著錄' => '恋著录',
+'戀著稱' => '恋著称',
+'戀著者' => '恋著者',
+'戀著述' => '恋著述',
+'恰如其份' => '恰如其分',
+'悠著' => '悠着',
+'悠著書' => '悠著书',
+'悠著作' => '悠著作',
+'悠著名' => '悠著名',
+'悠著錄' => '悠著录',
+'悠著稱' => '悠著称',
+'悠著者' => '悠著者',
+'悠著述' => '悠著述',
+'慣著' => '惯着',
+'慣著書' => '惯著书',
+'慣著作' => '惯著作',
+'慣著名' => '惯著名',
+'慣著錄' => '惯著录',
+'慣著稱' => '惯著称',
+'慣著者' => '惯著者',
+'慣著述' => '惯著述',
+'想著' => '想着',
+'想著書' => '想著书',
+'想著作' => '想著作',
+'想著名' => '想著名',
+'想著錄' => '想著录',
+'想著称' => '想著称',
+'想著稱' => '想著称',
+'想著者' => '想著者',
+'想著述' => '想著述',
+'義大利' => '意大利',
+'戈巴契夫' => '戈尔巴乔夫',
+'成份' => '成分',
+'戰著' => '战着',
+'戰著書' => '战著书',
+'戰著作' => '战著作',
+'戰著名' => '战著名',
+'戰著錄' => '战著录',
+'戰著稱' => '战著称',
+'戰著者' => '战著者',
+'戰著述' => '战著述',
+'坎城' => '戛纳',
+'黛安娜' => '戴安娜',
+'戴著' => '戴着',
+'戴著書' => '戴著书',
+'戴著作' => '戴著作',
+'戴著名' => '戴著名',
+'戴著錄' => '戴著录',
+'戴著稱' => '戴著称',
+'戴著者' => '戴著者',
+'戴著述' => '戴著述',
+'索羅門群島' => '所罗门群岛',
+'紮著' => '扎着',
+'紮著書' => '扎著书',
+'紮著作' => '扎著作',
+'紮著名' => '扎著名',
+'紮著錄' => '扎著录',
+'紮著稱' => '扎著称',
+'紮著者' => '扎著者',
+'紮著述' => '扎著述',
+'列印' => '打印',
+'印表機' => '打印机',
+'打著' => '打着',
+'打著書' => '打著书',
+'打著作' => '打著作',
+'打著名' => '打著名',
+'打著錄' => '打著录',
+'打著稱' => '打著称',
+'打著者' => '打著者',
+'打著述' => '打著述',
+'扛著' => '扛着',
+'扛著書' => '扛著书',
+'扛著作' => '扛著作',
+'扛著名' => '扛著名',
+'扛著錄' => '扛著录',
+'扛著稱' => '扛著称',
+'扛著者' => '扛著者',
+'扛著述' => '扛著述',
+'掃瞄' => '扫描',
+'掃瞄器' => '扫描仪',
+'抓著' => '抓着',
+'抓著作' => '抓著作',
+'抓著名' => '抓著名',
+'抓著錄' => '抓著录',
+'抓著稱' => '抓著称',
+'抓著者' => '抓著者',
+'抓著述' => '抓著述',
+'投機份子' => '投机分子',
+'護著' => '护着',
+'護著書' => '护著书',
+'護著作' => '护著作',
+'護著名' => '护著名',
+'護著錄' => '护著录',
+'護著稱' => '护著称',
+'護著者' => '护著者',
+'護著述' => '护著述',
+'報帳' => '报账',
+'披著' => '披着',
+'披著書' => '披著书',
+'披著作' => '披著作',
+'披著名' => '披著名',
+'披著錄' => '披著录',
+'披著稱' => '披著称',
+'披著者' => '披著者',
+'披著述' => '披著述',
+'抬著' => '抬着',
+'擡著' => '抬着',
+'抬著作' => '抬著作',
+'抬著名' => '抬著名',
+'抬著錄' => '抬著录',
+'抬著稱' => '抬著称',
+'抬著者' => '抬著者',
+'抬著述' => '抬著述',
+'抱著' => '抱着',
+'抱著作' => '抱著作',
+'抱著名' => '抱著名',
+'抱著錄' => '抱著录',
+'抱著稱' => '抱著称',
+'抱著者' => '抱著者',
+'抱著述' => '抱著述',
+'擔著' => '担着',
+'拉著' => '拉着',
+'拉著書' => '拉著书',
+'拉著作' => '拉著作',
+'拉著名' => '拉著名',
+'拉著錄' => '拉著录',
+'拉著稱' => '拉著称',
+'拉著者' => '拉著者',
+'拉著述' => '拉著述',
+'拎著' => '拎着',
+'拎著作' => '拎著作',
+'拎著名' => '拎著名',
+'拎著錄' => '拎著录',
+'拎著稱' => '拎著称',
+'拎著者' => '拎著者',
+'拎著述' => '拎著述',
+'拖著' => '拖着',
+'拖著作' => '拖著作',
+'拖著名' => '拖著名',
+'拖著錄' => '拖著录',
+'拖著稱' => '拖著称',
+'拖著者' => '拖著者',
+'拖著述' => '拖著述',
+'拼著' => '拼着',
+'拼著作' => '拼著作',
+'拼著名' => '拼著名',
+'拼著錄' => '拼著录',
+'拼著稱' => '拼著称',
+'拼著者' => '拼著者',
+'拼著述' => '拼著述',
+'拿著' => '拿着',
+'拿著作' => '拿著作',
+'拿著名' => '拿著名',
+'拿著錄' => '拿著录',
+'拿著稱' => '拿著称',
+'拿著者' => '拿著者',
+'拿著述' => '拿著述',
+'持著' => '持着',
+'持著作' => '持著作',
+'持著名' => '持著名',
+'持著錄' => '持著录',
+'持著稱' => '持著称',
+'持著者' => '持著者',
+'持著述' => '持著述',
+'掛著' => '挂着',
+'挑著' => '挑着',
+'挑著作' => '挑著作',
+'挑著名' => '挑著名',
+'挑著錄' => '挑著录',
+'挑著稱' => '挑著称',
+'挑著者' => '挑著者',
+'挑著述' => '挑著述',
+'擋著' => '挡着',
+'擋著作' => '挡著作',
+'擋著名' => '挡著名',
+'擋著錄' => '挡著录',
+'擋著稱' => '挡著称',
+'擋著者' => '挡著者',
+'擋著述' => '挡著述',
+'掙著' => '挣着',
+'掙著書' => '挣著书',
+'掙著作' => '挣著作',
+'掙著名' => '挣著名',
+'掙著錄' => '挣著录',
+'掙著稱' => '挣著称',
+'掙著者' => '挣著者',
+'掙著述' => '挣著述',
+'揮著' => '挥着',
+'揮著作' => '挥著作',
+'揮著名' => '挥著名',
+'揮著錄' => '挥著录',
+'揮著稱' => '挥著称',
+'揮著者' => '挥著者',
+'揮著述' => '挥著述',
+'挨著' => '挨着',
+'挨著作' => '挨著作',
+'挨著名' => '挨著名',
+'挨著錄' => '挨著录',
+'挨著稱' => '挨著称',
+'挨著者' => '挨著者',
+'挨著述' => '挨著述',
+'捆著' => '捆着',
+'捆著作' => '捆著作',
+'捆著名' => '捆著名',
+'捆著錄' => '捆著录',
+'捆著稱' => '捆著称',
+'捆著者' => '捆著者',
+'捆著述' => '捆著述',
+'據著' => '据着',
+'據著書' => '据著书',
+'據著作' => '据著作',
+'據著名' => '据著名',
+'據著錄' => '据著录',
+'據著稱' => '据著称',
+'據著者' => '据著者',
+'據著述' => '据著述',
+'積架' => '捷豹',
+'掖著' => '掖着',
+'掖著作' => '掖著作',
+'掖著名' => '掖著名',
+'掖著錄' => '掖著录',
+'掖著稱' => '掖著称',
+'掖著者' => '掖著者',
+'掖著述' => '掖著述',
+'接著' => '接着',
+'接著作' => '接著作',
+'接著名' => '接著名',
+'接著錄' => '接著录',
+'接著稱' => '接著称',
+'接著者' => '接著者',
+'接著述' => '接著述',
+'控制項' => '控件',
+'揉著' => '揉着',
+'揉著書' => '揉著书',
+'揉著作' => '揉著作',
+'揉著名' => '揉著名',
+'揉著錄' => '揉著录',
+'揉著稱' => '揉著称',
+'揉著者' => '揉著者',
+'揉著述' => '揉著述',
+'提著' => '提着',
+'提著作' => '提著作',
+'提著名' => '提著名',
+'提著錄' => '提著录',
+'提著稱' => '提著称',
+'提著者' => '提著者',
+'提著述' => '提著述',
+'外掛程式' => '插件',
+'摟著' => '搂着',
+'摟著作' => '搂著作',
+'摟著名' => '搂著名',
+'摟著錄' => '搂著录',
+'摟著稱' => '搂著称',
+'摟著者' => '搂著者',
+'摟著述' => '搂著述',
+'搜尋引擎' => '搜索引擎',
+'擺著' => '摆着',
+'擺著作' => '摆著作',
+'擺著名' => '摆著名',
+'擺著錄' => '摆著录',
+'擺著稱' => '摆著称',
+'擺著者' => '摆著者',
+'擺著述' => '摆著述',
+'電單車' => '摩托车',
+'戴卓爾' => '撒切尔',
+'柴契爾' => '撒切尔',
+'撼著' => '撼着',
+'撼著書' => '撼著书',
+'撼著作' => '撼著作',
+'撼著名' => '撼著名',
+'撼著錄' => '撼著录',
+'撼著稱' => '撼著称',
+'撼著者' => '撼著者',
+'撼著述' => '撼著述',
+'作業系統' => '操作系统',
+'收帳' => '收账',
+'放著' => '放着',
+'放著作' => '放著作',
+'放著名' => '放著名',
+'放著称' => '放著称',
+'放著稱' => '放著称',
+'放帳' => '放账',
+'敞著' => '敞着',
+'敞著作' => '敞著作',
+'敞著名' => '敞著名',
+'敞著錄' => '敞著录',
+'敞著稱' => '敞著称',
+'敞著者' => '敞著者',
+'敞著述' => '敞著述',
+'散佈著' => '散布着',
+'散布著' => '散布着',
+'數位訊號' => '数字信号',
+'數碼訊號' => '数字信号',
+'數位化' => '数字化',
+'數位技術' => '数字技术',
+'數位電視' => '数字电视',
+'數碼電視' => '数字电视',
+'資料庫' => '数据库',
+'數著' => '数着',
+'數位照相機' => '数码照相机',
+'數位相機' => '数码相机',
+'數著作' => '数著作',
+'數著名' => '数著名',
+'數著錄' => '数著录',
+'數著稱' => '数著称',
+'數著者' => '数著者',
+'數著述' => '数著述',
+'汶萊' => '文莱',
+'鬥著' => '斗着',
+'鬥著書' => '斗著书',
+'鬥著作' => '斗著作',
+'鬥著名' => '斗著名',
+'鬥著錄' => '斗著录',
+'鬥著稱' => '斗著称',
+'鬥著者' => '斗著者',
+'鬥著述' => '斗著述',
+'斥著' => '斥着',
+'斥著書' => '斥著书',
+'斥著作' => '斥著作',
+'斥著名' => '斥著名',
+'斥著錄' => '斥著录',
+'斥著稱' => '斥著称',
+'斥著者' => '斥著者',
+'斥著述' => '斥著述',
+'史丹福大學' => '斯坦福大学',
+'史達林' => '斯大林',
+'史瓦濟蘭' => '斯威士兰',
+'斯洛維尼亞' => '斯洛文尼亚',
+'史特勞斯' => '斯特劳斯',
+'紐幾內亞' => '新几内亚',
+'紐澤西' => '新泽西',
+'紐西蘭' => '新西兰',
+'舊帳' => '旧账',
+'三藩市' => '旧金山',
+'昂山素姬' => '昂山素季',
+'翁山蘇姬' => '昂山素季',
+'昂著' => '昂着',
+'昂著書' => '昂著书',
+'昂著作' => '昂著作',
+'昂著名' => '昂著名',
+'昂著錄' => '昂著录',
+'昂著稱' => '昂著称',
+'昂著者' => '昂著者',
+'昂著述' => '昂著述',
+'明白帳' => '明白账',
+'映著' => '映着',
+'映著書' => '映著书',
+'映著作' => '映著作',
+'映著名' => '映著名',
+'映著錄' => '映著录',
+'映著稱' => '映著称',
+'映著者' => '映著者',
+'映著述' => '映著述',
+'顯示卡' => '显卡',
+'显著' => '显著',
+'顯著' => '显著',
+'晃著' => '晃着',
+'晃著作' => '晃著作',
+'晃著名' => '晃著名',
+'晃著錄' => '晃著录',
+'晃著稱' => '晃著称',
+'晃著者' => '晃著者',
+'晃著述' => '晃著述',
+'普利茲' => '普利策',
+'蒲美蓬' => '普密蓬',
+'蒲朗克' => '普朗克',
+'電晶體' => '晶体管',
+'智慧型' => '智能',
+'智慧卡' => '智能卡',
+'智慧手機' => '智能手机',
+'暗著' => '暗着',
+'暗著書' => '暗著书',
+'暗著作' => '暗著作',
+'暗著名' => '暗著名',
+'暗著錄' => '暗著录',
+'暗著稱' => '暗著称',
+'暗著者' => '暗著者',
+'暗著述' => '暗著述',
+'有著' => '有着',
+'有著書' => '有著书',
+'有著作' => '有著作',
+'有著名' => '有著名',
+'有著錄' => '有著录',
+'有著稱' => '有著称',
+'有著者' => '有著者',
+'有著述' => '有著述',
+'伺服器' => '服务器',
+'望著' => '望着',
+'望著作' => '望著作',
+'望著名' => '望著名',
+'望著錄' => '望著录',
+'望著稱' => '望著称',
+'望著者' => '望著者',
+'望著述' => '望著述',
+'朝著' => '朝着',
+'朝著作' => '朝著作',
+'朝著名' => '朝著名',
+'朝著錄' => '朝著录',
+'朝著稱' => '朝著称',
+'朝著者' => '朝著者',
+'朝著述' => '朝著述',
+'賓·拉登' => '本·拉登',
+'本份' => '本分',
+'賓拉登' => '本拉登',
+'本本份份' => '本本分分',
+'班傑明' => '本杰明',
+'本著' => '本着',
+'本著書' => '本著书',
+'本著作' => '本著作',
+'本著名' => '本著名',
+'本著錄' => '本著录',
+'本著稱' => '本著称',
+'本著者' => '本著者',
+'本著述' => '本著述',
+'本帳' => '本账',
+'機械人' => '机器人',
+'工具機' => '机床',
+'殺著' => '杀着',
+'殺著書' => '杀著书',
+'殺著作' => '杀著作',
+'殺著名' => '杀著名',
+'殺著錄' => '杀著录',
+'殺著稱' => '杀著称',
+'殺著者' => '杀著者',
+'殺著述' => '杀著述',
+'雜著' => '杂着',
+'雜著書' => '杂著书',
+'雜著作' => '杂著作',
+'雜著名' => '杂著名',
+'雜著錄' => '杂著录',
+'雜著稱' => '杂著称',
+'雜著者' => '杂著者',
+'雜著述' => '杂著述',
+'杜塞道夫' => '杜塞尔多夫',
+'來著' => '来着',
+'來著書' => '来著书',
+'來著作' => '来著作',
+'來著名' => '来著名',
+'來著錄' => '来著录',
+'來著稱' => '来著称',
+'來著者' => '来著者',
+'來著述' => '来著述',
+'板著臉' => '板着脸',
+'枕著' => '枕着',
+'枕著作' => '枕著作',
+'枕著名' => '枕著名',
+'枕著錄' => '枕著录',
+'枕著稱' => '枕著称',
+'枕著者' => '枕著者',
+'枕著述' => '枕著述',
+'槍枝' => '枪支',
+'柏林圍牆' => '柏林墙',
+'查帳' => '查账',
+'查維茲' => '查韦斯',
+'標志著' => '标志着',
+'標誌著' => '标志着',
+'格瑞那達' => '格林纳达',
+'格林美獎' => '格莱美奖',
+'葛萊美獎' => '格莱美奖',
+'森巴舞' => '桑巴舞',
+'梅赫西迪' => '梅赛德斯',
+'夢著' => '梦着',
+'夢著書' => '梦著书',
+'夢著作' => '梦著作',
+'夢著名' => '梦著名',
+'夢著錄' => '梦著录',
+'夢著稱' => '梦著称',
+'夢著者' => '梦著者',
+'夢著述' => '梦著述',
+'梳著' => '梳着',
+'梳著作' => '梳著作',
+'梳著名' => '梳著名',
+'梳著錄' => '梳著录',
+'梳著稱' => '梳著称',
+'梳著者' => '梳著者',
+'梳著述' => '梳著述',
+'梵谷' => '梵高',
+'機率' => '概率',
+'欠帳' => '欠账',
+'死帳' => '死账',
+'庇里牛斯' => '比利牛斯',
+'畢卡索' => '毕加索',
+'茅利塔尼亞' => '毛里塔尼亚',
+'模里西斯' => '毛里求斯',
+'毛里裘斯' => '毛里求斯',
+'公厘' => '毫米',
+'公釐' => '毫米',
+'氧份' => '氧分',
+'胺基酸' => '氨基酸',
+'水份' => '水分',
+'水氣' => '水汽',
+'求著' => '求着',
+'求著書' => '求著书',
+'求著作' => '求著作',
+'求著名' => '求著名',
+'求著錄' => '求著录',
+'求著稱' => '求著称',
+'求著者' => '求著者',
+'求著述' => '求著述',
+'漢諾瓦' => '汉诺威',
+'沈著' => '沉着',
+'沉著' => '沉着',
+'沉著書' => '沉著书',
+'沉著作' => '沉著作',
+'沉著名' => '沉著名',
+'沉著錄' => '沉著录',
+'沉著稱' => '沉著称',
+'沉著者' => '沉著者',
+'沉著述' => '沉著述',
+'沙地阿拉伯' => '沙特阿拉伯',
+'沙烏地阿拉伯' => '沙特阿拉伯',
+'沿著' => '沿着',
+'沿著書' => '沿著书',
+'沿著作' => '沿著作',
+'沿著名' => '沿著名',
+'沿著錄' => '沿著录',
+'沿著稱' => '沿著称',
+'沿著者' => '沿著者',
+'沿著述' => '沿著述',
+'玻里尼西亞' => '波利尼西亚',
+'波士尼亞' => '波斯尼亚',
+'波士尼亞赫塞哥維納' => '波斯尼亚和黑塞哥维那',
+'鐵達尼號' => '泰坦尼克号',
+'幫浦' => '泵',
+'辛巴威' => '津巴布韦',
+'宏都拉斯' => '洪都拉斯',
+'活著' => '活着',
+'活著書' => '活著书',
+'活著作' => '活著作',
+'活著名' => '活著名',
+'活著錄' => '活著录',
+'活著稱' => '活著称',
+'活著者' => '活著者',
+'活著述' => '活著述',
+'流水帳' => '流水账',
+'流著' => '流着',
+'流著書' => '流著书',
+'流著作' => '流著作',
+'流著名' => '流著名',
+'流著錄' => '流著录',
+'流著稱' => '流著称',
+'流著者' => '流著者',
+'流著述' => '流著述',
+'流露著' => '流露着',
+'浮著' => '浮着',
+'蘭卡威' => '浮罗交怡',
+'浮著書' => '浮著书',
+'浮著作' => '浮著作',
+'浮著名' => '浮著名',
+'浮著錄' => '浮著录',
+'浮著稱' => '浮著称',
+'浮著者' => '浮著者',
+'浮著述' => '浮著述',
+'海洛英' => '海洛因',
+'海浬' => '海里',
+'塗著' => '涂着',
+'潤著' => '润着',
+'潤著書' => '润著书',
+'潤著作' => '润著作',
+'潤著名' => '润著名',
+'潤著錄' => '润著录',
+'潤著稱' => '润著称',
+'潤著者' => '润著者',
+'潤著述' => '润著述',
+'混帳' => '混账',
+'清澈' => '清澈',
+'清帳' => '清账',
+'渴著' => '渴着',
+'渴著書' => '渴著书',
+'渴著作' => '渴著作',
+'渴著名' => '渴著名',
+'渴著錄' => '渴著录',
+'渴著稱' => '渴著称',
+'渴著者' => '渴著者',
+'渴著述' => '渴著述',
+'原始碼' => '源代码',
+'溢著' => '溢着',
+'溢著書' => '溢著书',
+'溢著作' => '溢著作',
+'溢著名' => '溢著名',
+'溢著錄' => '溢著录',
+'溢著稱' => '溢著称',
+'溢著者' => '溢著者',
+'溢著述' => '溢著述',
+'滑鼠蛇' => '滑鼠蛇',
+'滿16進位' => '满16进位',
+'滿二進位' => '满二进位',
+'滿八進位' => '满八进位',
+'滿六進位' => '满六进位',
+'滿十六進位' => '满十六进位',
+'滿十進位' => '满十进位',
+'滿著' => '满着',
+'滿著作' => '满著作',
+'滿著名' => '满著名',
+'滿著者' => '满著者',
+'演著' => '演着',
+'演著書' => '演著书',
+'演著作' => '演著作',
+'演著名' => '演著名',
+'演著錄' => '演著录',
+'演著稱' => '演著称',
+'演著者' => '演著者',
+'演著述' => '演著述',
+'漫著' => '漫着',
+'漫著書' => '漫著书',
+'漫著作' => '漫著作',
+'漫著名' => '漫著名',
+'漫著錄' => '漫著录',
+'漫著稱' => '漫著称',
+'漫著者' => '漫著者',
+'漫著述' => '漫著述',
+'雷射' => '激光',
+'點著' => '点着',
+'點著作' => '点著作',
+'點著名' => '点著名',
+'點著錄' => '点著录',
+'點著稱' => '点著称',
+'點著者' => '点著者',
+'點著述' => '点著述',
+'爛帳' => '烂账',
+'燒著' => '烧着',
+'燒著作' => '烧著作',
+'燒著名' => '烧著名',
+'燒著錄' => '烧著录',
+'燒著稱' => '烧著称',
+'燒著者' => '烧著者',
+'燒著述' => '烧著述',
+'照著' => '照着',
+'照著書' => '照著书',
+'照著作' => '照著作',
+'照著名' => '照著名',
+'照著錄' => '照著录',
+'照著稱' => '照著称',
+'照著者' => '照著者',
+'照著述' => '照著述',
+'愛護著' => '爱护着',
+'愛著' => '爱着',
+'愛著書' => '爱著书',
+'愛著作' => '爱著作',
+'愛著名' => '爱著名',
+'愛著錄' => '爱著录',
+'愛著稱' => '爱著称',
+'愛著者' => '爱著者',
+'愛著述' => '爱著述',
+'牽著' => '牵着',
+'牽著書' => '牵著书',
+'牽著作' => '牵著作',
+'牽著名' => '牵著名',
+'牽著錄' => '牵著录',
+'牽著稱' => '牵著称',
+'牽著者' => '牵著者',
+'牽著述' => '牵著述',
+'千里達' => '特立尼达',
+'千里達及托巴哥' => '特立尼达和多巴哥',
+'千里達托貝哥' => '特立尼达和托巴哥',
+'狗隻' => '犬只',
+'猶豫著' => '犹豫着',
+'獨立國家國協' => '独立国家联合体',
+'獨立國協' => '独联体',
+'猜著' => '猜着',
+'猜著書' => '猜着书',
+'猜著作' => '猜著作',
+'猜著名' => '猜著名',
+'猜著錄' => '猜著录',
+'猜著稱' => '猜著称',
+'猜著者' => '猜著者',
+'猜著述' => '猜著述',
+'玩著' => '玩着',
+'班固著' => '班固著',
+'溫納圖' => '瓦努阿图',
+'萬那杜' => '瓦努阿图',
+'華勒沙' => '瓦文萨',
+'華里沙' => '瓦文萨',
+'甜著' => '甜着',
+'甜著書' => '甜著书',
+'甜著作' => '甜著作',
+'甜著名' => '甜著名',
+'甜著錄' => '甜著录',
+'甜著稱' => '甜著称',
+'甜著者' => '甜著者',
+'甜著述' => '甜著述',
+'用著' => '用着',
+'用著書' => '用著书',
+'用著作' => '用著作',
+'用著名' => '用著名',
+'用著錄' => '用著录',
+'用著稱' => '用著称',
+'用著者' => '用著者',
+'用著述' => '用著述',
+'A型肝炎' => '甲型肝炎',
+'A肝' => '甲肝',
+'電視劇集' => '电视剧',
+'電視影集' => '电视系列剧',
+'畫著' => '画着',
+'畫著作' => '画著作',
+'畫著名' => '画著名',
+'畫著稱' => '画著称',
+'畫著者' => '画著者',
+'介面' => '界面',
+'留著' => '留着',
+'留著書' => '留着书',
+'留著作' => '留著作',
+'留著名' => '留著名',
+'留著錄' => '留著录',
+'留著稱' => '留著称',
+'留著者' => '留著者',
+'留著述' => '留著述',
+'疑著' => '疑着',
+'疑著書' => '疑著书',
+'疑著作' => '疑著作',
+'疑著名' => '疑著名',
+'疑著錄' => '疑著录',
+'疑著稱' => '疑著称',
+'疑著者' => '疑著者',
+'疑著述' => '疑著述',
+'狂牛症' => '疯牛病',
+'徵狀' => '症状',
+'百慕達' => '百慕大',
+'皮雅斯·布士南' => '皮尔斯·布鲁斯南',
+'皺著' => '皱着',
+'皺著書' => '皱著书',
+'皺著作' => '皱著作',
+'皺著名' => '皱著名',
+'皺著錄' => '皱著录',
+'皺著稱' => '皱著称',
+'皺著者' => '皱著者',
+'皺著述' => '皱著述',
+'鹽份' => '盐分',
+'蓋著' => '盖着',
+'蓋著作' => '盖著作',
+'蓋著名' => '盖著名',
+'蓋著稱' => '盖著称',
+'盛著' => '盛着',
+'盛著書' => '盛著书',
+'盛著作' => '盛著作',
+'盛著名' => '盛著名',
+'盛著錄' => '盛著录',
+'盛著稱' => '盛著称',
+'盛著者' => '盛著者',
+'盛著述' => '盛著述',
+'盯著' => '盯着',
+'盯著書' => '盯着书',
+'盯著作' => '盯著作',
+'盯著名' => '盯著名',
+'盯著錄' => '盯著录',
+'盯著稱' => '盯著称',
+'盯著者' => '盯著者',
+'盯著述' => '盯著述',
+'看著' => '看着',
+'看著書' => '看着书',
+'看著作' => '看著作',
+'看著名' => '看著名',
+'看著錄' => '看著录',
+'看著稱' => '看著称',
+'看著者' => '看著者',
+'看著述' => '看著述',
+'著業' => '着业',
+'著絲' => '着丝',
+'著麼' => '着么',
+'著人' => '着人',
+'著什麼' => '着什么',
+'著甚麽' => '着什么',
+'著他' => '着他',
+'著令' => '着令',
+'著位' => '着位',
+'著體' => '着体',
+'著你' => '着你',
+'著便' => '着便',
+'著涼' => '着凉',
+'著力' => '着力',
+'著勁' => '着劲',
+'著號' => '着号',
+'著呢' => '着呢',
+'著哩' => '着哩',
+'著地' => '着地',
+'著墨' => '着墨',
+'著聲' => '着声',
+'著處' => '着处',
+'著她' => '着她',
+'著妳' => '着妳',
+'著姓' => '着姓',
+'著它' => '着它',
+'著定' => '着定',
+'著實' => '着实',
+'著己' => '着己',
+'著帳' => '着帐',
+'著床' => '着床',
+'著庸' => '着庸',
+'著式' => '着式',
+'著錄' => '着录',
+'著心' => '着心',
+'著志' => '着志',
+'著忙' => '着忙',
+'著急' => '着急',
+'著惱' => '着恼',
+'著驚' => '着惊',
+'著想' => '着想',
+'著意' => '着意',
+'著慌' => '着慌',
+'著我' => '着我',
+'著手' => '着手',
+'著抹' => '着抹',
+'著摸' => '着摸',
+'著撰' => '着撰',
+'著數' => '着数',
+'著明' => '着明',
+'著末' => '着末',
+'著極' => '着极',
+'著格' => '着格',
+'著棋' => '着棋',
+'著氣' => '着气',
+'著法' => '着法',
+'著淺' => '着浅',
+'著火' => '着火',
+'著然' => '着然',
+'著甚' => '着甚',
+'著生' => '着生',
+'著疑' => '着疑',
+'著白' => '着白',
+'著相' => '着相',
+'著眼' => '着眼',
+'著著' => '着着',
+'著祂' => '着祂',
+'著積' => '着积',
+'著稿' => '着稿',
+'著筆' => '着笔',
+'著籍' => '着籍',
+'著緊' => '着紧',
+'著緑' => '着緑',
+'著絆' => '着绊',
+'著績' => '着绩',
+'著緋' => '着绯',
+'著綠' => '着绿',
+'著肉' => '着肉',
+'著腳' => '着脚',
+'著艦' => '着舰',
+'著色' => '着色',
+'著節' => '着节',
+'著花' => '着花',
+'著莫' => '着莫',
+'著落' => '着落',
+'著槁' => '着藁',
+'著衣' => '着衣',
+'著裝' => '着装',
+'著要' => '着要',
+'著警' => '着警',
+'著趣' => '着趣',
+'著邊' => '着边',
+'著迷' => '着迷',
+'著跡' => '着迹',
+'著重' => '着重',
+'著録' => '着録',
+'著聞' => '着闻',
+'著陸' => '着陆',
+'著雝' => '着雝',
+'著鞭' => '着鞭',
+'著題' => '着题',
+'著魔' => '着魔',
+'睡著' => '睡着',
+'睡著書' => '睡著书',
+'睡著作' => '睡著作',
+'睡著名' => '睡著名',
+'睡著錄' => '睡著录',
+'睡著稱' => '睡著称',
+'睡著者' => '睡著者',
+'睡著述' => '睡著述',
+'瞞著' => '瞒着',
+'瞞著書' => '瞒著书',
+'瞞著作' => '瞒著作',
+'瞞著名' => '瞒著名',
+'瞞著錄' => '瞒著录',
+'瞞著稱' => '瞒著称',
+'瞞著者' => '瞒著者',
+'瞞著述' => '瞒著述',
+'瞧著' => '瞧着',
+'瞧著書' => '瞧着书',
+'瞧著作' => '瞧著作',
+'瞧著名' => '瞧著名',
+'瞧著錄' => '瞧著录',
+'瞧著稱' => '瞧著称',
+'瞧著者' => '瞧著者',
+'瞧著述' => '瞧著述',
+'瞪著' => '瞪着',
+'瞪著書' => '瞪著书',
+'瞪著作' => '瞪著作',
+'瞪著名' => '瞪著名',
+'瞪著錄' => '瞪著录',
+'瞪著稱' => '瞪著称',
+'瞪著者' => '瞪著者',
+'瞪著述' => '瞪著述',
+'矛盾著' => '矛盾着',
+'智慧財產權' => '知识产权',
+'智財權' => '知识产权',
+'知識份子' => '知识分子',
+'什勒斯維希' => '石勒苏益格',
+'矽塵' => '矽尘',
+'矽尘' => '矽尘',
+'矽肺' => '矽肺',
+'矽鋼' => '矽钢',
+'矽钢' => '矽钢',
+'矽' => '硅',
+'矽片' => '硅片',
+'矽谷' => '硅谷',
+'硬體' => '硬件',
+'硬碟' => '硬盘',
+'磁碟' => '磁盘',
+'磁軌' => '磁道',
+'福馬林' => '福尔马林',
+'福著' => '福着',
+'福著書' => '福著书',
+'福著作' => '福著作',
+'福著名' => '福著名',
+'福著錄' => '福著录',
+'福著稱' => '福著称',
+'福著者' => '福著者',
+'福著述' => '福著述',
+'私帳' => '私账',
+'葛摩' => '科摩罗',
+'象牙海岸' => '科特迪瓦',
+'積極份子' => '积极分子',
+'流動電話' => '移动电话',
+'行動電話' => '移动电话',
+'流動網絡' => '移动网络',
+'行動網路' => '移动网络',
+'程式設計師' => '程序员',
+'程式控制' => '程控',
+'空中巴士' => '空中客车',
+'空氣品質' => '空气质量',
+'空氣質素' => '空气质量',
+'空著' => '空着',
+'空著書' => '空著书',
+'空著作' => '空著作',
+'空著名' => '空著名',
+'空著錄' => '空著录',
+'空著稱' => '空著称',
+'空著者' => '空著者',
+'空著述' => '空著述',
+'穿著' => '穿着',
+'穿著書' => '穿著书',
+'穿著作' => '穿著作',
+'穿著名' => '穿著名',
+'穿著錄' => '穿著录',
+'穿著稱' => '穿著称',
+'穿著者' => '穿著者',
+'穿著述' => '穿著述',
+'突尼西亞' => '突尼斯',
+'立著' => '立着',
+'立著《' => '立著《',
+'立著作' => '立著作',
+'立著名' => '立著名',
+'立著有' => '立著有',
+'立著称' => '立著称',
+'立著稱' => '立著称',
+'立著者' => '立著者',
+'立著(' => '立著(',
+'豎著' => '竖着',
+'豎著書' => '竖著书',
+'豎著作' => '竖著作',
+'豎著名' => '竖著名',
+'豎著錄' => '竖著录',
+'豎著稱' => '竖著称',
+'豎著者' => '竖著者',
+'豎著述' => '竖著述',
+'站著' => '站着',
+'站著書' => '站著书',
+'站著作' => '站著作',
+'站著名' => '站著名',
+'站著錄' => '站著录',
+'站著稱' => '站著称',
+'站著者' => '站著者',
+'站著述' => '站著述',
+'笑著' => '笑着',
+'笑著書' => '笑著书',
+'笑著作' => '笑著作',
+'笑著名' => '笑著名',
+'笑著錄' => '笑著录',
+'笑著稱' => '笑著称',
+'笑著者' => '笑著者',
+'笑著述' => '笑著述',
+'筆帳' => '笔账',
+'提比里西' => '第比利斯',
+'簽著' => '签着',
+'簽帳' => '签账',
+'運算元' => '算子',
+'演算法' => '算法',
+'算帳' => '算账',
+'管著' => '管着',
+'管著書' => '管著书',
+'管著作' => '管著作',
+'管著名' => '管著名',
+'管著錄' => '管著录',
+'管著稱' => '管著称',
+'管著者' => '管著者',
+'管著述' => '管著述',
+'管帳' => '管账',
+'公尺' => '米',
+'糊塗帳' => '糊涂账',
+'糖份' => '糖分',
+'動畫影集' => '系列动画片',
+'繫著' => '系着',
+'索忍尼辛' => '索尔仁尼琴',
+'索贊尼辛' => '索尔仁尼琴',
+'蘇辛尼津' => '索尔仁尼琴',
+'索馬利亞' => '索马里',
+'索馬利蘭' => '索马里兰',
+'正體中文' => '繁体中文',
+'強斯頓環礁' => '约翰斯顿岛',
+'縱著' => '纵着',
+'組份' => '组分',
+'經常帳' => '经常账',
+'經濟帳' => '经济账',
+'綁著' => '绑着',
+'綁著書' => '绑著书',
+'綁著作' => '绑著作',
+'綁著名' => '绑著名',
+'綁著錄' => '绑著录',
+'綁著稱' => '绑著称',
+'綁著者' => '绑著者',
+'綁著述' => '绑著述',
+'結帳' => '结账',
+'繞著' => '绕着',
+'繞著書' => '绕著书',
+'繞著作' => '绕著作',
+'繞著名' => '绕著名',
+'繞著錄' => '绕著录',
+'繞著稱' => '绕著称',
+'繞著者' => '绕著者',
+'繞著述' => '绕著述',
+'維根斯坦' => '维特根斯坦',
+'繃著' => '绷着',
+'緣份' => '缘分',
+'纏著' => '缠着',
+'纏著書' => '缠著书',
+'纏著作' => '缠著作',
+'纏著名' => '缠著名',
+'纏著錄' => '缠著录',
+'纏著稱' => '缠著称',
+'纏著者' => '缠著者',
+'纏著述' => '缠著述',
+'網站連結' => '网站链接',
+'網路' => '网络',
+'網頁連結' => '网页链接',
+'罩著' => '罩着',
+'罩著書' => '罩著书',
+'罩著作' => '罩著作',
+'罩著名' => '罩著名',
+'罩著錄' => '罩著录',
+'罩著稱' => '罩著称',
+'罩著者' => '罩著者',
+'罩著述' => '罩著述',
+'美著' => '美着',
+'美著書' => '美著书',
+'美著作' => '美著作',
+'美著名' => '美著名',
+'美著錄' => '美著录',
+'美著称' => '美著称',
+'美著稱' => '美著称',
+'美著者' => '美著者',
+'美著述' => '美著述',
+'耀著' => '耀着',
+'耀著書' => '耀著书',
+'耀著作' => '耀著作',
+'耀著名' => '耀著名',
+'耀著錄' => '耀著录',
+'耀著稱' => '耀著称',
+'耀著者' => '耀著者',
+'耀著述' => '耀著述',
+'寮國' => '老挝',
+'寮人民民主共和國' => '老挝人民民主共和国',
+'寮語' => '老挝语',
+'考著' => '考着',
+'考著書' => '考著书',
+'考著作' => '考著作',
+'考著名' => '考著名',
+'考著錄' => '考著录',
+'考著稱' => '考著称',
+'考著者' => '考著者',
+'考著述' => '考著述',
+'職份' => '职分',
+'辛康納利' => '肖恩·康纳利',
+'蕭士塔高維奇' => '肖斯塔科维奇',
+'蕭士達高維契' => '肖斯塔科维奇',
+'甘迺迪' => '肯尼迪',
+'背著' => '背着',
+'背著書' => '背著书',
+'背著作' => '背著作',
+'背著名' => '背著名',
+'背著錄' => '背著录',
+'背著稱' => '背著称',
+'背著者' => '背著者',
+'背著述' => '背著述',
+'膠著' => '胶着',
+'膠著書' => '胶著书',
+'膠著作' => '胶著作',
+'膠著名' => '胶著名',
+'膠著錄' => '胶著录',
+'膠著稱' => '胶著称',
+'膠著者' => '胶著者',
+'膠著述' => '胶著述',
+'舒麥加' => '舒马赫',
+'太空梭' => '航天飞机',
+'穿梭機' => '航天飞机',
+'愛滋' => '艾滋',
+'晶元' => '芯片',
+'晶片' => '芯片',
+'蘇利南' => '苏里南',
+'苦著' => '苦着',
+'苦著書' => '苦著书',
+'苦著作' => '苦著作',
+'苦著名' => '苦著名',
+'苦著錄' => '苦著录',
+'苦著稱' => '苦著称',
+'苦著者' => '苦著者',
+'苦著述' => '苦著述',
+'英吋' => '英寸',
+'英呎' => '英尺',
+'共和联邦' => '英联邦',
+'大英國協' => '英联邦',
+'士多啤梨' => '草莓',
+'螢光棒' => '荧光棒',
+'螢屏' => '荧屏',
+'霍爾斯坦' => '荷尔斯泰因',
+'莫三比克' => '莫桑比克',
+'雷伊泰灣' => '莱特湾',
+'賴索托' => '莱索托',
+'獲著' => '获着',
+'穫著' => '获着',
+'獲著書' => '获著书',
+'獲著作' => '获著作',
+'獲著名' => '获著名',
+'獲著錄' => '获著录',
+'獲著稱' => '获著称',
+'獲著者' => '获著者',
+'獲著述' => '获著述',
+'塞拉耶佛' => '萨拉热窝',
+'落著' => '落着',
+'落著書' => '落著书',
+'落著作' => '落著作',
+'落著名' => '落著名',
+'落著錄' => '落著录',
+'落著稱' => '落著称',
+'落著者' => '落著者',
+'落著述' => '落著述',
+'滿地可' => '蒙特利尔',
+'蒙特婁' => '蒙特利尔',
+'蒙著' => '蒙着',
+'蒙著書' => '蒙著书',
+'蒙著作' => '蒙著作',
+'蒙著名' => '蒙著名',
+'蒙著錄' => '蒙著录',
+'蒙著稱' => '蒙著称',
+'蒙著者' => '蒙著者',
+'蒙著述' => '蒙著述',
+'藍芽' => '蓝牙',
+'蘊涵著' => '蕴涵着',
+'薛丁格' => '薛定谔',
+'藏著' => '藏着',
+'藏著書' => '藏著书',
+'藏著作' => '藏著作',
+'藏著名' => '藏著名',
+'藏著錄' => '藏著录',
+'藏著稱' => '藏著称',
+'藏著者' => '藏著者',
+'藏著述' => '藏著述',
+'蘸著' => '蘸着',
+'蘸著書' => '蘸著书',
+'蘸著作' => '蘸著作',
+'蘸著名' => '蘸著名',
+'蘸著錄' => '蘸著录',
+'蘸著稱' => '蘸著称',
+'蘸著者' => '蘸著者',
+'蘸著述' => '蘸著述',
+'行人路权' => '行人路权',
+'行人路權' => '行人路权',
+'行著' => '行着',
+'行著書' => '行著书',
+'行著作' => '行著作',
+'行著名' => '行著名',
+'行著錄' => '行著录',
+'行著稱' => '行著称',
+'行著者' => '行著者',
+'行著述' => '行著述',
+'衣著' => '衣着',
+'衣著書' => '衣著书',
+'衣著作' => '衣著作',
+'衣著名' => '衣著名',
+'衣著錄' => '衣著录',
+'衣著称' => '衣著称',
+'衣著稱' => '衣著称',
+'衣著者' => '衣著者',
+'衣著述' => '衣著述',
+'表姊' => '表姐',
+'裝著' => '装着',
+'裝著書' => '装著书',
+'裝著作' => '装著作',
+'裝著名' => '装著名',
+'裝著錄' => '装著录',
+'裝著稱' => '装著称',
+'裝著者' => '装著者',
+'裝著述' => '装著述',
+'裹著' => '裹着',
+'裹著書' => '裹著书',
+'裹著作' => '裹著作',
+'裹著名' => '裹著名',
+'裹著錄' => '裹著录',
+'裹著稱' => '裹著称',
+'裹著者' => '裹著者',
+'裹著述' => '裹著述',
+'要帳' => '要账',
+'覆蓋著' => '覆盖着',
+'覆著' => '覆着',
+'見著' => '见着',
+'見著書' => '见著书',
+'見著作' => '见著作',
+'見著名' => '见著名',
+'見著錄' => '见著录',
+'見著稱' => '见著称',
+'見著者' => '见著者',
+'見著述' => '见著述',
+'規畫' => '规划',
+'視著' => '视着',
+'視著名' => '视著名',
+'占士邦' => '詹姆斯·邦德',
+'警戒著' => '警戒着',
+'計畫' => '计划',
+'電腦程式' => '计算机程序',
+'認帳' => '认账',
+'記著' => '记着',
+'記著書' => '记著书',
+'記著作' => '记著作',
+'記著名' => '记著名',
+'記著錄' => '记著录',
+'記著稱' => '记著称',
+'記著者' => '记著者',
+'記著述' => '记著述',
+'記帳' => '记账',
+'片語' => '词组',
+'試著' => '试着',
+'試著書' => '试著书',
+'試著作' => '试著作',
+'試著名' => '试著名',
+'試著錄' => '试著录',
+'試著稱' => '试著称',
+'試著者' => '试著者',
+'試著述' => '试著述',
+'語著' => '语着',
+'語著書' => '语著书',
+'語著作' => '语著作',
+'語著名' => '语著名',
+'語著錄' => '语著录',
+'語著稱' => '语著称',
+'語著者' => '语著者',
+'語著述' => '语著述',
+'說著' => '说着',
+'說著作' => '说著作',
+'說著稱' => '说著称',
+'說著者' => '说著者',
+'說著述' => '说著述',
+'諾曼第' => '诺曼底',
+'數據機' => '调制解调器',
+'象徵著' => '象征着',
+'象徵著名' => '象征著名',
+'碧咸' => '贝克汉姆',
+'貝爾格勒' => '贝尔格莱德',
+'負著' => '负着',
+'貢寮' => '贡寮',
+'帳上' => '账上',
+'帳冊' => '账册',
+'帳務' => '账务',
+'帳單' => '账单',
+'帳號' => '账号',
+'帳外' => '账外',
+'帳戶' => '账户',
+'帳房' => '账房',
+'帳本' => '账本',
+'帳款' => '账款',
+'帳目' => '账目',
+'帳簿' => '账簿',
+'帳面' => '账面',
+'賒帳' => '赊账',
+'賴帳' => '赖账',
+'尚比亞' => '赞比亚',
+'西臺人' => '赫梯人',
+'西臺國' => '赫梯国',
+'西臺帝' => '赫梯帝',
+'西臺文' => '赫梯文',
+'西臺族' => '赫梯族',
+'西臺王' => '赫梯王',
+'西臺語' => '赫梯语',
+'赫魯雪夫' => '赫鲁晓夫',
+'走為上著' => '走为上着',
+'走著' => '走着',
+'走著書' => '走著书',
+'走著作' => '走著作',
+'走著名' => '走著名',
+'走著錄' => '走著录',
+'走著稱' => '走著称',
+'走著者' => '走著者',
+'走著述' => '走著述',
+'趕著' => '赶着',
+'趕著書' => '赶著书',
+'趕著作' => '赶著作',
+'趕著名' => '赶著名',
+'趕著錄' => '赶著录',
+'趕著稱' => '赶著称',
+'趕著者' => '赶著者',
+'趕著述' => '赶著述',
+'超連結' => '超链接',
+'趴著' => '趴着',
+'趴著書' => '趴著书',
+'趴著作' => '趴著作',
+'趴著名' => '趴著名',
+'趴著錄' => '趴著录',
+'趴著稱' => '趴著称',
+'趴著者' => '趴著者',
+'趴著述' => '趴著述',
+'躍著' => '跃着',
+'躍著書' => '跃著书',
+'躍著作' => '跃著作',
+'躍著名' => '跃著名',
+'躍著錄' => '跃著录',
+'躍著稱' => '跃著称',
+'躍著者' => '跃著者',
+'躍著述' => '跃著述',
+'跑著' => '跑着',
+'跑著書' => '跑著书',
+'跑著作' => '跑著作',
+'跑著名' => '跑著名',
+'跑著錄' => '跑著录',
+'跑著稱' => '跑著称',
+'跑著者' => '跑著者',
+'跑著述' => '跑著述',
+'跟著' => '跟着',
+'跟著書' => '跟著书',
+'跟著作' => '跟著作',
+'跟著名' => '跟著名',
+'跟著錄' => '跟著录',
+'跟著稱' => '跟著称',
+'跟著者' => '跟著者',
+'跟著述' => '跟著述',
+'跪著' => '跪着',
+'跪著書' => '跪著书',
+'跪著作' => '跪著作',
+'跪著名' => '跪著名',
+'跪著錄' => '跪著录',
+'跪著稱' => '跪著称',
+'跪著者' => '跪著者',
+'跪著述' => '跪著述',
+'跳著' => '跳着',
+'跳著書' => '跳著书',
+'跳著作' => '跳著作',
+'跳著名' => '跳著名',
+'跳著錄' => '跳著录',
+'跳著稱' => '跳著称',
+'跳著者' => '跳著者',
+'跳著述' => '跳著述',
+'踏著' => '踏着',
+'踏著書' => '踏著书',
+'踏著作' => '踏著作',
+'踏著名' => '踏著名',
+'踏著錄' => '踏著录',
+'踏著稱' => '踏著称',
+'踏著者' => '踏著者',
+'踏著述' => '踏著述',
+'踩著' => '踩着',
+'踩著書' => '踩著书',
+'踩著作' => '踩著作',
+'踩著名' => '踩著名',
+'踩著錄' => '踩著录',
+'踩著稱' => '踩著称',
+'踩著者' => '踩著者',
+'踩著述' => '踩著述',
+'笨豬跳' => '蹦极跳',
+'绑紧跳' => '蹦极跳',
+'身分' => '身份',
+'身著' => '身着',
+'身著書' => '身著书',
+'身著作' => '身著作',
+'身著名' => '身著名',
+'身著錄' => '身著录',
+'身著稱' => '身著称',
+'身著者' => '身著者',
+'身著述' => '身著述',
+'躺著' => '躺着',
+'躺著書' => '躺著书',
+'躺著作' => '躺著作',
+'躺著名' => '躺著名',
+'躺著錄' => '躺著录',
+'躺著稱' => '躺著称',
+'躺著者' => '躺著者',
+'躺著述' => '躺著述',
+'轉著' => '转着',
+'轉著書' => '转著书',
+'轉著作' => '转著作',
+'轉著名' => '转著名',
+'轉著錄' => '转著录',
+'轉著稱' => '转著称',
+'轉著者' => '转著者',
+'轉著述' => '转著述',
+'轉帳' => '转账',
+'軟體' => '软件',
+'軟體動物' => '软体动物',
+'軟體家具' => '软体家具',
+'軟碟機' => '软驱',
+'載著' => '载着',
+'載著書' => '载著书',
+'載著作' => '载著作',
+'載著名' => '载著名',
+'載著錄' => '载著录',
+'載著稱' => '载著称',
+'載著者' => '载著者',
+'載著述' => '载著述',
+'達·文西' => '达·芬奇',
+'達著' => '达着',
+'三蘭港' => '达累斯萨拉姆',
+'達文西' => '达芬奇',
+'達著書' => '达著书',
+'達著作' => '达著作',
+'達著名' => '达著名',
+'達著錄' => '达著录',
+'達著稱' => '达著称',
+'達著者' => '达著者',
+'達著述' => '达著述',
+'過份' => '过分',
+'過著' => '过着',
+'過著作' => '过著作',
+'過著名' => '过著名',
+'過著錄' => '过著录',
+'過著稱' => '过著称',
+'過著者' => '过著者',
+'過著述' => '过著述',
+'米高·奧雲' => '迈克尔·欧文',
+'還帳' => '还账',
+'演化論' => '进化论',
+'進帳' => '进账',
+'連著' => '连着',
+'連結他' => '连结他',
+'連著書' => '连著书',
+'連著作' => '连著作',
+'連著名' => '连著名',
+'連著錄' => '连著录',
+'連著稱' => '连著称',
+'連著者' => '连著者',
+'連著述' => '连著述',
+'杜拜' => '迪拜',
+'迫著' => '迫着',
+'疊代' => '迭代',
+'追著' => '追着',
+'追著書' => '追著书',
+'追著作' => '追著作',
+'追著名' => '追著名',
+'追著錄' => '追著录',
+'追著稱' => '追著称',
+'追著者' => '追著者',
+'追著述' => '追著述',
+'逆著' => '逆着',
+'逆著書' => '逆著书',
+'逆著作' => '逆著作',
+'逆著名' => '逆著名',
+'逆著錄' => '逆著录',
+'逆著稱' => '逆著称',
+'逆著者' => '逆著者',
+'逆著述' => '逆著述',
+'逼著' => '逼着',
+'逼著書' => '逼著书',
+'逼著作' => '逼著作',
+'逼著名' => '逼著名',
+'逼著錄' => '逼著录',
+'逼著稱' => '逼著称',
+'逼著者' => '逼著者',
+'逼著述' => '逼著述',
+'遇著' => '遇着',
+'遇著書' => '遇著书',
+'遇著作' => '遇著作',
+'遇著名' => '遇著名',
+'遇著錄' => '遇著录',
+'遇著称' => '遇著称',
+'遇著稱' => '遇著称',
+'遇著者' => '遇著者',
+'遇著述' => '遇著述',
+'遍佈著' => '遍布着',
+'遍布著' => '遍布着',
+'部份' => '部分',
+'配合著' => '配合着',
+'配合著名' => '配合著名',
+'配著' => '配着',
+'配著書' => '配著书',
+'配著作' => '配著作',
+'配著名' => '配著名',
+'配著錄' => '配著录',
+'配著稱' => '配著称',
+'配著者' => '配著者',
+'配著述' => '配著述',
+'釀著' => '酿着',
+'釀著書' => '酿著书',
+'釀著作' => '酿著作',
+'釀著名' => '酿著名',
+'釀著錄' => '酿著录',
+'釀著稱' => '酿著称',
+'釀著者' => '酿著者',
+'釀著述' => '酿著述',
+'黎克特制' => '里氏',
+'芮氏0' => '里氏0',
+'芮氏1' => '里氏1',
+'芮氏2' => '里氏2',
+'芮氏3' => '里氏3',
+'芮氏4' => '里氏4',
+'芮氏5' => '里氏5',
+'芮氏6' => '里氏6',
+'芮氏7' => '里氏7',
+'芮氏8' => '里氏8',
+'芮氏9' => '里氏9',
+'芮氏地震規模' => '里氏地震规模',
+'芮氏規模' => '里氏震级',
+'金夏沙' => '金沙萨',
+'鈽' => '钚',
+'鍅' => '钫',
+'狄托' => '铁托',
+'卯足' => '铆足',
+'鋪著' => '铺着',
+'鋪著書' => '铺著书',
+'鋪著作' => '铺著作',
+'鋪著名' => '铺著名',
+'鋪著錄' => '铺著录',
+'鋪著稱' => '铺著称',
+'鋪著者' => '铺著者',
+'鋪著述' => '铺著述',
+'鏈結' => '链接',
+'銷帳' => '销账',
+'鉲' => '锎',
+'鎝' => '锝',
+'鉳' => '锫',
+'鑀' => '锿',
+'鋂' => '镅',
+'錼' => '镎',
+'孟德爾遜' => '门德尔松',
+'孟德爾頌' => '门德尔松',
+'快閃記憶體' => '闪存',
+'閉著' => '闭着',
+'閉著書' => '闭著书',
+'閉著作' => '闭著作',
+'閉著名' => '闭著名',
+'閉著錄' => '闭著录',
+'閉著稱' => '闭著称',
+'閉著者' => '闭著者',
+'閉著述' => '闭著述',
+'閑著' => '闲着',
+'閒著' => '闲着',
+'閑著書' => '闲著书',
+'閑著作' => '闲著作',
+'閑著名' => '闲著名',
+'閑著錄' => '闲著录',
+'閑著稱' => '闲著称',
+'閑著者' => '闲著者',
+'閑著述' => '闲著述',
+'悶著' => '闷着',
+'鬧著' => '闹着',
+'聞著' => '闻着',
+'亞塞拜然' => '阿塞拜疆',
+'阿布達比' => '阿布扎比',
+'阿拉伯聯合大公國' => '阿拉伯联合酋长国',
+'亞斯文' => '阿斯旺',
+'附著' => '附着',
+'附著書' => '附著书',
+'附著作' => '附著作',
+'附著名' => '附著名',
+'附著錄' => '附著录',
+'附著稱' => '附著称',
+'附著者' => '附著者',
+'附著述' => '附著述',
+'陋著' => '陋着',
+'陋著書' => '陋著书',
+'陋著作' => '陋著作',
+'陋著名' => '陋著名',
+'陋著錄' => '陋著录',
+'陋著稱' => '陋著称',
+'陋著者' => '陋著者',
+'陋著述' => '陋著述',
+'陪著' => '陪着',
+'陪著書' => '陪著书',
+'陪著作' => '陪著作',
+'陪著名' => '陪著名',
+'陪著錄' => '陪著录',
+'陪著稱' => '陪著称',
+'陪著者' => '陪著者',
+'陪著述' => '陪著述',
+'隨著' => '随着',
+'隨著書' => '随著书',
+'隨著作' => '随著作',
+'隨著名' => '随著名',
+'隨著錄' => '随著录',
+'隨著稱' => '随著称',
+'隨著者' => '随著者',
+'隨著述' => '随著述',
+'私隱' => '隐私',
+'隔著' => '隔着',
+'隔著書' => '隔著书',
+'隔著作' => '隔著作',
+'隔著名' => '隔著名',
+'隔著錄' => '隔著录',
+'隔著稱' => '隔著称',
+'隔著者' => '隔著者',
+'隔著述' => '隔著述',
+'耶加達' => '雅加达',
+'雅爾達' => '雅尔塔',
+'雅著' => '雅着',
+'雅著書' => '雅著书',
+'雅著作' => '雅著作',
+'雅著名' => '雅著名',
+'雅著錄' => '雅著录',
+'雅著称' => '雅著称',
+'雅著稱' => '雅著称',
+'雅著者' => '雅著者',
+'雅著述' => '雅著述',
+'雷諾瓦' => '雷诺阿',
+'荷姆茲' => '霍尔木兹',
+'非份' => '非分',
+'靠著' => '靠着',
+'靠著作' => '靠著作',
+'靠著名' => '靠著名',
+'靠著錄' => '靠著录',
+'靠著稱' => '靠著称',
+'靠著者' => '靠著者',
+'靠著述' => '靠著述',
+'南韓' => '韩国',
+'音樂錄影帶' => '音乐录影带',
+'頂著' => '顶着',
+'頂著書' => '顶著书',
+'頂著作' => '顶著作',
+'頂著名' => '顶著名',
+'頂著錄' => '顶著录',
+'頂著稱' => '顶著称',
+'頂著者' => '顶著者',
+'頂著述' => '顶著述',
+'順著' => '顺着',
+'順著書' => '顺著书',
+'順著作' => '顺著作',
+'順著名' => '顺著名',
+'順著錄' => '顺著录',
+'順著稱' => '顺著称',
+'順著者' => '顺著者',
+'順著述' => '顺著述',
+'領著' => '领着',
+'領著書' => '领著书',
+'領著作' => '领著作',
+'領著名' => '领著名',
+'領著錄' => '领著录',
+'領著稱' => '领著称',
+'領著者' => '领著者',
+'領著述' => '领著述',
+'飃著' => '飘着',
+'飄著' => '飘着',
+'飄著書' => '飘著书',
+'飄著作' => '飘著作',
+'飄著名' => '飘著名',
+'飄著錄' => '飘著录',
+'飄著稱' => '飘著称',
+'飄著者' => '飘著者',
+'飄著述' => '飘著述',
+'行政總裁' => '首席执行官',
+'執行長、' => '首席执行官、',
+'執行長。' => '首席执行官。',
+'執行長,' => '首席执行官,',
+'財務長、' => '首席财务官、',
+'財務長。' => '首席财务官。',
+'財務長,' => '首席财务官,',
+'營運長、' => '首席运营官、',
+'營運長。' => '首席运营官。',
+'營運長,' => '首席运营官,',
+'馬爾地夫' => '马尔代夫',
+'萌島' => '马恩岛',
+'馬拉威' => '马拉维',
+'馬斯垂克' => '马斯特里赫特',
+'馬爾他' => '马耳他',
+'麻薩諸塞' => '马萨诸塞',
+'馬利共和國' => '马里共和国',
+'駛著' => '驶着',
+'駕著' => '驾着',
+'駕著書' => '驾著书',
+'駕著作' => '驾著作',
+'駕著名' => '驾著名',
+'駕著錄' => '驾著录',
+'駕著稱' => '驾著称',
+'駕著者' => '驾著者',
+'駕著述' => '驾著述',
+'罵著' => '骂着',
+'罵著書' => '骂著书',
+'罵著作' => '骂著作',
+'罵著名' => '骂著名',
+'罵著錄' => '骂著录',
+'罵著稱' => '骂著称',
+'罵著者' => '骂著者',
+'罵著述' => '骂著述',
+'騎著' => '骑着',
+'騎著書' => '骑著书',
+'騎著作' => '骑著作',
+'騎著名' => '骑著名',
+'騎著錄' => '骑著录',
+'騎著稱' => '骑著称',
+'騎著者' => '骑著者',
+'騎著述' => '骑著述',
+'騙著' => '骗着',
+'騙著書' => '骗著书',
+'騙著作' => '骗著作',
+'騙著名' => '骗著名',
+'騙著錄' => '骗著录',
+'騙著稱' => '骗著称',
+'騙著者' => '骗著者',
+'騙著述' => '骗著述',
+'尖峰時段' => '高峰时段',
+'尖峰時間' => '高峰时间',
+'高畫質' => '高清',
+'高著' => '高着',
+'高著書' => '高著书',
+'高著作' => '高著作',
+'高著名' => '高著名',
+'高著錄' => '高著录',
+'高著称' => '高著称',
+'高著稱' => '高著称',
+'高著者' => '高著者',
+'高著述' => '高著述',
+'魚雷' => '鱼雷',
+'鱼雷' => '鱼雷',
+'咪高峰' => '麦克风',
+'黏著' => '黏着',
+'黏著書' => '黏著书',
+'黏著作' => '黏著作',
+'黏著名' => '黏著名',
+'黏著錄' => '黏著录',
+'黏著稱' => '黏著称',
+'黏著者' => '黏著者',
+'黏著述' => '黏著述',
+'蒙特內哥羅' => '黑山',
+'滑鼠' => '鼠标',
+);
+}
index 47d10c2..0b35f9b 100644 (file)
        "resetpass_submit": "ضبط كلمة السر والدخول",
        "changepassword-success": "تم تغيير كلمة السر بنجاح!",
        "changepassword-throttled": "لديك محاولات تسجيل دخول كثيرة حديثة. من فضلك انتظر $1 قبل المحاولة ثانية.",
+       "botpasswords-label-appid": "اسم البوت:",
+       "botpasswords-label-create": "أنشأ",
        "botpasswords-label-cancel": "ألغ",
        "botpasswords-label-delete": "احذف",
        "botpasswords-label-resetpassword": "أعد ضبط كلمة السر",
        "userrights": "صلاحيات المستخدم",
        "userrights-lookup-user": "أدِر مجموعات المستخدم",
        "userrights-user-editname": "أدخل اسم مستخدم:",
-       "editusergroup": "عدل مجموعات المستخدم",
+       "editusergroup": "عدل مجموعات {{GENDER:$1|المستخدم|المستخدمة}}",
        "editinguser": "تغيير صلاحيات {{GENDER:$1|المستخدم|المستخدمة}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "تعديل مجموعات المستخدم",
-       "saveusergroups": "احفظ مجموعات المستخدم",
+       "saveusergroups": "احفظ مجموعات {{GENDER:$1|المستخدم|المستخدمة}}",
        "userrights-groupsmember": "عضو في:",
        "userrights-groupsmember-auto": "عضو ضمني في:",
        "userrights-groups-help": "يمكنك تغيير المجموعات التي ينتمي هذا المستخدم إليها:\n* يعني الصندوق المعلم أن المستخدم في هذه المجموعة.\n* يعني الصندوق غير المعلم أن المستخدم ليس في هذه المجموعة.\n* تعني علامة * عدم إمكانية إزالة المجموعة متى ما أضفتها، أو العكس.",
        "rcshowhidemine": "$1 تعديلاتي",
        "rcshowhidemine-show": "أظهر",
        "rcshowhidemine-hide": "أخف",
+       "rcshowhidecategorization": "$1 تصنيف الصفحات",
        "rcshowhidecategorization-show": "أظهر",
        "rcshowhidecategorization-hide": "أخف",
        "rclinks": "أظهر آخر $1 تعديل في آخر $2 يوم<br />$3",
        "recentchangeslinked-page": "اسم الصفحة:",
        "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضا عن ذلك",
        "recentchanges-page-added-to-category": "[[:$1]] أضيفت إلى التصنيف",
+       "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] و{{PLURAL:$2|صفحة واحدة|صفحتان|$2 صفحات}} إلى التصنيف",
+       "recentchanges-page-removed-from-category-bundled": "أزيلت [[:$1]] و{{PLURAL:$2|صفحة واحدة|صفحتان|$2 صفحات}} من التصنيف",
        "upload": "ارفع ملفا",
        "uploadbtn": "ارفع الملف",
        "reuploaddesc": "إلغاء الرفع والرجوع إلى استمارة الرفع",
        "querypage-disabled": "تم تعطيل هذه الصفحة الخاصة لأسباب تتعلق بالأداء.",
        "apihelp": "مساعدة API",
        "apihelp-no-such-module": "الوحدة \"$1\" غير موجودة.",
+       "apisandbox": "ملعب API",
+       "apisandbox-submit": "عمل الطلب",
+       "apisandbox-reset": "إفراغ",
+       "apisandbox-retry": "أعد المحاولة",
+       "apisandbox-examples": "أمثلة",
+       "apisandbox-results": "النتيجة",
+       "apisandbox-request-url-label": "مسار الطلب:",
+       "apisandbox-request-time": "وقت الطلب: $1",
        "booksources": "مصادر كتاب",
        "booksources-search-legend": "البحث عن مصادر الكتب",
        "booksources-isbn": "ردمك:",
        "wlshowhideliu": "المسجلين",
        "wlshowhideanons": "المجهولين",
        "wlshowhidemine": "تعديلاتي",
+       "wlshowhidecategorization": "تصنيف الصفحات",
        "watchlist-options": "خيارات قائمة المراقبة",
        "watching": "يراقب...",
        "unwatching": "إزالة المراقبة...",
        "newimages-legend": "المرشح",
        "newimages-label": "اسم الملف (أو جزء منه):",
        "newimages-showbots": "أظهر التحميلات بواسطة البوتات",
+       "newimages-hidepatrolled": "أخف المرفوعات المنظورة",
        "noimages": "لا شيء للعرض.",
        "ilsubmit": "بحث",
        "bydate": "حسب التاريخ",
        "version-hook-subscribedby": "يستخدم بواسطة",
        "version-version": "($1)",
        "version-no-ext-name": "[لا اسم]",
-       "version-svn-revision": "ن$1",
        "version-license": "ترخيص ميدياويكي",
        "version-ext-license": "ترخيص",
        "version-ext-colheader-name": "امتداد",
        "pagelang-language": "اللغة",
        "pagelang-use-default": "استخدام اللغة الافتراضية",
        "pagelang-select-lang": "اختر اللغة",
+       "pagelang-submit": "إرسال",
        "right-pagelang": "تغيير لغة الصفحة",
        "action-pagelang": "تغيير لغة الصفحة",
-       "log-name-pagelang": "تغÙ\8aÙ\8aر Ø³Ø¬Ù\84 Ø§Ù\84صÙ\81Ø­ة",
+       "log-name-pagelang": "سجÙ\84 ØªØºÙ\8aÙ\8aر Ø§Ù\84Ù\84غة",
        "log-description-pagelang": "هذا سجل تغيرات في صفحة اللغات.",
-       "logentry-pagelang-pagelang": " {{GENDER:$2|غÙ\8aÙ\91ر|غÙ\8aّرت}} $1 لغة الصفحة «$3» من $4 إلى $5.",
+       "logentry-pagelang-pagelang": " {{GENDER:$2|غÙ\8aÙ\8eÙ\91ر|غÙ\8aÙ\8eّرت}} $1 لغة الصفحة «$3» من $4 إلى $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (مفعل)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''معطل''')",
        "mediastatistics": "إحصاءات الميديا",
        "mediastatistics-header-text": "نصي",
        "mediastatistics-header-executable": "تنفيذية",
        "mediastatistics-header-archive": "صيغ مضغوطة",
+       "mediastatistics-header-total": "كل الملفات",
        "json-warn-trailing-comma": "تمت إزالة {{PLURAL:$1|فاصلة انتهائية واحدة|فاصلتين انتهائيتين|$1 فاصلات انتهائية|$1 فاصلة انتهائية}} من JSON",
        "json-error-unknown": "وقعت مشكلة مع JSON. رسالة الخطأ: $1",
        "json-error-depth": "عمق الستاك الأقصى تم تجاوزه",
        "mw-widgets-titleinput-description-new-page": "الصفحة غير موجودة بعد",
        "mw-widgets-titleinput-description-redirect": "تحويل إلى $1",
        "api-error-blacklisted": "اختر عنوانا مختلفا ومفهوما.",
+       "sessionprovider-generic": "جلسات $1",
        "randomrootpage": "صفحة جذر عشوائية"
 }
index 3e7650d..72c1e12 100644 (file)
        "unwatch": "ما تزيدش تعس",
        "watchlist-details": "{{PLURAL:$1||باجه وحده|باجتين|$1 باجات|$1 باجه}} في ليستت مراقبتك، من غير اعتبار باجات النقاش هي باجات منفصله.",
        "wlshowlast": "بين آخر $1 سوايع $2 يامات",
-       "watchlistall2": "لكل",
        "watchlist-options": "ابسيون ليستت المراقبه",
        "actioncomplete": "العمليه اندارت",
        "actionfailed": "العمليه فشلت",
        "allmessagesdefault": "الكتبه الافتراضيه",
        "thumbnail-more": "كبر",
        "thumbnail_error": "غلطه في خدمت صورة مصغرةالمينياتير: $1",
-       "tooltip-pt-userpage": "باجتÙ\83 Ù\86تع Ù\85ستعÙ\85Ù\84",
-       "tooltip-pt-mytalk": "باجÙ\87 Ù\86تع Ù\86Ù\82اشاتÙ\83",
-       "tooltip-pt-preferences": "وش خيرت",
+       "tooltip-pt-userpage": "اÙ\84باجة ØªØ§Ø¹ Ø§Ù\84Ù\85ستعÙ\85Ù\84Ù\8a {{GENDER:|تاعÙ\83}}",
+       "tooltip-pt-mytalk": "اÙ\84باجة ØªØ§Ø¹ Ø§Ù\84Ù\85Ù\87ادرة {{GENDER:|تاعÙ\83}}",
+       "tooltip-pt-preferences": "الختيّارات {{GENDER:|تاعك}}",
        "tooltip-pt-watchlist": "ليستت الباجات الي راك أتبع تبديلاتهم",
-       "tooltip-pt-mycontris": "ليسته نتع مساهماتك",
+       "tooltip-pt-mycontris": "الليستة تاع المساهمات {{GENDER:|تاعك}}",
        "tooltip-pt-login": "مادابيك تسجل دخلتك ، لكن ماشي لازم",
        "tooltip-pt-logout": "سجل خروج",
        "tooltip-pt-createaccount": "ننصح باش تصنع حساب و تسجل دخلتك ; على كل حال ماهوش ضروري",
        "tooltip-t-whatlinkshere": "ليستة تاع كامل باجات المحتاوا الواصله هنا",
        "tooltip-t-recentchangeslinked": "ليستة تاع التبديلات التوالا تاع الباجات الّي عندهم رباط معا هادي",
        "tooltip-feed-atom": "سيلان آتوم تاع هاد الباجة",
-       "tooltip-t-contributions": "شوفان ليسته مساهمات هاذا المستخدم",
+       "tooltip-t-contributions": "شوف ليستة تاع المساهمات تاع {{GENDER:$1|هاد المستعملي|هاد المستعمليّة}}",
        "tooltip-t-emailuser": "أرسل بريه لهاذ المستخدم",
        "tooltip-t-upload": "أرسل تصويرة و إلا أي ملف ميديا للسرفر",
        "tooltip-t-specialpages": "ليستة تاع كامل الباجات الخصوصيّة",
index 4d13aab..e0311dd 100644 (file)
        "mergehistory-from": "Páxina d'orixe:",
        "mergehistory-into": "Páxina de destín:",
        "mergehistory-list": "Historial d'ediciones fusionable",
-       "mergehistory-merge": "Les siguientes revisiones de [[:$1]] puen fusionase en [[:$2]]. Usa la columna de botones d'opción pa fusionar namaí les revisiones creaes na y enantes de la hora especificada. has fixate en que si uses los enllaces de navegación esborraránse les seleiciones feches nesta columna.",
+       "mergehistory-merge": "Les siguientes revisiones de [[:$1]] puen fusionase'n [[:$2]]. Usa la columna de botones d'opción pa fusionar namai les revisiones creaes na y enantes de la hora especificada.\nHas fixate en que si uses los enllaces de navegación esborraránse les seleiciones feches nesta columna.",
        "mergehistory-go": "Amosar ediciones fusionables",
        "mergehistory-submit": "Fusionar revisiones",
        "mergehistory-empty": "Nun se pue fusionar nenguna revisión.",
        "recentchangescount": "Númberu d'ediciones p'amosar de mou predetermináu:",
        "prefs-help-recentchangescount": "Incluye los cambios recientes, los historiales de páxines y los rexistros.",
        "prefs-help-watchlist-token2": "Esta ye la clave secreta pa la canal de noticies web de la so llista de vixilancia.\nCualquiera que la sepa podrá lleer la so llista de vixilancia; nun la comparta.\n[[Special:ResetTokens|Calque equí si necesita reaniciala]].",
-       "savedprefs": "Les tos preferencies quedaron grabaes.",
+       "savedprefs": "Guardáronse les preferencies.",
        "savedrights": "Guardáronse los permisos d'{{GENDER:$1|usuariu|usuaria}} de $1.",
        "timezonelegend": "Estaya horaria:",
        "localtime": "Hora llocal:",
        "right-import": "Importar páxines dende otres wikis",
        "right-importupload": "Importar páxines dende un ficheru xubíu",
        "right-patrol": "Marcar ediciones d'otros como supervisaes",
-       "right-autopatrol": "Marcar automáticamente les ediciones como supervisaes",
+       "right-autopatrol": "Marcar automáticamente les ediciones propies como supervisaes",
        "right-patrolmarks": "Ver les marques de supervisión nos cambeos de recién",
        "right-unwatchedpages": "Ver una llista de páxines non vixilaes",
        "right-mergehistory": "Fusionar historiales de páxines",
-       "right-userrights": "Editar tolos drechos d'usuariu",
-       "right-userrights-interwiki": "Editar los drechos d'usuariu d'usuarios d'otros sitios wiki",
+       "right-userrights": "Editar tolos permisos d'usuariu",
+       "right-userrights-interwiki": "Editar los permisos d'usuariu de los usuarios d'otres wikis",
        "right-siteadmin": "Candar y descandar la base de datos",
        "right-override-export-depth": "Esportar páxines, incluyendo páxines enllazaes fasta una fondura de 5",
        "right-sendemail": "Unviar corréu a otros usuarios",
        "right-managechangetags": "Crear y desaniciar [[Special:Tags|etiquetes]] dende la base de datos",
        "right-applychangetags": "Aplicar [[Special:Tags|etiquetes]] xunto colos cambios propios",
        "right-changetags": "Amestar y desaniciar [[Special:Tags|etiquetes]] arbitraries en revisiones individuales y entraes del rexistru",
-       "grant-generic": "Conxuntu de drechos \"$1\"",
+       "grant-generic": "Conxuntu de drechos «$1»",
        "grant-group-page-interaction": "Interactuar con páxines",
        "grant-group-file-interaction": "Interactuar con multimedia",
        "grant-group-watchlist-interaction": "Interactuar cola to llista de vixilancia",
        "grant-viewmywatchlist": "Ver la to llista de siguimientu",
        "newuserlogpage": "Rexistru de creación d'usuarios",
        "newuserlogpagetext": "Esti ye un rexistru de creación d'usuarios.",
-       "rightslog": "Rexistru de perfil d'usuariu",
-       "rightslogtext": "Esti ye un rexistru de los cambeos de los perfiles d'usuariu.",
+       "rightslog": "Rexistru de permisos d'usuariu",
+       "rightslogtext": "Esti ye un rexistru de los cambeos nos permisos d'usuariu.",
        "action-read": "lleer esta páxina",
        "action-edit": "editar esta páxina",
        "action-createpage": "crear páxines",
        "action-minoredit": "marcar esta edición como menor",
        "action-move": "treslladar esta páxina",
        "action-move-subpages": "treslladar esta páxina y les sos subpáxines",
-       "action-move-rootuserpages": "treslladar páxines d'un usuariu root",
+       "action-move-rootuserpages": "treslladar páxines principales d'usuariu",
        "action-move-categorypages": "treslladar les páxines de categoría",
-       "action-movefile": "treslladar esti archivu",
-       "action-upload": "xubir esti archivu",
-       "action-reupload": "sobreescribir esti archivu esistente",
-       "action-reupload-shared": "sustituyir esti archivu nun direutoriu compartíu",
-       "action-upload_by_url": "xubir esti archivu dende una direición URL",
+       "action-movefile": "treslladar esti ficheru",
+       "action-upload": "xubir esti ficheru",
+       "action-reupload": "reemplazar esti ficheru esistente",
+       "action-reupload-shared": "sustituyir esti ficheru d'un direutoriu compartíu",
+       "action-upload_by_url": "xubir esti ficheru dende una URL",
        "action-writeapi": "usar l'API d'escritura",
        "action-delete": "desaniciar esta páxina",
-       "action-deleterevision": "eliminar esta revisión",
+       "action-deleterevision": "desaniciar esta revisión",
        "action-deletedhistory": "ver l'historial elimináu d'esta páxina",
        "action-browsearchive": "buscar páxines desaniciaes",
        "action-undelete": "restaurar esta páxina",
-       "action-suppressrevision": "revisar y restaurar esta revisión oculta",
+       "action-suppressrevision": "revisar y restaurar esta revisión tapecida",
        "action-suppressionlog": "ver esti rexistru priváu",
        "action-block": "bloquiar qu'esti usuariu edite",
        "action-protect": "camudar los niveles de proteición pa esta páxina",
        "action-autopatrol": "marcar la to edición como supervisada",
        "action-unwatchedpages": "ver la llista de páxines non vixilaes",
        "action-mergehistory": "fusionar l'historial d'esta páxina",
-       "action-userrights": "editar tolos drechos d'usuariu",
-       "action-userrights-interwiki": "editar los drechos d'usuariu d'usuarios d'otres wikis",
+       "action-userrights": "editar tolos permisos d'usuariu",
+       "action-userrights-interwiki": "editar los permisos d'usuariu de los usuarios d'otres wikis",
        "action-siteadmin": "candar o descandar la base de datos",
        "action-sendemail": "unviar correos",
        "action-editmywatchlist": "editar la llista de vixilancia",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuariu|ususarios}} vixilando]",
+       "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuariu|usuarios}} vixilando]",
        "rc_categories": "Llendar a les categoríes (dixebrar con \"|\"):",
        "rc_categories_any": "Cualquiera de les esbillaes",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dempués del cambiu",
        "autochange-username": "Cambiu automáticu de MediaWiki",
        "upload": "Xubir ficheru",
        "uploadbtn": "Xubir ficheru",
-       "reuploaddesc": "Cancelar la xubida y tornar al formulariu de xubíes",
+       "reuploaddesc": "Encaboxar la xubida y tornar al formulariu de xubíes",
        "upload-tryagain": "Unviar descripción camudada del ficheru",
        "uploadnologin": "Nun anició sesión",
        "uploadnologintext": "Tien d'$1 pa xubir ficheros.",
-       "upload_directory_missing": "El direutoriu de xubida ($1) nun esiste y nun pudo ser creáu pol sirvidor de web.",
-       "upload_directory_read_only": "El sirvidor nun pue modificar el direutoriu de xubida d'archivos ($1).",
+       "upload_directory_missing": "El direutoriu de xubida ($1) nun esiste y nun pudo crease pol sirvidor web.",
+       "upload_directory_read_only": "El sirvidor web nun pue escribir nel direutoriu de xubíes ($1).",
        "uploaderror": "Error de xubida",
        "upload-recreate-warning": "'''Avisu: Se desanició o treslladó un ficheru con esi nome.'''\n\nEquí s'ufre'l rexistru de desaniciu y treslláu d'esta páxina por comodidá:",
        "uploadtext": "Usa'l formulariu de más abaxo pa xubir ficheros.\nPa ver o buscar ficheros xubíos previamente, vete a la [[Special:FileList|llista de ficheros xubíos]]. Les (re)xubíes tamién queden conseñaes nel [[Special:Log/upload|rexistru de xubíes]], y los desanicios nel [[Special:Log/delete|rexistru de desanicios]].\n\nPa incluir un ficheru nuna páxina, usa un enllaz con ún de los siguientes formatos:\n*<strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Ficheru.jpg]]</nowiki></code></strong> pa usar la versión completa del ficheru\n*<strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Ficheru.png|200px|thumb|left|testu alternativu]]</nowiki></code></strong> pa usar una versión de 200 píxeles d'anchu nun cuadru nel marxe izquierdu con «testu alternativu» como descripción\n*<strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Ficheru.ogg]]</nowiki></code></strong> pa enllazar al ficheru direutamente ensin amosalu",
        "uploaded-script-svg": "Alcontróse l'elementu «$1» que puede recibir scripts nel ficheru SVG xubíu.",
        "uploaded-hostile-svg": "Alcontróse CSS inseguru nel elementu d'estilu del ficheru SVG xubíu.",
        "uploaded-event-handler-on-svg": "Nun se permite configurar los atributos de controladores de socesos <code>$1=\"$2\"</code> nos ficheros SVG.",
-       "uploaded-href-attribute-svg": "Nun se permiten los atributos href <code>&lt;$1 $2=\"$3\"&gt;</code> con destín nun llocal (p. ex. http://, javascript:, etc) nos ficheros SVG.",
-       "uploaded-href-unsafe-target-svg": "Alcontróse un \"href\" a un destín inseguru <code>&lt;$1 $2=\"$3\"&gt;</code> nel ficheru SVG xubíu.",
+       "uploaded-href-attribute-svg": "Los atributos href de los ficheros SVG are sólo pueden enllazar a destinos http:// o https://, alcontróse <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Alcontróse un href a datos inseguros: la URI de destín <code>&lt;$1 $2=\"$3\"&gt;</code> nel ficheru SVG xubíu.",
        "uploaded-animate-svg": "Alcontróse la etiqueta \"animate\" que puede cambiar href, usando l'atributu \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> nel ficheru SVG xubíu.",
        "uploaded-setting-event-handler-svg": "Ta torgada la configuración d'atributos del xestor de socesos. Alcontróse <code>&lt;$1 $2=\"$3\"&gt;</code> nel ficheru SVG xubíu.",
        "uploaded-setting-href-svg": "Usar la etiqueta «set» p'amestar l'atributu «href» al elementu padre ta torgao.",
        "querypage-disabled": "Esta páxina especial ta desactivada por razones de rindimientu.",
        "apihelp": "Ayuda de la API",
        "apihelp-no-such-module": "Nun s'alcuentra'l módulu «$1».",
+       "apisandbox": "Zona de pruebes API",
+       "apisandbox-api-disabled": "La API ta desactivada nesti sitiu.",
+       "apisandbox-intro": "Usa esta páxina pa esperimentar cola <strong>API de serviciu web de MediaWiki</strong>.\nConsulta [[mw:API:Main page|la documentación de la API]] pa más detalles tocante al so usu. Exemplu: [//www.mediawiki.org/wiki/API#A_simple_example llamar al conteníu d'una Páxina principal]. Seleiciona una aición pa ver más exemplos.\n\nTen presente que, anque esto ye una zona de pruebes, les aiciones que faigas nesta páxina puen camudar la wiki.",
+       "apisandbox-fullscreen": "Espander el panel",
+       "apisandbox-submit": "Facer solicitú",
+       "apisandbox-reset": "Llimpiar",
+       "apisandbox-examples": "Exemplos",
+       "apisandbox-results": "Resultaos",
+       "apisandbox-request-url-label": "URL de la solicitú:",
+       "apisandbox-request-time": "Duración de la solicitú: {{PLURAL:$1|$1 ms}}",
        "booksources": "Fontes de llibros",
        "booksources-search-legend": "Busca de fontes de llibros",
        "booksources-search": "Buscar",
        "expand_templates_preview_fail_html": "<em>Como {{SITENAME}} tien activáu el códigu HTML puru y hebo una perda de datos de la sesión, la vista previa ta tapecida como precaución escontra ataques de JavaScript.</em>\n\n<strong>Si esti ye un intentu llexítimu d'accesu a la vista previa, vuelvi a intentalo.</strong>\nSi inda nun funciona, intenta [[Special:UserLogout|salir]] y volver a entrar na to cuenta.",
        "expand_templates_preview_fail_html_anon": "<em>Como {{SITENAME}} tien activáu el códigu HTML puru y nun aniciasti sesión, la vista previa ta tapecida como precaución escontra ataques de JavaScript.</em>\n\n<strong>Si esti ye un intentu llexítimu d'accesu a la vista previa, intenta [[Special:UserLogin|entrar]] y vuelvi a intentalo.</strong>",
        "expand_templates_input_missing": "Fai falta dar daqué de testu d'entrada.",
-       "pagelanguage": "Selector de llingua de la páxina",
+       "pagelanguage": "Cambiar la llingua de la páxina",
        "pagelang-name": "Páxina",
        "pagelang-language": "Llingua",
        "pagelang-use-default": "Usar la llingua predeterminada",
        "pagelang-submit": "Unviar",
        "right-pagelang": "Cambiar la llingua de la páxina",
        "action-pagelang": "cambiar la llingua de la páxina",
-       "log-name-pagelang": "Rexistru de cambios de llingua",
+       "log-name-pagelang": "Rexistru de cambeos d'idioma",
        "log-description-pagelang": "Esti ye un rexistru de los cambios de llingua de les páxines.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|cambió}} la llingua de la páxina $3 del $4 al $5.",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|cambió}} la llingua de $3 del $4 al $5.",
        "default-skin-not-found": "¡Vaya! L'aspeutu predetermináu pa la to wiki, definíu en <code dir=\"ltr\">$wgDefaultSkin</code> como <code>$1</code> nun ta disponible.\n\nLa instalación paez qu'incluye {{PLURAL:$4|el siguiente aspeutu|los siguientes aspeutos}}. Llei [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] pa más información sobro cómo {{PLURAL:$4|activalu|activalos y escoyer el predetermináu}}.\n\n$2\n\n; Si acabes d'instalar MediaWiki:\n: Probablemente instalasti dende git, o direutamente'l códigu fonte usando algún otru métodu. Esto ye d'esperar. Intenta instalar dellos aspeutos dende'l [https://www.mediawiki.org/wiki/Category:All_skins direutoriu d'aspeutos de mediawiki.org's], asina:\n:* Descargando [https://www.mediawiki.org/wiki/Download l'instalador tarball], que vien con dellos aspeutos y estensiones. Pues copiar y apegar el direutoriu <code>skins/</code> d'ehí.\n:* Descargando paquetes tar d'aspeutu individuales de [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git pa descargar aspeutos].\n: Facer esto nun tendría d'interferir col to repositoriu git si yes un desendolcador de MediaWiki.\n\n; Si acabes d'anovar MediaWiki:\n: MediaWiki 1.24 y más nuevu yá nun activa automáticamente los aspeutos instalaos (llei [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). Pues apegar {{PLURAL:$5|la llinia siguiente|les llinies siguientes}} en <code>LocalSettings.php</code> p'activar {{PLURAL:$5|l'aspeutu instaláu|tolos aspeutos instalaos}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si acabes d'editar <code>LocalSettings.php</code>:\n: Vuelvi a comprobar los nomes de los aspeutos por si hai errores d'escritura.",
        "default-skin-not-found-no-skins": "L'aspeutu predetermináu pa la to wiki, definíu en <code>$wgDefaultSkin</code> como <code>$1</code> nun ta disponible.\n\nNun tienes aspeutos instalaos.\n\n; Si acabes d'instalar MediaWiki:\n: Probablemente instalasti dende git, o'l códigu fonte direutamente usando algún otru métodu. Esto ye d'esperar. MediaWiki 1.24 y más nuevu nun incluye nengún aspeutu nel repositoriu principal. Intenta instalar dellos aspeutos dende'l [https://www.mediawiki.org/wiki/Category:All_skins direutoriu d'aspeutos de mediawiki.org], asina:\n:* Descargando [https://www.mediawiki.org/wiki/Download l'instalador tarball], que vien con dellos aspeutos y estensiones. Pues copiar y apegar el direutoriu <code>skins/</code> d'ehí.\n:* Descargando paquetes tar d'aspeutu individuales de [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:*  [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Usando Git pa descargar aspeutos].\n: Facer esto nun tendría d'interferir col to repositoriu git si yes un desendolcador de MediaWiki. Llei [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] pa más información sobro cómo activar los aspeutos y escoyer el predetermináu.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (activáu)",
index a879fbc..b530c19 100644 (file)
        "watchthisupload": "Bu faylı izlə",
        "filename-bad-prefix": "Yüklədiyiniz faylın adı, çox güman ki, rəqəmsal kameralar tərəfindən avtomatik olaraq əlavə edilən və heç bir açıqlaması olmayan '''\"$1\"''' ilə başlayır.\nXahiş edirik faylın adını daha düzgün seçin.",
        "filename-prefix-blacklist": " #<!-- Bu sətrə toxunmayın --> <pre>\n# Sintaksis aşağıdakı kimi görünür:\n#   * \"#\" simvolundan sətrin sonuna kimi yazılar şərhdir\n#   * Tipik fayl adları üçün olan prefiksdəki hər bir boş olmayan sətir rəqəmli kamera trəfindən avtomatik qeydə alınır\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # digər mobil telefonlar\nIMG # generic\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- Bu sətrə toxunmayın -->",
-       "upload-success-subj": "Yükləmə tamamlandı",
-       "upload-failure-subj": "Yükləmə problemi",
-       "upload-failure-msg": "Yüklədiyiniz [$2] forması ilə bağlı problem yaranıb:\n\n$1",
-       "upload-warning-subj": "Yükləmə xəbərdarlığı",
        "upload-proto-error": "Yanlış protokol",
        "upload-file-error": "Daxili xəta",
        "upload-misc-error": "Naməlum yükləmə xətası",
        "pager-newer-n": "{{PLURAL:$1|1 daha yeni|$1 daha yeni}}",
        "pager-older-n": "{{PLURAL:$1|1 daha köhnə|$1 daha köhnə}}",
        "suppress": "Gizlət",
+       "apisandbox-results": "Nəticə",
        "booksources": "Kitab mənbələri",
        "booksources-search-legend": "Kitab mənbələri axtar",
        "booksources-isbn": "ISBN:",
        "wlheader-showupdated": "Son ziyarətinizdən sonra edilən dəyişikliklər '''qalın şriftlərlə''' göstərilmişdir.",
        "wlnote": "Aşağıdakı {{PLURAL:$1|'''$1''' dəyişiklik|'''$1''' dəyişiklik}} son {{PLURAL:$2|saatda|'''$2''' saatda}} edilmişdir.",
        "wlshowlast": "Son $1 saatı $2 günü göstər",
-       "watchlistall2": "hamısı",
        "wlshowhidemine": "mənimn redaktələrim",
        "watchlist-options": "İzləmə siyahısının nizamlamaları",
        "watching": "İzlənilir...",
        "modifiedarticleprotection": "\"[[$1]]\" səhifəsi üçün mühafizə səviyyəsi dəyişildi",
        "unprotectedarticle": "mühafizə kənarlaşdırıldı \"[[$1]]\"",
        "protect-title": "\"$1\" üçün mühafizə səviyyəsinin dəyişdirilməsi",
-       "prot_1movedto2": "[[$1]] adı dəyişildi. Yeni adı: [[$2]]",
+       "prot_1movedto2": "[[$1]] səhifəsinin adı dəyişilib. Yeni adı: [[$2]]",
        "protect-legend": "Qorumayı təsdiq et",
        "protectcomment": "Səbəb:",
        "protectexpiry": "Vaxtı bitib",
index 980de92..0e03f7f 100644 (file)
        "prefs-labs": "آزماییشی اؤزل‌لیکلر",
        "prefs-user-pages": "ایستیفاده‌چی صحیفه‌لری",
        "prefs-personal": "ایشلدن وئری‌لری",
-       "prefs-rc": "سون دَییشیکلیکلر",
+       "prefs-rc": "سÙ\88Ù\92Ù\86 Ø¯Ù\8eÛ\8cÛ\8cØ´Û\8cÚ©Ù\84Û\8cÚ©Ù\84ر",
        "prefs-watchlist": "ایزله‌دیکلر",
        "prefs-editwatchlist": "ایزله‌دیکلریم صفحه‌‌لری دَییشدیر",
        "prefs-editwatchlist-label": "بۆتون ایزله‌دیکلرینیزین دَییشدیرمه‌سی:",
        "nchanges": "$1 {{PLURAL:$1|دَییشیکلیک}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|سون گوروش دن}}",
        "enhancedrc-history": "گئچمیش",
-       "recentchanges": "سون دَییشیکلیکلر",
+       "recentchanges": "سÙ\88Ù\92Ù\86 Ø¯Ù\8eÛ\8cÛ\8cØ´Û\8cÚ©Ù\84Û\8cÚ©Ù\84ر",
        "recentchanges-legend": "سون دَییشیکلیکلر سئچمه‌لری",
        "recentchanges-summary": "بۇ صفحه‌ده، بۇ ویکیده وئریلن ان سوْن دَییشیکلیکلری ایزله‌یین.",
        "recentchanges-noresult": "وئریلمیش دؤنم‌ده، بو معیارلارا تطبیق اولان دَییشدیرمه یوخدور.",
        "double-redirect-fixed-move": "[[$1]] آپاریلمیش‌دیر.\nاوْتوماتیک اوْلاراق گۆنجل‌له‌نیبدیر و ایندی [[$2]]-ه یوْل‌لاندیریر.",
        "double-redirect-fixed-maintenance": "[[$1]]-دن [[$2]]-ه ایکی‌قات یوْل‌لاندیرما، بیر ساخلاما ایشین‌ده، اوْتوماتیک اوْلاراق دۆزلدیلیر.",
        "double-redirect-fixer": "يؤنلندیرمه تعمیرجیسی",
-       "brokenredirects": "خطالی ایستیقامتلندیرمه",
+       "brokenredirects": "خطالی یوْللاندیرمالار",
        "brokenredirectstext": "آشاغی‌داکی ایستیقامتلندیرمه‌لر مؤوجود اولمایان صحیفه‌لره کئچید وئریر:",
        "brokenredirects-edit": "دَییشدیر",
        "brokenredirects-delete": "سیل",
        "withoutinterwiki-summary": "آشاغیداکی صحیفه‌لر، باشقا دیل‌لره باغلانتیلاری یوخدور.",
        "withoutinterwiki-legend": "اؤن‌اَک",
        "withoutinterwiki-submit": "گؤستر",
-       "fewestrevisions": "ان آز دَییشدیریلن صحیفه‌لر",
+       "fewestrevisions": "ان آز دَییشدیریلن صفحه‌لر",
        "nbytes": "{{PLURAL:$1|بیر|$1}} بایت",
        "ncategories": "{{PLURAL:$1|بیر|$1}} بؤلمه",
        "ninterwikis": "{{PLURAL:$1|بیر|$1}} ویکی‌آراسی",
        "specialpage-empty": "بو صحیفه بوشدور",
        "lonelypages": "يئتیم صحیفه‌‌لر",
        "lonelypagestext": "آشاغی‌داکی صحیفه‌لره {{SITENAME}} سایتین‌داکی دیگر صحیفه‌لردن علاقه وئریلممیش یا دا چارپاز داخیل ائدیلممیش.",
-       "uncategorizedpages": "بؤلمه‌سیز صحیفه‌لر",
+       "uncategorizedpages": "بؤلمه‌سیز صفحه‌لر",
        "uncategorizedcategories": "بؤلمه‌سیز بؤلمه‌لر",
-       "uncategorizedimages": "بؤلمه‌سیز شکیل‌لر",
-       "uncategorizedtemplates": "بؤلمه‌سیز شابلونلار",
+       "uncategorizedimages": "بؤلمه‌سیز فایللار",
+       "uncategorizedtemplates": "بؤلمه‌سیز شابلونلار",
        "unusedcategories": "ایستیفاده ائدیلمه‌میش بؤلمه‌لر",
        "unusedimages": "ایشلنمه‌میش فایل‌لار",
        "wantedcategories": "یسته نن بؤلمه‌لر",
        "prefixindex-namespace": "بوتون صفحه لر (آد فضاسی$1) قاباق دان یاپیشیقی وار",
        "prefixindex-strip": "لیست‌ده، اؤن‌اَکی قوْپارت",
        "shortpages": "قیسا صحیفه‌‌لر",
-       "longpages": "اوزون صحیفه‌‌لر",
+       "longpages": "اۇزون صفحه‌‌لر",
        "deadendpages": "کئچید وئرمه‌ين صحیفه‌‌لر",
        "deadendpagestext": "آشاغیداکی صحیفه‌‌لردن بو ویکیپئدیياداکی دیگر صحیفه‌‌لره هئچ بیر کئچید يوخدور.",
        "protectedpages": "محافظه‌‌لی صحیفه‌‌لر",
        "usercreated": "$1 تاریخینده، ساعات $2-ده {{GENDER:$3|یارانیب‌دیر}}",
        "newpages": "يئنی صفحه‌لر",
        "newpages-username": "ایشلدن آدی:",
-       "ancientpages": "ان اسکی صحیفه‌لر",
+       "ancientpages": "ان اسکی صفحه‌لر",
        "move": "آدینی دَییشدیر",
        "movethispage": "بو صحیفه‌‌نین آدینی ديَیشدیر",
        "unusedimagestext": "آشاغی‌داکی فایل‌لار وار آنجاق هر هانسی بیر صحیفه‌ده باسدیریلمیش دئییل.\nخاهیش ائدیریک اونوتمایین کی، دیگر web سایت‌لاری بیر فایلا بیرباشا بیر اورل ایله علاقه وئره بیلر، و بونا گؤره ائففئکتیو ایستیفاده‌ده اولماسا بئله هله بورادا لیستنبیلیر.",
        "querypage-disabled": "پِرفورمانس اوچون بو اؤزل صحیفه باغلانیب‌دیر.",
        "apihelp": "API یاردیمی",
        "apihelp-no-such-module": "«$1» ماژول تاپیلمادی.",
+       "apisandbox-reset": "تمیزله",
+       "apisandbox-examples": "میثال",
+       "apisandbox-results": "نتیجه",
+       "apisandbox-request-time": "زامان ایستمک:$1",
        "booksources": "کیتاب قایناقلاری",
        "booksources-search-legend": "کیتاب قایناقلارین آختار",
        "booksources-search": "آختار",
        "deleting-backlinks-warning": "'''اخطار:''' بو سیلمگه قصدینیز اولان صفحه‌یه، [[Special:WhatLinksHere/{{FULLPAGENAME}}|باشقا صفحه‌لر]] باغلانتی وئریب یا اونو اؤزلرین‌ده ایشلدیب‌لر.",
        "rollback": "اوولکی نوسخه لر",
        "rollbacklink": "قایتار",
-       "rollbacklinkcount": "گیتیرلمه $1  {{PLURAL:$1|دییشمک |دییشمک}} دییشدیرمه",
+       "rollbacklinkcount": "$1 دییشدیرمه‌نی قایتار",
        "rollbacklinkcount-morethan": "گیتیرلمه آرتیق $1 {{PLURAL:$1|دییشمک |دییشمک}} دییشدیرمه",
        "rollbackfailed": "گئری قایتارما اوغورسوزدور",
        "cantrollback": "دییشدیر گئری قایتاریلا بیلمز؛ آخیرینجی دییشدیر صحیفه‌ده اولان یئگانه فالیت‌دیر.",
        "protect-level-autoconfirmed": "تکجه اوْتوماتیک تأیید اوْلموش ایشلدن‌لره ایجازه وئر",
        "protect-level-sysop": "یالنیز ایداره‌چیلره ایجازه وئر",
        "protect-summary-cascade": "پیلله‌لی",
-       "protect-expiring": "$1 (UTC)- تاریخینده واختی بیتیر",
-       "protect-expiring-local": "$1-ده بیتیر",
+       "protect-expiring": "$1 (UTC)- تاریخینده وقتی قۇرتولور",
+       "protect-expiring-local": "$1-ده قۇرتولور",
        "protect-expiry-indefinite": "سوْن‌سۇز",
        "protect-cascade": "بو صحیفه‌ده ایستیفاده ائدیلن بوتون صحیفه‌لری قوروماغا آل (پیلله‌لی قوروماق)",
        "protect-cantedit": "بو صحیفه‌نین محافظه درجه‌سینی دییش‌دیره بیلمزسینیز، چونکی بو دییشیک‌لیک اوچون حقوقونوز یوخ‌دور.",
        "sp-contributions-toponly": "تکجه سون نوسخه اولان دییشیکلری گؤستر",
        "sp-contributions-newonly": "تکجه صفحه یاراتماق دَییشیکلیکلرینی گؤستر",
        "sp-contributions-submit": "آختار",
-       "whatlinkshere": "بو صفحه‌یه باغلانتیلار",
+       "whatlinkshere": "بۇ صفحه‌‌يه باغلانتیلار",
        "whatlinkshere-title": "«$1»-ه باغلانان صحیفه‌لر",
        "whatlinkshere-page": "صفحه:",
        "linkshere": "آشاغیداکی صفحه‌لر '''[[:$1]]'''-ه باغلانیب:",
        "reblock-logentry": "[[$1]] اوچون سون تاریخی $2 $3 اولماق اوزره بلوک پارامئترلری دییشدیریلدی",
        "blocklogtext": "ایستیفاده‌چی‌لرین باغلانماسی و باغلانماقین گؤتورولمه‌سی سیاهی‌سی.\nآوتوماتیک باغلانمیش ای پی-عنوان‌لار بورادا گؤستریلمیر.\nحال-هازیرکی [[Special:BlockList|قاداغا‌لارین و بلوکلاما‌لارین سیاهی‌سی]]نا باخ.",
        "unblocklogentry": "$1 اوزرین‌دکی آچیلدی",
-       "block-log-flags-anononly": "يالنیز قئيدیاتسیز ایستیفاده‌چیلر",
+       "block-log-flags-anononly": "\nتکجه تایید اوْلونمامیش ایشلدنلر",
        "block-log-flags-nocreate": "حساب یاراتماق اولماز",
        "block-log-flags-noautoblock": "آوتوبلوکلاما غيری مومکوندور",
        "block-log-flags-noemail": "ائ-مایل بلوکلانیب",
        "allmessagesname": "آد",
        "allmessagesdefault": "دفالت دانیشیق متنی",
        "allmessagescurrent": "ایندیکی متن",
-       "allmessagestext": "بو مئدیا ویکی-ده اولان سیستئم مئساژلارینین سیاهی‌سی‌دیر. اگر مئدیا ویکی-نی لوکاللاش‌دیرماق ایشینده کؤمک ائتمک ایسییرسینیزسه، لطفاً [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] و [//translatewiki.net translatewiki.net]-ا باش چکین.",
+       "allmessagestext": "بۇ مئدیاویکی-ده اوْلان سیستم مئساژلاری‌نین سیاهی‌سی‌دیر. اگر مئدیاویکی-نی لوْکاللاشدیرماق ایشینده کؤمک ائتمک ایسه‌يیرسینیزسه، لطفاً [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] و [//translatewiki.net translatewiki.net]-ه باش چکین.",
        "allmessagesnotsupportedDB": "'''$ wgUseDatabaseMessages''' باغ‌لی اولدوغو اوچون '{{ns:special}}: Allmessages ایستیفاده‌یه آچیق دئییل.",
        "allmessages-filter-legend": "سۆزگَج",
        "allmessages-filter": "خصوصی ائتمک وضعیتینه گؤره فیلترلی:",
        "others": "آیریلار",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|وسئر|یستیفاده‌چی}} $1",
        "anonusers": "{{SITENAME}} آنونیم {{PLURAL:$2|وسئر|یستیفاده‌چی}} $1",
-       "creditspage": "صحیفه اعتبارلاری",
+       "creditspage": "صفحه اعتبارلاری",
        "nocredits": "بو صحیفه اوچون هئچ بیر اعتیبار بیلگیلری ال‌ده دئییل.",
        "spamprotectiontitle": "فایداسیز یازما قوروما فیلتری",
        "spamprotectiontext": "سیز قئید ائتمک ایسته‌دیگینیز یازینین قاباغی، اِسپم فیلتِریله، آلیندی.\nبو ایش، اوندا ائشیک قره‌لیست‌ده اولان بیر سایتا باغلانتی وئرمک اوچون اولا بیلر.",
        "pageinfo-header-basic": "اساس معلومات‌لار",
        "pageinfo-header-edits": "تاریخچه نی دییشدیر",
        "pageinfo-header-restrictions": "صفحه دن محافظت ائله مک",
-       "pageinfo-header-properties": "صحیفه خصوصیت‌لری",
+       "pageinfo-header-properties": "صفحه خصوصیتلری",
        "pageinfo-display-title": "گؤستریلن باشلیق",
        "pageinfo-default-sort": "فرض ائدیلن سیرالاما آچاری",
        "pageinfo-length": "صحیفه‌‌ اوزونلوغو (بايت)",
        "img-lang-go": "گئت",
        "ascending_abbrev": "آرتما سیراسینا گؤره",
        "descending_abbrev": "آزالما سیراسینا گؤره",
-       "table_pager_next": "سÙ\88Ù\86راکÛ\8c ØµØ­Û\8cÙ\81ه",
+       "table_pager_next": "سÙ\88Ù\92Ù\86راکÛ\8c ØµÙ\81Ø­ه",
        "table_pager_prev": "قاباغکی صحیفه",
        "table_pager_first": "ایلک صحیفه‌‌",
        "table_pager_last": "سون صحیفه‌‌",
        "logentry-delete-delete": "$1، $3 صفحه‌سینی {{GENDER:$2|سیلدی}}",
        "logentry-delete-restore": "$1، $3 صفحه‌سینی {{GENDER:$2|قایتاردی}}",
        "logentry-delete-event": "$1، $3-ده $5 سیاهی اولایینین {{PLURAL:$5|گؤرونوشونو|گؤرونوشلرینی}} {{GENDER:$2|دَییشدیردی}}: $4",
-       "logentry-delete-revision": "$1، $3 صحیفه‌سینده $5 نوسخه‌نین {{PLURAL:گؤرونوشونو|گؤرونوشلرینی}} {{GENDER:$2|دَییشدیردی}}: $4",
+       "logentry-delete-revision": "$1، $3 صفحه‌سینده $5 نوسخه‌نین {{PLURAL:گؤرونوشونو|گؤرونوشلرینی}} {{GENDER:$2|دَییشدیردی}}: $4",
        "logentry-delete-event-legacy": "$1، $3-ده سیاهی اولایلارینین گؤرونوشلرینی {{GENDER:$2|دَییشدیردی}}",
        "logentry-delete-revision-legacy": "$1، $3 صحیفه‌سینده نوسخه‌لرین گؤرونوشلرینی {{GENDER:$2|دَییشدیردی}}",
        "logentry-suppress-delete": "$1، $3 صفحه‌سینی {{GENDER:$2|یاتیردی}}",
        "logentry-suppress-event": "$1، $3-ده $5 سیاهی اولایینین {{PLURAL:$5|گؤرونوشونو|گؤرونوشلرینی}} گیزلینجه {{GENDER:$2|دَییشدیردی}}: $4",
-       "logentry-suppress-revision": "$1، $3 صحیفه‌سینده $5 نوسخه‌نین {{PLURAL:گؤرونوشونو|گؤرونوشلرینی}} گیزلینجه {{GENDER:$2|دَییشدیردی}}: $4",
+       "logentry-suppress-revision": "$1، $3 صفحه‌سینده $5 نوسخه‌نین {{PLURAL:گؤرونوشونو|گؤرونوشلرینی}} گیزلینجه {{GENDER:$2|دَییشدیردی}}: $4",
        "logentry-suppress-event-legacy": "$1، $3-ده سیاهی اولایلارینین گؤرونوشلرینی گیزلینجه {{GENDER:$2|دَییشدیردی}}",
        "logentry-suppress-revision-legacy": "$1، $3 صحیفه‌سینده نوسخه‌لرین گؤرونوشلرینی گیزلینجه {{GENDER:$2|دَییشدیردی}}",
        "revdelete-content-hid": "ایچینده‌کیلر گیزلی‌دیر",
        "revdelete-uname-unhid": "ایستیفاده‌چی آدی گیزلیلیک‌دن چیخدی",
        "revdelete-restricted": "ایداره‌چیلره محدودیت قویدو",
        "revdelete-unrestricted": "ایداره‌چیلرین محدودیتلرینی گؤتوردو",
-       "logentry-block-block": "$1 {{GENDER:$4|$3}}-نی {{GENDER:$2|بلوکلادی}}. قورتارماق تاریخی: $5 $6",
+       "logentry-block-block": "$1 {{GENDER:$4|$3}}-نی {{GENDER:$2|باغلادی}}. قۇرتارماق تاریخی: $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$4|$3}}-نین {{GENDER:$2|بلوکلاماغینی قالدیردی}}",
        "logentry-move-move": "$1، $3 صفحه‌سینی $4-ه {{GENDER:$2|آپاردی}}",
        "logentry-move-move-noredirect": "$1، $3 صفحه‌سینی، یوْل‌لاندیرما قوْیماماق‌لا، $4-ه {{GENDER:$2|آپاردی}}",
index c8e00f8..4d8cfae 100644 (file)
        "searchrelated": "ҡағылышлы",
        "searchall": "барыһы",
        "showingresults": "Түбәндә №&nbsp;<strong>$2</strong> һөҙөмтәнән башлап <strong>$1</strong> {{PLURAL:$1|һөҙөмтә}} күрһәтелгән.",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> нәтижәнән <strong>$1</strong>| <strong>$3</strong> нәтижәләрҙән <strong>$1 — $2</strong>}}",
        "search-nonefound": "Был һорауға яуап биреүсе һөҙөмтәләр табылманы.",
        "powersearch-legend": "Киңәйтелгән эҙләү",
        "powersearch-ns": "Исем аралыҡтарында эҙләү:",
        "recentchanges-label-unpatrolled": "Был төҙәтеү ҡаралмаған әле",
        "recentchanges-label-plusminus": "Бит шул тиклем байтҡа үҙгәрҙе",
        "recentchanges-legend-heading": "'''Легенда:'''",
-       "recentchanges-legend-newpage": "$1 — яңы бит",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|Яңы биттәр исемлеген]] ҡарағыҙ)",
        "rcnotefrom": "Түбәндә '''$2''' башлап ('''$1''' тиклем) үҙгәртеүҙәр күрһәтелгән.",
        "rclistfrom": "$3 $2 башлап яңы үҙгәртеүҙәрҙе күрһәт.",
        "rcshowhideminor": "бәләкәй төҙәтеүҙәрҙе $1",
        "querypage-disabled": "Был махсус бит һөҙөмтәлелекте арттырыу өсөн ябылған.",
        "apihelp": "API белешмәһе",
        "apihelp-no-such-module": "«$1» модуле табылмаған.",
+       "apisandbox": "API һынау урыны",
+       "apisandbox-api-disabled": "Был сайтта API һүндерелгән.",
+       "apisandbox-intro": "''MediaWiki API''' өйрәнеү бите.  API ҡулланыу тураһында белешмә алыу өсөн [//www.mediawiki.org/wiki/API:Main_page API документацияһы]на мөрәжәғәт итегеҙ. Мәҫәләң, [//www.mediawiki.org/wiki/API#A_simple_example Башбит эстәлеген нисек алырға]. Башҡа миҫалдарҙы күреү өсөн ғәмәлде ҡулланығыҙ.",
+       "apisandbox-submit": "Һоратыу яһарға",
+       "apisandbox-reset": "Таҙарт",
+       "apisandbox-examples": "Миҫал",
+       "apisandbox-results": "Һөҙөмтә",
+       "apisandbox-request-url-label": "Һоратыуҙың URL-адресы:",
+       "apisandbox-request-time": "Мөрәжәғәт ваҡыты:$1",
        "booksources": "Китап сығанаҡтары",
        "booksources-search-legend": "Китап сығанаҡтарын эҙлә",
        "booksources-search": "Эҙләү",
        "tooltip-pt-logout": "Сығырға",
        "tooltip-pt-createaccount": "Мотлаҡ булмаһа ла, Һеҙгә иҫәп яҙмаһы төҙөргө һәм системала танылырға тәҡдим итәбеҙ.",
        "tooltip-ca-talk": "Биттең эстәлеге тураһында фекерләшеү",
-       "tooltip-ca-edit": "ҺеÒ\99 Ð±Ñ\8bл Ð±Ð¸Ñ\82Ñ\82е Ò¯Ò\99гÓ\99Ñ\80Ñ\82Ó\99 Ð°Ð»Ð°Ò»Ñ\8bÒ\93Ñ\8bÒ\99. Ð\97инһаÑ\80, Ñ\8fÒ\99Ñ\8bп Ò¡Ñ\83йÑ\8bÑ\80 Ð°Ð»Ð´Ñ\8bнан Ò¡Ð°Ñ\80ап Ñ\81Ñ\8bÒ\93Ñ\8bÒ\93Ñ\8bÒ\99",
+       "tooltip-ca-edit": "Ð\91Ñ\8bл Ð±Ð¸Ñ\82Ñ\82е Ò¯Ò\99гÓ\99Ñ\80Ñ\82еÑ\80гÓ\99",
        "tooltip-ca-addsection": "Яңы бүлек эшләргә",
        "tooltip-ca-viewsource": "Был бит үҙгәртеүҙән һаҡланған.\nТик сығанаҡ текстын ғына ҡарай һәм күсереп ала алаһығыҙ.",
        "tooltip-ca-history": "Биттең төҙәтеүҙәр исемлеге",
        "tooltip-t-recentchangeslinked": "Был биттән һылтанған биттәрҙә һуңғы үҙгәртеүҙәр",
        "tooltip-feed-rss": "Был бит өсөн RSS-таҫма",
        "tooltip-feed-atom": "Был бит өсөн Atom-таҫма",
-       "tooltip-t-contributions": "Был ҡулланыусының кереткән өлөшөн ҡарарға",
+       "tooltip-t-contributions": "{{GENDER:$1|Был ҡулланыусының}} кереткән өлөшөн ҡарарға",
        "tooltip-t-emailuser": "Был ҡулланыусыға хат ебәрергә",
        "tooltip-t-upload": "Рәсем йәки тауыш эстәлекле файлдарҙы тейәргә",
        "tooltip-t-specialpages": "Барлыҡ махсус биттәр исемлеге",
        "spam_reverting": "$1 һылтанмаһыҙ һуңғы өлгөгә ҡайтарыу",
        "spam_blanking": "Бөтә өлгөләрҙә лә $1 һылтанмаһы бар, таҙартыу",
        "spam_deleting": "Бөтә өлгөләрҙә лә $1 һылтанма бар, таҙартыу бара",
-       "simpleantispam-label": "Спамға ҡаршы тикшереү.\nБыны '''ТУЛТЫРМАҒЫҘ'''!",
+       "simpleantispam-label": "Спамға ҡаршы тикшереү.\nБыны <strong>ТУЛТЫРМАҒЫҘ</strong>!",
        "pageinfo-title": "«$1» буйынса мәғлүмәт",
        "pageinfo-not-current": "Ғәфү итегеҙ, был мәғлүмәтте иҫке версиялар өсөн күрһәтеп булмай.",
        "pageinfo-header-basic": "Төп мәғлүмәт",
index f915623..949d107 100644 (file)
        "botpasswords-label-delete": "Выдаліць",
        "botpasswords-label-resetpassword": "Ачысьціць пароль",
        "botpasswords-label-grants": "Прыдатныя дазволы:",
+       "botpasswords-help-grants": "Кожны дазвол дае доступ да правоў удзельніка, якія ўжо мае рахунак удзельніка. Глядзіце [[Special:ListGrants|табліцу дазволаў]] дзеля дадатковых зьвестак.",
        "botpasswords-label-restrictions": "Абмежаваньні на выкарыстаньне:",
        "botpasswords-label-grants-column": "Дазволена",
        "botpasswords-bad-appid": "Назва робата «$1» зьяўляецца няслушнай.",
+       "botpasswords-insert-failed": "Не атрымалася дадаць робата зь імем «$1». Магчыма, ён ужо быў дададзены?",
+       "botpasswords-update-failed": "Не атрымалася абнавіць робата зь імем «$1». Магчыма, ён быў выдалены?",
+       "botpasswords-created-title": "Пароль робата створаны",
+       "botpasswords-created-body": "Пароль робата «$1» быў пасьпяхова створаны.",
+       "botpasswords-updated-title": "Пароль робата абноўлены",
+       "botpasswords-updated-body": "Пароль робата «$1» быў пасьпяхова абноўлены.",
        "resetpass_forbidden": "Пароль ня можа быць зьменены",
        "resetpass-no-info": "Для непасрэднага доступу да гэтай старонкі Вам неабходна ўвайсьці ў сыстэму.",
        "resetpass-submit-loggedin": "Зьмяніць пароль",
        "right-managechangetags": "ствараць і выдаляць [[Special:Tags|меткі]] з базы зьвестак",
        "right-applychangetags": "дадаваць [[Special:Tags|меткі]] пры рэдагаваньні",
        "right-changetags": "дадаваць і выдаляць адвольныя [[Special:Tags|меткі]] да асобных вэрсіяў і запісаў у журнале падзеяў",
+       "grant-generic": "Набор правоў «$1»",
+       "grant-group-page-interaction": "Узаемадзеньне з старонкамі",
        "grant-createaccount": "Стварыць рахункі",
        "grant-createeditmovepage": "Ствараць, рэдагаваць і пераносіць старонкі",
        "grant-delete": "Выдаляць старонкі, вэрсіі і запісы журналу",
        "uploaded-script-svg": "У загружаным SVG-файле знойдзены небясьпечны элемэнт з падтрымкай сцэнароў «$1».",
        "uploaded-hostile-svg": "Знойдзены небясьпечны CSS у элемэнце стылю загружанага SVG-файла.",
        "uploaded-event-handler-on-svg": "Усталёўваць атрыбуты апрацоўніка падзеяў <code>$1=\"$2\"</code> не дазволена для SVG-файлаў.",
-       "uploaded-href-attribute-svg": "У SVG-файлах не дазволеныя href-атрыбуты <code>&lt;$1 $2=\"$3\"&gt;</code> зь нелякальнай мэтай (напрыклад, http://, javascript:, і г. д.).",
-       "uploaded-href-unsafe-target-svg": "У загружаным SVG-файле знойдзеная спасылка на небясьпечную мэту <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "У загружаным SVG-файле знойдзеная спасылка на небясьпечныя зьвесткі: URI-мэты <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "У загружаным SVG-файле знойдзены тэг «animate», які можа зьмяняць спасылку з дапамогай атрыбуту «from» <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Усталёўка атрыбутаў апрацоўкі падзеяў заблякаваная, у загружаным SVG-файле знойдзены код <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Выкарыстаньне тэгу «set» для дадаваньня атрыбуту «href» у бацькоўскі элемэнт заблякаванае.",
        "querypage-disabled": "Гэта спэцыяльная старонка адключаная для падвышэньня прадукцыйнасьці",
        "apihelp": "Даведка API",
        "apihelp-no-such-module": "Модуль «$1» ня знойдзены.",
+       "apisandbox": "Пясочніца API",
+       "apisandbox-api-disabled": "API забаронены на гэтым сайце.",
+       "apisandbox-intro": "Выкарыстоўвайце гэтую старонку для экспэрымэнтаў з <strong>API вэб-сэрвісу MediaWiki</strong>.\nЗьвяртайцеся да [[mw:API:Main page|дакумэнтацыі API]] для дадатковай інфармацыі па выкарыстаньні API. Напрыклад, [//www.mediawiki.org/wiki/API#A_simple_example як атрымаць зьмест галоўнай старонкі]. Абярыце дзеяньне, каб пабачыць болей узораў.\n\nЗьвярніце ўвагу, што нягледзячы на тое, што гэта пясочніца, вашыя дзеяньні могуць унесьці зьмены ў вікі.",
+       "apisandbox-submit": "Зрабіць запыт",
+       "apisandbox-reset": "Ачысьціць",
+       "apisandbox-examples": "Прыклады",
+       "apisandbox-results": "Вынікі",
+       "apisandbox-request-url-label": "URL-адрас запыту:",
+       "apisandbox-request-time": "Час апрацоўкі запыту: $1",
        "booksources": "Крыніцы кніг",
        "booksources-search-legend": "Пошук кніг",
        "booksources-isbn": "ISBN:",
        "whatlinkshere": "Спасылкі на старонку",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на $1",
        "whatlinkshere-page": "Старонка:",
-       "linkshere": "Наступныя старонкі спасылаюцца на '''[[:$1]]''':",
+       "linkshere": "Наступныя старонкі спасылаюцца на <strong>[[:$1]]</strong>:",
        "nolinkshere": "Ніводная старонка не спасылаецца на '''[[:$1]]'''.",
        "nolinkshere-ns": "Ніводная старонка не спасылаецца на '''[[:$1]]''' з выбранай прасторы назваў.",
        "isredirect": "старонка-перанакіраваньне",
        "version-hook-subscribedby": "Падпісаны на",
        "version-version": "($1)",
        "version-no-ext-name": "[бяз назвы]",
-       "version-svn-revision": "(r$2)",
        "version-license": "Ліцэнзія MediaWiki",
        "version-ext-license": "Ліцэнзія",
        "version-ext-colheader-name": "Пашырэньне",
        "version-libraries-authors": "Аўтары",
        "redirect": "Перанакіраваньне да файла, удзельніка, старонкі, вэрсіі або журнала",
        "redirect-legend": "Перанакіраваньне да файла або старонкі",
-       "redirect-summary": "Гэтая спэцыяльная старонка перанакіруе да файла (паводле імя файла), старонкі (паводле нумару вэрсіі або старонкі) або старонкі ўдзельніка (паводле нумару ўдзельніка). Ужываньне: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] або [[{{#Special:Redirect}}/user/101]].",
+       "redirect-summary": "Гэтая спэцыяльная старонка перанакіруе да файла (паводле імя файла), старонкі (паводле нумару вэрсіі або старонкі), старонкі ўдзельніка (паводле нумару ўдзельніка) або запісу ў журнале падзеяў (паводле нумару ў журнале). Ужываньне: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]],[[{{#Special:Redirect}}/user/101]] або [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Перайсьці",
        "redirect-lookup": "Шукаць паводле:",
        "redirect-value": "Значэньне:",
        "action-pagelang": "зьмену мовы старонкі",
        "log-name-pagelang": "Журнал зьменаў мовы",
        "log-description-pagelang": "Гэта журнал зьменаў мовы старонак.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} мову старонкі $3 з $4 на $5.",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} мову старонкі $3 з $4 на $5",
        "default-skin-not-found": "Упс! Тэма афармленьня па змоўчаньні для вашай вікі, вызначаная ў <code dir=\"ltr\">$wgDefaultSkin</code> як <code>$1</code> недаступная.\n\nВашае ўсталяваньне, падобна, уключае {{PLURAL:$4|наступную тэму афармленьне|наступныя тэмы афармленьня}}. Глядзіце старонку [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць {{PLURAL:$4|яе|іх і абраць тэму па змоўчаньні}}.\n\n$2\n\n; Калі вы толькі што ўсталявалі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins каталёгу тэмаў mediawiki.org]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code>skins/</code> зь яго.\n:* Спампуйце tarball-усталёўнікі для асобных тэмаў з [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Выкарыстайце Git, каб спампаваць тэмы афармленьня].\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча.\n\n; Калі вы толькі што абнавілі MediaWiki:\n: MediaWiki вэрсіі 1.24 і навейшыя больш не падключаюць тэмы афармленьня аўтаматычна (глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Інструкцыя:Аўтаматычнае выяўленьне тэмаў афармленьня]). Вы можаце дадаць {{PLURAL:$5|наступны радок у|наступныя радкі ў}} <code>LocalSettings.php</code>, каб падключыць {{PLURAL:$5|усталяваную тэму|усе ўсталяваныя тэмы}} афармленьня:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Калі вы толькі што зьмянілі <code>LocalSettings.php</code>:\n: Пераправерце назвы тэмаў афармленьня на наяўнасьць памылак.",
        "default-skin-not-found-no-skins": "Упс! Тэма афармленьня па змоўчаньні для вашай вікі, вызначаная ў <code>$wgDefaultSkin</code> як <code>$1</code>, недаступная.\n\nВы ня маеце ўсталяваных тэмаў афармленьня.\n\n; Калі вы толькі што ўсталявалі або абнавілі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. MediaWiki вэрсіі 1.24 і навейшыя ня ўтрымліваюць тэмы афармленьня ў галоўным сховішчы. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins каталёгу тэмаў mediawiki.org]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code dir=\"ltr\">skins/</code> зь яго.\n:* Спампуйце tarball-усталёўнікі для асобны тэмаў афармленьня з [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Выкарыстайце Git, каб спампаваць тэмы афармленьня].\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча. Глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць іх і абраць тэму па змоўчаньні.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
index fb49e5c..2d06b1e 100644 (file)
        "revdelete-no-file": "Посоченият файл не съществува.",
        "revdelete-show-file-confirm": "Необходимо е потвърждение, че желаете да прегледате изтритата версия на файла „<nowiki>$1</nowiki>“ от $2 $3.",
        "revdelete-show-file-submit": "Да",
+       "revdelete-selected-text": "{{PLURAL:$1|Избрана версия|Избрани версии}} от [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Избрано събитие|Избрани събития}}:",
        "revdelete-confirm": "Необходимо е да потвърдите, че желаете да извършите действието, разбирате последствията и го правите според [[{{MediaWiki:Policy-url}}|политиката]].",
        "revdelete-suppress-text": "Премахването трябва да се използва '''само''' при следните случаи:\n* Потенциално уязвима в правно отношение информация\n* Неподходяща лична информация\n*: ''домашни адреси и телефонни номера, номера за социално осигуряване и др.''",
        "right-override-export-depth": "Изнасяне на страници, включително свързаните с тях в дълбочина до пето ниво",
        "right-sendemail": "Изпращане на е-писма до другите потребители",
        "right-passwordreset": "Преглеждане на е-писма за възстановяване на парола",
+       "grant-group-email": "Изпращане на е-писмо",
        "grant-delete": "Изтриване на страници, редакции и записи в дневника",
        "grant-editmyoptions": "Редактиране на вашите потребителски настройки",
        "grant-editmywatchlist": "редактиране на списъка ви за наблюдение",
        "suppress": "Премахване от публичния архив",
        "querypage-disabled": "Тази специална страница е изключена, защото затруднява производителността на уикито.",
        "apihelp-no-such-module": "Модул \"$1\" не беше намерен.",
+       "apisandbox-reset": "Изчистване",
+       "apisandbox-examples": "Пример",
+       "apisandbox-results": "Резултат",
        "booksources": "Източници на книги",
        "booksources-search-legend": "Търсене на информация за книга",
        "booksources-search": "Търсене",
        "logempty": "Дневникът не съдържа записи, отговарящи на избрания критерий.",
        "log-title-wildcard": "Търсене на заглавия, започващи със",
        "showhideselectedlogentries": "Промяна на видимостта на избраните записи",
+       "checkbox-all": "Всички",
+       "checkbox-none": "Никои",
        "allpages": "Всички страници",
        "nextpage": "Следваща страница ($1)",
        "prevpage": "Предходна страница ($1)",
        "listgrouprights-removegroup-self-all": "Може да премахва всички групи от собствената сметка",
        "listgrouprights-namespaceprotection-header": "Ограничения на именните пространства",
        "listgrouprights-namespaceprotection-namespace": "Именно пространство",
+       "listgrants-rights": "Права",
        "trackingcategories": "Категории за проследяване",
        "trackingcategories-summary": "Тази страница съдържа списък на категории за проследяване, които се попълват автоматично от софтуера на МедияУики. Имената им могат да се променят чрез съответните системни съобщения в именното пространство {{ns:8}}.",
        "trackingcategories-msg": "Категория за проследяване",
index 1a1c0c4..252074a 100644 (file)
        "laggedslavemode": "সতর্কীকরণ: পাতাটি সম্ভবত সম্প্রতি হালনাগাদকৃত নয়।",
        "readonly": "ডেটাবেজের ব্যবহার সীমাবদ্ধ",
        "enterlockreason": "তালাবদ্ধ করার কারণ কি তা বলুন, সাথে কখন তালা খুলবেন তার আনুমানিক সময় উল্লখ্য করুন",
-       "readonlytext": "নতà§\81ন à¦­à§\81à¦\95à§\8dতি à¦\8fবà¦\82 à¦\85নà§\8dযানà§\8dয à¦¸à¦®à§\8dপাদনার à¦\9cনà§\8dয à¦¡à¦¾à¦\9fাবà§\87à¦\9c à¦¬à¦°à§\8dতমানà§\87 à¦¬à¦¨à§\8dধ à¦\95রা à¦\86à¦\9bà§\87। à¦¸à¦®à§\8dভবত à¦¡à¦¾à¦\9fাবà§\87à¦\9c à¦°à¦\95à§\8dষণাবà§\87à¦\95à§\8dষণà§\87র à¦¨à¦¿à¦¯à¦¼à¦®à¦¿à¦¤ à¦\95াà¦\9c à¦\9aলà¦\9bà§\87। à¦\95িà¦\9bà§\81à¦\95à§\8dষণ à¦ªà¦°à§\87 à¦\8fà¦\9fি à¦¸à§\8dবাভাবিà¦\95 à¦\85বসà§\8dথায় à¦«à¦¿à¦°à§\87 à¦\86সবà§\87।\n\nপà§\8dরশাসà¦\95 এই ব্যাখ্যা দিয়েছেন: $1",
+       "readonlytext": "নতà§\81ন à¦­à§\81à¦\95à§\8dতি à¦\8fবà¦\82 à¦\85নà§\8dযানà§\8dয à¦¸à¦®à§\8dপাদনার à¦\9cনà§\8dয à¦¡à¦¾à¦\9fাবà§\87à¦\9c à¦¬à¦°à§\8dতমানà§\87 à¦¬à¦¨à§\8dধ à¦\95রা à¦\86à¦\9bà§\87। à¦¸à¦®à§\8dভবত à¦¡à¦¾à¦\9fাবà§\87à¦\9c à¦°à¦\95à§\8dষণাবà§\87à¦\95à§\8dষণà§\87র à¦¨à¦¿à¦¯à¦¼à¦®à¦¿à¦¤ à¦\95াà¦\9c à¦\9aলà¦\9bà§\87। à¦\95িà¦\9bà§\81à¦\95à§\8dষণ à¦ªà¦°à§\87 à¦\8fà¦\9fি à¦¸à§\8dবাভাবিà¦\95 à¦\85বসà§\8dথায় à¦«à¦¿à¦°à§\87 à¦\86সবà§\87।\n\nসিসà§\8dà¦\9fà§\87ম à¦ªà§\8dরশাসà¦\95 à¦¯à¦¿à¦¨à¦¿ à¦\8fà¦\9fি à¦¬à¦¨à§\8dধ à¦\95রà§\87à¦\9bà§\87ন à¦¤à¦¿à¦¨à¦¿ এই ব্যাখ্যা দিয়েছেন: $1",
        "missing-article": "\"$1\" $2 লেখাটি ডাটাবেসের কোন পাতায় খুজে পাওয়া যায়নি।\n\nমুছে ফেলা কোন পাতায় সংযোগ থাকার কারনেই সাধারণত এমনটি ঘটে।\n\nযদি এমনটি না হয়, তাহলে আপনি সফটওয়্যারে কোন ত্রুটি খুজে পেয়েছেন।\nদয়াকরে এ ব্যাপার সম্পর্কে ইউআরএল সহ কোন [[Special:ListUsers/sysop|প্রশাসককে]] জানান।",
        "missingarticle-rev": "(সংস্করণ#: $1)",
        "missingarticle-diff": "(পার্থক্য: $1, $2)",
        "mypreferencesprotected": "আপনার পছন্দসমূহ সম্পাদনা করতে আপনার অনুমতি নেই",
        "ns-specialprotected": "বিশেষ পাতাসমূহ সম্পাদনা করা যাবে না।",
        "titleprotected": "[[User:$1|$1]] কর্তৃক এই শিরোনামটি সৃষ্টি করা থেকে সুরক্ষিত করা হয়েছে। কারণ: \"<em>$2</em>\"।",
-       "filereadonlyerror": "\"$1\" à¦«à¦¾à¦\87লà¦\9fিà¦\95à§\87 à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রা à¦¸à¦®à§\8dভব à¦¹à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾ à¦\95ারন \"$2\" à¦«à¦¾à¦\87ল à¦°à¦¿à¦ªà§\8bসিà¦\9fà§\8bরি à¦°à¦¿à¦¡-à¦\85নলি-মà§\8bডà§\87 à¦\86à¦\9bà§\87।\n\nà¦\8fà¦\95à¦\9cন à¦ªà§\8dরশাসà¦\95 à¦¯à¦¿à¦¨à¦¿ à¦\8fà¦\9fাà¦\95à§\87 à¦²à¦\95ড à¦\95রà§\87à¦\9bà§\87ন à¦¤à¦¾à¦° à¦¯à§\8cà¦\95à§\8dতিà¦\95তা à¦¦à§\87à¦\93য়া à¦¹à¦²: \"$3\"",
+       "filereadonlyerror": "\"$1\" à¦«à¦¾à¦\87লà¦\9fিà¦\95à§\87 à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রা à¦¸à¦®à§\8dভব à¦¹à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾ à¦\95ারণ \"$2\" à¦«à¦¾à¦\87ল à¦¸à¦\82à¦\97à§\8dরহসà§\8dথল à¦¶à§\81ধà§\81মাতà§\8dর-পঠন à¦®à§\8bডà§\87 à¦\86à¦\9bà§\87।\n\nসিসà§\8dà¦\9fà§\87ম à¦ªà§\8dরশাসà¦\95 à¦¯à¦¿à¦¨à¦¿ à¦\8fà¦\9fি à¦¬à¦¨à§\8dধ à¦\95রà§\87à¦\9bà§\87ন à¦¤à¦¿à¦¨à¦¿ à¦\8fà¦\87 à¦¬à§\8dযাà¦\96à§\8dযা à¦¦à¦¿à¦¯à¦¼à§\87à¦\9bà§\87ন: \"$3\"।",
        "invalidtitle-knownnamespace": "অবৈধ শিরোনাম, যেখানে নামস্থান \"$2\" এবং লেখা হয়েছে \"$3\"",
        "invalidtitle-unknownnamespace": "অবৈধ শিরোনাম, যেখানে ব্যবহৃত হয়েছে অপরিচিত নামস্থান সংখ্যা $1 এবং লেখা হয়েছে \"$2\"",
        "exception-nologin": "লগইন করা হয়নি",
        "botpasswords-label-delete": "অপসারণ",
        "botpasswords-label-resetpassword": "পাসওয়ার্ড পুনঃস্থাপন",
        "botpasswords-label-grants": "প্রয়োগযোগ্য মঞ্জুরি:",
+       "botpasswords-label-grants-column": "অনুমোদিত",
+       "botpasswords-bad-appid": "\"$1\" বট নামটি সঠিক নয়।",
+       "botpasswords-insert-failed": "\"$1\" নামের বট যুক্ত করা যায়নি। আগে থেকেই তালিকায় রয়েছে?",
+       "botpasswords-update-failed": "\"$1\" নামের বট যুক্ত করা যায়নি। আগে অপসারণ করা হয়েছিল?",
+       "botpasswords-created-title": "বট পাসওয়ার্ড তৈরী করা হয়েছে",
+       "botpasswords-created-body": "\"$1\", বট পাসওয়ার্ড তৈরী করা হয়েছে।",
+       "botpasswords-updated-title": "বট পাসওয়ার্ড আপডেট করা হয়েছে",
+       "botpasswords-updated-body": "\"$1\" বট পাসওয়ার্ডটি সফলভাবে হালনাগাদ করা হয়েছে।",
+       "botpasswords-deleted-title": "বট পাসওয়ার্ড অপসারণ করা হয়েছে",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider উপলব্ধ নয়।",
        "resetpass_forbidden": "পাসওয়ার্ড পরিবর্তন করা সম্ভব নয়",
        "resetpass-no-info": "এই পাতাটিতে সরাসরি প্রবেশাধিকার পেতে আপনাকে অবশ্যই লগইন করতে হবে।",
        "resetpass-submit-loggedin": "পাসওয়ার্ড পরিবর্তন",
        "passwordreset-emailtext-ip": "কেউ একজন (সম্ভবত আপনি, $1 আইপি ঠিকানা থেকে) {{SITENAME}} ($4) সাইটের জন্য আপনার\nপাসওয়ার্ড বদলের জন্য অনুরোধ করেছে। নিচের ব্যবহারকারী {{PLURAL:$3|অ্যাকাউন্টটি|অ্যাকাউন্টগুলো}}\nএই ই-মেইল ঠিকানার সাথে সংযুক্ত:\n\n$2\n\n{{PLURAL:$3|এই অস্থায়ী পাসওয়ার্ডটি|এই অস্থায়ী পাসওয়ার্ডগুলো}} আগামী {{PLURAL:$5|এক দিন|$5 দিন}} পর মেয়াদোত্তীর্ণ হয়ে যাবে।\nআপনার অবশ্যই লগ-ইন করে একটি নতুন পাসওয়ার্ড পছন্দ করা উচিত। যদি অন্য কেউ এই অনুরোধ করে থাকে,\nঅথবা আপনি যদি পুরোনো পাসওয়ার্ড মনে করতে পারেন, এবং আপনার সেটি পরিবর্তন করার কোনো ইচ্ছা না থাকে, তবে\nআপনি এই বার্তাটি উপেক্ষা করতে পারে, এবং আপনার পুরোনো পাসওয়ার্ড ব্যবহার করা চালিয়ে যেতে পারেন।",
        "passwordreset-emailtext-user": "ব্যবহারকারী $1 {{SITENAME}} ($4) সাইটের জন্য আপনার পাসওয়ার্ড বদলের জন্য অনুরোধ করেছে। নিচের ব্যবহারকারী {{PLURAL:$3|অ্যাকাউন্টটি|অ্যাকাউন্টগুলো}}\nএই ই-মেইল ঠিকানার সাথে সংযুক্ত:\n\n$2\n\n{{PLURAL:$3|এই অস্থায়ী পাসওয়ার্ডটি|এই অস্থায়ী পাসওয়ার্ডগুলো}} আগামী {{PLURAL:$5|এক দিন|$5 দিন}} পর মেয়াদোত্তীর্ণ হয়ে যাবে।\nআপনার অবশ্যই লগ-ইন করে একটি নতুন পাসওয়ার্ড পছন্দ করা উচিত। যদি অন্য কেউ এই অনুরোধ করে থাকে,\nঅথবা আপনি যদি পুরোনো পাসওয়ার্ড মনে করতে পারেন, এবং আপনার সেটি পরিবর্তন করার কোনো ইচ্ছা না থাকে, তবে\nআপনি এই বার্তাটি উপেক্ষা করতে পারে, এবং আপনার পুরোনো পাসওয়ার্ড ব্যবহার করা চালিয়ে যেতে পারেন।",
        "passwordreset-emailelement": "ব্যবহারকারী নাম: \n$1\n\nঅস্থায়ী পাসওয়ার্ড: \n$2",
-       "passwordreset-emailsentemail": "যদি à¦\86পনার à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà§\87র à¦\9cনà§\8dয à¦\8fà¦\9fি à¦\8fà¦\95à¦\9fি à¦¨à¦¿à¦¬à¦¨à§\8dধিত à¦\87মà§\87ল à¦ à¦¿à¦\95ানা à¦¹à¦¯à¦¼, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
+       "passwordreset-emailsentemail": "যদি à¦\8fà¦\87 à¦\87-মà§\87à¦\87ল à¦ à¦¿à¦\95ানা à¦\86পনার à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà§\87র à¦¸à¦¾à¦¥à§\87 à¦¸à¦\82যà§\81à¦\95à§\8dত à¦\95রা à¦¥à¦¾à¦\95à§\87, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
        "passwordreset-emailsent-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল করা হয়েছে, যা নিচে দেখানো হচ্ছে।",
        "passwordreset-emailerror-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল তৈরী করা হয়েছিল, যা নিচে দেখানো হচ্ছে, তবে $1 {{GENDER:$2|ব্যবহারকারীকে}} এটি পাঠানো যায়নি!",
        "changeemail": "ই-মেইল ঠিকানা পরিবর্তন বা বাতিল",
        "copyrightwarning2": "অনুগ্রহ করে লক্ষ করুন: {{SITENAME}}-এর এই ভুক্তিতে আপনার লেখা বা অবদান অন্যান্য ব্যবহারকারীরা পরিবর্তন বা পরিবর্ধন করতে, এমনকি মুছে ফেলতে পারবেন। {{SITENAME}} এ আপনার সকল লেখালেখি/অবদান গনু ফ্রি ডকুমেন্টেশনের ($1) আওতায় বিনামূল্যে প্রাপ্য ও হস্তান্তরযোগ্য। আপনার জমা দেয়া লেখা যে কেউ হৃদয়হীনভাবে সম্পাদনা করতে এবং যথেচ্ছভাবে ব্যবহার করতে পারেন। আপনি যদি এ ব্যাপারে একমত না হন, তাহলে এখানে আপনার লেখা জমা দেবেন না। আপনি আরো প্রতিজ্ঞা করছেন যে, এই লেখাগুলো আপনি নিজে লিখেছেন (তবে কোন মৌলিক গবেষণা নয়) বা সাধারণের ব্যবহারের জন্য উন্মুক্ত কোন উৎস থেকে সংগ্রহ করেছেন। '''স্বত্ব সংরক্ষিত কোন লেখা স্বত্বাধিকারীর অনুমতি ছাড়া এখানে জমা দেবেন না।'''",
        "editpage-cannot-use-custom-model": "এই পাতার বিষয়বস্তুর মডেল পরিবর্তন করা যাবে না।",
        "longpageerror": "'''ত্রুটি:  আপনার জমা দেয়া টেক্সটের পরিমাণ {{PLURAL:$1|এক কিলোবাইট|$1 কিলোবাইট}}, যা সর্বোচ্চ সীমা {{PLURAL:$2|এক কিলোবাইটের|$2 কিলোবাইটের}} চেয়ে বেশি।'''\nএটি সংরক্ষণ করা সম্ভব নয়।",
-       "readonlywarning": "'''সতর্কীকরণ: রক্ষণাবেক্ষণের জন্য ডাটাবেজ অবরুদ্ধ রাখা হয়েছে, তাই এই মুহূর্তে আপনার সম্পাদনা সংরক্ষণ করতে পারবেন না।'''\nআপনি চাইলে লেখাটি কাট এবং পেষ্ট করে ভবিষ্যতের জন্য কোন টেক্সট ফাইলে সংরক্ষণ করতে পারেন।\n\nযে প্রশাসক এই ডাটাবেজটি অবরুদ্ধ করেছেন তিনি যা ব্যাখ্যা দিয়েছেন: $1",
+       "readonlywarning": "<strong>সতর্কীকরণ: রক্ষণাবেক্ষণের জন্য ডাটাবেজ অবরুদ্ধ রাখা হয়েছে, তাই এই মুহূর্তে আপনি আপনার সম্পাদনা সংরক্ষণ করতে পারবেন না।</strong>\nআপনি চাইলে লেখাটি অনুলিপি করে ও কোন টেক্সট ফাইলে প্রতিলেপন করার দ্বারা ভবিষ্যতের জন্য সংরক্ষণ করতে পারেন।\n\nসিস্টেম প্রশাসক যিনি এটি বন্ধ করেছেন তিনি এই ব্যাখ্যা দিয়েছেন: $1",
        "protectedpagewarning": "'''সতর্কীকরণ: এই পাতাটি বন্ধ করা হয়েছে; কেবলমাত্র প্রশাসক মর্যাদার ব্যবহারকারীরাই এটি সম্পাদনা করতে পারবেন।'''\nআপনার সুবিধার্থে পাতাটির সাম্প্রতিক সংরক্ষণ লগের বিবরণ নিচে দেওয়া হলো।",
        "semiprotectedpagewarning": "'''নোট:''' এই পাতাটির ব্যবহার নিয়ন্ত্রণ করা হয়েছে তাই নিবন্ধনকৃত ব্যবহারকারী এটি সম্পাদনা করতে পারবেন।\nআপনার সুবিধার্থে পাতাটির সাম্প্রতিক সংরক্ষণ লগের বিবরণ নিচে দেওয়া হলো।",
        "cascadeprotectedwarning": "<strong>সতর্কীকরণ:</strong> এই পাতাটি সুরক্ষিত, ফলে এটি শুধুমাত্র প্রশাসক অধিকারপ্রাপ্ত ব্যবহারকারীগণ সম্পাদনা করতে পারেন, কারণ এটি নিচের প্রপাতাকার-সুরক্ষিত {{PLURAL:$1|পাতায়|পাতাসমূহে}} অন্তর্ভুক্ত আছে:",
        "prefs-watchlist-days": "যত দিনের নজরতালিকা দেখানো হবে:",
        "prefs-watchlist-days-max": "সর্বোচ্চ $1 {{PLURAL:$1|দিন|দিন}}",
        "prefs-watchlist-edits": "সম্প্রসারিত নজর তালিকায় সর্বোচ্চ সংখ্যার পরিবর্তন দেখানোর জন্য:",
-       "prefs-watchlist-edits-max": "সরà§\8dবà§\8bà¦\9aà§\8dà¦\9a à¦¨à¦¾à¦®à§\8dবার: ১০০০",
+       "prefs-watchlist-edits-max": "সরà§\8dবà§\8bà¦\9aà§\8dà¦\9a à¦¨à¦®à§\8dবর: ১০০০",
        "prefs-watchlist-token": "নজরতালিকা টোকেন:",
        "prefs-misc": "বিবিধ",
        "prefs-resetpass": "পাসওয়ার্ড পরিবর্তন",
        "foreign-structured-upload-form-label-infoform-categories": "বিষয়শ্রেণীসমূহ",
        "foreign-structured-upload-form-label-infoform-date": "তারিখ",
        "foreign-structured-upload-form-label-not-own-work-local-local": "এছাড়াও আপনি [[Special:Upload|ডিফল্ট আপলোডের পাতা]] চেষ্টা করতে পারেন।",
+       "foreign-structured-upload-form-label-not-own-work-local-default": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি এই ফাইলটি তাদের নীতিমালা অধীনে সেখানে আপলোড করা যায়।",
+       "foreign-structured-upload-form-label-own-work-message-shared": "আমি প্রত্যয়ন করছি যে আমি এই ফাইলের স্বত্তাধিকারী, এবং [https://creativecommons.org/licenses/by-sa/4.0/deed.bn ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন-শেয়ার অ্যালাইক ৪.০] লাইসেন্সের অধীনে এই ফাইলটি উইকিমিডিয়া কমন্সে অপরিবর্তনীয় প্রকাশে সম্মত হচ্ছি, এবং আমি [https://wikimediafoundation.org/wiki/Terms_of_Use ব্যবহারের শর্তাবলীর] সাথে সম্মত।",
+       "foreign-structured-upload-form-label-not-own-work-message-shared": "যদি আপনি এই ফাইলের স্বত্তাধিকারী না হন, বা আপনি একটি ভিন্ন লাইসেন্সের আওতায় প্রকাশ করতে ইচ্ছুক থাকেন, তাহলে [https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=bn কমন্স আপলোড উইজার্ড] ব্যবহার করতে বিবেচনা করুন।",
+       "foreign-structured-upload-form-label-not-own-work-local-shared": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি সাইটটি তাদের নীতিমালার অধীনে এই ফাইল আপলোড করার অনুমতি দেয়।",
        "foreign-structured-upload-form-2-label-ccbysa": "[https://creativecommons.org/licenses/by-sa/4.0/deed.bn ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন-শেয়ার অ্যালাইক ৪.০] লাইসেন্সের আওতায় এটি ইন্টারনেটে <strong>চিরতরে প্রকাশ করা ঠিক হবে</strong>",
+       "foreign-structured-upload-form-2-label-termsofuse": "ফাইল আপলোড করার দ্বারা, আপনি প্রত্যয়ন করছেন যে আপনি এই ফাইলের স্বত্তাধিকারী, এবং ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন-শেয়ারআলাইক ৪.০ লাইসেন্সের অধীনে এই ফাইলটি উইকিমিডিয়া কমন্সে অপরিবর্তনীয় প্রকাশে সম্মত হচ্ছেন, এবং আপনি [https://wikimediafoundation.org/wiki/Terms_of_Use ব্যবহারের শর্তাবলীর] সাথে সম্মত।",
+       "foreign-structured-upload-form-3-label-question-website": "আপনি কি একটি ওয়েবসাইট থেকে এই ছবি ডাউনলোড করেছেন, বা একটি চিত্র অনুসন্ধান থেকে এটি পেয়েছেন?",
+       "foreign-structured-upload-form-3-label-question-ownwork": "আপনি কি নিজে এই ছবিটি (তোলা ছবি, অঙ্কন, স্কেচ, ইত্যাদি) তৈরি করেছেন?",
        "foreign-structured-upload-form-3-label-yes": "হ্যাঁ",
        "foreign-structured-upload-form-3-label-no": "না",
        "backend-fail-stream": "\"$1\" ফাইলের স্ট্রিম দেখানো যাচ্ছে না।",
        "querypage-disabled": "কারিগরি কারণে এই বিশেষ পাতাটি আপাতত বন্ধ রয়েছে।",
        "apihelp": "এপিআই সাহায্য",
        "apihelp-no-such-module": "মডিউল \"$1\" পাওয়া যায়নি।",
+       "apisandbox": "এপিআই খেলাঘর",
+       "apisandbox-api-disabled": "এপিআই এই সাইটে নিষ্ক্রিয় করা আছে।",
+       "apisandbox-submit": "অনুরোধ রাখুন",
+       "apisandbox-reset": "পরিস্কার",
+       "apisandbox-retry": "পুনঃচেষ্টা করুন",
+       "apisandbox-examples": "উদাহরণ",
+       "apisandbox-results": "ফলাফল",
+       "apisandbox-request-time": "অনুরোধের সময়: {{PLURAL:$1|$1 মি.সে.}}",
        "booksources": "বইয়ের উৎস",
        "booksources-search-legend": "বইয়ের উৎসের জন্য অনুসন্ধান করা হোক",
        "booksources-isbn": "আইএসবিএন:",
        "block-log-flags-hiddenname": "ব্যবহারকারীনাম লুকায়িত",
        "range_block_disabled": "প্রশাসকের পক্ষে আইপি ঠিকানার শ্রেণী বাধাদানের ক্ষমতা নিষ্ক্রিয় আছে।",
        "ipb_expiry_invalid": "মেয়াদোত্তীর্ণকাল অবৈধ।",
+       "ipb_expiry_old": "মেয়াদোত্তীর্ণের সময় অতীত হয়েছে।",
        "ipb_expiry_temp": "লুকানো ব্যবহারকারীনাম বাধা চিরস্থায়ী হতে হবে।",
        "ipb_hide_invalid": "এই অ্যাকাউন্ট বাধা দেয়া সম্ভব নয়; এটি {{PLURAL:$1|একের অধিক|$1টি}} সম্পাদনা করেছে।",
        "ipb_already_blocked": "\"$1\" ইতিমধ্যে ব্লক",
        "lockedbyandtime": "({{GENDER:$1|$1}} $2 এর $3 সময়ে)",
        "move-page": "$1 স্থানান্তর",
        "move-page-legend": "পাতা স্থানান্তর",
-       "movepagetext": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\nযেসমস্ত পুনর্নির্দেশনা পুরনো শিরোনামটির দিকে নির্দেশ করছিল, সেগুলি স্বয়ংক্রিয়ভাবে হালনাগাদ করতে পারবেন।\nযদি তা না চান, তবে [[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে '''না''', যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে।\nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n'''সতর্কীকরণ!'''\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে; অগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
-       "movepagetext-noredirectfixer": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\n[[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে '''না''', যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে। \nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n'''সতর্কীকরণ!'''\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে;\nঅগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
+       "movepagetext": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\nযেসমস্ত পুনর্নির্দেশনা পুরনো শিরোনামটির দিকে নির্দেশ করছিল, সেগুলি স্বয়ংক্রিয়ভাবে হালনাগাদ করতে পারবেন।\nযদি তা না চান, তবে [[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে।\nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে; অগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
+       "movepagetext-noredirectfixer": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\n[[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে। \nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে;\nঅগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
        "movepagetalktext": "পাতাটির সাথে সাথে সংশ্লিষ্ট আলোচনা পাতাটিও স্বয়ংক্রিয়ভাবে সরানো হবে '''যদি না:'''\n*খালি নয় এমন একটি আলাপ পাতা নতুন শিরোনামটির অধীনে ইতিমধ্যেই বিদ্যমান থাকে, অথবা\n*আপনি নিচের বাক্সটি থেকে টিক সরিয়ে নিতে পারেন।\n\nএসব ক্ষেত্রে আপনি চাইলে নিজের হাতে পাতাটিকে সরাতে বা একত্রীকরণ করতে পারেন।",
        "moveuserpage-warning": "'''সতর্কতা:''' আপনি একটি ব্যবহারকারী পাতা স্থানান্তর করছেন। অনুগ্রহ করে লক্ষ্য করুন যে এর মাধ্যমে কেবলমাত্র পাতাটি স্থানান্তর হবে, কিন্তু পাতার নাম পরিবর্তন হবে ''না''।",
        "movecategorypage-warning": "<strong>সতর্কীকরণ:</strong> আপনি একটি বিষয়শ্রেণীর পাতা স্থানান্তর করতে চলেছেন। দয়া করে মনে রাখবেন যে এতে শুধুমাত্র পাতাটি স্থানান্তরিত হবে এবং পুরাতন বিষয়শ্রেণীতে থাকা কোন পাতা নতুনটিতে পুনঃশ্রেণীকরণ করা হবে <em>না</em>।",
        "movenosubpage": "এই পাতাটির কোনো উপপাতা নেই।",
        "movereason": "কারণ:",
        "revertmove": "পূর্বাবস্থায় ফেরত নেওয়া হোক",
-       "delete_and_move_text": "==মুছে ফেলা আবশ্যক==\n\n\"[[:$1]]\" শিরোনামের গন্তব্য পাতাটি ইতিমধ্যেই বিদ্যমান। আপনি কি স্থানান্তর সফল করার জন্য পাতাটি মুছে দিতে চান?",
+       "delete_and_move_text": "\"[[:$1]]\" শিরোনামের গন্তব্য পাতাটি ইতিমধ্যেই বিদ্যমান। আপনি কি স্থানান্তর সফল করার জন্য পাতাটি মুছে দিতে চান?",
        "delete_and_move_confirm": "হ্যাঁ, পাতাটি মুছে ফেলা হোক",
        "delete_and_move_reason": "\"[[$1]]\" থেকে স্থানান্তরের স্বার্থে মুছে ফেলা হয়েছে",
        "selfmove": "উৎস ও গন্তব্য পাতা একই শিরোনামের; কোন পাতা একই শিরোনামের আরেক পাতায় সরানো যাবে না।",
        "move-leave-redirect": "পুনর্নির্দেশ রেখে দিন",
        "protectedpagemovewarning": "'''সতর্কীকরণ:''' এই পাতাটি বন্ধ করা হয়েছে; কেবলমাত্র প্রশাসক মর্যাদার ব্যবহারকারীরাই এটি স্থানান্তর করতে পারবেন।\nআপনার সুবিধার্থে পাতাটির সাম্প্রতিক সংরক্ষণ লগের বিবরণ নিচে দেওয়া হলো।",
        "semiprotectedpagemovewarning": "'''নোট:''' এই পাতাটির ব্যবহার নিয়ন্ত্রণ করা হয়েছে তাই নিবন্ধনকৃত ব্যবহারকারী এটি স্থানান্তর করতে পারবেন।\nআপনার সুবিধার্থে পাতাটির সাম্প্রতিক সংরক্ষণ লগের বিবরণ নিচে দেওয়া হলো:",
-       "move-over-sharedrepo": "== এই নামের ফাইল রয়েছে ==\n[[:$1]] নামের ফাইলটি শেয়ার্ড রিপোজিটরীতে রয়েছে। একই নামের একটি ফাইল এখানে স্থানান্তর করা হলে পূর্বের ফাইলটি প্রতিস্থাপিত হবে।",
+       "move-over-sharedrepo": "[[:$1]] নামের ফাইলটি শেয়ার্ড সংগ্রহস্থলে রয়েছে। একই নামের একটি ফাইল এখানে স্থানান্তর করা হলে পূর্বের ফাইলটি প্রতিস্থাপিত হবে।",
        "file-exists-sharedrepo": "নির্ধিত নামের ফাইলটি পূর্বেই শেয়ার্ড রিপোজিরটীতে রয়েছে। \nঅনুগ্রহ করে অন্য কোনো নাম নির্বাচন করুন।",
        "export": "পাতা রপ্তানি",
        "exporttext": "আপনি কোন একটি নির্দিষ্ট পাতার বা অনেকগুলি পাতার একটি সেটের বিষয়বস্তু এবং সম্পাদনা ইতিহাস XML-এ আবৃত করে রপ্তানি করতে পারেন। এটি মিডিয়াউইকি সফটওয়্যার ব্যবহারকারী অন্য একটি উইকিতে [[Special:Import|আমদানি পাতার]] মাধ্যমে আমদানি করা সম্ভব।\n\nপাতা রপ্তানি করতে চাইলে নিচের টেক্সট বাক্সে শিরোনামগুলি প্রবেশ করান, প্রতি লাইনে একটি শিরোনাম দিয়ে, এবং নির্বাচন করুন আপনি বর্তমান সংস্করণসহ সবগুলি পুরনো সংস্করণ পাতার ইতিহাসের লাইনসহ রপ্তানি করতে চান, নাকি কেবল সর্বশেষ সম্পাদনাটির তথ্যসহ বর্তমান সংস্করণটি রপ্তানি করতে চান।\n\nদ্বিতীয় ক্ষেত্রটিতে আপনি একটি সংযোগও ব্যবহার করতে পারেন, যেমন \"[[{{MediaWiki:Mainpage}}]]\" পাতাটির জন্য [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]]।",
        "tooltip-t-recentchangeslinked": "এই পাতা থেকে সংযোগ আছে, এমন পাতাগুলিতে সাম্প্রতিক পরিবর্তন",
        "tooltip-feed-rss": "এই পাতার জন্য আরএসএস ফিড",
        "tooltip-feed-atom": "এই পাতার জন্য অ্যাটম ফিড",
-       "tooltip-t-contributions": "{{GENDER:|এই ব্যবহারকারীর}} অবদানগুলির একটি তালিকা",
-       "tooltip-t-emailuser": "{{GENDER:|এই ব্যবহারকারীকে}} একটি ই-মেইল পাঠান",
+       "tooltip-t-contributions": "{{GENDER:$1|এই ব্যবহারকারীর}} অবদানগুলির একটি তালিকা",
+       "tooltip-t-emailuser": "{{GENDER:$1|এই ব্যবহারকারীকে}} একটি ইমেইল পাঠান",
        "tooltip-t-info": "এই পাতা সম্পর্কে আরো তথ্য",
        "tooltip-t-upload": "ফাইল আপলোড করুন",
        "tooltip-t-specialpages": "সব বিশেষ পাতার তালিকা",
        "anonymous": "{{SITENAME}} এর বেনামী {{PLURAL:$1|ব্যবহারকারী|ব্যবহারকারীবৃন্দ}}",
        "siteuser": "{{SITENAME}} ব্যবহারকারী $1",
        "anonuser": "{{SITENAME}} বেনামী ব্যবহারকারী $1",
-       "lastmodifiedatby": "এই পাতাটিতে শেষ পরিবর্তন হয়েছিল $2, $1 by $3।",
+       "lastmodifiedatby": "$3 কর্তৃক $2, $1 তারিখে এই পাতাটিতে শেষ পরিবর্তন করা হয়েছিল।",
        "othercontribs": "$1-এর কাজের উপর ভিত্তি করে।",
        "others": "অন্যান্য",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|ব্যবহারকারী|ব্যবহারকারী}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|ব্যবহারকারী}}|ব্যবহারকারী}} $1",
        "anonusers": "{{SITENAME}} বেনামী {{PLURAL:$2|ব্যবহারকারী|ব্যবহারকারীগণ}} $1",
        "creditspage": "পাতার স্বীকৃতি",
        "nocredits": "এই পাতাটির জন্য কোন কৃতিত্ব-সম্পর্কিত তথ্য নেই।",
        "pageinfo-category-files": "ফাইলের সংখ্যা",
        "markaspatrolleddiff": "পরীক্ষিত হিসেবে চিহ্নিত করুন",
        "markaspatrolledtext": "এই পাতাটি পরীক্ষিত হিসেবে চিহ্নিত করুন",
+       "markaspatrolledtext-file": "এই ফাইলের সংস্করণ পরীক্ষিত হিসেবে চিহ্নিত করুন",
        "markedaspatrolled": "পরীক্ষিত বলে চিহ্নিত করুন",
        "markedaspatrolledtext": "আপনার নির্বাচিত সংস্করণ [[:$1]] পরীক্ষিত বলে চিহ্নিত করা হয়েছে।",
        "rcpatroldisabled": "সাম্প্রতিক পরিবর্তন প্যাট্রোল নিষ্ক্রিয়",
        "newimages-legend": "ছাকনী",
        "newimages-label": "ফাইলের নাম (অথবা এর কোন অংশ):",
        "newimages-showbots": "বটের আপলোড গুলো দেখাও।",
+       "newimages-hidepatrolled": "টহলকৃত আপলোড আড়াল করো",
        "noimages": "দেখার মত কিছু নেই।",
        "ilsubmit": "অনুসন্ধান",
        "bydate": "তারিখ অনুযায়ী",
        "metadata-help": "এই ফাইলে অতিরিক্ত কিছু তথ্য আছে। সম্ভবত যে ডিজিটাল ক্যামেরা বা স্ক্যানারের মাধ্যমে এটি তৈরি বা ডিজিটায়িত করা হয়েছিল, সেটি কর্তৃক তথ্যগুলি যুক্ত হয়েছে। যদি ফাইলটি তার আদি অবস্থা থেকে পরিবর্তিত হয়ে থাকে, কিছু কিছু বিবরণ পরিবর্তিত ফাইলটির জন্য প্রযোজ্য না-ও হতে পারে।",
        "metadata-expand": "সম্প্রসারিত সবিস্তারে দেখাও",
        "metadata-collapse": "সম্প্রসারিত সবিস্তারে দেখিও না",
-       "metadata-fields": "à¦\8fà¦\87 à¦¬à¦¾à¦°à§\8dতায় à¦¤à¦¾à¦²à¦¿à¦\95াভà§\81à¦\95à§\8dত à¦\9aিতà§\8dর à¦®à§\87à¦\9fাডাà¦\9fা à¦\95à§\8dষà§\87তà§\8dরà¦\97à§\81লি à¦\9bবির à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ à¦ªà§\8dরদরà§\8dশন à¦\95রা à¦¹à¦¬à§\87, à¦¯à¦\96ন à¦\85ধি-à¦\89পাতà§\8dত à¦¸à¦¾à¦°à¦£à¦¿à¦\9fি à¦¸à¦\82à¦\95à§\81à¦\9aিত à¦\95রা à¦¹à¦¬à§\87। à¦\85নà§\8dয à¦\95à§\8dষà§\87তà§\8dরà¦\97à§\81লি à¦¸à§\8dবাভাবিà¦\95 à¦\85বসà§\8dথায় à¦²à§\81à¦\95à§\8dà¦\95ায়িত à¦¥à¦¾à¦\95বà§\87।\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-fields": "এই বার্তায় তালিকাভুক্ত চিত্র মেটাডাটা ক্ষেত্রগুলি ছবির পাতায় প্রদর্শন করা হবে, যখন অধি-উপাত্ত সারণিটি সংকুচিত করা হবে। অন্য ক্ষেত্রগুলি স্বাভাবিক অবস্থায় লুকায়িত থাকবে।\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "চওড়া",
        "exif-imagelength": "লম্বা",
        "exif-bitspersample": "উপাদানপ্রতি বিট",
        "exif-originaltransmissionref": "মূল ট্রান্সমিশনকৃত স্থানের কোড",
        "exif-identifier": "আইডেন্টিফায়ার",
        "exif-lens": "ব্যবহৃত লেন্স",
-       "exif-serialnumber": "à¦\95à§\8dযামà§\87রার à¦¸à¦¿à¦°à¦¿à¦¯à¦¼à¦¾à¦² à¦¨à¦¾à¦®à§\8dবার",
+       "exif-serialnumber": "à¦\95à§\8dযামà§\87রার à¦\95à§\8dরমিà¦\95 à¦¨à¦®à§\8dবর",
        "exif-cameraownername": "ক্যামেরার স্বত্ত্বাধিকারী",
        "exif-label": "লেবেল",
        "exif-datetimemetadata": "মেটাডেটার তারিখ সর্বশেষ পরিবর্তিত হয়েছিলো",
        "exif-morepermissionsurl": "অতিরিক্ত লাইসেন্সিং তথ্যাদি",
        "exif-attributionurl": "যখন এই কাজটি পুনরায় ব্যবহার করবেন, অনুগ্রহ করে এই লিংকটি যোগ করুন",
        "exif-preferredattributionname": "যখন এই কাজটি পুনরায় ব্যবহার করবেন, অনুগ্রহ করে প্রণেতাকে ক্রেডিট দিন",
-       "exif-pngfilecomment": "পিএনজি ফাইল কমেন্ট",
+       "exif-pngfilecomment": "পিএনজি ফাইলের মন্তব্য",
        "exif-disclaimer": "দাবিত্যাগ",
        "exif-contentwarning": "বিষয়বস্তু সতর্কবার্তা",
-       "exif-giffilecomment": "জিআইএফ ফাইল কমেন্ট",
+       "exif-giffilecomment": "জিআইএফ ফাইলের মন্তব্য",
        "exif-intellectualgenre": "উপাদানের প্রকার",
        "exif-subjectnewscode": "বিষয় কোড",
        "exif-scenecode": "আইপিটিসি সিন কোড",
        "version-libraries-license": "লাইসেন্স",
        "version-libraries-description": "বিবরণ",
        "version-libraries-authors": "লেখক",
-       "redirect": "পাতা, à¦«à¦¾à¦\87ল, à¦¬à§\8dযবহারà¦\95রà§\80, à¦\85থবা à¦¸à¦\82শà§\8bধন আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে",
+       "redirect": "পাতা, à¦«à¦¾à¦\87ল, à¦¬à§\8dযবহারà¦\95রà§\80, à¦¸à¦\82শà§\8bধন à¦¬à¦¾ à¦²à¦\97 আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে",
        "redirect-legend": "একটি ফাইল অথবা পাতায় পুনঃনির্দেশ করা হয়েছে",
-       "redirect-summary": "à¦\8fà¦\87 à¦¬à¦¿à¦¶à§\87ষ à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\8fà¦\95à¦\9fি à¦«à¦¾à¦\87লà§\87 (ফাà¦\87লà§\87র à¦¨à¦¾à¦®), à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (সà¦\82সà§\8dà¦\95রণ à¦\86à¦\87ডি à¦¬à¦¾ à¦ªà¦¾à¦¤à¦¾ à¦\86à¦\87ডি), à¦\85থবা à¦\8fà¦\95à¦\9fি à¦¬à§\8dযবহারà¦\95রà§\80 à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (সà¦\82à¦\96à§\8dযায় à¦²à§\87à¦\96া à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি) à¦ªà§\81নà¦\83নিরà§\8dদà§\87শিত à¦¹à¦¯à¦¼à§\87à¦\9bà§\87। à¦¬à§\8dযবহার:  [[{{#Special:Redirect}}/file/à¦\89দাহরণ.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], à¦\85থবা [[{{#Special:Redirect}}/user/101]]।",
+       "redirect-summary": "à¦\8fà¦\87 à¦¬à¦¿à¦¶à§\87ষ à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\8fà¦\95à¦\9fি à¦«à¦¾à¦\87লà§\87 (পà§\8dরদতà§\8dত à¦«à¦¾à¦\87লà§\87র à¦¨à¦¾à¦®), à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (পà§\8dরদতà§\8dত à¦¸à¦\82সà§\8dà¦\95রণ à¦\86à¦\87ডি à¦¬à¦¾ à¦ªà¦¾à¦¤à¦¾ à¦\86à¦\87ডি), à¦\8fà¦\95à¦\9fি à¦¬à§\8dযবহারà¦\95রà§\80 à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (পà§\8dরদতà§\8dত à¦¸à¦\82à¦\96à§\8dযায় à¦²à§\87à¦\96া à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি) à¦¬à¦¾ à¦\8fà¦\95à¦\9fি à¦²à¦\97 à¦­à§\81à¦\95à§\8dতিতà§\87 (পà§\8dরদতà§\8dত à¦²à¦\97 à¦­à§\81à¦\95à§\8dতি) à¦ªà§\81নà¦\83নিরà§\8dদà§\87শিত à¦¹à¦¯à¦¼à§\87à¦\9bà§\87। à¦¬à§\8dযবহার:  [[{{#Special:Redirect}}/file/à¦\89দাহরণ.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], à¦¬à¦¾ [[{{#Special:Redirect}}/logid/186]]।",
        "redirect-submit": "যাও",
        "redirect-lookup": "দেখুন:",
        "redirect-value": "মান:",
        "redirect-page": "পাতার আইডি",
        "redirect-revision": "পাতা সংস্করণ",
        "redirect-file": "ফাইলের নাম",
+       "redirect-logid": "লগ আইডি",
        "redirect-not-exists": "মান পাওয়া যায়নি",
        "fileduplicatesearch": "সদৃশ ফাইলের জন্য অনুসন্ধান",
        "fileduplicatesearch-summary": "হ্যাশ ভ্যালুর ওর ভিত্তি করে একই ছবিগুলো খুঁজুন।",
        "htmlform-title-not-exists": "$1-এর অস্তিত্ব নেই।",
        "htmlform-user-not-exists": "<strong>$1</strong>-এর অস্তিত্ব নেই।",
        "htmlform-user-not-valid": "<strong>$1</strong> একটি বৈধ ব্যবহারকারীর নাম নয়।",
-       "sqlite-has-fts": "$1 সহ পূর্ণ টেক্সট সার্চ সমর্থন",
-       "sqlite-no-fts": "$1 বাদে পূর্ণ টেক্সট সার্চ সমর্থন",
+       "sqlite-has-fts": "$1 সহ পূর্ণ-পাঠ্য অনুসন্ধান সমর্থন",
+       "sqlite-no-fts": "$1 বাদে পূর্ণ-পাঠ্য অনুসন্ধান সমর্থন",
        "logentry-delete-delete": "$1 কর্তৃক $3 পাতাটি অপসারিত হয়েছে",
        "logentry-delete-restore": "$1 কর্তৃক $3 পাতাটি {{GENDER:$2|ফিরিয়ে আনা}} হয়েছে",
        "logentry-delete-event": "$1 {{PLURAL:$5|একটি লগ ইভেন্টের|$5 লগ ইভেন্টসমূহের}} দৃশ্যমানতা {{GENDER:$2|পরিবর্তন}} করেছেন $3: $4",
        "action-pagelang": "পাতার ভাষা পরিবর্তন করুন",
        "log-name-pagelang": "ভাষা পরিবর্তন লগ",
        "log-description-pagelang": "এটি পাতার ভাষা পরিবর্তনের লগ।",
-       "logentry-pagelang-pagelang": "$1 পাতার ভাষা $3 এর জন্য $4 থেকে $5 এ {{GENDER:$2|পরিবর্তন}} করেছেন।",
+       "logentry-pagelang-pagelang": "$1 $3-এর ভাষা $4 থেকে $5-এ {{GENDER:$2|পরিবর্তন}} করেছেন",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (সক্রিয় করা)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''নিষ্ক্রিয় করা''')",
        "mediastatistics": "মিডিয়া পরিসংখ্যান",
index d52c605..f688bae 100644 (file)
        "rcshowhidemine": "$1 moje izmjene",
        "rcshowhidemine-show": "Prikaži",
        "rcshowhidemine-hide": "Sakrij",
-       "rcshowhidecategorization": "$1 kategorizaciju stranice",
+       "rcshowhidecategorization": "$1 kategorizaciju stranica",
        "rcshowhidecategorization-show": "Prikaži",
        "rcshowhidecategorization-hide": "Sakrij",
        "rclinks": "Prikaži posljednjih $1 izmjena u posljednjih $2 dana<br />$3",
        "uploaded-script-svg": "Pronađen skriptni element \"$1\" u postavljenoj SVG datoteci.",
        "uploaded-hostile-svg": "Pronađen nesiguran CSS u stilskom elementu postavljene SVG datoteke.",
        "uploaded-event-handler-on-svg": "Nije dozvoljeno postavljanje atributa koji kontroliraju događaje <code>$1=\"$2\"</code> u SVG datotekama.",
-       "uploaded-href-attribute-svg": "href atributi <code>&lt;$1 $2=\"$3\"&gt;</code> sa nelokalnom metom (npr. http://, javascript:, etc) nisu dozvoljeni u SVG datotekama.",
        "uploaded-href-unsafe-target-svg": "Pronađen href sa nesigurnom metom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-animate-svg": "Pronađena \"animate\" oznaka koja možda mijenja href koristeći se \"from\" atributom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-setting-event-handler-svg": "Postavljanje kontrole događaja je blokirano, pronađeno <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "filename-thumb-name": "Izgleda da je naslov u obliku sličice. Nemojte postavljati sličice nazad na istu wiki. Ako je riječ o nečemu drugom, popravite naziv datoteke tako da ima više značenja i da nema prefiks sličice.",
        "filename-bad-prefix": "Naziv datoteke koju postavljate počinje sa '''\"$1\"''', što je naziv koji obično automatski dodjeljuju digitalni fotoaparati i kamere.\nMolimo Vas da odaberete naziv datoteke koji opisuje njen sadržaj.",
        "filename-prefix-blacklist": " #<!-- ostavite ovu liniju onakvom kakva jeste --> <pre>\n# Sintaksa je slijedeća:\n#   * Sve od karaktera \"#\" pa do kraja je komentar\n#   * Svaka neprazna linija je prefiks za tipična imena datoteka koja automatski dodjeljuje digitalna kamera\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # neki mobilni telefoni\nIMG # generic\nJD # Jenoptik\nMGP # Pentax\nPICT # razni\n #</pre> <!-- ostavite ovu liniju onakvom kakva jeste -->",
-       "upload-success-subj": "Uspješno slanje",
-       "upload-success-msg": "Vaša datoteka iz [$2] je uspješno postavljena. Dostupna je ovdje: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Problem pri postavljanju",
-       "upload-failure-msg": "Nastao je problem s Vašim postavljanjem sa [$2]:\n\n$1",
-       "upload-warning-subj": "Upozorenje pri slanju",
-       "upload-warning-msg": "Nastao je problem sa vašim postavljanjem sa [$2]. Morate se vratiti na [[Special:Upload/stash/$1|formu za postavljanje]] kako biste riješili ovaj problem.",
        "upload-proto-error": "Pogrešan protokol",
        "upload-proto-error-text": "Postavljanje sa vanjske lokacije zahtjeva URL-ove koji počinju sa <code>http://</code> ili <code>ftp://</code>.",
        "upload-file-error": "Unutrašnja greška",
        "wlheader-showupdated": "Stranice koje su izmijenjene otkad ste ih posljednji put posjetili prikazane su <strong>podebljanim slovima</strong>.",
        "wlnote": "Ispod {{PLURAL:$1|je najskorija izmjena|su <strong>$1</strong> najskorije izmjene|<strong>$1</strong> najskorijih izmjena}} načinjenih {{PLURAL:$2|posljednjeg sata|u posljednjih <strong>$2</strong> sata|u posljednjih <strong>$2</strong> sati}}, od $3, $4.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
-       "watchlistall2": "sve",
        "watchlist-hide": "Sakrij",
        "watchlist-submit": "Prikaži",
        "wlshowtime": "Prikaži posljednjih:",
index 38e90d3..9862680 100644 (file)
        "laggedslavemode": "Avís: La pàgina podria mancar de modificacions recents.",
        "readonly": "La base de dades està bloquejada",
        "enterlockreason": "Escriviu una raó pel bloqueig, així com una estimació de quan tindrà lloc el desbloqueig",
-       "readonlytext": "La base de dades està temporalment bloquejada segurament per tasques de manteniment, després de les quals es tornarà a la normalitat.\n\nL'administrador que l'ha bloquejada ha donat aquesta explicació: $1",
+       "readonlytext": "La base de dades està temporalment bloquejada a noves entrades i altres tasques de manteniment, segurament per tasques rutinàries de manteniment, després de les quals es tornarà a la normalitat.\n\nL'administrador que l'ha bloquejada ha donat aquesta explicació: $1",
        "missing-article": "La base de dades no ha trobat el text d'una pàgina que hauria d'haver trobat, anomenada «$1» $2.\n\nNormalment això passa perquè s'ha seguit una diferència desactualitzada o un enllaç d'historial a una pàgina que s'ha suprimit.\n\nSi no fos el cas, podríeu haver trobat un error en el programari.\nAviseu-ho llavors a un [[Special:ListUsers/sysop|administrador]], deixant-li clar l'adreça URL causant del problema.",
        "missingarticle-rev": "(revisió#: $1)",
        "missingarticle-diff": "(dif: $1, $2)",
        "virus-scanfailed": "escaneig fallit (codi $1)",
        "virus-unknownscanner": "antivirus desconegut:",
        "logouttext": "'''Heu finalitzat la sessió.'''\n\nTingueu en compte que, fins que buideu la memòria cau del navegador, algunes pàgines poden continuar mostrant-se com si encara estiguéssiu en una sessió.",
+       "cannotlogoutnow-title": "Ara no es pot finalitzar la sessió",
+       "cannotlogoutnow-text": "No es pot finalitzar la sessió quan s'utilitza $1.",
        "welcomeuser": "Benvingut, $1!",
        "welcomecreation-msg": "El vostre compte ha estat creat.\nNo oblideu de canviar les vostres [[Special:Preferences|preferències de {{SITENAME}}]].",
        "yourname": "Nom d'usuari",
        "remembermypassword": "Recorda la contrasenya entre sessions (per un màxim de $1 {{PLURAL:$1|dia|dies}})",
        "userlogin-remembermypassword": "Mantén-me connectat",
        "userlogin-signwithsecure": "Connexió segura",
+       "cannotloginnow-title": "Ara no es pot iniciar la sessió",
+       "cannotloginnow-text": "No es pot iniciar la sessió quan s'utilitza $1.",
        "yourdomainname": "El vostre domini",
        "password-change-forbidden": "No podeu canviar les contrasenyes en aquest wiki.",
        "externaldberror": "Hi ha hagut un error en la base de dades d'autenticació o bé no teniu permís per a actualitzar el vostre compte extern.",
        "grant-group-file-interaction": "Interacció amb fitxes multimèdia",
        "grant-group-watchlist-interaction": "Interacció amb la vostra llista de seguiment",
        "grant-group-email": "Enviament de correu",
+       "grant-createaccount": "Crea comptes",
+       "grant-createeditmovepage": "Crea, modifica i reanomena pàgines",
+       "grant-delete": "Suprimeix pàgines, revisions i entrades de registre",
        "newuserlogpage": "Registre de creació d'usuaris",
        "newuserlogpagetext": "Aquest és un registre de creació de nous usuaris.",
        "rightslog": "Registre dels permisos d'usuari",
        "uploaded-script-svg": "S’ha trobat l’element programable «$1» al fitxer SVG carregat.",
        "uploaded-hostile-svg": "S’ha trobat codi CSS no segur a l’element d’estil del fitxer SVG carregat.",
        "uploaded-event-handler-on-svg": "No es permet establir els atributs de gestió d’esdeveniments <code>$1=\"$2\"</code> en fitxers SVG.",
-       "uploaded-href-attribute-svg": "No es permeten els atributs d’«href» <code>&lt;$1 $2=\"$3\"&gt;</code> amb objectius no locals (p. ex., http:// i javascript:) als fitxers SVG.",
        "uploaded-href-unsafe-target-svg": "S’ha trobat un element «href» amb un objectiu no segur <code>&lt;$1 $2=\"$3\"&gt;</code> al fitxer SVG carregat.",
        "uploaded-animate-svg": "S'ha trobat l'etiqueta «animate» que pot estar canviant l'href mitjançant l'atribut <code>&lt;$1 $2=\"$3\"&gt;</code> en el fitxer SVG carregat.",
        "uploadscriptednamespace": "Aquest fitxer SVG conté un espai de noms \"$1\" no autoritzat",
        "querypage-disabled": "Aquesta pàgina especial està desactivada per a no perjudicar el rendiment.",
        "apihelp": "Ajuda de l'API",
        "apihelp-no-such-module": "No s'ha trobat el mòdul \"$1\".",
+       "apisandbox": "Pàgina de proves de l'API",
+       "apisandbox-api-disabled": "L'API està desactivada en aquest lloc.",
+       "apisandbox-intro": "Utilitzeu aquesta pàgina per experimentar amb l'<nowiki />'''API de web service de MediaWiki'''.\nVisiteu [//www.mediawiki.org/wiki/API:Main_page la documentació de l'API] per a més informació sobre l'ús de l'API. Exemple: [//www.mediawiki.org/wiki/API#A_simple_example recuperar el contingut d'una Pàgina Principal]. Seleccioneu una acció per veure més exemples.\n\nTingueu en compte que, encara que això és una pàgina de proves, les accions que feu en aquesta pàgina poden modificar la wiki.",
+       "apisandbox-submit": "Fes sol·licitud",
+       "apisandbox-reset": "Neteja",
+       "apisandbox-examples": "Exemple",
+       "apisandbox-results": "Resultat",
+       "apisandbox-request-url-label": "Sol·licita URL:",
+       "apisandbox-request-time": "Temps de sol·licitud: $1",
        "booksources": "Obres de referència",
        "booksources-search-legend": "Cerca fonts de llibres",
        "booksources-isbn": "ISBN:",
        "javascripttest-pagetext-frameworks": "Trieu un dels següents entorns de prova: $1",
        "javascripttest-pagetext-skins": "Trieu un tema per a executar-hi els tests:",
        "javascripttest-qunit-intro": "Consulteu la [documentació de tests de $1] a mediawiki.org.",
-       "tooltip-pt-userpage": "La vostra pàgina d'usuari",
+       "tooltip-pt-userpage": "{{GENDER:|La vostra}} pàgina d'usuari",
        "tooltip-pt-anonuserpage": "La pàgina d'usuari per la ip que utilitzeu",
-       "tooltip-pt-mytalk": "La vostra pàgina de discussió.",
+       "tooltip-pt-mytalk": "{{GENDER:|La vostra}} pàgina de discussió",
        "tooltip-pt-anontalk": "Discussió sobre les edicions per aquesta adreça ip.",
-       "tooltip-pt-preferences": "Les vostres preferències.",
+       "tooltip-pt-preferences": "{{GENDER:|Les vostres}} preferències",
        "tooltip-pt-watchlist": "La llista de pàgines de les quals vigileu els canvis.",
-       "tooltip-pt-mycontris": "Llista de les vostres contribucions.",
+       "tooltip-pt-mycontris": "Llista de {{GENDER:|les vostres}} contribucions",
        "tooltip-pt-login": "Us animem a registrar-vos, però no és obligatori",
        "tooltip-pt-logout": "Finalitza la sessió d'usuari",
        "tooltip-pt-createaccount": "Us animem a què creeu un compte i inicieu sessió, encara que no és obligatori",
        "tooltip-t-recentchangeslinked": "Canvis recents a pàgines enllaçades des d'aquesta pàgina",
        "tooltip-feed-rss": "Canal RSS d'aquesta pàgina",
        "tooltip-feed-atom": "Canal Atom d'aquesta pàgina",
-       "tooltip-t-contributions": "Llista de contribucions d'aquest usuari",
+       "tooltip-t-contributions": "Llista de les contribucions d'{{GENDER:$1|aquest usuari|aquesta usuària}}",
        "tooltip-t-emailuser": "Envia un correu en aquest usuari.",
        "tooltip-t-info": "Més informació sobre aquesta pàgina",
        "tooltip-t-upload": "Carregueu fitxers",
index e35509e..2601677 100644 (file)
@@ -9,7 +9,8 @@
                        "Mywood",
                        "Impersonator 1",
                        "LNDDYL",
-                       "唐吉訶德的侍從"
+                       "唐吉訶德的侍從",
+                       "Ztl8702"
                ]
        },
        "tog-underline": "下劃綫鏈接",
        "qbpageoptions": "茲蜀頁",
        "qbmyoptions": "我其頁面",
        "faq": "經稠碰著其問題",
-       "faqpage": "Project:ç\93稠碰è\91\97其問題",
+       "faqpage": "Project:稠å\95\8f其問題",
        "actions": "動作",
        "namespaces": "命名空間",
        "variants": "變體",
        "createaccountreason": "原因:",
        "createacct-reason": "原因",
        "createacct-reason-ph": "汝奚勢復想開另外蜀隻賬戶?",
-       "createacct-captcha": "安全檢查",
-       "createacct-imgcaptcha-ph": "將汝敆懸頂看見其文字拍出來",
        "createacct-submit": "開賬戶",
        "createacct-another-submit": "新建另外蜀萆賬號",
        "createacct-benefit-heading": "{{SITENAME}}是共汝蜀様其儂做其。",
        "passwordreset-username": "用戶名:",
        "passwordreset-domain": "域名:",
        "passwordreset-email": "電批地址:",
-       "passwordreset-emailsent": "蜀萆密碼重新設置其電批已經寄出去了。",
+       "passwordreset-emailsentemail": "蜀萆密碼重新設置其電批已經寄出去了。",
        "passwordreset-emailsent-capture": "蜀萆密碼重新設置其電批已經寄出去了,內容就是生下底總款。",
        "changeemail": "修改電批其地址",
+       "changeemail-header": "修改賬戶電子郵件地址",
        "changeemail-oldemail": "現刻時其電批地址:",
        "changeemail-newemail": "新其電批地址:",
        "changeemail-none": "(無)",
        "sourcefilename": "源文件名:",
        "destfilename": "目標文件名:",
        "watchthisupload": "監視茲文件",
-       "upload-success-subj": "成功上傳",
        "license": "版權聲明:",
        "license-header": "版權說明",
        "imgfile": "文件",
        "linksearch-ok": "尋討",
        "linksearch-line": "$1是趁$2𡅏鏈接過其",
        "emailuser": "寄電批乞茲隻用戶",
-       "emailpage": "寄電子郵件乞用戶",
        "defemailsubject": "{{SITENAME}}其用戶「$1」寄來其批",
        "noemailtitle": "無電批地址",
        "emailfrom": "趁:",
        "move-page-legend": "移動頁面",
        "movepagetext": "使下底其表單重新乞茲蜀頁起蜀萆名字,移動伊共伊所有其歷史遘伊其新名字。\n舊其標題會變成新其標題其重定向頁。\n汝會使自動更新重定向許蜀點遘原底其標題。\n如果伊結果伓是總款其話,汝著檢查蜀下[[Special:DoubleRedirects|雙重重定向]]或者[[Special:BrokenRedirects|獃其重定向]]。\n汝有責任讓頁面鏈接遘正確其地方。\n\n注意儷是許塊已經有蜀隻頁面,噲就'''無能耐'''移動過了,除開噲儷是蜀萆重定向並且無舊底其修改歷史。\n嚽其意思就是講儷是汝名字起綻了,汝會使將茲蜀萆頁面重新起伊原底其名字,但是𣍐使覆蓋已經有其頁面。\n\n'''警告!'''\n嚽可能會對一般頁面造成盡大其並且無能耐想遘其改變;\n起動汝著敆做之前會意總款做其後果。",
        "movepagetalktext": "相關其討論頁會自動共伊移遘'''無挃''':\n* 汝其新其用戶名已經有蜀頁有內容其討論頁,或者\n* 汝取消下底其框框。\n\n若總款,汝會使自家移動或者是合併頁面。",
-       "movearticle": "移動頁面",
        "movenologintext": "著[[Special:UserLogin|躒入]]才有能耐移動頁面。",
        "newtitle": "遘新題目:",
        "move-watch": "監視茲頁",
        "movelogpage": "移動日誌",
        "movelogpagetext": "下底是乞移動過其頁其單單。",
        "movereason": "原因:",
-       "delete_and_move": "刪掉並且移動",
        "delete_and_move_confirm": "正式,刪掉茲蜀頁",
        "allmessages": "系統消息",
        "allmessagesname": "名",
index ed2dd59..44f55bc 100644 (file)
        "emailconfirmlink": "Бакъде хьай электронан поштан адрес",
        "invalidemailaddress": "Электронан поштан адрес тӀелаца йиш яц, цуна формат нийса цахилар бахьнехь.\nДехар до, язъе нийса электронан адрес я и меттиг есса йита.",
        "cannotchangeemail": "ХӀокху декъашхочун дӀаяздарца долу электронан поштан адресаш хуьйцийла дац хӀокху вики чохь",
-       "emaildisabled": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\81айÑ\82ан Ñ\82аÑ\80о Ñ\8fÑ\86 Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\87те хаамаш бахьийта.",
+       "emaildisabled": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\81айÑ\82ан Ñ\82аÑ\80о Ñ\8fÑ\86 Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\88те хаамаш бахьийта.",
        "accountcreated": "Декъашхочун дӀаяздар кхоьллина",
        "accountcreatedtext": "Кхоьллина декъашхочун [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|дийцаре.]]) дӀаяздар.",
        "createaccount-title": "{{SITENAME}}: декъашхочун дӀаяздар кхоллар",
        "resetpass-submit-cancel": "Цаоьшу",
        "resetpass-wrong-oldpass": "Нийса йоцу я хана йолу карара пароль. Ахьа кхиамца пароль хийцина я керла хана йолу пароль ехна хила там бу.",
        "resetpass-recycled": "Дехар до, хӀинца йолччул башха пароль хӀотта йе.",
-       "resetpass-temp-emailed": "Ð\90Ñ\85Ñ\8cа Ñ\87Ñ\83гÓ\80оÑ\88 Ñ\8fзйина Ñ\86кÑ\8aаÑ\87Ñ\83нна Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\87те яийтина пароль. Чудахар чекхдалийта язъян еза керла пароль.",
+       "resetpass-temp-emailed": "Ð\90Ñ\85Ñ\8cа Ñ\87Ñ\83гÓ\80оÑ\88 Ñ\8fзйина Ñ\86кÑ\8aаÑ\87Ñ\83нна Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\88те яийтина пароль. Чудахар чекхдалийта язъян еза керла пароль.",
        "resetpass-temp-password": "Цхьан хана пароль:",
        "resetpass-abort-generic": "Пароль хийцар дӀахедар",
        "resetpass-expired": "Хьан паролан хан чекхелла. Дехар до керла пароль хӀоттаяр.",
        "recentchangeslinked-page": "АгӀон цӀе:",
        "recentchangeslinked-to": "Кхечу агӀор, гайта хийцамаш агӀонашца, хӀоттийначу агӀонтӀе хьажорг йолуш",
        "recentchanges-page-added-to-category": "[[:$1]] категори чу тоьхна",
+       "recentchanges-page-removed-from-category": "[[:$1]] дӀаяьккхина категори чура",
        "upload": "Файл чуяккхар",
        "uploadbtn": "Файл чуяккхар",
        "reuploaddesc": "Юху гӀо файл чуйоккху агӀоне",
        "suppress": "Хьулдар",
        "apihelp": "API гӀо",
        "apihelp-no-such-module": "Модуль «$1» цакарий.",
+       "apisandbox": "Ловзаран майда API",
+       "apisandbox-intro": "Лела йе хӀара агӀо '''MediaWiki API''' зуьйш.\nAPI кхин муха лела йо хьажа [//www.mediawiki.org/wiki/API:Main_page кхузахь]. Масала, [//www.mediawiki.org/wiki/API#A_simple_example Коьрта агӀона чулацам схьаэца]. Кхин масалаш ган харжа дийриг.",
+       "apisandbox-submit": "Дехар далар",
+       "apisandbox-reset": "ЦӀанъян",
+       "apisandbox-examples": "Масала",
+       "apisandbox-results": "Хилам",
+       "apisandbox-request-url-label": "Дехаран URL-адрес:",
+       "apisandbox-request-time": "Дехар дина хан: $1",
        "booksources": "Жайнан хьосташ",
        "booksources-search-legend": "Жайнех лаьцна хаам лахар",
        "booksources-search": "Лахар",
        "emailuser": "Декъашхочун хааман кехат",
        "emailuser-title-target": "{{GENDER:$1|декъашхочунга}} электронан хаам базбар",
        "emailuser-title-notarget": "Декъашхочунга кехат яздар",
-       "emailpagetext": "Ð¥Ó\80окÑ\85Ñ\83 Ð°Ð³Ó\80она Ð³Ó\80оÑ\8cнÑ\86а Ð¹Ð¸Ñ\88 Ñ\8e {{GENDER:$1|декÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н}} Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\87те хаам бахьийта.\nХьоьга жоп лур ду ахьа [[Special:Preferences|хьайн гӀирса чу]] дӀаяздина долу адрес тӀе.",
+       "emailpagetext": "Ð¥Ó\80окÑ\85Ñ\83 Ð°Ð³Ó\80она Ð³Ó\80оÑ\8cнÑ\86а Ð¹Ð¸Ñ\88 Ñ\8e {{GENDER:$1|декÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н}} Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\88те хаам бахьийта.\nХьоьга жоп лур ду ахьа [[Special:Preferences|хьайн гӀирса чу]] дӀаяздина долу адрес тӀе.",
        "defemailsubject": "Хаам {{grammar:genitive|{{SITENAME}}}} чура бу",
        "usermaildisabled": "Декъашхочун электронан пошт дӀаяйина ю",
        "noemailtitle": "Электронан поштан адрес дац",
        "notanarticle": "Яззам бац",
        "notvisiblerev": "Верси дӀаяьккхина хила",
        "watchlist-details": "Хьан тергаме могӀанца $1 {{PLURAL:$1|агӀо}} ю, дийцаре агӀонаш йоцуш.",
-       "wlheader-enotif": "ЭлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\87те хаамаш байтар латина ду.",
+       "wlheader-enotif": "ЭлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\88те хаамаш байтар латина ду.",
        "wlheader-showupdated": "Хийцам бина агӀонаш '''Ӏаьржа''' шрифтцан билгальяха ю.",
        "wlnote": "Гойту <strong>$2</strong> {{plural:$2|сахьтчохь}} бина {{PLURAL:$1|тӀеххьара '''$1''' хийцам}}, хан $3 $4",
        "wlshowlast": "Гайта тӀаьххьара $1 сахьт $2 де",
        "years": "{{PLURAL:$1|$1 шо|$1 шо}}",
        "ago": "$1 хьалха",
        "just-now": "хӀинца",
-       "hours-ago": "$1 {{PLURAL:$1|сахьт}}",
+       "hours-ago": "$1 {{PLURAL:$1|сахьт}} хьалха",
        "minutes-ago": "$1 {{PLURAL:$1|минот}} хьалха",
        "seconds-ago": "$1 {{PLURAL:$1|секунд}} хьалха",
        "monday-at": "оршотан дийнахь $1",
        "logentry-newusers-newusers": "{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1",
        "logentry-newusers-create": "{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1",
        "logentry-newusers-create2": "$1 {{GENDER:$2|кхоьллина}} декъашхочун дӀаяздапр $3",
-       "logentry-newusers-byemail": "$1 {{GENDER:$2|кÑ\85оÑ\8cллина}} Ð´ÐµÐºÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ð´Ó\80аÑ\8fздаÑ\80 $3 Ð¿Ð°Ñ\80олÑ\8c Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\87те яхьийтина",
+       "logentry-newusers-byemail": "$1 {{GENDER:$2|кÑ\85оÑ\8cллина}} Ð´ÐµÐºÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ð´Ó\80аÑ\8fздаÑ\80 $3 Ð¿Ð°Ñ\80олÑ\8c Ñ\8dлекÑ\82Ñ\80онан Ð¿Ð¾Ñ\88те яхьийтина",
        "logentry-newusers-autocreate": "Автоматически кхоьллина {{GENDER:$2|декъашхочун}} $1 дӀаяздар",
        "logentry-rights-rights": "$1 {{GENDER:$2|хийцина}} $3 бакъо $4 → $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|хийцина}} хӏокхуна $3 бакъо",
index 3ee81bd..590bcfa 100644 (file)
        "cancel": "ھەڵیوەشێنەوە",
        "moredotdotdot": "زیاتر",
        "morenotlisted": "ئەم لیستەیە تەواو نییە",
-       "mypage": "پەڕه‌",
+       "mypage": "پەڕە",
        "mytalk": "لێدوان",
        "anontalk": "لێدوان بۆ ئەم ئایپییە",
        "navigation": "ڕێدۆزی",
        "and": "&#32;و",
        "qbfind": "بدۆزەرەوە",
-       "qbbrowse": "بگه‌ڕێ",
+       "qbbrowse": "بگەڕێ",
        "qbedit": "دەستکاری",
        "qbpageoptions": "ئەم پەڕەیە",
        "qbmyoptions": "پەڕەکانم",
        "create": "دروستکردن",
        "create-local": "وەسفی ناوچەیی زۆر بکە",
        "editthispage": "دەستکاری ئەم پەڕەیە بکە‌",
-       "create-this-page": "ئەم پەڕە دروست بکە",
+       "create-this-page": "ئەم پەڕەیە دروست بکە",
        "delete": "سڕینەوە",
-       "deletethispage": "سڕینه‌وه‌ی ئه‌م په‌ڕه‌یه‌",
+       "deletethispage": "سڕینەوه‌ی ئەم پەڕەیە",
        "undeletethispage": "ئەم پەڕەیە بھێنەوە",
        "undelete_short": "{{PLURAL:$1|یەک گۆڕانکاریی|$1 گۆڕانکاریی}} سڕاوە بەجێبھێنەرەوە",
        "viewdeleted_short": "{{PLURAL:$1|یەک گۆڕانکاریی سڕاو|$1 گۆڕانکاریی سڕاو}} ببینە",
        "protect": "پاراستن",
        "protect_change": "گۆڕین",
-       "protectthispage": "ئه‌م په‌ڕه‌یه‌ بپارێزه‌",
+       "protectthispage": "ئەم پەڕەیە بپارێزە",
        "unprotect": "پاراستنی بگۆڕە",
        "unprotectthispage": "پاراستنی ئەم پەڕەیە بگۆڕە",
        "newpage": "پەڕەی نوێ",
        "talkpage": "باس لەسەر ئەم پەڕە بکە‌",
        "talkpagelinktext": "لێدوان",
-       "specialpage": "په‌ڕه‌ی تایبه‌ت",
+       "specialpage": "پەڕەی تایبەت",
        "personaltools": "ئامڕازە تاکەکەسییەکان",
        "articlepage": "پەڕەی ناوەرۆک ببینە",
        "talk": "وتووێژ",
        "projectpage": "پەڕەی پرۆژە نیشان بدە",
        "imagepage": "پەڕەی پەڕگە نیشان بدە",
        "mediawikipage": "پەڕەی پەیام نیشان بدە",
-       "templatepage": "په‌ڕه‌ی داڕێژە ببینە‌",
-       "viewhelppage": "په‌ڕه‌ی یارمه‌تی نیشانبده‌",
-       "categorypage": "په‌ڕه‌ی هاوپۆل نیشانبده‌",
+       "templatepage": "پەڕەی داڕێژە ببینە",
+       "viewhelppage": "پەڕەی یارمەتی ببینە",
+       "categorypage": "پەڕەی پۆل ببینە",
        "viewtalkpage": "بینینی لێدوان",
        "otherlanguages": "بە زمانەکانی تر",
        "redirectedfrom": "(ڕەوانەکراوە لە $1ەوە)",
        "confirmable-yes": "بەڵێ",
        "confirmable-no": "نا",
        "thisisdeleted": "$1 نیشان بدە یا بھێنەوە؟",
-       "viewdeleted": "$1 نیشان بده‌؟",
+       "viewdeleted": "بینینی $1؟",
        "restorelink": "{{PLURAL:$1|یەک گۆڕانکاریی سڕاو|$1 گۆڕانکاریی سڕاو}}",
        "feedlinks": "خۆراک:",
        "feed-invalid": "ئەندام بوونی ئەو جۆرە خۆراکە نەناسراوە.",
        "nosuchactiontext": "ئەو چالاکییەی لە لایەن بەستەرەوە دیاریکراوە ناتەواوە.\nلەوانەیە بە هەڵە بەستەرەکەت نووسیبێت، یان بەستەرێکی هەڵەی بە دواوە بێت.\nلەوانەیە ئەمە نیشانەی هەڵەیەک بێت لەو نەرمەکاڵایەی کە بەکاردێت لە لایەن {{SITENAME}}.",
        "nosuchspecialpage": "پەڕەی تایبەتی ئاوا بوونی نییە",
        "nospecialpagetext": "<strong>پەڕەیەکی تایبەت دەخوازیت کە بوونی نیە.</strong>\n\nلیستێکی پەڕە تایبەتە دروستەکان لە [[Special:SpecialPages|{{int:specialpages}}]] لە بەردەست‌دایە.",
-       "error": "هه‌ڵه‌",
+       "error": "ھەڵە",
        "databaseerror": "ھەڵەی بنکەدراوه",
        "databaseerror-function": "کردە: $1",
        "databaseerror-error": "هەڵە: $1",
        "laggedslavemode": "ئاگاداری: لەوانەیە لاپەڕەکە نوێکردنەکان لە بەر نەگرێت.",
        "readonly": "بنکەدراوە داخراوە",
        "enterlockreason": "هۆیەک بۆ قوفڵ‌کردنەکە بنووسە کە  تێیدا کاتی کردنەوەی قۆفڵەکە باس کرابێت",
-       "readonlytext": "بÙ\86Ú©Û\95دراÙ\88Û\95Ú©Û\95 Ù\84Û\95Ù\85 Ú©Ø§ØªÛ\95دا  Ù\84Û\95بÛ\95ر Ú\86اکسازÛ\8c Ø¦Ø§Ø³Ø§Û\8cÛ\8c Ø¨Û\86 Ù\86Ù\88سÛ\8cÙ\86Û\8c Ù\86Ù\88Û\8e Ù\88 Ø¯Û\95ستکارÛ\8c Ù\82Ù\88Ù\81Úµ Ú©Ø±Ø§Ù\88Ù\87. Ø¯Ù\88اÛ\8c Ø¦Û\95Ù\88Û\95 Ø¦Û\95گرÛ\8eتÛ\95Ù\88Û\95 Ø¨Û\86 Ø¦Ø§Ø³ØªÛ\8c Ø®Û\86Û\8c.\n\nئÛ\95Ù\88 Ø¨Û\95Ú\95Û\8eÙ\88بÛ\95رÛ\95Û\8c Ú©Û\95 Ù\82Ù\88Ù\81ÚµÛ\8c Ú©Ø±Ø¯Ù\88Ù\88Ù\87 Ø¦Û\95Ù\85 Ú\95Ù\88Ù\88Ù\86â\80\8cکردÙ\86Û\95Ù\88Û\95Û\8c Ù\86Ù\88Ù\88سÛ\8cÙ\88Û\95 : $1",
+       "readonlytext": "داتابÛ\8eس Ø¦Û\8eستا Ø¨Û\95 Ú¾Û\86Û\8c Ø¯Ø§Ù\86اÙ\86Û\8c Ø¨Ø§Ø¨Û\95تÛ\8c Ù\86Ù\88Û\8e Ù\88 Ú¯Û\86Ú\95اÙ\86کارÛ\8cÛ\8c Ø¯Û\8cÚ©Û\95 Ø¯Ø§Ø®Ø±Ø§Ù\88Û\95Ø\8c Ù\84Û\95Ù\88اÙ\86Û\95Û\8cÛ\95 Ø¨Û\95 Ù\85Û\95بÛ\95ستÛ\8c Ú\86اکسازÛ\8cÛ\8c Ú\95Û\86تÛ\8cÙ\86 Ø¨Û\8eت Ù\88 Ø¯Û\95Ú¯Ú\95Û\8eتÛ\95Ù\88Û\95 Ø¨Û\86 Ø¯Û\86Ø®Û\8c Ø¦Ø§Ø³Ø§Û\8cÛ\8c.\n\nئÛ\95Ù\88 Ø¨Û\95Ú\95Û\8eÙ\88Û\95بÛ\95رÛ\8c Ø³Û\8cستÛ\95Ù\85Û\95 Ú©Û\95 Ø¯Ø§Û\8cخستÙ\88Ù\88Û\95 Ø¦Û\95Ù\85 Ú\95Ù\88Ù\88Ù\86کردÙ\86Û\95Ù\88Û\95Û\8cÛ\95Û\8c Ù¾Û\8eØ´Ú©Û\95Ø´ Ú©Ø±Ø¯Ù\88Ù\88Û\95: $1",
        "missing-article": "داتابەیسەکە نەیتوانی دەقی پەڕەیەک بەناوی «$1» $2  بدۆزێتەوە کە دەبوا بیدۆزیبایەتەوە.\n\nئەمە زیاتر لە بەدواچوونی بەستەری جیاوازی یان مێژووی کۆنی پەڕەیەکی سڕدراو ڕوودەدات.\n\nئەگەر وا نەبێت، ئەوا ڕەنگە گرفتێکت لەم نەرمامێرەدا دۆزیبێتەوە.\nتکایە ئەمە بە ئاماژەدان بە ناونیشانی URLـەکەیەوە بە [[Special:ListUsers/sysop|بەڕێوبەرێک]] ڕاپۆرت بدە.",
        "missingarticle-rev": "(پێداچوونەوە#: $1)",
        "missingarticle-diff": "(جیاوازی: $1، $2)",
        "readonly_lag": "بنكه‌دراوه‌كه‌ به‌شێوه‌ی خۆكار به‌ندكراوه‌، له‌كاتێكدا بنكه‌دراوه‌ی ڕاژه‌كاره‌كه‌ ڕۆڵی له‌خۆگرتن ده‌گێڕێت",
        "internalerror": "ھەڵەی ناوخۆیی",
-       "internalerror_info": "هه‌ڵه‌ی ناوخۆیی: $1",
+       "internalerror_info": "ھەڵەی ناوخۆیی: $1",
        "filecopyerror": "نەکرا پەڕگەی «$1» کۆپی بکرێت بۆ «$2».",
-       "filerenameerror": "ناوی په‌ڕگه‌ی \"$1\" نه‌گۆڕدرا بۆ \"$2\".",
+       "filerenameerror": "ناکرێت ناوی پەڕگەی «$1» بگۆڕرێت بۆ «$2».",
        "filedeleteerror": "نەکرا پەڕگەی «$1» بسڕدرێتەوە.",
        "directorycreateerror": "نەتوانرا بوخچەی \"$1\"دروست بکرێت.",
-       "filenotfound": "په‌ڕگه‌ی \"$1\" نه‌دۆزرایه‌وه‌",
+       "filenotfound": "پەڕگەی «$1» نەدۆزرایەوە",
        "unexpected": "نرخی چاوەڕوان نەکراو: \"$1\"=\"$2\" .",
        "formerror": "هەڵە: فورمەکە نانێردرێت.",
        "badarticleerror": "ئەو ئاماژە لەم لاپەڕەدا پێک‌نایە.",
        "viewsourcetext": "دەتوانی سەرچاوەی ئەم پەڕە ببینی و کۆپیی بکەی:",
        "viewyourtext": "دەتوانی ژێدەری '''دەستکارییەکەت''' لەم پەڕەیەدا ببینی و کۆپی بکەی:",
        "protectedinterface": "ئەم پەڕەیە دەقی ڕواڵەتی نەرمامێری ئەم ویکییە نیشان دەدات و بۆ بەرگری لە خراپکاری پارێزراوە.\nبۆ زیادکردن یان گۆڕینی وەرگێڕانەکان بۆ ھەموو ویکییەکان، تکایە لە [//translatewiki.net/ translatewiki.net]، پرۆژەی ناوچەیی کردنی میدیاویکی کەڵک وەربگرە.",
-       "editinginterface": "<strong>ھۆشیار بە:</strong> خەریکی دەستکاریی پەڕەیەک دەکەیت کە بۆ دابینکردنی دەقی ڕووکاری نەرمامێر بەکاردێت.\nگۆڕانکارییەکانی لەم پەڕەیەدا کاریگەر دەبێت لە سەر ڕواڵەتی پەڕەکانی بەکارھێنەرانی تر لەم ویکییەدا.",
+       "editinginterface": "<strong>ھۆشیار بە:</strong> خەریکی دەستکاریی پەڕەیەک دەکەیت کە بۆ دابین کردنی دەقی ڕووکاری نەرمامێر بەکاردێت.\nگۆڕانکارییەکان لەم پەڕەیەدا لە سەر ڕواڵەتی پەڕەکان بۆ بەکارھێنەرانی تر لەم ویکییەدا کاریگەر دەبێت.",
        "cascadeprotected": "ئەم لاپەڕە پارێزراوە لە دەستکاریی، چونکا خراوەتە سەر ڕیزی ئەم {{PLURAL:$1|لاپەڕانه‌، کە}} که‌ به‌ هه‌ڵکردنی بژارده‌ی داڕژان هه‌ڵکراوه‌:\n$2",
        "namespaceprotected": "تۆ ناتوانی لاپەڕەکانی ناو نەیمسپەیسی '''$1''' بگۆڕی.",
        "customcssprotected": "دەسەڵاتی دەستکارییکردنی ئەم پەڕەی CSS ـەت نییە چوونکە ڕێکخستنەکانی کەسێکی تر لەخۆ دەگرێت.",
        "emaildisabled": "ئەم ماڵپەڕە ناتوانێ ئیمەیل بنێرێ.",
        "accountcreated": "ھەژمار دروست کرا",
        "accountcreatedtext": "هەژماری بەکارهێنەری [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|لێدوان]]) دروست کراوە.",
-       "createaccount-title": "درووست‌کردنی هەژمارە بۆ {{SITENAME}}",
-       "createaccount-text": "کەسێک هەژمارەیەکی بۆ ئی‌مێڵ ئەدرەسەکی تۆ لەسەر {{SITENAME}} ($4) بەناوی \"$2\"، بە وشەی نهێنی \"$3\".\nئێستا دەبێ بڕۆیتە ژوورەوە و وشەی نهێنی بگۆڕیت.\n\nئەگەر ئەو هەژمارە بە هەڵە درووست‌کراوە، ئەم برووسکە لە بەرچاو مەگرە.",
+       "createaccount-title": "درووست کردنی ھەژمار بۆ {{SITENAME}}",
+       "createaccount-text": "کەسێک ھەژمارێکی بۆ ناونیشانی ئیمێلی تۆ لە {{SITENAME}}دا ($4) بە ناوی «$2»ـەوە و بە تێپەڕوشەی  «$3»ـەوە دروست کردووە.\nدەبێت ھەر ئێستا بچیتە چوورەوە و تێپەڕوشەیەکەت بگۆڕیت.\n\nئەگەر ئەم ھەژمارە بە ھەڵە دروست کراوە، دەکرێت گوێ بەم پەیامە نەدەیت.",
        "login-throttled": "زۆر زۆر ھەوڵت داوە بۆ چوونە ژوورەوە.\nتکایە $1 بوەستە پێش ھەوڵی دووبارە.",
        "loginlanguagelabel": "زمان: $1",
        "pt-login": "بچۆ ژوورەوە",
        "missingcommentheader": "'''بیرهێنانەوە:''' بۆ ئەم بۆچوونەت سەردێڕ\\بابەت ڕاچاو نەکردووە.\nئەگەر دیسان «{{int:savearticle}}» لێبدەی، دەستکاریەکەت بێ سەردێڕ یان بابەت پاشەکەوت دەبێ.",
        "summary-preview": "پێشبینینی کورتە:",
        "subject-preview": "پێشبینینی بابەت/سەردێڕ:",
-       "blockedtitle": "به‌کار هینه‌ر له‌کار خراوه",
+       "blockedtitle": "بەکارھێنەر بەربەست کراوە",
        "blockedtext": "'''ناوی بەکارهێنەری یان ئای‌پی ئەدرەسی تۆ بەربەست‌ کراوە.'''\n\nبەربەست لە لایەن $1 کراوە.\nهۆکاری بەربەست کردن ''$2''ە.\n\n* دەستپێکی بەربەست‌کران: $8\n* کۆتایی هاتنی بەربەست‌کران: $6\n* بابەتی بەربەست: $7\n\nبۆ وتووێژ سەبارەت بە بەربەست‌کرانەکە دەبێ پەیوەندی بکەی بە $1 یان یەکێ دی لە [[{{MediaWiki:Grouppage-sysop}}|بەڕێوبەران]].\nلە بیرت بێ تاکوو ئیمەیل ئەدرەسێکی بڕوا پێ‌کراو لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر]] ڕاچاو نەکەی، نابێت لە هەلی «ئیمەیل ناردن بۆ ئەم بەکارهێنەرە» کەڵک وەر بگری؛ کەڵک وەرگرتن لەوە بەربەست نەکراوە بۆت.\n\nئای‌پی ئەدرەسی ئێستای تۆ $3 و پێناسەی بەربەست‌کراو #$5.\nتکایە لە هەر پرس و داواکاریەکت‌دا هەموو وردەکاریەکانی سەرەوە بگونجێنە.",
        "autoblockedtext": "ناونیشانی IPی تۆ بە شێوەی خۆکارانە بەرگیری لێ کراوە چوونکە بەکارھێنەرێکی دیکە بە خراپی بە کاری ھێناوە و بە دەستی $1 بەرگیری لێ کراوە.\nبەم ھۆکارەوە:\n\n:<em>$2</em>\n\n* دەست پێ کردنی بەرگیری: $8\n* بە سەر چوونی بەرگیری: $6\n* Intended blockee: $7\n\nدەتوانیت پەیوەندی بکەیت بە $1 یان یەکێکی دیکە لە [[{{MediaWiki:Grouppage-sysop}}|بەڕێوەبەران]] بۆ وتووێژ لە سەر بەرگیرییەکە.\n\nتێ بگە کە ناتوانیت ئامرازی «ئیمێل بنێرە بۆ ئەم بەکارھێنەرە» بە کار بھێنیت مەگەر ئەوەی کە پێشتر لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر]]تدا ناونیشانێکی گونجاوی ئیمێلت تۆمار کردبێت و بەرگیریت لێ نەکرابێت لە بەکارھێنانی ئەو ئامرازەش.\n\nناونیشانی IPی ئێستای تۆ $3ـە و پێناسەی یەرگیرییەکە #$5ـە.\nتکایە ھەموو وردەکارییەکانی سەرەوە ھەبێت لە ھەر پرس و داوایک کە دەیکەیت.",
        "blockednoreason": "هیچ هۆکارێک نەدراوە",
        "confirmedittext": "پێویستە پێش هەرجۆرە دەستکاریەکی لاپەڕەکان ئەدرەسی ئیمەیلت ڕاچاو کردبێت .<br />\nتکایە لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەر]] ئی‌مەیلەکەت دانێ و بڕواپێکراوی بکە.",
        "nosuchsectiontitle": "بەش نەدۆزرایەوە",
        "nosuchsectiontext": "هەوڵی دەستکاریکردنی بەشێکت داوە کە بوونی نیە.\nلەوانەیە لەو کاتە خەریکی بینینی پەڕە بوویت گۆزرابێتەوە یان سڕابێتەوە.",
-       "loginreqtitle": "پێویستە بچییە ژوورەوە",
-       "loginreqlink": "بچییە ژوورەوە",
+       "loginreqtitle": "پێویستە بچیتە ژوورەوە",
+       "loginreqlink": "بچیتە ژوورەوە",
        "loginreqpagetext": "بۆ دیتنی لاپەڕەکانی دیکە دەبێ $1 .",
        "accmailtitle": "تێپەڕوشە نێررا",
        "accmailtext": "تێپەڕوشەیەک کە بە هەڕەمەکی بۆ [[User talk:$1|$1]] دروست کرا، نێررا بۆ $2. دەتوانیت لە پەڕەی <em>[[Special:ChangePassword|گۆڕینی تێپەڕوشەدا]]</em> لە کاتی چوونەژوورەوەدا بیگۆڕی.",
        "anontalkpagetext": "----''ئەمە لاپەڕەی وتووێژە بۆ بەکارهێنەرێکی نەناسراوە کە هێشتا هەژمارەی درووست‌نەکردووه یان کەڵکی‌ لێ وەرناگرێ .\nلەبەر ئەوە مەجبوورین ئای‌پی ئەدرەسەکی ژمارەیی بۆ ناساندنی بەکار بێنین.\nئای‌پی ئەدرەسی وا لەوانەیه لە لایەن چەندین بەکارهێنەروە بەکاربێت.\nئەگەر تۆ بەکارهێنەرێکی نەناسراوی و هەست ئەکەی ئەم لێدوانە پەیوەندی بە تۆوە نیە تکایە [[Special:UserLogin/signup|ھەژمارێکی نوێ دروست بکە]] یان [[Special:UserLogin|بچۆ ژوورەوە]] لەبەر ئەوەی لەداهاتوودا دەگەڵ بەکارهێنەرانی‌ نەناسراوی دی تێکەڵ نەکرێیت. ''",
        "noarticletext": "ھەنووکە ھیچ دەقێک لەم پەڕەیەدا نییە.\nدەتوانی بۆ ئەم ناوە لە [[Special:Search/{{PAGENAME}}|پەڕەکانی تردا بگەڕێی]]، <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} لە لۆگەکاندا بگەڕێی]، یان [{{fullurl:{{FULLPAGENAME}}|action=edit}} ئەم پەڕەیە دەستکاری بکەیت]</span>.",
        "noarticletext-nopermission": "ھەنووکە ھیچ دەقێک لەم پەڕەیەدا نییە.\nدەتوانی لە پەڕەکانی تردا [[Special:Search/{{PAGENAME}}|بۆ ئەم ناوە بگەڕێی]]، یان <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} لە لۆگە پەیوەندیدارەکاندا بگەڕێی]</span>، بەڵام ناتوانی ئەم پەڕەیە دروست بکەی.",
-       "userpage-userdoesnotexist": "هەژماری بەکارهێنەری \"<nowiki>$1</nowiki>\" تۆمار نەکراوە.<br />\nگەر دەتەوێ ئەم لاپەڕە درووست‌کەی یان دەستکاری بکەی تکایە تاقی‌بکەوە .",
+       "userpage-userdoesnotexist": "ھەژماری بەکارھێنەریی «$1» تۆمار نەکراوە.\nتکایە دڵنیا ببەرەوە ئەگەر دەتھەوێت ئەم پەڕەیە دروست یان دەستکاری بکەیت.",
        "userpage-userdoesnotexist-view": "ھەژماری بەکارھێنەریی «$1» تۆمار نەکراوە.",
        "blocked-notice-logextract": "ھەنووکە ئەم بەکارھێنەرە بەربەست کراوە.\nدوایین بابەتی لۆگی بەربەستن لە ژێرەوە ھاتووە:",
        "clearyourcache": "تێبینی:''' لە دوای پاشەکەوت کردن، لەوانەیە  بۆ بینینی گۆڕانکارییەکان پێویست بێ cacheی وێبگەڕەکەت پاکبکەیتەوە.\n* '''Firefox / Safari:''' دوگمەی ''Shift'' بگرە کاتێک لەسەر ''Reload''دا کرتە دەکەی، یان ھەرکام لە ''Ctrl-F5'' یان ''Ctrl-R'' لێبدە (''⌘-R'' لەسەر Mac دا)\n* '''Google Chrome:''' دوگمەکانی ''Ctrl-Shift-R'' لێبدە  (''⌘-Shift-R'' لەسەر Mac دا)\n* '''Internet Explorer:''' دوگمەی ''Ctrl'' بگرە کاتێک لەسەر  ''Refresh''دا کرتە دەکەی، یان ''Ctrl-F5'' لێبدە\n* '''Opera:''' لە ڕێگەی ''Tools → Preferences'' ەوە cacheەکە بسڕەوە.",
        "usercssyoucanpreview": "'''سەرچەشن:''' «{{int:showpreview}}» بەکاربێنە بۆ تاقی‌کردنەوەی CSS نوێ‌کەت، پێش پاشەکەوت‌کردن.",
        "userjsyoucanpreview": "'''سەرچەشن:''' «{{int:showpreview}}» بەکاربێنە بۆ تاقی‌کردنەوەی جاڤاسکریپتە نوێ‌کەت، پێش پاشەکەوت‌کردن.",
-       "usercsspreview": "'''له‌یادت بێ که‌ ئێسته‌ ته‌نها پێشبینینی CSS به‌کارهێنه‌ریه‌که‌ت ده‌که‌ی.'''\n'''هێشتا پاشه‌که‌وت نه‌بووه !'''",
+       "usercsspreview": "<strong>لە بیرت ببێت کە تەنھا خەریکی پێشبینینی CSSـەکەت دەبینیت.\nھێشتا پاشەکەوەت نەکراوە!</strong>",
        "userjspreview": "'''لەیادت بێ کە ئێستە تەنها پێشبینین\\تاقی‌کردنەوەی جاڤاسکریپتی بەکارهێنەریەکەت دەکەی.'''\n'''هێشتا پاشەکەوت نەبووه !'''",
-       "sitecsspreview": "'''له‌یادت بێ که‌ ئێسته‌ ته‌نها پێشبینینی ئەم CSS ده‌که‌ی.'''\n'''هێشتا پاشه‌که‌وت نه‌کراوە !'''",
+       "sitecsspreview": "<strong>لە بیرت ببێت کە تەنھا خەریکی پێشبینینی ئەم CSSـە دەبینیت.\nھێشتا پاشەکەوەت نەکراوە!</strong>",
        "sitejspreview": "'''لە بیرت نەچێت ئەمە تەنیا پێشبینینی ئەم کۆدەی جاڤاسکریپتە.'''\n'''گۆڕانکارییەکانت ھێشتا پاشەکەوت نەکراون!'''",
        "userinvalidcssjstitle": "'''ئاگادارکردنەوە:''' پێست نیە بۆ \"$1\".\nلەیادت بێ کە لاپەڕەکانی‌ .css و .js لە بابەت بە پیتی بچووک کەڵک وەر ئەگرن. وەک {{ns:user}}:Foo/vector.css نە وەک {{ns:user}}:Foo/Vector.css .",
        "updated": "(نوێ‌کراوە)",
        "semiprotectedpagewarning": "'''ئاگاداری:''' ئەم پەڕە داخراوە بۆ ئەوی تەنھا بەکارھێنەرە تۆمارکراوەکان بتوانن دەستکاریی بکەن.\nدوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
        "cascadeprotectedwarning": "'''ئاگاداری:''' ئەم لاپەڕە داخراوە بۆیە تەنها ئەو کەسانەی مافی بەڕێوبەرایەتی‌یان هەیە ئەتوانن دەستکاری بکەن، چۆنکا ئەمە {{PLURAL:$1|لاپه‌ڕه‌|لاپه‌ڕانه‌}} لە زنجیرەی پارێزراوەکانی لە خۆ گرتووە‌:",
        "titleprotectedwarning": "'''ئاگاداری: ئەم پەڕە داخراوە، بۆئەوەی بۆ درووست‌کردنی [[Special:ListGroupRights|مافە تایبەتەکانت]] پێویستن.'''\nبۆ چاوانە دوایین لۆگ لە خوارەوەدا ھاتووە:",
-       "templatesused": "ئەو {{PLURAL:$1|داڕێژە کە لەم پەڕەیەدا بە کارھێنراوە|داڕێژانە کە لەم پەڕەیەدا بە کارھێنراون}}:",
-       "templatesusedpreview": "ئەو {{PLURAL:$1|داڕێژە کە لەم پێشبینینەدا بە کارھێنراوە|داڕێژانە کە لەم پێشبینینەدا بە کارھێنراون}}:",
+       "templatesused": "ئەو {{PLURAL:$1|داڕێژەیە کە لەم پەڕەیەدا بە کارھێنراوە|داڕێژانە کە لەم پەڕەیەدا بە کارھێنراون}}:",
+       "templatesusedpreview": "ئەو {{PLURAL:$1|داڕێژەیە کە لەم پێشبینینەدا بە کارھێنراوە|داڕێژانە کە لەم پێشبینینەدا بە کارھێنراون}}:",
        "templatesusedsection": "ئەو {{PLURAL:$1|داڕێژە|داڕێژانە}} کە لەم بەشەدا بە کارھێنراون:",
        "template-protected": "(پارێزراو)",
        "template-semiprotected": "(نیوەپارێزراو)",
        "hiddencategories": "ئەم پەڕە ئەندامێکی {{PLURAL:$1|١ پۆلی شاراوەیە|$1 پۆلی شاراوەیە}}:",
        "edittools": "<!-- دەقی ئێرە لە ژێری فۆرمی دەستکاری و بارکردندا نیشان دەدرێت. -->",
-       "nocreatetext": "{{SITENAME}} توانای درووست‌کردنی لاپەڕە نوێکانی داخستووە.<br />\nئەتوانی بگەڕێتەوە دواوە و یەکێک لەو لاپەڕانەی وا هەن دەستکاری بکەیت ، یان [[Special:UserLogin|بچۆ ژوورەوە یان هەژمارێک درووست‌بکە]]",
+       "nocreatetext": "{{SITENAME}} توانای دروست کردنی پەڕەی نوێی سنووردار کردووە.\nدەتوانیت بگەڕێیتەوە دواوە و پەڕەیەک دەستکاری بکەیت یان [[Special:UserLogin|بچیتە ژوورەوە یان ھەژمارێک دروست بکەیت]].",
        "nocreate-loggedin": "ئیجازەی دروست کردنی پەڕەی نوێت نیە.",
        "sectioneditnotsupported-title": "بەش دەستکاریکردنی پشتیوانی ناکرێ",
        "sectioneditnotsupported-text": "دەستکاریکردنی بەش لە پەڕەدا پشتیوانی ناکرێ.",
        "powersearch-legend": "گەڕانی پێشکەوتوو",
        "powersearch-ns": "گەڕان لە بۆشاییی ناوەکانی:",
        "powersearch-togglelabel": "تاوتوێ بکە:",
-       "powersearch-toggleall": "ھەموو",
+       "powersearch-toggleall": "ھەموویان",
        "powersearch-togglenone": "ھیچیان",
        "powersearch-remember": "ھەڵبژاردەکانت بۆ گەڕانەکانی تر لە بیر بێت",
        "search-external": "گەڕانی دەرەکی",
        "prefs-reset-intro": "دەتوانی لەم لاپەڕە بۆ گەڕانەوەی هەڵبژاردەکانت بۆ بنچینەیی ماڵپەر کەڵک وەرگریت.\nگەر ئەوە بکەی ئیتر گۆڕانەکەت ناگەڕێتەوە.",
        "prefs-emailconfirm-label": "پشتڕاستکردنەوەی ئیمەیل:",
        "youremail": "ئیمەیل:",
-       "username": "{{GENDER:$1|ناوی به‌کارھێنەر}}:",
+       "username": "{{GENDER:$1|ناوی بەکارھێنەر}}:",
        "prefs-memberingroups": "{{GENDER:$2|ئەندامی}} {{PLURAL:$1|گرووپی|گرووپەکانی}}:",
        "prefs-registration": "کاتی خۆتۆمارکردن:",
        "yourrealname": "ناوی ڕاستی:",
        "yourvariant": "شێوەزاری زمانی ناوەرۆک:",
        "yournick": "واژووی نوێ:",
        "prefs-help-signature": "بۆچوونەکان لە لاپەڕەکانی وتووێژدا دەبێ بە \"<nowiki>~~~~</nowiki>\" دیاری بکرێن، کە دواتر خۆکار دەگۆڕێ بە واژۆکەت و مۆری کاتی.",
-       "badsig": "ئیمزاكه‌ هه‌ڵه‌یه‌، ته‌ماشای كۆدی HTML بكه‌‌",
+       "badsig": "کۆدی ئیمزای ھەڵە.\nبە تاگە HTMLکاندا بچۆرەوە.",
        "badsiglength": "واژووەکەت زۆر درێژە.\nواژوو نابێ لە $1 {{PLURAL:$1|نووسە}} درێژتر بێت.",
        "yourgender": "پێت خۆشە چۆن وەسف بکرێیت؟",
        "gender-unknown": "پێم خۆشە باسی نەکەم",
        "newuserlogpagetext": "ئەمە لۆگێکی دروستکردنی بەکارھێنەرە.",
        "rightslog": "لۆگی مافەکانی بەکارھێنەر",
        "rightslogtext": "ئەمە لۆگی دەستکاری مافەکانی بەکار‌هێنەرە.",
-       "action-read": "خوێندنەوەی ئەم پەڕە",
+       "action-read": "خوێندنەوەی ئەم پەڕەیە",
        "action-edit": "دەستکاریی ئەم پەڕەیە",
        "action-createpage": "دروستکردنی پەڕەکان",
        "action-createtalk": "دروستکردنی پەڕەکانی وتووێژ",
-       "action-createaccount": "درووست‌کردنی هەژمارەی ئەم بەکارهێنەرە",
-       "action-history": "مێژووی ئەم پەڕەیە ببینە",
+       "action-createaccount": "دروست کردنی ئەم ھەژماری بەکارھێنەرییە",
+       "action-history": "بینینی مێژووی ئەم پەڕەیە",
        "action-minoredit": "نیشان‌کردنی ئەم دەستکاریە وەک بچووک",
        "action-move": "گواستنەوەی ئەم پەڕەیە",
        "action-move-subpages": "گواستنەوەی ئەم پەڕەیە و ژێرپەڕەکانی",
        "imagelinks": "بەکارھێنانی پەڕگە",
        "linkstoimage": "لەم {{PLURAL:$1|پەڕەی خوارەوە بەستەر دراوە|$1 پەڕەی خوارەوە بەستەر دراوە}} بۆ ئەم پەڕگە:",
        "linkstoimage-more": "زیاتر لە $1 {{PLURAL:$1|بەستەری لاپەڕە|بەستەری لاپەڕە}} بۆ ئەم پەڕگه.\nئەم لیستە {{PLURAL:$1|یەکەم لاپەڕەی بەستەرە|یەکەم لاپەڕە $1 بەستەرە}} بۆ تەنها یەم پەڕگە.\nهەروا [[Special:WhatLinksHere/$2|لیستی تەواو]] ئامادەی کەڵک وەرگرتنە.",
-       "nolinkstoimage": "‌لاپەڕەیەک نەدۆزرایەوە کە بەستەری هەبێ بۆ ئەم پەڕگە.",
+       "nolinkstoimage": "ھیچ پەڕەیەک نییە کە بەستەری ھەبێت بۆ ئەم پەڕگەیە.",
        "morelinkstoimage": "[[Special:WhatLinksHere/$1|بەستەری زیاتر]] ببینە بۆ ئەم پەڕگە.",
        "linkstoimage-redirect": "$1 (ڕەوانەکەری پەڕگە) $2",
        "duplicatesoffile": "ئەم {{PLURAL:$1|پەڕگە دووبارەکرنەوەیەکی|پەڕگانە دووبارەکردنەوەی}} ئەم پەڕگەن ([[Special:FileDuplicateSearch/$2|وردەکاری زیاتر]]):",
        "unusedtemplatestext": "ئەم پەڕە هەموو پەڕەکانی بۆشاییی ناوی {{ns:template}} بە لیست دەکات کە لە پەڕەی تردا بەکارنەھێنراون.\nلە بیری نەکەی پێش سڕینەوەیان پشکنینی بەستەرەکانی تر بۆ داڕێژەکان بکەی.",
        "unusedtemplateswlh": "بەستەرەکانی تر",
        "randompage": "پەڕەی ھەڕەمەکی",
-       "randompage-nopages": "هیچ لاپەڕەیەک لەم {{PLURAL:$2|ناوبۆشاییەدا|ناوبۆشاییانەدا}} نیە: $1.",
+       "randompage-nopages": "ھیچ پەڕەیەک لە {{PLURAL:$2|بۆشایی ناو|بۆشایی ناوەکان}}ی خوارەوەدا نییە: $1.",
        "randomincategory": "پەڕەیەک بە ھەڵکەوت لە پۆلدا",
        "randomincategory-submit": "بڕۆ",
        "randomredirect": "ڕەوانەکەری ھەڕەمەکی",
        "listgrouprights-addgroup-self": "زیادکردنی {{PLURAL:$2|گرووپ|گرووپەکان}} بۆ سەر ھەژماری خۆی: $1",
        "listgrouprights-removegroup-self": "لابردنی {{PLURAL:$2|گرووپ|گرووپەکان}} لە سەر ھەژماری خۆی: $1",
        "listgrouprights-addgroup-self-all": "زیادکردنی ھەموو گرووپەکان بۆ سەر ھەژماری خۆی",
-       "listgrouprights-removegroup-self-all": "لابردنی هەموو گرووپەکان له‌ سه‌ر هه‌ژماری خۆ",
+       "listgrouprights-removegroup-self-all": "لابردنی ھەموو گرووپەکان لە سەر ھەژماری خۆی",
        "listgrouprights-namespaceprotection-header": "سنوورداریی بۆشایی ناو",
        "listgrouprights-namespaceprotection-namespace": "بۆشایی ناو",
        "listgrouprights-namespaceprotection-restrictedto": "مافی رێ‌پێدراوی بەکارھێنەر بۆ دەستکاری",
        "trackingcategories": "پۆلەکانی شوێنکەوتن",
        "trackingcategories-name": "ناوی پەیام",
-       "mailnologin": "ناونیشان بۆ ناردن نییه‌",
+       "mailnologin": "ناونیشان بۆ ناردن نییە",
        "mailnologintext": "ده‌بێ له‌ [[Special:UserLogin|ژووره‌وه‌]] بیت و ناونیشانێکی بڕواپێ‌کراوی ئی‌مه‌یلت له‌ ناو [[Special:Preferences|هه‌ڵبژارده‌کان]] دیاری کردبێت تا بتوانی ئی‌مه‌یل بنێریت بۆ به‌کارهێنه‌رانی دیکه‌.",
        "emailuser": "ئیمەیل بنێرە بۆ ئەم بەکارھێنەرە",
        "emailuser-title-target": "ئیمەیلی ئەم {{GENDER:$1|بەکارھێنەر}}ە",
        "deletereason-dropdown": "* ھۆکارە باوەکانی سڕینەوە\n** سپام\n** خراپکاری\n** پێشێلکردنی مافی لەبەرگرتنەوە\n** داخوازی دانەر\n** ڕەوانەکەری شکاو",
        "delete-edit-reasonlist": "دەستکاری کردنی ھۆکارەکانی سڕینەوە",
        "delete-toobig": "ئەم لاپەڕە مێژوویەکی دەستکاری زۆر گەورەی هەیە، زیاتر لە $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}.\nبۆ بەرگری لە خراپ‌بوونی چاوەڕوان نەکراوی {{SITENAME}}، سڕینەوەی لاپەڕەی وا بەربەست‌کراوە.",
-       "delete-warning-toobig": "ئÛ\95Ù\85 Ù\84اپÛ\95Ú\95Û\95 Ù\85Û\8eÚ\98Ù\88Ù\88Û\8cÛ\95Ú©Û\8c Ø¯Û\95ستکارÛ\8c Ø²Û\86ر Ú¯Û\95Ù\88رÛ\95Û\8c Ù\87Û\95Û\8cÛ\95Ø\8c Ø²Û\8cاتر Ù\84Û\95 $1 {{PLURAL:$1|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95}}.\nسÚ\95Û\8cÙ\86Û\95Ù\88Û\8c Ø¦Û\95Ù\88Û\95 Ù\84Û\95 Ù\88اÙ\86Û\95Û\8cÛ\95 Ú©Ø§Ø±Û\95کاÙ\86Û\8c Ø¨Ù\86Ú©Û\95دراÙ\88Û\8c {{SITENAME}} ØªÙ\88Ù\88Ø´Û\8c Ú©Û\8eØ´Û\95 Ø¨Ú©Ø§ØªØ\9b\nدÙ\88Ù\88رÙ\86Ù\88اÚ\95اÙ\86Û\95 Ø¬Û\8eâ\80\8cبÛ\95جÛ\8eÛ\8c Ø¨Ú©ە.",
+       "delete-warning-toobig": "ئÛ\95Ù\85 Ù¾Û\95Ú\95Û\95Û\8cÛ\95 Ù\85Û\8eÚ\98Ù\88Ù\88Û\8cÛ\95Ú©Û\8c Ø¯Û\95ستکارÛ\8cÛ\8c Ø²Û\86ر Ú¯Û\95Ù\88رÛ\95Û\8c Ú¾Û\95Û\8cÛ\95Ø\8c Ø²Û\86رتر Ù\84Û\95 $1 {{PLURAL:$1|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95}}.\nسÚ\95Û\8cÙ\86Û\95Ù\88Û\95Û\8c Ø¦Û\95Ù\88 Ù¾Û\95Ú\95Û\95Û\8cÛ\95 Ù\84Û\95Ù\88اÙ\86Û\95Û\8c Ú©Ø§Ø±Û\95کاÙ\86Û\8c Ø¨Ù\86Ú©Û\95دراÙ\88Û\95Û\8c {{SITENAME}} ØªÙ\88Ù\88Ø´Û\8c Ú©Û\8eØ´Û\95 Ø¨Ú©Ø§ØªØ\9b\nبÛ\95 Ø³Û\95رÙ\86جÛ\95Ù\88Û\95 Ø¨Ú\86Û\86 Ù¾Û\8eØ´Û\95Ù\88ە.",
        "deleting-backlinks-warning": "'''ھۆشدار:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|پەڕەکانی تر]] بەم پەڕەیەی دەتەوێ بیسڕییەوە بەستەر دراوە.",
        "rollback": "گەڕاندنەوەی دەستکارییەکان",
        "rollbacklink": "گەڕاندنەوە",
        "protect-expiring-local": "بەسەردەچێ لە $1",
        "protect-expiry-indefinite": "بێسنوور",
        "protect-cascade": "پەڕەکانی نێو ئەم پەڕە بپارێزە (پاراستنی تاڤگەیی)",
-       "protect-cantedit": "ناتوانی ئاستی پاراستنی ئەم پەڕە بگۆڕی، چونکوو تۆ ئیجازەی ئەم کارەت نیە.",
+       "protect-cantedit": "ناتوانیت ئاستەکانی پاراستنی ئەم پەڕەیە بگۆڕیت، چونکە بۆت نییە دەستکاریی بکەیت.",
        "protect-othertime": "کاتی تر:",
        "protect-othertime-op": "کاتی تر",
        "protect-existing-expiry": "ئەم کاتی بەسەرچوونی ماوە کە هەیە: $3، $2",
        "cannotundelete": "ھێنانەوە سەرکەوتوو نەبوو:\n$1",
        "undeletedpage": "'''$1 هێنراوەتەوە'''\n\nبۆ دیتنی پێشینەی دوایین سڕینەوەکان و هێنانەوەکان سەرنجی [[Special:Log/delete|لۆگی سڕینەوە]] بدە.",
        "undelete-header": "بۆ دیتنی ئەو لاپەڕانەی لەم داییانەدا سڕاونەتەوە چاو لە [[Special:Log/delete|لۆگی سڕینەوە]] بکە.",
-       "undelete-search-title": "Ú¯Û\95Ú\95اÙ\86 Ø¨Û\86 Ù\84اپÛ\95Ú\95Û\95 Ø³Ú\95اوەکان",
-       "undelete-search-box": "Ú¯Û\95Ú\95اÙ\86 Ø¨Û\86 Ù\84اپÛ\95Ú\95Û\95 Ø³Ú\95اوەکان",
+       "undelete-search-title": "Ú¯Û\95Ú\95اÙ\86 Ø¨Û\86 Ù¾Û\95Ú\95Û\95 Ø³Ú\95راوەکان",
+       "undelete-search-box": "Ú¯Û\95Ú\95اÙ\86 Ø¨Û\86 Ù¾Û\95Ú\95Û\95 Ø³Ú\95راوەکان",
        "undelete-search-prefix": "نیشان‌دانی ئەو لاپەڕانەی دەستپێکیان ئەمەیە:",
        "undelete-search-submit": "گەڕان",
        "undelete-no-results": "لە ئەرشیڤی سڕاوەکانی لاپەڕەیەکی هاوتا نەدۆزرایەوە.",
        "whatlinkshere-title": "ئەو پەڕانەی بەستەریان ھەیە بۆ «$1»",
        "whatlinkshere-page": "پەڕە:",
        "linkshere": "پەڕەکانی ژێرەوە بەستەر دراون بۆ <strong>[[:$1]]</strong>:",
-       "nolinkshere": "هیچ لاپەڕەیەک بەستەری نەداوە بە '''[[:$1]]'''.",
-       "nolinkshere-ns": "هیچ لاپەڕەیەک بەستەری نەداوە بە '''[[:$1]]''' لە بۆشایی‌ناوی هەڵبژێردراو.",
+       "nolinkshere": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>[[:$1]]</strong>.",
+       "nolinkshere-ns": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>[[:$1]]</strong> لە بۆشایی ناوی هەڵبژێرراودا.",
        "isredirect": "پەڕەی ڕەوانەکەر",
        "istemplate": "بەکارھێنراو",
        "isimage": "بەستەری پەڕگە",
        "movenotallowed": "ڕێگەت پێ‌نەدراوە بۆ گواستنەوەی لاپەڕەکان.",
        "movenotallowedfile": "ڕێگەت پێ‌نەدراوە بۆ گواستنەوەی پەڕگەکان.",
        "cant-move-user-page": "ڕێگەت پێ‌نەدراوە بۆ گواستنەوەی لاپەڕەکانی بەکارهێنەر (جیاواز لە ژێرلاپەڕەکان).",
-       "cant-move-to-user-page": "ڕێگەت پێ‌نەدراوە بۆ گواستنەوەی لاپەڕەیەک بۆ لاپەڕەی بەکارهێنەر (غەیری بۆ ژێرلاپەڕەی بەکارهێنەر).",
+       "cant-move-to-user-page": "مافی ئەوەت نییە کە پەڕەیەک بگوێزیتەوە بۆ پەڕەیەکی بەکارھێنەری (بەڵام بۆ ژێرپەڕەیەکی بەکارھێنەری دەتوانیت).",
        "newtitle": "بۆ ناوی نوێی:",
        "move-watch": "پەڕەی سەرچاوە و مەبەست بخە ژێر چاودێری",
        "movepagebtn": "ئەم پەڕەیە بگوازەوە",
        "movepage-moved-redirect": "ڕەوانەکەرێک دروست کرا.",
        "movepage-moved-noredirect": "لە دانانی ڕەوانەکەر بەرگری کرا.",
        "articleexists": "پەڕەیەک بەم ناوە ھەیە یان ئەو ناوەی تۆ ھەڵتبژاردووە ڕێگەی پێنەدراوە.\nتکایە ناوێکی دیکە ھەڵبژێرە.",
-       "cantmove-titleprotected": "ناتوانی لاپەڕەیەک بگوێزیتەوە بۆ ئەم شوێنە، لەبەر ئەوەی سەردێڕی نوێ لە درووست‌کردن پارێزراوە.",
+       "cantmove-titleprotected": "ناتوانیت پەڕەیەک بگوێزیتەوە بۆ ئەم شوێنە، چونکە سەرناوە نوێیەکە پارێزراوە لە درووست کردن.",
        "movetalk": "پەڕەی لێدوانی پەیوەندیدار بگوازەوە",
        "move-subpages": "ژێرپەڕەکانی بگوازەوە (ھەتا $1 پەڕە)",
        "move-talk-subpages": "ژێرپەڕەکانی پەڕەی لێدوان بگوازەوە (ھەتا $1 پەڕە)",
        "delete_and_move_text": "== پێویستییەکانی سڕینەوە ==\nلاپەڕەی مەبەست \"[[:$1]]\" لە پێش‌دا هەیە.\nئایا دەتەوێ ئەوە بسڕیتەوە تا ڕێگە بۆ گواستنەوەی بکەیتەوە؟",
        "delete_and_move_confirm": "بەڵێ، پەڕەکە بسڕەوه",
        "delete_and_move_reason": "سڕایەوە بۆ کردنەوەی ڕیگە بۆ گواستنەوە لە «[[$1]]»ەوە",
-       "selfmove": "سەردێڕەکانی سەرچاوە و مەبەست یەکێکن؛\nناکرێ لاپەڕەیەک بۆ سەر خۆی‌ بگوازرێتەوە.",
+       "selfmove": "سەرناوی سەرچاوە و مەبەست یەکێکن؛\nناکرێت پەڕەیەک بۆ سەر خۆی‌ بگوازرێتەوە.",
        "immobile-source-namespace": "پەڕەکان لە بۆشاییی ناوی \"$1\"دا ناگوێزرێنەوە.",
        "immobile-target-namespace": "گواستنەوەی لاپەڕە بۆناو بۆشایی‌ناو \"$1\" ناکرێت.",
        "immobile-target-namespace-iw": "بەستەرێکی نێوان‌ویکی ئامانجێکی گونجاو نیە بۆ گواستنەوەی لاپەڕە.",
        "protectedpagemovewarning": "'''ھۆشیار بە: ئەم پەڕە پارێزراوە بۆ ئەوی تەنیا ئەو بەکارھێنەرانە کە مافەکانی بەڕێوەبەرایەتییان ھەیە بتوانن بیگوازنەوە.'''\nدوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
        "semiprotectedpagemovewarning": "'''ئاگاداری:''' ئەم پەڕە پارێزراوە بۆ ئەوی تەنھا بەکارھێنەرە تۆمارکراوەکان بتوانن بیگوازنەوە.\nدوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
        "export": "ھەناردنی پەڕەکان",
-       "exporttext": "دەتوانی دەق و مێژووی دەستکاری لاپەڕەیەکی تایبەت یان دەستە لاپەڕەیەک بۆ ناو پەڕگەیەکی XML هەناردن بکەیت.\nدواتر بە کەڵک‌وەرگرتن لە [[Special:Import|لاپەڕەی هێنانەناوە]] لە مێدیاویکی‌دا، دەتوانی بیهێنیتە ناو ویکی‌یەکانی دیکە.\n\nبۆ هەناردنی لاپەڕەکان، سەردێڕەکان لە چوارچێوەی دەقی خوارەوە بنووسە، هەر هێڵێک یەک سەردێڕ. هەروا هەڵبژێرە ئایا پێداچوونەوەی ئێستا و هەموو پێداچوونەوە کۆنەکانت دەوێ یان هەر پێداچوونەوەی ئێستا و زانیاریی سەبارەت بە دوایین دەستکاری.\n\nلە بابەتی دواتر هەروەها دەتوانی لە بەستەرێک کەڵک وەرگریت، بۆ نموونە [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] بۆ لەپەڕەی \"[[{{MediaWiki:Mainpage}}]]\".",
+       "exporttext": "دەتوانیت دەق و مێژووی دەستکاریی پەڕەیەکی دەستنیشان کراو یان کۆمەڵێک پەڕە کە ناو پەڕگەیەکی XML دا پێچراونەتەوە، هەناردە بکەیت.\nدەکرێت ئەمە لە ویکییەکی دیکەدا ھاوردە بکرێت بە کەڵک وەرگرتن لە  ئامرازی [[Special:Import|ھاوردە کردنی پەڕە]]ی MediaWiki.\n\nبۆ هەناردە کردنی پەڕەکان، سەرناوەکانیان لە چوارچێوەی خوارەوەدا بنووسە، هەر سەرناوێک لە هێڵێکدا. و هەڵبژێرە کە پێداچوونەوەی ئێستا و ھەموو پێداچوونەوە کۆنەکانت دەوێت یان تەنھا پێداچوونەوەی ئێستا و زانیاریی سەبارەت بە دوایین دەستکاری.\n\nئەگەر تەنھا پێداچوونەوەی ئێستات دەوێت، دەتوانیت بەستەرێکیش بە کار بھێنیت، بۆ نموونە [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] بۆ پەڕەی «[[{{MediaWiki:Mainpage}}]]».",
        "exportall": "ھەموو پەڕەکان ھەناردە بکە",
        "exportcuronly": "تەنها پێداچوونەوەی ئێستا لەخۆ بگرێت نەک هەموو مێژوو",
        "exportnohistory": "----\n'''ئاگاداربە: '''ھەناردنی ھەموو مێژووی پەڕەکان لەم فۆرمەوە لەبەر ھۆکاری ڕێخستن، داخراوە.",
        "tooltip-ca-undelete": "هێنانەوەی دەستکاریەکانی پیش سڕینەوە وا لەسەر ئەم لاپەڕە ڕووی‌داوە",
        "tooltip-ca-move": "ئەم پەڕەیە بگوازەوە",
        "tooltip-ca-watch": "ئەم پەڕە بخە سەر لیستی چاودێریت",
-       "tooltip-ca-unwatch": "ئەم پەڕە لە لیستی چاودێریت لابە",
+       "tooltip-ca-unwatch": "ئەم پەڕەیە لە لیستی چاودێریت لاببە",
        "tooltip-search": "لە {{SITENAME}} بگەڕێ",
        "tooltip-search-go": "بڕۆ بۆ پەڕەیەک کە بە تەواوی ئەم ناوەی ھەیە ئەگەر بببێت",
        "tooltip-search-fulltext": "لە پەڕەکاندا بگەڕێ بۆ ئەم دەقە",
        "tooltip-save": "گۆڕانکارییەکانی خۆت پاشکەوت بکە",
        "tooltip-preview": "پێش بینینی گۆڕانکارییەکان، تکایە پێش پاشکەوت کردن ئەمە بەکار بھێنە",
        "tooltip-diff": "نیشان دانی گۆڕانکارییەکانت لە دەقەکەدا",
-       "tooltip-compareselectedversions": "جیاوازییەکانی دوو وەشانە دیاریکراوەی ئەم پەڕە ببینە.",
+       "tooltip-compareselectedversions": "جیاوازییەکانی دوو وەشانە دیاریکراوەی ئەم پەڕەیە ببینە.",
        "tooltip-watch": "ئەم پەڕە بخە سەر لیستی چاودێریت",
        "tooltip-watchlistedit-normal-submit": "ناونیشانەکان لاببە",
        "tooltip-watchlistedit-raw-submit": "نوێکردنەوەی لیستی چاودێری",
-       "tooltip-recreate": "درووست‌کردنەوەی لاپەڕە ئەگەرچی سڕاوەتەوە",
+       "tooltip-recreate": "پەڕەکە دروست‌ بکەرەوە ئەگەرچی سڕراوەتەوە",
        "tooltip-upload": "دەستپێکردنی بارکردن",
        "tooltip-rollback": "«گەڕاندنەوە» بە یەک کرتە گۆڕانکاریی/گۆڕانکارییەکانی ئەم پەڕەیە دەگەڕێنێتەوە بۆ دوایین بەشداربوو",
        "tooltip-undo": "«پووچەڵکردنەوە» ئەم گۆڕانکارییە دەگەڕێنێتەوە و فۆرمی دەستکاریکردن لە شێوەی پێشبینیندا دەکاتەوە. بەم جۆرە دەکرێ ھۆکارێک لە کورتەی دەستکاریدا بنووسرێ.",
index 26205fc..ac313b7 100644 (file)
        "changeemail-newemail": "Nová e-mailová adresa:",
        "changeemail-newemail-help": "Toto pole by mělo zůstat prázdné, pokud chcete odstranit svou e-mailovou adresu. Pokud bude e-mailová adresa odstraněná, nebudete si moct obnovit zapomenuté heslo a přijímat e-maily z této wiki.",
        "changeemail-none": "(žádná)",
-       "changeemail-password": "Vaše heslo do {{gender:2sg|{{SITENAME}}}}:",
+       "changeemail-password": "{{GENDER:|Vaše heslo}} do {{GRAMMAR:2sg|{{SITENAME}}}}:",
        "changeemail-submit": "Změnit e-mail",
        "changeemail-throttled": "Provedli jste příliš mnoho pokusů o přihlášení.\nČekejte prosím $1 a zkuste to znovu.",
        "changeemail-nochange": "Zadejte prosím odlišnou e-mailovou adresu.",
        "uploaded-script-svg": "V načteném SVG souboru byl nalezen skriptovatelný element „$1“.",
        "uploaded-hostile-svg": "V načteném SVG souboru bylo v elementu se styly nalezeno nebezpečné CSS.",
        "uploaded-event-handler-on-svg": "Nastavování atributů pro obsluhu událostí <code>$1=\"$2\"</code> není v SVG souborech dovoleno.",
-       "uploaded-href-attribute-svg": "Atributy href <code>&lt;$1 $2=\"$3\"&gt;</code> s nelokálním cílem (např. http://, javascript: apod.) nejsou v SVG souborech dovoleny.",
-       "uploaded-href-unsafe-target-svg": "V načteném SVG souboru byl nalezen href s nebezpečným cílem <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "Atributy href v souborech SVG smějí odkazovat jen na cíle využívající http:// nebo https://, nalezeno <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "V načteném SVG souboru byl nalezen href odkazující na nebezpečný cíl s datovým URI <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "V načteném SVG souboru byla nalezena značka „animate“, která by mohla měnit href, s atributem „from“ <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Nastavování atributů pro obsluhu událostí je zablokováno, v načteném SVG souboru bylo nalezeno <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Použití značky „set“ pro přidání atributu „href“ rodičovskému elementu je zablokováno.",
        "querypage-disabled": "Tato speciální stránka je z výkonnostních důvodů vypnuta.",
        "apihelp": "Nápověda k API",
        "apihelp-no-such-module": "Modul „$1“ nebyl nalezen.",
+       "apisandbox": "API pískoviště",
+       "apisandbox-jsonly": "Pro použití API pískoviště je nutný JavaScript.",
+       "apisandbox-api-disabled": "API je na tomto webu vypnuto.",
+       "apisandbox-intro": "Pomocí této stránky můžete experimentovat s <strong>webovými službami MediaWiki API</strong>.\nPodrobnosti využití API najdete v [[mw:API:Main page|jeho dokumentaci]]. Příklad: [//www.mediawiki.org/wiki/API#A_simple_example získání obsahu Hlavní stránky]. Další příklady uvidíte vybráním parametru action.\n\nUvědomte si, že přestože jste na pískovišti, mohou akce provedené na této stránce wiki změnit.",
+       "apisandbox-fullscreen": "Rozbalit panel",
+       "apisandbox-fullscreen-tooltip": "Rozbalí panel pískoviště, aby vyplnil okno prohlížeče.",
+       "apisandbox-unfullscreen": "Zobrazit stránku",
+       "apisandbox-unfullscreen-tooltip": "Zmenší panel pískoviště, aby byly dostupné navigační odkazy MediaWiki.",
+       "apisandbox-submit": "Odeslat požadavek",
+       "apisandbox-reset": "Vyčistit",
+       "apisandbox-retry": "Zkusit znovu",
+       "apisandbox-loading": "Načítají se informace o API modulu „$1“…",
+       "apisandbox-load-error": "Při načítání informací k API modulu „$1“ došlo k chybě: $2",
+       "apisandbox-no-parameters": "Tento API modul nemá žádné parametry.",
+       "apisandbox-helpurls": "Odkazy na nápovědu",
+       "apisandbox-examples": "Příklady",
+       "apisandbox-dynamic-parameters": "Doplňkové parametry",
+       "apisandbox-dynamic-parameters-add-label": "Přidat parametr:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Jméno parametru",
+       "apisandbox-dynamic-error-exists": "Parametr s názvem „$1“ již existuje.",
+       "apisandbox-deprecated-parameters": "Zavržené parametry",
+       "apisandbox-fetch-token": "Automaticky naplnit token",
+       "apisandbox-submit-invalid-fields-title": "Některá pole jsou neplatná",
+       "apisandbox-submit-invalid-fields-message": "Opravte označená pole a zkuste to znovu.",
+       "apisandbox-results": "Výsledky",
+       "apisandbox-sending-request": "Odesílá se API požadavek…",
+       "apisandbox-loading-results": "Přijímají se API výsledky…",
+       "apisandbox-results-error": "Došlo k chybě při načítání odpovědi na API dotaz: $1.",
+       "apisandbox-request-url-label": "URL požadavku:",
+       "apisandbox-request-time": "Trvání požadavku: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Opravit token a znovu odeslat",
+       "apisandbox-results-fixtoken-fail": "Nepodařilo se načíst token „$1“.",
+       "apisandbox-alert-page": "Pole na této stránce nejsou platná.",
+       "apisandbox-alert-field": "Hodnota tohoto pole není platná.",
        "booksources": "Zdroje knih",
        "booksources-search-legend": "Vyhledat knižní zdroje",
        "booksources-search": "Hledat",
        "group-bot.js": "/* Zde uvedený JavaScript bude použit pouze pro boty */",
        "group-sysop.js": "/* Zde uvedený JavaScript bude použit pouze pro správce */",
        "group-bureaucrat.js": "/* Zde uvedený JavaScript bude použit pouze pro byrokraty */",
-       "anonymous": "anonymní {{PLURAL:$1|uživatel|uživatelé|uživatelé}} {{GRAMMAR:2sg|{{SITENAME}}}}",
+       "anonymous": "{{PLURAL:$1|anonymního uživatele|anonymních uživatelů}} {{GRAMMAR:2sg|{{SITENAME}}}}",
        "siteuser": "uživatel {{grammar:2sg|{{SITENAME}}}} $1",
        "anonuser": "anonymní uživatel {{grammar:2sg|{{SITENAME}}}} $1",
        "lastmodifiedatby": "Tuto stránku naposledy {{GENDER:$4|změnil|změnila|změnil}} $3 v $2, $1.",
-       "othercontribs": "Do textu {{PLURAL:$2|přispěl|přispěli}} $1.",
+       "othercontribs": "Založeno na práci $1.",
        "others": "další",
-       "siteusers": "{{PLURAL:$2|uživatel|uživatelé|uživatelé}} {{grammar:2sg|{{SITENAME}}}} $1",
+       "siteusers": "{{PLURAL:$2|{{GENDER:$1|uživatele|uživatelky}}|uživatelů}} {{grammar:2sg|{{SITENAME}}}} $1",
        "anonusers": "anonymní {{PLURAL:$2|uživatel|uživatelé}} {{grammar:2sg|{{SITENAME}}}} $1",
        "creditspage": "Zásluhy za stránku",
        "nocredits": "K této stránce neexistuje informace o zásluhách.",
        "expand_templates_preview_fail_html": "<em>Protože {{SITENAME}} má povolené syrové HTML a došlo ke ztrátě dat relace, je náhled skryt kvůli ochraně před JavaScriptovými útoky.</em>\n\n<strong>Pokud to byl legitimní pokus o náhled, zkuste to znovu.</strong>\nPokud to stále nebude fungovat, zkuste se [[Special:UserLogout|odhlásit]] a znovu přihlásit.",
        "expand_templates_preview_fail_html_anon": "<em>Protože {{SITENAME}} má povolené syrové HTML a vy nejste přihlášeni, je náhled skryt kvůli ochraně před JavaScriptovými útoky.</em>\n\n<strong>Pokud to byl legitimní pokus o náhled, [[Special:UserLogin|přihlaste se]] a zkuste to znovu.</strong>",
        "expand_templates_input_missing": "Musíte zadat alespoň nějaký vstupní text.",
-       "pagelanguage": "Volba jazyka stránky",
+       "pagelanguage": "Změnit jazyk stránky",
        "pagelang-name": "Stránka",
        "pagelang-language": "Jazyk",
        "pagelang-use-default": "Použít implicitní jazyk",
index 44b8704..86e4381 100644 (file)
        "october-date": "октѡврїꙗ $1 числа",
        "november-date": "ноємврїꙗ $1 числа",
        "december-date": "дєкємврїꙗ $1 числа",
+       "period-am": "до полоудьни",
+       "period-pm": "по полоудьни",
        "pagecategories": "{{PLURAL:$1|Катигорїꙗ|Катигорїи|Катигорїѩ|Катигорїѩ}}",
        "category_header": "катигорїѩ ⁖ $1 ⁖ страницѧ",
        "subcategories": "подъкатигорїѩ",
        "category-media-header": "катигорїѩ ⁖ $1 ⁖ дѣла",
-       "category-empty": "''си катигорїи нꙑнѣ страницѧ и дѣлъ нѣстъ''",
+       "category-empty": "''сѥи катигорїи нꙑнѣ страницѧ и дѣлъ нѣстъ''",
        "hidden-categories": "{{PLURAL:$1|съкрꙑта катигорїꙗ|съкрꙑти катигорїи|съкрꙑтꙑ катигорїѩ}}",
        "hidden-category-category": "съкрꙑтꙑ катигорїѩ",
        "category-subcat-count": "{{PLURAL:$2|Сѥи катигорїи тъкъмо сꙗ подъкатигорїꙗ ѥстъ|Сѥи катигорїи {{PLURAL:$1|ѥдина подъкатигорїꙗ ѥстъ|2 подъкатигорїи ѥстє|$1 подъкатигорїѩ сѫтъ}} · а вьсѩ жє подъкатигорїѩ число $2 ѥстъ}}",
@@ -94,7 +96,7 @@
        "anontalk": "бєсѣда",
        "navigation": "плаваниѥ",
        "and": "&#32;и",
-       "qbedit": "иÑ\81пÑ\80ави",
+       "qbedit": "иÑ\81пÑ\80авлѥниѥ",
        "qbpageoptions": "сꙗ страница",
        "qbmyoptions": "моꙗ страницѧ",
        "faq": "чѧстꙑ въпроси",
        "permalink": "въиньна съвѧꙁь",
        "print": "пєчатаниѥ",
        "view": "поꙁьрѣниѥ",
-       "edit": "иÑ\81пÑ\80ави",
+       "edit": "иÑ\81пÑ\80авлѥниѥ",
        "create": "сътворѥниѥ",
-       "editthispage": "си страницѧ исправлѥниѥ",
-       "create-this-page": "си страницѧ сътворѥниѥ",
+       "editthispage": "сѥѩ страницѧ исправлѥниѥ",
+       "create-this-page": "сѥѩ страницѧ сътворѥниѥ",
        "delete": "поничьжєниѥ",
-       "deletethispage": "си страницѧ поничьжєниѥ",
+       "deletethispage": "сѥѩ страницѧ поничьжєниѥ",
+       "undeletethispage": "сѥѩ страницѧ въстаниѥ иꙁ поничьжєниꙗ",
+       "undelete_short": "въстаниѥ {{PLURAL:$1|ѥдьнꙑ мѣнꙑ|$1 мѣноу|$1 мѣнъ}} иꙁ поничьжєниꙗ",
+       "viewdeleted_short": "{{PLURAL:$1|ѥдьнꙑ поничьжєнꙑ мѣнꙑ|$1 поничьжєноу мѣноу|$1 поничьжєнъ мѣнъ}} поꙁьрѣниѥ",
        "protect": "ꙁабранѥниѥ",
        "protect_change": "иꙁмѣнѥниѥ",
-       "protectthispage": "си страницѧ ꙁабранєниѥ",
+       "protectthispage": "сѥѩ страницѧ ꙁабранєниѥ",
        "unprotect": "ꙁабранѥниꙗ обраꙁа иꙁмѣнѥниѥ",
+       "unprotectthispage": "ꙁабранѥниꙗ сѥѩ страницѧ обраꙁа иꙁмѣнѥниѥ",
        "newpage": "нова страница",
-       "talkpage": "си страницѧ бєсѣда",
+       "talkpage": "сѥѩ страницѧ бєсѣда",
        "talkpagelinktext": "бєсѣда",
        "specialpage": "нарочьна страница",
        "personaltools": "моꙗ орѫдиꙗ",
+       "articlepage": "члѣна поꙁьрѣниѥ",
        "talk": "бєсѣда",
+       "views": "поꙁьрѣниꙗ",
        "toolbox": "орѫдиꙗ",
+       "userpage": "польꙃєватєлꙗ страницѧ поꙁьрѣниѥ",
+       "imagepage": "дѣла страницѧ поꙁьрѣниѥ",
+       "templatepage": "обраꙁьца страницѧ поꙁьрѣниѥ",
+       "viewhelppage": "помощи страницѧ поꙁьрѣниѥ",
+       "categorypage": "катигорїѩ страницѧ поꙁьрѣниѥ",
+       "viewtalkpage": "бєсѣдꙑ поꙁьрѣниѥ",
        "otherlanguages": "дроугꙑ ѩꙁꙑкꙑ",
        "redirectedfrom": "(прѣнаправлѥниѥ отъ ⁖ $1 ⁖)",
        "redirectpagesub": "прѣнаправлѥниѥ",
        "redirectto": "прѣнаправлѥниѥ къ :",
        "lastmodifiedat": "страницѧ послѣдьнꙗ мѣна сътворѥна $2 · $1 бѣ ⁙",
+       "protectedpage": "сꙗ страница ꙁабранѥна ѥстъ",
        "jumpto": "прѣиди къ :",
        "jumptonavigation": "плаваниѥ",
        "jumptosearch": "исканиѥ",
        "pool-errorunknown": "нєвѣдома блаꙁна",
-       "aboutsite": "О {{grammar:instrumental|{{SITENAME}}}}",
+       "aboutsite": "{{grammar:genitive|{{SITENAME}}}} опьсаниѥ",
        "aboutpage": "Project:О сѥмь опꙑтьствовании",
        "copyright": "подъ прощєниѥмь $1 пьсано ѥстъ · ащє ино нє каꙁано ѥстъ",
        "copyrightpage": "{{ns:project}}:Творьцъ права",
        "policy-url": "Project:Полїтїка",
        "portal": "обьщєниꙗ съвѣтъ",
        "portal-url": "Project:Обьщєниꙗ съвѣтъ",
+       "privacy": "личьнъ вѣстии полїтїка",
+       "privacypage": "Project:Личьнъ вѣстии полїтїка",
        "pagetitle": "$1 · {{SITENAME}}",
        "retrievedfrom": "поѩто иꙁ ⁖ $1 ⁖",
        "youhavenewmessages": "$1 тєбѣ напьсанꙑ сѫтъ ($2)",
        "newmessageslinkplural": "{{PLURAL:$1|ново напьсаниѥ|нова напьсании|999=новꙑ напьсаниꙗ}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|послѣдьнꙗ мѣна|послѣдьни мѣни|999=послѣдьн҄ь мѣнъ}}",
-       "editsection": "иÑ\81пÑ\80ави",
-       "editold": "иÑ\81пÑ\80ави",
+       "editsection": "иÑ\81пÑ\80авлѥниѥ",
+       "editold": "иÑ\81пÑ\80авлѥниѥ",
        "viewsourceold": "страницѧ источьнъ обраꙁъ",
-       "editlink": "иÑ\81пÑ\80ави",
+       "editlink": "иÑ\81пÑ\80авлѥниѥ",
        "viewsourcelink": "страницѧ источьнъ обраꙁъ",
        "editsectionhint": "исправлѥниѥ чѧсти : $1",
        "toc": "каталогъ",
        "showtoc": "виждь",
        "hidetoc": "съкрꙑи",
+       "confirmable-yes": "да",
+       "confirmable-no": "нѣтъ",
        "viewdeleted": "$1 видєти хощєши ;",
-       "red-link-title": "$1 (си страницѧ нѣстъ)",
+       "restorelink": "{{PLURAL:$1|ѥдьна поничьжєна мѣна|$1 поничьжєноу мѣноу|$1 поничьжєнъ мѣнъ}}",
+       "feedlinks": "потокъ :",
+       "red-link-title": "$1 (сѥѩ страницѧ нѣстъ)",
        "nstab-main": "члѣнъ",
        "nstab-user": "польꙃєватєл҄ь",
        "nstab-media": "срѣдьства",
        "nstab-help": "страница помощи",
        "nstab-category": "катигорїꙗ",
        "mainpage-nstab": "главьна страница",
-       "nosuchspecialpage": "си нарочнꙑ страницѧ нѣстъ",
+       "nosuchspecialpage": "сѥѩ нарочнꙑ страницѧ нѣстъ",
        "error": "блаꙁна",
+       "databaseerror-error": "блаꙁна : $1",
        "internalerror": "вънѫтрѣнꙗ блаꙁна",
        "badtitle": "ꙁъло имѧ",
        "viewsource": "страницѧ источьнъ обраꙁъ",
        "viewsource-title": "вижьдь страницѧ ⁖ $1 ⁖ источьнъ обраꙁъ",
+       "exception-nologin": "тꙑ нє въшьлъ ѥси",
        "welcomeuser": "Добрѣ прити · $1!",
        "welcomecreation-msg": "твоѥ польꙃєватєльско мѣсто сътворєно ѥстъ ⁙\nнꙑнѣ иꙁмѣнити [[Special:Preferences|{{GRAMMAR:genitive|{{SITENAME}}}} строи]] можєши",
        "yourname": "твоѥ имѧ",
        "userlogin-yourname": "польꙃєватєлꙗ имѧ",
        "userlogin-yourname-ph": "твоѥ польꙃєватєлꙗ имѧ напьши",
+       "createacct-another-username-ph": "польꙃєватєлꙗ имѧ напьши",
        "yourpassword": "таино слово напиши",
        "userlogin-yourpassword": "таино слово",
        "userlogin-yourpassword-ph": "твоѥ таино слово напьши",
        "userlogout": "ис̾ходъ",
        "notloggedin": "тꙑ нє въшьлъ ѥси",
        "userlogin-noaccount": "мѣсто ти нѣстъ ли ?",
+       "userlogin-joinproject": "въ {{grammar:locative|{{SITENAME}}}} чѧсть прими",
        "nologin": "мѣсто ти нѣстъ ли ? $1",
        "nologinlink": "съꙁижди си мѣсто",
        "createaccount": "съꙁижди си мѣсто",
        "gotaccount": "мѣсто ти ѥстъ ли? $1",
        "gotaccountlink": "въниди",
        "userlogin-resetpassword-link": "таино слово ꙁабꙑлъ ли ;",
+       "userlogin-helplink2": "помощь въниждєниꙗ дѣлꙗ",
        "createaccountreason": "какъ съмꙑслъ :",
        "createacct-reason": "какъ съмꙑслъ",
+       "createacct-reason-ph": "чєсо дѣлꙗ ино польꙃєватєльско мѣсто сътворити хощєши ;",
        "createacct-submit": "съꙁижди си мѣсто",
+       "createacct-another-submit": "съꙁижди мѣсто",
        "createacct-benefit-heading": "{{SITENAME}} съꙁьдаѥтъ сѧ чьловѣкꙑ · ижє ꙗко тꙑ сѫтъ",
        "createacct-benefit-body1": "{{PLURAL:$1|мѣна|мѣнꙑ|мѣнъ}}",
        "createacct-benefit-body2": "{{PLURAL:$1|страница|страници|страницѧ}}",
        "loginerror": "въхода блаꙁна",
        "createacct-error": "мѣста сътворѥниꙗ блаꙁна",
        "loginsuccess": "'''нꙑнѣ тꙑ {{GENDER|въшьлъ|въшьла}} въ {{grammar:locative|{{SITENAME}}}} подь имьньмъ ⁖ $1 ⁖.'''",
-       "mailmypassword": "поÑ\81Ñ\8aли Ð½Ð¾Ð²Ð¾ Ñ\82аино Ñ\81лово",
+       "mailmypassword": "нова Ñ\82аина Ñ\81лова Ð¾Ñ\83Ñ\81Ñ\82авлѥниѥ",
        "accountcreated": "мѣсто сътворєно ѥстъ",
        "accountcreatedtext": "польꙃєватєльско мѣсто [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|бєсѣда]]) сътворєно бѣ",
        "loginlanguagelabel": "ѩꙁꙑкъ : $1",
        "botpasswords-label-cancel": "отъмѣтаниѥ",
        "resetpass-submit-loggedin": "таина словєсє иꙁмѣнѥниѥ",
        "resetpass-submit-cancel": "отъмѣтаниѥ",
+       "passwordreset": "нова таина слова оуставлѥниѥ",
        "passwordreset-username": "польꙃєватєлꙗ имѧ :",
        "changeemail-none": "(нѣстъ)",
        "link_sample": "съвѧꙁи имѧ",
        "summary": "опьсаниѥ :",
        "subject": "ѳєма :",
        "minoredit": "малаꙗ мѣна",
-       "watchthis": "си страницѧ блюдєниѥ",
+       "watchthis": "сѥѩ страницѧ блюдєниѥ",
        "savearticle": "съхранѥниѥ",
        "showpreview": "мѣнꙑ поꙁьрѣниѥ (бєꙁ съхранѥниꙗ)",
        "blockedtitle": "польꙃєватєл҄ь ꙁаграждєнъ ѥстъ",
        "loginreqlink": "въниди",
        "newarticle": "(новъ)",
-       "noarticletext": "нꙑнѣ с̑ьдє ничєсожє нє напьсано ѥстъ ⁙\n[[Special:Search/{{PAGENAME}}|си страницѧ имѧ искати]] дроугꙑ страницѧ ·\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} съвѧꙁанꙑ їсторїѩ видѣти] ·\nили [{{fullurl:{{FULLPAGENAME}}|action=edit}} ѭжє исправити]</span> можєши",
-       "noarticletext-nopermission": "нꙑнѣ с̑ьдє ничєсожє нє напьсано ѥстъ ⁙\n[[Special:Search/{{PAGENAME}}|си страницѧ имѧ искати]] дроугꙑ страницѧ или\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} съвѧꙁанꙑ їсторїѩ видѣти]</span> можєши ⁙ сътворити жє си страницѧ нє можєши",
-       "userpage-userdoesnotexist": "польꙃєватєльска мѣста ⁖ $1 ⁖ нꙑнѣ нѣстъ ⁙\nпрѣдъ сътворѥниѥмь или исправлѥниѥмь си страницѧ помꙑсли жє ащє исто тъ дѣиство ноуждьно ли",
+       "noarticletext": "нꙑнѣ с̑ьдє ничєсожє нє напьсано ѥстъ ⁙\n[[Special:Search/{{PAGENAME}}|сѥѩ страницѧ имѧ искати]] дроугꙑ страницѧ ·\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} съвѧꙁанꙑ їсторїѩ видѣти] ·\nили [{{fullurl:{{FULLPAGENAME}}|action=edit}} ѭжє исправити]</span> можєши",
+       "noarticletext-nopermission": "нꙑнѣ с̑ьдє ничєсожє нє напьсано ѥстъ ⁙\n[[Special:Search/{{PAGENAME}}|сѥѩ страницѧ имѧ искати]] дроугꙑ страницѧ или\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} съвѧꙁанꙑ їсторїѩ видѣти]</span> можєши ⁙ сътворити жє сѭ страницѫ нє можєши",
+       "userpage-userdoesnotexist": "польꙃєватєльска мѣста ⁖ $1 ⁖ нꙑнѣ нѣстъ ⁙\nпрѣдъ сътворѥниѥмь или исправлѥниѥмь сѥѩ страницѧ помꙑсли жє ащє исто тъ дѣиство ноуждьно ли",
        "userpage-userdoesnotexist-view": "польꙃєватєльско мѣсто ⁖ $1 ⁖ сътворєно нѣстъ",
        "clearyourcache": "'''НАРОЧИТО''': По съхранѥнии можєши обити своѥго съмотрила съхранъ да видѣлъ би мѣнꙑ\n* '''Mozilla ли Firefox ли Safari''' ли жьмꙑи ''Shift'' а мꙑшиѭ жьми ''Reload'' или жьми ''Ctrl-F5'' ꙗко жє ''Ctrl-R'' (⌘-R вън Apple Mac)\n* '''Google Chrome:''' ли жьмꙑи ''Ctrl-Shift-R'' (⌘-Shift-R въ Mac)\n* '''Internet Explorer''' ли жьмꙑи ''Ctrl'' а мꙑшиѭ жьми ''Refresh'' или жьми ''Ctrl-F5'' \n* '''Опєрꙑ''' польꙃєватєльмъ можєть бꙑти ноужда пльнѣ поничьжити ихъ съмотрила съхранъ въ ''Tools → Preferences'' ⁙",
        "updated": "(оновлѥно ѥстъ)",
        "creating": "сътворѥниѥ ⁖ $1 ⁖",
        "editingsection": "исправлѥниѥ ⁖ $1 ⁖ (чѧсть)",
        "editingcomment": "исправлѥниѥ ⁖ $1 ⁖ (нова чѧсть)",
+       "explainconflict": "нѣкъто сѭ страницѫ иꙁмѣнилъ въ врѣмѧ ѥгда тꙑ ѥѩжє исправлꙗти почѧашє ⁙\nврьхоу нꙑнѣщьн҄ь страницѧ обраꙁъ авлѥнъ ѥстъ ⁙\nниꙁоу жє твоꙗ мѣна авлѥна ѥстъ ⁙\nсъѥдинити твоѭ мѣноу съ новомь обраꙁомь страницѧ длъжєнъ ѥси ⁙\nащє жє ⁖ {{int:savearticle}} ⁖ жьмєши · <strong>тъкъмо</strong> напьсаниѥ ижє врьхоу ѥстъ съхранѥно бѫдєтъ",
        "yourtext": "твоѥ напьсаниѥ",
        "templatesused": "сѥѩ страницѧ {{PLURAL:$1|сь обраꙁьць польꙃоуѥтъ сѧ ѥстъ|с҄и обраꙁьца польꙃоуѭтъ сѧ ѥстє|с҄и обраꙁьци польꙃоуѭтъ сѧ сѫтъ}} :",
        "template-protected": "(ꙁабранєно ѥстъ)",
        "template-semiprotected": "(чѧстьно ꙁабранѥно)",
        "hiddencategories": "сꙗ страница въ {{PLURAL:$1|1 съкрꙑтѣи катигорїи|$1 съкрꙑтѣхъ катигорїѩ}} сѧ авлꙗѥтъ :",
-       "moveddeleted-notice": "сꙗ страница поничьжєна ѥстъ ⁙\nпоничьжєниꙗ и прѣимєнованиꙗ їстории си страницѧ нижѣ видѣти можєши",
+       "moveddeleted-notice": "сꙗ страница поничьжєна ѥстъ ⁙\nпоничьжєниꙗ и прѣимєнованиꙗ їстории сѥѩ страницѧ нижѣ видѣти можєши",
+       "postedit-confirmation-created": "страница сътворѥна ѥстъ",
        "postedit-confirmation-saved": "твоꙗ мѣна съхранѥна ѥстъ",
-       "viewpagelogs": "си страницѧ їсторїѩ",
+       "viewpagelogs": "сѥѩ страницѧ їсторїѩ",
        "cur": "нꙑ҃н",
        "last": "пс҃лд",
        "page_first": "прьва страница",
        "deletedhist": "поничьжєна їсторїꙗ",
        "revdelete-otherreason": "инъ или допльнитєл҄ьнъ съмꙑслъ :",
        "revdelete-reasonotherlist": "инъ съмꙑслъ",
+       "revdelete-edit-reasonlist": "поничьжєниꙗ съмꙑслъ исправлѥниѥ",
        "mergehistory-reason": "какъ съмꙑслъ :",
+       "history-title": "иꙁмѣнѥнии їсторїꙗ страницѧ ⁖ $1 ⁖",
        "editundo": "отъмѣтаниѥ",
        "searchresults": "исканиꙗ слѣдьствиѥ",
        "searchresults-title": "исканиꙗ ⁖ $1 ⁖ слѣдьствиѥ",
        "right-delete": "страницѧ поничьжєниѥ",
        "newuserlogpage": "новъ мѣстъ сътворѥниꙗ їсторїꙗ",
        "rightslog": "чинодатєльства їсторїꙗ",
-       "action-edit": "си страницѧ исправлєниѥ",
+       "action-edit": "сѥѩ страницѧ исправлѥниѥ",
        "nchanges": "$1 {{PLURAL:$1|мѣна|мѣнꙑ|мѣнъ}}",
        "enhancedrc-history": "їсторїꙗ",
        "recentchanges": "послѣдьнѩ мѣнꙑ",
        "recentchanges-label-newpage": "по сѥи мѣнꙑ нова страница сътворѥна ѥстъ",
        "recentchanges-label-minor": "малаꙗ мѣна",
        "recentchanges-label-bot": "сѭ мѣноу аѵтоматъ сътворилъ",
+       "recentchanges-label-plusminus": "страницѧ мѣра на сѥ баитъ число иꙁмѣнѥна ѥстъ",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (таждє ꙁьри [[Special:NewPages|новъ страницѧ каталогъ]])",
        "rclistfrom": "новъ мѣнъ каꙁаниѥ отъ $2 · $3",
-       "rcshowhideminor": "$1 малꙑ мѣнꙑ",
+       "rcshowhideminor": "$1 малъ мѣнъ",
        "rcshowhideminor-show": "каꙁаниѥ",
        "rcshowhideminor-hide": "съкрꙑтиѥ",
        "rcshowhidebots": "$1 аѵтоматъ",
        "rcshowhidebots-show": "каꙁаниѥ",
        "rcshowhidebots-hide": "съкрꙑтиѥ",
-       "rcshowhideliu": "$1 польꙃєватєлъ · ѩжє съꙁижьдє сѥ мѣсто · мѣн",
+       "rcshowhideliu": "$1 польꙃєватєлъ · ѩжє съꙁижьдє сѥ мѣсто · мѣнъ",
        "rcshowhideliu-hide": "съкрꙑтиѥ",
-       "rcshowhideanons": "$1 анѡнѷмьнъ польꙃєватєлъ мѣн",
+       "rcshowhideanons": "$1 анѡнѷмьнъ польꙃєватєлъ мѣнъ",
        "rcshowhideanons-show": "каꙁаниѥ",
        "rcshowhideanons-hide": "съкрꙑтиѥ",
-       "rcshowhidemine": "$1 моꙗ мѣнꙑ",
+       "rcshowhidemine": "$1 моѩ мѣнъ",
        "rcshowhidemine-show": "каꙁаниѥ",
        "rcshowhidemine-hide": "съкрꙑтиѥ",
        "rclinks": "$1 послѣдьн҄ь  мѣнъ · ѩжє $2 послѣдьни дьни створѥнꙑ сѫтъ · каꙁаниѥ<br />$3",
        "statistics-pages-desc": "вьсѩ страницѧ въкоупомь съ бѣсєдꙑ · прѣнаправлѥниꙗ и инꙑ",
        "statistics-files": "положєнꙑ дѣла",
        "statistics-users-active": "дѣꙗтєльнꙑ польꙃєватєлє",
-       "brokenredirects-edit": "иÑ\81пÑ\80ави",
+       "brokenredirects-edit": "иÑ\81пÑ\80авлѥниѥ",
        "brokenredirects-delete": "поничьжєниѥ",
        "nbytes": "$1 {{PLURAL:$1|баитъ|баита|баитъ}}",
        "ncategories": "$1 {{PLURAL:$1|катигорїꙗ|катигорїи|катигорїѩ}}",
        "nlinks": "$1 {{PLURAL:$1|съвѧꙁь|съвѧꙁи|съвѧꙁии}}",
        "nmembers": "$1 {{PLURAL:$1|члѣнъ|члѣна|члѣни|члѣнъ}}",
        "shortpages": "кратъкꙑ страницѧ",
+       "longpages": "дльгꙑ страницѧ",
+       "protectedpages-reason": "какъ съмꙑслъ",
        "listusers": "польꙃєватєлъ каталогъ",
        "usereditcount": "$1 {{PLURAL:$1|мѣна|мѣнꙑ|мѣнъ}}",
        "usercreated": "{{GENDER:$3|сътворилъ|сътворила}} мѣсто $1 въ $2",
        "newpages-username": "польꙃєватєлꙗ имѧ :",
        "ancientpages": "давьни страницѧ",
        "move": "прѣимєнованиѥ",
-       "movethispage": "си страницѧ прѣимєнованиѥ",
+       "movethispage": "сѥѩ страницѧ прѣимєнованиѥ",
        "pager-newer-n": "{{PLURAL:$1|нова 1|новꙑ $1|новъ $1}}",
        "pager-older-n": "{{PLURAL:$1|давьнꙗ 1|давьни $1|давьн҄ь $1}}",
+       "booksources": "кънигъ кладѧꙃи",
+       "booksources-search-legend": "кънигъ кладѧꙃь исканиѥ",
        "booksources-search": "исканиѥ",
        "specialloguserlabel": "испльнитєл҄ь :",
        "speciallogtitlelabel": "страницѧ или польꙃєватєлꙗ имѧ :",
        "linksearch-ns": "имєнъ просторъ :",
        "linksearch-ok": "ищи",
        "listusers-submit": "виждь",
+       "listusers-blocked": "({{GENDER:$1|ꙁаграждєнъ|ꙁаграждєна}} ѥстъ)",
        "listgrouprights-members": "(польꙃєватєлъ каталогъ)",
        "emailuser": "посъли єпїстолѫ",
        "emailusername": "польꙃєватєлꙗ имѧ :",
        "addedwatchtext": "страница ⁖ [[:$1]] ⁖ нꙑнѣ подъ твоимь [[Special:Watchlist|блюдєниѥмь]] ѥстъ ⁙\nвсꙗ ѥѩ и ѥѩжє бєсѣдꙑ страницѧ мѣнꙑ твоꙗ блюдєнии каталоꙃѣ покаꙁанꙑ бѫдѫтъ",
        "removedwatchtext": "страница ⁖ [[:$1]] ⁖ нꙑнѣ твоѥго [[Special:Watchlist|блюдєниꙗ]] иꙁнєсєна ѥстъ",
        "watch": "блюдєниѥ",
-       "watchthispage": "си страницѧ блюдєниѥ",
+       "watchthispage": "сѥѩ страницѧ блюдєниѥ",
        "unwatch": "остави блюдєниѥ",
        "watchlist-options": "блюдєниѩ строи",
        "watching": "блюдєниѥ ...",
        "prot_1movedto2": "⁖ [[$1]] ⁖ нарєчєнъ ⁖ [[$2]] ⁖ ѥстъ",
        "protectcomment": "какъ съмꙑслъ :",
        "protect-cascadeon": "сꙗ страница отъ исправлєниꙗ ꙁабранѥна ѥстъ бо въ съставѣ {{PLURAL:$1|страницѧ ижє съвѧꙁьно ꙁабранѥниѥ иматъ|страницоу ижє съвѧꙁьно ꙁабранѥниѥ иматє|страниць ижє съвѧꙁьно ꙁабранѥниѥ имѫтъ}} ⁙\nсѥѩ страницѧ ꙁабранѥниꙗ обраꙁа иꙁмѣнѥниѥ ничєсо жє въ съвѧꙁьнѣ ꙁабранѥнии иꙁмѣнити нє можєтъ",
-       "protect-level-sysop": "толико съмотритєлє",
+       "protect-level-sysop": "тъкъмо съмотритєлє",
        "protect-othertime": "ино врѣмѧ :",
        "protect-othertime-op": "ино врѣмѧ",
        "protect-otherreason-op": "инъ съмꙑслъ",
        "protect-expiry-options": "1 часъ:1 hour,1 дьнь:1 day,1 сєдмица:1 week,2 сєдмици:2 weeks,1 мѣсѧць:1 month,3 мѣсѧць:3 months,6 мѣсѧць:6 months,1 лѣто:1 year,вѣчьно:infinite",
        "pagesize": "(баитъ)",
-       "restriction-edit": "иÑ\81пÑ\80ави",
+       "restriction-edit": "иÑ\81пÑ\80авлѥниѥ",
        "restriction-move": "прѣимєнованиѥ",
        "restriction-upload": "положєниѥ",
        "undeletecomment": "какъ съмꙑслъ :",
        "ipbreason": "какъ съмꙑслъ :",
        "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",
+       "blocklist": "ꙁаграждєнꙑ польꙃєватєлє",
        "ipblocklist": "ꙁаграждєнꙑ польꙃєватєлє",
        "blocklist-reason": "какъ съмꙑслъ",
        "ipblocklist-submit": "исканиѥ",
        "blocklogentry": "ꙁаградилъ [[$1]] на врѣмѧ $2 $3",
        "block-log-flags-anononly": "тъкъмо анѡнѷмьнꙑ польꙃєватєлє",
        "block-log-flags-nocreate": "сътворѥниѥ мѣстъ ꙁабранєно ѥстъ",
+       "ipb_already_blocked": "⁖ $1 ⁖ ю ꙁаграждєнъ ѥстъ",
        "move-page": "прѣимєнованиѥ ⁖ $1 ⁖",
        "move-page-legend": "страницѧ прѣимєнованиѥ",
        "newtitle": "ново имѧ :",
-       "move-watch": "си страницѧ блюдєниѥ",
+       "move-watch": "сѥѩ страницѧ блюдєниѥ",
        "movepagebtn": "прѣимєнованиѥ",
        "pagemovedsub": "прѣимєнованиѥ сътворѥно ѥстъ",
        "movepage-moved": "'''⁖ $1 ⁖ нарєчєнъ ⁖ $2⁖ ѥстъ'''",
        "movepage-moved-redirect": "прѣнаправлѥниѥ сътворѥно бѣ",
-       "movetalk": "си страницѧ бєсѣдꙑ прѣимєнованиѥ",
+       "movetalk": "сѥѩ страницѧ бєсѣдꙑ прѣимєнованиѥ",
        "movelogpage": "прѣимєнованиꙗ їсторїꙗ",
        "movereason": "какъ съмꙑслъ :",
        "move-leave-redirect": "прѣнаправлѥниꙗ сътворѥниѥ",
        "tooltip-pt-watchlist": "страницѧ ижє ихъжє иꙁмѣнѥниꙗ подъ твоимь блюдєниѥмь сѫтъ",
        "tooltip-pt-mycontris": "{{GENDER:|твоѩ}} добродѣꙗнии каталогъ",
        "tooltip-pt-logout": "ис̾ходъ",
-       "tooltip-ca-talk": "си страницѧ бєсѣда",
-       "tooltip-ca-edit": "си страницѧ исправлѥниѥ",
+       "tooltip-ca-talk": "сѥѩ страницѧ бєсѣда",
+       "tooltip-ca-edit": "сѥѩ страницѧ исправлѥниѥ",
        "tooltip-ca-viewsource": "си страница ꙁабранєна ѥстъ ⁙\nѥѩ источьнъ обраꙁъ видєти можєши",
-       "tooltip-ca-protect": "си страницѧ ꙁабранєниѥ",
-       "tooltip-ca-delete": "си страницѧ поничьжєниѥ",
-       "tooltip-ca-move": "си страницѧ прѣимєнованиѥ",
-       "tooltip-ca-watch": "си страницѧ блюдєниѥ",
+       "tooltip-ca-protect": "сѥѩ страницѧ ꙁабранєниѥ",
+       "tooltip-ca-delete": "сѥѩ страницѧ поничьжєниѥ",
+       "tooltip-ca-move": "сѥѩ страницѧ прѣимєнованиѥ",
+       "tooltip-ca-watch": "сѥѩ страницѧ блюдєниѥ",
        "tooltip-search": "ищи {{{grammar:genitive|{{SITENAME}}}}} страницѧ",
+       "tooltip-search-go": "прѣиди къ страницѧ съ симь имєньмь ащє жє та страница ѥстъ",
        "tooltip-search-fulltext": "исканиѥ страницѧ ижє сѥ напьсаниѥ дрьжатъ",
        "tooltip-p-logo": "главьна страница",
        "tooltip-n-mainpage": "виждь главьноу страницѫ",
        "tooltip-n-mainpage-description": "виждь главьноу страницѫ",
        "tooltip-n-recentchanges": "послѣдьн҄ь мѣнъ каталогъ",
+       "tooltip-t-whatlinkshere": "страницѧ ижє съвѧꙁи дос҄ьдє имѫтъ",
        "tooltip-t-contributions": "{{GENDER:$1|польꙃєватєлꙗ|польꙃєватєлицѧ}} добродѣꙗнии каталогъ",
        "tooltip-t-upload": "положєниѥ дѣлъ",
        "tooltip-t-specialpages": "вьсѣѩ нарочьнъ страницѧ каталогъ",
        "tooltip-ca-nstab-user": "виждь польꙃєватєлꙗ страницѫ",
        "tooltip-ca-nstab-special": "сѥ нарочьна страница ѥстъ · ѥѩжє иꙁмѣнꙗти нє можєши",
        "tooltip-ca-nstab-image": "виждь дѣла страницѫ",
+       "tooltip-ca-nstab-template": "обраꙁьца поꙁьрѣниѥ",
        "tooltip-ca-nstab-category": "виждь катигорїѩ страницѫ",
        "tooltip-minoredit": "оꙁначи ꙗко малоу мѣноу",
        "tooltip-save": "твоѩ мѣнъ съхранѥниѥ",
-       "tooltip-watch": "си страницѧ блюдєниѥ",
+       "tooltip-watch": "сѥѩ страницѧ блюдєниѥ",
        "tooltip-summary": "кратъко опьсаниѥ напьши",
        "pageinfo-header-edits": "мѣнъ їсторїꙗ",
        "pageinfo-header-restrictions": "страницѧ ꙁабранѥниѥ",
        "fileduplicatesearch-filename": "дѣла имѧ :",
        "fileduplicatesearch-submit": "ищи",
        "specialpages": "нарочьнꙑ страницѧ",
+       "specialpages-group-other": "инꙑ нарочьнꙑ страницѧ",
        "tag-filter": "[[Special:Tags|мѣтъць]] сито :",
-       "tags-edit": "исправи",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|мѣтъка|мѣтъцѣ|мѣтъци}}]]: $2)",
+       "tags-active-yes": "да",
+       "tags-active-no": "нѣтъ",
+       "tags-edit": "исправлѥниѥ",
+       "tags-hitcount": "$1 {{PLURAL:$1|мѣна|мѣноу|мѣнъ}}",
+       "tags-create-reason": "какъ съмꙑслъ :",
+       "tags-create-submit": "сътворѥниѥ",
+       "tags-delete-reason": "какъ съмꙑслъ :",
+       "tags-activate-reason": "какъ съмꙑслъ :",
+       "tags-deactivate-reason": "какъ съмꙑслъ :",
        "htmlform-no": "нѣтъ",
        "htmlform-yes": "да",
        "logentry-delete-delete": "$1 {{GENDER:$2|поничьжилъ|поничьжила}} страницѫ ⁖ $3 ⁖",
        "logentry-block-block": "$1 {{GENDER:$2|ꙁаградилъ|ꙁаградила}} {{GENDER:$4|$3}} на врѣмѧ $5 $6",
+       "logentry-suppress-block": "$1 {{GENDER:$2|ꙁаграждєнъ|ꙁаграждєна}} ѥстъ {{GENDER:$4|$3}} врѣмєньмь $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|нарєчє}} страницѫ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|нарєчє}} страницѫ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖ бєꙁ прѣнаправлєниꙗ сътворѥниꙗ",
        "logentry-move-move_redir": "$1 {{GENDER:$2|нарєчє}} страницѧ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖ врьхоу прѣнаправлѥниꙗ",
        "searchsuggest-search": "исканиѥ",
        "searchsuggest-containing": "сѥ дрьжащи···",
        "api-error-unknownerror": "нєвѣдома блаꙁна : ⁖ $1 ⁖",
+       "duration-seconds": "$1 {{PLURAL:$1|дєѵтєролєпто|дєѵтєролєпта|дєѵтєролєптъ}}",
+       "duration-minutes": "$1 {{PLURAL:$1|лєпто|лєпта|лєптъ}}",
+       "duration-hours": "$1 {{PLURAL:$1|чѧсъ|чѧса|чѧсъ}}",
+       "duration-days": "$1 {{PLURAL:$1|дьнь|дьнꙗ|дьнь}}",
+       "duration-weeks": "$1 {{PLURAL:$1|сєдмица|сєдмици|сєдмицѧ}}",
+       "duration-years": "$1 {{PLURAL:$1|лѣто|лѣта|лѣтъ}}",
+       "duration-decades": "$1 {{PLURAL:$1|дєсѧтилѣтиѥ|дєсѧтилѣтиꙗ|дєсѧтилѣтии}}",
+       "duration-centuries": "$1 {{PLURAL:$1|вѣкъ|вѣка|вѣкъ}}",
+       "duration-millennia": "$1 {{PLURAL:$1|тꙑсѫщєлѣтиѥ|тꙑсѫщєлѣтиꙗ|тꙑсѫщєлѣтии}}",
+       "limitreport-cputime-value": "$1 {{PLURAL:$1|дєѵтєролєпто|дєѵтєролєпта|дєѵтєролєптъ}}",
+       "limitreport-walltime-value": "$1 {{PLURAL:$1|дєѵтєролєпто|дєѵтєролєпта|дєѵтєролєптъ}}",
+       "pagelanguage": "страницѧ ѩꙁꙑка иꙁмѣнѥниѥ",
+       "pagelang-name": "страница",
+       "pagelang-language": "ѩꙁꙑкъ",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 баитъ|$1 баита|$1 баитъ}} ($2 · $3%)",
+       "mediastatistics-header-unknown": "нєвѣдомꙑ",
+       "mediastatistics-header-total": "вьсѥ дѣла",
+       "json-error-syntax": "сѷнтаѯьна блаꙁна",
        "special-characters-group-latin": "латиньска аꙁъбоукꙑ",
        "special-characters-group-latinextended": "латиньскꙑ аꙁъбоукьвє доложєниѥ",
        "special-characters-group-ipa": "М҃ФА",
        "special-characters-group-greek": "грьчьска аꙁъбоукꙑ",
        "special-characters-group-cyrillic": "климєнтовица / гражданьска аꙁъбоукꙑ",
        "special-characters-group-arabic": "аравьска аꙁъбоукꙑ",
+       "special-characters-group-arabicextended": "аравьскꙑ аꙁъбоукъвє доложєниѥ",
+       "special-characters-group-persian": "пєрсьска аꙁъбоукꙑ",
        "special-characters-group-hebrew": "єврєиска аꙁъбоукꙑ",
        "special-characters-group-bangla": "бангальска аꙁъбоукꙑ",
+       "special-characters-group-tamil": "тамильска аꙁъбоукꙑ",
        "special-characters-group-telugu": "тєлоужьска аꙁъбоукꙑ",
-       "special-characters-group-sinhala": "синхальска аꙁъбоукꙑ"
+       "special-characters-group-sinhala": "синхальска аꙁъбоукꙑ",
+       "special-characters-group-gujarati": "гоуджаратьска аꙁъбоукꙑ",
+       "special-characters-group-devanagari": "дєванагари",
+       "special-characters-group-thai": "таиска аꙁъбоукꙑ",
+       "special-characters-group-lao": "лаосьска аꙁъбоукꙑ",
+       "special-characters-group-khmer": "къмєрьска аꙁъбоукꙑ",
+       "mw-widgets-titleinput-description-new-page": "страницѧ ю нѣстъ",
+       "mw-widgets-titleinput-description-redirect": "прѣнаправлѥниѥ къ ⁖ $1 ⁖"
 }
index ade3f30..17aa7bd 100644 (file)
        "passwordreset-emailtext-ip": "Nogen (sandsynligvis dig, fra IP-adressen $1) har anmodet om at få nulstillet din adgangskode til {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brugerkonto er associeret|De følgende brugerkonti er associerede}} med denne e-mailadresse:\n\n$2\n\n{{PLURAL:$3|Denne midlertidige adgangskode|Disse midlertidige adgangskoder}} vil udløbe om {{PLURAL:$5|en dag|$5 dage}}.\nDu bør logge på og vælge en ny adgangskode nu. Hvis en anden end dig har lavet denne anmodning, eller hvis du er kommet i tanke om din oprindelig adgangskode og ikke længere ønsker at ændre den, kan du ignorere denne meddelelse og fortsætte med at bruge din gamle adgangskode.",
        "passwordreset-emailtext-user": "Brugeren $1 på {{SITENAME}} har anmodet om at få nulstillet din adgangskode til {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brugerkonto er associeret|De følgende brugerkonti er associerede}} med denne e-mailadresse:\n\n$2\n\n{{PLURAL:$3|Denne midlertidige adgangskode|Disse midlertidige adgangskoder}} vil udløbe om {{PLURAL:$5|en dag|$5 dage}}.\nDu bør logge på og vælge en ny adgangskode nu. Hvis en anden end dig har lavet denne anmodning, eller hvis du er kommet i tanke om din oprindelig adgangskode og ikke længere ønsker at ændre den, kan du ignorere denne meddelelse og fortsætte med at bruge din gamle adgangskode.",
        "passwordreset-emailelement": "Brugernavn: \n$1\n\nMidlertidig adgangskode: \n$2",
-       "passwordreset-emailsentemail": "Hvis dettte er en registreret e-mail-adresse til din konto, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
+       "passwordreset-emailsentemail": "Hvis denne e-mailadresse er knyttet til din konto, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
+       "passwordreset-emailsentusername": "Hvis der er en e-mailadresse forbundet med dette brugernavn, så vil en e-mail om nulstilling af adgangskoden blive sendt.",
        "passwordreset-emailsent-capture": "En e-mail om nulstilling af adgangskode, som vist nedenfor, er blevet sendt.",
        "passwordreset-emailerror-capture": "En mail om nulstilling af adgangskode, som vist nedenfor, blev genereret, men det lykkedes ikke at sende den til {{GENDER:$2|bruger}}: $1",
        "changeemail": "Ændr eller fjern e-mailadresse",
        "rcshowhidemine": "$1 egne bidrag",
        "rcshowhidemine-show": "Vis",
        "rcshowhidemine-hide": "Skjul",
+       "rcshowhidecategorization": "$1 kategorisering af sider",
        "rcshowhidecategorization-show": "Vis",
        "rcshowhidecategorization-hide": "Skjul",
        "rclinks": "Vis seneste $1 ændringer i de sidste $2 dage<br />$3",
        "recentchangeslinked-summary": "Dette er en liste over de seneste ændringer af sider, der linkes til fra en bestemt side (eller medlemmer af en bestemt kategori).\nSider på [[Special:Watchlist|din overvågningsliste]] er vist med '''fed''' skrift.",
        "recentchangeslinked-page": "Sidenavn:",
        "recentchangeslinked-to": "Vis ændringer i sider der henviser til den angivne side i stedet",
+       "recentchanges-page-added-to-category": "[[:$1]] tilføjet til kategori",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] og {{PLURAL:$2|én side|$2 sider}} tilføjet til kategori",
        "upload": "Læg en fil op",
        "uploadbtn": "Læg en fil op",
        "reuploaddesc": "Tilbage til formularen til at lægge filer op.",
        "querypage-disabled": "Denne specialside er deaktiveret af hensyn til ydeevnen.",
        "apihelp": "API-hjælp",
        "apihelp-no-such-module": "Modul \"$1\" ikke fundet.",
+       "apisandbox": "API-sandkassen",
+       "apisandbox-api-disabled": "API er deaktiveret på dette websted.",
+       "apisandbox-intro": "Brug denne side til at eksperimentere med '''MediaWiki web service API'''.\nVi henviser til [//www.mediawiki.org/wiki/API:Main_page dokumentationen af API] for yderligere oplysninger om brug af API.  Eksempel: [//www.mediawiki.org/wiki/API#A_simple_example få indholdet af en forside]. Vælg en handling at se flere eksempler.\n\nBemærk, at selv om dette er en sandkasse, vil handlinger du udfører på denne side redigere wikien.",
+       "apisandbox-submit": "Lav forespørgsel",
+       "apisandbox-reset": "Ryd",
+       "apisandbox-examples": "Eksempel",
+       "apisandbox-results": "Resultat",
+       "apisandbox-request-url-label": "Forespurgt URL:",
+       "apisandbox-request-time": "Forespørgselstid: $1",
        "booksources": "Bogkilder",
        "booksources-search-legend": "Søgning efter bøger",
        "booksources-search": "Søg",
        "wlshowhideanons": "anonyme brugere",
        "wlshowhidepatr": "patruljerede redigeringer",
        "wlshowhidemine": "mine redigeringer",
+       "wlshowhidecategorization": "kategorisering af sider",
        "watchlist-options": "Indstillinger for overvågningslisten",
        "watching": "Tilføjer overvågning …",
        "unwatching": "Fjerner overvågning …",
index 36e8ab8..bbe7556 100644 (file)
@@ -85,7 +85,8 @@
                        "R4c0r",
                        "MGChecker",
                        "FriedhelmW",
-                       "Schniggendiller"
+                       "Schniggendiller",
+                       "Predatorix"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "search": "Suche",
        "searchbutton": "Suchen",
        "go": "Ausführen",
-       "searcharticle": "Seite",
+       "searcharticle": "Suchen",
        "history": "Versionen",
        "history_short": "Versionsgeschichte",
        "updatedmarker": "Änderung seit deinem letzten Besuch",
        "copyrightpage": "{{ns:project}}:Urheberrechte",
        "currentevents": "Aktuelle Ereignisse",
        "currentevents-url": "Project:Aktuelle Ereignisse",
-       "disclaimers": "Impressum",
+       "disclaimers": "Haftungsausschluss",
        "disclaimerpage": "Project:Impressum",
        "edithelp": "Bearbeitungshilfe",
        "helppage-top-gethelp": "Hilfe",
        "versionrequiredtext": "Version $1 von MediaWiki ist erforderlich, um diese Seite zu nutzen.\nSiehe die [[Special:Version|Versionsseite]]",
        "ok": "Okay",
        "pagetitle": "$1 – {{SITENAME}}",
-       "retrievedfrom": "Von „$1“",
+       "retrievedfrom": "Abgerufen von „$1“",
        "youhavenewmessages": "Du hast $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Du hast}} $1 von {{PLURAL:$3|einem anderen Benutzer|$3 Benutzern}} ($2).",
        "youhavenewmessagesmanyusers": "Du hast $1 von vielen Benutzern ($2).",
        "uploaded-script-svg": "Skriptelement „$1“ in der hochgeladenen SVG-Datei gefunden.",
        "uploaded-hostile-svg": "Unsicheres CSS im Styleelement der hochgeladenen SVG-Datei gefunden.",
        "uploaded-event-handler-on-svg": "Das Festlegen von Ereignis-Handler-Attributen <code>$1=\"$2\"</code> ist in SVG-Dateien nicht erlaubt.",
-       "uploaded-href-attribute-svg": "href-Attribute <code>&lt;$1 $2=\"$3\"&gt;</code> mit nicht-lokalem Ziel (z.&nbsp;B. http://, javascript: etc.) sind in SVG-Dateien nicht erlaubt.",
-       "uploaded-href-unsafe-target-svg": "href zu unsicherem Ziel <code>&lt;$1 $2=\"$3\"&gt;</code> in der hochgeladenen SVG-Datei gefunden.",
+       "uploaded-href-attribute-svg": "href-Attribute in SVG-Dateien sind nur als Verlinkung zu http://- oder https://-Zielen erlaubt. <code>&lt;$1 $2=\"$3\"&gt;</code> gefunden.",
+       "uploaded-href-unsafe-target-svg": "href zu unsicheren Daten gefunden: URI-Ziel <code>&lt;$1 $2=\"$3\"&gt;</code> in der hochgeladenen SVG-Datei.",
        "uploaded-animate-svg": "Tag „animate“ gefunden, das href mithilfe des Attributs „from“ <code>&lt;$1 $2=\"$3\"&gt;</code> in der hochgeladenen SVG-Datei ändern könnte.",
        "uploaded-setting-event-handler-svg": "Das Festlegen von Ereignis-Handler-Attributen ist gesperrt. <code>&lt;$1 $2=\"$3\"&gt;</code> in der hochgeladenen SVG-Datei gefunden.",
        "uploaded-setting-href-svg": "Die Verwendung des Tags „set“ zum Hinzufügen des Attributs „href“ zum übergeordneten Element ist gesperrt.",
        "querypage-disabled": "Diese Spezialseite wurde aus Gründen der Leistungserhaltung deaktiviert.",
        "apihelp": "API-Hilfe",
        "apihelp-no-such-module": "Modul „$1“ nicht gefunden.",
+       "apisandbox": "API-Spielwiese",
+       "apisandbox-jsonly": "Zur Nutzung der API-Spielwiese ist JavaScript erforderlich.",
+       "apisandbox-api-disabled": "Die API wurde auf diesem Wiki deaktiviert.",
+       "apisandbox-intro": "Diese Seite kannst du für Versuche mit der <strong>MediaWiki-API</strong> verwenden.\nDie [[mw:API:Main page|Dokumentation zur API]] enthält weitere Hinweise zu ihrer Nutzung. Beispiel: [//www.mediawiki.org/wiki/API:Main_page/de#Ein_einfaches_Beispiel Den Inhalt der Hauptseite abrufen]. Für weitere Beispiele eine der verfügbaren Aktionen auswählen.\n\nObwohl dies eine Spielwiese ist, bedenke, dass Aktionen, die du auf dieser Seite durchführst, das Wiki verändern.",
+       "apisandbox-fullscreen": "Panel expandieren",
+       "apisandbox-fullscreen-tooltip": "Expandiert das Spielwiesen-Panel, um das Browserfenster auszufüllen.",
+       "apisandbox-unfullscreen": "Seite anzeigen",
+       "apisandbox-unfullscreen-tooltip": "Reduziert das Spielwiesen-Panel, so dass MediaWiki-Navigationslinks verfügbar sind.",
+       "apisandbox-submit": "Anfrage ausführen",
+       "apisandbox-reset": "Leeren",
+       "apisandbox-retry": "Erneut versuchen",
+       "apisandbox-loading": "Lade Informationen für das API-Modul „$1“ …",
+       "apisandbox-load-error": "Beim Laden von Informationen für das API-Modul „$1“ ist ein Fehler aufgetreten: $2",
+       "apisandbox-no-parameters": "Dieses API-Modul hat keine Parameter.",
+       "apisandbox-helpurls": "Hilfe-Links",
+       "apisandbox-examples": "Beispiele",
+       "apisandbox-dynamic-parameters": "Zusätzliche Parameter",
+       "apisandbox-dynamic-parameters-add-label": "Parameter hinzufügen:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Name des Parameters",
+       "apisandbox-dynamic-error-exists": "Ein Parameter mit dem Namen „$1“ ist bereits vorhanden.",
+       "apisandbox-deprecated-parameters": "Veraltete Parameter",
+       "apisandbox-fetch-token": "Den Token automatisch ausfüllen",
+       "apisandbox-submit-invalid-fields-title": "Einige Felder sind ungültig",
+       "apisandbox-submit-invalid-fields-message": "Korrigiere bitte die markierten Felder und versuche es erneut.",
+       "apisandbox-results": "Ergebnisse",
+       "apisandbox-sending-request": "Sende API-Anfrage …",
+       "apisandbox-loading-results": "Rufe API-Ergebnisse ab …",
+       "apisandbox-results-error": "Beim Laden der API-Anfragenantwort ist ein Fehler aufgetreten: $1.",
+       "apisandbox-request-url-label": "Anforderungs-URL:",
+       "apisandbox-request-time": "Dauer der Anfrage: {{PLURAL:$1|Eine Millisekunde|$1 Millisekunden}}",
+       "apisandbox-results-fixtoken": "Token korrigieren und erneut übertragen",
+       "apisandbox-results-fixtoken-fail": "Der „$1“-Token konnte nicht abgerufen werden.",
+       "apisandbox-alert-page": "Felder auf dieser Seite sind nicht gültig.",
+       "apisandbox-alert-field": "Der Wert dieses Feldes ist nicht gültig.",
        "booksources": "ISBN-Suche",
        "booksources-search-legend": "Suche nach Bezugsquellen für Bücher",
        "booksources-search": "Suchen",
        "tooltip-ca-watch": "Diese Seite zur persönlichen Beobachtungsliste hinzufügen",
        "tooltip-ca-unwatch": "Diese Seite von der persönlichen Beobachtungsliste entfernen",
        "tooltip-search": "{{SITENAME}} durchsuchen",
-       "tooltip-search-go": "Gehe direkt zu der Seite, die exakt dem eingegebenen Namen entspricht.",
+       "tooltip-search-go": "Gehe direkt zu der Seite mit genau diesem Namen, falls sie vorhanden ist.",
        "tooltip-search-fulltext": "Suche nach Seiten, die diesen Text enthalten",
        "tooltip-p-logo": "Hauptseite",
        "tooltip-n-mainpage": "Hauptseite anzeigen",
        "pageinfo-robot-index": "Erlaubt",
        "pageinfo-robot-noindex": "Nicht erlaubt",
        "pageinfo-watchers": "Anzahl der Beobachter dieser Seite",
-       "pageinfo-visiting-watchers": "Anzahl der Seitenbeobachter, die die letzten Bearbeitungen besucht haben",
+       "pageinfo-visiting-watchers": "Anzahl der Beobachter dieser Seite, die die letzten Bearbeitungen besucht haben",
        "pageinfo-few-watchers": "Weniger als {{PLURAL:$1|ein|$1}} Beobachter",
        "pageinfo-few-visiting-watchers": "Es könnte einen beobachtenden Benutzer geben oder nicht, der die letzten Bearbeitungen besucht hat",
        "pageinfo-redirects-name": "Anzahl der Weiterleitungen zu dieser Seite",
        "version-hook-subscribedby": "Aufruf von",
        "version-version": "($1)",
        "version-no-ext-name": "[kein Name]",
-       "version-svn-revision": "(Version $2)",
        "version-license": "MediaWiki-Lizenz",
        "version-ext-license": "Lizenz",
        "version-ext-colheader-name": "Bezeichnung",
index b46381d..b3e71d0 100644 (file)
        "october-date": "Tışrino Verên $1",
        "november-date": "Tışrino Peyên $1",
        "december-date": "Kanun $1",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Kategoriye|Kategoriyi}}",
        "category_header": "Pelê ke kategoriya \"$1\" derê",
        "subcategories": "Kategoriyê bınêni",
        "searchprofile-advanced": "Raverşiyaye",
        "searchprofile-articles-tooltip": "$1 de cı geyré",
        "searchprofile-images-tooltip": "Dosya cı geyr",
-       "searchprofile-everything-tooltip": "Tedeestey hemine cı geyre (pelanê mınaqeşey zi tey)",
+       "searchprofile-everything-tooltip": "Tedeesteyan hemine cı geyre (pelanê mınaqeşeyi zi tey)",
        "searchprofile-advanced-tooltip": "qe cayê nimeyî bigêre",
        "search-result-size": "$1 ({{PLURAL:$2|1 çekuyo|$2 çekuyê}})",
        "search-result-category-size": "{{PLURAL:$1|1 eza|$1 ezayan}} ({{PLURAL:$2|1 kategoriyê bini|$2 kategirayanê binan}}, {{PLURAL:$3|1 dosya|$3 dosyayan}})",
        "querypage-disabled": "Na pelaya xısusi,sebeb de performansi ra qefılneyê.",
        "apihelp": "Peştiya APIyi",
        "apihelp-no-such-module": "Modulê \"$1\" çıniyo.",
+       "apisandbox": "API qumdor",
+       "apisandbox-submit": "Bıwazê",
+       "apisandbox-reset": "Bestere",
+       "apisandbox-examples": "Misal",
+       "apisandbox-results": "Netice",
+       "apisandbox-request-url-label": "URL waştış:",
+       "apisandbox-request-time": "Demê waştışi: $1",
        "booksources": "Çımeyê kıtaban",
        "booksources-search-legend": "Seba çımeyanê kıtaban cı geyre",
        "booksources-isbn": "ISBN:",
        "restriction-upload": "Bar ke",
        "restriction-level-sysop": "tam pawiyayo",
        "restriction-level-autoconfirmed": "nêm pawiyayo",
-       "restriction-level-all": "heme yew sewiya",
+       "restriction-level-all": "kamci be sewiya",
        "undelete": "Peleyê ke besterneyayê enê bımocnê",
        "undeletepage": "bıewn revizyonê peli yê hewn a şiyayeyan u tepiya biyar",
        "undeletepagetitle": "'''pelo [[:$1|$1]] cêrın, wayirê revizyonê hewn a şiyayeyan o'''.",
        "version-hook-name": "Nameyê çengelî",
        "version-hook-subscribedby": "Eza biyayoğ",
        "version-version": "($1)",
-       "version-svn-revision": "(r$2)",
        "version-license": "Lisansê MediaWiki",
        "version-ext-license": "Lisans",
        "version-ext-colheader-name": "Dergiye",
index 0ccd390..db67490 100644 (file)
        "uploaded-script-svg": "Βρέθηκε στοιχείο με δυνατότητα δημιουργίας δέσμης ενεργειών «$1» στο ανεβασμένο αρχείο SVG.",
        "uploaded-hostile-svg": "Βρέθηκε μη ασφαλές CSS στο στοιχείο στυλ του ανεβασμένου αρχείου SVG.",
        "uploaded-event-handler-on-svg": "Δεν επιτρέπεται ο ορισμός ιδιοτήτων χειρισμού συμβάντων <code>$1=\"$2\"</code> σε αρχεία SVG.",
-       "uploaded-href-attribute-svg": "Δεν επιτρέπονται οι ιδιότητες href <code>&lt;$1 $2=\"$3\"&gt;</code> με μη τοπικό προορισμό (π.χ. http://, javascript:, κ.τ.λ.) σε αρχεία SVG.",
        "uploaded-href-unsafe-target-svg": "Βρέθηκε href προς έναν μη ασφαλή προορισμό <code>&lt;$1 $2=\"$3\"&gt;</code> στο ανεβασμένο αρχείο SVG.",
        "uploaded-animate-svg": "Βρέθηκε μία ετικέτα <code>&lt;animate&gt;</code> που ίσως να αλλάζει το href, με την ιδιότητα \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> στο ανεβασμένο αρχείο SVG.",
        "uploaded-setting-event-handler-svg": "Η ρύθμιση ιδιοτήτων χειρισμού σφαλμάτων είναι αποκλεισμένη, βρέθηκε <code>&lt;$1 $2=\"$3\"&gt;</code> στο ανεβασμένο αρχείο SVG.",
        "querypage-disabled": "Αυτή η ειδική σελίδα είναι απενεργοποιημένη για λόγους απόδοσης.",
        "apihelp": "Βοήθεια API",
        "apihelp-no-such-module": "Το Module \"$1\" δεν βρέθηκε.",
+       "apisandbox": "Αμμοδοχείο API",
+       "apisandbox-api-disabled": "Η Διεπαφή Προγραμματισμού Εφαρμογών (API) είναι απενεργοποιημένη σε αυτήν την τοποθεσία.",
+       "apisandbox-intro": "Χρησιμοποιήστε αυτήν τη σελίδα για να πειραματιστείτε με το '''API της υπηρεσίας ιστού του MediaWiki'''.\nΑνατρέξτε στην [//www.mediawiki.org/wiki/API:Main_page τεκμηρίωση του API] για περισσότερες πληροφορίες πάνω στη χρήση του API. Παράδειγμα: [//www.mediawiki.org/wiki/API#A_simple_example λήψη του περιεχομένου της Αρχικής Σελίδας]. Επιλέξτε μια ενέργεια για να δείτε περισσότερα παραδείγματα.\n\nΝα σημειωθεί ότι, παρόλο που αυτό εδώ είναι αμμοδοχείο, οι ενέργειες που εκτελείτε σε αυτήν τη σελίδα μπορούν να τροποποιήσουν το wiki.",
+       "apisandbox-submit": "Υποβολή του αιτήματος",
+       "apisandbox-reset": "Εκκαθάριση",
+       "apisandbox-examples": "Παράδειγμα",
+       "apisandbox-results": "Αποτέλεσμα",
+       "apisandbox-request-url-label": "Αίτηση URL:",
+       "apisandbox-request-time": "Χρόνος αιτήματος: $1",
        "booksources": "Πηγές βιβλίων",
        "booksources-search-legend": "Αναζήτηση για πηγές βιβλίων",
        "booksources-isbn": "ISBN:",
index 639af0f..2e1df41 100644 (file)
        "uploaded-script-svg": "Found scriptable element \"$1\" in the uploaded SVG file.",
        "uploaded-hostile-svg": "Found unsafe CSS in the style element of uploaded SVG file.",
        "uploaded-event-handler-on-svg": "Setting event-handler attributes <code>$1=\"$2\"</code> is not allowed in SVG files.",
-       "uploaded-href-attribute-svg": "href attributes <code>&lt;$1 $2=\"$3\"&gt;</code> with non-local target (e.g. http://, javascript:, etc) are not allowed in SVG files.",
-       "uploaded-href-unsafe-target-svg": "Found href to unsafe target <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
+       "uploaded-href-attribute-svg": "href attributes in SVG files are only allowed to link to http:// or https:// targets, found <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Found href to unsafe data: URI target <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "uploaded-animate-svg": "Found \"animate\" tag that might be changing href, using the \"from\" attribute <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "uploaded-setting-event-handler-svg": "Setting event-handler attributes is blocked, found <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "uploaded-setting-href-svg": "Using the \"set\" tag to add \"href\" attribute to parent element is blocked.",
        "apihelp-summary": "",
        "apihelp-no-such-module": "Module \"$1\" not found.",
        "apihelp-link": "[[Special:ApiHelp/$1|$2]]",
+       "apisandbox": "API sandbox",
+       "apisandbox-summary": "",
+       "apisandbox-jsonly": "JavaScript is required to use the API sandbox.",
+       "apisandbox-api-disabled": "The API is disabled on this site.",
+       "apisandbox-intro": "Use this page to experiment with the <strong>MediaWiki web service API</strong>.\nRefer to [[mw:API:Main page|the API documentation]] for further details of API usage. Example: [//www.mediawiki.org/wiki/API#A_simple_example get the content of a Main Page]. Select an action to see more examples.\n\nNote that, although this is a sandbox, actions you carry out on this page may modify the wiki.",
+       "apisandbox-fullscreen": "Expand panel",
+       "apisandbox-fullscreen-tooltip": "Expand the sandbox panel to fill the browser window.",
+       "apisandbox-unfullscreen": "Show page",
+       "apisandbox-unfullscreen-tooltip": "Reduce the sandbox panel, so MediaWiki navigation links are available.",
+       "apisandbox-submit": "Make request",
+       "apisandbox-reset": "Clear",
+       "apisandbox-retry": "Retry",
+       "apisandbox-loading": "Loading information for API module \"$1\"...",
+       "apisandbox-load-error": "An error occurred while loading information for API module \"$1\": $2",
+       "apisandbox-no-parameters": "This API module has no parameters.",
+       "apisandbox-helpurls": "Help links",
+       "apisandbox-examples": "Examples",
+       "apisandbox-dynamic-parameters": "Additional parameters",
+       "apisandbox-dynamic-parameters-add-label": "Add parameter:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Parameter name",
+       "apisandbox-dynamic-error-exists": "A parameter named \"$1\" already exists.",
+       "apisandbox-deprecated-parameters": "Deprecated parameters",
+       "apisandbox-fetch-token": "Auto-fill the token",
+       "apisandbox-submit-invalid-fields-title": "Some fields are invalid",
+       "apisandbox-submit-invalid-fields-message": "Please correct the marked fields and try again.",
+       "apisandbox-results": "Results",
+       "apisandbox-sending-request": "Sending API request...",
+       "apisandbox-loading-results": "Receiving API results...",
+       "apisandbox-results-error": "An error occurred while loading the API query response: $1.",
+       "apisandbox-request-url-label": "Request URL:",
+       "apisandbox-request-time": "Request time: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Correct token and resubmit",
+       "apisandbox-results-fixtoken-fail": "Failed to fetch \"$1\" token.",
+       "apisandbox-alert-page": "Fields on this page are not valid.",
+       "apisandbox-alert-field": "The value of this field is not valid.",
        "booksources": "Book sources",
        "booksources-summary": "",
        "booksources-search-legend": "Search for book sources",
        "version-hook-subscribedby": "Subscribed by",
        "version-version": "($1)",
        "version-no-ext-name": "[no name]",
-       "version-svn-revision": "r$1",
        "version-license": "MediaWiki License",
        "version-ext-license": "License",
        "version-ext-colheader-name": "Extension",
index 9abcabe..f214c12 100644 (file)
        "expensive-parserfunction-warning": "Averto: Ĉi tiu paĝo enhavas tro da multekostaj sintaksaj funkcio-vokoj.\n\nĜi havu malpli ol $2 {{PLURAL:$2|vokon|vokojn}}, sed nun estas $1 {{PLURAL:$1|voko|vokoj}}.",
        "expensive-parserfunction-category": "Paĝoj kun tro da multekostaj sintaksaj funkcio-vokoj",
        "post-expand-template-inclusion-warning": "Averto: Inkluziva pezo de ŝablonoj estas tro granda.\nIuj ŝablonoj ne estos inkluzivitaj.",
-       "post-expand-template-inclusion-category": "Paĝoj kie inkluziva pezo de ŝablonoj estas tro granda.",
+       "post-expand-template-inclusion-category": "Paĝoj kie inkluziva pezo de ŝablonoj estas tro granda",
        "post-expand-template-argument-warning": "Averto: Ĉi tiu paĝo enhavas almenaŭ unu ŝablonan argumenton, kiu havas tro grandan etendan pezon.\nĈi tiuj argumentoj estis forlasitaj.",
        "post-expand-template-argument-category": "Paĝoj enhavantaj forlasitajn argumentojn de ŝablonoj",
        "parser-template-loop-warning": "Rekursiva ŝablono estis trovita: [[$1]]",
        "querypage-disabled": "Tiu ĉi speciala paĝo estas malfunkciigita pro rendimentaj kialoj.",
        "apihelp": "Helpo pri API",
        "apihelp-no-such-module": "Modulo \"$1\" ne estis trovita.",
+       "apisandbox": "API testejo",
+       "apisandbox-api-disabled": "API estas malŝalta en ĉi tiu retejo.",
+       "apisandbox-intro": "Uzu tiun ĉi paĝon por eksperimenti kun '''MediaWiki API'''.\nVidu [//www.mediawiki.org/wiki/API:Main_page la API-dokumentadon] por pli da detaloj pri la uzo de API. Ekz-e: [//www.mediawiki.org/wiki/API#A_simple_example atingi la enhavon de la Ĉefpaĝo]. Elektu agon por vidi pliajn ekzemplojn.\n\nNotu ke, kvankam ĉi tiu estas provejo, agoj kiun vi faros en ĉi tiu paĝo povas modifi la vikion.",
+       "apisandbox-submit": "Fari mendon",
+       "apisandbox-reset": "Nuligi",
+       "apisandbox-examples": "Ekzemplo",
+       "apisandbox-results": "Rezulto",
+       "apisandbox-request-url-label": "Mendi URL-on.",
+       "apisandbox-request-time": "Tempo de peto: $1",
        "booksources": "Libroservoj",
        "booksources-search-legend": "Serĉi librofontojn",
        "booksources-search": "Serĉi",
        "javascripttest-pagetext-frameworks": "Bonvolu elekti unu el la jenaj test-framoj: $1",
        "javascripttest-pagetext-skins": "Elektu kun kio etoso irigi la testojn:",
        "javascripttest-qunit-intro": "Vidu [$1 testa dokumentaro] en mediawiki.org.",
-       "tooltip-pt-userpage": "Via uzantopaĝo",
+       "tooltip-pt-userpage": "Via uzantpaĝo",
        "tooltip-pt-anonuserpage": "La uzantopaĝo por la IP adreso sub kiu vi estas redaktanta",
        "tooltip-pt-mytalk": "Via diskutpaĝo",
        "tooltip-pt-anontalk": "Diskuto pri redaktoj sub tiu ĉi IP adreso",
-       "tooltip-pt-preferences": "Miaj preferoj",
+       "tooltip-pt-preferences": "{{GENDER:|Viaj}} preferoj",
        "tooltip-pt-watchlist": "Listo de paĝoj kies ŝanĝojn vi priatentas.",
        "tooltip-pt-mycontris": "Listo de viaj kontribuoj",
        "tooltip-pt-login": "Vi estas invitita ensaluti, tamen ne estas devige.",
        "tooltip-ca-move": "Alinomigi tiun ĉi paĝon",
        "tooltip-ca-watch": "Aldoni tiun ĉi paĝon al via atentaro",
        "tooltip-ca-unwatch": "Forigi tiun ĉi paĝon el via atentaro",
-       "tooltip-search": "Traserĉi {{SITENAME}}n",
+       "tooltip-search": "Serĉi tra {{SITENAME}}",
        "tooltip-search-go": "Iru al paĝo kun ĉi preciza nomo se ĝi ekzistas",
        "tooltip-search-fulltext": "Serĉi la paĝojn por ĉi tiu teksto",
        "tooltip-p-logo": "Ĉefpaĝo",
        "tooltip-t-recentchangeslinked": "Lastaj ŝanĝoj en paĝoj kiuj ligas al tiu ĉi paĝo",
        "tooltip-feed-rss": "RSS-fonto por tiu ĉi paĝo",
        "tooltip-feed-atom": "Atom-fonto por ĉi tiu paĝo",
-       "tooltip-t-contributions": "Rigardi la liston de kontribuoj de tiu ĉi uzanto",
+       "tooltip-t-contributions": "Listo de kontribuoj de {{GENDER:$1|ĉi tiu uzanto}}",
        "tooltip-t-emailuser": "Sendi retmesaĝon al tiu ĉi uzanto",
        "tooltip-t-info": "Pli da informo pri ĉi tiu paĝo",
        "tooltip-t-upload": "Alŝuti bildojn aŭ dosierojn",
index 681dd67..494033b 100644 (file)
                        "Syum90",
                        "Cindie.Capel",
                        "ElGatoSaez",
-                       "Joaquin1001"
+                       "Joaquin1001",
+                       "YoViajo"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "uploaded-script-svg": "Se encontró el elemento habilitado para secuencias de órdenes «$1» en el archivo SVG cargado.",
        "uploaded-hostile-svg": "Se encontró código CSS no seguro en el elemento de estilo del archivo SVG cargado.",
        "uploaded-event-handler-on-svg": "No está permitido configurar atributos controladores de eventos <code>$1=\"$2\"</code> en los archivos SVG.",
-       "uploaded-href-attribute-svg": "No se permite que los archivos SVG contengan los atributos de «href» <code>&lt;$1 $2=\"$3\"&gt;</code> apuntando a recursos no locales (p. ej., http:// o javascript:).",
        "uploaded-href-unsafe-target-svg": "Se encontró un \"href\" hacia un destino inseguro <code><$1 $2=\"$3\"></code> en el archivo SVG cargado.",
        "uploaded-animate-svg": "Se encontró un etiqueta \"animate\" que puede estar cambiando \"href\", mediante el atributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> en el archivo SVG cargado.",
        "uploaded-setting-event-handler-svg": "Está bloqueada la configuración de atributos controladores de eventos. Se encontró <code>&lt;$1 $2=\"$3\"&gt;</code> en el archivo SVG cargado.",
        "querypage-disabled": "Esta página especial está deshabilitada por motivos de rendimiento.",
        "apihelp": "Ayuda de la API",
        "apihelp-no-such-module": "No se encontró el módulo \"$1\".",
+       "apisandbox": "Zona de pruebas API",
+       "apisandbox-api-disabled": "La API está desactivada en este sitio.",
+       "apisandbox-intro": "Usa esta página para experimentar con la '''API de servicio web de MediaWiki'''.\nPara más detalles sobre el uso de la API, visita [//www.mediawiki.org/wiki/API:Main_page su documentación]. Ejemplo: [//www.mediawiki.org/wiki/API#A_simple_example obtener el contenido de una Página principal]. Selecciona una acción para ver más ejemplos.\n\nObserva que, aunque sea una página de pruebas, las acciones que realices en esta página pueden modificar el wiki.",
+       "apisandbox-fullscreen": "Expandir panel",
+       "apisandbox-unfullscreen": "Mostrar página",
+       "apisandbox-submit": "Realizar solicitud",
+       "apisandbox-reset": "Limpiar",
+       "apisandbox-retry": "Reintentar",
+       "apisandbox-no-parameters": "Este módulo API no tiene parámetros.",
+       "apisandbox-helpurls": "Enlaces de ayuda",
+       "apisandbox-examples": "Ejemplo",
+       "apisandbox-dynamic-parameters": "Parámetros adicionales",
+       "apisandbox-dynamic-parameters-add-label": "Añadir parámetro:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nombre del parámetro",
+       "apisandbox-deprecated-parameters": "Parámetros obsoletos",
+       "apisandbox-submit-invalid-fields-title": "Algunos campos no son válidos",
+       "apisandbox-results": "Resultados",
+       "apisandbox-sending-request": "Enviando pedido API...",
+       "apisandbox-request-url-label": "URL solicitante:",
+       "apisandbox-request-time": "Tiempo de solicitud: $1",
        "booksources": "Fuentes de libros",
        "booksources-search-legend": "Buscar fuentes de libros",
        "booksources-search": "Buscar",
        "listgrouprights-namespaceprotection-header": "Restricciones del espacio de nombres",
        "listgrouprights-namespaceprotection-namespace": "Espacio de nombres",
        "listgrouprights-namespaceprotection-restrictedto": "Derechos de usuario para editar",
+       "listgrants": "Subvenciones",
        "listgrants-grant": "Conceder",
        "listgrants-rights": "Conceder",
        "trackingcategories": "Categorías de seguimiento",
index c4057a3..c1a0fcc 100644 (file)
        "uploaded-script-svg": "Üleslaaditud SVG-failist leiti skriptitav element \"$1\".",
        "uploaded-hostile-svg": "Üleslaaditud SVG-faili laadielemendist leiti ebaturvaline CSS.",
        "uploaded-event-handler-on-svg": "Sündmuse halduse atribuutide <code>$1=\"$2\"</code> seadmine pole SVG-failis lubatud.",
-       "uploaded-href-attribute-svg": "Mittekohaliku sihtkohaga (nt http://, javascript:) href-atribuudid <code>&lt;$1 $2=\"$3\"&gt;</code> pole SVG-failides lubatud.",
        "uploaded-href-unsafe-target-svg": "Üleslaaditud SVG-failist leiti href, mille sihtkoht <code>&lt;$1 $2=\"$3\"&gt;</code> on ebaturvaline.",
        "uploaded-animate-svg": "Üleslaaditud SVG-failist leiti silt \"animate\", mis võib href-i muuta, kasutades from-atribuuti <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Sündmuse halduse atribuutide seadmine on keelatud, üleslaaditud SVG-failist leiti <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "filename-thumb-name": "Tundub, et tegu on pisipildi pealkirjaga. Palun ära laadi pisipilti samas vikis uuesti üles. Või siis paranda palun failinimi, nii et see oleks sisukam ja ei sisaldaks pisipildi eesliidet.",
        "filename-bad-prefix": "Üleslaaditava faili nimi algab eesliitega '''\"$1\"''', mis on omane digikaamera antud ebamäärastele nimedele.\nPalun vali oma failile kirjeldavam nimi.",
        "filename-prefix-blacklist": " #<!-- jäta see rida muutmata --> <pre>\n# Süntaks on järgmine:\n#   * Kõik alates märgist \"#\" kuni rea lõpuni on kommentaar.\n#   * Iga mittetühi rida on tüüpiline eesliide, mille digikaamerad automaatselt failinimele lisavad.\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # mõned mobiiltelefonid\nIMG # üldine\nJD # Jenoptik\nMGP # Pentax\nPICT # erinevad\n #</pre> <!-- jäta see rida muutmata -->",
-       "upload-success-subj": "Üleslaadimine õnnestus",
-       "upload-success-msg": "Üleslaadimine allikast [$2] läks edukalt. See on leitav siit: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Üleslaadimisprobleem",
-       "upload-failure-msg": "Üleslaadimisel allikast [$2] ilmnes probleem:\n\n$1",
-       "upload-warning-subj": "Üleslaadimishoiatus",
-       "upload-warning-msg": "Üleslaadimisel allikast [$2] tekkis probleem. Probleemi eemaldamiseks võid naasta [[Special:Upload/stash/$1|üleslaadimisvormi]] juurde.",
        "upload-proto-error": "Vigane protokoll",
        "upload-proto-error-text": "Teiselt saidilt üleslaadimiseks peab URL algama <code>http://</code> või <code>ftp://</code>.",
        "upload-file-error": "Sisemine viga",
        "querypage-disabled": "See erilehekülg on keelatud, et jõudlust hoida.",
        "apihelp": "API abi",
        "apihelp-no-such-module": "Moodulit \"$1\" ei leitud.",
+       "apisandbox": "API liivakast",
+       "apisandbox-api-disabled": "API on selles võrgukohas keelatud.",
+       "apisandbox-intro": "Kasuta seda lehekülge '''MediaWiki API''' katsetamiseks.\nÜksikasjad API kasutamise kohta leiad [//www.mediawiki.org/wiki/API:Main_page API dokumentatsioonist]. Näide: [//www.mediawiki.org/wiki/API#A_simple_example esilehe sisu hankimine]. Vali toiming, et näha veel näiteid.\n\nPane tähele, et kuigi siin on liivakast, võivad siin leheküljel tehtud toimingud vikit muuta.",
+       "apisandbox-submit": "Tee päring",
+       "apisandbox-reset": "Puhasta",
+       "apisandbox-examples": "Näide",
+       "apisandbox-results": "Tulemus",
+       "apisandbox-request-url-label": "Päringu URL:",
+       "apisandbox-request-time": "Päringuaeg: $1",
        "booksources": "Raamatuotsimine",
        "booksources-search-legend": "Raamatuotsimine",
        "booksources-search": "Otsi",
        "wlheader-showupdated": "Leheküljed, mida on muudetud peale sinu viimast külastust, on '''rasvases kirjas'''.",
        "wlnote": "Allpool on {{PLURAL:$1|viimane muudatus|viimased <strong>$1</strong> muudatust}} viimase {{PLURAL:$2|tunni|<strong>$2</strong> tunni}} jooksul seisuga $3, kell $4.",
        "wlshowlast": "Näita viimast $1 tundi $2 päeva.",
-       "watchlistall2": "kõike",
        "watchlist-hide": "Peida",
        "watchlist-submit": "Näita",
        "wlshowtime": "Näita viimast:",
index 0071de3..0c3bbe5 100644 (file)
        "resetpass_submit": "Pasahitza definitu eta saioa hasi",
        "changepassword-success": "Zure pasahitza ondo aldatu da!",
        "changepassword-throttled": "Saioa hasteko saiakera gehiegi egin berri dituzu.\nBerriro saiatu aurretik $1 itxoin, mesedez.",
-       "botpasswords-label-create": "Sortu",
-       "botpasswords-label-update": "Eguneratu",
-       "botpasswords-label-delete": "Ezabatu",
        "resetpass_forbidden": "Ezin dira pasahitzak aldatu",
        "resetpass-no-info": "Orrialde honetara zuzenean sartzeko izena eman behar duzu.",
        "resetpass-submit-loggedin": "Pasahitza aldatu",
index 645dca9..bc6a861 100644 (file)
        "uploaded-script-svg": "عنصر قابل برنامه‌ریزی «$1» در پرونده بارگذاری اس‌وی‌جی یافت شد.",
        "uploaded-hostile-svg": "سی‌اس‌اس نا امن در عنصر سبک پروندهٔ بارگذاری شدهٔ اس‌وی‌جی یافت شد.",
        "uploaded-event-handler-on-svg": "قرار دادن ویژگی‌های مدیریت رویداد <code>$1=\"$2\"</code> در پرونده‌های اس‌وی‌جی مجاز نیست.",
-       "uploaded-href-attribute-svg": "ویژگی‌های href <code>&lt;$1 $2=\"$3\"&gt;</code> با هدف غیر محلی (برای نمونه، http://, javascript:, etc) در پرونده‌های اس‌وی‌جی مجاز نیست.",
-       "uploaded-href-unsafe-target-svg": "در Ù¾Ø±Ù\88Ù\86دÙ\87 SVG Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±Û\8câ\80\8cشدÙ\87 Ø¨Ø±Ø§Û\8c Ù\87دÙ\81 Ù\86ادرست <code>&lt;$1 $2=\"$3\"&gt;</code> Ø¨Ø±Ú\86سب href یافت شد.",
+       "uploaded-href-attribute-svg": "ویژگی‌های href در پرونده‌های SVG فقط برای اهدافhttp:// &lrm; وhttps:// &lrm; مجاز هستند، <code>&lt;$1 $2=\"$3\"&gt;</code> یافت شد.",
+       "uploaded-href-unsafe-target-svg": "در Ù¾Ø±Ù\88Ù\86دÙ\87 SVG Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±Û\8câ\80\8cشدÙ\87 Ø¨Ø±Ø§Û\8c Ù\86شاÙ\86Û\8c Ù\87دÙ\81 <code>&lt;$1 $2=\"$3\"&gt;</code> Ø¨Ø±Ú\86سب href Ø¨Ù\87 Ø§Ø·Ù\84اعات Ù\86ااÙ\85Ù\86 یافت شد.",
        "uploaded-animate-svg": "برچسب  \"animate\" یافت شده ممکن است herf را تغییر دهد. از مشخصه \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> در پرونده SVG بارگذاری‌شده استفاده کنید.",
        "uploaded-setting-event-handler-svg": "تنظیمات مشخصه گرداننده رویداد بسته شده‌است. کد <code>&lt;$1 $2=\"$3\"&gt;</code>  در پرونده بارگذاری‌شده یافت شد.",
        "uploaded-setting-href-svg": "استفاده از برچسب \"set\" برای افزودن مشخصهٔ \"href\" به عنصر والد بسته شده",
        "querypage-disabled": "این صفحه ویژه به دلایل عملکردی غیرفعال شده‌است.",
        "apihelp": "راهنمای API",
        "apihelp-no-such-module": "پودمان \" $1 \" یافت نشد.",
+       "apisandbox": "گودال ماسه‌بازی رابط برنامه‌نویسی",
+       "apisandbox-api-disabled": "رابط برنامه‌نویسی در این تارنما غیرفعال شده‌است.",
+       "apisandbox-intro": "از این صفحه برای آزمایش <strong>خدمات وب API مدیاویکی</strong> استفاده کنید.\nبرای جزئیات بیشتر دربارهٔ نحوهٔ استفاده از API به [[mw:API:Main page|مستندات API]] رجوع کنید. مثال: [//www.mediawiki.org/wiki/API#A_simple_example دریافت محتوای صفحهٔ اصلی]. برای دیدن مثال‌های بیشتر عملکردی را انتخاب کنید.",
+       "apisandbox-fullscreen": "گسترش پنل",
+       "apisandbox-unfullscreen": "نمایش صفحه",
+       "apisandbox-submit": "ایجاد درخواست",
+       "apisandbox-reset": "پاک‌کردن",
+       "apisandbox-retry": "تلاش مجدد",
+       "apisandbox-helpurls": "پیوندهای راهنمایی",
+       "apisandbox-examples": "مثال‌ها",
+       "apisandbox-dynamic-parameters": "پارامترهای بیشتر",
+       "apisandbox-dynamic-parameters-add-label": "افزودن پارامتر:",
+       "apisandbox-dynamic-parameters-add-placeholder": "نام پارامتر",
+       "apisandbox-results": "نتیجه‌ها",
+       "apisandbox-sending-request": "ارسال درخواست ای‌پی‌آی...",
+       "apisandbox-loading-results": "دریافت درخواست‌های ای‌پی‌آی...",
+       "apisandbox-request-url-label": "درخواست آدرس:",
+       "apisandbox-request-time": "زمان درخواست: {{PLURAL:$1|$1 ms}}",
        "booksources": "منابع کتاب",
        "booksources-search-legend": "جستجوی منابع کتاب",
        "booksources-isbn": "شابک:",
        "lockedbyandtime": "(به وسیلهٔ $1 در $2 ساعت $3)",
        "move-page": "انتقال $1",
        "move-page-legend": "انتقال صفحه",
-       "movepagetext": "با استفاده از فرم زیر نام صفحه تغییر خواهد کرد، و تمام تاریخچه‌اش به نام جدید منتقل خواهد شد.\nعنوان قدیمی تبدیل به یک صفحهٔ تغییرمسیر به عنوان جدید خواهد شد.\nشما می‌توانید تغییرمسیرهایی که به عنوان اصلی اشاره دارند را به صورت خودکار به‌روزرسانی کنید.\nپیوندهای که به عنوان صفحهٔ قدیمی وجود دارند، تغییر نخواهند کرد؛ حتماً تغییرمسیرهای [[Special:DoubleRedirects|دوتایی]] یا [[Special:BrokenRedirects|خراب]] را بررسی کنید.\n'''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.\n\nتوجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،\nمگر این آخرین ویرایش تغییرمسیر باشد و در  تاریخچهٔ ویرایشی نداشته باشد.\nاین یعنی اگر اشتباه کردید می‌توانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمی‌توانید روی صفحات موجود بنویسید.\n\n'''هشدار!'''\nانتقال صفحات به نام جدید ممکن است تغییر اساسی و غیرمنتظره‌ای برای صفحات محبوب باشد؛\nلطفاً مطمئن شوید که قبل از انتقال دادن صفحه، عواقب این کار را درک می‌کنید.",
-       "movepagetext-noredirectfixer": "استفاده از فرم زیر سبب تغییر نام یک صفحه و انتقال تمام تاریخچهٔ آن به نام جدید می‌شود.\nعنوان پیشین تغییرمسیری به عنوان جدید خواهد شد.\nبه خاطر داشته باشید که [[Special:DoubleRedirects|تغییرمسیرهای دوتایی]] یا [[Special:BrokenRedirects|تغییرمسیرهای خراب]] را بررسی کنید.\nشما مسئولید که مطمئن شوید پس از انتقال، پیوندها به عنوان پیشین به جایی منتهی می‌شوند که باید.\n\nتوجه کنید که اگر صفحه‌ای تحت عنوان جدید از قبل موجود باشد، انتقال انجام '''نخواهد شد'''، مگر اینکه صفحه خالی و یا تغییرمسیر باشد و تاریخچهٔ ویرایشی دیگری نداشته باشد.\nاین یعنی اگر صفحه را به نامی اشتباه منتقل کردید می‌توانید این تغییر را واگردانی کنید، اما نمی‌توانید یک صفحه را به صفحه‌ای که از قبل موجود است انتقال دهید.\n\n'''هشدار!'''\nانتقال صفحه‌های پربیننده ممکن است عملی غیرمنتظره باشد؛\nلطفاً پیش از انتقال مطمئن شوید از نتیجهٔ کار آگاهید.",
+       "movepagetext": "با استفاده از فرم زیر نام صفحه تغییر خواهد کرد، و تمام تاریخچه‌اش به نام جدید منتقل خواهد شد.\nعنوان قدیمی تبدیل به یک صفحهٔ تغییرمسیر به عنوان جدید خواهد شد.\nشما می‌توانید تغییرمسیرهایی که به عنوان اصلی اشاره دارند را به صورت خودکار به‌روزرسانی کنید.\nپیوندهای که به عنوان صفحهٔ قدیمی وجود دارند، تغییر نخواهند کرد؛ حتماً تغییرمسیرهای [[Special:DoubleRedirects|دوتایی]] یا [[Special:BrokenRedirects|خراب]] را بررسی کنید.\n'''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.\n\nتوجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،\nمگر این آخرین ویرایش تغییرمسیر باشد و در  تاریخچهٔ ویرایشی نداشته باشد.\nاین یعنی اگر اشتباه کردید می‌توانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمی‌توانید روی صفحات موجود بنویسید.\n\n<strong>توضیح:</strong>\nانتقال صفحات به نام جدید ممکن است تغییر اساسی و غیرمنتظره‌ای برای صفحات محبوب باشد؛\nلطفاً مطمئن شوید که قبل از انتقال دادن صفحه، عواقب این کار را درک می‌کنید.",
+       "movepagetext-noredirectfixer": "استفاده از فرم زیر سبب تغییر نام یک صفحه و انتقال تمام تاریخچهٔ آن به نام جدید می‌شود.\nعنوان پیشین تغییرمسیری به عنوان جدید خواهد شد.\nبه خاطر داشته باشید که [[Special:DoubleRedirects|تغییرمسیرهای دوتایی]] یا [[Special:BrokenRedirects|تغییرمسیرهای خراب]] را بررسی کنید.\nشما مسئولید که مطمئن شوید پس از انتقال، پیوندها به عنوان پیشین به جایی منتهی می‌شوند که باید.\n\nتوجه کنید که اگر صفحه‌ای تحت عنوان جدید از قبل موجود باشد، انتقال انجام '''نخواهد شد'''، مگر اینکه صفحه خالی و یا تغییرمسیر باشد و تاریخچهٔ ویرایشی دیگری نداشته باشد.\nاین یعنی اگر صفحه را به نامی اشتباه منتقل کردید می‌توانید این تغییر را واگردانی کنید، اما نمی‌توانید یک صفحه را به صفحه‌ای که از قبل موجود است انتقال دهید.\n\n<strong>توضیح:</strong>\nانتقال صفحه‌های پربیننده ممکن است عملی غیرمنتظره باشد؛\nلطفاً پیش از انتقال مطمئن شوید از نتیجهٔ کار آگاهید.",
        "movepagetalktext": "اگر این گزینه را انتخاب کنید، صفحهٔ بحث مرتبط به صورت خودکار انتقال داده می‌شود به عنوان جدید و در صورت عدم انتخاب گزینه، صفحهٔ بحث جدید یک صفحهٔ خالی خواهد بود و در این حالت، باید صفحه را بطور دستی انتقال داده و یا محتویات دو صفحه را با ویرایش ادغام کنید.",
        "moveuserpage-warning": "'''هشدار:''' شما در حال انتقال دادن یک صفحهٔ کاربر هستید. توجه داشته باشید که تنها صفحه منتقل می‌شود و نام کاربر تغییر '''نمی‌یابد'''.",
        "movecategorypage-warning": "<strong>هشدار:</strong> شما در حال انتقال صفحه رده هستید. لطفاً توجه داشته باشید که فقط صفحه منتقل خواهد شد و  صفحات در رده قدیمی می‌مانند و به رده جدید <em>نمی‌روند</em>.",
        "movenosubpage": "این صفحه هیچ زیرصفحه‌ای ندارد.",
        "movereason": "دلیل:",
        "revertmove": "واگردانی",
-       "delete_and_move_text": "== نیاز به حذف ==\n\nمقالهٔ مقصد «[[:$1]]» وجود دارد. آیا می‌خواهید آن را حذف کنید تا انتقال ممکن شود؟",
+       "delete_and_move_text": "مقالهٔ مقصد «[[:$1]]» وجود دارد. آیا می‌خواهید آن را حذف کنید تا انتقال ممکن شود؟",
        "delete_and_move_confirm": "بله، صفحه حذف شود",
        "delete_and_move_reason": "حذف برای ممکن‌شدن انتقال  «[[$1]]»",
        "selfmove": "عنوان‌های صفحهٔ مبدأ و مقصد یکی است؛\nانتقال صفحه به خودش ممکن نیست.",
        "move-leave-redirect": "بر جا گذاشتن یک تغییرمسیر",
        "protectedpagemovewarning": "'''هشدار:''' این صفحه قفل شده‌است به طوری که تنها کاربران با دسترسی مدیریت می‌توانند آن را انتقال دهند.\nآخرین موارد سیاهه در زیر آمده است:",
        "semiprotectedpagemovewarning": "'''تذکر:''' این صفحه قفل شده‌است به طوری که تنها کاربران ثبت نام کرده می‌توانند آن را انتقال دهند.\nآخرین موارد سیاهه در زیر آمده است:",
-       "move-over-sharedrepo": "== پرونده موجود است ==\n[[:$1]] در یک مخزن مشترک وجود دارد. انتقال یک پرونده به این نام باعث باطل شدن پرونده مشترک خواهد شد.",
+       "move-over-sharedrepo": "[[:$1]] در یک مخزن مشترک وجود دارد. انتقال یک پرونده به این نام باعث باطل شدن پرونده مشترک خواهد شد.",
        "file-exists-sharedrepo": "نام پرونده انتخاب شده از قبل در یک مخزن مشترک استفاده شده‌است.\nلطفاً یک نام دیگر برگزینید.",
        "export": "برون‌بری صفحات",
        "exporttext": "شما می‌توانید متن و تاریخچهٔ ویرایش یک صفحهٔ مشخص یا مجموعه‌ای از صفحات را به شکل پوشیده در اکس‌ام‌ال برون‌بری کنید.\nاین اطلاعات را می‌توان در ویکی دیگری که نرم‌افزار «مدیاویکی» را اجرا می‌کند از طریق [[Special:Import|صفحهٔ درون‌ریزی]] وارد کرد.\n\nبرای برون‌بری صفحات، عنوان آن‌ها را در جعبهٔ زیر وارد کنید (در هر سطر فقط یک عنوان) و مشخص کنید که آیا نسخهٔ اخیر صفحه را به همراه نسخه‌های قدیمی‌تر و تاریخچهٔ صفحه می‌خواهید، یا تنها نسخهٔ اخیر صفحه و اطلاعات آخرین ویرایش را می‌خواهید.\n\nدر حالت دوم، شما می‌توانید از یک پیوند استفاده کنید، مثلاً [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] برای صفحهٔ «[[{{MediaWiki:Mainpage}}]]».",
        "lastmodifiedatby": "این صفحه آخرین بار در $2، $1 به دست $3 تغییر یافته‌است.",
        "othercontribs": "بر اساس اثری از $1",
        "others": "دیگران",
-       "siteusers": "$1، {{PLURAL:$2|کاربر|کاربران}} {{SITENAME}}",
+       "siteusers": "{{SITENAME}}{{PLURAL:$2|{{GENDER:$1|کاربر}}|کاربر}} $1",
        "anonusers": "$1 {{PLURAL:$2|کاربر|کاربران}} ناشناس {{SITENAME}}",
        "creditspage": "اعتبارات این صفحه",
        "nocredits": "اطلاعات سازندگان این صفحه موجود نیست.",
        "version-hook-subscribedby": "وارد شده توسط",
        "version-version": "($1)",
        "version-no-ext-name": "[بدون نام]",
-       "version-svn-revision": "(&رلم;r$2)",
        "version-license": "اجازه‌نامهٔ مدیاویکی",
        "version-ext-license": "مجوزها",
        "version-ext-colheader-name": "گستره‌ها",
        "version-poweredby-others": "دیگران",
        "version-poweredby-translators": "مترجمان translatewiki.net",
        "version-credits-summary": "افراد زیر را به خاطر ویرایش‌هایش در [[Special:Version|مدیاویکی]] معرفی می‌نمائیم.",
-       "version-license-info": "مدیاویکی یک نرم‌افزار آزاد است. می‌توانید آن را با شرایط نگارش ۲، یا (با نظر خودتان) هر نگارش جدیدتری از پروانه جامع همگانی گنو که توسط بنیاد نرم‌افزار آزاد منتشر شده‌است، بازنشر کنید.\n\nمدیاویکی با این امید که مفید واقع شود منتشر شده‌است، ولی هیچ‌گونه ضمانتی، حتا ضمانت ضمنی تجاری یا مناسب بودن برای یک مصرف خاص را ارائه نمی‌کند. برای اطلاعات بیش‌تر، پروانه جامع همگانی گنو را مشاهده کنید.\n\nشما باید [{{SERVER}}{{SCRIPTPATH}}/COPYING یک نسخه از پروانه جامع همگانی گنو] را به همراه این برنامه دریافت کرده باشید. در غیر این صورت با Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA یا آن را [//www.gnu.org/licenses/old-licenses/gpl-2.0.html مکاتبه کرده یا آن را به صورت برخط بخوانید].",
+       "version-license-info": "مدیاویکی یک نرم‌افزار آزاد است. می‌توانید آن را با شرایط نگارش ۲، یا (با نظر خودتان) هر نگارش جدیدتری از پروانه جامع همگانی گنو که توسط بنیاد نرم‌افزار آزاد منتشر شده‌است، بازنشر کنید.\n\nمدیاویکی با این امید که مفید واقع شود منتشر شده‌است، ولی هیچ‌گونه ضمانتی، حتی ضمانت ضمنی تجاری یا مناسب بودن برای یک مصرف خاص را ارائه نمی‌کند. برای اطلاعات بیش‌تر، پروانه جامع همگانی گنو را مشاهده کنید.\n\nشما باید [{{SERVER}}{{SCRIPTPATH}}/COPYING یک نسخه از پروانه جامع همگانی گنو] را به همراه این برنامه دریافت کرده باشید. در غیر این صورت با Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA یا آن را [//www.gnu.org/licenses/old-licenses/gpl-2.0.html مکاتبه کرده یا آن را به صورت برخط بخوانید].",
        "version-software": "نسخهٔ نصب‌شده",
        "version-software-product": "محصول",
        "version-software-version": "نسخه",
        "expand_templates_preview_fail_html": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروع است، لطفا دوباره سعی کنید. اگر هنوز کار نمی کند، سعی کنید [[Special:UserLogout|خروج از سیستم]] را کلیک نموده و دوباره وارد شوید.",
        "expand_templates_preview_fail_html_anon": "<em>زیرا {{SITENAME}} تا به HTML خام فعال و یک دست رفتن اطلاعات نشست وجود دارد، پیش نمایش به عنوان یک اقدام احتیاطی در برابر حملات جاوا اسکریپت پنهان است.</em>\n\n<strong>اگر این تلاش پیشنمایش مشروع است، لطفا دوباره سعی کنید. اگر هنوز کار نمی کند، سعی کنید [[Special:UserLogout|خروج از سیستم]] را کلیک نموده و دوباره وارد شوید.",
        "expand_templates_input_missing": "شما نیازمندید که حداقل متن‌هایی را برای وارد کردن تهیه کنید.",
-       "pagelanguage": "صÙ\81Ø­Ù\87 Ø§Ù\86تخاب Ø²Ø¨Ø§Ù\86",
+       "pagelanguage": "تغÛ\8cÛ\8cر Ø²Ø¨Ø§Ù\86 ØµÙ\81Ø­Ù\87",
        "pagelang-name": "صفحه",
        "pagelang-language": "زبان",
        "pagelang-use-default": "استفاده از زبان پیش‌فرض",
        "pagelang-submit": "اعمال",
        "right-pagelang": "تغییر صفحهٔ زبان",
        "action-pagelang": "تغییر زبان صفحه",
-       "log-name-pagelang": "تغÛ\8cÛ\8cر Ø³Û\8cاÙ\87Ù\87Ù\94 زبان",
+       "log-name-pagelang": "سÛ\8cاÙ\87Ù\87Ù\94 ØªØºÛ\8cÛ\8cر زبان",
        "log-description-pagelang": "این سیاههٔ تغییرات صفحهٔ زبان‌ها است.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2| تغییریافت}} زبان صفحه برای  $3  از  $4  به  $5 .",
+       "logentry-pagelang-pagelang": "$1 زبان $3  از  $4  به  $5 {{GENDER:$2| تغییریافت}}",
        "default-skin-not-found": "اوه! پوسته پیش‌فرض برای ویکی شما تعریف‌شده در <code dir=\"ltr\"<$wgDefaultSkin</code> به عنوان <code>$1</code>، در دسترس نیست.\n\nبه نظر می‌آید نصب شما شامل پوسته‌های زیر می‌شود. [https://www.mediawiki.org/wiki/Manual:Skin_configuration راهنما: تنظیمات پوسته] را برای کسب اطلاعات در باره چگونگی فعال‌ساختن آن‌ها و انتخاب پیش‌فرض ببینید.\n\n$2\n\n; اگر اخیراً مدیاویکی را نصب کرده‌اید:\n: احتمالاً از گیت، یا به طور مستقیم از کد مبدأ که از چند متد دیگر استفاده می‌کند نصب کردید. انتظار می‌رود. چند {{PLURAL:$4|پوسته|پوسته}} از [https://www.mediawiki.org/wiki/Category:All_skins فهرست پوسته mediawiki.org] نصب کنید، که همراه چندین پوسته و افزونه هستند. شما می‌توانید شاخه <code>skins/</code> را از آن نسخه‌برداری کرده و بچسبانید.\n\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins استفاده از گیت برای دریافت پوسته‌ها].\n: انجام این کار با مخزن گیت‌تان تداخل نمی‌کند اگر توسعه‌دهنده مدیاویکی هستید.\n\n; اگر اخیراً مدیاویکی را ارتقاء دادید:\n: مدیاویکی ۱٫۲۴ و تازه‌تر دیگر به طور خودکار پوسته‌های نصب‌شده را فعال نمی‌کند ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery راهنما: کشف خودکار پوسته] را ببینید). شما می‌توانید خطوط زیر را به داخل <code>LocalSettings.php</code> بچسبانید تا {{PLURAL:$5|همه|همه}} پوسته‌های نصب‌شده را فعال کنید:\n\n<pre dir=\"ltr\">$3</pre>\n\n; اگر اخیراً <code>LocalSettings.php</code> را تغییر دادید:\n: نام پوسته‌ها را برای غلط املایی دوباره بررسی کنید.",
        "default-skin-not-found-no-skins": "پوستهٔ پیش‌فرض برای ویکی شما تعریف‌شده در<code>$wgDefaultSkin</code> به عنوان <code>$1</code>، هست موجود نیست.\n\nشما پوسته‌ها را نصب نکرده‌اید.\n\n:اگر مدیاویکی را به‌روز یا نصب کرده‌اید:\n:ممکن است از گیت یا از کد منبع با روش‌های دیگر نصب کرده‌اید. انتظار می‌رود MediaWiki 1.24 یا جدیدتر در پوشهٔ اصلی هیچ پوسته‌ای نداشته باشند.\nسعی کنید تعدادی پوسته از [https://www.mediawiki.org/wiki/Category:All_skins پوشهٔ پوسته‌های مدیاویکی]، با:\n:*دریافت [https://www.mediawiki.org/wiki/Download نصب‌کننده تاربال]، که با چندین پوسته و افزونه هست. شما می توانید پوستهٔ <code>skins/</code> را از آن کپی و پیست کنید.\n:*کلون کردن یکی از <code dir=\"ltr\">mediawiki/skins/*</code> از مخزن در پوشهٔ <code>skins/</code> مدیاویکی‌تان.\n:اگر توسعه‌دهندهٔ مدیاویکی هستید، انجام این کار نباید تعارضی با مخزن گیت شما داشته باشد. برای اطلاعات بیشتر و فعال کردن پوسته‌ها و انتخاب آنها به عنوان پیش‌فرض [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: تنظیمات پوسته] را مشاهده کنید.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (فعال)",
index 9795daf..42f65fa 100644 (file)
        "grant-uploadeditmovefile": "Tallentaa, korvata ja siirtää tiedostoja",
        "grant-uploadfile": "Tallentaa uusia tiedostoja",
        "grant-basic": "Perustason oikeudet",
-       "grant-viewdeleted": "Näe poistetut tiedostot ja sivut",
-       "grant-viewmywatchlist": "Näe oma tarkkailulistasi",
+       "grant-viewdeleted": "Nähdä poistettuja sivuja ja tiedostoja",
+       "grant-viewmywatchlist": "Nähdä oma tarkkailulista",
        "newuserlogpage": "Uudet käyttäjät",
        "newuserlogpagetext": "Tämä on loki luoduista käyttäjätunnuksista.",
        "rightslog": "Käyttöoikeusloki",
        "uploaded-script-svg": "Found scriptable element \"$1\" in the uploaded SVG file.",
        "uploaded-hostile-svg": "Tallennetun SVG-tiedoston tyylielementissä löytyi turvaton CSS.",
        "uploaded-event-handler-on-svg": "Setting event-handler attributes <code>$1=\"$2\"</code> is not allowed in SVG files.",
-       "uploaded-href-attribute-svg": "href attributes <code>&lt;$1 $2=\"$3\"&gt;</code> with non-local target (e.g. http://, javascript:, etc) are not allowed in SVG files.",
        "uploaded-href-unsafe-target-svg": "Found href to unsafe target <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "uploaded-animate-svg": "Found \"animate\" tag that might be changing href, using the \"from\" attribute <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "uploaded-setting-event-handler-svg": "Setting event-handler attributes is blocked, found <code>&lt;$1 $2=\"$3\"&gt;</code> in the uploaded SVG file.",
        "querypage-disabled": "Tämä toimintosivu on poistettu käytöstä suorituskykyyn liittyvien syiden vuoksi.",
        "apihelp": "API-apu",
        "apihelp-no-such-module": "Moduulia ”$1” ei löydy.",
+       "apisandbox": "API-hiekkalaatikko",
+       "apisandbox-api-disabled": "API on poistettu käytöstä tällä sivustolla.",
+       "apisandbox-intro": "Tämä on '''MediaWiki API:n''' hiekkalaatikko.\n[//www.mediawiki.org/wiki/API:Main_page API-dokumentaatio] kertoo lisää API:en käytöstä.",
+       "apisandbox-submit": "Tee pyyntö",
+       "apisandbox-reset": "Tyhjennä",
+       "apisandbox-examples": "Esimerkki",
+       "apisandbox-results": "Tulos",
+       "apisandbox-request-url-label": "Pyynnön URL",
+       "apisandbox-request-time": "Pyyntöaika: $1",
        "booksources": "Kirjalähteet",
        "booksources-search-legend": "Etsi kirjalähteitä",
        "booksources-isbn": "ISBN",
        "listgrouprights-namespaceprotection-header": "Nimiavaruuksien rajoitukset",
        "listgrouprights-namespaceprotection-namespace": "Nimiavaruus",
        "listgrouprights-namespaceprotection-restrictedto": "Käyttäjän muokkausoikeudet",
+       "listgrants": "Toimintaoikeudet",
+       "listgrants-grant": "Toimintaoikeus",
+       "listgrants-rights": "Oikeudet",
        "trackingcategories": "Tarkkailuluokat",
        "trackingcategories-summary": "Tällä sivulla on luettelo sellaisista ongelmia havaitsevista luokista (tarkkailuluokat), joiden sisällön koostaa automaattisesti MediaWiki-ohjelmisto. Luokkien nimiä voi vaihtaa muuttamalla asianomaista järjestelmäviestiä nimiavaruudessa {{ns:8}}.",
        "trackingcategories-msg": "Tarkkailuluokka",
index 2c9dec0..57ac1b5 100644 (file)
                        "SRXcraft",
                        "StevenJ81",
                        "The RedBurn",
-                       "Fredlefred"
+                       "Fredlefred",
+                       "Lbayle"
                ]
        },
        "tog-underline": "Soulignement des liens :",
        "uploaded-script-svg": "Élément scriptable « $1 » trouvé dans le fichier SVG téléchargé.",
        "uploaded-hostile-svg": "CSS non sûr trouvé dans l’élément style d’un fichier SVG téléchargé.",
        "uploaded-event-handler-on-svg": "Fixer des attributs de gestionnaire d’événement <code>$1=\"$2\"</code> n’est pas autorisé dans les fichiers SVG.",
-       "uploaded-href-attribute-svg": "Les attributs href <code>&lt;$1 $2=\"$3\"&gt;</code> avec une cible non locale (par ex. http://, javascript:, etc.) ne sont pas autorisés dans les fichiers SVG.",
-       "uploaded-href-unsafe-target-svg": "href vers une cible non sûre <code>&lt;$1 $2=\"$3\"&gt;</code> trouvé dans le fichier SVG téléchargé.",
+       "uploaded-href-attribute-svg": "les attributs href dans les fichiers SVG ne sont autorisés que pour faire référence à des cibles http:// ou https://, <code>&lt;$1 $2=\"$3\"&gt;</code> trouvé.",
+       "uploaded-href-unsafe-target-svg": "href vers des données non sûres trouvé dans le fichier SVG téléchargé : URI cible <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "Balise « animate » trouvée, qui pourrait modifier le href en utilisant l’attribut « from » <code>&lt;$1 $2=\"$3\"&gt;</code> dans le fichier SVG téléchargé.",
        "uploaded-setting-event-handler-svg": "Positionner des attributs de gestionnaire d’événement est bloqué, <code>&lt;$1 $2=\"$3\"&gt;</code> trouvé dans le fichier SVG téléchargé.",
        "uploaded-setting-href-svg": "L’utilisation de la balise « set » pour ajouter un attribut « href » à l’élément parent est interdite.",
        "querypage-disabled": "Cette page spéciale est désactivée pour des raisons de performances.",
        "apihelp": "Aide de l’API",
        "apihelp-no-such-module": "Le module « $1 » est introuvable.",
+       "apisandbox": "Bac à sable API",
+       "apisandbox-jsonly": "Le bac à sable de l'API nécessite JavaScript",
+       "apisandbox-api-disabled": "API est désactivé sur ce site.",
+       "apisandbox-intro": "Utilisez cette page pour expérimenter l’<strong>API webservice de MediaWiki</strong>.\nReportez-vous à [[mw:API:Main page|la documentation de l’API]] pour plus de détails sur l’utilisation de l’API. Exemple: [//www.mediawiki.org/wiki/API#A_simple_example obtenir le contenu d'une page principale]. Choisissez une option pour voir d'autres exemples.",
+       "apisandbox-fullscreen": "Développer le panneau",
+       "apisandbox-fullscreen-tooltip": "Étendre le panneau du bac à sable pour remplir la fenêtre du navigateur.",
+       "apisandbox-unfullscreen": "Afficher la page",
+       "apisandbox-unfullscreen-tooltip": "Réduire le panneau du bac à sable, pour que les liens de navigation de MédiaWiki soient disponibles.",
+       "apisandbox-submit": "Faire la demande",
+       "apisandbox-reset": "Effacer",
+       "apisandbox-retry": "Réessayer",
+       "apisandbox-loading": "Chargement des informations du module \"$1\" de l'API...",
+       "apisandbox-load-error": "Une erreur s'est produite lors du chargement des informations du module \"$1\" de l'API: $2",
+       "apisandbox-no-parameters": "Ce module de l’API n’a pas de paramètres.",
+       "apisandbox-helpurls": "Liens d'aide",
+       "apisandbox-examples": "Exemples",
+       "apisandbox-dynamic-parameters": "Paramètres supplémentaires",
+       "apisandbox-dynamic-parameters-add-label": "Ajout du paramètre:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nom du paramètre",
+       "apisandbox-dynamic-error-exists": "Un paramètre nommé \"$1\" existe déjà.",
+       "apisandbox-deprecated-parameters": "Paramètres obsolètes",
+       "apisandbox-fetch-token": "Auto-remplissage du jeton",
+       "apisandbox-submit-invalid-fields-title": "Certains champs ne sont pas valides",
+       "apisandbox-submit-invalid-fields-message": "Veuillez corriger les champs marqués et essayez de nouveau.",
+       "apisandbox-results": "Résultats",
+       "apisandbox-sending-request": "Envoi de la requête à l'API...",
+       "apisandbox-loading-results": "Réception des résultats de l'API...",
+       "apisandbox-results-error": "Une erreur s'est produite lors du chargement de la réponse à la requête de l'API: $1.",
+       "apisandbox-request-url-label": "Requête URL :",
+       "apisandbox-request-time": "Durée de la demande: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Corrigez le jeton et renvoyez",
+       "apisandbox-results-fixtoken-fail": "Impossible de récupérer le jeton \"$1\"",
+       "apisandbox-alert-page": "Les champs de cette page ne sont pas valides.",
+       "apisandbox-alert-field": "La valeur de ce champ n'est pas valide.",
        "booksources": "Ouvrages de référence",
        "booksources-search-legend": "Rechercher parmi des ouvrages de référence",
        "booksources-isbn": "ISBN :",
        "move-page": "Renommer $1",
        "move-page-legend": "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. Vous pouvez mettre à jour automatiquement les redirections actuelles qui pointent vers le titre original. Si vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <string>pas</strong> renommée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
-       "movepagetext-noredirectfixer": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.\nL’ancien titre deviendra une page de redirection vers le nouveau titre.\nVérifiez bien les [[Special:DoubleRedirects|doubles redirections]] ou les [[Special:BrokenRedirects|redirections cassées]].\nVous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</stong> déplacée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est soit vide, soit une simple redirection. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné, et il est impossible d’écraser une page existante.\n\n<strong>Attention !</stong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
+       "movepagetext-noredirectfixer": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.\nL’ancien titre deviendra une page de redirection vers le nouveau titre.\nVérifiez bien les [[Special:DoubleRedirects|doubles redirections]] ou les [[Special:BrokenRedirects|redirections cassées]].\nVous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> déplacée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est soit vide, soit une simple redirection. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné, et il est impossible d’écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
        "movepagetalktext": "Si vous cochez cette case, la page de discussion associée sera automatiquement renommée, à moins qu’une page de discussion non vide existe déjà sous ce nouveau nom.\n\nDans ce cas, vous devrez renommer ou fusionner cette page de discussion manuellement si vous le désirez.",
        "moveuserpage-warning": "'''Attention :''' Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur '''ne''' sera '''pas''' renommé.",
        "movecategorypage-warning": "<strong>Avertissement :</strong> Vous êtes sur le point de renommer une page de catégorie. Veuillez noter que seule la catégorie sera renommée et <em>qu’aucune</em> des pages de l’ancienne catégorie ne sera transférée dans la nouvelle.",
index 79315b7..551586e 100644 (file)
@@ -9,7 +9,8 @@
                        "Tocaibon",
                        "Urhixidur",
                        "לערי ריינהארט",
-                       "아라"
+                       "아라",
+                       "Marsitown"
                ]
        },
        "tog-underline": "Sotlinee leams",
        "databaseerror-query": "Interogazion: $1",
        "databaseerror-function": "Funzion $1",
        "databaseerror-error": "Erôr: $1",
+       "transaction-duration-limit-exceeded": "Par evitâ masse ritart te rispueste, cheste operazion è je stade fermade par vie che la durade dal timp di scriture ($1) al à passât il limit di $2 {{PLURAL:$2|secont|seconts}}.\nSe si stan modificant tancj elements in un colp al sarès di provâ a fâ la stesse operazion cun mancul elements a la volte.",
        "laggedslavemode": "Atenzion: La pagjine podarès no segnalâ inzornaments recents.",
        "readonly": "Base di dâts blocade",
        "enterlockreason": "Scrivi il motîf dal bloc e indicâ cuant che al varès di jessi gjavât.",
-       "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.\n\nL'aministradôr ch'al à metût il bloc al à scrit cheste motivazion: $1",
+       "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, une volte finide dut al tornarà normâl.\n\nL'aministradôr che al à metût il bloc al à scrit cheste motivazion: $1",
        "missing-article": "La base di dâts no à cjatât il test di une pagjine che e varès di vê vût cjatât, di non \"$1\" $2.\n\nChest in gjenar al è causât dal jessi lâts daûr dal leam a une pagjine che e je stade eliminade, partint dal confront di dôs versions o di un leam tal storic.\n\nSe la cause no samee jessi cheste, tu podaressis vê cjatât un problem tal software.\nSegnalilu par plasê a un [[Special:ListUsers/sysop|administrator]], notant la URL.",
        "missingarticle-rev": "(numar de revision: $1)",
        "missingarticle-diff": "(Dif.: $1, $2)",
        "readonly_lag": "Par cumò il database al è stât blocât pe sincronizazion cul server",
+       "nonwrite-api-promise-error": "E je stade mandade la intestazion HTTP 'Promise-Non-Write-API-Action', ma la domande e jere di un modul API in scriture.",
        "internalerror": "Erôr interni",
        "internalerror_info": "Erôr interni: $1",
+       "internalerror-fatal-exception": "Erôr ireversibil di tipo \"$1\"",
        "filecopyerror": "No si pues copiâ il file \"$1\" in \"$2\"",
        "filerenameerror": "No si pues rinominâ \"$1\" in \"$2\"",
        "filedeleteerror": "No si pues eliminâ il file \"$1\".",
        "directorycreateerror": "No si pues creâ la cartele \"$1\"",
+       "directoryreadonlyerror": "La directory \"$1\" e je dome di leture.",
+       "directorynotreadableerror": "La directory \"$1\" non si rive a lei.",
        "filenotfound": "No si pues cjatâ il file \"$1\".",
        "unexpected": "Valor no proviodût: \"$1\" = \"$2\"",
        "formerror": "Erôr: no si rive a mandâ il form",
        "no-null-revision": "No si pues creâ une version vuedie de pagjine \"$1\"",
        "badtitle": "Titul sbaliât",
        "badtitletext": "Il titul de pagjine che tu âs inserît nol è valit, al è vuelit, o al veve un erôr tal colegament tra wiki diviersis o tra versions in altris lenghis.\nAl podarès vê dentri caratars che no podin jessi doprâts tai titui.",
+       "title-invalid-empty": "Il titul de pagjine domandade al è vueit o al à dome il non dal namespace",
+       "title-invalid-utf8": "Il titul de pagjine domandade al à une secuence UTF-8 no valide.",
+       "title-invalid-interwiki": "Il titul de pagjine domandade al à un leam interwiki che no si pues doprâ tai titui.",
+       "title-invalid-talk-namespace": "Il titul de pagjine domandade al clame une pagjine di discussion che no esist",
+       "title-invalid-characters": "Il titul de pagjine domandade al à caratars no valits: \"$1\".",
+       "title-invalid-relative": "Il titul al à un percors (./, ../). al è di cambiâ parcè che nol è dite che il browser dal utent al rivedi a cjatâlu.",
+       "title-invalid-magic-tilde": "Il titul de pagjine domandade nol + valit par vie che al à une sucession speciâl di tildis (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "Il titul de pagjine domandade al è masse lunc. Nol à di jessi plui lunc di {{PLURAL:$1|byte}} in codifiche UTF-8.",
+       "title-invalid-leading-colon": "Il titul de pagjine domandade nol è valit par vie che al à i doi pont al inizi dal titul",
        "perfcached": "I dats seguints a vegnin di une copie de \"cache\" dal database e a podaressin no jessi inzornâts. La cache e rive a tignî al massim  {{PLURAL:$1|un risultâ disponibil|$1 risultats disponibii}}",
        "perfcachedts": "I dats seguints a vegnin di une copie de \"cache\" dal database dal $1 e a podaressin no jessi inzornâts. La cache e rive a tignî al massim  {{PLURAL:$1|un risultâ disponibil|$1 risultats disponibii}}",
        "querypage-no-updates": "Inzornaments de pagjine a son al moment sospindûts. I dats metûts no saràn salvâts.",
        "viewsource": "Cjale risultive",
        "viewsource-title": "Cjale il codiç di $1",
        "actionthrottled": "Azion ritardade",
-       "actionthrottledtext": "Come misure anti-spam tu âs des limitazion tal fâ cheste azion masse voltis in toc di timp curt. Il limit al è stât superât. Tu puedis tornâ a provâ fra cualchi minût.",
+       "actionthrottledtext": "Come misure anti-spam tu âs des limitazion tal fâ cheste azion masse voltis in pôc timp. Il limit al è stât superât. Tu puedis tornâ a provâ fra cualchi minût.",
        "protectedpagetext": "Pagjine protete par evitâ modifichis o altris azions.",
        "viewsourcetext": "Tu puedis viodi e copiâ la risultive di cheste pagjine:",
        "viewyourtext": "Tu puedis viodi o copiâ il codiç des \"tôs modifichis\" in cheste pagjine.",
+       "mycustomcssprotected": "Non hai i permessi per modificare questa pagina CSS",
+       "mycustomjsprotected": "Non hai i permessi per modificare questa pagina JavaScript",
+       "myprivateinfoprotected": "Non si dispone dei permessi necessari per modificare i propri dati personali.",
+       "mypreferencesprotected": "Non si dispone dei permessi necessari per modificare le proprie preferenze.",
        "ns-specialprotected": "Lis pagjinis specialis no si puedin modificâ",
        "exception-nologin": "No tu sês jentrât",
        "virus-unknownscanner": "antivirus no cognossût:",
        "createacct-benefit-body2": "{{PLURAL:$1|pagjine|pagjinis}}",
        "createacct-benefit-body3": "{{PLURAL:$1|ultin contributôr|ultins contributôrs}}",
        "badretype": "Lis peraulis clâfs inseridis no son compagnis.",
-       "userexists": "Il non utent inserît al è za doprât. Sielç par plasê un non diferent.",
+       "userexists": "Il nome utente inserito è già utilizzato.\nScegli un nome utente diverso.",
        "loginerror": "Erôr te jentrade",
        "createaccounterror": "No si à podût creâ l'identitât: $1",
        "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.",
        "noname": "No tu âs inserît un non utent valit.",
        "loginsuccesstitle": "Jentrât cun sucès",
        "loginsuccess": "Cumò tu sês jentrât te {{SITENAME}} sicu \"$1\".",
-       "nosuchuser": "Nissun utent regjistrât cul non \"$1\". Controle il non inserît o [[Special:UserLogin/signup|cree tu une gnove identitât]].",
+       "nosuchuser": "Non è registrato alcun utente di nome \"$1\".\nI nomi utente sono sensibili alle maiuscole.\nVerificare il nome inserito o [[Special:UserLogin/signup|creare una nuova utenza]].",
        "nosuchusershort": "Nol esist nissun utent cul non \"$1\". Controle di no vê sbaliât di scrivi.",
        "nouserspecified": "Tu scugnis specificâ un non utent.",
        "wrongpassword": "La peraule clâf zontade no je juste. Torne par plasê a provâ.",
index 4e0b5c6..560e734 100644 (file)
        "uploaded-script-svg": "Atopado elemento de comandos \"$1\" no ficheiro SVG subido.",
        "uploaded-hostile-svg": "Atopado CSS non seguro no elemento de estilo do ficheiro SVG subido.",
        "uploaded-event-handler-on-svg": "Fixar atributos de xestión de eventos <code>$1=\"$2\"</code> no está permitido en ficheiros SVG.",
-       "uploaded-href-attribute-svg": "Atributos href <code>&lt;$1 $2=\"$3\"&gt;</code> con obxectivos non locais (p. ex. http://, javascript:, etc) non están permitidos en ficheiros SVG.",
-       "uploaded-href-unsafe-target-svg": "Atopado href a obxectivo non seguro <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
+       "uploaded-href-attribute-svg": "os atributos href nos ficheiros SVG só están autorizados a ligar a direccións http:// ou https://, atopado <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Atopado href a datos non seguros: dirección URI <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
        "uploaded-animate-svg": "Atopada etiqueta \"animate\" que podería estar cambiando a href, usando o atributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
        "uploaded-setting-event-handler-svg": "Fichar os atributos de xestión de eventos non está permitido, atopado <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
        "uploaded-setting-href-svg": "Usar a etiqueta \"set\" para engadir o atributo \"href\" ó elemento pai non está permitido.",
        "querypage-disabled": "Esta páxina especial está desactivada por razóns de rendemento.",
        "apihelp": "Axuda coa API",
        "apihelp-no-such-module": "Non se atopou o módulo \"$1\".",
+       "apisandbox": "Zona de probas API",
+       "apisandbox-jsonly": "É preciso activar o JavaScript para usar a zona de probas.",
+       "apisandbox-api-disabled": "API está desactivado neste sitio.",
+       "apisandbox-intro": "Use esta páxina para experimentar co <strong>servizo web da API de MediaWiki</strong>.\nConsulte a [[mw:API:Main page| documentación da API]] para obter máis información sobre o uso da API. Exemplo: [//www.mediawiki.org/wiki/API#A_simple_example obter o contido dunha páxina de inicio]. Seleccione unha acción para ollar máis exemplos.\n\nTeña en conta que, aínda que esta é unha páxina de probas, as accións que realice nesta páxina poden modificar o wiki.",
+       "apisandbox-fullscreen": "Expandir panel",
+       "apisandbox-fullscreen-tooltip": "Expande o panel da zona de probas para encher a pantalla do navegador.",
+       "apisandbox-unfullscreen": "Mostrar a páxina",
+       "apisandbox-unfullscreen-tooltip": "Reduce o panel da zona de probas, así as ligazóns de navegación MediaWiki están dispoñibles.",
+       "apisandbox-submit": "Facer a solicitude",
+       "apisandbox-reset": "Limpar",
+       "apisandbox-retry": "Reintentar",
+       "apisandbox-loading": "Cargando información para módulo de API \"$1\"...",
+       "apisandbox-load-error": "Houbo un erro mentres se cargaba a información do módulo API \"$1\": $2",
+       "apisandbox-no-parameters": "O módulo de API non ten parámetros.",
+       "apisandbox-helpurls": "Ligazóns de axuda",
+       "apisandbox-examples": "Exemplos",
+       "apisandbox-dynamic-parameters": "Parámetros adicionais",
+       "apisandbox-dynamic-parameters-add-label": "Engadir parámetro:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nome do parámetro",
+       "apisandbox-dynamic-error-exists": "Xa existe un parámetro co nome \"$1\".",
+       "apisandbox-deprecated-parameters": "Parámetros obsoletos",
+       "apisandbox-fetch-token": "Auto-enchido do identificador",
+       "apisandbox-submit-invalid-fields-title": "Algúns campos non son válidos",
+       "apisandbox-submit-invalid-fields-message": "Por favor, amañe os campos marcados e inténteo de novo.",
+       "apisandbox-results": "Resultados",
+       "apisandbox-sending-request": "Enviando a petición á API...",
+       "apisandbox-loading-results": "Recibindo os resultados da API...",
+       "apisandbox-results-error": "Houbo un erro mentres se cargaba a resposta á consulta da API: $1.",
+       "apisandbox-request-url-label": "URL da solicitude:",
+       "apisandbox-request-time": "Duración da solicitude: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Correxir identificador e reenviar",
+       "apisandbox-results-fixtoken-fail": "Erro ó recuperar o identificador \"$1\".",
+       "apisandbox-alert-page": "Os campos nesta páxina non son válidos.",
+       "apisandbox-alert-field": "O valor deste campo non é válido.",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Procurar fontes bibliográficas",
        "booksources-search": "Procurar",
index 7d986c7..832a2c6 100644 (file)
        "passwordreset-domain": "डोमेन:",
        "passwordreset-email": "ईमेल नामो:",
        "passwordreset-emailelement": "वापरप्याचें नांव: \n$1\n\nतात्पुरतें गुपीत उतर: \n$2",
-       "passwordreset-emailsent": "गुपीत उतर परतून तयार करपाचो ईमेल धाडला",
+       "passwordreset-emailsentemail": "गुपीत उतर परतून तयार करपाचो ईमेल धाडला",
        "changeemail": "ईमेल संदेश बदल्ला",
        "changeemail-oldemail": "सद्याचो ईमेल नामो:",
        "changeemail-newemail": "नवो ईमेल नामो:",
        "booksources-search": "सोद",
        "log": "सोत्रां",
        "allpages": "सगळीं पाना",
+       "nextpage": "फुडलें पान ($1)",
+       "prevpage": "फाटलें पान ($1)",
        "allarticles": "सगळीं पानां",
        "allpagessubmit": "वचात",
        "categories": "वर्ग",
        "unwatch": "पळोवंक नासलें",
        "watchlist-details": "लक्ष {{PLURAL:$1|$1वळेरींतलें|$1 वळेंरींतली}} {{PLURAL:$1|$1पान|$1 पानां}} उलोवपाची पानां सोडून",
        "wlshowlast": "फाटलें $1 वरांचें $2 दिसांचें  दाखयात",
-       "watchlistall2": "सगळें",
        "watchlist-options": "लक्षवळेंरींतलो पर्याय",
        "delete-legend": "काडून उडयात",
        "actioncomplete": "क्रिया पुराय जाल्या",
index 9575ede..4028d1b 100644 (file)
        "nstab-template": "Saacho",
        "nstab-help": "Adarachem pan",
        "nstab-category": "Vorg",
+       "mainpage-nstab": "Mukhel pan",
        "nosuchaction": "Oslem torechem karya nam",
        "nosuchspecialpage": "Oslem kaich khashellem pan na",
        "error": "Chuk",
        "passwordreset-domain": "Domain:",
        "passwordreset-email": "Email potto:",
        "passwordreset-emailelement": "Vapurpeachem nanv: \n$1\n\nTatpurtem gupitutor: \n$2",
-       "passwordreset-emailsent": "Gupitutor portun tharaipacho email dhadla.",
+       "passwordreset-emailsentemail": "Gupitutor portun tharaipacho email dhadla.",
        "changeemail": "Email potto bodol",
        "changeemail-oldemail": "Sodhyacho email potto:",
        "changeemail-newemail": "Novo email potto:",
        "prevn": "adlem {{PLURAL:$1|$1}}",
        "nextn": "fuddlem {{PLURAL:$1|$1}}",
        "next-page": "Fuddlem pan",
-       "prevn-title": "{{PLURAL:$1|Fattlem $1 porinnam|Fattlem $1 porinam}}",
+       "prevn-title": "{{PLURAL:$1|Fattlo $1 porinam|Fattleo $1 porinaman}}",
        "nextn-title": "{{PLURAL:$1|Fuddlem $1 porinnam|Fudnlim $1 porinnam}}",
        "shown-title": "Dor eka panar {{PLURAL:$1|porinam}} dakhoi",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) poloi",
        "speciallogtitlelabel": "Vishoi vo vapurpi:",
        "log": "Sotram",
        "allpages": "Sogllim panam",
-       "nextpage": "Mukklem pan ($1)",
-       "prevpage": "Ad'dlem pan ($1)",
+       "nextpage": "Fuddlem pan ($1)",
+       "prevpage": "Fattlem pan ($1)",
        "allpagesfrom": "Hanga thavn suru zatelea panank dakhoi:",
        "allarticles": "Sogllim panam",
        "allpagessubmit": "Voch",
        "watchlist-details": "Tujea sadurvollerint {{PLURAL:$1|$1 pan asa|$1 panam asat}}, ulovpachim panam veglim mezonastanam.",
        "wlheader-showupdated": "Tujea fatle bhette san bodol'lean tim panam '''datt''' dakhoileant.",
        "wlshowlast": "Xevottchim $1 voram $2 dis  dakhoi",
-       "watchlistall2": "soglle",
        "watchlist-options": "Sadurvollericheo poryay",
        "watching": "Disht dovortanv...",
        "unwatching": "Disht kaddthanv...",
        "contributions": "{{GENDER:$1|Vapuddpi}} yogdanam",
        "contributions-title": "$1 hea vapuddpean kelelim yogdanam",
        "mycontris": "Yogdanam",
+       "anoncontribs": "Yogdanam",
        "contribsub2": "{{GENDER:$3|$1}} hacheo ($2)",
        "uctop": "(atachem)",
        "month": "Mhoinea savn (ani adichem):",
        "allmessagesdefault": "Falta sondex mozkur",
        "thumbnail-more": "Vhodlem kor",
        "thumbnail_error": "Lhan-imaz toiar kortana chuk zali. Karonn: $1",
-       "tooltip-pt-userpage": "Tujem vapuddpachem pan",
-       "tooltip-pt-mytalk": "Tumchem bhasabhasachem pan",
-       "tooltip-pt-preferences": "Tumcheo avddi",
+       "tooltip-pt-userpage": "{{GENDER:|Tujem vapuddpachem}} pan",
+       "tooltip-pt-mytalk": "{{GENDER:|Tumchem}} bhasabhasachem pan",
+       "tooltip-pt-preferences": "{{GENDER:|Tumcheo}} avddi",
        "tooltip-pt-watchlist": "Bodlachea dekhrekh korpachea panachi volleri",
-       "tooltip-pt-mycontris": "Tujea yogdanachi suchi",
+       "tooltip-pt-mycontris": "{{GENDER:|Tujea}} yogdanachi suchi",
        "tooltip-pt-login": "Tumkam sotrormbh korunk protsavan asa; pun hem soktichem nhoi",
        "tooltip-pt-logout": "Sotr xevott",
        "tooltip-pt-createaccount": "Tumi khatem ugdun sotrorombh korunk protsavn asa; pun toxi sokti nam",
        "tooltip-t-whatlinkshere": "Hanga zoddlelea sogllea wiki pananchi volleri",
        "tooltip-t-recentchangeslinked": "Hea panak-sun zoddlelea panachim halinche bodol",
        "tooltip-feed-atom": "Hea panak Atom purovnni",
-       "tooltip-t-contributions": "Hea vapuddpeachea yogdanachi suchi",
+       "tooltip-t-contributions": "{{GENDER:$1|Hea vapuddpeachea}} yogdanachi suchi",
        "tooltip-t-emailuser": "Hea vapuddpeak email patthoi",
        "tooltip-t-upload": "Faili upload kor",
        "tooltip-t-specialpages": "Sogllea khaxelim pananchi volleri",
index 04b85f1..936af3f 100644 (file)
        "uploaded-script-svg": "Ir ufegladnigen SVG-Datei het’s ds Skript-Elemänt «$1».",
        "uploaded-hostile-svg": "Im Style-Elemänt vor ufegladnigen SVG-Datei het’s unsichers CSS.",
        "uploaded-event-handler-on-svg": "I SVG-Dateien isch ds Event-Handler-Attribut <code>$1=\"$2\"</code> nid erloubt.",
-       "uploaded-href-attribute-svg": "I SVG-Dateien isch ds href-Attribut <code>&lt;$1 $2=\"$3\"&gt;</code> mit emne nid-lokale Zil (byspilswys http://, javascript: etc.) nid erloubt.",
        "uploaded-href-unsafe-target-svg": "Ir ufegladnige SVG-Datei het’s es href uf ds unsichere Zil <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "Ir ufegladnigen SVG-Datei het’s en «animate»-Tag, wo über ds «from»-Attribut <code>&lt;$1 $2=\"$3\"&gt;</code> chönnt href ändere.",
        "uploaded-setting-event-handler-svg": "Ir ufegladnigen SVG-Datei het’s ds Event-Handler-Attribut <code>&lt;$1 $2=\"$3\"&gt;</code>. Event-Handler-Attribut sy nid erloubt.",
        "querypage-disabled": "Die Spezialsyte isch deaktiviert wore us Leischtigserhaltigs-Grind.",
        "apihelp": "API-Hilff",
        "apihelp-no-such-module": "Ds Modul «$1» lat sech nid la finde.",
+       "apisandbox": "API-Sandchaschte",
+       "apisandbox-api-disabled": "D API isch uf däm Wiki deaktiviert wore.",
+       "apisandbox-intro": "Die Syte chasch bruche fir Versuech mit dr '''MediaWiki-API'''.\nIn dr [//www.mediawiki.org/wiki/API:Main_page/de Dokumäntation zue dr API] het s no meh Hiiwys zue ihre Nutzig. Byschpel: [//www.mediawiki.org/wiki/API:Main_page/de#Beispiel Dr Inhalt vu dr Hauptsyte abruefe]. Fir meh Byschpel eini vu dr verfiegbare Aktionen uuswehle.",
+       "apisandbox-submit": "Aafrog uusfiere",
+       "apisandbox-reset": "Lääre",
+       "apisandbox-examples": "Byyschpil",
+       "apisandbox-results": "Ergebnis",
+       "apisandbox-request-url-label": "Aaforderigs-URL:",
+       "apisandbox-request-time": "Aafrogzyt: $1",
        "booksources": "ISBN-Suech",
        "booksources-search-legend": "Suech no Bezugsquälle fir Biecher",
        "booksources-search": "Sueche",
index 5f43e1e..6b75f8f 100644 (file)
        "querypage-disabled": "કાર્યક્ષમતાના કારણે આ ખાસ પાનું નિષ્ક્રિ કરાયું છે.",
        "apihelp": "API મદદ",
        "apihelp-no-such-module": "સાધન જૂથ \"$1\" ન મળ્યું.",
+       "apisandbox-submit": "વિનંતી કરો",
+       "apisandbox-reset": "સાફ કરો",
+       "apisandbox-examples": "ઉદાહરણ",
+       "apisandbox-results": "પરિણામ",
        "booksources": "પુસ્તક સ્રોત",
        "booksources-search-legend": "પુસ્તક સ્રોત શોધો",
        "booksources-isbn": "આઇએસબીએન:",
        "wlheader-showupdated": "તમારી છેલ્લી મુલાકાત પછી બદલાયેલાં પાના  '''ઘાટા''' અક્ષરો વડે દર્શાવ્યાં છે.",
        "wlnote": "નીચે $3, $4 વાગ્યા સુધીના છેલ્લા {{PLURAL:$2|એક કલાક|'''$2''' કલાક}}માં થયેલા {{PLURAL:$1|ફેરફાર|'''$1''' ફેરફારો }} દર્શાવ્યા છે.",
        "wlshowlast": "છેલ્લા $1 કલાકો $2 દિવસો બતાવો",
-       "watchlistall2": "બધા",
        "watchlist-options": "ધ્યાનસૂચિના વિકલ્પો",
        "watching": "નજર રાખી રહ્યાં છો...",
        "unwatching": "નજર રાખવાની બંધ કરી છે...",
        "enotif_lastvisited": "તમારી પાછલી મુલાકાત પછી થયેલા બધા ફેરફારો માટે $1 જુઓ",
        "enotif_lastdiff": "આ ફેરફાર જોવા $1 જુઓ",
        "enotif_anon_editor": "અનામિ સભ્ય $1",
-       "enotif_body": "પ્રિય $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nફેરફારોનો સારાંશ: $PAGESUMMARY $PAGEMINOREDIT\n\nસંપાદકનો સંપર્ક:\nઇમેલ: $PAGEEDITOR_EMAIL\nવિકિ: $PAGEEDITOR_WIKI\n\nજ્યાં સુધી તમે પ્રવેશ કરીને આ પાનાની મુલાકાત નહી લો ત્યાં સુધી તેમાં ભવિષ્યમાં થનાર કોઇ પણ ફેરફારની સૂચના તમને મળશે નહિ. તમે તમારી ધ્યાન સૂચિમાં તમે જોયેલા પાના સંબંધી સૂચનાને લાગતા વિકલ્પોમાં ફેરફાર કરી શકો છો.\n\n\nઆપની વિશ્વાસુ {{SITENAME}} સૂચના પ્રણાલી   \n\n--\nઇમેલ સૂચના પ્રણાલી બદલવા માટે, મુલાકાત લો\n{{canonicalurl:{{#special:Preferences}}}}\n\nતમારી ધ્યાનસૂચિની વિક્લ્પ ગોઠવણી માટે, મુલાકાત લો\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nધ્યાનસૂચિમાંથી પાનું હટાવવા માટે, મુલાકાત લો\n$UNWATCHURL\n\nમંતવ્યો અને વધુ મદદ માટે:\n$HELPPAGE",
+       "enotif_body": "પ્રિય $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nફેરફારોનો સારાંશ: $PAGESUMMARY $PAGEMINOREDIT\n\nસંપાદકનો સંપર્ક:\nઇમેલ: $PAGEEDITOR_EMAIL\nવિકિ: $PAGEEDITOR_WIKI\n\nજ્યાં સુધી તમે પ્રવેશ કરીને આ પાનાની મુલાકાત નહી લો ત્યાં સુધી તેમાં ભવિષ્યમાં થનાર કોઇ પણ ફેરફારની સૂચના તમને મળશે નહિ. તમે તમારી ધ્યાન સૂચિમાં તમે જોયેલા પાના સંબંધી સૂચનાને લાગતા વિકલ્પોમાં ફેરફાર કરી શકો છો.\n\nઆપની વિશ્વાસુ {{SITENAME}} સૂચના પ્રણાલી   \n\n--\nઇમેલ સૂચના પ્રણાલી બદલવા માટે, મુલાકાત લો\n{{canonicalurl:{{#special:Preferences}}}}\n\nતમારી ધ્યાનસૂચિની વિક્લ્પ ગોઠવણી માટે, મુલાકાત લો\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nધ્યાનસૂચિમાંથી પાનું હટાવવા માટે, મુલાકાત લો\n$UNWATCHURL\n\nમંતવ્યો અને વધુ મદદ માટે:\n$HELPPAGE",
        "created": "બનાવ્યું",
        "changed": "બદલ્યું",
        "deletepage": "પાનું હટાવો",
index 36ec2d7..ca39584 100644 (file)
        "createaccountreason": "原因:",
        "createacct-reason": "原因",
        "createacct-reason-ph": "汝做麽嘅愛創建另一隻帳號",
-       "createacct-captcha": "安全檢查",
-       "createacct-imgcaptcha-ph": "輸入汝在上背看到嘅字符",
        "createacct-submit": "建立帳號",
        "createacct-benefit-heading": "{{SITENAME}}是由撈您共樣嘅人建立。",
        "createacct-benefit-body1": "$1次編寫",
        "resetpass-temp-password": "臨時密碼:",
        "resetpass-abort-generic": "擴充插件已中止矣更改密碼操作。",
        "passwordreset": "重設密碼",
-       "passwordreset-legend": "重置密码",
        "passwordreset-disabled": "邇隻維基上已禁止矣重設密碼。",
        "passwordreset-emaildisabled": "電子郵件功能在此 wiki 上已禁用。",
        "passwordreset-username": "用戶名:",
        "passwordreset-capture-help": "係講汝選中邇隻框,電子郵件(包括臨時密碼)將顯示,並發送分用戶。",
        "passwordreset-email": "電郵地址:",
        "passwordreset-emailtitle": "在{{SITENAME}}上嘅詳細信息",
-       "passwordreset-emailsent": "密碼重置電子郵件已發送。",
+       "passwordreset-emailsentemail": "密碼重置電子郵件已發送。",
        "changeemail": "更改電子郵件地址",
+       "changeemail-header": "更改電子郵件帳戶",
        "changeemail-no-info": "汝必須登入後直接進入邇隻頁面。",
        "changeemail-oldemail": "當前電郵地址:",
        "changeemail-newemail": "新嘅電郵地址:",
        "default": "默認",
        "prefs-files": "文件",
        "youremail": "電子郵件:",
-       "username": "Yung-fu miàng-chhṳ̂n:",
+       "username": "{{GENDER:$1|用戶名稱}}:",
        "yourrealname": "真名:",
        "yourlanguage": "語言:",
        "yourvariant": "Sṳ-thí pien-von:",
-       "yournick": "Kién-chhṳ̂n:",
+       "yournick": "新个簽名:",
        "badsig": "錯誤嘅原始簽名。請檢查HTML標籤。",
        "badsiglength": "Tshiâm-miàng ko-liong.\nTshòng-tón pit-sî chhai $1-ke sṳ-ngièn yî-ha.",
        "email": "電子郵件",
        "destfilename": "目標文件名",
        "watchthisupload": "監視本文件",
        "filewasdeleted": "早先已經有一隻同名文件分上傳後又分刪除矣。在上傳邇文件之前汝愛檢查$1。",
-       "upload-success-subj": "上傳成功",
        "upload-proto-error": "協議毋著",
        "upload-proto-error-text": "遠程上傳要求URL以<code>http://</code>或 <code>ftp://</code>開頭。",
        "upload-file-error": "內部差錯",
        "nlinks": "$1隻鏈接",
        "nmembers": "$1隻成員",
        "nrevisions": "$1隻修訂版本",
-       "nviews": "$1次瀏覽",
        "specialpage-empty": "本報告無結果。",
        "lonelypages": "孤立頁面",
        "lonelypagestext": "Yî-ha vùn-chông mò-yû lièn-kiet liá-ke wiki chûng ke khì-thâ vùn-chông.",
        "mailnologin": "無電郵地址",
        "mailnologintext": "汝必須先[[Special:UserLogin|登入]]\n並在[[Special:Preferences|偏好設定]]\n肚有一隻有效嘅電郵地址正做得發郵件分其他用戶。",
        "emailuser": "電郵聯繫邇隻用戶",
-       "emailpage": "電郵聯繫用戶",
        "emailpagetext": "Kó-yèn ke-yung-fu yí-kîn chhai chhâm-su sat-chṳ chông chûng sû-ngi̍p yû-háu ke e-mail thi-tiám, yî-ha ke péu-kak chiông-ki yit-ke sêu-sit pûn ke-yung-fu. Ngì chhai chhâm-su sat-chṳ chûng só sû-ngi̍p ke e-mail thi-tiám chiông chhut-hien chhai email \"fat-khien-ngìn\" yit-làn-chûng, liá-yong ke-yung-fu chhiu khó-yî fì-fu̍k.",
        "defemailsubject": "{{SITENAME}} Email",
        "noemailtitle": "電郵地址:",
        "deleteotherreason": "其它/附加理由:",
        "deletereasonotherlist": "其它理由",
        "rollback": "編寫倒轉頭",
-       "rollback_short": "倒轉頭",
        "rollbacklink": "打轉頭",
        "rollbackfailed": "無法倒轉頭",
        "cantrollback": "編寫無法打轉頭;最後嘅貢獻者人本文嘅唯一作者。",
        "protect-cascadeon": "下背嘅$1嘅頁面包含緊本頁面嘅同時,還啟動矣連鎖保護,故所本頁面目前也分保護,還㬟做得編寫。汝做得設定本頁面嘅保護級別,毋過邇影響毋到連鎖保護。",
        "protect-default": "容許所有用戶",
        "protect-fallback": "Sî-yeu \"$1\" ke hí-khó",
-       "protect-level-autoconfirmed": "Kim-chṳ́  sîn-ke lâu hàn-mò chu-chhak ke yung-fu",
+       "protect-level-autoconfirmed": "只有已經自動確定个用戶",
        "protect-level-sysop": "Kón-lî-yèn chôn-cho",
        "protect-summary-cascade": "連鎖",
        "protect-expiring": "終止於$1(UTC)",
        "sp-contributions-uploads": "上傳",
        "sp-contributions-logs": "日誌",
        "sp-contributions-talk": "交流",
-       "sp-contributions-userrights": "Yung-fu khièn-han kón-lî",
+       "sp-contributions-userrights": "用戶權限管理",
        "sp-contributions-search": "搜尋貢獻記錄",
        "sp-contributions-username": "IP地址或用戶名:",
        "sp-contributions-toponly": "單淨展示最新修訂版本嘅編寫",
        "move-page-legend": "Yì-thung vùn-chông",
        "movepagetext": "Yung ha-mien ke péu-tân lòi chhùng-sîn min-miàng yit-ke vùn-chông, pin chiông siû-thin li̍t-sṳ́ thùng-sṳ̀ yì-thung to sîn vùn-chông.\nLó-ke vùn-chông chiông sṳ̀n-vì sîn vùn-chông ke chhûng-thin hong-mien.\nLièn-kiet to ló vùn-chông ke lièn-kiet pin-mò chhṳ-thung kiên-kói;\nchhiáng kiám-chhà sûng-chhûng fe̍t-he sún-fái chhûng-thin-hiong lièn-kiet.\nYin-tông fu-chit khok-thin só-yû lièn-kiet chiông-voi lièn-to chṳ́-thin ke vùn-chông.\n\nChu-yi kó-yèn sîn vùn-chông yí-kîn yû nui-yùng, vùn-chông chiông '''put-voi''' pûn yì-thung, chhù-fî sîn vùn-chông mò nui-yùng fe̍t-he chhûng-thin-hiong, yì-yèn mò-yû siû-thin li̍t-sṳ́.\nNgì chai pit-yeu sṳ̀ khó-yî chhai yì-thung to sîn vùn-chông heu chai yì-fì ló-ke vùn-chông, thùng-sṳ̀ ya-he vù-fap koi-hien yû hong-mien.\n\n'''Kín-ko!'''\nTui yit-ke kîn-sòng pûn fóng-mun ke vùn-chông lòi ngièn, liá khó-nèn he yit-ke chṳ̂n-thai khi̍p thòng-thu̍t ke kiên-kói;\nchhiáng chhai hàng-thung chṳ̂-chhièn siên liáu-kié khì-thâ khó-nèn tai-lòi ke heu-kó.",
        "movepagetalktext": "Yû-kôan ke tui-fa-hiong chiông-voi pûn chhṳ-thung lâu ke-vùn-chông yit-hí yì-thung, '''chhù-fî''':\n*Ngì chiông vùn-chông yì-thung to siông-thùng ke miàng-sṳ, fe̍t-chá\n*Sîn vùn-chông yí-kîn yû yit-ke pâu-hàm nui-yùng ke tui-fa-hiong, fe̍t-he\n*Ngì put kiêu-sién ha-mien ke fu̍k-sién khiông. Chhai liá-chúng chhìn-khóng hâ, pit-sî sú-kûng yì-thung fe̍t-he ha̍p-phîn vùn-chông.",
-       "movearticle": "Yì-thung vùn-chông",
        "movenologintext": "Ngì pit-sî he yit-miàng tên-ki yung-fu pin-chhiâ [[Special:UserLogin|tên-ngi̍p]] heu chhòi-nèn Yì-thung yit-ke vùn-chông.",
        "newtitle": "新標題:",
        "move-watch": "Kam-sṳ chhṳ́-chông",
        "movelogpagetext": "Yî-ha he yí-kîn yì-thung ke vùn-chông chhîn-tân.",
        "movereason": "原因:",
        "revertmove": "恢復",
-       "delete_and_move": "刪除並移動",
        "delete_and_move_text": "==愛刪除==\n\n目標頁面\"[[:$1]]\"已經存在。汝確認愛刪除原頁面並進行移動係無?",
        "delete_and_move_confirm": "著,刪除邇頁",
        "delete_and_move_reason": "Chhù-thet yî-phien yì-thung",
        "import-interwiki-text": "選擇一隻wiki撈頁面標題進行導入。\n修訂日期與編寫人嘅名會分保存。\n所有嘅跨wiki導入操作分記錄在[[Special:Log/import|導入日誌]]肚。",
        "import-interwiki-history": "Fuk-chṳ chhṳ́-chông ke só-yû li̍t-sṳ́ pán-pún",
        "import-interwiki-submit": "導入",
-       "import-interwiki-namespace": "Chiông vùn-chông chón-yì to miàng-sṳ khûng-kiên:",
        "importtext": "Chhiáng sṳ́-yung Special:Export kûng-nèn chhiùng-ngièn wiki thô-chhuttóng-on, tú-chhùn to ngì ke-phién pin song-chhòn to liá-piên.",
        "importstart": "頁面導入中……",
        "import-revision-count": "$1-ke siû-thin",
        "importnofile": "無上傳導入文件。",
        "importlogpage": "導入日誌",
        "importlogpagetext": "管理性導入在其他Wiki上有編寫歷史嘅頁面",
-       "import-logentry-upload": "Theu-ko tóng-on sông-chhòn thô-ngi̍p ke $1",
        "import-logentry-upload-detail": "$1-ke siû-thin",
-       "import-logentry-interwiki": "Khiam-wiki $1",
        "import-logentry-interwiki-detail": "Lòi-chhṳ $2-ke $1-ke siû-thin",
        "tooltip-pt-userpage": "汝嘅用戶頁面",
        "tooltip-pt-anonuserpage": "Ngì-ke phiên-siá pún-chham só yung IP ke tui-yin yung-fu-chông",
        "markedaspatrollederror": "Put-nèn phêu-ki sṳ̀n-vì yí-kîn kiám-chhà",
        "markedaspatrollederrortext": "Ngì sî-yeu chṳ́-thin mêu-ke pán-pún chhòi-nèn phêu-ki sṳ̀n-vì yí-kîn kiám-chhà.",
        "markedaspatrollederror-noautopatrol": "Ngì mò-fap chiông ngì chhṳ-kí só-chok ke kiên-kói phêu-ki sṳ̀n-vì yí-kîn kiám-chhà.",
-       "patrol-log-page": "Sùn-chhà ki-liu̍k",
+       "patrol-log-page": "巡邏檢查日誌",
        "deletedrevision": "已刪除舊版本$1",
        "previousdiff": "←上隻版本",
        "nextdiff": "下隻版本→",
index 23edb04..60c49d0 100644 (file)
@@ -32,7 +32,8 @@
                        "LaG roiL",
                        "Eraab",
                        "Geagea",
-                       "פוילישער"
+                       "פוילישער",
+                       "DatGuy"
                ]
        },
        "tog-underline": "סימון קישורים בקו תחתי:",
        "changepassword-success": "סיסמתך שונתה בהצלחה!",
        "changepassword-throttled": "ביצעתם לאחרונה ניסיונות רבים מדי להיכנס לחשבון זה.\nאנא המתינו $1 לפני שתנסו שוב.",
        "botpasswords": "ססמאות בוט",
-       "botpasswords-summary": "<em>סס×\9e×\90×\95ת ×\91×\95×\98</em> ×\9e×\90פשר×\95ת ×\9bנס×\94 ×\9c×\97ש×\91×\95×\9f ×\9eשת×\9eש ×\93ר×\9a API ×\9c×\9c×\90 ×©×\99×\9e×\95ש ×\91נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת ×\94ר×\90ש×\99×\99×\9d ×©×\9c ×\94×\97ש×\91×\95×\9f. ×\94רש×\90×\95ת ×\94×\9eשת×\9eש ×©×\96×\9e×\99× ×\95ת ×\9c×\9eשת×\9eש ×©× ×\9bנס ×¢×\9d ×¡×¡×\9eת ×\91×\95×\98 ×\99×\9b×\95×\9c×\95ת ×\9c×\94×\99×\95ת ×\9e×\95×\92×\91×\9c×\95ת.",
-       "botpasswords-disabled": "סס×\9e×\90×\95ת ×\91×\95×\98 ×\9b×\91×\95×\99×\95ת.",
-       "botpasswords-no-central-id": "×\9b×\93×\99 ×\9c×\94שת×\9eש ×\91סס×\9e×\90×\95ת ×\91×\95×\98, ×\99ש ×\9c×\94×\99×\9bנס ×\9c×\97ש×\91×\95×\9f ×\9eר×\9b×\96×\99.",
+       "botpasswords-summary": "<em>סס×\9e×\90×\95ת ×\91×\95×\98</em> ×\9e×\90פשר×\95ת ×\9b× ×\99ס×\94 ×\9c×\97ש×\91×\95×\9f ×\9eשת×\9eש ×\91×\90×\9eצע×\95ת API, ×\9c×\9c×\90 ×©×\99×\9e×\95ש ×\91נת×\95× ×\99 ×\94×\94×\96×\93×\94×\95ת ×\94ר×\90ש×\99×\99×\9d ×©×\9c ×\94×\97ש×\91×\95×\9f. × ×\99ת×\9f ×\9c×\94×\92×\91×\99×\9c ×\90ת ×\94רש×\90×\95ת ×\94×\9eשת×\9eש ×\94×\96×\9e×\99× ×\95ת ×\9b×\90שר × ×\9bנס×\99×\9d ×¢×\9d ×¡×¡×\9eת ×\91×\95×\98.",
+       "botpasswords-disabled": "×\90פשר×\95ת ×\94ש×\99×\9e×\95ש ×\91סס×\9e×\90×\95ת ×\91×\95×\98 ×\9e×\91×\95×\98×\9cת.",
+       "botpasswords-no-central-id": "×\9b×\93×\99 ×\9c×\94שת×\9eש ×\91סס×\9e×\90×\95ת ×\91×\95×\98, ×\99ש ×\9c×\94×\99×\9bנס ×¢×\9d ×\97ש×\91×\95×\9f ×\9eשת×\9eש ×\9e×\90×\95×\97×\93.",
        "botpasswords-existing": "ססמאות בוט קיימות",
        "botpasswords-createnew": "יצירת ססמת בוט חדשה",
        "botpasswords-editexisting": "עריכת ססמת בוט קיימת",
        "botpasswords-label-delete": "מחיקה",
        "botpasswords-label-resetpassword": "איפוס ססמה",
        "botpasswords-label-grants": "זיכיונות מתאימים",
-       "botpasswords-help-grants": "×\9b×\9c ×\96×\99×\9b×\99×\95×\9f × ×\95ת×\9f ×\92×\99ש×\94 ×\9c×\94רש×\90×\95ת ×\9eשת×\9eש ×¨×©×\95×\9e×\95ת ×©×\9b×\91ר ×\99ש ×\9c×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש. ×¨' ×\90ת [[Special:ListGrants|טבלת הזיכיונות]] למידע נוסף.",
+       "botpasswords-help-grants": "×\9b×\9c ×\96×\99×\9b×\99×\95×\9f × ×\95ת×\9f ×\92×\99ש×\94 ×\9c×\94רש×\90×\95ת ×\9eשת×\9eש ×¨×©×\95×\9e×\95ת ×©×\99ש ×\9c×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש. ×¢×\99×\99× ×\95 ×\91[[Special:ListGrants|טבלת הזיכיונות]] למידע נוסף.",
        "botpasswords-label-restrictions": "הגבלות שימוש:",
        "botpasswords-label-grants-column": "ניתן זיכיון",
-       "botpasswords-bad-appid": "ש×\9d ×\94×\91×\98×\95 \"$1\" אינו תקין.",
+       "botpasswords-bad-appid": "ש×\9d ×\94×\91×\95×\98 \"$1\" אינו תקין.",
        "botpasswords-insert-failed": "הוספת שם הבוט \"$1\" נכשלה. האם הוא כבר נוסף?",
        "botpasswords-update-failed": "לא היה אפשר לעדכן את שם הבוט \"$1\". האם הוא נמחק?",
-       "botpasswords-created-title": "ססמת בוט נוצרה",
+       "botpasswords-created-title": "סס×\9eת ×\94×\91×\95×\98 × ×\95צר×\94",
        "botpasswords-created-body": "ססמת הבוט \"$1\" נוצרה בהצלחה.",
        "botpasswords-updated-title": "ססמת הבוט עודכנה",
        "botpasswords-updated-body": "ססמת הבוט \"$1\" עודכנה בהצלחה.",
        "botpasswords-deleted-title": "ססמת הבוט נמחקה",
        "botpasswords-deleted-body": "ססמת הבוט \"$1\" נמחקה.",
-       "botpasswords-newpassword": "הססמה החדשה לכניסה <strong>$1</strong> היא <strong>$2</strong>. נא לרשום את זה לעיון עתידי.",
+       "botpasswords-newpassword": "הססמה החדשה לכניסה <strong>$1</strong> היא <strong>$2</strong>. <em>נא לשמור מידע זה לצורך עיון עתידי.</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider אינו זמין.",
-       "botpasswords-restriction-failed": "×\94×\92×\91×\9c×\95ת ×©×\9c ×¡×¡×\9eת ×\91×\95×\98 ×\9e×\95× ×¢×\95ת ×\90ת ×\94×\9b× ×\99ס×\94 ×\94×\96×\90ת.",
-       "botpasswords-invalid-name": "ש×\9d ×\94×\9eשת×\9eש ×©× ×\99ת×\9f ×\90×\99× ×\95 ×\9e×\9b×\99×\9c ×\90ת ×¤×¨×\99×\93 ססמאות הבוט (\"$1\").",
+       "botpasswords-restriction-failed": "×\9b× ×\99ס×\94 ×\96×\95 × ×\9e× ×¢×\94 ×\91ש×\9c ×\94×\92×\91×\9c×\95ת ×¢×\9c ×¡×¡×\9e×\90×\95ת ×\91×\95×\98.",
+       "botpasswords-invalid-name": "ש×\9d ×\94×\9eשת×\9eש ×©× ×\99ת×\9f ×\90×\99× ×\95 ×\9e×\9b×\99×\9c ×\90ת ×ª×\95 ×\94פר×\93ת ססמאות הבוט (\"$1\").",
        "botpasswords-not-exist": "למשתמש \"$1\" אין ססמת בוט בשם \"$2\".",
        "resetpass_forbidden": "לא ניתן לשנות סיסמאות.",
        "resetpass-no-info": "נדרשת כניסה לחשבון כדי לגשת לדף זה באופן ישיר.",
        "right-applychangetags": "החלת [[Special:Tags|תגיות]] יחד עם שינויים",
        "right-changetags": "הוספת והסרה של [[Special:Tags|תגיות]] כלשהן לגרסאות מסוימות ולרשומות יומן",
        "grant-generic": "חבילת ההרשאות \"$1\"",
-       "grant-group-page-interaction": "פע×\99×\9c×\95ת ×\94×\99×\93×\95×\93×\99ת ×\91דפים",
-       "grant-group-file-interaction": "פע×\99×\9c×\95ת ×\94×\99×\93×\95×\93×\99ת ×\91×\9e×\93×\99×\94",
-       "grant-group-watchlist-interaction": "פע×\99×\9c×\95ת ×\94×\99×\93×\95×\93×\99ת ×\91רשימת המעקב שלך",
+       "grant-group-page-interaction": "×\90×\99× ×\98ר×\90קצ×\99×\94 ×¢×\9d דפים",
+       "grant-group-file-interaction": "×\90×\99× ×\98ר×\90קצ×\99×\94 ×¢×\9d ×§×\91צ×\99×\9d",
+       "grant-group-watchlist-interaction": "×\90×\99× ×\98ר×\90קצ×\99×\94 ×¢×\9d רשימת המעקב שלך",
        "grant-group-email": "שליחת דוא\"ל",
        "grant-group-high-volume": "ביצוי פעולות מרובות",
        "grant-group-customization": "התאמה אישית והעדפות",
        "grant-blockusers": "חסימת משתמשים ושחרורם",
        "grant-createaccount": "יצירת חשבונות",
        "grant-createeditmovepage": "יצירה, עריכה והעברה של דפים",
-       "grant-delete": "×\9e×\97×\99קת ×\93פ×\99×\9d, ×\92רס×\90×\95ת ×\95×¢×\99×\95×\9c×\99 יומן",
+       "grant-delete": "×\9e×\97×\99קת ×\93פ×\99×\9d, ×\92רס×\90×\95ת ×\95רש×\95×\9e×\95ת יומן",
        "grant-editinterface": "עריכת מרחב השם מדיה ויקי ו־CSS/JavaScript של משתמשים",
        "grant-editmycssjs": "עריכת CSS/JavaScript שלך",
        "grant-editmyoptions": "עריכת העדפות המשתמש שלך",
        "grant-uploadfile": "העלאת קבצים חדשים",
        "grant-basic": "הרשאות בסיסיות",
        "grant-viewdeleted": "צפייה בקבצים ודפים שנמחקו",
-       "grant-viewmywatchlist": "צפייה ברשימת מעקב שלך",
+       "grant-viewmywatchlist": "צפ×\99×\99×\94 ×\91רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a",
        "newuserlogpage": "יומן רישום משתמשים",
        "newuserlogpagetext": "זהו יומן המכיל הרשמות של משתמשים.",
        "rightslog": "יומן תפקידים",
        "uploaded-script-svg": "נמצא אלמנט שאפשר לכתוב בו תסריט \"$1\" בקובץ ה־SVG שהועלה.",
        "uploaded-hostile-svg": "נמצא CSS בלתי־מאובטח באלמנט style בקובץ ה־SVG שהועלה.",
        "uploaded-event-handler-on-svg": "אסור להגדיר מאפייני טיפול באירועים <code dir=\"ltr\">$1=\"$2\"</code> בקובצי SVG.",
-       "uploaded-href-attribute-svg": "×\9e×\90פ×\99×\99× ×\99 href ×\91צ×\95רת <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> ×¢×\9d ×\99×¢×\93 ×\91×\9cת×\99Ö¾×\9eק×\95×\9e×\99 (×\9c×\9eש×\9c http://â\80\8eâ\80\8f, javascript:â\80\8e, ×\95×\9b×\95') ×\90ס×\95ר×\99×\9d ×\91ק×\95×\91צ×\99 SVG.",
-       "uploaded-href-unsafe-target-svg": "× ×\9eצ×\90 href ×\9c×\99×¢×\93 ×\91×\9cת×\99Ö¾×\9e×\90×\95×\91×\98×\97 <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> בקובץ ה־SVG שהועלה.",
+       "uploaded-href-attribute-svg": "×\9c×\9e×\90פ×\99×\99× ×\99 href ×\91ק×\95×\91צ×\99 SVG ×\9e×\95תר ×\9cקשר ×¨×§ ×\9c×\99×¢×\93×\99 http ×\90×\95 https, ×\95× ×\9eצ×\90 <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "× ×\9eצ×\90 href ×\9cנת×\95× ×\99×\9d ×\9c×\90 ×\9e×\90×\95×\91×\98×\97×\99×\9d <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> בקובץ ה־SVG שהועלה.",
        "uploaded-animate-svg": "נמצא תג \"animate\" שיכול לשנות href באמצעות מאפיין \"from\"  בצורת <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> בקובץ ה־SVG שהועלה.",
        "uploaded-setting-event-handler-svg": "הגדרת מאפייני טיפול באירועים חסומה, נמצא <code dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code> בקובץ ה־SVG שהועלה.",
        "uploaded-setting-href-svg": "השימוש בתג set כדי להוסיף מאפיין href לאלמנט הורה חסום.",
        "upload-too-many-redirects": "הכתובת מכילה הפניות רבות מדי",
        "upload-http-error": "התרחשה שגיאת HTTP‏: $1",
        "upload-copy-upload-invalid-domain": "העלאת קבצים משרת זה אינה אפשרית.",
-       "upload-foreign-cant-upload": "×\91×\95×\95×\99ק×\99 ×\94×\96×\94 ×\9c×\90 ×\9e×\95×\92×\93ר ×\90×\99×\9a ×\9c×\94×¢×\9c×\95ת ×§×\91צ×\99×\9d ×\9c×\9e×\90×\92ר ×§×\91צ×\99×\9d ×\96ר.",
+       "upload-foreign-cant-upload": "×\91×\90תר ×\94×\95×\95×\99ק×\99 ×\94×\96×\94 ×\9c×\90 ×\9e×\95פע×\9cת ×\94×\90פשר×\95ת ×\9c×\94×¢×\9c×\90ת ×§×\91צ×\99×\9d ×\9c×\9e×\90×\92ר ×\94ק×\91צ×\99×\9d ×\94×\96ר ×\94×\9e×\91×\95קש.",
        "upload-dialog-title": "העלאת קובץ",
        "upload-dialog-button-cancel": "ביטול",
        "upload-dialog-button-done": "בוצע",
        "querypage-disabled": "דף מיוחד זה מבוטל עקב בעיות ביצועים.",
        "apihelp": "עזרה עבור ה־API",
        "apihelp-no-such-module": "המודול \"$1\" לא נמצא.",
+       "apisandbox": "ארגז החול של ה־API",
+       "apisandbox-jsonly": "דרוש JavaScript כדי להשתמש בארגז החול של ה־API.",
+       "apisandbox-api-disabled": "API אינו פעיל באתר הזה.",
+       "apisandbox-intro": "השתמשו בדף הזה כדי להתנסות בשימוש ב<strong>שירות ה־API המבוסס Web של מדיה־ויקי</strong>.\nעיינו ב[[mw:API:Main page|תיעוד של ה־API]] (באנגלית) למידע נוסף של שימוש ב־API. למשל: [//www.mediawiki.org/wiki/API#A_simple_example איך לקבל את התוכן של העמוד הראשי]. בחרו באחת הפעולות (actions) לדוגמאות נוספות.\n\nשימו לב שאף שמדובר ב\"ארגז חול\", פעולות שנעשות כאן עשויות לשנות את התוכן של אתר הוויקי.",
+       "apisandbox-fullscreen": "הרחבת הפאנל",
+       "apisandbox-fullscreen-tooltip": "הרחבת הפאנל של ארגז החול כך שימלא את חלון הדפדפן.",
+       "apisandbox-unfullscreen": "הצגת הדף",
+       "apisandbox-unfullscreen-tooltip": "הקטנת הפאנל של ארגז החול, כך שקישורי הניווט של מדיה־ויקי יהיו זמינים לשימוש.",
+       "apisandbox-submit": "ביצוע שאילתה",
+       "apisandbox-reset": "ניקוי",
+       "apisandbox-retry": "ניסיון נוסף",
+       "apisandbox-loading": "המידע עבור מודול ה־API‏ \"$1\" בטעינה...",
+       "apisandbox-load-error": "אירעה שגיאה בעת טעינת המידע של מודול ה־API‏ \"$1\"‏: $2",
+       "apisandbox-no-parameters": "למודול ה־API אין פרמטרים.",
+       "apisandbox-helpurls": "קישורי עזרה",
+       "apisandbox-examples": "דוגמאות",
+       "apisandbox-dynamic-parameters": "פרמטרים נוספים",
+       "apisandbox-dynamic-parameters-add-label": "הוספת פרמטר:",
+       "apisandbox-dynamic-parameters-add-placeholder": "שם הפרמטר",
+       "apisandbox-dynamic-error-exists": "פרמטר בשם \"$1\" כבר קיים.",
+       "apisandbox-deprecated-parameters": "פרמטרים מיושנים",
+       "apisandbox-fetch-token": "מילוי אוטומטי של האסימון",
+       "apisandbox-submit-invalid-fields-title": "חלק מהשדות אינם תקינים",
+       "apisandbox-submit-invalid-fields-message": "אנא תקנו את השדות המסומנים ונסו שוב.",
+       "apisandbox-results": "תוצאות",
+       "apisandbox-sending-request": "בקשת ה־API בשליחה...",
+       "apisandbox-loading-results": "תוצאות ה־API בתהליך קבלה...",
+       "apisandbox-results-error": "אירעה שגיאה בעת טעינת תשובת ה־API לבקשה: $1.",
+       "apisandbox-request-url-label": "כתובת ה־URL של הבקשה:",
+       "apisandbox-request-time": "זמן הבקשה: {{PLURAL:$1|מילישנייה אחת|$1 מילישניות}}",
+       "apisandbox-results-fixtoken": "אנא תקנו את האסימון ושלחו שוב",
+       "apisandbox-results-fixtoken-fail": "קבלת האסימון \"$1\" נכשלה.",
+       "apisandbox-alert-page": "שדות בדף זה אינם תקינים.",
+       "apisandbox-alert-field": "הערך של שדה זה אינו תקין.",
        "booksources": "משאבי ספרות חיצוניים",
        "booksources-search-legend": "חיפוש משאבי ספרות חיצוניים",
        "booksources-isbn": "מסת\"ב (ISBN):",
        "block-log-flags-hiddenname": "שם המשתמש הוסתר",
        "range_block_disabled": "האפשרות לחסום טווח כתובות אינה פעילה.",
        "ipb_expiry_invalid": "זמן פקיעת החסימה אינו תקין.",
-       "ipb_expiry_old": "×\96×\9e×\9f ×ª×¤×\95×\92×\94 ×\91עבר.",
+       "ipb_expiry_old": "×\96×\9e×\9f ×\94תפ×\95×\92×\94 ×\9b×\91ר עבר.",
        "ipb_expiry_temp": "חסימות הכוללות הסתרת שם משתמש חייבות להיות לזמן בלתי מוגבל.",
        "ipb_hide_invalid": "לא ניתן להעלים את החשבון הזה; {{PLURAL:$1|בוצעה ממנו יותר מעריכה אחת|בוצעו ממנו יותר מ‏‏֫־$1 עריכות}}.",
        "ipb_already_blocked": "המשתמש \"$1\" כבר נחסם.",
        "version-libraries-license": "רישיון",
        "version-libraries-description": "תיאור",
        "version-libraries-authors": "יוצרים",
-       "redirect": "×\94פנ×\99×\94 ×\9cפ×\99 ×§×\95×\91×¥, ×\9eשת×\9eש, ×\93×£, ×\92רס×\94 ×\90×\95 ×\9e×\96×\94×\94 ×\99×\95×\9e×\9dן",
+       "redirect": "×\94פנ×\99×\94 ×\9cפ×\99 ×©×\9d ×§×\95×\91×¥, ×\9eספר ×\9eשת×\9eש, ×\9eספר ×\93×£, ×\9eספר ×\92רס×\94 ×\90×\95 ×\9e×\96×\94×\94 ×\99×\95×\9eן",
        "redirect-legend": "הפניה לקובץ או לדף",
-       "redirect-summary": "×\93×£ ×\9e×\99×\95×\97×\93 ×\96×\94 ×\9eפנ×\94 ×\9cק×\95×\91×¥ (×\91×\94×\99נת×\9f ×©×\9d ×\94ק×\95×\91×¥), ×\9c×\93×£ (×\91×\94×\99נת×\9f ×\9eספר ×\92רס×\94 ×\90×\95 ×\9eספר ×\93×£), ×\90×\95 ×\9c×\93×£ ×\9eשת×\9eש (×\91×\94×\99נת×\9f ×\9eספר ×\9eשת×\9eש), ×\90×\95 ×¢×\99×\95×\9c יומן (בהינתן מזהה יומן). דוגמאות לשימוש: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], או [[{{#Special:Redirect}}/user/101]], או [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-summary": "×\93×£ ×\9e×\99×\95×\97×\93 ×\96×\94 ×\9eפנ×\94 ×\9cק×\95×\91×¥ (×\91×\94×\99נת×\9f ×©×\9d ×\94ק×\95×\91×¥), ×\9c×\93×£ (×\91×\94×\99נת×\9f ×\9eספר ×\92רס×\94 ×\90×\95 ×\9eספר ×\93×£), ×\9c×\93×£ ×\9eשת×\9eש (×\91×\94×\99נת×\9f ×\9eספר ×\9eשת×\9eש), ×\90×\95 ×\9cרש×\95×\9eת יומן (בהינתן מזהה יומן). דוגמאות לשימוש: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], או [[{{#Special:Redirect}}/user/101]], או [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "מעבר",
        "redirect-lookup": "סוג:",
        "redirect-value": "ערך:",
        "api-error-blacklisted": "נא לבחור כותרת אחרת, המתארת טוב יותר את התוכן.",
        "sessionmanager-tie": "לא ניתן לצרף מספר סוגי אימות זהות: $1.",
        "sessionprovider-generic": "התחברויות של $1",
-       "sessionprovider-mediawiki-session-cookiesessionprovider": "×\94ת×\97×\91ר×\95×\99×\95ת ×\9e×\91×\95סס×\95ת־עוגיות",
-       "sessionprovider-nocookies": "×\90פשר ×\9c×\9b×\91×\95ת ×¢×\95×\92×\99×\95ת. ×\99ש ×\9c×\95×\95×\93×\90 ×©×\94×¢×\95×\92×\99×\95ת ×\9e×\95פע×\9c×\95ת ולהתחיל מחדש.",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "×\94ת×\97×\91ר×\95×\99×\95ת ×\94×\9e×\91×\95סס×\95ת ×¢×\9c עוגיות",
+       "sessionprovider-nocookies": "×\99×\99ת×\9b×\9f ×©×\90פשר×\95ת ×\94ש×\99×\9e×\95ש ×\91×¢×\95×\92×\99×\95ת ×\9b×\91×\95×\99×\94. ×\99ש ×\9c×\95×\95×\93×\90 ×©×\90פשר×\95ת ×\94ש×\99×\9e×\95ש ×\91×¢×\95×\92×\99×\95ת ×\9e×\95פע×\9cת ולהתחיל מחדש.",
        "randomrootpage": "דף שורש אקראי"
 }
index 53134ca..5af7555 100644 (file)
@@ -70,7 +70,8 @@
                        "Sfic",
                        "Niharika29",
                        "जनक राज भट्ट",
-                       "YmKavishwar"
+                       "YmKavishwar",
+                       "Upendradutt93"
                ]
        },
        "tog-underline": "कड़ियाँ अधोरेखन:",
        "october-date": "$1 अक्टूबर",
        "november-date": "$1 नवम्बर",
        "december-date": "$1 दिसम्बर",
+       "period-am": "पूर्वाह्न",
+       "period-pm": "अपराह्न",
        "pagecategories": "{{PLURAL:$1|श्रेणी|श्रेणियाँ}}",
        "category_header": "\"$1\" श्रेणी में पृष्ठ",
        "subcategories": "उपश्रेणियाँ",
        "resetpass_submit": "कूटशब्द बनाएँ और लॉग इन करें",
        "changepassword-success": "आपका कूटशब्द बदल दिया गया है!",
        "changepassword-throttled": "आपने हाल ही में कई बार लॉग इन करने के प्रयास किये हैं।\nपुनः प्रयास करने से पहले कृपया $1 प्रतीक्षा करें।",
+       "botpasswords-label-appid": "बॉट नाम:",
+       "botpasswords-label-create": "बनाएँ",
+       "botpasswords-label-update": "अद्यतन",
+       "botpasswords-label-cancel": "रद्द करें",
+       "botpasswords-label-delete": "हटाएँ",
        "resetpass_forbidden": "कूटशब्द बदले नहीं जा सकते",
        "resetpass-no-info": "इस पृष्ठ का सीधे प्रयोग करने के लिए आपको लॉग इन करना होगा।",
        "resetpass-submit-loggedin": "कूटशब्द बदलें",
        "right-managechangetags": "डेटाबेस से [[Special:Tags|चिप्पियाँ]] बनायें और हटायें",
        "right-applychangetags": "प्रयोग में लाइये [[Special:Tags|tags]] किसी के बदलाव के साथ।",
        "right-changetags": "जमा करो और हटाओ स्वतंत्र [[Special:Tags|टैग]] व्यक्तिगत अवतरणों और लॉग प्रविक्तियों पर",
+       "grant-group-email": "ई-मेल भेजें",
+       "grant-createaccount": "खाता बनाएँ",
+       "grant-basic": "सामान्य अधिकार",
+       "grant-viewmywatchlist": "अपनी ध्यानसूची देखें",
        "newuserlogpage": "सदस्य खाता निर्माण लॉग",
        "newuserlogpagetext": "यह सदस्य खातों के निर्माण का लॉग है।",
        "rightslog": "सदस्य अधिकार लॉग",
        "uploaded-script-svg": "अपलोड की गयी एसवीजी फ़ाइल में स्क्रीप्ट अवयव \"$1\" पाया गया।",
        "uploaded-hostile-svg": "अपलोड की गयी एसवीजी फाइल के शैली अवयव में असुरक्षित सीएसएस पायी गयी।",
        "uploaded-event-handler-on-svg": "सेटिंग ईवेंट हैंडलर (आयोजन प्रबन्धनकर्ता वरियता) <code>$1=\"$2\"</code> एसवीजी फ़ाइल में अनुमत नहीं है।",
-       "uploaded-href-attribute-svg": "गैर-स्थानीय लक्ष्य के साथ एचआरईऍफ श्रेय (href attributes) <code>&lt;$1 $2=\"$3\"&gt;</code> (उदाहरण के लिए http://, जावास्क्रीप्ट:, इत्यादि) एसवीजी फाइल में अनुमत नहीं हैं।",
        "uploaded-href-unsafe-target-svg": "अपलोड की गयी फ़ाइल में असुरक्षित लक्ष्य <code>&lt;$1 $2=\"$3\"&gt;</code> पाये गए।",
        "uploaded-animate-svg": "चिप्पि \"animate\" पायी गई जिससे href परिवर्तित हो सकता है, अपलोड की गयी फ़ाइल में \"from\" विशेषता <code>&lt;$1 $2=\"$3\"&gt;</code> काम में ली जा रही है।",
        "uploaded-setting-event-handler-svg": "विकल्प आयोजन-संभालने वाला अवरोधित है, एसवीजी फ़ाइल में मिला <code>&lt;$1 $2=\"$3\"&gt;</code> है।",
        "foreign-structured-upload-form-label-own-work-message-shared": "कम से कम इस फ़ाइल का प्रतिकृति अधिकार मेरे पास है और यह [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] के अंतर्गत है, व [https://wikimediafoundation.org/wiki/Terms_of_Use विकि उपयोग की शर्तों] का भी पालन करता है।",
        "foreign-structured-upload-form-label-not-own-work-message-shared": "यदि आपके पास इस फ़ाइल का प्रतिकृति अधिकार नहीं है और आप इसे किसी और अधिकार के तहत प्रदर्शित करना चाहते हैं तो आप [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard] का उपयोग करें।",
        "foreign-structured-upload-form-label-not-own-work-local-shared": "यदि आप चाहें तो आप [[Special:Upload|{{SITENAME}} के पृष्ठ]] पर फ़ाइल डाल सकते हैं, यदि यह फ़ाइल वहाँ के नियम के अंतर्गत हो तो।",
+       "foreign-structured-upload-form-3-label-question-website": "क्या आपने यह छवि किसी जालस्थल (वेबसाइट) से ली है, या छवि खोज के द्वारा प्राप्त की है?",
+       "foreign-structured-upload-form-3-label-question-ownwork": "क्या आपने इस छवि का निर्माण (आपके द्वारा खिचा हुआ, चित्रकारी, आदि) किया है?",
        "foreign-structured-upload-form-3-label-yes": "हाँ",
        "foreign-structured-upload-form-3-label-no": "नहीं",
        "backend-fail-stream": "फ़ाइल $1 स्ट्रीम नहीं हो पाई।",
        "usereditcount": "$1 {{PLURAL:$1|सम्पादन}}",
        "usercreated": "$1 को $2 बजे बनाया गया, सदस्यनाम $3 है",
        "newpages": "नए पृष्ठ",
+       "newpages-submit": "दिखाएँ",
        "newpages-username": "सदस्यनाम:",
        "ancientpages": "सबसे पुराने पृष्ठ",
        "move": "स्थानान्तरण",
        "querypage-disabled": "प्रदर्शन कारणों से यह विशेष पृष्ठ अक्षम किया गया है।",
        "apihelp": "ए पी आई सहाएता",
        "apihelp-no-such-module": "मॉड्यूल \"$1\" नहीं मिला",
+       "apisandbox": "ए॰पी॰आइ प्रयोगस्थल",
+       "apisandbox-api-disabled": "इस स्थल पर ए०पी०आई० सक्षम नहीं हैं।",
+       "apisandbox-intro": "याद रखिए कि, हालांकि यह प्रयोगपृष्ठ है, इस पृष्ठ पर किए गए आपके काम इस विकि में बदलाव ला सकते हैं।",
+       "apisandbox-unfullscreen": "पृष्ठ दिखाएँ",
+       "apisandbox-submit": "अनुरोध करें",
+       "apisandbox-reset": "स्पष्ट",
+       "apisandbox-retry": "दुबारा प्रयास करें",
+       "apisandbox-examples": "Example",
+       "apisandbox-results": "परिणाम",
+       "apisandbox-request-url-label": "अनुरोध URL:",
+       "apisandbox-request-time": "अनुरोध समय: $1",
        "booksources": "पुस्तकों के स्रोत",
        "booksources-search-legend": "पुस्तकों के स्रोत खोजें",
        "booksources-isbn": "आइ॰एस॰बी॰एन:",
        "specialloguserlabel": "कर्ता:",
        "speciallogtitlelabel": "प्रयोजन (शीर्षक अथवा सदस्यनाम):",
        "log": "लॉग",
+       "logeventslist-submit": "दिखाएँ",
        "all-logs-page": "सभी सार्वजनिक लॉग",
        "alllogstext": "{{SITENAME}} की सभी उपलब्ध लॉगों की प्रविष्टियों का मिला-जुला प्रदर्शन।\nआप और बारीकी के लिए लॉग का प्रकार, सदस्य नाम (लघु-दीर्घ-अक्षर संवेदी), या प्रभावित पृष्ठ (लघु-दीर्घ-अक्षर संवेदी) चुन सकते हैं।",
        "logempty": "लॉग में ऐसी प्रविष्टि नहीं है।",
        "cachedspecial-viewing-cached-ts": "आप इस पृष्ठ का कैश किया हुआ अवतरण देख रहे हैं, जो कि संभवतः वर्तमान अवस्था से भिन्न हो।",
        "cachedspecial-refresh-now": "नवीनतम देखें।",
        "categories": "श्रेणियाँ",
+       "categories-submit": "दिखाएँ",
        "categoriespagetext": "निम्नोक्त {{PLURAL:$1|श्रेणी|श्रेणियों}} में पृष्ठ या मीडिया है।\nजिन श्रेणियों का [[Special:UnusedCategories|अप्रयुक्त श्रेणियाँ]] यहाँ नहीं दिखाई गई हैं।\n[[Special:WantedCategories|वांछित श्रेणियाँ]] भी देखें।",
        "categoriesfrom": "इस अक्षर से शुरू होने वाली श्रेणीयाँ दर्शायें:",
        "special-categories-sort-count": "संख्यानुसार शक्रमांकित करें",
        "wlheader-showupdated": "पृष्ठ जो आपके द्वारा देखे जाने के बाद बदले गये हैं '''बोल्ड''' दिखेंगे।",
        "wlnote": "$3 को $4 बजे तक पिछले <strong>$2</strong> {{PLURAL:$2|घंटे|घंटों}} में {{PLURAL:$1|हुआ एक|हुए <strong>$1</strong>}} परिवर्तन निम्न {{PLURAL:$1|है|हैं}}।",
        "wlshowlast": "पिछले $1 घंटे $2 दिन  देखें",
+       "watchlist-hide": "छुपाएँ",
+       "watchlist-submit": "दिखाएँ",
        "wlshowtime": "अंतिम दिखाएँ:",
        "wlshowhideminor": "छोटा संपादन",
        "wlshowhidebots": "बॉट",
        "delete-confirm": "\"$1\" को हटाएँ",
        "delete-legend": "हटाएँ",
        "historywarning": "<strong>चेतावनी:<strong> आप जो पृष्ठ हटाने जा रहे हैं उसके इतिहास में $1 {{PLURAL:$1|अवतरण}} हैं:",
+       "historyaction-submit": "दिखाएँ",
        "confirmdeletetext": "आप एक पृष्ठ को उसके सभी अवतरणों सहित हटाने जा रहे हैं।\nजाँच लें कि आप ये करना चाहते हैं, आप इसके पर्निआमों से अवगत हैं, और आप ये [[{{MediaWiki:Policy-url}}|नीति]] के अनुसार कर रहे हैं।",
        "actioncomplete": "कार्य पूर्ण",
        "actionfailed": "क्रिया विफल",
index 59cc6fb..a3dbd5c 100644 (file)
        "rcshowhidemine": "$1 moje promjene",
        "rcshowhidemine-show": "prikaži",
        "rcshowhidemine-hide": "sakrij",
+       "rcshowhidecategorization": "$1 kategorizaciju stranica",
        "rcshowhidecategorization-show": "Prikaži",
        "rcshowhidecategorization-hide": "Sakrij",
        "rclinks": "Prikaži posljednjih $1 promjena {{PLURAL:$2|prethodni dan|u posljednja $2 dana|u posljednjih $2 dana}}<br />$3",
        "suppress": "Nadzor",
        "querypage-disabled": "Ova posebna stranica onemogućena je jer bi usporila funkcioniranje projekta.",
        "apihelp": "Pomoć za API",
+       "apisandbox-submit": "Napraviti zahtjev",
+       "apisandbox-reset": "Očisti",
+       "apisandbox-examples": "Primjer",
+       "apisandbox-results": "Rezultat",
        "booksources": "Pretraživanje po ISBN-u",
        "booksources-search-legend": "Traženje izvora za knjigu",
        "booksources-search": "Traži",
index fd73fca..b4a6817 100644 (file)
@@ -42,7 +42,8 @@
                        "Nyuszika7H",
                        "Matma Rex",
                        "JulesWinnfield-hu",
-                       "Bencoke"
+                       "Bencoke",
+                       "Máté"
                ]
        },
        "tog-underline": "Hivatkozások aláhúzása:",
@@ -77,6 +78,7 @@
        "tog-watchlisthidebots": "Robotok szerkesztéseinek elrejtése",
        "tog-watchlisthideminor": "Apró változtatások elrejtése",
        "tog-watchlisthideliu": "Bejelentkezett szerkesztők módosításainak elrejtése a figyelőlistáról",
+       "tog-watchlistreloadautomatically": "A figyelőlista automatikus újratöltése bármelyik szűrő megváltoztatása esetén (JavaScript szükséges)",
        "tog-watchlisthideanons": "Névtelen szerkesztések elrejtése",
        "tog-watchlisthidepatrolled": "Az ellenőrzött szerkesztések elrejtése",
        "tog-watchlisthidecategorization": "Lapok kategorizálásának elrejtése",
        "october-date": "Október $1",
        "november-date": "November $1",
        "december-date": "December $1",
+       "period-am": "de.",
+       "period-pm": "du.",
        "pagecategories": "{{PLURAL:$1|Kategória|Kategóriák}}",
        "category_header": "A(z) „$1” kategóriába tartozó lapok",
        "subcategories": "Alkategóriák",
        "readonly": "Az adatbázis le van zárva",
        "enterlockreason": "Add meg a lezárás okát, valamint egy becslést, hogy mikor lesz a lezárásnak vége",
        "readonlytext": "A wiki adatbázisa ideiglenesen le van zárva (valószínűleg adatbázis-karbantartás miatt). A lezárás időtartama alatt a lapok nem szerkeszthetők, és új szócikkek sem hozhatók létre, az oldalakat azonban lehet böngészni.\n\nAz rendszeradminisztrátor, aki lezárta az adatbázist, az alábbi indoklást adta: $1",
-       "missing-article": "Az adatbázisban nem található meg a(z) „$1” című lap szövege $2.\n\nEnnek az oka általában az, hogy egy olyan lapra vonatkozó linket követtél, amit már töröltek.\n\nHa ez nem így van, lehet, hogy hibát találtál a szoftverben.\nJelezd ezt egy [[Special:ListUsers/sysop|adminiszttrátornak]] az URL megadásával.",
+       "missing-article": "Az adatbázisban nem található meg a(z) „$1” című lap szövege $2.\n\nEnnek az oka általában az, hogy egy olyan lapra vonatkozó linket követtél, amelyet már töröltek.\n\nHa ez nem így van, lehet, hogy hibát találtál a szoftverben.\nJelezd ezt egy [[Special:ListUsers/sysop|adminiszttrátornak]] az URL megadásával.",
        "missingarticle-rev": "(változat azonosítója: $1)",
        "missingarticle-diff": "(eltérés: $1, $2)",
        "readonly_lag": "Az adatbázis automatikusan le lett zárva, amíg a mellékkiszolgálók utolérik a főkiszolgálót.",
        "badtitle": "Hibás cím",
        "badtitletext": "A kért oldal címe érvénytelen, üres, vagy rosszul hivatkozott nyelvközi vagy wikiközi cím volt. Olyan karaktereket is tartalmazhatott, melyek címekben nem használhatók.",
        "title-invalid-empty": "A kért lapcím üres vagy csak egy névtér nevét tartalmazza.",
-       "title-invalid-utf8": "A kért oldal címe tartalmazza érvénytelen UTF-8 karaktert tartalmaz.",
+       "title-invalid-utf8": "A kért oldal címe érvénytelen UTF-8 szekvenciát tartalmaz.",
        "title-invalid-interwiki": "A cím interwiki-hivatkozást tartalmaz, amelyet nem lehet címben használni.",
-       "title-invalid-talk-namespace": "A kért lapcím egy olyan vitalapra hivatkozik, ami nem létezhet.",
+       "title-invalid-talk-namespace": "A kért lapcím olyan vitalapra hivatkozik, amely nem létezhet.",
        "title-invalid-characters": "A kért lapcím érvénytelen karaktereket tartalmaz: „$1”",
        "title-invalid-relative": "A cím relatív útvonalat tartalmaz. A relatív lapcímek (./, ../) érvénytelenek, mert gyakran elérhetetlenné válnak, amikor a felhasználó böngészője feldolgozza őket.",
        "title-invalid-magic-tilde": "A kért oldal címe érvénytelen mágikus tilde sorozatot (<nowiki>~~~</nowiki>) tartalmaz.",
        "viewsource": "Lapforrás",
        "viewsource-title": "$1 forrásának megtekintése",
        "actionthrottled": "Művelet megszakítva",
-       "actionthrottledtext": "A spamek elleni védekezés miatt nem végezheted el a műveletet túl sokszor egy adott időn belül, és te átlépted a megengedett határt. Próbálkozz újra néhány perc múlva.",
-       "protectedpagetext": "Ez egy védett lap, így nem végezhető rajta szerkesztés és más tevékenység.",
+       "actionthrottledtext": "A visszaélések elleni védekezés miatt nem végezheted el a műveletet túl sokszor egy adott időn belül, és te átlépted a megengedett határt. Próbálkozz újra néhány perc múlva.",
+       "protectedpagetext": "Ez egy védett lap, így nem végezhető rajta szerkesztés és más művelet.",
        "viewsourcetext": "Megtekintheted és másolhatod a lap forrását.",
        "viewyourtext": "Megtekintheted és kimásolhatod a <strong>saját szerkesztéseidet</strong> az alábbi lapra.",
        "protectedinterface": "Ez a lap a szoftver felületéhez szolgáltat szöveget, és a visszaélések elkerülése miatt le van zárva.",
        "ns-specialprotected": "A speciális lapok nem szerkeszthetők.",
        "titleprotected": "Ilyen címmel nem lehet szócikket készíteni, [[User:$1|$1]] letiltotta.\nAz indoklás: „''$2''”.",
        "filereadonlyerror": "A(z) „$1” fájl nem módosítható, mert a(z) „$2” fájltároló csak olvasható módban üzemel.\n\nA lezárást végrehajtó rendszeradminisztrátor az alábbi indoklást adta meg: „$3”.",
-       "invalidtitle-knownnamespace": "Érvénytelen cím \"$2\" névtérrel és \"$3\" szöveggel",
-       "invalidtitle-unknownnamespace": "Érvénytelen cím az ismeretlen $1 névtérszámmal és \"$2\" szöveggel",
+       "invalidtitle-knownnamespace": "Érvénytelen cím „$2” névtérrel és „$3” szöveggel",
+       "invalidtitle-unknownnamespace": "Érvénytelen cím az ismeretlen $1 névtérszámmal és „$2” szöveggel",
        "exception-nologin": "Nem vagy bejelentkezve.",
        "exception-nologin-text": "Ezen lap vagy művelet eléréséhez kérlek [[Special:Userlogin|jelentkezz be]].",
        "exception-nologin-text-manual": "Ezen lap vagy művelet eléréséhez $1.",
        "virus-scanfailed": "az ellenőrzés nem sikerült (hibakód: $1)",
        "virus-unknownscanner": "ismeretlen antivírus:",
        "logouttext": "'''Sikeresen kijelentkeztél.'''\n\nLehetséges, hogy néhány oldalon továbbra is azt látod, be vagy jelentkezve, mindaddig, amíg nem üríted a böngésződ gyorsítótárát.",
+       "cannotlogoutnow-title": "Nem lehet most kijelentkezni",
+       "cannotlogoutnow-text": "A kijelentkezés nem lehetséges $1 használatakor.",
        "welcomeuser": "Üdvözlünk, $1!",
        "welcomecreation-msg": "A felhasználói fiókod elkészült.\nNe felejtsd el módosítani a [[Special:Preferences|{{SITENAME}} beállításaidat]].",
        "yourname": "Szerkesztőneved:",
        "remembermypassword": "Emlékezzen rám ezen a számítógépen (legfeljebb $1 napig)",
        "userlogin-remembermypassword": "Maradjak bejelentkezve",
        "userlogin-signwithsecure": "Biztonságos kapcsolat használata",
+       "cannotloginnow-title": "Nem lehet most bejelentkezni",
+       "cannotloginnow-text": "A bejelentkezés nem lehetséges $1 használatakor.",
        "yourdomainname": "A domainneved:",
        "password-change-forbidden": "Nem módosíthatod a jelszót ezen a wikin.",
        "externaldberror": "Hiba történt a külső adatbázis hitelesítése közben, vagy nem vagy jogosult a külső fiókod frissítésére.",
        "createacct-benefit-body2": "{{PLURAL:$1|lap|lap}}",
        "createacct-benefit-body3": "aktív {{PLURAL:$1|szerkesztő|szerkesztő}}",
        "badretype": "A megadott jelszavak nem egyeznek.",
+       "usernameinprogress": "Egy fiók létrehozása ezzel a névvel már folyamatban van.\nKérlek, várj.",
        "userexists": "A megadott felhasználónév már foglalt.\nKérlek, válassz másikat!",
        "loginerror": "Hiba történt a bejelentkezés során",
        "createacct-error": "Fióklétrehozási hiba",
        "wrongpasswordempty": "Nem adtál meg jelszót. Próbáld meg újra.",
        "passwordtooshort": "A jelszónak legalább $1 karakterből kell állnia.",
        "passwordtoolong": "A jelszó nem lehet hosszabb $1 karakternél.",
+       "passwordtoopopular": "A gyakori jelszavak nem használhatók. Válassz egy egyedibb jelszót.",
        "password-name-match": "A jelszavadnak különböznie kell a szerkesztőnevedtől.",
        "password-login-forbidden": "Ezen felhasználónév és jelszó használata tiltott.",
        "mailmypassword": "Jelszó alaphelyzetbe állítása",
        "resetpass_submit": "Add meg a jelszót és jelentkezz be",
        "changepassword-success": "A jelszavad megváltoztatása sikeresen befejeződött!",
        "changepassword-throttled": "Túl sok hibás bejelentkezés.\nVárj $1, mielőtt újra próbálkozol.",
-       "botpasswords-label-appid": "A Bot neve:",
+       "botpasswords": "Botjelszavak",
+       "botpasswords-summary": "A <em>botjelszavak</em> lehetővé teszik egy felhasználói fiókhoz való hozzáférést az API-n keresztül a fiók fő bejelentkezési adatainak megadása nélkül. A botjelszóval történő bejelentkezéskor a felhasználói jogok korlátozottak lehetnek.\n\nHa nem tudod, hogy miért szeretnél ilyet, valószínűleg nem kell csinálnod. Soha senkinek nem szabadna megkérnie téged, hogy generálj neki egyet, hogy odaadhasd neki.",
+       "botpasswords-disabled": "A botjelszavak le vannak tiltva.",
+       "botpasswords-no-central-id": "A botjelszavak használatához egy globális fiókba kell bejelentkezned.",
+       "botpasswords-existing": "Létező botjelszavak",
+       "botpasswords-createnew": "Új botjelszó létrehozása",
+       "botpasswords-editexisting": "Létező botjelszó szerkesztése",
+       "botpasswords-label-appid": "A bot neve:",
        "botpasswords-label-create": "Létrehozás",
        "botpasswords-label-update": "Frissítés",
        "botpasswords-label-cancel": "Mégsem",
        "botpasswords-label-delete": "Törlés",
        "botpasswords-label-resetpassword": "Új jelszó kérése",
+       "botpasswords-label-grants": "Elérhető jogosultságok:",
        "botpasswords-label-restrictions": "Használati korlátozások:",
-       "botpasswords-created-title": "Bot jelszó létrehozva",
-       "botpasswords-updated-title": "Bot jelszó frissítve",
-       "botpasswords-deleted-title": "Bot jelszó törölve",
+       "botpasswords-label-grants-column": "Megadva",
+       "botpasswords-bad-appid": "A(z) „$1” botnév érvénytelen.",
+       "botpasswords-insert-failed": "A(z) „$1” botnév hozzáadása sikertelen. Nem lehet, hogy már hozzá lett adva?",
+       "botpasswords-created-title": "Botjelszó létrehozva",
+       "botpasswords-updated-title": "Botjelszó frissítve",
+       "botpasswords-deleted-title": "Botjelszó törölve",
+       "botpasswords-no-provider": "A BotPasswordsSessionProvider nem áll rendelkezésre.",
        "resetpass_forbidden": "A jelszavak nem változtathatók meg",
        "resetpass-no-info": "Be kell jelentkezned, hogy közvetlenül elérd ezt a lapot.",
        "resetpass-submit-loggedin": "Jelszó megváltoztatása",
        "changeemail-no-info": "A lap közvetlen eléréséhez be kell jelentkezned.",
        "changeemail-oldemail": "Jelenlegi e-mail-cím:",
        "changeemail-newemail": "Új e-mail-cím:",
+       "changeemail-newemail-help": "Ha el akarod távolítani az e-mail-címed, ezt a mezőt üresen kell hagynod. Ha eltávolítod az e-mail-címed, nem fogod tudni visszaállítani a jelszavad, és nem fogsz tudni e-maileket fogadni erről a wikiről.",
        "changeemail-none": "(nincs)",
        "changeemail-password": "A {{SITENAME}} jelszavad:",
        "changeemail-submit": "E-mail cím megváltoztatása",
        "changeemail-throttled": "Túl sok hibás bejelentkezés.\nVárj $1, mielőtt újra próbálkozol.",
+       "changeemail-nochange": "Kérjük, adj meg egy másik új e-mail-címet.",
        "resettokens": "Tokenek törlése",
        "resettokens-text": "Újra generálhatod a tokeneket, amely a fiókodhoz rendelt bizonyos magánadatokhoz enged hozzáférést.\n\nEzt akkor érdemes használnod, hogy véletlenül megosztottad a tokeneket valakivel, vagy ha valaki feltörte a fiókodat.",
        "resettokens-no-tokens": "Nincs újragenerálható token.",
        "missingcommenttext": "Kérjük, írj összefoglalót a szerkesztésedhez.",
        "missingcommentheader": "<strong>Emlékeztető:</strong> Nem adtad meg a megjegyzés tárgyát.\nHa ismét a „{{int:savearticle}}” gombra kattintasz, akkor a szerkesztésed nélküle lesz elmentve.",
        "summary-preview": "A szerkesztési összefoglaló előnézete:",
-       "subject-preview": "A téma/főcím előnézete:",
+       "subject-preview": "Tárgy előnézete:",
        "previewerrortext": "Hiba történt a változások előnézete megjelenítése során.",
        "blockedtitle": "A szerkesztő blokkolva van",
        "blockedtext": "'''A szerkesztőnevedet vagy az IP-címedet blokkoltuk.'''\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: ''$2''.\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz 'E-mail küldése ennek a szerkesztőnek' funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
        "permissionserrorstext-withaction": "Nincs jogosultságod a következő művelet elvégzéséhez: $2, a következő {{PLURAL:$1|ok|okok}} miatt:",
        "recreate-moveddeleted-warn": "'''Figyelem! Olyan lapot készülsz létrehozni, amit már legalább egyszer töröltek.'''\n\nMielőtt létrehoznád, nézd meg, miért törölték a lap korábbi tartalmát, és győződj meg róla, hogy a törlés indoka érvényes-e még. A törlési és átnevezési naplókban az érintett lapról az alábbi bejegyzések szerepelnek:",
        "moveddeleted-notice": "Az oldal korábban törölve lett.\nA lap törlési és átnevezési naplója alább olvasható.",
+       "moveddeleted-notice-recent": "Sajnáljuk, az oldalt nemrég törölték (az elmúlt 24 órában).\nA részletekért lásd lentebb a törlési és átnevezési naplót.",
        "log-fulllog": "Teljes napló megtekintése",
        "edit-hook-aborted": "A szerkesztés meg lett szakítva egy hook által.\nNem lett magyarázat csatolva.",
        "edit-gone-missing": "Nem lehet frissíteni a lapot.\nÚgy tűnik, hogy törölve lett.",
        "userrights": "Szerkesztői jogok beállítása",
        "userrights-lookup-user": "Szerkesztőcsoportok beállítása",
        "userrights-user-editname": "Add meg a szerkesztő nevét:",
-       "editusergroup": "Szerkesztőcsoportok módosítása",
+       "editusergroup": "{{GENDER:$1|Szerkesztőcsoportok}} módosítása",
        "editinguser": "<strong>[[User:$1|$1]]</strong> felhasználó jogainak megváltoztatása $2",
        "userrights-editusergroup": "Szerkesztőcsoportok módosítása",
-       "saveusergroups": "Szerkesztőcsoportok mentése",
+       "saveusergroups": "{{GENDER:$1|Szerkesztőcsoportok}} mentése",
        "userrights-groupsmember": "Csoporttag:",
        "userrights-groupsmember-auto": "Alapértelmezetten tagja:",
        "userrights-groups-help": "Beállíthatod, hogy a szerkesztő mely csoportokba tartozik.\n* A bepipált doboz azt jelenti, hogy a szerkesztő benne van a csoportban, az üres azt, hogy nem.\n* A * az olyan csoportokat jelöli, amelyeket ha egyszer hozzáadtál, nem távolíthatod el, vagy nem adhatod hozzá.",
        "right-createpage": "lapok készítése (nem vitalapok)",
        "right-createtalk": "vitalapok készítése",
        "right-createaccount": "új felhasználói fiók készítése",
+       "right-autocreateaccount": "automatikus bejelentkezés külső felhasználói fiókkal",
        "right-minoredit": "szerkesztések apróként jelölésének lehetősége",
        "right-move": "lapok átnevezése",
        "right-move-subpages": "lapok átnevezése az allapjukkal együtt",
        "right-reupload-shared": "felülírhatja a közös megosztóhelyen lévő fájlokat helyben",
        "right-upload_by_url": "fájl feltöltése URL-cím alapján",
        "right-purge": "oldal gyorsítótárának ürítése megerősítés nélkül",
-       "right-autoconfirmed": "Nem érinti az IP-alapú szerkesztéskorlátozás",
+       "right-autoconfirmed": "nem érinti az IP-alapú szerkesztéskorlátozás",
        "right-bot": "automatikus folyamatként való kezelés",
        "right-nominornewtalk": "felhasználói lapok apró szerkesztésével nem jelenik meg az új üzenet értesítés",
        "right-apihighlimits": "nagyobb mennyiségű lekérdezés az API-n keresztül",
        "right-deletedtext": "törölt változatok szövegének és a változatok közötti eltérés megtekintése",
        "right-browsearchive": "keresés a törölt lapok között",
        "right-undelete": "lap helyreállítása",
-       "right-suppressrevision": "Bármely felhasználó által végzett változatok megtekintése, elrejtése és felfedése",
+       "right-suppressrevision": "bármely felhasználó által végzett változatok megtekintése, elrejtése és felfedése",
        "right-viewsuppressed": "Bármely felhasználó elrejtett változatainak megjelenítése",
        "right-suppressionlog": "privát naplók megtekintése",
        "right-block": "szerkesztők blokkolása",
        "right-editusercssjs": "más felhasználók CSS és JS fájljainak szerkesztése",
        "right-editusercss": "más felhasználók CSS fájljainak szerkesztése",
        "right-edituserjs": "más felhasználók JS fájljainak szerkesztése",
-       "right-editmyusercss": "saját szerkesztői CSS-fájlok szerkesztése",
-       "right-editmyuserjs": "Saját szerkesztői JavaScript-fájlok szerkesztése",
+       "right-editmyusercss": "saját szerkesztői CSS-fájlok szerkesztése",
+       "right-editmyuserjs": "saját szerkesztői JavaScript-fájlok szerkesztése",
        "right-viewmywatchlist": "saját figyelőlista megtekintése",
        "right-editmywatchlist": "saját figyelőlista szerkesztése; bizonyos műveletek képesek lapok figyelőlistához adására ezen jog nélkül is",
        "right-viewmyprivateinfo": "saját személyes adatok megtekintése (pl. e-mail cím, valódi név)",
        "right-override-export-depth": "Lapok exportálása a hivatkozott lapokkal együtt, legfeljebb 5-ös mélységig",
        "right-sendemail": "e-mail küldése más felhasználóknak",
        "right-passwordreset": "Jelszó visszaállítási emailek megtekintése",
-       "right-managechangetags": "Adatbázis [[Special:Tags|címkék]] létrehozása és törlése",
+       "right-managechangetags": "[[Special:Tags|címkék]] létrehozása és törlése az adatbázisban",
        "right-applychangetags": "[[Special:Tags|címkék]] alkalmazása a változakra",
-       "right-changetags": "Egyedi változtatásokon és napló bejegyzéseken tetszőleges [[Special:Tags|címkék]] hozzáadása és törlése",
+       "right-changetags": "egyedi lapváltozatokon és naplóbejegyzéseken tetszőleges [[Special:Tags|címkék]] hozzáadása és törlése",
        "grant-generic": "„$1” jogosultságcsomag",
        "grant-group-email": "E-mail küldése",
        "grant-group-high-volume": "Nagy mennyiségű szerkesztés végrehajtása",
        "grant-group-customization": "Személyre szabás és beállítások",
        "grant-group-administration": "Adminisztratív műveletek végrehajtása",
+       "grant-group-other": "egyéb műveletek",
        "grant-blockusers": "felhasználók blokkolása és blokk feloldása",
        "grant-createaccount": "fiókok létrehozása",
-       "grant-createeditmovepage": "Lapok készítése, szerkesztése és átnevezése",
+       "grant-createeditmovepage": "lapok létrehozása, szerkesztése és átnevezése",
        "grant-delete": "lapok, lapváltozatok és naplóbejegyzések törlése",
        "grant-editinterface": "MediaWiki-névtér és felhasználói CSS/JavaScript szerkesztése",
        "grant-editmycssjs": "Felhasználói CSS-ed/JavaScripted szerkesztése",
-       "grant-editmyoptions": "Felhasználói beállításaid szerkesztése",
+       "grant-editmyoptions": "felhasználói beállításaid módosítása",
        "grant-editmywatchlist": "figyelőlista szerkesztése",
        "grant-editpage": "létező lapok szerkesztése",
        "grant-editprotected": "védett lapok szerkesztése",
        "grant-rollback": "szerkesztések gyors visszaállítása",
        "grant-sendemail": "e-mail küldése más felhasználóknak",
        "grant-uploadeditmovefile": "fájlok feltöltése, felülírása és átnevezése",
-       "grant-uploadfile": "fájlok feltöltése",
-       "grant-viewdeleted": "Törölt fájlok és lapok megtekintése",
+       "grant-uploadfile": "új fájlok feltöltése",
+       "grant-basic": "alapvető jogosultságok",
+       "grant-viewdeleted": "törölt fájlok és lapok megtekintése",
        "grant-viewmywatchlist": "figyelőlista megtekintése",
        "newuserlogpage": "Új szerkesztők naplója",
        "newuserlogpagetext": "Ez a napló az újonnan regisztrált szerkesztők listáját tartalmazza.",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[Jelenleg {{PLURAL:$1|egy|$1}} felhasználó figyeli]",
        "rc_categories": "Szűkítés kategóriákra („|” jellel válaszd el őket)",
-       "rc_categories_any": "Bármelyik",
+       "rc_categories_any": "Választottak közül bármelyik",
        "rc-change-size-new": "$1 bájt módosítás után",
        "newsectionsummary": "/* $1 */ (új szakasz)",
        "rc-enhanced-expand": "Részletek megjelenítése",
        "recentchangeslinked-summary": "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap (vagy tagjai a megadott kategóriának).\nA [[Special:Watchlist|figyelőlistádon]] szereplő lapok '''félkövérrel''' vannak jelölve.",
        "recentchangeslinked-page": "Lap neve:",
        "recentchangeslinked-to": "Inkább az erre linkelő lapok változtatásait mutasd",
+       "recentchanges-page-added-to-category": "[[:$1]] hozzáadva a kategóriához",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] és {{PLURAL:$2|egy oldal|$2 oldal}} hozzáadva a kategóriához",
+       "recentchanges-page-removed-from-category": "[[:$1]] eltávolítva a kategóriából",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] és {{PLURAL:$2|egy oldal|$2 oldal}} eltávolítva a kategóriából",
        "upload": "Fájl feltöltése",
        "uploadbtn": "Fájl feltöltése",
        "reuploaddesc": "Visszatérés a feltöltési űrlaphoz.",
        "uploaded-script-svg": "A feltöltött SVG fájlodban szkriptelemet találtunk: \"$1\".",
        "uploaded-hostile-svg": "Nem biztonságos CSS kódot találtunk a feltöltött SVG fájlod stíluselemei között.",
        "uploaded-event-handler-on-svg": "Az alábbi eseménykezelő-attribútum beállítása nem megengedett az SVG fájlokban: <code>$1=$2</code>.",
-       "uploaded-href-attribute-svg": "Az alábbi nem lokális célra (pl. http://, javascript, stb.) mutató href attribútum nem megengedett az SVG fájlokban: <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "Nem biztonságos célra mutató href-et találtam a feltöltött SVG fájlban: <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "A feltöltött SVG fájlban \"animate\" taget találtam, ami az alábbi \"from\" attribútumával megváltoztathat egy href-et: <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-handler-svg": "Az SVG kódok, amelyek a \"handler\" attribútumot távolra/adatra/szkriptre állítják, le vannak tiltva. A feltöltött SVG fájlban a következőt találtam: <code>$1=\"$2\"</code>.",
        "upload-too-many-redirects": "Az URL túl sokszor volt átirányítva",
        "upload-http-error": "HTTP-hiba történt: $1",
        "upload-copy-upload-invalid-domain": "Másolás nem engedélyezett ebből a tartományból.",
+       "upload-dialog-title": "Fájl feltöltése",
+       "upload-dialog-button-cancel": "Mégse",
+       "upload-dialog-button-done": "Kész",
+       "upload-dialog-button-save": "Mentés",
+       "upload-dialog-button-upload": "Feltöltés",
+       "upload-form-label-select-file": "Fájl kiválasztása",
+       "upload-form-label-infoform-title": "Részletek",
+       "upload-form-label-infoform-name": "Név",
+       "upload-form-label-infoform-description": "Leírás",
+       "upload-form-label-usage-title": "Használat",
+       "upload-form-label-usage-filename": "Fájlnév",
+       "foreign-structured-upload-form-label-own-work": "Ez a saját munkám",
+       "foreign-structured-upload-form-label-infoform-categories": "Kategóriák",
+       "foreign-structured-upload-form-label-infoform-date": "Dátum",
+       "foreign-structured-upload-form-label-not-own-work-local-local": "Az [[Special:Upload|alapértelmezett feltöltőoldalt]] is kipróbálhatod.",
+       "foreign-structured-upload-form-3-label-question-ownwork": "Te magad hoztad lére ezt a képet (te fényképezted, rajzoltad stb.)?",
+       "foreign-structured-upload-form-3-label-yes": "Igen",
+       "foreign-structured-upload-form-3-label-no": "Nem",
        "backend-fail-stream": "Nem sikerült sugározni ezt a fájlt: $1.",
        "backend-fail-backup": "Nem lehet elmenteni ezt a fájlt: $1.",
        "backend-fail-notexists": "Ez a fájl nem létezik: $1 .",
        "querypage-disabled": "Ez a speciális lap a megfelelő teljesítmény fenntartása érdekében le van tiltva.",
        "apihelp": "API segítség",
        "apihelp-no-such-module": "A(z) „$1\" modul nem található.",
+       "apisandbox": "API homokozó",
+       "apisandbox-jsonly": "Az API-homokozó használatához JavaScriptre van szükség.",
+       "apisandbox-api-disabled": "API le van tiltva ezen az oldalon.",
+       "apisandbox-intro": "Ezen az oldalon kísérletezhetsz a <strong>MediaWiki web service API</strong>-val.\nA használattal kapcsolatos további részletek az [[mw:API:Main page|API-dokumentációnál]] találhatók. Példa: [//www.mediawiki.org/wiki/API#A_simple_example olvasd el a főoldal tartalomjegyzékét]. További példákért válassz egy tevékenységet!\n\nFigyelj rá, hogy bár ez csak egy „homokozó”, ettől még az általad végzett műveletek módosíthatják a wikit!",
+       "apisandbox-submit": "Kérés végrehajtása",
+       "apisandbox-reset": "Törlés",
+       "apisandbox-retry": "Újra",
+       "apisandbox-loading": "Információ betöltése a(z) „$1” API-modulhoz…",
+       "apisandbox-load-error": "Hiba történt az információk betöltésekor a(z) „$1” API-modulhoz: $2",
+       "apisandbox-no-parameters": "Ennek az API-modulnak nincsenek paraméterei.",
+       "apisandbox-helpurls": "Segítő linkek",
+       "apisandbox-examples": "Példák",
+       "apisandbox-dynamic-parameters": "További paraméterek",
+       "apisandbox-dynamic-parameters-add-label": "Paraméter hozzáadása:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Paraméter neve",
+       "apisandbox-dynamic-error-exists": "A(z) „$1” nevű paraméter már létezik.",
+       "apisandbox-deprecated-parameters": "Elavult paraméterek",
+       "apisandbox-results": "Eredmények",
+       "apisandbox-request-url-label": "Kérő URL:",
+       "apisandbox-request-time": "Kérés ideje: $1",
        "booksources": "Könyvforrások",
        "booksources-search-legend": "Könyvforrások keresése",
        "booksources-search": "Keresés",
        "activeusers-hidebots": "Botok elrejtése",
        "activeusers-hidesysops": "Adminisztrátorok elrejtése",
        "activeusers-noresult": "Nem található ilyen szerkesztő.",
+       "activeusers-submit": "Aktív szerkesztők megjelenítése",
        "listgrouprights": "Szerkesztői csoportok jogai",
        "listgrouprights-summary": "Lenn láthatóak a wikiben létező szerkesztői csoportok, valamint az azokhoz tartozó jogok.\nAz egyes csoportokról további információt [[{{MediaWiki:Listgrouprights-helppage}}|itt]] találhatsz.",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Kapott jog</span>\n* <span class=\"listgrouprights-revoked\">Elvett jog</span>",
        "listgrouprights-namespaceprotection-header": "Névtér korlátozások",
        "listgrouprights-namespaceprotection-namespace": "Névtér",
        "listgrouprights-namespaceprotection-restrictedto": "A szerkesztéshez szükséges jogosultság(ok)",
+       "listgrants": "Jogosultságok",
        "listgrants-summary": "Lenn láthatóak az OAuth által használt jogosultsági szintek, valamint az azokhoz tartozó jogok. A felhasználók engedélyezhetnek alkalmazásokat, hogy használják a fiókjukat, de csak korlátozott engedélyekkel, amelyek a felhasználó által engedélyezett jogosultsági szinteken alapulnak. Egy ilyen alkalmazás nem használhatja ezeket a jogokat, ha azokkal a felhasználó sem rendelkezik.\nLehetnek [[{{MediaWiki:Listgrouprights-helppage}}|további információk]] az egyes jogokról.",
        "listgrants-grant": "Jogosultsági szint",
-       "listgrants-rights": "Jogok",
+       "listgrants-rights": "Jogosultságok",
        "trackingcategories": "Nyomkövető kategóriák",
        "trackingcategories-summary": "Ez az oldal azokat a nyomkövető kategóriákat tartalmazza, amelyet a MediaWiki szoftver magától feltölt. Ezen neveket a megfelelő rendszer üzenet módosításával lehet megváltoztatni a {{ns:8}} névtérben.",
        "trackingcategories-msg": "Nyomkövető kategória",
        "wlshowhideliu": "bejelentkezett felhasználók",
        "wlshowhideanons": "névtelen felhasználók",
        "wlshowhidemine": "saját szerkesztéseim",
+       "wlshowhidecategorization": "kategóriaváltozások",
        "watchlist-options": "A figyelőlista beállításai",
        "watching": "Figyelés...",
        "unwatching": "Figyelés befejezése...",
        "block-log-flags-hiddenname": "rejtett felhasználónév",
        "range_block_disabled": "A rendszerfelelős tartományblokkolás létrehozási képessége letiltott.",
        "ipb_expiry_invalid": "Hibás lejárati dátum.",
+       "ipb_expiry_old": "A lejárati idő a múltban van.",
        "ipb_expiry_temp": "A láthatatlan felhasználóinév-blokkok lehetnek állandóak.",
        "ipb_hide_invalid": "A felhasználói fiókot nem lehet elrejteni; több mint $1 szerkesztése van.",
        "ipb_already_blocked": "\"$1\" már blokkolva",
        "movenosubpage": "Ez a lap nem rendelkezik allapokkal.",
        "movereason": "Indoklás:",
        "revertmove": "visszaállítás",
-       "delete_and_move_text": "== Törlés szükséges ==\n\nAz á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_text": "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 „[[$1]]” számára",
        "selfmove": "A cikk jelenlegi címe megegyezik azzal, amire át szeretnéd mozgatni. Egy szócikket saját magára mozgatni nem lehet.",
        "move-leave-redirect": "Átirányítás készítése a régi címről az új címre",
        "protectedpagemovewarning": "'''Figyelem:''' Ez a lap le van védve, így csak adminisztrátori jogosultságokkal rendelkező szerkesztők nevezhetik át.\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
        "semiprotectedpagemovewarning": "'''Figyelem:''' Ez a lap le van védve, így csak regisztrált felhasználók nevezhetik át.\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
-       "move-over-sharedrepo": "== Létező fájlnév ==\n\nA(z) [[:$1]] néven már létezik fájl egy megosztott tárhelyen. Ha ilyen néven töltöd fel, el fogja takarni a közös tárhelyen levőt.",
+       "move-over-sharedrepo": "A(z) [[:$1]] néven már létezik fájl egy megosztott tárhelyen. Ha ilyen néven töltöd fel, el fogja takarni a közös tárhelyen levőt.",
        "file-exists-sharedrepo": "A választott fájlnév már használatban van egy közös tárhelyen.\nKérlek válassz másik nevet.",
        "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\nfájlt importálhatod egy másik MediaWiki alapú rendszerbe\na Special:Import lapon keresztül.\n\nLapok 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,\nhogy az összes korábbi változatra és a teljes laptörténetekre szükséged van-e, vagy csak az aktuális\nváltozatok és a legutolsó változtatásokra vonatkozó információk kellenek.\n\nAz utóbbi esetben közvetlen hivatkozást is használhatsz, például a [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] a \"[[{{MediaWiki:Mainpage}}]]\" nevű lapot exportálja.",
        "pagelang-language": "Nyelv",
        "pagelang-use-default": "Alapértelmezett nyelv használata",
        "pagelang-select-lang": "Nyelv kiválasztása",
-       "right-pagelang": "Oldal nyelvének megváltoztatása",
+       "pagelang-submit": "Küldés",
+       "right-pagelang": "oldal nyelvének megváltoztatása",
        "action-pagelang": "oldal nyelvének módosítása",
        "log-name-pagelang": "Nyelvváltoztatások naplója",
        "log-description-pagelang": "Ebben a naplóban a lap nyelvének változásait követheted nyomon.",
        "mediastatistics": "Feltöltött fájlok statisztikája",
        "mediastatistics-summary": "Az alábbi statisztika a feltöltött fájlok alapján készült, mely a fájlok legfrissebb változatát tartalmazza a régi, vagy törölt fájlok kivételével.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 bájt|$1 bájt}} ($2; $3%)",
+       "mediastatistics-bytespertype": "Szakasz fájljainak teljes mérete: {{PLURAL:$1|$1 byte}} ($2; $3%).",
+       "mediastatistics-allbytes": "Az összes fájl teljes mérete: {{PLURAL:$1|$1 byte}} ($2).",
        "mediastatistics-table-mimetype": "MIME-típus",
        "mediastatistics-table-extensions": "Lehetséges kiterjesztések",
        "mediastatistics-table-count": "Fájlok száma",
        "mediastatistics-header-text": "Szöveges",
        "mediastatistics-header-executable": "Futtatható",
        "mediastatistics-header-archive": "Tömörített formátumok",
+       "mediastatistics-header-total": "Összes fájl",
        "json-warn-trailing-comma": "$1 bevezető vessző eltávolítva a JSON-ból",
        "json-error-unknown": "Hiba volt a JSON-ban. Hiba: $1",
        "json-error-depth": "A verem maximális mélység túllépték",
        "mw-widgets-titleinput-description-new-page": "a lap még nem létezik",
        "mw-widgets-titleinput-description-redirect": "átirányítás ide: $1",
        "api-error-blacklisted": "Válasszon egy másik, leíró címet.",
+       "sessionprovider-generic": "$1-munkamenetek",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "sütialapú munkamenetek",
+       "sessionprovider-nocookies": "A sütik le lehetnek tiltva. Engedélyezd a sütiket, és próbáld meg újra!",
        "randomrootpage": "Véletlen lap a gyökérből"
 }
index 5819bba..4128cc0 100644 (file)
        "preview": "Նախադիտում",
        "showpreview": "Նախադիտել",
        "showdiff": "Կատարված փոփոխությունները",
-       "anoneditwarning": "<strong>Ուշադրություն,</strong> Դուք չեք մտել համակարգ։ Ցանկացած խմբագրման դեպքում Ձեր IP հասցեն կդառնա բոլորին տեսանելի։ Եթե դուք <strong>[$1 մուտք գործեք]</strong> կամ <strong>[$2 ստեղծեք մասնակցային հաշիվ]</strong>, Ձեր կատարած խմբագրումները կկավեն Ձեր մասնակցային անվան հետ և Դուք կունենաք այլ առավելություններ։",
+       "anoneditwarning": "<strong>Ուշադրություն,</strong> Դուք չեք մտել համակարգ։ Ցանկացած խմբագրման դեպքում Ձեր IP հասցեն կդառնա բոլորին տեսանելի։ Եթե Դուք <strong>[$1 մուտք գործեք]</strong> կամ <strong>[$2 ստեղծեք մասնակցային հաշիվ]</strong>, Ձեր կատարած խմբագրումները կկապվեն Ձեր մասնակցային անվան հետ, ինչպես նաև կունենաք այլ առավելություններ։",
        "anonpreviewwarning": "<em>Դուք չեք մտել համակարգ։\nՀիշելով Ձեր կատարած խմբագրումը, այն կպահանվի Ձեր IP հասցեի հետ միասին այս էջի խմբագրումների պատմության մեջ։</em>",
        "missingsummary": "'''Հիշեցում.''' Դուք չեք տվել խմբագրման ամփոփում։ «Հիշել» կոճակի կրկնակի մատնահարման դեպքում փոփոխությունները կհիշվեն առանց ամփոփման։",
        "missingcommenttext": "Խնդրում ենք մեկնաբանություն ավելացնել ստորև։",
        "watchthisupload": "Հսկել այս նիշքը",
        "filewasdeleted": "Այս անվանմամբ նիշք նախկինում բեռնվել է և հետագայում ջնջվել։ Այն կրկին բեռնելուց առաջ խնդրում ենք ստուգել $1։",
        "filename-bad-prefix": "Բեռնվող նիշքի անվանումը սկսվում է '''<tt>«$1»</tt>''' արտահայտությամբ, որը ոչ-նկարագրական է և սովորաբար տրվում է թվային լուսանկարչական ապարատների կողմից։ Խնդրում ենք ընտրել ավելի նկարագրական անվանում ձեր նիշքի համար։",
-       "upload-success-subj": "Բեռնումը կատարված է",
-       "upload-failure-subj": "Ներբեռնման սխալ",
-       "upload-warning-subj": "Ներբեռնման զգուշացում",
        "upload-proto-error": "Սխալ պրոտոկոլ",
        "upload-proto-error-text": "Հեռավոր բեռնումը պահանջում է URL-հասցե, որը սկսվում է <code>http://</code> կամ <code>ftp://</code> նախածանցով։",
        "upload-file-error": "Ներքին սխալ",
        "wlheader-showupdated": "Էջերը, որոնք փոփոխվել են ձեր դրանց վերջին այցից հետո բերված են '''թավատառ'''։",
        "wlnote": "Ստորև բերված {{PLURAL:$1|է վերջին փոփոխությունը|են վերջին '''$1''' փոփոխությունները}} վերջին <strong>$2</strong> ժամվա ընթացքում։",
        "wlshowlast": "Ցուցադրել վերջին $1 ժամերը $2 օրերը",
-       "watchlistall2": "բոլոր",
        "watchlist-submit": "Ցույց տալ",
+       "wlshowhideliu": "գրանցված մասնակիցներ",
+       "wlshowhidemine": "իմ խմբագրումները",
        "watchlist-options": "Հսկացանկի նախընտրություններ",
        "watching": "Հսկվում է...",
        "unwatching": "Հանվում է հսկումից...",
index 2e93731..54471a6 100644 (file)
        "right-blockemail": "Blocar un usator de inviar e-mail",
        "right-hideuser": "Blocar un nomine de usator, celante lo del publico",
        "right-ipblock-exempt": "Contornar le blocadas de adresses IP, blocadas automatic e blocadas de intervallos IP",
-       "right-proxyunbannable": "Contornar le blocadas automatic de proxy",
        "right-unblockself": "Disblocar se mesme",
        "right-protect": "Cambiar nivellos de protection e modificar paginas protegite in cascada",
        "right-editprotected": "Modificar paginas protegite con \"{{int:protect-level-sysop}}\"",
        "right-managechangetags": "Crear e deler [[Special:Tags|etiquettas]] in le base de datos",
        "right-applychangetags": "Applicar [[Special:Tags|etiquettas]] al proprie modificationes",
        "right-changetags": "Adder e remover qualcunque [[Special:Tags|etiquettas]] sur individual versiones e entratas de registro",
+       "grant-generic": "gruppo de derectos \"$1\"",
+       "grant-group-administration": "Exequer actiones administrative",
+       "grant-blockusers": "Blocar e disblocar usatores",
+       "grant-createeditmovepage": "Crear, modificar e renominar paginas",
+       "grant-delete": "Deler paginas, versiones e entratas de registro",
+       "grant-editinterface": "Modificar le spatio de nomines MediaWiki e le CSS/JS de usatores",
+       "grant-editmycssjs": "Modificar le CSS/JS del proprie usator",
+       "grant-editmywatchlist": "Modificar le proprie observatorio",
+       "grant-editpage": "Modificar paginas existente",
+       "grant-editprotected": "Modificar paginas protegite",
+       "grant-highvolume": "Modification in massa",
+       "grant-oversight": "Celar usatores e supprimer versiones",
+       "grant-patrol": "Patruliar cambiamentos in paginas",
+       "grant-protect": "Proteger e disproteger paginas",
+       "grant-rollback": "Revocar cambiamentos in paginas",
+       "grant-sendemail": "Inviar e-mail a altere usatores",
+       "grant-uploadeditmovefile": "Actualisar, reimplaciar e renominar files",
+       "grant-uploadfile": "Incargar nove files",
+       "grant-viewdeleted": "Vider information delite",
+       "grant-viewmywatchlist": "Vider le proprie observatorio",
        "newuserlogpage": "Registro de creation de usatores",
        "newuserlogpagetext": "Isto es un registro de creation de usatores.",
        "rightslog": "Registro de derectos de usator",
        "uploaded-script-svg": "Un elemento de script \"$1\" se trova in le file SVG incargate.",
        "uploaded-hostile-svg": "Certe codice CSS insecur se trova in le elemento de stilo del file SVG incargate.",
        "uploaded-event-handler-on-svg": "Fixar attributos de gestion de eventos <code>$1=\"$2\"</code> non es permittite in files SVG.",
-       "uploaded-href-attribute-svg": "Attributos href <code>&lt;$1 $2=\"$3\"&gt;</code> con objectivos non local (p.ex. http://, javascript:, etc) non es permittite in files SVG.",
        "uploaded-href-unsafe-target-svg": "Un href a un objectivo non secur <code>&lt;$1 $2=\"$3\"&gt;</code> se trova in le file SVG incargate.",
        "uploaded-animate-svg": "Un etiqueta \"animate\" que poterea cambiar le href, usante le attributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code>, se trova in le file SVG incargate.",
        "uploaded-setting-event-handler-svg": "Fixar le attributos de gestion de eventos non es permittite, ma le codice <code>&lt;$1 $2=\"$3\"&gt;</code> se trova in le file SVG incargate.",
        "filename-thumb-name": "Isto pare como un titulo de miniatura. Per favor non re-incarga miniaturas in le mesme wiki. Alteremente, per favor modifica le nomine del file de maniera que illo es plus significative e non ha le prefixo de miniatura.",
        "filename-bad-prefix": "Le nomine del file que tu es super le puncto de incargar comencia con '''\"$1\"''', le qual es un nomine non descriptive, typicamente assignate automaticamente per le cameras digital.\nPer favor selige un nomine plus descriptive pro tu file.",
        "filename-prefix-blacklist": " #<!-- non modificar de alcun modo iste linea --> <pre>\n# Le syntaxe es como seque:\n#   * Toto a partir de un character \"#\" usque al fin del linea es un commento\n#   * Cata linea non vacue es un prefixo pro tal nomines de file como automaticamente assignate per cameras digital\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # alcun telephonos mobile\nIMG # generic\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- non modificar de alcun modo iste linea -->",
-       "upload-success-subj": "Incargamento succedite",
-       "upload-success-msg": "Le incargamento de [$2] ha succedite. Illo es disponibile hic: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Problema de incargamento",
-       "upload-failure-msg": "Il ha occurrite un problema con tu incargamento ab [$2]:\n\n$1",
-       "upload-warning-subj": "Advertimento de incargamento",
-       "upload-warning-msg": "Occurreva un problema con le incargamento de [$2]. Tu pote retornar al [[Special:Upload/stash/$1|formulario de incargamento]] pro corriger iste problema.",
        "upload-proto-error": "Protocollo incorrecte",
        "upload-proto-error-text": "Le incargamento remote require que le adresses URL comencia con <code>http://</code> o <code>ftp://</code>.",
        "upload-file-error": "Error interne",
        "querypage-disabled": "Iste pagina special es disactivate pro evitar de supercargar le systema.",
        "apihelp": "Adjuta con le API",
        "apihelp-no-such-module": "Modulo \"$1\" non trovate.",
+       "apisandbox": "Cassa de sablo pro API",
+       "apisandbox-api-disabled": "Le API ha essite disactivate in iste sito.",
+       "apisandbox-intro": "Usa iste pagina pro experimentar con le '''API de servicio web de MediaWiki'''.\nConsulta [//www.mediawiki.org/wiki/API:Main_page le documentation del API] pro ulterior detalios concernente le uso del API. Per exemplo: [//www.mediawiki.org/wiki/API#A_simple_example obtener le contento de un Pagina principal]. Selige un action pro vider altere exemplos.",
+       "apisandbox-submit": "Facer requesta",
+       "apisandbox-reset": "Rader",
+       "apisandbox-examples": "Exemplo",
+       "apisandbox-results": "Resultato",
+       "apisandbox-request-url-label": "URL de requesta:",
+       "apisandbox-request-time": "Duration del requesta: $1",
        "booksources": "Fontes de libros",
        "booksources-search-legend": "Cercar fontes de libros",
        "booksources-search": "Cercar",
        "wlheader-showupdated": "Le paginas que ha essite modificate post tu ultime visita se monstra in litteras '''grasse'''.",
        "wlnote": "Ecce le ultime {{PLURAL:$1|modification|<strong>$1</strong> modificationes}} durante le ultime {{PLURAL:$2|hora|<strong>$2</strong> horas}}, a partir del $3 a $4.",
        "wlshowlast": "Monstrar le ultime $1 horas $2 dies",
-       "watchlistall2": "toto",
        "watchlist-hide": "Celar",
        "wlshowtime": "Periodo de tempore a monstrar:",
        "wlshowhideminor": "modificationes minor",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "pagina non existe ancora",
        "mw-widgets-titleinput-description-redirect": "redirection a $1",
-       "api-error-blacklisted": "Per favor elige un altere titulo, plus descriptive."
+       "api-error-blacklisted": "Per favor elige un altere titulo, plus descriptive.",
+       "randomrootpage": "Pagina-radice aleatori"
 }
index 0aefcf4..7f3277f 100644 (file)
@@ -51,6 +51,7 @@
        "tog-hideminor": "Sembunyikan suntingan kecil di perubahan terbaru",
        "tog-hidepatrolled": "Sembunyikan suntingan terpatroli di perubahan terbaru",
        "tog-newpageshidepatrolled": "Sembunyikan halaman terpatroli dari daftar halaman baru",
+       "tog-hidecategorization": "Sembunyikan pengategorian halaman",
        "tog-extendwatchlist": "Kembangkan daftar pantauan untuk menunjukkan semua perubahan, tidak hanya yang terbaru",
        "tog-usenewrc": "Kelompokkan suntingan di tampilan perubahan terbaru dan daftar pantauan berdasarkan halaman",
        "tog-numberheadings": "Beri nomor judul secara otomatis",
        "tog-watchlisthidebots": "Sembunyikan suntingan bot di daftar pantauan",
        "tog-watchlisthideminor": "Sembunyikan suntingan kecil di daftar pantauan",
        "tog-watchlisthideliu": "Sembunyikan suntingan pengguna masuk log di daftar pantauan",
+       "tog-watchlistreloadautomatically": "Muat ulang daftar pantauan secara otomatis ketika sebuah penyaring berubah (JavaScript diperlukan)",
        "tog-watchlisthideanons": "Sembunyikan suntingan pengguna anonim di daftar pantauan",
        "tog-watchlisthidepatrolled": "Sembunyikan suntingan terpatroli di daftar pantauan",
+       "tog-watchlisthidecategorization": "Sembunyikan pengategorian halaman",
        "tog-ccmeonemails": "Kirimkan saya salinan surel yang saya kirimkan ke orang lain",
        "tog-diffonly": "Jangan tampilkan isi halaman di bawah perbedaan suntingan",
        "tog-showhiddencats": "Tampilkan kategori tersembunyi",
        "october-date": "$1 Oktober",
        "november-date": "$1 November",
        "december-date": "$1 Desember",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Kategori}}",
        "category_header": "Halaman dalam kategori \"$1\"",
        "subcategories": "Subkategori",
        "morenotlisted": "Daftar ini belum lengkap.",
        "mypage": "Halaman",
        "mytalk": "Pembicaraan",
-       "anontalk": "Pembicaraan IP ini",
+       "anontalk": "Pembicaraan",
        "navigation": "Navigasi",
        "and": "&#32;dan",
        "qbfind": "Pencarian",
        "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",
+       "readonlytext": "Basis data sedang dikunci terhadap masukan dan perubahan baru, mungkin dalam pembenahan basis data, setelah selesai keadaan akan normal sedia kala. \n\nPengurus yang melakukan penguncian memberikan penjelasan sebagai berikut: $1",
        "missing-article": "Basis data tidak dapat menemukan teks dari halaman yang seharusnya ada, yaitu \"$1\" $2.\n\nHal ini biasanya disebabkan oleh pranala usang ke revisi terdahulu halaman yang telah dihapuskan.\n\nJika bukan ini penyebabnya, Anda mungkin telah menemukan sebuah bug dalam perangkat lunak.\nSilakan laporkan hal ini kepada salah seorang [[Special:ListUsers/sysop|Pengurus]], dengan menyebutkan alamat URL yang dituju.",
        "missingarticle-rev": "(revisi#: $1)",
        "missingarticle-diff": "(Beda: $1, $2)",
        "readonly_lag": "Basis data telah dikunci otomatis selagi basis data sekunder melakukan sinkronisasi dengan basis data utama",
+       "nonwrite-api-promise-error": "Kepala HTTP 'Promise-Non-Write-API-Action' telah dikirim tetapi permintaan dibuat kepada modul menulis API.",
        "internalerror": "Kesalahan internal",
        "internalerror_info": "Kesalahan internal: $1",
        "internalerror-fatal-exception": "Kekecualian fatal mengetik \"$1\"",
        "badtitle": "Judul tidak sah",
        "badtitletext": "Judul halaman yang diminta tidak sah, kosong, atau judul antarbahasa atau antarwiki yang salah sambung.",
        "title-invalid-empty": "Judul halaman yang diminta kosong atau berisi hanya nama sebuah ruang nama.",
+       "title-invalid-utf8": "Judul halaman yang diminta mengandung rangkaian UTF-8 yang tidak sah.",
+       "title-invalid-interwiki": "Judul mengandung pranala antarwiki yang tidak bisa digunakan dalam judul.",
+       "title-invalid-talk-namespace": "Judul situs yang diminta merujuk kepada halaman pembicaraan yang tidak dapat tersedia.",
+       "title-invalid-characters": "Judul halaman yang diminta mengandung karakter tak sah: \"$1\".",
+       "title-invalid-relative": "Judul mengandung alamat relatif. Judul halaman relatif (./, ../) tidaklah sah, karena dapat mengalami kegagalan ketika ditangani oleh peramban pengguna.",
+       "title-invalid-magic-tilde": "Judul halaman mengandung rangkaian tilda yang tidak sah (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "Judul halaman yang diminta terlalu panjang. Ia harus dikodekan dengan UTF-8 dan tidak melebihi $1 bita.",
+       "title-invalid-leading-colon": "Judul halaman yang diminta dimulai dengan tanda titik dua yang tidak sah.",
        "perfcached": "Data berikut ini diambil dari singgahan dan mungkin bukan data mutakhir. {{PLURAL:$1|Hasil}} maksimal ada di singgahan.",
        "perfcachedts": "Data berikut ini diambil dari singgahan dan terakhir diperbarui pada $1. {{PLURAL:$4|Hasil}} maksimal ada di singgahan.",
        "querypage-no-updates": "Pemutakhiran dari halaman ini sedang dimatikan. Data yang ada di sini saat ini tidak akan dimuat ulang.",
        "viewsource": "Lihat sumber",
        "viewsource-title": "Lihat sumber untuk $1",
        "actionthrottled": "Tindakan dibatasi",
-       "actionthrottledtext": "Anda dibatasi untuk melakukan tindakan ini terlalu banyak dalam waktu pendek. Silakan mencoba lagi setelah beberapa menit.",
+       "actionthrottledtext": "Anda dibatasi untuk melakukan tindakan ini terlalu banyak dalam waktu pendek, dan Anda telah melebihi batas yang diberikan. Silakan mencoba lagi setelah beberapa menit.",
        "protectedpagetext": "Halaman ini telah dikunci untuk menghindari penyuntingan atau tindakan lain.",
-       "viewsourcetext": "Anda dapat melihat atau menyalin sumber halaman ini:",
-       "viewyourtext": "Anda dapat melihat atau menyalin sumber dari '''suntingan Anda''' ke halaman ini:",
+       "viewsourcetext": "Anda dapat melihat atau menyalin sumber halaman ini.",
+       "viewyourtext": "Anda dapat melihat dan menyalin sumber dari '''suntingan Anda''' ke halaman ini.",
        "protectedinterface": "Halaman ini memuat teks antarmuka untuk perangkat lunak pada wiki ini, dan dilindungi terhadap penyalahgunaan. Untuk menambah atau mengubah terjemahan pada semua wiki, harap gunakan [//translatewiki.net/ translatewiki.net], proyek pelokalan MediaWiki.",
        "editinginterface": "<strong>Peringatan:</strong> Anda menyunting suatu halaman yang digunakan untuk menyediakan teks antarmuka bagi perangkat lunak.\nPerubahan pada halaman ini akan memengaruhi tampilan pada antarmuka pengguna untuk pengguna lain pada wiki ini.",
        "translateinterface": "Untuk menambah atau mengubah terjemahan semua wiki, mohon gunakan [//translatewiki.net/ translatewiki.net], proyek pelokalan MediaWiki.",
        "mypreferencesprotected": "Anda tidak memiliki izin untuk menyunting preferensi Anda.",
        "ns-specialprotected": "Halaman pada ruang nama {{ns:special}} tidak dapat disunting.",
        "titleprotected": "Judul ini dilindungi dari pembuatan oleh [[User:$1|$1]].\nAlasan yang diberikan adalah ''$2''.",
-       "filereadonlyerror": "Tidak dapat memodifikasi file \" $1 \" karena file repositori \" $2 \" adalah pada mode baca-saja.\n\nAdministrator yang terkunci menawarkan penjelasan ini: \" $3 \".",
+       "filereadonlyerror": "Tidak dapat memodifikasi berkas \"$1\" karena file repositori \"$2\" adalah pada mode baca-saja.\n\nPengurus yang menguncinya memberikan alasan: \"$3\".",
        "invalidtitle-knownnamespace": "Judul yang tidak sah dengan ruangnama \"$2\" dan teks \"$3\"",
        "invalidtitle-unknownnamespace": "Judul yang tidak sah dengan nomor ruang nama tidak diketahui $1 dan teks \"$2\"",
        "exception-nologin": "Belum masuk log",
        "virus-scanfailed": "Pemindaian gagal (kode $1)",
        "virus-unknownscanner": "Antivirus tidak dikenal:",
        "logouttext": "'''Anda telah keluar log dari sistem.'''\n\nIngatlah bahwa beberapa halaman mungkin masih menampilkan anda seperti masih masuk log, sampai Anda membersihkan singgahan penjelajah web Anda.",
+       "cannotlogoutnow-title": "Tidak dapat keluar log saat ini",
+       "cannotlogoutnow-text": "Keluar log tidak memungkinkan ketika menggunakan $1.",
        "welcomeuser": "Selamat datang,  $1 !",
        "welcomecreation-msg": "Akun Anda telah dibuat. Jangan lupa mengatur konfigurasi [[Special:Preferences|preferensi {{SITENAME}}]] Anda.",
        "yourname": "Nama pengguna:",
        "remembermypassword": "Ingat kata sandi saya di komputer ini (selama $1 {{PLURAL:$1|hari|hari}})",
        "userlogin-remembermypassword": "Biarkan saya tetap masuk",
        "userlogin-signwithsecure": "Gunakan server aman",
+       "cannotloginnow-title": "Tidak dapat masuk log saat ini",
+       "cannotloginnow-text": "Masuk log tidak memungkinkan ketika menggunakan $1.",
        "yourdomainname": "Domain Anda:",
        "password-change-forbidden": "Anda tidak dapat mengubah kata sandi pada wiki ini.",
        "externaldberror": "Telah terjadi kesalahan otentikasi basis data eksternal atau Anda tidak diizinkan melakukan kemaskini terhadap akun eksternal Anda.",
        "createacct-benefit-body2": "{{PLURAL:$1|halaman}}",
        "createacct-benefit-body3": "{{PLURAL:$1|kontributor}} terakhir",
        "badretype": "Kata sandi yang Anda masukkan salah.",
+       "usernameinprogress": "Pembuatan akun untuk nama pengguna ini sedang dijalankan. Silahkan tunggu.",
        "userexists": "Nama pengguna yang dimasukkan telah digunakan.\nSilakan tentukan nama yang lain.",
        "loginerror": "Kesalahan masuk log",
        "createacct-error": "Pembuatan akun gagal",
        "wrongpasswordempty": "Anda tidak memasukkan kata sandi. Silakan coba lagi.",
        "passwordtooshort": "Kata sandi paling tidak harus terdiri dari {{PLURAL:$1|1 karakter|$1 karakter}}.",
        "passwordtoolong": "Passwords tidak boleh lebih dari {{PLURAL:$1|1 karakter|$1 karakter}}.",
+       "passwordtoopopular": "Kata sandi yang umum tidak dapat digunakan. Silakan pilih kata sandi yang berbeda.",
        "password-name-match": "Kata sandi Anda harus berbeda dari nama pengguna Anda.",
        "password-login-forbidden": "Penggunaan nama pengguna dan sandi ini telah dilarang.",
        "mailmypassword": "Setel ulang kata sandi",
        "noemail": "Tidak ada alamat surel yang tercatat untuk pengguna \"$1\".",
        "noemailcreate": "Anda perlu menyediakan alamat surel yang sah",
        "passwordsent": "Kata sandi baru telah dikirimkan ke alamat surel yang didaftarkan untuk \"$1\".\nSilakan masuk log kembali setelah menerima surel tersebut.",
-       "blocked-mailpassword": "Alamat IP Anda diblokir dari penyuntingan dan karenanya tidak diizinkan menggunakan fungsi pengingat kata sandi untuk mencegah penyalahgunaan.",
+       "blocked-mailpassword": "Alamat IP Anda diblokir dari penyuntingan sehingga tidak diizinkan menggunakan fungsi pengingat kata sandi untuk mencegah penyalahgunaan.",
        "eauthentsent": "Sebuah surel untuk konfirmasi telah dikirim ke alamat surel. Sebelum surel lainnya dikirim ke akun tersebut, Anda harus mengikuti instruksi di dalam surel tersebut, untuk melakukan konfirmasi bahwa alamat tersebut adalah benar kepunyaan Anda.",
        "throttled-mailpassword": "Suatu pengingat kata sandi telah dikirimkan dalam {{PLURAL:$1|$1 jam}} terakhir.\nUntuk menghindari penyalahgunaan, hanya satu kata sandi yang akan dikirimkan setiap {{PLURAL:$1|$1 jam}}.",
        "mailerror": "Kesalahan dalam mengirimkan surel: $1",
        "resetpass_submit": "Atur kata sandi dan masuk log",
        "changepassword-success": "Kata sandi Anda telah berhasil diubah!",
        "changepassword-throttled": "Anda terlalu sering mencoba masuk log.\nMohon tunggu $1 sebelum mencoba lagi.",
+       "botpasswords": "Kata sandi bot",
+       "botpasswords-disabled": "Kata sandi bot dinonaktifkan.",
+       "botpasswords-no-central-id": "Untuk menggunakan kata sandi bot, Anda harus masuk log ke akun yang telah tersentralisasi.",
+       "botpasswords-existing": "Kata sandi bot tersedia",
+       "botpasswords-createnew": "Buat kata sandi bot baru",
+       "botpasswords-editexisting": "Ubah kata sandi bot yang sudah ada",
+       "botpasswords-label-appid": "Nama bot:",
+       "botpasswords-label-create": "Buat",
+       "botpasswords-label-update": "Perbarui",
+       "botpasswords-label-cancel": "Batalkan",
+       "botpasswords-label-delete": "Hapus",
+       "botpasswords-label-resetpassword": "Setel ulang kata sandi",
+       "botpasswords-label-grants": "Akses yang dapat diberikan:",
        "resetpass_forbidden": "Kata sandi tidak dapat diubah",
        "resetpass-no-info": "Anda harus masuk log untuk mengakses halaman ini secara langsung.",
        "resetpass-submit-loggedin": "Ganti kata sandi",
        "missing-revision": "Revisi #$1 halaman berjudul \"{{FULLPAGENAME}}\" tidak eksis.\n\nHal ini biasanya disebabkan oleh tautan versi terdahulu menuju halaman yang sudah dihapus.\nRinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapusan].",
        "userpage-userdoesnotexist": "Akun pengguna \"<nowiki>$1</nowiki>\" tidak terdaftar.",
        "userpage-userdoesnotexist-view": "Pengguna \"$1\" tidak terdaftar.",
-       "blocked-notice-logextract": "Pengguna ini sedang diblokir.\nEntri log pemblokiran terakhir tersedia di bawah ini sebagai rujukan.",
+       "blocked-notice-logextract": "Pengguna ini sedang diblokir.\nEntri log pemblokiran terakhir tersedia di bawah ini sebagai rujukan:",
        "clearyourcache": "'''Catatan:''' Setelah menyimpan, Anda mungkin harus memintas singgahan peramban Anda untuk melihat perubahan.\n* '''Firefox / Safari:''' Tahan ''Shift'' sambil mengeklik ''Reload'', atau tekan ''Ctrl-F5'' atau ''Ctrl-R'' (''⌘-R'' di Mac)\n* '''Google Chrome:''' Tekan ''Ctrl-Shift-R'' (''⌘-Shift-R'' di Mac)\n* '''Internet Explorer:''' Tahan ''Ctrl'' sambl mengeklik ''Refresh'', atau tekan ''Ctrl-F5''\n* '''Opera:''' Bersihkan tembolok di ''Tools → Preferences''",
        "usercssyoucanpreview": "'''Tips:''' Gunakan tombol \"{{int:showpreview}}\" untuk menguji CSS baru Anda sebelum menyimpannya.",
        "userjsyoucanpreview": "'''Tips:''' Gunakan tombol \"{{int:showpreview}}\" untuk menguji JS baru Anda sebelum menyimpannya.",
        "revdelete-edit-reasonlist": "Alasan penghapusan suntingan",
        "revdelete-offender": "Revisi penulis:",
        "suppressionlog": "Log penyembunyian",
-       "suppressionlogtext": "Berikut adalah daftar penghapusan dan pemblokiran, termasuk konten yang disembunyikan dari para pengurus.\nLihat [[Special:BlockList|daftar pemblokiran]] untuk daftar terkininya.",
+       "suppressionlogtext": "Berikut adalah daftar penghapusan dan pemblokiran, termasuk isi yang disembunyikan dari para pengurus.\nLihat [[Special:BlockList|daftar pemblokiran]] untuk daftar terkininya.",
        "mergehistory": "Riwayat penggabungan sejarah halaman",
        "mergehistory-header": "Halaman ini memperbolehkan Anda untuk menggabungkan revisi-revisi dari satu halaman sumber ke halaman yang lebih baru.\nPastikan bahwa perubahan ini tetap mempertahankan kontinuitas versi terdahulu halaman.",
        "mergehistory-box": "Gabung revisi-revisi dari dua halaman:",
        "action-undelete": "membatalkan penghapusan halaman ini",
        "action-suppressrevision": "meninjau dan mengembalikan revisi yang disembunyikan ini",
        "action-suppressionlog": "melihat log privat ini",
-       "action-block": "memblokir pengguna ini dari menyunting",
+       "action-block": "memblokir pengguna ini dari penyuntingan",
        "action-protect": "mengganti tingkat pelindungan halaman ini",
        "action-rollback": "mengembalikan dengan cepat suntingan-suntingan pengguna terakhir yang menyunting halaman tertentu",
        "action-import": "mengimpor halaman ini dari wiki lain",
        "filewasdeleted": "Suatu berkas dengan nama ini pernah dimuat dan selanjutnya dihapus. Harap cek $1 sebelum memuat lagi berkas tersebut.",
        "filename-bad-prefix": "Nama berkas yang Anda muat diawali dengan '''\"$1\"''', yang merupakan nama non-deskriptif yang biasanya diberikan secara otomatis oleh kamera digital. Harap pilih nama lain yang lebih deskriptif untuk berkas Anda.",
        "filename-prefix-blacklist": " #<!-- biarkan baris ini seperti adanya --> <pre>\n# Contohnya sebagai berikut:\n#   * Semuanya dari karekter \"#\" sampai akhir baris ini adalah komentar\n#   * Setiap garis \"_\" adalah awalan untuk nama file khas yang diberikan secara otomatis oleh kamera digital\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # beberapa model telpon seluler\nIMG # generik\nJD # Jenoptik\nMGP # Pentax\nPICT # lainnya.\n #</pre> <!-- biarkan baris ini seperti adanya -->",
-       "upload-success-subj": "Berhasil dimuat",
-       "upload-success-msg": "Pengunggahan Anda dari [$2] berhasil. Hasilnya tersedia di sini: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Masalah pengunggahan",
-       "upload-failure-msg": "Ada masalah dengan unggahan Anda dari [$2]:\n\n$1",
-       "upload-warning-subj": "Peringatan pemuatan",
-       "upload-warning-msg": "Terjadi masalah dengan unggahan Anda dari [$2]. Anda dapat kembali ke [[Special:Upload/stash/$1|formulir pengunggahan]] untuk memerbaiki masalah ini.",
        "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",
        "querypage-disabled": "Halaman istimewa ini dinonaktifkan demi alasan kinerja.",
        "apihelp": "Bantuan API",
        "apihelp-no-such-module": "Modul \"$1\" tidak ditemukan.",
+       "apisandbox": "Bak pasir API",
+       "apisandbox-api-disabled": "API dinonaktifkan pada situs ini.",
+       "apisandbox-intro": "Gunakan halaman ini untuk bereksperimen dengan '''API layanan web MediaWiki'''.\nLihat [//www.mediawiki.org/wiki/API:Main_page dokumentasi API] untuk perincian lanjut penggunaan API. Contoh: [//www.mediawiki.org/wiki/API#A_simple_example dapatkan konten Halaman Utama]. Pilih tindakan untuk melihat contoh lain.\n\nPerhatikan bahwa, meskipun ini adalah bak pasir, tindakan yang Anda lakukan pada halaman ini dapat mengubah wiki.",
+       "apisandbox-submit": "Kirim permintaan",
+       "apisandbox-reset": "Kosongkan",
+       "apisandbox-examples": "Contoh",
+       "apisandbox-results": "Hasil",
+       "apisandbox-request-url-label": "URL Permintaan:",
+       "apisandbox-request-time": "Lama permintaan: $1",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari di sumber buku",
        "booksources-isbn": "ISBN:",
        "wlheader-showupdated": "Halaman-halaman yang telah berubah sejak kunjungan terakhir Anda ditampilkan dengan '''huruf tebal'''.",
        "wlnote": "Di bawah ini adalah {{PLURAL:$1|perubahan|<strong>$1</strong> perubahan}} terakhir dalam {{PLURAL:$2|jam|<strong>$2</strong> jam}}, per $3, $4.",
        "wlshowlast": "Tampilkan $1 jam $2 hari terakhir",
-       "watchlistall2": "semua",
        "wlshowtime": "Tampilkan hingga:",
        "wlshowhideminor": "suntingan kecil",
        "wlshowhidebots": "bot",
        "protect_expiry_old": "Waktu kedaluwarsa adalah pada masa lampau.",
        "protect-unchain-permissions": "Aktifkan opsi pelindungan lanjutan",
        "protect-text": "Anda dapat melihat atau mengganti tingkatan pelindungan untuk halaman '''$1''' di sini.",
-       "protect-locked-blocked": "Anda tak dapat mengganti tingkat pelindungan selagi diblokir. Berikut adalah konfigurasi saat ini untuk halaman '''$1''':",
+       "protect-locked-blocked": "Anda tak dapat mengganti tingkat pelindungan selagi diblokir. Berikut adalah konfigurasi saat ini untuk halaman <strong>$1</strong>:",
        "protect-locked-dblock": "Tingkat pelindungan tak dapat diganti karena aktifnya penguncian basis data. Berikut adalah konfigurasi saat ini untuk halaman '''$1''':",
        "protect-locked-access": "Akun Anda tidak dapat memiliki hak untuk mengganti tingkat pelindungan halaman. Berikut adalah konfigurasi saat ini untuk halaman '''$1''':",
        "protect-cascadeon": "Halaman ini sedang dilindungi karena disertakan dalam {{PLURAL:$1|halaman|halaman-halaman}} berikut yang telah dilindungi dengan pilihan pelindungan runtun diaktifkan.\nPenggantian tingkat pelindungan untuk halaman ini tidak akan mempengaruhi pelindungan runtun.",
        "sp-contributions-logs": "log",
        "sp-contributions-talk": "bicara",
        "sp-contributions-userrights": "pengelolaan hak pengguna",
-       "sp-contributions-blocked-notice": "Pengguna ini sedang diblokLog pemblokiran terakhir ditampilkan berikut untuk referensi:",
-       "sp-contributions-blocked-notice-anon": "Alamat IP ini diblokir pada saat ini.\nCatatan log pemblokiran terakhir tersedia di bawah ini sebagai rujukan:",
+       "sp-contributions-blocked-notice": "Pengguna ini sedang diblokir.\nLog pemblokiran terakhir ditampilkan berikut untuk referensi:",
+       "sp-contributions-blocked-notice-anon": "Alamat IP ini sedang diblokir saat ini.\nEntri log pemblokiran terakhir tersedia di bawah ini sebagai rujukan:",
        "sp-contributions-search": "Cari kontribusi",
        "sp-contributions-username": "Alamat IP atau nama pengguna:",
        "sp-contributions-toponly": "Tampilkan hanya revisi teratas",
        "ipb-unblock": "Hilangkan blokir seorang pengguna atau suatu alamat IP",
        "ipb-blocklist": "Lihat blokir yang diterapkan",
        "ipb-blocklist-contribs": "Kontribusi untuk {{GENDER:$1|$1}}",
-       "unblockip": "Hilangkan blokir terhadap alamat IP atau pengguna",
+       "unblockip": "Buka blokir pengguna",
        "unblockiptext": "Gunakan formulir di bawah untuk mengembalikan kemampuan menulis sebuah alamat IP atau pengguna yang sebelumnya telah diblokir.",
        "ipusubmit": "Hilangkan blokir ini",
-       "unblocked": "Blokir terhadap [[User:$1|$1]] telah dicabut",
+       "unblocked": "Blokir terhadap [[User:$1|$1]] telah dicabut.",
        "unblocked-range": "$1 telah diblokir",
-       "unblocked-id": "Blokir $1 telah dicabut",
-       "unblocked-ip": "[[Special:Contributions/$1|$1]] telah dibuka blokirnya.",
-       "blocklist": "Daftar pemblokiran pengguna",
+       "unblocked-id": "Blokir $1 telah dicabut.",
+       "unblocked-ip": "Pemblokiran [[Special:Contributions/$1|$1]] telah dicabut.",
+       "blocklist": "Daftar pengguna yang diblokir",
        "ipblocklist": "Daftar pemblokiran pengguna",
        "ipblocklist-legend": "Cari pengguna yang diblokir",
        "blocklist-userblocks": "Sembunyikan pemblokiran akun",
        "blocklist-timestamp": "Stempel waktu",
        "blocklist-target": "Target",
        "blocklist-expiry": "Kedaluwarsa",
-       "blocklist-by": "Admin pemblokir",
+       "blocklist-by": "Pengurus yang memblokir",
        "blocklist-params": "Parameter pemblokiran",
        "blocklist-reason": "Alasan",
        "ipblocklist-submit": "Cari",
-       "ipblocklist-localblock": "Blok lokal",
+       "ipblocklist-localblock": "Blokir lokal",
        "ipblocklist-otherblocks": "{{PLURAL:$1|pemblokiran|pemblokiran}} lain",
        "infiniteblock": "tak terbatas",
        "expiringblock": "kedaluwarsa pada $1 $2",
        "emailblock": "surel diblokir",
        "blocklist-nousertalk": "tidak dapat menyunting halaman pembicaraan sendiri",
        "ipblocklist-empty": "Daftar pemblokiran kosong.",
-       "ipblocklist-no-results": "alamat IP atau pengguna yang diminta tidak diblokir.",
+       "ipblocklist-no-results": "Alamat IP atau pengguna yang diminta tidak diblokir.",
        "blocklink": "blokir",
        "unblocklink": "hilangkan blokir",
-       "change-blocklink": "ubah blokir",
+       "change-blocklink": "ubah pemblokiran",
        "contribslink": "kontrib",
        "emaillink": "kirim surel",
        "autoblocker": "Diblokir secara otomatis karena alamat IP Anda digunakan oleh \"[[User:$1|$1]]\".\nAlasan yang diberikan untuk pemblokiran $1 adalah: \"$2\"",
        "blocklogpage": "Log pemblokiran",
-       "blocklog-showlog": "Pengguna ini telah diblokir sebelumnya. Log pemblokiran disediakan di bawah untuk referensi:",
+       "blocklog-showlog": "Pengguna ini telah diblokir sebelumnya.\nLog pemblokiran disediakan di bawah untuk referensi:",
        "blocklog-showsuppresslog": "Pengguna ini telah diblokir dan disembunyikan sebelumnya. Log supresi disediakan di bawah untuk referensi:",
        "blocklogentry": "memblokir [[$1]] dengan waktu kedaluwarsa $2 $3",
        "reblock-logentry": "mengubah pemblokiran [[$1]] dengan waktu kedaluwarsa $2 $3",
-       "blocklogtext": "Di bawah ini adalah log pemblokiran dan pembukaan blokir terhadap pengguna.\nAlamat IP yang diblokir secara otomatis tidak terdapat di dalam daftar ini.\nLihat [[Special:BlockList|daftar pemblokiran]] untuk semua pengguna yang saat ini diblokir.",
+       "blocklogtext": "Berikut adalah log tindakan pemblokiran dan pembukaan blokir terhadap pengguna.\nAlamat IP yang diblokir secara otomatis tidak terdapat di dalam daftar ini.\nLihat [[Special:BlockList|daftar pemblokiran]] untuk semua pengguna yang saat ini diblokir.",
        "unblocklogentry": "menghilangkan blokir \"$1\"",
        "block-log-flags-anononly": "hanya pengguna anonim",
        "block-log-flags-nocreate": "pembuatan akun dimatikan",
        "ipb_expiry_invalid": "Waktu kedaluwarsa tidak sah.",
        "ipb_expiry_temp": "Pemblokiran atas nama pengguna yang disembunyikan harus permanen.",
        "ipb_hide_invalid": "Tak dapat menutup akun ini; akun tersebut memiliki {{PLURAL:$1|satu suntingan|$1 suntingan}}.",
-       "ipb_already_blocked": "\"$1\" telah diblokir",
+       "ipb_already_blocked": "\"$1\" telah diblokir.",
        "ipb-needreblock": "$1 sudah diblokir. Apakah Anda ingin mengubah set pemblokiran yang bersangkutan?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Blok|Blok}} lain",
        "unblock-hideuser": "Anda tidak dapat membuka blokir pengguna ini karena nama pengguna mereka telah disembunyikan.",
        "ipb_cant_unblock": "Kesalahan: Blokir dengan ID $1 tidak ditemukan. Blokir tersebut kemungkinan telah dibuka.",
-       "ipb_blocked_as_range": "Kesalahan: IP $1 tidak diblok secara langsung dan tidak dapat dilepaskan. IP $1 diblok sebagai bagian dari pemblokiran kelompok IP $2, yang dapat dilepaskan.",
+       "ipb_blocked_as_range": "Kesalahan: IP $1 tidak diblokir secara langsung dan tidak dapat dilepaskan. IP $1 diblok sebagai bagian dari pemblokiran kelompok IP $2, yang dapat dilepaskan.",
        "ip_range_invalid": "Blok IP tidak sah.",
        "ip_range_toolarge": "Rentang blok lebih besar dari /$1 tidak diperbolehkan.",
        "proxyblocker": "Pemblokir proxy",
-       "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.",
+       "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.",
        "sorbs": "DNSBL",
        "sorbsreason": "Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL.",
        "sorbs_create_account_reason": "Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL. Anda tidak dapat membuat akun.",
-       "xffblockreason": "Sebuah alamat IP di kepala X-Forwarded-For, entah milik Anda atau server proxy yang Anda pakai, telah diblokir. Alasan pemblokirannya adalah: $1",
-       "cant-see-hidden-user": "Pengguna yang anda coba blokir telah di blokir dan di sembunyikan. Selama anda tidak memiliki hak sembunyikan pengguna, anda tidak dapat melihat atau menyunting pemblokiran pengguna ini.",
-       "ipbblocked": "Anda tidak dapat memblokir atau membuka blokir pengguna lain, karena anda sendiri diblokir",
+       "xffblockreason": "Sebuah alamat IP terdapat di kepala X-Forwarded-For, entah milik Anda atau peladen ''proxy'' yang Anda gunakan, telah diblokir. Alasan pemblokirannya adalah: $1",
+       "cant-see-hidden-user": "Pengguna yang Anda coba blokir telah diblokir dan disembunyikan. Selama Anda tidak memiliki hak sembunyikan pengguna, Anda tidak dapat melihat atau menyunting pemblokiran pengguna ini.",
+       "ipbblocked": "Anda tidak dapat memblokir atau membuka blokir pengguna lain, karena Anda sendiri diblokir.",
        "ipbnounblockself": "Anda tidak diizinkan untuk membuka blokir sendiri",
        "lockdb": "Kunci basis data",
        "unlockdb": "Buka kunci basis data",
        "creditspage": "Penghargaan halaman",
        "nocredits": "Tidak ada informasi penghargaan yang tersedia untuk halaman ini.",
        "spamprotectiontitle": "Filter pencegah spam",
-       "spamprotectiontext": "Halaman yang ingin Anda simpan telah diblokir oleh filter spam.\nIni mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hitam.",
+       "spamprotectiontext": "Halaman yang ingin Anda simpan telah diblokir oleh penyaring spam.\nHal ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hitam.",
        "spamprotectionmatch": "Teks berikut ini memancing filter spam kami: $1",
        "spambot_username": "Pembersihan span MediaWiki",
        "spam_reverting": "Membatalkan ke versi terakhir yang tak memiliki pranala ke $1",
        "version-hook-subscribedby": "Dilanggani oleh",
        "version-version": "($1)",
        "version-no-ext-name": "[tanpa nama]",
-       "version-svn-revision": "(r$2)",
        "version-license": "Lisensi MediaWiki",
        "version-ext-license": "Lisensi",
        "version-ext-colheader-name": "Ekstensi",
        "tags-activate": "aktifkan",
        "tags-deactivate": "nonaktifkan",
        "tags-hitcount": "$1 {{PLURAL:$1|perubahan}}",
+       "tags-manage-blocked": "Anda tidak dapat mengganti tag ketika sedang diblokir.",
        "tags-create-heading": "Buat sebuah tag baru",
        "tags-create-reason": "Alasan:",
        "tags-create-submit": "Buat",
        "tags-activate-submit": "Aktifkan",
        "tags-deactivate-reason": "Alasan:",
        "tags-deactivate-submit": "Matikan",
+       "tags-apply-blocked": "Anda tidak dapat menerapkan perubahan tag dan perubahan lainnya ketika sedang diblokir.",
+       "tags-update-blocked": "Anda tidak dapat menambah atau menghapus tag ketika sedang diblokir.",
        "tags-edit-reason": "Alasan:",
        "comparepages": "Bandingkan halaman",
        "compare-page1": "Halaman 1",
        "revdelete-restricted": "akses telah dibatasi untuk opsis",
        "revdelete-unrestricted": "pembatasan akses opsis dihapuskan",
        "logentry-block-block": "$1 {{GENDER:$2|memblokir}} {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
+       "logentry-block-unblock": "$1 telah {{GENDER:$2|mencabut pemblokiran}} atas {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|mengubah}} pemblokiran {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|memblokir}} {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|mengubah}} pemblokiran {{GENDER:$4|$3}} dengan waktu kedaluwarsa $5 $6",
index 8ef32b7..a4f8828 100644 (file)
        "right-blockemail": "Agserra iti agar-aramat manipud iti panagipatulod ti esurat",
        "right-hideuser": "Agserra iti nagan ti agar-aramat, ken agilemmeng manipud iti publiko",
        "right-ipblock-exempt": "Labsanna dagiti serra ti IP, dagiti automatiko a serra ken dagiti sakop a serra.",
-       "right-proxyunbannable": "Labsanna dagiti automatiko a serra dagiti pannakbagi",
        "right-unblockself": "Bukod nga agikkat it pannakaserra",
        "right-protect": "Agsukat kadagiti agpang ti salaknib ken agurnos kadagiti nasalakniban ti sariap a panid",
        "right-editprotected": "Agurnos kadagiti panid a nasalakniban a kas \"{{int:protect-level-sysop}}\"",
        "uploaded-script-svg": "Nakabiruk ti maieskritu nga elemento ti \"$1\" iti naikarga a papeles ti SVG.",
        "uploaded-hostile-svg": "Nakabiruk ti saan a natalged a CSS iti elemento ti estilo ti naikarga a papeles ti SVG.",
        "uploaded-event-handler-on-svg": "Ti panangisaad kadagiti gupit ti panagtengngel ti pasamak ti <code>$1=\"$2\"</code> ket saan a maipalubos kadagiti papeles ti SVG.$1",
-       "uploaded-href-attribute-svg": "Dagiti gupit ti href ti <code>&lt;$1 $2=\"$3\"&gt;</code> nga addaan iti saan a lokal a puntaan (kas ti http://, javascript:, kdpy) ket saan a maipalubos kadagiti papeles ti SVG.",
        "uploaded-href-unsafe-target-svg": "Nakabiruk ti href iti saan a natalged a puntaan ti <code>&lt;$1 $2=\"$3\"&gt;</code> iti naikarga a papeles ti SVG.",
        "uploaded-animate-svg": "Nakabiruk ti etiketa ti \"animado\" a mabalin a mangbalbaliw iti href, nga agus-usar iti gupit ti \"manipud\" ti <code>&lt;$1 $2=\"$3\"&gt;</code> iti naikarga a papeles ti SVG.",
        "uploaded-setting-event-handler-svg": "Naserraan ti panangisaad ti kadagiti gupit ti panagtengngel ti pasamak, nakabiruk iti <code>&lt;$1 $2=\"$3\"&gt;</code> iti naikarga a papeles ti SVG.",
        "watchthisupload": "Bantayan daytoy a papeles",
        "filewasdeleted": "Ti papeles iti daytoy a nagan ket dati a naikarga ken kanungpalan a naikkat.\nNasken a kitaem ti $1 sakbay nga agtuloy a mangikarga manen.",
        "filename-bad-prefix": "Ti nagan ti papeles nga ikarkargam ket mangrugi iti <strong>\"$1\"</strong>,  ken saan a deskriptibo a nagan a kadawyan nga automatiko nga ited babaen dagiti digital a kamera.\nPangngaasi nga agpili ti nasaysayaat a deskriptibo a nagan ti papelesmo.",
-       "upload-success-subj": "Balligi ti panagikarga",
-       "upload-success-msg": "Ti panagikargam manipud ti [$2] ket nagballigi. Daytoy ket magun-od ditoy [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Parikut ti panagikarga",
-       "upload-failure-msg": "Adda parikut ti panagikargam manipud iti [$2]:\n\n$1",
-       "upload-warning-subj": "Ballaag ti panagikarga",
-       "upload-warning-msg": "Adda parikut iti panagikargam manipud iti [$2]. Mabalinmo ti agsubli iti [[Special:Upload/stash/$1|porma ti panagikarga]] tapno masimpa daytoy a parikut.",
        "upload-proto-error": "Saan a husto a protokol",
        "upload-proto-error-text": "Ti adayo a panagikarga ket makasapul kadagiti URL a mangrugi iti <code>http://</code> wenno <code>ftp://</code>.",
        "upload-file-error": "Akin-uneg a biddut",
        "querypage-disabled": "Daytoy nga espesial a panid ket nabaldado gapu kadagiti rason ti kasayaat ti panagpataray.",
        "apihelp": "Tulong ti API",
        "apihelp-no-such-module": "Saan a nabirukan ti modulo ti \"$1\".",
+       "apisandbox": "Pagsubokan ti API",
+       "apisandbox-api-disabled": "Ti API ket nabaldado iti daytoy a sitio.",
+       "apisandbox-intro": "Usaren daytoy a panid iti panagsubok ti '''MediaWiki a serbisio ti web ti API'''.\nKitaen ti [//www.mediawiki.org/wiki/API:Main_page the API dokumentasion] para iti ad-adu pay a salaysay ti panagusar ti API. Kas pagarigan: [//www.mediawiki.org/wiki/API#A_simple_example alaen ti linaon ti Umuna a Panid].  Agpili ti maaramid tapno makakita ti adu pay a kas pagarigan.\n\nLaglagipen nga uray daytoy ket pagipadasan, dagiti tignay nga aramidem iti daytoy a panid ket mabalin a mangbaliw iti wiki.",
+       "apisandbox-submit": "Agaramid ti kiddaw",
+       "apisandbox-reset": "Dalusan",
+       "apisandbox-examples": "Kas pagarigan",
+       "apisandbox-results": "Nagbanagan",
+       "apisandbox-request-url-label": "Agkiddaw ti URL:",
+       "apisandbox-request-time": "Oras ti kiddaw: $1",
        "booksources": "Dagiti taudan ti libro",
        "booksources-search-legend": "Agbiruk para kadagiti taudan ti libro",
        "booksources-search": "Biruken",
        "wlheader-showupdated": "Dagiti panid a nasukatanen manipud ti kinaudi a panagsarungkarmo ket naipakita iti <strong>napuskol</strong>.",
        "wlnote": "Dita baba ket {{PLURAL:$1|naudi a sinukatan|dagiti naudi a <strong>$1</strong> a sinukatan}} iti napalabas {{PLURAL:$2|nga oras|a <strong>$2</strong> nga or-oras}}, manipud idi $3, $4.",
        "wlshowlast": "Ipakita dagiti naudi a $1 nga or-oras $2 nga al-aldaw",
-       "watchlistall2": "amin",
        "watchlist-hide": "Ilemmeng",
        "watchlist-submit": "Ipakita",
        "wlshowtime": "Ipakita a paset ti panawen:",
        "mw-widgets-dateinput-placeholder-month": "TTTT-BB",
        "mw-widgets-titleinput-description-new-page": "awan pay ti panid",
        "mw-widgets-titleinput-description-redirect": "ibaw-ing iti $1",
-       "api-error-blacklisted": "Pangngaasi nga agpili iti sabali, a mangipalpalawag a titulo."
+       "api-error-blacklisted": "Pangngaasi nga agpili iti sabali, a mangipalpalawag a titulo.",
+       "randomrootpage": "Pugto a ramut a panid"
 }
index f1b13ed..bf1c630 100644 (file)
                        "Sveinn í Felli",
                        "Jonbg",
                        "Matma Rex",
-                       "Xð"
+                       "Xð",
+                       "Sveinki"
                ]
        },
        "tog-underline": "Undirstrika tengla:",
        "tog-hideminor": "Fela minniháttar breytingar í nýlegum breytingum",
        "tog-hidepatrolled": "Fela yfirfarnar breytingar í nýlegum breytingum",
        "tog-newpageshidepatrolled": "Fela yfirfarnar breytingar í listanum yfir nýjar síður",
+       "tog-hidecategorization": "Fela flokkun á síðum",
        "tog-extendwatchlist": "Sýna allar breytingar á vaktlistanum, ekki einungis þær nýjustu",
        "tog-usenewrc": "Flokka breytingar eftir síðu í nýlegum breytingum og vaktlista",
        "tog-numberheadings": "Númera fyrirsagnir sjálfkrafa",
@@ -58,6 +60,7 @@
        "tog-watchlisthideliu": "Ekki sýna breytingar innskráðra notenda á vaktlistanum",
        "tog-watchlisthideanons": "Ekki sýna breytingar óþekktra notenda á vaktlistanum",
        "tog-watchlisthidepatrolled": "Fela yfirfarnar breytingar í vaktlistanum",
+       "tog-watchlisthidecategorization": "Fela flokkun á síðum",
        "tog-ccmeonemails": "Senda mér afrit af tölvupóstum sem ég sendi öðrum notendum",
        "tog-diffonly": "Ekki sýna síðuefni undir mismunum",
        "tog-showhiddencats": "Sýna falda flokka",
        "october-date": "$1. október",
        "november-date": "$1. nóvember",
        "december-date": "$1. desember",
+       "period-am": "FH",
+       "period-pm": "EH",
        "pagecategories": "{{PLURAL:$1|Flokkur|Flokkar}}",
        "category_header": "Síður í flokknum „$1“",
        "subcategories": "Undirflokkar",
        "nospecialpagetext": "Þú hefur beðið um kerfissíðu sem ekki er til. Listi yfir gildar kerfissíður er að finna á [[Special:SpecialPages|kerfissíður]].",
        "error": "Villa",
        "databaseerror": "Gagnagrunnsvilla",
+       "databaseerror-query": "Fyrirspurn: $1",
        "databaseerror-error": "Villa: $1",
        "laggedslavemode": "Viðvörun: Síðan inniheldur ekki nýjustu uppfærslur.",
        "readonly": "Gagnagrunnur læstur",
        "filerenameerror": "Gat ekki endurnefnt skrána „$1“ í „$2“.",
        "filedeleteerror": "Gat ekki eytt skránni „$1“.",
        "directorycreateerror": "Gat ekki búið til efnisskrána \"$1\".",
+       "directoryreadonlyerror": "Mappan \"$1\" er skrifvarin.",
+       "directorynotreadableerror": "Mappan \"$1\" er ekki lesanleg.",
        "filenotfound": "Gat ekki fundið skrána „$1“.",
        "unexpected": "Óvænt gildi: „$1“=„$2“.",
        "formerror": "Villa: gat ekki sent eyðublað",
        "passwordreset-emailerror-capture": "Tölvupóstur til að endursetja lykilorðið var búinn til, sem er sýndur hér fyrir neðan, en ekki tókst að senda hana til {{GENDER:$2|notandans}}: $1",
        "changeemail": "Breyta eða fjarlægja netfang",
        "changeemail-header": "Fylltu út þetta eyðublað til að breyta netfanginu þínu. Ef þú vilt fjarlægja tengingu allra netfanga frá aðganginum þínum skildu þá netfangs reitinn eftir tóman.",
+       "changeemail-passwordrequired": "Þú verður að setja inn lykilorðið þitt til að staðfesta þessa breytingu.",
        "changeemail-no-info": "Þú verður að vera skráð(ur) inn til að hafa aðgang að þessari síðu.",
        "changeemail-oldemail": "Núverandi netfang:",
        "changeemail-newemail": "Nýtt netfang:",
        "edit-conflict": "Breytingaárekstur.",
        "edit-no-change": "Breyting þín var hunsuð, því engin breyting var á textanum.",
        "postedit-confirmation-created": "Síðan hefur verið búin til.",
-       "postedit-confirmation-saved": "Breyting þín hefur verið vistuð.",
+       "postedit-confirmation-restored": "Síðan hefur verið endurheimt.",
+       "postedit-confirmation-saved": "Breytingin þín hefur verið vistuð.",
        "edit-already-exists": "Gat ekki skapað nýja síðu.\nHún er nú þegar til.",
-       "defaultmessagetext": "Sjálfgefinn skilaboða texti",
+       "defaultmessagetext": "Sjálfgefinn texti skilaboða",
        "content-failed-to-parse": "Gat ekki þáttað $2 efni samkvæmt $1 líkani: $3",
        "invalid-content-data": "Ógild efnisgögn.",
        "content-not-allowed-here": "„$1“ efni er ekki leyfilegt á síðunni [[$2]]",
        "notextmatches": "Engar samsvaranir á texta í síðum",
        "prevn": "síðustu {{PLURAL:$1|$1}}",
        "nextn": "næstu {{PLURAL:$1|$1}}",
+       "prev-page": "fyrri síða",
+       "next-page": "næsta síða",
        "prevn-title": "Fyrri $1 {{PLURAL:$1|niðurstaða|niðurstöður}}",
        "nextn-title": "{{PLURAL:$1|Næsta|Næstu}} $1 {{PLURAL:$1|niðurstaða|niðurstöður}}",
        "shown-title": "Sýna $1 {{PLURAL:$1|niðurstöðu|niðurstöður}} á hverri síðu",
        "search-result-category-size": "{{PLURAL:$1|1 meðlimur|$1 meðlimir}} ({{PLURAL:$2|1 undirflokks|$2 undirflokka}}, {{PLURAL:$3|1 skrá|$3 skrár}})",
        "search-redirect": "(tilvísun $1)",
        "search-section": "(hluti $1)",
+       "search-category": "(flokkur $1)",
        "search-file-match": "(passar við innihald skráa)",
        "search-suggest": "Varstu að leita að: $1",
        "search-interwiki-caption": "Systurverkefni",
        "columns": "Dálkar",
        "searchresultshead": "Leit",
        "stub-threshold": "Þröskuldur fyrir stílsnið stubbatengla ($1):",
+       "stub-threshold-sample-link": "dæmi",
        "stub-threshold-disabled": "Óvirkt",
        "recentchangesdays": "Fjöldi daga sem nýlegar breytingar ná yfir:",
        "recentchangesdays-max": "(hámark $1 {{PLURAL:$1|dag|daga}})",
        "right-override-export-depth": "Flytja út síður með greinum þar sem allt að 5 greinar tengja þær saman.",
        "right-sendemail": "Senda tölvupóst til annara notenda",
        "right-passwordreset": "Skoða tölvupósta um endurstillingu lykilorðs",
+       "grant-group-email": "Senda tölvupóst",
+       "grant-createaccount": "Stofna aðganga",
+       "grant-createeditmovepage": "Búa til, breyta og færa síður",
+       "grant-delete": "Eyða síðum, yfirferðum og annálsfærslum",
        "newuserlogpage": "Skrá yfir nýja notendur",
        "newuserlogpagetext": "Þetta er skrá yfir nýskráða notendur.",
        "rightslog": "Réttindaskrá notenda",
        "rcshowhidemine": "$1 mínar breytingar",
        "rcshowhidemine-show": "Sýna",
        "rcshowhidemine-hide": "Fela",
+       "rcshowhidecategorization-show": "Birta",
+       "rcshowhidecategorization-hide": "Fela",
        "rclinks": "Sýna síðustu $1 breytingar síðustu $2 daga<br />$3",
        "diff": "breyting",
        "hist": "breytingaskrá",
        "watchthisupload": "Vakta þessa skrá",
        "filewasdeleted": "Skrá af sama nafni hefur áður verið hlaðið inn og síðan eytt. Þú ættir að athuga $1 áður en þú hleður skránni inn.",
        "filename-bad-prefix": "Sráarnafnið lýsir ekki skránni, heldur var það búið til af myndavélinni, því það byrjar á '''\"$1\"'''.\nVeldu lýsandi nafn fyrir skránna og reyndu aftur.",
-       "upload-success-subj": "Innhlaðning tókst",
-       "upload-success-msg": "Upphlöðun frá [$2] tókst. Það er aðgengilegt hér: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Vandamál við upphleðslu",
-       "upload-failure-msg": "Upphlaðið frá [$2] mistókst:\n\n$1",
-       "upload-warning-subj": "Aðvörun",
-       "upload-warning-msg": "Upphal þitt [$2] mistókst. Þú getur farið aftur á [[Special:Upload/stash/$1|upphlaðsviðmótið]] og leiðrétt villuna.",
        "upload-proto-error": "Vitlaus samskiptaregla",
        "upload-proto-error-text": "Upphlöðun frá öðrum vefþjón þarfnast vefslóðar sem byrjar á <code>http://</code> eða <code>ftp://</code>.",
        "upload-file-error": "Innri villa",
        "upload-too-many-redirects": "Vefslóðin inniheldur of margar tilvísanir.",
        "upload-http-error": "HTTP villa kom upp: $1",
        "upload-copy-upload-invalid-domain": "Lokað er fyrir afritun skráa frá öðrum vefþjón á þessu vefsvæði.",
+       "upload-dialog-title": "Hlaða inn skrá",
+       "upload-dialog-button-cancel": "Hætta við",
+       "upload-dialog-button-done": "Lokið",
+       "upload-dialog-button-save": "Vista",
+       "upload-dialog-button-upload": "Hlaða inn",
+       "upload-form-label-select-file": "Velja skrá",
+       "upload-form-label-infoform-title": "Nánar",
+       "upload-form-label-infoform-name": "Heiti",
+       "upload-form-label-infoform-name-tooltip": "Einstakur og lýsandi titill, sem mun verða skráarnafn. Þú mátt nota einfalt mál með bilum. Ekki hafa með neina skráarendingu.",
+       "upload-form-label-infoform-description": "Lýsing",
+       "upload-form-label-infoform-description-tooltip": "Lýstu stuttlega öllu því sem er markvert um verkið.\nFyrir ljósmyndir, nefndu aðalatriði myndarinnar, tilefni eða staðsetningu.",
+       "upload-form-label-usage-title": "Notkun",
+       "upload-form-label-usage-filename": "Skráarheiti",
+       "foreign-structured-upload-form-label-own-work": "Það er mitt eigið verk",
+       "foreign-structured-upload-form-label-infoform-categories": "Flokkar",
+       "foreign-structured-upload-form-label-infoform-date": "Dagsetning",
+       "foreign-structured-upload-form-3-label-yes": "Já",
+       "foreign-structured-upload-form-3-label-no": "Nei",
        "backend-fail-stream": "Gat ekki streymt skránni „$1“.",
        "backend-fail-backup": "Öryggisafritun skrárinnar $1 mistókst.",
        "backend-fail-notexists": "Skráin $1 er ekki til.",
        "nolicense": "Ekkert valið",
        "licenses-edit": "Breyta leyfisvali",
        "license-nopreview": "(Forskoðun ekki fáanleg)",
-       "upload_source_url": "(þín valda skrá frá gildri, aðgengilegri vefslóð)",
-       "upload_source_file": "(þín valda skrá frá tölvunni þinni)",
+       "upload_source_url": "(skrá sem þú velur frá gildri og aðgengilegri vefslóð)",
+       "upload_source_file": "(skrá sem þú velur á tölvunni þinni)",
        "listfiles-delete": "eyða",
        "listfiles-summary": "Þessi kerfissíða sýnir allar upphlaðnar skrár.",
        "listfiles_search_for": "Leita að miðilsnafni:",
        "randomincategory-nopages": "Það eru engar síður í flokkinum [[:Category:$1|$1]].",
        "randomincategory-category": "Flokkur:",
        "randomincategory-legend": "Handhófsvalin síða í flokki",
+       "randomincategory-submit": "Fara",
        "randomredirect": "Handahófsvalin tilvísun",
        "randomredirect-nopages": "Það eru engar tilvísanir í nafnrýminu „$1“.",
        "statistics": "Tölfræði",
        "mostrevisions": "Síður eftir fjölda breytinga",
        "prefixindex": "Allar síður með forskeyti",
        "prefixindex-namespace": "Allar síður með forskeyti ($1 nafnrými)",
+       "prefixindex-submit": "Birta",
        "prefixindex-strip": "Fjarlægja forskeyti í listanum",
        "shortpages": "Stuttar síður",
        "longpages": "Langar síður",
        "protectedpages-performer": "Vernduð af",
        "protectedpages-params": "Verndunar stikar",
        "protectedpages-reason": "Ástæða",
+       "protectedpages-submit": "Birta síður",
        "protectedpages-unknown-timestamp": "Óþekktur",
        "protectedpages-unknown-performer": "Óþekktur notandi",
        "protectedtitles": "Verndaðir titlar",
        "protectedtitlesempty": "Engir titlar eru verndaðir með þessum stikum.",
+       "protectedtitles-submit": "Sýna titla",
        "listusers": "Notendalisti",
        "listusers-editsonly": "Sýna eingöngu notendur með breytingar",
        "listusers-creationsort": "Raða eftir stofndegi",
        "usereditcount": "$1 {{PLURAL:$1|breyting|breytingar}}",
        "usercreated": "{{GENDER:$3|Stofnað|}} $1 $2",
        "newpages": "Nýjustu greinar",
+       "newpages-submit": "Birta",
        "newpages-username": "Notandanafn:",
        "ancientpages": "Síst uppfærðar síður",
        "move": "Færa",
        "specialloguserlabel": "Gerandi:",
        "speciallogtitlelabel": "Beinist að (titill eða {{ns:user}}:notendanafn fyrir notanda):",
        "log": "Aðgerðaskrár",
+       "logeventslist-submit": "Birta",
        "all-logs-page": "Allar aðgerðir",
        "alllogstext": "Safn allra aðgerðaskráa {{SITENAME}}.\nÞú getur takmarkað listann með því að velja tegund aðgerðaskráar, notandanafn, eða síðu.",
        "logempty": "Engin slík aðgerð fannst.",
        "log-title-wildcard": "Leita að titlum sem byrja á þessum texta",
        "showhideselectedlogentries": "Sýna/fela valdar aðgerða færslur",
+       "checkbox-select": "Velja: $1",
+       "checkbox-all": "Allt",
+       "checkbox-none": "Ekkert",
+       "checkbox-invert": "Snúa við",
        "allpages": "Allar síður",
        "nextpage": "Næsta síða ($1)",
        "prevpage": "Fyrri síða ($1)",
        "cachedspecial-viewing-cached-ts": "Þetta er útgáfa þessarar síðu úr skyndiminni og sem endurspeglar ekki endilega núverandi ástand.",
        "cachedspecial-refresh-now": "Skoða síðustu",
        "categories": "Flokkar",
+       "categories-submit": "Birta",
        "categoriespagetext": "Eftirfarandi {{PLURAL:$1|flokkur inniheldur|flokkar innihalda}} síður eða skrár.\n[[Special:UnusedCategories|Ónotaðir flokkar]] birtast ekki hér.\nSjá einnig [[Special:WantedCategories|eftirsótta flokka]].",
        "categoriesfrom": "Sýna flokka frá:",
        "special-categories-sort-count": "raða eftir fjölda",
        "activeusers-hidebots": "Fela vélmenni",
        "activeusers-hidesysops": "Fela möppudýr",
        "activeusers-noresult": "Enginn notandi fannst.",
+       "activeusers-submit": "Sýna virka notendur",
        "listgrouprights": "Notandahópréttindi",
        "listgrouprights-summary": "Hér er listi yfir notendahópa á þessum wiki, með þeirra réttindum. \nÞað gæti verið til síða með [[{{MediaWiki:Listgrouprights-helppage}}|frekari upplýsingar]] um einstök réttindi.",
        "listgrouprights-key": "Skýringar:\n* <span class=\"listgrouprights-granted\">Veitt réttindi</span>\n* <span class=\"listgrouprights-revoked\">Afturkölluð réttindi</span>",
        "listgrouprights-removegroup-self": "Fjarlægja sjálfan sig úr {{PLURAL:$2|hópinum|hópunum}}: $1",
        "listgrouprights-addgroup-self-all": "Bæta sjálfum sér í alla hópa",
        "listgrouprights-removegroup-self-all": "Fjarlægja sjálfan sig úr öllum hópum",
+       "listgrouprights-namespaceprotection-header": "Takmarkanir nafnrýmis",
+       "listgrouprights-namespaceprotection-namespace": "Nafnrými",
+       "listgrants-rights": "Réttindi",
+       "trackingcategories-nodesc": "Enginn lýsing tiltæk.",
+       "trackingcategories-disabled": "Flokkurinn er óvirkur",
        "mailnologin": "Ekkert netfang til að senda á",
        "mailnologintext": "Þú verður að vera [[Special:UserLogin|innskráð(ur)]] auk þess að hafa gilt netfang í [[Special:Preferences|stillingunum]] þínum til að senda tölvupóst til annara notenda.",
        "emailuser": "Senda þessum notanda tölvupóst",
        "wlheader-showupdated": "Síðum sem hefur verið breytt síðan þú skoðaðir þær síðast eru '''feitletraðar'''.",
        "wlnote": "Hér fyrir neðan {{PLURAL:$1|er síðasta <strong>$1</strong> breyting|eru síðustu <strong>$1</strong> breytingar}} {{PLURAL:$2|síðasta <strong>$2</strong> klukkutímann|síðustu <strong>$2</strong> klukkutímana}}, frá $3, $4.",
        "wlshowlast": "Sýna síðustu $1 klukkutíma, $2 daga",
-       "watchlistall2": "allt",
+       "watchlist-hide": "Fela",
+       "watchlist-submit": "Birta",
+       "wlshowhideliu": "skráðir notendur",
+       "wlshowhideanons": "óskráðir notendur",
+       "wlshowhidepatr": "vaktaðar breytingar",
+       "wlshowhidemine": "mínar breytingar",
        "watchlist-options": "Vaktlistastillingar",
        "watching": "Vakta...",
        "unwatching": "Afvakta...",
        "rollback-success": "Tók til baka breytingar eftir $1; núverandi $2.",
        "sessionfailure-title": "Mistök í setu",
        "sessionfailure": "Líklega er vandamál með innskráningar setuna þína;\nhætt hefur verið við þessa aðgerð sem vörn gegn mögulegu samskiptaráni setunar.\nFarðu aftur á fyrri síðu, endurhladdu hana og reyndu aftur.",
+       "changecontentmodel-title-label": "Titill síðu",
+       "changecontentmodel-reason-label": "Ástæða:",
        "protectlogpage": "Verndunarskrá",
        "protectlogtext": "Fyrir neðan er listi yfir síðuverndanir og -afverndanir.\nSjáðu [[Special:ProtectedPages|Verndunarskrá]] fyrir núverandi lista yfir verndaðar síður.",
        "protectedarticle": "verndaði „[[$1]]“",
        "whatlinkshere-hidelinks": "$1 tengla",
        "whatlinkshere-hideimages": "$1 skrátenglar",
        "whatlinkshere-filters": "Síur",
+       "whatlinkshere-submit": "Fara",
        "autoblockid": "Sjálfvirkt bann $1",
        "block": "Banna notanda",
        "unblock": "Afbanna notanda",
        "export-pagelinks": "Innifela tengdar síður með dýptinni:",
        "allmessages": "Meldingar",
        "allmessagesname": "Titill",
-       "allmessagesdefault": "Sjálfgefinn skilaboða texti",
+       "allmessagesdefault": "Sjálfgefinn texti skilaboða",
        "allmessagescurrent": "Núverandi texti",
        "allmessagestext": "Þetta er listi yfir kerfismeldingar í Melding-nafnrýminu.\nVinsamlegast heimsæktu [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki-staðfæringuna] og [//translatewiki.net translatewiki.net] ef þú vilt taka þátt í almennri MediaWiki-staðfæringu.",
        "allmessagesnotsupportedDB": "Það er ekki hægt að nota '''{{ns:special}}:Allmessages''' því '''$wgUseDatabaseMessages''' hefur verið gerð óvirk.",
        "tooltip-t-recentchangeslinked": "Nýlegar breytingar á ítengdum síðum",
        "tooltip-feed-rss": "RSS fyrir þessa síðu",
        "tooltip-feed-atom": "Atom fyrir þessa síðu",
-       "tooltip-t-contributions": "Sýna framlagslista þessa notanda",
+       "tooltip-t-contributions": "Listi yfir framlög frá þessum notanda",
        "tooltip-t-emailuser": "Senda þessum notanda tölvupóst",
        "tooltip-t-upload": "Hlaða inn skrám",
        "tooltip-t-specialpages": "Listi yfir kerfissíður",
        "logentry-block-unblock": "$1 {{GENDER:$2|afbannaði}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|breytti}} bann stillingum fyrir {{GENDER:$4|$3}}, rennur út $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|bannaði}} {{GENDER:$4|$3}}, rennur út eftir $5 $6",
+       "logentry-merge-merge": "$1 {{GENDER:$2|sameinaði}} $3 inn í $4 (útgáfur til $5)",
        "logentry-move-move": "$1 {{GENDER:$2|færði}} $3 á $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|færði}} $3 á $4 án þess að skilja eftir tilvísun",
        "logentry-move-move_redir": "$1 {{GENDER:$2|færði}} $3 á $4 yfir tilvísun",
index 08170be..21d22d5 100644 (file)
@@ -94,7 +94,8 @@
                        "Oggioniale",
                        "Wim b",
                        "V6rg",
-                       "JackLantern"
+                       "JackLantern",
+                       "Mpiva"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "prefs-rc": "Ultime modifiche",
        "prefs-watchlist": "Osservati speciali",
        "prefs-editwatchlist": "Modifica osservati speciali",
-       "prefs-editwatchlist-label": "Modifica le pagine della tua watchlist:",
-       "prefs-editwatchlist-edit": "Visualizza e rimuovi titoli sulla tua watchlist",
+       "prefs-editwatchlist-label": "Modifica i tuoi osservati speciali:",
+       "prefs-editwatchlist-edit": "Visualizza e rimuovi titoli nei tuoi osservati speciali",
        "prefs-editwatchlist-raw": "Modifica la lista in formato testo",
-       "prefs-editwatchlist-clear": "Cancella la tua watchlist",
+       "prefs-editwatchlist-clear": "Svuota i tuoi osservati speciali",
        "prefs-watchlist-days": "Numero di giorni da mostrare negli osservati speciali:",
        "prefs-watchlist-days-max": "Massimo $1 {{PLURAL:$1|giorno|giorni}}",
        "prefs-watchlist-edits": "Numero di modifiche da mostrare con le funzioni avanzate:",
        "uploaded-script-svg": "Trovato elemento di script \"$1\" nel file caricato in formato SVG.",
        "uploaded-hostile-svg": "Trovato CSS non sicuro nell'elemento di stile del file in formato SVG caricato.",
        "uploaded-event-handler-on-svg": "Impostazione gestione eventi ed attributi <code>$1=\"$2\"</code> non è consentito in file SGV",
-       "uploaded-href-attribute-svg": "Attributi href <code>&lt;$1 $2=\"$3\"&gt;</code> com un bersaglio non locale (e.g. http://, javascript:, etc) non sono permessi file SGV",
-       "uploaded-href-unsafe-target-svg": "Trovati href ad un bersaglio non sicuro <code>&lt;$1 $2=\"$3\"&gt;</code> caricato nel file SVG",
+       "uploaded-href-attribute-svg": "attributi href in file SVG sono consentiti collegamenti solo verso destinazioni http:// o https://, trovato <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Trovati href a dati non sicuri: destinazione URI <code>&lt;$1 $2=\"$3\"&gt;</code> caricato nel file SVG",
        "uploaded-animate-svg": "Trovato il tag \"animate\" che potrebbe cambiare href, usando l'attributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> nel file SVG caricato.",
        "uploaded-setting-event-handler-svg": "La configurazione di attributi per il gestore di eventi è bloccata, trovato <code>&lt;$1 $2=\"$3\"&gt;</code> nel file SVG caricato.",
        "uploaded-setting-href-svg": "Utilizzare il tag \"set\" per aggiungere l'attributo \"href\" all'elemento parentale è bloccato.",
        "querypage-disabled": "Questa pagina speciale è disattivata per motivi di prestazioni.",
        "apihelp": "Aiuto API",
        "apihelp-no-such-module": "Modulo \"$1\" non trovato.",
+       "apisandbox": "Pagina di prova API",
+       "apisandbox-jsonly": "È richiesto JavaScript per utilizzare la sandbox API.",
+       "apisandbox-api-disabled": "Le funzionalità API sono disabilitate su questo sito.",
+       "apisandbox-intro": "Utilizza questa pagina per sperimentare con le <strong>API web service MediaWiki</strong>.\nPer ulteriori dettagli di utilizzo delle API, fai riferimento alla [[mw:API:Main page|documentazione API]]. Esempio: [//www.mediawiki.org/wiki/API#A_simple_example ottenere il contenuto della pagina principale]. Seleziona un'azione per vedere altri esempi.\n\nNota che, anche se questa è una pagina per le prove, le azioni che esegui qui potrebbero modificare il wiki.",
+       "apisandbox-fullscreen": "Espandi pannello",
+       "apisandbox-fullscreen-tooltip": "Espandi il pannello sandbox per riempire la finestra del browser.",
+       "apisandbox-unfullscreen": "Mostra la pagina",
+       "apisandbox-unfullscreen-tooltip": "Riduci il pannello sandbox, così che i collegamenti di navigazione MediaWiki siano disponibili.",
+       "apisandbox-submit": "Inoltra richiesta",
+       "apisandbox-reset": "Pulisci",
+       "apisandbox-retry": "Riprova",
+       "apisandbox-loading": "Caricamento delle informazioni per il modulo API \"$1\"...",
+       "apisandbox-load-error": "Si è verificato un errore durante il caricamento delle informazioni per il modulo API \"$1\": $2",
+       "apisandbox-no-parameters": "Questo modulo API non ha parametri.",
+       "apisandbox-helpurls": "Collegamenti alla guida",
+       "apisandbox-examples": "Esempi",
+       "apisandbox-dynamic-parameters": "Parametri aggiuntivi",
+       "apisandbox-dynamic-parameters-add-label": "Aggiungi parametro:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nome del parametro",
+       "apisandbox-dynamic-error-exists": "Un parametro denominato \"$1\" esiste già.",
+       "apisandbox-deprecated-parameters": "Parametri sconsigliati",
+       "apisandbox-fetch-token": "Auto-compila il token",
+       "apisandbox-submit-invalid-fields-title": "Alcuni campi non sono validi",
+       "apisandbox-submit-invalid-fields-message": "Correggi i campi evidenziati e riprova.",
+       "apisandbox-results": "Risultati",
+       "apisandbox-sending-request": "Invio richiesta di API...",
+       "apisandbox-loading-results": "Ricezione dei risultati di API in corso...",
+       "apisandbox-results-error": "Si è verificato un errore durante il caricamento della risposta all'interrogazione API: $1",
+       "apisandbox-request-url-label": "URL di richiesta:",
+       "apisandbox-request-time": "Tempo richiesto: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Correggi token e reinvia",
+       "apisandbox-results-fixtoken-fail": "Impossibile recuperare il token \"$1\".",
+       "apisandbox-alert-page": "I campi su questa pagina non sono validi.",
+       "apisandbox-alert-field": "Il valore di questo campo non è valido.",
        "booksources": "Fonti librarie",
        "booksources-search-legend": "Ricerca di fonti librarie",
        "booksources-isbn": "Codice ISBN:",
index 1e29e7b..b10b201 100644 (file)
@@ -76,7 +76,7 @@
        "tog-hideminor": "最近の更新に細部の編集を表示しない",
        "tog-hidepatrolled": "最近の更新に巡回済みの編集を表示しない",
        "tog-newpageshidepatrolled": "新しいページの一覧に、巡回済みのページを表示しない",
-       "tog-hidecategorization": "ページのカテゴリ化を隠す",
+       "tog-hidecategorization": "ページのカテゴリを表示しない",
        "tog-extendwatchlist": "ウォッチリストを拡張し、最新のものだけではなくすべての変更を表示",
        "tog-usenewrc": "最近の更新とウォッチリストで、複数の変更をページごとにまとめる",
        "tog-numberheadings": "見出しに番号を自動的に振る",
@@ -87,7 +87,7 @@
        "tog-watchdefault": "自分が編集したページやファイルをウォッチリストに追加",
        "tog-watchmoves": "自分が移動したページやファイルをウォッチリストに追加",
        "tog-watchdeletion": "自分が削除したページやファイルをウォッチリストに追加",
-       "tog-watchrollback": "è\87ªå\88\86ã\81\8cå·»ã\81\8dæ\88»ã\81\97ã\81\9fã\83\9aã\83¼ã\82¸ã\82\92ã\80\81ã\82¦ã\82©ã\83\83ã\83\81ã\83ªã\82¹ã\83\88ã\81«è¿½å\8a ",
+       "tog-watchrollback": "自分が巻き戻したページをウォッチリストに追加",
        "tog-minordefault": "編集をすべて既定で細部の編集とする",
        "tog-previewontop": "プレビューを編集ボックスの前に配置",
        "tog-previewonfirst": "編集開始時にもプレビューを表示",
        "tog-oldsig": "既存の署名:",
        "tog-fancysig": "署名をウィキ文として扱う (自動リンクなし)",
        "tog-uselivepreview": "ライブプレビューを使用",
-       "tog-forceeditsummary": "要約欄が空欄の場合に確認をうながす",
+       "tog-forceeditsummary": "要約欄が空欄の場合に確認をす",
        "tog-watchlisthideown": "自分の編集をウォッチリストに表示しない",
        "tog-watchlisthidebots": "ボットによる編集をウォッチリストに表示しない",
        "tog-watchlisthideminor": "細部の編集をウォッチリストに表示しない",
        "tog-watchlisthideliu": "ログイン利用者による編集をウォッチリストに表示しない",
-       "tog-watchlistreloadautomatically": "フィルタが変更されるたびに、ウォッチリストを自動的に再読み込みする(JavaScript が必要)",
+       "tog-watchlistreloadautomatically": "フィルタが変更されるたびに、ウォッチリストを自動的に再読み込みする (JavaScript が必要)",
        "tog-watchlisthideanons": "匿名利用者による編集をウォッチリストに表示しない",
        "tog-watchlisthidepatrolled": "巡回済みの編集をウォッチリストに表示しない",
-       "tog-watchlisthidecategorization": "ページのカテゴリ化を隠す",
+       "tog-watchlisthidecategorization": "ページのカテゴリを表示しない",
        "tog-ccmeonemails": "他の利用者に送信したメールの控えを自分にも送信",
        "tog-diffonly": "差分の下にページ内容を表示しない",
        "tog-showhiddencats": "隠しカテゴリを表示",
        "morenotlisted": "この一覧は完全ではありません。",
        "mypage": "ページ",
        "mytalk": "トーク",
-       "anontalk": "議論",
+       "anontalk": "トーク",
        "navigation": "案内",
        "and": "&#32;と",
        "qbfind": "検索",
        "cannotdelete-title": "「$1」というページを削除できません",
        "delete-hook-aborted": "フックによって削除が中止されました。\n理由は不明です。",
        "no-null-revision": "ページ「$1」に新しい空編集の版を作成できませんでした。",
-       "badtitle": "正しくないページ名",
+       "badtitle": "不適切なページ名",
        "badtitletext": "無効または空のページ名が指定されたか、言語間/ウィキ間リンクの方法に誤りがあります。\nページ名に使用できない文字が含まれている可能性があります。",
        "title-invalid-empty": "指定されたページ名は空であるか、もしくは名前空間しか含んでいません。",
        "title-invalid-utf8": "指定されたページ名が無効なUTF-8シーケンスを含んでいます。",
        "userlogin-remembermypassword": "ログイン状態を保持",
        "userlogin-signwithsecure": "安全な接続の使用",
        "cannotloginnow-title": "今はログインできません",
+       "cannotloginnow-text": "$1 使用中には、ログインは不可能です。",
        "yourdomainname": "あなたのドメイン:",
        "password-change-forbidden": "このウィキではパスワードを変更できません。",
        "externaldberror": "認証データベースでエラーが発生したか、または外部アカウントの更新が許可されていません。",
        "botpasswords-disabled": "ボットのパスワードは無効です。",
        "botpasswords-existing": "既存のボットのパスワード",
        "botpasswords-createnew": "ボットのパスワードの新規作成",
+       "botpasswords-editexisting": "既存のボットのパスワードを編集",
        "botpasswords-label-appid": "ボット名:",
        "botpasswords-label-create": "作成",
        "botpasswords-label-update": "更新",
        "botpasswords-label-cancel": "中止",
        "botpasswords-label-delete": "削除",
        "botpasswords-label-resetpassword": "パスワードをリセット",
+       "botpasswords-label-restrictions": "使用制限:",
        "botpasswords-bad-appid": "ボット「$1」は有効ではありません。",
        "botpasswords-insert-failed": "ボット「$1」の追加に失敗しました。既に追加されていないか確認してください。",
        "botpasswords-update-failed": "ボット「$1」の更新に失敗しました。削除されていないか確認してください。",
        "hr_tip": "水平線を挿入 (利用は控えめに)",
        "summary": "編集内容の要約:",
        "subject": "題名:",
-       "minoredit": "これは細部の編集です",
+       "minoredit": "細部の編集",
        "watchthis": "このページをウォッチ",
        "savearticle": "ページを保存",
        "preview": "プレビュー",
        "right-bot": "自動処理と認識させる",
        "right-nominornewtalk": "議論ページの細部の編集をした際に、新着メッセージとして通知しない",
        "right-apihighlimits": "API要求でより高い制限値を使用",
-       "right-writeapi": "書き込みAPIを使用",
+       "right-writeapi": "書き込み API を使用",
        "right-delete": "ページを削除",
        "right-bigdelete": "大きな履歴があるページを削除",
        "right-deletelogentry": "特定の記録項目を削除/復元",
        "grant-group-email": "メールの送信",
        "grant-group-customization": "カスタマイズと個人設定",
        "grant-group-other": "その他の活動",
-       "grant-blockusers": "利用者をブロック/ブロック解除",
+       "grant-blockusers": "利用者をブロックおよびブロック解除",
        "grant-createaccount": "アカウントを作成",
        "grant-createeditmovepage": "ページを作成、編集、および移動",
        "grant-delete": "ページ、版、記録項目を削除",
        "grant-editinterface": "MediaWiki 名前空間および利用者 CSS/JavaScript を編集",
        "grant-editmycssjs": "あなた自身の利用者 CSS/JavaScript を編集",
        "grant-editmyoptions": "あなたの個人設定を編集",
-       "grant-editmywatchlist": "自身のウォッチリストを編集",
+       "grant-editmywatchlist": "あなたのウォッチリストを編集",
        "grant-editpage": "既存のページを編集",
        "grant-editprotected": "保護されたページを編集",
        "grant-oversight": "利用者名および版を秘匿",
        "grant-sendemail": "他の利用者へのメールの送信",
        "grant-uploadeditmovefile": "ファイルをアップロード/置き換え/移動",
        "grant-uploadfile": "新しいファイルをアップロード",
+       "grant-basic": "基礎的な権限",
        "grant-viewdeleted": "削除されたファイルとページを閲覧",
        "grant-viewmywatchlist": "自身のウォッチリストを閲覧",
        "newuserlogpage": "アカウント作成記録",
        "recentchanges-label-minor": "細部の編集",
        "recentchanges-label-bot": "ボットによる編集",
        "recentchanges-label-unpatrolled": "巡回されていない編集",
-       "recentchanges-label-plusminus": "ページ サイズの増減 (バイト単位)",
+       "recentchanges-label-plusminus": "ページサイズの増減 (バイト単位)",
        "recentchanges-legend-heading": "'''凡例:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|新しいページ一覧]]も参照)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "rcshowhidemine": "自分の編集を$1",
        "rcshowhidemine-show": "表示",
        "rcshowhidemine-hide": "非表示",
-       "rcshowhidecategorization": "$1 ページ カテゴリ化",
+       "rcshowhidecategorization": "ページのカテゴライズを$1",
        "rcshowhidecategorization-show": "表示",
        "rcshowhidecategorization-hide": "非表示",
        "rclinks": "最近 $2 日間の更新を最大 $1 件表示<br />$3",
        "recentchangeslinked-summary": "これは指定したページからリンクされている (または指定したカテゴリに含まれている) ページの最近の変更の一覧です。\n[[Special:Watchlist|自分のウォッチリスト]]にあるページは<strong>太字</strong>で表示されます。",
        "recentchangeslinked-page": "ページ名:",
        "recentchangeslinked-to": "このページへのリンク元での変更の表示に切り替え",
-       "recentchanges-page-added-to-category": "[[:$1]] カテゴリに追加",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]]と他{{PLURAL:$2|1ページ|$2ページ}}をカテゴリに追加しました",
-       "recentchanges-page-removed-from-category": "[[:$1]] ã\82«ã\83\86ã\82´ã\83ªã\81\8bã\82\89å\89\8aé\99¤",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]]と他{{PLURAL:$2|1ページ|$2ページ}}をカテゴリから削除しました",
+       "recentchanges-page-added-to-category": "[[:$1]] ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81«è¿½å\8a ",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]]と他{{PLURAL:$2|1ページ|$2ページ}}をカテゴリに追加",
+       "recentchanges-page-removed-from-category": "[[:$1]] ã\82\92ã\82«ã\83\86ã\82´ã\83ªã\81\8bã\82\89é\99¤å¤\96",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]]と他{{PLURAL:$2|1ページ|$2ページ}}をカテゴリから除外",
        "autochange-username": "メディアウィキ自動変更",
        "upload": "ファイルをアップロード",
        "uploadbtn": "ファイルをアップロード",
        "uploaded-script-svg": "アップロードされたSVGファイルにスクリプト可能な要素「$1」が見つかりました。",
        "uploaded-hostile-svg": "アップロードされたSVGファイルのスタイル要素に安全ではないCSSが見つかりました。",
        "uploaded-event-handler-on-svg": "イベントハンドラをセットする属性 <code>$1=\"$2\"</code> は、SVGファイルを許可されていません。",
-       "uploaded-href-attribute-svg": "ローカル以外のターゲット(http://、javascript: など) と href 属性の <code>&lt;$1 $2=\"$3\"&gt;</code> は、SVGファイルで許可されません。",
-       "uploaded-href-unsafe-target-svg": "アップロードされたSVGファイルに、安全ではないターゲット <code>&lt;$1 $2=\"$3\"&gt;</code> の href が見つかりました。",
+       "uploaded-href-attribute-svg": "SVG ファイルの href 属性が http:// または https:// のターゲットのみにリンクする <code>&lt;$1 $2=\"$3\"&gt;</code> が見つかりました。",
+       "uploaded-href-unsafe-target-svg": "アップロードされた SVG ファイルの、安全ではないデータ URI にターゲット <code>&lt;$1 $2=\"$3\"&gt;</code> の href が見つかりました。",
        "uploaded-animate-svg": "アップロードされたSVGファイルに、「from」属性 <code>&lt;$1 $2=\"$3\"&gt;</code> を使用した、href を変更させる可能性がある「animate」タグが見つかりました。",
        "uploaded-setting-event-handler-svg": "アップロードされたSVGファイルに、ブロックされているイベントハンドラ属性が設定された <code>&lt;$1 $2=\"$3\"&gt;</code> が見つかりました。",
        "uploaded-setting-href-svg": "親要素に「href」属性を追加する「set」タグの使用がブロックされています。",
        "shared-repo": "共有リポジトリ",
        "shared-repo-name-wikimediacommons": "ウィキメディア・コモンズ",
        "filepage.css": "/* ここに記述したCSSはファイル解説ページにて読み込まれます。また外部のクライアントウィキにも影響します */",
-       "upload-disallowed-here": "ã\81\82ã\81ªã\81\9fã\81¯ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\82\92上書きできません。",
+       "upload-disallowed-here": "ã\81\93ã\81®ã\83\95ã\82¡ã\82¤ã\83«ã\81¯上書きできません。",
        "filerevert": "$1を差し戻す",
        "filerevert-legend": "ファイルを差し戻す",
        "filerevert-intro": "ファイル<strong>[[Media:$1|$1]]</strong>を[$4 $2$3版]に差し戻そうとしています。",
        "querypage-disabled": "パフォーマンスに悪影響を与えるおそれがあるため、この特別ページは無効になっています。",
        "apihelp": "API のヘルプ",
        "apihelp-no-such-module": "モジュール「$1」が見つかりません。",
+       "apisandbox": "APIサンドボックス",
+       "apisandbox-api-disabled": "このウェブサイトでは、API は無効になっています。",
+       "apisandbox-intro": "このページでは、<strong>MediaWiki ウェブサービス API</strong> を試用できます。\nAPI の使用方法の詳細は[[mw:API:Main page|API のドキュメント]]をご覧ください。例: [//www.mediawiki.org/wiki/API#A_simple_example Main Pageの内容を取得]。操作を選択すると他の例を閲覧できます。\n\nこれはサンドボックスですが、このページで実行した操作によってウィキが変更される場合があることにご注意ください。",
+       "apisandbox-unfullscreen": "ページを表示",
+       "apisandbox-submit": "リクエストする",
+       "apisandbox-reset": "消去",
+       "apisandbox-retry": "再試行",
+       "apisandbox-no-parameters": "この API モジュールにはパラメーターがありません。",
+       "apisandbox-helpurls": "ヘルプリンク",
+       "apisandbox-examples": "例",
+       "apisandbox-dynamic-parameters-add-placeholder": "引数名",
+       "apisandbox-results": "結果",
+       "apisandbox-request-url-label": "リクエスト URL:",
+       "apisandbox-request-time": "リクエスト時間: {{PLURAL:$1|$1ミリ秒}}",
        "booksources": "書籍情報源",
        "booksources-search-legend": "書籍情報源を検索",
        "booksources-isbn": "ISBN:",
        "wlshowhideanons": "IP利用者",
        "wlshowhidepatr": "巡回された編集",
        "wlshowhidemine": "自分の編集",
-       "wlshowhidecategorization": "ã\83\9aã\83¼ã\82¸ã\81®ã\82«ã\83\86ã\82´ã\83ªå\8c\96",
+       "wlshowhidecategorization": "ã\83\9aã\83¼ã\82¸ã\81®ã\82«ã\83\86ã\82´ã\83©ã\82¤ã\82º",
        "watchlist-options": "ウォッチリストのオプション",
        "watching": "ウォッチリストに追加中...",
        "unwatching": "ウォッチリストから除去中...",
        "tooltip-ca-nstab-category": "カテゴリページを閲覧",
        "tooltip-minoredit": "この編集に細部の変更の印を付ける",
        "tooltip-save": "変更を保存する",
-       "tooltip-preview": "変更内容をプレビューで確認できます。保存前に使用してください!",
+       "tooltip-preview": "変更内容をプレビューで確認できます。保存前に使用してください",
        "tooltip-diff": "文章への変更箇所を表示する",
        "tooltip-compareselectedversions": "選択した2つの版の差分を表示する",
        "tooltip-watch": "このページをウォッチリストに追加する",
        "filedelete-old-unregistered": "指定されたファイルの版「$1」はデータベース内にありません。",
        "filedelete-current-unregistered": "指定されたファイル「$1」はデータベース内にありません。",
        "filedelete-archive-read-only": "保存版ディレクトリ「$1」は、ウェブサーバーから書き込み不可になっています。",
-       "previousdiff": "←古い編集",
-       "nextdiff": "新しい編集→",
+       "previousdiff": "← 古い編集",
+       "nextdiff": "新しい編集 →",
        "mediawarning": "<strong>警告:</strong> この種類のファイルは、悪意があるコードを含んでいる可能性があります。\n実行するとシステムが危険にさらされるおそれがあります。",
        "imagemaxsize": "画像のサイズ制限: <br /><em>(ファイルページに対する)</em>",
        "thumbsize": "サムネイルの大きさ:",
        "logentry-suppress-block": "$1 が {{GENDER:$4|$3}} を$5で{{GENDER:$2|ブロックしました}} $6",
        "logentry-suppress-reblock": "$1 が {{GENDER:$4|$3}} のブロックの期限を$5に{{GENDER:$2|変更しました}} $6",
        "logentry-import-upload": "$1 がファイルをアップロードして $3 を{{GENDER:$2|インポートしました}}",
+       "logentry-import-upload-details": "$1 がファイルのアップロードにより、$3 を{{GENDER:$2|インポートしました}} ({{PLURAL:$4|版}} $4)",
        "logentry-import-interwiki": "$1 が他のウィキから $3 を{{GENDER:$2|インポートしました}}",
        "logentry-import-interwiki-details": "$1 が $3 を $5 から{{GENDER:$2|取り込み}}ました ($4 {{PLURAL:$4|版}})",
        "logentry-merge-merge": "$1{{GENDER:$2|統合元}} と$3を$4に統合(改訂版を$5に掲載)",
index 73099eb..8cab5c3 100644 (file)
        "cancel": "Kiansl",
        "moredotdotdot": "Muo...",
        "mypage": "Fimi Piej",
-       "mytalk": "Mi chat",
+       "mytalk": "Taak",
        "anontalk": "Taak fi dis IP ajres",
        "navigation": "Navigieshan",
        "and": "&#32;ahn",
        "actions": "Akshan",
        "namespaces": "Niemspies",
        "variants": "Vieriant",
+       "navigation-heading": "Navigieshan menyuu",
        "errorpagetitle": "Era",
        "returnto": "Ritoern a $1",
        "tagline": "Frahn {{SITENAME}}",
        "permalink": "Poermanint lingk",
        "print": "Print",
        "view": "Riid",
+       "view-foreign": "Vyuu pah $1",
        "edit": "Edit",
        "create": "Kriet",
+       "create-local": "Ad luokal diskripshan‎",
        "editthispage": "Edit dis piej",
        "create-this-page": "Kriet dis piej",
        "delete": "Diliit",
        "otherlanguages": "Ina ada langwij",
        "redirectedfrom": "(Riidirek frahn $1)",
        "redirectpagesub": "Riidirek piej",
+       "redirectto": "Ridirek tu:",
        "lastmodifiedat": "Dis piej laas madifai pahn $1, a $2",
        "viewcount": "Dis piej akses {{PLURAL:$1|wans|$1 taim}}.",
        "protectedpage": "Protek piej",
        "pool-queuefull": "Puul kyuu fulop",
        "pool-errorunknown": "Anuon era",
        "aboutsite": "Habowt {{SITENAME}}",
-       "aboutpage": "Project:About",
+       "aboutpage": "Project:Bout‎",
        "copyright": "Kantent avielobl anda $1.",
        "copyrightpage": "{{ns:project}}:Kapirait",
        "currentevents": "Korant ivent",
        "virus-unknownscanner": "anuon antivairos:",
        "logouttext": "'''Yu nou lag out.'''\n\nYu kiahn kantiniu yuuz {{SITENAME}} ananimosli, ar yu kiahn <span class='plainlinks'>[$1 lag iin agen]</span> az di siem ar az difrant yuuza.\nNuot se som piej maita kantiniu fi displie laik se yu stil log iin, antel yu klier yu brouza kiash.",
        "yourname": "Yuuzaniem:",
+       "userlogin-yourname": "Yuuzaniem",
+       "userlogin-yourname-ph": "Enta yu yuuzaniem",
        "yourpassword": "Paaswod:",
+       "userlogin-yourpassword": "Paaswod",
+       "userlogin-yourpassword-ph": "Enta yu paaswod‎",
+       "createacct-yourpassword-ph": "Enta paaswod",
        "yourpasswordagain": "Ritaip paaswod:",
+       "createacct-yourpasswordagain": "Kanfoerm paaswod",
+       "createacct-yourpasswordagain-ph": "Enta paaswod agen",
        "remembermypassword": "Memba mi lagiin pan dis brouza (fi a maximom a $1 {{PLURAL:$1|die|die}})",
+       "userlogin-remembermypassword": "Kip mi lagiin‎",
        "yourdomainname": "Yu domien:",
        "externaldberror": "Aida aatentikieshan dietabies era okor ar yu no lou fi opdiet yu extoernal akount.",
        "login": "Lag iin",
        "logout": "Lag out",
        "userlogout": "Lag out",
        "notloggedin": "No lag iin",
+       "userlogin-noaccount": "No gat no akount?‎",
+       "userlogin-joinproject": "Jain {{SITENAME}}‎",
        "nologin": "Naa no akount? $1.",
        "nologinlink": "Kriet a akount",
        "createaccount": "Kriet akount",
        "gotaccount": "Aredi gat akount? $1.",
        "gotaccountlink": "Lag iin",
        "userlogin-resetlink": "Figet yu lagin detail dem?",
+       "userlogin-resetpassword-link": "Figat yu paaswod?‎",
+       "userlogin-helplink2": "Elp wid lagiin‎",
+       "createacct-emailoptional": "Iimiel ajres (apshanal)",
+       "createacct-email-ph": "Enta yu iimiel ajres",
        "createaccountmail": "Bai e-miel",
        "createaccountreason": "Riizn:",
+       "createacct-submit": "Kriet yu akount",
+       "createacct-benefit-heading": "{{SITENAME}} mek bai smadi laka yu.",
+       "createacct-benefit-body1": "{{PLURAL:$1|edit|edits}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|page|pages}}",
+       "createacct-benefit-body3": "riisent {{PLURAL:$1|kanchribiuta|kanchribiutadem}}",
        "badretype": "Di paaswod yu enta no mach.",
        "userexists": "Yuuza niem enta aredi a yuuz.\nBegyu chuuz wahn difrahn niem.",
        "loginerror": "Lagiin era",
        "loginlanguagelabel": "Langwij: $1",
        "suspicious-userlogout": "Yu rikwes fi lag out dinai bikaa iluk laik se isen bai a brok brouza ar kiashin praxi.",
        "pt-login": "Lagiin‎",
+       "pt-login-button": "Lagiin‎",
        "pt-createaccount": "Kriet akount‎",
+       "pt-userlogout": "Lag out",
        "resetpass_announce": "Yu lag iin wid a tempareri e-miel kuod.\nFi finish lag iin, yu mos set a nyuu paaswod yaso:",
        "resetpass_header": "Chienj akount paaswod",
        "oldpassword": "Uol paaswod:",
        "resetpass-submit-cancel": "Kiansl",
        "resetpass-wrong-oldpass": "Invalid ar tempareri paaswod.\nYu maita chienj yu paaswod soksesfuli aredi ar rikwes wahn nyuu tempareri paaswod.",
        "resetpass-temp-password": "Tempareri paaswod",
+       "passwordreset": "Riiset paaswod‎",
        "passwordreset-username": "Yuuzaniem:",
        "passwordreset-domain": "Domien:",
        "bold_sample": "Buol tex",
        "preview": "Priivyuu",
        "showpreview": "Shuo priivyuu",
        "showdiff": "Shuo chienjdem",
-       "anoneditwarning": "'''Waanin:''' Yu no lag iin.\nYu IP ajres wi rikaad ina dis piej edit ischri.",
+       "anoneditwarning": "<strong>Waanin:</strong> Yu no lagiin. Yu IP ajres wi vizibl tu poblik ef yu mek eni edit. Ef yu <strong>[$1 lagiin]</strong> ar <strong>[$2 kriet akount]</strong>, yu editdem wi get achribiut tu yu yuuzaniem, wid adaels benifit.‎",
        "anonpreviewwarning": "''Yu no lag iin. Sievin wi rikaad yu IP ajres ina dis piej edit ischri.''",
        "missingsummary": "'''Rimainda:''' Yu no provaid no edit somari.\nEf yu klik \"{{int:savearticle}}\" agen, yu edit wi siev widoutn wan.",
        "missingcommenttext": "Begyu enta a kament biluo.",
        "newarticletext": "Yu fala lingk tu piej we no egzis yet.\nFi kriet di piej, taat taip ina di bax biluo (si di [$1 elp piej] fi muo infamieshan).\nEf yu de ya by mistiek, klik yu brouza '''bak''' botn.",
        "anontalkpagetext": "----''Dis a di diskoshan piej fi ananimos yuuza uu no kriet no akount yet, ar uu no yuuzi.\nWi dierfuor afi yuuz di nyuumerikal IP ajres fi aidentifai im/ar.\nSoch a IP ajres kiahn shier bai sebral yuuza.\nEf yu a ananimos yuuza ahn fiil se irelivant kament dairek tu yu, begyu [[Special:UserLogin/signup|kriet a akount]] ar [[Special:UserLogin|lag iin]] fi avaid fyuucha kanfyuujan wid ada ananimos yuuza.''",
        "noarticletext": "Korentli no tex no de ina dis piej.\nYu kiahn [[Special:Search/{{PAGENAME}}|saach fi dis piej taikl]] ina ada piej,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} saach di rilietid lagdem],\nar [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit dis piej]</span>.",
+       "noarticletext-nopermission": "Korantli no tex no de ina dis piej.\nYu kiah [[Special:Search/{{PAGENAME}}|saach fi dis piej taikl]] ina ada piej, ar <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} saach di rilietid lagdem]</span>, bot yu not ab pomishan fi kriet dis piej.‎",
        "userpage-userdoesnotexist": "Yuuza akount \"<nowiki>$1</nowiki>\" no rejista.\nBegyu chek ef yu waahn fi kriet/edit dis piej.",
        "userpage-userdoesnotexist-view": "Yuuza akount \"$1\" no rejista.",
        "blocked-notice-logextract": "Dis yuuza korantli blak.\nDi lietis blak lag enchri provaid biluo fi refrans:",
        "session_fail_preview_html": "'''Sari! Wi kudn pruoses yu edit juu tu laas a seshan dieta.'''\n\n''Bikaa {{SITENAME}} ab raa HTML eniebl, di priivyuu aidwe az prikaashan gens JavaScript atak.''\n\n'''Ef dis a lejitimet edit atemp, begyu chrai agen.'''\nEf istil no wok, chrai [[Special:UserLogout|lag out]] ahn lag bak iin.",
        "token_suffix_mismatch": "'''Yu edit rijek bikaa yu klayant manggl di pongtyueshan kiaraktadem ina di edit tuokn.'''\nDi edit rijek fi privent koropshan a di piej tex.\nDis somtaim apn wen yu a yuuz a bogi web-bies ananimos praxi saabis.",
        "editing": "Editin $1",
+       "creating": "Krietin $1",
        "editingsection": "Editin $1 (sekshan)",
        "editingcomment": "Editin $1 (nyuu sekshan)",
        "editconflict": "Edit kanflik: $1",
        "hiddencategories": "Dis piej a memb a {{PLURAL:$1|1 idn kiatigari|$1 idn kiatigari}}:",
        "permissionserrors": "Permishan herro",
        "permissionserrorstext-withaction": "Yu no ab no poermishan fi $2, fi di falarin {{PLURAL:$1|riizn|riizndem}}:",
+       "moveddeleted-notice": "Dis piej eh diliit.\nDi diliishan ah muuv lag fi di piej provaid biluo fi refrans.‎",
        "edit-conflict": "Hedit kanflik: $1",
        "cantcreateaccounttitle": "Cyannat mek di hakkount",
        "viewpagelogs": "Vyuu lagdem fi dis piej",
        "currentrev-asof": "Lietis rivijan az av $1",
        "revisionasof": "Rivijan az av $1",
+       "revision-info": "Rivijan optel $1 by {{GENDER:$6|$2}}$7‎",
        "previousrevision": "← Uola rivijan",
        "nextrevision": "Nyuwa rivijan",
        "currentrevisionlink": "Lietis rivijan",
        "revdel-restore": "chienj vizibiliti",
        "revertmerge": "Anmoerj",
        "history-title": "Rivijan ischri a \"$1\"",
+       "difference-title": "Difrans bitwiin rivijan a \"$1\"",
        "lineno": "Lain $1:",
        "compareselectedversions": "Kompier silektid rivijan",
        "editundo": "andu",
+       "diff-multi-sameuser": "({{PLURAL:$1|Wan intamidiet rivijan|$1 intamidiet rivijandem}} bai di siem yuuza we no shuo)",
        "searchresults": "Saach rizolt",
        "searchresults-title": "Saach rizolt fi \"$1\"",
        "notextmatches": "No piej tex mach",
        "prevn": "priivos {{PLURAL:$1|$1}}",
        "nextn": "nex {{PLURAL:$1|$1}}",
+       "nextn-title": "Nex $1 {{PLURAL:$1|rizolt|rizoltdem}}‎",
+       "shown-title": "Shuo $1 {{PLURAL:$1|result|results}} po piej",
        "viewprevnext": "Vyuu ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-new": "<strong>Kriet di piej \"[[:$1]]\" pah dis wiki!</strong> {{PLURAL:$2|0=|Si azwel di piej we fain wid yu saach.|Si azwel di saach rizolt wa fain.}}‎",
+       "searchprofile-articles": "Kantent piej",
+       "searchprofile-images": "Moltimidia",
+       "searchprofile-everything": "Ebriting",
+       "searchprofile-advanced": "Advans",
+       "searchprofile-articles-tooltip": "Saach ina $1",
+       "searchprofile-images-tooltip": "Saach fi fail",
+       "searchprofile-everything-tooltip": "Saach aal kantent (inkluudn taak piej)",
+       "searchprofile-advanced-tooltip": "Saach ina kostom niemspies",
        "search-result-size": "$1 ({{PLURAL:$2|1 wod|$2 wod}})",
        "search-redirect": "(riidirek $1)",
        "search-section": "(sekshan $1)",
        "search-interwiki-caption": "Sista prajek",
        "search-interwiki-default": "$1 rizoltdem:",
        "search-interwiki-more": "(muo)",
+       "searchall": "aal",
+       "search-showingresults": "{{PLURAL:$4|Rizolt <strong>$1</strong> a <strong>$3</strong>|Rizoltdem <strong>$1 - $2</strong> a <strong>$3</strong>}}‎",
+       "search-nonefound": "No rizolt no de we mach di kweiri.",
        "powersearch-legend": "Advans saach",
        "powersearch-ns": "Saach ina niemspies:",
        "preferences": "Prefrens",
-       "mypreferences": "Mi prefrans",
+       "mypreferences": "Prefrans",
        "prefs-help-realname": "Riil niem apshanal. Ef yu giit, imaita yuuz az achribyuushan fi yu wok.",
        "group-sysop": "Adminischrieta",
        "grouppage-sysop": "{{ns:project}}:Adminischrieta",
+       "right-writeapi": "Yuus a di rait API",
        "newuserlogpage": "Yuuza krieshan lag",
        "rightslog": "Yuuza raits lag",
        "action-edit": "edit dis piej",
        "nchanges": "$1 {{PLURAL:$1|chienj|chienjdem}}",
+       "enhancedrc-history": "ischri",
        "recentchanges": "Riisant chienjdem",
        "recentchanges-legend": "Riisant chienj apshan",
+       "recentchanges-summary": "Chrak di muos riisent chienj tu di wiki pah dis piej.‎",
        "recentchanges-feed-description": "Chrak di muos riisant chienjdem tu di wiki ina dis fiid.",
+       "recentchanges-label-newpage": "Dis edit kriet nyuu piej",
+       "recentchanges-label-minor": "Dis a maina edit",
+       "recentchanges-label-bot": "Dis edit pofaam bai bot",
+       "recentchanges-label-unpatrolled": "Dis edit no get pachuol yet",
+       "recentchanges-label-plusminus": "Di piej saiz chienj bai dis nomba a bait",
+       "recentchanges-legend-heading": "'''Lejen:'''",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (azwel si [[Special:NewPages|lis a nyuu piej]])",
        "rclistfrom": "Shuo nyuu chienjdem we taat frahn $3 $2",
        "rcshowhideminor": "$1 maina editdem",
+       "rcshowhideminor-show": "Shuo",
+       "rcshowhideminor-hide": "Aid",
        "rcshowhidebots": "$1 batdem",
-       "rcshowhideliu": "$1 lag-iin yuuzadem",
+       "rcshowhidebots-show": "Shuo",
+       "rcshowhidebots-hide": "Aid",
+       "rcshowhideliu": "$1 rejista yuuzadem",
+       "rcshowhideliu-hide": "Aid",
        "rcshowhideanons": "$1 ananimos yuuzadem",
+       "rcshowhideanons-show": "Shuo",
+       "rcshowhideanons-hide": "Aid",
        "rcshowhidemine": "$1 mi editdem",
+       "rcshowhidemine-show": "Shuo",
+       "rcshowhidemine-hide": "Aid",
        "rclinks": "Shuo laas $1 chienj ina laas $2 die<br />$3",
        "diff": "dif",
        "hist": "isch",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|bait|baitdem}} afta chienj‎",
        "rc-enhanced-expand": "Shuo ditiel (rikwaya JavaScript)",
        "rc-enhanced-hide": "Aid ditiel",
        "recentchangeslinked": "Rilietid chienj",
+       "recentchangeslinked-toolbox": "Rilietid chienj‎",
        "recentchangeslinked-title": "Chienj riliet tu \"$1\"",
        "recentchangeslinked-summary": "Dis a lis a riisent chienj wa mek tu piej wa lingk frahn spesifai piej (ar tu memba a spesifai kiatigeri).\nPiej pahn [[Special:Watchlist|yu wachlis]] dem '''buol'''.",
        "recentchangeslinked-page": "Piej niem",
        "recentchangeslinked-to": "Shuo chienjdem tu piej wa lingk tu di gibn piej insted",
        "upload": "Opluod fail",
        "uploadlogpage": "Opluod lag",
+       "filedesc": "Somari‎",
+       "license-header": "Laisnsin‎",
+       "imgfile": "fail",
+       "file-anchor-link": "Fail",
        "filehist": "Fail ischri",
        "filehist-help": "Klik pan a diet/taim fi vyuu di fail az ou iapier a di taim.",
        "filehist-current": "korant",
        "filehist-user": "Yuuza",
        "filehist-dimensions": "Daimenshan",
        "filehist-comment": "Kament",
-       "imagelinks": "Fail lingk",
+       "imagelinks": "Fail Yuusij",
        "linkstoimage": "Di falarin {{PLURAL:$1|piej lingk|$1 piejdem lingk}}",
+       "nolinkstoimage": "No piej no de we lingk dis fail.",
        "sharedupload": "Dis fail kom frahn $1 ahn kiahn yuuz bai ada prajek.",
+       "sharedupload-desc-here": "Dis fail koh frah $1 ah kiah yuuz pah adaels prajek. Di diskripshan fiit [$2 fail diskripshan piej] shuo biluo.‎",
        "uploadnewversion-linktext": "Opluod nyuu voerjan a dis fail",
+       "upload-disallowed-here": "Yu kyaah uobarait dis fail.",
+       "randompage": "Random piej",
        "statistics": "Tatistik",
        "nbytes": "$1 {{PLURAL:$1|bait|bait}}",
        "nmembers": "$1 {{PLURAL:$1|memba|membadem}}",
        "pager-older-n": "{{PLURAL:$1|uola 1|uola $1}}",
        "booksources": "Buk suos",
        "booksources-search-legend": "Saach fi buk suos",
+       "booksources-search": "Saach",
        "log": "Lagdem",
        "allpages": "Aal piej",
        "prevpage": "Priivos piej ($1)",
        "allpagesto": "Displie piej en a:",
        "allarticles": "Aal piej",
        "allpagessubmit": "Gwaan",
+       "categories": "Kiatigaridem‎",
        "linksearch": "Extoernal lingk",
        "listgrouprights-members": "(lis a memba)",
        "emailuser": "E-miel dis yuuza",
        "deleteotherreason": "Ada/adishanal riizn:",
        "deletereasonotherlist": "Ada riizn",
        "rollbacklink": "ruolbak",
+       "rollbacklinkcount": "roulbak $1 {{PLURAL:$1|edit|editdem}}‎",
        "protectlogpage": "Protekshan lag",
        "protectedarticle": "don protek \"[[$1]]\"",
        "modifiedarticleprotection": "don chienj protekshan lebl fi \"[[$1]]\"",
        "undeletelink": "vyuu/ristuor",
        "namespace": "Niemspies",
        "invert": "Invoert silekshan",
+       "tooltip-invert": "Chek dis bax fi aid chienj tu piej widin di silek niemspies (ah di asuosietid niemspies ef ichek)",
+       "namespace_association": "Asuosietid niemspies",
+       "tooltip-namespace_association": "Chek dis bax fi azwel ingkluud di taak ar sobjek niemspies asuosiet wid di silek niemspies",
        "blanknamespace": "(Mien)",
-       "contributions": "Yuuza kanchribyuushan",
+       "contributions": "{{GENDER:$1|Yuuza}} kanchribyuushan",
        "contributions-title": "Yuuza kanchribiushan fi $1",
        "mycontris": "Mi kanchribyuushan",
+       "anoncontribs": "Kanchribyuushan",
        "contribsub2": "Fi $1 ($2)",
        "uctop": "(tap)",
        "month": "Frahn mont (ahn oerlia):",
        "linkshere": "Di falarin piejdem lingk tu '''[[:$1]]''':",
        "isredirect": "riidirek piej",
        "istemplate": "chranskluujan",
-       "isimage": "imij lingk",
+       "isimage": "fail lingk",
        "whatlinkshere-prev": "{{PLURAL:$1|priivos|priivos $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|nex|nex $1}}",
        "whatlinkshere-links": "← lingkdem",
        "thumbnail-more": "Inlaaj",
        "import": "Himpuot piejdem",
        "import-comment": "Kament:",
-       "tooltip-pt-userpage": "Yu yuuza piej",
-       "tooltip-pt-mytalk": "Yu taak piej",
-       "tooltip-pt-preferences": "Yu prefrans",
+       "tooltip-pt-userpage": "{{GENDER:|Yu yuuza}} piej",
+       "tooltip-pt-mytalk": "{{GENDER:|Fiyu}} taak piej‎",
+       "tooltip-pt-preferences": "{{GENDER:|Yu}} prefrans",
        "tooltip-pt-watchlist": "Di lis a piej yu a manita fi chienj",
-       "tooltip-pt-mycontris": "Lis a yu kanchribyuushan",
+       "tooltip-pt-mycontris": "Lis a {{GENDER:|Fiyu}} kanchribyuushan‎",
        "tooltip-pt-login": "Yu inkorij fi lag iin; ousomeba, ino mos ahn boun",
        "tooltip-pt-logout": "Lag out",
+       "tooltip-pt-createaccount": "Yu inkorij fi kriet wah akount ah lagiin; ousomeba, a no mos",
        "tooltip-ca-talk": "Diskoshan bout di kantent piej",
-       "tooltip-ca-edit": "Yu kiahn edit dis piej. Du yuuz di priivyuu botn bifuo yu sieb",
+       "tooltip-ca-edit": "Edit dis piej",
        "tooltip-ca-addsection": "Taat a nyuu sekshan",
        "tooltip-ca-viewsource": "Dis piej protek.\nYu kiahn vyuu isuos.",
        "tooltip-ca-history": "Paas rivijan a dis piej",
        "tooltip-search": "Saach {{SITENAME}}",
        "tooltip-search-go": "Go tu a piej wid disaya egzak niem ef iegzis",
        "tooltip-search-fulltext": "Saach di piejdem fi disaya tex",
+       "tooltip-p-logo": "Visit di mien piej",
        "tooltip-n-mainpage": "Vizit di mien piej",
        "tooltip-n-mainpage-description": "Vizit di mien piej",
        "tooltip-n-portal": "Bout di prajek, wa yu kiahn du, we fi fain tingz",
        "tooltip-t-recentchangeslinked": "Riisant chienj ina piej wa lingk frahn dis piej",
        "tooltip-feed-rss": "RSS fiid fi dis piej",
        "tooltip-feed-atom": "Atom fiid fi dis piej",
-       "tooltip-t-contributions": "Vyuu di lis a kanchribyuushan a dis yuuza",
+       "tooltip-t-contributions": "Lis a kanchribyuushan bai {{GENDER:$1|dis yuuza}}‎",
        "tooltip-t-emailuser": "Sen e-miel tu dis yuuza",
        "tooltip-t-info": "Muo infamieshan bout da piej ya",
        "tooltip-t-upload": "Opluod fail",
        "tooltip-watch": "Ad dis piej tu yu wachlis",
        "tooltip-rollback": "\"Ruolbak\" rivoert edit(dem) tu dis piej a di laas kanchribiuta ina wan klik",
        "tooltip-undo": "\"Andu\" rivoert dis edit ahn opin di edit faam ina priivyuu muod. Ilou yu fi ad riizn ina di somari.",
+       "tooltip-summary": "Enta shaat somari",
+       "simpleantispam-label": "Anti-spam chek.\n<strong>No</strong> fuliin dis!‎",
+       "pageinfo-toolboxlink": "Piej infamieshan",
        "previousdiff": "← Uola edit",
        "nextdiff": "Nyuwa edit",
        "file-info-size": "$1 × $2 pixl, fail saiz: $3, MIME taip: $4",
        "file-nohires": "No aya rezaluushan no avielobl.",
        "svg-long-desc": "SVG fail, naminali $1 × $2 pixl, fail saiz: $3",
-       "show-big-image": "Ful rezaluushan",
+       "show-big-image": "Orijinal fail",
+       "show-big-image-preview": "Saiz a dis priivyuu: $1.",
+       "show-big-image-other": "Adaels {{PLURAL:$2|rezaluushan|rezaluushandem}}: $1.",
+       "show-big-image-size": "$1 × $2 pixels",
        "bad_image_list": "Di faamat go so:\n\nOnggl lis aitem (lain taat wid *) wi kansida.\nDi fos lingk pan a lain mos bi a lingk tu a bad fail.\nEni sobsikwent lingk pahn di siem lain kansida fi bi eksepshan, i.e. piej we di fail maita okor inlain.",
        "metadata": "Metadieta",
        "metadata-help": "Dis fail kantien adishanal infamieshan, prabli wa ad frahn di dijital kiamara ar skiana yuuz fi kriet ar dijitaizi.\nEf di fail madifai frahn iarijinal stiet, som ditiel maita no fuli riflek di madifai fail.",
        "metadata-expand": "Shuo extendid ditiel",
        "metadata-collapse": "Aid extendid ditiel",
        "metadata-fields": "EXIF metadieta fiil wa lis ina dis mechiz wi inkluud pahn imij piej displie wen di metadieta tiebl get kalaps.\nAda wandem wi aid bai difaalt.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Orientieshan‎",
+       "exif-xresolution": "Arizantal rezaluushan‎",
+       "exif-yresolution": "Voertikal rezaluushan‎",
+       "exif-datetime": "Fail chienj diet ah taim‎",
+       "exif-make": "Kiamara maniufakchra‎",
+       "exif-model": "Kiamara magl‎",
+       "exif-software": "Saafwier yuuz‎",
+       "exif-exifversion": "Exif voerjan",
+       "exif-colorspace": "Kola spies‎",
+       "exif-datetimeoriginal": "Diet ah taim a dieta jinarieshan‎",
+       "exif-datetimedigitized": "Diet ah taim a dijitaizin‎",
+       "exif-orientation-1": "Naamal‎",
        "namespacesall": "aal",
        "monthsall": "aal",
        "watchlisttools-view": "Vyuu rilivant chienjdem",
        "watchlisttools-edit": "Vyuu ahn edit wachlis",
        "watchlisttools-raw": "Edit raa wachlis",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1| talk]])‎",
        "specialpages": "Peshal piej",
+       "tag-filter": "[[Special:Tags|Tag]] filta:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+       "logentry-delete-delete": "$1 {{GENDER:$2|diliitid}} piej $3‎",
+       "logentry-move-move": "$1 {{GENDER:$2|muuv}} piej $3 tu $4‎",
+       "logentry-newusers-create": "Yuuza akount $1 eh {{GENDER:$2|krietid}}‎",
+       "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "searchsuggest-search": "Saach‎"
 }
index c077a82..ff3d3cc 100644 (file)
        "databaseerror-query": "მოთხოვნა: $1",
        "databaseerror-function": "ფუნქცია: $1",
        "databaseerror-error": "შეცდომა: $1",
+       "transaction-duration-limit-exceeded": "თავიდან რომ ავიცილოთ რეპლიკაციის მაღალი ლაგი, ეს ტრანზაქცია გაუქმნა, რადგან ჩაწერის ხანგრძლივობა ($1) ასცდა $2 წამიან ლიმიტს.",
        "laggedslavemode": "ყურადღება: გვერდი შესაძლოა არ შეიცავდეს ბოლო ცვლილებებს.",
        "readonly": "მონაცემთა ბაზა დახურულია",
        "enterlockreason": "მიუთიეთ ბლოკირების მიზეზი და ხანგრძლივობის ვადა",
        "missingarticle-rev": "(ჩასწორება#: $1)",
        "missingarticle-diff": "(ცვლილება: $1, $2)",
        "readonly_lag": "მონაცემთა ბაზა ავტომატურად დაიხურა, სანამ შვილობილი ბაზის სერვერები მთავარ ბაზასთან სინქრონიზაციას ახდენს",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP-header გაიგზავნა, თუმცა მიმღები იყო API წერის მოდული.",
        "internalerror": "შიდა შეცდომა",
        "internalerror_info": "შიდა შეცდომა: $1",
        "internalerror-fatal-exception": "ფატალური გამონაკლისის ტიპი „$1“",
        "changepassword-success": "თქვენი პაროლი წარმატებით შეიცვალა!",
        "changepassword-throttled": "თქვენ განახორციელეთ ანგარიშში შესვლის ზედმეტად ბევრი მცდელობა. გამორებით შეყვანამდე გთხოვთ დაიცადოთ $1.",
        "botpasswords": "ბოტის პაროლები",
+       "botpasswords-summary": "<em>ბოტების კოდები</em> საშუალებას იძლევა მომხმარებლის ანგარიშთან დაკავშირების API-ის გამოყენებით ანგარიშის ძირითადი შესვლის მონაცემების გამოყენების გარეშე. მომხმარებლის უფლებები ასეთი შესვლისას შესაძლოა შეზღუდული იყოს.\n\nთუ არ იცით ეს რატომ უნდა გააკეთოთ, ალბათ არც უნდა გააკეთოთ. ასეთი კოდის წამოქმნა და სხვისთვის გადაცემა არაა რეკომენდირებული.",
        "botpasswords-disabled": "ბოტის პაროლები გათიშულია.",
        "botpasswords-no-central-id": "ბოტის პაროლების გამოსაყენებლად, საჭიროა ცენტრალიზებული ანგარიშით შესვლა.",
        "botpasswords-existing": "არსებული ბოტის პაროლები",
        "permissionserrors": "ნებართვის შეცდომა",
        "permissionserrorstext": "თქვენ არ გაქვთ ამის გაკეთების უფლება, შემდეგი {{PLURAL:$1|მიზეზის|მიზეზების}} გამო:",
        "permissionserrorstext-withaction": "თქვენ არ გაქვთ ამ მოქმედების - „$2“ განხორციელების ნებართვა შემდეგი {{PLURAL:$1|მიზეზის|მიზეზის}} გამო:",
+       "contentmodelediterror": "არ შეგიძლიათ ამ ვერსიის რედაქტირება, რადგან მისი კონტენტის მოდელი არის <code>$1</code>, რაც განსხვავდება გვერდის მიმდინარე კონტენტის მოედლისაგან <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''გაფრთხილება: თქვენ ხელახლა ქმნით გვერდს, რომელიც ადრე წაიშალა.'''\n\nგთხოვთ დაფიქრდეთ, მისაღები არის თუ არა ამ გვერდის რედაქტირების გაგრძელება.\nინფორმაციისთვის ქვემოთ მოყვანილია ამ გვერდის წაშლის ისტორია:",
        "moveddeleted-notice": "ეს გვერდი წაიშალა. ინფორმაციის მისაღებად ქვემოთ წარმოდგენილია შესაბამისი ჩანაწერები წაშლისა და გადარქმევის ჟურნალებიდან.",
+       "moveddeleted-notice-recent": "ბოდიში, ეს გვერდი წაშლილია (ბოლო 24 საათის განმავლობაში).\nწაშლისა და გადატანის ჟურნალი ქმენოთ არის მოცემული.",
        "log-fulllog": "ყველა ჟურნალის ხილვა",
        "edit-hook-aborted": "შესწორება გაუქმებულია გადამჭერით.\nდამატებითი ახსნა არ ჩაწერილა.",
        "edit-gone-missing": "გვერდის განახლეა შეუძლებელია.\nშესაძლოა, იგი წაიშალა.",
        "badsig": "არასწორი ნედლი ხელმოწერა; შეამოწმეთ HTML ჭდეები.",
        "badsiglength": "ხელმოწერა ძალიან გრძელია.\nუნდა შედგებოდეს მაქსიმუმ $1 ნიშნისაგან.",
        "yourgender": "რომელი აღწერა უფრო შეგეფერებათ თქვენ?",
-       "gender-unknown": "á\83\9bá\83\98á\83\97á\83\98á\83\97á\83\94á\83\91á\83\90á\83¡ á\83\90á\83  á\83\95á\83\97á\83\95á\83\9aá\83\98 á\83¡á\83\90á\83­á\83\98á\83 á\83\9dá\83\93",
+       "gender-unknown": "á\83\9eá\83 á\83\9dá\83\92á\83 á\83\90á\83\9bá\83£á\83\9aá\83\98 á\83£á\83\96á\83 á\83£á\83\9cá\83\95á\83\94á\83\9aá\83§á\83\9dá\83¤á\83\90 á\83\97á\83¥á\83\95á\83\94á\83\9cá\83\96á\83\94 á\83¡á\83\90á\83£á\83\91á\83 á\83\98á\83¡á\83\90á\83¡ á\83\92á\83\94á\83\9cá\83\93á\83\94á\83 á\83£á\83\9aá\83\90á\83\93 á\83\9cá\83\94á\83\98á\83¢á\83 á\83\90á\83\9aá\83£á\83  á\83¡á\83\98á\83¢á\83§á\83\95á\83\94á\83\91á\83¡ á\83\92á\83\90á\83\9bá\83\9dá\83\98á\83§á\83\94á\83\9cá\83\94á\83\91á\83¡, á\83 á\83\9dá\83\93á\83\94á\83¡á\83\90á\83ª á\83¨á\83\94á\83¡á\83\90á\83«á\83\9aá\83\94á\83\91á\83\94á\83\9aá\83\98á\83\90",
        "gender-male": "ის (მამრობითი) არედაქტირებს ვიკი-გვერდებს",
        "gender-female": "ის (მდედრობითი) არედაქტირებს ვიკი-გვერდებს",
        "prefs-help-gender": "ამ პარამეტრის დაყენება არასავალდებულოა.\nპროგრამული უზრუნველყოფა ამ ინფორმაციას იყენებს მხოლოდ სწორი გრამატიკული სქესით მომართვისათვის.\nეს ინფორმაცია საჯარო იქნება ყველასათვის.",
        "grant-group-file-interaction": "კავშირი მედია-ფაილებთან",
        "grant-group-watchlist-interaction": "კავშირი კონტროლის სიასთან",
        "grant-group-email": "ელექტრონული ფოსტის გაგზავნა",
+       "grant-group-high-volume": "მაღალი სიხშირის მოქმედების შესრულება",
        "grant-group-customization": "კონფიგურაცია",
        "grant-group-administration": "ადმინისტრაციული მოქმედებების შესრულება",
+       "grant-group-other": "სხვადასხვა ქმედებები",
        "grant-blockusers": "მომხმარებლების დაბლოკვა და ბლოკის მოხსნა",
        "grant-createaccount": "ანგარიშების შექმნა",
        "grant-createeditmovepage": "გვერდის შექმნა, რედაქტირება და გადატანა",
        "grant-editmywatchlist": "თქვენი კონტროლის სიის რედაქტირება",
        "grant-editpage": "არსებული გვერდების რედაქტირება",
        "grant-editprotected": "დაცული გვერდების რედაქტირება",
+       "grant-highvolume": "დიდი მოცულობით რედაქტირება",
        "grant-oversight": "მომხმარებლებისა და შესწორებების დამალვა",
        "grant-patrol": "გვერდების რედაქტირებების შემოწმება",
        "grant-protect": "გვერდების და დაცვა და დაცვის მოხსნა",
        "uploaddisabledtext": "ფაილების ატვირთვა შეუძლებელია.",
        "php-uploaddisabledtext": "ფაილების ატვირთვა შეჩერებულია PHP-ით. გთხოვთ შეამოწმოთ file_uploads-ის მნიშვნელობა.",
        "uploadscripted": "ფაილი შეიცავს HTML-კოდს, ან სკრიპტს, რომელიც ბროუზერმა შეიძლება არასწორედ გაანალიზოს.",
+       "upload-scripted-pi-callback": "შეუძლებელია ფაილის ატვირთვა, რომელიც XML-stylesheet წარმოქმნის ინსტრუქციას შეიცავს.",
        "uploaded-hostile-svg": "ატვირთულ SVG-ფაილის style ელემენტში ნაპოვნია საფრთხის შემცვლელი CSS-ის კოდი.",
        "uploadscriptednamespace": "ეს SVG ფაილი შეიცავს სახელთა არაკორექტულ სივრცეს \"$1\".",
        "uploadinvalidxml": "XML ჩატვირთულ ფაილში არ შეიძლება იყოს ანალიზირებული",
        "upload-form-label-infoform-title": "დეტალები",
        "upload-form-label-infoform-name": "სახელი",
        "upload-form-label-infoform-description": "აღწერა",
+       "upload-form-label-infoform-description-tooltip": "მოკლედ აღწერეთ ამ ნამუშევრის შესახებ ყველაფერი მნიშვნელოვანი.\nფოტოსათვის, მიუთითეთ რა არის გამოსახული, სად არის გადაღებული, რა ვითარებაში.",
        "upload-form-label-usage-title": "გამოყენება",
        "upload-form-label-usage-filename": "ფაილის სახელი",
        "foreign-structured-upload-form-label-own-work": "ეს ჩემი პირადი ნამუშევარია",
        "foreign-structured-upload-form-label-infoform-categories": "კატეგორიები",
        "foreign-structured-upload-form-label-infoform-date": "თარიღი",
+       "foreign-structured-upload-form-label-own-work-message-local": "ვადასტურებ, რომ ვტვირთავვ ამ ფაილს მომსახურების პირობებისა და ლიცენსიის პოლიტიკის შესაბამისად {{SITENAME}}-ზე.",
+       "foreign-structured-upload-form-label-not-own-work-message-local": "თუ ვერ ტვირთავთ ამ ფაილს {{SITENAME}}-ის წესების დაცვით, გთხოვთ დახურეთ ეს ფანჯარა და სცადეთ სხვა მეთოდი.",
        "foreign-structured-upload-form-label-not-own-work-local-local": "შეგიძლიათ სცადოთ [[Special:Upload|მთავარი ატვირთვის გვერდი]].",
+       "foreign-structured-upload-form-label-own-work-message-default": "ვიცი, რომ ამ ფაილს ვტვირთავ საზიარო ბაზაში. ვადასტურებ, რომ ამას ვაკეთებ მომსახურების პირობებისა და ლიცენზიის პოლიტიკის შესაბამისად.",
+       "foreign-structured-upload-form-label-not-own-work-message-default": "თუ ვერ ტვირთავთ ამ ფაილს {{SITENAME}}-ის წესების დაცვით, გთხოვთ დახურეთ ეს ფანჯარა და სცადეთ სხვა მეთოდი.",
+       "foreign-structured-upload-form-label-not-own-work-local-default": "შეგიძლიათ ასევე სცადოთ [[Special:Upload|ატვირთვის გვერდი {{SITENAME}}-ზე]], თუ ამ ფაილის ატვირთვა დაშვებულია მათი პოლიტიკის მიხედვით.",
        "foreign-structured-upload-form-label-own-work-message-shared": "მე ვადასტურებ, რომ ამ ფაილზე საავტორო უფლებების მფლობელი ვარ და ვთანხმდები ამ ფაილის შეუქცევადად განთავსებაზე ვიკისაწყობში [https://creativecommons.org/licenses/by-sa/4.0/deed.ka Creative Commons Attribution-ShareAlike 4.0] ლიცენზიით, აგრეთვე ვეთანხმები [https://wikimediafoundation.org/wiki/Terms_of_Use გამოყენების წესებს].",
+       "foreign-structured-upload-form-2-label-intro": "მადლობას გიხდით სურათის შემოტანისთვის {{SITENAME}}-ზე გამოსაყენებლად. გააგრძელეთ მხოლოდ მაშინ თუ ის აკმაკოყილებს რამდენიმე კრიტერიუმს:",
+       "foreign-structured-upload-form-2-label-ownwork": "ის აუცილებლად უნდა იყოს <strong>თქვენი შემოქმედება</strong> და არა ინტერნეტიდან აღებული.",
        "foreign-structured-upload-form-2-label-noderiv": "<strong>არ უნდა შეიცავდეს</strong> სხვის ნამუშევარს, ასევე არ უნდა იგრძნობოდეს სხვისი ნამუშევრის გავლენა",
        "foreign-structured-upload-form-2-label-useful": "უნდა იყოს სხვებისთვის <strong>საგანმანათლებლო და სასარგებლო</strong>",
+       "foreign-structured-upload-form-2-label-ccbysa": "მისი ატვირთვა ინტერნეტში <strong>დასაშვები</strong> უნდა იყოს [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] ლიცენზიით",
+       "foreign-structured-upload-form-2-label-alternative": "თუ ყველა ჩამოთვლილი პირობა არ სრულდება, თქვენ მაინც შეიძლება შეძლოთ ფაილის ატვირთვა [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard]-ით, თუ მასზე ვრცელდება თავისუფალი ლიცენზია.",
+       "foreign-structured-upload-form-3-label-question-website": "ეს სურათი ვებ-გვერდიდან გადმოწერეთ თუ სურათების ძებნით მიაკვლიეთ მას?",
+       "foreign-structured-upload-form-3-label-question-ownwork": "თავად შექმნეთ ეს სურათი (გადაიღეთ ფოტო, დახატეთ და ა.შ.)?",
+       "foreign-structured-upload-form-3-label-question-noderiv": "შეიცავს ის ან დაფუძნებულია სხვის ნამუშევარზე, მაგალითად ლოგოზე?",
        "foreign-structured-upload-form-3-label-yes": "დიახ",
        "foreign-structured-upload-form-3-label-no": "არა",
        "backend-fail-stream": "ფაილი $1 ტრანსლირება ვერ მოხერხდა.",
        "querypage-disabled": "ეს სპეცგვერდი გამორთულია წარმადობის გასაზრდელად.",
        "apihelp": "API დახმარება",
        "apihelp-no-such-module": "მოდული „$1“ ვერ მოიძებნა.",
+       "apisandbox": "API-ს სავარჯიშო",
+       "apisandbox-jsonly": "API-ის სავარჯიშოს გამოსაყენებლად საჭიროა JavaScript.",
+       "apisandbox-api-disabled": "API ამ საიტზე გამორთულია.",
+       "apisandbox-fullscreen": "პანელის გაშლა",
+       "apisandbox-fullscreen-tooltip": "პანელის გაშლა ისე, რომ ბრაუზერის მთელი ფანფარა დაიკავოს.",
+       "apisandbox-unfullscreen": "გვერდის ჩვენება",
+       "apisandbox-submit": "მოთხოვნის გაკეთება",
+       "apisandbox-reset": "წაშლა",
+       "apisandbox-retry": "ხელახლა ცდა",
+       "apisandbox-no-parameters": "API მოდულს არ აქვს პარამეტრები.",
+       "apisandbox-helpurls": "დახმარების ბმულები",
+       "apisandbox-examples": "მაგალითები",
+       "apisandbox-dynamic-parameters": "დამატებითი პარამეტრები",
+       "apisandbox-dynamic-parameters-add-label": "პარამეტრის დამატება:",
+       "apisandbox-dynamic-parameters-add-placeholder": "პარამეტრის სახელი",
+       "apisandbox-dynamic-error-exists": "პარამეტრი \"$1\" სახელით უკვე არსებობს.",
+       "apisandbox-submit-invalid-fields-message": "გთხოვთ, შეასწორეთ მონიშნული ველები და თავიდან სცადეთ.",
+       "apisandbox-results": "შედეგები",
+       "apisandbox-sending-request": "API მოთხოვნის გაგზავნა...",
+       "apisandbox-loading-results": "API შედეგების მიღება...",
+       "apisandbox-request-url-label": "მოთხოვნის URL:",
+       "apisandbox-request-time": "თხოვნის დრო: $1მწ",
+       "apisandbox-results-fixtoken-fail": "ვერ მოხერხდა $1 ტოკენის მოძიება.",
+       "apisandbox-alert-page": "ველები ამ გვერდზე არ არის ვალიდური",
+       "apisandbox-alert-field": "ამ ველის მნიშვნელობა არ არის ვალიდური",
        "booksources": "წიგნის წყაროები",
        "booksources-search-legend": "წიგნის წყაროს ძებნა",
        "booksources-isbn": "ISBN:",
        "move-page-legend": "გვერდის გადატანა",
        "movepagetext": "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. \nძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე. \nბმულები ძველი გვერდის სათაურზე არ შეიცვლება; \nშეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი გადამისამართებები]]. \nთქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.\n\nგაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, როდესაც მსგავსი გვერდი ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. \nეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.\n\n'''ფრთხილად!'''\nამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; \nსანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.",
        "movepagetext-noredirectfixer": "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. \nძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე.\nშეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი]] გადამისამართებები. \nთქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.\n\nგაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, თუ ის ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.\n\n'''გაფრთხილებთ!''' \nამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; სანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.",
-       "movepagetalktext": "დაკავშირებული განხილვის გვერდი ავტომატურად გადავა მასთან ერთად, '''გარდა იმ შემთხვევისა, თუ''':\n*განხილვის გვერდი ახალი სათაურით და გარკვეული შინაარსით უკვე არსებობს, ან\n*თქვენ მოხსნით ნიშნულს ქვევით დაფაზე.\n\nამ შემთხვევებში, თქვენ თავად მოგიწევთ ამ გვერდის გადატანა, სურვილისამებრ.",
+       "movepagetalktext": "დაკავშირებული განხილვის გვერდი ავტომატურად გადავა მასთან ერთად, გარდა იმ შემთხვევისა, თუ განხილვის გვერდი ახალი სათაურით და გარკვეული შინაარსით უკვე არსებობს.\n\nამ შემთხვევებში, თქვენ თავად მოგიწევთ ამ გვერდის გადატანა, სურვილისამებრ.",
        "moveuserpage-warning": "'''გაფრთხილება:''' თქვენ გადაგაქვთ მომხმარებლის გვერდი. გთხოვთ გაითვალისწინეთ, რომ გადატანა შესრულდება, მომხმარებლის სახელის გადარქმევა კი ''არა''.",
        "movecategorypage-warning": "<strong>გაფრთხილება:</strong> თქვენ გადაგაქვთ კატეგორიის გვერდი. გაითვალისწინეთ, რომ გვერდი გადავა, თუმცა მასში შემავალი გვერდები <em>დარჩება</em> ძველ კატეგორიაში. საჭირო იქნება კატეგორიის ჩასწორება სტატიებში ინდივიდუალურად.",
        "movenologintext": "თქვენ უნდა [[Special:UserLogin|წარუდგინოთ თავი]],\nსისტემას რათა გადაიტანოთ გვერდები.",
        "tooltip-search": "ძიება {{SITENAME}}",
        "tooltip-search-go": "მოიძიე გვერდი ზუსტად ამ სახელით",
        "tooltip-search-fulltext": "მოძებნე გვერდები, რომლებიც ამ ტექსტს შეიცავენ",
-       "tooltip-p-logo": "მთავარი გვერდი",
+       "tooltip-p-logo": "á\83\98á\83®á\83\98á\83\9aá\83\94á\83\97 á\83\9bá\83\97á\83\90á\83\95á\83\90á\83 á\83\98 á\83\92á\83\95á\83\94á\83 á\83\93á\83\98",
        "tooltip-n-mainpage": "იხილეთ მთავარი გვერდი",
        "tooltip-n-mainpage-description": "იხილეთ მთავარი გვერდი",
        "tooltip-n-portal": "პროექტის შესახებ, რა შეგიძლიათ გააკეთოთ, სად იპოვოთ",
        "version-hook-subscribedby": "ჩაწერილია",
        "version-version": "($1)",
        "version-no-ext-name": "[სახელის გარეშე]",
-       "version-svn-revision": "(r$2)",
        "version-license": "მედიავიკის ლიცენზია",
        "version-ext-license": "ლიცენზია",
        "version-ext-colheader-name": "გაფართოებები",
        "version-libraries-authors": "ავტორები",
        "redirect": "გადამისამართება ფაილიდან, მომხმარებლიდან, გვერდიდან, ვერსიის ან ავტორიზაციის იდენტიფიკატორიდან",
        "redirect-legend": "გადამისამართება ფაილზე ან გვერდზე",
-       "redirect-summary": "á\83\94á\83¡ á\83\93á\83\90á\83\9bá\83®á\83\9bá\83\90á\83 á\83\94 á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\90á\83\9bá\83\98á\83¡á\83\90á\83\9bá\83\90á\83 á\83\97á\83\94á\83\91á\83¡ á\83¤á\83\90á\83\98á\83\9aá\83\98á\83¡ (á\83¤á\83\90á\83\98á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98á\83\93á\83\90á\83\9c) á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94, (á\83\92á\83\95á\83\94á\83 á\83\93á\83\98á\83¡ á\83\90á\83\9c á\83\95á\83\94á\83 á\83¡á\83\98á\83\98á\83¡ á\83\98á\83\93á\83\94á\83\9cá\83¢á\83\98á\83¤á\83\98á\83\99á\83\90á\83¢á\83\9dá\83 á\83\98á\83\93á\83\90á\83\9c) á\83\90á\83\9c á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94 (á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83 á\83\90á\83\9dá\83\93á\83\94á\83\9cá\83\9dá\83\91á\83 á\83\98á\83\95á\83\98 á\83\98á\83\93á\83\94á\83\9cá\83¢á\83\98á\83¤á\83\98á\83\99á\83\90á\83¢á\83\9dá\83 á\83\98á\83\93á\83\90á\83\9c). á\83\92á\83\90á\83\9bá\83\9dá\83§á\83\94á\83\9cá\83\94á\83\91á\83\90: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] á\83\90á\83\9c [[{{#Special:Redirect}}/user/101]].",
+       "redirect-summary": "á\83\94á\83¡ á\83\93á\83\90á\83\9bá\83®á\83\9bá\83\90á\83 á\83\94 á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\90á\83\9bá\83\98á\83¡á\83\90á\83\9bá\83\90á\83 á\83\97á\83\94á\83\91á\83¡ á\83¤á\83\90á\83\98á\83\9aá\83\96á\83\94 (á\83¤á\83\90á\83\98á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98á\83\93á\83\90á\83\9c) á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94, (á\83\92á\83\95á\83\94á\83 á\83\93á\83\98á\83¡ á\83\90á\83\9c á\83\95á\83\94á\83 á\83¡á\83\98á\83\98á\83¡ á\83\98á\83\93á\83\94á\83\9cá\83¢á\83\98á\83¤á\83\98á\83\99á\83\90á\83¢á\83\9dá\83 á\83\98á\83\93á\83\90á\83\9c), á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83\92á\83\95á\83\94á\83 á\83\93á\83\96á\83\94 (á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83 á\83\90á\83\9dá\83\93á\83\94á\83\9cá\83\9dá\83\91á\83 á\83\98á\83\95á\83\98 á\83\98á\83\93á\83\94á\83\9cá\83¢á\83\98á\83¤á\83\98á\83\99á\83\90á\83¢á\83\9dá\83 á\83\98á\83\93á\83\90á\83\9c) á\83\90á\83\9c á\83\9fá\83£á\83 á\83\9cá\83\90á\83\9aá\83\98á\83¡ á\83\9bá\83\9dá\83\9cá\83\90á\83ªá\83\94á\83\9bá\83\96á\83\94. á\83\92á\83\90á\83\9bá\83\9dá\83§á\83\94á\83\9cá\83\94á\83\91á\83\90:\n[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "მიდი",
        "redirect-lookup": "ძიება:",
        "redirect-value": "მნიშვნელობა:",
        "logentry-suppress-block": "მომხმარებელმა $1 {{GENDER:$2|დაბლოკა}} {{GENDER:$4|$3}} ბლოკირების ვადაა $5 $6",
        "logentry-suppress-reblock": "მომხმარებელმა $1 {{GENDER:$2|შეცვალა}} ბლოკირების პარამეტრები {{GENDER:$4|$3}}-თვის  ბლოკირების ვადაა $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|იმპორტირებული}} $3 ატვირთული ფაილი",
+       "logentry-import-upload-details": "$1-მ {{GENDER:$2|გადაიტანა}} $3 ფაილის ატვირთვით ($4 {{PLURAL:$4|ცვლილება|ცვლილება}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|იმპორტირებული}} $3 სხვა ვიკიდან",
+       "logentry-import-interwiki-details": "$1-მ {{GENDER:$2|გადაიტანა}} $3 $5-ზე ($4 {{PLURAL:$4|ცვლილება|ცვლილება}})",
        "logentry-merge-merge": "მომხმარებელმა $1 {{GENDER:$2|გააერთიანა}} $3 $4-ში ($5-მდე ვერსია)",
        "logentry-move-move": "მომხმარებელმა $1 გვერდი „$3“ {{GENDER:$2|გადაიტანა}} გვერდზე „$4“",
        "logentry-move-move-noredirect": "მომხმარებელმა $1 გვერდი „$3“ {{GENDER:$2|გადაიტანა}} გვერდზე „$4“ გადამისამართების დატოვების გარეშე",
        "logentry-newusers-create2": "მომხმარებლის ანგარიში $3 {{GENDER:$2|შექმნა}} მომხმარებელმა $1",
        "logentry-newusers-byemail": "მომხმარებლის ანგარიში $3 {{GENDER:$2|შექმნა}} მომხმარებელმა $1 და პაროლი გაგზავნა ელ. ფოსტით",
        "logentry-newusers-autocreate": "ავტომატურად {{GENDER:$2|შეიქმნა}} მომხმარებლის ანგარიში $1",
+       "logentry-protect-move_prot": "$1-მ {{GENDER:$2|გადაიტანა}} დაცვის კონფიგურაცია $4-დან $3-ზე",
+       "logentry-protect-unprotect": "$1-მა {{GENDER:$2|მოუხსნა}} დაცვა $3-ს",
        "logentry-protect-protect": "$1-მ {{GENDER:$2|დაიცვა}} $3 $4",
        "logentry-protect-protect-cascade": "$1-მ {{GENDER:$2|დაიცვა}} $3 $4 [კასკადური]",
        "logentry-protect-modify": "$1-მ {{GENDER:$2|შეცვალა}} დაცვის დონე $3 $4-სთვის",
index eab9811..4fe3fb6 100644 (file)
        "unwatch": "Şêr meke",
        "watchlist-details": "Pelunê hurênaişi ra qêri {{PLURAL:$1|$1 pele lista şêrkerdişi dera|$1 peli lista şêrkerdişi derê}}.",
        "wlshowlast": "$1 saetunê $2 rozunê peyênu bıasne",
-       "watchlistall2": "pêro",
        "watchlist-options": "Alternatifê lista şêrkerdene",
        "watching": "Şêr ke…",
        "unwatching": "Şêr meke…",
        "restriction-upload": "Bar ke",
        "restriction-level-sysop": "tam sevekiyo",
        "restriction-level-autoconfirmed": "nêm sevekiyo",
-       "restriction-level-all": "heme jü sewiya",
+       "restriction-level-all": "kamci be sewiya",
        "undelete": "Pelunê esteriyau basna",
        "undeletepage": "Pelunê esteriyau bıvine u peyser biya",
        "undeletepagetitle": "'''Ni, [[:$1|$1]] be çımraviarnaunê pele ra yenê pêra'''.",
index a82d4d1..45a62d6 100644 (file)
@@ -56,7 +56,8 @@
                        "Macofe",
                        "Yearning",
                        "고솜",
-                       "Sternradio"
+                       "Sternradio",
+                       "Joolee0104"
                ]
        },
        "tog-underline": "링크에 밑줄:",
        "october-date": "10월 $1일",
        "november-date": "11월 $1일",
        "december-date": "12월 $1일",
+       "period-am": "오전",
+       "period-pm": "오후",
        "pagecategories": "{{PLURAL:$1|분류}}",
        "category_header": "\"$1\" 분류에 속하는 문서",
        "subcategories": "하위 분류",
        "title-invalid-interwiki": "요청한 페이지 제목에 제목에는 사용될 수 없는 위키간 링크가 있습니다.",
        "title-invalid-talk-namespace": "요청한 페이지 제목이 존재하지 않는 토론 문서를 가리킵니다.",
        "title-invalid-characters": "요청된 문서 제목이 잘못된 문자를 포함하고 있습니다: \"$1\".",
+       "title-invalid-too-long": "페이지 제목이 너무 깁니다. 페이지 제목 길이는 최대 $1 까지 설정할 수 있습니다.",
+       "title-invalid-leading-colon": "페이지 제목에 잘못된 문자가 포함되어 있습니다.",
        "perfcached": "다음 자료는 캐시된 것이며 최신이 아닐 수 있습니다. 캐시에 최대 {{PLURAL:$1|결과 한 개|결과 $1개}}가 있습니다.",
        "perfcachedts": "다음 자료는 캐시된 것으로, $1에 마지막으로 업데이트되었습니다. 캐시에 최대 {{PLURAL:$4|결과 한 개|결과 $4개}}가 있습니다.",
        "querypage-no-updates": "이 문서의 갱신이 현재 중지되어 있습니다.\n자료가 잠시 갱신되지 않을 것입니다.",
        "throttled-mailpassword": "비밀번호 재설정 이메일을 이미 최근 {{PLURAL:$1|$1시간}} 안에 보냈습니다.\n악용을 방지하기 위해 비밀번호 재설정 메일은 {{PLURAL:$1|$1시간}}마다 오직 하나씩만 보낼 수 있습니다.",
        "mailerror": "메일을 보내는 중 오류: $1",
        "acct_creation_throttle_hit": "당신의 IP 주소를 이용한 방문자가 이전에 이미 {{PLURAL:$1|계정 $1개}}를 만들어, 계정 만들기 한도를 초과하였습니다.\n따라서 지금은 이 IP 주소로는 더 이상 계정을 만들 수 없습니다.",
-       "emailauthenticated": "이메일 주소는 $2 에 $3 에서 인증되었습니다.",
+       "emailauthenticated": "이메일 주소가 $2 $3에 인증되었습니다.",
        "emailnotauthenticated": "이메일 주소를 인증하지 않았습니다.\n이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.",
        "noemailprefs": "이 기능을 사용하기 위해서는 사용자 환경 설정에서 이메일 주소를 설정해야 합니다.",
        "emailconfirmlink": "이메일 주소 확인",
        "rcshowhidemine": "내 편집을 $1",
        "rcshowhidemine-show": "보이기",
        "rcshowhidemine-hide": "숨기기",
+       "rcshowhidecategorization": "$1 문서 분류",
        "rcshowhidecategorization-show": "보이기",
        "rcshowhidecategorization-hide": "숨기기",
        "rclinks": "최근 $2일간의 $1개 바뀐 문서 보기<br />$3",
        "querypage-disabled": "이 특수 문서는 성능상의 이유로 비활성화되었습니다.",
        "apihelp": "API 도움말",
        "apihelp-no-such-module": "\"$1\" 모듈을 찾을 수 없습니다.",
+       "apisandbox": "API 실험실",
+       "apisandbox-api-disabled": "이 사이트에서는 API가 꺼져 있습니다.",
+       "apisandbox-intro": "'''미디어위키 웹 서비스 API'''를 시험해보려면 이 페이지를 이용해보세요. API 용법에 대해서는 [//www.mediawiki.org/wiki/API:Main_page API 문서]을 참고하십시오. 예: [//www.mediawiki.org/wiki/API#A_simple_example 대문의 내용 요청하기]. 더 많은 예를 보려면 액션을 선택하세요.\n\n여기가 연습장이라도 이 페이지에서 실행하는 동작때문에 위키를 변경할 수도 있다는 점에 유의하십시오.",
+       "apisandbox-submit": "요청하기",
+       "apisandbox-reset": "지우기",
+       "apisandbox-examples": "예시",
+       "apisandbox-results": "결과",
+       "apisandbox-request-url-label": "요청 URL:",
+       "apisandbox-request-time": "요청 처리 시간: $1",
        "booksources": "책 찾기",
        "booksources-search-legend": "책 원본 검색",
        "booksources-isbn": "ISBN:",
index 9f43b61..d941bea 100644 (file)
        "uploaded-script-svg": "Mer han e verbodde Skrepp_Elemänd en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge: „$1“",
        "uploaded-hostile-svg": "Mer han onseescher <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Cascading Style Sheet\">CSS</i>-Befähle en enem „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">style</code>“-Ellemänt vun dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "uploaded-event-handler-on-svg": "Projramme för Ä'eijschneße ze behanndelle „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1=\"$2\"&gt;</code>“ ennzesäze es en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Datteije verbodde.",
-       "uploaded-href-attribute-svg": "De Eijeschaff „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“ „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ met Zihl_Datteije ußerhallef vum Wikki, Beijschpelle „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">http://</code>“,  „<code $3lang=\"en\" xml:lang=\"en\" dir=\"ltr\">javascript:</code>“, un esu wigger, sin verbodde en dä <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Datteije.",
        "uploaded-href-unsafe-target-svg": "Mer han ene „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Befähl obb e onseescher Zihl „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "uploaded-animate-svg": "Mer han dä Befähl „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">animate</code>“ en dä huhjelahde \n<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge, dä ene „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">href</code>“-Befähl verändere künnt övver de „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">from</code>“-Eijeschaff „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“.",
        "uploaded-setting-event-handler-svg": "Ed es verbodde, Projramme för Ä'eijschneße ze behanndelle ennzesäze, un de Datteije, di dat donn, wähde jeschpächt. Mer han „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">&lt;$1 $2=\"$3\"&gt;</code>“ en dä huhjelahde <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Scalable Vector Graphics\">SVG</i>_Dattei jefonge.",
        "querypage-disabled": "Heh di {{int:specialpage}} es ußjeschalldt, domet dä ẞööver jät winnijer ze brassele hät.",
        "apihelp": "Hölp för de <i lang=\"en\" xml:lang=\"en\" title=\"Application Programmers Interface\">API</i>",
        "apihelp-no-such-module": "Et Moduhl „$1“ wood nit jefonge.",
+       "apisandbox": "De <i lang=\"en\">API</i> ußprobeere",
+       "apisandbox-api-disabled": "Dat <i lang=\"en\">API</i> es en heh dämm Wiki afjeschalldt.",
+       "apisandbox-intro": "Op heh dä Sigg kanns De met dä '''MediaWiki web service <i lang=\"en\">API</i>''' eröm schpelle.\nBeloor Der de Einzelheite, wi di jebruch weed, op dä iere [//www.mediawiki.org/wiki/API:Main_page Sigg met de Verklieronge].\nE Beiscpell: [//www.mediawiki.org/wiki/API#A_simple_example De Houpsigg holle].\nSöhk ene {{int:Apisb-label-action}} uß, öm mieh Beishpell aanjezeisch ze krijje.\nOch wann dat heh nor zom Ußprobeere es, kann dat, wat De heh mähß, et Wiki verändere.",
+       "apisandbox-submit": "Lohß jonn!",
+       "apisandbox-reset": "Läddesch maache",
+       "apisandbox-examples": "Bäijshpell",
+       "apisandbox-dynamic-parameters": "Zohsäzlejje Parrameetere",
+       "apisandbox-results": "Erus jekumme es",
+       "apisandbox-request-url-label": "Dä <i lang=\"en\">URL</i> vun dä Aanfrooch:",
+       "apisandbox-request-time": "De Zigg vum Afroof: $1",
        "booksources": "Böcher",
        "booksources-search-legend": "Söök noh Bezochsquelle för Bööcher",
        "booksources-isbn": "ISBN:",
index bc6c06b..f645a28 100644 (file)
        "retypenew": "Şîfreya nû careke din binîvîse",
        "resetpass_submit": "Şîfreyê pêkbîne û têkeve",
        "changepassword-success": "Guhertine şîfreya te serkeftî bû!",
+       "botpasswords-label-update": "Rojane bike",
+       "botpasswords-label-cancel": "Betal bike",
        "resetpass_forbidden": "Şîfre nikarin werin guhertin",
        "resetpass-submit-loggedin": "Şîfreyê biguherîne",
        "resetpass-submit-cancel": "Betal bike",
        "sig_tip": "Îmze û demxeya wext ya te",
        "hr_tip": "Rastexêza berwarî (kêm bi kar bîne)",
        "summary": "Kurte (Te çi kir?):",
-       "subject": "Mijar/sernivîs:",
+       "subject": "Mijar:",
        "minoredit": "Ev guhertineke biçûk e",
        "watchthis": "Vê gotarê bişopîne",
        "savearticle": "Rûpelê tomar bike",
        "editusergroup": "Komên bikarhêneran biguherîne",
        "editinguser": "Mafên bikarhêner '''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]]) tên guhertin",
        "userrights-editusergroup": "Komên bikarhêneran biguherîne",
-       "saveusergroups": "Komên bikarhêneran tomar bike",
+       "saveusergroups": "Komên {{GENDER:$1|bikarhêneran}} tomar bike",
        "userrights-groupsmember": "Endamê/a:",
        "userrights-groups-help": "Tu dikarî komên bikarhêneran ên vê/vî bikarhênerê/î biguherînî:\n* Qutiyeke nîşankirî dibêje ku ev bikarhêner di wê komê de ye.\n* Qutiyeke nenîşankirî dibêje ku ev bikarhêner ne di wê komê de ye.\n* Stêrkek (*) nîşan dide ku tu nikarî wê komê jêbibî, heke te berê ew lê zêde kiribe.",
        "userrights-reason": "Sedem:",
        "right-userrights-interwiki": "Mafên bikarhênerên li ser wîkiyên din biguherîne",
        "right-sendemail": "Ji bikarhênerên di re ename bişîne",
        "newuserlogpage": "Çêkirina hesabê nû",
+       "newuserlogpagetext": "Ev têketina hesabên bikarhêneriyê ye ên ku nû hatine afirandin.",
        "rightslog": "Guhertina mafê bikarhêneriyê",
        "rightslogtext": "Ev guhertineke ji bo mafên bikarhêneriyê ye.",
        "action-read": "vê rûpelê bixwîne",
        "watchthisupload": "Vê rûpelê bişopîne",
        "filewasdeleted": "Data'yek bi vê navê hatibû barkirin û jêbirin. Xêra xwe li $1 seke ku barkirina te hêja ye ya na.",
        "filename-bad-prefix": "Nava wê data'yê, yê tu niha bardikê, bi '''\"$1\"''' destpêdike. Kamêrayên dîjîtal wan navan didin wêneyên xwe. Ji kerema xwe navekî baştir binivisîne ji bo mirov zûtir zanibin ku şayeşê vê wêneyê çî ye.",
-       "upload-success-subj": "Barkirina serkeftî",
-       "upload-failure-subj": "Pirsgirêka barkirinê",
-       "upload-warning-subj": "Hişyariya barkirinê",
        "upload-file-error": "Çewtiya navxweyî",
        "upload-dialog-button-cancel": "Betal bike",
        "upload-dialog-button-done": "Çêbû",
        "notargettitle": "Armanc tune",
        "pager-newer-n": "{{PLURAL:$1|nûtir 1|nûtir $1}}",
        "pager-older-n": "{{PLURAL:$1|kevintir 1|kevintir $1}}",
+       "apisandbox-unfullscreen": "Rûpelê nîşan bide",
+       "apisandbox-helpurls": "Girêdanên alîkariyê",
+       "apisandbox-examples": "Mînak",
+       "apisandbox-results": "Encam",
        "booksources": "Çavkaniyên pirtûkan",
        "booksources-search-legend": "Li çavkanîyên pirtûkan bigere",
        "booksources-search": "Lêgerîn",
        "wlheader-showupdated": "Ev rûpela hatî guhertin dema te lê meyzand bi '''nivîsa stûr''' tê xuyakirin.",
        "wlnote": "Niha {{PLURAL:$1|xeyrandinê|'''$1''' xeyrandinên}} dawî yê {{PLURAL:$2|seetê|'''$2''' seetên}} dawî {{PLURAL:$1|tê|tên}} dîtin.",
        "wlshowlast": "Guhertinên berî $1 saetan, $2 rojan, ya  nîşan bide",
-       "watchlistall2": "hemû",
        "watchlist-hide": "Veşêre",
        "watchlist-submit": "Nîşan bide",
        "wlshowhideliu": "bikarhênerên tomarkirî",
        "expand_templates_output": "Encam",
        "expand_templates_ok": "Baş e",
        "expand_templates_preview": "Pêşdîtin",
+       "pagelanguage": "Zimanê rûpelê biguherîne",
        "pagelang-language": "Ziman",
        "pagelang-select-lang": "Zimanekî hilbijêre",
        "pagelang-submit": "Tomar bike",
        "right-pagelang": "Zimanê rûpelê biguherîne",
        "action-pagelang": "zimanê rûpelê biguherîne",
-       "log-name-pagelang": "Têketina ziman biguherîne",
+       "log-name-pagelang": "Têketina guherandina ziman",
        "mediastatistics-header-total": "Hemû dosye",
        "special-characters-group-latin": "Latînî",
        "special-characters-group-latinextended": "Latînî berfirehkirî",
index b274dfe..aabcdc1 100644 (file)
        "shown-title": "Monstrare $1 {{PLURAL:$1|eventum|eventus}} per paginam",
        "viewprevnext": "Videre ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "'''Iam est pagina \"[[:$1]]\"'''",
-       "searchmenu-new": "<strong>Si vis, paginam \"[[:$1]]\" crea!<strong> {{PLURAL:$2|0=|Conferatur etiam pagina sequens, ubi quaesitum quodam modo continetur.|Conferantur etiam paginae $2 sequentes, in quibus quaesitum quodam modo continetur.}}",
+       "searchmenu-new": "<strong>Si vis, paginam \"[[:$1]]\" crea!</strong> {{PLURAL:$2|0=|Conferatur etiam pagina sequens, ubi quaesitum quodam modo continetur.|Conferantur etiam paginae $2 sequentes, in quibus quaesitum quodam modo continetur.}}",
        "searchprofile-articles": "Paginae contentorum",
        "searchprofile-images": "Multimedia",
        "searchprofile-everything": "Omnia",
index 6abfcc5..416eafc 100644 (file)
        "botpasswords-disabled": "Botpasswierder sinn desaktivéiert.",
        "botpasswords-no-central-id": "Fir Botpasswierder ze benotze musst Dir mat engem zentraliséierte Benotzerkont ageloggt sidd.",
        "botpasswords-existing": "Aktuell Botpasswierder.",
+       "botpasswords-createnew": "En neit Botpasswuert uleeën",
        "botpasswords-editexisting": "E Botpasswuert änneren",
        "botpasswords-label-appid": "Numm vum Bot:",
        "botpasswords-label-create": "Uleeën",
        "grant-group-customization": "Upassungen an Astellungen",
        "grant-group-administration": "Administrativ Aktioune maachen",
        "grant-group-other": "Verschidden Aktivitéiten",
-       "grant-blockusers": "Benotzer spären an hir Spär ophiewen",
+       "grant-blockusers": "Benotzer spären an d'Spären ophiewen",
        "grant-createaccount": "Benotzerkonten opmaachen",
        "grant-createeditmovepage": "Säiten uleeën, änneren a réckelen",
        "grant-delete": "Säiten, Versiounen a Rubriken a Logbicher läschen",
        "grant-uploadfile": "Nei Fichieren eroplueden",
        "grant-basic": "Basisrechter",
        "grant-viewdeleted": "Geläscht Fichieren a Säite weisen",
-       "grant-viewmywatchlist": "Kuckt Är Iwwerwaachungslëscht",
+       "grant-viewmywatchlist": "Är Iwwerwaachungslëscht weisen",
        "newuserlogpage": "Logbuch vun den neien Umeldungen",
        "newuserlogpagetext": "Dëst ass d'Lescht vun de Benotzernimm déi ugeluecht goufen.",
        "rightslog": "Logbuch vun de Benotzerrechter",
        "querypage-disabled": "Dës Spezialsäit ass aus Performance-Grënn ausgeschalt.",
        "apihelp": "API-Hëllef",
        "apihelp-no-such-module": "Modul \"$1\" net fonnt.",
+       "apisandbox": "API-Sandkëscht",
+       "apisandbox-api-disabled": "API ass op dësem Site ausgeschalt.",
+       "apisandbox-unfullscreen": "Säit weisen",
+       "apisandbox-submit": "Ufro maachen",
+       "apisandbox-reset": "Eidel maachen",
+       "apisandbox-examples": "Beispiller",
+       "apisandbox-dynamic-parameters": "Zousätzlech Parameteren",
+       "apisandbox-dynamic-parameters-add-label": "Parameter derbäisetzen:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Numm vum Parameter",
+       "apisandbox-deprecated-parameters": "Vereelst Parameter",
+       "apisandbox-submit-invalid-fields-title": "E puer Felder sinn net valabel.",
+       "apisandbox-results": "Resultater",
+       "apisandbox-request-url-label": "URL fir Ufroen:",
+       "apisandbox-request-time": "Dauer vun der Ufro: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-alert-page": "Felder op dëser Säit sinn net valabel.",
        "booksources": "Bicherreferenzen",
        "booksources-search-legend": "No Bicherreferenze sichen",
        "booksources-search": "Sichen",
        "lastmodifiedatby": "Dës Säit gouf den $1 ëm $2 Auer vum $3 fir d'lescht geännert.",
        "othercontribs": "Op der Basis vun der Aarbecht vum $1",
        "others": "anerer",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|Benotzer|Benotzer}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|Benotzer}} $1",
        "anonusers": "{{PLURAL:$2|Anonyme(n)|Anonym}} {{SITENAME}}-Benotzer $1",
        "creditspage": "Quellen",
        "nocredits": "Fir dës Säit si keng Informatiounen iwwer d'Mataarbechter vun der Säit disponibel.",
        "expand_templates_generate_rawhtml": "HTML-Format weisen",
        "expand_templates_preview": "Kucken ouni ofzespäicheren",
        "expand_templates_input_missing": "Dir musst mindestens een Text aginn.",
-       "pagelanguage": "Eraussiche vun der Sprooch vun der Säit",
+       "pagelanguage": "Sprooch vun der Säit änneren",
        "pagelang-name": "Säit",
        "pagelang-language": "Sprooch",
        "pagelang-use-default": "Standard-Sprooch benotzen",
index a765f3f..643c334 100644 (file)
        "uploaded-script-svg": "عنصر قابل برنامه‌ریزی «$1» در پرونده بارگذاری اس‌وی‌جی یافت شد.",
        "uploaded-hostile-svg": "سی‌اس‌اس نا امن در عنصر سبک پروندهٔ بارگذاری شدهٔ اس‌وی‌جی یافت شد.",
        "uploaded-event-handler-on-svg": "قرار دادن ویژگی‌های مدیریت رویداد <code>$1=\"$2\"</code> در پرونده‌های اس‌وی‌جی مجاز نیست.",
-       "uploaded-href-attribute-svg": "ویژگی‌های href <code>&lt;$1 $2=\"$3\"&gt;</code> با هدف غیر محلی (برای نمونه، http://, javascript:, etc) در پرونده‌های اس‌وی‌جی مجاز نیست.",
        "uploaded-href-unsafe-target-svg": "در پرونده SVG بارگذاری‌شده برای هدف نادرست <code>&lt;$1 $2=\"$3\"&gt;</code> برچسب href یافت شد.",
        "uploaded-animate-svg": "برچسب  \"animate\" یافت شده ممکن است herf را تغییر دهد. از مشخصه \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> در پرونده SVG بارگذاری‌شده استفاده کنید.",
        "uploaded-setting-event-handler-svg": "تنظیمات مشخصه گرداننده رویداد بسته شده‌است. کد <code>&lt;$1 $2=\"$3\"&gt;</code>  در پرونده بارگذاری‌شده یافت شد.",
index 1086375..64339a4 100644 (file)
        "uploaded-script-svg": "Įkeltame SVG faile rastas programuojamas elementas \"$1\".",
        "uploaded-hostile-svg": "Įkelto SVG failo stiliaus elemente rastas nesaugus CSS.",
        "uploaded-event-handler-on-svg": "SVG failuose neleidžiamas event-handler atributų nustatymas <code>$1=\"$2\"</code>.",
-       "uploaded-href-attribute-svg": "SVG failuose neleidžiami nuorodos atributai <code>&lt;$1 $2=\"$3\"&gt;</code> su ne lokalia nukreiptimi (pvz. http://, javascript:, ir kt.).",
        "uploaded-href-unsafe-target-svg": "Įkeltame SVG faile rasta nesaugi nukreiptis <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "Įkeltame SVG faile rasta \"animate\" žymė, kuri gali keisti nuorodas, panaudodama \"from\" atributą <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "event-handler atributų nustatymas yra draudžiamas, įkeltame SVG faile rasta <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "upload-too-many-redirects": "URL yra per daug kartų peradresuotas",
        "upload-http-error": "Įvyko HTTP klaida: $1",
        "upload-copy-upload-invalid-domain": "Pakrovimų kopijos yra neleidžiamos iš šio domeno.",
+       "upload-foreign-cant-upload": "Šis vikis nėra sukonfigūruotas failų įkėlimui į nurodytą išorinę failų talpyklą.",
        "upload-dialog-title": "Įkelti failą",
        "upload-dialog-button-cancel": "Atšaukti",
        "upload-dialog-button-done": "Atlikta",
        "querypage-disabled": "Šiame specialiajame puslapyje yra išjungta dėl neefektyvumo.",
        "apihelp": "API pagalba",
        "apihelp-no-such-module": "Nerasta modulio $1.",
+       "apisandbox": "API smėlio dėžės",
+       "apisandbox-api-disabled": "API yra išjungtas šioje svetainėje.",
+       "apisandbox-intro": "Naudokite šį puslapį norėdami eksperimentuoti su '''MediaWiki API \"„.\n\tIeškokite [//www.mediawiki.org/wiki/API:Main_page API dokumentacijoje] Išsamesnės informacijos apie API naudojimo.",
+       "apisandbox-submit": "Pateikti prašymą",
+       "apisandbox-reset": "Išvalyti",
+       "apisandbox-examples": "Pavyzdys",
+       "apisandbox-results": "Rezultatai",
+       "apisandbox-request-url-label": "Prašyti URL:",
+       "apisandbox-request-time": "Užklausos laikas: $1",
        "booksources": "Knygų šaltiniai",
        "booksources-search-legend": "Knygų šaltinių paieška",
        "booksources-search": "Ieškoti",
index 623ab53..8d79620 100644 (file)
@@ -17,7 +17,8 @@
                        "灰太狼Wolffy55",
                        "RalfX",
                        "Davidzdh",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "飞舞回堂前"
                ]
        },
        "tog-underline": "鏈墊線:",
        "viewsourceold": "察源碼",
        "editlink": "纂",
        "viewsourcelink": "察源碼",
-       "editsectionhint": "纂 $1",
+       "editsectionhint": "纂段:$1",
        "toc": "章",
        "showtoc": "示",
        "hidetoc": "藏",
        "prefs-displayrc": "示項",
        "prefs-displaywatchlist": "示項",
        "prefs-diffs": "異",
-       "email-address-validity-valid": "電郵有效之",
-       "email-address-validity-invalid": "貢一效之電郵",
        "userrights": "秉治權任",
        "userrights-lookup-user": "司社",
        "userrights-user-editname": "簿名:",
        "right-blockemail": "鎖簿無電郵",
        "right-hideuser": "鎖簿名,予藏眾",
        "right-ipblock-exempt": "繞IP鎖、自鎖與圍鎖",
-       "right-proxyunbannable": "繞Proxy之自鎖",
        "right-unblockself": "自解鎖",
        "right-protect": "改錮級與纂錮頁",
        "right-editprotected": "纂錮頁(無連錮)",
        "upload-options": "貢項",
        "watchthisupload": "派哨",
        "filename-bad-prefix": "獻檔以'''「$1」'''首,常由相機瞎造,惠更述之。",
-       "upload-success-subj": "檔案安矣",
-       "upload-success-msg": "爾自[$2]之貢安矣,見於此:[[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "貢問",
-       "upload-failure-msg": "爾自[$2]之貢現問也:\n\n$1",
-       "upload-warning-subj": "貢警",
-       "upload-warning-msg": "爾自[$2]之貢出問。爾可回[[Special:Upload/stash/$1|貢表]]修此問。",
        "upload-proto-error": "協訂錯誤",
        "upload-too-many-redirects": "網址含多轉",
        "upload-http-error": "發一HTTP之錯:$1",
        "movelogpagetext": "頁遷如下:",
        "movereason": "因",
        "revertmove": "還",
-       "delete_and_move": "刪遷",
        "delete_and_move_text": "==准刪==\n\n往遷\"[[:$1]]\"存,刪之以替乎?",
        "delete_and_move_confirm": "刪之",
        "delete_and_move_reason": "為遷而刪之",
        "tooltip-pt-logout": "凡事盡,乘雲飄",
        "tooltip-pt-createaccount": "勸君增簿以登,然非必須之舉",
        "tooltip-ca-talk": "求異見、辯是非、妥紛擾",
-       "tooltip-ca-edit": "拓文意、校誤謬、潤辭藻",
+       "tooltip-ca-edit": "纂是頁",
        "tooltip-ca-addsection": "有言議,添新要",
        "tooltip-ca-viewsource": "文函緘,讀源老",
        "tooltip-ca-history": "誌流衍、備謄本、修惡盜",
        "tooltip-ca-move": "安居所,嚮正道",
        "tooltip-ca-watch": "哨此報",
        "tooltip-ca-unwatch": "撤此哨",
-       "tooltip-search": "索大典,籲自曉",
+       "tooltip-search": "尋於{{SITENAME}}",
        "tooltip-search-go": "確合契,躍步到",
        "tooltip-search-fulltext": "尋通篇,列倣傚",
        "tooltip-p-logo": "返卷首,訪露朝",
        "tooltip-t-contributions": "同肩戰,苦功高",
        "tooltip-t-emailuser": "言未猶,書信捎",
        "tooltip-t-upload": "貢彩件、獻樂謠",
-       "tooltip-t-specialpages": "å¥\87æ\80ªæ±\82ï¼\8cç\89¹æ\9f¥æ\89¾",
+       "tooltip-t-specialpages": "å±\95ç\9b¡å¥\87é \81",
        "tooltip-t-print": "備印墨,整版貌",
        "tooltip-t-permalink": "鏈緊焊,橋吊牢",
        "tooltip-ca-nstab-main": "閱文稿",
        "tooltip-ca-nstab-user": "返齋寮",
        "tooltip-ca-nstab-media": "聽媒紹",
-       "tooltip-ca-nstab-special": "特查報,謝纂校",
+       "tooltip-ca-nstab-special": "是爲奇頁,謝纂校",
        "tooltip-ca-nstab-project": "探爐灶",
        "tooltip-ca-nstab-image": "觀揮毫",
        "tooltip-ca-nstab-mediawiki": "聞官耗",
        "specialpages": "特查",
        "specialpages-note": "* 準特查。\n* <strong class=\"mw-specialpagerestricted\">限特查。</strong>",
        "specialpages-group-maintenance": "護報",
-       "specialpages-group-other": "它之奇頁",
+       "specialpages-group-other": "奇頁",
        "specialpages-group-login": "登/增",
        "specialpages-group-changes": "近易與誌",
        "specialpages-group-media": "媒報兼呈",
index 280a99c..3fca0eb 100644 (file)
        "rcshowhidemine": "$1 हमर सम्पादन सभ",
        "rcshowhidemine-show": "देखाउ",
        "rcshowhidemine-hide": "नुकाऊ",
-       "rcshowhidecategorization-show": "दà¥\87à¤\96ाà¤\8a",
-       "rcshowhidecategorization-hide": "नà¥\81à¤\95ाà¤\8a",
+       "rcshowhidecategorization-show": "दà¥\87à¤\96ाबà¥\80",
+       "rcshowhidecategorization-hide": "नà¥\81à¤\95ाबà¥\80",
        "rclinks": "देखाऊ अंतिम $1 परिवर्त्तन अंतिम $2 दिनमे<br />$3",
        "diff": "अन्तर",
        "hist": "इति.",
        "querypage-disabled": "ई विशिष्ट पन्ना कार्य दक्षता लेल अशक्त कएल गेल अछि।",
        "apihelp": "API मद्दत",
        "apihelp-no-such-module": "मोड्युल \"$1\" नै भेटल।",
+       "apisandbox": "ए॰पी॰आइ प्रयोगपृष्ठ",
+       "apisandbox-submit": "अनुरोध करु",
+       "apisandbox-reset": "स्पष्ट",
+       "apisandbox-examples": "उदाहरण",
+       "apisandbox-results": "परिणाम",
+       "apisandbox-request-url-label": "अनुरोध URL:",
+       "apisandbox-request-time": "अनुरोध समय: $1",
        "booksources": "किताबक सन्दर्भ सभ",
        "booksources-search-legend": "किताबक सन्दर्भक लेल ताकू",
        "booksources-isbn": "आइ.एस.बी.एन.:",
        "contributions": "प्रयोक्ताक योगदान सभ",
        "contributions-title": "$1 लेल प्रयोक्ताक अवदान",
        "mycontris": "योगदान",
+       "anoncontribs": "योगदानसभ",
        "contribsub2": "$1 ($2) लेल",
        "contributions-userdoesnotexist": "प्रयोक्ता खाता \"$1\" पंजीकृत नै अछि।",
        "nocontribs": "कोनो परिवर्तन ऐ सँ मेल नै खाइए।",
        "javascripttest-pagetext-frameworks": "कृपया निम्न परीक्षण ढाँचा सभ में सँ एक चुनु: $1",
        "javascripttest-pagetext-skins": "परीक्षण करए के लेल त्वचा चुनु:",
        "javascripttest-qunit-intro": "mediawiki.org पर [$1 परीक्षण के प्रलेखन] देखु।",
-       "tooltip-pt-userpage": "अहाँक खेसरा पन्ना",
+       "tooltip-pt-userpage": "{{GENDER:|अहाँक प्रयोगकर्ता}} पृष्ठ",
        "tooltip-pt-anonuserpage": "सम्पाद्न कएल जा रहल स्थानक  अनिकेतक प्रयोक्ता पन्ना",
-       "tooltip-pt-mytalk": "अहाँक वार्त्ता पृष्ठ",
+       "tooltip-pt-mytalk": "{{GENDER:|अहाँक}} वार्ता पृष्ठ",
        "tooltip-pt-anontalk": "ऐ अनिकेतसँ भेल सम्पादनक वार्ता",
-       "tooltip-pt-preferences": "हमर मोनपसंद",
+       "tooltip-pt-preferences": "{{GENDER:|अहाँक}} अभिरुचीसभ",
        "tooltip-pt-watchlist": "पन्ना सभ जकर परिवर्त्तन पर अहाँक नजरि अछि",
-       "tooltip-pt-mycontris": "अहाँक योगदानक सूची",
+       "tooltip-pt-mycontris": "{{GENDER:|अहाँक}} योगदानक सूची",
        "tooltip-pt-login": "अहाँक खाता खोलक लेल प्रोत्साहित केल जाएत अछि; मुदा ई अनिवार्य नै अछि",
        "tooltip-pt-logout": "फेर आयब",
        "tooltip-pt-createaccount": "अहाँक खाता खोलक लेल प्रोत्साहित केल जाएत अछि; मुदा ई अनिवार्य नै छै",
index 5c5c1db..df1de22 100644 (file)
        "resetpass_submit": "Поставете лозинка и најавете се",
        "changepassword-success": "Вашата лозинка е успешно сменета!",
        "changepassword-throttled": "Имате премногу обиди за најава за кратко време.\nПочекајте $1 пред да се обидете повторно.",
+       "botpasswords-label-appid": "Име на ботот:",
+       "botpasswords-label-create": "Создај",
+       "botpasswords-label-update": "Поднови",
+       "botpasswords-label-cancel": "Откажи",
+       "botpasswords-label-delete": "Избриши",
+       "botpasswords-label-resetpassword": "Ставете нова лозинка",
+       "botpasswords-label-grants": "Применливи доделувања:",
        "resetpass_forbidden": "Лозинките не може да се менуваат",
        "resetpass-no-info": "Мора да сте најавени ако сакате да имате директен пристап до оваа страница.",
        "resetpass-submit-loggedin": "Смени лозинка",
        "uploaded-script-svg": "Пронајдов скриптен елемент „$1“ во подигнатата SVG-податотека.",
        "uploaded-hostile-svg": "Пронајдов небезбеден CSS во стилскиот елемент на подигнатата SVG-податотека.",
        "uploaded-event-handler-on-svg": "Задавањето на атрибути <code>$1=\"$2\"</code> за работа со настани не е дозволено за SVG-податотеки.",
-       "uploaded-href-attribute-svg": "href-атрибути <code>&lt;$1 $2=\"$3\"&gt;</code> со немесна цел (на пр. http://, javascript: и тн.) не се дозволени во SVG-податотеки.",
        "uploaded-href-unsafe-target-svg": "Пронајдов href кон небезбедна цел <code>&lt;$1 $2=\"$3\"&gt;</code> во подигнатата SVG-податотека.",
        "uploaded-animate-svg": "Пронајдов ознака „animate“ што може да го менува href, користејќи го атрибутот „from“ <code>&lt;$1 $2=\"$3\"&gt;</code> во подигнатата SVG-податотека.",
        "uploaded-setting-event-handler-svg": "Задавањето на атрибути за работа со настани е спречено. Пронајдов <code>&lt;$1 $2=\"$3\"&gt;</code> во подигнатата SVG-податотека.",
        "querypage-disabled": "Оваа службена страница е оневозможена за да не попречува на делотворноста.",
        "apihelp": "Помош со извршникот",
        "apihelp-no-such-module": "Модулот „$1“ не е пронајден.",
+       "apisandbox": "Извршнички песочник",
+       "apisandbox-api-disabled": "Извршникот е оневозможен на ова мрежно место.",
+       "apisandbox-intro": "Страницава служи за вршење проби со '''Извршник на МедијаВики'''.\n\nПовеќе за употребата на овој извршник ќе најдете во [//www.mediawiki.org/wiki/API:Main_page неговата документација].  Пример: [//www.mediawiki.org/wiki/API#A_simple_example преземање на содржината на главната страница].  Одберете дејство за да видите повеќе примери.\n\nИмајте предвид дека она шо го правите на страницава може да се одрази врз викито, иако ова е песочник.",
+       "apisandbox-submit": "Постави барање",
+       "apisandbox-reset": "Исчисти",
+       "apisandbox-examples": "Пример",
+       "apisandbox-results": "Извод",
+       "apisandbox-request-url-label": "URL на барањето:",
+       "apisandbox-request-time": "Време за барањето: $1",
        "booksources": "Печатени извори",
        "booksources-search-legend": "Пребарување на извори за книга",
        "booksources-isbn": "ISBN:",
        "log-title-wildcard": "Пребарај наслови кои почнуваат со овој текст",
        "showhideselectedlogentries": "Прикажи/скриј одбрани записи",
        "log-edit-tags": "Измени ознаки на одредени дневнички записи",
+       "checkbox-select": "Одбери: $1",
+       "checkbox-all": "Сите",
+       "checkbox-none": "Ништо",
+       "checkbox-invert": "Избери обратно",
        "allpages": "Сите страници",
        "nextpage": "Следна страница ($1)",
        "prevpage": "Претходна страница ($1)",
        "lockedbyandtime": "(од $1 на $2 цо $3 ч.)",
        "move-page": "Премести $1",
        "move-page-legend": "Премести страница",
-       "movepagetext": "Со ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9aеÑ\82о Ð½Ð° Ð¾Ð²Ð¾Ñ\98 Ð¾Ð±Ñ\80азеÑ\86 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82Ñ\83ваÑ\98Ñ\9cи Ñ\98а Ñ\86елаÑ\82а Ð½ÐµÑ\98зина Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð¿Ð¾Ð´ Ð½Ð¾Ð²Ð¾ Ð¸Ð¼Ðµ.\nСÑ\82аÑ\80иоÑ\82 Ð½Ð°Ñ\81лов Ñ\9cе Ñ\81Ñ\82ане Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\87ка Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ð½ Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов.\nÐ\90вÑ\82омаÑ\82Ñ\81ки Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð³Ð¸ Ð¿Ð¾Ð´Ð½Ð¾Ð²Ð¸Ñ\82е Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aаÑ\82а ÐºÐ¾Ð¸ Ð¿Ð¾ÐºÐ°Ð¶Ñ\83вааÑ\82 ÐºÐ¾Ð½ Ð¿Ñ\80вобиÑ\82ниоÑ\82 Ð½Ð°Ñ\81лов.\nÐ\90ко Ð½Ðµ Ð¸Ð·Ð±ÐµÑ\80еÑ\82е Ð°Ð²Ñ\82омаÑ\82Ñ\81ко Ð¿Ð¾Ð´Ð½Ð¾Ð²Ñ\83ваÑ\9aе, Ð¿Ñ\80овеÑ\80еÑ\82е Ð½Ð° [[Special:DoubleRedirects|двоÑ\98ни]] Ð¸Ð»Ð¸ [[Special:BrokenRedirects|пÑ\80екинаÑ\82и Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа]].\nÐ\9dа Ð²Ð°Ñ\81 Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80ноÑ\81Ñ\82а Ð´Ð° Ñ\81е Ð¾Ñ\81игÑ\83Ñ\80аÑ\82е Ð´ÐµÐºÐ° Ð²Ñ\80Ñ\81киÑ\82е Ñ\9cе Ð¿Ñ\80одолжаÑ\82 Ð´Ð° Ð½Ð°Ñ\81оÑ\87Ñ\83вааÑ\82 Ñ\82амÑ\83 Ð·Ð° ÐºÐ°Ð´Ðµ Ñ\81е Ð¿Ñ\80едвидени.\n\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а '''нема''' Ð´Ð° Ð±Ð¸Ð´Ðµ Ð¿Ñ\80емеÑ\81Ñ\82ена Ð°ÐºÐ¾ Ð²ÐµÑ\9cе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81о Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов, Ð¾Ñ\81вен Ð°ÐºÐ¾ Ðµ Ð½Ðµ Ðµ Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð¸ Ð½ÐµÐ¼Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð½Ð° Ð¼Ð¸Ð½Ð°Ñ\82и Ñ\83Ñ\80едÑ\83ваÑ\9aа. Ð¢Ð¾Ð° Ð·Ð½Ð°Ñ\87и Ð´ÐµÐºÐ° Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а ÐºÐ°ÐºÐ¾ Ñ\88Ñ\82о Ð±Ð¸Ð»Ð° Ð¿Ñ\80еÑ\82Ñ\85одно Ð´Ð¾ÐºÐ¾Ð»ÐºÑ\83 Ñ\81Ñ\82е Ð½Ð°Ð¿Ñ\80авиле Ð³Ñ\80еÑ\88ка Ð±ÐµÐ· Ð´Ð° Ñ\98а Ð¿Ñ\80екÑ\80иеÑ\82е Ð¿Ð¾Ñ\81Ñ\82оеÑ\87каÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а.\n\n'''Ð\9fÑ\80едÑ\83пÑ\80едÑ\83ваÑ\9aе!'''\nОва може да биде драстична и неочекувана промена за популарна страница;\nосигурајте се дека сте ги разбрале последиците од ова пред да продолжите.",
-       "movepagetext-noredirectfixer": "Со ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9aеÑ\82о Ð½Ð° Ð¾Ð²Ð¾Ñ\98 Ð¾Ð±Ñ\80азеÑ\86 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82Ñ\83ваÑ\98Ñ\9cи Ñ\98а Ñ\86елаÑ\82а Ð½ÐµÑ\98зина Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð¿Ð¾Ð´ Ð½Ð¾Ð²Ð¾ Ð¸Ð¼Ðµ.\nСÑ\82аÑ\80иоÑ\82 Ð½Ð°Ñ\81лов Ñ\9cе Ñ\81Ñ\82ане Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\87ка Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ð½ Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов.\nÐ\90вÑ\82омаÑ\82Ñ\81ки Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð³Ð¸ Ð¿Ð¾Ð´Ð½Ð¾Ð²Ð¸Ñ\82е Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aаÑ\82а ÐºÐ¾Ð¸ Ð¿Ð¾ÐºÐ°Ð¶Ñ\83вааÑ\82 ÐºÐ¾Ð½ Ð¿Ñ\80вобиÑ\82ниоÑ\82 Ð½Ð°Ñ\81лов.\nÐ\9dе Ð·Ð°Ð±Ð¾Ñ\80аваÑ\98Ñ\82е Ð´Ð° Ð¿Ñ\80овеÑ\80иÑ\82е [[Special:DoubleRedirects|двоÑ\98ни]] Ð¸ [[Special:BrokenRedirects|пÑ\80екинаÑ\82и Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа]].\nÐ\9dа Ð²Ð°Ñ\81 Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80ноÑ\81Ñ\82а Ð´Ð° Ñ\81е Ð¾Ñ\81игÑ\83Ñ\80аÑ\82е Ð´ÐµÐºÐ° Ð²Ñ\80Ñ\81киÑ\82е Ñ\9cе Ð¿Ñ\80одолжаÑ\82 Ð´Ð° Ð½Ð°Ñ\81оÑ\87Ñ\83вааÑ\82 Ñ\82амÑ\83 Ð·Ð° ÐºÐ°Ð´Ðµ Ñ\81е Ð¿Ñ\80едвидени.\n\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а '''Ð\9dÐ\95Ð\9cÐ\90''' Ð´Ð° Ð±Ð¸Ð´Ðµ Ð¿Ñ\80емеÑ\81Ñ\82ена Ð°ÐºÐ¾ Ð²ÐµÑ\9cе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81о Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов, Ð¾Ñ\81вен Ð°ÐºÐ¾ Ðµ Ð¿Ñ\80азна Ð¸Ð»Ð¸ Ð°ÐºÐ¾ Ðµ Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð¸ Ð½ÐµÐ¼Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð½Ð° Ð¼Ð¸Ð½Ð°Ñ\82и Ñ\83Ñ\80едÑ\83ваÑ\9aа. Ð¢Ð¾Ð° Ð·Ð½Ð°Ñ\87и Ð´ÐµÐºÐ° Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а ÐºÐ°ÐºÐ¾ Ñ\88Ñ\82о Ð±Ð¸Ð»Ð° Ð¿Ñ\80еÑ\82Ñ\85одно Ð´Ð¾ÐºÐ¾Ð»ÐºÑ\83 Ñ\81Ñ\82е Ð½Ð°Ð¿Ñ\80авиле Ð³Ñ\80еÑ\88ка Ð±ÐµÐ· Ð´Ð° Ñ\98а Ð¿Ñ\80екÑ\80иеÑ\82е Ð¿Ð¾Ñ\81Ñ\82оеÑ\87каÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а.\n\n'''Ð\9fРÐ\95Ð\94УÐ\9fРÐ\95Ð\94УÐ\92Ð\90Ð\8aÐ\95!'''\nОва може да биде драстична и неочекувана промена за популарна страница;\nосигурајте се дека сте ги разбрале последиците од ова пред да продолжите.",
+       "movepagetext": "Со ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9aеÑ\82о Ð½Ð° Ð¾Ð²Ð¾Ñ\98 Ð¾Ð±Ñ\80азеÑ\86 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82Ñ\83ваÑ\98Ñ\9cи Ñ\98а Ñ\86елаÑ\82а Ð½ÐµÑ\98зина Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð¿Ð¾Ð´ Ð½Ð¾Ð²Ð¾ Ð¸Ð¼Ðµ.\nСÑ\82аÑ\80иоÑ\82 Ð½Ð°Ñ\81лов Ñ\9cе Ñ\81Ñ\82ане Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\87ка Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ð½ Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов.\nÐ\90вÑ\82омаÑ\82Ñ\81ки Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð³Ð¸ Ð¿Ð¾Ð´Ð½Ð¾Ð²Ð¸Ñ\82е Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aаÑ\82а ÐºÐ¾Ð¸ Ð¿Ð¾ÐºÐ°Ð¶Ñ\83вааÑ\82 ÐºÐ¾Ð½ Ð¿Ñ\80вобиÑ\82ниоÑ\82 Ð½Ð°Ñ\81лов.\nÐ\90ко Ð½Ðµ Ð¸Ð·Ð±ÐµÑ\80еÑ\82е Ð°Ð²Ñ\82омаÑ\82Ñ\81ко Ð¿Ð¾Ð´Ð½Ð¾Ð²Ñ\83ваÑ\9aе, Ð¿Ñ\80овеÑ\80еÑ\82е Ð½Ð° [[Special:DoubleRedirects|двоÑ\98ни]] Ð¸Ð»Ð¸ [[Special:BrokenRedirects|пÑ\80екинаÑ\82и Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа]].\nÐ\9dа Ð²Ð°Ñ\81 Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80ноÑ\81Ñ\82а Ð´Ð° Ñ\81е Ð¾Ñ\81игÑ\83Ñ\80аÑ\82е Ð´ÐµÐºÐ° Ð²Ñ\80Ñ\81киÑ\82е Ñ\9cе Ð¿Ñ\80одолжаÑ\82 Ð´Ð° Ð½Ð°Ñ\81оÑ\87Ñ\83вааÑ\82 Ñ\82амÑ\83 Ð·Ð° ÐºÐ°Ð´Ðµ Ñ\81е Ð¿Ñ\80едвидени.\n\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а '''нема''' Ð´Ð° Ð±Ð¸Ð´Ðµ Ð¿Ñ\80емеÑ\81Ñ\82ена Ð°ÐºÐ¾ Ð²ÐµÑ\9cе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81о Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов, Ð¾Ñ\81вен Ð°ÐºÐ¾ Ðµ Ð½Ðµ Ðµ Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð¸ Ð½ÐµÐ¼Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð½Ð° Ð¼Ð¸Ð½Ð°Ñ\82и Ñ\83Ñ\80едÑ\83ваÑ\9aа. Ð¢Ð¾Ð° Ð·Ð½Ð°Ñ\87и Ð´ÐµÐºÐ° Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а ÐºÐ°ÐºÐ¾ Ñ\88Ñ\82о Ð±Ð¸Ð»Ð° Ð¿Ñ\80еÑ\82Ñ\85одно Ð´Ð¾ÐºÐ¾Ð»ÐºÑ\83 Ñ\81Ñ\82е Ð½Ð°Ð¿Ñ\80авиле Ð³Ñ\80еÑ\88ка Ð±ÐµÐ· Ð´Ð° Ñ\98а Ð¿Ñ\80екÑ\80иеÑ\82е Ð¿Ð¾Ñ\81Ñ\82оеÑ\87каÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а.\n\n'''Ð\9dапомена:'''\nОва може да биде драстична и неочекувана промена за популарна страница;\nосигурајте се дека сте ги разбрале последиците од ова пред да продолжите.",
+       "movepagetext-noredirectfixer": "Со ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9aеÑ\82о Ð½Ð° Ð¾Ð²Ð¾Ñ\98 Ð¾Ð±Ñ\80азеÑ\86 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82Ñ\83ваÑ\98Ñ\9cи Ñ\98а Ñ\86елаÑ\82а Ð½ÐµÑ\98зина Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð¿Ð¾Ð´ Ð½Ð¾Ð²Ð¾ Ð¸Ð¼Ðµ.\nСÑ\82аÑ\80иоÑ\82 Ð½Ð°Ñ\81лов Ñ\9cе Ñ\81Ñ\82ане Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\87ка Ñ\81Ñ\82Ñ\80аниÑ\86а ÐºÐ¾Ð½ Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов.\nÐ\90вÑ\82омаÑ\82Ñ\81ки Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð³Ð¸ Ð¿Ð¾Ð´Ð½Ð¾Ð²Ð¸Ñ\82е Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aаÑ\82а ÐºÐ¾Ð¸ Ð¿Ð¾ÐºÐ°Ð¶Ñ\83вааÑ\82 ÐºÐ¾Ð½ Ð¿Ñ\80вобиÑ\82ниоÑ\82 Ð½Ð°Ñ\81лов.\nÐ\9dе Ð·Ð°Ð±Ð¾Ñ\80аваÑ\98Ñ\82е Ð´Ð° Ð¿Ñ\80овеÑ\80иÑ\82е [[Special:DoubleRedirects|двоÑ\98ни]] Ð¸ [[Special:BrokenRedirects|пÑ\80екинаÑ\82и Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aа]].\nÐ\9dа Ð²Ð°Ñ\81 Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð¾Ñ\80ноÑ\81Ñ\82а Ð´Ð° Ñ\81е Ð¾Ñ\81игÑ\83Ñ\80аÑ\82е Ð´ÐµÐºÐ° Ð²Ñ\80Ñ\81киÑ\82е Ñ\9cе Ð¿Ñ\80одолжаÑ\82 Ð´Ð° Ð½Ð°Ñ\81оÑ\87Ñ\83вааÑ\82 Ñ\82амÑ\83 Ð·Ð° ÐºÐ°Ð´Ðµ Ñ\81е Ð¿Ñ\80едвидени.\n\nÐ\98маÑ\98Ñ\82е Ð¿Ñ\80едвид Ð´ÐµÐºÐ° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а '''Ð\9dÐ\95Ð\9cÐ\90''' Ð´Ð° Ð±Ð¸Ð´Ðµ Ð¿Ñ\80емеÑ\81Ñ\82ена Ð°ÐºÐ¾ Ð²ÐµÑ\9cе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\81о Ð½Ð¾Ð²Ð¸Ð¾Ñ\82 Ð½Ð°Ñ\81лов, Ð¾Ñ\81вен Ð°ÐºÐ¾ Ðµ Ð¿Ñ\80азна Ð¸Ð»Ð¸ Ð°ÐºÐ¾ Ðµ Ð¿Ñ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð¸ Ð½ÐµÐ¼Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а Ð½Ð° Ð¼Ð¸Ð½Ð°Ñ\82и Ñ\83Ñ\80едÑ\83ваÑ\9aа. Ð¢Ð¾Ð° Ð·Ð½Ð°Ñ\87и Ð´ÐµÐºÐ° Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\98а Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а ÐºÐ°ÐºÐ¾ Ñ\88Ñ\82о Ð±Ð¸Ð»Ð° Ð¿Ñ\80еÑ\82Ñ\85одно Ð´Ð¾ÐºÐ¾Ð»ÐºÑ\83 Ñ\81Ñ\82е Ð½Ð°Ð¿Ñ\80авиле Ð³Ñ\80еÑ\88ка Ð±ÐµÐ· Ð´Ð° Ñ\98а Ð¿Ñ\80екÑ\80иеÑ\82е Ð¿Ð¾Ñ\81Ñ\82оеÑ\87каÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а.\n\n'''Ð\9dапомена:'''\nОва може да биде драстична и неочекувана промена за популарна страница;\nосигурајте се дека сте ги разбрале последиците од ова пред да продолжите.",
        "movepagetalktext": "Ако го штиклирате кутивчево, соодветната страница за разговор ќе биде автоматски преместена на нов наслов, освен ако таму веќе постои страница за разговор што не е празна.\n\nВо тој случај, ќе треба да ја преместите или споите страницата рачно, доколку сакате.",
        "moveuserpage-warning": "'''Предупредување:''' На пат сте да преместите корисничка страница. Имајте предвид дека само страницата ќе биде преместена, а самиот корисник ''нема'' да биде преименуван.",
        "movecategorypage-warning": "<strong>Предупредување:</strong> Преместувате категориска страница. Имајте предвид дека ќе се премести само страницата, а страниците во старата категорија <em>нема</em> да се прекатегоризираат во новата.",
        "movenosubpage": "Оваа страница нема потстраници.",
        "movereason": "Причина:",
        "revertmove": "врати",
-       "delete_and_move_text": "==Потребно бришење==\nЦелната статија „[[:$1]]“ веќе постои.\nДали сакате да ја избришете за да ослободите место за преместувањето?",
+       "delete_and_move_text": "Целната статија „[[:$1]]“ веќе постои.\nДали сакате да ја избришете за да ослободите место за преместувањето?",
        "delete_and_move_confirm": "Да, избриши ја страницата",
        "delete_and_move_reason": "Избришано за да се ослободи место за преместувањето од „[[$1]]“",
        "selfmove": "Појдовната и целната страница се истоветни;\nне можам да преместам.",
        "move-leave-redirect": "Направи пренасочување",
        "protectedpagemovewarning": "'''Предупредување:'''  Оваа страница е заштитена, така што само може да ја преместуваат само корисници со администраторски привилегии.\nЗа ваша информација, подолу е прикажана последната ставка во дневникот на измени:",
        "semiprotectedpagemovewarning": "'''Напомена:'''  Оваа страница е заштитена, така што може да ја преместуваат само регистрирани корисници.\nЗа ваша информација, подолу е прикажана последната ставка во дневникот на измени:",
-       "move-over-sharedrepo": "== Податотеката постои ==\n[[:$1]] постои на заедничко складиште. Ако податотеката ја преместите на овој наслов, тоа ќе ја потисне заедничката податотека.",
+       "move-over-sharedrepo": "[[:$1]] постои на заедничко складиште. Ако податотеката ја преместите на овој наслов, тоа ќе ја потисне заедничката податотека.",
        "file-exists-sharedrepo": "Одбраното име на податотеката веќе се користи на заедничко складиште.\nОдберете друго име.",
        "export": "Извоз на страници",
        "exporttext": "Можете да го извезете текстот и историјата на уредување на избрана страница или група на страници во XML формат.\nОвие податоци може да бидат вчитани на некое друго вики кое се користи со МедијаВики преку [[Special:Import|увезување на страница]].\n\nЗа извезување на страници, внесете ги насловите во полето прикажано подолу, еден наслов на статија во ред, потоа изберете дали сакате да ја извезете само последната преработка или и сите постари преработки.\n\nАко ја сакате само тековната верзија, би можеле да искористите врска од видот [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] за страницата „[[{{MediaWiki:Mainpage}}]]“.",
        "tooltip-feed-rss": "RSS емитување за оваа страница",
        "tooltip-feed-atom": "Атом-емитување за оваа страница",
        "tooltip-t-contributions": "Список на придонеси {{GENDER:$1|на овој корисник}}",
-       "tooltip-t-emailuser": "Испрати е-пошта на овој корисник",
+       "tooltip-t-emailuser": "Испрати е-пошта {{GENDER:$1|на овој корисник}}",
        "tooltip-t-info": "Повеќе информаици за страницава",
        "tooltip-t-upload": "Подигни податотеки",
        "tooltip-t-specialpages": "Список на сите службени страници",
        "lastmodifiedatby": "Последната промена на страницава е извршена на $1 г Сво $2 ч. Промената ја направи $3.",
        "othercontribs": "Засновано на работата на $1.",
        "others": "други",
-       "siteusers": "{{PLURAL:$2|корисникот|корисниците}} на {{SITENAME}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|корисник}}|корисници}} $1",
        "anonusers": "{{PLURAL:$2|анонимен корисник|анонимни корисници}} на {{SITENAME}} $1",
        "creditspage": "Автори на страницата",
        "nocredits": "Не постојат податоци за авторите на оваа страница.",
        "version-hook-subscribedby": "Претплатено од",
        "version-version": "($1)",
        "version-no-ext-name": "[нема име]",
-       "version-svn-revision": "прер. $1",
        "version-license": "Лиценца на МедијаВики",
        "version-ext-license": "Лиценца",
        "version-ext-colheader-name": "Додаток",
        "redirect-page": "Назнака на страницата",
        "redirect-revision": "Преработка на страницата",
        "redirect-file": "Име на податотека",
+       "redirect-logid": "Назнака на дневникот",
        "redirect-not-exists": "Вредноста не е најдена",
        "fileduplicatesearch": "Барање на дуплирани податотеки",
        "fileduplicatesearch-summary": "Пребарување на дуплирани податотеки по тарабни вредности.",
        "expand_templates_preview_fail_html": "<em>Бидејќи {{SITENAME}} има овозможено сиров HTML и се јави губиток на седнички податоци, прегледот е скриен како мерка на претпазливост против напади со JavaScript.</em>\n\n<strong>Ако ова е е легитимен обид за преглед, тогаш обидете се повторно.</strong>\nАко не работи и тогаш, [[Special:UserLogout|одјавете се]] и повторно најавете се.",
        "expand_templates_preview_fail_html_anon": "<em>Бидејќи {{SITENAME}} има овозможено сиров HTML, а вие не сте најавени, прегледот е скриен како мерка на претпазливост против напади со JavaScript.</em>\n\n<strong>Ако ова е е легитимен обид за преглед, тогаш обидете се повторно.</strong>\nАко не работи и тогаш, [[Special:UserLogout|одјавете се]] и повторно најавете се.",
        "expand_templates_input_missing": "Треба да внесете некаков текст.",
-       "pagelanguage": "Ð\98збоÑ\80ник Ð·Ð° Ñ\98азик Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а",
+       "pagelanguage": "Ð\9cенÑ\83ваÑ\9aе Ñ\98азик Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а",
        "pagelang-name": "Страница",
        "pagelang-language": "Јазик",
        "pagelang-use-default": "Користи стандарден јазик",
        "mw-widgets-titleinput-description-new-page": "страницата сè уште не постои",
        "mw-widgets-titleinput-description-redirect": "пренасочување кон $1",
        "api-error-blacklisted": "Одберете поинаков, описен наслов.",
+       "sessionprovider-generic": "$1 седници",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "седници со колачиња",
        "randomrootpage": "Случајна основна страница"
 }
index 2b53d20..fe7396e 100644 (file)
        "uploaded-script-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ സ്ക്രിപ്റ്റ് ചെയ്യാവുന്ന ഭാഗമായ \"$1\" കണ്ടെത്തി.",
        "uploaded-hostile-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ സുരക്ഷിതമല്ലാത്ത സി.എസ്.എസ്. സ്റ്റൈൽ ഭാഗം കണ്ടെത്താനായി.",
        "uploaded-event-handler-on-svg": "എസ്.വി.ജി. പ്രമാണങ്ങളിൽ എവന്റ്-ഹാൻഡ്‌ലർ ആട്രിബ്യൂട്ടുകൾ <code>$1=\"$2\"</code>  എന്ന് സജ്ജീകരിച്ചിരിക്കുന്നവ അനുവദിച്ചിട്ടില്ല.",
-       "uploaded-href-attribute-svg": "എസ്.വി.ജി. പ്രമാണങ്ങളിൽ എച്ച്റെഫ് (href) ആട്രിബ്യൂട്ടുകൾ പ്രാദേശികമല്ലാത്ത ലക്ഷ്യങ്ങളിലേക്ക് <code>&lt;$1 $2=\"$3\"&gt;</code> എന്നുള്ളവ (ഉദാ: http://, javascript:, തുടങ്ങിയവ) അനുവദിച്ചിട്ടില്ല.",
        "uploaded-href-unsafe-target-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ സുരക്ഷിതമല്ലാത്ത ലക്ഷ്യമായ <code>&lt;$1 $2=\"$3\"&gt;</code> കണ്ടെത്തി.",
        "uploaded-animate-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ <code>&lt;$1 $2=\"$3\"&gt;</code> ആട്രിബ്യൂട്ട് ഉപയോഗിച്ച് href മാറ്റിയേക്കാവുന്ന \"animate\" റ്റാഗായ <code>&lt;$1 $2=\"$3\"&gt;</code> കണ്ടെത്തി.",
        "uploaded-setting-event-handler-svg": "അപ്‌ലോഡ് ചെയ്ത എസ്.വി.ജി. പ്രമാണത്തിൽ <code>&lt;$1 $2=\"$3\"&gt;</code> കണ്ടെത്തി, ഇവന്റ്-കൈകാര്യ സജ്ജീകരണ ആട്രിബ്യൂട്ടുകൾ തടഞ്ഞിരിക്കുന്നു.",
        "querypage-disabled": "പ്രവർത്തനമികവിനെ ബാധിക്കുന്ന കാരണങ്ങളാൽ ഈ പ്രത്യേക താൾ പ്രവർത്തന രഹിതമാക്കിയിരിക്കുന്നു.",
        "apihelp": "എ.പി.ഐ. സഹായം",
        "apihelp-no-such-module": "ഘടകം \"$1\" കണ്ടെത്താനായില്ല.",
+       "apisandbox": "എ.പി.ഐ. എഴുത്തുകളരി",
+       "apisandbox-api-disabled": "ഈ സൈറ്റിൽ എ.പി.ഐ. പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു.",
+       "apisandbox-intro": "'''മീഡിയവിക്കി വെബ്‌ സെർവീസ് എ.പി.ഐ.'''യിൽ പരീക്ഷണങ്ങൾ നടത്താൻ ഈ താൾ ഉപയോഗിക്കുക.\nഎ.പി.ഐ.യുടെ ഉപയോഗത്തെക്കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾക്കായി [//www.mediawiki.org/wiki/API:Main_page the എ.പി.ഐ. സഹായം] പരിശോധിക്കുക. ഉദാഹരണം: [//www.mediawiki.org/wiki/API#A_simple_example പ്രധാന താളിന്റെ ഉള്ളടക്കം എടുക്കുക]. കൂടുതൽ ഉദാഹരണങ്ങൾക്കായി പ്രവൃത്തി തിരഞ്ഞെടുക്കുക.\n\nഇതൊരു പരീക്ഷണകളരിയാണെങ്കിലും ഇവിടെ ചെയ്യുന്നവ വിക്കിയിൽ മാറ്റങ്ങൾ വരുത്തിയേക്കാമെന്ന് ഓർക്കുക.",
+       "apisandbox-submit": "അഭ്യർത്ഥിക്കുക",
+       "apisandbox-reset": "ശൂന്യമാക്കുക",
+       "apisandbox-examples": "ഉദാഹരണം",
+       "apisandbox-results": "ഫലം",
+       "apisandbox-request-url-label": "അഭ്യർത്ഥനാ യൂ.ആർ.എൽ.:",
+       "apisandbox-request-time": "നടപ്പിലാക്കാൻ എടുത്ത സമയം: $1",
        "booksources": "പുസ്തക സ്രോതസ്സുകൾ",
        "booksources-search-legend": "പുസ്തകസ്രോതസ്സുകൾക്കായി തിരയുക",
        "booksources-isbn": "ഐ.എസ്.ബി.എൻ.:",
index 4628e81..27d49c6 100644 (file)
@@ -12,7 +12,8 @@
                        "Zorigt",
                        "לערי ריינהארט",
                        "아라",
-                       "Sembuk"
+                       "Sembuk",
+                       "Munkhzaya.E"
                ]
        },
        "tog-underline": "Линкүүдийн доогуур зураас зур:",
        "createaccountreason": "Шалтгаан:",
        "createacct-reason": "Шалтгаан",
        "createacct-reason-ph": "Өөр бүртгэл үүсгэх шалтгаан",
-       "createacct-captcha": "Аюулгүй байдлын хяналт",
-       "createacct-imgcaptcha-ph": "Дээр харагдаж буй бичвэрийг оруулна уу",
        "createacct-submit": "Бүртгүүлэх",
        "createacct-another-submit": "Өөр нэгэн хэрэглэгч бүртгэх",
        "createacct-benefit-heading": "{{SITENAME}}-г тан шиг хүмүүс хийж байна.",
        "passwordreset-emailtext-ip": "Хэн нэгэн ($1 гэсэн IP хаягаас) {{SITENAME}} ($4) дээр таны бүртгэлийн сануулга авахаар хүссэн байна. Дараах {{PLURAL:$3|бүртгэл|бүртгэл}}\nуг е-шуудантай холбоотой:\n\n$2\n\n{{PLURAL:$3|Уг түр хэрэглэх нууц үг|Уг түр хэрэглэх нууц үгүүд}} нь {{PLURAL:$5|нэг өдрийн|$5 өдрийн}} дотор устах болно.\nТа уг нууц үгээр нэвтэрч, түүнийг шинэчлэх хэрэгтэй. Хэрэв өөр нэгэн уг хүсэлтийг явуулсан бол \nэсвэл өөрийн ориг нууц үгээ санаж байгаад түүнийгээ өөрчлөхийг хүсэхгүй байгаа бол энэ захиаг үл ойшоож \nэнгийнээр нэвтэрч болно.",
        "passwordreset-emailtext-user": "{{SITENAME}} дээрх $1 хэрэглэгч {{SITENAME}} ($4) дээр өөрийн тань бүртгэл дээр сануулга хүссэн байна. \nДараах {{PLURAL:$3|бүртгэл|бүртгэлүүд}} уг е-шуудантай холбоотой байна:\n\n$2\n\nЭнэ {{PLURAL:$3|түр нууц үг|түр нууц үгс}} {{PLURAL:$5|нэг өдрийн дараа|$5 өдрийн дараа}} устах болно.\nТүүгээр нэвтэрч ороод нууц үгээ шинэчилнэ үү. Энэ сануулгыг өөр хэн нэгэн хийсэн, эсвэл та\nнууц үгээ санаж байгаа бол энэ захиаг анхааралгүйгээр хуучнаараа ороход болно.",
        "passwordreset-emailelement": "Хэрэглэгчийн нэр: \n$1\n\nТүр зуурын нууц үг: \n$2",
-       "passwordreset-emailsent": "Нууц үг солин емайл илгээсэн.",
+       "passwordreset-emailsentemail": "Нууц үг солин емайл илгээсэн.",
        "passwordreset-emailsent-capture": "Доор харагдаж байгаа нь танируу илгээсэн нууц үг ресет хийх емайл.",
        "passwordreset-emailerror-capture": "Доор харагдаж байгаа нууц үг ресет хийх емайл үүссэх боловч {{GENDER:$2|хэрэглэгчид}} илгээхэд алдаа гарлаа : $1",
        "changeemail": "Цахим шуудангийн хаяг солих",
-       "changeemail-text": "Энэ маягтийг бөглөж цахим шуудангийн хаягаа солино уу. Өөрчлөлт хийхийн тулд нууц үгээ оруулна уу.",
+       "changeemail-header": "Цахим шуудангийн бүртгэлийн хаяг солих",
        "changeemail-no-info": "Энэ хуудсыг үзэхэд хэрэглэгчийн нэрээр орсон байх шаардлагатай.",
        "changeemail-oldemail": "Одоогийн цахим шуудан:",
        "changeemail-newemail": "Шинэ цахим шуудангийн хаяг:",
        "prefs-diffs": "Ялгаанууд",
        "prefs-help-prefershttps": "Гараад орох уг тохиргоо идэвхижнэ.",
        "prefs-tabs-navigation-hint": "Зөвлөмж: Баруун зүүн сумаар таб хооронд шилжиж болно.",
-       "email-address-validity-valid": "Цахим шуудан хүчинтэй байна",
-       "email-address-validity-invalid": "и-майл хаягаа зөв оруулна уу.",
        "userrights": "Хэрэглэгчдийн эрхийн удирдлага",
        "userrights-lookup-user": "Хэрэглэгчдийн бүлгүүдийг удирдах",
        "userrights-user-editname": "Хэрэглэгчийн нэрээ оруулна уу:",
        "right-blockemail": "Хэрэглэгчийг мэйл явуулахаас түгжих",
        "right-hideuser": "Хэрэглэгчийн нэрийг түгжиж нийтээс нуух",
        "right-ipblock-exempt": "IP-н түгжээ, автомат түгжээ, бүсийн түгжээг тойрч гарах",
-       "right-proxyunbannable": "Проксинуудын автомат түгжээг тойрч гарах",
        "right-unblockself": "Өөрт хийсэн түгжээг тайлах",
        "right-protect": "Хамгаалалтын түвшингүүдийг өөрчилж хамгаалагдсан хуудсуудыг засварлах",
        "right-editprotected": "Хамгаалагдсан хуудсуудыг \"{{int:protect-level-sysop}}\" хэлбэрээр засварлах",
        "filewasdeleted": "Өмнө нь ийм нэртэй файл оруулагдсан бөгөөд дараа нь устгагдсан байна.\nТа үүнийг дахин оруулахын өмнө $1-г шалгаж үзнэ үү.",
        "filename-bad-prefix": "Таны оруулж байгаа файлын нэр '''\"$1\"'''-р эхэлж байна. Энэ нь файлыг тодорхойлойлоогүй, голдуу дижитал аппаратын автоматаар гаргадаг нэр болно.\nФайланд түүнийг илүү сайн тодорхойлсон нэр өгнө үү.",
        "filename-prefix-blacklist": " #<!-- leave this line exactly as it is --> <pre>\n# Syntax is as follows:\n#   * Everything from a \"#\" character to the end of the line is a comment\n#   * Every non-blank line is a prefix for typical filenames assigned automatically by digital cameras\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # зарим гар утаснууд\nIMG # ерөнхий\nJD # Jenoptik\nMGP # Pentax\nPICT # бусад.\n #</pre> <!-- leave this line exactly as it is -->",
-       "upload-success-subj": "Файлыг амжилттай орууллаа",
-       "upload-success-msg": "[$2]-с амжилттай оруулав. Энд байна: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Оруулах үеийн асуудал",
-       "upload-failure-msg": "[$2]-с оруулахад асуудал үүсчээ:\n\n$1",
-       "upload-warning-subj": "Оруулах үеийн анхааруулга",
-       "upload-warning-msg": "[$2]-с хийсэн оруулалтад асуудал үүсэв. [[Special:Upload/stash/$1|Оруулах талбар]] руу буцаж энэ асуудлыг шийдвэрлэж болно.",
        "upload-proto-error": "Буруу протокол",
        "upload-proto-error-text": "Файл оруулахад хэрэгтэй URL-үүд нь <code>http://</code> эсвэл <code>ftp://</code>-р эхлэсэн байх шаардлагатай.",
        "upload-file-error": "Дотоод алдаа",
        "movenosubpage": "Энэ хуудас нь дэд хуудасгүй.",
        "movereason": "Шалтгаан:",
        "revertmove": "хуучин төлөвт шилжүүлэх",
-       "delete_and_move": "Устгаад зөөх",
        "delete_and_move_text": "==Устгалын шаардав==\nЗорьсон хуудас \"[[:$1]]\"-г нь урьд нь оруулсан байна.\nТа зөөхөд зай гаргахын тулд устгах уу?",
        "delete_and_move_confirm": "Тийм, хуудсыг устга",
        "delete_and_move_reason": "[[$1]] -с зөөхөд зай гаргахын тулд устгагдсан",
        "newimages-summary": "Энэ тусгай хуудсанд хамгийн сүүлд оруулагдсан файлуудыг үзүүлнэ.",
        "newimages-legend": "Шүүлтүүр",
        "newimages-label": "Файлын нэр (эсвэл түүний нэг хэсэг):",
+       "newimages-hidepatrolled": "Шалгасан файлуудыг нуух",
        "noimages": "Харах юмгүй.",
        "ilsubmit": "Хайлт",
        "bydate": "Огноогоор",
        "duration-millennia": "$1 {{PLURAL:$1|мянган|мянган}}",
        "expand_templates_input": "Оруулах бичиг:",
        "expand_templates_output": "Үр дүн",
-       "expand_templates_remove_comments": "Товч агуулгыг авч хаях"
+       "expand_templates_remove_comments": "Товч агуулгыг авч хаях",
+       "pagelanguage": "Хуудасны хэлийг өөрчлөх",
+       "log-name-pagelang": "Хэлний өөрчлөлтийн лог"
 }
index bdc2e67..cad0551 100644 (file)
        "right-blockemail": "Menyekat pengguna lain daripada mengirim e-mel",
        "right-hideuser": "Menyekat sesebuah nama pengguna, menyembunyikannya daripada orang ramai",
        "right-ipblock-exempt": "Melangkau sekatan IP, sekatan automatik dan sekatan julat",
-       "right-proxyunbannable": "Melangkau sekatan proksi automatik",
        "right-unblockself": "Menyahsekat diri sendiri",
        "right-protect": "Mengubah tahap perlindungan serta menyunting halaman yang dilindungi lata",
        "right-editprotected": "Menyunting halaman-halaman yang dilindungi sebagai \"{{int:protect-level-sysop}}\"",
        "uploaded-script-svg": "Terdapat elemen terskrip \"$1\" dalam fail SVG yang dimuat naik.",
        "uploaded-hostile-svg": "Terdapat CSS yang tidak selamat dalam elemen stail fail SVG yang dimuat naik.",
        "uploaded-event-handler-on-svg": "Penetapan atribut <i>event-handler</i> <code>$1=\"$2\"</code> tidak dibenarkan dalam fail SVG.",
-       "uploaded-href-attribute-svg": "Atribut href <code>&lt;$1 $2=\"$3\"&gt;</code> dengan sasaran bukan setempat (cth. http://, javascript:, dsb) tidak dibenarkan dalam fail SVG.",
        "uploaded-href-unsafe-target-svg": "Terdapat href ke sasaran tak selamat <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-animate-svg": "Terdapat teg \"animate\" yang mungkin sedang mengubah href, menggunakan atribut \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "uploaded-setting-event-handler-svg": "Dilarang menetapkan atribut <i>event-handler</i>, terdapat <code>&lt;$1 $2=\"$3\"&gt;</code> dalam fail SVG yang dimuat naik.",
        "filename-thumb-name": "Nampaknya macam tajuk gambar kenit (thumbnail). Tolong jangan muat naik gambar kenit balik ke dalam wiki yang sama. Selain itu, sila betulkan nama fail supaya ia nampak lebih bererti dan tiada awalan gambar kenit.",
        "filename-bad-prefix": "Nama bagi fail yang dimuat naik bermula dengan '''\"$1\"''', yang mana merupakan nama yang tidak deskriptif yang biasanya ditetapkan oleh kamera digital secara automatik. Sila berikan nama yang lebih deskriptif bagi fail tersebut.",
        "filename-prefix-blacklist": " #<!-- biarkan baris ini seperti sediakala --> <pre>\n# Sintaks adalah seperti berikut:\n#   * Segalanya mulai aksara \"#\" hingga akhir baris ialah komen\n#   * Setiap baris bukan kosong ialah awalan bagi nama-nama fail biasa yang ditetapkan secara automatik oleh kamera digital\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # sesetengah telefon bimbit\nIMG # generik\nJD # Jenoptik\nMGP # Pentax\nPICT # dll.\n #</pre> <!-- biarkan baris ini seperti sediakala -->",
-       "upload-success-subj": "Muat naik berjaya",
-       "upload-success-msg": "Muat naik anda dari [$2] berjaya. Ia ada di sini: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Masalah muat naik",
-       "upload-failure-msg": "Terdapat masalah dengan muat naik anda daripada [$2]:\n\n$1",
-       "upload-warning-subj": "Amaran muat naik",
-       "upload-warning-msg": "Terdapat masalah dengan muat naik anda daripada [$2]. Anda boleh kembali ke [[Special:Upload/stash/$1|borang muat naik]] untuk mengatasi masalah ini.",
        "upload-proto-error": "Protokol salah",
        "upload-proto-error-text": "Muat naik jauh memerlukan URL yang dimulakan dengan <code>http://</code> atau <code>ftp://</code>.",
        "upload-file-error": "Ralat dalaman",
        "querypage-disabled": "Laman khas ini dilumpuhkan atas sebab-sebab prestasi.",
        "apihelp": "Bantuan API",
        "apihelp-no-such-module": "Modul \"$1\" tidak dijumpai.",
+       "apisandbox": "Kotak pasir API",
+       "apisandbox-api-disabled": "API dimatikan di tapak web ini.",
+       "apisandbox-intro": "Gunakan laman ini untuk bereksperimen dengan '''API perkhidmatan sesawang MediaWiki'''.\nRujuk [//www.mediawiki.org/wiki/API:Main_page dokumentasi API] untuk keterangan lanjut tentang penggunaan API.\nContoh: [//www.mediawiki.org/wiki/API#A_simple_example dapatkan kandungan Laman Utama].  Pilih satu tindakan untuk melihat banyak lagi contoh.",
+       "apisandbox-submit": "Buat permintaan",
+       "apisandbox-reset": "Padamkan",
+       "apisandbox-examples": "Contoh",
+       "apisandbox-results": "Hasil",
+       "apisandbox-request-url-label": "URL permohonan:",
+       "apisandbox-request-time": "Waktu pemohonan: $1",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari sumber buku",
        "booksources-search": "Cari",
        "wlheader-showupdated": "Laman-laman yang telah diubah sejak kunjungan terakhir anda dipaparkan dalam '''teks tebal'''.",
        "wlnote": "Yang berikut ialah <strong>$1</strong> perubahan terakhir sejak $2 jam yang lalu, sehingga $3, $4.",
        "wlshowlast": "Tunjukkan $2 hari $1 jam yang lalu",
-       "watchlistall2": "semua",
        "watchlist-hide": "Sorok",
        "wlshowtime": "Tempoh masa untuk dipaparkan:",
        "wlshowhideminor": "suntingan kecil",
        "mw-widgets-dateinput-no-date": "Tarik belum dipilih",
        "mw-widgets-titleinput-description-new-page": "laman belum wujud",
        "mw-widgets-titleinput-description-redirect": "melencong ke $1",
-       "api-error-blacklisted": "Sila pilih tajuk yang berbeza dan deskriptif."
+       "api-error-blacklisted": "Sila pilih tajuk yang berbeza dan deskriptif.",
+       "randomrootpage": "Laman akar rawak"
 }
index ba28a76..9bfd0f7 100644 (file)
        "helppage-top-gethelp": "အကူအညီ",
        "mainpage": "ဗဟိုစာမျက်နှာ",
        "mainpage-description": "ဗ​ဟို​စာ​မျက်​နှာ​",
-       "policy-url": "Project:မူ​ဝါ​ဒ",
+       "policy-url": "Project:မူဝါဒ",
        "portal": "ပေါင်းကူးနေရာ",
        "portal-url": "Project:ပေါင်းကူးနေရာ",
        "privacy": "ကိုယ်ပိုင်ရေးရာ မူဝါဒ",
        "password-login-forbidden": "ဤအသုံးပြုသူအမည်နှင့် စကားဝှက်အား အသုံးပြုခြင်းကို တားမြစ်ထားသည်။",
        "mailmypassword": "စကားဝှက်ကို ပြန်ချိန်ရန်",
        "passwordremindertitle": "{{SITENAME}} အတွက် ယာယီစကားဝှက်အသစ်",
+       "passwordremindertext": "တစ်စုံတစ်ယောက် ($1 အိုင်ပီလိပ်စာမှ သင်လည်းဖြစ်နိုင်) သည် {{SITENAME}} ($4) အတွက် စကားဝှက်အသစ်ကို တောင်းဆိုခဲ့သည်။ \nအသုံးပြုသူ \"$2\" အတွက် ယာယီစကားဝှက်အသစ်ကို ဖန်တီးပြီး \"$3\" အဖြစ် သတ်မှတ်လိုက်သည်။ \nဤအရာကို သင်ရည်ရွယ်သည်ဆိုပါက လော့ဂ်အင်ဝင်ရန်ပြီး စကားဝှက်အသစ် ရွေးချယ်ရန် လိုအပ်ပါသည်။ \nသင်၏ ယာယီစကားဝှက်သည် {{PLURAL:$5|တစ်ရက်|$5 ရက်}}အတွင်း သက်တမ်းကုန်ပါလိမ့်မည်။\n\nအကယ်၍ တစ်စုံတစ်ယောက်က ဤတောင်းဆိုမှုကို ပြုလုပ်ခဲ့ပါက၊ သို့မဟုတ် သင်သည် သင့်စကားဝှက်အား မှတ်မိပြီး \nပြောင်းလဲရန် ဆန္ဒမရှိပါ ဤစာလွှာကို မျက်ကွယ်ပြုပြီး စကားဝှက်အဟောင်းဖြင့် ဆက်လက်သုံးစွဲနိုင်ပါသည်။",
        "noemail": "အသုံးပြုသူ \"$1\" အတွက် မည်သည့်အီးမေးလိပ်စာမှ မှတ်သားထားခြင်း မရှိပါ။",
        "noemailcreate": "တရာဝင်အီးမေးလိပ်စာ ပေးရန် လိုအပ်သည်",
        "mailerror": "မေးပို့ခြင်း အမှား - $1",
        "loginreqpagetext": "အခြားစာမျက်နှာများကို ကြည့်ရန် $1ရမည်။",
        "accmailtitle": "စကားဝှက်ကို ပို့ပြီးပြီ",
        "newarticle": "(အသစ်)",
-       "newarticletext": "သင်သည် မရှိသေးသော စာမျက်နှာလင့် ကို ရောက်လာခြင်းဖြစ်သည်။\nစာမျက်နှာအသစ်စတင်ရန် အောက်မှ သေတ္တာထဲတွင် စတင်ရိုက်ထည့်ပါ (နောက်ထပ် သတင်းအချက်အလက်များအတွက်[$1 အကူအညီ စာမျက်နှာ]ကို ကြည့်ပါ)။\nမတော်တဆရောက်လာခြင်း ဖြစ်ပါက ဘရောက်ဆာ၏ နောက်ပြန်ပြန်သွားသော'''back''' ခလုတ်ကို နှိပ်ပါ။",
+       "newarticletext": "သင်သည် မရှိသေးသော စာမျက်နှာလင့် ကို ရောက်လာခြင်းဖြစ်သည်။\nစာမျက်နှာအသစ်စတင်ရန် အောက်မှ သေတ္တာထဲတွင် စတင်ရိုက်ထည့်ပါ (နောက်ထပ် သတင်းအချက်အလက်များအတွက်[$1 အကူအညီ စာမျက်နှာ]ကို ကြည့်ပါ)။\nမတော်တဆရောက်လာခြင်း ဖြစ်ပါက ဘရောက်ဆာ၏ နောက်ပြန်ပြန်သွားသော <strong>back</strong> ခလုတ်ကို နှိပ်ပါ။",
        "noarticletext": "ဤစာမျက်နှာတွင် ယခုလက်ရှိတွင် မည်သည့်စာသားမှ မရှိပါ။\nသင်သည် အခြားစာမျက်နှာများတွင် [[Special:Search/{{PAGENAME}}|ဤစာမျက်နှာ၏ ခေါင်းစဉ်ကို ရှာနိုင်သည်]]၊ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ဆက်စပ်ရာ Logs များကို ရှာနိုင်သည်]၊ သို့မဟုတ် [{{fullurl:{{FULLPAGENAME}}|action=edit}} ဤစာမျက်နှာကို တည်းဖြတ်နိုင်သည်]</span>။",
        "noarticletext-nopermission": "ဤစာမျက်နှာတွင် ယခုလက်ရှိတွင် မည်သည့်စာသားမှ မရှိပါ။\nသင်သည် အခြားစာမျက်နှာများတွင် [[Special:Search/{{PAGENAME}}|ဤစာမျက်နှာ၏ ခေါင်းစဉ်ကို ရှာနိုင်သည်]]၊ သို့မဟုတ် <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ဆက်စပ်ရာ Logs များကို ရှာနိုင်သည်]</span>။ သို့သော် ဤစာမျက်နှာကို ဖန်တီးရန် သင့်တွင် အခွင့်အရေး မရှိပါ။",
        "note": "'''မှတ်ချက် -'''",
        "right-createtalk": "ဆွေးနွေးချက်စာမျက်နှာများ စတင်ရေးသားရန်",
        "right-createaccount": "အသုံးပြုသူအကောင့်အသစ်ကို ဖန်တီးရန်",
        "right-minoredit": "တည်းဖြတ်မှုများကို အရေးမကြီးဟု မှတ်သားရန်",
-       "right-move": "á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ရွှေ့ပြောင်းပါ",
+       "right-move": "á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\99á\80»á\80¬á\80¸á\80\80á\80­á\80¯ ရွှေ့ပြောင်းပါ",
        "right-move-subpages": "စာမျက်နှာများကို ယင်းတို့၏စာမျက်နှာအခွဲတို့နှင့်တကွ ရွှေ့ရန်",
        "right-movefile": "ဖိုင်များရွှေ့ရန်",
        "right-suppressredirect": "စာမျက်နှာများကို ရွှေ့သောအခါ မူရင်းစာမျက်နှာတို့မှ ပြန်ညွှန်းများ မဖန်တီးရန်",
        "right-autoconfirmed": "အိုင်ပီအခြေပြု ကန့်သတ်ချက်များကို အကျိုးမသက်ရောက်ပါ",
        "right-bot": "အလိုအလျောက်ပြုမူသော ဖြစ်စဉ်အဖြစ်ဆောင်ရွက်ရန်",
        "right-writeapi": "ရေးသားမှု API ကို သုံးရန်",
-       "right-delete": "စာမျက်နှာများကိုဖျက်ပါ။",
+       "right-delete": "စာမျက်နှာများကို ဖျက်ပါ",
        "right-bigdelete": "လွန်စွာများပြားသော ရာဇဝင်များရှိသည့် စာမျက်နှာများကို ဖျက်ရန်",
        "right-browsearchive": "ဖျက်ပစ်လိုက်သော စာမျက်နှာများကို ရှာရန်",
        "right-undelete": "စာမျက်နှာတစ်ခုကို မဖျက်တော့ရန်",
        "removedwatchtext": "\"[[:$1]]\" နှင့် ၎င်း၏ ဆွေးနွေးချက်စာမျက်နှာကို သင်၏ [[Special:Watchlist|စောင့်ကြည့်စာရင်း]] မှ ဖယ်ထုတ်ပြီး ဖြစ်သည်။",
        "watch": "စောင့်ကြည့်ရန်",
        "watchthispage": "ဤစာမျက်နှာကို စောင့်ကြည့်ရန်",
-       "unwatch": "á\80\86á\80\80á\80ºá\80\9cá\80\80á\80º á\80\85á\80±á\80¬á\80\84á\80·á\80ºá\80\99á\80\80á\80¼á\80\8aá\80·á\80ºá\80\90á\80±á\80¬á\80·á\80\9bá\80\94်",
+       "unwatch": "á\80\85á\80±á\80¬á\80\84á\80·á\80ºá\80\99á\80\80á\80¼á\80\8aá\80·á\80ºá\80\95á\80«á\80\94á\80¾á\80\84á\80·်",
        "unwatchthispage": "စောင့်ကြည့်ခြင်းကို ရပ်တန့်ရန်",
        "notanarticle": "မာတိကာစာမျက်နှာတစ်ခု မဟုတ်",
        "watchlist-details": "{{PLURAL:$1|စာမျက်နှာ $1 ခု|စာမျက်နှာ $1 ခု}} သည် သင့်စောင့်ကြည့်စာရင်းတွင် ရှိပြီး ဆွေးနွေးချက်စာမျက်နှာများကို ထည့်တွက် မထားပါ။",
        "ipb_already_blocked": "\"$1\" ကို အစကတည်းက ပိတ်ထားသည်",
        "move-page": "$1 ကို ရွှေ့ရန်",
        "move-page-legend": "စာ​မျက်​နှာ​ကို ရွှေ့ပြောင်းရန်",
-       "movepagetext": "á\80¡á\80±á\80¬á\80\80á\80ºá\80\95á\80«á\80\95á\80¯á\80¶á\80\85á\80¶á\80\80á\80­á\80¯ á\80¡á\80\9eá\80¯á\80¶á\80¸á\80\95á\80¼á\80¯á\80\81á\80¼á\80\84á\80ºá\80¸á\80\9eá\80\8aá\80º á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80¡á\80\99á\80\8aá\80ºá\80\95á\80¼á\80±á\80¬á\80\84á\80ºá\80¸á\80\9cá\80²á\80\95á\80±á\80¸á\80\99á\80\8aá\80º á\80\96á\80¼á\80\85á\80ºá\80\95á\80¼á\80®á\80¸ á\80¡á\80\99á\80\8aá\80ºá\80\9eá\80\85á\80ºá\80\9eá\80­á\80¯á\80· á\80\9aá\80\84á\80ºá\80¸á\81\8f á\80\99á\80¾á\80\90á\80ºá\80\90á\80\99á\80ºá\80¸á\80\94á\80¾á\80\84á\80·á\80ºá\80\90á\80\80á\80½ á\80\9bá\80½á\80¾á\80±á\80·á\80\95á\80±á\80¸á\80\99á\80\8aá\80º á\80\96á\80¼á\80\85á\80ºá\80\9eá\80\8aá\80ºá\81\8b\ná\80¡á\80\99á\80\8aá\80ºá\80\9fá\80±á\80¬á\80\84á\80ºá\80¸á\80\9eá\80\8aá\80º á\80¡á\80\99á\80\8aá\80ºá\80\9eá\80\85á\80ºá\80\9eá\80­á\80¯á\80· á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬ á\80\96á\80¼á\80\85á\80ºá\80\9cá\80¬á\80\99á\80\8aá\80ºá\81\8b\ná\80\9eá\80\84á\80ºá\80\9eá\80\8aá\80º á\80\99á\80°á\80\9cá\80\81á\80±á\80«á\80\84á\80ºá\80¸á\80\85á\80\89á\80ºá\80\9eá\80­á\80¯á\80· á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\99á\80»á\80¬á\80¸á\80\80á\80­á\80¯ á\80¡á\80\9cá\80­á\80¯á\80¡á\80\9cá\80»á\80±á\80¬á\80\80á\80º á\80¡á\80\95á\80ºá\80\92á\80­á\80\90á\80º update á\80\9cá\80¯á\80\95á\80ºá\80\94á\80­á\80¯á\80\84á\80ºá\80\9eá\80\8aá\80ºá\81\8b\ná\80¡á\80\80á\80\9aá\80ºá\81\8d á\80\99á\80\95á\80¼á\80¯á\80\9cá\80¯á\80\95á\80ºá\80\9cá\80­á\80¯á\80\95á\80«á\80\80 [[Special:DoubleRedirects|á\80\94á\80¾á\80\85á\80ºá\80\81á\80«á\80\91á\80\95á\80º]][[Special:BrokenRedirects|á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸ á\80¡á\80\95á\80»á\80\80á\80ºá\80\99á\80»á\80¬á\80¸]] á\80\80á\80­á\80¯ á\80\99á\80¾á\80\90á\80ºá\80\9eá\80¬á\80¸á\80\9bá\80\94á\80º á\80\99á\80\99á\80±á\80·á\80\95á\80«á\80\94á\80¾á\80\84á\80·á\80ºá\81\8b\ná\80\9cá\80\84á\80·á\80ºá\80\99á\80»á\80¬á\80¸ á\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\9cá\80­á\80¯á\80\9eá\80\8aá\80·á\80º á\80\94á\80±á\80\9bá\80¬á\80\9eá\80­á\80¯á\80· á\80\8aá\80½á\80¾á\80\94á\80ºá\80\95á\80¼á\80\94á\80±á\80\9bá\80\94á\80º á\80\9eá\80\84á\80·á\80ºá\80\90á\80½á\80\84á\80º á\80\90á\80¬á\80\9dá\80\94á\80º á\80\9bá\80¾á\80­á\80\9eá\80\8aá\80ºá\81\8b\n\ná\80¡á\80\80á\80\9aá\80ºá\81\8d á\80\81á\80±á\80«á\80\84á\80ºá\80¸á\80\85á\80\89á\80ºá\80¡á\80\9eá\80\85á\80ºá\80\90á\80½á\80\84á\80º á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\9bá\80¾á\80­á\80\94á\80¾á\80\84á\80·á\80ºá\80\95á\80¼á\80®á\80¸ á\80\96á\80¼á\80\85á\80ºá\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\9aá\80\84á\80ºá\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\9eá\80\8aá\80º á\80¡á\80\9cá\80½á\80\90á\80ºá\80\99á\80\96á\80¼á\80\85á\80ºá\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\99á\80\9bá\80¾á\80­á\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\9aá\80\81á\80\84á\80ºá\80\80 á\80\95á\80¼á\80¯á\80\95á\80¼á\80\84á\80ºá\80\91á\80¬á\80¸á\80\9eá\80±á\80¬ á\80\99á\80¾á\80\90á\80ºá\80\90á\80\99á\80ºá\80¸ á\80\99á\80\9bá\80¾á\80­á\80\95á\80«á\80\80 á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\9eá\80\8aá\80º <strong>á\80\9bá\80½á\80±á\80·á\80\99á\80\8aá\80ºá\80\99á\80\9fá\80¯á\80\90á\80º</strong> á\80\9eá\80\8aá\80ºá\80\80á\80­á\80¯ á\80\9eá\80\90á\80­á\80\95á\80¼á\80¯á\80\95á\80«á\81\8b \ná\80\86á\80­á\80¯á\80\9cá\80­á\80¯á\80\9eá\80\8aá\80ºá\80\99á\80¾á\80¬ á\80\9eá\80\84á\80ºá\80\9eá\80\8aá\80º á\80¡á\80\99á\80¾á\80¬á\80¸á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\95á\80¼á\80¯á\80\9cá\80¯á\80\95á\80ºá\80\99á\80­á\80\95á\80«á\80\80 á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80\9aá\80\81á\80\84á\80ºá\80¡á\80\99á\80\8aá\80ºá\80\80á\80­á\80¯ á\80\95á\80¼á\80\94á\80ºá\80\9cá\80\8aá\80º á\80\95á\80¼á\80±á\80¬á\80\84á\80ºá\80¸á\80\9cá\80²á\80\95á\80±á\80¸á\80\94á\80­á\80¯á\80\84á\80ºá\80\9eá\80\8aá\80ºá\81\8b á\80\9bá\80¾á\80­á\80\95á\80¼á\80®á\80\9eá\80¬á\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\90á\80\85á\80ºá\80\81á\80¯á\80\80á\80­á\80¯ á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬ á\80¡á\80\9eá\80\85á\80ºá\80\94á\80¾á\80\84á\80·á\80º á\80\95á\80¼á\80\94á\80ºá\80¡á\80¯á\80\95á\80º overwrite á\80\81á\80¼á\80\84á\80ºá\80¸ á\80\99á\80\95á\80¼á\80¯á\80\94á\80­á\80¯á\80\84á\80ºá\81\8b\n\n<strong>á\80\9eá\80\90á\80­á\80\95á\80±á\80¸á\80\81á\80»á\80\80á\80º!</strong>\nဤသည်မှာ လူဖတ်များသော စာမျက်နှာတစ်ခုဖြစ်ပါက မမျှော်လင့်ထားသော၊ ကြီးမားသော အပြောင်းအလဲတစ်ခု ဖြစ်ပေါ်လာနိုင်သည်။\nထို့ကြောင့် ဆက်လက် မဆောင်ရွက်မီ သင်သည် နောက်ဆက်တွဲ အကျိုးဆက်များကို နားလည်ကြောင်း ကျေးဇူးပြု၍ သေချာပါစေ။",
+       "movepagetext": "á\80¡á\80±á\80¬á\80\80á\80ºá\80\95á\80«á\80\95á\80¯á\80¶á\80\85á\80¶á\80\80á\80­á\80¯ á\80¡á\80\9eá\80¯á\80¶á\80¸á\80\95á\80¼á\80¯á\80\81á\80¼á\80\84á\80ºá\80¸á\80\9eá\80\8aá\80º á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80¡á\80\99á\80\8aá\80ºá\80\95á\80¼á\80±á\80¬á\80\84á\80ºá\80¸á\80\9cá\80²á\80\95á\80±á\80¸á\80\99á\80\8aá\80º á\80\96á\80¼á\80\85á\80ºá\80\95á\80¼á\80®á\80¸ á\80¡á\80\99á\80\8aá\80ºá\80\9eá\80\85á\80ºá\80\9eá\80­á\80¯á\80· á\80\9aá\80\84á\80ºá\80¸á\81\8f á\80\99á\80¾á\80\90á\80ºá\80\90á\80\99á\80ºá\80¸á\80\94á\80¾á\80\84á\80·á\80ºá\80\90á\80\80á\80½ á\80\9bá\80½á\80¾á\80±á\80·á\80\95á\80±á\80¸á\80\99á\80\8aá\80º á\80\96á\80¼á\80\85á\80ºá\80\9eá\80\8aá\80ºá\81\8b\ná\80¡á\80\99á\80\8aá\80ºá\80\9fá\80±á\80¬á\80\84á\80ºá\80¸á\80\9eá\80\8aá\80º á\80¡á\80\99á\80\8aá\80ºá\80\9eá\80\85á\80ºá\80\9eá\80­á\80¯á\80· á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬ á\80\96á\80¼á\80\85á\80ºá\80\9cá\80¬á\80\99á\80\8aá\80ºá\81\8b\ná\80\9eá\80\84á\80ºá\80\9eá\80\8aá\80º á\80\99á\80°á\80\9cá\80\81á\80±á\80«á\80\84á\80ºá\80¸á\80\85á\80\89á\80ºá\80\9eá\80­á\80¯á\80· á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\99á\80»á\80¬á\80¸á\80\80á\80­á\80¯ á\80¡á\80\9cá\80­á\80¯á\80¡á\80\9cá\80»á\80±á\80¬á\80\80á\80º á\80¡á\80\95á\80ºá\80\92á\80­á\80\90á\80º update á\80\9cá\80¯á\80\95á\80ºá\80\94á\80­á\80¯á\80\84á\80ºá\80\9eá\80\8aá\80ºá\81\8b\ná\80¡á\80\80á\80\9aá\80ºá\81\8d á\80\99á\80\95á\80¼á\80¯á\80\9cá\80¯á\80\95á\80ºá\80\9cá\80­á\80¯á\80\95á\80«á\80\80 [[Special:DoubleRedirects|á\80\94á\80¾á\80\85á\80ºá\80\81á\80«á\80\91á\80\95á\80º]][[Special:BrokenRedirects|á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸ á\80¡á\80\95á\80»á\80\80á\80ºá\80\99á\80»á\80¬á\80¸]] á\80\80á\80­á\80¯ á\80\99á\80¾á\80\90á\80ºá\80\9eá\80¬á\80¸á\80\9bá\80\94á\80º á\80\99á\80\99á\80±á\80·á\80\95á\80«á\80\94á\80¾á\80\84á\80·á\80ºá\81\8b\ná\80\9cá\80\84á\80·á\80ºá\80\99á\80»á\80¬á\80¸ á\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\9cá\80­á\80¯á\80\9eá\80\8aá\80·á\80º á\80\94á\80±á\80\9bá\80¬á\80\9eá\80­á\80¯á\80· á\80\8aá\80½á\80¾á\80\94á\80ºá\80\95á\80¼á\80\94á\80±á\80\9bá\80\94á\80º á\80\9eá\80\84á\80·á\80ºá\80\90á\80½á\80\84á\80º á\80\90á\80¬á\80\9dá\80\94á\80º á\80\9bá\80¾á\80­á\80\9eá\80\8aá\80ºá\81\8b\n\ná\80¡á\80\80á\80\9aá\80ºá\81\8d á\80\81á\80±á\80«á\80\84á\80ºá\80¸á\80\85á\80\89á\80ºá\80¡á\80\9eá\80\85á\80ºá\80\90á\80½á\80\84á\80º á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\9bá\80¾á\80­á\80\94á\80¾á\80\84á\80·á\80ºá\80\95á\80¼á\80®á\80¸ á\80\96á\80¼á\80\85á\80ºá\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\9aá\80\84á\80ºá\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\9eá\80\8aá\80º á\80¡á\80\9cá\80½á\80\90á\80ºá\80\99á\80\96á\80¼á\80\85á\80ºá\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\99á\80\9bá\80¾á\80­á\80\95á\80«á\80\80 (á\80\9eá\80­á\80¯á\80·) á\80\9aá\80\81á\80\84á\80ºá\80\80 á\80\95á\80¼á\80¯á\80\95á\80¼á\80\84á\80ºá\80\91á\80¬á\80¸á\80\9eá\80±á\80¬ á\80\99á\80¾á\80\90á\80ºá\80\90á\80\99á\80ºá\80¸ á\80\99á\80\9bá\80¾á\80­á\80\95á\80«á\80\80 á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\9eá\80\8aá\80º <strong>á\80\9bá\80½á\80±á\80·á\80\99á\80\8aá\80ºá\80\99á\80\9fá\80¯á\80\90á\80º</strong> á\80\9eá\80\8aá\80ºá\80\80á\80­á\80¯ á\80\9eá\80\90á\80­á\80\95á\80¼á\80¯á\80\95á\80«á\81\8b \ná\80\86á\80­á\80¯á\80\9cá\80­á\80¯á\80\9eá\80\8aá\80ºá\80\99á\80¾á\80¬ á\80\9eá\80\84á\80ºá\80\9eá\80\8aá\80º á\80¡á\80\99á\80¾á\80¬á\80¸á\80\90á\80\85á\80ºá\80\81á\80¯ á\80\95á\80¼á\80¯á\80\9cá\80¯á\80\95á\80ºá\80\99á\80­á\80\95á\80«á\80\80 á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80\9aá\80\81á\80\84á\80ºá\80¡á\80\99á\80\8aá\80ºá\80\80á\80­á\80¯ á\80\95á\80¼á\80\94á\80ºá\80\9cá\80\8aá\80º á\80\95á\80¼á\80±á\80¬á\80\84á\80ºá\80¸á\80\9cá\80²á\80\95á\80±á\80¸á\80\94á\80­á\80¯á\80\84á\80ºá\80\9eá\80\8aá\80ºá\81\8b á\80\9bá\80¾á\80­á\80\95á\80¼á\80®á\80\9eá\80¬á\80¸á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\90á\80\85á\80ºá\80\81á\80¯á\80\80á\80­á\80¯ á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬ á\80¡á\80\9eá\80\85á\80ºá\80\94á\80¾á\80\84á\80·á\80º á\80\95á\80¼á\80\94á\80ºá\80¡á\80¯á\80\95á\80º overwrite á\80\81á\80¼á\80\84á\80ºá\80¸ á\80\99á\80\95á\80¼á\80¯á\80\94á\80­á\80¯á\80\84á\80ºá\81\8b\n\n<strong>á\80\99á\80¾á\80\90á\80ºá\80\81á\80»á\80\80á\80ºá\81\8b</strong>\nဤသည်မှာ လူဖတ်များသော စာမျက်နှာတစ်ခုဖြစ်ပါက မမျှော်လင့်ထားသော၊ ကြီးမားသော အပြောင်းအလဲတစ်ခု ဖြစ်ပေါ်လာနိုင်သည်။\nထို့ကြောင့် ဆက်လက် မဆောင်ရွက်မီ သင်သည် နောက်ဆက်တွဲ အကျိုးဆက်များကို နားလည်ကြောင်း ကျေးဇူးပြု၍ သေချာပါစေ။",
        "movepagetalktext": "ဤအကွက်ကို အမှန်ခြစ်လိုက်ခြင်းဖြင့် ဗလာမဟုတ်သော ဆွေးနွေးချက်စာမျက်နှာသည် ရှိနှင့်ပြီး မဟုတ်လျှင် ဆက်နွယ်နေသော ဆွေးနွေးချက် စာမျက်နှာကို ခေါင်းစဉ်အသစ်သို့  အလိုအလျောက် ရွှေ့ပစ်မည် ဖြစ်သည်။\n\nဤကိစ္စရပ်တွင် သင် ဆန္ဒရှိလျှင် စာမျက်နှာကို မိမိကိုယ်တိုင် သွားရောက်ရွှေ့ပြောင်း ပေါင်းစပ်နိုင်သည်။",
        "newtitle": "ခေါင်းစဉ်အသစ်:",
        "move-watch": "မူရင်းစာမျက်နှာနှင့် ဦးတည်ထားသော စာမျက်နှာတို့ကို စောင့်ကြည့်ရန်",
index a38d0b3..c37fdd5 100644 (file)
        "uploaded-script-svg": "Truvato n'elemento pe script \"$1\" int' 'o file SVG carrecato.",
        "uploaded-hostile-svg": "Truvato nu CSS insecuro int'a l'elemente 'e stile d' 'o file SVG carrecate.",
        "uploaded-event-handler-on-svg": "Mpustà 'e parametre 'e gistore-evente <code>$1=\"$2\"</code> nun è premmesso dint' 'e file SVG.",
-       "uploaded-href-attribute-svg": "Ll'attribbute href <code>&lt;$1 $2=\"$3\"&gt;</code> cu target non-local (e.g. http://, javascript:, ecc) nun so' premmesse int' 'e file SVG.",
-       "uploaded-href-unsafe-target-svg": "S'è truvato nu href a nu target ca nun era sicuro <code>&lt;$1 $2=\"$3\"&gt;</code> dint' 'o file SVG carrecato.",
+       "uploaded-href-attribute-svg": "ll'attribbute href dint' 'e file SVG songo premmesse sulamente mmerz'a na destinaziona http:// o https:// , ca se truvasse <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "S'è truvato nu href a nu target 'e date: URI ca nun era sicuro <code>&lt;$1 $2=\"$3\"&gt;</code> dint' 'o file SVG carrecato.",
        "uploaded-animate-svg": "Truvato 'o tag \"animate\" ca putesse stà a cagnà href, ausanno l'attribbuto \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file carrecato SVG.",
        "uploaded-setting-event-handler-svg": "Mpustà n'attributo event-handler è bluccato, truvato <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o fie carrecato SVG.",
        "uploaded-setting-href-svg": "Ausà 'o tag \"set\" pe' putè azzeccà attribbute \"href\" a l'elemento parente è bluccato.",
        "upload-too-many-redirects": "L'URL teneva troppe redirect",
        "upload-http-error": "N'errore HTTP è succiesso: $1",
        "upload-copy-upload-invalid-domain": "Nun è permessa 'a carreca 'e copie 'a chistu dumminio.",
+       "upload-foreign-cant-upload": "Stu wiki nun è mpustato pe' puté carrecà 'e file dint' 'o repository 'e file 'e fore addimannato.",
        "upload-dialog-title": "Carreca file",
        "upload-dialog-button-cancel": "Canciella",
        "upload-dialog-button-done": "Fatto",
        "querypage-disabled": "Sta paggena speciale è stutata pe' mutive 'e prestaziune.",
        "apihelp": "Ajuto cu l'API",
        "apihelp-no-such-module": "'O modulo \"$1\" nun se trova.",
+       "apisandbox": "Casciulella 'e pprove API",
+       "apisandbox-jsonly": "'O JavaScript è necessario pe' puté ausà 'a casciulella 'e pprove 'e ll'API.",
+       "apisandbox-api-disabled": "Ll'API è stutata ind'a stu sito.",
+       "apisandbox-intro": "Aùsa sta paggena pe' puté ffà prove c' 'o  <strong>servizio web 'e ll'API MediaWiki</strong>.\nVedite e ve piglià riferimento ncopp' 'a [[mw:API:Main page|documentazione 'e ll'API]] pe' n'avé cchiù dettaglie 'e comm'ausà n'API. Esempio: [//www.mediawiki.org/wiki/API#A_simple_example piglia 'e ccuntenute 'e na Paggena Prencepale]. Sceglie n'aziona pe' n'avé cchiù dettaglie.\n\nTenite a mmente ca, pure si chest'è na casciulella 'e pprove, ll'aziune ca vuje facite putessero cagnà sta wiki.",
+       "apisandbox-fullscreen": "Spanne pannello",
+       "apisandbox-fullscreen-tooltip": "Spanne 'o pannello 'e casciulella 'e pprove pe' puté ghienchere tuttaquanta 'a fenestella d' 'o navigatóre.",
+       "apisandbox-unfullscreen": "Mmusta paggena",
+       "apisandbox-unfullscreen-tooltip": "Reduce 'o pannello sandbox, accussì facenno ch' 'e cullegamente 'e navigazione 'e MediaWiki fossero a disposizione.",
+       "apisandbox-submit": "Fà 'na richiesta",
+       "apisandbox-reset": "Pulezza",
+       "apisandbox-retry": "Riprova",
+       "apisandbox-loading": "Carreca 'e nfurmaziune p' 'o modulo API \"$1\"...",
+       "apisandbox-load-error": "Se scassaje coccosa pe' tramente ca se carrecava nfurmazione p' 'o modulo API \"$1\": $2",
+       "apisandbox-no-parameters": "Stu modulo API nun tene parametre.",
+       "apisandbox-helpurls": "Cullegamente â guida",
+       "apisandbox-examples": "Esempio",
+       "apisandbox-dynamic-parameters": "Parametre addiziunale",
+       "apisandbox-dynamic-parameters-add-label": "Azzecca nu parametro:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nomme d' 'o parametro",
+       "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
+       "apisandbox-deprecated-parameters": "Parametre mò obsoleti",
+       "apisandbox-fetch-token": "Auto-ghienche 'o token",
+       "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
+       "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
+       "apisandbox-results": "Rezurtate",
+       "apisandbox-sending-request": "Mannanno na richiesta 'API..",
+       "apisandbox-loading-results": "Ricezione d' 'e risultate 'e ll'API 'ncurzo...",
+       "apisandbox-results-error": "N'errore cumparette pe' tramente ca se steva carrecanno na risposta 'e query API: $1.",
+       "apisandbox-request-url-label": "URL addimannata:",
+       "apisandbox-request-time": "Tiempo addimannato: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Curregge 'e token e manna n'ata vota",
+       "apisandbox-results-fixtoken-fail": "Scassaje a se piglià 'o token \"$1\".",
+       "apisandbox-alert-page": "'E campe int'a sta paggene nun so' valide.",
+       "apisandbox-alert-field": "'O valore int'a stu campo nun è valido.",
        "booksources": "Funte libbrarie",
        "booksources-search-legend": "Ascìa 'e fonte ncopp' 'e libbre",
        "booksources-search": "Ascìa",
        "lockedbyandtime": "(pe' {{GENDER:$1|$1}} 'o $2 a 'e $3)",
        "move-page": "Mòve $1",
        "move-page-legend": "Mòve paggena",
-       "movepagetext": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. Putite agghiurnà 'e redirect ca puntassero ô titolo origgenale automaticamente.\nSi chesto nun facite, state sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già. <strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
-       "movepagetext-noredirectfixer": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. State sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già. <strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
+       "movepagetext": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. Putite agghiurnà 'e redirect ca puntassero ô titolo origgenale automaticamente.\nSi chesto nun facite, state sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già.\n<strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
+       "movepagetext-noredirectfixer": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. State sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già. \n<strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
        "movepagetalktext": "Si vuje facite click a sta casciulella, 'a paggena 'e chiacchiera suoccia a chesta sarrà spustata automaticamente addò 'o titolo nuovo, si nun è ca na paggena abbacante 'e chiacchiera esiste mo' mo' llàn\n\nInd' 'a stu caso, 'a paggena nun se muoverrà, ma 'a putite sempe scagnà manualmente si vulite.",
        "moveuserpage-warning": "<strong>Attenziò:</strong> Vuje state a muovere na paggena utente. Vedite bbuono ca sulamente 'a paggena sarrà spustata e l'utente <em>nun</em> sarrà reanummenato.",
        "movecategorypage-warning": "<strong>Attenziò:</strong> Vuje state a muovere na categurìa. Vedite bbuono ca sulamente 'a paggena sarrà spustata e 'a categurìa viecchia <em>nun</em> sarrà cagnata â nnova.",
        "movenosubpage": "Sta paggena nun tene sottopaggene.",
        "movereason": "Raggióne",
        "revertmove": "arrepiglia",
-       "delete_and_move_text": "== Scancellamiento richiesto ==\n'A paggena 'e destinazione \"[[:$1]]\" esiste già.\n'A vulite scancellà pe' ne putè ffà 'o spazio abbacante necessario?",
+       "delete_and_move_text": "'A paggena 'e destinazione \"[[:$1]]\" esiste già.\n'A vulite scancellà pe' ne putè ffà 'o spazio abbacante necessario?",
        "delete_and_move_confirm": "Sì, suprascrivi 'a paggena asistente",
        "delete_and_move_reason": "Scancellata pe ne fà spazio abbacante e putè spustà 'a \"[[$1]]\"",
        "selfmove": "'O titolo 'e sorgente e destinazione songh' 'e stesse;\nnun se può muovere na paggena ncopp' 'a essa stessa.",
        "move-leave-redirect": "Lassa nu ridirezionamiento arreto",
        "protectedpagemovewarning": "<strong>Attenziò:</strong> sta paggena è stata prutetta 'n modo tale ca sulamente l'utente ch' 'e privilegge d'ammenistratore 'a ponno muovere.\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe' n'avé riferimento:",
        "semiprotectedpagemovewarning": "'''Nota:''' Sta paggena è prutetta 'n modo ca sulamente l'utente riggistrate 'a ponno mòvere.\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe n'avé nfurmazione:",
-       "move-over-sharedrepo": "== 'O file esiste ==\n[[:$1]] esiste ncopp'a l'archivio spartuto. Spustanno 'o file ncopp'a stu titolo sovrascreverrà 'o file spartuto.",
+       "move-over-sharedrepo": "[[:$1]] esiste ncopp'a l'archivio spartuto. Spustanno 'o file ncopp'a stu titolo sovrascreverrà 'o file spartuto.",
        "file-exists-sharedrepo": "'O nomme d' 'o file c'avite scigliuto se sta ausanno dint'a l'archivio spartuto.\nPe' piacere, scigliete n'atu nomme.",
        "export": "Spurta 'e ppaggene",
        "exporttext": "Vuje putite espurtà 'e teste e cagnà 'a cronologgia 'e na paggena particulare o n'inzieme 'e paggena ca stessero dint' 'a cocche XML.\nChisto po' essere 'mpurtato int'a n'ata wiki ausanno [[Special:Import|mporta pàggene]] 'e MediaWiki.\n\nPe' spurtà paggene, mettite 'o titolo dint' 'e casciulelle ccà abbascio, nu titolo pe' linea e sciglite si vulite 'a verziona 'e mò cu tutt' 'e verziun' 'assieme, o pùre sulamente 'a verziona 'e mò c' 'a nfurmaziona ncopp' 'a ll'urdemo cagnamiento.\n\nComme urtema possibbiletà, putite pure ausà nu cullegamento, p'esempio [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] p' 'a pàggena \"[[{{MediaWiki:Mainpage}}]]\".",
        "lastmodifiedatby": "Sta paggena è stata cagnata l'urdema vota 'e $2, d' 'o $1 da $3.",
        "othercontribs": "Basata ncopp' 'a fatica 'e $1.",
        "others": "ate",
-       "siteusers": "{{PLURAL:$2|utente|utente}} 'e {{SITENAME}} $1",
+       "siteusers": "{{PLURAL:$2|{{GENDER:$1|utente}}|utente}} 'e {{SITENAME}} $1",
        "anonusers": "{{PLURAL:$2|utente|utente}} anonime 'e {{SITENAME}} $1",
        "creditspage": "Auture d' 'a paggena",
        "nocredits": "Nun ce stanno nfurmaziune ncopp'a l'auture 'e sta paggena.",
        "expand_templates_preview_fail_html": "<em>Siccomme {{SITENAME}} téne 'o HTML 'ncruro appicciato e se songhe spierze 'e date d' 'a sessiona, 'a previsualizzaziona s'è annascunnuta comm'a na prutezione annanz'e uerre 'e JavaScript.</em>\n\n<strong>Si chist'è nu tentativo giustificato 'e previsualizzaziona, pe' piacere facite n'ata vota.</strong>\nSi nun funziona ancora, facite d'[[Special:UserLogout|ascì]] e trasì n'ata vota.",
        "expand_templates_preview_fail_html_anon": "<em>Siccomme {{SITENAME}} téne 'o HTML 'ncruro e vuje nun site trasute 'o sito, 'a previsualizzaziona s'è annascunnuta comm'a na prutezione annanz'e uerre 'e JavaScript.</em>\n\n<strong>Si chist'è nu tentativo giustificato 'e previsualizzaziona, pe' piacere facite d'[[Special:UserLogout|ascì]] e trasì n'ata vota.</strong>",
        "expand_templates_input_missing": "Avita dà minimo nu poco 'e testo scritto.",
-       "pagelanguage": "Scigliete 'a lengua d' 'a paggena pe' bbìa e stu strumiento",
+       "pagelanguage": "Cagna 'o nomme d' 'a paggena",
        "pagelang-name": "Paggena",
        "pagelang-language": "Lengua",
        "pagelang-use-default": "Aùsa 'a lengua predefinita",
        "pagelang-submit": "Manna",
        "right-pagelang": "Cagnate 'a lengua d' 'a paggena",
        "action-pagelang": "càgna 'a lengua d' 'a paggena",
-       "log-name-pagelang": "Càgna 'o riggistro 'e llengue",
+       "log-name-pagelang": "Cagna 'o riggistro d' 'a lengua",
        "log-description-pagelang": "Chest'è nu riggistro 'e cagnamiente 'e lengua d' 'e paggene.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ave cagnato}} 'a lengua d' 'a paggena $3 'a $4 a $5.",
        "default-skin-not-found": "Oops! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe' n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o scegliere chilla predefinita.\n\n$2\n\n; Si avite installato MediaWiki mò mò:\n: Probabbilmente l'avite installato 'a git, o direttamente 'a 'o codece sorgente ausanno cocch'atu metodo. Chesto era permesso. Verite 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse fornito ch' 'e diverze skin ed estenziune. Putite fare copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mò mò:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mò mò <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà cocch'errore 'e battitura.",
index 86971d1..8c2b0ef 100644 (file)
        "passwordreset-emailtext-ip": "Noen (sannsynligvis deg fra IP-adressen $1) ba om en tilbakestilling av ditt passord for {{SITENAME}} ($4). {{PLURAL:$3|Den følgende brukerkontoen|De følgende brukerkontoene}} er\ntilknyttet denne e-postadressen:\n\n$2\n\n{{PLURAL:$3|Dette midlertidige passordet|Disse midlertidige passordene}} utløper om {{PLURAL:$5|én dag|$5 dager}}.\nDu bør logge på og velge et nytt passord nå. Dersom noen andre kom med denne\nforespørselen, eller du har kommet på ditt opprinnelige passord, og ikke lenger\nønsker å endre det, kan du ignorere denne meldingen og fortsette å bruke ditt gamle\npassord.",
        "passwordreset-emailtext-user": "Brukeren $1 på {{SITENAME}} ba om en tilbakestilling av passordet ditt for {{SITENAME}}\n($4). {{PLURAL:$3|Den følgende brukerkontoen|De følgende brukerkontoene}} er tilknyttet denne e-postadressen:\n\n$2\n\n{{PLURAL:$3|Dette midlertidige passordet|Disse midlertidige passordene}} utløper om {{én dag|$5 dager}}.\nDu bør logge på og velge et nytt passord nå. Dersom noen andre kom med denne\nforespørselen, eller du har kommet på ditt opprinnelige passord, og ikke lenger\nønsker å endre det, kan du ignorere denne meldingen og fortsette å bruke ditt gamle\npassord.",
        "passwordreset-emailelement": "Brukernavn: \n$1\n\nMidlertidig passord: \n$2",
-       "passwordreset-emailsentemail": "Hvis dette er en registrert epostadresse for din konto, vil det bli sendt ut en passordtilbakestillingsepost.",
+       "passwordreset-emailsentemail": "Hvis denne epostadressen er koblet til din konto, så vil det bli sendt en epost om tilbakestilling av passord.",
        "passwordreset-emailsentusername": "Hvis det finnes en epostadresse knyttet til dette brukernavnet, vil en epost med informasjon om tilbakestilling av passord bli sendt.",
        "passwordreset-emailsent-capture": "Passordtilbakestillingseposten vist under har blitt sendt ut.",
        "passwordreset-emailerror-capture": "En passordtilbakestillingsepost ble laget, men det lyktes ikke å sende denne til {{GENDER:$2|brukeren}}: $1",
        "number_of_watching_users_pageview": "[$1 overvåkende {{PLURAL:$1|bruker|brukere}}]",
        "rc_categories": "Begrens til kategorier (skilletegn: «|»)",
        "rc_categories_any": "Alle",
-       "rc-change-size-new": "$1 {{PLURAL:$1|byte}} etter endring",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} etter endring",
        "newsectionsummary": "/* $1 */ ny seksjon",
        "rc-enhanced-expand": "Vis detaljer",
        "rc-enhanced-hide": "Skjul detaljer",
        "querypage-disabled": "Denne spesialsiden er deaktivert av ytelsesårsaker.",
        "apihelp": "API hjelp",
        "apihelp-no-such-module": "Modulen «$1» ikke funnet.",
+       "apisandbox": "API-sandkasse",
+       "apisandbox-api-disabled": "API er deaktivert på dette nettstedet.",
+       "apisandbox-intro": "Bruk denne siden for å eksperimentere med '''MediaWiki web service APIet'''.\nSjekk [//www.mediawiki.org/wiki/API:Main_page API-dokumentasjonen] for mer informasjon om bruk av APIet. Eksempel: [//www.mediawiki.org/wiki/API#A_simple_example hente innholdet til en hovedside]. Velg en handling for å se flere eksempler.\n\nMerk at du kan utføre handlinger her som fører til endringer på wikien.",
+       "apisandbox-submit": "Foreta en forespørsel",
+       "apisandbox-reset": "Tilbakestill",
+       "apisandbox-examples": "Eksempel",
+       "apisandbox-results": "Resultat",
+       "apisandbox-request-url-label": "Forespurt URL:",
+       "apisandbox-request-time": "Forespørselstid: $1",
        "booksources": "Bokkilder",
        "booksources-search-legend": "Søk etter bokkilder",
        "booksources-search": "Søk",
        "javascripttest-pagetext-frameworks": "Vennligst velg en av følgende testerammeverk: $1",
        "javascripttest-pagetext-skins": "Velg et utseende for testene:",
        "javascripttest-qunit-intro": "Se [$1 testedokumentasjonen] på mediawiki.org.",
-       "tooltip-pt-userpage": "Din brukerside",
+       "tooltip-pt-userpage": "{{GENDER:|Din brukerside}}",
        "tooltip-pt-anonuserpage": "Brukersiden for IP-adressen du redigerer fra",
-       "tooltip-pt-mytalk": "Din diskusjonsside",
+       "tooltip-pt-mytalk": "{{GENDER:|Din}} diskusjonsside",
        "tooltip-pt-anontalk": "Diskusjon om redigeringer fra denne IP-adressen",
-       "tooltip-pt-preferences": "Dine innstillinger",
+       "tooltip-pt-preferences": "{{GENDER:|Dine}} innstillinger",
        "tooltip-pt-watchlist": "Liste over sider du overvåker for endringer.",
-       "tooltip-pt-mycontris": "Liste over dine bidrag",
+       "tooltip-pt-mycontris": "En liste over {{GENDER:|dine}} bidrag",
        "tooltip-pt-anoncontribs": "En liste over redigeringer gjort fra denne IP-adressen",
        "tooltip-pt-login": "Du oppfordres til å logge inn, men det er ikke obligatorisk",
        "tooltip-pt-logout": "Logg ut",
        "tooltip-t-recentchangeslinked": "Siste endringer i sider som blir lenket fra denne siden",
        "tooltip-feed-rss": "RSS-mating for denne siden",
        "tooltip-feed-atom": "Atom-mating for denne siden",
-       "tooltip-t-contributions": "Vis liste over bidrag fra denne brukeren",
+       "tooltip-t-contributions": "En liste over bidrag fra {{GENDER:$1|denne brukeren}}",
        "tooltip-t-emailuser": "Send en e-post til denne brukeren",
        "tooltip-t-info": "Mer informasjon om denne siden",
        "tooltip-t-upload": "Last opp filer",
index 5b5e3a5..6152a32 100644 (file)
        "tog-shownumberswatching": "Het aantal gebruikers weergeven dat deze pagina volgt",
        "tog-oldsig": "Bestaande ondertekening:",
        "tog-fancysig": "Handtekening als wikitekst behandelen (zonder automatische koppeling)",
-       "tog-uselivepreview": "Live voorvertoning gebruiken",
+       "tog-uselivepreview": "Livevoorvertoning gebruiken",
        "tog-forceeditsummary": "Een melding geven bij een lege bewerkingssamenvatting",
        "tog-watchlisthideown": "Eigen bewerkingen op mijn volglijst verbergen",
        "tog-watchlisthidebots": "Botbewerkingen op mijn volglijst verbergen",
        "databaseerror-query": "Zoekopdracht: $1",
        "databaseerror-function": "Functie: $1",
        "databaseerror-error": "Fout: $1",
-       "transaction-duration-limit-exceeded": "Deze transactie ($1) werd afgebroken omdat de {{PLURAL:$2|seconde|seconden}} limiet werd bereikt. Hiermee worden grote achterstanden bij het repliceren voorkomen. \nWanneer u meerdere items tegelijk bewerkt, probeer het dan in meerdere kleinere opdrachten te doen.",
+       "transaction-duration-limit-exceeded": "Deze transactie ($1) is afgebroken omdat de limiet van $2 {{PLURAL:$2|seconde|seconden}} is bereikt. Hiermee worden grote achterstanden bij het repliceren voorkomen. \nWanneer u meerdere items tegelijk bewerkt, probeer het dan in meerdere kleinere opdrachten te doen.",
        "laggedslavemode": "<strong>Waarschuwing:</strong> in deze pagina zijn recente wijzigingen mogelijk nog niet verwerkt.",
        "readonly": "Database geblokkeerd",
        "enterlockreason": "Geef een reden op voor de blokkade en geef op wanneer die waarschijnlijk wordt opgeheven",
        "missingarticle-rev": "(versienummer: $1)",
        "missingarticle-diff": "(Wijziging: $1, $2)",
        "readonly_lag": "De database is automatisch vergrendeld terwijl de ondergeschikte databaseservers synchroniseren met de hoofdserver.",
-       "nonwrite-api-promise-error": "De 'Promise-Non-Write-API-Action' HTTP header was meegestuurd, maar het verzoek behelsde een API-schrijfverzoek.",
+       "nonwrite-api-promise-error": "De HTTP-header 'Promise-Non-Write-API-Action' was meegestuurd, maar het verzoek behelsde een API-schrijfverzoek.",
        "internalerror": "Interne fout",
        "internalerror_info": "Interne fout: $1",
        "internalerror-fatal-exception": "Fatale fout van type \"$1\"",
        "virus-scanfailed": "scannen is mislukt (code $1)",
        "virus-unknownscanner": "onbekend antivirusprogramma:",
        "logouttext": "<strong>U bent nu afgemeld.</strong>\n\nSommige pagina's kunnen blijven weergegeven alsof u nog aangemeld bent, totdat u uw browsercache leegt.",
-       "cannotlogoutnow-title": "Niet mogelijk om nu uit te loggen",
-       "cannotlogoutnow-text": "Uitloggen is niet mogelijk bij het gebruik van $1.",
+       "cannotlogoutnow-title": "Niet mogelijk om nu af te melden",
+       "cannotlogoutnow-text": "Afmelden is niet mogelijk bij het gebruik van $1.",
        "welcomeuser": "Welkom, $1!",
        "welcomecreation-msg": "Uw account is aangemaakt.\nIndien gewenst kunt u uw [[Special:Preferences|voorkeuren]] voor {{SITENAME}} aanpassen.",
        "yourname": "Gebruikersnaam:",
        "remembermypassword": "Aanmeldgegevens onthouden (maximaal $1 {{PLURAL:$1|dag|dagen}})",
        "userlogin-remembermypassword": "Aangemeld blijven",
        "userlogin-signwithsecure": "Beveiligde verbinding gebruiken",
-       "cannotloginnow-title": "Niet mogelijk om nu in te loggen",
-       "cannotloginnow-text": "Inloggen is niet mogelijk bij het gebruik van $1.",
+       "cannotloginnow-title": "Niet mogelijk om aan te melden",
+       "cannotloginnow-text": "Aanmelden is niet mogelijk bij het gebruik van $1.",
        "yourdomainname": "Uw domein:",
        "password-change-forbidden": "U kunt uw wachtwoord niet wijzigen in deze wiki.",
        "externaldberror": "Er is een fout opgetreden bij het aanmelden bij de database of u hebt geen toestemming uw externe gebruiker bij te werken.",
        "changepassword-success": "Uw wachtwoord is gewijzigd.",
        "changepassword-throttled": "U heeft recentelijk te veel mislukte aanmeldpogingen gedaan.\nWacht alstublieft $1 voordat u het opnieuw probeert.",
        "botpasswords": "Botwachtwoorden",
+       "botpasswords-summary": "<em>Botwachtwoorden</em> zorgen voor toegang tot de API via een gebruikersaccount zonder gebruik te maken van de aanmeldgegevens van dat account. De gebruikersrechten die beschikbaar zijn kunnen afwijken indien er aangemeld is met een botwachtwoord.\n\nAls u niet weet wat de gevolgen hiervan zijn, is het handiger om dit ook dan niet te doen. Niemand hoort u te vragen om een botwachtwoord aan te maken en deze vervolgens aan hem of haar te geven.",
        "botpasswords-disabled": "Botwachtwoorden zijn uitgeschakeld.",
        "botpasswords-no-central-id": "Om botwachtwoorden te gebruiken, moet u ingelogd zijn met een gecentraliseerd account",
        "botpasswords-existing": "Bestaande botwachtwoorden",
        "botpasswords-updated-body": "Het botwachtwoord \"$1\" is succesvol bijgewerkt.",
        "botpasswords-deleted-title": "Botwachtwoord verwijderd",
        "botpasswords-deleted-body": "Het botwachtwoord \"$1\" is verwijderd.",
-       "botpasswords-newpassword": "Het nieuwe wachtwoord om in te loggen met <strong>$1</strong> is nu <strong>$2</strong>. <em>Bewaar dit goed voor toekomstig gebruik.</em>",
+       "botpasswords-newpassword": "Het nieuwe wachtwoord om aan te melden met <strong>$1</strong> is nu <strong>$2</strong>. <em>Bewaar dit goed voor toekomstig gebruik.</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider is niet beschikbaar.",
-       "botpasswords-restriction-failed": "Botwachtwoord-beperkingen maken het aanmelden onmogelijk.",
+       "botpasswords-restriction-failed": "Botwachtwoordbeperkingen maken het aanmelden onmogelijk.",
        "botpasswords-invalid-name": "De gebruikersnaam mag niet het scheidingsteken van het botwachtwoord (\"$1\") bevatten.",
        "botpasswords-not-exist": "Gebruiker \"$1\" heeft geen botwachtwoord genaamd \"$2\"",
        "resetpass_forbidden": "Wachtwoorden kunnen niet gewijzigd worden",
        "accmailtext": "Een willekeurig gegenereerd wachtwoord voor [[User talk:$1|$1]] is verzonden naar $2. Het kan worden gewijzigd op de pagina \"[[Special:ChangePassword|wachtwoord wijzigen]]\" na het aanmelden.",
        "newarticle": "(Nieuw)",
        "newarticletext": "Deze pagina bestaat niet.\nTyp in het onderstaande veld om de pagina aan te maken (meer informatie staat op de [$1 hulppagina]).\nGebruik de knop <strong>Terug</strong> in uw browser als u hier per ongeluk terecht bent gekomen.",
-       "anontalkpagetext": "----''Deze overlegpagina hoort bij een anonieme gebruiker die geen gebruikersnaam heeft of deze niet gebruikt.\nDaarom wordt het IP-adres ter identificatie gebruikt.\nHet is mogelijk dat meerdere personen hetzelfde IP-adres gebruiken.\nMogelijk ontvangt u hier berichten die niet voor u bedoeld zijn.\nAls u dat wilt voorkomen, [[Special:UserLogin/signup|registreer u]] of [[Special:UserLogin|meld u aan]] om verwarring met andere anonieme gebruikers te voorkomen.''",
+       "anontalkpagetext": "----\n<em>Deze overlegpagina hoort bij een anonieme gebruiker die geen gebruikersnaam heeft of deze niet gebruikt.</em>\nDaarom wordt het IP-adres ter identificatie gebruikt.\nHet is mogelijk dat meerdere personen hetzelfde IP-adres gebruiken.\nMogelijk ontvangt u hier berichten die niet voor u bedoeld zijn.\nAls u dat wilt voorkomen, [[Special:UserLogin/signup|registreer u]] of [[Special:UserLogin|meld u aan]] om verwarring met andere anonieme gebruikers te voorkomen.",
        "noarticletext": "Deze pagina bevat geen tekst.\nU kunt [[Special:Search/{{PAGENAME}}|naar deze term zoeken]] in andere pagina's, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} de logboeken doorzoeken] of [{{fullurl:{{FULLPAGENAME}}|action=edit}} deze pagina bewerken]</span>.",
        "noarticletext-nopermission": "Deze pagina bevat geen tekst.\nU kunt [[Special:Search/{{PAGENAME}}|naar deze term zoeken]] in andere pagina's of\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} de logboeken doorzoeken]</span>, maar u mag de pagina niet aanmaken.",
        "missing-revision": "De versie #$1 van de pagina \"{{FULLPAGENAME}}\" bestaat niet.\n\nDit wordt meestal veroorzaakt door het volgen van een verouderde koppeling naar een pagina die is verwijderd.\nMeer gegevens zijn mogelijk te vinden in het [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} verwijderingslogboek].",
        "prefs-info": "Basisinformatie",
        "prefs-i18n": "Taalinstellingen",
        "prefs-signature": "Ondertekening",
-       "prefs-dateformat": "Datumopmaak:",
+       "prefs-dateformat": "Datumopmaak",
        "prefs-timeoffset": "Tijdverschil",
        "prefs-advancedediting": "Algemene instellingen",
        "prefs-editor": "Tekstverwerker",
        "userrights": "Gebruikersrechtenbeheer",
        "userrights-lookup-user": "Gebruikersgroepen beheren",
        "userrights-user-editname": "Voer een gebruikersnaam in:",
-       "editusergroup": "{{GENDER:$1|Gebruiker}}sgroepen wijzigen",
+       "editusergroup": "{{GENDER:$1|Gebruikersgroepen}} wijzigen",
        "editinguser": "Bezig met wijzigen van de gebruikersrechten van gebruiker '''[[User:$1|$1]]''' $2",
        "userrights-editusergroup": "Gebruikersgroepen wijzigen",
-       "saveusergroups": "{{GENDER:$1|Gebruiker}}sgroepen opslaan",
+       "saveusergroups": "{{GENDER:$1|Gebruikersgroepen}} opslaan",
        "userrights-groupsmember": "Lid van:",
        "userrights-groupsmember-auto": "Impliciet lid van:",
        "userrights-groups-help": "U kunt de groepen wijzigen waar deze gebruiker lid van is.\n* Een aangekruist vakje betekent dat de gebruiker lid is van de groep.\n* Een niet aangekruist vakje betekent dat de gebruiker geen lid is van de groep.\n* Een \"*\" betekent dat u een gebruiker niet uit een groep kunt verwijderen nadat u die hebt toegevoegd of vice versa.",
        "right-createpage": "Pagina's aanmaken",
        "right-createtalk": "Overlegpagina's aanmaken",
        "right-createaccount": "Nieuwe gebruikers aanmaken",
-       "right-autocreateaccount": "Automatisch inloggen met een extern gebruikersaccount",
+       "right-autocreateaccount": "Automatisch aanmelden met een extern gebruikersaccount",
        "right-minoredit": "Bewerkingen als klein markeren",
        "right-move": "Pagina's hernoemen",
        "right-move-subpages": "Pagina's inclusief subpagina's verplaatsen",
        "grant-group-administration": "Beheerdershandelingen uitvoeren",
        "grant-group-other": "Diverse handelingen",
        "grant-blockusers": "Gebruikers (de)blokkeren",
-       "grant-createaccount": "Gebruikers aanmaken",
+       "grant-createaccount": "Accounts aanmaken",
        "grant-createeditmovepage": "Pagina's aanmaken, bewerken en hernoemen",
-       "grant-delete": "Pagina's, wijzigingen en vermeldingen in het logboek verwijderen",
+       "grant-delete": "Pagina's, wijzigingen en logboekregels verwijderen",
        "grant-editinterface": "De naamruimte MediaWiki en CSS en JavaScript van gebruikers bewerken",
-       "grant-editmycssjs": "Uw eigen CSS/JavaScript bewerken",
+       "grant-editmycssjs": "Eigen CSS en JavaScript bewerken",
        "grant-editmyoptions": "Eigen voorkeuren instellen",
-       "grant-editmywatchlist": "Uw eigen volglijst bewerken",
+       "grant-editmywatchlist": "Eigen volglijst bewerken",
        "grant-editpage": "Bestaande pagina's bewerken",
        "grant-editprotected": "Beveiligde pagina's bewerken",
        "grant-highvolume": "Veel bewerkingen in korte tijd maken",
        "grant-uploadfile": "Nieuwe bestanden uploaden",
        "grant-basic": "Basisrechten",
        "grant-viewdeleted": "Verwijderde bestanden en pagina's bekijken",
-       "grant-viewmywatchlist": "Uw volglijst bekijken",
+       "grant-viewmywatchlist": "Eigen volglijst bekijken",
        "newuserlogpage": "Logboek nieuwe gebruikers",
        "newuserlogpagetext": "Hieronder staan de nieuw ingeschreven gebruikers",
        "rightslog": "Gebruikersrechtenlogboek",
        "uploaded-script-svg": "Scriptbaar element \"$1\" in het geüploade SVG-bestand gevonden.",
        "uploaded-hostile-svg": "Onveilige CSS in het \"style\"-element van het geüploade SVG-bestand gevonden.",
        "uploaded-event-handler-on-svg": "Het instellen van de event-handlereigenschappen <code>$1=\"$2\"</code> is niet toegestaan in SVG-bestanden.",
-       "uploaded-href-attribute-svg": "href-eigenschappen <code>&lt;$1 $2=\"$3\"&gt;</code> met niet-lokaal doel (bijvoorbeeld http://, javascript:, enz.) zijn niet toegestaan in SVG-bestanden.",
        "uploaded-href-unsafe-target-svg": "href met onveilig doel <code>&lt;$1 $2=\"$3\"&gt;</code> in het geüploade SVG-bestand gevonden.",
        "uploaded-animate-svg": "\"animate\"-label gevonden in het geüploade svg-bestand die href zou kunnen veranderen, met behulp van het \"from\"-attribuut <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Het instellen van de event-handlereigenschappen is geblokkeerd, <code>&lt;$1 $2=\"$3\"&gt;</code> gevonden in het geüploade SVG-bestand.",
        "querypage-disabled": "Deze speciale pagina is uitgeschakeld om performanceredenen.",
        "apihelp": "API-hulp",
        "apihelp-no-such-module": "Module \"$1\" niet gevonden.",
+       "apisandbox": "API-zandbak",
+       "apisandbox-api-disabled": "De API is uitgeschakeld op deze site.",
+       "apisandbox-intro": "Gebruik deze pagina om te experimenteren met de '''MediaWiki-API'''.\nZie de [//www.mediawiki.org/wiki/API:Main_page API-documentatie] voor verdere details over het gebruik van de API. Voorbeeld: [//www.mediawiki.org/wiki/API#A_simple_example hoe de inhoud van een Hoofdpagina ophalen]. Selecteer een handeling om meer voorbeelden te zien.\n\nHoewel dit een testfunctie is, kunnen sommige handelingen toch wijzigingen in de wiki maken.",
+       "apisandbox-submit": "Verzoek uitvoeren",
+       "apisandbox-reset": "Wissen",
+       "apisandbox-examples": "Voorbeeld",
+       "apisandbox-results": "Resultaten",
+       "apisandbox-request-url-label": "Verzoek-URL:",
+       "apisandbox-request-time": "Doorlooptijd verzoek: $1",
        "booksources": "Boekinformatie",
        "booksources-search-legend": "Bronnen en gegevens over een boek zoeken",
        "booksources-search": "Zoeken",
        "wlshowlast": "Laatste $1 uur, $2 dagen bekijken",
        "watchlist-hide": "Verbergen",
        "watchlist-submit": "Weergeven",
-       "wlshowtime": "Periode om te weergeven:",
+       "wlshowtime": "Weer te geven periode:",
        "wlshowhideminor": "kleine bewerkingen",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "geregistreerde gebruikers",
        "lockedbyandtime": "(door $1 om $3 op $2)",
        "move-page": "\"$1\" hernoemen",
        "move-page-legend": "Pagina hernoemen",
-       "movepagetext": "Door middel van het onderstaande formulier kunt u een pagina hernoemen.\nDe geschiedenis gaat mee naar de nieuwe pagina.\n* De oude naam wordt automatisch een doorverwijzing naar de nieuwe pagina.\n* Koppelingen naar de oude pagina worden niet aangepast.\n* De pagina's die doorverwijzen naar de oorspronkelijke paginanaam worden automatisch bijgewerkt.\nAls u dit niet wenst, controleer dan of er geen [[Special:DoubleRedirects|dubbele]] of [[Special:BrokenRedirects|onjuiste doorverwijzingen]] zijn ontstaan.\n\nEen pagina kan '''alleen''' hernoemd worden als de nieuwe paginanaam niet bestaat of een doorverwijspagina zonder verdere geschiedenis is.\n\n'''Waarschuwing!'''\nVoor veel bekeken pagina's kan het hernoemen drastische en onvoorziene gevolgen hebben.\nZorg ervoor dat u die gevolgen overziet voordat u deze handeling uitvoert.",
-       "movepagetext-noredirectfixer": "Door middel van het onderstaande formulier kunt u een pagina en alle bijbehorende oude versies hernoemen.\nDe oude naam wordt automatisch een doorverwijzing naar de nieuwe pagina.\nControleer dan of er geen [[Special:DoubleRedirects|dubbele]] of [[Special:BrokenRedirects|onjuiste doorverwijzingen]] zijn ontstaan.\n\nEen pagina kan '''alleen''' hernoemd worden als de nieuwe paginanaam niet bestaat of een doorverwijspagina zonder verdere geschiedenis is.\nU kunt dus een pagina die per ongeluk is hernoemd terug hernoemen en u kunt een bestaande pagina niet overschrijven. \n\n'''Waarschuwing!'''\nVoor veel bekeken pagina's kan het hernoemen drastische en onvoorziene gevolgen hebben.\nZorg ervoor dat u die gevolgen overziet voordat u deze handeling uitvoert.",
+       "movepagetext": "Door middel van het onderstaande formulier kunt u een pagina hernoemen.\nDe geschiedenis gaat mee naar de nieuwe pagina.\n* De oude naam wordt automatisch een doorverwijzing naar de nieuwe pagina.\n* Koppelingen naar de oude pagina worden niet aangepast.\n* De pagina's die doorverwijzen naar de oorspronkelijke paginanaam worden automatisch bijgewerkt.\nAls u dit niet wenst, controleer dan of er geen [[Special:DoubleRedirects|dubbele]] of [[Special:BrokenRedirects|onjuiste doorverwijzingen]] zijn ontstaan.\n\nEen pagina kan <strong>alleen</strong> hernoemd worden als de nieuwe paginanaam niet bestaat of een doorverwijspagina zonder verdere geschiedenis is.\n\n<strong>Opmerking:</strong>\nVoor veel bekeken pagina's kan het hernoemen drastische en onvoorziene gevolgen hebben.\nZorg ervoor dat u die gevolgen overziet voordat u deze handeling uitvoert.",
+       "movepagetext-noredirectfixer": "Door middel van het onderstaande formulier kunt u een pagina en alle bijbehorende oude versies hernoemen.\nDe oude naam wordt automatisch een doorverwijzing naar de nieuwe pagina.\nControleer dan of er geen [[Special:DoubleRedirects|dubbele]] of [[Special:BrokenRedirects|onjuiste doorverwijzingen]] zijn ontstaan.\n\nEen pagina kan <strong>alleen</strong> hernoemd worden als de nieuwe paginanaam niet bestaat of een doorverwijspagina zonder verdere geschiedenis is.\nU kunt dus een pagina die per ongeluk is hernoemd terug hernoemen en u kunt een bestaande pagina niet overschrijven. \n\n<strong>Opmerking:</strong>\nVoor veel bekeken pagina's kan het hernoemen drastische en onvoorziene gevolgen hebben.\nZorg ervoor dat u die gevolgen overziet voordat u deze handeling uitvoert.",
        "movepagetalktext": "Als u het onderstaande vinkje selecteert, krijgt de bijbehorende overlegpagina automatisch een andere naam, tenzij de overlegpagina onder de nieuwe naam al bestaat.\n\nIn dit geval moet u de pagina handmatig hernoemen of samenvoegen.",
        "moveuserpage-warning": "'''Waarschuwing:''' u gaat een gebruikerspagina hernoemen. Houd er rekening mee dat alleen de pagina wordt hernoemd, ''niet'' de gebruiker.",
        "movecategorypage-warning": "<strong>Waarschuwing:</strong> U staat op het punt een categoriepagina te hernoemen. Houdt u er rekening mee dat alleen de categoriepagina zelf hernoemd wordt; pagina's in de oude categorie worden <em>niet</em> automatisch naar de nieuwe verplaatst.",
        "version-libraries-license": "Licentie",
        "version-libraries-description": "Beschrijving",
        "version-libraries-authors": "Auteurs",
-       "redirect": "Doorverwijzen op bestandsnaam, gebruikers-, pagina-, versie- of lognummer",
+       "redirect": "Doorverwijzen op bestandsnaam, gebruikers-, pagina-, versie- of logboekregelnummer",
        "redirect-legend": "Doorverwijzen naar een bestand of pagina",
-       "redirect-summary": "Deze speciale pagina verwijst door naar een bestand (als een bestandsnaam wordt opgegeven), een pagina (als een paginanummer of versienummer wordt opgegeven) of een gebruikerspagina (als een gebruikersnummer wordt opgegeven). Gebruik: [[{{#Special:Redirect}}/file/Voorbeeld.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] of [[{{#Special:Redirect}}/user/101]].",
+       "redirect-summary": "Deze speciale pagina verwijst door naar een bestand (als een bestandsnaam wordt opgegeven), een pagina (als een paginanummer of versienummer wordt opgegeven), een gebruikerspagina (als een gebruikersnummer wordt opgegeven) of een logboekregel (als een logboekregel-ID wordt opgegeven). Gebruik: [[{{#Special:Redirect}}/file/Voorbeeld.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] of [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "OK",
        "redirect-lookup": "Opzoeken:",
        "redirect-value": "Waarde:",
        "redirect-page": "Pagina-ID",
        "redirect-revision": "Paginaversie",
        "redirect-file": "Bestandsnaam",
-       "redirect-logid": "ID opslaan",
+       "redirect-logid": "Logboekregel-ID",
        "redirect-not-exists": "Waarde niet gevonden",
        "fileduplicatesearch": "Duplicaatbestanden zoeken",
        "fileduplicatesearch-summary": "Duplicaatbestanden zoeken op basis van de hashwaarde.",
        "logentry-suppress-block": "$1 {{GENDER:$2|heeft}} {{GENDER:$4|$3}} geblokkeerd voor de duur van $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|heeft}} de blokkade voor {{GENDER:$4|$3}} aangepast. Deze vervalt nu op $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|heeft}} $3 geïmporteerd via een bestandsupload",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|heeft}} $3 door middel van een bestandsupload geïmporteerd ($4 {{PLURAL:$4|versie|versies}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|heeft}} $3 geïmporteerd vanuit een andere wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|heeft}} $3 uit $5 geïmporteerd ($4 {{PLURAL:$4|versie|versies}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|heeft}} $3 samengevoegd naar $4 (versies tot en met $5)",
        "logentry-move-move": "$1 {{GENDER:$2|heeft}} pagina $3 hernoemd naar $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|heeft}} de pagina $3 hernoemd naar $4 zonder een doorverwijzing achter te laten",
        "pagelang-language": "Taal",
        "pagelang-use-default": "Standaard taal gebruiken",
        "pagelang-select-lang": "Taal selecteren",
-       "pagelang-submit": "Verzenden",
+       "pagelang-submit": "Opslaan",
        "right-pagelang": "Paginataal wijzigen",
        "action-pagelang": "paginataal te wijzigen",
        "log-name-pagelang": "Logboek taalwijzigingen",
        "mw-widgets-titleinput-description-new-page": "pagina bestaat nog niet",
        "mw-widgets-titleinput-description-redirect": "doorverwijzing naar $1",
        "api-error-blacklisted": "Kies een andere, beschrijvende naam.",
+       "sessionmanager-tie": "Het is niet mogelijk om meerdere authenticatietypen voor verzoeken te combineren: $1.",
        "sessionprovider-generic": "$1 sessies",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessies gebaseerd op cookies",
        "sessionprovider-nocookies": "Cookies kunnen uitgeschakeld zijn. Zorg ervoor dat u cookies hebt ingeschakeld en probeer het opnieuw.",
index d214eec..90330a5 100644 (file)
        "recentchanges-label-plusminus": "Storleiken til sida vart endra med så mange byte",
        "recentchanges-legend-heading": "'''Tyding:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (sjå dessutan [[Special:NewPages|lista over nye sider]])",
+       "recentchanges-submit": "Vis",
        "rcnotefrom": "Nedanfor er endringane gjorde sidan <strong>$2</strong> viste (opp til <strong>$1</strong> stykke)",
        "rclistfrom": "Vis nye endringar sidan $3 $2",
        "rcshowhideminor": "$1 småplukk",
        "rcshowhidemine": "$1 endringane mine",
        "rcshowhidemine-show": "Vis",
        "rcshowhidemine-hide": "Gøym",
+       "rcshowhidecategorization-show": "Vis",
        "rclinks": "Vis dei siste $1 endringane dei siste $2 dagane<br />$3",
        "diff": "skil",
        "hist": "hist",
        "mostrevisions": "Sidene med flest endringar",
        "prefixindex": "Alle sider med forstaving",
        "prefixindex-namespace": "Alle sider med førefeste ($1-namnerommet)",
+       "prefixindex-submit": "Vis",
        "prefixindex-strip": "Fjern førefestet i lista",
        "shortpages": "Korte sider",
        "longpages": "Lange sider",
        "usereditcount": "{{PLURAL:$1|éi endring|$1 endringar}}",
        "usercreated": "{{GENDER:$3|Oppretta}} den $1 $2",
        "newpages": "Nye sider",
+       "newpages-submit": "Vis",
        "newpages-username": "Brukarnamn:",
        "ancientpages": "Eldste sider",
        "move": "Flytt",
        "pager-older-n": "{{PLURAL:$1|eldre|eldre $1}}",
        "suppress": "Historikkfjerning",
        "querypage-disabled": "Spesialsida er slegen av for skuld yting.",
+       "apisandbox": "API-sandkasse",
+       "apisandbox-api-disabled": "API er slege av på nettstaden.",
+       "apisandbox-intro": "Nytt sida til å røyna ut '''MediaWiki web service API''-en.\nSjå [//www.mediawiki.org/wiki/API:Main_page API-dokumentasjonen] for meir informasjon om bruk av API-en. Døme: [//www.mediawiki.org/wiki/API#A_simple_example hent innhaldet til ei hovudside].\nVel ei handling for å sjå fleire døme.",
+       "apisandbox-submit": "Gjer førespurnad",
+       "apisandbox-reset": "Tøm",
+       "apisandbox-examples": "Døme",
+       "apisandbox-results": "Utfall",
+       "apisandbox-request-url-label": "Førespurd URL:",
+       "apisandbox-request-time": "Førespurnadstid: $1",
        "booksources": "Bokkjelder",
        "booksources-search-legend": "Søk etter bokkjelder",
        "booksources-search": "Søk",
        "specialloguserlabel": "Utøvar:",
        "speciallogtitlelabel": "Mål (tittel eller brukar):",
        "log": "Loggar",
+       "logeventslist-submit": "Vis",
        "all-logs-page": "Alle offentlege loggar",
        "alllogstext": "Kombinert vising av alle loggane på {{SITENAME}}. Du kan avgrense resultatet ved å velje loggtype, brukarnamn eller den sida som er påverka (hugs å skilje mellom store og små bokstavar)",
        "logempty": "Ingen element i loggen passar.",
        "cachedspecial-viewing-cached-ts": "Du ser på ein mellomlagra versjon av sida, som ikkje tarv vera heilt oppdatert.",
        "cachedspecial-refresh-now": "Sjå siste.",
        "categories": "Kategoriar",
+       "categories-submit": "Vis",
        "categoriespagetext": "Følgjande {{PLURAL:$1|category contains|kategoriar inneheld}} sider eller media.\n[[Special:UnusedCategories|Unytta kategoriar]] vert ikkje vist her.\nSjå òg [[Special:WantedCategories|ønska kategoriar]].",
        "categoriesfrom": "Vis kategoriar frå og med:",
        "special-categories-sort-count": "sorter etter storleik",
        "wlshowhideanons": "anonyme brukarar",
        "wlshowhidepatr": "patruljerte endringar",
        "wlshowhidemine": "mine endringar",
+       "wlshowhidecategorization": "kategorisering av sider",
        "watchlist-options": "Alternativ for overvakingslista",
        "watching": "Overvakar...",
        "unwatching": "Fjernar frå overvakinglista...",
        "delete-confirm": "Slett «$1»",
        "delete-legend": "Slett",
        "historywarning": "'''Åtvaring:''' Sida du held på å slette har ein historikk med om lag $1 {{PLURAL:$1|versjon|versjonar}}:",
+       "historyaction-submit": "Vis",
        "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 gjere dette, at du skjønar konsekvensane, og at du gjer dette i tråd med [[{{MediaWiki:Policy-url}}|retningslinene]].",
        "actioncomplete": "Ferdig",
        "actionfailed": "Handlinga kunne ikkje verta utførd",
        "contributions": "{{GENDER:$1|Brukarbidrag}}",
        "contributions-title": "Bidrag av $1",
        "mycontris": "Bidrag",
+       "anoncontribs": "Bidrag",
        "contribsub2": "For {{GENDER:$3|$1}} ($2)",
        "nocontribs": "Det vart ikkje funne nokon endringar gjorde av denne brukaren.",
        "uctop": "(gjeldande)",
        "javascripttest-pagetext-frameworks": "Vel eitt av dei fylgjande utrøyningsrammeverka: $1",
        "javascripttest-pagetext-skins": "Vel ei drakt som utrøyningane skal køyrast med:",
        "javascripttest-qunit-intro": "Sjå [$1 utrøyningsdokumentasjon] på mediawiki.org.",
-       "tooltip-pt-userpage": "Brukarsida di",
+       "tooltip-pt-userpage": "{{GENDER:|Brukarsida}} di",
        "tooltip-pt-anonuserpage": "Brukarsida for ip-adressa du endrar under",
-       "tooltip-pt-mytalk": "Diskusjonssida di",
+       "tooltip-pt-mytalk": "{{GENDER:|Diskusjonssida}} di",
        "tooltip-pt-anontalk": "Diskusjon om endringar gjorde av denne ip-adressa",
-       "tooltip-pt-preferences": "Innstillingane dine",
+       "tooltip-pt-preferences": "{{GENDER:|Innstillingane}} dine",
        "tooltip-pt-watchlist": "Liste over sidene du overvakar.",
-       "tooltip-pt-mycontris": "Liste over bidraga dine",
+       "tooltip-pt-mycontris": "{{GENDER:|Liste}} over bidraga dine",
        "tooltip-pt-login": "Det er ikkje obligatorisk å logga inn, men medfører mange fordelar.",
        "tooltip-pt-logout": "Logg ut",
        "tooltip-pt-createaccount": "Me oppfordrar til at du oppretter ein konto og loggar inn, men det er ikkje påkravd.",
        "tooltip-ca-talk": "Diskusjon om innhaldssida",
-       "tooltip-ca-edit": "Du kan endre denne sida. Bruk førehandsvisings-knappen før du lagrar.",
+       "tooltip-ca-edit": "Endre denne sida",
        "tooltip-ca-addsection": "Start ein ny bolk",
        "tooltip-ca-viewsource": "Denne sida er verna, men du kan sjå kjeldeteksten.",
        "tooltip-ca-history": "Eldre versjonar av sida",
        "tooltip-t-recentchangeslinked": "Nylege endringar på sider denne sida lenkjar til",
        "tooltip-feed-rss": "RSS-mating for denne sida",
        "tooltip-feed-atom": "Atom-mating for denne sida",
-       "tooltip-t-contributions": "Sjå liste over bidrag frå denne brukaren",
+       "tooltip-t-contributions": "Sjå liste over bidrag frå {{GENDER:$1|denne brukaren}}",
        "tooltip-t-emailuser": "Send ein e-post til denne brukaren",
        "tooltip-t-info": "Meir informasjon om sida",
        "tooltip-t-upload": "Last opp filer",
        "spam_reverting": "Attenderullar til siste versjon utan lenkje til $1",
        "spam_blanking": "Alle versjonar inneheldt lenkje til $1, tømmer sida",
        "spam_deleting": "Alle versjonane inneheldt lenkjer til $1, slettar.",
-       "simpleantispam-label": "Antispam-kontroll.\n<strong>IKKJE</strong> fyll ut dette feltet!",
+       "simpleantispam-label": "Antispam-kontroll.\n<strong>ikkje</strong> fyll ut dette feltet!",
        "pageinfo-title": "Informasjon om «$1»",
        "pageinfo-not-current": "Diverre er det umogeleg å gje ut denne informasjonen for gamle versjonar.",
        "pageinfo-header-basic": "Grunnleggjande informasjon",
        "logentry-newusers-create2": "Brukarkontoen $3 vart {{GENDER:$2|oppretta}} av $1",
        "logentry-newusers-byemail": "Brukarkontoen $3 vart {{GENDER:$2|oppretta}} av $1 og passord vart sendt med e-post",
        "logentry-newusers-autocreate": "Brukarkontoen $1 vart {{GENDER:$2|oppretta}} av seg sjølv",
+       "logentry-protect-protect": "$1 {{GENDER:$2|verna}} $3 $4",
        "logentry-rights-rights": "$1 {{GENDER:$2|endra}} gruppemedlemskap for $3 frå $4 til $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|endra}} gruppemedlemskap for $3",
        "logentry-rights-autopromote": "$1 vart automatisk {{GENDER:$2|forfremja}} frå $4 til $5",
        "special-characters-group-gujarati": "Gujarati",
        "mw-widgets-dateinput-placeholder-day": "ÅÅÅÅ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
+       "mw-widgets-titleinput-description-new-page": "sida finst ikkje enno",
+       "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "api-error-blacklisted": "Vel eit anna namn som er meir skildrande.",
        "randomrootpage": "Tilfeldig rotsida"
 }
index df9c0d3..c1b8b59 100644 (file)
@@ -20,7 +20,7 @@
        "tog-underline": "ଲିଙ୍କତଳେଗାର ଟାଣିବା:",
        "tog-hideminor": "ନିକଟରେ ହୋଇଥିବା ଛୋଟ ବଦଳସବୁକୁ ଲୁଚାଇବେ",
        "tog-hidepatrolled": "ନଗଦ ବଦଳରେ ନିରିକ୍ଷଣ କରାଯାଇଥିବା ବଦଳ ସବୁକୁ ଲୁଚାଇବେ",
-       "tog-newpageshidepatrolled": "ନà­\82à¬\86 à¬ªà­\83ଷà­\8dଠାତାଲିà¬\95ାରà­\81 à¬\9cà¬\97ାହୋଇଥିବା ବଦଳସବୁକୁ ଲୁଚାଇବେ",
+       "tog-newpageshidepatrolled": "ନà­\82à¬\86 à¬ªà­\83ଷà­\8dଠାତାଲିà¬\95ାରà­\81 à¬ªà¬°à¬\96ା ହୋଇଥିବା ବଦଳସବୁକୁ ଲୁଚାଇବେ",
        "tog-hidecategorization": "ପୃଷ୍ଠାସବୁର ଶ୍ରେଣୀବିଭାଗ ଲୁଚାନ୍ତୁ",
        "tog-extendwatchlist": "କେବଳ ନଗଦ ହିଁ ନୁହେଁ, ସବୁଯାକ ବଦଳକୁ ଦେଖାଇବା ପାଇଁ ଦେଖଣାତାଲିକାକୁ ପୂରା ଦେଖାଇବେ",
        "tog-usenewrc": "ନଗଦ ବଦଳରେ ପୃଷ୍ଠା ଅନୁଯାୟୀ ଗୋଷ୍ଠୀ ବଦଳ ଏବଂ ଦେଖଣା",
@@ -33,7 +33,7 @@
        "tog-watchmoves": "ମୁଁ ଘୁଞ୍ଚାଇଥିବା ପୃଷ୍ଠା ଏବଂ ଫାଇଲଗୁଡ଼ିକୁ ମୋର ଦେଖଣାତାଲିକାରେ ଯୋଡ଼ନ୍ତୁ",
        "tog-watchdeletion": "ମୁଁ ଲିଭାଇଥିବା ପୃଷ୍ଠା ଏବଂ ଫାଇଲଗୁଡ଼ିକୁ ମୋର ଦେଖଣାତାଲିକାରେ ଯୋଡ଼ନ୍ତୁ",
        "tog-watchrollback": "ମୁଁ ପଛକୁ ଫେରାଇଦେଇଥିବା ମୋ ଦେଖଣାତାଲିକାର ପୃଷ୍ଠାସବୁକୁ ଯୋଡ଼ନ୍ତୁ",
-       "tog-minordefault": "ସବà­\81ଯାà¬\95 à¬¸à¬®à­\8dପାଦନାà¬\95à­\81 à¬\9bାà¬\8fà¬\81 ଛୋଟ ବଦଳ ଭାବରେ ସୂଚିତ କରିବେ",
+       "tog-minordefault": "ସବà­\81ଯାà¬\95 à¬¸à¬®à­\8dପାଦନାà¬\95à­\81 à¬\86ପà­\87 ଛୋଟ ବଦଳ ଭାବରେ ସୂଚିତ କରିବେ",
        "tog-previewontop": "ଏଡ଼ିଟ ବାକ୍ସ ଆଗରୁ ଦେଖଣା ଦେଖାଇବେ",
        "tog-previewonfirst": "ପ୍ରଥମ ବଦଳର ଦେଖଣା ଦେଖାଇବେ",
        "tog-enotifwatchlistpages": "ମୋ ଦେଖଣାତାଲିକାରେ ଥିବା ପୃଷ୍ଠା ବା ଫାଇଲରେ କିଛି ବଦଳ ହେଲେ ମୋତେ ଇମେଲ କରିବେ",
        "tog-watchlisthideminor": "ଦେଖଣା ତାଲିକାରେ ଛୋଟ ଛୋଟ ବଦଳ ଗୁଡ଼ିକ ଲୁଚାଇବେ",
        "tog-watchlisthideliu": "ଲଗ ଇନ କରିଥିବା ସଭ୍ୟମାନଙ୍କ ଦେଇ କରାହୋଇଥିବା ବଦଳଗୁଡ଼ିକ ଲୁଚାଇବେ",
        "tog-watchlisthideanons": "ଅଜଣା ସଭ୍ୟମାନଙ୍କ ଦେଇ କରାହୋଇଥିବା ବଦଳଗୁଡ଼ିକ ଲୁଚାଇବେ",
-       "tog-watchlisthidepatrolled": "ମà­\8b à¬¦à­\87à¬\96ଣା à¬¤à¬¾à¬²à¬¿à¬\95ାରà­\81 à¬\9cà¬\97ାଯାଇଥିବା ସମ୍ପାଦନାଗୁଡ଼ିକ ଲୁଚାଇବେ",
+       "tog-watchlisthidepatrolled": "ମà­\8b à¬¦à­\87à¬\96ଣା à¬¤à¬¾à¬²à¬¿à¬\95ାରà­\81 à¬ªà¬°à¬\96ା ଯାଇଥିବା ସମ୍ପାଦନାଗୁଡ଼ିକ ଲୁଚାଇବେ",
        "tog-watchlisthidecategorization": "ପୃଷ୍ଠାସବୁର ଶ୍ରେଣୀବିଭାଗ ଲୁଚାନ୍ତୁ",
        "tog-ccmeonemails": "ମୁଁ ଯେଉଁ ଇ-ମେଲ ସବୁ ଅନ୍ୟମାନଙ୍କୁ ପଠାଉଛି ସେସବୁର ନକଲ ମୋତେ ପଠାଇବେ ।",
        "tog-diffonly": "ତୁଳନା ତଳେ ପୃଷ୍ଠାର ଭିତର ଭାଗ ଦେଖାନ୍ତୁ ନାହିଁ",
        "tog-showhiddencats": "ଲୁଚାଯାଇଥିବା ଶ୍ରେଣୀଗୁଡ଼ିକ ଦେଖାଇବେ",
-       "tog-norollbackdiff": "ରà­\8bଲବà­\8dà­\9fାà¬\95 à¬\95ଲାପରେ ତୁଳନା ଦେଖାନ୍ତୁ ନାହିଁ",
+       "tog-norollbackdiff": "ପà¬\9bà¬\95à­\81 à¬«à­\87ରାà¬\87ଲାପରେ ତୁଳନା ଦେଖାନ୍ତୁ ନାହିଁ",
        "tog-useeditwarning": "ଯେତେବେଳେ ମୁଁ ଗୋଟିଏ ସାଇତାଯାଇନଥିବା ପୃଷ୍ଠାକୁ ବନ୍ଦ କରିଦିଏ ମୋତେ ଚେତାବନୀ ଦେବେ",
        "tog-prefershttps": "ଲଗ ଇନ କଲାପରେ ସର୍ବଦା ସୁରକ୍ଷିତ କନେକ୍ସନ ବ୍ୟବହାର କରିବେ",
        "underline-always": "ସବୁବେଳେ",
@@ -64,7 +64,7 @@
        "editfont-style": "ଫଣ୍ଟ ଶୈଳୀକୁ ବଦଳାଇବେ:",
        "editfont-default": "ବ୍ରାଉଜରରେ ଆଗରୁ ଥିବା ସୁବିଧା",
        "editfont-monospace": "ମନୋସ୍ପେସ ଥିବା ଫଣ୍ଟ",
-       "editfont-sansserif": "ସାନସ-ସେରିଫ ଫଣ୍ଟ",
+       "editfont-sansserif": "ସାନà­\8dସ-ସà­\87ରିଫ à¬«à¬£à­\8dà¬\9f",
        "editfont-serif": "ସେରିଫ ଫଣ୍ଟ",
        "sunday": "ରବିବାର",
        "monday": "ସୋମବାର",
        "listingcontinuesabbrev": "ଆହୁରି ଅଛି..",
        "index-category": "ସୂଚୀଥିବା ପୃଷ୍ଠାସବୁ",
        "noindex-category": "ସୂଚୀହୀନ ପୃଷ୍ଠାସବୁ",
-       "broken-file-category": "ଭà¬\99à­\8dà¬\97ା ଫାଇଲ ଲିଙ୍କ ଥିବା ପୃଷ୍ଠାସମୂହ",
+       "broken-file-category": "à¬\85ବà­\8cଧ ଫାଇଲ ଲିଙ୍କ ଥିବା ପୃଷ୍ଠାସମୂହ",
        "about": "ଏହା ବାବଦରେ",
        "article": "ସୂଚୀପତ୍ର",
        "newwindow": "(ଏହା ନୂଆ ଉଇଣ୍ଡୋରେ ଖୋଲିବ)",
        "navigation": "ଦିଗବାରେଣି",
        "and": "&#32;ଓ",
        "qbfind": "ଖୋଜନ୍ତୁ",
-       "qbbrowse": "ବà­\8dରାà¬\89à¬\9c",
+       "qbbrowse": "ଦà­\87à¬\96ିବà­\87",
        "qbedit": "ସମ୍ପାଦନା (Edit)",
        "qbpageoptions": "ଏହି ପୃଷ୍ଠାଟି",
        "qbmyoptions": "ମୋ ପୃଷ୍ଠାଗୁଡ଼ିକ",
        "viewtalkpage": "ଆଲୋଚନାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ",
        "otherlanguages": "ଅଲଗା ଭାଷାରେ",
        "redirectedfrom": "($1 ରୁ ଲେଉଟି ଆସିଛି)",
-       "redirectpagesub": "à¬\86à¬\89ଥରà­\87 à¬«à­\87ରିବା ପୃଷ୍ଠା",
+       "redirectpagesub": "ପà­\81ନà¬\83ପà­\8dରà­\87ରଣ ପୃଷ୍ଠା",
        "redirectto": "କେଉଁଠାକୁ ଲେଉଟାଣି:",
        "lastmodifiedat": "ଏହି ପୃଷ୍ଠାଟି $1 ତାରିଖ $2 ବେଳେ ବଦଳାଯାଇଥିଲା ।",
        "viewcount": "ଏହି ପୃଷ୍ଠାଟି {{PLURAL:$1|ଥରେ|$1 ଥର}} ଖୋଲାଯାଇଛି ।",
        "createacct-another-username-ph": "ଆପଣଙ୍କ ଇଉଜର ନାମ ଟାଇପ କରନ୍ତୁ",
        "yourpassword": "ପାସୱାର୍ଡ଼",
        "userlogin-yourpassword": "ପାସୱାର୍ଡ଼",
-       "userlogin-yourpassword-ph": "à¬\86ପଣà¬\99à­\8dà¬\95 à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ଼ à¬²à­\87à¬\96ନ୍ତୁ",
+       "userlogin-yourpassword-ph": "à¬\86ପଣà¬\99à­\8dà¬\95 à¬ªà¬¾à¬¸à­±à¬°à­\8dଡ଼ à¬¦à¬¿à¬\85ନ୍ତୁ",
        "createacct-yourpassword-ph": "ପାସୱର୍ଡ଼ ଦିଅନ୍ତୁ",
        "yourpasswordagain": "ପାସୱାର୍ଡ଼ ଆଉଥରେ:",
        "createacct-yourpasswordagain": "ପାସୱର୍ଡ଼ ନିଶ୍ଚିତ କରିବେ",
        "right-blockemail": "ଇ-ମେଲ ପଠାଇବାରୁ ଜଣେ ସଭ୍ୟଙ୍କୁ ବାରଣ କରିବେ",
        "right-hideuser": "ସାଧାରଣରୁ ଲୁଚାଇ ଏକ ଇଉଜର ନାମକୁ ଅଟକାଇବେ",
        "right-ipblock-exempt": "IP ଅଟକ, ଆପେଆପେ-ଅଟକ ଓ ସୀମା ଅଟକସବୁକୁ ଅଲଗା ଦିଗଗାମୀ କରିବେ",
-       "right-proxyunbannable": "ପ୍ରକ୍ସିର ଆପେଆପେ ହେଉଥିବା ଅଟକସବୁକୁ ଅଲଗା ଦିଗଗାମୀ କରିବେ",
        "right-unblockself": "ଜଣଙ୍କୁ ଅଟକରୁ ଚାଡ଼କରିବେ",
        "right-protect": "ନିରାପତ୍ତା ବଢ଼ାଇ କ୍ୟାସକେଡ଼-ନିରାପତ୍ତା ପୃଷ୍ଠାମାନଙ୍କୁ ବଦଳାନ୍ତୁ",
        "right-editprotected": "କିଳାଯାଇଥିବା ପୃଷ୍ଠାମାନଙ୍କର ସମ୍ପାଦନା କରିବେ (କ୍ୟାସକେଡ଼କରା କିଳଣା ବିନା)",
        "watchthisupload": "ଏହି ପୃଷ୍ଠାଟିକୁ ଦେଖିବେ",
        "filewasdeleted": "ଆଗରୁ ଏହି ନାମରେ ଅପଲୋଡ଼ କରାଯାଇଥିବା ଫାଇଲଟିଏ ଲିଭାଇ ଦିଆଯାଇଅଛି  ।\nଆଉଥରେ ଅପଲୋଡ଼ କରିବା ଆଗରୁ ଆପଣ $1ଟି ଠାରେ ପରଖି ନିଅନ୍ତୁ ।",
        "filename-bad-prefix": "ଆପଣ ଅପଲୋଡ଼ କରୁଥିବା '''\"$1\"'' ନାମରେ ଆରମ୍ଭ ହେଉଥିବା ଫାଇଲ, ଯାହାକି ଏକ ବଖଣାଯାଇନଥିବା ନାମରେ ନାମିତ ଓ ଆପେଆପେ ଡିଜିଟାଲ କ୍ୟାମେରାରୁ ଆସିଥାଏ ।\nଦୟାକରି ଏହି ଫାଇଲ ପାଇଁ ଏକ ବୁଝାପଡୁଥିବା ନାମଟିଏ ଦିଅନ୍ତୁ ।",
-       "upload-success-subj": "ଅପଲୋଡ଼ ସଫଳ",
-       "upload-success-msg": "ଆପଣଙ୍କ ଅପଲୋଡ଼ ଫର୍ମ [$2] ସଫଳ ହେଲା । ଏହା [[:{{ns:file}}:$1]] ଠାରେ ମିଳୁଅଛି ।",
-       "upload-failure-subj": "ଅପଲୋଡ଼ରେ ଅସୁବିଧା",
-       "upload-failure-msg": " [$2]ରୁ ଆପଣଙ୍କ କରିଥିବା ଅପଲୋଡ଼ରେ ଗୋଟିଏ ଅସୁବିଧା ଥିଲା:\n\n$1",
-       "upload-warning-subj": "ଅପଲୋଡ଼ ଚେତାବନୀ",
-       "upload-warning-msg": "[$2]ରୁ ଆପଣ କରିଥିବା ଅପଲୋଡରେ ଗୋଟିଏ ଅସୁବିଧା ଥିଲା । ଆପଣ [[Special:Upload/stash/$1|ଅପଲୋଡ଼ ଫର୍ମ]]କୁ ଫେରି ଏହି ଅସୁବିଧାଟିକୁ ସୁଧାରି ପାରନ୍ତି ।",
        "upload-proto-error": "ଭୁଲ ପ୍ରଟକଲ",
        "upload-proto-error-text": "ସୁଦୂରର ଅପଲୋଡ଼ପାଇଁ URL ସବୁ <code>http://</code> କିମ୍ବା <code>ftp://</code> ରେ ଆରମ୍ଭ ହେଉଥିବା ଲୋଡ଼ା ।",
        "upload-file-error": "ଭିତରର ଭୁଲ",
        "pager-older-n": "{{PLURAL:$1|ପୁରୁଣା 1|ପୁରୁଣା $1}}",
        "suppress": "ଅଜାଣତ ଅଣଦେଖା",
        "querypage-disabled": "ଏହି ବିଶେଷ ପୃଷ୍ଠାଟି ଦେଖଣା କାରଣରୁ ଅଚଳ କରାଯାଇଅଛି ।",
+       "apisandbox": "API ପରଖଘର",
+       "apisandbox-api-disabled": "API ଟି ଏହି ସାଇଟରେ ଅଚଳ କରାଯାଇଛି ।",
+       "apisandbox-submit": "ଅନୁରୋଧ କରିବେ",
+       "apisandbox-reset": "ଖାଲି କରିଦିଅନ୍ତୁ",
+       "apisandbox-examples": "ଉଦାହରଣ",
+       "apisandbox-results": "ପରିଣାମ",
+       "apisandbox-request-url-label": "URL ଅନୁରୋଧ କରିବେ:",
+       "apisandbox-request-time": "ଅନୁରୋଧ ସମୟ: $1",
        "booksources": "ବହିର ମୁଳାଧାର",
        "booksources-search-legend": "ବହିର ସ୍ରୋତସବୁକୁ ଖୋଜିବେ",
        "booksources-search": "ଖୋଜିବେ",
        "wlheader-showupdated": "ଆପଣ ଶେଷଥର ଦେଖିଥିବା ପୃଷ୍ଠାଗୁଡ଼ିକ '''ମୋଟା ଅକ୍ଷର'''ରେ ଦେଖାଯାଉଅଛି ।",
        "wlnote": "$3, $4 ଅନୁସାରେ ବିଗତ {{PLURAL:$2|ଘଣ୍ଟାକରେ|<strong>$2</strong> ଘଣ୍ଟାରେ}}{{PLURAL:$1|ଶେଷ ବଦଳ|ଶେଷ <strong>$1</strong> ବଦଳ ତଳେ ଦିଆଗଲା}} ।",
        "wlshowlast": "ଗତ $1 ଘଣ୍ଟା $2 ଦିନ ଦେଖାନ୍ତୁ",
-       "watchlistall2": "ସବୁ",
        "watchlist-options": "ଦେଖଣା ବିକଳ୍ପସବୁ",
        "watching": "ଦେଖୁଛି...",
        "unwatching": "ଦେଖୁନାହିଁ...",
        "javascripttest-pagetext-frameworks": "ଦୟାକରି ନିମ୍ନରେ ଥିବା ଏକ ପରଖ ପ୍ରକ୍ରିୟାକୁ ବାଛନ୍ତୁ :$1",
        "javascripttest-pagetext-skins": "ଏହି ପରଖକୁ ଚାଲୁ କରିବା ପାଇଁ ଏକ ଆବରଣ ବାଛନ୍ତୁ ।",
        "javascripttest-qunit-intro": "mediawiki.orgରେ [$1 testing documentation]କୁ ଦେଖନ୍ତୁ ।",
-       "tooltip-pt-userpage": "ଆପଣଙ୍କ ବ୍ୟବହାରକାରୀ ପୃଷ୍ଠା",
+       "tooltip-pt-userpage": "{{GENDER:|ଆପଣଙ୍କ}} ବ୍ୟବହାରକାରୀ ପୃଷ୍ଠା",
        "tooltip-pt-anonuserpage": "ଆପଣ ଯେଉଁ IP ଠିକଣାର ବ୍ୟବହାରକାରୀ ପୃଷ୍ଠାଟି ବଦଳାଇବା ପାଇଁ ଚେଷ୍ଟା କରୁଛନ୍ତି",
-       "tooltip-pt-mytalk": "ଆପଣଙ୍କ ଆଲୋଚନା ପୃଷ୍ଠା",
+       "tooltip-pt-mytalk": "{{GENDER:|ଆପଣଙ୍କ}} ଆଲୋଚନା ପୃଷ୍ଠା",
        "tooltip-pt-anontalk": "ଏହି IP ଠିକଣାରୁ କେହିଜଣେ କରିଥିବା ସମ୍ପାଦନାର ଆଲୋଚନା",
-       "tooltip-pt-preferences": "ମୋ ପସନ୍ଦ",
+       "tooltip-pt-preferences": "{{GENDER:|ମୋ}} ପସନ୍ଦ",
        "tooltip-pt-watchlist": "ବଦଳ ପାଇଁ ଆପଣ ଦେଖାଶୁଣା କରୁଥିବା ପୃଷ୍ଠାଗୁଡ଼ିକର ତାଲିକା",
-       "tooltip-pt-mycontris": "ଆପଣଙ୍କ ଅବଦାନ",
+       "tooltip-pt-mycontris": "{{GENDER:|ଆପଣଙ୍କ}} ଅବଦାନ ତାଲିକା",
        "tooltip-pt-login": "ଆପଣଙ୍କୁ ଲଗ-ଇନ କରିବାକୁ କୁହାଯାଉଅଛି ସିନା, ବାଧ୍ୟ କରାଯାଉନାହିଁ",
        "tooltip-pt-logout": "ଲଗଆଉଟ",
        "tooltip-pt-createaccount": "ଆପଣଙ୍କୁ ଗୋଟେ ଖାତା ଖୋଲି ଲଗ ଇନ କରିବା ପାଇଁ ପ୍ରୋତ୍ସାହିତ କରାଯାଉଛି, ଏମିତିବି ଏହା କରିବା ନିତାନ୍ତ ଆବଶ୍ୟକ ନୁହେଁ ।",
        "tooltip-t-recentchangeslinked": "ଏହି ପୃଷ୍ଠା ସଙ୍ଗେ ଯୋଡ଼ା ଫରଦଗୁଡ଼ିକରେ ଏବେ ଏବେ କରାଯାଇଥିବା ଅଦଳବଦଳ",
        "tooltip-feed-rss": "ଏହି ପୃଷ୍ଠାଟି ପାଇଁ RSS ଫିଡ଼",
        "tooltip-feed-atom": "ଏହି ପୃଷ୍ଠାଟି ପାଇଁ ଆଟମ ଫିଡ଼",
-       "tooltip-t-contributions": "ଏହି ଇଉଜରଙ୍କର ଦ୍ଵାରା ହୋଇଥିବା ବଦଳ ତାଲିକା",
+       "tooltip-t-contributions": "{{GENDER:$1|ଏହି ଇଉଜରଙ୍କର}} ଦ୍ଵାରା ହୋଇଥିବା ବଦଳ ତାଲିକା",
        "tooltip-t-emailuser": "ଏହି ସଭ୍ୟଙ୍କୁ ଇ-ମେଲଟିଏ ପଠାଇବେ",
        "tooltip-t-upload": "ଫାଇଲ ଅପଲୋଡ଼ କରିବେ",
        "tooltip-t-specialpages": "ବିଶେଷ ପୃଷ୍ଠାମାନଙ୍କର ଏକ ତାଲିକା",
index 114e694..1a9c854 100644 (file)
        "querypage-disabled": "Ta strona specjalna została wyłączona ze względu na ograniczenia wydajności.",
        "apihelp": "Pomoc API",
        "apihelp-no-such-module": "Moduł \"$1\" nie znaleziony.",
+       "apisandbox": "Środowisko testowe API",
+       "apisandbox-api-disabled": "API jest wyłączone na tej stronie.",
+       "apisandbox-intro": "Użyj tej strony do eksperymentowania z '<strong>API serwisu MediaWiki</strong>.\nWięcej szczegółów na temat wykorzystywania API można znaleźć w [[mw:API:Main page|dokumentacji API]]. Przykład: [//www.mediawiki.org/wiki/API#A_simple_example pobranie zawartości strony głównej]. Wybierz akcję, by zobaczyć więcej przykładów.\n\nZwróć uwagę, że chociaż jest to brudnopis, to działania, które można przeprowadzać na tej stronie, mogą zmienić wiki.",
+       "apisandbox-unfullscreen": "Pokaż stronę",
+       "apisandbox-submit": "Wykonaj zapytanie",
+       "apisandbox-reset": "Wyczyść",
+       "apisandbox-retry": "Ponów próbę",
+       "apisandbox-no-parameters": "Ten moduł API nie posiada parametrów.",
+       "apisandbox-helpurls": "Linki pomocy",
+       "apisandbox-examples": "Przykłady",
+       "apisandbox-dynamic-parameters": "Parametry dodatkowe",
+       "apisandbox-dynamic-parameters-add-label": "Dodaj parametr:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Nazwa parametru",
+       "apisandbox-dynamic-error-exists": "Parametr o nazwie „$1” już istnieje.",
+       "apisandbox-submit-invalid-fields-title": "Niektóre pola są nieprawidłowe",
+       "apisandbox-submit-invalid-fields-message": "Popraw zaznaczone pola i spróbuj ponownie.",
+       "apisandbox-results": "Wyniki",
+       "apisandbox-loading-results": "Pobieranie wyników API...",
+       "apisandbox-request-url-label": "URL zapytania:",
+       "apisandbox-request-time": "Czas przetwarzania zapytania: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-alert-page": "Pola na tej stronie są nieprawidłowe.",
+       "apisandbox-alert-field": "Wartość tego pola jest nieprawidłowa.",
        "booksources": "Książki",
        "booksources-search-legend": "Szukaj informacji o książkach",
        "booksources-search": "Szukaj",
        "scarytranscludefailed-httpstatus": "[Pobranie szablonu dla $1 nie powiodło się: HTTP $2]",
        "scarytranscludetoolong": "[zbyt długi adres URL]",
        "deletedwhileediting": "'''Uwaga!''' Ta strona została usunięta po tym, jak rozpoczął{{GENDER:|eś|aś|eś(‐aś)}} jej edycję!",
-       "confirmrecreate": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jego edycję, podając jako powód usunięcia:\n: <em>$2</em>\nPotwierdź, że na pewno chcesz odtworzyć tę stronę.",
-       "confirmrecreate-noreason": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jego edycję. Potwierdź, że naprawdę chcesz odtworzyć tę stronę.",
+       "confirmrecreate": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jej edycję, podając jako powód usunięcia:\n: <em>$2</em>\nPotwierdź, że na pewno chcesz odtworzyć tę stronę.",
+       "confirmrecreate-noreason": "{{GENDER:$1|Użytkownik|Użytkowniczka}} [[User:$1|$1]] ([[User talk:$1|dyskusja]]) {{GENDER:$1|usunął|usunęła}} tę stronę po tym, jak rozpocząłeś/rozpoczęłaś jej edycję. Potwierdź, że naprawdę chcesz odtworzyć tę stronę.",
        "recreate": "Utwórz powtórnie",
        "confirm_purge_button": "Wyczyść",
        "confirm-purge-top": "Wyczyścić pamięć podręczną dla tej strony?",
        "expand_templates_generate_rawhtml": "Pokaż surowy HTML",
        "expand_templates_preview": "Podgląd",
        "expand_templates_preview_fail_html": "<em>Ponieważ {{SITENAME}} ma włączony surowy kod HTML i zaistniała strata danych z sesji, podgląd jest ukryty jako zabezpieczenie przed atakiem JavaScript.</em>\n\n<strong>Jeśli to jest próba słusznego podglądu, proszę spróbować ponownie.</strong>\nJeśli to nadal nie działa, spróbuj [[Special:UserLogout|wylogować się]] i zalogować się z powrotem.",
-       "pagelanguage": "Wybór języka strony",
+       "pagelanguage": "Zmiana języka strony",
        "pagelang-name": "Strona",
        "pagelang-language": "Język",
        "pagelang-use-default": "Użyj domyślnego języka",
index 207f175..a416870 100644 (file)
        "createaccountreason": "Rason:",
        "createacct-reason": "Rason",
        "createacct-reason-ph": "Përchè a crea n'àutr cont",
-       "createacct-captcha": "Contròl ëd sigurëssa",
-       "createacct-imgcaptcha-ph": "Ch'a anserissa ël test ch'a s-ciàira sì-dzora",
        "createacct-submit": "Ch'a crea sò cont",
        "createacct-another-submit": "Creé n'àutr cont",
        "createacct-benefit-heading": "{{SITENAME}} a l'é fàit da 'd gent coma chiel.",
        "passwordreset-emailtext-ip": "Quaidun (a l'é bel fé ch'a sia chiel, da l'adrëssa IP $1) a l'ha ciamà na riampostassion ëd soa ciav për {{SITENAME}} ($4). {{PLURAL:$3|Ël cont utent sì-sota a l'é|Ij cont utent sì-sota a son}} \nassocià a st'adrëssa ëd pòsta eletrònica:\n\n$2\n\n{{PLURAL:$3|Costa ciav provisòria|Coste ciav provisòrie}} a scadran da-sì {{PLURAL:$5|un di|$5 di}}.\nA dovrìa intré ant ël sistema e serne na ciav neuva adess. Se quaidun d'àutr a l'ha fàit costa arcesta, o s'a l'é arcordasse soa ciav original, e a veul pa pi cangela, a peule ignoré ës mëssagi e continué a dovré soa veja ciav.",
        "passwordreset-emailtext-user": "L'utent $1 ansima a {{SITENAME}} a l'ha ciamà na riampostassion ëd soa ciav për {{SITENAME}} ($4). {{PLURAL:$3|Ël cont utent sì-sota a l'é|Ij cont utent sì-sota a son}} associà a st'adrëssa ëd pòsta eletrònica:\n\n$2\n\n{{PLURAL:$3|Costa ciav provisòria|Coste ciav provisòrie}} a scadran da-sì {{PLURAL:$5|un di|$5 di}}.\nA dovrìa intré ant ël sistema e serne na ciav neuva adess. Se quaidun d'àutr a l'ha fàit costa arcesta, o s'a l'é arcordasse soa ciav original, e a veul pa pi cangela, a peul ignoré ës mëssagi e continué a dovré soa veja ciav.",
        "passwordreset-emailelement": "Stranòm: \n$1\n\nCiav provisòria: \n$2",
-       "passwordreset-emailsent": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit spedì.",
+       "passwordreset-emailsentemail": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit spedì.",
        "passwordreset-emailsent-capture": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit mandà, e a l'é mostrà sì-sota.",
        "passwordreset-emailerror-capture": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit generà, e a l'é smonù sì-sota, ma la spedission a {{GENDER:$2|l'utent}} a l'é falìa: $1",
        "changeemail": "Cangé l'adrëssa ëd pòsta eletrònica",
        "prefs-help-prefershttps": "Costa preferensa a ancaminrà a marcé a soa pròssima conession.",
        "prefswarning-warning": "A l'ha fàit dle modìfiche ai sò gust ch'a son ancor nen ëstàire argistrà.\nS'a chita sa pàgina sensa sgnaché «$1» ij sò gust a saran pa agiorné.",
        "prefs-tabs-navigation-hint": "Astussia: A peul dovré le flece a snistra e a drita për navighé antra le schede ant la lista dle schede.",
-       "email-address-validity-valid": "A smija bon",
-       "email-address-validity-invalid": "A-i é da manca ëd n'adrëssa bon-a!",
        "userrights": "Gestion dij drit dj'utent",
        "userrights-lookup-user": "Gestion dle partìe d'utent",
        "userrights-user-editname": "Che a buta në stranòm:",
        "right-blockemail": "Bloché n'utent da mandé 'd mëssagi an pòsta eletrònica",
        "right-hideuser": "Bloché un nòm utent, stërmandlo al pùblich",
        "right-ipblock-exempt": "Dëscavalché ij blocagi ëd j'IP, ij blocagi automàtich e ij blocagi ëd partìe d'IP",
-       "right-proxyunbannable": "Dëscavalché ij blòch automatich dij servent d'anonimà",
        "right-unblockself": "Dësblochesse da soj",
        "right-protect": "Cambié ij livej ëd protession e modifiché le pàgine protegiùe an cascada",
        "right-editprotected": "Modifiché le pàgine protegiùe con «{{int:protect-level-sysop}}»",
        "uploaded-script-svg": "Element ëscrivìbil «$1» trovà ant l'archivi SVG carià.",
        "uploaded-hostile-svg": "CSS nen sigur trovà ant l'element dë stil ëd n'archivi SVG carià.",
        "uploaded-event-handler-on-svg": "Fissé dj'atribù ëd gestion d'eveniment <code>$1=\"$2\"</code> a l'é nen përmëttù ant j'archivi SVG.",
-       "uploaded-href-attribute-svg": "J'atribù <code>&lt;$1 $2=\"$3\"&gt;</code> con un bërsaj nen local (për esempi http://, javascript:, e via fòrt) a son nen përmëttù ant j'archivi SVG.",
        "uploaded-href-unsafe-target-svg": "href ver un bërsaj nen sigur <code>&lt;$1 $2=\"$3\"&gt;</code> trovà ant l'archivi SVG carià.",
        "uploaded-animate-svg": "Trovà na tichëtta «animate», ch'a podrìa modifiché ël href an dovrand l'atribù «from» <code>&lt;$1 $2=\"$3\"&gt;</code> ant l'archivi SVG carià.",
        "uploaded-setting-event-handler-svg": "Ël posissionament dj'atribù ëd mansé a l'é blocà, <code>&lt;$1 $2=\"$3\"&gt;</code> trovà ant l'archivi SVG carià.",
        "filewasdeleted": "N'archivi con ës nòm-sì a l'é già stàit carià e peui scancelà. Për piasì, che a verìfica $1 anans che carielo n'àutra vira.",
        "filename-bad-prefix": "Ël nòm dl'archivi ch'a l'é dapress a carié as anandia për '''\"$1\"''', ch'a l'é un nòm sensa sust, për sòlit butà-lì n'aotomàtich da le màchine fotogràfiche digitaj, basta ch'a-i në sia un. Për piasì, ch'a-j daga a sò archivi un nòm ch'a disa lòn ch'a l'é.",
        "filename-prefix-blacklist": " #<!-- ch'a lassa sta riga-sì tanme ch'a l'é --> <pre>\n# La sintassi a l'é:\n#   * Tut lòn ch'a-i ven dapress al segn \"#\" fin a la fin dla riga a resta mach un coment\n#   * Na riga nen veujda a la resta un prefiss ëd nòm d'archivi për sòlit dovrà da na chèich màchina fotogràfica digitala\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # chèich sacociàbil\nIMG # genérich\nJD # Jenoptik\nMGP # Pentax\nPICT # vàire marche diferente\n #</pre> <!-- ch'a lassa sta riga-sì tanme ch'a l'é -->",
-       "upload-success-subj": "Carià con sucess",
-       "upload-success-msg": "A l'ha carià da [$2] për da bin. Lòn ch'a l'ha carià a l'é disponìbil ambelessì: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Problema a carié",
-       "upload-failure-msg": "A-i é staje un problema con lòn ch'a l'ha carià da [$2]:\n\n$1",
-       "upload-warning-subj": "Avis antramentre ch'as caria",
-       "upload-warning-msg": "A-i era un problema con lòn ch'a l'ha carià da [$2]. A peul artorné al [[Special:Upload/stash/$1|formolari për carié]] për corege ël problema.",
        "upload-proto-error": "Protocòl cioch",
        "upload-proto-error-text": "Për carié da dij servent lontan a venta buté dj'anliure ch'as anandio për <code>http://</code> ò pura <code>ftp://</code>.",
        "upload-file-error": "Eror antern",
        "querypage-disabled": "Sta pàgina special a l'é disabilità për dle rason ëd prestassion.",
        "apihelp": "Agiut ëd l'API",
        "apihelp-no-such-module": "Ël mòdol «$1» as treuva nen.",
+       "apisandbox": "Spassi dle preuve API",
+       "apisandbox-api-disabled": "API a l'é disabilità ansima a 's sit.",
+       "apisandbox-intro": "Ch'a deuvra sta pàgina për sperimenté ël '''servissi an sl'aragnà MediaWiki API'''.\nCh'a fasa riferiment a [//www.mediawiki.org/wiki/API:Main_page la documentassion ëd l'API] për d'àutri detaj an sl'utilisassion ëd l'API. Për esempi: [//www.mediawiki.org/wiki/API#A_simple_example oten-e ël contnù ëd na pàgina d'Intrada]. Ch'a selession-a n'assion për vëdde d'àutri esempi.",
+       "apisandbox-submit": "Fé l'arcesta",
+       "apisandbox-reset": "Scancela",
+       "apisandbox-examples": "Esempi",
+       "apisandbox-results": "Arzultà",
+       "apisandbox-request-url-label": "Anliura d'arcesta:",
+       "apisandbox-request-time": "Temp necessari: $1",
        "booksources": "Andoa trové dij lìber",
        "booksources-search-legend": "Sërché antra ij lìber d'arferiment",
        "booksources-search": "Arserché",
        "movenosubpage": "Sta pàgina-sì a l'ha gnun-e sot-pàgine.",
        "movereason": "Rason:",
        "revertmove": "buté torna coma a l'era",
-       "delete_and_move": "Scancelé e tramudé",
        "delete_and_move_text": "==A fa da manca dë scancelé==\n\nL'artìcol ëd destinassion «[[:$1]]» a-i é già. Veul-lo scancelelo për avèj ëd pòst për tramudé l'àutr?",
        "delete_and_move_confirm": "É, scancelé la pàgina",
        "delete_and_move_reason": "Scancelà për liberé ël pòst për tramudé «[[$1]]»",
        "special-characters-title-minus": "segn meno",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
-       "api-error-blacklisted": "Për piasì sern un tìtol diferent, descritiv."
+       "api-error-blacklisted": "Për piasì sern un tìtol diferent, descritiv.",
+       "randomrootpage": "Pàgina root a cas"
 }
index 94f20a7..212f335 100644 (file)
        "prefs-watchlist-edits-max": "د شمېر اکثر بريد: 1000",
        "prefs-misc": "بېلابېل",
        "prefs-resetpass": "پټنوم بدلول",
-       "prefs-changeemail": "برېښليک بدلول",
+       "prefs-changeemail": "برېښليک پته بدلول يا ليرې کول",
        "prefs-setemail": "يوه برېښليک پته ورکړۍ",
        "prefs-email": "د برېښليک خوښنې",
        "prefs-rendering": "ښکارېدنه",
        "rcshowhidemine": "زما سمونې $1",
        "rcshowhidemine-show": "ښکاره کول",
        "rcshowhidemine-hide": "پټول",
+       "rcshowhidecategorization": "د مخ وېشنيزې $1",
        "rcshowhidecategorization-show": "ښکاره کول",
        "rcshowhidecategorization-hide": "پټول",
        "rclinks": "هغه وروستي $1 بدلونونه ښکاره کړی چې په $2 ورځو کې پېښ شوي<br />$3",
        "suppress": "ځپل",
        "apihelp": "API لارښود",
        "apihelp-no-such-module": "د \"$1\" ماډيول و نه موندل شو.",
+       "apisandbox": "API آزمونمخ",
+       "apisandbox-unfullscreen": "مخ ښکاره کول",
+       "apisandbox-submit": "غوښته کول",
+       "apisandbox-reset": "سپينول",
+       "apisandbox-retry": "بيا هڅه کول",
+       "apisandbox-examples": "بېلگې",
+       "apisandbox-dynamic-parameters-add-label": "پاراميټرونه ورگډول",
+       "apisandbox-results": "پايلې",
+       "apisandbox-request-url-label": "د URL غوښتنه کول:",
+       "apisandbox-request-time": "د غوښتنې وخت: {{PLURAL:$1|$1 م.ث}}",
        "booksources": "د کتاب سرچينې",
        "booksources-search-legend": "د کتابي سرچينو پلټنه",
        "booksources-isbn": "ISBN:",
        "redirect-user": "کارن پېژند",
        "redirect-page": "د مخ پېژند",
        "redirect-file": "د دوتنې نوم",
+       "redirect-logid": "پېژند يادښت",
        "redirect-not-exists": "ارزښت و نه موندل شو",
        "fileduplicatesearch": "د دوه گونو دوتنو پلټنه",
        "fileduplicatesearch-legend": "د دوه گونو دوتنو پلټنه",
        "expand_templates_remove_nowiki": "په پايلو کې د <nowiki> نښلنونه ځپل",
        "expand_templates_generate_rawhtml": "خام HTML ښکاره کول",
        "expand_templates_preview": "مخليدنه",
-       "pagelanguage": "د Ù\85Ø® Ú\98بټاکÙ\88Ù\86Ú©Û\8c",
+       "pagelanguage": "د Ù\85Ø® Ú\98بÙ\87 Ø¨Ø¯Ù\84Ù\88Ù\84",
        "pagelang-name": "مخ",
        "pagelang-language": "ژبه",
        "pagelang-use-default": "تلواليزه ژبه کارول",
        "pagelang-submit": "سپارل",
        "right-pagelang": "د مخ ژبه بدلول",
        "action-pagelang": "د مخ ژبه بدلول",
-       "log-name-pagelang": "ژبيادښت بدلول",
+       "log-name-pagelang": "د ژب بدلون يادښت",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (چارن)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ناچارن''')",
        "mediastatistics": "د رسنيو شمار",
index 8a153dd..74b16e5 100644 (file)
        "october-date": "$1 de outubro",
        "november-date": "$1 de novembro",
        "december-date": "$1 de dezembro",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Categoria|Categorias}}",
        "category_header": "Páginas na categoria \"$1\"",
        "subcategories": "Subcategorias",
        "laggedslavemode": "'''Aviso:''' A página pode não conter as atualizações mais recentes.",
        "readonly": "Base de dados bloqueada (limitada a leituras)",
        "enterlockreason": "Introduza um motivo para bloquear, incluindo uma estimativa de quando será desbloqueada",
-       "readonlytext": "A base de dados está bloqueada para impedir a inserção e modificação de dados, provavelmente para uma manutenção de rotina, após a qual a situação será normalizada.\n\nO administrador que a bloqueou deu a seguinte explicação: $1",
+       "readonlytext": "A base de dados está atualmente bloqueada para novas entradas e outras modificações, provavelmente para uma manutenção de rotina, após a qual voltará à sua normalidade.\n\nO administrador que a bloqueou deu a seguinte explicação: $1",
        "missing-article": "A base de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nGeralmente, esta situação ocorre ao clicar numa ligação para diferenças desatualizada ou para o histórico de uma página que tenha sido removida.\n\nSe nenhuma destas situações se verifica, pode ter encontrado um defeito no programa.\nAnote a URL e reporte este incidente a um [[Special:ListUsers/sysop|administrador]], por favor.",
        "missingarticle-rev": "(revisão#: $1)",
        "missingarticle-diff": "(Dif.: $1, $2)",
        "mypreferencesprotected": "Não tem permissão para editar as suas preferências.",
        "ns-specialprotected": "Não é possível editar páginas especiais.",
        "titleprotected": "Este título foi protegido contra criação por [[User:$1|$1]].\nA justificação dada foi \"''$2''\".",
-       "filereadonlyerror": "Não é possível modificar o ficheiro \"$1\" porque o repositório de ficheiros \"$2\" está em modo de leitura.\n\nO administrador que efetuou o bloqueio deu a seguinte explicação: \"$3\".",
+       "filereadonlyerror": "Não é possível modificar o ficheiro \"$1\" porque o repositório de ficheiros \"$2\" está em modo de leitura.\n\nO administrador do sistema que efetuou o bloqueio deu a seguinte explicação: \"$3\".",
        "invalidtitle-knownnamespace": "Título inválido com o domínio \"$2\" e texto \"$3\"",
        "invalidtitle-unknownnamespace": "Título inválido com número de domínio $1 desconhecido e texto \"$2\"",
        "exception-nologin": "Não está autenticado",
        "virus-unknownscanner": "antivírus desconhecido:",
        "logouttext": "<strong>Já não está autenticado.</strong>\n\nTenha em atenção que algumas páginas poderão continuar a ser apresentadas como se ainda estivesse autenticado até limpar a ''cache'' do seu navegador.",
        "cannotlogoutnow-title": "Não é possível encerrar a sessão agora",
+       "cannotlogoutnow-text": "Não pode encerrar a sessão quando utilizar $1.",
        "welcomeuser": "Bem-vindo, $1!",
        "welcomecreation-msg": "A sua conta foi criada.\nNão se esqueça de personalizar as suas [[Special:Preferences|preferências]].",
        "yourname": "Nome de utilizador(a):",
        "userlogin-remembermypassword": "Manter-me autenticado",
        "userlogin-signwithsecure": "Usar uma ligação segura",
        "cannotloginnow-title": "Não é possível iniciar sessão agora",
+       "cannotloginnow-text": "Não pode iniciar a sessão quando utilizar $1.",
        "yourdomainname": "O seu domínio:",
        "password-change-forbidden": "Não pode alterar palavras-passe nesta wiki.",
        "externaldberror": "Ocorreu um erro externo à base de dados durante a autenticação ou não lhe é permitido atualizar a sua conta externa.",
        "changepassword-success": "A sua palavra-passe foi alterada!",
        "changepassword-throttled": "Realizou demasiadas tentativas de início de sessão com esta conta.\nAguarde $1 antes de tentar novamente, por favor.",
        "botpasswords": "Palavras-passe de robô",
+       "botpasswords-summary": "As <em>palavras-passe de robô</em> permitem o acesso a uma conta de utilizador através da API sem utilizar as principais credenciais de login da conta. Os direitos de um utilizador, ao iniciar sessão com uma palavra-passe de robô, podem estar limitados.\n\nSe não sabe o que o leva a fazer isso, provavelmente não deveria fazê-lo. Ninguém deve solicitar que gere uma destas palavras-passe e a entregue.",
+       "botpasswords-disabled": "As palavras-passe de robô estão desactivadas.",
+       "botpasswords-no-central-id": "Para utilizar palavras-passe de robô, deve iniciar sessão com uma conta centralizada.",
+       "botpasswords-existing": "Palavras-passe de robô existentes",
        "botpasswords-createnew": "Criar uma nova palavra-passe para robô",
+       "botpasswords-editexisting": "Editar uma palavra-passe de robô existente",
        "botpasswords-label-appid": "Nome do robô:",
        "botpasswords-label-create": "Criar",
        "botpasswords-label-update": "Atualizar",
        "botpasswords-label-cancel": "Cancelar",
        "botpasswords-label-delete": "Eliminar",
        "botpasswords-label-resetpassword": "Redefinir palavra-passe",
+       "botpasswords-label-grants": "Permissões aplicáveis:",
        "botpasswords-label-restrictions": "Restrições de uso:",
+       "botpasswords-label-grants-column": "Concedido",
+       "botpasswords-bad-appid": "O nome do robô \"$1\" não é válido.",
+       "botpasswords-insert-failed": "Falhou ao adicionar o nome do robô \"$1\". Já foi adicionado?",
        "botpasswords-update-failed": "Falha ao atualizar o nome do robô \"$1\". Será que foi eliminado?",
        "botpasswords-created-title": "Criada palavra-passe para o robô",
        "botpasswords-created-body": "A palavra-passe para o robô \"$1\" foi criada com sucesso.",
+       "botpasswords-updated-title": "A palavra-passe de robô foi actualizada.",
+       "botpasswords-updated-body": "A palavra-passe de robô \"$1\" foi actualizada com sucesso.",
+       "botpasswords-deleted-title": "Palavra-passe de robô eliminada",
+       "botpasswords-deleted-body": "A palavra-passe de robô \"$1\" foi eliminada.",
        "botpasswords-newpassword": "A nova palavra-passe para iniciar sessão com <strong>$1</strong> é <strong>$2</strong>. Por favor, recorde-se dela para futura referência.</em>",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider não está disponível.",
        "resetpass_forbidden": "Não é possível alterar palavras-passe",
        "resetpass-no-info": "Precisa de iniciar sessão para aceder diretamente a esta página.",
        "resetpass-submit-loggedin": "Alterar palavra-passe",
        "right-changetags": "Adicionar ou remover [[Special:Tags|etiquetas]] arbitrárias em revisões e entradas de registo individuais",
        "grant-generic": "Pacote de direitos \"$1\"",
        "grant-group-page-interaction": "Interagir com páginas",
-       "grant-group-file-interaction": "Interagir com multimédia",
+       "grant-group-file-interaction": "Interagir com conteúdo multimédia",
        "grant-group-watchlist-interaction": "Interagir com a sua lista de vigiados",
        "grant-group-email": "Enviar correio electrónico",
        "grant-group-high-volume": "Realizar actividades em grande quantidade",
        "action-createpage": "criar páginas",
        "action-createtalk": "criar páginas de discussão",
        "action-createaccount": "criar esta conta de utilizador",
+       "action-autocreateaccount": "criar automaticamente esta conta de utilizador externa",
        "action-history": "ver histórico desta página",
        "action-minoredit": "marcar esta edição como uma edição menor",
        "action-move": "mover esta página",
        "uploaded-script-svg": "Encontrou um elemento scriptable no ficheiro \"$1\" SVG carregado.",
        "uploaded-hostile-svg": "Encontrou-se um código CSS não seguro no elemento de estilo do arquivo SVG carregado.",
        "uploaded-event-handler-on-svg": "Não está permitido configurar atributos controladores de eventos <code>$1=\"$2\"</code> nos arquivos SVG.",
-       "uploaded-href-attribute-svg": "Não se permite que os arquivos SVG contenham os atributos de <code>&lt;$1 $2=\"$3\"&gt;</code> apontando a recursos não locais (p.ex. http://, javascript:,etc)",
        "uploadscriptednamespace": "Este ficheiro SVG contém um domínio que não é permitido \"$1\".",
        "uploadinvalidxml": "Erro detectado na análise do XML do ficheiro carregado.",
        "uploadvirus": "O ficheiro contém um vírus! \nDetalhes: $1",
        "upload-form-label-infoform-description": "Descrição",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nome do ficheiro",
+       "foreign-structured-upload-form-label-own-work": "Este é minha obra própria",
        "foreign-structured-upload-form-label-infoform-categories": "Categorias",
        "foreign-structured-upload-form-label-infoform-date": "Data",
        "foreign-structured-upload-form-label-own-work-message-local": "Confirmo que estou a carregar este ficheiro segundo as condições de serviço e política de licenças de {{SITENAME}}.",
+       "foreign-structured-upload-form-label-not-own-work-message-local": "Se não é capaz de carregar este ficheiro sob as políticas de {{SITENAME}}, por favor feche esta janela e tente outro método.",
        "foreign-structured-upload-form-label-not-own-work-local-local": "Poderá querer experimentar [[Special:Upload|a página padrão de carregamento]].",
+       "foreign-structured-upload-form-label-own-work-message-default": "Entendo que estou a carregar este ficheiro em um repositório partilhado. Confirmo que estou a fazê-lo cumprindo com os termos de serviço e com as políticas de licenciamento.",
+       "foreign-structured-upload-form-label-not-own-work-message-default": "Se não é capaz de carregar este ficheiro sob as políticas do repositório partilhado, por favor feche esta janela e tente outro método.",
+       "foreign-structured-upload-form-label-not-own-work-local-default": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se este ficheiro puder ser carregado de acordo com suas as políticas.",
+       "foreign-structured-upload-form-label-own-work-message-shared": "Confirmo que sou o proprietário dos direitos de autor deste ficheiro, e aceito partilhar irrevogavelmente este ficheiro para o Wikimedia Commons nos termos da licença [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuição-CompartilhaIgual 4.0], e concordo com os [https://wikimediafoundation.org/wiki/Terms_of_Use Termos de Utilização].",
+       "foreign-structured-upload-form-label-not-own-work-message-shared": "Se não é o proprietário dos direitos de autor deste ficheiro, ou caso deseje partilhá-lo sob uma licença diferente, considere utilizar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Assistente de Envio de Ficheiros do Commons].",
+       "foreign-structured-upload-form-label-not-own-work-local-shared": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento em {{SITENAME}}]], se o sítio aceitar o carregamento deste ficheiro de acordo com as suas políticas.",
        "foreign-structured-upload-form-2-label-intro": "Obrigado por doar uma imagem para utilização em {{SITENAME}}. Deverá continuar apenas se cumprir algumas condições:",
+       "foreign-structured-upload-form-2-label-ownwork": "Deve ser inteiramente <strong>sua obra própria</strong>, não apenas retirada da Internet",
+       "foreign-structured-upload-form-2-label-noderiv": "Não pode conter <strong>nenhuma obra de qualquer outra pessoa</strong>, ou inspirado por elas",
+       "foreign-structured-upload-form-2-label-useful": "Deve ser <strong>educativo e útil</strong> para ensinar a outros",
+       "foreign-structured-upload-form-2-label-ccbysa": "Deve estar <strong>aceito para publicar para sempre</strong> na Internet nos termos da licença [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Atribuição-CompartilhaIgual 4.0]",
+       "foreign-structured-upload-form-2-label-alternative": "Caso nenhum dos itens acima for o correto, ainda pode ser capaz de carregar este ficheiro ao utilizar o [https://commons.wikimedia.org/wiki/Special:UploadWizard Assistente de Envio de Ficheiros do Commons], desde que esteja disponível sob uma licença livre.",
        "foreign-structured-upload-form-3-label-yes": "Sim",
        "foreign-structured-upload-form-3-label-no": "Não",
        "foreign-structured-upload-form-4-label-bad": "Não pode carregar imagens encontradas num motor de busca ou descarregadas de outros sítios.",
        "querypage-disabled": "Esta página especial está desativada para não prejudicar o desempenho.",
        "apihelp": "Ajuda API",
        "apihelp-no-such-module": "Módulo \"$1\" não encontrado.",
+       "apisandbox": "Testes da API",
+       "apisandbox-api-disabled": "A API está desativada neste site.",
+       "apisandbox-intro": "Use esta página para fazer experiências com a '''API de <i>web services</i> do MediaWiki'''.\nConsulte a [//www.mediawiki.org/wiki/API:Main_page documentação da API] para informações sobre o uso da API. Exemplo: [//www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo da Página Principal]. Selecione uma operação para ver mais exemplos.\n\nNote que, embora esta seja uma área de testes, as operações que executar nesta página podem modificar a wiki.",
+       "apisandbox-submit": "Fazer o pedido",
+       "apisandbox-reset": "Limpar",
+       "apisandbox-examples": "Exemplos",
+       "apisandbox-results": "Resultado",
+       "apisandbox-request-url-label": "URL do pedido:",
+       "apisandbox-request-time": "Tempo de processamento: $1",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Pesquisar referências bibliográficas",
        "booksources-search": "Pesquisar",
        "wlshowtime": "Período de tempo a mostrar:",
        "wlshowhideminor": "edições menores",
        "wlshowhidebots": "robôs",
-       "wlshowhideliu": "usuários registrados",
-       "wlshowhideanons": "usuários anônimos",
+       "wlshowhideliu": "utilizadores registados",
+       "wlshowhideanons": "utilizadores anónimos",
        "wlshowhidepatr": "edições patrulhadas",
        "wlshowhidemine": "minhas edições",
        "wlshowhidecategorization": "categorização de páginas",
index 61aaeaa..fec3079 100644 (file)
        "readonly_lag": "Error message displayed when the database is locked.",
        "nonwrite-api-promise-error": "Error message displayed when the 'Promise-Non-Write-API-Action' HTTP header is misused.",
        "internalerror": "{{Identical|Internal error}}",
-       "internalerror_info": "Parameters:\n* $1 - error message",
+       "internalerror_info": "Parameters:\n* $1 - error message\n{{Identical|Internal error}}",
        "internalerror-fatal-exception": "Error message displayed by MediaWiki itself when the request failed, inside an error box which also contains a code, a timestamp and a colon before this message.\nParameters:\n* $1 - proper name of the kind of error\n* $2 - alphanumeric code identifying the error in the server logs\n* $3 - URL which resulted in the error\n$2 and $3 are not used by default and only available for wiki customisations, because they are useful for communication to the wiki system administrator.",
        "filecopyerror": "Parameters:\n* $1 - source file name\n* $2 - destination file name",
        "filerenameerror": "Parameters:\n* $1 - old file name\n* $2 - new file name",
        "showpreview": "The text of the button to preview the page you are editing. See also {{msg-mw|showdiff}} and {{msg-mw|savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}\n{{Identical|Show preview}}",
        "showdiff": "Button below the edit page. See also {{msg-mw|Showpreview}} and {{msg-mw|Savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}\n{{Identical|Show change}}",
        "blankarticle": "Notice displayed once after the user tries to save an empty page.",
-       "anoneditwarning": "Shown when editing a page anonymously.\n\nParameters:\n* $1 – A link to log in, <nowiki>{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}</nowiki>\n* $2 – A link to sign up, <nowiki>{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}</nowiki>\n\nSee also:\n* {{msg-mw|mobile-frontend-editor-anoneditwarning}}",
+       "anoneditwarning": "Shown when editing a page anonymously.\n\nParameters:\n* $1 – A link to log in, <nowiki>{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}</nowiki>\n* $2 – A link to sign up, <nowiki>{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}</nowiki>\n\nSee also:\n* {{msg-mw|Mobile-frontend-editor-anonwarning}}",
        "anonpreviewwarning": "See also:\n* {{msg-mw|Anoneditwarning}}",
        "missingsummary": "The text \"edit summary\" is in {{msg-mw|Summary}}.\n\nSee also:\n* {{msg-mw|Missingcommentheader}}\n* {{msg-mw|Savearticle}}",
        "selfredirect": "Notice displayed once after the user tries to create a redirect to the same article.",
        "uploaded-script-svg": "Used as error message when uploading an SVG file that contains scriptable tags (script, handler, stylesheet, iframe).\n\nParameters:\n* $1 - The scriptable tag that blocked the SVG file from uploading.",
        "uploaded-hostile-svg": "Used as error message when uploading an SVG file that contains unsafe CSS.",
        "uploaded-event-handler-on-svg": "Used as error message when uploading an SVG file that contains event-handler attributes.\n\nParameters:\n* $1 - The event-handler attribute that is being modified in the SVG file.\n* $2 - The value that is given to the event-handler attribute.",
-       "uploaded-href-attribute-svg": "Used as error message when uploading an SVG file that contains href attribute with non-local target (like http://, javascript:, etc).\n\nParameters:\n* $1 - The name of the tag containing href attribute.\n* $2 - The attribute \"href\".\n* $3 - The value of the href attribute.",
+       "uploaded-href-attribute-svg": "Used as error message when uploading an SVG file that contains href attribute with disallowed target.\n\nParameters:\n* $1 - The name of the tag containing href attribute.\n* $2 - The attribute \"href\".\n* $3 - The value of the href attribute.",
        "uploaded-href-unsafe-target-svg": "Used as error message when uploading an SVG file that contains href to some unsafe target.\n\nParameters:\n* $1 - The name of the tag containing href attribute.\n* $2 - The attribute \"href\".\n* $3 - The value of the href attribute.",
        "uploaded-animate-svg": "Used as error message when uploading an SVG file that contains the element <animate> that might be changing href.\n\nParameters:\n* $1 - The name of the HTML tag.\n* $2 - The name of the attribute.\n* $3 - The value getting assigned to the attribute.",
        "uploaded-setting-event-handler-svg": "Used as error message when uploading an SVG file that sets the event-handler attribute, using <set> or <animate> tags.\n\nParameters:\n* $1 - The name of the HTML tag.\n* $2 - The name of the attribute.\n* $3 - The value getting assigned to the attribute.",
        "withoutinterwiki-submit": "{{Identical|Show}}",
        "fewestrevisions": "{{doc-special|FewestRevisions}}",
        "fewestrevisions-summary": "{{doc-specialpagesummary|fewestrevisions}}",
-       "nbytes": "Message used on the history page of a wiki page. Each version of a page consist of a number of bytes. $1 is the number of bytes that the page uses. Uses plural as configured for a language based on $1.",
+       "nbytes": "Message used on the history page of a wiki page. Each version of a page consist of a number of bytes. $1 is the number of bytes that the page uses. Uses plural as configured for a language based on $1.\n{{Identical|Byte}}",
        "ncategories": "Used in the special page '[[Special:MostCategories]]' in brackets after each entry on the list signifying how many categories a page is part of. $1 is the number of categories.",
        "ninterwikis": "Used in the special page '[[Special:MostInterwikis]]' in brackets after each entry on the list signifying how many interwikis a page is part of.\n\nParameters:\n* $1 - the number of interwiki links",
        "nlinks": "This appears in brackets after each entry on the special page [[Special:MostLinked]]. $1 is the number of wiki links.",
        "apihelp-summary": "{{doc-specialpagesummary|ApiHelp}}",
        "apihelp-no-such-module": "Used as an error message if the requested API module is not found.\n\nParameters:\n* $1 - Requested module name",
        "apihelp-link": "{{notranslate}} Used to construct a link to [[Special:ApiHelp]]\n\nParameters:\n* $1 - module to link\n* $2 - link text",
+       "apisandbox": "{{doc-special|ApiSandbox}}",
+       "apisandbox-summary": "{{ignored}}\n{{doc-specialpagesummary|ApiSandbox}}",
+       "apisandbox-jsonly": "Displayed as an error message if the browser does not have JavaScript enabled.",
+       "apisandbox-api-disabled": "Displayed as an error message if the API is disabled on this site.",
+       "apisandbox-intro": "Displayed (from JavaScript) as a header on [[Special:ApiSandbox]].",
+       "apisandbox-fullscreen": "JavaScript button label for enabling full-page mode.",
+       "apisandbox-fullscreen-tooltip": "Tooltip for the {{msg-mw|apisandbox-fullscreen}} button.",
+       "apisandbox-unfullscreen": "JavaScript button label for disabling full-page mode.",
+       "apisandbox-unfullscreen-tooltip": "Tooltip for the {{msg-mw|apisandbox-unfullscreen}} button.",
+       "apisandbox-submit": "JavaScript button label for submitting the request.",
+       "apisandbox-reset": "JavaScript button label for clearing the form.\n{{Identical|Clear}}",
+       "apisandbox-retry": "JavaScript button label for retrying the submission.\n{{Identical|Retry}}",
+       "apisandbox-loading": "JavaScript message displayed while data is loading.\n\nParameters:\n* $1 - Module being loaded",
+       "apisandbox-load-error": "Displayed as an error message from JavaScript when data failed to load.\n\nParameters:\n* $1 - Module being loaded\n* $2 - Error message from the API",
+       "apisandbox-no-parameters": "Displayed (from JavaScript) when the loaded API module has no parameters.",
+       "apisandbox-helpurls": "JavaScript button label for showing help URLs.",
+       "apisandbox-examples": "JavaScript button label for showing example queries.\n{{Identical|Example}}",
+       "apisandbox-dynamic-parameters": "JavaScript fieldset legend for the section containing the widgets to add arbitrary parameters to a module that can accept dynamic parameters.",
+       "apisandbox-dynamic-parameters-add-label": "JavaScript label for the widget to add a new arbitrary parameter.",
+       "apisandbox-dynamic-parameters-add-placeholder": "JavaScript text field placeholder for the widget to add a new arbitrary parameter.",
+       "apisandbox-dynamic-error-exists": "Displayed as an error message from JavaScript when trying to add a new arbitrary parameter with a name that already exists. Parameters:\n* $1 - Parameter name that failed.",
+       "apisandbox-deprecated-parameters": "JavaScript button label and fieldset legend for separating deprecated parameters in the UI.",
+       "apisandbox-fetch-token": "Tooltop for the button that fetches a CSRF token.",
+       "apisandbox-submit-invalid-fields-title": "Title for a JavaScript error message when fields are invalid.",
+       "apisandbox-submit-invalid-fields-message": "Content for a JavaScript error message when fields are invalid.",
+       "apisandbox-results": "JavaScript tab label for the tab displaying the API query results.\n{{Identical|Result}}",
+       "apisandbox-sending-request": "JavaScript message displayed while the request is being sent.",
+       "apisandbox-loading-results": "JavaScript message displayed while the response is being read.",
+       "apisandbox-results-error": "Displayed as an error message from JavaScript when the request failed.\n\nParameters:\n* $1 - Error message",
+       "apisandbox-request-url-label": "Label for the text field displaying the URL used to make this request.",
+       "apisandbox-request-time": "Label and value for displaying the time taken by the request.\n\nParameters:\n* $1 - Time taken in milliseconds",
+       "apisandbox-results-fixtoken": "JavaScript button label",
+       "apisandbox-results-fixtoken-fail": "Displayed as an error message from JavaScript when a CSRF token could not be fetched.\n\nParameters:\n* $1 - Token type",
+       "apisandbox-alert-page": "Tooltip for the alert icon on a module's page tab when the page contains fields with issues.",
+       "apisandbox-alert-field": "Tooltip for the alert icon on a field when the field has issues.",
        "booksources": "{{doc-special|BookSources}}\n\n'''This message shouldn't be changed unless it has serious mistakes.'''\n\nIt's used as the page name of the configuration page of [[Special:BookSources]]. Changing it breaks existing sites using the default version of this message.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-summary": "{{doc-specialpagesummary|booksources}}",
        "booksources-search-legend": "Box heading on [[Special:BookSources|book sources]] special page. The box is for searching for places where a particular book can be bought or viewed.",
        "version-hook-subscribedby": "Shown in [[Special:Version]]",
        "version-version": "{{Optional}}\nUsed in [[Special:Version]]. Preceded by the MediaWiki extension name.\n\nParameters:\n* $1 - version number of the extension",
        "version-no-ext-name": "Used in [[Special:Version]], in the rows of the main table when a name for an extension is not provided.",
-       "version-svn-revision": "{{Identical|Revision}}{{optional}}\nUsed in [[Special:Version]], preceeding the Subversion revision numbers of the extensions loaded inside brackets, like this: \"({{int:version-revision}} r012345\"). Parameters:\n* $1 - (Unused) directory revision number or empty string\n* $2 - checkout revision number",
        "version-license": "Used specifically for the MediaWiki software.\n\nUsed as heading in [[Special:Version]].",
        "version-ext-license": "Used in [[Special:Version]].\n\nUsed as label for the link pointing to the extension's license page. e.g. [[Special:Version/License/Maps]]\n{{Identical|License}}",
        "version-ext-colheader-name": "Column header for the name of an extension.\n{{Identical|Extension}}",
        "version-libraries-license": "Column header for the library's license\n{{Identical|License}}",
        "version-libraries-description": "Column header for the library's description\n{{Identical|Description}}",
        "version-libraries-authors": "Column header for the library's authors\n{{Identical|Author}}",
-       "redirect": "{{doc-special|Redirect}}\nThis means \"Redirect by file'''name''', user '''ID''', page '''ID''', or revision ID\".",
+       "redirect": "{{doc-special|Redirect}}\nThis means \"Redirect by file '''name''', user '''ID''', page '''ID''', revision '''ID''', or log '''ID'''\".",
        "redirect-legend": "Legend of fieldset around input box in [[Special:Redirect]]",
        "redirect-text": "Inside fieldset for [[Special:Redirect]]",
        "redirect-summary": "Shown at top of [[Special:Redirect]]",
index 6f0cdc2..21c998e 100644 (file)
        "uploaded-script-svg": "S-a găsit elementul „$1” scriptabil în fișierul SVG încărcat.",
        "uploaded-hostile-svg": "S-a descoperit CSS vulnerabil în elementul de stil al fișierului SVG încărcat.",
        "uploaded-event-handler-on-svg": "Setarea atributelor <code>$1=„$2”</code> de gestionare a evenimentului nu este permisă pentru fișierele SVG.",
-       "uploaded-href-attribute-svg": "Atributele href <code>&lt;$1 $2=„$3”&gt;</code> cu alte destinații decât cele locale (de ex. http://, javascript: etc.) nu sunt permise în fișierele SVG.",
        "uploaded-href-unsafe-target-svg": "S-a găsit href către o destinație nesigură <code>&lt;$1 $2=„$3”&gt;</code> în fișierul SVG încărcat.",
        "uploaded-animate-svg": "S-a găsit în fișierul SVG încărcat eticheta „animate” care ar putea modifica valoarea href folosind atributul „from” <code>&lt;$1 $2=„$3”&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Setarea atributelor de gestionare a evenimentului nu este permisă; s-a găsit <code>&lt;$1 $2=„$3”&gt;</code> în fișierul SVG încărcat.",
        "querypage-disabled": "Această pagină specială este dezactivată din motive de performanță.",
        "apihelp": "Ajutor API",
        "apihelp-no-such-module": "Modulul „$1” nu a fost găsit.",
+       "apisandbox": "Cutia cu nisip pentru API",
+       "apisandbox-api-disabled": "API este dezactivat pe acest site.",
+       "apisandbox-submit": "Efectuați cererea",
+       "apisandbox-reset": "Curăță",
+       "apisandbox-examples": "Exemplu",
+       "apisandbox-results": "Rezultat",
+       "apisandbox-request-url-label": "URL cerere:",
+       "apisandbox-request-time": "Durata cererii: $1",
        "booksources": "Surse de cărți",
        "booksources-search-legend": "Căutare surse pentru cărți",
        "booksources-search": "Caută",
index c607569..1dbfd5f 100644 (file)
        "passwordreset-emailtext-ip": "Quacchedune (pò essere tu, da 'u 'ndirizze IP $1) ha richieste 'na mail pe arrecurdarse de le dettaglie d'u cunde sue pe {{SITENAME}} ($4). {{PLURAL:$3|'U cunde utende seguende jè|le cunde utinde seguende sonde}} associate cu st'indirizze e-mail:\n\n$2\n\n{{PLURAL:$3|Sta passuord temboranèe scade|Ste passuord temboranèe scadene}} 'mbrà {{PLURAL:$5|'nu sciurne|$5 sciurne}}.\nTu avissa trasè e scacchià 'na passuord nova. Ce quacchedun'otre ha fatte sta richieste, o ce tu t'è arrecurdate 'a passuord origgenale toje, e non g'a vuè ccu cange cchiù, tu puè ignorà stu messagge e condinuà ausanne 'a passuord vecchie.",
        "passwordreset-emailtext-user": "L'utende $1 sus a {{SITENAME}} ave richieste 'na mail pe arrecurdarse le dettaglie d'u cunde sue pe {{SITENAME}}\n($4). {{PLURAL:$3|'U cunde utende seguende jè|le cunde utinde seguende sonde}} associate cu st'indirizze e-mail:\n\n$2\n\n{{PLURAL:$3|Sta passuord temboranèe scade|Ste passuord temboranèe scadene}}  'mbrà {{PLURAL:$5|'nu sciurne|$5 sciurne}}.\nTu avissa trasè e scacchià 'na passuord nova. Ce quacchedun'otre ha fatte sta richieste, o ce tu t'è arrecurdate 'a passuord origgenale toje, e non g'a vuè ccu cange cchiù, tu puè ignorà stu messagge e condinuà ausanne 'a passuord vecchie.",
        "passwordreset-emailelement": "Nome utende: \n$1\n\nPassuord temboranèe: \n$2",
-       "passwordreset-emailsent": "Ce quiste jè 'n'e-mail pu cunde tune, allore 'na password azzerate ha state mannate addà.",
+       "passwordreset-emailsentemail": "Ce quiste jè 'n'e-mail pu cunde tune, allore 'na password azzerate ha state mannate addà.",
        "passwordreset-emailsent-capture": "'Na e-mail pe azzeramende d'a passuord ha state mannate, ca jè fatte vedè aqquà sotte.",
        "passwordreset-emailerror-capture": "'Na e-mail de azzeramende d'a passuord ha state generate, ca jè fatte vedè aqquà sotte, ma 'u 'nvie a {{GENDER:$2|l'utende}} ha fallite: $1",
        "changeemail": "Cange o live 'u 'ndirizze e-mail",
        "prefs-help-prefershttps": "Sta preferenze pigghie effette sulamende quanne tràse arrete.",
        "prefswarning-warning": "Tu è fatte cangiaminde sus a le preferenze tune ca non g'onne state angore reggistrate.\nCe tu lasse sta pàgene senze ca è cazzate \"$1\" le preferenze tune non g'avènene aggiornate.",
        "prefs-tabs-navigation-hint": "Conziglie: Tu puè ausà le freccie de destre e sinistre pe navigà 'mbrà le schede de l'elenghe.",
-       "email-address-validity-valid": "L'indirizze e-mail pare valide",
-       "email-address-validity-invalid": "Mitte 'n'indirizze e-mail valide",
        "userrights": "Gestione de le deritte utende",
        "userrights-lookup-user": "Gestisce le gruppe de l'utinde",
        "userrights-user-editname": "Mitte 'nu nome utende:",
        "right-blockemail": "Blocche l'utente a fà mannà le email",
        "right-hideuser": "Bluecche 'nu cunde utende, scunnènnele da 'u pubbliche",
        "right-ipblock-exempt": "Zumbe le blocche de l'IP, auto blocche e le blocche a indervalle",
-       "right-proxyunbannable": "Zumbe automaticamende le condrolle d'u proxy",
        "right-unblockself": "Sbluecche da sule",
        "right-protect": "Cange le levèlle de protezione e cange le pàggene prutette",
        "right-editprotected": "Cange le pàggene prutette (senza protezzione a cascata)",
        "uploaded-script-svg": "Acchiate elemende pe script \"$1\" jndr'à 'u file SVG carecate.",
        "uploaded-hostile-svg": "Acchiate 'nu CSS insecure ndr'à l'elemende de stile d'u file SVG carecate.",
        "uploaded-event-handler-on-svg": "'A 'mbostazione de le attribute de gestione de l'evende <code>$1=\"$2\"</code> non ge se pò ffà cu le file SVG.",
-       "uploaded-href-attribute-svg": "le attribbute href <code>&lt;$1 $2=\"$3\"&gt;</code> cu le destinaziune de fore (p.e. http://, javascript:, etc) non ge se ponne mettere jndr'à le file SVG.",
        "uploaded-href-unsafe-target-svg": "Acchiate 'na destinazione href non secure <code>&lt;$1 $2=\"$3\"&gt;</code> jndr'à 'u file SVG carecate.",
        "uploadscriptednamespace": "Stu file SVG tène 'nu namespace illegale '$1'",
        "uploadinvalidxml": "L'XML jndr'à 'u file carecate non ge pò essere analizzate.",
        "filewasdeleted": "'Nu file ca se chiamave cumme a quidde tue ha state apprime carecate e pò ha state scangellete.\nTu avissa condrollà 'u $1 apprime ca condinue cu 'u carecamende.",
        "filename-bad-prefix": "'U nome d'u file ca tu ste careche accumenze pe '''\"$1\"''', ca normalmende jè 'u nome ca assegne a machena fotografeche e non 'nu nome descrittive d'u file ca vuè ccu careche.\nPe piacere scacchie 'n'otre nome ca jè cchiù descrittive.",
        "filename-prefix-blacklist": " #<!-- leave this line exactly as it is --> <pre>\n# 'A sindasse jè 'a seguende:\n#   * Ogneccose da 'u carattere \"#\" 'mbonde 'a fine d'a linèe jè 'nu commende\n#   * Ogne linèe chiene jè 'nu prefisse pe nome de file tipece assignate automaticamende da le fotocamere\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # quacche telefone mobbile\nIMG # generiche\nJD # Jenoptik\nMGP # Pentax\nPICT # misckate\n #</pre> <!-- leave this line exactly as it is -->",
-       "upload-success-subj": "Carecamende sciute apposte",
-       "upload-success-msg": "'U carecamende tue da [$2] ha riuscite. Mò jè disponibbele aqquà: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Careche le probbleme",
-       "upload-failure-msg": "Stave 'nu probbleme cu 'u carecamende tune da [$2]:\n\n$1",
-       "upload-warning-subj": "Avvise de carecamende",
-       "upload-warning-msg": "Stave 'nu probbleme cu 'u carecamende tune da [$2]. Tu puè turnà rrete a 'u [[Special:Upload/stash/$1|module de carecamende]] pe aggiustà stu probbleme.",
        "upload-proto-error": "Protocolle scorrette",
        "upload-proto-error-text": "Le carecaminde remote onne abbesogne de le URL ca accumenzene cu 'a parole <code>http://</code> o <code>ftp://</code>.",
        "upload-file-error": "Errore inderne",
        "querypage-disabled": "Sta pàgena speciale jè desabbilitate pe mutive de prestaziune.",
        "apihelp": "Aijute de l'API",
        "apihelp-no-such-module": "Module \"$1\" none acchiate.",
+       "apisandbox": "Sandbox de l'API",
+       "apisandbox-api-disabled": "API non g'è abbiletate sus a stu site.",
+       "apisandbox-intro": "Ause sta pàgene pe sperimendà cu le '''API de le web service pe MediaUicchi'''.\nFà referimende a [//www.mediawiki.org/wiki/API:Main_page 'a documendazione de l'API] pe cchiù dettaglie de l'ause de l'API.\nEsembie: [//www.mediawiki.org/wiki/API#A_simple_example pigghie 'u condenute d'a Pàgene Prengepàle]. Scacchie 'n'azione pe 'ndrucà otre esembie.\n\nVide ca, pure ca queste jè 'na buatte de sabbie tu puè carrescià le cangiaminde de sta pàgene sus 'a uicchi.",
+       "apisandbox-submit": "Fà 'na richieste",
+       "apisandbox-reset": "Pulizze",
+       "apisandbox-examples": "Esembie",
+       "apisandbox-results": "Resultate",
+       "apisandbox-request-url-label": "URL richieste:",
+       "apisandbox-request-time": "Tiembe cercate: $1",
        "booksources": "Sorgende de le libbre",
        "booksources-search-legend": "Cirche pe le fonde de le libbre",
        "booksources-isbn": "ISBN:",
        "wlheader-showupdated": "* Le pàggene ca onne state cangiate da l'urtema visite avènene fatte vedè in '''grascette'''",
        "wlnote": "Aqquà sotte {{PLURAL:$1|ste l'urteme cangiamende|stonne l'urteme <strong>$1</strong> cangiaminde}} jndr'à {{PLURAL:$2|l'urtema ore|l'urteme <strong>$2</strong> ore}}, jndr'à $3, $4.",
        "wlshowlast": "Vide l'urteme $1 ore $2 sciurne",
-       "watchlistall2": "tutte",
        "watchlist-options": "Opzione d'a liste de le pàggene condrollete",
        "watching": "Fà vedè...",
        "unwatching": "No fà vedè...",
        "movenosubpage": "Sta pàgene non ge tène sottopàggene.",
        "movereason": "Raggione:",
        "revertmove": "a smerse",
-       "delete_and_move": "Scangille e spuèste",
        "delete_and_move_text": "== Scangellazzione richieste ==\n'A pàgene de destinazione \"[[:$1]]\" esiste già.\nTu à vuè ccu scangille o vuè ccù iacchie 'nu mode pe spustarle?",
        "delete_and_move_confirm": "Sine, scangille 'a pàggene",
        "delete_and_move_reason": "'U scangellamende avène fatte pe spustà da \"[[$1]]\"",
        "version-hook-subscribedby": "Sottoscritte da",
        "version-version": "($1)",
        "version-no-ext-name": "[nisciune nome]",
-       "version-svn-revision": "(r$2)",
        "version-license": "Licenze",
        "version-ext-license": "Licenze",
        "version-ext-colheader-name": "Estenzione",
        "mw-widgets-dateinput-no-date": "Nisciune date scacchiate",
        "mw-widgets-titleinput-description-new-page": "'a pàgene non g'esiste angore",
        "mw-widgets-titleinput-description-redirect": "redirezionate sus a $1",
-       "api-error-blacklisted": "Pe piacere scacchie 'nu titole diverse, descrittive."
+       "api-error-blacklisted": "Pe piacere scacchie 'nu titole diverse, descrittive.",
+       "randomrootpage": "Pàgene prengepàle a uecchije"
 }
index 87c383d..108725a 100644 (file)
@@ -87,7 +87,8 @@
                        "INS Pirat",
                        "Краснорядцева Елена",
                        "Frhdkazan",
-                       "Ядерный Трамвай"
+                       "Ядерный Трамвай",
+                       "Исмаил Садуев"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "uploaded-script-svg": "Найден небезопасный элемент с поддержкой сценариев «$1» в загруженном SVG-файле.",
        "uploaded-hostile-svg": "Найден небезопасный CSS-код в элементе стиля загруженного SVG-файла.",
        "uploaded-event-handler-on-svg": "Установка атрибутов обработчика событий <code>$1=\"$2\"</code> не разрешено для SVG-файлов.",
-       "uploaded-href-attribute-svg": "В SVG-файлах не допускаются href-атрибуты <code>&lt;$1 $2=\"$3\"&gt;</code> с нелокальной целью (т.е. http://, javascript:, и пр.).",
-       "uploaded-href-unsafe-target-svg": "В загруженном SVG-файле найдена ссылка на небезопасную цель <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "В SVG-файлах href-атрибуты для ссылки, найденной в <code><$1 $2=\"$3\"></code>, разрешены только цели, начинающиеся на http:// или https://.",
+       "uploaded-href-unsafe-target-svg": "В загруженном SVG-файле найдены небезопасные данные: URI <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "Найден тег «animate», который может изменять ссылку с помощью «from»-атрибута <code>&lt;$1 $2=\"$3\"&gt;</code> в загруженном SVG-файле.",
        "uploaded-setting-event-handler-svg": "Установка атрибутов обработчика событий заблокирована, в загруженном SVG-файле найден код <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Использование тега «set» для добавления атрибута «href» в родительский элемент заблокировано.",
        "querypage-disabled": "Эта спецстраница отключена для повышения производительности.",
        "apihelp": "Справка по API",
        "apihelp-no-such-module": "Модуль «$1» не найден.",
+       "apisandbox": "Песочница API",
+       "apisandbox-jsonly": "Для использования API-песочницы требуется JavaScript.",
+       "apisandbox-api-disabled": "API отключен на этом сайте.",
+       "apisandbox-intro": "Используйте эту страницу для экспериментов с <strong>MediaWiki API</strong>.\nОбратитесь к [[mw:API:Main page|документации API]] для получения дополнительной информации об использовании API. Например, о том, [//www.mediawiki.org/wiki/API#A_simple_example как получить содержание Заглавной страницы]. Выберите действие, чтобы увидеть другие примеры.\nОбратите внимание, что, хотя это и песочница, действия, выполненные на этой странице, могут внести изменения в вики.",
+       "apisandbox-fullscreen": "Развернуть панель",
+       "apisandbox-fullscreen-tooltip": "Развернуть панель песочницы, чтобы заполнить окно браузера.",
+       "apisandbox-unfullscreen": "Показать страницу",
+       "apisandbox-unfullscreen-tooltip": "Уменьшить панель песочницы, чтоб стали доступны навигационные ссылки MediaWiki.",
+       "apisandbox-submit": "Сделать запрос",
+       "apisandbox-reset": "Очистить",
+       "apisandbox-retry": "Повторить",
+       "apisandbox-loading": "Загрузка информации для API-модуля «$1»…",
+       "apisandbox-load-error": "Произошла ошибка при загрузке информации для API-модуля «$1»: $2",
+       "apisandbox-no-parameters": "У этого API-модуля нет параметров.",
+       "apisandbox-helpurls": "Ссылки на справочные материалы",
+       "apisandbox-examples": "Примеры",
+       "apisandbox-dynamic-parameters": "Дополнительные параметры",
+       "apisandbox-dynamic-parameters-add-label": "Добавить параметр:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Имя параметра",
+       "apisandbox-dynamic-error-exists": "Параметр с именем «$1» уже существует.",
+       "apisandbox-deprecated-parameters": "Устаревшие параметры",
+       "apisandbox-fetch-token": "Автозаполнение токена",
+       "apisandbox-submit-invalid-fields-title": "Некоторые поля некорректны",
+       "apisandbox-submit-invalid-fields-message": "Пожалуйста, исправьте отмеченные поля и попробуйте снова.",
+       "apisandbox-results": "Результаты",
+       "apisandbox-sending-request": "Отправка API-запроса…",
+       "apisandbox-loading-results": "Получение API-результатов…",
+       "apisandbox-results-error": "Произошла ошибка при загрузке API-ответа на запрос: $1.",
+       "apisandbox-request-url-label": "URL-адрес запроса:",
+       "apisandbox-request-time": "Время запроса: {{PLURAL:$1|$1 мс}}",
+       "apisandbox-results-fixtoken": "Исправьте токен и повторите отправку",
+       "apisandbox-results-fixtoken-fail": "Не удалось вызвать токен «$1».",
+       "apisandbox-alert-page": "Поля на этой странице некорректны.",
+       "apisandbox-alert-field": "Значение этого поля является недопустимым.",
        "booksources": "Источники книг",
        "booksources-search-legend": "Поиск информации о книге",
        "booksources-isbn": "ISBN:",
index 2a53b49..8a20bc4 100644 (file)
@@ -48,6 +48,7 @@
        "tog-watchlisthidebots": "Кэтээн көрүү тиһигэр робот уларытыытын көрдөрүмэ",
        "tog-watchlisthideminor": "Кыра уларытыылары кэтээмэ",
        "tog-watchlisthideliu": "Бэлиэтэммит кыттааччылар уларытыыларын кэтиир тиһиккэ көрдөрүмэ",
+       "tog-watchlistreloadautomatically": "Сиидэ уларыйда да кэтээһин тиһилигин саҥардан ис(JavaScript баар буолуохтаах)",
        "tog-watchlisthideanons": "Ааттарын эппэтэх кыттааччылар уларытыыларын кэтээһин тиһигэр көрдөрүмэ",
        "tog-watchlisthidepatrolled": "Ботурууллааччы көрбүт көннөрүүтүн кэтээһин испииһэгэр көрдөрүмэ",
        "tog-watchlisthidecategorization": "Сирэй категорияларын көрдөрүмэ",
        "october-date": "Алтынньы $1",
        "november-date": "Сэтинньи $1",
        "december-date": "Ахсынньы $1",
+       "period-am": "ОИ",
+       "period-pm": "ОК",
        "pagecategories": "{{PLURAL:$1|Категория|Категориялар}}",
        "category_header": "\"$1\" категория ыстатыйалара",
        "subcategories": "Субкатегориялар",
        "viewsourceold": "исходнигын көрүү",
        "editlink": "көннөрөргө",
        "viewsourcelink": "исходнигын көрүү",
-       "editsectionhint": "$1 Ñ\81екÑ\86иÑ\8fнÑ\8b уларыт",
+       "editsectionhint": "$1 Ñ\81иÑ\8dкÑ\81ийÑ\8dни уларыт",
        "toc": "Ис хоһооно",
        "showtoc": "көрдөр",
        "hidetoc": "көрдөрүмэ",
        "virus-scanfailed": "скан сыыһата (куода $1)",
        "virus-unknownscanner": "биллибэт антивирус:",
        "logouttext": "'''Эн тиһиликтэн таҕыстыҥ.'''\n\nСорох сирэйдэр өссө даҕаны эйигин урукку ааккынан көрдөрүөхтэрин сөп, ону суох гыныаххын баҕардаххына интэриниэт көрдөрөөччүҥ кээһин ыраастаа.",
+       "cannotlogoutnow-title": "Сип-билин тахсар кыаллыбат",
+       "cannotlogoutnow-text": "Маны $1 туһанар кэмҥэ тахсар кыах суох.",
        "welcomeuser": "Нөрүөн нөргүй, $1!",
        "welcomecreation-msg": "Аатыҥ бэлиэтэннэ.\n{{SITENAME}} ситим-сиргэ үлэлииргэ табыгастаах буоллун диэн [[Special:Preferences|тус туруорууларгын]] уларытыаххын сөп.",
        "yourname": "Кыттааччы аатыҥ:",
        "remembermypassword": "Миигин бу көмпүүтэргэ сигээ ($1 {{PLURAL:$1|күн|күнтэн ордуга суох}})",
        "userlogin-remembermypassword": "Тиһиликтэн тахсыма",
        "userlogin-signwithsecure": "Бигэ холбонуу",
+       "cannotloginnow-title": "Сип-билигин киирэр кыах суох",
+       "cannotloginnow-text": "Маны $1 туһанар кэмҥэ киирэр кыах суох.",
        "yourdomainname": "Эн дөмүөнүҥ:",
        "password-change-forbidden": "Бу биикигэ киирии тылы уоарытар табыллыбат.",
        "externaldberror": "Тас киирии билиитин олоҕун сыыһата буолла, эбэтэр тас киирии билииҥ олоҕун саҥардар кыаҕыҥ суох.",
        "wrongpasswordempty": "Киирии тылгын суруйбатаххын. Өссө киирэн көр.",
        "passwordtooshort": "Киирии тылыҥ наһаа кылгас.\nКырата {{PLURAL:$1|1 бэлиэлээх|$1 бэлиэлээх}} буолуохтаах.",
        "passwordtoolong": "Аһарык {{PLURAL:$1|1 бэлиэттэн|$1 бэлиэттэн}} уһун буолуо суохтаах.",
+       "passwordtoopopular": "Элбэхтэ туттуллар аһарыктары туттар сатаммат. Бука диэн атын аһарыкта тал.",
        "password-name-match": "Киирии тыл ааккыттан атын буолуохтаах.",
        "password-login-forbidden": "Маннык ааты уонна киирии тылы туһаныы бобуллар.",
        "mailmypassword": "Киирии тылы саҥардыы",
        "resetpass_submit": "Киирии тылы уларыт уонна киир",
        "changepassword-success": "Киирии тылыҥ этэҥҥэ уларыйда!",
        "changepassword-throttled": "Ааккын аһара элбэхтик билиһиннэрэ сатаатыҥ.\nБука диэн $1 буолан баран өссө киирэн көрөөр.",
+       "botpasswords": "Оруобаттар аһарыктара",
+       "botpasswords-disabled": "Оруобаттар аһарыктара араарыллыбыттар.",
+       "botpasswords-no-central-id": "Оруобат аһарыгын туһанарга кииннэммит ааккынан киириэхтээххин.",
+       "botpasswords-existing": "Билигин баар оруобат аһарыктара",
+       "botpasswords-createnew": "Оруобат саҥа аһарыгын оҥор",
+       "botpasswords-editexisting": "Оруобат аһарыгын уларыт",
+       "botpasswords-label-appid": "Оруобат аата:",
+       "botpasswords-label-create": "Оҥоруу",
+       "botpasswords-label-update": "Саҥарт",
+       "botpasswords-label-cancel": "Бигэргэтимэ",
+       "botpasswords-label-delete": "Сот",
+       "botpasswords-label-resetpassword": "Аһарыгы саҥаттан",
+       "botpasswords-label-grants": "Туттуллар көҥүллэр:",
+       "botpasswords-label-restrictions": "Туттарга хааччахтаах:",
+       "botpasswords-label-grants-column": "Көҥүллэннэ",
+       "botpasswords-bad-appid": "Маннык аат «$1» сатаммат.",
+       "botpasswords-insert-failed": "«$1» диэн ааттаах оруобаты эбэр табыллыбата. Баҕар хайыы-үйэ эбиллибитэ буолаарай?",
+       "botpasswords-created-title": "Оруобат аһарыга оҥоһулунна",
+       "botpasswords-created-body": "«$1» оруобат аһарыга бигэргэтилиннэ.",
+       "botpasswords-updated-title": "Оруобат аһарыга саҥардылынна",
+       "botpasswords-updated-body": "«$1» оруобат аһарыга уларытылынна.",
+       "botpasswords-deleted-title": "Оруобат аһарыга сотулунна",
+       "botpasswords-deleted-body": "«$1» оруобат аһарыга сотулунна.",
        "resetpass_forbidden": "Киирии тылы уларытар сатаммат",
        "resetpass-no-info": "Ааккын билиһиннэрдэххинэ эрэ бу сирэйгэ быһа тиийиэххин сөп.",
        "resetpass-submit-loggedin": "Киирии тылы уларытыы",
        "passwordreset-emailtext-ip": "Ким эрэ (баҕар эн буолуо, бу IP-ттан $1)  {{SITENAME}} ($4) бырайыакка киирии тылы уларытар туһунан ыйытык биэрбит.\nБу электрон аадырыһы кытта бу {{PLURAL:$3|аат ситимнээх|ааттар ситимнээхтэр}}:\n\n$2\n\nБу быстах кэмҥэ аналлаах {{PLURAL:$3|киирии тыл|кирии тыллар}} {{PLURAL:$5|биир күн үлэлиэҕэ|$5 күн үлэлиэхтэрэ}}.\nЭн тиһиликкэ ааккын этэн саҥа киирии тылы киллэриэхтээххин.\nӨскө бу ыйытыгы ыыппатах буоллаххына, эбэтэр урукку киирии тылгын өйдөөн кэлбит буоллаххына \nбу биллэриини ааххайыа суоххун сөп.\nОччоҕо урукку киирии тылыҥ оннунан хаалыа.",
        "passwordreset-emailtext-user": "$1 диэн кыттааччы  {{SITENAME}} ($4) бырайыакка киирии тылгын уларытар туһунан ыйытык ыыппыт.\nБу электрон аадырыһы кытта бу {{PLURAL:$3|аат ситимнээх|ааттар ситимнээхтэр}}\n\n$2\n\nБу быстах кэмҥэ аналлаах {{PLURAL:$3|киирии тыл|кирии тыллар}} {{PLURAL:$5|биир күн үлэлиэҕэ|$5 күн үлэлиэхтэрэ}}.\nЭн тиһиликкэ ааккын этэн саҥа киирии тылы киллэриэхтээххин.\nӨскө бу ыйытыгы ыыппатах буоллаххына, эбэтэр урукку киирии тылгын өйдөөн кэлбит буоллаххына \nбу биллэриини ааххайыа суоххун сөп.\nОччоҕо урукку киирии тылыҥ оннунан хаалыа.",
        "passwordreset-emailelement": "Кыттааччы: \n$1\n\nБыстах киирии тыл: \n$2",
-       "passwordreset-emailsent": "Өскө ааккар баайыллыбыт аадырыһы суруйбут буоллаххына, аһарык тылы уларытар туһунан сурук онно барыа.",
+       "passwordreset-emailsentemail": "Өскө бу Эн ааккар баайыллыбыт аадырыс буоллаҕына, аһарык тылы уларытар туһунан сурук барыа.",
+       "passwordreset-emailsentusername": "Өскө бу аакка баайыллыбыт аадырыс баар буоллаҕына, аһарык тылы уларытар туһунан сурук онно барыа.",
        "passwordreset-emailsent-capture": "Киирии тылы уларытар туһунан сурук аллара эмиэ көрдөрүлүннэ.",
        "passwordreset-emailerror-capture": "Манна киирии тылы уларытар туһунан сурук көрдөрүлүннэ. Ол эрэн сурук бу төрүөттэн $2 кыттааччыга сатаан барбата: $1",
        "changeemail": "Аадырыһы уларытыы уонна сотуу",
        "copyrightwarning2": "Болҕой, эн суруйбут матырыйаалгын ким баҕарар уларытар уонна суох гынар бырааптаах. Суруйбуккун уларыталларын сөбүлээбэт буоллаххына манна суруйума.<br />\nЭбиитин манна суруйдаххына, уларытыы ааптара мин буолабын, эбэтэр көҥүл туһанары уонна уларытары көҥүллүүр сиртэн ыллым диэн бигэргэтэҕин (маны көр $1).<br /> '''КИМ ЭРЭ БАС БИЛИИТИН МАННА КИНИТТЭН КӨҤҮЛЭ СУОХ УГУМА!'''",
        "editpage-cannot-use-custom-model": "Бу сирэй иһинээҕитин тутула уларыйар кыаҕа суох.",
        "longpageerror": "'''Алҕас: Суруйар кэрчиккит {{PLURAL:$1|биир килобаайт|$1 килобаайт}} ыйааһыннаах, онтуккут көҥүллэммит {{PLURAL:$2|биир килобаайты|$2 килобайты}} килобаайты куоһарар. Онон сирэй бигэргэтиллэр кыаҕа суох.'''",
-       "readonlywarning": "'''Сэрэтии: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута бигэргэнэр кыахтара суох.'''\nОнон уларытыыгын тиэкистээх билэҕэ уган баран, кэлин манна киллэриэххин сөп.\n\nХааччаҕы туруорбут дьаһабыл маннык быһаарыыны хаалларбыт: $1",
+       "readonlywarning": "<strong>Сэрэтии: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута бигэргэнэр кыахтара суох.</strong>\nОнон уларытыыгын тиэкистээх билэҕэ уган хаалларан баран, манна кэлин угуоххун сөп.\n\nХааччаҕы туруорбут дьаһабыл маннык быһаарыыны хаалларбыт: $1",
        "protectedpagewarning": "'''Сэрэтии:  Бу сирэй хатанан турар, администратор бырааптаах эрэ кыттааччылар уларытар кыахтаахтар.'''\nАллара сурунаал бүтэһик суруга көрдөрүлүннэ:",
        "semiprotectedpagewarning": "'''Биллэрии:''' Бу сирэй хатанан турар; ааттарын билиһиннэрбит эрэ кыттааччылар уларытар кыахтаахтар.\nАллара сурунаал бүтэһик суруга көрдөрүлүннэ:",
        "cascadeprotectedwarning": "<strong>Сэрэтии:</strong> Бу сирэйи дьаһабыллар эрэ уларытар кыахтаахтар, тоҕо диэтэххэ сирэй каскаднай көмүскэллээх {{PLURAL:$1|сирэй бөлөҕөр|сирэйдэр бөлөхтөрүгэр}} киирэр:",
        "permissionserrors": "Киирии алҕаһа",
        "permissionserrorstext": "Маны оҥорор кыаҕыҥ суох, {{PLURAL:$1|төрүтэ|төрүттэрэ}}:",
        "permissionserrorstext-withaction": "Бу дьайыыны ($2) оҥорор кыаҕыҥ суох.  {{PLURAL:$1|Биричиинэтэ|Биричиинэлэрэ}}:",
-       "contentmodelediterror": "Ð\91Ñ\83 Ñ\82оÑ\80Ñ\83мÑ\83 Ñ\83лаÑ\80Ñ\8bÑ\82аÑ\80 ÐºÑ\8bаÒ\95Ñ\8bÒ¥ Ñ\81Ñ\83оÑ\85 Ñ\8dбиÑ\82, Ñ\82оÒ\95о Ð´Ð¸Ñ\8dÑ\82Ñ\8dÑ\85Ñ\85Ñ\8d Ð¸Ò»Ð¸Ð½Ñ\8dÑ\8dÒ\95иÑ\82ин Ð¼Ð°Ð´Ñ\8cÑ\8bала Ð¼Ð°Ð½Ð½Ñ\8bк <code>$1</code>, Ð¾Ñ\82Ñ\82он Ñ\81иÑ\80Ñ\8dй Ð¸Ò»Ð¸Ð½Ñ\8dÑ\8dÒ\95иÑ\82ин Ð±Ð¸Ð»Ð¸Ò¥Ò¥Ð¸Ñ\82Ñ\8d Ð¼Ð°Ð½Ð½Ñ\8bк — <code>$2</code>.",
+       "contentmodelediterror": "Ð\91Ñ\83 Ñ\82оÑ\80Ñ\83мÑ\83 Ñ\83лаÑ\80Ñ\8bÑ\82аÑ\80 ÐºÑ\8bаÒ\95Ñ\8bÒ¥ Ñ\81Ñ\83оÑ\85 Ñ\8dбиÑ\82, Ñ\82оÒ\95о Ð´Ð¸Ñ\8dÑ\82Ñ\8dÑ\85Ñ\85Ñ\8d Ð¸Ò»Ð¸Ð½Ñ\8dÑ\8dÒ\95иÑ\82ин Ð¼Ð°Ð´Ñ\8cÑ\8bала Ð¼Ð°Ð½Ð½Ñ\8bк <code>$1</code>, Ð¾Ñ\82Ñ\82он Ñ\81иÑ\80Ñ\8dй Ð¸Ò»Ð¸Ð½Ñ\8dÑ\8dÒ\95иÑ\82ин Ð¼Ð°Ð´Ñ\8cÑ\8bала Ð±Ð¸Ð»Ð¸Ò¥Ò¥Ð¸Ñ\82Ñ\8d Ñ\83Ñ\80аÑ\82Ñ\8bлааÑ\85 — <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''Болҕой: сотулубут сирэйи төттөрү оҥорон эрэҕин.'''\n\nТолкуйдаан көр, кырдьык бу сирэйи оҥорор туһалаах дуо.\nАллара сотуулар уонна аат уларыйыытын сурунааллара көрдөрүлүннэ.",
        "moveddeleted-notice": "Бу сирэй сотуллубут.\nАллара сотуу уонна аат уларытыытын сурунаалларыгар онно сыһыаннаах туох суруллубута көстөр.",
        "moveddeleted-notice-recent": "Бу сирэй соторутааҕыта (тиһэх 24 чаас иһигэр) сотуллубут эбит.\nАллара сотуу уонна көһөрүү сурунаалларыгар сигэлэр көстөллөр.",
        "prefs-help-prefershttps": "Аныгыскы киириигэр үлэлиир буолуо.",
        "prefswarning-warning": "Туруорууларгын уларыппыккын ол эрэн бигэргэппэтэххин.\nБу сирэйтэн «$1» баттамы баттаабакка таҕытаххына, барыта уруккутунан хаалыа.",
        "prefs-tabs-navigation-hint": "Сүбэ: Көмпүүтэриҥ клаватууратын стрелкаларын туһанан кыбытыктан кыбытыкка көһүөххүн сөп.",
-       "email-address-validity-valid": "Сөп курдук көстөр",
-       "email-address-validity-invalid": "Алҕаһа суох аадырыс ирдэнэр",
        "userrights": "Кыттааччылар бырааптарын салайыы",
        "userrights-lookup-user": "Кыттаачылар бөлөхтөрүн салайыы",
        "userrights-user-editname": "Кыттааччы аата:",
-       "editusergroup": "Кыттааччылар бөлөхтөрүн уларытарга",
+       "editusergroup": "{{GENDER:$1|Кыттааччы}} бөлөхтөрүн уларытарга",
        "editinguser": "<strong>[[User:$1|$1]]</strong> кыттааччы $2 быраабын уларытыы",
        "userrights-editusergroup": "Кыттааччы бөлөхтөрүн уларытарга",
-       "saveusergroups": "Кыттааччы бөлөхтөрүн бигэргэт",
+       "saveusergroups": "{{GENDER:$1|Кыттааччы}} бөлөхтөрүн бигэргэт",
        "userrights-groupsmember": "Бу бөлөхтөргө киирэр:",
        "userrights-groupsmember-auto": "Көстүбэт чилиэн:",
        "userrights-groups-help": "Бу киһи киирэр бөлөхтөрүн уларытыаххын сөп:\n* Бөлөх аатын таһыгар бэлиэ турар буоллаҕына бу кыттааччы бу бөлөххө киирэр.\n* Бэлиэ суох буоллаҕына - кыттааччы бөлөххө киирбэт\n* Маннык бэлиэ * кыттааччы бөлөххө киирэрин/киирбэтин уларытар кыаҕыҥ суоҕун көрдөрөр.",
        "right-createpage": "Сирэйдэри оҥоруу (ырытыы сирэйдэриттэн ураты)",
        "right-createtalk": "Ырытыы сирэйдэрин оҥоруу",
        "right-createaccount": "Саҥа кыттааччыны бэлиэтээһин",
+       "right-autocreateaccount": "Тас бэлиэ-аатынан киирии",
        "right-minoredit": "Уларытыыны кыра суолталаах курдук бэлиэтээ",
        "right-move": "Сирэйдэр ааттарын уларытыы",
        "right-move-subpages": "Сирэйдэр ааттарын иһигэр киирэр сирэйдэри кытта уларытыы",
        "right-blockemail": "Эл. суругу ыытары бобуу",
        "right-hideuser": "Кыттааччы аатын бобуу уонна кистээһин",
        "right-ipblock-exempt": "IP хааччахтааһынын, аптамаатынан уонна диапазоннары хааччахтааһыны тумнуу",
-       "right-proxyunbannable": "Прокси аптааматынан хааччахтааһынын тумнуу",
        "right-unblockself": "Хааччаҕы бэйэ устуута",
        "right-protect": "Сирэйдэр көмүскэллэрин таһымын уонна каскаадынан көмүскэммит сирэйдэри уларытыы",
        "right-editprotected": "Уларытыллар сирэйдэр \"{{int:protect-level-sysop}}\" таһымынан көмүскэммиттэр",
        "right-managechangetags": "[[Special:Tags|Бэлиэлэри]] билии олоҕуттан ылыы уонна сотуу",
        "right-applychangetags": "Улартыыларгын кытта [[Special:Tags|тиэктэри]] тутун",
        "right-changetags": "Ханнык баҕарар [[Special:Tags|тиэктэри]] биирдиилээн уларытыыларга уонна сурунаал суруйууларыгар эбэри уонна сотору көҥүллээ",
+       "grant-generic": "Быраап «$1» нобуора",
+       "grant-group-page-interaction": "Сирэйдиин алтыһыы",
+       "grant-group-file-interaction": "Миэдьийэлиин алтыһыы",
+       "grant-group-watchlist-interaction": "Кэтиир тиһиликкин кытта алтыһыы",
+       "grant-group-email": "Сурук ыытыы",
+       "grant-group-high-volume": "Кылгас кэм иһигэр элбэҕи оҥоруу",
+       "grant-group-customization": "Нарылааһын уонна туруоруулар",
+       "grant-group-administration": "Дьаһайыы",
+       "grant-group-other": "Эгэлгэ тэрээһиннэр",
+       "grant-blockusers": "Бэлиэ ааттары хааччахтааһын ууонна хааччаҕын устуу",
+       "grant-createaccount": "Бэлиэтэнии",
+       "grant-createeditmovepage": "Сирэй оҥоруу, тупсарыы уонна аатын уларытыы",
+       "grant-delete": "Сурунаалтан сирэйи, уларытыыны уонна суруктарын сотуу",
+       "grant-editinterface": "MediaWiki аат далыгар уонна тус CSS/JavaScript иһинэн үлэ",
+       "grant-editmycssjs": "Бэйэҥ тус CSS/JavaScript-кын уларытыы",
+       "grant-editmyoptions": "Бэйэҥ туруорууларгын уларытыы",
+       "grant-editmywatchlist": "Кэтиир тиһиликкин уларытыы",
+       "grant-editpage": "Баар сирэйдэри уларытыы",
+       "grant-editprotected": "Көмүскэммит сирэйдэри уларытыы",
+       "grant-highvolume": "Түргэнник элбэҕи уларытыы",
+       "grant-oversight": "Кыттааччылар уларытыыларын уонна сирэйдэр барылларын кистээһин",
+       "grant-patrol": "Сирэй уларыйыытын ботурууллааһын",
+       "grant-protect": "Көмүскээһин уонна көмүскэли суох гыныы",
+       "grant-rollback": "Сирэй уларыйыытын төннөрүү",
+       "grant-sendemail": "Атын кыттааччыларга эл. суругу ыытыы",
+       "grant-uploadeditmovefile": "Билэни хачайдааһын, солбуйан биэрии уонна аатын уларытыы",
+       "grant-uploadfile": "Саҥа билэни киллэрии",
+       "grant-basic": "Сүрүн быраап",
+       "grant-viewdeleted": "Сотуллубут билэлэри уонна сирэйдэри көрүү",
+       "grant-viewmywatchlist": "Кэтиир тиһиликкин көрүү",
        "newuserlogpage": "Кыттааччылары бэлиэтиир сурунаал",
        "newuserlogpagetext": "Соторутааҕыта бэлиэтэммит кыттааччылар.",
        "rightslog": "Кыттаачы бырааптарын сурунаала",
        "action-createpage": "сирэйдэри оҥоруу",
        "action-createtalk": "ырытыы сирэйдэрин оҥоруу",
        "action-createaccount": "кыттааччы бу бэлиэтэнэр аатын оҥоруу",
+       "action-autocreateaccount": "тас бэлиэ-аатынан аптамаатынан киирии",
        "action-history": "сирэй устуоруйатын көрүү",
        "action-minoredit": "бу уларытыыны суолтата суох курдук бэлиэтээ",
        "action-move": "бу сирэй аатын уларытыы",
        "recentchanges-label-plusminus": "Сирэй кээмэйэ бачча баайтынан уларыйбыт",
        "recentchanges-legend-heading": "'''Легендата:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (өссө көр: [[Special:NewPages|Саҥа сирэйдэр тиһиктэрэ]])",
+       "recentchanges-submit": "Көрдөр",
        "rcnotefrom": "Манна {{PLURAL:$5|уларытыы көрдөрүлүннэ|уларытыылар көһүннүлэр}} баччаттан <strong>$3, $4</strong> (баччаттан элбэх көстүбэт <strong>$1</strong>).",
        "rclistfrom": "Бу кэм $3 $2 кэнниттэн оҥоһуллубуттары көрдөр",
        "rcshowhideminor": "$1 кыра уларыйыылары",
        "rcshowhidemine": "Мин уларытыыларбын $1",
        "rcshowhidemine-show": "Көрдөр",
        "rcshowhidemine-hide": "Кистээ",
+       "rcshowhidecategorization": "$1 сирэй категориялааһынын",
        "rcshowhidecategorization-show": "Көрдөр",
        "rcshowhidecategorization-hide": "Кистээ",
        "rclinks": "$2 күҥҥэ бүтэһик $1 уларытыыны көрдөр;<br />$3.",
        "uploaded-script-svg": "Хачайдаммыт SVG-билэҕэ сценарийы өйүүр куттааллаах «$1» элэмиэн көһүннэ.",
        "uploaded-hostile-svg": "Хачайдаммыт SVG-билэ истиилин элэмиэнигэр кутталлаах CSS-куод көһүннэ.",
        "uploaded-event-handler-on-svg": "SVG-билэлэргэ <code>$1=\"$2\"</code> сабыытыйаны таҥастааччы атрибууттарын туруоруу көҥүллэммэт.",
-       "uploaded-href-attribute-svg": "SVG-билэлэргэ олохтоох соруга суох href-атрибууттар <code>&lt;$1 $2=\"$3\"&gt;</code> бобуллаллар (а.э. http://, javascript:, уо.д.а.).",
        "uploaded-href-unsafe-target-svg": "Хачайдаммыт SVG-билэҕэ кутталлаах сигэ көһүннэ <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-animate-svg": "«Animate» тиэк көһүннэ, кини «from»-атрибут көмөтүнэн  <code>&lt;$1 $2=\"$3\"&gt;</code> хачайдаммыт SVG-билэҕэ сигэни уларытыан сөп.",
        "uploaded-setting-event-handler-svg": "Дьайыы таҥастыыр тэрил атрибуутун уларытар бобуллубут, киллэриллибит SVG-билэҕэ <code>&lt;$1 $2=\"$3\"&gt;</code> куод көстүбүт.",
        "filename-thumb-name": "Билэҥ аата кыра ойуу аатыгар маарыҥныыр. Бука диэн, манныгы угума. Өскө, бу билэни хайаан да угуоххун баҕарар буоллаххына, аатын уларыт, кыра ойуу префиксын сотон баран.",
        "filename-bad-prefix": "Киллэрээри гынар билэҥ аата '''\"$1\"''' фотоаппарат аптамаатынан ааттыыр аатыгар майгынныыр. Бука диэн атыннык, арыый сиһилии ааттаан киллэрэриҥ буоллар.",
        "filename-prefix-blacklist": " #<!-- Бу строканы оннунан хааллар --> <pre>\n# Синтаксииһа маннык:\n#   * Бу \"#\" бэлиэттэн саҕалаан строка бүтүөр дылы быһаарыы\n#   * Кураанах буолбатах строка - билэ фотоаппарат аптамаатынан ааттаабыт ааттарын префикса\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # сорох мобильнай төлөппүөннэр\nIMG # generic\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- Бу строканы оннунан хааллар -->",
-       "upload-success-subj": "Сатанна",
-       "upload-success-msg": "[$2]  хачайдааһын табылынна. Ол түмүгүн манна көрүөххүн сөп: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Хачайдааһын моһуога",
-       "upload-failure-msg": "Эн хачайдааһыныҥ (мантан [$2]) моһуогурда:\n\n$1",
-       "upload-warning-subj": "Хачайдыырга сэрэтии",
-       "upload-warning-msg": "[$2] хачайдыырга алҕас таҕыста. Ол алҕаһы көннөрөргө манна төнүн [[Special:Upload/stash/$1|upload form]].",
        "upload-proto-error": "Сыыһа боротокуол",
        "upload-proto-error-text": "Ыраахтан суруттарарга маннык аадырыстар наадалар: <code>http://</code> эбэтэр <code>ftp://</code>.",
        "upload-file-error": "Ис сыыһа",
        "foreign-structured-upload-form-label-own-work-message-shared": "Бу билэни бас билэрбин уонна Биики Ыскылаакка төнүннэрбэттии [https://creativecommons.org/licenses/by-sa/4.0/deed.ru Creative Commons Attribution-ShareAlike 4.0] лиссиэнсийэннэн угары бигэргэтэбин. Ону тэҥэ [https://wikimediafoundation.org/wiki/Условия_использования Туһаныы усулуобуйатын кытта] сөбүлэһэбин.",
        "foreign-structured-upload-form-label-not-own-work-message-shared": "Өскөтө билэни бас билбэт буоллаххына, биитэр атын лиссиэнсийэннэн угуоххун баҕарар буоллаххына, манна баар ньыманы туһаныаххын сөп: [https://commons.wikimedia.org/wiki/Special:UploadWizard Биики Ыскылаакка угуу маастара].",
        "foreign-structured-upload-form-label-not-own-work-local-shared": "Өскө, {{SITENAME}} быраабылатынан угар сатанар буоллаҕына, кини [[Special:Upload|киллэрии тэрилин]] туһаныаххын эмиэ сөп.",
+       "foreign-structured-upload-form-3-label-question-website": "Ойууну ханнык эрэ саайтан хачайдаан ыллыҥ дуо?",
+       "foreign-structured-upload-form-3-label-question-ownwork": "Бэйэҥ уруһуйдаабыт ойууҥ (эскииһиҥ, чертеһүҥ), түһэрбит хаартыскаҥ дуо?",
+       "foreign-structured-upload-form-3-label-question-noderiv": "Үлэҥ иһигэр ким эрэ бас билэр үлэтэ баар дуо, холобур, логотип?",
+       "foreign-structured-upload-form-3-label-yes": "Оннук",
+       "foreign-structured-upload-form-3-label-no": "Суох",
+       "foreign-structured-upload-form-3-label-alternative": "Оннук буоллаҕына, бу тэрил көмөтүнэн хачайдыыр сатаммат. Ол эрээри, өскөтө көҥүл лиссиэнсийэлээх буоллаҕына, син биир [https://commons.wikimedia.org/wiki/Special:UploadWizard Биики-ыскылаат маастарын] көмөтүнэн угуохха сөп.",
        "backend-fail-stream": "$1 билэни ыытар табыллыбата.",
        "backend-fail-backup": "Бу билэ $1 резервнэй куопуйатын оҥорор табыллыбата.",
        "backend-fail-notexists": "Маннык $1 билэ суох эбит.",
        "mostrevisions": "Саамай элбэхтик уларытыллыбыт ыстатыйалар",
        "prefixindex": "Мантан саҕаланар (префикстаах) сирэйдэр барыта",
        "prefixindex-namespace": "Сирэй саҕаланыытынан наардаан көрдөрүү ($1 аат далыгар)",
+       "prefixindex-submit": "Көрдөр",
        "prefixindex-strip": "Түмүк тиһигэр префиксы көрдөрүмэ",
        "shortpages": "Кылгас ыстатыйалар",
        "longpages": "Уһун ыстатыйалар",
        "protectedpages-performer": "Кытааччы көмүскээһинэ",
        "protectedpages-params": "Көмүскээһин кээмэйдэрэ",
        "protectedpages-reason": "Төрүөтэ",
+       "protectedpages-submit": "Сирэйдэри көрдөр",
        "protectedpages-unknown-timestamp": "Биллибэт",
        "protectedpages-unknown-performer": "Биллибэт кыттааччы",
        "protectedtitles": "Көмүскэммит ааттар",
        "protectedtitles-summary": "Манна бобуллубут сирэйдэр ааттара сурулуннулар. Билигин көмүскэммит сирэйдэр тиһиктэрин манна көрүөххэ сөп: [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Биир да аат бу параметрдарынан көмүскэммэт",
+       "protectedtitles-submit": "Ааттарын көрдөр",
        "listusers": "Кыттааччылар испииһэктэрэ",
        "listusers-editsonly": "Саатар биир көннөрүүнү оҥорбут кыттааччылары көрдөр",
        "listusers-creationsort": "Айыллыбыт күнүнэн наардаа",
        "usereditcount": "$1 {{PLURAL:$1|көннөрүү|көннөрүү}}",
        "usercreated": "Баччаҕа {{GENDER:$3|бэлиэтэммит}} $1,  $2",
        "newpages": "Саҥа ыстатыйалар",
+       "newpages-submit": "Көрдөр",
        "newpages-username": "Кыттааччы:",
        "ancientpages": "Бүтэһик уларытыы киирбитинэн наардаммыт ыстатыйалар",
        "move": "Аатын уларыт",
        "specialloguserlabel": "Толорооччу:",
        "speciallogtitlelabel": "Сыал (тиэкис эбэтэр {{ns:user}}:кыттааччы аата):",
        "log": "Сурунааллар",
+       "logeventslist-submit": "Көрдөрүү",
        "all-logs-page": "Көстөр сурунааллар барыта",
        "alllogstext": "{{SITENAME}} сурунаалларын уопсай испииһэгэ.\nСурунаал көрүҥүнэн, кыттааччы аатынан (улахан-кыра буукубата учуоттанар) эбэтэр сирэй аатынан (эмиэ улахана-кырата учуоттанар) наардыаххытын сөп.",
        "logempty": "Сурунаалга сөп түбэһэр элэмиэннэр суохтар.",
        "log-title-wildcard": "Бу сурук бэлиэлэриттэн (буукубалартан) саҕаланар ааттары бул",
        "showhideselectedlogentries": "Талыллыбыт суруктары кистээ/көрдөр",
        "log-edit-tags": "Сурунаалтан талбыт суругуҥ тиэгин уларыт",
+       "checkbox-select": "Талыы: $1",
+       "checkbox-all": "Бары (барыта)",
+       "checkbox-none": "Суох",
        "allpages": "Сирэйдэр барыта",
        "nextpage": "Аныгыскы сирэй ($1)",
        "prevpage": "Бу иннинээҕи сирэй ($1)",
        "cachedspecial-viewing-cached-ts": "Сирэй кээскэ киирбит барылын көрөҕүн, дьиҥнээх сирэй чыҥха атын буолуон сөп.",
        "cachedspecial-refresh-now": "Бүтэһик барылы көр.",
        "categories": "Категориялар",
+       "categories-submit": "Көрдөр",
        "categoriespagetext": "Бу {{PLURAL:$1|категория иһигэр|категориялар истэригэр}} сирэйдэр эбэтэр медиа-билэлэр бааллар.\n[[Special:UnusedCategories|Туттуллубат категориялар]] манна көстүбэттэр.\nӨссө маны көр: [[Special:WantedCategories|Баар буолуохтаах категориялар тиһиктэрэ]].",
        "categoriesfrom": "Мантан саҕаланар категориялары көрдөр:",
        "special-categories-sort-count": "ахсаанынан бэрээдэктээһин",
        "activeusers-hidebots": "Руобаттары көрдөрүмэ",
        "activeusers-hidesysops": "Дьаһабыллары көрдөрүмэ",
        "activeusers-noresult": "Кыттааччылар көстүбэтилэр.",
+       "activeusers-submit": "Көхтөөх кыттааччылары көрдөр",
        "listgrouprights": "Кыттааччылар бөлөхтөрүн бырааптара",
        "listgrouprights-summary": "Манна бу биикигэ баар бөлөхтөр уонна кинилэр киирэр бырааптара көстөллөр.\nБаҕар дьон туспа бырааптарын  туһунан [[{{MediaWiki:Listgrouprights-helppage}}|эбии информация]] баара буолуо.",
        "listgrouprights-key": "Суруга: * <span class=\"listgrouprights-granted\">Биэриллибит бырааптар</span>\n* <span class=\"listgrouprights-revoked\">Быһыллыбыт бырааптар</span>",
        "listgrouprights-namespaceprotection-header": "Аат далын хааччахтара",
        "listgrouprights-namespaceprotection-namespace": "Аат дала",
        "listgrouprights-namespaceprotection-restrictedto": "Кыттааччы көннөрөр бырааба",
+       "listgrants": "Көҥүл",
+       "listgrants-grant": "Көҥүл",
+       "listgrants-rights": "Быраап",
        "trackingcategories": "Кэтиир категориялар",
        "trackingcategories-summary": "Манна MediaWiki аптамаатынан толорор кэтиир категориялара көстөллөр.  Бу аат далыгар {{ns:8}} систиэмэ биллэриилэрин уларытан ааттарын уларытыахха сөп.",
        "trackingcategories-msg": "Кэтиир категория",
        "wlheader-showupdated": "Бүтэһик киирииҥ кэннэ уларыйбыт сирэйдэр '''модьу''' бичигинэн бэлиэтэннилэр.",
        "wlnote": "Манна кэлиҥҥи {{PLURAL:$2|чаас|<strong>$2</strong> чаас}} иһигэр оҥоһуллубут бүтэһик <strong>$1</strong> уларытыы көрдөрүлүннэ, бу кэминээҕи туругунан $3, $4.",
        "wlshowlast": "Бүтэһик $2 күҥҥэ $1 чааска көрдөр",
-       "watchlistall2": "бары",
-       "wlshowtime": "Тиһэҕи көрдөр:",
+       "watchlist-hide": "Кистээ",
+       "watchlist-submit": "Көрдөр",
+       "wlshowtime": "Бу ыккардыгар буолбуту көрдөр:",
        "wlshowhideminor": "кыра суолталаах уларытыы",
        "wlshowhidebots": "оруобат",
        "wlshowhideliu": "бэлиэтэммит кыттааччы",
        "wlshowhideanons": "ааттарын эппэтэх кыттааччы",
        "wlshowhidepatr": "тургутуллубут уларытыы",
        "wlshowhidemine": "бэйэм уларытыым",
+       "wlshowhidecategorization": "сирэй категоризациятын",
        "watchlist-options": "Кэтээн көрүү туруоруутун уларытыы",
        "watching": "Кэтээ...",
        "unwatching": "Кэтээмэ...",
        "delete-confirm": "Маны \"$1\" соторго",
        "delete-legend": "Сотуу",
        "historywarning": "<strong>Сэрэтии</strong>: Сотоору турар сирэйиҥ $1 {{PLURAL:$1|соҕотох барыллаах|барыллаах}} устуоруйалаах:",
+       "historyaction-submit": "Көрдөр",
        "confirmdeletetext": "Эн сирэйи (ойууну) уонна кини устуоруйатын букатын сотоору гынаҕын.\nБука диэн, кырдьык инньэ гынаары гынаргын,\nбу дьайыы туох содуллаах буоларын толору билэргин\nуонна [[{{MediaWiki:Policy-url}}]] сиэрин кэспэккин бигэргэт.",
        "actioncomplete": "Дьайыы оҥоһулунна",
        "actionfailed": "Дьайыы оҥоһуллубата",
        "contributions": "{{GENDER:$1|Кыттааччы}} суруйуута (кылаата)",
        "contributions-title": "$1 кыттааччы киллэрбит уларытыылара",
        "mycontris": "Суруйуу тиһигэ",
+       "anoncontribs": "Суруйуу тиһилигэ",
        "contribsub2": "$1 ($2) суруйуута",
        "contributions-userdoesnotexist": "Маннык \"$1\" кыттааччы аата бэлиэтэниллибэтэх.",
        "nocontribs": "Эппит критерийгэр эппиэттиир уларытыылар көстүбэтилэр.",
        "whatlinkshere-hidelinks": "$1 сигэ (ыйынньык)",
        "whatlinkshere-hideimages": "$1 билэ сигэтэ",
        "whatlinkshere-filters": "Фильтрдар",
+       "whatlinkshere-submit": "Толор",
        "autoblockid": "Аптамаатынан хааччахтааһын #$1",
        "block": "Кыттааччыны хааччахтааһын",
        "unblock": "Кытааччы хааччаҕын устуу",
        "javascripttest-pagetext-frameworks": "Бука диэн, бу тургуутуу эйгэлэриттэн биирин тал: $1",
        "javascripttest-pagetext-skins": "Тургутууну ыытарга тас көрүҥүн бастаан тал:",
        "javascripttest-qunit-intro": "[$1 тургутуу документациятын] манна mediawiki.org көр.",
-       "tooltip-pt-userpage": "Кыттааччы быһыытынан тус сирэйиҥ",
+       "tooltip-pt-userpage": "{{GENDER:|Кыттааччы}} быһыытынан тус сириҥ",
        "tooltip-pt-anonuserpage": "Билигин киирбит IP-м сирэйэ",
-       "tooltip-pt-mytalk": "Кэпсэтэр-ырытар сириҥ",
+       "tooltip-pt-mytalk": "Кэпсэтэр-ырытар {{GENDER:|сириҥ}}",
        "tooltip-pt-anontalk": "Бу IP ырытыыта",
-       "tooltip-pt-preferences": "Бэйэм туруорууларым",
+       "tooltip-pt-preferences": "{{GENDER:|Бэйэҥ}} туруорууларыҥ",
        "tooltip-pt-watchlist": "Кэтээн көрөр сирэйдэрим тиһигэ",
-       "tooltip-pt-mycontris": "Суруйбут/уларыппыт Ñ\81иÑ\80Ñ\8dйдÑ\8dÑ\80иҥ Ñ\82иһикÑ\82Ñ\8dÑ\80Ñ\8d",
+       "tooltip-pt-mycontris": "Суруйбут/уларыппыт {{GENDER:|Ñ\81иÑ\80Ñ\8dйдÑ\8dÑ\80иҥ}} Ñ\82иһиликÑ\82Ñ\8dÑ\80Ñ\8d",
        "tooltip-pt-login": "Манна бэйэҕин билиһиннэриэххин сөп (булгуччута суох).",
        "tooltip-pt-logout": "Тахсыы",
        "tooltip-pt-createaccount": "Манна киирэргэ бэлиэтэнэр уонна куруук ол аатынан киирэр ордук; ол булгуччута суох",
        "tooltip-t-recentchangeslinked": "Бу сирэй сигэнэр сирэйдэригэр кэнники уларыйыылар",
        "tooltip-feed-rss": "RSS бу сирэйгэ",
        "tooltip-feed-atom": "Atom бу сирэйгэ",
-       "tooltip-t-contributions": "Бу кыттааччы уларыппыт сирэйдэрин испииһэгэ",
+       "tooltip-t-contributions": "{{GENDER:$1|Бу кыттааччы}} уларыппыт сирэйдэрин тиһилигэ",
        "tooltip-t-emailuser": "Бу киһиэхэ сурук ыытарга",
        "tooltip-t-info": "Бу сирэй туһунан сиһилии",
        "tooltip-t-upload": "Билэлэри суруттарыы",
        "watchlisttools-edit": "Кэтэбил испииһэгин көрүү/уларытыы",
        "watchlisttools-raw": "\"Сиикэй\" испииһэги уларытыы",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ырытыы]])",
+       "timezone-local": "Олохтоох",
        "duplicate-defaultsort": "Болҕой: Наардааһын «$2» күлүүһэ урукку «$1» күлүүһү сабар (Ключ сортировки переопределяет прежний ключ).",
        "duplicate-displaytitle": "<strong>Болҕой:</strong> Көрдөрүллүбүт «$2» аат урут көрдөрүллүбүт «$1» ааты уларытар.",
        "invalid-indicator-name": "<strong>Алҕас:Сирэй туругун көрдөрөр индикатор </strong> атрибута <code>name</code> кураанах буолуо суохтаах.",
        "redirect-page": "Сирэй нүөмэрэ",
        "redirect-revision": "Сирэй барыла",
        "redirect-file": "Билэ аата",
+       "redirect-logid": "Сурунаал ID нүөмэрэ",
        "redirect-not-exists": "Суолта көстүбэтэ",
        "fileduplicatesearch": "Хос билэлэри көрдөөһүн",
        "fileduplicatesearch-summary": "Тэҥ билэлэри хэш-куодтарынан көрдөөһүн.",
        "tags-deactivate": "араар",
        "tags-hitcount": "$1 {{PLURAL:$1|уларытыы|уларытыылар}}",
        "tags-manage-no-permission": "Тиэктэри уларытар кыаҕыҥ суох эбит.",
+       "tags-manage-blocked": "Хааччахтаммыт буолаҥҥын уларытыы бэлиэлэрин уларытар кыаҕыҥ суох.",
        "tags-create-heading": "Саҥа тиэги оҥоруу",
        "tags-create-explanation": "Саҥа оҥоһуллубут тиэктэри кыттааччылар уонна буоттар уларытар кыахтаах буолуохтара.",
        "tags-create-tag-name": "Бэлиэ аата:",
index ed06150..4fd5ef6 100644 (file)
        "passwordreset-emailtext-ip": "Quarchidunu (prubbabbilmenti tu, dô nnirizzu IP $1) fici n'addumannata pi l'azziramentu dâ tò password pi {{SITENAME}} ($4). {{PLURAL:$3|Lu cuntu utenti siguenti è assuciatu|Li cunti utenti siguenti sù assuciati}} cu stu nnirizzu di posta elittrònica:\n\n$2\n\n{{PLURAL:$3|Sta password timpurània|Sti password timpurànii}} scàdinu tra {{PLURAL:$5|un jornu|$5 jorna}}.\nOra tu avissi a tràsiri e scègghiri na password nova. Si fu quarchidun'àutru a fari st'addumannata e nun tu, o si t'arricurdasti la tò password origginali e nun la voi canciari cchiù, poi gnurari stu missaggiu e cuntinuari a adupirari la tò password vecchia.",
        "passwordreset-emailtext-user": "L'utenti $1 supra a {{SITENAME}} fici n'addumannata pi l'azziramentu dâ tò password pi {{SITENAME}} ($4). {{PLURAL:$3|Lu cuntu utenti siguenti è assuciatu|Li cunti utenti siguenti sù assuciati}} cu stu nnirizzu di posta elittrònica:\n\n$2\n\n{{PLURAL:$3|Sta password timpurània|Sti password timpurànii}} scàdinu tra {{PLURAL:$5|un jornu|$5 jorna}}.\nOra tu avissi a tràsiri e scègghiri na password nova. Si fu quarchidun'àutru a fari st'addumannata e nun tu, o si t'arricurdasti la tò password origginali e nun la voi canciari cchiù, poi gnurari stu missaggiu e cuntinuari a adupirari la tò password vecchia.",
        "passwordreset-emailelement": "Nomu utenti: \n$1\n\nPassword timpurània: \n$2",
-       "passwordreset-emailsent": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu mannatu.",
+       "passwordreset-emailsentemail": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu mannatu.",
        "passwordreset-emailsent-capture": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu mannatu, cû cuntinutu chi si pò taliari ccassutta.",
        "passwordreset-emailerror-capture": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu cumpilatu, cû cuntinutu chi si pò taliari ccassutta, pirò la sò spidizzioni a l'utenti {{GENDER:$2|user}} nun arriniscìu: $1",
        "changeemail": "Canciu dû nnirizzu di posta elittrònica",
        "prefs-help-prefershttps": "Sta prifirenza fa effettu â tò pròssima trasuta.",
        "prefswarning-warning": "Facisti canciamenti ê tò prifirenzi chi ancora nun foru sarvati.\nSi ti nni vai di sta pàggina senza carcari \"$1\" li tò prifirenzi nun sunnu sarvati.",
        "prefs-tabs-navigation-hint": "Cunzigghiu: Poi adupirari li buttuna fileccia a manu manca e a manu dritta pi navigari tra dî linguetti ntâ lista.",
-       "email-address-validity-valid": "Lu nnirizzu e-mail pari bonu",
-       "email-address-validity-invalid": "Nzirisci nu nnirizzu e-mail bonu",
        "userrights": "Gistioni dî dritti di l'utenti",
        "userrights-lookup-user": "Gistisci li gruppi di l'utenti",
        "userrights-user-editname": "Metti nu nomu utenti:",
        "right-blockemail": "Bluccari n'utenti pi nun fàricci mannari posta elittrònica",
        "right-hideuser": "Bluccari nu nomu utenti, ammucciànnulu ô pùbblicu",
        "right-ipblock-exempt": "Sautari li blocchi di IP, autumàtici e di ntirvalli di IP",
-       "right-proxyunbannable": "Sautari li blocchi autumàtici dî proxy",
        "right-unblockself": "Sbluccàrisi iddu stissu",
        "right-protect": "Canciari li liveddi di prutizzioni e canciari pàggini prutetti a cascata",
        "right-editprotected": "Canciari pàggini cu prutizzioni \"{{int:protect-level-sysop}}\"",
        "uploaded-script-svg": "Fu attruvatu n'elimentu prugrammàbbili \"$1\" ntô file SVG carricatu.",
        "uploaded-hostile-svg": "Fu attruvatu còdici CSS risicusu nta l'elimentu style dû file SVG carricatu.",
        "uploaded-event-handler-on-svg": "Nun è cunzintutu di mpustari l'attribbuti gistura d'eventi <code>$1=\"$2\"</code> ntê file SVG.",
-       "uploaded-href-attribute-svg": "Nun sunnu cunzintuti l'attribbuti href <code>&lt;$1 $2=\"$3\"&gt;</code> cu na distinazzioni ca nun è lucali (p'esempiu http://, javascript:, etc) ntê file SVG.",
        "uploaded-href-unsafe-target-svg": "Fu attruvatu n'href cu na distinazzioni risicusa <code>&lt;$1 $2=\"$3\"&gt;</code> ntô file SVG carricatu.",
        "uploaded-animate-svg": "Fu attruvata n'etichetta \"animate\" ca purrìa canciari href, adupirannu l'attribbutu \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code>, ntô file SVG carricatu.",
        "uploaded-setting-event-handler-svg": "Lu mpustari l'attribbuti dî gistura di l'eventi veni bluccatu; fu attruvatu <code>&lt;$1 $2=\"$3\"&gt;</code> ntô file SVG carricatu.",
        "filewasdeleted": "Nu file cu stu nomu hà statu già carricatu e cancillatu n passatu. Virificari $1 prima di carricàrilu di novu.",
        "filename-bad-prefix": "Lu nomu dô file chi stai carricannu ncigna cu '''\"$1\"''', chi è nu nomu non descrittivu assignatu, di solitu, automaticamenti dê màchini fotugràfici diggitali. Pi favuri scegghia nu nomu cchiù descrtittivu pi lu tò file.",
        "filename-prefix-blacklist": " #<!-- dassa sta lìnia comu è già --> <pre>\n# Chista di sèquitu è la sintassi:\n#   * Tutti li scritti a pàrtiri dô carattiri \"#\" sugnu commenti\n#   * Tutti li lìnii non vacanti sugnu prefissi pi tipici nomi di file assignati automaticamenti dê màchini fotugràfici diggitali\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # arcuni cellulari\nIMG # genericu\nJD # Jenoptik\nMGP # Pentax\nPICT # arcuni\n #</pre> <!-- dassa sta lìnia comu è già -->",
-       "upload-success-subj": "Carricamentu arrinisciutu",
-       "upload-success-msg": "Lu tò carricamentu di [$2] arriniscìu. Ccà c'è lu file carricatu: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Prubblema ntô carricamentu",
-       "upload-failure-msg": "Ammattìu un prubblema ntô tò carricamentu di [$2]:\n\n$1",
-       "upload-warning-subj": "Avvisu pû carricamentu",
-       "upload-warning-msg": "Ammattìu un prubblema ntô tò carricamentu di [$2]. Poi turnari ô [[Special:Upload/stash/$1|mòdulu di carricamentu]] pi currèggiri stu prubblema.",
        "upload-proto-error": "Protucollu erratu",
        "upload-proto-error-text": "Pi l'upload rimotu è nicissariu spicificari URL ca nìzzianu cu <code>http://</code> oppuru <code>ftp://</code>.",
        "upload-file-error": "Erruri nternu",
        "querypage-disabled": "Sta pàggina spiciali fu disattivata pi mutivi di pristazzioni.",
        "apihelp": "Guida a l'API",
        "apihelp-no-such-module": "Mòdulu «$1» nun attruvatu.",
+       "apisandbox": "Pàggina di prova API",
+       "apisandbox-submit": "Addumanna",
        "booksources": "Fonti libbrarî",
        "booksources-search-legend": "Arricerca di fonti libbrarî",
        "booksources-isbn": "Còdici ISBN:",
        "wlheader-showupdated": "Li pàggini ca foru canciati dâ tò ùrtima vìsita sunnu evidinziati n <strong>grassettu</strong>.",
        "wlnote": "Sutta attrovi l'ùrtim{{PLURAL:$1|u canciamentu|i <strong>$1</strong> canciamenti}} fatti nta l'ùrtim{{PLURAL:$1|a ura|i <strong>$2</strong> uri}}, aggiurnati ê $4 dû $3.",
        "wlshowlast": "Ammustra l'ùrtimi $1 uri $2 jorna",
-       "watchlistall2": "tutti",
        "watchlist-options": "Opzioni dâ lista taliata",
        "watching": "Agghiunciuta â lista taliata...",
        "unwatching": "Cancillata dâ lista taliata...",
        "movenosubpage": "Sta pàggina nun havi suttapàggini.",
        "movereason": "Mutivu:",
        "revertmove": "riprìstina",
-       "delete_and_move": "Cancella e sposta",
        "delete_and_move_text": "==Richiesta di cancillazzioni==\n\nLa pàggina di distinazzioni \"[[:$1]]\" asisti già. S'addisìa cancillàrila pi rènniri pussìbbili lu spustamentu?",
        "delete_and_move_confirm": "Sì, suvrascrivi la pàggina asistenti",
        "delete_and_move_reason": "Cancillata pi fari largu ô spustamentu di \"[[$1]]\"",
        "special-characters-title-minus": "signu menu",
        "mw-widgets-dateinput-no-date": "Nudda data scigghiuta",
        "mw-widgets-titleinput-description-new-page": "sta pàggina ancora nun esisti",
-       "mw-widgets-titleinput-description-redirect": "rimannu a $1"
+       "mw-widgets-titleinput-description-redirect": "rimannu a $1",
+       "randomrootpage": "Pàggina ràdica casuali"
 }
index 11dbca2..b9f8739 100644 (file)
        "uploaded-script-svg": "اسڪرپٽ جوڳو ايليمينٽ ”$1” مليو آهي، اپلوڊ ٿيل ايس وي جي فائيل ۾.",
        "uploaded-hostile-svg": "اپلوڊ ٿيل ايس وي جي فائيل جو غير محفوظ سي ايس ايس ۾ اسٽائيل ايلمينٽ مليو",
        "uploaded-event-handler-on-svg": "ايس وي جي فائيل ۾ ايوينٽ هينڊلر خصوصيتون <code>$1=\"$2\"</code> مقرر ڪرڻ جي اجازت نہ آهي.",
-       "uploaded-href-attribute-svg": "Href خاصيتون <code>&lt;$1 $2=\"$3\"&gt;</code> نان لوڪل ٽارگيٽ سان جهڙوڪ ( http://, javascript:, وغيره) ايس وي جي فائيل ۾ اجازت مليل نه آهن.",
        "uploaded-href-unsafe-target-svg": "href جو غير محفوظ نشانو مليو آهي <code>&lt;$1 $2=\"$3\"&gt;</code> اپلوڊ ٿيل ايس وي جي فائيل ۾",
        "uploaded-animate-svg": "”اينيميٽ“ ٽيگ ڳوليو  جيڪا ٿي سگهي ٿو href کي تبديل ڪري رهي هجي. \"form\" وصف استعمال ڪندي <code>&lt;$1 $2=\"$3\"&gt;</code> اپلوڊ ٿيل ايس وي جي فائيل ۾",
        "uploaded-setting-event-handler-svg": "واقعي کي هينڊل ڪندڙ جي سيٽنگ جون وصفون بلاڪ ٿيل آهن. \n<code>&lt;$1 $2=\"$3\"&gt;</code> اپلوڊ ٿيل ايس وي جي فائيل ۾ مليو",
        "upload-description": "فائيل جي تشريح",
        "upload-options": "چاڙھ جا چارا",
        "watchthisupload": "هيءُ فائيل ٽيٽيو",
-       "upload-success-subj": "چاڙهہ ڪامياب",
-       "upload-failure-subj": "چاڙھ جو مسئلو",
-       "upload-warning-subj": "چاڙھ جو چتاءُ",
        "upload-file-error": "اندروني چُڪَ",
        "upload-dialog-title": "فائيل چاڙهيو",
        "upload-dialog-button-cancel": "رد",
        "notanarticle": "غير موادي صفحو",
        "watchlist-details": "{{PLURAL:$1|$1 صفحو|$1 صفحا}} توهان جي ٽيٽ فهرست، ڳالھ ٻولھ جا صفحا الڳ شمار نٿا ٿين.",
        "wlshowlast": "گذريل $1 ڪلاڪ $2 ڏينهن ڏيکاريو",
-       "watchlistall2": "سڀ",
        "watchlist-hide": "لڪايو",
        "watchlist-submit": "ڏيکاريو",
        "wlshowtime": "ڪيترو عرصو ڏيکارجي:",
index a673d6e..8c05fca 100644 (file)
@@ -11,7 +11,8 @@
                        "Macofe",
                        "KWiki",
                        "Matma Rex",
-                       "Srdjan m"
+                       "Srdjan m",
+                       "Conquistador"
                ]
        },
        "tog-underline": "Podvuci linkove:",
        "moredotdotdot": "Još...",
        "morenotlisted": "Ovaj spisak nije kompletan.",
        "mypage": "Moja stranica",
-       "mytalk": "Razgovor / Разговор",
+       "mytalk": "Razgovor",
        "anontalk": "Razgovor za ovu IP adresu",
        "navigation": "Navigacija - Навигација",
        "and": "&#32;i",
        "specialpage": "Posebna stranica",
        "personaltools": "Lični alati",
        "articlepage": "Pogledaj stranicu sa sadržajem (članak)",
-       "talk": "Razgovor / Разговор",
+       "talk": "Razgovor",
        "views": "Pregledi",
        "toolbox": "Alatke / Алатке",
        "userpage": "Pogledaj korisničku stranicu - Погледај корисничку страницу",
        "nav-login-createaccount": "Prijavi se / Registruj se",
        "userlogin": "Prijavi se / Пријави се",
        "userloginnocreate": "Prijavi se",
-       "logout": "Odjavi se / Одјави се",
+       "logout": "Odjava",
        "userlogout": "Odjavi se / Одјави се",
        "notloggedin": "Niste prijavljeni",
        "userlogin-noaccount": "Nemate račun?",
        "loginlanguagelabel": "Jezik: $1",
        "suspicious-userlogout": "Vaš zahtjev za odjavu je odbijen jer je poslan preko pokvarenog preglednika ili keširanog proksija.",
        "createacct-another-realname-tip": "Pravo ime nije obavezno.\nAko izaberete da date ime, biće korišteno za pripisivanje za vaš rad.",
-       "pt-login": "Prijavi me / Пријави ме",
+       "pt-login": "Prijava",
        "pt-login-button": "Prijavi me / Пријави ме",
        "pt-createaccount": "Napraviti novi nalog / Направити нови налог",
-       "pt-userlogout": "Odjavi se / Одјави се",
+       "pt-userlogout": "Odjava",
        "php-mail-error-unknown": "Nepoznata greška u PHP funkciji mail()",
        "user-mail-no-addy": "Pokušaj slanja e-maila bez e-mail adrese.",
        "user-mail-no-body": "Pokušano slanje e-maila s praznim ili nerazumno kratkim sadržajem.",
        "passwordreset-emailtext-ip": "Netko (vjerovatno Vi, s IP adrese $1) je zatražio resetiranje vaše lozinke/zaporke {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun korisnika je|računi korisnika su}}\npovezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ako je neko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše početne lozinke, a ne želite je promijeniti, \nmožete zanemariti ovu poruku i nastaviti koristiti staru lozinku.",
        "passwordreset-emailtext-user": "Korisnik $1 na {{SITENAME}} je zatražio resetiranje vaše lozinke/zaporke za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|korisnički račun je|korisnički računi su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ako je neko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše originalne lozinke, a ne želite je više promijeniti, \nmožete zanemariti ovu poruku i nastaviti koristiti staru lozinku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena šifra: \n$2",
-       "passwordreset-emailsent": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre/lozinke/zaporke će vam biti poslan na vašu adresu e-pošte.",
+       "passwordreset-emailsentemail": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre/lozinke/zaporke će vam biti poslan na vašu adresu e-pošte.",
        "passwordreset-emailsent-capture": "E-mail za resetiranje lozinke/zaporke je poslan (prikazan dolje).",
        "passwordreset-emailerror-capture": "E-mail za resetiranje lozinke/zaporke, prikazan dolje, je poslan, ali slanje {{GENDER:$2|korisniku|korisnici|korisniku}} nije uspjelo: $1",
        "changeemail": "Promeni ili ukloni e-adresu",
        "search-external": "Vanjska/spoljna pretraga",
        "searchdisabled": "Pretraga teksta na ovoj Wiki je trenutno onemogućena.\nU međuvremenu možete pretraživati preko Googlea.\nUzmite u obzir da njegovi indeksi za ovu Wiki ne moraju biti ažurirani.",
        "search-error": "Dogodila se pogreška prilikom pretraživanja: $1",
-       "preferences": "Postavke / Подешавања",
-       "mypreferences": "Postavke / Подешавања",
+       "preferences": "Postavke",
+       "mypreferences": "Postavke",
        "prefs-edits": "Broj izmjena:",
        "prefsnologintext2": "Molimo Vas prijavite se da biste promijenili postavke.",
        "prefs-skin": "Izgled (skin)",
        "prefs-help-prefershttps": "Ova mogućnost će stupiti na snagu kod vaše sljedeće prijave.",
        "prefswarning-warning": "Napravili ste promjene u vašim postavkama koje još uvijek nisu sačuvane. Ako napustite ovu stranicu bez da pritisnete na \"$1\", postavke neće biti ažurirane.",
        "prefs-tabs-navigation-hint": "Savjet: Možete koristi lijevu i desnu navigacijsku tipku kako biste se kretali između tabova u popisu tabova.",
-       "email-address-validity-valid": "E-mail adresa izgleda valjano",
-       "email-address-validity-invalid": "Unesite valjanu e-mail adresu",
        "userrights": "Postavke korisničkih prava",
        "userrights-lookup-user": "Menadžment korisničkih prava",
        "userrights-user-editname": "Unesi korisničko ime:",
        "right-blockemail": "Blokiranje korisnika da šalje e-mail",
        "right-hideuser": "Blokiranje korisničkog imena, i njegovo sakrivanje od javnosti",
        "right-ipblock-exempt": "Zaobilaženje IP blokada, autoblokada i blokada IP grupe",
-       "right-proxyunbannable": "Zaobilaženje automatskih blokada proxy-ja",
        "right-unblockself": "Deblokiraj samog sebe",
        "right-protect": "Promjena nivoa zaštite i uređivanje kaskadno zaštićenih stranica",
        "right-editprotected": "Uređivanje stranice zaštićenih kao \"{{int:protect-level-sysop}}\"",
        "uploaded-script-svg": "Pronađen skriptni element \"$1\" u postavljenoj SVG datoteci.",
        "uploaded-hostile-svg": "Pronađen nesiguran CSS u stilskom elementu postavljene SVG datoteke.",
        "uploaded-event-handler-on-svg": "Nije dozvoljeno postavljanje atributa koji kontroliraju događaje <code>$1=\"$2\"</code> u SVG datotekama.",
-       "uploaded-href-attribute-svg": "href atributi <code>&lt;$1 $2=\"$3\"&gt;</code> sa nelokalnom metom (npr. http://, javascript:, etc) nisu dozvoljeni u SVG datotekama.",
        "uploaded-href-unsafe-target-svg": "Pronađen href sa nesigurnom metom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-animate-svg": "Pronađena \"animate\" oznaka koja možda mijenja href koristeći se \"from\" atributom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploaded-setting-event-handler-svg": "Postavljanje kontrole događaja je blokirano, pronađeno <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "filewasdeleted": "Datoteka s ovim nazivom je ranije postavljana i nakon toga obrisana.\nPrije nego što nastavite da je ponovno postavite trebate provjeriti $1.",
        "filename-thumb-name": "Ovo izgleda kao thumbnail naslov. Molimo ne postavljate thumbnaile natrag na istu wiki. Ukoliko je riječ o nečemu drugome, molimo popravite ime datoteke tako da ima više značenja i nema thumbnail prefiks.",
        "filename-bad-prefix": "Naziv datoteke koju postavljate počinje sa '''\"$1\"''', što je naziv koji obično automatski dodjeljuju digitalni fotoaparati i kamere.\nMolimo Vas da odaberete naziv datoteke koji opisuje njen sadržaj.",
-       "upload-success-subj": "Uspješno slanje",
-       "upload-success-msg": "Vaša datoteka iz [$2] je uspješno postavljena. Dostupna je ovdje: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Problem pri postavljanju",
-       "upload-failure-msg": "Nastao je problem s Vašim postavljanjem iz [$2]:\n\n$1",
-       "upload-warning-subj": "Upozorenje pri slanju",
-       "upload-warning-msg": "Nastao je problem sa vašim postavljanjem sa [$2]. Morate se vratiti na [[Special:Upload/stash/$1|formular za postavljanje]] kako biste riješili ovaj problem.",
        "upload-proto-error": "Pogrešan protokol",
        "upload-proto-error-text": "Postavljanje sa vanjske lokacije zahtjeva URL-ove koji počinju sa <code>http://</code> ili <code>ftp://</code>.",
        "upload-file-error": "Interna pogreška",
        "usermessage-summary": "Ostavljanje sistemske poruke.",
        "usermessage-editor": "Sistem za poruke",
        "watchlist": "Spisak praćenja / Списак праћења",
-       "mywatchlist": "Popis praćenja / Списак надгледања",
+       "mywatchlist": "Lista motrenja",
        "watchlistfor2": "Za $1 $2",
        "nowatchlist": "Nemate ništa na svom spisku praćenih članaka.",
        "watchlistanontext": "Morate biti prijavljeni kako biste vidjeli ili uređivali svoj spisak praćenih članaka.",
        "wlheader-showupdated": "* Stranice koje su izmijenjene od kad ste ih posljednji put posjetili su prikazane '''podebljanim slovima'''",
        "wlnote": "Ispod {{PLURAL:$1|je najskorija izmjena|su <strong>$1</strong> najskorije izmjene|<strong>$1</strong> najskorijih izmjena}} načinjenih {{PLURAL:$2|posljednjeg sata|u posljednjih <strong>$2</strong> sata|u posljednjih <strong>$2</strong> sati}}, od $3, $4.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
-       "watchlistall2": "sve",
        "watchlist-options": "Opcije liste praćenja",
        "watching": "Pratim... / Додавање на списак надгледања...",
        "unwatching": "Ne pratim…",
        "blanknamespace": "(Glavno)",
        "contributions": "Doprinosi {{GENDER:$1|korisnika|korisnice|korisnika}}",
        "contributions-title": "Korisnički doprinosi od $1",
-       "mycontris": "Doprinosi / Доприноси",
+       "mycontris": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Korisnički račun \"$1\" nije registrovan.",
        "nocontribs": "Nisu nađene promjene koje zadovoljavaju ove uslove.",
        "tooltip-pt-mytalk": "Vaša stranica za razgovor",
        "tooltip-pt-anontalk": "Razgovor o doprinosu sa ove IP adrese",
        "tooltip-pt-preferences": "Vaše postavke",
-       "tooltip-pt-watchlist": "Spisak stranica koje pratite radi izmjena",
-       "tooltip-pt-mycontris": "Spisak vaših doprinosa",
+       "tooltip-pt-watchlist": "Lista stranica kojih izmjene motrite",
+       "tooltip-pt-mycontris": "Lista vaših doprinosa",
        "tooltip-pt-login": "Predlažem da se prijavite; međutim, to nije obavezno",
        "tooltip-pt-logout": "Odjava sa projekta {{SITENAME}}",
        "tooltip-pt-createaccount": "Ohrabrujemo vas da otvorite račun i prijavite se; to, međutim, nije obavezno",
index 7033701..5bfe107 100644 (file)
        "pager-older-n": "{{PLURAL:$1|1 starší|$1 staršie|$1 starších}}",
        "suppress": "Dozor",
        "querypage-disabled": "Táto špeciálna stránka bola zakázaná z výkonnostných dôvodov.",
+       "apisandbox": "API pieskovisko",
+       "apisandbox-api-disabled": "API je na tejto stránke vypnuté.",
+       "apisandbox-submit": "Podať žiadosť",
+       "apisandbox-reset": "Vyčistiť",
+       "apisandbox-examples": "Príklad",
+       "apisandbox-results": "Výsledok",
+       "apisandbox-request-url-label": "URL požiadavky:",
        "booksources": "Knižné zdroje",
        "booksources-search-legend": "Vyhľadávať knižné zdroje",
        "booksources-search": "Hľadať",
        "log-title-wildcard": "Hľadať názvy začínajúce týmto textom",
        "showhideselectedlogentries": "Zobraziť/skryť vybraté položky záznamu",
        "log-edit-tags": "Editovať značky zvolených položiek záznamu",
+       "checkbox-select": "Zvoliť: $1",
+       "checkbox-all": "Všetky",
+       "checkbox-none": "Ždiadne",
+       "checkbox-invert": "Invertovať",
        "allpages": "Všetky stránky",
        "nextpage": "Ďalšia stránka ($1)",
        "prevpage": "Predchádzajúca stránka ($1)",
        "wlshowhideanons": "anonymov",
        "wlshowhidepatr": "preverené úpravy",
        "wlshowhidemine": "moje úpravy",
+       "wlshowhidecategorization": "kategorizáciu stránok",
        "watchlist-options": "Nastavenia zoznamu sledovaných",
        "watching": "Pridávam do zoznamu sledovaných...",
        "unwatching": "Odoberám zo zoznamu sledovaných...",
        "delete-edit-reasonlist": "Upraviť dôvody zmazania",
        "delete-toobig": "Táto stránka má veľkú históriu úprav, viac ako $1 {{PLURAL:$1|revíziu|revízie|revízií}}. Mazanie takýchto stránok bolo obmedzené, aby sa zabránilo náhodnému poškodeniu {{GRAMMAR:genitív|{{SITENAME}}}}.",
        "delete-warning-toobig": "Táto stránka má veľkú históriu úprav, viac ako $1 {{PLURAL:$1|revíziu|revízie|revízií}}. Jej zmazanie by mohlo narušiť databázové operácie {{GRAMMAR:genitív|{{SITENAME}}}}; postupujte opatrne.",
+       "deleteprotected": "Túto stránku nemôžete vymazať, pretože je zamknutá.",
+       "deleting-backlinks-warning": "'''Upozornenie:''' Stránka, ktorú sa chystáte zmazať, je odkazovaná [[Special:WhatLinksHere/{{FULLPAGENAME}}|z iných stránok]], prípadne do nich vložená.",
        "rollback": "Vrátiť späť úpravy",
        "rollbacklink": "vrátiť",
        "rollbacklinkcount": "vrátenie $1 {{PLURAL:$1|úpravy|úprav}}",
index 3191510..180b534 100644 (file)
        "uploaded-script-svg": "V naloženi datoteki SVG smo našli skriptni element »$1«.",
        "uploaded-hostile-svg": "V slogovnem elementu naložene datoteke SVG smo našli nevaren CSS.",
        "uploaded-event-handler-on-svg": "Določevanje atributov za dogodke <code>$1=\"$2\"</code> v datotekah SVG ni dovoljeno.",
-       "uploaded-href-attribute-svg": "Atributi href <code>&lt;$1 $2=\"$3\"&gt;</code> z nelokalnimi cilji (npr. http://, javascript: idr.) v datotekah SVG niso dovoljeni.",
-       "uploaded-href-unsafe-target-svg": "V naloženi datoteki SVG smo našli href z nevarnim ciljem <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "Atributi href v datotekah SVG lahko ciljajo samo na http:// ali https://, našli smo <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Našli smo href na nevaren podatek: cilj URI <code>&lt;$1 $2=\"$3\"&gt;</code> v naloženi datoteki SVG.",
        "uploaded-animate-svg": "V naloženi datoteki SVG smo našli oznako »animate«, ki lahko spreminja href z uporabo atributa »from« <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Določevanje atributov za dogodke je blokirano; v naloženi datoteki SVG smo našli <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-href-svg": "Uporaba oznake »set« za določevanje atributa »href« starševskega elementa je blokirano.",
        "querypage-disabled": "Ta posebna stran je onemogočena iz zmogljivostnih razlogov.",
        "apihelp": "Pomoč za API",
        "apihelp-no-such-module": "Modula »$1« nismo našli.",
+       "apisandbox": "Peskovnik API",
+       "apisandbox-jsonly": "Za uporabo peskovnika API je zahtevan JavaScript.",
+       "apisandbox-api-disabled": "API je onemogočen na tej spletni strani.",
+       "apisandbox-intro": "Uporabite to stran za preizkušanje <strong>API spletnih storitev MediaWiki</strong>.\nOglejte si [[mw:API:Main page|dokumentacijo API]] za nadaljnje podrobnosti o uporabi API. Primer: [//www.mediawiki.org/wiki/API#A_simple_example pridobi vsebino Glavne strani]. Izberite dejanje, da si ogledate več primerov.\n\nPomnite, da čeprav je to peskovnik, bodo dejanja, izvedena na tej strani, morda spremenila wiki.",
+       "apisandbox-fullscreen": "Razširi ploščo",
+       "apisandbox-fullscreen-tooltip": "Razširi ploščo peskovnika, da bo zapolnila okno obrskalnika.",
+       "apisandbox-unfullscreen": "Prikaži stran",
+       "apisandbox-unfullscreen-tooltip": "Zmanjšaš ploščo peskovnik, da postanejo navigacijske povezave MediaWiki na voljo.",
+       "apisandbox-submit": "Izvedi zahtevo",
+       "apisandbox-reset": "Počisti",
+       "apisandbox-retry": "Poskusi znova",
+       "apisandbox-loading": "Nalaganje informacij o modulu API »$1« ...",
+       "apisandbox-load-error": "Med nalaganjem informacij o modulu API »$1« je prišlo do napake: $2",
+       "apisandbox-no-parameters": "Modul API nima parametrov.",
+       "apisandbox-helpurls": "Povezave s pomočjo",
+       "apisandbox-examples": "Primeri",
+       "apisandbox-dynamic-parameters": "Dodatni parametri",
+       "apisandbox-dynamic-parameters-add-label": "Dodaj parameter:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Ime parametra",
+       "apisandbox-dynamic-error-exists": "Parameter z imenom »$1« že obstaja.",
+       "apisandbox-deprecated-parameters": "Zastareli parametri",
+       "apisandbox-fetch-token": "Samodejno izpolni žeton",
+       "apisandbox-submit-invalid-fields-title": "Nekatera polja niso veljavna",
+       "apisandbox-submit-invalid-fields-message": "Prosimo, popravite označena polja in poskusite znova.",
+       "apisandbox-results": "Rezultati",
+       "apisandbox-sending-request": "Pošiljanje zahteve API ...",
+       "apisandbox-loading-results": "Prejemanje zahteve API ...",
+       "apisandbox-results-error": "Med nalaganjem odgovora poizvedbe API je prišlo do napake: $1.",
+       "apisandbox-request-url-label": "URL zahteve:",
+       "apisandbox-request-time": "Trajanje zahteve: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "Popravite žeton in ponovno pošljite",
+       "apisandbox-results-fixtoken-fail": "Pridobivanje žetona »$1« je spodletelo.",
+       "apisandbox-alert-page": "Polja na strani niso veljavna.",
+       "apisandbox-alert-field": "Vrednost polja ni veljavna.",
        "booksources": "Viri knjig",
        "booksources-search-legend": "Išči knjižne vire",
        "booksources-search": "Išči",
index 229fa0a..51bb686 100644 (file)
        "recentchanges-page-added-to-category-bundled": "[[:$1]] и још {{PLURAL:$2|једна страница|$2 странице}} су додате у категорију",
        "recentchanges-page-removed-from-category": "[[:$1]] је уклоњена из категорије",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] и још {{PLURAL:$2|једна страница|$2 странице}} су уклоњене из категорије",
+       "autochange-username": "Медијавики аутоматска измена",
        "upload": "Пошаљи датотеку",
        "uploadbtn": "Пошаљи датотеку",
        "reuploaddesc": "Назад на образац за отпремање",
        "uploaded-script-svg": "Пронађен скриптни елеменат „$1“ у постављеној SVG датотеци.",
        "uploaded-hostile-svg": "Пронађен небезбедан CSS у стилском елементу постављене SVG датотеке.",
        "uploaded-event-handler-on-svg": "Није дозвољено постављање атрибута који контролишу догађаје <code>$1=\"$2\"</code> у SVG датотекама.",
-       "uploaded-href-attribute-svg": "href атрибути <code>&lt;$1 $2=\"$3\"&gt;</code> са нелокалном метом (нпр. http://, javascript:, итд) нису дозвољени у SVG датотекама.",
        "uploaded-href-unsafe-target-svg": "Пронађен href са несигурном метом <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploaded-animate-svg": "Пронађена „animate“ ознака која можда мења href користећи се „from“ атрибутом <code>&lt;$1 $2=\"$3\"&gt;</code> у постављеној SVG датотеци.",
        "uploadscriptednamespace": "Ова SVG датотека садржи погрешан именски простор „$1“",
        "lockmanager-notlocked": "Не могу да откључам „$1“ јер није закључан.",
        "lockmanager-fail-closelock": "Не могу да затворим катанац за „$1“.",
        "lockmanager-fail-deletelock": "Не могу да обришем катанац за „$1“.",
-       "lockmanager-fail-acquirelock": "Не могу да добијем катанац за „$1“.",
+       "lockmanager-fail-acquirelock": "Не могу да се закључам за „$1“.",
        "lockmanager-fail-openlock": "Не могу да отворим катанац за „$1“.",
        "lockmanager-fail-releaselock": "Не могу да ослободим катанац за „$1“.",
        "lockmanager-fail-db-bucket": "Не могу да контактирам с довољно катанаца у канти $1.",
        "protectedpages-performer": "Заштитио",
        "protectedpages-params": "Ниво заштите",
        "protectedpages-reason": "Разлог",
+       "protectedpages-submit": "Прикажи странице",
        "protectedpages-unknown-timestamp": "нема",
        "protectedpages-unknown-performer": "нема",
        "protectedtitles": "Заштићени наслови",
        "protectedtitles-summary": "На овој страници се налази списак тренутно заштићених наслова. За списак тренутно заштићених страница види [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Нема заштићених наслова с овим параметрима.",
+       "protectedtitles-submit": "Прикажи наслове",
        "listusers": "Списак корисника",
        "listusers-editsonly": "Прикажи само кориснике који су уређивали",
        "listusers-creationsort": "Поређај по датуму стварања",
        "querypage-disabled": "Ова посебна страница је онемогућена ради побољшања перформанси.",
        "apihelp": "API помоћ",
        "apihelp-no-such-module": "Модул „$1“ није пронађен.",
+       "apisandbox": "API песак",
+       "apisandbox-api-disabled": "АПИ је онемогућен на овом сајту.",
+       "apisandbox-submit": "Постави захтев",
+       "apisandbox-reset": "Очисти",
+       "apisandbox-results": "Резултати",
+       "apisandbox-request-url-label": "Адреса захтева:",
        "booksources": "Штампани извори",
        "booksources-search-legend": "Тражи књижевне изворе",
        "booksources-isbn": "ISBN:",
        "wlshowhideanons": "анонимне кориснике",
        "wlshowhidepatr": "патролиране измене",
        "wlshowhidemine": "моје измене",
+       "wlshowhidecategorization": "категоризацију страница",
        "watchlist-options": "Поставке списка надгледања",
        "watching": "Надгледање…",
        "unwatching": "Прекидање надгледања…",
        "version-hook-subscribedby": "Пријављено од",
        "version-version": "($1)",
        "version-no-ext-name": "[нема имена]",
-       "version-svn-revision": "(изм. $2)",
        "version-license": "Медијавики лиценца",
        "version-ext-license": "Лиценца",
        "version-ext-colheader-name": "Екстензија",
        "logentry-import-upload": "$1 је {{GENDER:$2|увезао|увезла}} $3 отпремањем датотеке",
        "logentry-import-upload-details": "$1 је {{GENDER:$2|увезао|увезла}} $3 отпремањем датотеке ($4 {{PLURAL:$4|измена|измене|измена}})",
        "logentry-import-interwiki": "$1 је {{GENDER:$2|увезао|увезла}} $3 с другог викија",
-       "logentry-import-interwiki-details": "$1 је {{GENDER:$2|увезао|увезла}} $3 из $5 ($4 {{PLURAL:$4|измена|измене|измена}})",
+       "logentry-import-interwiki-details": "$1 је {{GENDER:$2|увезао|увезла}} $3 из $5 ($4 {{PLURAL:$4|1=измена|измене|измена}})",
        "logentry-merge-merge": "$1 је {{GENDER:$2|спојио|спојила}} $3 у $4 (све до измене $5)",
        "logentry-move-move": "$1 је {{GENDER:$2|преместио|преместила}} страницу $3 на $4",
        "logentry-move-move-noredirect": "$1 је {{GENDER:$2|преместио|преместила}} страницу $3 на $4 без остављања преусмерења",
index d65ea82..7bae3ac 100644 (file)
@@ -28,6 +28,7 @@
        "tog-hideminor": "Sakrij manje izmene u spisku skorašnjih izmena",
        "tog-hidepatrolled": "Sakrij patrolirane izmene u spisku skorašnjih izmena",
        "tog-newpageshidepatrolled": "Sakrij patrolirane stranice sa spiska novih stranica",
+       "tog-hidecategorization": "Sakrij kategorizaciju stranica",
        "tog-extendwatchlist": "Proširi spisak nadgledanja za prikaz svih izmena, ne samo skorašnjih",
        "tog-usenewrc": "Grupni prikaz izmena svake pojedinačne stranice u skorašnjim izmenama i spisku nadgledanja",
        "tog-numberheadings": "Automatski numeriši podnaslove",
        "tog-watchlisthidebots": "Sakrij izmene botova sa spiska nadgledanja",
        "tog-watchlisthideminor": "Sakrij manje izmene sa spiska nadgledanja",
        "tog-watchlisthideliu": "Sakrij izmene prijavljenih korisnika sa spiska nadgledanja",
+       "tog-watchlistreloadautomatically": "Automatski osveži spisak nadgledanja kad god se filter izmeni (potrebna JavaScript-a)",
        "tog-watchlisthideanons": "Sakrij izmene anonimnih korisnika sa spiska nadgledanja",
        "tog-watchlisthidepatrolled": "Sakrij patrolirane izmene sa spiska nadgledanja",
+       "tog-watchlisthidecategorization": "Sakrij kategorizaciju stranica",
        "tog-ccmeonemails": "Pošalji mi primerke e-poruka koje pošaljem drugim korisnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice ispod razlika",
        "tog-showhiddencats": "Prikaži skrivene kategorije",
        "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice}}",
        "createacct-benefit-body3": "{{PLURAL:$1|aktivni korisnik|aktivnih korisnika}}",
        "badretype": "Unete lozinke se ne poklapaju.",
+       "usernameinprogress": "Nalog za ovo korisničko ime se već pravi, molimo sačekajte.",
        "userexists": "Korisničko ime je zauzeto. Izaberite drugo.",
        "loginerror": "Greška pri prijavljivanju",
        "createacct-error": "Došlo je do greške pri otvaranju naloga",
        "resetpass_submit": "Postavi lozinku i prijavi me",
        "changepassword-success": "Vaša lozinka je uspešno promenjena.",
        "changepassword-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
+       "botpasswords-label-cancel": "Otkaži",
+       "botpasswords-label-delete": "Obriši",
        "resetpass_forbidden": "Lozinka ne može biti promenjena",
        "resetpass-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "resetpass-submit-loggedin": "Promeni lozinku",
        "passwordreset-emailtext-user": "{{GENDER:$1|Korisnik je zatražio|Korisnica je zatražila}} podsetnik o podacima za prijavu na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom e-adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena lozinka: \n$2",
        "passwordreset-emailsentemail": "Podsetnik o lozinci je poslat na vašu adresu.",
+       "passwordreset-emailsentusername": "Ako ste naveli imejl adresu prilikom registracije, biće poslat imejl za resetovanje lozinke.",
        "passwordreset-emailsent-capture": "Poslat je podsetnik preko e-pošte (prikazan dole).",
        "passwordreset-emailerror-capture": "E-poruka za resetovanje lozinke, prikazana ispod je poslata, ali slanje {{GENDER:$2|korisniku|korisnici}} nije uspelo: $1",
        "changeemail": "Promeni ili ukloni e-adresu",
        "changeemail-header": "Promenite e-adresu naloga",
+       "changeemail-passwordrequired": "Morate uneti lozinku da bi potvrdili ovu izmenu.",
        "changeemail-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "changeemail-oldemail": "Trenutna e-adresa:",
        "changeemail-newemail": "Nova e-adresa:",
        "permissionserrorstext-withaction": "Nemate dozvolu za $2 iz {{PLURAL:$1|sledećeg|sledećih}} razloga:",
        "recreate-moveddeleted-warn": "<strong>Upozorenje: ponovo pravite stranicu koja je prethodno obrisana.</strong>\n\nRazmotrite da li je prikladno da nastavite s uređivanjem ove stranice.\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem:",
        "moveddeleted-notice": "Ova stranica je obrisana.\nIstorija njenog brisanja i premeštanja nalazi se ispod:",
+       "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno obrisana (u poslednjih 24 sata).\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem.",
        "log-fulllog": "Pogledaj celu istoriju",
        "edit-hook-aborted": "Izmenu je prekinula kuka.\nNije dato nikakvo obrazloženje.",
        "edit-gone-missing": "Ne mogu da ažuriram stranicu.\nIzgleda da je obrisana.",
        "rev-suppressed-unhide-diff": "Jedna od izmena ove razlike je '''sakrivena'''.\nDetalji se nalaze u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} istoriji sakrivanja].\nIpak možete da [$1 vidite ovu razliku] ako želite da nastavite.",
        "rev-deleted-diff-view": "Jedna od izmena ove razlike je '''obrisana'''.\nIpak možete da vidite ovu razliku; više detalja možete naći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} istoriji brisanja].",
        "rev-suppressed-diff-view": "Jedna od izmena ove razlike je '''sakrivena'''.\nIpak možete da vidite ovu razliku; više detalja možete naći u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} istoriji sakrivanja].",
-       "rev-delundel": "prikaži/sakrij",
+       "rev-delundel": "promeni vidljivost",
        "rev-showdeleted": "prikaži",
        "revisiondelete": "Obriši/vrati izmene",
        "revdelete-nooldid-title": "Nema tražene izmene",
        "columns": "Kolona",
        "searchresultshead": "Pretraga",
        "stub-threshold": "Prag za oblikovanje veze kao klice ($1):",
+       "stub-threshold-sample-link": "primer",
        "stub-threshold-disabled": "Onemogućeno",
        "recentchangesdays": "Broj dana u skorašnjim izmenama:",
        "recentchangesdays-max": "Najviše $1 {{PLURAL:$1|dan|dana}}",
        "prefs-help-recentchangescount": "Podrazumeva skorašnje izmene, istorije stranica i dnevnike.",
        "prefs-help-watchlist-token2": "Ovo je tajni ključ za veb-dovod Vašeg spiska nadgledanja. \nSvako ko zna ovaj ključ biće u mogućnosti da vidi Vaša nadgledanja; stoga, ključ nemojte odavati nikome. \nAko je potrebno, ključ možete [[Special:ResetTokens|resetovati]].",
        "savedprefs": "Vaša podešavanja su sačuvana.",
+       "savedrights": "Korisnička prava za {{GENDER:$1|$1}} su sačuvana.",
        "timezonelegend": "Vremenska zona:",
        "localtime": "Lokalno vreme:",
        "timezoneuseserverdefault": "podrazumevane vrednosti ($1)",
        "grant-createeditmovepage": "Pravljenje, uređivanje i premeštanje stranica",
        "grant-delete": "Brisanje stranica, izmena i unosa u dnevnicima",
        "grant-editinterface": "Uređivanje Medijaviki imenskog prostora i korisničkih CSS/JavaScript stranica",
+       "grant-editmywatchlist": "Uređivanje vašeg spiska nadgledanja",
        "grant-editpage": "Uređivanje postojećih stranica",
+       "grant-editprotected": "Uređivanje zaštićenih stranica",
        "grant-uploadeditmovefile": "Otpremanje, zamena i premeštanje datoteka",
        "grant-uploadfile": "Slanje novih datoteka",
        "newuserlogpage": "Dnevnik novih korisnika",
        "recentchanges-label-plusminus": "Promena veličine stranice u bajtovima",
        "recentchanges-legend-heading": "'''Legenda:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|spisak novih stranica]])",
+       "recentchanges-submit": "Prikaži",
        "rcnotefrom": "Ispod {{PLURAL:$5|je izmena|su izmene}} od <strong>$3, $4</strong> (do <strong>$1</strong> prikazano).",
        "rclistfrom": "Prikaži nove izmene počev od $2 $3",
        "rcshowhideminor": "$1 manje izmene",
        "rcshowhidemine": "$1 moje izmene",
        "rcshowhidemine-show": "Prikaži",
        "rcshowhidemine-hide": "Sakrij",
+       "rcshowhidecategorization": "$1 kategorizaciju stranica",
+       "rcshowhidecategorization-show": "Prikaži",
+       "rcshowhidecategorization-hide": "Sakrij",
        "rclinks": "Prikaži poslednjih $1 izmena {{PLURAL:$2|prethodni dan|u poslednja $2 dana|u poslednjih $2 dana}}<br />$3",
        "diff": "razl",
        "hist": "ist",
        "recentchangeslinked-summary": "Ova posebna stranica prikazuje spisak poslednjih izmena na stranicama koje su povezane (ili članovi određene kategorije).\nStranice s [[Special:Watchlist|vašeg spiska nadgledanja]] su '''podebljane'''.",
        "recentchangeslinked-page": "Naziv stranice:",
        "recentchangeslinked-to": "Prikaži izmene stranica koje su povezane s datom stranicom",
+       "recentchanges-page-added-to-category": "[[:$1]] je dodata u kategoriju",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] i još {{PLURAL:$2|jedna stranica|$2 stranice}} su dodate u kategoriju",
+       "recentchanges-page-removed-from-category": "[[:$1]] je uklonjena iz kategorije",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] i još {{PLURAL:$2|jedna stranica|$2 stranice}} su uklonjene iz kategorije",
+       "autochange-username": "Medijaviki automatska izmena",
        "upload": "Pošalji datoteku",
        "uploadbtn": "Pošalji datoteku",
        "reuploaddesc": "Nazad na obrazac za otpremanje",
        "upload-too-many-redirects": "Adresa sadrži previše preusmerenja",
        "upload-http-error": "Došlo je do HTTP greške: $1",
        "upload-copy-upload-invalid-domain": "Primerci otpremanja nisu dostupni na ovom domenu.",
+       "upload-dialog-title": "Otpremanje datoteka",
+       "upload-dialog-button-cancel": "Otkaži",
+       "upload-dialog-button-done": "Gotovo",
+       "upload-dialog-button-save": "Sačuvaj",
+       "upload-dialog-button-upload": "Pošalji",
+       "upload-form-label-select-file": "Izaberi datoteku",
+       "upload-form-label-infoform-title": "Detalji",
+       "upload-form-label-infoform-name": "Ime",
+       "upload-form-label-infoform-description": "Opis",
+       "upload-form-label-usage-filename": "Naziv datoteke",
+       "foreign-structured-upload-form-label-own-work": "Ovo je moje sopstveno delo",
+       "foreign-structured-upload-form-label-infoform-categories": "Kategorije",
+       "foreign-structured-upload-form-label-infoform-date": "Datum",
+       "foreign-structured-upload-form-2-label-ownwork": "Mora biti <strong>isključivo Vaše delo</strong>, a ne skinuto sa interneta",
+       "foreign-structured-upload-form-2-label-noderiv": "Ne sme biti <strong>tuđe delo</strong> ili prerada istog",
+       "foreign-structured-upload-form-2-label-useful": "Mora biti <strong>obrazovna i korisna</strong> za druge",
+       "foreign-structured-upload-form-2-label-ccbysa": "Mora biti <strong>u redu da se objavi zauvek</strong> na internetu pod licencom [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Autorstvo-Deliti pod istim uslovima 4.0]",
+       "foreign-structured-upload-form-2-label-termsofuse": "Otpremanjem ove datoteke potvrđujete da ste nosilac autorskih prava iste i nepozivo je predajte Vikimedijinoj ostavi pod licencom Creative Commons Autorstvo-Deliti pod istim uslovima 4.0 i prihvatate [https://wikimediafoundation.org/wiki/Terms_of_Use uslove korišćenja].",
+       "foreign-structured-upload-form-3-label-question-website": "Da li ste ovu sliku preuzeli sa nekog sajta ili pretragom slika?",
+       "foreign-structured-upload-form-3-label-question-ownwork": "Da li ste vi napravili ovu sliku (slikali fotoaparatom, nacrtali i sl.)?",
+       "foreign-structured-upload-form-3-label-question-noderiv": "Da li sadrži logotip ili je inspirisana nekim tuđim delom?",
+       "foreign-structured-upload-form-3-label-yes": "Da",
+       "foreign-structured-upload-form-3-label-no": "Ne",
        "backend-fail-stream": "Ne mogu da emitujem datoteku $1.",
        "backend-fail-backup": "Ne mogu da napravim rezervu datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
        "lockmanager-notlocked": "Ne mogu da otključam „$1“ jer nije zaključan.",
        "lockmanager-fail-closelock": "Ne mogu da zatvorim katanac za „$1“.",
        "lockmanager-fail-deletelock": "Ne mogu da obrišem katanac za „$1“.",
-       "lockmanager-fail-acquirelock": "Ne mogu da dobijem katanac za „$1“.",
+       "lockmanager-fail-acquirelock": "Ne mogu da se zaključam za „$1“.",
        "lockmanager-fail-openlock": "Ne mogu da otvorim katanac za „$1“.",
        "lockmanager-fail-releaselock": "Ne mogu da oslobodim katanac za „$1“.",
        "lockmanager-fail-db-bucket": "Ne mogu da kontaktiram s dovoljno katanaca u kanti $1.",
        "mostrevisions": "Stranice s najviše izmena",
        "prefixindex": "Sve stranice s prefiksom",
        "prefixindex-namespace": "Sve stranice s predmetkom (imenski prostor $1)",
+       "prefixindex-submit": "Prikaži",
        "prefixindex-strip": "Sakrij prefiks u spisku",
        "shortpages": "Kratke stranice",
        "longpages": "Dugačke stranice",
        "protectedpages-performer": "Zaštitio",
        "protectedpages-params": "Nivo zaštite",
        "protectedpages-reason": "Razlog",
+       "protectedpages-submit": "Prikaži stranice",
        "protectedpages-unknown-timestamp": "nema",
        "protectedpages-unknown-performer": "nema",
        "protectedtitles": "Zaštićeni naslovi",
        "protectedtitles-summary": "Na ovoj stranici se nalazi spisak trenutno zaštićenih naslova. Za spisak trenutno zaštićenih stranica vidi [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Nema zaštićenih naslova s ovim parametrima.",
+       "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Spisak korisnika",
        "listusers-editsonly": "Prikaži samo korisnike koji su uređivali",
        "listusers-creationsort": "Poređaj po datumu stvaranja",
        "usereditcount": "$1 {{PLURAL:$1|izmena|izmene|izmena}}",
        "usercreated": "{{GENDER:$3|je napravio|je napravila|je napravio}} dana $1 u $2",
        "newpages": "Nove stranice",
+       "newpages-submit": "Prikaži",
        "newpages-username": "Korisničko ime:",
        "ancientpages": "Najstarije stranice",
        "move": "premesti",
        "querypage-disabled": "Ova posebna stranica je onemogućena radi poboljšanja performansi.",
        "apihelp": "API pomoć",
        "apihelp-no-such-module": "Modul „$1“ nije pronađen.",
+       "apisandbox": "API pesak",
+       "apisandbox-api-disabled": "API je onemogućen na ovom sajtu.",
+       "apisandbox-submit": "Postavi zahtev",
+       "apisandbox-results": "Rezultati",
+       "apisandbox-request-url-label": "Adresa zahteva:",
        "booksources": "Štampani izvori",
        "booksources-search-legend": "Traži književne izvore",
        "booksources-isbn": "ISBN:",
        "specialloguserlabel": "Izvršilac:",
        "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:korisničko ime):",
        "log": "Dnevnici",
+       "logeventslist-submit": "Prikaži",
        "all-logs-page": "Svi javni dnevnici",
        "alllogstext": "Skupni prikaz svih dostupnih istorija ovog vikija.\nMožete suziti prikaz odabirući vrstu istorije, korisničkog imena ili tražene stranice.",
        "logempty": "Nema pronađenih unosa u dnevniku.",
        "log-title-wildcard": "Traži naslove koji počinju s ovim tekstom",
        "showhideselectedlogentries": "Prikaži/sakrij izabrane događaje",
+       "log-edit-tags": "Uredi oznake izabranih unosa u dnevnicima",
+       "checkbox-select": "Izaberi: $1",
+       "checkbox-all": "sve",
+       "checkbox-none": "ništa",
+       "checkbox-invert": "obrni",
        "allpages": "Sve stranice",
        "nextpage": "Sledeća stranica ($1)",
        "prevpage": "Prethodna stranica ($1)",
        "cachedspecial-viewing-cached-ts": "Gledate keširanu verziju ove stranice, koja može da se razlikuje od trenutne.",
        "cachedspecial-refresh-now": "Pogledaj najnoviju.",
        "categories": "Kategorije",
+       "categories-submit": "Prikaži",
        "categoriespagetext": "{{PLURAL:$1|1=Sledeća kategorija sadrži|Sledeće kategorije sadrže}} stranice ili datoteke.\n[[Special:UnusedCategories|Nekorišćene kategorije]] nisu prikazane ovde.\nPogledajte i [[Special:WantedCategories|tražene kategorije]].",
        "categoriesfrom": "Prikaži kategorije počev od:",
        "special-categories-sort-count": "poređaj po broju",
        "activeusers-hidebots": "Sakrij botove",
        "activeusers-hidesysops": "Sakrij administratore",
        "activeusers-noresult": "Korisnik nije pronađen.",
+       "activeusers-submit": "Prikaži aktivne korisnike",
        "listgrouprights": "Prava korisničkih grupa",
        "listgrouprights-summary": "Sledi spisak korisničkih grupa na ovom vikiju, zajedno s pravima pristupa.\nPogledajte [[{{MediaWiki:Listgrouprights-helppage}}|više detalja]] o pojedinačnim pravima.",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Dodeljeno pravo</span>\n* <span class=\"listgrouprights-revoked\">Ukinuto pravo</span>",
        "listgrouprights-namespaceprotection-restrictedto": "Prava potrebna za uređivanje",
        "listgrants-rights": "Prava",
        "trackingcategories": "Medijaviki kategorije",
+       "trackingcategories-summary": "Ova posebna stranica je spisak kategorija koje su deo Medijavikija, one se automatski ažuriraju i njihovi nazivi se mogu menjanjati uređivanjem sistemskih poruka u imenskom prostoru {{ns:8}}.",
        "trackingcategories-name": "Ime poruke",
        "trackingcategories-desc": "Koje stranice se nalaze u kategoriji",
        "noindex-category-desc": "Stranice koje u sebi imaju magičnu reč <code><nowiki>__NOINDEX__</nowiki></code>.",
        "wlheader-showupdated": "Stranice koje su izmenjene otkad ste ih poslednji put posetili su '''podebljane'''.",
        "wlnote": "Ispod {{PLURAL:$1|je poslednja izmena|su poslednje <strong>$1</strong> izmene|je poslednjih <strong>$1</strong> izmena}} u {{PLURAL:$2|prethodnom satu|prethodna <strong>$2</strong> sata|prethodnih <strong>$2</strong> sati}}, zaključno sa $3, $4.",
        "wlshowlast": "Prikaži poslednjih $1 sati, $2 dana",
+       "watchlist-hide": "Sakrij",
+       "watchlist-submit": "Prikaži",
        "wlshowtime": "Period za prikaz:",
+       "wlshowhideminor": "manje izmene",
+       "wlshowhidebots": "botove",
+       "wlshowhideliu": "registrovane korisnike",
+       "wlshowhideanons": "anonimne korisnike",
+       "wlshowhidepatr": "patrolirane izmene",
+       "wlshowhidemine": "moje izmene",
+       "wlshowhidecategorization": "kategorizaciju stranica",
        "watchlist-options": "Postavke spiska nadgledanja",
        "watching": "Nadgledanje…",
        "unwatching": "Prekidanje nadgledanja…",
        "delete-confirm": "Brisanje stranice „$1“",
        "delete-legend": "Obriši",
        "historywarning": "<strong>Upozorenje:</strong> stranica koju želite da obrišete ima istoriju sa $1 {{PLURAL:$1|izmenom|izmene|izmena}}:",
+       "historyaction-submit": "Prikaži",
        "confirmdeletetext": "Upravo ćete obrisati stranicu, uključujući i njenu istoriju.\nPotvrdite svoju nameru, da razumete posledice i da ovo radite u skladu s [[{{MediaWiki:Policy-url}}|pravilima]].",
        "actioncomplete": "Radnja je završena",
        "actionfailed": "Radnja nije uspela",
        "contributions": "{{GENDER:$1|Korisnički}} doprinosi",
        "contributions-title": "Doprinosi {{GENDER:$1|korisnika|korisnice}} $1",
        "mycontris": "Doprinosi",
+       "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Korisnički nalog „$1“ nije registrovan.",
        "nocontribs": "Nema izmena koje odgovaraju navedenim kriterijumima.",
        "whatlinkshere-hidelinks": "$1 veze",
        "whatlinkshere-hideimages": "$1 veze do datoteke",
        "whatlinkshere-filters": "Filteri",
+       "whatlinkshere-submit": "Idi",
        "autoblockid": "Automatsko blokiranje #$1",
        "block": "Blokiraj korisnika",
        "unblock": "Deblokiraj korisnika",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] je {{GENDER:$1|blokiran|blokirana|blokiran}}.<br />\nBlokiranja možete da pogledate [[Special:BlockList|ovde]].",
        "ipb-blockingself": "Ovom radnjom ćete blokirati sebe! Jeste li sigurni da to želite?",
        "ipb-confirmhideuser": "Upravo ćete blokirati korisnika s uključenom mogućnošću „sakrij korisnika“. Ovim će korisničko ime biti sakriveno u svim spiskovima i izveštajima. Želite li to da uradite?",
+       "ipb-confirmaction": "Ako ste sigurni da želite nastaviti označite polje „{{int:ipb-confirm}}“ na dnu stranice.",
        "ipb-edit-dropdown": "Uredi razloge blokiranja",
        "ipb-unblock-addr": "Deblokiraj $1",
        "ipb-unblock": "Deblokiraj korisničko ime ili IP adresu",
        "import-interwiki-history": "Kopiraj sve verzije istorije za ovu stranicu",
        "import-interwiki-templates": "Uključi sve šablone",
        "import-interwiki-submit": "Uvezi",
+       "import-mapping-default": "Isto kao i izvorne stranice",
        "import-mapping-namespace": "Uvezi u imenski prostor:",
+       "import-mapping-subpage": "Uvezi kao podstranice sledeće stranice:",
        "import-upload-filename": "Naziv datoteke:",
        "import-comment": "Komentar:",
        "importtext": "Izvezite datoteku s izvornog vikija koristeći [[Special:Export|izvoz]].\nSačuvajte je na računar i pošaljite ovde.",
        "tooltip-pt-preferences": "Vaša podešavanja",
        "tooltip-pt-watchlist": "Spisak stranica koje nadgledate",
        "tooltip-pt-mycontris": "Spisak vaših doprinosa",
+       "tooltip-pt-anoncontribs": "Spisak izmena napravljenih sa ove IP adrese",
        "tooltip-pt-login": "Preporučujemo vam da se prijavite, iako to nije obavezno.",
        "tooltip-pt-logout": "Odjavite se",
        "tooltip-pt-createaccount": "Ohrabrujemo vas da otvorite nalog i prijavite se ali to nije obavezno",
        "pageinfo-category-files": "Broj datoteka",
        "markaspatrolleddiff": "Označi kao patrolirano",
        "markaspatrolledtext": "Označi stranicu kao patroliranu",
+       "markaspatrolledtext-file": "Označi ovu verziju datoteke kao patroliranu",
        "markedaspatrolled": "Označeno kao patrolirano",
        "markedaspatrolledtext": "Izabrana izmena na [[:$1]] je označena kao patrolirana.",
        "rcpatroldisabled": "Patroliranje skorašnjih izmena je onemogućeno",
        "patrol-log-page": "Dnevnik patroliranja",
        "patrol-log-header": "Ovo je dnevnik patroliranih izmena.",
        "log-show-hide-patrol": "$1 dnevnik patroliranja",
+       "log-show-hide-tag": "$1 dnevnik oznaka",
        "deletedrevision": "Obrisana stara izmena $1.",
        "filedeleteerror-short": "Greška pri brisanju datoteke: $1",
        "filedeleteerror-long": "Došlo je do grešaka pri brisanju datoteke:\n\n$1",
        "svg-long-error": "Neispravna SVG datoteka: $1",
        "show-big-image": "Puna veličina",
        "show-big-image-preview": "Veličina ovog prikaza: $1.",
+       "show-big-image-preview-differ": "Veličina ovog $3 pregleda za ovu $2 datoteku je $1.",
        "show-big-image-other": "{{PLURAL:$2|Druga rezolucija|Druge rezolucije}}: $1.",
        "show-big-image-size": "$1 × $2 piksela",
        "file-info-gif-looped": "petlja",
        "newimages-legend": "Filter",
        "newimages-label": "Naziv datoteke (ili njen deo):",
        "newimages-showbots": "Prikaži datoteke koje su poslali botovi",
+       "newimages-hidepatrolled": "Sakrij patrolirana otpremanja",
        "noimages": "Nema ništa.",
        "ilsubmit": "Pretraži",
        "bydate": "po datumu",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|razgovor]])",
        "timezone-utc": "UTC",
        "duplicate-defaultsort": "'''Upozorenje:''' podrazumevani ključ svrstavanja „$2“ menja nekadašnji ključ „$1“.",
+       "duplicate-displaytitle": "<strong>Upozorenje:</strong> naslov za prikaz „$2“ zameniće postojeći „$1“.",
        "version": "Verzija",
        "version-extensions": "Instalirana proširenja",
        "version-skins": "Instalirane teme",
        "version-hook-subscribedby": "Prijavljeno od",
        "version-version": "($1)",
        "version-no-ext-name": "[nema imena]",
-       "version-svn-revision": "(izm. $2)",
        "version-license": "Medijaviki licenca",
        "version-ext-license": "Licenca",
        "version-ext-colheader-name": "Ekstenzija",
        "version-libraries": "Instalirane biblioteke",
        "version-libraries-library": "Biblioteka",
        "version-libraries-version": "Verzija",
+       "version-libraries-license": "Licenca",
+       "version-libraries-description": "Opis",
+       "version-libraries-authors": "Autori",
        "redirect": "Preusmerenje na datoteku, korisnika, stranicu ili izmenu",
        "redirect-legend": "Preusmeri na datoteku ili stranicu",
        "redirect-submit": "Idi",
        "tags-actions-header": "Radnje",
        "tags-active-yes": "Da",
        "tags-active-no": "Ne",
+       "tags-source-extension": "Deo ekstenzije",
+       "tags-source-manual": "Ručno je dodaju korisnici i botovi",
        "tags-source-none": "Van upotrebe",
        "tags-edit": "uredi",
        "tags-delete": "obriši",
        "tags-hitcount": "$1 {{PLURAL:$1|izmena|izmene|izmena}}",
        "tags-manage-no-permission": "Nemate dozvolu da menjate oznake.",
        "tags-create-heading": "Nova oznaka",
+       "tags-create-explanation": "Po podrazumevanim podešavanjima nove oznake moći će da koriste korisnici i botovi.",
        "tags-create-tag-name": "Naziv oznake:",
        "tags-create-reason": "Razlog:",
        "tags-create-submit": "Napravi",
        "tags-create-warnings-below": "Pravite novu oznaku, želite li da nastavite?",
        "tags-delete-title": "Brisanje oznaka",
        "tags-delete-explanation-initial": "Brišete oznaku „$1“ iz baze podataka.",
+       "tags-delete-explanation-warning": "Ova radnja je <strong>nepovratna</strong> i <strong>ne može se poništiti</strong>, čak ni administratori baze podataka je ne mogu poništiti. Budite sigurni da je ovo oznaka koju želite obrisati.",
        "tags-delete-reason": "Razlog:",
        "tags-delete-submit": "Nepovratno obriši ovu oznaku",
        "tags-delete-not-found": "Oznaka „$1“ ne postoji.",
        "tags-deactivate-reason": "Razlog:",
        "tags-deactivate-not-allowed": "Nije moguće deaktivirati oznaku „$1“.",
        "tags-deactivate-submit": "Dekativiraj",
+       "tags-edit-title": "Uredi oznake",
+       "tags-edit-manage-link": "Upravljaj oznakama",
        "tags-edit-existing-tags": "Postojeće oznake:",
        "tags-edit-new-tags": "Nove oznake:",
        "tags-edit-reason": "Razlog:",
        "htmlform-cloner-create": "Dodaj još",
        "htmlform-cloner-delete": "Ukloni",
        "htmlform-cloner-required": "Bar jedna vrednost je potrebna.",
+       "htmlform-title-badnamespace": "[[:$1]] nije u imenskom prostoru „{{ns:$2}}“.",
+       "htmlform-title-not-exists": "$1 ne postoji.",
        "htmlform-user-not-exists": "<strong>$1</strong> ne postoji.",
        "htmlform-user-not-valid": "<strong>$1</strong> nije ispravno korisničko ime.",
        "sqlite-has-fts": "$1 s podrškom pretrage celog teksta",
        "logentry-suppress-block": "$1 je {{GENDER:$2|blokirao|blokirala}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-suppress-reblock": "$1 je {{GENDER:$2|promenio|promenila}} podešavanja za blokiranje {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-import-upload": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke",
+       "logentry-import-upload-details": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke ($4 {{PLURAL:$4|izmena|izmene|izmena}})",
        "logentry-import-interwiki": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 s drugog vikija",
+       "logentry-import-interwiki-details": "$1 је {{GENDER:$2|увезао|увезла}} $3 из $5 ($4 {{PLURAL:$4|1=измена|измене|измена}})",
        "logentry-merge-merge": "$1 je {{GENDER:$2|spojio|spojila}} $3 u $4 (sve do izmene $5)",
        "logentry-move-move": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4",
        "logentry-move-move-noredirect": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 bez ostavljanja preusmerenja",
        "logentry-newusers-create2": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3",
        "logentry-newusers-byemail": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3 i lozinka je poslata na e-poštu",
        "logentry-newusers-autocreate": "Korisnički nalog $1 je automatski {{GENDER:$2|otvoren}}",
+       "logentry-protect-move_prot": "$1 je {{GENDER:$2|premestio|premestila}} postavke zaštite sa $4 na $3",
+       "logentry-protect-unprotect": "$1 je {{GENDER:$2|skinuo|skinula}} zaštitu sa stranice $3",
+       "logentry-protect-protect": "$1 je {{GENDER:$2|zaštitio|zaštitila}} $3 $4",
+       "logentry-protect-protect-cascade": "$1 je {{GENDER:$2|zaštitio|zaštitila}} $3 $4 [prenosiva zaštita]",
+       "logentry-protect-modify": "$1 je {{GENDER:$2|promenio|promenila}} stepen zaštite za $3 $4",
+       "logentry-protect-modify-cascade": "$1 je {{GENDER:$2|promenio|promenila}} stepen zaštite za $3 $4 [prenosiva zaštita]",
        "logentry-rights-rights": "$1 je {{GENDER:$2|promenio|promenila}} članstvo grupe za $3 iz $4 u $5",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|promenio|promenila}} čalnstvo grupe za $3",
        "logentry-rights-autopromote": "$1 je automatski {{GENDER:$1|unapređen|unapređena}} iz $4 u $5",
        "logentry-managetags-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} oznaku „$4“ (uklonjena je iz $5 {{PLURAL:$5|izmene ili dnevnika|izmena i/ili dnevnika}})",
        "logentry-managetags-activate": "$1 je {{GENDER:$2|aktivirao|aktivirala}} oznaku „$4“ za upotrebu od strane korisnika i botova",
        "logentry-managetags-deactivate": "$1 je {{GENDER:$2|deaktivirao|deaktivirala}} oznaku „$4“ za upotrebu od strane korisnika i botova",
+       "log-name-tag": "Dnevnik oznaka",
+       "log-description-tag": "Ovaj dnevnik prikazuje dodavanje/uklanjanje [[Special:Tags|oznaka]] na pojedinačne izmene ili unose u dnevnicima. Ovaj dnevnik ne prikazuje označavanje kada su ona deo uređivanja, brisanja ili neke druge radnje.",
        "rightsnone": "(nema)",
        "revdelete-summary": "opis izmene",
        "feedback-adding": "Dodajem povratnu informaciju na stranicu…",
        "feedback-bugornote": "Ako ste spremni da detaljno opišete tehnički problem, onda [$1 prijavite grešku].\nU suprotnom, poslužite se jednostavnim obrascem ispod. Vaš komentar će stajati na stranici „[$3 $2]“, zajedno s korisničkim imenom i pregledačem koji koristite.",
        "feedback-cancel": "Otkaži",
        "feedback-close": "Urađeno",
+       "feedback-external-bug-report-button": "Prijavi bag",
        "feedback-error-title": "Greška",
        "feedback-error1": "Greška: neprepoznat rezultat od API-ja",
        "feedback-error2": "Greška: uređivanje nije uspelo",
        "feedback-message": "Poruka:",
        "feedback-subject": "Naslov:",
        "feedback-submit": "Pošalji",
+       "feedback-termsofuse": "Prihvatam da pošaljem povratne informacije u skladu sa uslovima korišćenja.",
        "feedback-thanks": "Hvala! Vaša povratna informacija je postavljena na stranicu „[$2 $1]“.",
        "feedback-thanks-title": "Hvala vam!",
        "searchsuggest-search": "Pretraga",
        "pagelang-name": "Stranica",
        "pagelang-language": "Jezik",
        "pagelang-select-lang": "Izaberi jezik",
+       "pagelang-submit": "Pošalji",
        "right-pagelang": "menjanje jezika stranice",
        "action-pagelang": "promenu jezika stranice",
        "logentry-pagelang-pagelang": "$1 je {{GENDER:$2|promenio|promenila}} jezik stranice $3 iz $4 u $5.",
        "mediastatistics-header-text": "Tekstualne",
        "mediastatistics-header-executable": "Izvršne",
        "mediastatistics-header-archive": "Kompresovane",
+       "mediastatistics-header-total": "Sve datoteke",
        "json-error-syntax": "Greška u sintaksi",
        "headline-anchor-title": "Veza do ovog odeljka",
        "special-characters-group-latin": "latinica",
        "special-characters-group-thai": "tajlandski",
        "special-characters-group-lao": "laoski",
        "special-characters-group-khmer": "kmerski",
+       "mw-widgets-dateinput-no-date": "Datum nije izabran",
        "mw-widgets-dateinput-placeholder-day": "GGGG-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
        "mw-widgets-titleinput-description-new-page": "stranica još uvek ne postoji",
index 8f0ae06..b4fda80 100644 (file)
        "uploaded-script-svg": "Hittade skriptelementet \"$1\" i den uppladdade SVG-filen.",
        "uploaded-hostile-svg": "Hittade osäker CSS i den uppladdade filens stilelement.",
        "uploaded-event-handler-on-svg": "Att ange event-handler-attribut <code>$1=\"$2\"</code> är inte tillåtet i SVG-filer.",
-       "uploaded-href-attribute-svg": "href-attribut <code>&lt;$1 $2=\"$3\"&gt;</code> med icke-lokala mål (t.ex. http://, javascript:, etc) tillåts inte i SVG filer.",
-       "uploaded-href-unsafe-target-svg": "Hittade href till ett osäkert mål <code>&lt;$1 $2=\"$3\"&gt;</code> i den uppladdade SVG-filen.",
+       "uploaded-href-attribute-svg": "href-attribut i SVG-filer tillåts endast att länka till http:// eller https:// som återfinns <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Hittade href till osäker data: URI-mål <code>&lt;$1 $2=\"$3\"&gt;</code> i den uppladdade SVG-filen.",
        "uploaded-animate-svg": "Hittades taggen \"animate\" som kan ändra href med hjälp av attributen \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> i den uppladdade SVG-filen.",
        "uploaded-setting-event-handler-svg": "Att ange event-handler-attribut är blockerat. Hittade <code>&lt;$1 $2=\"$3\"&gt;</code> i den uppladdade SVG-filen.",
        "uploaded-setting-href-svg": "Användning av taggen \"set\" för att lägga till attributen \"href\" till överordnade element blockeras.",
        "querypage-disabled": "Den här specialsidan är inaktiverad av prestandaskäl.",
        "apihelp": "API-hjälp",
        "apihelp-no-such-module": "Modulen ”$1” hittades inte",
+       "apisandbox": "API-sandlåda",
+       "apisandbox-jsonly": "JavaScript krävs för att använda API-sandlådan.",
+       "apisandbox-api-disabled": "API är inaktiverat på denna webbplats.",
+       "apisandbox-intro": "Använd den här sidan för att experimentera med <strong>MediaWikis API för webbtjänster</strong>.\nSe [[mw:API:Main page|API-dokumentationen]] för ytterligare detaljer kring API-användningen. Exempel: [//www.mediawiki.org/wiki/API#A_simple_example få innehållet från en huvudsida]. Välj en handling för att se fler exempel.\n\nObservera att även om detta är en sandlåda kan handlingar du utför på denna sida påverka wikin.",
+       "apisandbox-fullscreen": "Utvidga panel",
+       "apisandbox-fullscreen-tooltip": "Utvidga sandlådspanelen för att fylla webbläsarens fönster.",
+       "apisandbox-unfullscreen": "Visa sida",
+       "apisandbox-unfullscreen-tooltip": "Förminska sandlådspanelen så MediaWikis navigeringslänkar syns.",
+       "apisandbox-submit": "Utför begäran",
+       "apisandbox-reset": "Rensa",
+       "apisandbox-retry": "Försök igen",
+       "apisandbox-loading": "Läser in information för API-modulen \"$1\"...",
+       "apisandbox-load-error": "Ett fel uppstod när information för API-modulen \"$1\" lästes in: $2",
+       "apisandbox-no-parameters": "Denna API-modul har inga parametrar.",
+       "apisandbox-helpurls": "Hjälplänkar",
+       "apisandbox-examples": "Exempel",
+       "apisandbox-dynamic-parameters": "Ytterligare parametrar",
+       "apisandbox-dynamic-parameters-add-label": "Lägg till parameter:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Parameternamn",
+       "apisandbox-dynamic-error-exists": "En parameter som heter \"$1\" finns redan.",
+       "apisandbox-deprecated-parameters": "Föråldrade parametrar",
+       "apisandbox-submit-invalid-fields-title": "En del fält är ogiltiga",
+       "apisandbox-submit-invalid-fields-message": "Korrigera de markerade fälten och försök igen.",
+       "apisandbox-results": "Resultat",
+       "apisandbox-sending-request": "Skickar API-begäran...",
+       "apisandbox-loading-results": "Hämtar API-resultat...",
+       "apisandbox-request-url-label": "Begärd URL:",
+       "apisandbox-request-time": "Tid för begäran: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-alert-page": "Fälten på denna sida är inte giltiga.",
+       "apisandbox-alert-field": "Värdet i detta fält är inte giltigt.",
        "booksources": "Bokkällor",
        "booksources-search-legend": "Sök efter bokkällor",
        "booksources-search": "Sök",
index b08fae9..f31ac1b 100644 (file)
        "print": "Drukuj",
        "view": "Podglůnd",
        "view-foreign": "Uobejrzij we {{grammar:MS.lp|$1}}",
-       "edit": "Sprowiyj",
+       "edit": "Sprowjej",
        "create": "Stwůrz",
        "create-local": "Wkludź lokalny uopis",
        "editthispage": "Sprowjej ta zajta",
        "newmessageslinkplural": "{{PLURAL:$1|jedno nowina|999=nowiny}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|uostatńe sprowjyńe|999=uostatńe sprowjyńa}}",
        "youhavenewmessagesmulti": "Mosz nowe powjadůmjyńa: $1",
-       "editsection": "Sprowiyj",
+       "editsection": "Sprowjej",
        "editold": "sprowjej",
        "viewsourceold": "pokoż zdrzůdło",
        "editlink": "sprowjej",
        "createaccountreason": "Kůmyntorz:",
        "createacct-reason": "Powůd:",
        "createacct-reason-ph": "Pojakymu tworzisz nowe kůnta",
-       "createacct-captcha": "Zicherkontrola",
-       "createacct-imgcaptcha-ph": "Wszkryflej tekst, kery widoć powyżyj",
        "createacct-submit": "Twůrz kůnto",
        "createacct-another-submit": "Twůrz inksze kůnto",
        "createacct-benefit-heading": "{{grammar:B.lp|{{SITENAME}}}} tworzům perzůny take kej Ty.",
        "passwordreset-emailtitle": "Kůnto na {{GRAMMAR:MS.lp|{{SITENAME}}}}",
        "passwordreset-emailtext-ip": "Ftoś (cheba Ty, s IP $1)\npado, aże chce informacyji lo konta do {{GRAMMAR:MS.lp{{SITENAME}}}} ($4).\nZe tym ausdrukym sům powjůnzane kůnta:\n$2\n\n{{PLURAL:$3|Tymczasowygo hasła|Tymczasowych hasył}} możno użyć we {{PLURAL:$5|jedyn dźyń|$5 dńi}}.\n\nJak chćołżeś gynał to zrobjyć, to zaloguj śe terozki a podej swoje hasło.\n\nJak ftoś inkszy chćoł nowe hasło abo jak Ci śe przipůmńoło stare a ńy chcysz nowygo, to zignoruj to a używej starygo hasła.",
        "passwordreset-emailelement": "Mjano sprowjorza: \n$1\n\nTymczasowe hasło: \n$2",
-       "passwordreset-emailsent": "E-brif posłany.",
+       "passwordreset-emailsentemail": "E-brif posłany.",
        "passwordreset-emailsent-capture": "E-brif posłony, kerego widać niżej.",
        "passwordreset-emailerror-capture": "Ńy udoło śe posłać wjadomości lo {{GENDER:$2|używocza|używoczki}}: $1",
        "changeemail": "Pomjyno ausdruka e-mail",
        "right-blockemail": "Zablokuj użytkowńikowi posyłańy e-brifůw",
        "right-hideuser": "Zablokuj mjano użytkowńika i schrůń to przed publicznym dostympym",
        "right-ipblock-exempt": "Uobejdź zawarća uod sprowjyń do IP, autozawarća i zawarća zakresůw",
-       "right-proxyunbannable": "Uobejdź autůmatyczne zawarća uod sprowjyń do proxy",
        "right-protect": "Zmjyń poźůmy zawarć i sprowjej zawarte zajty",
        "right-editprotected": "Sprowjej zawarte zajty (ze zawarćym kaskadowym)",
        "right-editinterface": "Sprowjej interfejs użytkowńika",
        "watchthisupload": "Dowej pozůr na ta zajta",
        "filewasdeleted": "Plik uo takym mjańy juž bůu sam wćepany, ale zostou wyćepńjynty. Ńim wćepńeš go zaś, sprowdź $1.",
        "filename-bad-prefix": "Mjano plika, kery wćepujesz, zaczyno śe uod '''\"$1\"''' &ndash; je to mjano nojczynśćy przipisywane autůmatyczńy bez cyfrowe fotoaparaty, a  ńy dowo uůno żodnych informacyji uo zawartośći plika. Proszymy cobyś nadoł plikowi inksze, lepij zrozůmjałe mjano.",
-       "upload-success-subj": "Wćepańe plika udouo śe",
        "upload-proto-error": "Ńyprowidłowy protokůł",
        "upload-proto-error-text": "Zdalne přesůuańy plikůw wymago podańo adresu URL kery začyno śe na <code>http://</code> abo <code>ftp://</code>.",
        "upload-file-error": "Wewnyntřny feler",
        "movelogpagetext": "Uoto lista zajtůw, kere uostatńo zostouy přećepane.",
        "movereason": "Czymu:",
        "revertmove": "cofej",
-       "delete_and_move": "Wyćep i przećep",
        "delete_and_move_text": "== Przećepańy wymogo wyćepańo inkszyj zajty ==\nZajta docelowo „[[:$1]]” już sam jest.\nCzy chcysz jům wyćepać, coby zrobić plac do przećepywanej zajty?",
        "delete_and_move_confirm": "Toć, wyćep zajta",
        "delete_and_move_reason": "Wyćepano coby zrobić plac do přećepywanyj zajty",
index 861a294..4b170ce 100644 (file)
        "php-uploaddisabledtext": "Дар PHP боркунии парванда ғайрифаъол шудааст.\nЛутфан танзимоти file_uploads баррасӣ намоед.",
        "uploadscripted": "Ин парванда коди скриптӣ ё HTML дорад, ки метавонад дар мурургарӣ веб нодуруст намоён шавад.",
        "upload-scripted-pi-callback": "Имкони боргузории файл ки мундариҷаи услуби коркарди XML-дастур дорад, нест.",
-       "uploaded-href-attribute-svg": "Муайянкунанда <нишон>&lt;$1 $2=\"$3\"&gt;</нишон> дар ҳадафҳои ғайри маҳаллӣ (масалан: http://, JavaScript:, ва ғайра) дар SVG-файлҳо иҷозат дода намешавад.",
        "uploadvirus": "Ин парванда вирус дорад! Ҷузъиёт: $1",
        "upload-source": "Парвандаи манбаъ",
        "sourcefilename": "Номи парвандаи аслӣ:",
        "watchthisupload": "Пайгирии ин парванда",
        "filewasdeleted": "Парвандае бо ҳамин ном пештар боргузорӣ ва пас аз он пок шудааст. Пеш аз боргузорӣ ба $1 нигаред.",
        "filename-bad-prefix": "Номи парвандае, ки шумо боргузори карданиед бо '''\"$1\"''' оғоз мешавад, ки як пешванди махсуси аксҳои сабтшуда тавассути аксбардоракҳои рақамӣ аст. Лутфан номи беҳтари тавсифотӣ барои парванда интихоб кунед.",
-       "upload-success-subj": "Фиристодан бомуваффақият",
-       "upload-success-msg": "Боркуниатон аз [$2] муваффақ буд. Он дар инҷо дастрас аст: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "Ишколи боркунӣ",
-       "upload-warning-subj": "Ҳушдори боркунӣ",
        "upload-proto-error": "Қарордоди нодуруст",
        "upload-proto-error-text": "Боргузори аз дурдаст бо нишонаҳое, ки бо <code>http://</code> ё <code>ftp://</code> оғоз мешаванд, ниёз дорад.",
        "upload-file-error": "Хатои дохилӣ",
        "wlheader-showupdated": "Саҳифаҳое, ки пас аз охирин сар заданатон ба онҳо тағйир кардаанд '''пурранг''' нишон дода шудаанд",
        "wlnote": "Дар зер {{PLURAL:$1|охирин тағйир|'''$1''' охирин тағйирот}} дар $2 соати охир {{PLURAL:омадааст|омадаанд}}.",
        "wlshowlast": "Намоиши охирин $1 соат $2 рӯзҳо",
-       "watchlistall2": "ҳама",
        "watchlist-options": "Ихтиёроти феҳристи пайгириҳо",
        "watching": "Пайгири...",
        "unwatching": "Тавқифи пайгири...",
        "expand_templates_ok": "Таъйид",
        "expand_templates_remove_comments": "Ҳазфи тавзеҳот",
        "expand_templates_generate_xml": "Намоиши дарахти таҷзеҳи XML",
-       "expand_templates_preview": "Пешнамоиш"
+       "expand_templates_preview": "Пешнамоиш",
+       "randomrootpage": "Саҳифаи решавии тасодуфӣ"
 }
index 3f92eb1..5620cbb 100644 (file)
        "log-title-wildcard": "ค้นหาชื่อเรื่องซึ่งขึ้นต้นด้วยข้อความนี้",
        "showhideselectedlogentries": "เปลี่ยนทัศนวิสัยของหน่วยปูมที่เลือก",
        "log-edit-tags": "ป้ายระบุการแก้ไขของรายการปูมที่เลือก",
+       "checkbox-select": "เลือก: $1",
+       "checkbox-all": "ทั้งหมด",
+       "checkbox-none": "ไม่เลือก",
+       "checkbox-invert": "กลับ",
        "allpages": "หน้าทั้งหมด",
        "nextpage": "หน้าถัดไป ($1)",
        "prevpage": "หน้าก่อนหน้า ($1)",
        "wlheader-showupdated": "หน้าที่มีการเปลี่ยนแปลงตั้งแต่คุณเยี่ยมครั้งสุดท้ายแสดงด้วย<strong>ตัวหนา</strong>",
        "wlnote": "ด้านล่างเป็น{{PLURAL:$1|การเปลี่ยนแปลงหลังสุด| <strong>$1</strong> การเปลี่ยนแปลงหลังสุด}} ใน{{PLURAL:$2|ชั่วโมง| <strong>$2</strong> ชั่วโมง}}ที่หลังสุด จนถึง $3, $4",
        "wlshowlast": "แสดง $1 ชั่วโมง $2 วันล่าสุด",
-       "watchlistall2": "ทั้งหมด",
        "watchlist-hide": "ซ่อน",
        "watchlist-submit": "แสดง",
        "wlshowtime": "ระยะเวลาที่แสดง:",
        "wlshowhideanons": "ผู้ใช้นิรนาม",
        "wlshowhidepatr": "การแก้ไขที่ตรวจสอบแล้ว",
        "wlshowhidemine": "การแก้ไขของฉัน",
+       "wlshowhidecategorization": "การจัดหมวดหมู่หน้า",
        "watchlist-options": "ตัวเลือกรายการเฝ้าดู",
        "watching": "กำลังเฝ้าดู...",
        "unwatching": "กำลังเลิกเฝ้าดู...",
        "unblock": "ปลดบล็อกผู้ใช้",
        "blockip": "บล็อกผู้ใช้",
        "blockip-legend": "บล็อกผู้ใช้",
-       "blockiptext": "à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81สิà¸\97à¸\98ิà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีหรือà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\82à¸\94ยà¹\80à¸\88าะà¸\88à¸\87 à¸\81ารà¸\9aลà¹\87อà¸\81à¸\99ีà¹\89à¸\84วรà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารà¸\81à¹\88อà¸\81วà¸\99à¹\80à¸\97à¹\88าà¸\99ัà¹\89à¸\99 à¹\81ละà¹\83หà¹\89สอà¸\94à¸\84ลà¹\89อà¸\87à¸\81ัà¸\9a[[{{MediaWiki:Policy-url}}|à¸\99à¹\82ยà¸\9aาย]]\nà¸\81รอà¸\81à¹\80หà¸\95ุà¸\9cลà¹\82à¸\94ยà¹\80à¸\88าะà¸\88à¸\87à¸\94à¹\89าà¸\99ลà¹\88าà¸\87 (à¹\80à¸\8aà¹\88à¸\99 à¸­à¹\89าà¸\87à¸\96ึà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81à¸\81à¹\88อà¸\81วà¸\99)",
+       "blockiptext": "à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81à¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีหรือà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\82à¸\94ยà¹\80à¸\88าะà¸\88à¸\87 à¸\81ารà¸\9aลà¹\87อà¸\81à¸\99ีà¹\89à¸\84วรà¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¹\80à¸\9eืà¹\88อà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารà¸\81à¹\88อà¸\81วà¸\99à¹\80à¸\97à¹\88าà¸\99ัà¹\89à¸\99 à¹\81ละà¹\83หà¹\89สอà¸\94à¸\84ลà¹\89อà¸\87à¸\81ัà¸\9a[[{{MediaWiki:Policy-url}}|à¸\99à¹\82ยà¸\9aาย]]\nà¸\81รอà¸\81à¹\80หà¸\95ุà¸\9cลà¹\82à¸\94ยà¹\80à¸\88าะà¸\88à¸\87à¸\94à¹\89าà¸\99ลà¹\88าà¸\87 (à¹\80à¸\8aà¹\88à¸\99 à¸­à¹\89าà¸\87à¸\96ึà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81à¸\81à¹\88อà¸\81วà¸\99)\nà¸\84ุà¸\93สามารà¸\96à¸\9aลà¹\87อà¸\81à¸\8aà¹\88วà¸\87à¹\84อà¸\9eีà¹\84à¸\94à¹\89à¹\82à¸\94ยà¹\83à¸\8aà¹\89วาà¸\81ยสัมà¸\9eัà¸\99à¸\98à¹\8c CIDR à¸\8aà¹\88วà¸\87à¹\83หà¸\8dà¹\88à¸\97ีà¹\88สุà¸\94à¸\97ีà¹\88อà¸\99ุà¸\8dาà¸\95 à¸\84ือ /$1 à¸ªà¸³à¸«à¸£à¸±à¸\9a IPv4 à¹\81ละ /$2 à¸ªà¸³à¸«à¸£à¸±à¸\9a IPv6",
        "ipaddressorusername": "เลขที่อยู่ไอพีหรือชื่อผู้ใช้:",
        "ipbexpiry": "หมดอายุ:",
        "ipbreason": "เหตุผล:",
        "block-log-flags-hiddenname": "ชื่อผู้ใช้ถูกซ่อน",
        "range_block_disabled": "การบล็อกช่วงไอพีของผู้ดูแลระบบถูกปิดใช้งาน",
        "ipb_expiry_invalid": "เวลาหมดอายุไม่ถูกต้อง",
+       "ipb_expiry_old": "เวลาหมดอายุอยู่ในอดีต",
        "ipb_expiry_temp": "การบล็อกชื่อผู้ใช้ที่ซ่อนต้องเป็นการบล็อกถาวร",
        "ipb_hide_invalid": "ไม่สามารถยับยั้งชื่อผู้ใช้นี้ได้ อาจเพราะมีการแก้ไขมากกว่า $1 การแก้ไข",
        "ipb_already_blocked": "\"$1\" ถูกบล็อกแล้ว",
        "lockedbyandtime": "(โดย {{GENDER:$1|$1}} เมื่อวันที่ $2 เวลา $3)",
        "move-page": "ย้าย $1",
        "move-page-legend": "เปลี่ยนชื่อ",
-       "movepagetext": "à¸\81ารà¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\88ะà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อหà¸\99à¹\89า à¹\81ละยà¹\89ายà¸\9bระวัà¸\95ิà¸\97ัà¹\89à¸\87หมà¸\94à¹\84à¸\9bยัà¸\87à¸\8aืà¹\88อà¹\83หมà¹\88\nà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\80à¸\81à¹\88าà¸\88ะà¸\81ลายà¹\80à¸\9bà¹\87à¸\99หà¸\99à¹\89าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\97าà¸\87à¹\84à¸\9bยัà¸\87ชื่อเรื่องใหม่\nคุณสามารถปรับการเปลี่ยนทางซึ่งชี้ไปยังชื่อเรื่องเดิมได้อัตโนมัติ\nแต่หากคุณเลือกไม่ทำเช่นนั้น ให้แน่ใจว่าตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางเสีย]]\nคุณเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร\n\nโปรดทราบว่าหน้าดังกล่าวจะ<strong>ไม่</strong>ถูกย้าย ถ้ามีหน้าที่ใช้ชื่อเรื่องใหม่แล้ว เว้นแต่หน้านั้นเป็นหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต\nซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้\n\n<strong>คำเตือน!</strong>\nสิ่งนี้อาจเป็นการเปลี่ยนแปลงที่รุนแรงและไม่คาดคิดสำหรับหน้าที่เป็นที่นิยม\nโปรดให้แน่ใจว่าคุณเข้าใจผลลัพธ์นี้ก่อนดำเนินการ",
+       "movepagetext": "à¸\81ารà¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¸\88ะà¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อหà¸\99à¹\89า à¹\81ละยà¹\89ายà¸\9bระวัà¸\95ิà¸\97ัà¹\89à¸\87หมà¸\94à¹\84à¸\9bà¸\8aืà¹\88อà¹\83หมà¹\88\nà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¹\80à¸\81à¹\88าà¸\88ะà¸\81ลายà¹\80à¸\9bà¹\87à¸\99หà¸\99à¹\89าà¹\80à¸\9bลีà¹\88ยà¸\99à¸\97าà¸\87à¹\84à¸\9bชื่อเรื่องใหม่\nคุณสามารถปรับการเปลี่ยนทางซึ่งชี้ไปยังชื่อเรื่องเดิมได้อัตโนมัติ\nแต่หากคุณเลือกไม่ทำเช่นนั้น ให้แน่ใจว่าตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางเสีย]]\nคุณเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร\n\nโปรดทราบว่าหน้าดังกล่าวจะ<strong>ไม่</strong>ถูกย้าย ถ้ามีหน้าที่ใช้ชื่อเรื่องใหม่แล้ว เว้นแต่หน้านั้นเป็นหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต\nซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้\n\n<strong>คำเตือน!</strong>\nสิ่งนี้อาจเป็นการเปลี่ยนแปลงที่รุนแรงและไม่คาดคิดสำหรับหน้าที่เป็นที่นิยม\nโปรดให้แน่ใจว่าคุณเข้าใจผลลัพธ์นี้ก่อนดำเนินการ",
        "movepagetext-noredirectfixer": "การใช้แบบด้านล่างจะเปลี่ยนชื่อหน้า ซึ่งจะทำให้ประวัติทั้งหมดย้ายไปยังชื่อใหม่\nชื่อเรื่องเก่าจะกลายเป็นหน้าเปลี่ยนทางไปยังชื่อเรื่องใหม่\nให้แน่ใจว่า ตรวจสอบ[[Special:DoubleRedirects|หน้าเปลี่ยนทางซ้ำซ้อน]]หรือ[[Special:BrokenRedirects|หน้าเปลี่ยนทางที่เสีย]]\nคุณจะเป็นผู้รับผิดชอบเพื่อให้แน่ใจว่าลิงก์ต่าง ๆ ยังชี้ไปยังที่ที่สมควร\n\nโปรดทราบว่าหน้าดังกล่าวจะ'''ไม่'''ถูกย้าย ถ้ามีหน้าที่ใช้ชื่อเรื่องใหม่อยู่แล้ว เว้นแต่เป็นหน้าว่างหรือหน้าเปลี่ยนทาง และไม่มีประวัติการแก้ไขในอดีต\nซึ่งหมายความว่า คุณสามารถเปลี่ยนชื่อหน้ากลับเป็นชื่อเดิมได้หากคุณทำผิดพลาด และคุณไม่สามารถเขียนทับหน้าที่มีอยู่แล้วได้\n\n'''คำเตือน!'''\nสิ่งนี้อาจเป็นการเปลี่ยนแปลงที่รุนแรงและไม่คาดคิดสำหรับหน้าที่เป็นที่นิยม\nโปรดแน่ใจว่าคุณเข้าใจถึงผลลัพธ์นี้ก่อนที่จะดำเนินการต่อไป",
-       "movepagetalktext": "หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\88ะà¸\96ูà¸\81à¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อà¸\95ามà¹\84à¸\9bà¹\82à¸\94ยอัà¸\95à¹\82à¸\99มัà¸\95ิ<strong>à¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88:</strong>\n*มีหà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\8bึà¹\88à¸\87à¹\84มà¹\88วà¹\88าà¸\87ภายà¹\83à¸\95à¹\89à¸\8aืà¹\88อà¹\83หมà¹\88à¹\81ลà¹\89ว à¸«à¸£à¸·à¸­\n*à¸\84ุà¸\93à¹\84มà¹\88à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\94à¹\89าà¸\99ลà¹\88าà¸\87\n\nในกรณีเหล่านี้ คุณจะต้องย้ายหรือรวมหน้าเองหากต้องการ",
+       "movepagetalktext": "หาà¸\81à¸\84ุà¸\93à¹\80ลือà¸\81à¸\81ลà¹\88อà¸\87à¸\99ีà¹\89 à¸«à¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89à¸\88ะà¸\96ูà¸\81à¹\80à¸\9bลีà¹\88ยà¸\99à¸\8aืà¹\88อà¸\95ามà¹\84à¸\9bà¹\82à¸\94ยอัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80วà¹\89à¸\99à¹\81à¸\95à¹\88à¸\9bลายà¸\97าà¸\87มีหà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยà¹\84มà¹\88วà¹\88าà¸\87à¹\81ลà¹\89ว\n\nในกรณีเหล่านี้ คุณจะต้องย้ายหรือรวมหน้าเองหากต้องการ",
        "moveuserpage-warning": "<strong>คำเตือน:</strong> คุณกำลังย้ายหน้าผู้ใช้ โปรดทราบว่าหน้าผู้ใช้เท่านั้นที่จะถูกเปลี่ยนชื่อ แต่ผู้ใช้จะ<em>ไม่</em>ถูกเปลี่ยนชื่อ",
        "movecategorypage-warning": "<strong>คำเตือน:</strong> คุณกำลังย้ายหน้าหมวดหมู่ โปรดทราบว่า จะย้ายเฉพาะหน้าและทุกหน้าในหมวดหมู่เก่าจะ<em>ไม่</em>ถูกจัดเข้าหมวดหมู่ใหม่",
        "movenologintext": "ถ้าต้องการเปลี่ยนชื่อหน้านี้ ต้องเป็นผู้ใช้ลงทะเบียนและ[[Special:UserLogin|ล็อกอิน]]",
        "movenosubpage": "หน้านี้ไม่มีหน้าย่อย",
        "movereason": "เหตุผล:",
        "revertmove": "ย้อน",
-       "delete_and_move_text": "== ต้องการลบ ==\nมีหน้าปลายทาง \"[[:$1]]\" แล้ว \nคุณต้องการลบหน้าดังกล่าวเพื่อสร้างหนทางสำหรับการย้ายหรือไม่",
+       "delete_and_move_text": "มีหน้าปลายทาง \"[[:$1]]\" แล้ว \nคุณต้องการลบหน้าดังกล่าวเพื่อสร้างทางสำหรับการย้ายหรือไม่",
        "delete_and_move_confirm": "ใช่ ลบหน้านั้น",
        "delete_and_move_reason": "ถูกลบเพื่อสร้างหนทางสำหรับการย้ายจาก \"[[$1]]\"",
        "selfmove": "ชื่อหน้าต้นทางและปลายทางเหมือนกัน\nไม่สามารถเปลี่ยนชื่อมาใช้ชื่อเดิมได้",
        "move-leave-redirect": "สร้างหน้าเปลี่ยนทางตามมา",
        "protectedpagemovewarning": "<strong>คำเตือน:</strong>  หน้านี้ถูกล็อก เฉพาะผู้ใช้ที่มีสิทธิผู้ดูแลระบบเท่านั้นที่ย้ายได้\nปูมล่าสุดแสดงไว้ด้านล่างเพื่อการอ้างอิง:",
        "semiprotectedpagemovewarning": "'''หมายเหตุ:''' หน้านี้ถูกล็อก เฉพาะผู้ใช้ลงทะเบียนเท่านั้นที่ย้ายได้\nรายการปูมล่าสุดได้ถูกแสดงไว้ด้านล่างนี้เพื่อการอ้างอิง:",
-       "move-over-sharedrepo": "== มีไฟล์เดิมปรากฏ ==\nไฟล์ [[:$1]] มีปรากฏเดิมอยู่แล้วในคลังเก็บภาพส่วนกลาง การย้ายไฟล์ที่มีชื่อเรื่องนี้อาจจะเป็นการเขียนทับไฟล์เดิมในคลังเก็บได้",
+       "move-over-sharedrepo": "มี [[:$1]] ในคลังเก็บภาพส่วนกลางแล้ว การย้ายไฟล์ไปชื่อเรื่องนี้จะเขียนทับไฟล์ที่ใช้ร่วมกัน",
        "file-exists-sharedrepo": "ชื่อไฟล์นี้มีปรากฏเดิมอยู่แล้วในคลังเก็บภาพส่วนกลาง\nกรุณาเลือกชื่ออื่น",
        "export": "ส่งออกหน้า",
        "exporttext": "คุณสามารถส่งออกข้อความและประวัติการแก้ไขของหน้าใด ๆ หรือชุดหน้าในคราวเดียว ออกมาในรูปแบบ XML ซึ่งสามารถนำไปใส่เข้าไว้ในวิกิแห่งอื่นที่ใช้ซอฟต์แวร์มีเดียวิกิได้ ผ่านคำสั่ง[[Special:Import|การนำเข้าหน้า]]\n\nการจะส่งออกหน้านั้นสามารถทำได้โดยใส่ชื่อเรื่องหน้าที่ต้องการ ลงในกล่องข้อความด้านล่าง หนึ่งชื่อต่อหนึ่งบรรทัด จากนั้นเลือกว่าต้องการทั้งรุ่นปัจจุบันและรุ่นเก่าทั้งหมดพร้อมกับประวัติของหน้านั้น หรือต้องการเพียงเนื้อหารุ่นปัจจุบันพร้อมกับสารสนเทศของการแก้ไขครั้งสุดท้ายเท่านั้น\n\nในกรณีที่ต้องการเฉพาะรุ่นปัจจุบัน คุณสามารถใช้ในรูปแบบของลิงก์ เช่น [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] สำหรับหน้า \"[[{{MediaWiki:Mainpage}}]]\"",
        "tooltip-pt-preferences": "การตั้งค่าของคุณ",
        "tooltip-pt-watchlist": "รายการหน้าที่คุณกำลังเฝ้าดูการเปลี่ยนแปลง",
        "tooltip-pt-mycontris": "รายการหน้าที่คุณเขียน",
+       "tooltip-pt-anoncontribs": "รายการการแก้ไขจากเลขที่อยู่ไอพีนี้",
        "tooltip-pt-login": "สนับสนุนให้คุณล็อกอิน แต่ไม่บังคับ",
        "tooltip-pt-logout": "ล็อกเอาต์",
        "tooltip-pt-createaccount": "สนับสนุนให้คุณสร้างบัญชีและล็อกอิน แต่ไม่บังคับ",
        "pageinfo-category-files": "จำนวนไฟล์",
        "markaspatrolleddiff": "ทำเครื่องหมายว่าตรวจสอบแล้ว",
        "markaspatrolledtext": "ทำเครื่องหมายว่าหน้านี้ถูกตรวจสอบแล้ว",
+       "markaspatrolledtext-file": "ทำเครื่องหมายรุ่นไฟล์นี้ว่าตรวจสอบแล้ว",
        "markedaspatrolled": "ตรวจสอบแล้ว",
        "markedaspatrolledtext": "กำหนดรุ่นที่เลือกของ [[:$1]] ว่าตรวจสอบแล้ว",
        "rcpatroldisabled": "การตรวจสอบหน้าปรับปรุงล่าสุดถูกปิดใช้งาน",
        "newimages-legend": "ตัวกรอง",
        "newimages-label": "ชื่อไฟล์ (หรือส่วนหนึ่งของชื่อ):",
        "newimages-showbots": "แสดงไฟล์ที่บอตอัปโหลด",
+       "newimages-hidepatrolled": "ซ่อนการอัปโหลดที่ตรวจสอบแล้ว",
        "noimages": "ไม่มีให้ดู",
        "ilsubmit": "สืบค้น",
        "bydate": "ตามวันที่",
        "version-software-version": "รุ่น",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath เส้นทางบทความ]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath เส้นทางสคริปต์]",
-       "redirect": "การเปลี่ยนทางตามชื่อไฟล์ รหัสประจำผู้ใช้ หน้าหรือรุ่น",
+       "redirect": "การเปลี่ยนทางตามชื่อไฟล์ รหัสประจำผู้ใช้ หน้า รุ่นหรือปูม",
        "redirect-legend": "การเปลี่ยนทางไปยังไฟล์หรือหน้า",
        "redirect-summary": "หน้าพิเศษนี้เปลี่ยนทางไปยังไฟล์ (ระบุเป็นชื่อไฟล์) หน้า (ระบุเป็นรหัสรุ่นหรือรหัสหน้า) หรือหน้าผู้ใช้ (ระบุเป็นรหัสผู้ใช้ตัวเลข) การใช้งาน: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] หรือ [[{{#Special:Redirect}}/user/101]]",
        "redirect-submit": "ไป",
        "expand_templates_ok": "ตกลง",
        "expand_templates_remove_comments": "นำส่วนความเห็นออก",
        "expand_templates_preview": "ตัวอย่างผลแสดง",
-       "pagelanguage": "ตัวเลือกภาษาหน้า",
+       "expand_templates_input_missing": "คุณต้องให้ข้อความป้อนเข้าบ้าง",
+       "pagelanguage": "เปลี่ยนภาษาของหน้า",
        "pagelang-name": "หน้า",
        "pagelang-language": "ภาษา",
        "pagelang-use-default": "ใช้ภาษาโดยปริยาย",
        "pagelang-select-lang": "เลือกภาษา",
+       "pagelang-submit": "ส่ง",
        "right-pagelang": "เปลี่ยนภาษาหน้า",
        "action-pagelang": "เปลี่ยนภาษาหน้า",
        "log-name-pagelang": "ปูมการเปลี่ยนภาษา",
index 5b781b2..6732d32 100644 (file)
@@ -82,7 +82,8 @@
                        "Diyapazon",
                        "Matma Rex",
                        "HakanIST",
-                       "Imabadplayer"
+                       "Imabadplayer",
+                       "İnternion"
                ]
        },
        "tog-underline": "Bağlantıların altını çiz:",
        "may": "May",
        "jun": "Haz",
        "jul": "Tem",
-       "aug": "Ağu",
+       "aug": "Agu",
        "sep": "Eyl",
        "oct": "Eki",
        "nov": "Kas",
        "right-applychangetags": "Değişiklikleriyle beraber [[Special:Tags|etiketleri]] uygula",
        "right-changetags": "Tekil sürümler ve günlük kayıtlarına rastgele [[Special:Tags|etiket]] ekleme veya çıkarma",
        "grant-group-email": "E-posta gönder",
+       "grant-createeditmovepage": "Sayfaları oluşturma, düzenleme ve taşıma",
+       "grant-editmycssjs": "Kullanıcı CSS/JavaScript'ini düzenle",
+       "grant-editmywatchlist": "İzleme listeni düzenle",
+       "grant-editprotected": "Korumalı sayfaları Düzenle",
+       "grant-patrol": "Sayfadaki değişiklikleri incele",
+       "grant-uploadfile": "Dosya yükle",
        "grant-basic": "Basit haklar",
+       "grant-viewdeleted": "Silinen dosya ve sayfaları görüntüle",
+       "grant-viewmywatchlist": "İzleme listeni gör",
        "newuserlogpage": "Yeni kullanıcı kayıtları",
        "newuserlogpagetext": "En son kaydolan kullanıcı kayıtları.",
        "rightslog": "Kullanıcı hakları kayıtları",
        "uploaded-script-svg": "Yüklenen SVG dosyasında komutlanabilir (scriptable) öğe bulundu: \"$1\"",
        "uploaded-hostile-svg": "Yüklenen SVG dosyasının \"style\" öğesinde güvensiz CSS bulundu.",
        "uploaded-event-handler-on-svg": "SVG dosyalarında event-handler özniteliğini <code>$1=\"$2\"</code> şeklinde ayarlanmasına izin verilmiyor.",
-       "uploaded-href-attribute-svg": "SVG dosyalarında yerel olmayan (örn. http://, javascript:, vb.) hedefleri olan <code>&lt;$1 $2=\"$3\"&gt;</code> href özniteliklerine izin verilmez.",
        "uploaded-href-unsafe-target-svg": "Yüklenen SVG dosyasında <code>&lt;$1 $2=\"$3\"&gt;</code> güvensiz hedefine href bulundu.",
        "uploaded-animate-svg": "\"animate\" etiketi bulundu, href'i değiştiriyor olabilir. Yüklenen SVG dosyasındaki \"from\" özniteliği kullanılıyor  <code>&lt;$1 $2=\"$3\"&gt;</code>",
        "uploadscriptednamespace": "Bu SVG dosyası geçersiz \"$1\" alan adını içermektedir.",
        "upload-too-many-redirects": "URL çok fazla yönlendirme içeriyor",
        "upload-http-error": "Bir HTTP hatası oluştu: $1",
        "upload-copy-upload-invalid-domain": "Kopya yüklemeler bu etki alanında mevcut değil.",
+       "upload-dialog-title": "Dosya Yükle",
        "upload-dialog-button-cancel": "İptal",
+       "upload-dialog-button-done": "Yapıldı",
        "upload-dialog-button-save": "Kaydet",
        "upload-dialog-button-upload": "Yükle",
        "upload-form-label-select-file": "Dosya seç",
        "mostrevisions": "En çok değişikliğe uğramış sayfalar",
        "prefixindex": "Önek ile tüm sayfalar",
        "prefixindex-namespace": "Önek ile tüm sayfalar ($1 ad alanında)",
+       "prefixindex-submit": "Göster",
        "prefixindex-strip": "Listede öneki kırp",
        "shortpages": "Kısa sayfalar",
        "longpages": "Uzun sayfalar",
        "usereditcount": "$1 {{PLURAL:$1|değişiklik|değişiklik}}",
        "usercreated": "$1 tarihinde $2'de {{GENDER:$3|oluşturuldu}}.",
        "newpages": "Yeni sayfalar",
+       "newpages-submit": "Göster",
        "newpages-username": "Kullanıcı adı:",
        "ancientpages": "En son değişiklik tarihi en eski olan maddeler",
        "move": "Taşı",
        "querypage-disabled": "Bu özel sayfa, performansa dayalı nedenlerle devre dışı bırakılır.",
        "apihelp": "API yardımı",
        "apihelp-no-such-module": "\"$1\" modülü bulunamadı.",
+       "apisandbox-unfullscreen": "Sayfayı göster",
+       "apisandbox-submit": "İstek yap",
+       "apisandbox-reset": "Temizle",
+       "apisandbox-retry": "Tekrar dene",
+       "apisandbox-examples": "Örnekler",
+       "apisandbox-results": "Sonuç",
+       "apisandbox-request-url-label": "İstek URL:",
+       "apisandbox-request-time": "İstek zamanı: $1",
        "booksources": "Kaynak kitaplar",
        "booksources-search-legend": "Kitap kaynaklarını ara",
        "booksources-isbn": "ISBN:",
        "log-title-wildcard": "Bu metinle başlayan başlıklar ara",
        "showhideselectedlogentries": "Seçili günlük girdilerinin görünürlüğünü değiştir",
        "log-edit-tags": "Seçili kayıtların etiketlerini düzenle",
+       "checkbox-all": "Tüm",
+       "checkbox-none": "Hiçbiri",
        "allpages": "Tüm sayfalar",
        "nextpage": "Sonraki sayfa ($1)",
        "prevpage": "Önceki sayfa ($1)",
        "listgrouprights-namespaceprotection-header": "Ad kısıtlamaları",
        "listgrouprights-namespaceprotection-namespace": "Ad alanı",
        "listgrouprights-namespaceprotection-restrictedto": "Kullanıcının değişiklik yapmasına izin veren hak(lar)",
+       "listgrants-rights": "Haklar",
        "trackingcategories": "Eşleşen kategoriler",
        "trackingcategories-summary": "Bu sayfa MediaWiki yazılımı tarafından otomatik olarak doldurulan takip kategorilerini listelemektedir. {{ns:8}} ad alanındaki ilgili sistem mesajları değiştirilerek isimleri düzenlenebilir.",
        "trackingcategories-msg": "İzleme kategorisi",
        "delete-confirm": "\"$1\" sil",
        "delete-legend": "sil",
        "historywarning": "<strong>Uyarı:</strong> Silmek üzere olduğunuz sayfanın yaklaşık olarak $1 sürüme sahip bir geçmişi var:",
+       "historyaction-submit": "Göster",
        "confirmdeletetext": "Bu sayfayı veya dosyayı tüm geçmişi ile birlikte veritabanından kalıcı olarak silmek üzeresiniz.\nBu işlemden kaynaklı doğabilecek sonuçların farkında iseniz ve işlemin [[{{MediaWiki:Policy-url}}|Silme kurallarına]] uygun olduğuna eminseniz, işlemi onaylayın.",
        "actioncomplete": "İşlem tamamlandı",
        "actionfailed": "İşlem başarısız oldu",
index 841dc31..9cb4c89 100644 (file)
        "retypenew": "Яңа серсүзне кабатлагыз:",
        "resetpass_submit": "Серсүз куеп керү",
        "changepassword-success": "Серсүзегез уңышлы үзгәртелде!",
+       "botpasswords": "Ботларның серсүзләре",
        "botpasswords-label-appid": "Бот исеме:",
        "botpasswords-label-create": "Төзү",
        "botpasswords-label-update": "Яңарту",
        "resettokens": "Токеннарны ташлау",
        "resettokens-tokens": "Токеннар:",
        "resettokens-token-label": "$1 (агымдагы мәгънә: $2)",
+       "resettokens-done": "Токеннар ташланды.",
+       "resettokens-resetbutton": "Сайланган токеннарны ташлау",
        "bold_sample": "Калын язылыш",
        "bold_tip": "Калын язылыш",
        "italic_sample": "Курсив язылыш",
        "diff-multi-manyusers": "($2 күбрәк {{PLURAL:$2|кулланучының|кулланучының}} {{PLURAL:$1|Бер арадаш юрамасы|$1 арадаш юрамасы}} күрсәтелмәгән)",
        "searchresults": "Эзләү нәтиҗәләре",
        "searchresults-title": "«$1» өчен эзләү нәтиҗәләре",
+       "titlematches": "Бит исемнәрендә тиңдәшлек",
+       "textmatches": "Бит эчтәлегендә тиңдәшлек",
        "notextmatches": "Тиңдәш текстлы битләр юк",
        "prevn": "алдагы {{PLURAL:$1|$1}}",
        "nextn": "чираттагы {{PLURAL:$1|$1}}",
        "right-reupload": "Булган файллар өстеннән язарга",
        "right-writeapi": "Язма өчен API куллану",
        "right-delete": "битләрне бетерү",
+       "right-browsearchive": "Бетерелгән битләрне эзләү",
+       "right-undelete": "Битләрне торгызу",
        "right-editinterface": "Кулланучы интерфейсын үзгәртү",
        "grant-group-email": "Хатлар җибәрү",
        "grant-uploadfile": "Яңа файллар йөкләү",
        "rcshowhidemine": "минем үзгәртүләремне $1",
        "rcshowhidemine-show": "Күрсәтү",
        "rcshowhidemine-hide": "Яшер",
+       "rcshowhidecategorization": "битләрне төркемләүне $1",
        "rcshowhidecategorization-show": "Күрсәт",
        "rcshowhidecategorization-hide": "Яшер",
        "rclinks": "Соңгы $2 көн эчендә ясалган $1 үзгәртүне күрсәт<br />$3",
        "imagelinks": "Файлны куллану",
        "linkstoimage": "{{PLURAL:$1|Киләсе $1 бит|Киләсе $1 битләр|}} әлеге файлга сылтама ясый:",
        "nolinkstoimage": "Бу файлга сылтаган битләр юк.",
+       "linkstoimage-redirect": "$1 (файл юнәлтүе) $2",
        "duplicatesoffile": "{{PLURAL:$1|Әлеге $1 файл }} астагы файлның күчерелмәсе булып тора ([[Special:FileDuplicateSearch/$2|тулырак]]):",
        "sharedupload": "Бу файл $1 проектыннан һәм башка проектларда кулланырга мөмкин",
        "sharedupload-desc-here": "Бу файл $1 проектыннан һәм башка проектларда кулланырга мөмкин. \nФайл турында [$2 тулырак мәгълүмат] түбәндәрәк күрсәтелгән.",
        "filedelete-comment": "Сәбәп:",
        "filedelete-submit": "Бетерү",
        "filedelete-nofile": "<strong>$1</strong> файлы юк.",
+       "filedelete-otherreason": "Башка сәбәп:",
        "filedelete-reason-otherlist": "Башка сәбәп",
+       "filedelete-reason-dropdown": "*Киң таралган бетерү сәбәпләре \n** авторлык хокукларны бозу\n** кабатланган файл",
+       "filedelete-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
        "mimesearch": "MIME эзләү",
        "mimetype": "MIME-тип:",
        "download": "йөкләү",
        "statistics-users": "Теркәлгән [[Special:ListUsers|кулланучылар]]",
        "statistics-users-active": "Актив кулланучылар",
        "statistics-users-active-desc": "{{PLURAL:$1|$1 көн }} өчендә нинди дә булса үзгәртүләр керткән кулланучылар",
+       "pageswithprop": "Үзенчәлекләре кабаттан билгеләнгән битләр",
+       "pageswithprop-legend": "Үзенчәлекләре кабаттан билгеләнгән битләр",
+       "pageswithprop-text": "Монда кайбер үзенчәлекләре кулдан яңартылган битләр күрсәтелгән.",
        "pageswithprop-prop": "Үзенчәлекнең атамасы:",
        "pageswithprop-submit": "Табу",
        "doubleredirects": "Икеләтә юнәлтүләр",
+       "double-redirect-fixer": "Юнәлтүләрне төзәтүче",
        "brokenredirects": "Бәйләнешсез юнәлтүләр",
        "brokenredirectstext": "Бу юнәлтүләр булмаган битләргә сылтыйлар:",
        "brokenredirects-edit": "үзгәртү",
        "longpages": "Озын битләр",
        "deadendpages": "Тупик битләре",
        "protectedpages": "Якланган битләр",
+       "protectedpages-timestamp": "Дата/вакыт",
        "protectedpages-page": "Бит",
        "protectedpages-expiry": "Тәмамлана",
        "protectedpages-performer": "Кулланучыны яклау",
        "protectedpages-unknown-timestamp": "Билгесез",
        "protectedpages-unknown-performer": "Билгесез кулланучы",
        "protectedtitles": "Тыелган исемнәр",
+       "protectedtitles-submit": "Башлыкларны күрсәтү",
        "listusers": "Кулланучылар исемлеге",
        "usercreated": "$3 $1 көнне $2 вакытта {{GENDER:$3|теркәлде}}",
        "newpages": "Яңа битләр",
        "ancientpages": "Иң иске битләр",
        "move": "Күчерү",
        "movethispage": "Бу битне күчерү",
+       "notargettitle": "Максатсыз",
        "nopagetitle": "Мондый бит юк",
        "nopagetext": "Күрсәтелгән бит юк.",
        "pager-newer-n": "{{PLURAL:$1|$1 яңарак}}",
        "pager-older-n": "$1 {{PLURAL:$1|искерәк}}",
        "suppress": "Яшерү",
+       "apihelp": "API ярдәм",
+       "apihelp-no-such-module": "«$1» модуле табылмады.",
        "booksources": "Китап чыганаклары",
        "booksources-search-legend": "Китап чыганакларыны эзләү",
        "booksources-search": "Эзләү",
        "allinnamespace": "«$1» исемнәр мәйданындагы барлык битләр",
        "allpagessubmit": "Башкару",
        "allpagesprefix": "Алкушымчалы битләрне күрсәтү:",
+       "allpages-bad-ns": "{{SITENAME}} проектында «$1» исемнәр мәйданы юк.",
        "allpages-hide-redirects": "Юнәлтүләрне яшер",
+       "cachedspecial-refresh-now": "Соңгы юраманы карау.",
        "categories": "Төркемнәр",
        "categories-submit": "Күрсәт",
        "categoriespagetext": "{{PLURAL:$1|1=Әлеге төркем үз өченә|Әлеге төркемнәр  үз өченә}}   битләрне һәм медиа-файлларны ала.\nАста [[Special:UnusedCategories|кулланылмаган төркемнәр]] кәрсәтелгән.\nШулай ук  [[Special:WantedCategories|кирәкле төркемнәр исемлегендә]] карагыз.",
        "special-categories-sort-count": "исәп буенча тәртипләү",
        "special-categories-sort-abc": "әлифба буенча тәртипләү",
+       "deletedcontributions": "Кулланучының бетерелгән кертеме",
+       "deletedcontributions-title": "Бетерелгән кертем",
        "sp-deletedcontributions-contribs": "кертем",
        "linksearch": "Тышкы сылтамаларны эзләү",
        "linksearch-pat": "Эзләү өчен үрнәк:",
        "wlshowhideanons": "аноним кулланучыларныкын",
        "wlshowhidepatr": "тикшерелгән үзгәртүләр",
        "wlshowhidemine": "үзгәртүләрем",
+       "wlshowhidecategorization": "битләрне төркемләүне",
        "watchlist-options": "Күзәтү исемлеге көйләүләре",
        "watching": "Күзәтү исемлегемә өстәүе…",
        "unwatching": "Күзәтү исемлегемнән чыгаруы…",
        "movedarticleprotection": "яклау көйләнмәләрен «[[$2]]» битеннән «[[$1]]» битенә күчерде",
        "protect-title": "«$1» өчен яклау дәрәҗәсен билгеләү",
        "prot_1movedto2": "«[[$1]]» бите «[[$2]]» битенә күчерелде",
+       "protect-norestrictiontypes-title": "Сакланмаган бит",
        "protect-legend": "Битне яклау турында раслагыз",
        "protectcomment": "Сәбәп:",
        "protectexpiry": "Бетә:",
        "protect-level-autoconfirmed": "Автоматик рәвештә расланган кулланучыларга гына рөхсәт ителә",
        "protect-level-sysop": "Идарәчеләргә генә рөхсәт ителә",
        "protect-summary-cascade": "каскадлы",
-       "protect-expiring": "$1 үтә (UTC)",
+       "protect-expiring": "$1 тәмамлана (UTC)",
+       "protect-expiring-local": "$1 тәмамлана",
        "protect-expiry-indefinite": "Вакыт чикләнмәгән",
        "protect-cascade": "Бу биткә кергән битләрне яклау (каскадлы яклау)",
        "protect-cantedit": "Сез бу битнең яклау дәрәҗәсене үзгәрә алмыйсыз, чөнки сездә аны үзгәртергә рөхсәтегез юк.",
        "protect-othertime": "Башка вакыт:",
        "protect-othertime-op": "башка вакыт",
+       "protect-existing-expiry": "Хәзерге тәмамлану вакыты: $2 $3",
+       "protect-existing-expiry-infinity": "Хәзерге тәмамлану вакыты: чикләнмәгән",
+       "protect-otherreason": "Башка/өстәмә сәбәп:",
        "protect-otherreason-op": "Башка сәбәп",
        "protect-dropdown": "* Гади яклау сәбәпләре\n** вандаллык\n** зур спам\n** кирәксез үзгәртүләр саны\n** популяр бит",
        "protect-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
        "blocklist-reason": "Сәбәп",
        "ipblocklist-submit": "Эзләү",
        "ipblocklist-localblock": "Локаль тыюлык",
+       "ipblocklist-otherblocks": "Башка {{PLURAL:$1|1=тыю|тыюлар}}",
        "infiniteblock": "билгеле бер вакытсыз",
        "expiringblock": "$1 $2 тәмамлана",
        "anononlyblock": "анонимнар гына",
        "block-log-flags-nocreate": "яңа хисап язмасы теркәү тыелган",
        "block-log-flags-noemail": "хат җибәрү тыелган",
        "block-log-flags-hiddenname": "кулланучының исеме яшерелгән",
+       "ipb-otherblocks-header": "Башка {{PLURAL:$1|1=тыю|тыюлар}}",
        "proxyblocker": "Прокси тыю",
        "sorbsreason": "Сезнең IP адресыгыз DNSBLда ачык прокси дип санала.",
+       "lockdb": "Мәгълүматлар базасын чикләү",
+       "unlockdb": "Мәгълүматлар базасына язу мөмкинлеген кайтару",
+       "lockbtn": "Мәгълүматлар базасын чикләү",
        "unlockbtn": "Мәгълүматлар базасына язу мөмкинлеген кайтару",
+       "locknoconfirm": "Сез раслау юлында билге куймагансыз.",
        "move-page": "$1 — исемен алмаштыру",
        "move-page-legend": "Битне күчерү",
        "movepagetext": "Астагы форманы куллану битнең исемен алыштырып, аның барлык тарихын яңа исемле биткә күчерер.\nИске исемле бит яңа исемле биткә юнәлтү булып калыр.\nСез иске исемгә юнәлтүләрне автоматик рәвештә яңа исемгә күчерә аласыз.\nӘгәр моны эшләмәсәгез, [[Special:DoubleRedirects|икеле]] һәм [[Special:BrokenRedirects|өзелгән юнәлтүләрне]] тикшерегез.\nСез барлык сылтамаларның кирәкле җиргә сылтавына җаваплы.\n\nКүздә тотыгыз: әгәр яңа исем урынында бит булса инде, һәм ул буш яки юнәлтү түгел исә, бит <strong>күчерелмәячәк</strong>.\nБу шуны аңлата: сез ялгышып күчерсәгез, битне кайтара аласыз, әмма инде булган битне бетерә алмыйсыз.\n\n<strong>Искәрмә:</strong>\nПопуляр битләрне күчерү зур һәм көтелмәгән нәтиҗәләргә китерә ала.\nДәвам иткәнче, барлык нәтиҗәләрне аңлавыгызны тагын бер кат уйлагыз.",
        "movelogpage": "Күчерү көндәлеге",
        "movereason": "Сәбәп:",
        "revertmove": "кире кайту",
+       "delete_and_move_confirm": "Әйе, битне бетерү",
        "delete_and_move_reason": "Күчерүне мөмкин итәр өчен бетерелде «[[$1]]»",
        "move-leave-redirect": "Юнәлтү калдырылсын",
        "export": "Битләрне чыгаруы",
        "allmessages-filter-modified": "Үзгәртелгән",
        "allmessages-language": "Тел:",
        "allmessages-filter-submit": "Күчү",
+       "allmessages-filter-translate": "Тәрҗемә итү",
        "thumbnail-more": "Зурайту",
        "filemissing": "Файл табылмады",
        "thumbnail_error": "Кечкенә сүрәт төзүе хатасы: $1",
        "import": "Битләр кертү",
        "importinterwiki": "Башка викидан кертү",
        "import-interwiki-text": "Викины һәм кертелүче битнең исемен языгыз.\nҮзгәртүләр вакыты һәм аның авторлары сакланачак.\nБөтен викиара күчерүләр [[Special:Log/import|махсус журналда]] сакланачак.",
+       "import-interwiki-sourcewiki": "Чыганак вики:",
+       "import-interwiki-sourcepage": "Чыганак бит:",
        "import-interwiki-history": "Бу битнең барлык үзгәртү тарихын күчермәләү",
        "import-interwiki-templates": "Барлык үрнәкләрне кертү",
        "import-interwiki-submit": "Импортлау",
        "import-revision-count": "$1 {{PLURAL:$1|юрама}}",
        "importnopages": "Импортлау өчен битләр юк.",
        "importlogpage": "Кертү көндәлеге",
+       "javascripttest": "JavaScript тикшерү",
+       "javascripttest-pagetext-noframework": "Әлеге бит JavaScript тестларын ачу өчен ясалган.",
        "tooltip-pt-userpage": "{{GENDER:|Кулланучы}} битегез",
        "tooltip-pt-mytalk": "Бәхәс {{GENDER:|битегез}}",
        "tooltip-pt-preferences": "{{GENDER:|Көйләнмәләрегез}}",
        "anonymous": "{{grammar:genitive|{{SITENAME}}}} {{PLURAL:$1|1=Аноним кулланучысы|Аноним кулланучылары}}",
        "siteuser": "{{SITENAME}} кулланучысы $1",
        "othercontribs": "Төзүдә катнаштылар: $1.",
+       "others": "башкалар",
        "siteusers": "{{{{SITENAME}}}} {{PLURAL:$2|1=кулланучы|кулланучылары}} $1",
        "creditspage": "Рәхмәтләр",
        "spamprotectiontitle": "Спам фильтры",
        "simpleantispam-label": "Анти-спам тикшерә.\nМоны <strong>ТУТЫРМАГЫЗ!</strong>",
+       "pageinfo-header-basic": "Төп мәгълүмат",
+       "pageinfo-header-edits": "Үзгәртүләр тарихы",
+       "pageinfo-header-restrictions": "Битне яклау",
+       "pageinfo-header-properties": "Битнең үзенчәлекләре",
+       "pageinfo-display-title": "Күренмә башлык",
+       "pageinfo-default-sort": "Гадәти сайлау ачкычы",
+       "pageinfo-length": "Бит озынлыгы (байтларда)",
+       "pageinfo-article-id": "Бит идентификаторы",
+       "pageinfo-language": "Битнең теле",
+       "pageinfo-robot-index": "Рөхсәт",
+       "pageinfo-robot-noindex": "Рөхсәтсез",
+       "pageinfo-firstuser": "Битне төзүче",
+       "pageinfo-firsttime": "Битне төзү датасы",
+       "pageinfo-lastuser": "Соңгы мөхәррирләүче",
+       "pageinfo-lasttime": "Соңгы үзгәртү датасы",
+       "pageinfo-edits": "Гомуми төзәтүләр саны",
+       "pageinfo-authors": "Гомуми авторлар саны",
        "pageinfo-toolboxlink": "Бит турында мәгълүмат",
+       "pageinfo-redirectsto-info": "мәгълүмат",
+       "pageinfo-contentpage-yes": "Әйе",
+       "pageinfo-protect-cascading-yes": "Әйе",
        "markaspatrolledtext": "Бу мәкаләне тикшерелгән дип тамгалау",
        "markedaspatrolled": "Тикшерелгән дип тамгаланды",
        "markedaspatrolledtext": "Сайланган [[:$1]] мәкаләсенең әлеге юрамасы тикшерелгән дип тамгаланды.",
        "show-big-image-preview": "Алдан карауның зурлыгы: $1.",
        "show-big-image-other": "{{PLURAL:$2|1=Башка зурлык|Башка зурлыклар}}: $1.",
        "show-big-image-size": "$1 × $2 пиксель",
+       "file-info-gif-looped": "әйләнешле",
+       "file-info-gif-frames": "$1 {{PLURAL:$1|фрейм}}",
+       "file-info-png-looped": "әйләнешле",
        "newimages": "Яңа сүрәтләр җыелмасы",
        "newimages-legend": "Фильтр",
        "ilsubmit": "Эзләү",
+       "bydate": "дата буенча",
+       "seconds": "{{PLURAL:$1|$1 секунд}}",
+       "minutes": "{{PLURAL:$1|$1 минут}}",
        "hours": "{{PLURAL:$1|$1 cәгать}}",
        "days": "{{PLURAL:$1|$1 көн}}",
+       "weeks": "{{PLURAL:$1|$1 атна}}",
+       "months": "{{PLURAL:$1|$1 ай}}",
+       "years": "{{PLURAL:$1|$1 ел}}",
        "ago": "$1 элек",
+       "just-now": "яңа гына",
        "hours-ago": "$1 cәгать элек",
        "minutes-ago": "$1 минут элек",
+       "seconds-ago": "$1 {{PLURAL:$1|секунд}} элек",
+       "monday-at": "дүшәмбе $1",
+       "tuesday-at": "сишәмбе $1",
+       "wednesday-at": "чәршәмбе $1",
+       "thursday-at": "пәнҗешәмбе $1",
+       "friday-at": "җомга $1",
+       "saturday-at": "шимбә $1",
+       "sunday-at": "якшәмбе $1",
+       "yesterday-at": "Кичә $1",
        "bad_image_list": "Киләчәк рәвеш кирәк:\n\nИсемлек кисәкләре генә (* символыннан башланучы юллар) саналырлар.\nЮлның беренче сылтамасы куйма өчен тыелган рәсемгә сылтама булырга тиеш.\nШул ук юлның киләчәк сылтамалары чыгармалар, рәсемгә тыелмаган битләре, саналырлар.",
        "metadata": "Мета мәгълүматлар",
        "metadata-help": "Бу файлда гадәттә санлы камера яки сканер тарафыннан өстәлгән мәгълүмат бар. Әгәр бу файл төзү вакытыннан соң үзгәртелгән булса, аның кайбер параметрлары дөрес булмаска мөмкин.",
        "metadata-fields": "Бу исемлеккә кергән метабирелмәләр кырлары рәсем битендә күрсәтелер, калганнары исә килешү буенча яшерелер.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Киңлек",
        "exif-imagelength": "Биеклек",
+       "exif-bitspersample": "Төс тирәнлеге",
+       "exif-compression": "Кысу ысулы",
+       "exif-photometricinterpretation": "Төс моделе",
        "exif-orientation": "Кадр куелышы",
+       "exif-samplesperpixel": "Төс өлешләре саны",
        "exif-xresolution": "Горизонталь зурлык",
        "exif-yresolution": "Вертикаль зурлык",
        "exif-datetime": "Файл үзгәртүләр датасы һәм вакыты",
        "exif-model": "Камераның төре",
        "exif-software": "Программалы тәэмин ителеш",
        "exif-artist": "Автор",
-       "exif-copyright": "Автор хокуклары хуҗасы",
+       "exif-copyright": "Автор хокуклары иясе",
        "exif-exifversion": "Exif юрамасы",
        "exif-flashpixversion": "FlashPix юрамасын тәэмин итү",
        "exif-colorspace": "Төсләр тирәлеге",
        "exif-gpsspeedref": "Тизлекне исәпләү берәмлеге",
        "exif-gpsspeed": "Хәрәкәт тизлеге",
        "exif-gpsdatestamp": "Дата",
+       "exif-keywords": "Иң мөһиме",
+       "exif-source": "Чыганак",
+       "exif-writer": "Язучы",
+       "exif-languagecode": "Тел",
+       "exif-iimversion": "IIM юрамасы",
+       "exif-iimcategory": "Төркем",
+       "exif-identifier": "Идентификатор",
+       "exif-label": "Билгеләү",
+       "exif-copyrighted": "Автор хокуклары халәте:",
+       "exif-copyrightowner": "Автор хокуклары иясе",
+       "exif-usageterms": "Куллану шартлары",
        "exif-orientation-1": "Нормаль",
        "exif-orientation-3": "180° ка борылган",
        "exif-meteringmode-0": "Билгесез",
        "duration-days": "$1 {{PLURAL:$1|көн}}",
        "expandtemplates": "Үрнәкләрне ачу",
        "expand_templates_ok": "OK",
+       "mediastatistics": "Медиа хисабы",
        "special-characters-group-latin": "Латин",
        "special-characters-group-latinextended": "Латин (киңәйтелгән)",
        "special-characters-group-ipa": "ХФӘ (IPA)",
index 57ac62a..cf5e812 100644 (file)
@@ -9,7 +9,8 @@
                        "friends at tyvawiki.org",
                        "לערי ריינהארט",
                        "아라",
-                       "Монгуш Салим"
+                       "Монгуш Салим",
+                       "Көпек"
                ]
        },
        "tog-underline": "Холбааны шыяры:",
        "oct": "октябрь",
        "nov": "ноябрь",
        "dec": "декабрь",
-       "pagecategories": "{{PLURAL:$1|Ð\9aаÑ\82егоÑ\80иÑ\8f\9aаÑ\82егоÑ\80иÑ\8fлар}}",
-       "category_header": "«$1» ÐºÐ°Ñ\82егоÑ\80иÑ\8fның арыннары",
+       "pagecategories": "{{PLURAL:$1|Ð\90ңгÑ\8bлал|Ð\90ңгÑ\8bлалдар}}",
+       "category_header": "«$1» Ð°Ò£Ð³Ñ\8bлалдың арыннары",
        "subcategories": "Адаккы бөлүктер",
        "category-media-header": "«$1» деп бөлүкте файлдар",
        "category-empty": "''Амгы бо бөлүкте медиа база арыннар чок.''",
-       "hidden-categories": "{{PLURAL:$1|1=Ð\9aөзүлбеÑ\81 ÐºÐ°Ñ\82егоÑ\80иÑ\8f\9aөзүлбеÑ\81 ÐºÐ°Ñ\82егоÑ\80иÑ\8fлар}}",
+       "hidden-categories": "{{PLURAL:$1|1=Ð\9aөзүлбеÑ\81 Ð°Ò£Ð³Ñ\8bлал|Ð\9aөзүлбеÑ\81 Ð°Ò£Ð³Ñ\8bлалдар}}",
        "hidden-category-category": "Чажыт бөлүктер",
-       "category-subcat-count": "{{PLURAL:$2|1=Ð\91о ÐºÐ°Ñ\82егоÑ\80иÑ\8f Ñ\87үгле Ð´Ð°Ñ\80аазÑ\8bнда Ð¸Ñ\88Ñ\82ики ÐºÐ°Ñ\82егоÑ\80иÑ\8fлÑ\8bг.|Ð\91о ÐºÐ°Ñ\82егоÑ\80иÑ\8fда Ð±Ð°Ñ\80-ла $2 Ð¸Ñ\88Ñ\82ики ÐºÐ°Ñ\82егоÑ\80иÑ\8fлаÑ\80нÑ\8bÒ£ $1 Ð´ÐµÐ¿ Ð¸Ñ\88Ñ\82ики ÐºÐ°Ñ\82егоÑ\80иÑ\8fзы көстүп турар.}}",
-       "category-subcat-count-limited": "Ð\91о Ð°Ò£Ð³Ñ\8bлал {{PLURAL:$1|1=биÑ\80|$1}} Ð°Ò£Ð³Ñ\8bламнÑ\8bг.",
-       "category-article-count": "{{PLURAL:$2|1=Ð\91о ÐºÐ°Ñ\82егоÑ\80иÑ\8fда Ñ\87үгле Ñ\87аңгÑ\8bÑ\81 Ð°Ñ\80Ñ\8bн Ð±Ð°Ñ\80.|Ук ÐºÐ°Ñ\82егоÑ\80иÑ\8fда бар $2 арыннарының аразындан}} |{{PLURAL:$1 арынны көргүскен| $1 арыннарны көргүскен.}}",
-       "category-file-count": "{{PLURAL:$2|1=Ð\91о ÐºÐ°Ñ\82егоÑ\80иÑ\8f Ñ\87үгле Ñ\87аңгÑ\8bÑ\81 Ñ\84айлдÑ\8bг.|Ð\91о ÐºÐ°Ñ\82егоÑ\80иÑ\8fнÑ\8bÒ£ Ñ\88Ñ\83пÑ\82Ñ\83 $2 Ñ\84айлÑ\8bнÑ\8bÒ£ $1 файлын көргүскен.}}",
+       "category-subcat-count": "{{PLURAL:$2|1=Ук Ð°Ò£Ð³Ñ\8bлал Ñ\87үгле Ð´Ð°Ñ\80аазÑ\8bнда Ð¸Ñ\88Ñ\82ики Ð°Ò£Ð³Ñ\8bлалдÑ\8bг.|Ук Ð°Ò£Ð³Ñ\8bлалда Ð±Ð°Ñ\80-ла $2 Ð¸Ñ\88Ñ\82ики Ð°Ò£Ð³Ñ\8bлалдаÑ\80нÑ\8bÒ£ $1 Ð¸Ñ\88Ñ\82ики Ð°Ò£Ð³Ñ\8bлалы көстүп турар.}}",
+       "category-subcat-count-limited": "Ук Ð°Ò£Ð³Ñ\8bлалда {{PLURAL:$1|1=биÑ\80|$1}} Ð¸Ñ\88Ñ\82ики Ð°Ò£Ð³Ñ\8bлал Ð±Ð°Ñ\80.",
+       "category-article-count": "{{PLURAL:$2|1=Ук Ð°Ò£Ð³Ñ\8bлалда Ñ\87үгле Ñ\87аңгÑ\8bÑ\81 Ð°Ñ\80Ñ\8bн Ð±Ð°Ñ\80.|Ук Ð°Ò£Ð³Ñ\8bлалда бар $2 арыннарының аразындан}} |{{PLURAL:$1 арынны көргүскен| $1 арыннарны көргүскен.}}",
+       "category-file-count": "{{PLURAL:$2|1=Ук Ð°Ò£Ð³Ñ\8bлал Ñ\87үгле Ñ\87аңгÑ\8bÑ\81 Ñ\84айлдÑ\8bг.|Ук Ð°Ò£Ð³Ñ\8bлалдÑ\8bÒ£ Ñ\88Ñ\83пÑ\82Ñ\83 $2 Ñ\84айлдаÑ\80Ñ\8bнÑ\8bÒ£ Ð°Ñ\80азÑ\8bндан $1 файлын көргүскен.}}",
        "listingcontinuesabbrev": "(уланчы)",
        "noindex-category": "Индекстелбес арынар",
        "broken-file-category": "Ажылдавайн турар файл-шөлүлгелиг арыннар",
        "mainpage": "Кол арын",
        "mainpage-description": "Кол арын",
        "policy-url": "Project:Чурум",
-       "portal": "Ниитилелдиң порталы",
-       "portal-url": "Project:Ниитилелдиң порталы",
-       "privacy": "Ð\91үзүÑ\80ел Ð´Ñ\83гÑ\83Ñ\80жÑ\83лгазÑ\8b",
+       "portal": "Ниитилел хаалгазы",
+       "portal-url": "Project:Ниитилел хаалгазы",
+       "privacy": "Ð\90кÑ\82Ñ\8bг Ð´Ñ\83Ñ\80жÑ\83лга",
        "privacypage": "Project:Бүзүрел дугуржулгазы",
        "badaccess": "Алдаг:Эргеңер чок.",
        "versionrequired": "МедиаВикиниң $1 үндүреризи херек",
        "nstab-mediawiki": "Чагаа",
        "nstab-template": "Майык",
        "nstab-help": "Дуза",
-       "nstab-category": "Ð\9aаÑ\82егоÑ\80иÑ\8f",
+       "nstab-category": "Ð\90ңгÑ\8bлал",
        "mainpage-nstab": "Кол арын",
        "nosuchaction": "Ындыг кылыг чок",
        "nosuchspecialpage": "Ындыг тускай арын чок",
        "templatesused": "Бо арында ажыглап турар{{PLURAL:$1|1=майык|майыктар}}:",
        "template-protected": "(камгалаан)",
        "template-semiprotected": "(чартык-чамдыызы камгалалдыг)",
-       "hiddencategories": "Бо арын{{PLURAL:$1|$1 көзүлбес категорияга|$1 көзүлбес категорияларга|1=бир көзүлбес категорияга}} хамааржыр:",
+       "hiddencategories": "Бо арын {{PLURAL:$1|$1 көзүлбес аңгылалга|$1 көзүлбес аңгылалдарга|1=чаңгыс көзүлбес аңгылалга}} хамааржыр:",
        "permissionserrorstext-withaction": "{{PLURAL:$1|1=дараазында чылдагаан-биле|дараазында чылдагааннар-биле}} $2-ни ажыглаар эрге силерде чок:",
        "recreate-moveddeleted-warn": "'''Кичээңейлиг. Ооң мурнунда казыттынган арынны катап тургузар деп тур Силер.'''\n\nОл арынны катап тургузары шынап-ла чугула бе, боданыңар.\nБо адаанда ол арынның казыышкыннар болгаш өскээр адалгалар журналдарын көргүскен.",
-       "moveddeleted-notice": "Ð\91о Ð°Ñ\80Ñ\8bн Ð°Ð¿ ÐºÐ°Ð°Ð²Ñ\8bÑ\82кан.\nÐ\90даанда Ð°Ð¿ ÐºÐ°Ð°Ð²Ñ\8bÑ\82кан Ð±Ð¸Ð»Ðµ өскээр адаан бижиктер шынзылгазын көргүскен.",
+       "moveddeleted-notice": "Ук Ð°Ñ\80Ñ\8bн ÐºÐ°Ð·Ñ\8bÑ\82Ñ\8bнган.\nÐ\90даанда ÐºÐ°Ð·Ñ\8bлда Ð±Ð¾Ð»Ð³Ð°Ñ\88 өскээр адаан бижиктер шынзылгазын көргүскен.",
        "post-expand-template-inclusion-warning": "Сагындырыг: Кошкан майыктарның ниити хемчээли дендии улуг.\nЧамдык майыктар коштунмаан боор.",
        "post-expand-template-inclusion-category": "Кожар майыктарга чөшпээрээн хемчээлин ашкан арыннар",
        "post-expand-template-argument-warning": "'''Кичээнгейлиг:''' бо арында тоң дора дээрге (по крайней мере) чаңгыс майыктыг, а ооң аргументизи эмин эрттир улуг калбаяр хемчээлдиг.\nЫндыг чергелиг аргументилерни эрттирип каан.",
        "filehist-filesize": "Файл хемчээли",
        "filehist-comment": "Тайылбыр",
        "imagelinks": "Файлдың ажыглаашкыны",
-       "linkstoimage": "Дараазында {{PLURAL:$1|1=арын|$1 арыннарның шөлүлгези файл}}:",
+       "linkstoimage": "Дараазында {{PLURAL:$1|1=арын|$1 ажыг арын ук файлче айтып турар}}:",
        "nolinkstoimage": "Бердинген файлче шөлүп турар арыннар чок.",
        "sharedupload-desc-here": "Моон $1 алган файл өске төлевилелдерге база ажыглаттынып болур.\nОоң [$2 тайылбыр арнындан] медээни адаанда киирген.",
        "upload-disallowed-here": "Бо файлды эде бижидип шыдавас силер.",
        "movelogpage": "Шимчээринге журнал",
        "movereason": "Чылдагаан:",
        "revertmove": "эгидип тургузары",
-       "delete_and_move": "Ырадыры болгаш шимчээри",
        "export": "Арынар үндүр дамчыдары",
        "allmessages": "Системниң дыңнадыглары",
        "allmessagesname": "Ат",
        "tooltip-ca-nstab-image": "Файлдың арны",
        "tooltip-ca-nstab-template": "Майыкты көөрү",
        "tooltip-ca-nstab-help": "Дуза арынын көөрү",
-       "tooltip-ca-nstab-category": "Ð\9aаÑ\82егоÑ\80иÑ\8f арны",
+       "tooltip-ca-nstab-category": "Ð\90ңгÑ\8bлал арны",
        "tooltip-minoredit": "Бо өскертилгени \"биче\" деп демдеглээр",
        "tooltip-save": "Эдилгелериңерни шыгжап арттырар",
        "tooltip-preview": "Арынның чижек көрүлдези: шыгжаар бетинде ону ажыглаар силер!",
index 473395f..a2a1411 100644 (file)
        "uploaded-script-svg": " \t\t\nЗнайдений небезпечний елемент з підтримкою сценаріїв «$1» в завантаженому файлі SVG.",
        "uploaded-hostile-svg": " \t\nЗнайдений небезпечний CSS-код в елементі стилю завантаженого файлу SVG.",
        "uploaded-event-handler-on-svg": " \t\nУстановка атрибутів обробника подій <code>$1=\"$2\"</code> не дозволено для SVG-файлів.",
-       "uploaded-href-attribute-svg": "У SVG-файлів не допускаються href-атрибути <code>&lt;$1 $2=\"$3\"&gt;</code> з не локальною ціллю (напр. http://, javascript:, тощо).",
        "uploaded-href-unsafe-target-svg": "У завантаженому SVG-файлі знайдено href до цілі <code>&lt;$1 $2=\"$3\"&gt;</code>, що не є безпечною.",
        "uploaded-animate-svg": "У завантаженому SVG-файлі знайдено теґ «animate», який може змінювати href, використовуючи атрибут «from» <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-setting-event-handler-svg": "Встановлення  атрибутів обробника подій заблоковане, у завантаженому файлі SVG знайдено <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "querypage-disabled": "Цю спеціальну сторінку вимкнуто для покращення продуктивності.",
        "apihelp": "Довідка з API",
        "apihelp-no-such-module": "Додаток \"$1\" не знайдено.",
+       "apisandbox": "Майданчик для тестування API",
+       "apisandbox-api-disabled": "API вимкнуто на цьому сайті.",
+       "apisandbox-intro": "Ця сторінка служить для експериментування з '''MediaWiki API'''.\nЗвертайтеся до [//www.mediawiki.org/wiki/API:Main_page документації] для докладнішої інформації про використання API.  Наприклад: [//www.mediawiki.org/wiki/API#A_simple_example як отримати вміст головної сторінки].  Виберіть дію, щоб побачити більше прикладів.\n\nЗверніть увагу, що, хоча це пісочниця, дії, виконані вами, на цій сторінці можуть змінити вікі.",
+       "apisandbox-submit": "Зробити запит",
+       "apisandbox-reset": "Очистити",
+       "apisandbox-examples": "Приклад",
+       "apisandbox-results": "Результат",
+       "apisandbox-request-url-label": "URL-адреса запиту:",
+       "apisandbox-request-time": "Час запиту $1",
        "booksources": "Джерела книг",
        "booksources-search-legend": "Пошук інформації про книгу",
        "booksources-isbn": "ISBN:",
        "log-title-wildcard": "Знайти заголовки, що починаються з цих символів",
        "showhideselectedlogentries": "Показати/приховати виділені записи журналу",
        "log-edit-tags": "Змінити мітки для вибраних записів журналів",
+       "checkbox-select": "Виберіть: $1",
+       "checkbox-all": "Всі",
+       "checkbox-none": "Нічого",
+       "checkbox-invert": "Інвертувати",
        "allpages": "Усі сторінки",
        "nextpage": "Наступна сторінка ($1)",
        "prevpage": "Попередня сторінка ($1)",
        "version-hook-subscribedby": "Підписаний на",
        "version-version": "($1)",
        "version-no-ext-name": "[без назви]",
-       "version-svn-revision": "(r$2)",
        "version-license": "Ліцензія MediaWiki",
        "version-ext-license": "Ліцензія",
        "version-ext-colheader-name": "Розширення",
index 17cfff1..ba19298 100644 (file)
        "rcshowhidemine": "ذاتی ترامیم $1",
        "rcshowhidemine-show": "دکھاؤ",
        "rcshowhidemine-hide": "چھپائیں",
+       "rcshowhidecategorization": "صفحاتی زمرہ بندی $1",
        "rcshowhidecategorization-show": "دکھائیں",
        "rcshowhidecategorization-hide": "چھپائیں",
        "rclinks": "آخری $2 روز میں ہونے والی $1 تبدیلیوں کا مشاہدہ کریں<br />$3",
        "recentchangeslinked-title": "\"$1\" سے متعلقہ تبدیلیاں",
        "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات متجل (bold) نظر آئیں گےـ",
        "recentchangeslinked-page": "صفحۂ منصوبہ دیکھئے",
+       "recentchanges-page-added-to-category": "[[:$1]] کو زمرہ میں شامل کیا گیا",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] اور {{PLURAL:$2|ایک صفحہ|$2 صفحات}} زمرہ میں شامل {{PLURAL:$2|کیا گیا|$2 کیے گئے}}",
+       "recentchanges-page-removed-from-category": "[[:$1]] کو زمرہ سے ہٹایا",
        "autochange-username": "میڈیاویکی خودکار تبدیلیاں",
        "upload": "فائل اثقال/اپلوڈ فائل",
        "uploadbtn": "زبراثقال ملف (اپ لوڈ فائل)",
        "pager-older-n": "{{PLURAL:$1|پُرانا 1|پُرانے $1}}",
        "apihelp": "معاونت اے پی آئی",
        "apihelp-no-such-module": "ماڈیول \"$1\" نہیں ملا",
+       "apisandbox-submit": "بنانے کی درخواست",
+       "apisandbox-reset": "واضح",
+       "apisandbox-examples": "مثال کے طور پر",
+       "apisandbox-results": "نتیجہ",
        "booksources": "کتابی وسائل",
        "booksources-search-legend": "تلاش برائے مآخذاتِ کتاب",
        "booksources-search": "تلاش",
        "watchlist-details": "آپ کی زیرِنظرفہرست پر {{PLURAL:$1|$1 صفحہ ہے|$1 صفحات ہیں}}، اِس میں تبادلۂ خیال صفحات کی تعداد شامل نہیں.",
        "wlnote": "نیچےآخری $1 تبدیلیاں ہیں جو کے پیچھلے <b>$2</b> گھنٹوں میں کی گئیں۔",
        "wlshowlast": "دکھائیں آخری $1 گھنٹے $2 دن",
-       "watchlistall2": "تمام",
        "watchlist-hide": "چھپائیں",
        "watchlist-submit": "دکھائیں",
        "wlshowhideminor": "معمولی ترامیم",
index efe997e..bff4cf9 100644 (file)
        "uploaded-script-svg": "Tìm thấy phần tử “$1” có khả năng chạy kịch bản trong tập tin SVG được tải lên.",
        "uploaded-hostile-svg": "Tìm thấy CSS nguy hiểm trong phần tử style của tập tin SVG được tải lên.",
        "uploaded-event-handler-on-svg": "Không cho phép đặt thuộc tính xử lý sự kiện <code>$1=\"$2\"</code> trong tập tin SVG.",
-       "uploaded-href-attribute-svg": "Không cho phép thuộc tính href <code>&lt;$1 $2=\"$3\"&gt;</code> có đích ngoài máy (ví dụ http://, javascript:, v.v.) trong tập tin SVG.",
        "uploaded-href-unsafe-target-svg": "Tìm thấy href đến đích nguy hiểm <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-animate-svg": "Tìm thấy thẻ “animate” có thể thay đổi href qua thuộc tính “from” <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-setting-event-handler-svg": "Đã ngăn cản việc đặt thuộc tính xử lý sự kiện khi tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "querypage-disabled": "Trang đặc biệt này bị tắt vì lý do hiệu suất.",
        "apihelp": "Trợ giúp API",
        "apihelp-no-such-module": "Không tìm thấy mô đun “$1”",
+       "apisandbox": "Chỗ thử API",
+       "apisandbox-api-disabled": "API đã bị vô hiệu hóa trên trang web này.",
+       "apisandbox-intro": "Trang này dùng để thử nghiệm với '''API dịch vụ Web của MediaWiki'''.\nHãy tra cứu [//www.mediawiki.org/wiki/API:Main_page tài liệu API] để biết chi tiết về cách sử dụng API. Ví dụ: [//www.mediawiki.org/wiki/API#A_simple_example lấy nội dung của Trang Chính]. Chọn một tác vụ để xem thêm ví dụ.\n\nLưu ý rằng, mặc dù đây là một chỗ thử, nhưng các tác vụ của bạn tại trang này có thể thực hiện các thay đổi trên wiki.",
+       "apisandbox-submit": "Yêu cầu",
+       "apisandbox-reset": "Tẩy trống",
+       "apisandbox-examples": "Ví dụ",
+       "apisandbox-results": "Kết quả",
+       "apisandbox-request-url-label": "URL của yêu cầu:",
+       "apisandbox-request-time": "Thời gian xử lý: $1",
        "booksources": "Nguồn sách",
        "booksources-search-legend": "Tìm kiếm nguồn sách",
        "booksources-search": "Tìm kiếm",
index 3999604..3dda0f6 100644 (file)
@@ -10,7 +10,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Rachmat.Wahidi",
-                       "Macofe"
+                       "Macofe",
+                       "Robin van der Vliet"
                ]
        },
        "tog-underline": "Dislienükön yümis:",
        "nstab-template": "Samafomot",
        "nstab-help": "Yufapad",
        "nstab-category": "Klad",
+       "mainpage-nstab": "Cifapad",
        "nosuchaction": "Atos no mögon",
        "nosuchactiontext": "Dun peflagöl fa el URL no sevädon vüke.\nBa epenol eli URL neverätiko, u ba esukol yümi dobik.\nMögos i, das atos sinifon, das dabinon säkädil pö program fa {{SITENAME}} pageböl.",
        "nosuchspecialpage": "Pad patik at no dabinon",
        "createaccountmail": "me pot leäktronik",
        "createaccountreason": "Kod:",
        "createacct-reason": "Kod",
-       "createacct-imgcaptcha-ph": "Penolöd vödemi, keli logol löpo",
        "createacct-submit": "Jafön kali olik",
        "createacct-benefit-body1": "{{PLURAL:$1|redakam|redakams}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pad|pads}}",
        "right-blockemail": "Blokön gitäti gebana ad sedön penedis leäktronik",
        "right-hideuser": "Blokön gebananemi, klänedölo oni de votikans",
        "right-ipblock-exempt": "Nedemön blokamis-IP, blokamis itjäfidik e grupiblokamis",
-       "right-proxyunbannable": "Nedemön blokamis itjäfidik pladulömas",
        "right-protect": "Votükön jelanivodis e redakön padis pejelöl",
        "right-editprotected": "Bevobön padis pejelöl äs \"{{int:protect-level-sysop}}\"",
        "right-editinterface": "Votükön gebanaloveikömi",
        "watchthisupload": "Galädolöd ragivi at",
        "filewasdeleted": "Ragiv labü nem at büo pelöpükon e poso pemoükon. Kontrololös eli $1 büä olöpükol oni dönu.",
        "filename-bad-prefix": "Nem ragiva fa ol palöpüköl primon me '''\"$1\"''': nem no bepenöl nomiko pagevöl itjäfidiko fa käms nulädik. Välolös, begö! nemi bepenöl pro ragiv olik.",
-       "upload-success-subj": "Löpükam eplöpon",
        "upload-proto-error": "Protok neverätik",
        "upload-proto-error-text": "Löpükam flagon elis URLs me <code>http://</code> u <code>ftp://</code> primölis.",
        "upload-file-error": "Pöl ninik",
        "pager-newer-n": "{{PLURAL:$1|nulikum 1|nulikum $1}}",
        "pager-older-n": "{{PLURAL:$1|büikum 1|büikum $1}}",
        "suppress": "Lovelogam",
+       "apisandbox-examples": "Sam",
        "booksources": "Bukafons",
        "booksources-search-legend": "Sukön bukafonis:",
        "booksources-search": "Sukön",
        "contributions": "{{GENDER:$1|Gebanakeblünots}}",
        "contributions-title": "Gebanakeblünots pro $1",
        "mycontris": "Keblünots",
+       "anoncontribs": "Keblünots",
        "contribsub2": "{{GENDER:$3|Hiela|Jiela|Ela}} $1 ($2)",
        "nocontribs": "Votükams nonik petuvons me paramets at.",
        "uctop": "(anuik)",
        "movenosubpage": "Pad at no labon donapadis.",
        "movereason": "Kod:",
        "revertmove": "sädunön",
-       "delete_and_move": "Moükolöd e topätükolöd",
        "delete_and_move_text": "==Moükam peflagon==\n\nYeged nulik \"[[:$1]]\" ya dabinon. Vilol-li moükön oni ad jafön spadi pro topätükam?",
        "delete_and_move_confirm": "Si! moükolöd padi",
        "delete_and_move_reason": "Pemoükon ad jafön spadi pro topätükam se ''[[$1]]''",
index 13edba7..6a481a4 100644 (file)
        "virus-scanfailed": "Pakyas an pag-scan (kodigo $1)",
        "virus-unknownscanner": "diri-nasasabtan nga antivirus:",
        "logouttext": "'''Nakalog-out kana.'''\n\nGinpapasabot ka la nga an iba nga pakli in magpapadayon nga magpakita komo nga ikaw naka-log-in pa, tubtob imo ginlimpyo an imo browser cache.",
+       "cannotlogoutnow-title": "Diri nakakalog-out yana",
+       "cannotlogoutnow-text": "Iton pag-log-out in imposible samtang nagamit hin $1.",
        "welcomeuser": "¡Uswag ngan Dayon, $1!",
        "welcomecreation-msg": "An im akawnt in nahimo na.\nAyaw kalimti pagbalyo han imo [[Special:Preferences|{{SITENAME}} preperensya]].",
        "yourname": "Agnay hit gumaramit:",
        "remembermypassword": "Hinumdumi an akon pan-sakob dinhi nga panngaykay ''(browser)'' (para ha pinakamaiha $1 {{PLURAL:$1|ka adlaw|ka mga adlaw}})",
        "userlogin-remembermypassword": "I-log-in la ako",
        "userlogin-signwithsecure": "Gamit hin koneksyon nga nakakasegurado",
+       "cannotloginnow-title": "Diri nakakalog-in yana",
+       "cannotloginnow-text": "Iton paglog-in in diri posible samtang nagamit hin $1.",
        "yourdomainname": "Imo dominyo:",
        "password-change-forbidden": "Diri ka makakabalyo hin pulong-pagsulod ha dinhi nga wiki.",
        "externaldberror": "Mayda authenticaton database error o diri ka tinutugotan pag-update an imo akwant ha gawas.",
        "wrongpasswordempty": "An tigaman-pagsulod nga ginbutang in waray sulod.\nAlayon pagutro pagbutang.",
        "passwordtooshort": "An tigaman-pagsulod dapat diri maubos hit {{PLURAL:$1|1 nga agi|$1 nga agi}}.",
        "passwordtoolong": "It mga password in diri puydi mas huruhilaba hin {{PLURAL:$1|1 ka karakter|$1 ka mga karakter}}.",
+       "passwordtoopopular": "Iton agsob pinipili nga mga password in diri puydi gamiton. Alayon pagpili hin mas kakaiba nga password.",
        "password-name-match": "An imo tigaman-pagsulod in kinahanglan iba ha imo agnay-hiton-gumaramit.",
        "password-login-forbidden": "An paggamit hini nga agnay-hit-gumaramit ngan tigaman-pagsulod in diri gintutugotan.",
        "mailmypassword": "Ig-reset an tigaman-pagsulod",
        "resetpass_submit": "Igbutang an password ngan log in",
        "changepassword-success": "Malinamposon an pagbal-iw hit imo tigaman-panakob!",
        "changepassword-throttled": "Damo na nga mga paningkamot hin pagsakob an imo ginhimò.\nAlayon paghulat hin $1 san-o ka umutro.",
+       "botpasswords": "Mga bot password",
        "resetpass_forbidden": "Diri mababalyoan an mga tigaman-pagsulod",
        "resetpass-no-info": "Kinahanglan mo paglog-in para direkta ka makasakob dinhi nga pakli.",
        "resetpass-submit-loggedin": "Igbal-iw an tigaman-pagsulod",
        "prefs-signature": "Pirma",
        "prefs-dateformat": "Batakan han petsa",
        "prefs-advancedediting": "Mga kasahiran nga pagpipilian",
+       "prefs-editor": "Editor",
        "prefs-preview": "Pahiuna nga pakita",
        "prefs-advancedrc": "Abansado nga mga pagpipilian",
        "prefs-advancedrendering": "Abansado nga mga pagpipilian",
        "uploadbtn": "Igkarga an file",
        "reuploaddesc": "Undanga an pagkarga-pasaka ngan balik ngadto ha porma han pagkarga-pasaka",
        "uploadnologin": "Diri nakalog-in",
+       "uploadnologintext": "Alayon $1 para han pag-upload han mga file.",
        "uploaderror": "Sayop hit pagkarga-pasaka",
        "upload-recreate-warning": "'''Pahimatngon:  An fayl nga may-ada hiton nga ngaran in ginpara o ginbalhin.'''\n\nAn taramdan han pagpara ngan pagbalhin para hini nga pakli in ginhahatag para han imo kamurayaw:",
        "upload-permitted": "Gintutugotan nga mga klase han paypay: $1.",
        "upload-description": "Pangilal-an han paypay",
        "upload-options": "Mga pirilion han pagkarga paigbaw",
        "watchthisupload": "Bantayi ini nga paypay",
-       "upload-success-subj": "Malinamposan an imo pagkarga-paigbaw.",
-       "upload-success-msg": "An imo pagkarga-paigbaw tikang ha [$2] in malinamposon.  Ini in aada dinhi: [[:{{ns:file}}:$1]]",
-       "upload-failure-subj": "May-ada problema an pagkarga-paigbaw",
-       "upload-failure-msg": "May-ada problema an imo pagkarga-paigbaw tikang ha [$2]:\n\n$1",
-       "upload-warning-subj": "Pahimatngon han pagkarga paigbaw",
        "upload-proto-error": "Sayop nga protocol",
        "upload-file-error": "Sayop ha sulod",
        "upload-misc-error": "Waray kasasabti nga sayop hin pagkarga-paigbaw",
        "foreign-structured-upload-form-label-own-work": "Buhat ko ini",
        "foreign-structured-upload-form-label-infoform-categories": "Mga kategorya",
        "foreign-structured-upload-form-label-infoform-date": "Petsa",
+       "foreign-structured-upload-form-3-label-yes": "Oo",
+       "foreign-structured-upload-form-3-label-no": "Diri",
        "backend-fail-notexists": "Waray ngada an paypay nga $1.",
        "backend-fail-delete": "Diri nakakapara han paypay nga \"$1\".",
        "backend-fail-alreadyexists": "May-ada na paypay nga \"$1\".",
        "license": "Palilisensya:",
        "license-header": "Palilisensya:",
        "nolicense": "Waray napili",
+       "listfiles-delete": "igpara",
+       "listfiles-summary": "Ini nga pinaurog nga pakli in nagpapakita han ngatanan nga pinan-upload nga mga file.",
+       "listfiles_search_for": "Pamiling hin media nga ngaran:",
        "imgfile": "paypay",
        "listfiles": "Listahan han fayl",
        "listfiles_date": "Pitsa",
        "listfiles_user": "Nagamit",
        "listfiles_size": "Kadako",
        "listfiles_count": "Mga bersyon",
+       "listfiles-latestversion": "Bersyon yana",
        "listfiles-latestversion-yes": "Oo",
        "listfiles-latestversion-no": "Diri",
        "file-anchor-link": "Paypay",
        "unusedtemplates": "Waray kagamiti nga mga batakan",
        "unusedtemplateswlh": "iba nga mga sumpay",
        "randompage": "Bisan ano nga pakli",
+       "randomincategory-submit": "Kadto-a",
        "randomredirect": "Bisan ano la nga redirect",
        "randomredirect-nopages": "Waray mga redirecta ha ngaran-lat'ang nga \"$1\".",
        "statistics": "Mga estadistika",
        "usereditcount": "$1 {{PLURAL:$1|ka pagliwat|ka mga pagliwat}}",
        "usercreated": "{{GENDER:$3|Ginhimo}} han $1 ha $2",
        "newpages": "Bag-o nga mga pakli",
+       "newpages-submit": "Igpakita",
        "newpages-username": "Agnay hiton gumaramit:",
        "ancientpages": "Mga gidaani nga pakli",
        "move": "Balhina",
        "nopagetitle": "Waray sugad hito nga kakadtoan nga pakli",
        "pager-newer-n": "{{PLURAL:$1|burubag-o 1|burubag-o $1}}",
        "pager-older-n": "{{PLURAL:$1|durudaan 1|durudaan $1}}",
+       "apisandbox-unfullscreen": "Igpakita an pakli",
+       "apisandbox-submit": "Paghimo hin request",
+       "apisandbox-reset": "Hawana",
+       "apisandbox-retry": "Utroha",
+       "apisandbox-helpurls": "Mga sumpay hit pabulig",
+       "apisandbox-examples": "Mga pananglitan",
+       "apisandbox-dynamic-parameters": "Dugang nga mga parameter",
+       "apisandbox-dynamic-parameters-add-label": "Dugngi hin parameter:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Ngaran hit parameter",
+       "apisandbox-dynamic-error-exists": "May-ada na nakangaran nga \"$1\" nga parameter.",
+       "apisandbox-results": "Mga resulta",
        "booksources": "Mga libro nga tinikangan",
        "booksources-search-legend": "Pamilnga an mga libro nga gintikangan",
        "booksources-search": "Bilnga",
        "notvisiblerev": "An urhi nga pagliwat han iba nga gumaramit in ginpara",
        "watchlist-details": "{{PLURAL:$1|$1 nga pakli|$1 nga mga pakli}} nga aada ha imo talaan nga binabantayan, diri bulag nga paglakip han mga hiruhimangraw-nga-pakli.",
        "wlshowlast": "Igpakita an katapusan nga $1 nga mga oras $2 nga mga adlaw",
-       "watchlistall2": "ngatanan",
+       "watchlist-hide": "Tago-a",
+       "watchlist-submit": "Pakit-a",
+       "wlshowhideminor": "gudti nga mga pagliwat",
+       "wlshowhidebots": "Mga bot",
+       "wlshowhideliu": "Mga nakarehistro nga gumaramit",
+       "wlshowhideanons": "Mga waray magpakilala nga gumaramit",
+       "wlshowhidepatr": "Nakapatrolya na nga mga pagliwat",
+       "wlshowhidemine": "ako mga pagliwat",
        "watchlist-options": "Mga pirilian han talaan han binabantayan",
        "watching": "Ginbabantay...",
        "unwatching": "Diri na ginbabantay...",
        "protect-othertime-op": "lain nga oras",
        "protect-otherreason": "Lain/dugang nga katadongan:",
        "protect-otherreason-op": "Lain nga katadongan",
+       "protect-expiry-options": "1 ka oras:1 hour,1 ka adlaw:1 day,1 ka semana:1 week,2 ka mga semana:2 weeks,1 ka bulan:1 month,3 ka mga bulan:3 months,6 ka mga bulan:6 months,1 ka tuig:1 year, waray kataposan:infinite",
        "restriction-type": "Pagtugot:",
        "minimum-size": "Pinakaguti nga kadako",
        "maximum-size": "Pinakadako nga kadako:",
        "whatlinkshere-hidelinks": "$1 an mga sumpay",
        "whatlinkshere-hideimages": "$1 an mga sumpay han paypay",
        "whatlinkshere-filters": "Mga panara",
+       "whatlinkshere-submit": "Kadto-a",
        "block": "Pugngi an gumaramit",
        "blockip": "Pugngi an gumaramit",
        "blockip-legend": "Pugngi an gumaramit",
        "allmessages-filter-all": "Ngatanan",
        "allmessages-language": "Yinaknan:",
        "allmessages-filter-submit": "Kadto-a",
+       "allmessages-filter-translate": "Ighubad",
        "thumbnail-more": "Padako-a",
        "filemissing": "Nawawara an fayl",
        "thumbnail_error": "Sayo han paghihimo hin thumbnail: $1",
+       "thumbnail_error_remote": "Sayop nga mensahe tikang $1:\n$2",
        "thumbnail_image-type": "An klase han hulagway in diri suportado",
        "import": "Naangbit hit mga pakli",
        "import-interwiki-templates": "Lakip an ngatanan nga mga batakan",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|gumaramit|mga gumaramit}} $1",
        "simpleantispam-label": "Anti-spam check.\n<strong>Ayaw</strong> pagbinutangi dinhi!",
        "pageinfo-title": "Impormasyon para \"$1\"",
+       "pageinfo-not-current": "Pasaylo-a, imposible makahatag hin impormasyon hiunong han mga daan nga rebisyon.",
        "pageinfo-header-basic": "Panguna nga pananabotan",
        "pageinfo-header-edits": "Kaagi han pagliwat",
        "pageinfo-header-restrictions": "Panalipod han pakli",
        "pageinfo-edits": "Ngatanan nga ihap han mga pakli",
        "pageinfo-toolboxlink": "Impormasyon han pakli",
        "pageinfo-redirectsto": "Igredirect ngadto ha",
+       "pageinfo-redirectsto-info": "info",
        "pageinfo-contentpage": "Ginlakip komo uska unod nga pakli",
        "pageinfo-contentpage-yes": "Oo",
        "pageinfo-protect-cascading-yes": "Oo",
        "pageinfo-category-info": "Impormasyon han kaarangay",
+       "pageinfo-category-total": "Ngatanan nga mga naka-api.",
        "pageinfo-category-pages": "Ihap han mga pakli",
        "pageinfo-category-subcats": "Ihap han mga ubos-kaarangay",
        "pageinfo-category-files": "Ihap han mga paypay",
        "bydate": "pinaagi han petsa",
        "ago": "$1 an nakalabay",
        "just-now": "yana pala",
+       "monday-at": "Lunes ha $1",
+       "tuesday-at": "Martes ha $1",
+       "wednesday-at": "Miyerkules ha $1",
+       "thursday-at": "Huybes ha $1",
+       "friday-at": "Biyernes ha $1",
+       "saturday-at": "Sabado ha $1",
+       "sunday-at": "Dominggo ha $1",
+       "yesterday-at": "Kakulop ha $1",
        "bad_image_list": "An kabutangan in masunod:\n\nAn nakatalala la nga mga butang (mga bagis nga nagtitikang hin *) in mahiuupod paglabot.\nAn syahan nga sumpay ha uska bagis in dapat may-ada sumpay ngadto ha maraot nga fayl.\nAn bisan ano nga masunod nga mga sumpay ha kapareho nga bagis in igtratrato nga eksepsyon, sugad hin, mga pakli kun diin an mga fayl in puydi mabubutang ha sulod han bagis.",
        "metadata": "Metadata",
        "metadata-help": "Iní nga paypay mayda dugang nga pagpasabot, nga bangin gindugáng tikang han digital nga camera o iskaner nga gin-gamit paghimo o pag-digitar hini.\nKon an paypay ginliwat tikang han orihinal nga kamutangan, mayda mga detalye nga bangin diri magpakita han ginliwat nga paypay",
        "exif-model": "Modelo han kamera",
        "exif-software": "Software nga gingamit",
        "exif-artist": "Tag-iya",
+       "exif-copyright": "May katungod han copyright",
        "exif-exifversion": "Version han Exif",
        "exif-colorspace": "Kolor lat-ang",
        "exif-datetimeoriginal": "Petsa ngan oras han data generation",
        "exif-datetimereleased": "Ginpagawas han",
        "exif-lens": "Mga lente nga gingamit",
        "exif-cameraownername": "Tag-iya han kamera",
+       "exif-copyrighted": "Kahimtang han copyright",
+       "exif-copyrightowner": "Tag-iya han copyright",
        "exif-usageterms": "Mga termino hit paggamit",
        "exif-copyrighted-false": "Status hin katungod-hin-panag-iya waray mahabutang",
        "exif-unknowndate": "Waray kasabti an petsa",
index bd1b89d..ed1b46a 100644 (file)
@@ -49,7 +49,7 @@
        "tog-enotifrevealaddr": "電子信通知單裏顯示我個電子信地址",
        "tog-shownumberswatching": "顯示關注人數",
        "tog-oldsig": "本生个签名:",
-       "tog-fancysig": "畀簽名當wiki文本(弗自動鏈接)",
+       "tog-fancysig": "拿签名当成维基文本(弗自动链接)",
        "tog-uselivepreview": "使用实时预览",
        "tog-forceeditsummary": "編要空白到提醒我",
        "tog-watchlisthideown": "關注表裏囥脫我所編",
        "searchbutton": "搜寻",
        "go": "去",
        "searcharticle": "去",
-       "history": "é \81史",
+       "history": "页é\9d¢å\8e\86史",
        "history_short": "历史",
        "updatedmarker": "從上趟訪問起個更新",
        "printableversion": "打印版",
        "nstab-image": "文件",
        "nstab-mediawiki": "信息",
        "nstab-template": "模板",
-       "nstab-help": "幫å¿\99é \81",
+       "nstab-help": "帮å¿\99页",
        "nstab-category": "分类",
        "mainpage-nstab": "封面",
        "nosuchaction": "嘸能操作",
        "nosuchactiontext": "URL指定個命令無效。爾嘸數畀URL打錯哉,要勿点击仔出錯個鏈接。也嘸數{{SITENAME}}用個軟件本身出錯緣故。",
-       "nosuchspecialpage": "å\98¸è\83½å\80\8bç\89¹å\88¥é \81",
+       "nosuchspecialpage": "å\91\92ä¸\8då®\9eæ¢\97个ç\89¹å\88«é¡µé\9d¢",
        "nospecialpagetext": "<strong>侬请求个特殊页面无效。</strong>\n\n参考特殊页面列表[[Special:SpecialPages| {{int:specialpages}}]]。",
        "error": "错误",
        "databaseerror": "数据库错误",
        "virus-badscanner": "设置问题:未知个反病毒扫描器:''$1''",
        "virus-scanfailed": "扫描失败(代码 $1)",
        "virus-unknownscanner": "未知个反病毒扫描器:",
-       "logouttext": "'''你侬登出哉。'''\n\n部份页面呒数还会显示你侬还登勒里,到你侬畀浏览器慢存清爻止。",
+       "logouttext": "<strong>侬已经登出哉。</strong>\n\n请注意有星页面作兴还是会得搭侬登出前头一样显示,一脚到侬个浏览器缓存清脱为止。",
        "welcomeuser": "走来赞,$1!",
        "welcomecreation-msg": "你个账号建起来哉。\n覅忘记哉走去改你个[[Special:Preferences|{{SITENAME}}个私人偏好]]。",
        "yourname": "用户名:",
        "yourpasswordagain": "密码再打一遍:",
        "createacct-yourpasswordagain": "确认密码",
        "createacct-yourpasswordagain-ph": "再打一遍密码",
-       "remembermypassword": "徕箇浏览器里畀我登进去个记牢(记$1{{PLURAL:$1|日|日}})",
+       "remembermypassword": "来箇只浏览器上记牢我个登录状态(顶长$1天)",
        "userlogin-remembermypassword": "记牢我个登录状态",
        "userlogin-signwithsecure": "用保险链接",
        "yourdomainname": "侬个域名:",
        "changepassword-success": "密碼改好哉!\n能界登錄當中...",
        "changepassword-throttled": "侬试登录忒多次哉。等$1再试试看。",
        "resetpass_forbidden": "密码弗好更改",
-       "resetpass-no-info": "侬必须登录ä»\94å\86\8d好ç\9b´æ\8e¥è¿\9bå\85¥ç®\87å\8fªé¡µé\9d¢ã\80\82",
+       "resetpass-no-info": "侬必须登录è\91\97æ\89\8d好ç\9b´æ\8e¥è¿\9bå\85¥ç®\87å\8fªé¡µé\9d¢ã\80\82",
        "resetpass-submit-loggedin": "更改密码",
        "resetpass-submit-cancel": "取消",
        "resetpass-wrong-oldpass": "无效个临时或者现有密码。\n侬作兴已经成功拿密码改脱,或者已经请求一个新个临时密码。",
        "passwordreset-emailelement": "用户名:\n$1\n\n临时密码:\n$2",
        "changeemail": "更改或删脱电子邮箱地址",
        "changeemail-passwordrequired": "侬需要输入密码来确认本次更改。",
-       "changeemail-no-info": "侬必须登录著å\86\8d好ç\9b´æ\8e¥è¿\9bå\85¥ç®\87å\8fªé¡µé\9d¢ã\80\82",
+       "changeemail-no-info": "侬必须登录著æ\89\8d好ç\9b´æ\8e¥è¿\9bå\85¥ç®\87å\8fªé¡µé\9d¢ã\80\82",
        "changeemail-oldemail": "当前电子邮件地址:",
        "changeemail-newemail": "新个电子邮件地址:",
        "changeemail-password": "侬个{{SITENAME}}密码:",
        "nosuchsectiontext": "侬尝试编辑个章节弗存在。\n作兴是垃拉侬查看页面个辰光已经移动或者畀删除。",
        "loginreqtitle": "必须登录",
        "loginreqlink": "登录",
-       "loginreqpagetext": "侬必须$1再好查看其它页面。",
+       "loginreqpagetext": "请$1来望其他页面。",
        "accmailtitle": "密码已发送哉。",
        "accmailtext": "已经为[[User talk:$1|$1]]产生只随机密码,并且已经发送到$2。登录之后,侬可以垃拉<em>[[Special:ChangePassword|箇只页面]]</em>更改密码。",
        "newarticle": "(新)",
        "newarticletext": "倷跟仔链接来着一个还弗勒里个页面。\n要创建该页面呢,就勒下底个框框里向开始写([$1 帮助页面]浪有更加多个信息)。\n要是倷是弗用心到该搭个说话,只要点击倷浏览器个'''返回'''揿钮。",
        "anontalkpagetext": "---- ''箇是一个还弗曾建立账户个匿名用户个讨论页, 箇咾我伲只好用IP地址来搭渠联络。该IP地址可能由几名用户共享。如果侬是一名匿名用户并认为箇只页面高头个评语搭侬弗搭界,请 [[Special:UserLogin/signup|创建新账户]]或[[Special:UserLogin|登录]]来避免垃拉将来搭其他匿名用户混淆。''",
-       "noarticletext": "箇页目前呒有文本。\n你侬好来别个页[[Special:Search/{{PAGENAME}}|搜寻箇页标题]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜寻相关日志]要勿[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编箇页]。</span>",
+       "noarticletext": "箇只页面目前呒没文本。侬可以垃拉其他页面高头[[Special:Search/{{PAGENAME}}|寻该只标题]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 寻相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑此页]</span>。",
        "noarticletext-nopermission": "箇只页面目前还呒不文本。侬好来别个页面[[Special:Search/{{PAGENAME}}|寻箇页标题]],或者<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 寻相关日志]</span>,但必过侬呒不权限建立箇只页面。",
        "userpage-userdoesnotexist": "用户账户“<nowiki>$1</nowiki>”弗曾创建。请垃拉创建/编辑迭个页面前头先检查一记。",
        "userpage-userdoesnotexist-view": "用户账户“$1”弗曾创建。",
        "blocked-notice-logextract": "箇位用户箇歇畀封锁垃许。\n下头有最近个封锁纪录以供参考:",
-       "clearyourcache": "<strong>注意:</strong>垃拉保存之后,侬作兴要清除浏览器个缓存å\86\8d好ç\9c\8bè§\81æ\94¹å\8f\98ã\80\82\n* <strong>Firefoxæ\88\96Safariï¼\9a</strong>æ\8f¿ç\89¢â\80\9cShiftâ\80\9d个å\90\8cæ\97¶ç\82¹å\87»â\80\9cå\88·æ\96°â\80\9dï¼\8cæ\88\96æ\8f¿â\80\9cCtrl-F5â\80\9dæ\88\96â\80\9cCtrl-Râ\80\9dï¼\88Macä¸\8aæ\98¯â\80\9câ\8c\98-Râ\80\9dï¼\89\n* <strong>Google Chromeï¼\9a</strong>æ\8f¿â\80\9cCtrl-Shift-Râ\80\9dï¼\88Macä¸\8aæ\98¯â\80\9câ\8c\98-Shift-Râ\80\9dï¼\89\n* <strong>Internet Explorerï¼\9a</strong>æ\8f¿ç\89¢â\80\9cCtrlâ\80\9d个å\90\8cæ\97¶ç\82¹å\87»â\80\9cå\88·æ\96°â\80\9dï¼\8cæ\88\96æ\8f¿â\80\9cCtrl-F5â\80\9d\n* <strong>Operaï¼\9a</strong>å\9e\83æ\8b\89â\80\9cå·¥å\85·â\86\92é¦\96é\80\89项â\80\9dé\87\8cå\90\91æ¸\85é\99¤ç¼\93å­\98",
+       "clearyourcache": "<strong>注意:</strong>垃拉保存之后,侬作兴要清除浏览器个缓存æ\89\8d好ç\9c\8bè§\81æ\94¹å\8f\98ã\80\82\n* <strong>Firefoxæ\88\96Safariï¼\9a</strong>æ\8f¿ç\89¢â\80\9cShiftâ\80\9d个å\90\8cæ\97¶ç\82¹å\87»â\80\9cå\88·æ\96°â\80\9dï¼\8cæ\88\96æ\8f¿â\80\9cCtrl-F5â\80\9dæ\88\96â\80\9cCtrl-Râ\80\9dï¼\88Macä¸\8aæ\98¯â\80\9câ\8c\98-Râ\80\9dï¼\89\n* <strong>Google Chromeï¼\9a</strong>æ\8f¿â\80\9cCtrl-Shift-Râ\80\9dï¼\88Macä¸\8aæ\98¯â\80\9câ\8c\98-Shift-Râ\80\9dï¼\89\n* <strong>Internet Explorerï¼\9a</strong>æ\8f¿ç\89¢â\80\9cCtrlâ\80\9d个å\90\8cæ\97¶ç\82¹å\87»â\80\9cå\88·æ\96°â\80\9dï¼\8cæ\88\96æ\8f¿â\80\9cCtrl-F5â\80\9d\n* <strong>Operaï¼\9a</strong>å\9e\83æ\8b\89â\80\9cå·¥å\85·â\86\92é¦\96é\80\89项â\80\9dé\87\8cå\90\91æ¸\85é\99¤ç¼\93å­\98",
        "usercssyoucanpreview": "'''提示:''' 垃拉保存之前请用“{{int:showpreview}}”揿钮来测试新 CSS 。",
        "userjsyoucanpreview": "'''提示:''' 垃拉保存之前请用“{{int:showpreview}}”揿钮来测试新 JavaScript 。",
        "usercsspreview": "'''注意侬只是垃许预览侬个 CSS。'''\n'''还弗曾保存!'''",
        "copyrightwarning2": "请注意侬对{{SITENAME}}个所有贡献\n侪可能畀别个贡献者编辑,修改或删除。\n假使侬弗希望侬个文字畀任意修改搭仔再发布,请弗要提交。<br />\n侬同时也要向我伲保证侬提交个内容是侬自家所作,或得自一个弗受版权保护或相似自由个来源(参阅$1个细节)。\n''' 弗要垃拉弗曾获得授权个情况下头发表!'''",
        "longpageerror": "<strong>错误:侬提交个文本长度有$1KB,大于$2KB个顶大值。</strong>该文本弗能保存。",
        "readonlywarning": "<strong>警告:数据库锁定垃许维护,侬箇歇弗好保存侬个修改。</strong>侬作兴希望先拿侬个文字复制并保存到文本文件,等歇再修改。\n\n锁牢数据库个系统管理员有如下解释:$1",
-       "protectedpagewarning": "<strong>警告:此页已经畀保护,只有拥有管理员权限个用户å\86\8d好修æ\94¹ã\80\82</strong>æ\9c\80è¿\91个æ\97¥å¿\97å\9e\83æ\8b\89ä¸\8båº\95æ\8f\90ä¾\9b以便å\8f\82è\80\83ï¼\9a",
+       "protectedpagewarning": "<strong>警告:此页已经畀保护,只有拥有管理员权限个用户æ\89\8d好修æ\94¹ã\80\82</strong>æ\9c\80è¿\91个æ\97¥å¿\97å\9e\83æ\8b\89ä¸\8båº\95æ\8f\90ä¾\9b以便å\8f\82è\80\83ï¼\9a",
        "semiprotectedpagewarning": "'''注意:''' 本页面畀锁定,仅限注册用户编辑。\n最近个日志垃拉下底提供以便参考:",
-       "cascadeprotectedwarning": "<strong>警告:</strong>本页已经畀保护,只有拥有管理员权限个用户å\86\8d好修æ\94¹ï¼\8cå\9b ä¸ºæ\9c¬é¡µå·²ç\95\80ä¸\8båº\95ç\9c¼çº§è\81\94ä¿\9dæ\8a¤ä¸ª{{PLURAL:$1|ä¸\80å\8fª|å¤\9aå\8fª}}页é\9d¢æ\89\80åµ\8cå\85¥ï¼\9a",
+       "cascadeprotectedwarning": "<strong>警告:</strong>本页已经畀保护,只有拥有管理员权限个用户æ\89\8d好修æ\94¹ï¼\8cå\9b ä¸ºæ\9c¬é¡µå·²ç\95\80ä¸\8båº\95ç\9c¼çº§è\81\94ä¿\9dæ\8a¤ä¸ª{{PLURAL:$1|ä¸\80å\8fª|å¤\9aå\8fª}}页é\9d¢æ\89\80åµ\8cå\85¥ï¼\9a",
        "titleprotectedwarning": "'''警告:本页面已畀锁定,需要[[Special:ListGroupRights|指定权限]]方可创建。'''\n最近个日志垃拉下底提供以便参考:",
        "templatesused": "箇页有{{PLURAL:$1|个模板}}:",
        "templatesusedpreview": "{{PLURAL:$1|只模板}}垃拉箇趟预览里向拨使用:",
        "revdelete-selected-file": "已选择文件[[:$2]]个$1只版本:",
        "logdelete-selected": "选取$1个日志事件:",
        "revdelete-confirm": "假使侬想箇能介做个闲话,请确认侬已经清爽箇能介做个后果,外加箇个程序符合[[{{MediaWiki:Policy-url}}|政策]]。",
-       "revdelete-suppress-text": "<strong>只有</strong>出现下头眼情况å\86\8dåº\94é\98»æ­¢è®¿é\97®ï¼\9a\n* æ½\9cå\9c¨ä¸ªè¯½è°¤ä¿¡æ\81¯\n* å¼\97é\80\82å\90\88个个人信æ\81¯\n*: <em>家庭å\9c°å\9d\80ã\80\81ç\94µè¯\9då\8f·ç \81ã\80\81身份è¯\81å\8f·ç \81ç­\89ã\80\82</em>",
+       "revdelete-suppress-text": "<strong>只有</strong>出现下头眼情况æ\89\8dåº\94é\98»æ­¢è®¿é\97®ï¼\9a\n* æ½\9cå\9c¨ä¸ªè¯½è°¤ä¿¡æ\81¯\n* å¼\97é\80\82å\90\88个个人信æ\81¯\n*: <em>家庭å\9c°å\9d\80ã\80\81ç\94µè¯\9då\8f·ç \81ã\80\81身份è¯\81å\8f·ç \81ç­\89ã\80\82</em>",
        "revdelete-legend": "设置可见性之限制",
        "revdelete-hide-text": "修订文本",
        "revdelete-hide-image": "隐藏文件内容",
        "gender-male": "男",
        "gender-female": "女",
        "email": "电子邮件",
-       "prefs-help-email": "电子信由你侬填弗填,转设密码用得着。",
+       "prefs-help-email": "电子邮箱是选填个,来侬忘脱密码之后好拿新密码寄畀侬。",
        "prefs-help-email-others": "你侬也好来你侬个用户|讨论页里添加自己个电子信连接畀别人联系你用。\n别人联系你是弗晓得你侬个电子信地址个。",
        "prefs-help-email-required": "需要电子邮件地址。",
        "prefs-info": "基本信息",
        "prefs-advancedwatchlist": "高级选项",
        "prefs-tabs-navigation-hint": "提示:侬可以用左、右箭头键来选项卡之间切换。",
        "userrights-user-editname": "输入用户名:",
-       "editusergroup": "编辑用户组",
+       "editusergroup": "编辑{{GENDER:$1|用户}}组",
+       "editinguser": "改动{{GENDER:$1|用户}}<strong>[[User:$1|$1]]</strong>个用户权限$2",
        "group-bot": "机器人",
        "group-sysop": "管理员",
        "group-bureaucrat": "行政员",
        "right-deleterevision": "删脱搭恢复页面个特定版本",
        "right-deletedhistory": "检视畀删脱个历史项目,弗包括相关文本",
        "right-browsearchive": "搜尋已刪頁",
+       "right-unblockself": "解封自家",
        "right-editusercss": "编辑其他用户个CSS文件",
        "right-edituserjs": "编辑其他用户个JavaScript文件",
        "right-editmyusercss": "编辑侬自家个用户CSS文件",
        "grant-group-page-interaction": "搭頁面互動",
        "grant-group-file-interaction": "搭媒體互動",
        "grant-group-watchlist-interaction": "搭侬个关注表互动",
-       "grant-group-email": "發電子信",
+       "grant-group-email": "发电子邮件",
+       "grant-createaccount": "建立账号",
+       "grant-createeditmovepage": "建立、编辑搭著捅荡页面",
        "grant-rollback": "畀修改擂轉到頁面",
        "grant-sendemail": "發電子信畀各許用戶",
        "newuserlogpage": "用户创建日志",
        "rcshowhideanons": "$1匿名用户",
        "rcshowhideanons-show": "显示",
        "rcshowhideanons-hide": "囥脱",
+       "rcshowhidepatr-hide": "囥脱",
        "rcshowhidemine": "$1我个编辑",
        "rcshowhidemine-show": "显示",
        "rcshowhidemine-hide": "囥脱",
+       "rcshowhidecategorization-hide": "囥脱",
        "rclinks": "显示来拉上个 $2 日里向个最近 $1 趟改动<br />$3",
        "diff": "两样",
        "hist": "历史",
        "uploadbtn": "上载文件",
        "reuploaddesc": "弗傳,轉到傳表單",
        "uploadnologin": "朆登录",
-       "uploadnologintext": "倷板定要$1再好上载文件。",
+       "uploadnologintext": "请$1来上载文件。",
        "uploaderror": "上载出错",
        "uploadtext": "拿下头只表格来上载文件。要查看或者搜寻之前上载个图片个说法,请到[[Special:FileList|已上载文件列表]],上载搭仔删脱也记录勒拉[[Special:Log/upload|上载日志]]里向。\n\n要勒拉页面里向摆进图片个说法,用下头该种形式个链接\n'''<nowiki>[[{{ns:file}}:文件.jpg]]</nowiki>''',\n'''<nowiki>[[{{ns:file}}:文件.png|替代文本]]</nowiki>''' 或者用\n'''<nowiki>[[{{ns:media}}:文件.ogg]]</nowiki>''' 直接链到文件。",
        "uploadlogpage": "文件上传日志",
        "filehist-comment": "备注",
        "imagelinks": "文件用法",
        "linkstoimage": "下头$1个页面链到箇文件:",
-       "nolinkstoimage": "呒有页链到箇文件。",
+       "nolinkstoimage": "呒不页面链接到该只文件。",
        "linkstoimage-redirect": "$1(文件轉戳到)$2",
        "sharedupload": "箇只文件来源于$1,渠作兴垃拉其它项目当中拨应用。",
        "sharedupload-desc-here": "箇文件$1里个,作兴会畀别个项目使用。\n渠个[$2 描述页]里个说明显示如下。",
        "categories": "页面分类",
        "categoriespagetext": "下底个{{PLURAL:$1|分类包括}}页面或者媒体文件。[[Special:UnusedCategories|未使用分类]]弗勒伊𡍲显示。另见[[Special:WantedCategories|需要个分类]]。",
        "deletedcontributions": "删脱个用户贡献",
+       "deletedcontributions-title": "删脱个用户贡献",
        "linksearch": "外部链接搜寻",
        "linksearch-ns": "名字空間:",
        "linksearch-ok": "搜尋",
        "emailsenttext": "倷个电子邮件讯息已经拨发送哉。",
        "watchlist": "關注表",
        "mywatchlist": "我个关注表",
-       "nowatchlist": "倷个监控列表是空个。",
+       "nowatchlist": "倷个关注表是空个。",
        "watchnologin": "朆登录",
-       "addedwatchtext": "“[[:$1]]”及其讨论页已经加进侬个[[Special:Watchlist|关注表]]哉。",
+       "addedwatchtext": "“[[:$1]]”连牢著讨论页已经加进侬个[[Special:Watchlist|关注表]]哉。",
        "removewatch": "從關注表移爻",
-       "removedwatchtext": "“[[:$1]]”及其讨论页已经从侬个[[Special:Watchlist|关注表]]去脱哉。",
+       "removedwatchtext": "“[[:$1]]”连牢著讨论页已经从侬个[[Special:Watchlist|关注表]]去脱哉。",
        "watch": "关注",
        "watchthispage": "监控该只页面",
        "unwatch": "弗关注",
        "unwatchthispage": "停止监控",
        "notanarticle": "弗是內容頁",
        "watchlist-details": "有$1页垃拉侬关注表高头,弗包括讨论页。",
-       "wlheader-showupdated": "勒侬上趟查看之后畀修改个页面<strong>加粗</strong>显示。",
+       "wlheader-showupdated": "勒侬上趟查看之后修改过个页面<strong>加粗</strong>显示。",
        "wlnote": "下底是{{PLURAL:$2|过去<strong>$2</strong>个钟头}}个{{PLURAL:$1|最后<strong>$1</strong>届更改}},截至$3 $4。",
        "wlshowlast": "显示上$1个钟头$2日天",
-       "watchlistall2": "全部",
+       "watchlist-hide": "囥脱",
+       "wlshowhidemine": "我个编辑",
        "watchlist-options": "监控列表选项",
        "watching": "监控……",
        "unwatching": "解除监控……",
        "undelete-search-submit": "搜尋",
        "namespace": "名字空间:",
        "invert": "反选择",
-       "tooltip-invert": "请选择该框来囥脱指定名字空间(搭有关名字空间,如果你选择)个页面更改",
+       "tooltip-invert": "打上扎钩头来囥脱选定名字空间个改动(如果勾选有关名字空间,箇么一道囥脱)",
        "namespace_association": "有关个名字空间",
-       "tooltip-namespace_association": "选中该复选框可包括搭选定名字空间有关个讨论页或子页面",
+       "tooltip-namespace_association": "打上扎钩头来加上搭选定名字空间搭界个讨论或主题名字空间",
        "blanknamespace": "(主)",
        "contributions": "{{GENDER:$1|用户}}贡献",
        "contributions-title": "$1个贡献",
        "year": "从箇年往前:",
        "sp-contributions-newbies": "只显示新用户个贡献",
        "sp-contributions-blocklog": "查封记录",
+       "sp-contributions-deleted": "删脱个用户贡献",
        "sp-contributions-talk": "讲张",
        "sp-contributions-search": "搜寻贡献记录",
        "sp-contributions-username": "IP地址要勿用户名:",
        "whatlinkshere-hidelinks": "$1链接",
        "whatlinkshere-filters": "过滤器",
        "blockip": "查封{{GENDER:$1|用户}}",
-       "blockiptext": "用下头个表单来禁止来自某一特定IP地址或用户名个修改权限。只有勒勒为仔防止破坏,及符合[[{{MediaWiki:Policy-url}}|政策]]个情况下底再好采取此行动。请勒勒下底输入一个具体个理由(譬如引述一只畀破坏个页面)。",
+       "blockiptext": "用下头个表单来禁止来自某一特定IP地址或用户名个修改权限。只有勒勒为仔防止破坏,及符合[[{{MediaWiki:Policy-url}}|政策]]个情况下底才好采取此行动。请勒勒下底输入一个具体个理由(譬如引述一只畀破坏个页面)。侬好用[https://zh.wikipedia.org/wiki/无类别域间路由 CIDR]语法查封IP地址段;允许个最大段是/$1(针对IPv4)搭/$2(针对IPv6)。",
        "ipaddressorusername": "IP地址或用户名:",
        "ipbreason": "理由:",
        "ipbsubmit": "封杀该个用户",
        "move-page-legend": "页面捅荡",
        "movepagetext": "用下底个表会重命名一只页面,全部历史侪移到新名字里。老个名字会变成戳到新名字个重定向页。注意检查[[Special:DoubleRedirects|双重重定向]]或者[[Special:BrokenRedirects|坏脱个重定向]]。倷有实概个责任,让链接仍旧链到俚笃应该链到个场化去。\n\n注意,如果新名字归面搭已经有页面个说话,老名字个页面'''弗'''会畀移动,除非归个是只空页面或者是只重定向并且呒不编辑历史。箇也就是讲,假使倷犯错误个说话,倷好拿一只重命名过个页面还原到原来个名字,但倷弗好覆盖一只已经来上个页面。\n\n<strong>警告!</strong>箇呒数会引起对一只热门页面剧烈个、想弗着个改变。来操作前头请倷确定倷已经充分了解行为个后果。",
        "movepagetalktext": "如果侬勾选此框,相关讨论页会自动移动到新标题,除非箇𡍲已经有著一只非空个讨论页。\n\n来箇种情况下底,如果有需要,侬必须手工移动或合并页面。",
-       "movenologintext": "倷板定要是å·²ç\99»è®°ç\94¨æ\88·ä¸\94å\8b\92æ\8b\89[[Special:UserLogin|ç\99»å½\95]]ç\8a¶æ\80\81ä¸\8b头å\86\8d好æ\8b¿é¡µé\9d¢æ\8d\85è\8d¡ã\80\82",
+       "movenologintext": "倷板定要是注å\86\8cç\94¨æ\88·å¹¶ä¸\94[[Special:UserLogin|ç\99»å½\95]]è\91\97æ\89\8d好æ\8b¿é¡µé\9d¢æ\8d\85è\8d¡ã\80\82",
        "newtitle": "新标题:",
        "move-watch": "监控来源以及目标页",
        "movepagebtn": "页面移动",
        "movereason": "理由:",
        "revertmove": "恢复",
        "delete_and_move_confirm": "对哉,删脱该只页面",
+       "semiprotectedpagemovewarning": "<strong>注意:</strong>箇只页面畀保护来许,只有注册用户才好移动渠。下底提供最近个日志畀侬参考:",
        "export": "页导出",
        "allmessages": "系统讯息",
        "allmessagesname": "名字",
        "tooltip-ca-watch": "拿箇只页面加到侬个关注表里向",
        "tooltip-ca-unwatch": "拿箇只页面从侬个关注表里删脱",
        "tooltip-search": "搜寻{{SITENAME}}",
-       "tooltip-search-go": "如果存在相同标题,箇么直接去该页面",
+       "tooltip-search-go": "如果存在一样个标题就直接到箇只页面𡍲去",
        "tooltip-search-fulltext": "搜寻包含箇星文本个页面",
        "tooltip-p-logo": "翻到封面",
        "tooltip-n-mainpage": "翻到封面",
        "tooltip-t-whatlinkshere": "列出全部搭箇页链个页",
        "tooltip-t-recentchangeslinked": "箇页链出去个全部页箇阶段变化",
        "tooltip-feed-rss": "订阅本页",
-       "tooltip-feed-atom": "此页个Atom 订阅",
+       "tooltip-feed-atom": "此页个Atom订阅",
        "tooltip-t-contributions": "{{GENDER:$1|箇位用户}}个贡献列表",
-       "tooltip-t-emailuser": "发电子信畀箇个用户",
+       "tooltip-t-emailuser": "发电子信畀{{GENDER:$1|箇位用户}}",
        "tooltip-t-upload": "上传文件",
        "tooltip-t-specialpages": "全部特殊页列表",
        "tooltip-t-print": "箇页个打印版",
        "tooltip-ca-nstab-main": "望内容页",
        "tooltip-ca-nstab-user": "查看用户页",
        "tooltip-ca-nstab-media": "查看媒体页",
-       "tooltip-ca-nstab-special": "箇是特æ®\8a页é\9d¢ï¼\8cå¼\97è\83½ç¼\96è¾\91",
+       "tooltip-ca-nstab-special": "箇是特å\88«é¡µé\9d¢ï¼\8cå¼\97好ç¼\96è¾\91",
        "tooltip-ca-nstab-project": "望项目页",
        "tooltip-ca-nstab-image": "望文件页",
        "tooltip-ca-nstab-mediawiki": "查看系统讯息",
        "tooltip-ca-nstab-category": "望分类页",
        "tooltip-minoredit": "标作小编写",
        "tooltip-save": "保存侬个修改",
-       "tooltip-preview": "望望相你侬个修改,保存之前用!",
+       "tooltip-preview": "预览侬个改变。保存前头请检查一遍。",
        "tooltip-diff": "显示侬对文本个修改",
        "tooltip-compareselectedversions": "查看本页面两只选定个修订版个差异。",
        "tooltip-watch": "拿箇页加到侬个关注表里",
        "confirmemail_body_changed": "用IP地址$1嗰人,(呒数是你侬)徕{{SITENAME}}里一个账号“$2”建起,用你侬个电子信箱地址。\n\n确认记箇账号是弗是你侬嘅,激活{{SITENAME}}里嗰电子信功能。用浏览器打开下向嗰链接:\n\n$3\n\n假使你侬*朆*注册过箇账号,揿下向嗰链接取消电子信确认:\n\n$5\n\n确认码会到$4过期。",
        "scarytranscludetoolong": "[URL忒长]",
        "deletedwhileediting": "<strong>警告:</strong>此页拉侬开始编辑之后已经畀删脱!",
-       "confirmrecreate": "用户[[User:$1|$1]] ([[User talk:$1|讲张]])勒拉倷开始编辑该页面之后拿俚删脱,理由是: : ''$2'' 请拿定章程,倷阿是真个要重建该页面。",
+       "confirmrecreate": "用户[[User:$1|$1]]([[User talk:$1|讲张]])勒拉倷开始编辑该页面之后拿俚{{GENDER:$1|删脱}},理由是:\n: <em>$2</em>\n请拿定章程,倷啊是真个要重建该页面。",
        "confirm_purge_button": "确定",
        "comma-separator": "、",
        "parentheses": "($1)",
        "autoredircomment": "重定向页面至[[$1]]",
        "autosumm-new": "新页面:“$1”",
        "watchlistedit-normal-title": "编辑监视列表",
+       "watchlistedit-normal-done": "{{PLURAL:$1|$1个}}标题已经从倷个关注表里向拿脱哉:",
+       "watchlistedit-raw-done": "侬个关注表已经更新。",
        "watchlistedit-raw-added": "$1个标题已经加进去哉:",
        "watchlistedit-raw-removed": "$1个标题已经拿脱哉:",
+       "watchlistedit-clear-legend": "清空关注表",
+       "watchlistedit-clear-submit": "清空关注表(永远!)",
+       "watchlisttools-clear": "清空关注表",
        "watchlisttools-view": "望相关修改",
        "watchlisttools-edit": "查看并编辑关注表",
        "watchlisttools-raw": "编写原始关注表",
        "revdelete-unrestricted": "已移除对管理员个限制",
        "logentry-block-block": "$1{{GENDER:$2|查封}}{{GENDER:$4|$3}},终止辰光为$5$6",
        "logentry-move-move": "$1{{GENDER:$2|捅荡}}页面$3到$4",
+       "logentry-move-move-noredirect": "$1{{GENDER:$2|捅荡}}页面$3到$4,弗留重定向",
        "logentry-newusers-create": "用户账号$1畀{{GENDER:$2|创建}}",
        "logentry-newusers-create2": "用户账号$3畀$1{{GENDER:$2|创建}}",
        "logentry-newusers-autocreate": "用户账号$1畀自动{{GENDER:$2|创建}}",
index 700d739..aed8ee5 100644 (file)
@@ -87,7 +87,8 @@
                        "Cdz",
                        "凡人丶",
                        "Nbdd0121",
-                       "Apflu"
+                       "Apflu",
+                       "飞舞回堂前"
                ]
        },
        "tog-underline": "链接下划线:",
        "databaseerror-function": "函数:$1",
        "databaseerror-error": "错误:$1",
        "transaction-duration-limit-exceeded": "因为写入时间($1)超过了$2{{PLURAL:$2|秒}}的限制,为防止创建大量复制延迟,此次处理已被中止。如果您正在同时更改很多项目,请尝试进行多次小规模操作。",
-       "laggedslavemode": "'''警告:'''页面中可能没有包含最近的更新。",
+       "laggedslavemode": "<strong>警告:</strong>页面中可能没有包含最近的更新。",
        "readonly": "数据库被锁定",
        "enterlockreason": "请输入锁定的原因,这包括预计解除锁定的时间",
        "readonlytext": "数据库当前被锁定,不能添加新条目或进行其他修改,锁定可能是因为例行的数据库维护,完成后即可恢复正常。\n\n锁定数据库的系统管理员做出如下解释:$1",
        "editinginterface": "<strong>警告:</strong>您正在编辑用于提供软件的界面文字的页面。改变此页将影响其他在此wiki上其他用户的用户界面外观。",
        "translateinterface": "要加入或更改所有wiki的翻译,请访问MediaWiki本地化项目网站[//translatewiki.net/ translatewiki.net]。",
        "cascadeprotected": "本页面已经受到保护,不能编辑,因为它被嵌入于以下被“连锁保护”的{{PLURAL:$1|页面}}:\n$2",
-       "namespaceprotected": "您没有权限编辑'''$1'''名字空间内的页面。",
+       "namespaceprotected": "您没有权限编辑<strong>$1</strong>名字空间内的页面。",
        "customcssprotected": "您没有权限编辑此CSS页面,因为它包含另一位用户的个人设置。",
        "customjsprotected": "您没有权限编辑此JavaScript页面,因为它包含另一位用户的个人设置。",
        "mycustomcssprotected": "您没有权限编辑这个 CSS 页面。",
        "mycustomjsprotected": "您没有权限编辑这个 JavaScript 页面。",
-       "myprivateinfoprotected": "你没有权限编辑你的私人信息。",
+       "myprivateinfoprotected": "您没有权限编辑您的私人信息。",
        "mypreferencesprotected": "您没有权限来编辑您的个人设置。",
        "ns-specialprotected": "特殊页面不可编辑。",
-       "titleprotected": "此标题已被[[User:$1|$1]]保护以防止创建。理由是“$2”。",
+       "titleprotected": "此标题已被[[User:$1|$1]]保护以防止创建。理由是“<em>$2</em>”。",
        "filereadonlyerror": "因为媒体库“$2”处于只读模式而无法修改文件“$1”。\n\n锁定数据库的系统管理员做出如下解释:“$3”。",
        "invalidtitle-knownnamespace": "使用名字空间“$2”和文本“$3”的无效标题",
        "invalidtitle-unknownnamespace": "使用未知名字空间编号$1和文本“$2”的无效标题",
        "exception-nologin": "未登录",
        "exception-nologin-text": "请登录以访问此页面或进行操作。",
        "exception-nologin-text-manual": "查看该页面或进行此操作需要您$1。",
-       "virus-badscanner": "错误的配置:未知的病毒扫描程序:''$1''",
+       "virus-badscanner": "错误的配置:未知的病毒扫描程序:<em>$1</em>",
        "virus-scanfailed": "扫描失败(代码 $1)",
        "virus-unknownscanner": "未知的反病毒软件:",
        "logouttext": "<strong>您现在已经退出登录。</strong>\n\n请注意一些页面可能仍然显示您处于登录状态,直到您清空浏览器缓存为止。",
        "cannotlogoutnow-title": "现在不能退出",
        "cannotlogoutnow-text": "当使用$1时无法退出。",
        "welcomeuser": "欢迎,$1!",
-       "welcomecreation-msg": "你的账户已创建。请不要忘记更改你的[[Special:Preferences|{{SITENAME}}设置]]。",
+       "welcomecreation-msg": "您的账户已创建。\n如果需要,您可以更改您在{{SITENAME}}的[[Special:Preferences|参数设置]]。",
        "yourname": "用户名:",
        "userlogin-yourname": "用户名",
        "userlogin-yourname-ph": "请输入你的用户名",
        "showpreview": "显示预览",
        "showdiff": "显示更改",
        "blankarticle": "<strong>警告</strong>:您创建的页面是空白的。如果您再次点击“{{int:savearticle}}”,您将真的创建没有任何内容的页面。",
-       "anoneditwarning": "<strong>警告:</strong>您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您<strong>[$1 登]</strong>或<strong>[$2 创建]</strong>一个账户,您的编辑将归属于您的用户名,且将享受其他好处。",
+       "anoneditwarning": "<strong>警告:</strong>您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您<strong>[$1 登]</strong>或<strong>[$2 创建]</strong>一个账户,您的编辑将归属于您的用户名,且将享受其他好处。",
        "anonpreviewwarning": "<em>您没有登录。保存将您的IP地址记录至此页面的编辑历史中。</em>",
-       "missingsummary": "'''提示:'''你没有提供编辑摘要。如果你再次点击“{{int:savearticle}}”,你的编辑将不带编辑摘要保存。",
+       "missingsummary": "<strong>提示:</strong>您没有提供编辑摘要。如果您再次点击“{{int:savearticle}}”,您的编辑将不带摘要保存。",
        "selfredirect": "<strong>警告:</strong>您正在将此页面重定向至它自己。\n您可能指定了错误的重定向目标,或者您正在编辑错误的页面。\n如果您再次点击“{{int:savearticle}}”,重定向将无论如何被创建。",
        "missingcommenttext": "请在下面输入评论。",
        "missingcommentheader": "<strong>提示:</strong>您还没有为此评论提供一个标题。如果您再次点击“{{int:savearticle}}”,您的编辑将不带标题保存。",
        "subject-preview": "主题预览:",
        "previewerrortext": "尝试预览您的更改时发生未知错误。",
        "blockedtitle": "用户被封禁",
-       "blockedtext": "<strong>你的用户名或IP地址已被封禁。</strong>\n\n执行封禁的管理员是$1。封禁原因是<em>$2</em>。\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n你可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当你在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。你当前的IP地址是$3,该封禁ID是#$5。请在你的询问中包含上面的所有信息。",
+       "blockedtext": "<strong>您的用户名或IP地址已被封禁。</strong>\n\n执行封禁的管理员是$1。封禁原因是<em>$2</em>。\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联络$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当您在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。您当前的IP地址是$3,该封禁ID是#$5。请在您的询问中包含上面的所有信息。",
        "autoblockedtext": "您的IP地址因曾被一位被$1封禁的用户使用而被自动封禁。封禁原因:\n\n:<em>$2</em>\n\n* 开始时间:$8\n* 到期时间:$6\n* 目标用户:$7\n\n您可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]申诉该封禁。\n\n请注意,只有当您已在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才能发送电子邮件联系管理员。\n\n您当前的IP地址为$3,该封禁ID为#$5。\n请您在申诉内容中说明以上所有信息。",
        "blockednoreason": "未给出原因",
        "whitelistedittext": "请$1以编辑页面。",
        "accmailtext": "为[[User talk:$1|$1]]随机生成的密码已送至$2。登录后可以在<em>[[Special:ChangePassword|更改密码]]</em>页面中修改。",
        "newarticle": "(新页面)",
        "newarticletext": "您点击了一个尚不存在的页面的链接。要创建该页面,请在下面的编辑框中输入内容(更多信息请见[$1 帮助页面])。如果您是错误地进入了此页面,请点击您的浏览器的<strong>返回</strong>按钮。",
-       "anontalkpagetext": "---- ''这是一个还未建立账户的匿名用户的讨论页, 因此我们只能用IP地址来与他或她联络。该IP地址可能由几名用户共享。如果您是一名匿名用户并认为此页上的评语与您无关,请[[Special:UserLogin/signup|创建新账户]]或[[Special:UserLogin|登录]]以避免在未来与其他匿名用户混淆。''",
-       "noarticletext": "本页面目前没有内容。可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页面]。</span>",
-       "noarticletext-nopermission": "本页面目前没有内容。你可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]或<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]</span>,但你没有权限创建本页面。",
+       "anontalkpagetext": "----\n<em>这是一个还未建立账户的匿名用户的讨论页, 因此我们只能用IP地址来与他或她联络。</em>该IP地址可能由几名用户共享。如果您是一名匿名用户并认为此页上的评语与您无关,请[[Special:UserLogin/signup|创建新账户]]或[[Special:UserLogin|登录]]以避免在未来与其他匿名用户混淆。",
+       "noarticletext": "本页面目前没有内容。可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页面]。</span>",
+       "noarticletext-nopermission": "本页面目前没有内容。您可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索本页标题]]或<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]</span>,但您没有权限创建本页面。",
        "missing-revision": "“{{FULLPAGENAME}}”的版本#$1不存在。\n\n这通常是因为进入了一个已被删除的页面的历史链接。\n详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。",
        "userpage-userdoesnotexist": "用户账户“$1”没有注册。请在创建/编辑本页前检查。",
        "userpage-userdoesnotexist-view": "用户账户“$1”没有被注册。",
        "clearyourcache": "<strong>注意:</strong>在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。\n* <strong>Firefox或Safari:</strong>按住“Shift”的同时单击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)\n* <strong>Google Chrome:</strong>按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)\n* <strong>Internet Explorer:</strong>按住“Ctrl”的同时单击“刷新”,或按“Ctrl-F5”\n* <strong>Opera:</strong>在“工具→首选项”中清除缓存",
        "usercssyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
        "userjsyoucanpreview": "<strong>提示:</strong>在保存前请用“{{int:showpreview}}”按钮来测试您新的 JavaScript 。",
-       "usercsspreview": "'''请记住你现在只是在预览你的用户CSS。它尚未保存!'''",
-       "userjspreview": "'''请记住你现在只是在测试/预览你的用户JavaScript。它尚未保存!'''",
-       "sitecsspreview": "'''请记住你现在只是在预览该CSS。它尚未保存!'''",
-       "sitejspreview": "'''请记住你现在只是在预览该JavaScript代码。它尚未保存!'''",
+       "usercsspreview": "<strong>请记住您现在只是在预览你的用户CSS。它尚未保存!</strong>",
+       "userjspreview": "<strong>请记住你现在只是在测试/预览你的用户JavaScript。它尚未保存!</strong>",
+       "sitecsspreview": "<strong>请记住你现在只是在预览该CSS。它尚未保存!</strong>",
+       "sitejspreview": "<strong>请记住你现在只是在预览该JavaScript代码。它尚未保存!</strong>",
        "userinvalidcssjstitle": "<strong>警告:</strong>不存在皮肤“$1”。注意自定义的 .css 和 .js 页要使用小写标题,例如,{{ns:user}}:Foo/vector.css 不同于 {{ns:user}}:Foo/Vector.css。",
        "updated": "(已更新)",
-       "note": "'''注意:'''",
-       "previewnote": "'''请记住这只是预览。'''你的更改还没有保存!",
+       "note": "<strong>注意:</strong>",
+       "previewnote": "<strong>请记住这只是预览。</strong>\n您的更改还没有保存!",
        "continue-editing": "前往编辑区",
        "previewconflict": "该预览反映了上面文字编辑区中的文字在你保存后的显示状况。",
-       "session_fail_preview": "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''请重试。如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
-       "session_fail_preview_html": "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''\n\n''因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。''\n\n'''如果该编辑尝试合法,请重试。'''如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
+       "session_fail_preview": "<strong>对不起!由于会话数据丢失,我们无法处理您的编辑。</strong>\n请重试。如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
+       "session_fail_preview_html": "<strong>对不起!由于会话数据丢失,我们无法处理您的编辑。</strong>\n\n<em>因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。</em>\n\n<strong>如果该编辑尝试合法,请重试。</strong>如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
        "token_suffix_mismatch": "<strong>由于您客户端中的编辑令牌毁损了一些标点符号字符,您的编辑已经被拒绝。</strong>\n此次编辑被拒绝以防止页面文本损坏。\n这种情况通常在您使用含有故障的网页式匿名代理服务的时候出现。",
-       "edit_form_incomplete": "'''编辑表格的某些部分没有到达服务器,请检查你的编辑是否完整并重试。'''",
+       "edit_form_incomplete": "<strong>编辑表格的某些部分没有到达服务器,请检查您的编辑是否完整并重试。</strong>",
        "editing": "编辑“$1”",
        "creating": "创建“$1”",
        "editingsection": "编辑“$1(段落)”",
        "explainconflict": "其他用户在你开始编辑后更改了该页面。上面的文字区含有该页面当前的文字。下面的文字区显示你的更改。你必须把你的更改合并至现有文字。'''只有'''当你单击“{{int:savearticle}}”后,上面的文字区中的文字才会被保存。",
        "yourtext": "您的文字",
        "storedversion": "已保存的版本",
-       "nonunicodebrowser": "'''警告:您的浏览器不兼容Unicode编码。'''这里有一个工作区将使您能安全地编辑页面:非ASCII字符将以十六进制编码方式出现在编辑框中。",
-       "editingold": "'''警告:你正在编辑的是本页面的旧版本。'''如果你保存该编辑,该版本后的所有更改都会丢失。",
+       "nonunicodebrowser": "<strong>警告:您的浏览器不兼容Unicode编码。</strong>这里有一个工作区将使您能安全地编辑页面:非ASCII字符将以十六进制编码方式出现在编辑框中。",
+       "editingold": "<strong>警告:您正在编辑的是本页面的旧版本。</strong>如果您保存该编辑,该版本后的所有更改都会丢失。",
        "yourdiff": "差异",
        "copyrightwarning": "请注意您对{{SITENAME}}的所有贡献都被认为是在$2下发布,请查看在$1的细节。\n如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源。\n'''不要在未获授权的情况下发表!'''<br />",
-       "copyrightwarning2": "请注意,您对{{SITENAME}}的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅$1的细节)。'''不要在未获授权的情况下发表!'''",
+       "copyrightwarning2": "请注意,您对{{SITENAME}}的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅$1的细节)。<strong>不要在未获授权的情况下发表!</strong>",
        "editpage-cannot-use-custom-model": "此页面的内容模型不能被更改。",
-       "longpageerror": "'''错误:您所提交的文本长度有{{PLURAL:$1|1|$1}}KB,这大于{{PLURAL:$2|1|$2}}KB的最大值。'''\n因此,该文本无法保存。",
+       "longpageerror": "<strong>错误:您所提交的文本长度有{{PLURAL:$1|1|$1}}KB,这大于{{PLURAL:$2|1|$2}}KB的最大值。</strong>\n因此,该文本无法保存。",
        "readonlywarning": "<strong>警告:数据库被锁定以进行维护,所以您目前将无法保存您的编辑。</strong>您可以将您的文本复制粘贴到一个文本文档并保存它,以便稍后更改。\n\n锁定数据库的系统管理员做出如下解释:$1",
-       "protectedpagewarning": "'''警告:本页面已被保护,只有拥有管理员权限的用户可以编辑。'''下面提供最后的日志条目以供参考:",
-       "semiprotectedpagewarning": "'''注意:'''本页面已被保护,只有注册用户可以编辑。下面提供最后的日志条目以供参考:",
+       "protectedpagewarning": "<strong>警告:本页面已被保护,只有拥有管理员权限的用户可以编辑。</strong>下面提供最后的日志条目以供参考:",
+       "semiprotectedpagewarning": "<strong>注意:</strong>本页面已被保护,只有注册用户可以编辑。下面提供最后的日志条目以供参考:",
        "cascadeprotectedwarning": "<strong>警告:</strong>本页面已经被保护,只有拥有管理员权限的用户可以编辑,因为它被嵌入于以下启用连锁保护的{{PLURAL:$1|页面}}中:",
-       "titleprotectedwarning": "'''警告:本页面已被保护,创建本页面需要[[Special:ListGroupRights|特定权限]]。'''下面提供最后的日志条目以供参考:",
+       "titleprotectedwarning": "<strong>警告:本页面已被保护,创建本页面需要[[Special:ListGroupRights|特定权限]]。</strong>下面提供最后的日志条目以供参考:",
        "templatesused": "该页面使用的{{PLURAL:$1|模板}}:",
        "templatesusedpreview": "本预览使用的{{PLURAL:$1|模板}}:",
        "templatesusedsection": "该段落使用的{{PLURAL:$1|模板}}:",
        "template-semiprotected": "(受半保护)",
        "hiddencategories": "该页面属于$1个隐藏分类:",
        "edittools": "<!-- 这里的文字将显示在编辑和上传表格下面。 -->",
-       "nocreatetext": "{{SITENAME}}已经限制创建新页面功能。可以返回编辑现有页面或[[Special:UserLogin|登录或创建账户]]。",
-       "nocreate-loggedin": "没有权限创建新页面。",
+       "nocreatetext": "{{SITENAME}}已经限制创建新页面功能。可以返回编辑现有页面或[[Special:UserLogin|登录或创建账户]]。",
+       "nocreate-loggedin": "没有权限创建新页面。",
        "sectioneditnotsupported-title": "段落编辑不支持",
        "sectioneditnotsupported-text": "本页面不支持段落编辑。",
        "permissionserrors": "权限错误",
-       "permissionserrorstext": "因为以下{{PLURAL:$1|原因}},你没有权限进行该操作:",
-       "permissionserrorstext-withaction": "因为以下{{PLURAL:$1|原因}},没有权限$2:",
+       "permissionserrorstext": "因为以下{{PLURAL:$1|原因}},您没有权限这样做:",
+       "permissionserrorstext-withaction": "因为以下{{PLURAL:$1|原因}},没有权限$2:",
        "contentmodelediterror": "您不能编辑此修订版本,因为它的内容模型是<code>$1</code>,这与当前页面<code>$2</code>的内容模型不同。",
-       "recreate-moveddeleted-warn": "'''警告:你正在重新创建曾经被删除的页面。'''\n\n你应该考虑继续编辑本页是否合适。这里提供本页的删除和移动日志以供参考:",
+       "recreate-moveddeleted-warn": "<strong>警告:您正在重新创建曾经被删除的页面。</strong>\n\n您应该考虑继续编辑本页是否合适。这里提供本页的删除和移动日志以供参考:",
        "moveddeleted-notice": "本页面已被删除。下面提供本页的删除和移动日志以供参考。",
        "moveddeleted-notice-recent": "抱歉,此页面刚刚被删除(在最近24小时内)。\n页面的删除和移动日志在下方提供以供参考。",
        "log-fulllog": "查看完整日志",
        "edit-hook-aborted": "编辑被hook指令取消。\n无解释。",
        "edit-gone-missing": "不能更新页面。\n它可能刚刚被删除。",
        "edit-conflict": "编辑冲突。",
-       "edit-no-change": "因为没有文字更改,的编辑已被忽略。",
+       "edit-no-change": "因为没有文字更改,的编辑已被忽略。",
        "postedit-confirmation-created": "页面已创建。",
        "postedit-confirmation-restored": "页面已恢复。",
-       "postedit-confirmation-saved": "的编辑已保存。",
+       "postedit-confirmation-saved": "的编辑已保存。",
        "edit-already-exists": "不可以建立一个新页面。\n它已经存在。",
        "defaultmessagetext": "默认消息文本",
        "content-failed-to-parse": "未能将 $2 内容转换为 $1:$3",
        "invalid-content-data": "无效的内容数据",
        "content-not-allowed-here": "[[$2]]页面上不允许“$1”内容",
-       "editwarning-warning": "离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“{{int:prefs-editing}}”部分停用该警告。",
+       "editwarning-warning": "离开本页面可能导致您失去任何你已经作出的更改。如果您处于登录状态,您可以在您的设置的“{{int:prefs-editing}}”部分停用该警告。",
        "editpage-notsupportedcontentformat-title": "内容格式尚不支持",
        "editpage-notsupportedcontentformat-text": "内容模型$2尚不支持内容格式$1。",
        "content-model-wikitext": "维基文字",
        "duplicate-args-warning": "<strong>警告:</strong>[[:$1]]正在调用超过一个[[:$2]]中“$3”参数的值。只有最后提供的值会被使用。",
        "duplicate-args-category": "调用重复模板参数的页面",
        "duplicate-args-category-desc": "页面包含调用了重复参数的模板,例如<code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code>或<code><nowiki>{{foo|bar|1=baz}}</nowiki></code>。",
-       "expensive-parserfunction-warning": "<strong>警告:</strong>这个页面有太多高昂的语法功能调用。\n\n它应该少过$2次呼叫,现在有$1次呼叫。",
+       "expensive-parserfunction-warning": "<strong>警告:</strong>这个页面有太多高开销解析器函数调用。\n\n它应少于$2次{{PLURAL:$2|调用}},而目前有{{PLURAL:$1|$1次调用}}。",
        "expensive-parserfunction-category": "有过多高开销解析器函数调用的页面",
-       "post-expand-template-inclusion-warning": "'''警告:'''包含模板大小过大。\n一些模板将不会包含。",
+       "post-expand-template-inclusion-warning": "<strong>警告:</strong>包含模板大小过大。\n一些模板将不会包含。",
        "post-expand-template-inclusion-category": "模板包含上限已经超过的页面",
        "post-expand-template-argument-warning": "<strong>警告:</strong>本页面包含至少一个模板参数有过大扩展大小。这些参数会被略过。",
        "post-expand-template-argument-category": "含有略过模板参数的页面",
        "expansion-depth-exceeded-category": "扩展深度超出限制的页面",
        "expansion-depth-exceeded-category-desc": "页面超出最大展开深度限制。",
        "expansion-depth-exceeded-warning": "页面超出展开深度限制",
-       "parser-unstrip-loop-warning": "检测到回圈",
-       "parser-unstrip-recursion-limit": "递归超过限制 ($1)",
+       "parser-unstrip-loop-warning": "检测到Unstrip循环",
+       "parser-unstrip-recursion-limit": "已超出Unstrip递归限制($1)",
        "converter-manual-rule-error": "在手动语言转换规则中检测到错误",
-       "undo-success": "该编辑可以被撤销。请检查下面的对比以核实想要撤销的内容,然后保存下面的更改以完成撤销。",
+       "undo-success": "该编辑可以被撤销。请检查下面的对比以核实想要撤销的内容,然后保存下面的更改以完成撤销。",
        "undo-failure": "因存在冲突的中间编辑,本编辑不能撤销。",
        "undo-norev": "该编辑无法撤消,因为它不存在或已被删除。",
        "undo-nochange": "这次编辑似乎已被撤销。",
        "rev-deleted-user": "(用户名被删除)",
        "rev-deleted-event": "(日志详情已移除)",
        "rev-deleted-user-contribs": "[用户名或IP地址被删除 - 编辑在贡献中隐藏]",
-       "rev-deleted-text-permission": "本页面版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+       "rev-deleted-text-permission": "本页面版本已被<strong>删除</strong>。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
        "rev-suppressed-text-permission": "此页面修订已经被<strong>监督隐藏</strong>。详细信息可在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中找到。",
-       "rev-deleted-text-unhide": "本页面版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。如果你想继续操作,你仍然可以[$1 查看本版本]。",
-       "rev-suppressed-text-unhide": "该页面版本已经被'''监督隐藏'''。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。如果您想继续的话,您可以仍然[$1 去查看这次版本]。",
-       "rev-deleted-text-view": "本页面版本已被'''删除'''。你可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
-       "rev-suppressed-text-view": "该页面版本已经被'''监督隐藏'''。您可以查看它。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。",
-       "rev-deleted-no-diff": "你不能查看该差异,因为其中一个版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+       "rev-deleted-text-unhide": "本页面版本已被<strong>删除</strong>。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。如果您想继续操作,您仍然可以[$1 查看本版本]。",
+       "rev-suppressed-text-unhide": "该页面版本已经被<strong>监督隐藏</strong>。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。如果您想继续的话,您可以仍然[$1 去查看这次版本]。",
+       "rev-deleted-text-view": "本页面版本已被<strong>删除</strong>。您可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+       "rev-suppressed-text-view": "该页面版本已经被<strong>监督隐藏</strong>。您可以查看它。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。",
+       "rev-deleted-no-diff": "您不能查看该差异,因为其中一个版本已被<strong>删除</strong>。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
        "rev-suppressed-no-diff": "无法查看该差异,因为其中一个版本已被<strong>删除<strong>。",
        "rev-deleted-unhide-diff": "该差异对比的其中的一个版本已经被<strong>删除</strong>。在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中可以找到更多的信息。如果您想继续的话,您仍然可以[$1 查看此版本]。",
        "rev-suppressed-unhide-diff": "该页面的其中一次版本已经被<strong>监督隐藏</strong>。\n在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到更多的资料。如果您想继续的话,您可以仍然[$1 去查看这版本]。",
        "logdelete-text": "已删除日志事件仍将在日志中显示,但涉及部分的内容将对公众不可见。",
        "revdelete-text-others": "其他管理员仍将可以访问隐藏内容并删除它,除非附加条件被设定。",
        "revdelete-confirm": "请确认该操作,明白其后果,并确保该操作符合[[{{MediaWiki:Policy-url}}|方针]]。",
-       "revdelete-suppress-text": "阻止应'''仅'''用于以下情况:\n* 潜在的诽谤信息\n* 不合适的个人信息\n*: ''家庭地址、电话号码和社保号码等。''",
+       "revdelete-suppress-text": "阻止应<strong>仅</strong>用于以下情况:\n* 潜在的诽谤信息\n* 不合适的个人信息\n*: <em>家庭地址、电话号码和社保号码等。</em>",
        "revdelete-legend": "设置可见性之限制",
        "revdelete-hide-text": "版本文字",
        "revdelete-hide-image": "隐藏文件内容",
        "revdelete-submit": "应用于选中的{{PLURAL:$1|版本}}",
        "revdelete-success": "版本可见性更新成功。",
        "revdelete-failure": "版本可见性无法更新:\n$1",
-       "logdelete-success": "'''事件的可见性已经成功设置。'''",
-       "logdelete-failure": "'''事件的可见性无法设置:'''\n$1",
+       "logdelete-success": "事件的可见性已经成功设置。",
+       "logdelete-failure": "事件的可见性无法设置:\n$1",
        "revdel-restore": "更改可见性",
        "pagehist": "页面历史",
        "deletedhist": "已删除历史",
        "revdelete-show-no-access": "正在显示于$1 $2之项目错误:这个项目已经标示为\"已限制\",您对它并无通行权。",
        "revdelete-modify-no-access": "正在更改于$1 $2之项目错误:这个项目已经标示为\"已限制\",您对它并无通行权。",
        "revdelete-modify-missing": "正在更改项目ID $1错误:它在资料库中遗失!",
-       "revdelete-no-change": "警告:于$1 $2之项目已经请求了可见性的设置。",
+       "revdelete-no-change": "<strong>警告:</strong>于$1 $2之项目已经请求了可见性的设置。",
        "revdelete-concurrent-change": "正在更改于$1 $2之项目错误:当我们尝试更改它的设置时,已经被另一些人更改过。请检查纪录。",
        "revdelete-only-restricted": "在隐藏$1 $2的项目时发生错误:您不能在选择了另一可见性选项后废止管理员查看该项目。",
        "revdelete-reason-dropdown": "*常用删除理由\n** 侵犯版权\n** 不适当的评论或个人信息\n** 不适当的用户名\n** 潜在毁谤性信息",
        "nextn-title": "后$1个结果",
        "shown-title": "每页显示$1项结果",
        "viewprevnext": "查看($1{{int:pipe-separator}}$2)($3)",
-       "searchmenu-exists": "'''本wiki上有名为“[[:$1]]”的页面。'''",
+       "searchmenu-exists": "<strong>本wiki上有名为“[[:$1]]”的页面。</strong>{{PLURAL:$2|0=|另请查看找到的其他搜索结果。}}",
        "searchmenu-new": "<strong>在本Wiki上新建名为“[[:$1]]”的页面!</strong>{{PLURAL:$2|0=|另请查看您的搜索找的结果。|另请查看搜索结果。}}",
        "searchprofile-articles": "内容页面",
        "searchprofile-images": "多媒体",
        "search-relatedarticle": "相关",
        "searchrelated": "相关",
        "searchall": "所有",
-       "showingresults": "下面显示从第'''$2'''条结果开始的'''$1'''条结果。",
+       "showingresults": "下面显示从第<strong>$2</strong>条结果开始的<strong>$1</strong>条结果。",
        "showingresultsinrange": "下面显示区间#<strong>$2</strong>至#<strong>$3</strong>的<strong>$1</strong>条结果。",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong>条结果中的<strong>$1</strong>条|<strong>$3</strong>条结果中的<strong>$1~$2</strong>条}}",
        "search-nonefound": "找不到和查询相匹配的结果。",
        "saveusergroups": "保存{{GENDER:$1|用户}}组",
        "userrights-groupsmember": "用户组:",
        "userrights-groupsmember-auto": "自动用户组:",
-       "userrights-groups-help": "可以更改该用户的用户组:\n* 选中的选项框表示该用户属于该用户组。\n* 未选中的选项框表示该用户不属于该用户组。\n* 星号(*)表示一旦添加该用户组后不能删除,反之亦然。",
+       "userrights-groups-help": "可以更改该用户的用户组:\n* 选中的选项框表示该用户属于该用户组。\n* 未选中的选项框表示该用户不属于该用户组。\n* 星号(*)表示一旦添加该用户组后不能删除,反之亦然。",
        "userrights-reason": "原因:",
        "userrights-no-interwiki": "您并没有权限去编辑在其它wiki上的用户权限。",
        "userrights-nodatabase": "数据库$1不存在或并非为本地的。",
        "userrights-nologin": "您必须要以管理员帐户[[Special:UserLogin|登录]]之后才可以指定用户权限。",
-       "userrights-notallowed": "没有权限添加或删除用户权限。",
-       "userrights-changeable-col": "可以更改的用户组",
-       "userrights-unchangeable-col": "不能更改的用户组",
+       "userrights-notallowed": "没有权限添加或删除用户权限。",
+       "userrights-changeable-col": "可以更改的用户组",
+       "userrights-unchangeable-col": "不能更改的用户组",
        "userrights-conflict": "用户权限的更改存在冲突!请检查并确认您的更改。",
        "userrights-removed-self": "您已成功删除您自己的权利。因此,您不再能够访问此页。",
        "group": "用户组:",
        "group-suppress": "Flow监督员",
        "group-all": "(所有)",
        "group-user-member": "{{GENDER:$1|用户}}",
-       "group-autoconfirmed-member": "自动确认用户",
-       "group-bot-member": "机器人",
+       "group-autoconfirmed-member": "{{GENDER:$1|自动确认用户}}",
+       "group-bot-member": "{{GENDER:$1|机器人}}",
        "group-sysop-member": "{{GENDER:$1|管理员}}",
-       "group-bureaucrat-member": "行政员",
+       "group-bureaucrat-member": "{{GENDER:$1|行政员}}",
        "group-suppress-member": "{{GENDER:$1|Flow监督员}}",
        "grouppage-user": "{{ns:project}}:用户",
        "grouppage-autoconfirmed": "{{ns:project}}:自动确认用户",
        "upload_directory_missing": "上传目录($1)遗失,不能由网页服务器建立。",
        "upload_directory_read_only": "上传目录($1)不存在或无写权限。",
        "uploaderror": "上传出错",
-       "upload-recreate-warning": "'''警告:一个相同名字的文件曾经被删除或者移动至别处。'''\n\n这个页面的删除和移动日志在这里提供以便参考:",
+       "upload-recreate-warning": "<strong>警告:一个相同名字的文件曾经被删除或者移动至别处。</strong>\n\n这个页面的删除和移动日志在这里提供以便参考:",
        "uploadtext": "请使用下面的表格上传文件。要查看或搜索以往上传的文件,请前往[[Special:FileList|上传的文件的列表]],(重新)上传也将记录在[[Special:Log/upload|上传日志]]中,删除将记录在[[Special:Log/delete|删除日志]]中。\n\n要在页面中包含文件,请使用一种以下形式的链接:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong>使用文件的完整版本\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|替代文字]]</nowiki></code></strong>使用位于页面左边的框内的200像素宽的图片,以“替代文字”作为说明\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong>直接链接到文件而不显示文件",
        "upload-permitted": "允许的文件{{PLURAL:$2|类型}}:$1。",
        "upload-preferred": "建议的文件{{PLURAL:$2|类型}}:$1。",
        "filetype-mime-mismatch": "文件扩展名“.$1”与检测到的文件MIME类型($2)不匹配。",
        "filetype-badmime": "“$1”类型的文件已被禁止上传。",
        "filetype-bad-ie-mime": "无法上传该文件,因为Internet Explorer会将它检测为“$1”,这是一种禁止且带有潜在危险的文件类型。",
-       "filetype-unwanted-type": "'''“.$1”'''是一种不需要的文件类型。\n建议的{{PLURAL:$3|一种|多种}}文件类型有$2。",
-       "filetype-banned-type": "'''\".$1\"'''{{PLURAL:$4|不是一个允许的文件类型|不是一个允许的文件类型}}。\n允许 {{PLURAL:$3|文件类型是}} $2。",
+       "filetype-unwanted-type": "<strong>“.$1”</strong>是一种不需要的文件类型。\n建议的{{PLURAL:$3|一种|多种}}文件类型有$2。",
+       "filetype-banned-type": "<strong>“.$1”</strong>{{PLURAL:$4|不是允许的文件类型}}。\n允许的{{PLURAL:$3|文件类型是}}$2。",
        "filetype-missing": "该文件名称并没有扩展名(例如“.jpg”)。",
        "empty-file": "您所提交的文件为空文件。",
        "file-too-large": "您所提交的文件过大。",
        "filename-tooshort": "文件名过短。",
        "filetype-banned": "此类文件被禁止。",
        "verification-error": "文件未通过验证。",
-       "hookaborted": "尝试的修改被扩展程序中止。",
+       "hookaborted": "尝试的修改被扩展程序中止。",
        "illegal-filename": "文件名非法。",
        "overwrite": "不允许覆盖现有文件。",
        "unknown-error": "发生未知错误。",
        "largefileserver": "这个文件的大小比服务器配置允许的大小还要大。",
        "emptyfile": "您所上传的文件不存在。这可能是由于文件名键入错误。请检查您是否真的要上传此文件。",
        "windows-nonascii-filename": "本wiki不支持在文件名中使用特殊字符。",
-       "fileexists": "已存在相同名称的文件,如果您无法确定您是否要改变它,请检查<strong><strong>[[:$1]]</strong></strong>。 [[$1|thumb]]",
-       "filepageexists": "该文件的说明页面已经创建于<strong>[[:$1]]</strong>,但是目前没有名称为此的文件存在。你输入的摘要不会显示在说明页面上。要使你的摘要在那里显示,你需要手工编辑它。[[$1|thumb]]",
+       "fileexists": "已存在相同名称的文件,如果您无法确定您是否要改变它,请检查<strong>[[:$1]]</strong>。 [[$1|thumb]]",
+       "filepageexists": "该文件的说明页面已经创建于<strong>[[:$1]]</strong>,但是目前没有名称为此的文件存在。您输入的摘要不会显示在说明页面上。要使你的摘要在那里显示,您需要手工编辑它。[[$1|thumb]]",
        "fileexists-extension": "一个相似名称的文件已经存在: [[$2|thumb]]\n* 上传文件的文件名:<strong>[[:$1]]</strong>\n* 现有文件的文件名:<strong>[[:$2]]</strong>\n请选择一个不同的名字。",
-       "fileexists-thumbnail-yes": "此文件可能是另一幅图像的缩小版本''(缩略图)''。 [[$1|thumb]]\n请仔细检查该文件<strong>[[:$1]]</strong>。\n如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
-       "file-thumbnail-no": "文件名以<strong>$1</strong>开始。它似乎是缩小的图像''(缩略图)''。如果你有完整分辨率的该图像,请上传它,否则请更改文件名。",
+       "fileexists-thumbnail-yes": "此文件可能是另一幅图像的缩小版本<em>(缩略图)</em>。 [[$1|thumb]]\n请仔细检查该文件<strong>[[:$1]]</strong>。\n如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
+       "file-thumbnail-no": "文件名以<strong>$1</strong>开始。它似乎是缩小的图像<em>(缩略图)</em>。如果您有完整分辨率的该图像,请上传它,否则请更改文件名。",
        "fileexists-forbidden": "已存在相同名称的文件,且不能覆盖;请返回并用一个新的名称来上传此文件。[[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "共享文件库中存在该名称的文件。如果仍想上传你的文件,请返回使用其他名称。[[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "共享文件库中存在该名称的文件。如果仍想上传你的文件,请返回使用其他名称。[[File:$1|thumb|center|$1]]",
        "file-exists-duplicate": "本文件是以下{{PLURAL:$1|文件}}的副本:",
        "file-deleted-duplicate": "一个相同名称的文件 ([[:$1]]) 在先前删除过。您应该在重新上传之前检查一下该文件之删除纪录。",
        "file-deleted-duplicate-notitle": "之前有与此相同的文件被删除和取消标题。您应该询问查看过改文件数据的任何人以复查重新上传时的诸多问题。",
        "uploaded-script-svg": "在上传的SVG文件中找到可编写脚本的元素“$1”。",
        "uploaded-hostile-svg": "在上传的SVG文件中的样式元素中找到不安全CSS。",
        "uploaded-event-handler-on-svg": "在SVG文件中不允许设置event-handler属性<code>$1=\"$2\"</code>。",
-       "uploaded-href-attribute-svg": "在SVG文件中不允许href属性<code>&lt;$1 $2=\"$3\"&gt;</code>带非本地目标(例如http://、javascript:等)。",
-       "uploaded-href-unsafe-target-svg": "在上传的SVG文件中找到href至不安全目标<code>&lt;$1 $2=\"$3\"&gt;</code>。",
+       "uploaded-href-attribute-svg": "SVG文件中的href属性只允许链接至http://或https://目标,已找到<code>&lt;$1 $2=\"$3\"&gt;</code>。",
+       "uploaded-href-unsafe-target-svg": "在上传的SVG文件中找到了至不安全数据的href:URI目标<code>&lt;$1 $2=\"$3\"&gt;</code>。",
        "uploaded-animate-svg": "在上传的SVG文件找到“animate”标签,它可能会更改href,使用“from”属性<code>&lt;$1 $2=\"$3\"&gt;</code>。",
        "uploaded-setting-event-handler-svg": "设置event-handler属性时受阻,在上传的SVG文件中找到<code>&lt;$1 $2=\"$3\"&gt;</code>。",
        "uploaded-setting-href-svg": "使用“set”标签加入“href”属性至父元素时受阻。",
        "uploaded-setting-handler-svg": "通过远程/数据/脚本设置“handler”属性的SVG时受阻。在上传的SVG文件中找到<code>$1=\"$2\"</code>。",
        "uploaded-remote-url-svg": "通过远程URL设置任意样式属性的SVG时受阻。在上传的SVG文件中找到<code>$1=\"$2\"</code>。",
        "uploaded-image-filter-svg": "在上传的SVG文件中找到图片过滤器带URL:<code>&lt;$1 $2=\"$3\"&gt;</code>。",
-       "uploadscriptednamespace": "此SVG文件包含非法名字空间“$1”",
+       "uploadscriptednamespace": "此SVG文件包含非法名字空间“$1”",
        "uploadinvalidxml": "上传文件中的XML无法解析。",
        "uploadvirus": "该文件包含病毒!\n详情:$1",
        "uploadjava": "该文件是 ZIP 文件,其中包含 Java 的.class 文件。上传Java文件不被允许,因为它们可能绕过限制,从而引起安全问题。",
        "backend-fail-closetemp": "无法创建临时文件。",
        "backend-fail-read": "找不到文件“$1”。",
        "backend-fail-create": "无法写入文件 $1 。",
-       "backend-fail-maxsize": "无法写入文件 $1,因为它大于$2字节。",
-       "backend-fail-readonly": "“$1”存储后端目前在只读模式,因为:“$2”",
+       "backend-fail-maxsize": "无法写入文件“$1”,因为它大于$2字节。",
+       "backend-fail-readonly": "“$1”存储后端目前在只读模式,因为:“<em>$2</em>”",
        "backend-fail-synced": "文件\"$1\"在内部存储后端之中处于不一致状态",
        "backend-fail-connect": "无法连接到存储后端“$1。",
        "backend-fail-internal": "存储后端“$1”发生了一个未知错误。",
        "uploadstash": "上传隐藏",
        "uploadstash-summary": "这个页面提供已经上传(或者上传中)但未发布到wiki之文件存取。这些文件除了上传的用户之外不会被其他人可见。",
        "uploadstash-clear": "清除贮藏文件",
-       "uploadstash-nofiles": "没有被隐藏的文件。",
+       "uploadstash-nofiles": "没有被隐藏的文件。",
        "uploadstash-badtoken": "该操作执行失败,可能是因为你的编辑凭证已过期。请重试。",
        "uploadstash-errclear": "清除文件不成功。",
        "uploadstash-refresh": "更新文件列表",
        "upload-disallowed-here": "您不可以覆盖此文件。",
        "filerevert": "恢复$1",
        "filerevert-legend": "恢复文件",
-       "filerevert-intro": "你将要恢复文件'''[[Media:$1|$1]]'''至[$4 $2 $3的版本]。",
+       "filerevert-intro": "您将要恢复文件<strong>[[Media:$1|$1]]</strong>至[$4 $2 $3的版本]。",
        "filerevert-comment": "原因:",
        "filerevert-defaultcomment": "回退至$1 $2($3)的版本",
        "filerevert-submit": "恢复",
        "filerevert-badversion": "文件并无所请求时间戳下的早期本地版本。",
        "filedelete": "删除$1",
        "filedelete-legend": "删除文件",
-       "filedelete-intro": "你将要删除文件'''[[Media:$1|$1]]'''及其全部历史。",
-       "filedelete-intro-old": "你正在删除'''[[Media:$1|$1]]'''[$4 $2$3]的版本。",
+       "filedelete-intro": "您将要删除文件<strong>[[Media:$1|$1]]</strong>及其全部历史。",
+       "filedelete-intro-old": "你正在删除<strong>[[Media:$1|$1]]</strong>[$4 $2$3]的版本。",
        "filedelete-comment": "原因:",
        "filedelete-submit": "删除",
-       "filedelete-success": "'''$1'''已经删除。",
-       "filedelete-success-old": "'''[[Media:$1|$1]]'''于 $2 $3 的版本已经删除。",
-       "filedelete-nofile": "'''$1'''不存在。",
-       "filedelete-nofile-old": "在已指定属性的情况下,这里没有'''$1'''的保存版本。",
+       "filedelete-success": "<strong>$1</strong>已经删除。",
+       "filedelete-success-old": "<strong>[[Media:$1|$1]]</strong> 于 $2 $3 的版本已经删除。",
+       "filedelete-nofile": "<strong>$1</strong>不存在。",
+       "filedelete-nofile-old": "在已指定属性的情况下,这里没有<strong>$1</strong>的保存版本。",
        "filedelete-otherreason": "其他/附加原因:",
        "filedelete-reason-otherlist": "其他原因",
-       "filedelete-reason-dropdown": "\n*常用删除理由\n** 侵犯版权\n** 重复文件",
+       "filedelete-reason-dropdown": "*常用删除理由\n** 侵犯版权\n** 重复文件",
        "filedelete-edit-reasonlist": "编辑删除原因",
        "filedelete-maintenance": "维护期间文件删除和恢复暂时停用。",
        "filedelete-maintenance-title": "无法删除文件",
        "randompage-nopages": "在以下{{PLURAL:$2|名字空间}}中没有页面:$1。",
        "randomincategory": "分类中随机页面",
        "randomincategory-invalidcategory": "“$1”不是一个有效的分类名称。",
-       "randomincategory-nopages": "[[:Category:$1]]中没有页面。",
+       "randomincategory-nopages": "[[:Category:$1|$1]]分类中没有页面。",
        "randomincategory-category": "分类:",
-       "randomincategory-legend": "分中随机页面",
+       "randomincategory-legend": "分中随机页面",
        "randomincategory-submit": "提交",
        "randomredirect": "随机重定向",
        "randomredirect-nopages": "“$1”名字空间中没有重定向。",
        "querypage-disabled": "本特殊页面因性能问题而停用。",
        "apihelp": "API 帮助",
        "apihelp-no-such-module": "找不到模块“$1”。",
+       "apisandbox": "API 沙盒",
+       "apisandbox-jsonly": "需要JavaScript以使用API沙盒。",
+       "apisandbox-api-disabled": "API在该网站停用。",
+       "apisandbox-intro": "使用这个页面来试验<strong>MediaWiki Web 服务应用程序接口(API)</strong>。\n欲知API使用详情,请参阅[[mw:API:Main page|API文档]]。\n例如:[//www.mediawiki.org/wiki/API#A_simple_example 取得某个主页的内容],然后选择一个操作来看更多范例。\n\n请注意,虽然这是一个沙盒,但是你在这个页面上的改动可能会修改维基。",
+       "apisandbox-fullscreen": "展开面板",
+       "apisandbox-fullscreen-tooltip": "展开沙盒面板以填充浏览器窗口。",
+       "apisandbox-unfullscreen": "显示页面",
+       "apisandbox-unfullscreen-tooltip": "缩小沙盒面板,这样就可以使用MediaWiki导航链接。",
+       "apisandbox-submit": "提交请求",
+       "apisandbox-reset": "清除",
+       "apisandbox-retry": "重试",
+       "apisandbox-loading": "正在加载用于API模块“$1”的信息...",
+       "apisandbox-load-error": "加载用于API模块“$1”的信息时出错:$2",
+       "apisandbox-no-parameters": "此API模块没有参数。",
+       "apisandbox-helpurls": "帮助链接",
+       "apisandbox-examples": "示例",
+       "apisandbox-dynamic-parameters": "额外参数",
+       "apisandbox-dynamic-parameters-add-label": "添加参数:",
+       "apisandbox-dynamic-parameters-add-placeholder": "参数名称",
+       "apisandbox-dynamic-error-exists": "已存在名为“$1”的参数。",
+       "apisandbox-deprecated-parameters": "弃用参数",
+       "apisandbox-fetch-token": "自动填充令牌",
+       "apisandbox-submit-invalid-fields-title": "一些字段无效",
+       "apisandbox-submit-invalid-fields-message": "请改正标记的字段并重试。",
+       "apisandbox-results": "结果",
+       "apisandbox-sending-request": "正在发送API请求...",
+       "apisandbox-loading-results": "正在接收API请求...",
+       "apisandbox-results-error": "加载API查询响应时出错:$1。",
+       "apisandbox-request-url-label": "请求的URL:",
+       "apisandbox-request-time": "请求时间:{{PLURAL:$1|$1毫秒}}",
+       "apisandbox-results-fixtoken": "改正令牌并重新提交",
+       "apisandbox-results-fixtoken-fail": "检索“$1”令牌失败。",
+       "apisandbox-alert-page": "此页面上的字段无效。",
+       "apisandbox-alert-field": "此字段的值无效。",
        "booksources": "网络书源",
        "booksources-search-legend": "搜索图书来源",
        "booksources-isbn": "ISBN:",
        "trackingcategories-nodesc": "没有可用说明。",
        "trackingcategories-disabled": "分类被禁用",
        "mailnologin": "无电子邮件地址",
-       "mailnologintext": "你必须[[Special:UserLogin|登录]]并在你的[[Special:Preferences|系统设置]]中拥有有效的电子邮件地址才能向其他用户发送电子邮件。",
+       "mailnologintext": "您必须[[Special:UserLogin|登录]]并在您的[[Special:Preferences|系统设置]]中拥有有效的电子邮件地址才能向其他用户发送电子邮件。",
        "emailuser": "电邮联系",
        "emailuser-title-target": "电邮联系该{{GENDER:$1|用户}}",
        "emailuser-title-notarget": "电邮联系",
-       "emailpagetext": "你可以使用下面的表格发送电子邮件信息至该{{GENDER:$1|用户}}。你在[[Special:Preferences|系统设置]]中输入的电子邮件地址将显示为邮件的“发件人”地址,所以该用户将可以直接回复你。",
+       "emailpagetext": "您可以使用下面的表格发送电子邮件信息至该{{GENDER:$1|用户}}。您在[[Special:Preferences|系统设置]]中输入的电子邮件地址将显示为邮件的“发件人”地址,所以该用户将可以直接回复您。",
        "defemailsubject": "来自{{SITENAME}}用户“$1”的电子邮件",
        "usermaildisabled": "用户电子邮件停用",
        "usermaildisabledtext": "你不能发送电子邮件至本wiki的其他用户",
        "watchlist": "监视列表",
        "mywatchlist": "监视列表",
        "watchlistfor2": "$1的监视列表$2",
-       "nowatchlist": "的监视列表为空。",
+       "nowatchlist": "的监视列表为空。",
        "watchlistanontext": "请登录以查看或编辑您的监视列表。",
        "watchnologin": "未登录",
        "addwatch": "添加至监视列表",
        "tooltip-invert": "请选择该框以隐藏指定名字空间(及相关名字空间,若被选择)的页面更改",
        "tooltip-whatlinkshere-invert": "勾选此框以隐藏来自选定名字空间内页面的链接。",
        "namespace_association": "关联的名字空间",
-       "tooltip-namespace_association": "选中此复选框可包括与选定名字空间相关的讨论页或子页面",
+       "tooltip-namespace_association": "选中此复选框可包括与选定名字空间相关的讨论或主题名字空间",
        "blanknamespace": "(主)",
        "contributions": "{{GENDER:$1|用户}}贡献",
        "contributions-title": "$1的用户贡献",
        "imageinvalidfilename": "目标文件名称无效",
        "fix-double-redirects": "更新所有指向原始标题的重定向",
        "move-leave-redirect": "保留重定向",
-       "protectedpagemovewarning": "'''警告:'''本页面已被保护,只有拥有管理员权限的用户可以移动。下面提供最后的日志条目以供参考:",
-       "semiprotectedpagemovewarning": "'''注意:'''本页面已被保护,只有注册用户可以移动。下面提供最后的日志条目以供参考:",
+       "protectedpagemovewarning": "<strong>警告:</strong>本页面已被保护,只有拥有管理员权限的用户可以移动。下面提供最后的日志条目以供参考:",
+       "semiprotectedpagemovewarning": "<strong>注意:</strong>本页面已被保护,只有注册用户可以移动。下面提供最后的日志条目以供参考:",
        "move-over-sharedrepo": "[[:$1]]已在一个共享的存储库存在。将文件移动到此标题将覆盖共享的文件。",
        "file-exists-sharedrepo": "同名文件已于共享资源存在。\n请选择另一个文件名。",
        "export": "导出页面",
        "pageinfo-robot-index": "允许",
        "pageinfo-robot-noindex": "不允许",
        "pageinfo-watchers": "页面监视者数",
-       "pageinfo-visiting-watchers": "访问最近编辑的页面浏览者数量",
+       "pageinfo-visiting-watchers": "已访问最近编辑的页面监视者数",
        "pageinfo-few-watchers": "少于$1个监视者",
        "pageinfo-few-visiting-watchers": "这里可能有或可能没有观察用户正在访问最近编辑",
        "pageinfo-redirects-name": "至该页面的重定向数",
        "version-libraries-license": "许可协议",
        "version-libraries-description": "描述",
        "version-libraries-authors": "作者",
-       "redirect": "重定向(按文件、用户、页面、修订版本ID或日志ID)",
+       "redirect": "重定向(按文件、用户、页面、修订版本或日志ID)",
        "redirect-legend": "重定向至文件或页面",
        "redirect-summary": "本特殊页面可以跳转至一个文件(提供文件名)、页面(提供修订版本ID或页面ID)、用户页(提供数字用户ID)或日志记录(提供日志ID)。用法:[[{{#Special:Redirect}}/file/Example.jpg]]、[[{{#Special:Redirect}}/page/64308]]、[[{{#Special:Redirect}}/revision/328429]]、[[{{#Special:Redirect}}/user/101]]或[[{{#Special:Redirect}}/logid/186]]。",
        "redirect-submit": "提交",
        "logentry-newusers-byemail": "$1创建用户$3,并且密码已通过电子邮件发送",
        "logentry-newusers-autocreate": "用户账户$1被自动{{GENDER:$2|创建}}",
        "logentry-protect-move_prot": "$1将保护设置从$4{{GENDER:$2|移动}}到了$3",
-       "logentry-protect-unprotect": "$1{{GENDER:$2|移除了}}来自$3的保护",
+       "logentry-protect-unprotect": "$1{{GENDER:$2|移除了}}$3的保护",
        "logentry-protect-protect": "$1{{GENDER:$2|保护了}}$3 $4",
        "logentry-protect-protect-cascade": "$1{{GENDER:$2|保护了}}$3 $4[级联]",
        "logentry-protect-modify": "$1{{GENDER:$2|更改了}}$3的保护等级$4",
index 2ac3e67..f2a8b3c 100644 (file)
        "missingarticle-rev": "(修訂#:$1)",
        "missingarticle-diff": "(差異:$1, $2)",
        "readonly_lag": "資料庫已自動鎖定,正在等候次要資料庫同步資料到主要資料庫",
+       "nonwrite-api-promise-error": "非寫入 API 動作 'Promise-Non-Write-API-Action' HTTP 標頭已送出但請求被送至 API 寫入模組。",
        "internalerror": "內部錯誤",
        "internalerror_info": "內部錯誤:$1",
        "internalerror-fatal-exception": "嚴重例外類型 \"$1\"",
        "botpasswords-label-delete": "刪除",
        "botpasswords-label-resetpassword": "重設密碼",
        "botpasswords-label-grants": "適用的權限:",
+       "botpasswords-help-grants": "每個授權會給予擁有該授權的使用者帳號列於該授權清單的使用者權限。 請參考 [[Special:ListGrants|授權表]] 取得更多資訊。",
        "botpasswords-label-restrictions": "使用限制:",
        "botpasswords-label-grants-column": "已授權",
        "botpasswords-bad-appid": "機器人名稱 \"$1\" 無效。",
        "botpasswords-updated-body": "機器人密碼 \"$1\" 已修改成功。",
        "botpasswords-deleted-title": "已刪除機器人密碼",
        "botpasswords-deleted-body": "機器人密碼 \"$1\" 已刪除。",
+       "botpasswords-newpassword": "用來登入 <strong>$1</strong> 的新密碼為 <strong>$2</strong>。 <em>請記錄此密碼以供未來參考使用。</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider 無法使用。",
        "botpasswords-restriction-failed": "機器人密碼限制已拒絕此次登入。",
        "botpasswords-invalid-name": "指定的使用者名稱未包含機器人密碼分隔字元 (\"$1\")。",
        "undo-summary": "取消由 [[Special:Contributions/$2|$2]] ([[User talk:$2|對話]]) 所作出的修訂 $1",
        "undo-summary-username-hidden": "還原隱藏使用者的修訂 $1",
        "cantcreateaccounttitle": "無法建立帳號",
-       "cantcreateaccount-text": "自這個 IP 位址(<strong>$1</strong>)建立帳號已經被 [[User:$3|$3]] 封鎖。\n\n$3 封鎖的原因是 <em>$2</em>",
+       "cantcreateaccount-text": "自這個 IP 位址 (<strong>$1</strong>) 建立帳號已經被 [[User:$3|$3]] 封鎖。\n\n$3 封鎖的原因是 <em>$2</em>",
        "cantcreateaccount-range-text": "來自 IP 位址範圍 '''$1''',包含您的 IP 位址 ('''$4''') 所建立的帳號已經被 [[User:$3|$3]] 封鎖。\n\n$3 封鎖的原因是 ''$2''",
        "viewpagelogs": "檢視此頁面的日誌",
        "nohistory": "此頁沒有任何的修訂記錄。",
        "rev-suppressed-unhide-diff": "檢視差異的其中一個修訂已被 <strong>禁止顯示</strong>。\n可至 [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 禁止顯示日誌] 取得詳細資訊。\n若您要繼續,您仍可以 [$1 檢視此差異]。",
        "rev-deleted-diff-view": "檢視差異的其中一個修訂已被 <strong>刪除</strong>。\n您可繼續檢視差異,可至 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 刪除日誌] 取得詳細資訊。",
        "rev-suppressed-diff-view": "檢視差異的其中一個修訂已被 <strong>禁止顯示</strong>。\n您可繼續檢視差異,可至 [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 禁止顯示日誌] 取得詳細資訊。",
-       "rev-delundel": "變更可見",
+       "rev-delundel": "變更可見",
        "rev-showdeleted": "顯示",
        "revisiondelete": "刪除/取消刪除修訂",
        "revdelete-nooldid-title": "無效的目標修訂",
        "uploaded-script-svg": "於已上傳的 SVG 檔案中找到可程式的腳本標籤 \"$1\"。",
        "uploaded-hostile-svg": "於已上傳的 SVG 檔案的樣式標籤中找到不安全的 CSS。",
        "uploaded-event-handler-on-svg": "不允許在 SVG 檔案設定 event-handler 屬性 <code>$1=\"$2\"</code>。",
-       "uploaded-href-attribute-svg": "不允許在 SVG 檔案中的 href 屬性 <code>&lt;$1 $2=\"$3\"&gt;</code> 使用非本地的目標  (例如 http://, javascript:, 等)。",
-       "uploaded-href-unsafe-target-svg": "於已上傳的 SVG 檔案中找到 href 連結至不安全的目標 <code>&lt;$1 $2=\"$3\"&gt;</code>。",
+       "uploaded-href-attribute-svg": "發現 SVG 檔案中的 href 屬性為 <code>&lt;$1 $2=\"$3\"&gt;</code>,僅允許連結至 http:// 或 https:// 的目標。",
+       "uploaded-href-unsafe-target-svg": "於已上傳的 SVG 檔案中找到 href 連結至不安全的資料:URI 目標為 <code>&lt;$1 $2=\"$3\"&gt;</code>。",
        "uploaded-animate-svg": "於已上傳的 SVG 檔案中找到 \"animate\" 標籤可能會使用 \"from\" 屬性 <code>&lt;$1 $2=\"$3\"&gt;</code> 更改 href。",
        "uploaded-setting-event-handler-svg": "於已上傳的 SVG 檔案中找到 <code>&lt;$1 $2=\"$3\"&gt;</code>,已禁止設定 event-handler 屬性。",
        "uploaded-setting-href-svg": "已禁止使用 \"set\" 標籤來加入 \"href\" 屬性至父元素。",
        "upload-too-many-redirects": "該 URL 重新導向至太多其他位址",
        "upload-http-error": "發生 HTTP 錯誤:$1",
        "upload-copy-upload-invalid-domain": "此網域不允許複製上傳的檔案。",
+       "upload-foreign-cant-upload": "此 wiki 未設定可上傳來自遠端檔案庫的請求的檔案。",
        "upload-dialog-title": "上傳檔案",
        "upload-dialog-button-cancel": "取消",
        "upload-dialog-button-done": "完成",
        "upload-form-label-select-file": "選擇檔案",
        "upload-form-label-infoform-title": "詳細資料",
        "upload-form-label-infoform-name": "名稱",
+       "upload-form-label-infoform-name-tooltip": "具獨特描述性的檔案標題,將會用來做為檔名。 您可以使用您的語系及空白做為檔名,請勿包含檔案副檔名。",
        "upload-form-label-infoform-description": "描述",
+       "upload-form-label-infoform-description-tooltip": "簡短描述該作品任何值得說明的事項。\n以照片為例,可提及照片中的事物、情境及地點。",
        "upload-form-label-usage-title": "用法",
        "upload-form-label-usage-filename": "檔案名稱",
        "foreign-structured-upload-form-label-own-work": "這是我的作品",
        "querypage-disabled": "此特殊頁面因考量效能問題已被停用。",
        "apihelp": "API 說明",
        "apihelp-no-such-module": "查無模組 \"$1\"。",
+       "apisandbox": "API 沙盒",
+       "apisandbox-api-disabled": "此網站已關閉 API 使用。",
+       "apisandbox-intro": "使用此頁面可測試 '''MediaWiki Web Service API'''。\n請參考 [//www.mediawiki.org/wiki/API:Main_page API 說明文件] 以取得詳細資訊。例:[//www.mediawiki.org/wiki/API#A_simple_example 取得主頁的內容]。 請選擇動作以取得更多範例。\n\n請注意,雖然此為沙盒,您在此頁所執行的動作仍有可能會修改到 Wiki。",
+       "apisandbox-fullscreen": "展開面板",
+       "apisandbox-fullscreen-tooltip": "展開沙盒面板來填滿瀏覽器視窗。",
+       "apisandbox-unfullscreen": "顯示頁面",
+       "apisandbox-unfullscreen-tooltip": "減少沙盒面板大小,以讓 MediaWiki 導覽連結可使用。",
+       "apisandbox-submit": "發出請求",
+       "apisandbox-reset": "清除",
+       "apisandbox-retry": "重試",
+       "apisandbox-loading": "讀取 API 模組 \"$1\" 的資訊...",
+       "apisandbox-load-error": "在讀取 API 模組 \"$1\" 的資訊時發生錯誤:$2",
+       "apisandbox-no-parameters": "此 API 模組沒有參數。",
+       "apisandbox-helpurls": "說明連結",
+       "apisandbox-examples": "範例",
+       "apisandbox-dynamic-parameters": "其他參數",
+       "apisandbox-dynamic-parameters-add-label": "加入參數:",
+       "apisandbox-dynamic-parameters-add-placeholder": "參數名稱",
+       "apisandbox-dynamic-error-exists": "命名的參數 \"$1\" 已經存在。",
+       "apisandbox-deprecated-parameters": "停用的參數",
+       "apisandbox-fetch-token": "自動填寫密鑰",
+       "apisandbox-submit-invalid-fields-title": "部份欄位無效",
+       "apisandbox-submit-invalid-fields-message": "請更正已標註的欄位,然後再試一次。",
+       "apisandbox-results": "結果",
+       "apisandbox-sending-request": "傳送 API 請求中...",
+       "apisandbox-loading-results": "接收 API 結果中...",
+       "apisandbox-request-url-label": "請求 URL:",
+       "apisandbox-request-time": "請求時間:{{PLURAL:$1|$1 ms}}",
+       "apisandbox-results-fixtoken": "更正密鑰並重新送出",
        "booksources": "圖書資源",
        "booksources-search-legend": "尋找圖書資源",
        "booksources-isbn": "國際標準書號:",
        "movenosubpage": "此頁面沒有任何子頁面。",
        "movereason": "原因",
        "revertmove": "還原",
-       "delete_and_move_text": "== 需要刪除 ==\n目標頁面 \"[[:$1]]\" 已存在。\n您是否要刪除該頁面以完成移動?",
+       "delete_and_move_text": "目標頁面 \"[[:$1]]\" 已存在。\n您是否要刪除該頁面以完成移動?",
        "delete_and_move_confirm": "是的,刪除該頁面",
        "delete_and_move_reason": "已刪除讓來自 [[$1]] 頁面可移動",
        "selfmove": "原始標題與目標標題相同,無法移動至自身頁面。",
        "move-leave-redirect": "留下重新導向頁面",
        "protectedpagemovewarning": "<strong>警告:</strong>本頁已經被保護,只有擁有管理員權限的使用者才可移動。\n以下提供最近的日誌以便參考:",
        "semiprotectedpagemovewarning": "<strong>注意:</strong>本頁已經被保護,只有已註冊的使用者才可移動。\n以下提供最近的日誌以便參考:",
-       "move-over-sharedrepo": "== 檔案已存在 ==\n[[:$1]] 已存在於共用檔案庫,將檔案移動到此標題會覆蓋該共用檔案。",
+       "move-over-sharedrepo": "[[:$1]] 已存在於共用檔案庫,將檔案移動到此標題會覆蓋該共用檔案。",
        "file-exists-sharedrepo": "選擇的檔案名稱於共用檔案庫已有其他檔案使用。\n請改選擇其他名稱。",
        "export": "匯出頁面",
        "exporttext": "您可以匯出指定頁面或多頁的文字與編輯歷史,使用 XML 格式包裝。\n這些檔案可以匯入至其他使用 MediaWiki 的 Wiki,透過 [[Special:Import|匯入頁面]]。\n\n要匯出頁面,請在下方文字方塊中輸入頁面標題,一個標題使用一行,並選擇是否要匯出目前的修訂含所有的歷史修訂記錄,或者只匯出目前的修訂與最後編輯的資訊。\n\n在文字方塊中您也可使用連結,如:[[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] 代表匯出頁面 \"[[{{MediaWiki:Mainpage}}]]\"。",
        "pageinfo-robot-index": "允許",
        "pageinfo-robot-noindex": "不允許",
        "pageinfo-watchers": "頁面監視者數",
-       "pageinfo-visiting-watchers": "最後一次編輯後參觀人數",
+       "pageinfo-visiting-watchers": "已訪問最近編輯的頁面監視者數",
        "pageinfo-few-watchers": "少於 $1 名監視者",
        "pageinfo-few-visiting-watchers": "參觀近期編輯的使用者可能為監視使用者",
        "pageinfo-redirects-name": "指向此頁面的重新導向頁面數量",
        "version-libraries-license": "授權條款",
        "version-libraries-description": "描述",
        "version-libraries-authors": "作者",
-       "redirect": "重新導向至檔案、使用者、頁面或修訂 ID",
+       "redirect": "依檔案、使用者、頁面、修訂或日誌 ID 來重新導向",
        "redirect-legend": "重新導向至檔案或頁面",
-       "redirect-summary": "此特殊頁面可用來重新導向至檔案 (指定檔案名稱)、頁面 (指定修訂 ID 或頁面 ID) 或使用者頁面 (指定使用者 ID)。用法:[[{{#Special:Redirect}}/file/Example.jpg]]、[[{{#Special:Redirect}}/page/64308]]、[[{{#Special:Redirect}}/revision/328429]] 或 [[{{#Special:Redirect}}/user/101]]。",
+       "redirect-summary": "此特殊頁面可用來重新導向至檔案 (指定檔案名稱)、頁面 (指定修訂 ID 或頁面 ID)、使用者頁面 (指定使用者 ID)、或者日誌項目 (指定日誌 ID)。用法:[[{{#Special:Redirect}}/file/Example.jpg]]、[[{{#Special:Redirect}}/page/64308]]、[[{{#Special:Redirect}}/revision/328429]]、[[{{#Special:Redirect}}/user/101]] 或 [[{{#Special:Redirect}}/logid/186]]。",
        "redirect-submit": "執行",
        "redirect-lookup": "查詢:",
        "redirect-value": "值:",
        "redirect-page": "頁面 ID",
        "redirect-revision": "頁面修訂 ID",
        "redirect-file": "檔案名稱",
+       "redirect-logid": "日誌 ID",
        "redirect-not-exists": "查無值",
        "fileduplicatesearch": "搜尋重複檔案",
        "fileduplicatesearch-summary": "依據雜湊值 (Hash) 來搜尋重複的檔案。",
        "expand_templates_preview": "預覽",
        "expand_templates_preview_fail_html": "<em>因連線階段的資料遺失且 {{SITENAME}} 已開啟顯示原始 HTML 功能,為預防 JavaScript 攻擊已隱藏預覽內容。</em>\n\n<strong>若您目前的預覽動作並無非法,請再試一次。</strong>\n若仍然無效,請嘗試[[Special:UserLogout|登出]]並再登入一次。",
        "expand_templates_preview_fail_html_anon": "<em>因您尚未登入且 {{SITENAME}} 已開啟顯示原始 HTML 功能,為預防 JavaScript 攻擊已隱藏預覽內容。</em>\n\n<strong>若您目前的預覽動作並無非法,請[[Special:UserLogin|登入]]後再試一次。</strong>",
-       "pagelanguage": "頁面語言選擇器",
+       "pagelanguage": "變更頁面語言",
        "pagelang-name": "頁面",
        "pagelang-language": "語言",
        "pagelang-use-default": "使用預設語言",
        "pagelang-submit": "送出",
        "right-pagelang": "變更頁面語言",
        "action-pagelang": "變更頁面語言",
-       "log-name-pagelang": "è®\8aæ\9b´èª\9eè¨\80日誌",
+       "log-name-pagelang": "èª\9eè¨\80è®\8aæ\9b´日誌",
        "log-description-pagelang": "此頁為頁面語言的變更日誌。",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|已更改}}頁面 $3 的語言從 $4 到 $5",
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|已更改}}頁面 $3 的語言從 $4 到 $5",
        "default-skin-not-found": "哎呀!您於 <code dir=\"ltr\">$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您的安裝程序應包含以下{{PLURAL:$4|外觀}}。請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何{{PLURAL:$4|開啟外觀並設為預設值}}的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins 使用 Git 下載外觀]。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。您可以將下列{{PLURAL:$5|行}}貼上至 <code>LocalSettings.php</code> 來開啟{{PLURAL:$5|所有}}目前已經安裝的{{PLURAL:$5|外觀}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
        "default-skin-not-found-no-skins": "哎呀!您於 <code>$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 自 [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org] 下載個別外觀 tarball。\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins 使用 Git 下載外觀]。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (已開啟)",
index 2a1f85b..bd2ac04 100644 (file)
@@ -390,6 +390,7 @@ $specialPageAliases = array(
        'AllMyUploads'              => array( 'AllMyUploads', 'AllMyFiles' ),
        'Allpages'                  => array( 'AllPages' ),
        'ApiHelp'                   => array( 'ApiHelp' ),
+       'ApiSandbox'                => array( 'ApiSandbox' ),
        'Ancientpages'              => array( 'AncientPages' ),
        'Badtitle'                  => array( 'Badtitle' ),
        'Blankpage'                 => array( 'BlankPage' ),
index 291920b..5a7f769 100644 (file)
@@ -84,7 +84,7 @@ abstract class Maintenance {
        protected $mQuiet = false;
        protected $mDbUser, $mDbPass;
 
-       // A description of the script, children should change this
+       // A description of the script, children should change this via addDescription()
        protected $mDescription = '';
 
        // Have we already loaded our user input?
index a2ea554..deab60b 100644 (file)
@@ -38,7 +38,7 @@ class AttachLatest extends Maintenance {
                $this->addOption( "fix", "Actually fix the entries, will dry run otherwise" );
                $this->addOption( "regenerate-all",
                        "Regenerate the page_latest field for all records in table page" );
-               $this->mDescription = "Fix page_latest entries in the page table";
+               $this->addDescription( 'Fix page_latest entries in the page table' );
        }
 
        public function execute() {
index 1569234..40a877f 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchHttpHttps extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark HTTP request vs HTTPS request.";
+               $this->addDescription( 'Benchmark HTTP request vs HTTPS request.' );
        }
 
        public function execute() {
index 810937a..439947d 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchWikimediaBaseConvert extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark for Wikimedia\\base_convert.";
+               $this->addDescription( 'Benchmark for Wikimedia\base_convert.' );
                $this->addOption( "inbase", "Input base", false, true );
                $this->addOption( "outbase", "Output base", false, true );
                $this->addOption( "length", "Size in digits to generate for input", false, true );
index 572c548..9acb93a 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchmarkDeleteTruncate extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmarks SQL DELETE vs SQL TRUNCATE.";
+               $this->addDescription( 'Benchmarks SQL DELETE vs SQL TRUNCATE.' );
        }
 
        public function execute() {
index 698a0f0..8f7f61d 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchIfSwitch extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark if elseif... versus switch case.";
+               $this->addDescription( 'Benchmark if elseif... versus switch case.' );
        }
 
        public function execute() {
index 44c8e03..f34d27f 100644 (file)
@@ -41,7 +41,7 @@ function bfNormalizeTitleStrReplace( $str ) {
 class BenchStrtrStrReplace extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark for strtr() vs str_replace().";
+               $this->addDescription( 'Benchmark for strtr() vs str_replace().' );
        }
 
        public function execute() {
index b742f66..bd18adb 100644 (file)
@@ -64,11 +64,10 @@ class BenchUtf8TitleCheck extends Benchmarker {
                $this->canRun = function_exists( 'mb_check_encoding' );
 
                if ( $this->canRun ) {
-                       $this->mDescription = "Benchmark for using a regexp vs. mb_check_encoding " .
-                               "to check for UTF-8 encoding.";
-                       mb_internal_encoding( 'UTF-8' );
+                       $this->addDescription( "Benchmark for using a regexp vs. mb_check_encoding " .
+                               "to check for UTF-8 encoding." );
                } else {
-                       $this->mDescription = "CANNOT RUN benchmark using mb_check_encoding: function not available.";
+                       $this->addDescription( 'CANNOT RUN benchmark using mb_check_encoding: function not available.' );
                }
        }
 
index 8446694..ea919ef 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchWfIsWindows extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark for wfIsWindows.";
+               $this->addDescription( 'Benchmark for wfIsWindows.' );
        }
 
        public function execute() {
index 1446871..3106f89 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchmarkHooks extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Benchmark MediaWiki Hooks.';
+               $this->addDescription( 'Benchmark MediaWiki Hooks.' );
        }
 
        public function execute() {
index 9eca73c..e67d226 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Benchmarker.php';
 class BenchmarkPurge extends Benchmarker {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Benchmark the Squid purge functions.";
+               $this->addDescription( 'Benchmark the Squid purge functions.' );
        }
 
        public function execute() {
index 5d98e1f..8687f81 100644 (file)
@@ -37,7 +37,7 @@ class ChangePassword extends Maintenance {
                $this->addOption( "user", "The username to operate on", false, true );
                $this->addOption( "userid", "The user id to operate on", false, true );
                $this->addOption( "password", "The password to use", true, true );
-               $this->mDescription = "Change a user's password";
+               $this->addDescription( "Change a user's password" );
        }
 
        public function execute() {
index 500fc35..985df56 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class CheckBadRedirects extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Check for bad redirects";
+               $this->addDescription( 'Check for bad redirects' );
        }
 
        public function execute() {
index 7a85d64..9ec61dc 100644 (file)
@@ -12,8 +12,8 @@ require_once __DIR__ . '/Maintenance.php';
 class CheckComposerLockUpToDate extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       'Checks whether your composer.lock file is up to date with the current composer.json';
+               $this->addDescription(
+                       'Checks whether your composer.lock file is up to date with the current composer.json' );
        }
 
        public function execute() {
index 9761927..9a8203f 100644 (file)
@@ -31,7 +31,7 @@ class CheckImages extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Check images to see if they exist, are readable, etc";
+               $this->addDescription( 'Check images to see if they exist, are readable, etc' );
                $this->setBatchSize( 1000 );
        }
 
index 2f533cf..889c903 100644 (file)
@@ -30,8 +30,8 @@ class CheckLess extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       'Checks LESS files for errors by running the LessTestSuite PHPUnit test suite';
+               $this->addDescription(
+                       'Checks LESS files for errors by running the LessTestSuite PHPUnit test suite' );
        }
 
        public function execute() {
index 30a23d3..4821e04 100644 (file)
@@ -36,7 +36,7 @@ class CheckSyntax extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Check syntax for all PHP files in MediaWiki";
+               $this->addDescription( 'Check syntax for all PHP files in MediaWiki' );
                $this->addOption( 'with-extensions', 'Also recurse the extensions folder' );
                $this->addOption(
                        'path',
index 6f4d170..1b9a1cc 100644 (file)
@@ -35,7 +35,7 @@ class CheckUsernames extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Verify that database usernames are actually valid";
+               $this->addDescription( 'Verify that database usernames are actually valid' );
                $this->setBatchSize( 1000 );
        }
 
index f1467d5..7f67b60 100644 (file)
@@ -33,7 +33,7 @@ class CleanupAncientTables extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Cleanup ancient tables and indexes";
+               $this->addDescription( 'Cleanup ancient tables and indexes' );
                $this->addOption( 'force', 'Actually run this script' );
        }
 
index 437abe9..2efd7ab 100644 (file)
@@ -33,7 +33,7 @@ class CleanupBlocks extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Cleanup user blocks with user names not matching the 'user' table";
+               $this->addDescription( "Cleanup user blocks with user names not matching the 'user' table" );
                $this->setBatchSize( 1000 );
        }
 
index e0a0f49..a79c2d3 100644 (file)
@@ -42,7 +42,7 @@ class CapsCleanup extends TableCleanup {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to cleanup capitalization";
+               $this->addDescription( 'Script to cleanup capitalization' );
                $this->addOption( 'namespace', 'Namespace number to run caps cleanup on', false, true );
        }
 
index ab2d808..0110685 100644 (file)
@@ -42,7 +42,7 @@ class ImageCleanup extends TableCleanup {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to clean up broken, unparseable upload filenames";
+               $this->addDescription( 'Script to clean up broken, unparseable upload filenames' );
        }
 
        protected function processRow( $row ) {
index 810fad9..19949bc 100644 (file)
@@ -34,7 +34,8 @@ class CleanupRemovedModules extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Remove cache entries for removed ResourceLoader modules from the database';
+               $this->addDescription(
+                       'Remove cache entries for removed ResourceLoader modules from the database' );
                $this->addOption( 'batchsize', 'Delete rows in batches of this size. Default: 500', false, true );
        }
 
index b43ce81..020f5cd 100644 (file)
@@ -32,7 +32,7 @@ class CleanupSpam extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Cleanup all spam from a given hostname";
+               $this->addDescription( 'Cleanup all spam from a given hostname' );
                $this->addOption( 'all', 'Check all wikis in $wgLocalDatabases' );
                $this->addOption( 'delete', 'Delete pages containing only spam instead of blanking them' );
                $this->addArg(
index 07df1b1..574d5bd 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/cleanupTable.inc';
 class TitleCleanup extends TableCleanup {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to clean up broken, unparseable titles";
+               $this->addDescription( 'Script to clean up broken, unparseable titles' );
        }
 
        /**
index 70490e1..480059d 100644 (file)
@@ -37,7 +37,7 @@ class UploadStashCleanup extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Clean up abandoned files in temporary uploaded file stash";
+               $this->addDescription( 'Clean up abandoned files in temporary uploaded file stash' );
                $this->setBatchSize( 50 );
        }
 
index 16f7b61..d8c682b 100644 (file)
@@ -46,7 +46,7 @@ class WatchlistCleanup extends TableCleanup {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to remove broken, unparseable titles in the Watchlist";
+               $this->addDescription( 'Script to remove broken, unparseable titles in the Watchlist' );
                $this->addOption( 'fix', 'Actually remove entries; without will only report.' );
        }
 
index 6a6527f..4b5773c 100644 (file)
@@ -32,7 +32,7 @@ class ClearInterwikiCache extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Clear all interwiki links for all languages from the cache";
+               $this->addDescription( 'Clear all interwiki links for all languages from the cache' );
        }
 
        public function execute() {
index 98441b6..e5f0bb3 100644 (file)
@@ -27,7 +27,7 @@ require_once __DIR__ . '/Maintenance.php';
 class CompareParserCache extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Parse random pages and compare output to cache.";
+               $this->addDescription( 'Parse random pages and compare output to cache.' );
                $this->addOption( 'namespace', 'Page namespace number', true, true );
                $this->addOption( 'maxpages', 'Number of pages to try', true, true );
        }
index e67c439..f2540c7 100644 (file)
@@ -43,7 +43,7 @@ class CompareParsers extends DumpIterator {
        public function __construct() {
                parent::__construct();
                $this->saveFailed = false;
-               $this->mDescription = "Run a file or dump with several parsers";
+               $this->addDescription( 'Run a file or dump with several parsers' );
                $this->addOption( 'parser1', 'The first parser to compare.', true, true );
                $this->addOption( 'parser2', 'The second parser to compare.', true, true );
                $this->addOption( 'tidy', 'Run tidy on the articles.', false, false );
index 3113533..eeb2e6d 100644 (file)
@@ -55,7 +55,7 @@ class ConvertExtensionToRegistration extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Converts extension entry points to the new JSON registration format';
+               $this->addDescription( 'Converts extension entry points to the new JSON registration format' );
                $this->addArg( 'path', 'Location to the PHP entry point you wish to convert',
                        /* $required = */ true );
                $this->addOption( 'skin', 'Whether to write to skin.json', false, false );
index 15ca14b..fa9c574 100644 (file)
@@ -36,9 +36,9 @@ class ConvertLinks extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "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";
+               $this->addDescription(
+                       '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' );
 
                $this->addArg( 'logperformance', "Log performance to perfLogFilename.", false );
                $this->addArg(
index 11768c8..c245a1e 100644 (file)
@@ -34,7 +34,7 @@ class ConvertUserOptions extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Convert user options from old to new system";
+               $this->addDescription( 'Convert user options from old to new system' );
                $this->setBatchSize( 50 );
        }
 
index b39ff55..25073f7 100644 (file)
@@ -40,7 +40,7 @@ class CopyFileBackend extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Copy files in one backend to another.";
+               $this->addDescription( 'Copy files in one backend to another.' );
                $this->addOption( 'src', 'Backend containing the source files', true, true );
                $this->addOption( 'dst', 'Backend where files should be copied to', true, true );
                $this->addOption( 'containers', 'Pipe separated list of containers', true, true );
index a9c9547..42c2dd4 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
 class CopyJobQueue extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Copy jobs from one queue system to another.";
+               $this->addDescription( 'Copy jobs from one queue system to another.' );
                $this->addOption( 'src', 'Key to $wgJobQueueMigrationConfig for source', true, true );
                $this->addOption( 'dst', 'Key to $wgJobQueueMigrationConfig for destination', true, true );
                $this->addOption( 'type', 'Types of jobs to copy (use "all" for all)', true, true );
index c1a2022..e7d666a 100644 (file)
@@ -35,7 +35,7 @@ class CreateAndPromote extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Create a new user account and/or grant it additional rights";
+               $this->addDescription( 'Create a new user account and/or grant it additional rights' );
                $this->addOption(
                        'force',
                        'If acccount exists already, just grant it rights or change password.'
index c678712..87e7e08 100644 (file)
@@ -37,7 +37,7 @@ class GenerateCommonPassword extends Maintenance {
        public function __construct() {
                global $IP;
                parent::__construct();
-               $this->mDescription = "Generate CDB file of common passwords";
+               $this->addDescription( 'Generate CDB file of common passwords' );
                $this->addOption( 'limit', "Max number of passwords to write", false, true, 'l' );
                $this->addArg( 'inputfile', 'List of passwords (one per line) to use or - for stdin', true );
                $this->addArg(
index 94ebf87..92f1a91 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteArchivedFiles extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Deletes all archived images.";
+               $this->addDescription( 'Deletes all archived images.' );
                $this->addOption( 'delete', 'Perform the deletion' );
                $this->addOption( 'force', 'Force deletion of rows from filearchive' );
        }
index 9924eb0..2fb83fc 100644 (file)
@@ -35,8 +35,8 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteArchivedRevisions extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Deletes all archived revisions\nThese revisions will no longer be restorable";
+               $this->addDescription(
+                       "Deletes all archived revisions\nThese revisions will no longer be restorable" );
                $this->addOption( 'delete', 'Performs the deletion' );
        }
 
index 6c89e67..e8839c5 100644 (file)
@@ -39,7 +39,7 @@ class DeleteBatch extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Deletes a batch of pages";
+               $this->addDescription( 'Deletes a batch of pages' );
                $this->addOption( 'u', "User to perform deletion", false, true );
                $this->addOption( 'r', "Reason to delete page", false, true );
                $this->addOption( 'i', "Interval to sleep between deletions" );
index a5c6199..7e1d315 100644 (file)
@@ -33,8 +33,8 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteDefaultMessages extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Deletes all pages in the MediaWiki namespace" .
-                       " which were last edited by \"MediaWiki default\"";
+               $this->addDescription( 'Deletes all pages in the MediaWiki namespace' .
+                       ' which were last edited by "MediaWiki default"' );
        }
 
        public function execute() {
index e7bb866..f21f3e1 100644 (file)
@@ -30,8 +30,8 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteEqualMessages extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Deletes all pages in the MediaWiki namespace that are equal to '
-                       . 'the default message';
+               $this->addDescription( 'Deletes all pages in the MediaWiki namespace that are equal to '
+                       . 'the default message' );
                $this->addOption( 'delete', 'Actually delete the pages (default: dry run)' );
                $this->addOption( 'delete-talk', 'Don\'t leave orphaned talk pages behind during deletion' );
                $this->addOption( 'lang-code', 'Check for subpages of this language code (default: root '
index f411148..123163f 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteOldRevisions extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Delete old (non-current) revisions from the database";
+               $this->addDescription( 'Delete old (non-current) revisions from the database' );
                $this->addOption( 'delete', 'Actually perform the deletion' );
                $this->addOption( 'page_id', 'List of page ids to work on', false );
        }
index 3d5c1a4..5f08b5a 100644 (file)
@@ -34,7 +34,8 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteOrphanedRevisions extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Maintenance script to delete revisions which refer to a nonexisting page";
+               $this->addDescription(
+                       'Maintenance script to delete revisions which refer to a nonexisting page' );
                $this->addOption( 'report', 'Prints out a count of affected revisions but doesn\'t delete them' );
        }
 
index 6cda784..4606d92 100644 (file)
@@ -33,7 +33,7 @@ class DeleteRevision extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Delete one or more revisions by moving them to the archive table";
+               $this->addDescription( 'Delete one or more revisions by moving them to the archive table' );
        }
 
        public function execute() {
index f9bb416..ed15fd1 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class DeleteSelfExternals extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Delete self-references to $wgServer from externallinks';
+               $this->addDescription( 'Delete self-references to $wgServer from externallinks' );
                $this->mBatchSize = 1000;
        }
 
index 18737a4..1904325 100644 (file)
@@ -31,7 +31,7 @@ class DumpBackup extends BackupDumper {
        function __construct( $args = null ) {
                parent::__construct();
 
-               $this->mDescription = <<<TEXT
+               $this->addDescription( <<<TEXT
 This script dumps the wiki page or logging database into an
 XML interchange wrapper format for export or backup.
 
@@ -40,7 +40,8 @@ XML output is sent to stdout; progress reports are sent to stderr.
 WARNING: this is not a full database dump! It is merely for public export
          of your wiki. For full backup, see our online help at:
          https://www.mediawiki.org/wiki/Backup
-TEXT;
+TEXT
+               );
                $this->stderr = fopen( "php://stderr", "wt" );
                // Actions
                $this->addOption( 'full', 'Dump all revisions of every page' );
index d8bc3a4..eef535a 100644 (file)
@@ -40,7 +40,7 @@ abstract class DumpIterator extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Does something with a dump";
+               $this->addDescription( 'Does something with a dump' );
                $this->addOption( 'file', 'File with text to run.', false, true );
                $this->addOption( 'dump', 'XML dump to execute all revisions.', false, true );
                $this->addOption( 'from', 'Article from XML dump to start from.', false, true );
@@ -164,7 +164,7 @@ class SearchDump extends DumpIterator {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Runs a regex in the revisions from a dump";
+               $this->addDescription( 'Runs a regex in the revisions from a dump' );
                $this->addOption( 'regex', 'Searching regex', true, true );
        }
 
index 74b500a..7139786 100644 (file)
@@ -40,7 +40,7 @@ require_once __DIR__ . '/Maintenance.php';
 class DumpLinks extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Quick demo hack to generate a plaintext link dump";
+               $this->addDescription( 'Quick demo hack to generate a plaintext link dump' );
        }
 
        public function execute() {
index 7511392..8169ef5 100644 (file)
@@ -93,13 +93,14 @@ class TextPassDumper extends BackupDumper {
        function __construct( $args = null ) {
                parent::__construct();
 
-               $this->mDescription = <<<TEXT
+               $this->addDescription( <<<TEXT
 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.
-TEXT;
+TEXT
+               );
                $this->stderr = fopen( "php://stderr", "wt" );
 
                $this->addOption( 'stub', 'To load a compressed stub dump instead of stdin. ' .
index 026ac02..64884d5 100644 (file)
@@ -32,8 +32,8 @@ require_once __DIR__ . '/Maintenance.php';
 class UploadDumper extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Generates list of uploaded files which can be fed to tar or similar.
-By default, outputs relative paths against the parent directory of \$wgUploadDirectory.";
+               $this->addDescription( 'Generates list of uploaded files which can be fed to tar or similar.
+By default, outputs relative paths against the parent directory of $wgUploadDirectory.' );
                $this->addOption( 'base', 'Set base relative path instead of wiki include root', false, true );
                $this->addOption( 'local', 'List all local files, used or not. No shared files included' );
                $this->addOption( 'used', 'Skip local images that are not used' );
index b67a957..fc83a91 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class EditCLI extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Edit an article from the command line, text is from stdin";
+               $this->addDescription( 'Edit an article from the command line, text is from stdin' );
                $this->addOption( 'user', 'Username', false, true, 'u' );
                $this->addOption( 'summary', 'Edit summary', false, true, 's' );
                $this->addOption( 'minor', 'Minor edit', false, false, 'm' );
index 69a95e2..2fcdd14 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
 class EraseArchivedFile extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Erases traces of deleted files.";
+               $this->addDescription( 'Erases traces of deleted files.' );
                $this->addOption( 'delete', 'Perform the deletion' );
                $this->addOption( 'filename', 'File name', false, true );
                $this->addOption( 'filekey', 'File storage key (with extension) or "*"', true, true );
index 145c924..157a323 100644 (file)
@@ -15,7 +15,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
 class ExportSites extends Maintenance {
 
        public function __construct() {
-               $this->mDescription = 'Exports site definitions the sites table to XML file';
+               $this->addDescription( 'Exports site definitions the sites table to XML file' );
 
                $this->addArg( 'file', 'A file to write the XML to (see docs/sitelist.txt). ' .
                        'Use "php://stdout" to write to stdout.', true
index cf12838..989e90a 100644 (file)
@@ -32,9 +32,10 @@ require_once __DIR__ . '/Maintenance.php';
 class FetchText extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Fetch the raw revision blob from an old_id.\n" .
+               $this->addDescription( "Fetch the raw revision blob from an old_id.\n" .
                        "NOTE: Export transformations are NOT applied. " .
-                       "This is left to backupTextPass.php";
+                       "This is left to backupTextPass.php"
+               );
        }
 
        /**
index 9dba818..feb927e 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class TestFileOpPerformance extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Test fileop performance";
+               $this->addDescription( 'Test fileop performance' );
                $this->addOption( 'b1', 'Backend 1', true, true );
                $this->addOption( 'b2', 'Backend 2', false, true );
                $this->addOption( 'srcdir', 'File source directory', true, true );
index 8c7e242..9022292 100644 (file)
@@ -124,7 +124,7 @@ class DeprecatedInterfaceFinder extends FileAwareNodeVisitor {
 class FindDeprecated extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Find deprecated interfaces';
+               $this->addDescription( 'Find deprecated interfaces' );
        }
 
        public function getFiles() {
index f9c61c7..1cf818e 100644 (file)
@@ -49,7 +49,7 @@ class FindHooks extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Find hooks that are undocumented, missing, or just plain wrong';
+               $this->addDescription( 'Find hooks that are undocumented, missing, or just plain wrong' );
                $this->addOption( 'online', 'Check against MediaWiki.org hook documentation' );
        }
 
index 5818ee2..2fad7ce 100644 (file)
@@ -25,7 +25,7 @@ class FindMissingFiles extends Maintenance {
        function __construct() {
                parent::__construct();
 
-               $this->mDescription = 'Find registered files with no corresponding file.';
+               $this->addDescription( 'Find registered files with no corresponding file.' );
                $this->addOption( 'start', 'Start after this file name', false, true );
                $this->addOption( 'mtimeafter', 'Only include files changed since this time', false, true );
                $this->addOption( 'mtimebefore', 'Only includes files changed before this time', false, true );
index 41650bd..2362957 100644 (file)
@@ -25,7 +25,7 @@ class FindOrphanedFiles extends Maintenance {
        function __construct() {
                parent::__construct();
 
-               $this->mDescription = "Find unregistered files in the 'public' repo zone.";
+               $this->addDescription( "Find unregistered files in the 'public' repo zone." );
                $this->addOption( 'subdir',
                        'Only scan files in this subdirectory (e.g. "a/a0")', false, true );
                $this->addOption( 'verbose', "Mention file paths checked" );
index 25ec342..18334d6 100644 (file)
@@ -32,8 +32,8 @@ require_once __DIR__ . '/Maintenance.php';
 class FixDefaultJsonContentPages extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                               'Fix instances of JSON pages prior to them being the ContentHandler default';
+               $this->addDescription(
+                       'Fix instances of JSON pages prior to them being the ContentHandler default' );
                $this->setBatchSize( 100 );
        }
 
index ca551f8..8faca27 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
 class FixDoubleRedirects extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to fix double redirects";
+               $this->addDescription( 'Script to fix double redirects' );
                $this->addOption( 'async', 'Don\'t fix anything directly, just queue the jobs' );
                $this->addOption( 'title', 'Fix only redirects pointing to this page', false, true );
                $this->addOption( 'dry-run', 'Perform a dry run, fix nothing' );
index a44f8e5..d04e0c2 100644 (file)
@@ -34,8 +34,8 @@ require_once __DIR__ . '/Maintenance.php';
 class FixExtLinksProtocolRelative extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Fixes any entries in the externallinks table containing protocol-relative URLs";
+               $this->addDescription(
+                       'Fixes any entries in the externallinks table containing protocol-relative URLs' );
        }
 
        protected function getUpdateKey() {
index c2a748c..0fb3d38 100644 (file)
@@ -36,7 +36,7 @@ require_once __DIR__ . '/Maintenance.php';
 class FixTimestamps extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "";
+               $this->addDescription( '' );
                $this->addArg( 'offset', '' );
                $this->addArg( 'start', 'Starting timestamp' );
                $this->addArg( 'end', 'Ending timestamp' );
index d09760b..44ac220 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class FixUserRegistration extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Fix the user_registration field";
+               $this->addDescription( 'Fix the user_registration field' );
                $this->setBatchSize( 1000 );
        }
 
index b9c07fb..0b4f2ed 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
 class GenerateJsonI18n extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Build JSON messages files from a PHP messages file";
+               $this->addDescription( 'Build JSON messages files from a PHP messages file' );
 
                $this->addArg( 'phpfile', 'PHP file defining a $messages array', false );
                $this->addArg( 'jsondir', 'Directory to write JSON files to', false );
index c40d0ce..256824e 100644 (file)
@@ -145,7 +145,7 @@ class GenerateSitemap extends Maintenance {
         */
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Creates a sitemap for the site";
+               $this->addDescription( 'Creates a sitemap for the site' );
                $this->addOption(
                        'fspath',
                        'The file system path to save to, e.g. /tmp/sitemap; defaults to current directory',
index 5838201..b1140ec 100644 (file)
@@ -49,7 +49,7 @@ class GetConfiguration extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Get serialized MediaWiki site configuration";
+               $this->addDescription( 'Get serialized MediaWiki site configuration' );
                $this->addOption( 'regex', 'regex to filter variables with', false, true );
                $this->addOption( 'iregex', 'same as --regex but case insensitive', false, true );
                $this->addOption( 'settings', 'Space-separated list of wg* variables', false, true );
index 7365a2e..c2c6958 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class GetLagTimes extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Dump replication lag times";
+               $this->addDescription( 'Dump replication lag times' );
        }
 
        public function execute() {
index c858c38..81228cc 100644 (file)
@@ -32,7 +32,7 @@ class GetSlaveServer extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addOption( "group", "Query group to check specifically" );
-               $this->mDescription = "Report the hostname of a slave server";
+               $this->addDescription( 'Report the hostname of a slave server' );
        }
 
        public function execute() {
index c4b8cc9..f519a79 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class GetTextMaint extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Outputs page text to stdout';
+               $this->addDescription( 'Outputs page text to stdout' );
                $this->addOption( 'show-private', 'Show the text even if it\'s not available to the public' );
                $this->addArg( 'title', 'Page title' );
        }
index 5806ffc..7c452a6 100644 (file)
@@ -49,7 +49,8 @@ class BackupReader extends Maintenance {
                        ? 'ok'
                        : '(disabled; requires PHP bzip2 module)';
 
-               $this->mDescription = <<<TEXT
+               $this->addDescription(
+                       <<<TEXT
 This script reads pages from an XML file as produced from Special:Export or
 dumpBackup.php, and saves them into the current wiki.
 
@@ -61,7 +62,8 @@ Compressed XML files may be read directly:
 Note that for very large data sets, importDump.php may be slow; there are
 alternate methods which can be much faster for full site restoration:
 <https://www.mediawiki.org/wiki/Manual:Importing_XML_dumps>
-TEXT;
+TEXT
+               );
                $this->stderr = fopen( "php://stderr", "wt" );
                $this->addOption( 'report',
                        'Report position and speed after every n pages processed', false, true );
index 5dfd2a8..366594d 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ImportSiteScripts extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Import site scripts from a site';
+               $this->addDescription( 'Import site scripts from a site' );
                $this->addArg( 'api', 'API base url' );
                $this->addArg( 'index', 'index.php base url' );
                $this->addOption( 'username', 'User name of the script importer' );
index c5c00aa..8845c60 100644 (file)
@@ -15,7 +15,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
 class ImportSites extends Maintenance {
 
        public function __construct() {
-               $this->mDescription = 'Imports site definitions from XML into the sites table.';
+               $this->addDescription( 'Imports site definitions from XML into the sites table.' );
 
                $this->addArg( 'file', 'An XML file containing site definitions (see docs/sitelist.txt). ' .
                        'Use "php://stdin" to read from stdin.', true
index 14d8420..70b6574 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ImportTextFiles extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Reads in text files and imports their content to pages of the wiki";
+               $this->addDescription( 'Reads in text files and imports their content to pages of the wiki' );
                $this->addOption( 'user', 'Username to which edits should be attributed. ' .
                        'Default: "Maintenance script"', false, true, 'u' );
                $this->addOption( 'summary', 'Specify edit summary for the edits', false, true, 's' );
index dee5db8..5d0dcc6 100644 (file)
@@ -35,7 +35,7 @@ class InitEditCount extends Maintenance {
 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 the load balancer, usually indicating a replication environment.' );
-               $this->mDescription = "Batch-recalculate user_editcount fields from the revision table";
+               $this->addDescription( 'Batch-recalculate user_editcount fields from the revision table' );
        }
 
        public function execute() {
index 8d26063..7e62b89 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class InitSiteStats extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Re-initialise the site statistics tables";
+               $this->addDescription( 'Re-initialise the site statistics tables' );
                $this->addOption( 'update', 'Update the existing statistics' );
                $this->addOption( 'active', 'Also update active users count' );
                $this->addOption( 'use-master', 'Count using the master database' );
index fddfc02..770251c 100644 (file)
@@ -33,7 +33,7 @@ class JSParseHelper extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Runs parsing/syntax checks on JavaScript files";
+               $this->addDescription( 'Runs parsing/syntax checks on JavaScript files' );
                $this->addArg( 'file(s)', 'JavaScript file to test', false );
        }
 
index 52f8201..9d92794 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class DatabaseLag extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Shows database lag";
+               $this->addDescription( 'Shows database lag' );
                $this->addOption( 'r', "Don't exit immediately, but show the lag every 5 seconds" );
        }
 
index d0e6e84..931718f 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class AllTrans extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Get all messages as defined by the English language file";
+               $this->addDescription( 'Get all messages as defined by the English language file' );
        }
 
        public function execute() {
index 1463418..dc275ab 100644 (file)
@@ -34,7 +34,7 @@ class DateFormats extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Test various language time and date functions";
+               $this->addDescription( 'Test various language time and date functions' );
        }
 
        public function execute() {
index a6e0456..eddfa26 100644 (file)
@@ -41,7 +41,7 @@ class Digit2Html extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Check digit transformation";
+               $this->addDescription( 'Check digit transformation' );
        }
 
        public function execute() {
index a72e25b..5768232 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class DumpMessages extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Dump an entire language, using the keys from English";
+               $this->addDescription( 'Dump an entire language, using the keys from English' );
        }
 
        public function execute() {
index 52ed81f..722db06 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class GenerateNormalizerDataAr extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Generate the normalizer data file for Arabic';
+               $this->addDescription( 'Generate the normalizer data file for Arabic' );
                $this->addOption( 'unicode-data-file', 'The local location of the data file ' .
                        'from http://unicode.org/Public/UNIDATA/UnicodeData.txt', false, true );
        }
index cb6ae69..412e7ef 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class GenerateNormalizerDataMl extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Generate the normalizer data file for Malayalam';
+               $this->addDescription( 'Generate the normalizer data file for Malayalam' );
        }
 
        public function getDbType() {
index 3520b87..676297e 100644 (file)
@@ -37,8 +37,8 @@ class GenerateUtf8Case extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Generate Utf8Case.ser from the Unicode Character Database ' .
-                       'and supplementary files';
+               $this->addDescription( 'Generate Utf8Case.ser from the Unicode Character Database ' .
+                       'and supplementary files' );
                $this->addOption( 'unicode-data-file', 'The local location of the data file ' .
                        'from http://unicode.org/Public/UNIDATA/UnicodeData.txt', false, true );
        }
index 32cfcd7..7c16602 100644 (file)
@@ -34,8 +34,8 @@ class LangMemUsage extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Dumb program that tries to get the memory usage\n" .
-                       "for each language file";
+               $this->addDescription( "Dumb program that tries to get the memory usage\n" .
+                       "for each language file" );
        }
 
        public function execute() {
index 4bff891..e8137ba 100644 (file)
@@ -32,7 +32,7 @@ class ListVariants extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Outputs a list of language variants';
+               $this->addDescription( 'Outputs a list of language variants' );
                $this->addOption( 'flat', 'Output variants in a flat list' );
                $this->addOption( 'json', 'Output variants as JSON' );
        }
index 9d3637f..afa71f2 100644 (file)
@@ -1,2 +1,2 @@
-../../../includes/ZhConversion.php: Makefile.py $(wildcard *.manual)
+../../../languages/data/ZhConversion.php: Makefile.py $(wildcard *.manual)
        ./Makefile.py
index 5924c66..999f25c 100755 (executable)
@@ -414,22 +414,25 @@ def main():
  * @file
  */
 
-$zh2Hant = array(\n'''
+namespace MediaWiki\Languages\Data;
+
+class ZhConversion {
+public static $zh2Hant = array(\n'''
     php += PHPArray(toHant) \
-        + '\n);\n\n$zh2Hans = array(\n' \
+        + '\n);\n\npublic static $zh2Hans = array(\n' \
         + PHPArray(toHans) \
-        + '\n);\n\n$zh2TW = array(\n' \
+        + '\n);\n\npublic static $zh2TW = array(\n' \
         + PHPArray(toTW) \
-        + '\n);\n\n$zh2HK = array(\n' \
+        + '\n);\n\npublic static $zh2HK = array(\n' \
         + PHPArray(toHK) \
-        + '\n);\n\n$zh2CN = array(\n' \
+        + '\n);\n\npublic static $zh2CN = array(\n' \
         + PHPArray(toCN) \
-        + '\n);\n'
+        + '\n);\n}\n'
 
     if pyversion[:1] in ['2']:
-        f = open(os.path.join('..', '..', '..', 'includes', 'ZhConversion.php'), 'wb', encoding='utf8')
+        f = open(os.path.join('..', '..', '..', 'languages', 'data', 'ZhConversion.php'), 'wb', encoding='utf8')
     else:
-        f = open(os.path.join('..', '..', '..', 'includes', 'ZhConversion.php'), 'w', buffering=4096, encoding='utf8')
+        f = open(os.path.join('..', '..', '..', 'languages', 'data', 'ZhConversion.php'), 'w', buffering=4096, encoding='utf8')
     print ('Writing ZhConversion.php ... ')
     f.write(php)
     f.close()
index c6569a0..ca2f7c5 100644 (file)
@@ -30,7 +30,7 @@ require_once __DIR__ . '/Maintenance.php';
 class MakeTestEdits extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Make test edits for a user";
+               $this->addDescription( 'Make test edits for a user' );
                $this->addOption( 'user', 'User name', true, true );
                $this->addOption( 'count', 'Number of edits', true, true );
                $this->addOption( 'namespace', 'Namespace number', false, true );
index a97d2e1..619ada6 100644 (file)
@@ -33,8 +33,8 @@ require_once __DIR__ . '/Maintenance.php';
 class McTest extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Makes several 'set', 'incr' and 'get' requests on every"
-                       . " memcached server and shows a report";
+               $this->addDescription( "Makes several 'set', 'incr' and 'get' requests on every"
+                       . " memcached server and shows a report" );
                $this->addOption( 'i', 'Number of iterations', false, true );
                $this->addOption( 'cache', 'Use servers from this $wgObjectCaches store', false, true );
                $this->addArg( 'server[:port]', 'Memcached server to test, with optional port', false );
index b491497..20b333e 100644 (file)
@@ -51,8 +51,9 @@ class MergeMessageFileList extends Maintenance {
                );
                $this->addOption( 'extensions-dir', 'Path where extensions can be found.', false, true );
                $this->addOption( 'output', 'Send output to this file (omit for stdout)', false, true );
-               $this->mDescription = 'Merge $wgExtensionMessagesFiles and $wgMessagesDirs from ' .
-                       ' various extensions to produce a single file listing all message files and dirs.';
+               $this->addDescription( 'Merge $wgExtensionMessagesFiles and $wgMessagesDirs from ' .
+                       ' various extensions to produce a single file listing all message files and dirs.'
+               );
        }
 
        public function execute() {
index 68b97e3..77d88f5 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class MigrateFileRepoLayout extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Copy files in repo to a different layout.";
+               $this->addDescription( 'Copy files in repo to a different layout.' );
                $this->addOption( 'oldlayout', "Old layout; one of 'name' or 'sha1'", true, true );
                $this->addOption( 'newlayout', "New layout; one of 'name' or 'sha1'", true, true );
                $this->addOption( 'since', "Copy only files from after this timestamp", false, true );
index dc20eee..df6665a 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class MigrateUserGroup extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Re-assign users from an old group to a new one";
+               $this->addDescription( 'Re-assign users from an old group to a new one' );
                $this->addArg( 'oldgroup', 'Old user group key', true );
                $this->addArg( 'newgroup', 'New user group key', true );
                $this->setBatchSize( 200 );
index c357eeb..16e4d1c 100644 (file)
@@ -40,9 +40,10 @@ class MinifyScript extends Maintenance {
                        "Directory for output. If this is not specified, and neither is --outfile, then the\n" .
                        "output files will be sent to the same directories as the input files.",
                        false, true );
-               $this->mDescription = "Minify a file or set of files.\n\n" .
+               $this->addDescription( "Minify a file or set of files.\n\n" .
                        "If --outfile is not specified, then the output file names will have a .min extension\n" .
-                       "added, e.g. jquery.js -> jquery.min.js.";
+                       "added, e.g. jquery.js -> jquery.min.js."
+               );
        }
 
        public function execute() {
index 43d4d25..8645ab1 100644 (file)
@@ -45,7 +45,7 @@ require_once __DIR__ . '/Maintenance.php';
 class MoveBatch extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Moves a batch of pages";
+               $this->addDescription( 'Moves a batch of pages' );
                $this->addOption( 'u', "User to perform move", false, true );
                $this->addOption( 'r', "Reason to move page", false, true );
                $this->addOption( 'i', "Interval to sleep between moves" );
index 00a15e5..35fca8e 100644 (file)
@@ -46,7 +46,7 @@ class MWDocGen extends Maintenance {
         */
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Build doxygen documentation';
+               $this->addDescription( 'Build doxygen documentation' );
 
                $this->addOption( 'doxygen',
                        'Path to doxygen',
index 6e5cd38..b59f4a9 100644 (file)
@@ -47,7 +47,7 @@ class NamespaceConflictChecker extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "";
+               $this->addDescription( 'Find and fix pages affected by namespace addition/removal' );
                $this->addOption( 'fix', 'Attempt to automatically fix errors' );
                $this->addOption( 'merge', "Instead of renaming conflicts, do a history merge with " .
                        "the correct title" );
index 0f2dbf6..8b45e57 100644 (file)
@@ -44,7 +44,7 @@ require_once __DIR__ . '/Maintenance.php';
 class NukeNS extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Remove pages with only 1 revision from any namespace";
+               $this->addDescription( 'Remove pages with only 1 revision from any namespace' );
                $this->addOption( 'delete', "Actually delete the page" );
                $this->addOption( 'ns', 'Namespace to delete from, default NS_MEDIAWIKI', false, true );
                $this->addOption( 'all', 'Delete everything regardless of revision count' );
index dc45520..44235d5 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class NukePage extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Remove a page record from the database";
+               $this->addDescription( 'Remove a page record from the database' );
                $this->addOption( 'delete', "Actually delete the page" );
                $this->addArg( 'title', 'Title to delete' );
        }
index 67e5ded..ba1e879 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class AlterSharedConstraints extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Alter foreign key to reference master tables in shared database setup.";
+               $this->addDescription( 'Alter foreign key to reference master tables in shared database setup.' );
        }
 
        public function getDbType() {
index 3c5566f..24ead60 100644 (file)
@@ -39,10 +39,11 @@ require_once __DIR__ . '/Maintenance.php';
 class Orphans extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Look for 'orphan' revisions hooked to pages which don't exist\n" .
+               $this->addDescription( "Look for 'orphan' revisions hooked to pages which don't exist\n" .
                        "and 'childless' pages with no revisions\n" .
                        "Then, kill the poor widows and orphans\n" .
-                       "Man this is depressing";
+                       "Man this is depressing"
+               );
                $this->addOption( 'fix', 'Actually fix broken entries' );
        }
 
index f414383..b631005 100644 (file)
@@ -27,7 +27,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PageExists extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Report whether a specific page exists";
+               $this->addDescription( 'Report whether a specific page exists' );
                $this->addArg( 'title', 'Page title to check whether it exists' );
        }
 
index d655965..effed56 100644 (file)
@@ -61,7 +61,7 @@ class CLIParser extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Parse a given wikitext";
+               $this->addDescription( 'Parse a given wikitext' );
                $this->addOption(
                        'title',
                        'Title name for the given wikitext (Default: \'CLIParser\')',
index 1f77bdb..f94046a 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PatchSql extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Run an SQL file into the DB, replacing prefix and charset vars";
+               $this->addDescription( 'Run an SQL file into the DB, replacing prefix and charset vars' );
                $this->addArg(
                        'patch-name',
                        'Name of the patch file, either full path or in maintenance/archives'
index 054f792..901cdaa 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateBacklinkNamespace extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populate the *_from_namespace fields";
+               $this->addDescription( 'Populate the *_from_namespace fields' );
                $this->addOption( 'lastUpdatedId', "Highest page_id with updated links", false, true );
        }
 
index 481e073..5a8ef90 100644 (file)
@@ -35,7 +35,8 @@ class PopulateCategory extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = <<<TEXT
+               $this->addDescription(
+                       <<<TEXT
 This script will populate the category table, added in MediaWiki 1.13.  It will
 print out progress indicators every 1000 categories it adds to the table.  The
 script is perfectly safe to run on large, live wikis, and running it multiple
@@ -49,8 +50,9 @@ added after the software update and so will be populated anyway.
 
 When the script has finished, it will make a note of this in the database, and
 will not run again without the --force option.
-TEXT;
-# '
+TEXT
+               );
+
                $this->addOption(
                        'begin',
                        'Only do categories whose names are alphabetically after the provided name',
index 4f9c7ae..c158cb4 100644 (file)
@@ -30,7 +30,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateContentModel extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Populate the various content_* fields';
+               $this->addDescription( 'Populate the various content_* fields' );
                $this->addOption( 'ns', 'Namespace to run in, or "all" for all namespaces', true, true );
                $this->addOption( 'table', 'Table to run in', true, true );
                $this->setBatchSize( 100 );
index 5a67262..24c25b1 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populate the fa_sha1 field from fa_storage_key";
+               $this->addDescription( 'Populate the fa_sha1 field from fa_storage_key' );
        }
 
        protected function getUpdateKey() {
index cc52239..51cc72a 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateImageSha1 extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populate the img_sha1 field";
+               $this->addDescription( 'Populate the img_sha1 field' );
                $this->addOption( 'force', "Recalculate sha1 for rows that already have a value" );
                $this->addOption( 'multiversiononly', "Calculate only for files with several versions" );
                $this->addOption( 'method', "Use 'pipe' to pipe to mysql command line,\n" .
index 4c1a72e..41c3bc9 100644 (file)
@@ -40,7 +40,7 @@ class PopulateLogSearch extends LoggedUpdateMaintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Migrate log params to new table and index for searching";
+               $this->addDescription( 'Migrate log params to new table and index for searching' );
                $this->setBatchSize( 100 );
        }
 
index 60329c0..ec3c472 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateLogUsertext extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populates the log_user_text field";
+               $this->addDescription( 'Populates the log_user_text field' );
                $this->setBatchSize( 100 );
        }
 
index 9baf28e..beb8cc8 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateParentId extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populates rev_parent_id";
+               $this->addDescription( 'Populates rev_parent_id' );
        }
 
        protected function getUpdateKey() {
index 25a51d7..452d213 100644 (file)
@@ -32,8 +32,8 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateRecentChangesSource extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Populates rc_source field of the recentchanges table with the data in rc_type.";
+               $this->addDescription(
+                       'Populates rc_source field of the recentchanges table with the data in rc_type.' );
                $this->setBatchSize( 100 );
        }
 
index a9fb394..297bed2 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateRevisionLength extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populates the rev_len and ar_len fields";
+               $this->addDescription( 'Populates the rev_len and ar_len fields' );
                $this->setBatchSize( 200 );
        }
 
index 43504b1..3aff77e 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Populates the rev_sha1 and ar_sha1 fields";
+               $this->addDescription( 'Populates the rev_sha1 and ar_sha1 fields' );
                $this->setBatchSize( 200 );
        }
 
index 449a7ad..4a3148a 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class Protect extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Protect or unprotect a page from the command line.";
+               $this->addDescription( 'Protect or unprotect a page from the command line.' );
                $this->addOption( 'unprotect', 'Removes protection' );
                $this->addOption( 'semiprotect', 'Adds semi-protection' );
                $this->addOption( 'cascade', 'Add cascading protection' );
index 455e9c0..8e6978d 100644 (file)
@@ -34,7 +34,7 @@ class PruneFileCache extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Build file cache for content pages";
+               $this->addDescription( 'Build file cache for content pages' );
                $this->addOption( 'agedays', 'How many days old files must be in order to delete', true, true );
                $this->addOption( 'subdir', 'Prune one $wgFileCacheDirectory subdirectory name', false, true );
        }
index b98e95f..4f10b6e 100644 (file)
@@ -61,7 +61,7 @@ class PurgeChangedFiles extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Scan the logging table and purge files and thumbnails.";
+               $this->addDescription( 'Scan the logging table and purge files and thumbnails.' );
                $this->addOption( 'starttime', 'Starting timestamp', true, true );
                $this->addOption( 'endtime', 'Ending timestamp', true, true );
                $this->addOption( 'type', 'Comma-separated list of types of changes to send purges for (' .
index 31500c9..cb4f85d 100644 (file)
@@ -36,7 +36,7 @@ class PurgeChangedPages extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Send purge requests for edits in date range to squid/varnish';
+               $this->addDescription( 'Send purge requests for edits in date range to squid/varnish' );
                $this->addOption( 'starttime', 'Starting timestamp', true, true );
                $this->addOption( 'endtime', 'Ending timestamp', true, true );
                $this->addOption( 'htcp-dest', 'HTCP announcement destination (IP:port)', false, true );
index 9963cbf..a733d67 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PurgeList extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Send purge requests for listed pages to squid";
+               $this->addDescription( 'Send purge requests for listed pages to squid' );
                $this->addOption( 'purge', 'Whether to update page_touched.', false, false );
                $this->addOption( 'namespace', 'Namespace number', false, true );
                $this->addOption( 'all', 'Purge all pages', false, false );
index 3d81e2d..1b78c7d 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class PurgeOldText extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Purge old text records from the database";
+               $this->addDescription( 'Purge old text records from the database' );
                $this->addOption( 'purge', 'Performs the deletion' );
        }
 
index e68937a..4d3baaf 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ReassignEdits extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Reassign edits from one user to another";
+               $this->addDescription( 'Reassign edits from one user to another' );
                $this->addOption( "force", "Reassign even if the target user doesn't exist" );
                $this->addOption( "norc", "Don't update the recent changes table" );
                $this->addOption( "report", "Print out details of what would be changed, but don't update it" );
index e07bf03..21cd3a1 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RebuildFileCache extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Build file cache for content pages";
+               $this->addDescription( 'Build file cache for content pages' );
                $this->addOption( 'start', 'Page_id to start from', false, true );
                $this->addOption( 'end', 'Page_id to end on', false, true );
                $this->addOption( 'overwrite', 'Refresh page cache' );
index 1b0a27d..521ab54 100644 (file)
@@ -51,7 +51,7 @@ class ImageBuilder extends Maintenance {
                // make sure to update old, but compatible img_metadata fields.
                $wgUpdateCompatibleMetadata = true;
 
-               $this->mDescription = 'Script to update image metadata records';
+               $this->addDescription( 'Script to update image metadata records' );
 
                $this->addOption( 'missing', 'Check for files without associated database record' );
                $this->addOption( 'dry-run', 'Only report, don\'t update the database' );
index f89877e..36caa3a 100644 (file)
@@ -39,7 +39,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RebuildLocalisationCache extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Rebuild the localisation cache";
+               $this->addDescription( 'Rebuild the localisation cache' );
                $this->addOption( 'force', 'Rebuild all files, even ones not out of date' );
                $this->addOption( 'threads', 'Fork more than one thread', false, true );
                $this->addOption( 'outdir', 'Override the output directory (normally $wgCacheDirectory)',
index 2bc7510..044bafd 100644 (file)
@@ -32,7 +32,7 @@ class RebuildSitesCache extends Maintenance {
        public function __construct() {
                parent::__construct();
 
-               $this->mDescription = "Cache sites as json for file-based lookup.";
+               $this->addDescription( 'Cache sites as json for file-based lookup.' );
                $this->addOption( 'file', 'File to output the json to', false, true );
        }
 
index 4ff873e..d2ee6fc 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RebuildAll extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Rebuild links, text index and recent changes";
+               $this->addDescription( 'Rebuild links, text index and recent changes' );
        }
 
        public function getDbType() {
index f223f1a..3b40556 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RebuildMessages extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Purge all language messages from the cache";
+               $this->addDescription( 'Purge all language messages from the cache' );
        }
 
        public function execute() {
index 34560fd..d61906c 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RebuildRecentchanges extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Rebuild recent changes";
+               $this->addDescription( 'Rebuild recent changes' );
        }
 
        public function execute() {
index e8d59bc..dff734b 100644 (file)
@@ -42,7 +42,7 @@ class RebuildTextIndex extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Rebuild search index table from scratch";
+               $this->addDescription( 'Rebuild search index table from scratch' );
        }
 
        public function getDbType() {
index 6bc72ec..3f1b167 100644 (file)
@@ -34,7 +34,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RefreshFileHeaders extends Maintenance {
        function __construct() {
                parent::__construct();
-               $this->mDescription = 'Script to update file HTTP headers';
+               $this->addDescription( 'Script to update file HTTP headers' );
                $this->addOption( 'verbose', 'Output information about each file.', false, false, 'v' );
                $this->addOption( 'start', 'Name of file to start with', false, true );
                $this->addOption( 'end', 'Name of file to end with', false, true );
index 4f2341c..01fb15e 100644 (file)
@@ -44,7 +44,7 @@ class RefreshImageMetadata extends Maintenance {
        function __construct() {
                parent::__construct();
 
-               $this->mDescription = 'Script to update image metadata records';
+               $this->addDescription( 'Script to update image metadata records' );
                $this->setBatchSize( 200 );
 
                $this->addOption(
index 1159e53..651255b 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RefreshLinks extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Refresh link tables";
+               $this->addDescription( 'Refresh link tables' );
                $this->addOption( 'dfn-only', 'Delete links from nonexistent articles only' );
                $this->addOption( 'new-only', 'Only affect articles with just a single edit' );
                $this->addOption( 'redirects-only', 'Only fix redirects, not all links' );
index 2218a5e..09b1b1c 100644 (file)
@@ -43,7 +43,8 @@ class DumpRenderer extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Take page text out of an XML dump file and render basic HTML out to files";
+               $this->addDescription(
+                       'Take page text out of an XML dump file and render basic HTML out to files' );
                $this->addOption( 'output-dir', 'The directory to output the HTML files to', true, true );
                $this->addOption( 'prefix', 'Prefix for the rendered files (defaults to wiki)', false, true );
                $this->addOption( 'parser', 'Use an alternative parser class', false, true );
diff --git a/maintenance/resetUserEmail.php b/maintenance/resetUserEmail.php
new file mode 100644 (file)
index 0000000..816e8a4
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Reset user email.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that resets user email.
+ *
+ * @since 1.27
+ * @ingroup Maintenance
+ */
+class ResetUserEmail extends Maintenance {
+       public function __construct() {
+               $this->addDescription( "Resets a user's email" );
+               $this->addArg( 'user', 'Username or user ID, if starts with #', true );
+               $this->addArg( 'email', 'Email to assign' );
+               parent::__construct();
+       }
+
+       public function execute() {
+               $userName = $this->getArg( 0 );
+               if ( preg_match( '/^#\d+$/', $userName ) ) {
+                       $user = User::newFromId( substr( $userName, 1 ) );
+               } else {
+                       $user = User::newFromName( $userName );
+               }
+               if ( !$user || !$user->getId() || !$user->loadFromId() ) {
+                       $this->error( "Error: user '$userName' does not exist\n", 1 );
+               }
+
+               $email = $this->getArg( 1 );
+               if ( !Sanitizer::validateEmail( $email ) ) {
+                       $this->error( "Error: email '$email' is not valid\n", 1 );
+               }
+
+               // Code from https://wikitech.wikimedia.org/wiki/Password_reset
+               $user->setEmail( $email );
+               $user->setEmailAuthenticationTimestamp( wfTimestampNow() );
+               $user->saveSettings();
+               // Kick whomever is currently controlling the account off
+               $user->setPassword( PasswordFactory::generateRandomPasswordString( 128 ) );
+       }
+}
+
+$maintClass = 'ResetUserEmail';
+require_once RUN_MAINTENANCE_IF_MAIN;
index 9c7aef2..7acf975 100644 (file)
@@ -34,8 +34,9 @@ require_once __DIR__ . '/Maintenance.php';
 class ResetUserTokens extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Reset the user_token of all users on the wiki. Note that this may log some of them out.";
+               $this->addDescription(
+                       'Reset the user_token of all users on the wiki. Note that this may log some of them out.'
+               );
                $this->addOption( 'nowarn', "Hides the 5 seconds warning", false, false );
                $this->addOption(
                        'nulls',
index 831e2dc..48d9705 100755 (executable)
@@ -44,9 +44,15 @@ mkdir -p "$REPO_DIR/$TARGET_DIR/i18n"
 mkdir -p "$REPO_DIR/$TARGET_DIR/images"
 mkdir -p "$REPO_DIR/$TARGET_DIR/themes/mediawiki/images"
 mkdir -p "$REPO_DIR/$TARGET_DIR/themes/apex/images"
-cp ./node_modules/oojs-ui/dist/oojs-ui.js "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/{oojs-ui-mediawiki-noimages.css,oojs-ui-mediawiki.js} "$REPO_DIR/$TARGET_DIR"
-cp ./node_modules/oojs-ui/dist/{oojs-ui-apex-noimages.css,oojs-ui-apex.js} "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-core.js "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-core-{mediawiki,apex}.css "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-widgets.js "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-widgets-{mediawiki,apex}.css "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-toolbars.js "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-toolbars-{mediawiki,apex}.css "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-windows.js "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-windows-{mediawiki,apex}.css "$REPO_DIR/$TARGET_DIR"
+cp ./node_modules/oojs-ui/dist/oojs-ui-{mediawiki,apex}.js "$REPO_DIR/$TARGET_DIR"
 cp -R ./node_modules/oojs-ui/dist/i18n "$REPO_DIR/$TARGET_DIR"
 cp -R ./node_modules/oojs-ui/dist/images "$REPO_DIR/$TARGET_DIR"
 cp -R ./node_modules/oojs-ui/dist/themes/mediawiki/images "$REPO_DIR/$TARGET_DIR/themes/mediawiki"
index 7134453..a2ddb93 100644 (file)
@@ -33,8 +33,8 @@ require_once __DIR__ . '/Maintenance.php';
 class RollbackEdits extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Rollback all edits by a given user or IP provided they're the most recent edit";
+               $this->addDescription(
+                       "Rollback all edits by a given user or IP provided they're the most recent edit" );
                $this->addOption(
                        'titles',
                        'A list of titles, none means all titles where the given user is the most recent',
index 3fd9e02..2feae02 100644 (file)
@@ -33,9 +33,9 @@ require_once __DIR__ . '/Maintenance.php';
 class BatchedQueryRunner extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
+               $this->addDescription(
                        "Run a query repeatedly until it affects 0 rows, and wait for slaves in between.\n" .
-                               "NOTE: You need to set a LIMIT clause yourself.";
+                               "NOTE: You need to set a LIMIT clause yourself." );
        }
 
        public function execute() {
index 3c5d28b..86cade2 100644 (file)
@@ -33,7 +33,7 @@ use MediaWiki\Logger\LoggerFactory;
 class RunJobs extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Run pending jobs";
+               $this->addDescription( 'Run pending jobs' );
                $this->addOption( 'maxjobs', 'Maximum number of jobs to run', false, true );
                $this->addOption( 'maxtime', 'Maximum amount of wall-clock time', false, true );
                $this->addOption( 'type', 'Type of job to run', false, true );
index 25a096c..992c238 100644 (file)
@@ -43,7 +43,7 @@ class ShowJobs extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Show number of jobs waiting in master database";
+               $this->addDescription( 'Show number of jobs waiting in master database' );
                $this->addOption( 'group', 'Show number of jobs per job type' );
                $this->addOption( 'list', 'Show a list of all jobs instead of counts' );
                $this->addOption( 'type', 'Only show/count jobs of a given type', false, true );
index 56cc573..098aba5 100644 (file)
@@ -39,7 +39,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ShowSiteStats extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Show the cached statistics";
+               $this->addDescription( 'Show the cached statistics' );
        }
 
        public function execute() {
index a93e51f..f089972 100644 (file)
@@ -32,8 +32,8 @@ require_once __DIR__ . '/Maintenance.php';
 class MwSql extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Send SQL queries to a MediaWiki database. " .
-                               "Takes a file name containing SQL as argument or runs interactively.";
+               $this->addDescription( 'Send SQL queries to a MediaWiki database. ' .
+                       'Takes a file name containing SQL as argument or runs interactively.' );
                $this->addOption( 'query', 'Run a single query instead of running interactively', false, true );
                $this->addOption( 'cluster', 'Use an external cluster by name', false, true );
                $this->addOption( 'wikidb', 'The database wiki ID to use if not the current one', false, true );
index 96a8a38..5cc35ed 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
 class SqliteMaintenance extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Performs some operations specific to SQLite database backend";
+               $this->addDescription( 'Performs some operations specific to SQLite database backend' );
                $this->addOption(
                        'vacuum',
                        'Clean up database by removing deleted pages. Decreases database file size'
index b27b111..dd3ba04 100644 (file)
@@ -63,7 +63,7 @@ class CompressOld extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = 'Compress the text of a wiki';
+               $this->addDescription( 'Compress the text of a wiki' );
                $this->addOption( 'type', 'Set compression type to either: gzip|concat', false, true, 't' );
                $this->addOption(
                        'chunksize',
index e926f56..d353b88 100644 (file)
@@ -36,7 +36,7 @@ class FixBug20757 extends Maintenance {
 
        function __construct() {
                parent::__construct();
-               $this->mDescription = 'Script to fix bug 20757 assuming that blob_tracking is intact';
+               $this->addDescription( 'Script to fix bug 20757 assuming that blob_tracking is intact' );
                $this->addOption( 'dry-run', 'Report only' );
                $this->addOption( 'start', 'old_id to start at', false, true );
        }
index b1bf95b..21f50f5 100644 (file)
@@ -32,8 +32,8 @@ require_once __DIR__ . '/../Maintenance.php';
 class OrphanStats extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription =
-                       "Show some statistics on the blob_orphans table, created with trackBlobs.php";
+               $this->addDescription(
+                       "Show some statistics on the blob_orphans table, created with trackBlobs.php" );
        }
 
        protected function &getDB( $cluster, $groups = array(), $wiki = false ) {
index 63d5e9f..c0663a7 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class SyncFileBackend extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Sync one file backend with another using the journal";
+               $this->addDescription( 'Sync one file backend with another using the journal' );
                $this->addOption( 'src', 'Name of backend to sync from', true, true );
                $this->addOption( 'dst', 'Name of destination backend to sync', false, true );
                $this->addOption( 'start', 'Starting journal ID', false, true );
index 71b4de1..861f5ed 100644 (file)
@@ -26,7 +26,7 @@ require_once __DIR__ . '/Maintenance.php';
 class Undelete extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Undelete a page";
+               $this->addDescription( 'Undelete a page' );
                $this->addOption( 'user', 'The user to perform the undeletion', false, true, 'u' );
                $this->addOption( 'reason', 'The reason to undelete', false, true, 'r' );
                $this->addArg( 'pagename', 'Page to undelete' );
index eeaf9c8..06e947c 100755 (executable)
@@ -36,7 +36,7 @@ require_once __DIR__ . '/Maintenance.php';
 class UpdateMediaWiki extends Maintenance {
        function __construct() {
                parent::__construct();
-               $this->mDescription = "MediaWiki database updater";
+               $this->addDescription( 'MediaWiki database updater' );
                $this->addOption( 'skip-compat-checks', 'Skips compatibility checks, mostly for developers' );
                $this->addOption( 'quick', 'Skip 5 second countdown before starting' );
                $this->addOption( 'doshared', 'Also update shared tables' );
index 9537a79..baba6c8 100644 (file)
@@ -35,7 +35,7 @@ class UpdateArticleCount extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Count of the number of articles and update the site statistics table";
+               $this->addDescription( 'Count of the number of articles and update the site statistics table' );
                $this->addOption( 'update', 'Update the site_stats table with the new count' );
                $this->addOption( 'use-master', 'Count using the master database' );
        }
index bd75b3b..37c9948 100644 (file)
@@ -42,12 +42,13 @@ class UpdateCollation extends Maintenance {
                parent::__construct();
 
                global $wgCategoryCollation;
-               $this->mDescription = <<<TEXT
+               $this->addDescription( <<<TEXT
 This script will find all rows in the categorylinks table whose collation is
 out-of-date (cl_collation != '$wgCategoryCollation') and repopulate cl_sortkey
 using the page title and cl_sortkey_prefix.  If all collations are
 up-to-date, it will do nothing.
-TEXT;
+TEXT
+               );
 
                $this->addOption( 'force', 'Run on all rows, even if the collation is ' .
                        'supposed to be up-to-date.' );
index 5c21b40..f5bb881 100644 (file)
@@ -34,7 +34,7 @@ class UpdateDoubleWidthSearch extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script to normalize double-byte latin UTF-8 characters";
+               $this->addDescription( 'Script to normalize double-byte latin UTF-8 characters' );
                $this->addOption( 'q', 'quiet', false, true );
                $this->addOption(
                        'l',
index ebfffe4..98d9389 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
 class UpdateRestrictions extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Updates page_restrictions table from old page_restriction column";
+               $this->addDescription( 'Updates page_restrictions table from old page_restriction column' );
                $this->setBatchSize( 100 );
        }
 
index 18edecc..b2f2577 100644 (file)
@@ -39,7 +39,7 @@ class UpdateSearchIndex extends Maintenance {
 
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Script for periodic off-peak updating of the search index";
+               $this->setDescription( 'Script for periodic off-peak updating of the search index' );
                $this->addOption( 's', 'starting timestamp', false, true );
                $this->addOption( 'e', 'Ending timestamp', false, true );
                $this->addOption(
index e0c10f8..2534ca6 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/Maintenance.php';
 class WrapOldPasswords extends Maintenance {
        public function __construct() {
                parent::__construct();
-               $this->mDescription = "Wrap all passwords of a certain type in a new layered type";
+               $this->addDescription( 'Wrap all passwords of a certain type in a new layered type' );
                $this->addOption( 'type',
                        'Password type to wrap passwords in (must inherit LayeredParameterizedPassword)', true, true );
                $this->addOption( 'verbose', 'Enables verbose output', false, false, 'v' );
index 458d5f1..7c3bc74 100644 (file)
@@ -1695,6 +1695,61 @@ return array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.js',
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.css',
        ),
+       'mediawiki.special.apisandbox.styles' => array(
+               'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css',
+       ),
+       'mediawiki.special.apisandbox' => array(
+               'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.css',
+               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.js',
+               'dependencies' => array(
+                       'mediawiki.special',
+                       'mediawiki.api',
+                       'mediawiki.jqueryMsg',
+                       'oojs-ui',
+                       'mediawiki.widgets.datetime',
+               ),
+               'messages' => array(
+                       'apisandbox-intro',
+                       'apisandbox-submit',
+                       'apisandbox-reset',
+                       'apisandbox-fullscreen',
+                       'apisandbox-fullscreen-tooltip',
+                       'apisandbox-unfullscreen',
+                       'apisandbox-unfullscreen-tooltip',
+                       'apisandbox-retry',
+                       'apisandbox-loading',
+                       'apisandbox-load-error',
+                       'apisandbox-fetch-token',
+                       'apisandbox-helpurls',
+                       'apisandbox-examples',
+                       'apisandbox-dynamic-parameters',
+                       'apisandbox-dynamic-parameters-add-label',
+                       'apisandbox-dynamic-parameters-add-placeholder',
+                       'apisandbox-dynamic-error-exists',
+                       'apisandbox-deprecated-parameters',
+                       'apisandbox-no-parameters',
+                       'api-help-param-limit',
+                       'api-help-param-limit2',
+                       'api-help-param-integer-min',
+                       'api-help-param-integer-max',
+                       'api-help-param-integer-minmax',
+                       'api-help-param-multi-separate',
+                       'api-help-param-multi-max',
+                       'apisandbox-submit-invalid-fields-title',
+                       'apisandbox-submit-invalid-fields-message',
+                       'apisandbox-results',
+                       'apisandbox-sending-request',
+                       'apisandbox-loading-results',
+                       'apisandbox-results-error',
+                       'apisandbox-request-url-label',
+                       'apisandbox-request-time',
+                       'apisandbox-results-fixtoken',
+                       'apisandbox-results-fixtoken-fail',
+                       'apisandbox-alert-page',
+                       'apisandbox-alert-field',
+                       'blanknamespace',
+               ),
+       ),
        'mediawiki.special.block' => array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.block.js',
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.block.css',
@@ -2036,8 +2091,6 @@ return array(
                        'jquery.byteLimit',
                        // TitleOptionWidget
                        'jquery.autoEllipsis',
-                       // FIXME: Kept for bc
-                       'mediawiki.widgets.CategorySelector',
                ),
                'messages' => array(
                        // NamespaceInputWidget
index d3b74f2..647efa2 100644 (file)
@@ -32,19 +32,38 @@ return call_user_func( function () {
        $themes = array_map( 'strtolower', $themes );
        $themes['default'] = 'mediawiki';
 
+       // Helper function to generate paths to files used in 'skinStyles' and 'skinScripts'.
+       $getSkinSpecific = function ( $module, $ext = 'css' ) use ( $themes ) {
+               return array_combine(
+                       array_keys( $themes ),
+                       array_map( function ( $theme ) use ( $module, $ext ) {
+                               $module = $module ? "$module-" : '';
+                               // TODO Allow extensions to specify this path somehow
+                               return "resources/lib/oojs-ui/oojs-ui-$module$theme.$ext";
+                       }, array_values( $themes ) )
+               );
+       };
+
        $modules = array();
+
+       // Omnibus module.
        $modules['oojs-ui'] = array(
+               'dependencies' => array(
+                       'oojs-ui-core',
+                       'oojs-ui-widgets',
+                       'oojs-ui-toolbars',
+                       'oojs-ui-windows',
+               ),
+               'targets' => array( 'desktop', 'mobile' ),
+       );
+
+       // The core JavaScript library.
+       $modules['oojs-ui-core'] = array(
                'scripts' => array(
-                       'resources/lib/oojs-ui/oojs-ui.js',
+                       'resources/lib/oojs-ui/oojs-ui-core.js',
                        'resources/src/oojs-ui-local.js',
                ),
-               'skinScripts' => array_combine(
-                       array_keys( $themes ),
-                       array_map( function ( $theme ) {
-                               // TODO Allow extensions to specify this path somehow
-                               return "resources/lib/oojs-ui/oojs-ui-$theme.js";
-                       }, array_values( $themes ) )
-               ),
+               'skinScripts' => $getSkinSpecific( null, 'js' ),
                'dependencies' => array(
                        'es5-shim',
                        'oojs',
@@ -54,13 +73,25 @@ return call_user_func( function () {
                        'oojs-ui.styles.textures',
                        'mediawiki.language',
                ),
+               'targets' => array( 'desktop', 'mobile' ),
+       );
+       // This contains only the styles required by core widgets.
+       $modules['oojs-ui-core.styles'] = array(
+               'position' => 'top',
+               'styles' => 'resources/src/oojs-ui-local.css', // HACK, see inside the file
+               'skinStyles' => $getSkinSpecific( 'core' ),
+               'targets' => array( 'desktop', 'mobile' ),
+       );
+
+       // Deprecated old name for the module 'oojs-ui-core.styles'.
+       $modules['oojs-ui.styles'] = $modules['oojs-ui-core.styles'];
+
+       // Additional widgets and layouts module.
+       $modules['oojs-ui-widgets'] = array(
+               'scripts' => 'resources/lib/oojs-ui/oojs-ui-widgets.js',
+               'skinStyles' => $getSkinSpecific( 'widgets' ),
+               'dependencies' => 'oojs-ui-core',
                'messages' => array(
-                       'ooui-dialog-message-accept',
-                       'ooui-dialog-message-reject',
-                       'ooui-dialog-process-continue',
-                       'ooui-dialog-process-dismiss',
-                       'ooui-dialog-process-error',
-                       'ooui-dialog-process-retry',
                        'ooui-outline-control-move-down',
                        'ooui-outline-control-move-up',
                        'ooui-outline-control-remove',
@@ -68,21 +99,33 @@ return call_user_func( function () {
                        'ooui-selectfile-dragdrop-placeholder',
                        'ooui-selectfile-not-supported',
                        'ooui-selectfile-placeholder',
+               ),
+               'targets' => array( 'desktop', 'mobile' ),
+       );
+       // Toolbar and tools module.
+       $modules['oojs-ui-toolbars'] = array(
+               'scripts' => 'resources/lib/oojs-ui/oojs-ui-toolbars.js',
+               'skinStyles' => $getSkinSpecific( 'toolbars' ),
+               'dependencies' => 'oojs-ui-core',
+               'messages' => array(
                        'ooui-toolbar-more',
                        'ooui-toolgroup-collapse',
                        'ooui-toolgroup-expand',
                ),
                'targets' => array( 'desktop', 'mobile' ),
        );
-       $modules['oojs-ui.styles'] = array(
-               'position' => 'top',
-               'styles' => 'resources/src/oojs-ui-local.css', // HACK, see inside the file
-               'skinStyles' => array_combine(
-                       array_keys( $themes ),
-                       array_map( function ( $theme ) {
-                               // TODO Allow extensions to specify this path somehow
-                               return "resources/lib/oojs-ui/oojs-ui-$theme-noimages.css";
-                       }, array_values( $themes ) )
+       // Windows and dialogs module.
+       $modules['oojs-ui-windows'] = array(
+               'scripts' => 'resources/lib/oojs-ui/oojs-ui-windows.js',
+               'skinStyles' => $getSkinSpecific( 'windows' ),
+               'dependencies' => 'oojs-ui-core',
+               'messages' => array(
+                       'ooui-dialog-message-accept',
+                       'ooui-dialog-message-reject',
+                       'ooui-dialog-process-continue',
+                       'ooui-dialog-process-dismiss',
+                       'ooui-dialog-process-error',
+                       'ooui-dialog-process-retry',
                ),
                'targets' => array( 'desktop', 'mobile' ),
        );
diff --git a/resources/lib/oojs-ui/i18n/cdo.json b/resources/lib/oojs-ui/i18n/cdo.json
new file mode 100644 (file)
index 0000000..cb46b43
--- /dev/null
@@ -0,0 +1,23 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Yejianfei"
+               ]
+       },
+       "ooui-outline-control-move-down": "下移項目",
+       "ooui-outline-control-move-up": "上移項目",
+       "ooui-outline-control-remove": "移除項目",
+       "ooui-toolbar-more": "更価",
+       "ooui-toolgroup-expand": "更価",
+       "ooui-toolgroup-collapse": "更少",
+       "ooui-dialog-message-accept": "確定",
+       "ooui-dialog-message-reject": "取消",
+       "ooui-dialog-process-error": "什乇出毛病了",
+       "ooui-dialog-process-dismiss": "關閉",
+       "ooui-dialog-process-retry": "重試",
+       "ooui-dialog-process-continue": "繼續",
+       "ooui-selectfile-button-select": "選擇蜀萆文件",
+       "ooui-selectfile-not-supported": "𣍐支持選擇其文件",
+       "ooui-selectfile-placeholder": "未選文件",
+       "ooui-selectfile-dragdrop-placeholder": "共文件拖遘嚽塊"
+}
index 2cd688e..341d0ff 100644 (file)
@@ -7,7 +7,7 @@
                        "Vahe Gharakhanyan"
                ]
        },
-       "ooui-outline-control-move-down": "Ô»Õ»Õ¥Ö\81Õ¶Õ¥Õ¬ Õ¯Õ¥Õ¿Õ¨",
+       "ooui-outline-control-move-down": "Ô»Õ»Õ¥Ö\81Õ¶Õ¥Õ¬ Õ¶Õ¥Ö\80Ö\84Ö\87",
        "ooui-outline-control-move-up": "Բարձրացնել կետը",
        "ooui-outline-control-remove": "Հեռացնել տարրը",
        "ooui-toolbar-more": "Ավելին",
index 68a25b5..4b95ffc 100644 (file)
@@ -15,7 +15,8 @@
                        "Ontsed",
                        "Alexmar983",
                        "Nemo bis",
-                       "Jdforrester"
+                       "Jdforrester",
+                       "Fringio"
                ]
        },
        "ooui-outline-control-move-down": "Sposta in basso",
@@ -33,5 +34,5 @@
        "ooui-selectfile-button-select": "Seleziona un file",
        "ooui-selectfile-not-supported": "La selezione del file non è supportata",
        "ooui-selectfile-placeholder": "Nessun file è selezionato",
-       "ooui-selectfile-dragdrop-placeholder": "Posiziona i files qui"
+       "ooui-selectfile-dragdrop-placeholder": "Posiziona i file qui"
 }
index db6fa3c..532ba3f 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "OC Ripper"
+                       "OC Ripper",
+                       "Sf"
                ]
        },
        "ooui-outline-control-move-down": "Pomakni stavku dolje",
@@ -16,6 +17,8 @@
        "ooui-dialog-process-dismiss": "Odbaci",
        "ooui-dialog-process-retry": "Pokušajte ponovo",
        "ooui-dialog-process-continue": "Nastavi",
+       "ooui-selectfile-button-select": "Izaberi datoteku",
        "ooui-selectfile-not-supported": "Izbor datoteke nije podržan",
-       "ooui-selectfile-placeholder": "Nijedna datoteka nije odabrana"
+       "ooui-selectfile-placeholder": "Nijedna datoteka nije odabrana",
+       "ooui-selectfile-dragdrop-placeholder": "Prevuci datoteku ovdje"
 }
index f5bfa2c..4109c36 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "David1010"
+                       "David1010",
+                       "Silovan"
                ]
        },
        "ooui-outline-control-move-down": "ელემენტის ქვემოთ გადატანა",
@@ -15,5 +16,9 @@
        "ooui-dialog-process-error": "მოხდა რაღაც შეცდომა",
        "ooui-dialog-process-dismiss": "დამალვა",
        "ooui-dialog-process-retry": "კიდევ სცადეთ",
-       "ooui-dialog-process-continue": "გაგრძელება"
+       "ooui-dialog-process-continue": "გაგრძელება",
+       "ooui-selectfile-button-select": "გეგშაგორით ფაილი",
+       "ooui-selectfile-not-supported": "ფაილიშ აშაგორუა ვა რე ხენწყილი",
+       "ooui-selectfile-placeholder": "ფაილი ვა რე გიშაგორილი",
+       "ooui-selectfile-dragdrop-placeholder": "ქინაჸათით ფაილი ათაქ"
 }
index 9934d9d..132c32d 100644 (file)
@@ -17,7 +17,8 @@
                        "Zhangjintao",
                        "乌拉跨氪",
                        "Great Brightstar",
-                       "Nbdd0121"
+                       "Nbdd0121",
+                       "Yejianfei"
                ]
        },
        "ooui-outline-control-move-down": "向下移动一项",
@@ -33,7 +34,7 @@
        "ooui-dialog-process-retry": "重试",
        "ooui-dialog-process-continue": "继续",
        "ooui-selectfile-button-select": "选择一个文件",
-       "ooui-selectfile-not-supported": "文件选择不受支持",
+       "ooui-selectfile-not-supported": "不支持文件选择器",
        "ooui-selectfile-placeholder": "没有选定文件",
        "ooui-selectfile-dragdrop-placeholder": "将文件拖动至此"
 }
diff --git a/resources/lib/oojs-ui/oojs-ui-apex-noimages.css b/resources/lib/oojs-ui/oojs-ui-apex-noimages.css
deleted file mode 100644 (file)
index a616f4d..0000000
+++ /dev/null
@@ -1,2938 +0,0 @@
-/*!
- * OOjs UI v0.15.1
- * https://www.mediawiki.org/wiki/OOjs_UI
- *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
- * Released under the MIT license
- * http://oojs.mit-license.org
- *
- * Date: 2016-01-26T21:14:25Z
- */
-@-webkit-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@-moz-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@-ms-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@-o-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-/* @noflip */
-.oo-ui-rtl {
-       direction: rtl;
-}
-/* @noflip */
-.oo-ui-ltr {
-       direction: ltr;
-}
-.oo-ui-element-hidden {
-       display: none !important;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       cursor: pointer;
-       display: inline-block;
-       vertical-align: middle;
-       font: inherit;
-       white-space: nowrap;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       display: none;
-}
-.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-frameless {
-       display: inline-block;
-       position: relative;
-}
-.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       display: inline-block;
-       vertical-align: top;
-       text-align: center;
-}
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       color: #333333;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: 0;
-}
-.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.46875em;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 1.875em;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
-       outline: none;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
-       opacity: 1;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #000000;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #333333;
-}
-.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.25em;
-}
-.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
-       padding-left: 0.25em;
-       color: #333333;
-}
-.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:focus {
-       color: #000000;
-}
-.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #087ecc;
-}
-.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #76ab36;
-}
-.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #d45353;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #cccccc;
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       padding: 0.2em 0.8em;
-       border-radius: 0.3em;
-       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-       border: 1px #c9c9c9 solid;
-       -webkit-transition: border-color 100ms ease;
-          -moz-transition: border-color 100ms ease;
-               transition: border-color 100ms ease;
-       background: #eeeeee;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fff', endColorstr='#ddd');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
-       background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:    -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:      -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:         linear-gradient(to bottom, #ffffff 0%, #dddddd 100%);
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
-       border-color: #aaaaaa;
-       outline: none;
-}
-.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       line-height: 1.875em;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       color: black;
-       border-color: #c9c9c9;
-       background: #eeeeee;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ddd', endColorstr='#fff');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
-       background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:    -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:      -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:         linear-gradient(to bottom, #dddddd 0%, #ffffff 100%);
-}
-.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: -0.5em;
-       margin-right: -0.5em;
-}
-.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-right: 0.3em;
-}
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: -0.005em;
-       margin-right: -0.005em;
-}
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-       margin-right: -0.275em;
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       border: 1px solid #a6cee1;
-       background: #cde7f4;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #eaf4fa), color-stop(100%, #b0d9ee));
-       background-image: -webkit-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:    -moz-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:      -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:         linear-gradient(to bottom, #eaf4fa 0%, #b0d9ee 100%);
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       border-color: #9dc2d4;
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       border: 1px solid #a6cee1;
-       background: #cde7f4;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
-       background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:    -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:      -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:         linear-gradient(to bottom, #b0d9ee 0%, #eaf4fa 100%);
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       border: 1px solid #b8d892;
-       background: #daf0be;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f0fbe1', endColorstr='#c3e59a');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f0fbe1), color-stop(100%, #c3e59a));
-       background-image: -webkit-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-       background-image:    -moz-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-       background-image:      -o-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-       background-image:         linear-gradient(to bottom, #f0fbe1 0%, #c3e59a 100%);
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       border-color: #adcb89;
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       border: 1px solid #b8d892;
-       background: #daf0be;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#c3e59a', endColorstr='#f0fbe1');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #c3e59a), color-stop(100%, #f0fbe1));
-       background-image: -webkit-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-       background-image:    -moz-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-       background-image:      -o-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-       background-image:         linear-gradient(to bottom, #c3e59a 0%, #f0fbe1 100%);
-}
-.oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #d45353;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       opacity: 0.5;
-       -webkit-transform: translate3d(0, 0, 0);
-       box-shadow: none;
-       color: #333333;
-       background: #eeeeee;
-       border-color: #cccccc;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
-       border-color: #cccccc;
-       box-shadow: none;
-}
-.oo-ui-clippableElement-clippable {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-draggableElement {
-       cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
-}
-.oo-ui-draggableElement-dragging {
-       cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
-       background: rgba(0, 0, 0, 0.2);
-       opacity: 0.4;
-}
-.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
-       display: inline-block;
-}
-.oo-ui-draggableGroupElement-placeholder {
-       position: absolute;
-       display: block;
-       background: rgba(0, 0, 0, 0.4);
-}
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
-       opacity: 0.8;
-}
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       opacity: 0.8;
-}
-.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
-}
-.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-       overflow-y: hidden;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-       padding: 2em;
-}
-.oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 3em;
-       overflow-y: auto;
-}
-.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
-}
-.oo-ui-bookletLayout-outlinePanel {
-       border-right: 1px solid #dddddd;
-}
-.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 3em;
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 3em;
-}
-.oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
-}
-.oo-ui-fieldLayout {
-       display: block;
-       margin-bottom: 1em;
-}
-.oo-ui-fieldLayout:before,
-.oo-ui-fieldLayout:after {
-       content: " ";
-       display: table;
-}
-.oo-ui-fieldLayout:after {
-       clear: both;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: block;
-       float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       text-align: right;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       display: table;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       display: inline-block;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
-       float: right;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5em;
-}
-.oo-ui-fieldLayout:last-child {
-       margin-bottom: 0;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.5em;
-       margin-right: 5%;
-       width: 35%;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 60%;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-       margin-bottom: 1.25em;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 0.5em;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.5em 0;
-}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
-       margin-top: 0.25em;
-}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       color: #cccccc;
-}
-.oo-ui-fieldLayout-messages {
-       list-style: none none;
-       margin: 0;
-       padding: 0;
-       margin-top: 0.25em;
-       margin-left: 0.25em;
-}
-.oo-ui-fieldLayout-messages > li {
-       margin: 0;
-       padding: 0;
-}
-.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
-       display: none;
-}
-.oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error {
-       color: #d45353;
-}
-.oo-ui-fieldLayout-messages .oo-ui-labelWidget {
-       padding: 0;
-       line-height: 1.875em;
-       vertical-align: middle;
-}
-.oo-ui-actionFieldLayout-input,
-.oo-ui-actionFieldLayout-button {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-actionFieldLayout-input {
-       padding-right: 1em;
-}
-.oo-ui-actionFieldLayout-button {
-       width: 1%;
-       white-space: nowrap;
-}
-.oo-ui-fieldsetLayout {
-       position: relative;
-       margin: 0;
-       padding: 0;
-       border: none;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       display: block;
-       position: absolute;
-}
-.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: inline-block;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
-       float: right;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5em;
-}
-.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
-.oo-ui-fieldsetLayout + .oo-ui-formLayout {
-       margin-top: 2em;
-}
-.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
-       font-size: 1.1em;
-       margin-bottom: 0.5em;
-       padding: 0.25em 0;
-       font-weight: bold;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-       padding-left: 2em;
-       line-height: 1.8em;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0.25em;
-       width: 1.875em;
-       height: 1.875em;
-}
-.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
-}
-.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-formLayout + .oo-ui-fieldsetLayout,
-.oo-ui-formLayout + .oo-ui-formLayout {
-       margin-top: 2em;
-}
-.oo-ui-menuLayout {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-menuLayout-menu,
-.oo-ui-menuLayout-content {
-       position: absolute;
-       -webkit-transition: all 200ms ease;
-          -moz-transition: all 200ms ease;
-               transition: all 200ms ease;
-}
-.oo-ui-menuLayout-menu {
-       height: 18em;
-       width: 18em;
-}
-.oo-ui-menuLayout-content {
-       top: 18em;
-       left: 18em;
-       right: 18em;
-       bottom: 18em;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
-       width: 0 !important;
-       height: 0 !important;
-       overflow: hidden;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       left: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       left: 0;
-       top: 0;
-       right: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
-       right: 0 !important;
-       bottom: 0 !important;
-       left: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       top: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
-       bottom: 0 !important;
-       left: 0 !important;
-       top: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       right: 0;
-       bottom: 0;
-       left: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
-       left: 0 !important;
-       top: 0 !important;
-       right: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       bottom: 0;
-       left: 0;
-       top: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
-}
-.oo-ui-panelLayout {
-       position: relative;
-}
-.oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
-}
-.oo-ui-panelLayout-expanded {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-panelLayout-padded {
-       padding: 1.25em;
-}
-.oo-ui-panelLayout-framed {
-       border-radius: 0.5em;
-       box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
-}
-.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
-       margin: 1em 0;
-}
-.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-       display: block;
-       position: relative;
-}
-.oo-ui-horizontalLayout > .oo-ui-widget {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout {
-       display: inline-block;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout,
-.oo-ui-horizontalLayout > .oo-ui-widget {
-       margin-right: 0.5em;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout:last-child,
-.oo-ui-horizontalLayout > .oo-ui-widget:last-child {
-       margin-right: 0;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout {
-       margin-bottom: 0;
-}
-.oo-ui-popupTool .oo-ui-popupWidget-popup,
-.oo-ui-popupTool .oo-ui-popupWidget-anchor {
-       z-index: 4;
-}
-.oo-ui-popupTool .oo-ui-popupWidget {
-       /* @noflip */
-       margin-left: 1.25em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
-       border: 0;
-       border-radius: 0;
-       margin: 0;
-}
-.oo-ui-toolGroupTool:first-child > .oo-ui-popupToolGroup {
-       border-top-left-radius: 0.3125em;
-       border-bottom-left-radius: 0.3125em;
-}
-.oo-ui-toolGroupTool:last-child > .oo-ui-popupToolGroup {
-       border-top-right-radius: 0.3125em;
-       border-bottom-right-radius: 0.3125em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
-       height: 1.875em;
-       padding: 0.3125em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.1em;
-}
-.oo-ui-toolGroup {
-       display: inline-block;
-       vertical-align: middle;
-       margin: 0.375em;
-       border-radius: 0.3125em;
-       border: 1px solid transparent;
-       -webkit-transition: border-color 250ms ease;
-          -moz-transition: border-color 250ms ease;
-               transition: border-color 250ms ease;
-}
-.oo-ui-toolGroup-empty {
-       display: none;
-}
-.oo-ui-toolGroup .oo-ui-tool-link {
-       text-decoration: none;
-}
-.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
-       margin-left: 0;
-}
-.oo-ui-toolGroup.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #000000;
-}
-.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
-.oo-ui-barToolGroup > .oo-ui-labelElement-label {
-       display: none;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       display: inline-block;
-       position: relative;
-       vertical-align: top;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       display: block;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
-       display: none;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: top;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
-       display: none;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
-       display: inline;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link {
-       outline: 0;
-       cursor: default;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       margin: -1px 0 -1px -1px;
-       border: 1px solid transparent;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:first-child {
-       border-top-left-radius: 0.3125em;
-       border-bottom-left-radius: 0.3125em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:last-child {
-       margin-right: -1px;
-       border-top-right-radius: 0.3125em;
-       border-bottom-right-radius: 0.3125em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       height: 1.875em;
-       padding: 0.3125em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2.1em;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.2);
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background: #f8fbfd;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#F1F7FB', endColorstr='#fff');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0%, #ffffff 100%);
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-left-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link:focus {
-       outline: 0;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 1;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool:focus {
-       outline: 0;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link:focus {
-       outline: 0;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-popupToolGroup {
-       position: relative;
-       height: 2.5em;
-       min-width: 2.5em;
-}
-.oo-ui-popupToolGroup-handle {
-       display: block;
-       cursor: pointer;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       position: absolute;
-}
-.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-       outline: 0;
-       cursor: default;
-}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       display: none;
-       position: absolute;
-       z-index: 4;
-}
-.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-       display: block;
-}
-.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-       left: 0;
-}
-.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-       right: 0;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link {
-       display: table;
-       width: 100%;
-       vertical-align: middle;
-       white-space: nowrap;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       text-align: right;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not(:empty) {
-       padding-left: 3em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
-       min-width: 1.875em;
-}
-.oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 3.125em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 2.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 4.375em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 3.75em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.6em;
-       margin: 0 1em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin: 0 0.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 2.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 2.25em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 1.75em;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.78125em;
-       top: 0;
-       right: 0;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       right: -0.3125em;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3125em;
-       top: 0;
-       left: 0.3125em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-popupToolGroup-header {
-       line-height: 2.6em;
-       margin: 0 0.6em;
-       font-weight: bold;
-}
-.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
-       border-bottom-left-radius: 0;
-       border-bottom-right-radius: 0;
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background: #f8fbfd;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#F1F7FB', endColorstr='#fff');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0%, #ffffff 100%);
-}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       top: 2.5em;
-       margin: 0 -1px;
-       border: 1px solid #cccccc;
-       background-color: white;
-       box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link {
-       padding: 0.3125em 0 0.3125em 0.3125em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
-       min-width: 1.875em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       padding-left: 0.5em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #888888;
-}
-.oo-ui-listToolGroup .oo-ui-tool {
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-listToolGroup .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-       cursor: default;
-}
-.oo-ui-listToolGroup .oo-ui-toolGroup-tools {
-       padding: 0.3125em;
-}
-.oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-listToolGroup .oo-ui-tool {
-       border: 1px solid transparent;
-       margin: -1px 0;
-       padding: 0 0.625em 0 0;
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.1);
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background: #f8fbfd;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#F1F7FB', endColorstr='#fff');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0%, #ffffff 100%);
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-top-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 1;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #dddddd;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-listToolGroup.oo-ui-widget-disabled {
-       color: #cccccc;
-}
-.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
-.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-menuToolGroup {
-       border-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-menuToolGroup .oo-ui-tool {
-       display: block;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-       cursor: default;
-}
-.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 10em;
-}
-.oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 8.125em;
-}
-.oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
-       padding: 0.3125em 0 0.3125em 0;
-}
-.oo-ui-menuToolGroup.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-menuToolGroup.oo-ui-popupToolGroup-active {
-       border-color: rgba(0, 0, 0, 0.25);
-}
-.oo-ui-menuToolGroup .oo-ui-tool {
-       padding: 0 1.25em 0 0.3125em;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: none;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: url("themes/apex/images/icons/check.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/apex/images/icons/check.png");
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: #e1f3ff;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-menuToolGroup.oo-ui-widget-disabled {
-       color: #cccccc;
-       border-color: rgba(0, 0, 0, 0.05);
-}
-.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
-.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-toolbar {
-       clear: both;
-}
-.oo-ui-toolbar-bar {
-       line-height: 1em;
-       position: relative;
-}
-.oo-ui-toolbar-actions {
-       float: right;
-}
-.oo-ui-toolbar-actions .oo-ui-toolbar {
-       display: inline-block;
-}
-.oo-ui-toolbar-tools {
-       display: inline;
-       white-space: nowrap;
-}
-.oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
-       white-space: normal;
-}
-.oo-ui-toolbar-tools .oo-ui-tool {
-       white-space: normal;
-}
-.oo-ui-toolbar-tools,
-.oo-ui-toolbar-actions,
-.oo-ui-toolbar-shadow {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-toolbar-actions .oo-ui-popupWidget {
-       -webkit-touch-callout: default;
-       -webkit-user-select: all;
-          -moz-user-select: all;
-           -ms-user-select: all;
-               user-select: all;
-}
-.oo-ui-toolbar-shadow {
-       background-position: left top;
-       background-repeat: repeat-x;
-       position: absolute;
-       width: 100%;
-       pointer-events: none;
-}
-.oo-ui-toolbar-bar {
-       border-bottom: 1px solid #cccccc;
-       background: #f8fbfd;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fff', endColorstr='#F1F7FB');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #f1f7fb));
-       background-image: -webkit-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-       background-image:    -moz-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-       background-image:      -o-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-       background-image:         linear-gradient(to bottom, #ffffff 0%, #f1f7fb 100%);
-}
-.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-       border: none;
-       background: none;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-framed,
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-framed:last-child {
-       margin-top: 0.4em;
-       margin-bottom: 0.4em;
-       margin-right: 0.5em;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement,
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement {
-       margin: 0;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button,
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button {
-       margin: 0;
-       padding: 0 0.3125em;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
-.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin: 0 1em;
-       line-height: 3.40625em;
-}
-.oo-ui-toolbar-shadow {
-       background-image: /* @embed */ url(themes/apex/images/toolbar-shadow.png);
-       bottom: -9px;
-       height: 9px;
-       opacity: 0.5;
-       -webkit-transition: opacity 500ms ease;
-          -moz-transition: opacity 500ms ease;
-               transition: opacity 500ms ease;
-}
-.oo-ui-optionWidget {
-       position: relative;
-       display: block;
-       padding: 0.25em 0.5em;
-       border: none;
-}
-.oo-ui-optionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
-}
-.oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
-}
-.oo-ui-optionWidget-highlighted {
-       background-color: #e1f3ff;
-}
-.oo-ui-optionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
-}
-.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
-}
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
-}
-.oo-ui-optionWidget.oo-ui-widget-disabled {
-       color: #cccccc;
-}
-.oo-ui-decoratedOptionWidget {
-       padding: 0.5em 2em 0.5em 3em;
-}
-.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-       position: absolute;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       top: 0;
-       height: 100%;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       width: 1.875em;
-       left: 0.5em;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       right: 0.5em;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-buttonSelectWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 0.3em;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonSelectWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 0.3em;
-       border-top-left-radius: 0.3em;
-       margin-left: 0;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 0.3em;
-       border-top-right-radius: 0.3em;
-}
-.oo-ui-radioSelectWidget {
-       padding: 0.75em 0 0.5em 0;
-}
-.oo-ui-buttonOptionWidget {
-       display: inline-block;
-       padding: 0;
-       background-color: transparent;
-}
-.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       position: relative;
-}
-.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       position: static;
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       height: 1.875em;
-}
-.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       margin-top: 0;
-}
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
-}
-.oo-ui-radioOptionWidget {
-       cursor: default;
-       padding: 0;
-       background-color: transparent;
-}
-.oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
-.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
-}
-.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding-left: 0.5em;
-}
-.oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
-       margin-right: 0;
-}
-.oo-ui-labelWidget {
-       display: inline-block;
-       padding: 0.5em 0;
-}
-.oo-ui-iconWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
-       height: 1.875em;
-       width: 1.875em;
-}
-.oo-ui-iconWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
-}
-.oo-ui-indicatorWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
-       height: 0.9375em;
-       width: 0.9375em;
-       margin: 0.46875em;
-}
-.oo-ui-indicatorWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
-}
-.oo-ui-buttonWidget {
-       display: inline-block;
-       vertical-align: middle;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 0.3em;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonGroupWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 0.3em;
-       border-top-left-radius: 0.3em;
-       margin-left: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 0.3em;
-       border-top-right-radius: 0.3em;
-}
-.oo-ui-toggleButtonWidget {
-       display: inline-block;
-       vertical-align: middle;
-       margin-right: 0.5em;
-}
-.oo-ui-toggleButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-toggleSwitchWidget {
-       position: relative;
-       display: inline-block;
-       vertical-align: middle;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       -webkit-transform: translateZ(0);
-          -moz-transform: translateZ(0);
-           -ms-transform: translateZ(0);
-               transform: translateZ(0);
-       height: 2em;
-       width: 4em;
-       border-radius: 1em;
-       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
-       border: 1px solid #cccccc;
-       margin-right: 0.5em;
-       background: #eeeeee;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ddd', endColorstr='#fff');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
-       background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:    -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:      -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-       background-image:         linear-gradient(to bottom, #dddddd 0%, #ffffff 100%);
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
-       cursor: pointer;
-}
-.oo-ui-toggleSwitchWidget-grip {
-       position: absolute;
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       right: 0;
-       left: 0;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-       display: none;
-}
-.oo-ui-toggleSwitchWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-       opacity: 0.5;
-}
-.oo-ui-toggleSwitchWidget-grip {
-       top: 0.25em;
-       left: 0.25em;
-       width: 1.5em;
-       height: 1.5em;
-       margin-top: -1px;
-       border-radius: 1em;
-       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
-       border: 1px #c9c9c9 solid;
-       -webkit-transition: left 250ms ease, margin-left 250ms ease;
-          -moz-transition: left 250ms ease, margin-left 250ms ease;
-               transition: left 250ms ease, margin-left 250ms ease;
-       background: #eeeeee;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fff', endColorstr='#ddd');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
-       background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:    -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:      -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:         linear-gradient(to bottom, #ffffff 0%, #dddddd 100%);
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
-       border-color: #aaaaaa;
-}
-.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-       border-radius: 1em;
-       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       -webkit-transition: opacity 250ms ease;
-          -moz-transition: opacity 250ms ease;
-               transition: opacity 250ms ease;
-       background: #cde7f4;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
-       background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:    -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:      -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-       background-image:         linear-gradient(to bottom, #b0d9ee 0%, #eaf4fa 100%);
-}
-.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow {
-       opacity: 1;
-}
-.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       left: 2.25em;
-       margin-left: -2px;
-}
-.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-       display: block;
-       opacity: 0;
-}
-.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-       left: 0.25em;
-       margin-left: 0;
-}
-.oo-ui-progressBarWidget {
-       max-width: 50em;
-       background-color: #ffffff;
-       border: 1px solid #cccccc;
-       border-radius: 0.25em;
-       overflow: hidden;
-}
-.oo-ui-progressBarWidget-bar {
-       height: 1em;
-       border-right: 1px solid #cccccc;
-       -webkit-transition: width 250ms ease, margin-left 250ms ease;
-          -moz-transition: width 250ms ease, margin-left 250ms ease;
-               transition: width 250ms ease, margin-left 250ms ease;
-       background: #cde7f4;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #eaf4fa), color-stop(100%, #b0d9ee));
-       background-image: -webkit-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:    -moz-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:      -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-       background-image:         linear-gradient(to bottom, #eaf4fa 0%, #b0d9ee 100%);
-}
-.oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
-       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-       width: 40%;
-       margin-left: -10%;
-       border-left: 1px solid #a6cee1;
-}
-.oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.6;
-}
-.oo-ui-actionWidget.oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
-}
-.oo-ui-popupWidget {
-       position: absolute;
-       /* @noflip */
-       left: 0;
-}
-.oo-ui-popupWidget-popup {
-       position: relative;
-       overflow: hidden;
-       z-index: 1;
-}
-.oo-ui-popupWidget-anchor {
-       display: none;
-       z-index: 1;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-       display: block;
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-       background-repeat: no-repeat;
-}
-.oo-ui-popupWidget-head {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       float: right;
-}
-.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       float: left;
-       cursor: default;
-}
-.oo-ui-popupWidget-body {
-       clear: both;
-       overflow: hidden;
-}
-.oo-ui-popupWidget-popup {
-       background-color: #ffffff;
-       border: 1px solid #cccccc;
-       border-radius: 0.25em;
-       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-       margin-top: 6px;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       content: "";
-       position: absolute;
-       width: 0;
-       height: 0;
-       border-style: solid;
-       border-color: transparent;
-       border-top: 0;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
-       bottom: -7px;
-       left: -6px;
-       border-bottom-color: #aaaaaa;
-       border-width: 7px;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       bottom: -7px;
-       left: -5px;
-       border-bottom-color: #ffffff;
-       border-width: 6px;
-}
-.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
-       -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-          -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-               transition: width 100ms ease, height 100ms ease, left 100ms ease;
-}
-.oo-ui-popupWidget-head {
-       height: 2.5em;
-}
-.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       margin: 0.25em;
-}
-.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       margin: 0.75em 1em;
-}
-.oo-ui-popupWidget-body-padded {
-       padding: 0 1em;
-}
-.oo-ui-popupButtonWidget {
-       position: relative;
-}
-.oo-ui-popupButtonWidget .oo-ui-popupWidget {
-       position: absolute;
-       cursor: auto;
-}
-.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1em;
-}
-.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1.25em;
-}
-.oo-ui-inputWidget {
-       margin-right: 0.5em;
-}
-.oo-ui-inputWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonInputWidget {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonInputWidget > button,
-.oo-ui-buttonInputWidget > input {
-       border: 0;
-       padding: 0;
-       background-color: transparent;
-}
-.oo-ui-dropdownInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-dropdownInputWidget select {
-       display: inline-block;
-       width: 100%;
-       resize: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dropdownInputWidget select {
-       background-color: #ffffff;
-       height: 2.5em;
-       padding: 0.5em;
-       font-size: inherit;
-       font-family: inherit;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
-}
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
-       border-color: rgba(0, 0, 0, 0.2);
-       outline: none;
-}
-.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
-       color: #cccccc;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
-}
-.oo-ui-textInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
-       display: inline-block;
-       width: 100%;
-       resize: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-textInputWidget textarea {
-       overflow: auto;
-}
-.oo-ui-textInputWidget input[type="search"] {
-       -webkit-appearance: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-ms-clear {
-       display: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-ms-reveal {
-       display: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-cancel-button,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-button,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-decoration {
-       display: none;
-}
-.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       display: none;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       display: block;
-       position: absolute;
-       top: 0;
-       height: 100%;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: text;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
-}
-.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: block;
-}
-.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       position: absolute;
-       top: 0;
-}
-.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
-       right: 0;
-}
-.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
-       left: 0;
-}
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
-       padding: 0.5em;
-       line-height: 1.275em;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: #ffffff;
-       color: black;
-       border: 1px solid #cccccc;
-       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
-       border-radius: 0.25em;
-       -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
-          -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
-               transition: border-color 250ms ease, box-shadow 250ms ease;
-}
-.oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
-.oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
-       background-color: transparent;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-       outline: none;
-       border-color: #a7dcff;
-       box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-       color: #777777;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-       background-color: #ffdddd;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       color: #dddddd;
-       text-shadow: 0 1px 1px #ffffff;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement input,
-.oo-ui-textInputWidget.oo-ui-iconElement textarea {
-       padding-left: 2.475em;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       width: 1.875em;
-       max-height: 2.375em;
-       margin-left: 0.3em;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement input,
-.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-       padding-right: 2.4875em;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       max-height: 2.375em;
-       margin-right: 0.775em;
-}
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       padding: 0.4em;
-       line-height: 1.5em;
-       color: #888888;
-}
-.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       margin-right: 2.0875em;
-}
-.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-       margin-left: 2.075em;
-}
-.oo-ui-menuSelectWidget {
-       position: absolute;
-       background-color: #ffffff;
-       margin-top: -1px;
-       border: 1px solid #cccccc;
-       border-radius: 0 0 0.25em 0.25em;
-       box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
-}
-.oo-ui-menuSelectWidget input {
-       position: absolute;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       opacity: 0;
-}
-.oo-ui-menuOptionWidget {
-       position: relative;
-}
-.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
-       display: none;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: transparent;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: block;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: transparent;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-       background-color: #e1f3ff;
-}
-.oo-ui-menuSectionOptionWidget {
-       cursor: default;
-       padding: 0.33em 0.75em;
-       color: #888888;
-}
-.oo-ui-dropdownWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       background-color: #ffffff;
-       margin-right: 0.5em;
-}
-.oo-ui-dropdownWidget-handle {
-       width: 100%;
-       display: inline-block;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       position: absolute;
-}
-.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
-       cursor: pointer;
-}
-.oo-ui-dropdownWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-dropdownWidget-handle {
-       height: 2.5em;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
-}
-.oo-ui-dropdownWidget-handle:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       left: 0.25em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       line-height: 2.5em;
-       margin: 0 0.5em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       top: 0;
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.775em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       top: 0;
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3em;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
-       outline: 0;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
-}
-.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
-}
-.oo-ui-selectFileWidget {
-       display: inline-block;
-       vertical-align: middle;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
-}
-.oo-ui-selectFileWidget-selectButton {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       position: relative;
-       overflow: hidden;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > input[type="file"] {
-       position: absolute;
-       margin: 0;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       width: 100%;
-       height: 100%;
-       opacity: 0;
-       z-index: 1;
-       cursor: pointer;
-       padding-top: 100px;
-}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > input[type="file"] {
-       display: none;
-}
-.oo-ui-selectFileWidget-info {
-       width: 100%;
-       display: table-cell;
-       vertical-align: middle;
-       position: relative;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
-       float: left;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
-       float: right;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       position: absolute;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       z-index: 2;
-}
-.oo-ui-selectFileWidget-dropTarget {
-       cursor: default;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget {
-       cursor: pointer;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
-       display: none;
-}
-.oo-ui-selectFileWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       margin-left: 0.5em;
-}
-.oo-ui-selectFileWidget-info {
-       height: 2.4em;
-       background-color: #ffffff;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
-       line-height: 2.3em;
-       margin: 0;
-       overflow: hidden;
-       white-space: nowrap;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       text-overflow: ellipsis;
-       left: 0.5em;
-       right: 0.5em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
-       color: #888888;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       top: 0;
-       width: 1.875em;
-       margin-right: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       height: 2.3em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       top: 0;
-       width: 0.9375em;
-       height: 2.3em;
-       margin-right: 0.775em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       top: 0;
-       width: 1.875em;
-       height: 2.3em;
-       margin-left: 0.3em;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-       color: #cccccc;
-}
-.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       left: 2.475em;
-}
-.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 2.175em;
-}
-.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
-       right: 0;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 4.2625em;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
-       right: 2.0875em;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 0.5em;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 2em;
-}
-.oo-ui-selectFileWidget-dropTarget {
-       line-height: 3.5em;
-       background-color: #ffffff;
-       border: 1px dashed #aaaaaa;
-       padding: 0.5em 1em;
-       margin-bottom: 0.5em;
-       text-align: center;
-       vertical-align: middle;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget:hover,
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop oo-ui-selectfilewidget-droptarget {
-       background-color: #e1f3ff;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-outlineOptionWidget {
-       position: relative;
-       cursor: pointer;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       font-size: 1.1em;
-       padding: 0.75em;
-}
-.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
-}
-.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget-level-0 {
-       padding-left: 3.5em;
-}
-.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
-       left: 1em;
-}
-.oo-ui-outlineOptionWidget-level-1 {
-       padding-left: 5em;
-}
-.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
-       left: 2.5em;
-}
-.oo-ui-outlineOptionWidget-level-2 {
-       padding-left: 6.5em;
-}
-.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
-       left: 4em;
-}
-.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
-       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-       font-weight: bold;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
-       font-style: italic;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-       opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-       color: #777777;
-}
-.oo-ui-outlineControlsWidget {
-       height: 3em;
-       background-color: #ffffff;
-}
-.oo-ui-outlineControlsWidget-items,
-.oo-ui-outlineControlsWidget-movers {
-       float: left;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       float: left;
-       background-position: right center;
-}
-.oo-ui-outlineControlsWidget-items {
-       float: left;
-}
-.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-       float: left;
-}
-.oo-ui-outlineControlsWidget-movers {
-       float: right;
-}
-.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-       float: right;
-}
-.oo-ui-outlineControlsWidget-items,
-.oo-ui-outlineControlsWidget-movers {
-       height: 2em;
-       margin: 0.5em 0.5em 0.5em 0;
-       padding: 0;
-}
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       width: 1.5em;
-       height: 2em;
-       margin: 0.5em 0 0.5em 0.5em;
-       opacity: 0.2;
-}
-.oo-ui-tabSelectWidget {
-       text-align: left;
-       white-space: nowrap;
-       overflow: hidden;
-       background-color: #eeeeee;
-       box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
-}
-.oo-ui-tabOptionWidget {
-       display: inline-block;
-       vertical-align: bottom;
-       padding: 0.5em 1em;
-       margin: 0.5em 0 0 0.75em;
-       border: 1px solid transparent;
-       border-bottom: none;
-       border-top-left-radius: 0.5em;
-       border-top-right-radius: 0.5em;
-}
-.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
-}
-.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
-}
-.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-pressed {
-       background-color: transparent;
-}
-.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
-       background-color: rgba(255, 255, 255, 0.2);
-       border-color: #dddddd;
-}
-.oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
-       background-color: #ffffff;
-       border-color: #dddddd;
-}
-.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
-       background-color: #ffffff;
-       border-color: #dddddd;
-}
-.oo-ui-capsuleMultiSelectWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-capsuleMultiSelectWidget-handle {
-       width: 100%;
-       display: inline-block;
-       position: relative;
-}
-.oo-ui-capsuleMultiSelectWidget-content {
-       position: relative;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
-       display: none;
-}
-.oo-ui-capsuleMultiSelectWidget-group {
-       display: inline;
-}
-.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-capsuleMultiSelectWidget-handle {
-       background-color: #ffffff;
-       cursor: text;
-       min-height: 2.4em;
-       margin-right: 0.5em;
-       padding: 0.15em 0.25em;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-capsuleMultiSelectWidget-handle:last-child {
-       margin-right: 0;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
-       position: absolute;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
-       border: none;
-       line-height: 1.675em;
-       margin: 0;
-       margin-left: 0.2em;
-       padding: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: transparent;
-       color: black;
-       vertical-align: middle;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
-       outline: none;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-right: 2.4875em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
-       right: 0;
-       top: 0;
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.775em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-left: 2.475em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0;
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3em;
-}
-.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-       cursor: default;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon,
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget {
-       border-top-color: #ffffff;
-}
-.oo-ui-capsuleItemWidget {
-       position: relative;
-       display: inline-block;
-       cursor: default;
-       white-space: nowrap;
-       width: auto;
-       max-width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       vertical-align: middle;
-       padding: 0 0.4em;
-       margin: 0.1em;
-       height: 1.7em;
-       line-height: 1.7em;
-       background: #eeeeee;
-       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fff', endColorstr='#ddd');
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
-       background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:    -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:      -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-       background-image:         linear-gradient(to bottom, #ffffff 0%, #dddddd 100%);
-       border: 1px solid #cccccc;
-       color: #555555;
-       border-radius: 0.25em;
-}
-.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon {
-       cursor: pointer;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon {
-       cursor: default;
-}
-.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       text-overflow: ellipsis;
-       overflow: hidden;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       padding-right: 1.3375em;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       position: absolute;
-       right: 0.4em;
-       top: 0;
-       width: 0.9375em;
-       height: 100%;
-       background-repeat: no-repeat;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicator-clear {
-       cursor: pointer;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
-       opacity: 0.5;
-       -webkit-transform: translate3d(0, 0, 0);
-       box-shadow: none;
-       color: #333333;
-       background: #eeeeee;
-       border-color: #cccccc;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-comboBoxInputWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
-}
-.oo-ui-comboBoxInputWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
-}
-.oo-ui-comboBoxInputWidget-php input::-webkit-calendar-picker-indicator {
-       opacity: 0 !important;
-       position: absolute;
-       right: 0;
-       top: 0;
-       height: 2.5em;
-       width: 2.5em;
-       padding: 0;
-}
-.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
-       pointer-events: none;
-}
-.oo-ui-comboBoxInputWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-comboBoxInputWidget-empty .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       cursor: default;
-       opacity: 0.2;
-}
-.oo-ui-comboBoxInputWidget > .oo-ui-selectWidget {
-       margin-top: -3px;
-}
-.oo-ui-searchWidget-query {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       width: 100%;
-}
-.oo-ui-searchWidget-results {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       overflow-x: hidden;
-       overflow-y: auto;
-}
-.oo-ui-searchWidget-query {
-       height: 4em;
-       padding: 0 1em;
-       box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
-}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       margin: 0.75em 0;
-}
-.oo-ui-searchWidget-results {
-       top: 4em;
-       padding: 1em;
-       line-height: 0;
-}
-.oo-ui-numberInputWidget {
-       display: inline-block;
-       position: relative;
-       max-width: 50em;
-}
-.oo-ui-numberInputWidget-field {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
-       width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
-       white-space: nowrap;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
-       width: 2.25em;
-}
-.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       border-top-right-radius: 0;
-       border-bottom-right-radius: 0;
-       border-right-width: 0;
-}
-.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       border-top-left-radius: 0;
-       border-bottom-left-radius: 0;
-       border-left-width: 0;
-}
-.oo-ui-numberInputWidget .oo-ui-textInputWidget input {
-       border-radius: 0;
-}
-.oo-ui-window {
-       background-color: transparent;
-       background-image: none;
-}
-.oo-ui-window-frame {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-window-content:focus {
-       outline: none;
-}
-.oo-ui-window-head,
-.oo-ui-window-foot {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-window-body {
-       margin: 0;
-       padding: 0;
-       background: none;
-}
-.oo-ui-window-overlay {
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-head,
-.oo-ui-dialog-content > .oo-ui-window-body,
-.oo-ui-dialog-content > .oo-ui-window-foot {
-       position: absolute;
-       left: 0;
-       right: 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dialog-content > .oo-ui-window-head {
-       overflow: hidden;
-       z-index: 1;
-       top: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-body {
-       overflow: auto;
-       z-index: 2;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-foot {
-       overflow: hidden;
-       z-index: 1;
-       bottom: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-body {
-       box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
-}
-.oo-ui-messageDialog-actions-horizontal {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       display: table-cell;
-       width: 1%;
-}
-.oo-ui-messageDialog-actions-vertical {
-       display: block;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       display: block;
-       overflow: hidden;
-       text-overflow: ellipsis;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       position: relative;
-       text-align: center;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       display: block;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-       position: relative;
-       top: auto;
-       bottom: auto;
-       display: inline;
-       white-space: nowrap;
-}
-.oo-ui-messageDialog-content .oo-ui-window-body {
-       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
-}
-.oo-ui-messageDialog-title,
-.oo-ui-messageDialog-message {
-       display: block;
-       text-align: center;
-}
-.oo-ui-messageDialog-title.oo-ui-labelElement,
-.oo-ui-messageDialog-message.oo-ui-labelElement {
-       padding-top: 0.5em;
-}
-.oo-ui-messageDialog-title {
-       font-size: 1.5em;
-       line-height: 1em;
-       color: #000000;
-}
-.oo-ui-messageDialog-message {
-       font-size: 0.9em;
-       line-height: 1.25em;
-       color: #666666;
-}
-.oo-ui-messageDialog-message-verbose {
-       font-size: 1.1em;
-       line-height: 1.5em;
-       text-align: left;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       border-right: 1px solid #e5e5e5;
-       margin: 0;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-       border-right-width: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       border-bottom: 1px solid #e5e5e5;
-       margin: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-       border-bottom-width: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       height: 3.4em;
-       margin-right: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       text-align: center;
-       line-height: 3.4em;
-       padding: 0 2em;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
-}
-.oo-ui-processDialog-location {
-       overflow: hidden;
-       text-overflow: ellipsis;
-       white-space: nowrap;
-}
-.oo-ui-processDialog-title {
-       display: inline;
-       padding: 0;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-       white-space: nowrap;
-}
-.oo-ui-processDialog-actions-safe,
-.oo-ui-processDialog-actions-primary {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-processDialog-actions-safe {
-       left: 0;
-}
-.oo-ui-processDialog-actions-primary {
-       right: 0;
-}
-.oo-ui-processDialog-errors {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       z-index: 2;
-       overflow-x: hidden;
-       overflow-y: auto;
-}
-.oo-ui-processDialog-content .oo-ui-window-head {
-       height: 3.4em;
-}
-.oo-ui-processDialog-content .oo-ui-window-body {
-       top: 3.4em;
-       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
-}
-.oo-ui-processDialog-navigation {
-       position: relative;
-       height: 3.4em;
-       padding: 0 1em;
-}
-.oo-ui-processDialog-location {
-       padding: 0.75em 0;
-       height: 1.875em;
-       cursor: default;
-       text-align: center;
-}
-.oo-ui-processDialog-title {
-       font-weight: bold;
-       line-height: 1.875em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       min-width: 1.875em;
-       min-height: 1.875em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
-       line-height: 1.875em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       margin-top: -0.125em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-       margin: 0.75em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       padding: 0 1em;
-       vertical-align: middle;
-       margin: -1px;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
-       margin: 0;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
-       padding: 0.75em 1em;
-       vertical-align: middle;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
-}
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
-       margin-right: 0;
-}
-.oo-ui-processDialog > .oo-ui-window-frame {
-       min-height: 5em;
-}
-.oo-ui-processDialog-errors {
-       background-color: rgba(255, 255, 255, 0.9);
-       padding: 3em 3em 1.5em 3em;
-       text-align: center;
-}
-.oo-ui-processDialog-errors .oo-ui-buttonWidget {
-       margin: 2em 1em 2em 1em;
-}
-.oo-ui-processDialog-errors-title {
-       font-size: 1.5em;
-       color: #000000;
-       margin-bottom: 2em;
-}
-.oo-ui-processDialog-error {
-       text-align: left;
-       margin: 1em;
-       padding: 1em;
-       border: 1px solid #ff9e9e;
-       background-color: #fff7f7;
-       border-radius: 0.25em;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog {
-       position: fixed;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
-       width: auto;
-       height: auto;
-       top: 0;
-       right: 0;
-       bottom: 0;
-       left: 0;
-       padding: 1em;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-       position: absolute;
-       right: 0;
-       left: 0;
-       margin: auto;
-       overflow: hidden;
-       max-width: 100%;
-       max-height: 100%;
-}
-.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-       width: 100%;
-       height: 100%;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog {
-       background-color: rgba(255, 255, 255, 0.5);
-       opacity: 0;
-       -webkit-transition: opacity 250ms ease;
-          -moz-transition: opacity 250ms ease;
-               transition: opacity 250ms ease;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       background-color: #ffffff;
-       opacity: 0;
-       -webkit-transform: scale(0.5);
-          -moz-transform: scale(0.5);
-           -ms-transform: scale(0.5);
-               transform: scale(0.5);
-       -webkit-transition: all 250ms ease;
-          -moz-transition: all 250ms ease;
-               transition: all 250ms ease;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-       opacity: 1;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-       opacity: 1;
-       -webkit-transform: scale(1);
-          -moz-transform: scale(1);
-           -ms-transform: scale(1);
-               transform: scale(1);
-}
-.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-       top: 1em;
-       bottom: 1em;
-       border: 1px solid #cccccc;
-       border-radius: 0.5em;
-       box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
-}
index 5f9c93c..83ffbd7 100644 (file)
@@ -1,13 +1,17 @@
 /*!
- * OOjs UI v0.15.1
+ * OOjs UI v0.15.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-01-26T21:14:23Z
+ * Date: 2016-02-02T22:07:00Z
  */
+( function ( OO ) {
+
+'use strict';
+
 /**
  * @class
  * @extends OO.ui.Theme
@@ -26,3 +30,5 @@ OO.inheritClass( OO.ui.ApexTheme, OO.ui.Theme );
 /* Instantiation */
 
 OO.ui.theme = new OO.ui.ApexTheme();
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui-core-apex.css b/resources/lib/oojs-ui/oojs-ui-core-apex.css
new file mode 100644 (file)
index 0000000..168ab71
--- /dev/null
@@ -0,0 +1,1128 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-ms-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-o-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-element-hidden {
+       display: none !important;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+       cursor: pointer;
+       display: inline-block;
+       vertical-align: middle;
+       font: inherit;
+       white-space: nowrap;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       display: none;
+}
+.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+       cursor: default;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-frameless {
+       display: inline-block;
+       position: relative;
+}
+.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+       display: inline-block;
+       vertical-align: top;
+       text-align: center;
+}
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       cursor: default;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+       color: #333333;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       margin-left: 0;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.46875em;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       margin-left: 0.46875em;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       width: 1.875em;
+       height: 1.875em;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
+       outline: none;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
+       opacity: 1;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+       color: #000000;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #333333;
+}
+.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       margin-left: 0.25em;
+}
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
+       padding-left: 0.25em;
+       color: #333333;
+}
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:focus {
+       color: #000000;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #087ecc;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #76ab36;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #d45353;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #cccccc;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+       padding: 0.2em 0.8em;
+       border-radius: 0.3em;
+       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+       border: 1px #c9c9c9 solid;
+       -webkit-transition: border-color 100ms ease;
+          -moz-transition: border-color 100ms ease;
+               transition: border-color 100ms ease;
+       background-color: #eeeeee;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
+       background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:         linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
+       border-color: #aaaaaa;
+       outline: none;
+}
+.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       line-height: 1.875em;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+       color: black;
+       border-color: #c9c9c9;
+       background-color: #eeeeee;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #dddddd), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #dddddd 0, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #dddddd 0, #ffffff 100%);
+       background-image:         linear-gradient(to bottom, #dddddd 0, #ffffff 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       margin-left: -0.5em;
+       margin-right: -0.5em;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       margin-right: 0.3em;
+}
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       margin-left: -0.005em;
+       margin-right: -0.005em;
+}
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       margin-left: 0.46875em;
+       margin-right: -0.275em;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
+       border: 1px solid #a6cee1;
+       background-color: #cde7f4;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
+       background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+       background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+       background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+       border-color: #9dc2d4;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       border: 1px solid #a6cee1;
+       background-color: #cde7f4;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
+       background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+       background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+       background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+       border: 1px solid #b8d892;
+       background-color: #daf0bd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f0fbe1), color-stop(100%, #c3e59a));
+       background-image: -webkit-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
+       background-image:    -moz-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
+       background-image:         linear-gradient(to bottom, #f0fbe1 0, #c3e59a 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff0fbe1', endColorstr='#ffc3e59a' )";
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+       border-color: #adcb89;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       border: 1px solid #b8d892;
+       background-color: #daf0bd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #c3e59a), color-stop(100%, #f0fbe1));
+       background-image: -webkit-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
+       background-image:    -moz-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
+       background-image:         linear-gradient(to bottom, #c3e59a 0, #f0fbe1 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffc3e59a', endColorstr='#fff0fbe1' )";
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+       color: #d45353;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       opacity: 0.5;
+       -webkit-transform: translate3d(0, 0, 0);
+       box-shadow: none;
+       color: #333333;
+       background: #eeeeee;
+       border-color: #cccccc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
+       border-color: #cccccc;
+       box-shadow: none;
+}
+.oo-ui-clippableElement-clippable {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-iconElement.oo-ui-iconElement-icon {
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-iconElement.oo-ui-iconElement-icon {
+       opacity: 0.8;
+}
+.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+       opacity: 0.8;
+}
+.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
+}
+.oo-ui-fieldLayout {
+       display: block;
+       margin-bottom: 1em;
+}
+.oo-ui-fieldLayout:before,
+.oo-ui-fieldLayout:after {
+       content: " ";
+       display: table;
+}
+.oo-ui-fieldLayout:after {
+       clear: both;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       display: block;
+       float: left;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       text-align: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+       display: table;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       display: inline-block;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
+       float: right;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+       z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
+       padding: 0.5em 0.75em;
+       line-height: 1.5em;
+}
+.oo-ui-fieldLayout:last-child {
+       margin-bottom: 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding-top: 0.5em;
+       margin-right: 5%;
+       width: 35%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       width: 60%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
+       margin-bottom: 1.25em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding: 0.25em 0.25em 0.25em 0.5em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding: 0.5em 0;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+       margin-top: 0.25em;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       color: #cccccc;
+}
+.oo-ui-fieldLayout-messages {
+       list-style: none none;
+       margin: 0;
+       padding: 0;
+       margin-top: 0.25em;
+       margin-left: 0.25em;
+}
+.oo-ui-fieldLayout-messages > li {
+       margin: 0;
+       padding: 0;
+}
+.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
+       display: none;
+}
+.oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error {
+       color: #d45353;
+}
+.oo-ui-fieldLayout-messages .oo-ui-labelWidget {
+       padding: 0;
+       line-height: 1.875em;
+       vertical-align: middle;
+}
+.oo-ui-actionFieldLayout-input,
+.oo-ui-actionFieldLayout-button {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-actionFieldLayout-input {
+       padding-right: 1em;
+}
+.oo-ui-actionFieldLayout-button {
+       width: 1%;
+       white-space: nowrap;
+}
+.oo-ui-fieldsetLayout {
+       position: relative;
+       margin: 0;
+       padding: 0;
+       border: none;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+       display: block;
+       position: absolute;
+}
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
+       display: inline-block;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
+       float: right;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+       z-index: 1;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
+       padding: 0.5em 0.75em;
+       line-height: 1.5em;
+}
+.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
+.oo-ui-fieldsetLayout + .oo-ui-formLayout {
+       margin-top: 2em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
+       font-size: 1.1em;
+       margin-bottom: 0.5em;
+       padding: 0.25em 0;
+       font-weight: bold;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
+       padding-left: 2em;
+       line-height: 1.8em;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+       left: 0;
+       top: 0.25em;
+       width: 1.875em;
+       height: 1.875em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-formLayout + .oo-ui-fieldsetLayout,
+.oo-ui-formLayout + .oo-ui-formLayout {
+       margin-top: 2em;
+}
+.oo-ui-panelLayout {
+       position: relative;
+}
+.oo-ui-panelLayout-scrollable {
+       overflow-y: auto;
+}
+.oo-ui-panelLayout-expanded {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-panelLayout-padded {
+       padding: 1.25em;
+}
+.oo-ui-panelLayout-framed {
+       border-radius: 0.5em;
+       box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
+       margin: 1em 0;
+}
+.oo-ui-horizontalLayout > .oo-ui-widget {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout {
+       display: inline-block;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout,
+.oo-ui-horizontalLayout > .oo-ui-widget {
+       margin-right: 0.5em;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout:last-child,
+.oo-ui-horizontalLayout > .oo-ui-widget:last-child {
+       margin-right: 0;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout {
+       margin-bottom: 0;
+}
+.oo-ui-optionWidget {
+       position: relative;
+       display: block;
+       padding: 0.25em 0.5em;
+       border: none;
+}
+.oo-ui-optionWidget.oo-ui-widget-enabled {
+       cursor: pointer;
+}
+.oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: block;
+       white-space: nowrap;
+       text-overflow: ellipsis;
+       overflow: hidden;
+}
+.oo-ui-optionWidget-highlighted {
+       background-color: #e1f3ff;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+       line-height: 1.5em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
+       background-color: #a7dcff;
+}
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
+       background-color: #a7dcff;
+}
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+       color: #cccccc;
+}
+.oo-ui-decoratedOptionWidget {
+       padding: 0.5em 2em 0.5em 3em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+       position: absolute;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       top: 0;
+       height: 100%;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       width: 1.875em;
+       left: 0.5em;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       right: 0.5em;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-radioSelectWidget {
+       padding: 0.75em 0 0.5em 0;
+}
+.oo-ui-radioOptionWidget {
+       cursor: default;
+       padding: 0;
+       background-color: transparent;
+}
+.oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
+.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: transparent;
+}
+.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       padding-left: 0.5em;
+}
+.oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
+       margin-right: 0;
+}
+.oo-ui-labelWidget {
+       display: inline-block;
+       padding: 0.5em 0;
+}
+.oo-ui-iconWidget {
+       display: inline-block;
+       vertical-align: middle;
+       line-height: 2.5em;
+       height: 1.875em;
+       width: 1.875em;
+}
+.oo-ui-iconWidget.oo-ui-widget-disabled {
+       opacity: 0.2;
+}
+.oo-ui-indicatorWidget {
+       display: inline-block;
+       vertical-align: middle;
+       line-height: 2.5em;
+       height: 0.9375em;
+       width: 0.9375em;
+       margin: 0.46875em;
+}
+.oo-ui-indicatorWidget.oo-ui-widget-disabled {
+       opacity: 0.2;
+}
+.oo-ui-buttonWidget {
+       display: inline-block;
+       vertical-align: middle;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget {
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 0.3em;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonGroupWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+       border-radius: 0;
+       margin-left: -1px;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
+       border-bottom-left-radius: 0.3em;
+       border-top-left-radius: 0.3em;
+       margin-left: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
+       border-bottom-right-radius: 0.3em;
+       border-top-right-radius: 0.3em;
+}
+.oo-ui-popupWidget {
+       position: absolute;
+       /* @noflip */
+       left: 0;
+}
+.oo-ui-popupWidget-popup {
+       position: relative;
+       overflow: hidden;
+       z-index: 1;
+}
+.oo-ui-popupWidget-anchor {
+       display: none;
+       z-index: 1;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
+       display: block;
+       position: absolute;
+       top: 0;
+       /* @noflip */
+       left: 0;
+       background-repeat: no-repeat;
+}
+.oo-ui-popupWidget-head {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
+       float: right;
+}
+.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
+       float: left;
+       cursor: default;
+}
+.oo-ui-popupWidget-body {
+       clear: both;
+       overflow: hidden;
+}
+.oo-ui-popupWidget-popup {
+       background-color: #ffffff;
+       border: 1px solid #cccccc;
+       border-radius: 0.25em;
+       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
+       margin-top: 6px;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
+       content: "";
+       position: absolute;
+       width: 0;
+       height: 0;
+       border-style: solid;
+       border-color: transparent;
+       border-top: 0;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
+       bottom: -7px;
+       left: -6px;
+       border-bottom-color: #aaaaaa;
+       border-width: 7px;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
+       bottom: -7px;
+       left: -5px;
+       border-bottom-color: #ffffff;
+       border-width: 6px;
+}
+.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
+       -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+          -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+               transition: width 100ms ease, height 100ms ease, left 100ms ease;
+}
+.oo-ui-popupWidget-head {
+       height: 2.5em;
+}
+.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
+       margin: 0.25em;
+}
+.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
+       margin: 0.75em 1em;
+}
+.oo-ui-popupWidget-body-padded {
+       padding: 0 1em;
+}
+.oo-ui-popupButtonWidget {
+       position: relative;
+}
+.oo-ui-popupButtonWidget .oo-ui-popupWidget {
+       position: absolute;
+       cursor: auto;
+}
+.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
+       /* @noflip */
+       left: 1em;
+}
+.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
+       /* @noflip */
+       left: 1.25em;
+}
+.oo-ui-inputWidget {
+       margin-right: 0.5em;
+}
+.oo-ui-inputWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonInputWidget {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonInputWidget > button,
+.oo-ui-buttonInputWidget > input {
+       border: 0;
+       padding: 0;
+       background-color: transparent;
+}
+.oo-ui-dropdownInputWidget {
+       position: relative;
+       vertical-align: middle;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-dropdownInputWidget select {
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dropdownInputWidget select {
+       background-color: #ffffff;
+       height: 2.5em;
+       padding: 0.5em;
+       font-size: inherit;
+       font-family: inherit;
+       border: 1px solid rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
+       border-color: rgba(0, 0, 0, 0.2);
+       outline: none;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
+       color: #cccccc;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
+       margin-bottom: 0;
+}
+.oo-ui-textInputWidget {
+       position: relative;
+       vertical-align: middle;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-textInputWidget textarea {
+       overflow: auto;
+}
+.oo-ui-textInputWidget input[type="search"] {
+       -webkit-appearance: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-ms-clear {
+       display: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-ms-reveal {
+       display: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-decoration,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-cancel-button,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-button,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-decoration {
+       display: none;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       display: none;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
+       display: block;
+       position: absolute;
+       top: 0;
+       height: 100%;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+       cursor: text;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
+       cursor: pointer;
+}
+.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
+       display: block;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       position: absolute;
+       top: 0;
+}
+.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
+       right: 0;
+}
+.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
+       left: 0;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+       padding: 0.5em;
+       line-height: 1.275em;
+       font-size: inherit;
+       font-family: inherit;
+       background-color: #ffffff;
+       color: black;
+       border: 1px solid #cccccc;
+       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
+       border-radius: 0.25em;
+       -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
+          -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
+               transition: border-color 250ms ease, box-shadow 250ms ease;
+}
+.oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
+.oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
+       background-color: transparent;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+       outline: none;
+       border-color: #a7dcff;
+       box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
+       color: #777777;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
+       background-color: #ffdddd;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled input,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
+       color: #dddddd;
+       text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement input,
+.oo-ui-textInputWidget.oo-ui-iconElement textarea {
+       padding-left: 2.475em;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       width: 1.875em;
+       max-height: 2.375em;
+       margin-left: 0.3em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement input,
+.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
+       padding-right: 2.4875em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       max-height: 2.375em;
+       margin-right: 0.775em;
+}
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       padding: 0.4em;
+       line-height: 1.5em;
+       color: #888888;
+}
+.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
+       margin-right: 2.0875em;
+}
+.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
+       margin-left: 2.075em;
+}
+.oo-ui-menuSelectWidget {
+       position: absolute;
+       background-color: #ffffff;
+       margin-top: -1px;
+       border: 1px solid #cccccc;
+       border-radius: 0 0 0.25em 0.25em;
+       box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
+}
+.oo-ui-menuSelectWidget input {
+       position: absolute;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+       opacity: 0;
+}
+.oo-ui-menuOptionWidget {
+       position: relative;
+}
+.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
+       display: none;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
+       background-color: transparent;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
+       display: block;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
+       background-color: transparent;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
+       background-color: #e1f3ff;
+}
+.oo-ui-menuSectionOptionWidget {
+       cursor: default;
+       padding: 0.33em 0.75em;
+       color: #888888;
+}
+.oo-ui-dropdownWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+       background-color: #ffffff;
+       margin-right: 0.5em;
+}
+.oo-ui-dropdownWidget-handle {
+       width: 100%;
+       display: inline-block;
+       white-space: nowrap;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       position: absolute;
+}
+.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
+       cursor: pointer;
+}
+.oo-ui-dropdownWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-dropdownWidget-handle {
+       height: 2.5em;
+       border: 1px solid rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
+}
+.oo-ui-dropdownWidget-handle:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       left: 0.25em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       line-height: 2.5em;
+       margin: 0 0.5em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+       top: 0;
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.775em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       top: 0;
+       width: 1.875em;
+       height: 1.875em;
+       margin: 0.3em;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
+       outline: 0;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       margin-left: 3em;
+}
+.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       margin-right: 2em;
+}
+.oo-ui-comboBoxInputWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+       margin-right: 0.5em;
+}
+.oo-ui-comboBoxInputWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+       cursor: pointer;
+}
+.oo-ui-comboBoxInputWidget-php input::-webkit-calendar-picker-indicator {
+       opacity: 0 !important;
+       position: absolute;
+       right: 0;
+       top: 0;
+       height: 2.5em;
+       width: 2.5em;
+       padding: 0;
+}
+.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
+       pointer-events: none;
+}
+.oo-ui-comboBoxInputWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-comboBoxInputWidget-empty .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       cursor: default;
+       opacity: 0.2;
+}
+.oo-ui-comboBoxInputWidget > .oo-ui-selectWidget {
+       margin-top: -3px;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
new file mode 100644 (file)
index 0000000..fe0d45b
--- /dev/null
@@ -0,0 +1,1380 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-element-hidden {
+       display: none !important;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+       cursor: pointer;
+       display: inline-block;
+       vertical-align: middle;
+       font: inherit;
+       white-space: nowrap;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       display: none;
+}
+.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+       cursor: default;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-frameless {
+       display: inline-block;
+       position: relative;
+}
+.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+       display: inline-block;
+       vertical-align: top;
+       text-align: center;
+}
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       cursor: default;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+       font-weight: bold;
+       text-decoration: none;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       margin-left: 0;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       height: 0.9375em;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       margin-left: 0.46875em;
+}
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       width: 1.875em;
+       height: 1.875em;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.2);
+       outline: none;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
+       margin-right: 0;
+}
+.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       margin-left: 0.25em;
+       margin-right: 0.25em;
+}
+.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
+       padding-left: 0.25em;
+       padding-right: 0.25em;
+       color: #333333;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > input.oo-ui-buttonElement-button,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #555555;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #444444;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+       color: #2962cc;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #347bff;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #1f4999;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+       color: #008064;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #00af89;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #005946;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+       color: #8c130d;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #d11d13;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       color: #73100a;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+       color: #cccccc;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus {
+       box-shadow: none;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
+       padding-left: 2.4em;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+       padding: 0.5em 1em;
+       min-height: 1.2em;
+       min-width: 1em;
+       border-radius: 2px;
+       position: relative;
+       -webkit-transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
+          -moz-transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
+               transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
+       outline: none;
+}
+.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       line-height: 1.2em;
+       display: inline-block;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       position: absolute;
+       top: 0.2em;
+       left: 0.5625em;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       margin-left: 0.3em;
+}
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       display: inline-block;
+}
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       margin-left: 0.46875em;
+       margin-right: -0.275em;
+}
+.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+       position: relative;
+       left: 0.2em;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+       background: #dddddd;
+       color: #ffffff;
+       border: 1px solid #dddddd;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+       color: #555555;
+       background-color: #ffffff;
+       border: 1px solid #cccccc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+       background-color: #ebebeb;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       background-color: #d9d9d9;
+       border-color: #d9d9d9;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
+       color: #347bff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
+       background-color: rgba(52, 123, 255, 0.1);
+       border-color: rgba(31, 73, 153, 0.5);
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #1f4999;
+       border-color: #1f4999;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #1f4999;
+       border-color: #1f4999;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+       color: #00af89;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
+       background-color: rgba(0, 171, 137, 0.1);
+       border-color: rgba(0, 89, 70, 0.5);
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #005946;
+       border-color: #005946;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #005946;
+       border-color: #005946;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+       color: #d11d13;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
+       background-color: rgba(209, 29, 19, 0.1);
+       border-color: rgba(115, 16, 10, 0.5);
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #73100a;
+       border-color: #73100a;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #73100a;
+       border-color: #73100a;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #347bff;
+       border-color: #347bff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
+       background: #2962cc;
+       border-color: #2962cc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #ffffff;
+       border-color: #347bff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #1f4999;
+       border-color: #1f4999;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #00af89;
+       border-color: #00af89;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
+       background: #008064;
+       border-color: #008064;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #ffffff;
+       border-color: #00af89;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #005946;
+       border-color: #005946;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #d11d13;
+       border-color: #d11d13;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
+       background: #8c130d;
+       border-color: #8c130d;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+       box-shadow: inset 0 0 0 1px #ffffff;
+       border-color: #d11d13;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
+       background-color: #73100a;
+       border-color: #73100a;
+       box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
+.oo-ui-clippableElement-clippable {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-iconElement.oo-ui-iconElement-icon {
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
+}
+.oo-ui-fieldLayout {
+       display: block;
+       margin-bottom: 1em;
+}
+.oo-ui-fieldLayout:before,
+.oo-ui-fieldLayout:after {
+       content: " ";
+       display: table;
+}
+.oo-ui-fieldLayout:after {
+       clear: both;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       display: block;
+       float: left;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       text-align: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+       display: table;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       display: inline-block;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
+       float: right;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+       z-index: 1;
+}
+.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
+       padding: 0.5em 0.75em;
+       line-height: 1.5em;
+}
+.oo-ui-fieldLayout:last-child {
+       margin-bottom: 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding-top: 0.5em;
+       margin-right: 5%;
+       width: 35%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+       width: 60%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
+       margin-bottom: 1.25em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding: 0.25em 0.25em 0.25em 1em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       padding-top: 0.25em;
+       padding-bottom: 0.5em;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
+       color: #cccccc;
+}
+.oo-ui-fieldLayout-messages {
+       list-style: none none;
+       margin: 0.25em 0 0 0.25em;
+       padding: 0;
+}
+.oo-ui-fieldLayout-messages > li {
+       margin: 0;
+       padding: 0;
+       display: table;
+}
+.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
+       display: table-cell;
+       border-right: 0.5em solid transparent;
+}
+.oo-ui-fieldLayout-messages .oo-ui-labelWidget {
+       display: table-cell;
+       padding: 0;
+       line-height: 1.875em;
+       vertical-align: middle;
+}
+.oo-ui-actionFieldLayout-input,
+.oo-ui-actionFieldLayout-button {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-actionFieldLayout-input {
+       padding-right: 1em;
+}
+.oo-ui-actionFieldLayout-button {
+       width: 1%;
+       white-space: nowrap;
+}
+.oo-ui-fieldsetLayout {
+       position: relative;
+       margin: 0;
+       padding: 0;
+       border: 0;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+       display: block;
+       position: absolute;
+}
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
+       display: inline-block;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
+       float: right;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+       z-index: 1;
+}
+.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
+       padding: 0.5em 0.75em;
+       line-height: 1.5em;
+}
+.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
+.oo-ui-fieldsetLayout + .oo-ui-formLayout {
+       margin-top: 2em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
+       font-size: 1.1em;
+       margin-bottom: 0.5em;
+       padding: 0.25em 0;
+       font-weight: bold;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
+       padding-left: 2em;
+       line-height: 1.8em;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+       left: 0;
+       top: 0.25em;
+       width: 1.875em;
+       height: 1.875em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-formLayout + .oo-ui-fieldsetLayout,
+.oo-ui-formLayout + .oo-ui-formLayout {
+       margin-top: 2em;
+}
+.oo-ui-panelLayout {
+       position: relative;
+}
+.oo-ui-panelLayout-scrollable {
+       overflow-y: auto;
+}
+.oo-ui-panelLayout-expanded {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-panelLayout-padded {
+       padding: 1.25em;
+}
+.oo-ui-panelLayout-framed {
+       border: 1px solid #aaaaaa;
+       border-radius: 2px;
+       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+}
+.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
+       margin: 1em 0;
+}
+.oo-ui-horizontalLayout > .oo-ui-widget {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout {
+       display: inline-block;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout,
+.oo-ui-horizontalLayout > .oo-ui-widget {
+       margin-right: 0.5em;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout:last-child,
+.oo-ui-horizontalLayout > .oo-ui-widget:last-child {
+       margin-right: 0;
+}
+.oo-ui-horizontalLayout > .oo-ui-layout {
+       margin-bottom: 0;
+}
+.oo-ui-optionWidget {
+       position: relative;
+       display: block;
+       padding: 0.25em 0.5em;
+       border: 0;
+}
+.oo-ui-optionWidget.oo-ui-widget-enabled {
+       cursor: pointer;
+}
+.oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: block;
+       white-space: nowrap;
+       text-overflow: ellipsis;
+       overflow: hidden;
+}
+.oo-ui-optionWidget-highlighted {
+       background-color: #eeeeee;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+       line-height: 1.5em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
+       background-color: #d0d0d0;
+}
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+       color: #cccccc;
+}
+.oo-ui-decoratedOptionWidget {
+       padding: 0.5em 2em 0.5em 3em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+       position: absolute;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       top: 0;
+       height: 100%;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       width: 1.875em;
+       left: 0.5em;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       right: 0.5em;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-radioOptionWidget {
+       cursor: default;
+       padding: 0.25em 0;
+       background-color: transparent;
+}
+.oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
+.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
+.oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: transparent;
+}
+.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       padding: 0.25em 0.25em 0.25em 1em;
+}
+.oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
+       margin-right: 0;
+}
+.oo-ui-labelWidget {
+       display: inline-block;
+}
+.oo-ui-iconWidget {
+       display: inline-block;
+       vertical-align: middle;
+       line-height: 2.5em;
+       width: 1.875em;
+       height: 1.875em;
+}
+.oo-ui-iconWidget.oo-ui-widget-disabled {
+       opacity: 0.2;
+}
+.oo-ui-indicatorWidget {
+       display: inline-block;
+       vertical-align: middle;
+       line-height: 2.5em;
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.46875em;
+}
+.oo-ui-indicatorWidget.oo-ui-widget-disabled {
+       opacity: 0.2;
+}
+.oo-ui-buttonWidget {
+       display: inline-block;
+       vertical-align: middle;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget {
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 2px;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonGroupWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+       border-radius: 0;
+       margin-left: -1px;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
+       border-bottom-left-radius: 2px;
+       border-top-left-radius: 2px;
+       margin-left: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
+       border-bottom-right-radius: 2px;
+       border-top-right-radius: 2px;
+}
+.oo-ui-popupWidget {
+       position: absolute;
+       /* @noflip */
+       left: 0;
+}
+.oo-ui-popupWidget-popup {
+       position: relative;
+       overflow: hidden;
+       z-index: 1;
+}
+.oo-ui-popupWidget-anchor {
+       display: none;
+       z-index: 1;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
+       display: block;
+       position: absolute;
+       top: 0;
+       /* @noflip */
+       left: 0;
+       background-repeat: no-repeat;
+}
+.oo-ui-popupWidget-head {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
+       float: right;
+}
+.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
+       float: left;
+       cursor: default;
+}
+.oo-ui-popupWidget-body {
+       clear: both;
+       overflow: hidden;
+}
+.oo-ui-popupWidget-popup {
+       background-color: #ffffff;
+       border: 1px solid #aaaaaa;
+       border-radius: 2px;
+       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
+       margin-top: 9px;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
+       content: "";
+       position: absolute;
+       width: 0;
+       height: 0;
+       border-style: solid;
+       border-color: transparent;
+       border-top: 0;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
+       bottom: -10px;
+       left: -9px;
+       border-bottom-color: #888888;
+       border-width: 10px;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
+       bottom: -10px;
+       left: -8px;
+       border-bottom-color: #ffffff;
+       border-width: 9px;
+}
+.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
+       -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+          -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+               transition: width 100ms ease, height 100ms ease, left 100ms ease;
+}
+.oo-ui-popupWidget-head {
+       height: 2.5em;
+}
+.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
+       margin: 0.25em;
+}
+.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
+       margin: 0.75em 1em;
+}
+.oo-ui-popupWidget-body-padded {
+       padding: 0 1em;
+}
+.oo-ui-popupButtonWidget {
+       position: relative;
+}
+.oo-ui-popupButtonWidget .oo-ui-popupWidget {
+       position: absolute;
+       cursor: auto;
+}
+.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
+       /* @noflip */
+       left: 1em;
+}
+.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
+       /* @noflip */
+       left: 1.75em;
+}
+.oo-ui-inputWidget {
+       margin-right: 0.5em;
+}
+.oo-ui-inputWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonInputWidget {
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonInputWidget > button,
+.oo-ui-buttonInputWidget > input {
+       border: 0;
+       padding: 0;
+       background-color: transparent;
+}
+.oo-ui-checkboxInputWidget {
+       position: relative;
+       line-height: 1.6em;
+       white-space: nowrap;
+}
+.oo-ui-checkboxInputWidget * {
+       font: inherit;
+       vertical-align: middle;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"] {
+       opacity: 0;
+       z-index: 1;
+       position: relative;
+       cursor: pointer;
+       margin: 0;
+       width: 1.6em;
+       height: 1.6em;
+       max-width: none;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"] + span {
+       -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+          -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+               transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       position: absolute;
+       left: 0;
+       border-radius: 2px;
+       width: 1.6em;
+       height: 1.6em;
+       background-color: white;
+       border: 1px solid #777777;
+       background-image: url("themes/mediawiki/images/icons/check-constructive.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-constructive.png");
+       background-repeat: no-repeat;
+       background-position: center center;
+       background-origin: border-box;
+       background-size: 0 0;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:checked + span {
+       background-size: 100% 100%;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span {
+       background-color: #cccccc;
+       border-color: #cccccc;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span {
+       border-width: 2px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:focus:hover + span,
+.oo-ui-checkboxInputWidget input[type="checkbox"]:hover + span {
+       border-bottom-width: 3px;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled {
+       cursor: default;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span {
+       background-color: #dddddd;
+       border-color: #dddddd;
+}
+.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled:checked + span {
+       background-image: url("themes/mediawiki/images/icons/check-invert.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-invert.png");
+}
+.oo-ui-dropdownInputWidget {
+       position: relative;
+       vertical-align: middle;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-dropdownInputWidget select {
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dropdownInputWidget select {
+       background-color: #ffffff;
+       height: 2.275em;
+       font-size: inherit;
+       font-family: inherit;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+       padding-left: 1em;
+       vertical-align: middle;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
+.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
+       border-color: #aaaaaa;
+       outline: none;
+}
+.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
+       color: #cccccc;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-radioInputWidget {
+       position: relative;
+       line-height: 1.6em;
+       white-space: nowrap;
+}
+.oo-ui-radioInputWidget * {
+       font: inherit;
+       vertical-align: middle;
+}
+.oo-ui-radioInputWidget input[type="radio"] {
+       opacity: 0;
+       z-index: 1;
+       position: relative;
+       cursor: pointer;
+       margin: 0;
+       width: 1.6em;
+       height: 1.6em;
+       max-width: none;
+}
+.oo-ui-radioInputWidget input[type="radio"] + span {
+       -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+          -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+               transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       position: absolute;
+       left: 0;
+       border-radius: 100%;
+       width: 1.6em;
+       height: 1.6em;
+       background: white;
+       border: 1px solid #777777;
+       background-image: url("themes/mediawiki/images/icons/circle-constructive.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-constructive.png");
+       background-repeat: no-repeat;
+       background-position: center center;
+       background-origin: border-box;
+       background-size: 0 0;
+}
+.oo-ui-radioInputWidget input[type="radio"]:checked + span {
+       background-size: 100% 100%;
+}
+.oo-ui-radioInputWidget input[type="radio"]:active + span {
+       background-color: #cccccc;
+       border-color: #cccccc;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus + span {
+       border-width: 2px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:focus:hover + span,
+.oo-ui-radioInputWidget input[type="radio"]:hover + span {
+       border-bottom-width: 3px;
+}
+.oo-ui-radioInputWidget input[type="radio"]:disabled {
+       cursor: default;
+}
+.oo-ui-radioInputWidget input[type="radio"]:disabled + span {
+       background-color: #dddddd;
+       border-color: #dddddd;
+}
+.oo-ui-radioInputWidget input[type="radio"]:disabled:checked + span {
+       background-image: url("themes/mediawiki/images/icons/circle-invert.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-invert.png");
+}
+.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
+       margin-bottom: 0;
+}
+.oo-ui-textInputWidget {
+       position: relative;
+       vertical-align: middle;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-textInputWidget textarea {
+       overflow: auto;
+}
+.oo-ui-textInputWidget input[type="search"] {
+       -webkit-appearance: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-ms-clear {
+       display: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-ms-reveal {
+       display: none;
+}
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-decoration,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-cancel-button,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-button,
+.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-decoration {
+       display: none;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       display: none;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
+       display: block;
+       position: absolute;
+       top: 0;
+       height: 100%;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+       cursor: text;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
+       cursor: pointer;
+}
+.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
+       display: block;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       position: absolute;
+       top: 0;
+}
+.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
+       right: 0;
+}
+.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
+       left: 0;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+       padding: 0.5em;
+       line-height: 1.275em;
+       margin: 0;
+       font-size: inherit;
+       font-family: inherit;
+       background-color: #ffffff;
+       color: #000000;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
+.oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
+       background-color: transparent;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
+       box-shadow: inset 0 0 0 0.1em #ffffff;
+       -webkit-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+          -moz-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+               transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+       outline: none;
+       border-color: #347bff;
+       box-shadow: inset 0 0 0 0.1em #347bff;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
+       color: #777777;
+       text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:focus,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:focus {
+       border-color: #cccccc;
+       box-shadow: inset 0 0 0 0.1em #cccccc;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
+       border-color: #ff0000;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
+.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
+       border-color: #ff0000;
+       box-shadow: inset 0 0 0 0.1em #ff0000;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled input,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
+       color: #dddddd;
+       text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement input,
+.oo-ui-textInputWidget.oo-ui-iconElement textarea {
+       padding-left: 2.875em;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       left: 0;
+       width: 1.875em;
+       max-height: 2.375em;
+       margin-left: 0.5em;
+       height: 100%;
+       background-position: right center;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement input,
+.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
+       padding-right: 2.4875em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       max-height: 2.375em;
+       margin: 0 0.775em;
+       height: 100%;
+}
+.oo-ui-textInputWidget > .oo-ui-labelElement-label {
+       padding: 0.4em;
+       line-height: 1.5em;
+       color: #888888;
+}
+.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
+       margin-right: 2.0875em;
+}
+.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
+       margin-left: 2.475em;
+}
+.oo-ui-menuSelectWidget {
+       position: absolute;
+       background-color: #ffffff;
+       margin-top: -1px;
+       border: 1px solid #aaaaaa;
+       border-radius: 0 0 2px 2px;
+       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+}
+.oo-ui-menuSelectWidget input {
+       position: absolute;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+       opacity: 0;
+}
+.oo-ui-menuOptionWidget {
+       position: relative;
+       padding: 0.5em 1em;
+}
+.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
+       display: none;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
+       background-color: transparent;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
+       display: block;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
+       background-color: #d8e6fe;
+       color: rgba(0, 0, 0, 0.8);
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
+       display: none;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: #eeeeee;
+       color: #000000;
+}
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: #d8e6fe;
+}
+.oo-ui-menuSectionOptionWidget {
+       cursor: default;
+       padding: 0.33em 0.75em;
+       color: #888888;
+}
+.oo-ui-dropdownWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+       background-color: #ffffff;
+       margin-right: 0.5em;
+}
+.oo-ui-dropdownWidget-handle {
+       width: 100%;
+       display: inline-block;
+       white-space: nowrap;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       position: absolute;
+}
+.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
+       cursor: pointer;
+}
+.oo-ui-dropdownWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-dropdownWidget-handle {
+       padding: 0.5em 0;
+       height: 2.275em;
+       line-height: 1.275;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       left: 0.25em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       line-height: 1.275em;
+       margin: 0 1em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
+       top: 0;
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.775em;
+}
+.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
+       top: 0;
+       width: 1.875em;
+       height: 1.875em;
+       margin: 0.3em;
+}
+.oo-ui-dropdownWidget:hover .oo-ui-dropdownWidget-handle {
+       border-color: #aaaaaa;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
+       outline: 0;
+}
+.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       margin-left: 3em;
+}
+.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
+       margin-right: 2em;
+}
+.oo-ui-dropdownWidget .oo-ui-selectWidget {
+       border-top-color: #ffffff;
+}
+.oo-ui-comboBoxInputWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+       margin-right: 0.5em;
+}
+.oo-ui-comboBoxInputWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
+       cursor: pointer;
+}
+.oo-ui-comboBoxInputWidget-php input::-webkit-calendar-picker-indicator {
+       opacity: 0 !important;
+       position: absolute;
+       right: 0;
+       top: 0;
+       height: 2.5em;
+       width: 2.5em;
+       padding: 0;
+}
+.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
+       pointer-events: none;
+}
+.oo-ui-comboBoxInputWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-comboBoxInputWidget input,
+.oo-ui-comboBoxInputWidget textarea {
+       height: 2.35em;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-core.js b/resources/lib/oojs-ui/oojs-ui-core.js
new file mode 100644 (file)
index 0000000..2d5ed3a
--- /dev/null
@@ -0,0 +1,9368 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:00Z
+ */
+( function ( OO ) {
+
+'use strict';
+
+/**
+ * Namespace for all classes, static methods and static properties.
+ *
+ * @class
+ * @singleton
+ */
+OO.ui = {};
+
+OO.ui.bind = $.proxy;
+
+/**
+ * @property {Object}
+ */
+OO.ui.Keys = {
+       UNDEFINED: 0,
+       BACKSPACE: 8,
+       DELETE: 46,
+       LEFT: 37,
+       RIGHT: 39,
+       UP: 38,
+       DOWN: 40,
+       ENTER: 13,
+       END: 35,
+       HOME: 36,
+       TAB: 9,
+       PAGEUP: 33,
+       PAGEDOWN: 34,
+       ESCAPE: 27,
+       SHIFT: 16,
+       SPACE: 32
+};
+
+/**
+ * Constants for MouseEvent.which
+ *
+ * @property {Object}
+ */
+OO.ui.MouseButtons = {
+       LEFT: 1,
+       MIDDLE: 2,
+       RIGHT: 3
+};
+
+/**
+ * @property {Number}
+ */
+OO.ui.elementId = 0;
+
+/**
+ * Generate a unique ID for element
+ *
+ * @return {String} [id]
+ */
+OO.ui.generateElementId = function () {
+       OO.ui.elementId += 1;
+       return 'oojsui-' + OO.ui.elementId;
+};
+
+/**
+ * Check if an element is focusable.
+ * Inspired from :focusable in jQueryUI v1.11.4 - 2015-04-14
+ *
+ * @param {jQuery} element Element to test
+ * @return {boolean}
+ */
+OO.ui.isFocusableElement = function ( $element ) {
+       var nodeName,
+               element = $element[ 0 ];
+
+       // Anything disabled is not focusable
+       if ( element.disabled ) {
+               return false;
+       }
+
+       // Check if the element is visible
+       if ( !(
+               // This is quicker than calling $element.is( ':visible' )
+               $.expr.filters.visible( element ) &&
+               // Check that all parents are visible
+               !$element.parents().addBack().filter( function () {
+                       return $.css( this, 'visibility' ) === 'hidden';
+               } ).length
+       ) ) {
+               return false;
+       }
+
+       // Check if the element is ContentEditable, which is the string 'true'
+       if ( element.contentEditable === 'true' ) {
+               return true;
+       }
+
+       // Anything with a non-negative numeric tabIndex is focusable.
+       // Use .prop to avoid browser bugs
+       if ( $element.prop( 'tabIndex' ) >= 0 ) {
+               return true;
+       }
+
+       // Some element types are naturally focusable
+       // (indexOf is much faster than regex in Chrome and about the
+       // same in FF: https://jsperf.com/regex-vs-indexof-array2)
+       nodeName = element.nodeName.toLowerCase();
+       if ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) {
+               return true;
+       }
+
+       // Links and areas are focusable if they have an href
+       if ( ( nodeName === 'a' || nodeName === 'area' ) && $element.attr( 'href' ) !== undefined ) {
+               return true;
+       }
+
+       return false;
+};
+
+/**
+ * Find a focusable child
+ *
+ * @param {jQuery} $container Container to search in
+ * @param {boolean} [backwards] Search backwards
+ * @return {jQuery} Focusable child, an empty jQuery object if none found
+ */
+OO.ui.findFocusable = function ( $container, backwards ) {
+       var $focusable = $( [] ),
+               // $focusableCandidates is a superset of things that
+               // could get matched by isFocusableElement
+               $focusableCandidates = $container
+                       .find( 'input, select, textarea, button, object, a, area, [contenteditable], [tabindex]' );
+
+       if ( backwards ) {
+               $focusableCandidates = Array.prototype.reverse.call( $focusableCandidates );
+       }
+
+       $focusableCandidates.each( function () {
+               var $this = $( this );
+               if ( OO.ui.isFocusableElement( $this ) ) {
+                       $focusable = $this;
+                       return false;
+               }
+       } );
+       return $focusable;
+};
+
+/**
+ * Get the user's language and any fallback languages.
+ *
+ * These language codes are used to localize user interface elements in the user's language.
+ *
+ * In environments that provide a localization system, this function should be overridden to
+ * return the user's language(s). The default implementation returns English (en) only.
+ *
+ * @return {string[]} Language codes, in descending order of priority
+ */
+OO.ui.getUserLanguages = function () {
+       return [ 'en' ];
+};
+
+/**
+ * Get a value in an object keyed by language code.
+ *
+ * @param {Object.<string,Mixed>} obj Object keyed by language code
+ * @param {string|null} [lang] Language code, if omitted or null defaults to any user language
+ * @param {string} [fallback] Fallback code, used if no matching language can be found
+ * @return {Mixed} Local value
+ */
+OO.ui.getLocalValue = function ( obj, lang, fallback ) {
+       var i, len, langs;
+
+       // Requested language
+       if ( obj[ lang ] ) {
+               return obj[ lang ];
+       }
+       // Known user language
+       langs = OO.ui.getUserLanguages();
+       for ( i = 0, len = langs.length; i < len; i++ ) {
+               lang = langs[ i ];
+               if ( obj[ lang ] ) {
+                       return obj[ lang ];
+               }
+       }
+       // Fallback language
+       if ( obj[ fallback ] ) {
+               return obj[ fallback ];
+       }
+       // First existing language
+       for ( lang in obj ) {
+               return obj[ lang ];
+       }
+
+       return undefined;
+};
+
+/**
+ * Check if a node is contained within another node
+ *
+ * Similar to jQuery#contains except a list of containers can be supplied
+ * and a boolean argument allows you to include the container in the match list
+ *
+ * @param {HTMLElement|HTMLElement[]} containers Container node(s) to search in
+ * @param {HTMLElement} contained Node to find
+ * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match, otherwise only match descendants
+ * @return {boolean} The node is in the list of target nodes
+ */
+OO.ui.contains = function ( containers, contained, matchContainers ) {
+       var i;
+       if ( !Array.isArray( containers ) ) {
+               containers = [ containers ];
+       }
+       for ( i = containers.length - 1; i >= 0; i-- ) {
+               if ( ( matchContainers && contained === containers[ i ] ) || $.contains( containers[ i ], contained ) ) {
+                       return true;
+               }
+       }
+       return false;
+};
+
+/**
+ * Return a function, that, as long as it continues to be invoked, will not
+ * be triggered. The function will be called after it stops being called for
+ * N milliseconds. If `immediate` is passed, trigger the function on the
+ * leading edge, instead of the trailing.
+ *
+ * Ported from: http://underscorejs.org/underscore.js
+ *
+ * @param {Function} func
+ * @param {number} wait
+ * @param {boolean} immediate
+ * @return {Function}
+ */
+OO.ui.debounce = function ( func, wait, immediate ) {
+       var timeout;
+       return function () {
+               var context = this,
+                       args = arguments,
+                       later = function () {
+                               timeout = null;
+                               if ( !immediate ) {
+                                       func.apply( context, args );
+                               }
+                       };
+               if ( immediate && !timeout ) {
+                       func.apply( context, args );
+               }
+               clearTimeout( timeout );
+               timeout = setTimeout( later, wait );
+       };
+};
+
+/**
+ * Proxy for `node.addEventListener( eventName, handler, true )`.
+ *
+ * @param {HTMLElement} node
+ * @param {string} eventName
+ * @param {Function} handler
+ * @deprecated
+ */
+OO.ui.addCaptureEventListener = function ( node, eventName, handler ) {
+       node.addEventListener( eventName, handler, true );
+};
+
+/**
+ * Proxy for `node.removeEventListener( eventName, handler, true )`.
+ *
+ * @param {HTMLElement} node
+ * @param {string} eventName
+ * @param {Function} handler
+ * @deprecated
+ */
+OO.ui.removeCaptureEventListener = function ( node, eventName, handler ) {
+       node.removeEventListener( eventName, handler, true );
+};
+
+/**
+ * Reconstitute a JavaScript object corresponding to a widget created by
+ * the PHP implementation.
+ *
+ * This is an alias for `OO.ui.Element.static.infuse()`.
+ *
+ * @param {string|HTMLElement|jQuery} idOrNode
+ *   A DOM id (if a string) or node for the widget to infuse.
+ * @return {OO.ui.Element}
+ *   The `OO.ui.Element` corresponding to this (infusable) document node.
+ */
+OO.ui.infuse = function ( idOrNode ) {
+       return OO.ui.Element.static.infuse( idOrNode );
+};
+
+( function () {
+       /**
+        * Message store for the default implementation of OO.ui.msg
+        *
+        * Environments that provide a localization system should not use this, but should override
+        * OO.ui.msg altogether.
+        *
+        * @private
+        */
+       var messages = {
+               // Tool tip for a button that moves items in a list down one place
+               'ooui-outline-control-move-down': 'Move item down',
+               // Tool tip for a button that moves items in a list up one place
+               'ooui-outline-control-move-up': 'Move item up',
+               // Tool tip for a button that removes items from a list
+               'ooui-outline-control-remove': 'Remove item',
+               // Label for the toolbar group that contains a list of all other available tools
+               'ooui-toolbar-more': 'More',
+               // Label for the fake tool that expands the full list of tools in a toolbar group
+               'ooui-toolgroup-expand': 'More',
+               // Label for the fake tool that collapses the full list of tools in a toolbar group
+               'ooui-toolgroup-collapse': 'Fewer',
+               // Default label for the accept button of a confirmation dialog
+               'ooui-dialog-message-accept': 'OK',
+               // Default label for the reject button of a confirmation dialog
+               'ooui-dialog-message-reject': 'Cancel',
+               // Title for process dialog error description
+               'ooui-dialog-process-error': 'Something went wrong',
+               // Label for process dialog dismiss error button, visible when describing errors
+               'ooui-dialog-process-dismiss': 'Dismiss',
+               // Label for process dialog retry action button, visible when describing only recoverable errors
+               'ooui-dialog-process-retry': 'Try again',
+               // Label for process dialog retry action button, visible when describing only warnings
+               'ooui-dialog-process-continue': 'Continue',
+               // Label for the file selection widget's select file button
+               'ooui-selectfile-button-select': 'Select a file',
+               // Label for the file selection widget if file selection is not supported
+               'ooui-selectfile-not-supported': 'File selection is not supported',
+               // Label for the file selection widget when no file is currently selected
+               'ooui-selectfile-placeholder': 'No file is selected',
+               // Label for the file selection widget's drop target
+               'ooui-selectfile-dragdrop-placeholder': 'Drop file here'
+       };
+
+       /**
+        * Get a localized message.
+        *
+        * In environments that provide a localization system, this function should be overridden to
+        * return the message translated in the user's language. The default implementation always returns
+        * English messages.
+        *
+        * After the message key, message parameters may optionally be passed. In the default implementation,
+        * any occurrences of $1 are replaced with the first parameter, $2 with the second parameter, etc.
+        * Alternative implementations of OO.ui.msg may use any substitution system they like, as long as
+        * they support unnamed, ordered message parameters.
+        *
+        * @param {string} key Message key
+        * @param {Mixed...} [params] Message parameters
+        * @return {string} Translated message with parameters substituted
+        */
+       OO.ui.msg = function ( key ) {
+               var message = messages[ key ],
+                       params = Array.prototype.slice.call( arguments, 1 );
+               if ( typeof message === 'string' ) {
+                       // Perform $1 substitution
+                       message = message.replace( /\$(\d+)/g, function ( unused, n ) {
+                               var i = parseInt( n, 10 );
+                               return params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;
+                       } );
+               } else {
+                       // Return placeholder if message not found
+                       message = '[' + key + ']';
+               }
+               return message;
+       };
+} )();
+
+/**
+ * Package a message and arguments for deferred resolution.
+ *
+ * Use this when you are statically specifying a message and the message may not yet be present.
+ *
+ * @param {string} key Message key
+ * @param {Mixed...} [params] Message parameters
+ * @return {Function} Function that returns the resolved message when executed
+ */
+OO.ui.deferMsg = function () {
+       var args = arguments;
+       return function () {
+               return OO.ui.msg.apply( OO.ui, args );
+       };
+};
+
+/**
+ * Resolve a message.
+ *
+ * If the message is a function it will be executed, otherwise it will pass through directly.
+ *
+ * @param {Function|string} msg Deferred message, or message text
+ * @return {string} Resolved message
+ */
+OO.ui.resolveMsg = function ( msg ) {
+       if ( $.isFunction( msg ) ) {
+               return msg();
+       }
+       return msg;
+};
+
+/**
+ * @param {string} url
+ * @return {boolean}
+ */
+OO.ui.isSafeUrl = function ( url ) {
+       // Keep this function in sync with php/Tag.php
+       var i, protocolWhitelist;
+
+       function stringStartsWith( haystack, needle ) {
+               return haystack.substr( 0, needle.length ) === needle;
+       }
+
+       protocolWhitelist = [
+               'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs',
+               'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh',
+               'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp'
+       ];
+
+       if ( url === '' ) {
+               return true;
+       }
+
+       for ( i = 0; i < protocolWhitelist.length; i++ ) {
+               if ( stringStartsWith( url, protocolWhitelist[ i ] + ':' ) ) {
+                       return true;
+               }
+       }
+
+       // This matches '//' too
+       if ( stringStartsWith( url, '/' ) || stringStartsWith( url, './' ) ) {
+               return true;
+       }
+       if ( stringStartsWith( url, '?' ) || stringStartsWith( url, '#' ) ) {
+               return true;
+       }
+
+       return false;
+};
+
+/*!
+ * Mixin namespace.
+ */
+
+/**
+ * Namespace for OOjs UI mixins.
+ *
+ * Mixins are named according to the type of object they are intended to
+ * be mixed in to.  For example, OO.ui.mixin.GroupElement is intended to be
+ * mixed in to an instance of OO.ui.Element, and OO.ui.mixin.GroupWidget
+ * is intended to be mixed in to an instance of OO.ui.Widget.
+ *
+ * @class
+ * @singleton
+ */
+OO.ui.mixin = {};
+
+/**
+ * Each Element represents a rendering in the DOM—a button or an icon, for example, or anything
+ * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not have events
+ * connected to them and can't be interacted with.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are added
+ *  to the top level (e.g., the outermost div) of the element. See the [OOjs UI documentation on MediaWiki][2]
+ *  for an example.
+ *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#cssExample
+ * @cfg {string} [id] The HTML id attribute used in the rendered tag.
+ * @cfg {string} [text] Text to insert
+ * @cfg {Array} [content] An array of content elements to append (after #text).
+ *  Strings will be html-escaped; use an OO.ui.HtmlSnippet to append raw HTML.
+ *  Instances of OO.ui.Element will have their $element appended.
+ * @cfg {jQuery} [$content] Content elements to append (after #text).
+ * @cfg {jQuery} [$element] Wrapper element. Defaults to a new element with #getTagName.
+ * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number, array, object).
+ *  Data can also be specified with the #setData method.
+ */
+OO.ui.Element = function OoUiElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$ = $;
+       this.visible = true;
+       this.data = config.data;
+       this.$element = config.$element ||
+               $( document.createElement( this.getTagName() ) );
+       this.elementGroup = null;
+       this.debouncedUpdateThemeClassesHandler = OO.ui.debounce( this.debouncedUpdateThemeClasses );
+
+       // Initialization
+       if ( Array.isArray( config.classes ) ) {
+               this.$element.addClass( config.classes.join( ' ' ) );
+       }
+       if ( config.id ) {
+               this.$element.attr( 'id', config.id );
+       }
+       if ( config.text ) {
+               this.$element.text( config.text );
+       }
+       if ( config.content ) {
+               // The `content` property treats plain strings as text; use an
+               // HtmlSnippet to append HTML content.  `OO.ui.Element`s get their
+               // appropriate $element appended.
+               this.$element.append( config.content.map( function ( v ) {
+                       if ( typeof v === 'string' ) {
+                               // Escape string so it is properly represented in HTML.
+                               return document.createTextNode( v );
+                       } else if ( v instanceof OO.ui.HtmlSnippet ) {
+                               // Bypass escaping.
+                               return v.toString();
+                       } else if ( v instanceof OO.ui.Element ) {
+                               return v.$element;
+                       }
+                       return v;
+               } ) );
+       }
+       if ( config.$content ) {
+               // The `$content` property treats plain strings as HTML.
+               this.$element.append( config.$content );
+       }
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.Element );
+
+/* Static Properties */
+
+/**
+ * The name of the HTML tag used by the element.
+ *
+ * The static value may be ignored if the #getTagName method is overridden.
+ *
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.Element.static.tagName = 'div';
+
+/* Static Methods */
+
+/**
+ * Reconstitute a JavaScript object corresponding to a widget created
+ * by the PHP implementation.
+ *
+ * @param {string|HTMLElement|jQuery} idOrNode
+ *   A DOM id (if a string) or node for the widget to infuse.
+ * @return {OO.ui.Element}
+ *   The `OO.ui.Element` corresponding to this (infusable) document node.
+ *   For `Tag` objects emitted on the HTML side (used occasionally for content)
+ *   the value returned is a newly-created Element wrapping around the existing
+ *   DOM node.
+ */
+OO.ui.Element.static.infuse = function ( idOrNode ) {
+       var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, false );
+       // Verify that the type matches up.
+       // FIXME: uncomment after T89721 is fixed (see T90929)
+       /*
+       if ( !( obj instanceof this['class'] ) ) {
+               throw new Error( 'Infusion type mismatch!' );
+       }
+       */
+       return obj;
+};
+
+/**
+ * Implementation helper for `infuse`; skips the type check and has an
+ * extra property so that only the top-level invocation touches the DOM.
+ * @private
+ * @param {string|HTMLElement|jQuery} idOrNode
+ * @param {jQuery.Promise|boolean} domPromise A promise that will be resolved
+ *     when the top-level widget of this infusion is inserted into DOM,
+ *     replacing the original node; or false for top-level invocation.
+ * @return {OO.ui.Element}
+ */
+OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
+       // look for a cached result of a previous infusion.
+       var id, $elem, data, cls, parts, parent, obj, top, state;
+       if ( typeof idOrNode === 'string' ) {
+               id = idOrNode;
+               $elem = $( document.getElementById( id ) );
+       } else {
+               $elem = $( idOrNode );
+               id = $elem.attr( 'id' );
+       }
+       if ( !$elem.length ) {
+               throw new Error( 'Widget not found: ' + id );
+       }
+       data = $elem.data( 'ooui-infused' ) || $elem[ 0 ].oouiInfused;
+       if ( data ) {
+               // cached!
+               if ( data === true ) {
+                       throw new Error( 'Circular dependency! ' + id );
+               }
+               return data;
+       }
+       data = $elem.attr( 'data-ooui' );
+       if ( !data ) {
+               throw new Error( 'No infusion data found: ' + id );
+       }
+       try {
+               data = $.parseJSON( data );
+       } catch ( _ ) {
+               data = null;
+       }
+       if ( !( data && data._ ) ) {
+               throw new Error( 'No valid infusion data found: ' + id );
+       }
+       if ( data._ === 'Tag' ) {
+               // Special case: this is a raw Tag; wrap existing node, don't rebuild.
+               return new OO.ui.Element( { $element: $elem } );
+       }
+       parts = data._.split( '.' );
+       cls = OO.getProp.apply( OO, [ window ].concat( parts ) );
+       if ( cls === undefined ) {
+               // The PHP output might be old and not including the "OO.ui" prefix
+               // TODO: Remove this back-compat after next major release
+               cls = OO.getProp.apply( OO, [ OO.ui ].concat( parts ) );
+               if ( cls === undefined ) {
+                       throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );
+               }
+       }
+
+       // Verify that we're creating an OO.ui.Element instance
+       parent = cls.parent;
+
+       while ( parent !== undefined ) {
+               if ( parent === OO.ui.Element ) {
+                       // Safe
+                       break;
+               }
+
+               parent = parent.parent;
+       }
+
+       if ( parent !== OO.ui.Element ) {
+               throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );
+       }
+
+       if ( domPromise === false ) {
+               top = $.Deferred();
+               domPromise = top.promise();
+       }
+       $elem.data( 'ooui-infused', true ); // prevent loops
+       data.id = id; // implicit
+       data = OO.copy( data, null, function deserialize( value ) {
+               if ( OO.isPlainObject( value ) ) {
+                       if ( value.tag ) {
+                               return OO.ui.Element.static.unsafeInfuse( value.tag, domPromise );
+                       }
+                       if ( value.html ) {
+                               return new OO.ui.HtmlSnippet( value.html );
+                       }
+               }
+       } );
+       // allow widgets to reuse parts of the DOM
+       data = cls.static.reusePreInfuseDOM( $elem[ 0 ], data );
+       // pick up dynamic state, like focus, value of form inputs, scroll position, etc.
+       state = cls.static.gatherPreInfuseState( $elem[ 0 ], data );
+       // rebuild widget
+       // jscs:disable requireCapitalizedConstructors
+       obj = new cls( data );
+       // jscs:enable requireCapitalizedConstructors
+       // now replace old DOM with this new DOM.
+       if ( top ) {
+               // An efficient constructor might be able to reuse the entire DOM tree of the original element,
+               // so only mutate the DOM if we need to.
+               if ( $elem[ 0 ] !== obj.$element[ 0 ] ) {
+                       $elem.replaceWith( obj.$element );
+                       // This element is now gone from the DOM, but if anyone is holding a reference to it,
+                       // let's allow them to OO.ui.infuse() it and do what they expect (T105828).
+                       // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design.
+                       $elem[ 0 ].oouiInfused = obj;
+               }
+               top.resolve();
+       }
+       obj.$element.data( 'ooui-infused', obj );
+       // set the 'data-ooui' attribute so we can identify infused widgets
+       obj.$element.attr( 'data-ooui', '' );
+       // restore dynamic state after the new element is inserted into DOM
+       domPromise.done( obj.restorePreInfuseState.bind( obj, state ) );
+       return obj;
+};
+
+/**
+ * Pick out parts of `node`'s DOM to be reused when infusing a widget.
+ *
+ * This method **must not** make any changes to the DOM, only find interesting pieces and add them
+ * to `config` (which should then be returned). Actual DOM juggling should then be done by the
+ * constructor, which will be given the enhanced config.
+ *
+ * @protected
+ * @param {HTMLElement} node
+ * @param {Object} config
+ * @return {Object}
+ */
+OO.ui.Element.static.reusePreInfuseDOM = function ( node, config ) {
+       return config;
+};
+
+/**
+ * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of a HTML DOM node
+ * (and its children) that represent an Element of the same class and the given configuration,
+ * generated by the PHP implementation.
+ *
+ * This method is called just before `node` is detached from the DOM. The return value of this
+ * function will be passed to #restorePreInfuseState after the newly created widget's #$element
+ * is inserted into DOM to replace `node`.
+ *
+ * @protected
+ * @param {HTMLElement} node
+ * @param {Object} config
+ * @return {Object}
+ */
+OO.ui.Element.static.gatherPreInfuseState = function () {
+       return {};
+};
+
+/**
+ * Get a jQuery function within a specific document.
+ *
+ * @static
+ * @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to
+ * @param {jQuery} [$iframe] HTML iframe element that contains the document, omit if document is
+ *   not in an iframe
+ * @return {Function} Bound jQuery function
+ */
+OO.ui.Element.static.getJQuery = function ( context, $iframe ) {
+       function wrapper( selector ) {
+               return $( selector, wrapper.context );
+       }
+
+       wrapper.context = this.getDocument( context );
+
+       if ( $iframe ) {
+               wrapper.$iframe = $iframe;
+       }
+
+       return wrapper;
+};
+
+/**
+ * Get the document of an element.
+ *
+ * @static
+ * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for
+ * @return {HTMLDocument|null} Document object
+ */
+OO.ui.Element.static.getDocument = function ( obj ) {
+       // jQuery - selections created "offscreen" won't have a context, so .context isn't reliable
+       return ( obj[ 0 ] && obj[ 0 ].ownerDocument ) ||
+               // Empty jQuery selections might have a context
+               obj.context ||
+               // HTMLElement
+               obj.ownerDocument ||
+               // Window
+               obj.document ||
+               // HTMLDocument
+               ( obj.nodeType === 9 && obj ) ||
+               null;
+};
+
+/**
+ * Get the window of an element or document.
+ *
+ * @static
+ * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for
+ * @return {Window} Window object
+ */
+OO.ui.Element.static.getWindow = function ( obj ) {
+       var doc = this.getDocument( obj );
+       return doc.defaultView;
+};
+
+/**
+ * Get the direction of an element or document.
+ *
+ * @static
+ * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for
+ * @return {string} Text direction, either 'ltr' or 'rtl'
+ */
+OO.ui.Element.static.getDir = function ( obj ) {
+       var isDoc, isWin;
+
+       if ( obj instanceof jQuery ) {
+               obj = obj[ 0 ];
+       }
+       isDoc = obj.nodeType === 9;
+       isWin = obj.document !== undefined;
+       if ( isDoc || isWin ) {
+               if ( isWin ) {
+                       obj = obj.document;
+               }
+               obj = obj.body;
+       }
+       return $( obj ).css( 'direction' );
+};
+
+/**
+ * Get the offset between two frames.
+ *
+ * TODO: Make this function not use recursion.
+ *
+ * @static
+ * @param {Window} from Window of the child frame
+ * @param {Window} [to=window] Window of the parent frame
+ * @param {Object} [offset] Offset to start with, used internally
+ * @return {Object} Offset object, containing left and top properties
+ */
+OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) {
+       var i, len, frames, frame, rect;
+
+       if ( !to ) {
+               to = window;
+       }
+       if ( !offset ) {
+               offset = { top: 0, left: 0 };
+       }
+       if ( from.parent === from ) {
+               return offset;
+       }
+
+       // Get iframe element
+       frames = from.parent.document.getElementsByTagName( 'iframe' );
+       for ( i = 0, len = frames.length; i < len; i++ ) {
+               if ( frames[ i ].contentWindow === from ) {
+                       frame = frames[ i ];
+                       break;
+               }
+       }
+
+       // Recursively accumulate offset values
+       if ( frame ) {
+               rect = frame.getBoundingClientRect();
+               offset.left += rect.left;
+               offset.top += rect.top;
+               if ( from !== to ) {
+                       this.getFrameOffset( from.parent, offset );
+               }
+       }
+       return offset;
+};
+
+/**
+ * Get the offset between two elements.
+ *
+ * The two elements may be in a different frame, but in that case the frame $element is in must
+ * be contained in the frame $anchor is in.
+ *
+ * @static
+ * @param {jQuery} $element Element whose position to get
+ * @param {jQuery} $anchor Element to get $element's position relative to
+ * @return {Object} Translated position coordinates, containing top and left properties
+ */
+OO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) {
+       var iframe, iframePos,
+               pos = $element.offset(),
+               anchorPos = $anchor.offset(),
+               elementDocument = this.getDocument( $element ),
+               anchorDocument = this.getDocument( $anchor );
+
+       // If $element isn't in the same document as $anchor, traverse up
+       while ( elementDocument !== anchorDocument ) {
+               iframe = elementDocument.defaultView.frameElement;
+               if ( !iframe ) {
+                       throw new Error( '$element frame is not contained in $anchor frame' );
+               }
+               iframePos = $( iframe ).offset();
+               pos.left += iframePos.left;
+               pos.top += iframePos.top;
+               elementDocument = iframe.ownerDocument;
+       }
+       pos.left -= anchorPos.left;
+       pos.top -= anchorPos.top;
+       return pos;
+};
+
+/**
+ * Get element border sizes.
+ *
+ * @static
+ * @param {HTMLElement} el Element to measure
+ * @return {Object} Dimensions object with `top`, `left`, `bottom` and `right` properties
+ */
+OO.ui.Element.static.getBorders = function ( el ) {
+       var doc = el.ownerDocument,
+               win = doc.defaultView,
+               style = win.getComputedStyle( el, null ),
+               $el = $( el ),
+               top = parseFloat( style ? style.borderTopWidth : $el.css( 'borderTopWidth' ) ) || 0,
+               left = parseFloat( style ? style.borderLeftWidth : $el.css( 'borderLeftWidth' ) ) || 0,
+               bottom = parseFloat( style ? style.borderBottomWidth : $el.css( 'borderBottomWidth' ) ) || 0,
+               right = parseFloat( style ? style.borderRightWidth : $el.css( 'borderRightWidth' ) ) || 0;
+
+       return {
+               top: top,
+               left: left,
+               bottom: bottom,
+               right: right
+       };
+};
+
+/**
+ * Get dimensions of an element or window.
+ *
+ * @static
+ * @param {HTMLElement|Window} el Element to measure
+ * @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties
+ */
+OO.ui.Element.static.getDimensions = function ( el ) {
+       var $el, $win,
+               doc = el.ownerDocument || el.document,
+               win = doc.defaultView;
+
+       if ( win === el || el === doc.documentElement ) {
+               $win = $( win );
+               return {
+                       borders: { top: 0, left: 0, bottom: 0, right: 0 },
+                       scroll: {
+                               top: $win.scrollTop(),
+                               left: $win.scrollLeft()
+                       },
+                       scrollbar: { right: 0, bottom: 0 },
+                       rect: {
+                               top: 0,
+                               left: 0,
+                               bottom: $win.innerHeight(),
+                               right: $win.innerWidth()
+                       }
+               };
+       } else {
+               $el = $( el );
+               return {
+                       borders: this.getBorders( el ),
+                       scroll: {
+                               top: $el.scrollTop(),
+                               left: $el.scrollLeft()
+                       },
+                       scrollbar: {
+                               right: $el.innerWidth() - el.clientWidth,
+                               bottom: $el.innerHeight() - el.clientHeight
+                       },
+                       rect: el.getBoundingClientRect()
+               };
+       }
+};
+
+/**
+ * Get scrollable object parent
+ *
+ * documentElement can't be used to get or set the scrollTop
+ * property on Blink. Changing and testing its value lets us
+ * use 'body' or 'documentElement' based on what is working.
+ *
+ * https://code.google.com/p/chromium/issues/detail?id=303131
+ *
+ * @static
+ * @param {HTMLElement} el Element to find scrollable parent for
+ * @return {HTMLElement} Scrollable parent
+ */
+OO.ui.Element.static.getRootScrollableElement = function ( el ) {
+       var scrollTop, body;
+
+       if ( OO.ui.scrollableElement === undefined ) {
+               body = el.ownerDocument.body;
+               scrollTop = body.scrollTop;
+               body.scrollTop = 1;
+
+               if ( body.scrollTop === 1 ) {
+                       body.scrollTop = scrollTop;
+                       OO.ui.scrollableElement = 'body';
+               } else {
+                       OO.ui.scrollableElement = 'documentElement';
+               }
+       }
+
+       return el.ownerDocument[ OO.ui.scrollableElement ];
+};
+
+/**
+ * Get closest scrollable container.
+ *
+ * Traverses up until either a scrollable element or the root is reached, in which case the window
+ * will be returned.
+ *
+ * @static
+ * @param {HTMLElement} el Element to find scrollable container for
+ * @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either
+ * @return {HTMLElement} Closest scrollable container
+ */
+OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {
+       var i, val,
+               // props = [ 'overflow' ] doesn't work due to https://bugzilla.mozilla.org/show_bug.cgi?id=889091
+               props = [ 'overflow-x', 'overflow-y' ],
+               $parent = $( el ).parent();
+
+       if ( dimension === 'x' || dimension === 'y' ) {
+               props = [ 'overflow-' + dimension ];
+       }
+
+       while ( $parent.length ) {
+               if ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {
+                       return $parent[ 0 ];
+               }
+               i = props.length;
+               while ( i-- ) {
+                       val = $parent.css( props[ i ] );
+                       if ( val === 'auto' || val === 'scroll' ) {
+                               return $parent[ 0 ];
+                       }
+               }
+               $parent = $parent.parent();
+       }
+       return this.getDocument( el ).body;
+};
+
+/**
+ * Scroll element into view.
+ *
+ * @static
+ * @param {HTMLElement} el Element to scroll into view
+ * @param {Object} [config] Configuration options
+ * @param {string} [config.duration] jQuery animation duration value
+ * @param {string} [config.direction] Scroll in only one direction, e.g. 'x' or 'y', omit
+ *  to scroll in both directions
+ * @param {Function} [config.complete] Function to call when scrolling completes
+ */
+OO.ui.Element.static.scrollIntoView = function ( el, config ) {
+       var rel, anim, callback, sc, $sc, eld, scd, $win;
+
+       // Configuration initialization
+       config = config || {};
+
+       anim = {};
+       callback = typeof config.complete === 'function' && config.complete;
+       sc = this.getClosestScrollableContainer( el, config.direction );
+       $sc = $( sc );
+       eld = this.getDimensions( el );
+       scd = this.getDimensions( sc );
+       $win = $( this.getWindow( el ) );
+
+       // Compute the distances between the edges of el and the edges of the scroll viewport
+       if ( $sc.is( 'html, body' ) ) {
+               // If the scrollable container is the root, this is easy
+               rel = {
+                       top: eld.rect.top,
+                       bottom: $win.innerHeight() - eld.rect.bottom,
+                       left: eld.rect.left,
+                       right: $win.innerWidth() - eld.rect.right
+               };
+       } else {
+               // Otherwise, we have to subtract el's coordinates from sc's coordinates
+               rel = {
+                       top: eld.rect.top - ( scd.rect.top + scd.borders.top ),
+                       bottom: scd.rect.bottom - scd.borders.bottom - scd.scrollbar.bottom - eld.rect.bottom,
+                       left: eld.rect.left - ( scd.rect.left + scd.borders.left ),
+                       right: scd.rect.right - scd.borders.right - scd.scrollbar.right - eld.rect.right
+               };
+       }
+
+       if ( !config.direction || config.direction === 'y' ) {
+               if ( rel.top < 0 ) {
+                       anim.scrollTop = scd.scroll.top + rel.top;
+               } else if ( rel.top > 0 && rel.bottom < 0 ) {
+                       anim.scrollTop = scd.scroll.top + Math.min( rel.top, -rel.bottom );
+               }
+       }
+       if ( !config.direction || config.direction === 'x' ) {
+               if ( rel.left < 0 ) {
+                       anim.scrollLeft = scd.scroll.left + rel.left;
+               } else if ( rel.left > 0 && rel.right < 0 ) {
+                       anim.scrollLeft = scd.scroll.left + Math.min( rel.left, -rel.right );
+               }
+       }
+       if ( !$.isEmptyObject( anim ) ) {
+               $sc.stop( true ).animate( anim, config.duration || 'fast' );
+               if ( callback ) {
+                       $sc.queue( function ( next ) {
+                               callback();
+                               next();
+                       } );
+               }
+       } else {
+               if ( callback ) {
+                       callback();
+               }
+       }
+};
+
+/**
+ * Force the browser to reconsider whether it really needs to render scrollbars inside the element
+ * and reserve space for them, because it probably doesn't.
+ *
+ * Workaround primarily for <https://code.google.com/p/chromium/issues/detail?id=387290>, but also
+ * similar bugs in other browsers. "Just" forcing a reflow is not sufficient in all cases, we need
+ * to first actually detach (or hide, but detaching is simpler) all children, *then* force a reflow,
+ * and then reattach (or show) them back.
+ *
+ * @static
+ * @param {HTMLElement} el Element to reconsider the scrollbars on
+ */
+OO.ui.Element.static.reconsiderScrollbars = function ( el ) {
+       var i, len, scrollLeft, scrollTop, nodes = [];
+       // Save scroll position
+       scrollLeft = el.scrollLeft;
+       scrollTop = el.scrollTop;
+       // Detach all children
+       while ( el.firstChild ) {
+               nodes.push( el.firstChild );
+               el.removeChild( el.firstChild );
+       }
+       // Force reflow
+       void el.offsetHeight;
+       // Reattach all children
+       for ( i = 0, len = nodes.length; i < len; i++ ) {
+               el.appendChild( nodes[ i ] );
+       }
+       // Restore scroll position (no-op if scrollbars disappeared)
+       el.scrollLeft = scrollLeft;
+       el.scrollTop = scrollTop;
+};
+
+/* Methods */
+
+/**
+ * Toggle visibility of an element.
+ *
+ * @param {boolean} [show] Make element visible, omit to toggle visibility
+ * @fires visible
+ * @chainable
+ */
+OO.ui.Element.prototype.toggle = function ( show ) {
+       show = show === undefined ? !this.visible : !!show;
+
+       if ( show !== this.isVisible() ) {
+               this.visible = show;
+               this.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );
+               this.emit( 'toggle', show );
+       }
+
+       return this;
+};
+
+/**
+ * Check if element is visible.
+ *
+ * @return {boolean} element is visible
+ */
+OO.ui.Element.prototype.isVisible = function () {
+       return this.visible;
+};
+
+/**
+ * Get element data.
+ *
+ * @return {Mixed} Element data
+ */
+OO.ui.Element.prototype.getData = function () {
+       return this.data;
+};
+
+/**
+ * Set element data.
+ *
+ * @param {Mixed} Element data
+ * @chainable
+ */
+OO.ui.Element.prototype.setData = function ( data ) {
+       this.data = data;
+       return this;
+};
+
+/**
+ * Check if element supports one or more methods.
+ *
+ * @param {string|string[]} methods Method or list of methods to check
+ * @return {boolean} All methods are supported
+ */
+OO.ui.Element.prototype.supports = function ( methods ) {
+       var i, len,
+               support = 0;
+
+       methods = Array.isArray( methods ) ? methods : [ methods ];
+       for ( i = 0, len = methods.length; i < len; i++ ) {
+               if ( $.isFunction( this[ methods[ i ] ] ) ) {
+                       support++;
+               }
+       }
+
+       return methods.length === support;
+};
+
+/**
+ * Update the theme-provided classes.
+ *
+ * @localdoc This is called in element mixins and widget classes any time state changes.
+ *   Updating is debounced, minimizing overhead of changing multiple attributes and
+ *   guaranteeing that theme updates do not occur within an element's constructor
+ */
+OO.ui.Element.prototype.updateThemeClasses = function () {
+       this.debouncedUpdateThemeClassesHandler();
+};
+
+/**
+ * @private
+ * @localdoc This method is called directly from the QUnit tests instead of #updateThemeClasses, to
+ *   make them synchronous.
+ */
+OO.ui.Element.prototype.debouncedUpdateThemeClasses = function () {
+       OO.ui.theme.updateElementClasses( this );
+};
+
+/**
+ * Get the HTML tag name.
+ *
+ * Override this method to base the result on instance information.
+ *
+ * @return {string} HTML tag name
+ */
+OO.ui.Element.prototype.getTagName = function () {
+       return this.constructor.static.tagName;
+};
+
+/**
+ * Check if the element is attached to the DOM
+ * @return {boolean} The element is attached to the DOM
+ */
+OO.ui.Element.prototype.isElementAttached = function () {
+       return $.contains( this.getElementDocument(), this.$element[ 0 ] );
+};
+
+/**
+ * Get the DOM document.
+ *
+ * @return {HTMLDocument} Document object
+ */
+OO.ui.Element.prototype.getElementDocument = function () {
+       // Don't cache this in other ways either because subclasses could can change this.$element
+       return OO.ui.Element.static.getDocument( this.$element );
+};
+
+/**
+ * Get the DOM window.
+ *
+ * @return {Window} Window object
+ */
+OO.ui.Element.prototype.getElementWindow = function () {
+       return OO.ui.Element.static.getWindow( this.$element );
+};
+
+/**
+ * Get closest scrollable container.
+ */
+OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
+       return OO.ui.Element.static.getClosestScrollableContainer( this.$element[ 0 ] );
+};
+
+/**
+ * Get group element is in.
+ *
+ * @return {OO.ui.mixin.GroupElement|null} Group element, null if none
+ */
+OO.ui.Element.prototype.getElementGroup = function () {
+       return this.elementGroup;
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.Element.prototype.setElementGroup = function ( group ) {
+       this.elementGroup = group;
+       return this;
+};
+
+/**
+ * Scroll element into view.
+ *
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
+       return OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config );
+};
+
+/**
+ * Restore the pre-infusion dynamic state for this widget.
+ *
+ * This method is called after #$element has been inserted into DOM. The parameter is the return
+ * value of #gatherPreInfuseState.
+ *
+ * @protected
+ * @param {Object} state
+ */
+OO.ui.Element.prototype.restorePreInfuseState = function () {
+};
+
+/**
+ * Wraps an HTML snippet for use with configuration values which default
+ * to strings.  This bypasses the default html-escaping done to string
+ * values.
+ *
+ * @class
+ *
+ * @constructor
+ * @param {string} [content] HTML content
+ */
+OO.ui.HtmlSnippet = function OoUiHtmlSnippet( content ) {
+       // Properties
+       this.content = content;
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.HtmlSnippet );
+
+/* Methods */
+
+/**
+ * Render into HTML.
+ *
+ * @return {string} Unchanged HTML snippet.
+ */
+OO.ui.HtmlSnippet.prototype.toString = function () {
+       return this.content;
+};
+
+/**
+ * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in a way
+ * that is centrally controlled and can be updated dynamically. Layouts can be, and usually are, combined.
+ * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout}, {@link OO.ui.FormLayout FormLayout},
+ * {@link OO.ui.PanelLayout PanelLayout}, {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},
+ * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout} for more information and examples.
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Element
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.Layout = function OoUiLayout( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Layout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-layout' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Layout, OO.ui.Element );
+OO.mixinClass( OO.ui.Layout, OO.EventEmitter );
+
+/**
+ * Widgets are compositions of one or more OOjs UI elements that users can both view
+ * and interact with. All widgets can be configured and modified via a standard API,
+ * and their state can change dynamically according to a model.
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Element
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [disabled=false] Disable the widget. Disabled widgets cannot be used and their
+ *  appearance reflects this state.
+ */
+OO.ui.Widget = function OoUiWidget( config ) {
+       // Initialize config
+       config = $.extend( { disabled: false }, config );
+
+       // Parent constructor
+       OO.ui.Widget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+
+       // Properties
+       this.disabled = null;
+       this.wasDisabled = null;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-widget' );
+       this.setDisabled( !!config.disabled );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Widget, OO.ui.Element );
+OO.mixinClass( OO.ui.Widget, OO.EventEmitter );
+
+/* Static Properties */
+
+/**
+ * Whether this widget will behave reasonably when wrapped in a HTML `<label>`. If this is true,
+ * wrappers such as OO.ui.FieldLayout may use a `<label>` instead of implementing own label click
+ * handling.
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.Widget.static.supportsSimpleLabel = false;
+
+/* Events */
+
+/**
+ * @event disable
+ *
+ * A 'disable' event is emitted when the disabled state of the widget changes
+ * (i.e. on disable **and** enable).
+ *
+ * @param {boolean} disabled Widget is disabled
+ */
+
+/**
+ * @event toggle
+ *
+ * A 'toggle' event is emitted when the visibility of the widget changes.
+ *
+ * @param {boolean} visible Widget is visible
+ */
+
+/* Methods */
+
+/**
+ * Check if the widget is disabled.
+ *
+ * @return {boolean} Widget is disabled
+ */
+OO.ui.Widget.prototype.isDisabled = function () {
+       return this.disabled;
+};
+
+/**
+ * Set the 'disabled' state of the widget.
+ *
+ * When a widget is disabled, it cannot be used and its appearance is updated to reflect this state.
+ *
+ * @param {boolean} disabled Disable widget
+ * @chainable
+ */
+OO.ui.Widget.prototype.setDisabled = function ( disabled ) {
+       var isDisabled;
+
+       this.disabled = !!disabled;
+       isDisabled = this.isDisabled();
+       if ( isDisabled !== this.wasDisabled ) {
+               this.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled );
+               this.$element.toggleClass( 'oo-ui-widget-enabled', !isDisabled );
+               this.$element.attr( 'aria-disabled', isDisabled.toString() );
+               this.emit( 'disable', isDisabled );
+               this.updateThemeClasses();
+       }
+       this.wasDisabled = isDisabled;
+
+       return this;
+};
+
+/**
+ * Update the disabled state, in case of changes in parent widget.
+ *
+ * @chainable
+ */
+OO.ui.Widget.prototype.updateDisabled = function () {
+       this.setDisabled( this.disabled );
+       return this;
+};
+
+/**
+ * Theme logic.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.Theme = function OoUiTheme( config ) {
+       // Configuration initialization
+       config = config || {};
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.Theme );
+
+/* Methods */
+
+/**
+ * Get a list of classes to be applied to a widget.
+ *
+ * The 'on' and 'off' lists combined MUST contain keys for all classes the theme adds or removes,
+ * otherwise state transitions will not work properly.
+ *
+ * @param {OO.ui.Element} element Element for which to get classes
+ * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists
+ */
+OO.ui.Theme.prototype.getElementClasses = function () {
+       return { on: [], off: [] };
+};
+
+/**
+ * Update CSS classes provided by the theme.
+ *
+ * For elements with theme logic hooks, this should be called any time there's a state change.
+ *
+ * @param {OO.ui.Element} element Element for which to update classes
+ * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists
+ */
+OO.ui.Theme.prototype.updateElementClasses = function ( element ) {
+       var $elements = $( [] ),
+               classes = this.getElementClasses( element );
+
+       if ( element.$icon ) {
+               $elements = $elements.add( element.$icon );
+       }
+       if ( element.$indicator ) {
+               $elements = $elements.add( element.$indicator );
+       }
+
+       $elements
+               .removeClass( classes.off.join( ' ' ) )
+               .addClass( classes.on.join( ' ' ) );
+};
+
+/**
+ * The TabIndexedElement class is an attribute mixin used to add additional functionality to an
+ * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the
+ * order in which users will navigate through the focusable elements via the "tab" key.
+ *
+ *     @example
+ *     // TabIndexedElement is mixed into the ButtonWidget class
+ *     // to provide a tabIndex property.
+ *     var button1 = new OO.ui.ButtonWidget( {
+ *         label: 'fourth',
+ *         tabIndex: 4
+ *     } );
+ *     var button2 = new OO.ui.ButtonWidget( {
+ *         label: 'second',
+ *         tabIndex: 2
+ *     } );
+ *     var button3 = new OO.ui.ButtonWidget( {
+ *         label: 'third',
+ *         tabIndex: 3
+ *     } );
+ *     var button4 = new OO.ui.ButtonWidget( {
+ *         label: 'first',
+ *         tabIndex: 1
+ *     } );
+ *     $( 'body' ).append( button1.$element, button2.$element, button3.$element, button4.$element );
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$tabIndexed] The element that should use the tabindex functionality. By default,
+ *  the functionality is applied to the element created by the class ($element). If a different element is specified, the tabindex
+ *  functionality will be applied to it instead.
+ * @cfg {number|null} [tabIndex=0] Number that specifies the element’s position in the tab-navigation
+ *  order (e.g., 1 for the first focusable element). Use 0 to use the default navigation order; use -1
+ *  to remove the element from the tab-navigation flow.
+ */
+OO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {
+       // Configuration initialization
+       config = $.extend( { tabIndex: 0 }, config );
+
+       // Properties
+       this.$tabIndexed = null;
+       this.tabIndex = null;
+
+       // Events
+       this.connect( this, { disable: 'onTabIndexedElementDisable' } );
+
+       // Initialization
+       this.setTabIndex( config.tabIndex );
+       this.setTabIndexedElement( config.$tabIndexed || this.$element );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * Set the element that should use the tabindex functionality.
+ *
+ * This method is used to retarget a tabindex mixin so that its functionality applies
+ * to the specified element. If an element is currently using the functionality, the mixin’s
+ * effect on that element is removed before the new element is set up.
+ *
+ * @param {jQuery} $tabIndexed Element that should use the tabindex functionality
+ * @chainable
+ */
+OO.ui.mixin.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed ) {
+       var tabIndex = this.tabIndex;
+       // Remove attributes from old $tabIndexed
+       this.setTabIndex( null );
+       // Force update of new $tabIndexed
+       this.$tabIndexed = $tabIndexed;
+       this.tabIndex = tabIndex;
+       return this.updateTabIndex();
+};
+
+/**
+ * Set the value of the tabindex.
+ *
+ * @param {number|null} tabIndex Tabindex value, or `null` for no tabindex
+ * @chainable
+ */
+OO.ui.mixin.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {
+       tabIndex = typeof tabIndex === 'number' ? tabIndex : null;
+
+       if ( this.tabIndex !== tabIndex ) {
+               this.tabIndex = tabIndex;
+               this.updateTabIndex();
+       }
+
+       return this;
+};
+
+/**
+ * Update the `tabindex` attribute, in case of changes to tab index or
+ * disabled state.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.mixin.TabIndexedElement.prototype.updateTabIndex = function () {
+       if ( this.$tabIndexed ) {
+               if ( this.tabIndex !== null ) {
+                       // Do not index over disabled elements
+                       this.$tabIndexed.attr( {
+                               tabindex: this.isDisabled() ? -1 : this.tabIndex,
+                               // Support: ChromeVox and NVDA
+                               // These do not seem to inherit aria-disabled from parent elements
+                               'aria-disabled': this.isDisabled().toString()
+                       } );
+               } else {
+                       this.$tabIndexed.removeAttr( 'tabindex aria-disabled' );
+               }
+       }
+       return this;
+};
+
+/**
+ * Handle disable events.
+ *
+ * @private
+ * @param {boolean} disabled Element is disabled
+ */
+OO.ui.mixin.TabIndexedElement.prototype.onTabIndexedElementDisable = function () {
+       this.updateTabIndex();
+};
+
+/**
+ * Get the value of the tabindex.
+ *
+ * @return {number|null} Tabindex value
+ */
+OO.ui.mixin.TabIndexedElement.prototype.getTabIndex = function () {
+       return this.tabIndex;
+};
+
+/**
+ * ButtonElement is often mixed into other classes to generate a button, which is a clickable
+ * interface element that can be configured with access keys for accessibility.
+ * See the [OOjs UI documentation on MediaWiki] [1] for examples.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#Buttons
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$button] The button element created by the class.
+ *  If this configuration is omitted, the button element will use a generated `<a>`.
+ * @cfg {boolean} [framed=true] Render the button with a frame
+ */
+OO.ui.mixin.ButtonElement = function OoUiMixinButtonElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$button = null;
+       this.framed = null;
+       this.active = false;
+       this.onMouseUpHandler = this.onMouseUp.bind( this );
+       this.onMouseDownHandler = this.onMouseDown.bind( this );
+       this.onKeyDownHandler = this.onKeyDown.bind( this );
+       this.onKeyUpHandler = this.onKeyUp.bind( this );
+       this.onClickHandler = this.onClick.bind( this );
+       this.onKeyPressHandler = this.onKeyPress.bind( this );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-buttonElement' );
+       this.toggleFramed( config.framed === undefined || config.framed );
+       this.setButtonElement( config.$button || $( '<a>' ) );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.ButtonElement );
+
+/* Static Properties */
+
+/**
+ * Cancel mouse down events.
+ *
+ * This property is usually set to `true` to prevent the focus from changing when the button is clicked.
+ * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and {@link OO.ui.ButtonOptionWidget ButtonOptionWidget}
+ * use a value of `false` so that dragging behavior is possible and mousedown events can be handled by a
+ * parent widget.
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.mixin.ButtonElement.static.cancelButtonMouseDownEvents = true;
+
+/* Events */
+
+/**
+ * A 'click' event is emitted when the button element is clicked.
+ *
+ * @event click
+ */
+
+/* Methods */
+
+/**
+ * Set the button element.
+ *
+ * This method is used to retarget a button mixin so that its functionality applies to
+ * the specified button element instead of the one created by the class. If a button element
+ * is already set, the method will remove the mixin’s effect on that element.
+ *
+ * @param {jQuery} $button Element to use as button
+ */
+OO.ui.mixin.ButtonElement.prototype.setButtonElement = function ( $button ) {
+       if ( this.$button ) {
+               this.$button
+                       .removeClass( 'oo-ui-buttonElement-button' )
+                       .removeAttr( 'role accesskey' )
+                       .off( {
+                               mousedown: this.onMouseDownHandler,
+                               keydown: this.onKeyDownHandler,
+                               click: this.onClickHandler,
+                               keypress: this.onKeyPressHandler
+                       } );
+       }
+
+       this.$button = $button
+               .addClass( 'oo-ui-buttonElement-button' )
+               .attr( { role: 'button' } )
+               .on( {
+                       mousedown: this.onMouseDownHandler,
+                       keydown: this.onKeyDownHandler,
+                       click: this.onClickHandler,
+                       keypress: this.onKeyPressHandler
+               } );
+};
+
+/**
+ * Handles mouse down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse down event
+ */
+OO.ui.mixin.ButtonElement.prototype.onMouseDown = function ( e ) {
+       if ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {
+               return;
+       }
+       this.$element.addClass( 'oo-ui-buttonElement-pressed' );
+       // Run the mouseup handler no matter where the mouse is when the button is let go, so we can
+       // reliably remove the pressed class
+       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
+       // Prevent change of focus unless specifically configured otherwise
+       if ( this.constructor.static.cancelButtonMouseDownEvents ) {
+               return false;
+       }
+};
+
+/**
+ * Handles mouse up events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse up event
+ */
+OO.ui.mixin.ButtonElement.prototype.onMouseUp = function ( e ) {
+       if ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {
+               return;
+       }
+       this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
+       // Stop listening for mouseup, since we only needed this once
+       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
+};
+
+/**
+ * Handles mouse click events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse click event
+ * @fires click
+ */
+OO.ui.mixin.ButtonElement.prototype.onClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               if ( this.emit( 'click' ) ) {
+                       return false;
+               }
+       }
+};
+
+/**
+ * Handles key down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.mixin.ButtonElement.prototype.onKeyDown = function ( e ) {
+       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
+               return;
+       }
+       this.$element.addClass( 'oo-ui-buttonElement-pressed' );
+       // Run the keyup handler no matter where the key is when the button is let go, so we can
+       // reliably remove the pressed class
+       this.getElementDocument().addEventListener( 'keyup', this.onKeyUpHandler, true );
+};
+
+/**
+ * Handles key up events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key up event
+ */
+OO.ui.mixin.ButtonElement.prototype.onKeyUp = function ( e ) {
+       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
+               return;
+       }
+       this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
+       // Stop listening for keyup, since we only needed this once
+       this.getElementDocument().removeEventListener( 'keyup', this.onKeyUpHandler, true );
+};
+
+/**
+ * Handles key press events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key press event
+ * @fires click
+ */
+OO.ui.mixin.ButtonElement.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+               if ( this.emit( 'click' ) ) {
+                       return false;
+               }
+       }
+};
+
+/**
+ * Check if button has a frame.
+ *
+ * @return {boolean} Button is framed
+ */
+OO.ui.mixin.ButtonElement.prototype.isFramed = function () {
+       return this.framed;
+};
+
+/**
+ * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame on and off.
+ *
+ * @param {boolean} [framed] Make button framed, omit to toggle
+ * @chainable
+ */
+OO.ui.mixin.ButtonElement.prototype.toggleFramed = function ( framed ) {
+       framed = framed === undefined ? !this.framed : !!framed;
+       if ( framed !== this.framed ) {
+               this.framed = framed;
+               this.$element
+                       .toggleClass( 'oo-ui-buttonElement-frameless', !framed )
+                       .toggleClass( 'oo-ui-buttonElement-framed', framed );
+               this.updateThemeClasses();
+       }
+
+       return this;
+};
+
+/**
+ * Set the button's active state.
+ *
+ * The active state occurs when a {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} or
+ * a {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} is pressed. This method does nothing
+ * for other button types.
+ *
+ * @param {boolean} value Make button active
+ * @chainable
+ */
+OO.ui.mixin.ButtonElement.prototype.setActive = function ( value ) {
+       this.active = !!value;
+       this.$element.toggleClass( 'oo-ui-buttonElement-active', this.active );
+       return this;
+};
+
+/**
+ * Check if the button is active
+ *
+ * @return {boolean} The button is active
+ */
+OO.ui.mixin.ButtonElement.prototype.isActive = function () {
+       return this.active;
+};
+
+/**
+ * Any OOjs UI widget that contains other widgets (such as {@link OO.ui.ButtonWidget buttons} or
+ * {@link OO.ui.OptionWidget options}) mixes in GroupElement. Adding, removing, and clearing
+ * items from the group is done through the interface the class provides.
+ * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Groups
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$group] The container element created by the class. If this configuration
+ *  is omitted, the group element will use a generated `<div>`.
+ */
+OO.ui.mixin.GroupElement = function OoUiMixinGroupElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$group = null;
+       this.items = [];
+       this.aggregateItemEvents = {};
+
+       // Initialization
+       this.setGroupElement( config.$group || $( '<div>' ) );
+};
+
+/* Methods */
+
+/**
+ * Set the group element.
+ *
+ * If an element is already set, items will be moved to the new element.
+ *
+ * @param {jQuery} $group Element to use as group
+ */
+OO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) {
+       var i, len;
+
+       this.$group = $group;
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               this.$group.append( this.items[ i ].$element );
+       }
+};
+
+/**
+ * Check if a group contains no items.
+ *
+ * @return {boolean} Group is empty
+ */
+OO.ui.mixin.GroupElement.prototype.isEmpty = function () {
+       return !this.items.length;
+};
+
+/**
+ * Get all items in the group.
+ *
+ * The method returns an array of item references (e.g., [button1, button2, button3]) and is useful
+ * when synchronizing groups of items, or whenever the references are required (e.g., when removing items
+ * from a group).
+ *
+ * @return {OO.ui.Element[]} An array of items.
+ */
+OO.ui.mixin.GroupElement.prototype.getItems = function () {
+       return this.items.slice( 0 );
+};
+
+/**
+ * Get an item by its data.
+ *
+ * Only the first item with matching data will be returned. To return all matching items,
+ * use the #getItemsFromData method.
+ *
+ * @param {Object} data Item data to search for
+ * @return {OO.ui.Element|null} Item with equivalent data, `null` if none exists
+ */
+OO.ui.mixin.GroupElement.prototype.getItemFromData = function ( data ) {
+       var i, len, item,
+               hash = OO.getHash( data );
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               item = this.items[ i ];
+               if ( hash === OO.getHash( item.getData() ) ) {
+                       return item;
+               }
+       }
+
+       return null;
+};
+
+/**
+ * Get items by their data.
+ *
+ * All items with matching data will be returned. To return only the first match, use the #getItemFromData method instead.
+ *
+ * @param {Object} data Item data to search for
+ * @return {OO.ui.Element[]} Items with equivalent data
+ */
+OO.ui.mixin.GroupElement.prototype.getItemsFromData = function ( data ) {
+       var i, len, item,
+               hash = OO.getHash( data ),
+               items = [];
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               item = this.items[ i ];
+               if ( hash === OO.getHash( item.getData() ) ) {
+                       items.push( item );
+               }
+       }
+
+       return items;
+};
+
+/**
+ * Aggregate the events emitted by the group.
+ *
+ * When events are aggregated, the group will listen to all contained items for the event,
+ * and then emit the event under a new name. The new event will contain an additional leading
+ * parameter containing the item that emitted the original event. Other arguments emitted from
+ * the original event are passed through.
+ *
+ * @param {Object.<string,string|null>} events An object keyed by the name of the event that should be
+ *  aggregated  (e.g., ‘click’) and the value of the new name to use (e.g., ‘groupClick’).
+ *  A `null` value will remove aggregated events.
+
+ * @throws {Error} An error is thrown if aggregation already exists.
+ */
+OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
+       var i, len, item, add, remove, itemEvent, groupEvent;
+
+       for ( itemEvent in events ) {
+               groupEvent = events[ itemEvent ];
+
+               // Remove existing aggregated event
+               if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
+                       // Don't allow duplicate aggregations
+                       if ( groupEvent ) {
+                               throw new Error( 'Duplicate item event aggregation for ' + itemEvent );
+                       }
+                       // Remove event aggregation from existing items
+                       for ( i = 0, len = this.items.length; i < len; i++ ) {
+                               item = this.items[ i ];
+                               if ( item.connect && item.disconnect ) {
+                                       remove = {};
+                                       remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
+                                       item.disconnect( this, remove );
+                               }
+                       }
+                       // Prevent future items from aggregating event
+                       delete this.aggregateItemEvents[ itemEvent ];
+               }
+
+               // Add new aggregate event
+               if ( groupEvent ) {
+                       // Make future items aggregate event
+                       this.aggregateItemEvents[ itemEvent ] = groupEvent;
+                       // Add event aggregation to existing items
+                       for ( i = 0, len = this.items.length; i < len; i++ ) {
+                               item = this.items[ i ];
+                               if ( item.connect && item.disconnect ) {
+                                       add = {};
+                                       add[ itemEvent ] = [ 'emit', groupEvent, item ];
+                                       item.connect( this, add );
+                               }
+                       }
+               }
+       }
+};
+
+/**
+ * Add items to the group.
+ *
+ * Items will be added to the end of the group array unless the optional `index` parameter specifies
+ * a different insertion point. Adding an existing item will move it to the end of the array or the point specified by the `index`.
+ *
+ * @param {OO.ui.Element[]} items An array of items to add to the group
+ * @param {number} [index] Index of the insertion point
+ * @chainable
+ */
+OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
+       var i, len, item, event, events, currentIndex,
+               itemElements = [];
+
+       for ( i = 0, len = items.length; i < len; i++ ) {
+               item = items[ i ];
+
+               // Check if item exists then remove it first, effectively "moving" it
+               currentIndex = this.items.indexOf( item );
+               if ( currentIndex >= 0 ) {
+                       this.removeItems( [ item ] );
+                       // Adjust index to compensate for removal
+                       if ( currentIndex < index ) {
+                               index--;
+                       }
+               }
+               // Add the item
+               if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
+                       events = {};
+                       for ( event in this.aggregateItemEvents ) {
+                               events[ event ] = [ 'emit', this.aggregateItemEvents[ event ], item ];
+                       }
+                       item.connect( this, events );
+               }
+               item.setElementGroup( this );
+               itemElements.push( item.$element.get( 0 ) );
+       }
+
+       if ( index === undefined || index < 0 || index >= this.items.length ) {
+               this.$group.append( itemElements );
+               this.items.push.apply( this.items, items );
+       } else if ( index === 0 ) {
+               this.$group.prepend( itemElements );
+               this.items.unshift.apply( this.items, items );
+       } else {
+               this.items[ index ].$element.before( itemElements );
+               this.items.splice.apply( this.items, [ index, 0 ].concat( items ) );
+       }
+
+       return this;
+};
+
+/**
+ * Remove the specified items from a group.
+ *
+ * Removed items are detached (not removed) from the DOM so that they may be reused.
+ * To remove all items from a group, you may wish to use the #clearItems method instead.
+ *
+ * @param {OO.ui.Element[]} items An array of items to remove
+ * @chainable
+ */
+OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
+       var i, len, item, index, remove, itemEvent;
+
+       // Remove specific items
+       for ( i = 0, len = items.length; i < len; i++ ) {
+               item = items[ i ];
+               index = this.items.indexOf( item );
+               if ( index !== -1 ) {
+                       if (
+                               item.connect && item.disconnect &&
+                               !$.isEmptyObject( this.aggregateItemEvents )
+                       ) {
+                               remove = {};
+                               if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
+                                       remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
+                               }
+                               item.disconnect( this, remove );
+                       }
+                       item.setElementGroup( null );
+                       this.items.splice( index, 1 );
+                       item.$element.detach();
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Clear all items from the group.
+ *
+ * Cleared items are detached from the DOM, not removed, so that they may be reused.
+ * To remove only a subset of items from a group, use the #removeItems method.
+ *
+ * @chainable
+ */
+OO.ui.mixin.GroupElement.prototype.clearItems = function () {
+       var i, len, item, remove, itemEvent;
+
+       // Remove all items
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               item = this.items[ i ];
+               if (
+                       item.connect && item.disconnect &&
+                       !$.isEmptyObject( this.aggregateItemEvents )
+               ) {
+                       remove = {};
+                       if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
+                               remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
+                       }
+                       item.disconnect( this, remove );
+               }
+               item.setElementGroup( null );
+               item.$element.detach();
+       }
+
+       this.items = [];
+       return this;
+};
+
+/**
+ * IconElement is often mixed into other classes to generate an icon.
+ * Icons are graphics, about the size of normal text. They are used to aid the user
+ * in locating a control or to convey information in a space-efficient way. See the
+ * [OOjs UI documentation on MediaWiki] [1] for a list of icons
+ * included in the library.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,
+ *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that
+ *  the icon element be set to an existing icon instead of the one generated by this class, set a
+ *  value using a jQuery selection. For example:
+ *
+ *      // Use a <div> tag instead of a <span>
+ *     $icon: $("<div>")
+ *     // Use an existing icon element instead of the one generated by the class
+ *     $icon: this.$element
+ *     // Use an icon element from a child widget
+ *     $icon: this.childwidget.$element
+ * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of
+ *  symbolic names.  A map is used for i18n purposes and contains a `default` icon
+ *  name and additional names keyed by language code. The `default` name is used when no icon is keyed
+ *  by the user's language.
+ *
+ *  Example of an i18n map:
+ *
+ *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
+ *  See the [OOjs UI documentation on MediaWiki] [2] for a list of icons included in the library.
+ * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
+ * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title
+ *  text. The icon title is displayed when users move the mouse over the icon.
+ */
+OO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$icon = null;
+       this.icon = null;
+       this.iconTitle = null;
+
+       // Initialization
+       this.setIcon( config.icon || this.constructor.static.icon );
+       this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
+       this.setIconElement( config.$icon || $( '<span>' ) );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.IconElement );
+
+/* Static Properties */
+
+/**
+ * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used
+ * for i18n purposes and contains a `default` icon name and additional names keyed by
+ * language code. The `default` name is used when no icon is keyed by the user's language.
+ *
+ * Example of an i18n map:
+ *
+ *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
+ *
+ * Note: the static property will be overridden if the #icon configuration is used.
+ *
+ * @static
+ * @inheritable
+ * @property {Object|string}
+ */
+OO.ui.mixin.IconElement.static.icon = null;
+
+/**
+ * The icon title, displayed when users move the mouse over the icon. The value can be text, a
+ * function that returns title text, or `null` for no title.
+ *
+ * The static property will be overridden if the #iconTitle configuration is used.
+ *
+ * @static
+ * @inheritable
+ * @property {string|Function|null}
+ */
+OO.ui.mixin.IconElement.static.iconTitle = null;
+
+/* Methods */
+
+/**
+ * Set the icon element. This method is used to retarget an icon mixin so that its functionality
+ * applies to the specified icon element instead of the one created by the class. If an icon
+ * element is already set, the mixin’s effect on that element is removed. Generated CSS classes
+ * and mixin methods will no longer affect the element.
+ *
+ * @param {jQuery} $icon Element to use as icon
+ */
+OO.ui.mixin.IconElement.prototype.setIconElement = function ( $icon ) {
+       if ( this.$icon ) {
+               this.$icon
+                       .removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )
+                       .removeAttr( 'title' );
+       }
+
+       this.$icon = $icon
+               .addClass( 'oo-ui-iconElement-icon' )
+               .toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );
+       if ( this.iconTitle !== null ) {
+               this.$icon.attr( 'title', this.iconTitle );
+       }
+
+       this.updateThemeClasses();
+};
+
+/**
+ * Set icon by symbolic name (e.g., ‘remove’ or ‘menu’). Use `null` to remove an icon.
+ * The icon parameter can also be set to a map of icon names. See the #icon config setting
+ * for an example.
+ *
+ * @param {Object|string|null} icon A symbolic icon name, a {@link #icon map of icon names} keyed
+ *  by language code, or `null` to remove the icon.
+ * @chainable
+ */
+OO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {
+       icon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;
+       icon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;
+
+       if ( this.icon !== icon ) {
+               if ( this.$icon ) {
+                       if ( this.icon !== null ) {
+                               this.$icon.removeClass( 'oo-ui-icon-' + this.icon );
+                       }
+                       if ( icon !== null ) {
+                               this.$icon.addClass( 'oo-ui-icon-' + icon );
+                       }
+               }
+               this.icon = icon;
+       }
+
+       this.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );
+       this.updateThemeClasses();
+
+       return this;
+};
+
+/**
+ * Set the icon title. Use `null` to remove the title.
+ *
+ * @param {string|Function|null} iconTitle A text string used as the icon title,
+ *  a function that returns title text, or `null` for no title.
+ * @chainable
+ */
+OO.ui.mixin.IconElement.prototype.setIconTitle = function ( iconTitle ) {
+       iconTitle = typeof iconTitle === 'function' ||
+               ( typeof iconTitle === 'string' && iconTitle.length ) ?
+                       OO.ui.resolveMsg( iconTitle ) : null;
+
+       if ( this.iconTitle !== iconTitle ) {
+               this.iconTitle = iconTitle;
+               if ( this.$icon ) {
+                       if ( this.iconTitle !== null ) {
+                               this.$icon.attr( 'title', iconTitle );
+                       } else {
+                               this.$icon.removeAttr( 'title' );
+                       }
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Get the symbolic name of the icon.
+ *
+ * @return {string} Icon name
+ */
+OO.ui.mixin.IconElement.prototype.getIcon = function () {
+       return this.icon;
+};
+
+/**
+ * Get the icon title. The title text is displayed when a user moves the mouse over the icon.
+ *
+ * @return {string} Icon title text
+ */
+OO.ui.mixin.IconElement.prototype.getIconTitle = function () {
+       return this.iconTitle;
+};
+
+/**
+ * IndicatorElement is often mixed into other classes to generate an indicator.
+ * Indicators are small graphics that are generally used in two ways:
+ *
+ * - To draw attention to the status of an item. For example, an indicator might be
+ *   used to show that an item in a list has errors that need to be resolved.
+ * - To clarify the function of a control that acts in an exceptional way (a button
+ *   that opens a menu instead of performing an action directly, for example).
+ *
+ * For a list of indicators included in the library, please see the
+ * [OOjs UI documentation on MediaWiki] [1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$indicator] The indicator element created by the class. If this
+ *  configuration is omitted, the indicator element will use a generated `<span>`.
+ * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
+ *  See the [OOjs UI documentation on MediaWiki][2] for a list of indicators included
+ *  in the library.
+ * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
+ * @cfg {string|Function} [indicatorTitle] A text string used as the indicator title,
+ *  or a function that returns title text. The indicator title is displayed when users move
+ *  the mouse over the indicator.
+ */
+OO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$indicator = null;
+       this.indicator = null;
+       this.indicatorTitle = null;
+
+       // Initialization
+       this.setIndicator( config.indicator || this.constructor.static.indicator );
+       this.setIndicatorTitle( config.indicatorTitle || this.constructor.static.indicatorTitle );
+       this.setIndicatorElement( config.$indicator || $( '<span>' ) );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.IndicatorElement );
+
+/* Static Properties */
+
+/**
+ * Symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
+ * The static property will be overridden if the #indicator configuration is used.
+ *
+ * @static
+ * @inheritable
+ * @property {string|null}
+ */
+OO.ui.mixin.IndicatorElement.static.indicator = null;
+
+/**
+ * A text string used as the indicator title, a function that returns title text, or `null`
+ * for no title. The static property will be overridden if the #indicatorTitle configuration is used.
+ *
+ * @static
+ * @inheritable
+ * @property {string|Function|null}
+ */
+OO.ui.mixin.IndicatorElement.static.indicatorTitle = null;
+
+/* Methods */
+
+/**
+ * Set the indicator element.
+ *
+ * If an element is already set, it will be cleaned up before setting up the new element.
+ *
+ * @param {jQuery} $indicator Element to use as indicator
+ */
+OO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicator ) {
+       if ( this.$indicator ) {
+               this.$indicator
+                       .removeClass( 'oo-ui-indicatorElement-indicator oo-ui-indicator-' + this.indicator )
+                       .removeAttr( 'title' );
+       }
+
+       this.$indicator = $indicator
+               .addClass( 'oo-ui-indicatorElement-indicator' )
+               .toggleClass( 'oo-ui-indicator-' + this.indicator, !!this.indicator );
+       if ( this.indicatorTitle !== null ) {
+               this.$indicator.attr( 'title', this.indicatorTitle );
+       }
+
+       this.updateThemeClasses();
+};
+
+/**
+ * Set the indicator by its symbolic name: ‘alert’, ‘down’, ‘next’, ‘previous’, ‘required’, ‘up’. Use `null` to remove the indicator.
+ *
+ * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator
+ * @chainable
+ */
+OO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {
+       indicator = typeof indicator === 'string' && indicator.length ? indicator.trim() : null;
+
+       if ( this.indicator !== indicator ) {
+               if ( this.$indicator ) {
+                       if ( this.indicator !== null ) {
+                               this.$indicator.removeClass( 'oo-ui-indicator-' + this.indicator );
+                       }
+                       if ( indicator !== null ) {
+                               this.$indicator.addClass( 'oo-ui-indicator-' + indicator );
+                       }
+               }
+               this.indicator = indicator;
+       }
+
+       this.$element.toggleClass( 'oo-ui-indicatorElement', !!this.indicator );
+       this.updateThemeClasses();
+
+       return this;
+};
+
+/**
+ * Set the indicator title.
+ *
+ * The title is displayed when a user moves the mouse over the indicator.
+ *
+ * @param {string|Function|null} indicator Indicator title text, a function that returns text, or
+ *   `null` for no indicator title
+ * @chainable
+ */
+OO.ui.mixin.IndicatorElement.prototype.setIndicatorTitle = function ( indicatorTitle ) {
+       indicatorTitle = typeof indicatorTitle === 'function' ||
+               ( typeof indicatorTitle === 'string' && indicatorTitle.length ) ?
+                       OO.ui.resolveMsg( indicatorTitle ) : null;
+
+       if ( this.indicatorTitle !== indicatorTitle ) {
+               this.indicatorTitle = indicatorTitle;
+               if ( this.$indicator ) {
+                       if ( this.indicatorTitle !== null ) {
+                               this.$indicator.attr( 'title', indicatorTitle );
+                       } else {
+                               this.$indicator.removeAttr( 'title' );
+                       }
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Get the symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
+ *
+ * @return {string} Symbolic name of indicator
+ */
+OO.ui.mixin.IndicatorElement.prototype.getIndicator = function () {
+       return this.indicator;
+};
+
+/**
+ * Get the indicator title.
+ *
+ * The title is displayed when a user moves the mouse over the indicator.
+ *
+ * @return {string} Indicator title text
+ */
+OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
+       return this.indicatorTitle;
+};
+
+/**
+ * LabelElement is often mixed into other classes to generate a label, which
+ * helps identify the function of an interface element.
+ * See the [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$label] The label element created by the class. If this
+ *  configuration is omitted, the label element will use a generated `<span>`.
+ * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified
+ *  as a plaintext string, a jQuery selection of elements, or a function that will produce a string
+ *  in the future. See the [OOjs UI documentation on MediaWiki] [2] for examples.
+ *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
+ * @cfg {boolean} [autoFitLabel=true] Fit the label to the width of the parent element.
+ *  The label will be truncated to fit if necessary.
+ */
+OO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$label = null;
+       this.label = null;
+       this.autoFitLabel = config.autoFitLabel === undefined || !!config.autoFitLabel;
+
+       // Initialization
+       this.setLabel( config.label || this.constructor.static.label );
+       this.setLabelElement( config.$label || $( '<span>' ) );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.LabelElement );
+
+/* Events */
+
+/**
+ * @event labelChange
+ * @param {string} value
+ */
+
+/* Static Properties */
+
+/**
+ * The label text. The label can be specified as a plaintext string, a function that will
+ * produce a string in the future, or `null` for no label. The static value will
+ * be overridden if a label is specified with the #label config option.
+ *
+ * @static
+ * @inheritable
+ * @property {string|Function|null}
+ */
+OO.ui.mixin.LabelElement.static.label = null;
+
+/* Methods */
+
+/**
+ * Set the label element.
+ *
+ * If an element is already set, it will be cleaned up before setting up the new element.
+ *
+ * @param {jQuery} $label Element to use as label
+ */
+OO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {
+       if ( this.$label ) {
+               this.$label.removeClass( 'oo-ui-labelElement-label' ).empty();
+       }
+
+       this.$label = $label.addClass( 'oo-ui-labelElement-label' );
+       this.setLabelContent( this.label );
+};
+
+/**
+ * Set the label.
+ *
+ * An empty string will result in the label being hidden. A string containing only whitespace will
+ * be converted to a single `&nbsp;`.
+ *
+ * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that returns nodes or
+ *  text; or null for no label
+ * @chainable
+ */
+OO.ui.mixin.LabelElement.prototype.setLabel = function ( label ) {
+       label = typeof label === 'function' ? OO.ui.resolveMsg( label ) : label;
+       label = ( ( typeof label === 'string' && label.length ) || label instanceof jQuery || label instanceof OO.ui.HtmlSnippet ) ? label : null;
+
+       this.$element.toggleClass( 'oo-ui-labelElement', !!label );
+
+       if ( this.label !== label ) {
+               if ( this.$label ) {
+                       this.setLabelContent( label );
+               }
+               this.label = label;
+               this.emit( 'labelChange' );
+       }
+
+       return this;
+};
+
+/**
+ * Get the label.
+ *
+ * @return {jQuery|string|Function|null} Label nodes; text; a function that returns nodes or
+ *  text; or null for no label
+ */
+OO.ui.mixin.LabelElement.prototype.getLabel = function () {
+       return this.label;
+};
+
+/**
+ * Fit the label.
+ *
+ * @chainable
+ */
+OO.ui.mixin.LabelElement.prototype.fitLabel = function () {
+       if ( this.$label && this.$label.autoEllipsis && this.autoFitLabel ) {
+               this.$label.autoEllipsis( { hasSpan: false, tooltip: true } );
+       }
+
+       return this;
+};
+
+/**
+ * Set the content of the label.
+ *
+ * Do not call this method until after the label element has been set by #setLabelElement.
+ *
+ * @private
+ * @param {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or
+ *  text; or null for no label
+ */
+OO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {
+       if ( typeof label === 'string' ) {
+               if ( label.match( /^\s*$/ ) ) {
+                       // Convert whitespace only string to a single non-breaking space
+                       this.$label.html( '&nbsp;' );
+               } else {
+                       this.$label.text( label );
+               }
+       } else if ( label instanceof OO.ui.HtmlSnippet ) {
+               this.$label.html( label.toString() );
+       } else if ( label instanceof jQuery ) {
+               this.$label.empty().append( label );
+       } else {
+               this.$label.empty();
+       }
+};
+
+/**
+ * The FlaggedElement class is an attribute mixin, meaning that it is used to add
+ * additional functionality to an element created by another class. The class provides
+ * a ‘flags’ property assigned the name (or an array of names) of styling flags,
+ * which are used to customize the look and feel of a widget to better describe its
+ * importance and functionality.
+ *
+ * The library currently contains the following styling flags for general use:
+ *
+ * - **progressive**:  Progressive styling is applied to convey that the widget will move the user forward in a process.
+ * - **destructive**: Destructive styling is applied to convey that the widget will remove something.
+ * - **constructive**: Constructive styling is applied to convey that the widget will create something.
+ *
+ * The flags affect the appearance of the buttons:
+ *
+ *     @example
+ *     // FlaggedElement is mixed into ButtonWidget to provide styling flags
+ *     var button1 = new OO.ui.ButtonWidget( {
+ *         label: 'Constructive',
+ *         flags: 'constructive'
+ *     } );
+ *     var button2 = new OO.ui.ButtonWidget( {
+ *         label: 'Destructive',
+ *         flags: 'destructive'
+ *     } );
+ *     var button3 = new OO.ui.ButtonWidget( {
+ *         label: 'Progressive',
+ *         flags: 'progressive'
+ *     } );
+ *     $( 'body' ).append( button1.$element, button2.$element, button3.$element );
+ *
+ * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an action, use these flags: **primary** and **safe**.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Flagged
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'constructive' or 'primary') to apply.
+ *  Please see the [OOjs UI documentation on MediaWiki] [2] for more information about available flags.
+ *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Flagged
+ * @cfg {jQuery} [$flagged] The flagged element. By default,
+ *  the flagged functionality is applied to the element created by the class ($element).
+ *  If a different element is specified, the flagged functionality will be applied to it instead.
+ */
+OO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.flags = {};
+       this.$flagged = null;
+
+       // Initialization
+       this.setFlags( config.flags );
+       this.setFlaggedElement( config.$flagged || this.$element );
+};
+
+/* Events */
+
+/**
+ * @event flag
+ * A flag event is emitted when the #clearFlags or #setFlags methods are used. The `changes`
+ * parameter contains the name of each modified flag and indicates whether it was
+ * added or removed.
+ *
+ * @param {Object.<string,boolean>} changes Object keyed by flag name. A Boolean `true` indicates
+ * that the flag was added, `false` that the flag was removed.
+ */
+
+/* Methods */
+
+/**
+ * Set the flagged element.
+ *
+ * This method is used to retarget a flagged mixin so that its functionality applies to the specified element.
+ * If an element is already set, the method will remove the mixin’s effect on that element.
+ *
+ * @param {jQuery} $flagged Element that should be flagged
+ */
+OO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) {
+       var classNames = Object.keys( this.flags ).map( function ( flag ) {
+               return 'oo-ui-flaggedElement-' + flag;
+       } ).join( ' ' );
+
+       if ( this.$flagged ) {
+               this.$flagged.removeClass( classNames );
+       }
+
+       this.$flagged = $flagged.addClass( classNames );
+};
+
+/**
+ * Check if the specified flag is set.
+ *
+ * @param {string} flag Name of flag
+ * @return {boolean} The flag is set
+ */
+OO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) {
+       // This may be called before the constructor, thus before this.flags is set
+       return this.flags && ( flag in this.flags );
+};
+
+/**
+ * Get the names of all flags set.
+ *
+ * @return {string[]} Flag names
+ */
+OO.ui.mixin.FlaggedElement.prototype.getFlags = function () {
+       // This may be called before the constructor, thus before this.flags is set
+       return Object.keys( this.flags || {} );
+};
+
+/**
+ * Clear all flags.
+ *
+ * @chainable
+ * @fires flag
+ */
+OO.ui.mixin.FlaggedElement.prototype.clearFlags = function () {
+       var flag, className,
+               changes = {},
+               remove = [],
+               classPrefix = 'oo-ui-flaggedElement-';
+
+       for ( flag in this.flags ) {
+               className = classPrefix + flag;
+               changes[ flag ] = false;
+               delete this.flags[ flag ];
+               remove.push( className );
+       }
+
+       if ( this.$flagged ) {
+               this.$flagged.removeClass( remove.join( ' ' ) );
+       }
+
+       this.updateThemeClasses();
+       this.emit( 'flag', changes );
+
+       return this;
+};
+
+/**
+ * Add one or more flags.
+ *
+ * @param {string|string[]|Object.<string, boolean>} flags A flag name, an array of flag names,
+ *  or an object keyed by flag name with a boolean value that indicates whether the flag should
+ *  be added (`true`) or removed (`false`).
+ * @chainable
+ * @fires flag
+ */
+OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) {
+       var i, len, flag, className,
+               changes = {},
+               add = [],
+               remove = [],
+               classPrefix = 'oo-ui-flaggedElement-';
+
+       if ( typeof flags === 'string' ) {
+               className = classPrefix + flags;
+               // Set
+               if ( !this.flags[ flags ] ) {
+                       this.flags[ flags ] = true;
+                       add.push( className );
+               }
+       } else if ( Array.isArray( flags ) ) {
+               for ( i = 0, len = flags.length; i < len; i++ ) {
+                       flag = flags[ i ];
+                       className = classPrefix + flag;
+                       // Set
+                       if ( !this.flags[ flag ] ) {
+                               changes[ flag ] = true;
+                               this.flags[ flag ] = true;
+                               add.push( className );
+                       }
+               }
+       } else if ( OO.isPlainObject( flags ) ) {
+               for ( flag in flags ) {
+                       className = classPrefix + flag;
+                       if ( flags[ flag ] ) {
+                               // Set
+                               if ( !this.flags[ flag ] ) {
+                                       changes[ flag ] = true;
+                                       this.flags[ flag ] = true;
+                                       add.push( className );
+                               }
+                       } else {
+                               // Remove
+                               if ( this.flags[ flag ] ) {
+                                       changes[ flag ] = false;
+                                       delete this.flags[ flag ];
+                                       remove.push( className );
+                               }
+                       }
+               }
+       }
+
+       if ( this.$flagged ) {
+               this.$flagged
+                       .addClass( add.join( ' ' ) )
+                       .removeClass( remove.join( ' ' ) );
+       }
+
+       this.updateThemeClasses();
+       this.emit( 'flag', changes );
+
+       return this;
+};
+
+/**
+ * TitledElement is mixed into other classes to provide a `title` attribute.
+ * Titles are rendered by the browser and are made visible when the user moves
+ * the mouse over the element. Titles are not visible on touch devices.
+ *
+ *     @example
+ *     // TitledElement provides a 'title' attribute to the
+ *     // ButtonWidget class
+ *     var button = new OO.ui.ButtonWidget( {
+ *         label: 'Button with Title',
+ *         title: 'I am a button'
+ *     } );
+ *     $( 'body' ).append( button.$element );
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$titled] The element to which the `title` attribute is applied.
+ *  If this config is omitted, the title functionality is applied to $element, the
+ *  element created by the class.
+ * @cfg {string|Function} [title] The title text or a function that returns text. If
+ *  this config is omitted, the value of the {@link #static-title static title} property is used.
+ */
+OO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$titled = null;
+       this.title = null;
+
+       // Initialization
+       this.setTitle( config.title || this.constructor.static.title );
+       this.setTitledElement( config.$titled || this.$element );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.TitledElement );
+
+/* Static Properties */
+
+/**
+ * The title text, a function that returns text, or `null` for no title. The value of the static property
+ * is overridden if the #title config option is used.
+ *
+ * @static
+ * @inheritable
+ * @property {string|Function|null}
+ */
+OO.ui.mixin.TitledElement.static.title = null;
+
+/* Methods */
+
+/**
+ * Set the titled element.
+ *
+ * This method is used to retarget a titledElement mixin so that its functionality applies to the specified element.
+ * If an element is already set, the mixin’s effect on that element is removed before the new element is set up.
+ *
+ * @param {jQuery} $titled Element that should use the 'titled' functionality
+ */
+OO.ui.mixin.TitledElement.prototype.setTitledElement = function ( $titled ) {
+       if ( this.$titled ) {
+               this.$titled.removeAttr( 'title' );
+       }
+
+       this.$titled = $titled;
+       if ( this.title ) {
+               this.$titled.attr( 'title', this.title );
+       }
+};
+
+/**
+ * Set title.
+ *
+ * @param {string|Function|null} title Title text, a function that returns text, or `null` for no title
+ * @chainable
+ */
+OO.ui.mixin.TitledElement.prototype.setTitle = function ( title ) {
+       title = typeof title === 'function' ? OO.ui.resolveMsg( title ) : title;
+       title = ( typeof title === 'string' && title.length ) ? title : null;
+
+       if ( this.title !== title ) {
+               if ( this.$titled ) {
+                       if ( title !== null ) {
+                               this.$titled.attr( 'title', title );
+                       } else {
+                               this.$titled.removeAttr( 'title' );
+                       }
+               }
+               this.title = title;
+       }
+
+       return this;
+};
+
+/**
+ * Get title.
+ *
+ * @return {string} Title string
+ */
+OO.ui.mixin.TitledElement.prototype.getTitle = function () {
+       return this.title;
+};
+
+/**
+ * AccessKeyedElement is mixed into other classes to provide an `accesskey` attribute.
+ * Accesskeys allow an user to go to a specific element by using
+ * a shortcut combination of a browser specific keys + the key
+ * set to the field.
+ *
+ *     @example
+ *     // AccessKeyedElement provides an 'accesskey' attribute to the
+ *     // ButtonWidget class
+ *     var button = new OO.ui.ButtonWidget( {
+ *         label: 'Button with Accesskey',
+ *         accessKey: 'k'
+ *     } );
+ *     $( 'body' ).append( button.$element );
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$accessKeyed] The element to which the `accesskey` attribute is applied.
+ *  If this config is omitted, the accesskey functionality is applied to $element, the
+ *  element created by the class.
+ * @cfg {string|Function} [accessKey] The key or a function that returns the key. If
+ *  this config is omitted, no accesskey will be added.
+ */
+OO.ui.mixin.AccessKeyedElement = function OoUiMixinAccessKeyedElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$accessKeyed = null;
+       this.accessKey = null;
+
+       // Initialization
+       this.setAccessKey( config.accessKey || null );
+       this.setAccessKeyedElement( config.$accessKeyed || this.$element );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.AccessKeyedElement );
+
+/* Static Properties */
+
+/**
+ * The access key, a function that returns a key, or `null` for no accesskey.
+ *
+ * @static
+ * @inheritable
+ * @property {string|Function|null}
+ */
+OO.ui.mixin.AccessKeyedElement.static.accessKey = null;
+
+/* Methods */
+
+/**
+ * Set the accesskeyed element.
+ *
+ * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to the specified element.
+ * If an element is already set, the mixin's effect on that element is removed before the new element is set up.
+ *
+ * @param {jQuery} $accessKeyed Element that should use the 'accesskeyes' functionality
+ */
+OO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $accessKeyed ) {
+       if ( this.$accessKeyed ) {
+               this.$accessKeyed.removeAttr( 'accesskey' );
+       }
+
+       this.$accessKeyed = $accessKeyed;
+       if ( this.accessKey ) {
+               this.$accessKeyed.attr( 'accesskey', this.accessKey );
+       }
+};
+
+/**
+ * Set accesskey.
+ *
+ * @param {string|Function|null} accesskey Key, a function that returns a key, or `null` for no accesskey
+ * @chainable
+ */
+OO.ui.mixin.AccessKeyedElement.prototype.setAccessKey = function ( accessKey ) {
+       accessKey = typeof accessKey === 'string' ? OO.ui.resolveMsg( accessKey ) : null;
+
+       if ( this.accessKey !== accessKey ) {
+               if ( this.$accessKeyed ) {
+                       if ( accessKey !== null ) {
+                               this.$accessKeyed.attr( 'accesskey', accessKey );
+                       } else {
+                               this.$accessKeyed.removeAttr( 'accesskey' );
+                       }
+               }
+               this.accessKey = accessKey;
+       }
+
+       return this;
+};
+
+/**
+ * Get accesskey.
+ *
+ * @return {string} accessKey string
+ */
+OO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {
+       return this.accessKey;
+};
+
+/**
+ * ButtonWidget is a generic widget for buttons. A wide variety of looks,
+ * feels, and functionality can be customized via the class’s configuration options
+ * and methods. Please see the [OOjs UI documentation on MediaWiki] [1] for more information
+ * and examples.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches
+ *
+ *     @example
+ *     // A button widget
+ *     var button = new OO.ui.ButtonWidget( {
+ *         label: 'Button with Icon',
+ *         icon: 'remove',
+ *         iconTitle: 'Remove'
+ *     } );
+ *     $( 'body' ).append( button.$element );
+ *
+ * NOTE: HTML form buttons should use the OO.ui.ButtonInputWidget class.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.ButtonElement
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.AccessKeyedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [href] Hyperlink to visit when the button is clicked.
+ * @cfg {string} [target] The frame or window in which to open the hyperlink.
+ * @cfg {boolean} [noFollow] Search engine traversal hint (default: true)
+ */
+OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ButtonWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ButtonElement.call( this, config );
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
+       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$button } ) );
+
+       // Properties
+       this.href = null;
+       this.target = null;
+       this.noFollow = false;
+
+       // Events
+       this.connect( this, { disable: 'onDisable' } );
+
+       // Initialization
+       this.$button.append( this.$icon, this.$label, this.$indicator );
+       this.$element
+               .addClass( 'oo-ui-buttonWidget' )
+               .append( this.$button );
+       this.setHref( config.href );
+       this.setTarget( config.target );
+       this.setNoFollow( config.noFollow );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ButtonWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.ButtonElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TabIndexedElement );
+OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.AccessKeyedElement );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ButtonWidget.prototype.onMouseDown = function ( e ) {
+       if ( !this.isDisabled() ) {
+               // Remove the tab-index while the button is down to prevent the button from stealing focus
+               this.$button.removeAttr( 'tabindex' );
+       }
+
+       return OO.ui.mixin.ButtonElement.prototype.onMouseDown.call( this, e );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ButtonWidget.prototype.onMouseUp = function ( e ) {
+       if ( !this.isDisabled() ) {
+               // Restore the tab-index after the button is up to restore the button's accessibility
+               this.$button.attr( 'tabindex', this.tabIndex );
+       }
+
+       return OO.ui.mixin.ButtonElement.prototype.onMouseUp.call( this, e );
+};
+
+/**
+ * Get hyperlink location.
+ *
+ * @return {string} Hyperlink location
+ */
+OO.ui.ButtonWidget.prototype.getHref = function () {
+       return this.href;
+};
+
+/**
+ * Get hyperlink target.
+ *
+ * @return {string} Hyperlink target
+ */
+OO.ui.ButtonWidget.prototype.getTarget = function () {
+       return this.target;
+};
+
+/**
+ * Get search engine traversal hint.
+ *
+ * @return {boolean} Whether search engines should avoid traversing this hyperlink
+ */
+OO.ui.ButtonWidget.prototype.getNoFollow = function () {
+       return this.noFollow;
+};
+
+/**
+ * Set hyperlink location.
+ *
+ * @param {string|null} href Hyperlink location, null to remove
+ */
+OO.ui.ButtonWidget.prototype.setHref = function ( href ) {
+       href = typeof href === 'string' ? href : null;
+       if ( href !== null && !OO.ui.isSafeUrl( href ) ) {
+               href = './' + href;
+       }
+
+       if ( href !== this.href ) {
+               this.href = href;
+               this.updateHref();
+       }
+
+       return this;
+};
+
+/**
+ * Update the `href` attribute, in case of changes to href or
+ * disabled state.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.ButtonWidget.prototype.updateHref = function () {
+       if ( this.href !== null && !this.isDisabled() ) {
+               this.$button.attr( 'href', this.href );
+       } else {
+               this.$button.removeAttr( 'href' );
+       }
+
+       return this;
+};
+
+/**
+ * Handle disable events.
+ *
+ * @private
+ * @param {boolean} disabled Element is disabled
+ */
+OO.ui.ButtonWidget.prototype.onDisable = function () {
+       this.updateHref();
+};
+
+/**
+ * Set hyperlink target.
+ *
+ * @param {string|null} target Hyperlink target, null to remove
+ */
+OO.ui.ButtonWidget.prototype.setTarget = function ( target ) {
+       target = typeof target === 'string' ? target : null;
+
+       if ( target !== this.target ) {
+               this.target = target;
+               if ( target !== null ) {
+                       this.$button.attr( 'target', target );
+               } else {
+                       this.$button.removeAttr( 'target' );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Set search engine traversal hint.
+ *
+ * @param {boolean} noFollow True if search engines should avoid traversing this hyperlink
+ */
+OO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {
+       noFollow = typeof noFollow === 'boolean' ? noFollow : true;
+
+       if ( noFollow !== this.noFollow ) {
+               this.noFollow = noFollow;
+               if ( noFollow ) {
+                       this.$button.attr( 'rel', 'nofollow' );
+               } else {
+                       this.$button.removeAttr( 'rel' );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * A ButtonGroupWidget groups related buttons and is used together with OO.ui.ButtonWidget and
+ * its subclasses. Each button in a group is addressed by a unique reference. Buttons can be added,
+ * removed, and cleared from the group.
+ *
+ *     @example
+ *     // Example: A ButtonGroupWidget with two buttons
+ *     var button1 = new OO.ui.PopupButtonWidget( {
+ *         label: 'Select a category',
+ *         icon: 'menu',
+ *         popup: {
+ *             $content: $( '<p>List of categories...</p>' ),
+ *             padded: true,
+ *             align: 'left'
+ *         }
+ *     } );
+ *     var button2 = new OO.ui.ButtonWidget( {
+ *         label: 'Add item'
+ *     });
+ *     var buttonGroup = new OO.ui.ButtonGroupWidget( {
+ *         items: [button1, button2]
+ *     } );
+ *     $( 'body' ).append( buttonGroup.$element );
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.ButtonWidget[]} [items] Buttons to add
+ */
+OO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ButtonGroupWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-buttonGroupWidget' );
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ButtonGroupWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.GroupElement );
+
+/**
+ * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}. In general, IconWidgets should be used with OO.ui.LabelWidget,
+ * which creates a label that identifies the icon’s function. See the [OOjs UI documentation on MediaWiki] [1]
+ * for a list of icons included in the library.
+ *
+ *     @example
+ *     // An icon widget with a label
+ *     var myIcon = new OO.ui.IconWidget( {
+ *         icon: 'help',
+ *         iconTitle: 'Help'
+ *      } );
+ *      // Create a label.
+ *      var iconLabel = new OO.ui.LabelWidget( {
+ *          label: 'Help'
+ *      } );
+ *      $( 'body' ).append( myIcon.$element, iconLabel.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IconWidget = function OoUiIconWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.IconWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, $.extend( {}, config, { $icon: this.$element } ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
+       OO.ui.mixin.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-iconWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.FlaggedElement );
+
+/* Static Properties */
+
+OO.ui.IconWidget.static.tagName = 'span';
+
+/**
+ * IndicatorWidgets create indicators, which are small graphics that are generally used to draw
+ * attention to the status of an item or to clarify the function of a control. For a list of
+ * indicators included in the library, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example of an indicator widget
+ *     var indicator1 = new OO.ui.IndicatorWidget( {
+ *         indicator: 'alert'
+ *     } );
+ *
+ *     // Create a fieldset layout to add a label
+ *     var fieldset = new OO.ui.FieldsetLayout();
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( indicator1, { label: 'An alert indicator:' } )
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.IndicatorWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$element } ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-indicatorWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.TitledElement );
+
+/* Static Properties */
+
+OO.ui.IndicatorWidget.static.tagName = 'span';
+
+/**
+ * LabelWidgets help identify the function of interface elements. Each LabelWidget can
+ * be configured with a `label` option that is set to a string, a label node, or a function:
+ *
+ * - String: a plaintext string
+ * - jQuery selection: a jQuery selection, used for anything other than a plaintext label, e.g., a
+ *   label that includes a link or special styling, such as a gray color or additional graphical elements.
+ * - Function: a function that will produce a string in the future. Functions are used
+ *   in cases where the value of the label is not currently defined.
+ *
+ * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget}, which
+ * will come into focus when the label is clicked.
+ *
+ *     @example
+ *     // Examples of LabelWidgets
+ *     var label1 = new OO.ui.LabelWidget( {
+ *         label: 'plaintext label'
+ *     } );
+ *     var label2 = new OO.ui.LabelWidget( {
+ *         label: $( '<a href="default.html">jQuery label</a>' )
+ *     } );
+ *     // Create a fieldset layout with fields for each example
+ *     var fieldset = new OO.ui.FieldsetLayout();
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( label1 ),
+ *         new OO.ui.FieldLayout( label2 )
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.InputWidget} [input] {@link OO.ui.InputWidget Input widget} that uses the label.
+ *  Clicking the label will focus the specified input field.
+ */
+OO.ui.LabelWidget = function OoUiLabelWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.LabelWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element } ) );
+       OO.ui.mixin.TitledElement.call( this, config );
+
+       // Properties
+       this.input = config.input;
+
+       // Events
+       if ( this.input instanceof OO.ui.InputWidget ) {
+               this.$element.on( 'click', this.onClick.bind( this ) );
+       }
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-labelWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.LabelWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.TitledElement );
+
+/* Static Properties */
+
+OO.ui.LabelWidget.static.tagName = 'span';
+
+/* Methods */
+
+/**
+ * Handles label mouse click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.LabelWidget.prototype.onClick = function () {
+       this.input.simulateLabelClick();
+       return false;
+};
+
+/**
+ * PendingElement is a mixin that is used to create elements that notify users that something is happening
+ * and that they should wait before proceeding. The pending state is visually represented with a pending
+ * texture that appears in the head of a pending {@link OO.ui.ProcessDialog process dialog} or in the input
+ * field of a {@link OO.ui.TextInputWidget text input widget}.
+ *
+ * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked as pending, but only when
+ * used in {@link OO.ui.MessageDialog message dialogs}. The behavior is not currently supported for action widgets used
+ * in process dialogs.
+ *
+ *     @example
+ *     function MessageDialog( config ) {
+ *         MessageDialog.parent.call( this, config );
+ *     }
+ *     OO.inheritClass( MessageDialog, OO.ui.MessageDialog );
+ *
+ *     MessageDialog.static.actions = [
+ *         { action: 'save', label: 'Done', flags: 'primary' },
+ *         { label: 'Cancel', flags: 'safe' }
+ *     ];
+ *
+ *     MessageDialog.prototype.initialize = function () {
+ *         MessageDialog.parent.prototype.initialize.apply( this, arguments );
+ *         this.content = new OO.ui.PanelLayout( { $: this.$, padded: true } );
+ *         this.content.$element.append( '<p>Click the \'Done\' action widget to see its pending state. Note that action widgets can be marked pending in message dialogs but not process dialogs.</p>' );
+ *         this.$body.append( this.content.$element );
+ *     };
+ *     MessageDialog.prototype.getBodyHeight = function () {
+ *         return 100;
+ *     }
+ *     MessageDialog.prototype.getActionProcess = function ( action ) {
+ *         var dialog = this;
+ *         if ( action === 'save' ) {
+ *             dialog.getActions().get({actions: 'save'})[0].pushPending();
+ *             return new OO.ui.Process()
+ *             .next( 1000 )
+ *             .next( function () {
+ *                 dialog.getActions().get({actions: 'save'})[0].popPending();
+ *             } );
+ *         }
+ *         return MessageDialog.parent.prototype.getActionProcess.call( this, action );
+ *     };
+ *
+ *     var windowManager = new OO.ui.WindowManager();
+ *     $( 'body' ).append( windowManager.$element );
+ *
+ *     var dialog = new MessageDialog();
+ *     windowManager.addWindows( [ dialog ] );
+ *     windowManager.openWindow( dialog );
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$pending] Element to mark as pending, defaults to this.$element
+ */
+OO.ui.mixin.PendingElement = function OoUiMixinPendingElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.pending = 0;
+       this.$pending = null;
+
+       // Initialisation
+       this.setPendingElement( config.$pending || this.$element );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.PendingElement );
+
+/* Methods */
+
+/**
+ * Set the pending element (and clean up any existing one).
+ *
+ * @param {jQuery} $pending The element to set to pending.
+ */
+OO.ui.mixin.PendingElement.prototype.setPendingElement = function ( $pending ) {
+       if ( this.$pending ) {
+               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
+       }
+
+       this.$pending = $pending;
+       if ( this.pending > 0 ) {
+               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
+       }
+};
+
+/**
+ * Check if an element is pending.
+ *
+ * @return {boolean} Element is pending
+ */
+OO.ui.mixin.PendingElement.prototype.isPending = function () {
+       return !!this.pending;
+};
+
+/**
+ * Increase the pending counter. The pending state will remain active until the counter is zero
+ * (i.e., the number of calls to #pushPending and #popPending is the same).
+ *
+ * @chainable
+ */
+OO.ui.mixin.PendingElement.prototype.pushPending = function () {
+       if ( this.pending === 0 ) {
+               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
+               this.updateThemeClasses();
+       }
+       this.pending++;
+
+       return this;
+};
+
+/**
+ * Decrease the pending counter. The pending state will remain active until the counter is zero
+ * (i.e., the number of calls to #pushPending and #popPending is the same).
+ *
+ * @chainable
+ */
+OO.ui.mixin.PendingElement.prototype.popPending = function () {
+       if ( this.pending === 1 ) {
+               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
+               this.updateThemeClasses();
+       }
+       this.pending = Math.max( 0, this.pending - 1 );
+
+       return this;
+};
+
+/**
+ * Element that can be automatically clipped to visible boundaries.
+ *
+ * Whenever the element's natural height changes, you have to call
+ * {@link OO.ui.mixin.ClippableElement#clip} to make sure it's still
+ * clipping correctly.
+ *
+ * The dimensions of #$clippableContainer will be compared to the boundaries of the
+ * nearest scrollable container. If #$clippableContainer is too tall and/or too wide,
+ * then #$clippable will be given a fixed reduced height and/or width and will be made
+ * scrollable. By default, #$clippable and #$clippableContainer are the same element,
+ * but you can build a static footer by setting #$clippableContainer to an element that contains
+ * #$clippable and the footer.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$clippable] Node to clip, assigned to #$clippable, omit to use #$element
+ * @cfg {jQuery} [$clippableContainer] Node to keep visible, assigned to #$clippableContainer,
+ *   omit to use #$clippable
+ */
+OO.ui.mixin.ClippableElement = function OoUiMixinClippableElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$clippable = null;
+       this.$clippableContainer = null;
+       this.clipping = false;
+       this.clippedHorizontally = false;
+       this.clippedVertically = false;
+       this.$clippableScrollableContainer = null;
+       this.$clippableScroller = null;
+       this.$clippableWindow = null;
+       this.idealWidth = null;
+       this.idealHeight = null;
+       this.onClippableScrollHandler = this.clip.bind( this );
+       this.onClippableWindowResizeHandler = this.clip.bind( this );
+
+       // Initialization
+       if ( config.$clippableContainer ) {
+               this.setClippableContainer( config.$clippableContainer );
+       }
+       this.setClippableElement( config.$clippable || this.$element );
+};
+
+/* Methods */
+
+/**
+ * Set clippable element.
+ *
+ * If an element is already set, it will be cleaned up before setting up the new element.
+ *
+ * @param {jQuery} $clippable Element to make clippable
+ */
+OO.ui.mixin.ClippableElement.prototype.setClippableElement = function ( $clippable ) {
+       if ( this.$clippable ) {
+               this.$clippable.removeClass( 'oo-ui-clippableElement-clippable' );
+               this.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );
+               OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
+       }
+
+       this.$clippable = $clippable.addClass( 'oo-ui-clippableElement-clippable' );
+       this.clip();
+};
+
+/**
+ * Set clippable container.
+ *
+ * This is the container that will be measured when deciding whether to clip. When clipping,
+ * #$clippable will be resized in order to keep the clippable container fully visible.
+ *
+ * If the clippable container is unset, #$clippable will be used.
+ *
+ * @param {jQuery|null} $clippableContainer Container to keep visible, or null to unset
+ */
+OO.ui.mixin.ClippableElement.prototype.setClippableContainer = function ( $clippableContainer ) {
+       this.$clippableContainer = $clippableContainer;
+       if ( this.$clippable ) {
+               this.clip();
+       }
+};
+
+/**
+ * Toggle clipping.
+ *
+ * Do not turn clipping on until after the element is attached to the DOM and visible.
+ *
+ * @param {boolean} [clipping] Enable clipping, omit to toggle
+ * @chainable
+ */
+OO.ui.mixin.ClippableElement.prototype.toggleClipping = function ( clipping ) {
+       clipping = clipping === undefined ? !this.clipping : !!clipping;
+
+       if ( this.clipping !== clipping ) {
+               this.clipping = clipping;
+               if ( clipping ) {
+                       this.$clippableScrollableContainer = $( this.getClosestScrollableElementContainer() );
+                       // If the clippable container is the root, we have to listen to scroll events and check
+                       // jQuery.scrollTop on the window because of browser inconsistencies
+                       this.$clippableScroller = this.$clippableScrollableContainer.is( 'html, body' ) ?
+                               $( OO.ui.Element.static.getWindow( this.$clippableScrollableContainer ) ) :
+                               this.$clippableScrollableContainer;
+                       this.$clippableScroller.on( 'scroll', this.onClippableScrollHandler );
+                       this.$clippableWindow = $( this.getElementWindow() )
+                               .on( 'resize', this.onClippableWindowResizeHandler );
+                       // Initial clip after visible
+                       this.clip();
+               } else {
+                       this.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );
+                       OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
+
+                       this.$clippableScrollableContainer = null;
+                       this.$clippableScroller.off( 'scroll', this.onClippableScrollHandler );
+                       this.$clippableScroller = null;
+                       this.$clippableWindow.off( 'resize', this.onClippableWindowResizeHandler );
+                       this.$clippableWindow = null;
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Check if the element will be clipped to fit the visible area of the nearest scrollable container.
+ *
+ * @return {boolean} Element will be clipped to the visible area
+ */
+OO.ui.mixin.ClippableElement.prototype.isClipping = function () {
+       return this.clipping;
+};
+
+/**
+ * Check if the bottom or right of the element is being clipped by the nearest scrollable container.
+ *
+ * @return {boolean} Part of the element is being clipped
+ */
+OO.ui.mixin.ClippableElement.prototype.isClipped = function () {
+       return this.clippedHorizontally || this.clippedVertically;
+};
+
+/**
+ * Check if the right of the element is being clipped by the nearest scrollable container.
+ *
+ * @return {boolean} Part of the element is being clipped
+ */
+OO.ui.mixin.ClippableElement.prototype.isClippedHorizontally = function () {
+       return this.clippedHorizontally;
+};
+
+/**
+ * Check if the bottom of the element is being clipped by the nearest scrollable container.
+ *
+ * @return {boolean} Part of the element is being clipped
+ */
+OO.ui.mixin.ClippableElement.prototype.isClippedVertically = function () {
+       return this.clippedVertically;
+};
+
+/**
+ * Set the ideal size. These are the dimensions the element will have when it's not being clipped.
+ *
+ * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix
+ * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix
+ */
+OO.ui.mixin.ClippableElement.prototype.setIdealSize = function ( width, height ) {
+       this.idealWidth = width;
+       this.idealHeight = height;
+
+       if ( !this.clipping ) {
+               // Update dimensions
+               this.$clippable.css( { width: width, height: height } );
+       }
+       // While clipping, idealWidth and idealHeight are not considered
+};
+
+/**
+ * Clip element to visible boundaries and allow scrolling when needed. Call this method when
+ * the element's natural height changes.
+ *
+ * Element will be clipped the bottom or right of the element is within 10px of the edge of, or
+ * overlapped by, the visible area of the nearest scrollable container.
+ *
+ * @chainable
+ */
+OO.ui.mixin.ClippableElement.prototype.clip = function () {
+       var $container, extraHeight, extraWidth, ccOffset,
+               $scrollableContainer, scOffset, scHeight, scWidth,
+               ccWidth, scrollerIsWindow, scrollTop, scrollLeft,
+               desiredWidth, desiredHeight, allotedWidth, allotedHeight,
+               naturalWidth, naturalHeight, clipWidth, clipHeight,
+               buffer = 7; // Chosen by fair dice roll
+
+       if ( !this.clipping ) {
+               // this.$clippableScrollableContainer and this.$clippableWindow are null, so the below will fail
+               return this;
+       }
+
+       $container = this.$clippableContainer || this.$clippable;
+       extraHeight = $container.outerHeight() - this.$clippable.outerHeight();
+       extraWidth = $container.outerWidth() - this.$clippable.outerWidth();
+       ccOffset = $container.offset();
+       $scrollableContainer = this.$clippableScrollableContainer.is( 'html, body' ) ?
+               this.$clippableWindow : this.$clippableScrollableContainer;
+       scOffset = $scrollableContainer.offset() || { top: 0, left: 0 };
+       scHeight = $scrollableContainer.innerHeight() - buffer;
+       scWidth = $scrollableContainer.innerWidth() - buffer;
+       ccWidth = $container.outerWidth() + buffer;
+       scrollerIsWindow = this.$clippableScroller[ 0 ] === this.$clippableWindow[ 0 ];
+       scrollTop = scrollerIsWindow ? this.$clippableScroller.scrollTop() : 0;
+       scrollLeft = scrollerIsWindow ? this.$clippableScroller.scrollLeft() : 0;
+       desiredWidth = ccOffset.left < 0 ?
+               ccWidth + ccOffset.left :
+               ( scOffset.left + scrollLeft + scWidth ) - ccOffset.left;
+       desiredHeight = ( scOffset.top + scrollTop + scHeight ) - ccOffset.top;
+       allotedWidth = Math.ceil( desiredWidth - extraWidth );
+       allotedHeight = Math.ceil( desiredHeight - extraHeight );
+       naturalWidth = this.$clippable.prop( 'scrollWidth' );
+       naturalHeight = this.$clippable.prop( 'scrollHeight' );
+       clipWidth = allotedWidth < naturalWidth;
+       clipHeight = allotedHeight < naturalHeight;
+
+       if ( clipWidth ) {
+               this.$clippable.css( { overflowX: 'scroll', width: Math.max( 0, allotedWidth ) } );
+       } else {
+               this.$clippable.css( { width: this.idealWidth ? this.idealWidth - extraWidth : '', overflowX: '' } );
+       }
+       if ( clipHeight ) {
+               this.$clippable.css( { overflowY: 'scroll', height: Math.max( 0, allotedHeight ) } );
+       } else {
+               this.$clippable.css( { height: this.idealHeight ? this.idealHeight - extraHeight : '', overflowY: '' } );
+       }
+
+       // If we stopped clipping in at least one of the dimensions
+       if ( ( this.clippedHorizontally && !clipWidth ) || ( this.clippedVertically && !clipHeight ) ) {
+               OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
+       }
+
+       this.clippedHorizontally = clipWidth;
+       this.clippedVertically = clipHeight;
+
+       return this;
+};
+
+/**
+ * PopupWidget is a container for content. The popup is overlaid and positioned absolutely.
+ * By default, each popup has an anchor that points toward its origin.
+ * Please see the [OOjs UI documentation on Mediawiki] [1] for more information and examples.
+ *
+ *     @example
+ *     // A popup widget.
+ *     var popup = new OO.ui.PopupWidget( {
+ *         $content: $( '<p>Hi there!</p>' ),
+ *         padded: true,
+ *         width: 300
+ *     } );
+ *
+ *     $( 'body' ).append( popup.$element );
+ *     // To display the popup, toggle the visibility to 'true'.
+ *     popup.toggle( true );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.ClippableElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {number} [width=320] Width of popup in pixels
+ * @cfg {number} [height] Height of popup in pixels. Omit to use the automatic height.
+ * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup
+ * @cfg {string} [align='center'] Alignment of the popup: `center`, `force-left`, `force-right`, `backwards` or `forwards`.
+ *  If the popup is forced-left the popup body is leaning towards the left. For force-right alignment, the body of the
+ *  popup is leaning towards the right of the screen.
+ *  Using 'backwards' is a logical direction which will result in the popup leaning towards the beginning of the sentence
+ *  in the given language, which means it will flip to the correct positioning in right-to-left languages.
+ *  Using 'forward' will also result in a logical alignment where the body of the popup leans towards the end of the
+ *  sentence in the given language.
+ * @cfg {jQuery} [$container] Constrain the popup to the boundaries of the specified container.
+ *  See the [OOjs UI docs on MediaWiki][3] for an example.
+ *  [3]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups#containerExample
+ * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a number of pixels.
+ * @cfg {jQuery} [$content] Content to append to the popup's body
+ * @cfg {jQuery} [$footer] Content to append to the popup's footer
+ * @cfg {boolean} [autoClose=false] Automatically close the popup when it loses focus.
+ * @cfg {jQuery} [$autoCloseIgnore] Elements that will not close the popup when clicked.
+ *  This config option is only relevant if #autoClose is set to `true`. See the [OOjs UI docs on MediaWiki][2]
+ *  for an example.
+ *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups#autocloseExample
+ * @cfg {boolean} [head] Show a popup header that contains a #label (if specified) and close
+ *  button.
+ * @cfg {boolean} [padded] Add padding to the popup's body
+ */
+OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.PopupWidget.parent.call( this, config );
+
+       // Properties (must be set before ClippableElement constructor call)
+       this.$body = $( '<div>' );
+       this.$popup = $( '<div>' );
+
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, {
+               $clippable: this.$body,
+               $clippableContainer: this.$popup
+       } ) );
+
+       // Properties
+       this.$head = $( '<div>' );
+       this.$footer = $( '<div>' );
+       this.$anchor = $( '<div>' );
+       // If undefined, will be computed lazily in updateDimensions()
+       this.$container = config.$container;
+       this.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;
+       this.autoClose = !!config.autoClose;
+       this.$autoCloseIgnore = config.$autoCloseIgnore;
+       this.transitionTimeout = null;
+       this.anchor = null;
+       this.width = config.width !== undefined ? config.width : 320;
+       this.height = config.height !== undefined ? config.height : null;
+       this.setAlignment( config.align );
+       this.closeButton = new OO.ui.ButtonWidget( { framed: false, icon: 'close' } );
+       this.onMouseDownHandler = this.onMouseDown.bind( this );
+       this.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );
+
+       // Events
+       this.closeButton.connect( this, { click: 'onCloseButtonClick' } );
+
+       // Initialization
+       this.toggleAnchor( config.anchor === undefined || config.anchor );
+       this.$body.addClass( 'oo-ui-popupWidget-body' );
+       this.$anchor.addClass( 'oo-ui-popupWidget-anchor' );
+       this.$head
+               .addClass( 'oo-ui-popupWidget-head' )
+               .append( this.$label, this.closeButton.$element );
+       this.$footer.addClass( 'oo-ui-popupWidget-footer' );
+       if ( !config.head ) {
+               this.$head.addClass( 'oo-ui-element-hidden' );
+       }
+       if ( !config.$footer ) {
+               this.$footer.addClass( 'oo-ui-element-hidden' );
+       }
+       this.$popup
+               .addClass( 'oo-ui-popupWidget-popup' )
+               .append( this.$head, this.$body, this.$footer );
+       this.$element
+               .addClass( 'oo-ui-popupWidget' )
+               .append( this.$popup, this.$anchor );
+       // Move content, which was added to #$element by OO.ui.Widget, to the body
+       if ( config.$content instanceof jQuery ) {
+               this.$body.append( config.$content );
+       }
+       if ( config.$footer instanceof jQuery ) {
+               this.$footer.append( config.$footer );
+       }
+       if ( config.padded ) {
+               this.$body.addClass( 'oo-ui-popupWidget-body-padded' );
+       }
+
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PopupWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );
+
+/* Methods */
+
+/**
+ * Handles mouse down events.
+ *
+ * @private
+ * @param {MouseEvent} e Mouse down event
+ */
+OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
+       if (
+               this.isVisible() &&
+               !$.contains( this.$element[ 0 ], e.target ) &&
+               ( !this.$autoCloseIgnore || !this.$autoCloseIgnore.has( e.target ).length )
+       ) {
+               this.toggle( false );
+       }
+};
+
+/**
+ * Bind mouse down listener.
+ *
+ * @private
+ */
+OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
+       // Capture clicks outside popup
+       this.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, true );
+};
+
+/**
+ * Handles close button click events.
+ *
+ * @private
+ */
+OO.ui.PopupWidget.prototype.onCloseButtonClick = function () {
+       if ( this.isVisible() ) {
+               this.toggle( false );
+       }
+};
+
+/**
+ * Unbind mouse down listener.
+ *
+ * @private
+ */
+OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
+       this.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );
+};
+
+/**
+ * Handles key down events.
+ *
+ * @private
+ * @param {KeyboardEvent} e Key down event
+ */
+OO.ui.PopupWidget.prototype.onDocumentKeyDown = function ( e ) {
+       if (
+               e.which === OO.ui.Keys.ESCAPE &&
+               this.isVisible()
+       ) {
+               this.toggle( false );
+               e.preventDefault();
+               e.stopPropagation();
+       }
+};
+
+/**
+ * Bind key down listener.
+ *
+ * @private
+ */
+OO.ui.PopupWidget.prototype.bindKeyDownListener = function () {
+       this.getElementWindow().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
+};
+
+/**
+ * Unbind key down listener.
+ *
+ * @private
+ */
+OO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {
+       this.getElementWindow().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
+};
+
+/**
+ * Show, hide, or toggle the visibility of the anchor.
+ *
+ * @param {boolean} [show] Show anchor, omit to toggle
+ */
+OO.ui.PopupWidget.prototype.toggleAnchor = function ( show ) {
+       show = show === undefined ? !this.anchored : !!show;
+
+       if ( this.anchored !== show ) {
+               if ( show ) {
+                       this.$element.addClass( 'oo-ui-popupWidget-anchored' );
+               } else {
+                       this.$element.removeClass( 'oo-ui-popupWidget-anchored' );
+               }
+               this.anchored = show;
+       }
+};
+
+/**
+ * Check if the anchor is visible.
+ *
+ * @return {boolean} Anchor is visible
+ */
+OO.ui.PopupWidget.prototype.hasAnchor = function () {
+       return this.anchor;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupWidget.prototype.toggle = function ( show ) {
+       var change;
+       show = show === undefined ? !this.isVisible() : !!show;
+
+       change = show !== this.isVisible();
+
+       // Parent method
+       OO.ui.PopupWidget.parent.prototype.toggle.call( this, show );
+
+       if ( change ) {
+               if ( show ) {
+                       if ( this.autoClose ) {
+                               this.bindMouseDownListener();
+                               this.bindKeyDownListener();
+                       }
+                       this.updateDimensions();
+                       this.toggleClipping( true );
+               } else {
+                       this.toggleClipping( false );
+                       if ( this.autoClose ) {
+                               this.unbindMouseDownListener();
+                               this.unbindKeyDownListener();
+                       }
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Set the size of the popup.
+ *
+ * Changing the size may also change the popup's position depending on the alignment.
+ *
+ * @param {number} width Width in pixels
+ * @param {number} height Height in pixels
+ * @param {boolean} [transition=false] Use a smooth transition
+ * @chainable
+ */
+OO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {
+       this.width = width;
+       this.height = height !== undefined ? height : null;
+       if ( this.isVisible() ) {
+               this.updateDimensions( transition );
+       }
+};
+
+/**
+ * Update the size and position.
+ *
+ * Only use this to keep the popup properly anchored. Use #setSize to change the size, and this will
+ * be called automatically.
+ *
+ * @param {boolean} [transition=false] Use a smooth transition
+ * @chainable
+ */
+OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
+       var popupOffset, originOffset, containerLeft, containerWidth, containerRight,
+               popupLeft, popupRight, overlapLeft, overlapRight, anchorWidth,
+               align = this.align,
+               widget = this;
+
+       if ( !this.$container ) {
+               // Lazy-initialize $container if not specified in constructor
+               this.$container = $( this.getClosestScrollableElementContainer() );
+       }
+
+       // Set height and width before measuring things, since it might cause our measurements
+       // to change (e.g. due to scrollbars appearing or disappearing)
+       this.$popup.css( {
+               width: this.width,
+               height: this.height !== null ? this.height : 'auto'
+       } );
+
+       // If we are in RTL, we need to flip the alignment, unless it is center
+       if ( align === 'forwards' || align === 'backwards' ) {
+               if ( this.$container.css( 'direction' ) === 'rtl' ) {
+                       align = ( { forwards: 'force-left', backwards: 'force-right' } )[ this.align ];
+               } else {
+                       align = ( { forwards: 'force-right', backwards: 'force-left' } )[ this.align ];
+               }
+
+       }
+
+       // Compute initial popupOffset based on alignment
+       popupOffset = this.width * ( { 'force-left': -1, center: -0.5, 'force-right': 0 } )[ align ];
+
+       // Figure out if this will cause the popup to go beyond the edge of the container
+       originOffset = this.$element.offset().left;
+       containerLeft = this.$container.offset().left;
+       containerWidth = this.$container.innerWidth();
+       containerRight = containerLeft + containerWidth;
+       popupLeft = popupOffset - this.containerPadding;
+       popupRight = popupOffset + this.containerPadding + this.width + this.containerPadding;
+       overlapLeft = ( originOffset + popupLeft ) - containerLeft;
+       overlapRight = containerRight - ( originOffset + popupRight );
+
+       // Adjust offset to make the popup not go beyond the edge, if needed
+       if ( overlapRight < 0 ) {
+               popupOffset += overlapRight;
+       } else if ( overlapLeft < 0 ) {
+               popupOffset -= overlapLeft;
+       }
+
+       // Adjust offset to avoid anchor being rendered too close to the edge
+       // $anchor.width() doesn't work with the pure CSS anchor (returns 0)
+       // TODO: Find a measurement that works for CSS anchors and image anchors
+       anchorWidth = this.$anchor[ 0 ].scrollWidth * 2;
+       if ( popupOffset + this.width < anchorWidth ) {
+               popupOffset = anchorWidth - this.width;
+       } else if ( -popupOffset < anchorWidth ) {
+               popupOffset = -anchorWidth;
+       }
+
+       // Prevent transition from being interrupted
+       clearTimeout( this.transitionTimeout );
+       if ( transition ) {
+               // Enable transition
+               this.$element.addClass( 'oo-ui-popupWidget-transitioning' );
+       }
+
+       // Position body relative to anchor
+       this.$popup.css( 'margin-left', popupOffset );
+
+       if ( transition ) {
+               // Prevent transitioning after transition is complete
+               this.transitionTimeout = setTimeout( function () {
+                       widget.$element.removeClass( 'oo-ui-popupWidget-transitioning' );
+               }, 200 );
+       } else {
+               // Prevent transitioning immediately
+               this.$element.removeClass( 'oo-ui-popupWidget-transitioning' );
+       }
+
+       // Reevaluate clipping state since we've relocated and resized the popup
+       this.clip();
+
+       return this;
+};
+
+/**
+ * Set popup alignment
+ * @param {string} align Alignment of the popup, `center`, `force-left`, `force-right`,
+ *  `backwards` or `forwards`.
+ */
+OO.ui.PopupWidget.prototype.setAlignment = function ( align ) {
+       // Validate alignment and transform deprecated values
+       if ( [ 'left', 'right', 'force-left', 'force-right', 'backwards', 'forwards', 'center' ].indexOf( align ) > -1 ) {
+               this.align = { left: 'force-right', right: 'force-left' }[ align ] || align;
+       } else {
+               this.align = 'center';
+       }
+};
+
+/**
+ * Get popup alignment
+ * @return {string} align Alignment of the popup, `center`, `force-left`, `force-right`,
+ *  `backwards` or `forwards`.
+ */
+OO.ui.PopupWidget.prototype.getAlignment = function () {
+       return this.align;
+};
+
+/**
+ * PopupElement is mixed into other classes to generate a {@link OO.ui.PopupWidget popup widget}.
+ * A popup is a container for content. It is overlaid and positioned absolutely. By default, each
+ * popup has an anchor, which is an arrow-like protrusion that points toward the popup’s origin.
+ * See {@link OO.ui.PopupWidget PopupWidget} for an example.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object} [popup] Configuration to pass to popup
+ * @cfg {boolean} [popup.autoClose=true] Popup auto-closes when it loses focus
+ */
+OO.ui.mixin.PopupElement = function OoUiMixinPopupElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.popup = new OO.ui.PopupWidget( $.extend(
+               { autoClose: true },
+               config.popup,
+               { $autoCloseIgnore: this.$element }
+       ) );
+};
+
+/* Methods */
+
+/**
+ * Get popup.
+ *
+ * @return {OO.ui.PopupWidget} Popup widget
+ */
+OO.ui.mixin.PopupElement.prototype.getPopup = function () {
+       return this.popup;
+};
+
+/**
+ * PopupButtonWidgets toggle the visibility of a contained {@link OO.ui.PopupWidget PopupWidget},
+ * which is used to display additional information or options.
+ *
+ *     @example
+ *     // Example of a popup button.
+ *     var popupButton = new OO.ui.PopupButtonWidget( {
+ *         label: 'Popup button with options',
+ *         icon: 'menu',
+ *         popup: {
+ *             $content: $( '<p>Additional options here.</p>' ),
+ *             padded: true,
+ *             align: 'force-left'
+ *         }
+ *     } );
+ *     // Append the button to the DOM.
+ *     $( 'body' ).append( popupButton.$element );
+ *
+ * @class
+ * @extends OO.ui.ButtonWidget
+ * @mixins OO.ui.mixin.PopupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
+       // Parent constructor
+       OO.ui.PopupButtonWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.PopupElement.call( this, config );
+
+       // Events
+       this.connect( this, { click: 'onAction' } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-popupButtonWidget' )
+               .attr( 'aria-haspopup', 'true' )
+               .append( this.popup.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PopupButtonWidget, OO.ui.ButtonWidget );
+OO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.mixin.PopupElement );
+
+/* Methods */
+
+/**
+ * Handle the button action being triggered.
+ *
+ * @private
+ */
+OO.ui.PopupButtonWidget.prototype.onAction = function () {
+       this.popup.toggle();
+};
+
+/**
+ * Mixin for OO.ui.Widget subclasses to provide OO.ui.mixin.GroupElement.
+ *
+ * Use together with OO.ui.mixin.ItemWidget to make disabled state inheritable.
+ *
+ * @private
+ * @abstract
+ * @class
+ * @extends OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.mixin.GroupWidget = function OoUiMixinGroupWidget( config ) {
+       // Parent constructor
+       OO.ui.mixin.GroupWidget.parent.call( this, config );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.mixin.GroupWidget, OO.ui.mixin.GroupElement );
+
+/* Methods */
+
+/**
+ * Set the disabled state of the widget.
+ *
+ * This will also update the disabled state of child widgets.
+ *
+ * @param {boolean} disabled Disable widget
+ * @chainable
+ */
+OO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) {
+       var i, len;
+
+       // Parent method
+       // Note: Calling #setDisabled this way assumes this is mixed into an OO.ui.Widget
+       OO.ui.Widget.prototype.setDisabled.call( this, disabled );
+
+       // During construction, #setDisabled is called before the OO.ui.mixin.GroupElement constructor
+       if ( this.items ) {
+               for ( i = 0, len = this.items.length; i < len; i++ ) {
+                       this.items[ i ].updateDisabled();
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Mixin for widgets used as items in widgets that mix in OO.ui.mixin.GroupWidget.
+ *
+ * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group. This
+ * allows bidirectional communication.
+ *
+ * Use together with OO.ui.mixin.GroupWidget to make disabled state inheritable.
+ *
+ * @private
+ * @abstract
+ * @class
+ *
+ * @constructor
+ */
+OO.ui.mixin.ItemWidget = function OoUiMixinItemWidget() {
+       //
+};
+
+/* Methods */
+
+/**
+ * Check if widget is disabled.
+ *
+ * Checks parent if present, making disabled state inheritable.
+ *
+ * @return {boolean} Widget is disabled
+ */
+OO.ui.mixin.ItemWidget.prototype.isDisabled = function () {
+       return this.disabled ||
+               ( this.elementGroup instanceof OO.ui.Widget && this.elementGroup.isDisabled() );
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.mixin.ItemWidget.prototype.setElementGroup = function ( group ) {
+       // Parent method
+       // Note: Calling #setElementGroup this way assumes this is mixed into an OO.ui.Element
+       OO.ui.Element.prototype.setElementGroup.call( this, group );
+
+       // Initialize item disabled states
+       this.updateDisabled();
+
+       return this;
+};
+
+/**
+ * OptionWidgets are special elements that can be selected and configured with data. The
+ * data is often unique for each option, but it does not have to be. OptionWidgets are used
+ * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information
+ * and examples, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.OptionWidget = function OoUiOptionWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.OptionWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ItemWidget.call( this );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+
+       // Properties
+       this.selected = false;
+       this.highlighted = false;
+       this.pressed = false;
+
+       // Initialization
+       this.$element
+               .data( 'oo-ui-optionWidget', this )
+               .attr( 'role', 'option' )
+               .attr( 'aria-selected', 'false' )
+               .addClass( 'oo-ui-optionWidget' )
+               .append( this.$label );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.ItemWidget );
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.FlaggedElement );
+
+/* Static Properties */
+
+OO.ui.OptionWidget.static.selectable = true;
+
+OO.ui.OptionWidget.static.highlightable = true;
+
+OO.ui.OptionWidget.static.pressable = true;
+
+OO.ui.OptionWidget.static.scrollIntoViewOnSelect = false;
+
+/* Methods */
+
+/**
+ * Check if the option can be selected.
+ *
+ * @return {boolean} Item is selectable
+ */
+OO.ui.OptionWidget.prototype.isSelectable = function () {
+       return this.constructor.static.selectable && !this.isDisabled() && this.isVisible();
+};
+
+/**
+ * Check if the option can be highlighted. A highlight indicates that the option
+ * may be selected when a user presses enter or clicks. Disabled items cannot
+ * be highlighted.
+ *
+ * @return {boolean} Item is highlightable
+ */
+OO.ui.OptionWidget.prototype.isHighlightable = function () {
+       return this.constructor.static.highlightable && !this.isDisabled() && this.isVisible();
+};
+
+/**
+ * Check if the option can be pressed. The pressed state occurs when a user mouses
+ * down on an item, but has not yet let go of the mouse.
+ *
+ * @return {boolean} Item is pressable
+ */
+OO.ui.OptionWidget.prototype.isPressable = function () {
+       return this.constructor.static.pressable && !this.isDisabled() && this.isVisible();
+};
+
+/**
+ * Check if the option is selected.
+ *
+ * @return {boolean} Item is selected
+ */
+OO.ui.OptionWidget.prototype.isSelected = function () {
+       return this.selected;
+};
+
+/**
+ * Check if the option is highlighted. A highlight indicates that the
+ * item may be selected when a user presses enter or clicks.
+ *
+ * @return {boolean} Item is highlighted
+ */
+OO.ui.OptionWidget.prototype.isHighlighted = function () {
+       return this.highlighted;
+};
+
+/**
+ * Check if the option is pressed. The pressed state occurs when a user mouses
+ * down on an item, but has not yet let go of the mouse. The item may appear
+ * selected, but it will not be selected until the user releases the mouse.
+ *
+ * @return {boolean} Item is pressed
+ */
+OO.ui.OptionWidget.prototype.isPressed = function () {
+       return this.pressed;
+};
+
+/**
+ * Set the option’s selected state. In general, all modifications to the selection
+ * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}
+ * method instead of this method.
+ *
+ * @param {boolean} [state=false] Select option
+ * @chainable
+ */
+OO.ui.OptionWidget.prototype.setSelected = function ( state ) {
+       if ( this.constructor.static.selectable ) {
+               this.selected = !!state;
+               this.$element
+                       .toggleClass( 'oo-ui-optionWidget-selected', state )
+                       .attr( 'aria-selected', state.toString() );
+               if ( state && this.constructor.static.scrollIntoViewOnSelect ) {
+                       this.scrollElementIntoView();
+               }
+               this.updateThemeClasses();
+       }
+       return this;
+};
+
+/**
+ * Set the option’s highlighted state. In general, all programmatic
+ * modifications to the highlight should be handled by the
+ * SelectWidget’s {@link OO.ui.SelectWidget#highlightItem highlightItem( [item] )}
+ * method instead of this method.
+ *
+ * @param {boolean} [state=false] Highlight option
+ * @chainable
+ */
+OO.ui.OptionWidget.prototype.setHighlighted = function ( state ) {
+       if ( this.constructor.static.highlightable ) {
+               this.highlighted = !!state;
+               this.$element.toggleClass( 'oo-ui-optionWidget-highlighted', state );
+               this.updateThemeClasses();
+       }
+       return this;
+};
+
+/**
+ * Set the option’s pressed state. In general, all
+ * programmatic modifications to the pressed state should be handled by the
+ * SelectWidget’s {@link OO.ui.SelectWidget#pressItem pressItem( [item] )}
+ * method instead of this method.
+ *
+ * @param {boolean} [state=false] Press option
+ * @chainable
+ */
+OO.ui.OptionWidget.prototype.setPressed = function ( state ) {
+       if ( this.constructor.static.pressable ) {
+               this.pressed = !!state;
+               this.$element.toggleClass( 'oo-ui-optionWidget-pressed', state );
+               this.updateThemeClasses();
+       }
+       return this;
+};
+
+/**
+ * A SelectWidget is of a generic selection of options. The OOjs UI library contains several types of
+ * select widgets, including {@link OO.ui.ButtonSelectWidget button selects},
+ * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget
+ * menu selects}.
+ *
+ * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For more
+ * information, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example of a select widget with three options
+ *     var select = new OO.ui.SelectWidget( {
+ *         items: [
+ *             new OO.ui.OptionWidget( {
+ *                 data: 'a',
+ *                 label: 'Option One',
+ *             } ),
+ *             new OO.ui.OptionWidget( {
+ *                 data: 'b',
+ *                 label: 'Option Two',
+ *             } ),
+ *             new OO.ui.OptionWidget( {
+ *                 data: 'c',
+ *                 label: 'Option Three',
+ *             } )
+ *         ]
+ *     } );
+ *     $( 'body' ).append( select.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.GroupWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.OptionWidget[]} [items] An array of options to add to the select.
+ *  Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See
+ *  the [OOjs UI documentation on MediaWiki] [2] for examples.
+ *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ */
+OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.SelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupWidget.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       // Properties
+       this.pressed = false;
+       this.selecting = null;
+       this.onMouseUpHandler = this.onMouseUp.bind( this );
+       this.onMouseMoveHandler = this.onMouseMove.bind( this );
+       this.onKeyDownHandler = this.onKeyDown.bind( this );
+       this.onKeyPressHandler = this.onKeyPress.bind( this );
+       this.keyPressBuffer = '';
+       this.keyPressBufferTimer = null;
+
+       // Events
+       this.connect( this, {
+               toggle: 'onToggle'
+       } );
+       this.$element.on( {
+               mousedown: this.onMouseDown.bind( this ),
+               mouseover: this.onMouseOver.bind( this ),
+               mouseleave: this.onMouseLeave.bind( this )
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' )
+               .attr( 'role', 'listbox' );
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );
+
+// Need to mixin base class as well
+OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupElement );
+OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );
+
+/* Static */
+OO.ui.SelectWidget.static.passAllFilter = function () {
+       return true;
+};
+
+/* Events */
+
+/**
+ * @event highlight
+ *
+ * A `highlight` event is emitted when the highlight is changed with the #highlightItem method.
+ *
+ * @param {OO.ui.OptionWidget|null} item Highlighted item
+ */
+
+/**
+ * @event press
+ *
+ * A `press` event is emitted when the #pressItem method is used to programmatically modify the
+ * pressed state of an option.
+ *
+ * @param {OO.ui.OptionWidget|null} item Pressed item
+ */
+
+/**
+ * @event select
+ *
+ * A `select` event is emitted when the selection is modified programmatically with the #selectItem method.
+ *
+ * @param {OO.ui.OptionWidget|null} item Selected item
+ */
+
+/**
+ * @event choose
+ * A `choose` event is emitted when an item is chosen with the #chooseItem method.
+ * @param {OO.ui.OptionWidget} item Chosen item
+ */
+
+/**
+ * @event add
+ *
+ * An `add` event is emitted when options are added to the select with the #addItems method.
+ *
+ * @param {OO.ui.OptionWidget[]} items Added items
+ * @param {number} index Index of insertion point
+ */
+
+/**
+ * @event remove
+ *
+ * A `remove` event is emitted when options are removed from the select with the #clearItems
+ * or #removeItems methods.
+ *
+ * @param {OO.ui.OptionWidget[]} items Removed items
+ */
+
+/* Methods */
+
+/**
+ * Handle mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ */
+OO.ui.SelectWidget.prototype.onMouseDown = function ( e ) {
+       var item;
+
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.togglePressed( true );
+               item = this.getTargetItem( e );
+               if ( item && item.isSelectable() ) {
+                       this.pressItem( item );
+                       this.selecting = item;
+                       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
+                       this.getElementDocument().addEventListener( 'mousemove', this.onMouseMoveHandler, true );
+               }
+       }
+       return false;
+};
+
+/**
+ * Handle mouse up events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse up event
+ */
+OO.ui.SelectWidget.prototype.onMouseUp = function ( e ) {
+       var item;
+
+       this.togglePressed( false );
+       if ( !this.selecting ) {
+               item = this.getTargetItem( e );
+               if ( item && item.isSelectable() ) {
+                       this.selecting = item;
+               }
+       }
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT && this.selecting ) {
+               this.pressItem( null );
+               this.chooseItem( this.selecting );
+               this.selecting = null;
+       }
+
+       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
+       this.getElementDocument().removeEventListener( 'mousemove', this.onMouseMoveHandler, true );
+
+       return false;
+};
+
+/**
+ * Handle mouse move events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse move event
+ */
+OO.ui.SelectWidget.prototype.onMouseMove = function ( e ) {
+       var item;
+
+       if ( !this.isDisabled() && this.pressed ) {
+               item = this.getTargetItem( e );
+               if ( item && item !== this.selecting && item.isSelectable() ) {
+                       this.pressItem( item );
+                       this.selecting = item;
+               }
+       }
+       return false;
+};
+
+/**
+ * Handle mouse over events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse over event
+ */
+OO.ui.SelectWidget.prototype.onMouseOver = function ( e ) {
+       var item;
+
+       if ( !this.isDisabled() ) {
+               item = this.getTargetItem( e );
+               this.highlightItem( item && item.isHighlightable() ? item : null );
+       }
+       return false;
+};
+
+/**
+ * Handle mouse leave events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse over event
+ */
+OO.ui.SelectWidget.prototype.onMouseLeave = function () {
+       if ( !this.isDisabled() ) {
+               this.highlightItem( null );
+       }
+       return false;
+};
+
+/**
+ * Handle key down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.SelectWidget.prototype.onKeyDown = function ( e ) {
+       var nextItem,
+               handled = false,
+               currentItem = this.getHighlightedItem() || this.getSelectedItem();
+
+       if ( !this.isDisabled() && this.isVisible() ) {
+               switch ( e.keyCode ) {
+                       case OO.ui.Keys.ENTER:
+                               if ( currentItem && currentItem.constructor.static.highlightable ) {
+                                       // Was only highlighted, now let's select it. No-op if already selected.
+                                       this.chooseItem( currentItem );
+                                       handled = true;
+                               }
+                               break;
+                       case OO.ui.Keys.UP:
+                       case OO.ui.Keys.LEFT:
+                               this.clearKeyPressBuffer();
+                               nextItem = this.getRelativeSelectableItem( currentItem, -1 );
+                               handled = true;
+                               break;
+                       case OO.ui.Keys.DOWN:
+                       case OO.ui.Keys.RIGHT:
+                               this.clearKeyPressBuffer();
+                               nextItem = this.getRelativeSelectableItem( currentItem, 1 );
+                               handled = true;
+                               break;
+                       case OO.ui.Keys.ESCAPE:
+                       case OO.ui.Keys.TAB:
+                               if ( currentItem && currentItem.constructor.static.highlightable ) {
+                                       currentItem.setHighlighted( false );
+                               }
+                               this.unbindKeyDownListener();
+                               this.unbindKeyPressListener();
+                               // Don't prevent tabbing away / defocusing
+                               handled = false;
+                               break;
+               }
+
+               if ( nextItem ) {
+                       if ( nextItem.constructor.static.highlightable ) {
+                               this.highlightItem( nextItem );
+                       } else {
+                               this.chooseItem( nextItem );
+                       }
+                       nextItem.scrollElementIntoView();
+               }
+
+               if ( handled ) {
+                       // Can't just return false, because e is not always a jQuery event
+                       e.preventDefault();
+                       e.stopPropagation();
+               }
+       }
+};
+
+/**
+ * Bind key down listener.
+ *
+ * @protected
+ */
+OO.ui.SelectWidget.prototype.bindKeyDownListener = function () {
+       this.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );
+};
+
+/**
+ * Unbind key down listener.
+ *
+ * @protected
+ */
+OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {
+       this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true );
+};
+
+/**
+ * Clear the key-press buffer
+ *
+ * @protected
+ */
+OO.ui.SelectWidget.prototype.clearKeyPressBuffer = function () {
+       if ( this.keyPressBufferTimer ) {
+               clearTimeout( this.keyPressBufferTimer );
+               this.keyPressBufferTimer = null;
+       }
+       this.keyPressBuffer = '';
+};
+
+/**
+ * Handle key press events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.SelectWidget.prototype.onKeyPress = function ( e ) {
+       var c, filter, item;
+
+       if ( !e.charCode ) {
+               if ( e.keyCode === OO.ui.Keys.BACKSPACE && this.keyPressBuffer !== '' ) {
+                       this.keyPressBuffer = this.keyPressBuffer.substr( 0, this.keyPressBuffer.length - 1 );
+                       return false;
+               }
+               return;
+       }
+       if ( String.fromCodePoint ) {
+               c = String.fromCodePoint( e.charCode );
+       } else {
+               c = String.fromCharCode( e.charCode );
+       }
+
+       if ( this.keyPressBufferTimer ) {
+               clearTimeout( this.keyPressBufferTimer );
+       }
+       this.keyPressBufferTimer = setTimeout( this.clearKeyPressBuffer.bind( this ), 1500 );
+
+       item = this.getHighlightedItem() || this.getSelectedItem();
+
+       if ( this.keyPressBuffer === c ) {
+               // Common (if weird) special case: typing "xxxx" will cycle through all
+               // the items beginning with "x".
+               if ( item ) {
+                       item = this.getRelativeSelectableItem( item, 1 );
+               }
+       } else {
+               this.keyPressBuffer += c;
+       }
+
+       filter = this.getItemMatcher( this.keyPressBuffer, false );
+       if ( !item || !filter( item ) ) {
+               item = this.getRelativeSelectableItem( item, 1, filter );
+       }
+       if ( item ) {
+               if ( item.constructor.static.highlightable ) {
+                       this.highlightItem( item );
+               } else {
+                       this.chooseItem( item );
+               }
+               item.scrollElementIntoView();
+       }
+
+       return false;
+};
+
+/**
+ * Get a matcher for the specific string
+ *
+ * @protected
+ * @param {string} s String to match against items
+ * @param {boolean} [exact=false] Only accept exact matches
+ * @return {Function} function ( OO.ui.OptionItem ) => boolean
+ */
+OO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) {
+       var re;
+
+       if ( s.normalize ) {
+               s = s.normalize();
+       }
+       s = exact ? s.trim() : s.replace( /^\s+/, '' );
+       re = '^\\s*' + s.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' ).replace( /\s+/g, '\\s+' );
+       if ( exact ) {
+               re += '\\s*$';
+       }
+       re = new RegExp( re, 'i' );
+       return function ( item ) {
+               var l = item.getLabel();
+               if ( typeof l !== 'string' ) {
+                       l = item.$label.text();
+               }
+               if ( l.normalize ) {
+                       l = l.normalize();
+               }
+               return re.test( l );
+       };
+};
+
+/**
+ * Bind key press listener.
+ *
+ * @protected
+ */
+OO.ui.SelectWidget.prototype.bindKeyPressListener = function () {
+       this.getElementWindow().addEventListener( 'keypress', this.onKeyPressHandler, true );
+};
+
+/**
+ * Unbind key down listener.
+ *
+ * If you override this, be sure to call this.clearKeyPressBuffer() from your
+ * implementation.
+ *
+ * @protected
+ */
+OO.ui.SelectWidget.prototype.unbindKeyPressListener = function () {
+       this.getElementWindow().removeEventListener( 'keypress', this.onKeyPressHandler, true );
+       this.clearKeyPressBuffer();
+};
+
+/**
+ * Visibility change handler
+ *
+ * @protected
+ * @param {boolean} visible
+ */
+OO.ui.SelectWidget.prototype.onToggle = function ( visible ) {
+       if ( !visible ) {
+               this.clearKeyPressBuffer();
+       }
+};
+
+/**
+ * Get the closest item to a jQuery.Event.
+ *
+ * @private
+ * @param {jQuery.Event} e
+ * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found
+ */
+OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) {
+       return $( e.target ).closest( '.oo-ui-optionWidget' ).data( 'oo-ui-optionWidget' ) || null;
+};
+
+/**
+ * Get selected item.
+ *
+ * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected
+ */
+OO.ui.SelectWidget.prototype.getSelectedItem = function () {
+       var i, len;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               if ( this.items[ i ].isSelected() ) {
+                       return this.items[ i ];
+               }
+       }
+       return null;
+};
+
+/**
+ * Get highlighted item.
+ *
+ * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted
+ */
+OO.ui.SelectWidget.prototype.getHighlightedItem = function () {
+       var i, len;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               if ( this.items[ i ].isHighlighted() ) {
+                       return this.items[ i ];
+               }
+       }
+       return null;
+};
+
+/**
+ * Toggle pressed state.
+ *
+ * Press is a state that occurs when a user mouses down on an item, but
+ * has not yet let go of the mouse. The item may appear selected, but it will not be selected
+ * until the user releases the mouse.
+ *
+ * @param {boolean} pressed An option is being pressed
+ */
+OO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {
+       if ( pressed === undefined ) {
+               pressed = !this.pressed;
+       }
+       if ( pressed !== this.pressed ) {
+               this.$element
+                       .toggleClass( 'oo-ui-selectWidget-pressed', pressed )
+                       .toggleClass( 'oo-ui-selectWidget-depressed', !pressed );
+               this.pressed = pressed;
+       }
+};
+
+/**
+ * Highlight an option. If the `item` param is omitted, no options will be highlighted
+ * and any existing highlight will be removed. The highlight is mutually exclusive.
+ *
+ * @param {OO.ui.OptionWidget} [item] Item to highlight, omit for no highlight
+ * @fires highlight
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.highlightItem = function ( item ) {
+       var i, len, highlighted,
+               changed = false;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               highlighted = this.items[ i ] === item;
+               if ( this.items[ i ].isHighlighted() !== highlighted ) {
+                       this.items[ i ].setHighlighted( highlighted );
+                       changed = true;
+               }
+       }
+       if ( changed ) {
+               this.emit( 'highlight', item );
+       }
+
+       return this;
+};
+
+/**
+ * Fetch an item by its label.
+ *
+ * @param {string} label Label of the item to select.
+ * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches
+ * @return {OO.ui.Element|null} Item with equivalent label, `null` if none exists
+ */
+OO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {
+       var i, item, found,
+               len = this.items.length,
+               filter = this.getItemMatcher( label, true );
+
+       for ( i = 0; i < len; i++ ) {
+               item = this.items[ i ];
+               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
+                       return item;
+               }
+       }
+
+       if ( prefix ) {
+               found = null;
+               filter = this.getItemMatcher( label, false );
+               for ( i = 0; i < len; i++ ) {
+                       item = this.items[ i ];
+                       if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
+                               if ( found ) {
+                                       return null;
+                               }
+                               found = item;
+                       }
+               }
+               if ( found ) {
+                       return found;
+               }
+       }
+
+       return null;
+};
+
+/**
+ * Programmatically select an option by its label. If the item does not exist,
+ * all options will be deselected.
+ *
+ * @param {string} [label] Label of the item to select.
+ * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches
+ * @fires select
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.selectItemByLabel = function ( label, prefix ) {
+       var itemFromLabel = this.getItemFromLabel( label, !!prefix );
+       if ( label === undefined || !itemFromLabel ) {
+               return this.selectItem();
+       }
+       return this.selectItem( itemFromLabel );
+};
+
+/**
+ * Programmatically select an option by its data. If the `data` parameter is omitted,
+ * or if the item does not exist, all options will be deselected.
+ *
+ * @param {Object|string} [data] Value of the item to select, omit to deselect all
+ * @fires select
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.selectItemByData = function ( data ) {
+       var itemFromData = this.getItemFromData( data );
+       if ( data === undefined || !itemFromData ) {
+               return this.selectItem();
+       }
+       return this.selectItem( itemFromData );
+};
+
+/**
+ * Programmatically select an option by its reference. If the `item` parameter is omitted,
+ * all options will be deselected.
+ *
+ * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all
+ * @fires select
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.selectItem = function ( item ) {
+       var i, len, selected,
+               changed = false;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               selected = this.items[ i ] === item;
+               if ( this.items[ i ].isSelected() !== selected ) {
+                       this.items[ i ].setSelected( selected );
+                       changed = true;
+               }
+       }
+       if ( changed ) {
+               this.emit( 'select', item );
+       }
+
+       return this;
+};
+
+/**
+ * Press an item.
+ *
+ * Press is a state that occurs when a user mouses down on an item, but has not
+ * yet let go of the mouse. The item may appear selected, but it will not be selected until the user
+ * releases the mouse.
+ *
+ * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all
+ * @fires press
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.pressItem = function ( item ) {
+       var i, len, pressed,
+               changed = false;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               pressed = this.items[ i ] === item;
+               if ( this.items[ i ].isPressed() !== pressed ) {
+                       this.items[ i ].setPressed( pressed );
+                       changed = true;
+               }
+       }
+       if ( changed ) {
+               this.emit( 'press', item );
+       }
+
+       return this;
+};
+
+/**
+ * Choose an item.
+ *
+ * Note that ‘choose’ should never be modified programmatically. A user can choose
+ * an option with the keyboard or mouse and it becomes selected. To select an item programmatically,
+ * use the #selectItem method.
+ *
+ * This method is identical to #selectItem, but may vary in subclasses that take additional action
+ * when users choose an item with the keyboard or mouse.
+ *
+ * @param {OO.ui.OptionWidget} item Item to choose
+ * @fires choose
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.chooseItem = function ( item ) {
+       if ( item ) {
+               this.selectItem( item );
+               this.emit( 'choose', item );
+       }
+
+       return this;
+};
+
+/**
+ * Get an option by its position relative to the specified item (or to the start of the option array,
+ * if item is `null`). The direction in which to search through the option array is specified with a
+ * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or
+ * `null` if there are no options in the array.
+ *
+ * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.
+ * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward
+ * @param {Function} filter Only consider items for which this function returns
+ *  true. Function takes an OO.ui.OptionWidget and returns a boolean.
+ * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select
+ */
+OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direction, filter ) {
+       var currentIndex, nextIndex, i,
+               increase = direction > 0 ? 1 : -1,
+               len = this.items.length;
+
+       if ( !$.isFunction( filter ) ) {
+               filter = OO.ui.SelectWidget.static.passAllFilter;
+       }
+
+       if ( item instanceof OO.ui.OptionWidget ) {
+               currentIndex = this.items.indexOf( item );
+               nextIndex = ( currentIndex + increase + len ) % len;
+       } else {
+               // If no item is selected and moving forward, start at the beginning.
+               // If moving backward, start at the end.
+               nextIndex = direction > 0 ? 0 : len - 1;
+       }
+
+       for ( i = 0; i < len; i++ ) {
+               item = this.items[ nextIndex ];
+               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
+                       return item;
+               }
+               nextIndex = ( nextIndex + increase + len ) % len;
+       }
+       return null;
+};
+
+/**
+ * Get the next selectable item or `null` if there are no selectable items.
+ * Disabled options and menu-section markers and breaks are not selectable.
+ *
+ * @return {OO.ui.OptionWidget|null} Item, `null` if there aren't any selectable items
+ */
+OO.ui.SelectWidget.prototype.getFirstSelectableItem = function () {
+       var i, len, item;
+
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               item = this.items[ i ];
+               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() ) {
+                       return item;
+               }
+       }
+
+       return null;
+};
+
+/**
+ * Add an array of options to the select. Optionally, an index number can be used to
+ * specify an insertion point.
+ *
+ * @param {OO.ui.OptionWidget[]} items Items to add
+ * @param {number} [index] Index to insert items after
+ * @fires add
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.addItems = function ( items, index ) {
+       // Mixin method
+       OO.ui.mixin.GroupWidget.prototype.addItems.call( this, items, index );
+
+       // Always provide an index, even if it was omitted
+       this.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index );
+
+       return this;
+};
+
+/**
+ * Remove the specified array of options from the select. Options will be detached
+ * from the DOM, not removed, so they can be reused later. To remove all options from
+ * the select, you may wish to use the #clearItems method instead.
+ *
+ * @param {OO.ui.OptionWidget[]} items Items to remove
+ * @fires remove
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.removeItems = function ( items ) {
+       var i, len, item;
+
+       // Deselect items being removed
+       for ( i = 0, len = items.length; i < len; i++ ) {
+               item = items[ i ];
+               if ( item.isSelected() ) {
+                       this.selectItem( null );
+               }
+       }
+
+       // Mixin method
+       OO.ui.mixin.GroupWidget.prototype.removeItems.call( this, items );
+
+       this.emit( 'remove', items );
+
+       return this;
+};
+
+/**
+ * Clear all options from the select. Options will be detached from the DOM, not removed,
+ * so that they can be reused later. To remove a subset of options from the select, use
+ * the #removeItems method.
+ *
+ * @fires remove
+ * @chainable
+ */
+OO.ui.SelectWidget.prototype.clearItems = function () {
+       var items = this.items.slice();
+
+       // Mixin method
+       OO.ui.mixin.GroupWidget.prototype.clearItems.call( this );
+
+       // Clear selection
+       this.selectItem( null );
+
+       this.emit( 'remove', items );
+
+       return this;
+};
+
+/**
+ * DecoratedOptionWidgets are {@link OO.ui.OptionWidget options} that can be configured
+ * with an {@link OO.ui.mixin.IconElement icon} and/or {@link OO.ui.mixin.IndicatorElement indicator}.
+ * This class is used with OO.ui.SelectWidget to create a selection of mutually exclusive
+ * options. For more information about options and selects, please see the
+ * [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Decorated options in a select widget
+ *     var select = new OO.ui.SelectWidget( {
+ *         items: [
+ *             new OO.ui.DecoratedOptionWidget( {
+ *                 data: 'a',
+ *                 label: 'Option with icon',
+ *                 icon: 'help'
+ *             } ),
+ *             new OO.ui.DecoratedOptionWidget( {
+ *                 data: 'b',
+ *                 label: 'Option with indicator',
+ *                 indicator: 'next'
+ *             } )
+ *         ]
+ *     } );
+ *     $( 'body' ).append( select.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ *
+ * @class
+ * @extends OO.ui.OptionWidget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.DecoratedOptionWidget = function OoUiDecoratedOptionWidget( config ) {
+       // Parent constructor
+       OO.ui.DecoratedOptionWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-decoratedOptionWidget' )
+               .prepend( this.$icon )
+               .append( this.$indicator );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.DecoratedOptionWidget, OO.ui.OptionWidget );
+OO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IndicatorElement );
+
+/**
+ * MenuOptionWidget is an option widget that looks like a menu item. The class is used with
+ * OO.ui.MenuSelectWidget to create a menu of mutually exclusive options. Please see
+ * the [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.DecoratedOptionWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.MenuOptionWidget = function OoUiMenuOptionWidget( config ) {
+       // Configuration initialization
+       config = $.extend( { icon: 'check' }, config );
+
+       // Parent constructor
+       OO.ui.MenuOptionWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element
+               .attr( 'role', 'menuitem' )
+               .addClass( 'oo-ui-menuOptionWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );
+
+/* Static Properties */
+
+OO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;
+
+/**
+ * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to group one or more related
+ * {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets cannot be highlighted or selected.
+ *
+ *     @example
+ *     var myDropdown = new OO.ui.DropdownWidget( {
+ *         menu: {
+ *             items: [
+ *                 new OO.ui.MenuSectionOptionWidget( {
+ *                     label: 'Dogs'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'corgi',
+ *                     label: 'Welsh Corgi'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'poodle',
+ *                     label: 'Standard Poodle'
+ *                 } ),
+ *                 new OO.ui.MenuSectionOptionWidget( {
+ *                     label: 'Cats'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'lion',
+ *                     label: 'Lion'
+ *                 } )
+ *             ]
+ *         }
+ *     } );
+ *     $( 'body' ).append( myDropdown.$element );
+ *
+ * @class
+ * @extends OO.ui.DecoratedOptionWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.MenuSectionOptionWidget = function OoUiMenuSectionOptionWidget( config ) {
+       // Parent constructor
+       OO.ui.MenuSectionOptionWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-menuSectionOptionWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MenuSectionOptionWidget, OO.ui.DecoratedOptionWidget );
+
+/* Static Properties */
+
+OO.ui.MenuSectionOptionWidget.static.selectable = false;
+
+OO.ui.MenuSectionOptionWidget.static.highlightable = false;
+
+/**
+ * MenuSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains options and
+ * is used together with OO.ui.MenuOptionWidget. It is designed be used as part of another widget.
+ * See {@link OO.ui.DropdownWidget DropdownWidget}, {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget},
+ * and {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.
+ * MenuSelectWidgets themselves are not instantiated directly, rather subclassed
+ * and customized to be opened, closed, and displayed as needed.
+ *
+ * By default, menus are clipped to the visible viewport and are not visible when a user presses the
+ * mouse outside the menu.
+ *
+ * Menus also have support for keyboard interaction:
+ *
+ * - Enter/Return key: choose and select a menu option
+ * - Up-arrow key: highlight the previous menu option
+ * - Down-arrow key: highlight the next menu option
+ * - Esc key: hide the menu
+ *
+ * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ *
+ * @class
+ * @extends OO.ui.SelectWidget
+ * @mixins OO.ui.mixin.ClippableElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu items that match
+ *  the text the user types. This config is used by {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}
+ *  and {@link OO.ui.mixin.LookupElement LookupElement}
+ * @cfg {jQuery} [$input] Text input used to implement option highlighting for menu items that match
+ *  the text the user types. This config is used by {@link OO.ui.CapsuleMultiSelectWidget CapsuleMultiSelectWidget}
+ * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks the mouse
+ *  anywhere on the page outside of this widget, the menu is hidden. For example, if there is a button
+ *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks
+ *  that button, unless the button (or its parent widget) is passed in here.
+ * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.
+ * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input
+ */
+OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.MenuSelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
+
+       // Properties
+       this.newItems = null;
+       this.autoHide = config.autoHide === undefined || !!config.autoHide;
+       this.filterFromInput = !!config.filterFromInput;
+       this.$input = config.$input ? config.$input : config.input ? config.input.$input : null;
+       this.$widget = config.widget ? config.widget.$element : null;
+       this.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );
+       this.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-menuSelectWidget' )
+               .attr( 'role', 'menu' );
+
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MenuSelectWidget, OO.ui.SelectWidget );
+OO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.ClippableElement );
+
+/* Methods */
+
+/**
+ * Handles document mouse down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.MenuSelectWidget.prototype.onDocumentMouseDown = function ( e ) {
+       if (
+               !OO.ui.contains( this.$element[ 0 ], e.target, true ) &&
+               ( !this.$widget || !OO.ui.contains( this.$widget[ 0 ], e.target, true ) )
+       ) {
+               this.toggle( false );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) {
+       var currentItem = this.getHighlightedItem() || this.getSelectedItem();
+
+       if ( !this.isDisabled() && this.isVisible() ) {
+               switch ( e.keyCode ) {
+                       case OO.ui.Keys.LEFT:
+                       case OO.ui.Keys.RIGHT:
+                               // Do nothing if a text field is associated, arrow keys will be handled natively
+                               if ( !this.$input ) {
+                                       OO.ui.MenuSelectWidget.parent.prototype.onKeyDown.call( this, e );
+                               }
+                               break;
+                       case OO.ui.Keys.ESCAPE:
+                       case OO.ui.Keys.TAB:
+                               if ( currentItem ) {
+                                       currentItem.setHighlighted( false );
+                               }
+                               this.toggle( false );
+                               // Don't prevent tabbing away, prevent defocusing
+                               if ( e.keyCode === OO.ui.Keys.ESCAPE ) {
+                                       e.preventDefault();
+                                       e.stopPropagation();
+                               }
+                               break;
+                       default:
+                               OO.ui.MenuSelectWidget.parent.prototype.onKeyDown.call( this, e );
+                               return;
+               }
+       }
+};
+
+/**
+ * Update menu item visibility after input changes.
+ * @protected
+ */
+OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
+       var i, item,
+               len = this.items.length,
+               showAll = !this.isVisible(),
+               filter = showAll ? null : this.getItemMatcher( this.$input.val() );
+
+       for ( i = 0; i < len; i++ ) {
+               item = this.items[ i ];
+               if ( item instanceof OO.ui.OptionWidget ) {
+                       item.toggle( showAll || filter( item ) );
+               }
+       }
+
+       // Reevaluate clipping
+       this.clip();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.bindKeyDownListener = function () {
+       if ( this.$input ) {
+               this.$input.on( 'keydown', this.onKeyDownHandler );
+       } else {
+               OO.ui.MenuSelectWidget.parent.prototype.bindKeyDownListener.call( this );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.unbindKeyDownListener = function () {
+       if ( this.$input ) {
+               this.$input.off( 'keydown', this.onKeyDownHandler );
+       } else {
+               OO.ui.MenuSelectWidget.parent.prototype.unbindKeyDownListener.call( this );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.bindKeyPressListener = function () {
+       if ( this.$input ) {
+               if ( this.filterFromInput ) {
+                       this.$input.on( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
+               }
+       } else {
+               OO.ui.MenuSelectWidget.parent.prototype.bindKeyPressListener.call( this );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = function () {
+       if ( this.$input ) {
+               if ( this.filterFromInput ) {
+                       this.$input.off( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
+                       this.updateItemVisibility();
+               }
+       } else {
+               OO.ui.MenuSelectWidget.parent.prototype.unbindKeyPressListener.call( this );
+       }
+};
+
+/**
+ * Choose an item.
+ *
+ * When a user chooses an item, the menu is closed.
+ *
+ * Note that ‘choose’ should never be modified programmatically. A user can choose an option with the keyboard
+ * or mouse and it becomes selected. To select an item programmatically, use the #selectItem method.
+ * @param {OO.ui.OptionWidget} item Item to choose
+ * @chainable
+ */
+OO.ui.MenuSelectWidget.prototype.chooseItem = function ( item ) {
+       OO.ui.MenuSelectWidget.parent.prototype.chooseItem.call( this, item );
+       this.toggle( false );
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.addItems = function ( items, index ) {
+       var i, len, item;
+
+       // Parent method
+       OO.ui.MenuSelectWidget.parent.prototype.addItems.call( this, items, index );
+
+       // Auto-initialize
+       if ( !this.newItems ) {
+               this.newItems = [];
+       }
+
+       for ( i = 0, len = items.length; i < len; i++ ) {
+               item = items[ i ];
+               if ( this.isVisible() ) {
+                       // Defer fitting label until item has been attached
+                       item.fitLabel();
+               } else {
+                       this.newItems.push( item );
+               }
+       }
+
+       // Reevaluate clipping
+       this.clip();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.removeItems = function ( items ) {
+       // Parent method
+       OO.ui.MenuSelectWidget.parent.prototype.removeItems.call( this, items );
+
+       // Reevaluate clipping
+       this.clip();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.clearItems = function () {
+       // Parent method
+       OO.ui.MenuSelectWidget.parent.prototype.clearItems.call( this );
+
+       // Reevaluate clipping
+       this.clip();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
+       var i, len, change;
+
+       visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
+       change = visible !== this.isVisible();
+
+       // Parent method
+       OO.ui.MenuSelectWidget.parent.prototype.toggle.call( this, visible );
+
+       if ( change ) {
+               if ( visible ) {
+                       this.bindKeyDownListener();
+                       this.bindKeyPressListener();
+
+                       if ( this.newItems && this.newItems.length ) {
+                               for ( i = 0, len = this.newItems.length; i < len; i++ ) {
+                                       this.newItems[ i ].fitLabel();
+                               }
+                               this.newItems = null;
+                       }
+                       this.toggleClipping( true );
+
+                       // Auto-hide
+                       if ( this.autoHide ) {
+                               this.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );
+                       }
+               } else {
+                       this.unbindKeyDownListener();
+                       this.unbindKeyPressListener();
+                       this.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );
+                       this.toggleClipping( false );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * DropdownWidgets are not menus themselves, rather they contain a menu of options created with
+ * OO.ui.MenuOptionWidget. The DropdownWidget takes care of opening and displaying the menu so that
+ * users can interact with it.
+ *
+ * If you want to use this within a HTML form, such as a OO.ui.FormLayout, use
+ * OO.ui.DropdownInputWidget instead.
+ *
+ *     @example
+ *     // Example: A DropdownWidget with a menu that contains three options
+ *     var dropDown = new OO.ui.DropdownWidget( {
+ *         label: 'Dropdown menu: Select a menu option',
+ *         menu: {
+ *             items: [
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'a',
+ *                     label: 'First'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'b',
+ *                     label: 'Second'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'c',
+ *                     label: 'Third'
+ *                 } )
+ *             ]
+ *         }
+ *     } );
+ *
+ *     $( 'body' ).append( dropDown.$element );
+ *
+ *     dropDown.getMenu().selectItemByData( 'b' );
+ *
+ *     dropDown.getMenu().getSelectedItem().getData(); // returns 'b'
+ *
+ * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.FloatingMenuSelectWidget menu select widget}
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
+ *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
+ *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
+ */
+OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
+       // Configuration initialization
+       config = $.extend( { indicator: 'down' }, config );
+
+       // Parent constructor
+       OO.ui.DropdownWidget.parent.call( this, config );
+
+       // Properties (must be set before TabIndexedElement constructor call)
+       this.$handle = this.$( '<span>' );
+       this.$overlay = config.$overlay || this.$element;
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
+
+       // Properties
+       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend( {
+               widget: this,
+               $container: this.$element
+       }, config.menu ) );
+
+       // Events
+       this.$handle.on( {
+               click: this.onClick.bind( this ),
+               keypress: this.onKeyPress.bind( this )
+       } );
+       this.menu.connect( this, { select: 'onMenuSelect' } );
+
+       // Initialization
+       this.$handle
+               .addClass( 'oo-ui-dropdownWidget-handle' )
+               .append( this.$icon, this.$label, this.$indicator );
+       this.$element
+               .addClass( 'oo-ui-dropdownWidget' )
+               .append( this.$handle );
+       this.$overlay.append( this.menu.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.DropdownWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * Get the menu.
+ *
+ * @return {OO.ui.MenuSelectWidget} Menu of widget
+ */
+OO.ui.DropdownWidget.prototype.getMenu = function () {
+       return this.menu;
+};
+
+/**
+ * Handles menu select events.
+ *
+ * @private
+ * @param {OO.ui.MenuOptionWidget} item Selected menu item
+ */
+OO.ui.DropdownWidget.prototype.onMenuSelect = function ( item ) {
+       var selectedLabel;
+
+       if ( !item ) {
+               this.setLabel( null );
+               return;
+       }
+
+       selectedLabel = item.getLabel();
+
+       // If the label is a DOM element, clone it, because setLabel will append() it
+       if ( selectedLabel instanceof jQuery ) {
+               selectedLabel = selectedLabel.clone();
+       }
+
+       this.setLabel( selectedLabel );
+};
+
+/**
+ * Handle mouse click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.DropdownWidget.prototype.onClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.menu.toggle();
+       }
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.DropdownWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() &&
+               ( ( e.which === OO.ui.Keys.SPACE && !this.menu.isVisible() ) || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.menu.toggle();
+               return false;
+       }
+};
+
+/**
+ * RadioOptionWidget is an option widget that looks like a radio button.
+ * The class is used with OO.ui.RadioSelectWidget to create a selection of radio options.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Button_selects_and_option
+ *
+ * @class
+ * @extends OO.ui.OptionWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.RadioOptionWidget = function OoUiRadioOptionWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties (must be done before parent constructor which calls #setDisabled)
+       this.radio = new OO.ui.RadioInputWidget( { value: config.data, tabIndex: -1 } );
+
+       // Parent constructor
+       OO.ui.RadioOptionWidget.parent.call( this, config );
+
+       // Events
+       this.radio.$input.on( 'focus', this.onInputFocus.bind( this ) );
+
+       // Initialization
+       // Remove implicit role, we're handling it ourselves
+       this.radio.$input.attr( 'role', 'presentation' );
+       this.$element
+               .addClass( 'oo-ui-radioOptionWidget' )
+               .attr( 'role', 'radio' )
+               .attr( 'aria-checked', 'false' )
+               .removeAttr( 'aria-selected' )
+               .prepend( this.radio.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.RadioOptionWidget, OO.ui.OptionWidget );
+
+/* Static Properties */
+
+OO.ui.RadioOptionWidget.static.highlightable = false;
+
+OO.ui.RadioOptionWidget.static.scrollIntoViewOnSelect = true;
+
+OO.ui.RadioOptionWidget.static.pressable = false;
+
+OO.ui.RadioOptionWidget.static.tagName = 'label';
+
+/* Methods */
+
+/**
+ * @param {jQuery.Event} e Focus event
+ * @private
+ */
+OO.ui.RadioOptionWidget.prototype.onInputFocus = function () {
+       this.radio.$input.blur();
+       this.$element.parent().focus();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioOptionWidget.prototype.setSelected = function ( state ) {
+       OO.ui.RadioOptionWidget.parent.prototype.setSelected.call( this, state );
+
+       this.radio.setSelected( state );
+       this.$element
+               .attr( 'aria-checked', state.toString() )
+               .removeAttr( 'aria-selected' );
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioOptionWidget.prototype.setDisabled = function ( disabled ) {
+       OO.ui.RadioOptionWidget.parent.prototype.setDisabled.call( this, disabled );
+
+       this.radio.setDisabled( this.isDisabled() );
+
+       return this;
+};
+
+/**
+ * RadioSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains radio
+ * options and is used together with OO.ui.RadioOptionWidget. The RadioSelectWidget provides
+ * an interface for adding, removing and selecting options.
+ * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
+ *
+ * If you want to use this within a HTML form, such as a OO.ui.FormLayout, use
+ * OO.ui.RadioSelectInputWidget instead.
+ *
+ *     @example
+ *     // A RadioSelectWidget with RadioOptions.
+ *     var option1 = new OO.ui.RadioOptionWidget( {
+ *         data: 'a',
+ *         label: 'Selected radio option'
+ *     } );
+ *
+ *     var option2 = new OO.ui.RadioOptionWidget( {
+ *         data: 'b',
+ *         label: 'Unselected radio option'
+ *     } );
+ *
+ *     var radioSelect=new OO.ui.RadioSelectWidget( {
+ *         items: [ option1, option2 ]
+ *      } );
+ *
+ *     // Select 'option 1' using the RadioSelectWidget's selectItem() method.
+ *     radioSelect.selectItem( option1 );
+ *
+ *     $( 'body' ).append( radioSelect.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+
+ *
+ * @class
+ * @extends OO.ui.SelectWidget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.RadioSelectWidget = function OoUiRadioSelectWidget( config ) {
+       // Parent constructor
+       OO.ui.RadioSelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+
+       // Events
+       this.$element.on( {
+               focus: this.bindKeyDownListener.bind( this ),
+               blur: this.unbindKeyDownListener.bind( this )
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-radioSelectWidget' )
+               .attr( 'role', 'radiogroup' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.RadioSelectWidget, OO.ui.SelectWidget );
+OO.mixinClass( OO.ui.RadioSelectWidget, OO.ui.mixin.TabIndexedElement );
+
+/**
+ * Element that will stick under a specified container, even when it is inserted elsewhere in the
+ * document (for example, in a OO.ui.Window's $overlay).
+ *
+ * The elements's position is automatically calculated and maintained when window is resized or the
+ * page is scrolled. If you reposition the container manually, you have to call #position to make
+ * sure the element is still placed correctly.
+ *
+ * As positioning is only possible when both the element and the container are attached to the DOM
+ * and visible, it's only done after you call #togglePositioning. You might want to do this inside
+ * the #toggle method to display a floating popup, for example.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element
+ * @cfg {jQuery} [$floatableContainer] Node to position below
+ */
+OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.$floatable = null;
+       this.$floatableContainer = null;
+       this.$floatableWindow = null;
+       this.$floatableClosestScrollable = null;
+       this.onFloatableScrollHandler = this.position.bind( this );
+       this.onFloatableWindowResizeHandler = this.position.bind( this );
+
+       // Initialization
+       this.setFloatableContainer( config.$floatableContainer );
+       this.setFloatableElement( config.$floatable || this.$element );
+};
+
+/* Methods */
+
+/**
+ * Set floatable element.
+ *
+ * If an element is already set, it will be cleaned up before setting up the new element.
+ *
+ * @param {jQuery} $floatable Element to make floatable
+ */
+OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) {
+       if ( this.$floatable ) {
+               this.$floatable.removeClass( 'oo-ui-floatableElement-floatable' );
+               this.$floatable.css( { left: '', top: '' } );
+       }
+
+       this.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' );
+       this.position();
+};
+
+/**
+ * Set floatable container.
+ *
+ * The element will be always positioned under the specified container.
+ *
+ * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset
+ */
+OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) {
+       this.$floatableContainer = $floatableContainer;
+       if ( this.$floatable ) {
+               this.position();
+       }
+};
+
+/**
+ * Toggle positioning.
+ *
+ * Do not turn positioning on until after the element is attached to the DOM and visible.
+ *
+ * @param {boolean} [positioning] Enable positioning, omit to toggle
+ * @chainable
+ */
+OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) {
+       var closestScrollableOfContainer, closestScrollableOfFloatable;
+
+       positioning = positioning === undefined ? !this.positioning : !!positioning;
+
+       if ( this.positioning !== positioning ) {
+               this.positioning = positioning;
+
+               closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] );
+               closestScrollableOfFloatable = OO.ui.Element.static.getClosestScrollableContainer( this.$floatable[ 0 ] );
+               if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) {
+                       // If the scrollable is the root, we have to listen to scroll events
+                       // on the window because of browser inconsistencies (or do we? someone should verify this)
+                       if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) {
+                               closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer );
+                       }
+               }
+
+               if ( positioning ) {
+                       this.$floatableWindow = $( this.getElementWindow() );
+                       this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler );
+
+                       if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) {
+                               this.$floatableClosestScrollable = $( closestScrollableOfContainer );
+                               this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler );
+                       }
+
+                       // Initial position after visible
+                       this.position();
+               } else {
+                       if ( this.$floatableWindow ) {
+                               this.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler );
+                               this.$floatableWindow = null;
+                       }
+
+                       if ( this.$floatableClosestScrollable ) {
+                               this.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler );
+                               this.$floatableClosestScrollable = null;
+                       }
+
+                       this.$floatable.css( { left: '', top: '' } );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Position the floatable below its container.
+ *
+ * This should only be done when both of them are attached to the DOM and visible.
+ *
+ * @chainable
+ */
+OO.ui.mixin.FloatableElement.prototype.position = function () {
+       var pos;
+
+       if ( !this.positioning ) {
+               return this;
+       }
+
+       pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() );
+
+       // Position under container
+       pos.top += this.$floatableContainer.height();
+       this.$floatable.css( pos );
+
+       // We updated the position, so re-evaluate the clipping state.
+       // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so
+       // will not notice the need to update itself.)
+       // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does
+       // it not listen to the right events in the right places?
+       if ( this.clip ) {
+               this.clip();
+       }
+
+       return this;
+};
+
+/**
+ * FloatingMenuSelectWidget is a menu that will stick under a specified
+ * container, even when it is inserted elsewhere in the document (for example,
+ * in a OO.ui.Window's $overlay). This is sometimes necessary to prevent the
+ * menu from being clipped too aggresively.
+ *
+ * The menu's position is automatically calculated and maintained when the menu
+ * is toggled or the window is resized.
+ *
+ * See OO.ui.ComboBoxInputWidget for an example of a widget that uses this class.
+ *
+ * @class
+ * @extends OO.ui.MenuSelectWidget
+ * @mixins OO.ui.mixin.FloatableElement
+ *
+ * @constructor
+ * @param {OO.ui.Widget} [inputWidget] Widget to provide the menu for.
+ *   Deprecated, omit this parameter and specify `$container` instead.
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$container=inputWidget.$element] Element to render menu under
+ */
+OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWidget, config ) {
+       // Allow 'inputWidget' parameter and config for backwards compatibility
+       if ( OO.isPlainObject( inputWidget ) && config === undefined ) {
+               config = inputWidget;
+               inputWidget = config.inputWidget;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.FloatingMenuSelectWidget.parent.call( this, config );
+
+       // Properties (must be set before mixin constructors)
+       this.inputWidget = inputWidget; // For backwards compatibility
+       this.$container = config.$container || this.inputWidget.$element;
+
+       // Mixins constructors
+       OO.ui.mixin.FloatableElement.call( this, $.extend( {}, config, { $floatableContainer: this.$container } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-floatingMenuSelectWidget' );
+       // For backwards compatibility
+       this.$element.addClass( 'oo-ui-textInputMenuSelectWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.FloatingMenuSelectWidget, OO.ui.MenuSelectWidget );
+OO.mixinClass( OO.ui.FloatingMenuSelectWidget, OO.ui.mixin.FloatableElement );
+
+// For backwards compatibility
+OO.ui.TextInputMenuSelectWidget = OO.ui.FloatingMenuSelectWidget;
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.FloatingMenuSelectWidget.prototype.toggle = function ( visible ) {
+       var change;
+       visible = visible === undefined ? !this.isVisible() : !!visible;
+       change = visible !== this.isVisible();
+
+       if ( change && visible ) {
+               // Make sure the width is set before the parent method runs.
+               this.setIdealSize( this.$container.width() );
+       }
+
+       // Parent method
+       // This will call this.clip(), which is nonsensical since we're not positioned yet...
+       OO.ui.FloatingMenuSelectWidget.parent.prototype.toggle.call( this, visible );
+
+       if ( change ) {
+               this.togglePositioning( this.isVisible() );
+       }
+
+       return this;
+};
+
+/**
+ * InputWidget is the base class for all input widgets, which
+ * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox inputs},
+ * {@link OO.ui.RadioInputWidget radio inputs}, and {@link OO.ui.ButtonInputWidget button inputs}.
+ * See the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.AccessKeyedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.
+ * @cfg {string} [value=''] The value of the input.
+ * @cfg {string} [dir] The directionality of the input (ltr/rtl).
+ * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the value of an input
+ *  before it is accepted.
+ */
+OO.ui.InputWidget = function OoUiInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.InputWidget.parent.call( this, config );
+
+       // Properties
+       this.$input = this.getInputElement( config );
+       this.value = '';
+       this.inputFilter = config.inputFilter;
+
+       // Mixin constructors
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
+       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$input } ) );
+
+       // Events
+       this.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );
+
+       // Initialization
+       this.$input
+               .addClass( 'oo-ui-inputWidget-input' )
+               .attr( 'name', config.name )
+               .prop( 'disabled', this.isDisabled() );
+       this.$element
+               .addClass( 'oo-ui-inputWidget' )
+               .append( this.$input );
+       this.setValue( config.value );
+       this.setAccessKey( config.accessKey );
+       if ( config.dir ) {
+               this.setDir( config.dir );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TabIndexedElement );
+OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.AccessKeyedElement );
+
+/* Static Properties */
+
+OO.ui.InputWidget.static.supportsSimpleLabel = true;
+
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.InputWidget.static.reusePreInfuseDOM = function ( node, config ) {
+       config = OO.ui.InputWidget.parent.static.reusePreInfuseDOM( node, config );
+       // Reusing $input lets browsers preserve inputted values across page reloads (T114134)
+       config.$input = $( node ).find( '.oo-ui-inputWidget-input' );
+       return config;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.InputWidget.static.gatherPreInfuseState = function ( node, config ) {
+       var state = OO.ui.InputWidget.parent.static.gatherPreInfuseState( node, config );
+       state.value = config.$input.val();
+       // Might be better in TabIndexedElement, but it's awkward to do there because mixins are awkward
+       state.focus = config.$input.is( ':focus' );
+       return state;
+};
+
+/* Events */
+
+/**
+ * @event change
+ *
+ * A change event is emitted when the value of the input changes.
+ *
+ * @param {string} value
+ */
+
+/* Methods */
+
+/**
+ * Get input element.
+ *
+ * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in
+ * different circumstances. The element must have a `value` property (like form elements).
+ *
+ * @protected
+ * @param {Object} config Configuration options
+ * @return {jQuery} Input element
+ */
+OO.ui.InputWidget.prototype.getInputElement = function ( config ) {
+       // See #reusePreInfuseDOM about config.$input
+       return config.$input || $( '<input>' );
+};
+
+/**
+ * Handle potentially value-changing events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event
+ */
+OO.ui.InputWidget.prototype.onEdit = function () {
+       var widget = this;
+       if ( !this.isDisabled() ) {
+               // Allow the stack to clear so the value will be updated
+               setTimeout( function () {
+                       widget.setValue( widget.$input.val() );
+               } );
+       }
+};
+
+/**
+ * Get the value of the input.
+ *
+ * @return {string} Input value
+ */
+OO.ui.InputWidget.prototype.getValue = function () {
+       // Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
+       // it, and we won't know unless they're kind enough to trigger a 'change' event.
+       var value = this.$input.val();
+       if ( this.value !== value ) {
+               this.setValue( value );
+       }
+       return this.value;
+};
+
+/**
+ * Set the directionality of the input, either RTL (right-to-left) or LTR (left-to-right).
+ *
+ * @deprecated since v0.13.1, use #setDir directly
+ * @param {boolean} isRTL Directionality is right-to-left
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
+       this.setDir( isRTL ? 'rtl' : 'ltr' );
+       return this;
+};
+
+/**
+ * Set the directionality of the input.
+ *
+ * @param {string} dir Text directionality: 'ltr', 'rtl' or 'auto'
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.setDir = function ( dir ) {
+       this.$input.prop( 'dir', dir );
+       return this;
+};
+
+/**
+ * Set the value of the input.
+ *
+ * @param {string} value New value
+ * @fires change
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.setValue = function ( value ) {
+       value = this.cleanUpValue( value );
+       // Update the DOM if it has changed. Note that with cleanUpValue, it
+       // is possible for the DOM value to change without this.value changing.
+       if ( this.$input.val() !== value ) {
+               this.$input.val( value );
+       }
+       if ( this.value !== value ) {
+               this.value = value;
+               this.emit( 'change', this.value );
+       }
+       return this;
+};
+
+/**
+ * Set the input's access key.
+ * FIXME: This is the same code as in OO.ui.mixin.ButtonElement, maybe find a better place for it?
+ *
+ * @param {string} accessKey Input's access key, use empty string to remove
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.setAccessKey = function ( accessKey ) {
+       accessKey = typeof accessKey === 'string' && accessKey.length ? accessKey : null;
+
+       if ( this.accessKey !== accessKey ) {
+               if ( this.$input ) {
+                       if ( accessKey !== null ) {
+                               this.$input.attr( 'accesskey', accessKey );
+                       } else {
+                               this.$input.removeAttr( 'accesskey' );
+                       }
+               }
+               this.accessKey = accessKey;
+       }
+
+       return this;
+};
+
+/**
+ * Clean up incoming value.
+ *
+ * Ensures value is a string, and converts undefined and null to empty string.
+ *
+ * @private
+ * @param {string} value Original value
+ * @return {string} Cleaned up value
+ */
+OO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {
+       if ( value === undefined || value === null ) {
+               return '';
+       } else if ( this.inputFilter ) {
+               return this.inputFilter( String( value ) );
+       } else {
+               return String( value );
+       }
+};
+
+/**
+ * Simulate the behavior of clicking on a label bound to this input. This method is only called by
+ * {@link OO.ui.LabelWidget LabelWidget} and {@link OO.ui.FieldLayout FieldLayout}. It should not be
+ * called directly.
+ */
+OO.ui.InputWidget.prototype.simulateLabelClick = function () {
+       if ( !this.isDisabled() ) {
+               if ( this.$input.is( ':checkbox, :radio' ) ) {
+                       this.$input.click();
+               }
+               if ( this.$input.is( ':input' ) ) {
+                       this.$input[ 0 ].focus();
+               }
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.InputWidget.prototype.setDisabled = function ( state ) {
+       OO.ui.InputWidget.parent.prototype.setDisabled.call( this, state );
+       if ( this.$input ) {
+               this.$input.prop( 'disabled', this.isDisabled() );
+       }
+       return this;
+};
+
+/**
+ * Focus the input.
+ *
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.focus = function () {
+       this.$input[ 0 ].focus();
+       return this;
+};
+
+/**
+ * Blur the input.
+ *
+ * @chainable
+ */
+OO.ui.InputWidget.prototype.blur = function () {
+       this.$input[ 0 ].blur();
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {
+       OO.ui.InputWidget.parent.prototype.restorePreInfuseState.call( this, state );
+       if ( state.value !== undefined && state.value !== this.getValue() ) {
+               this.setValue( state.value );
+       }
+       if ( state.focus ) {
+               this.focus();
+       }
+};
+
+/**
+ * ButtonInputWidget is used to submit HTML forms and is intended to be used within
+ * a OO.ui.FormLayout. If you do not need the button to work with HTML forms, you probably
+ * want to use OO.ui.ButtonWidget instead. Button input widgets can be rendered as either an
+ * HTML `<button/>` (the default) or an HTML `<input/>` tags. See the
+ * [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ *     @example
+ *     // A ButtonInputWidget rendered as an HTML button, the default.
+ *     var button = new OO.ui.ButtonInputWidget( {
+ *         label: 'Input button',
+ *         icon: 'check',
+ *         value: 'check'
+ *     } );
+ *     $( 'body' ).append( button.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs#Button_inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ * @mixins OO.ui.mixin.ButtonElement
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [type='button'] The value of the HTML `'type'` attribute: 'button', 'submit' or 'reset'.
+ * @cfg {boolean} [useInputTag=false] Use an `<input/>` tag instead of a `<button/>` tag, the default.
+ *  Widgets configured to be an `<input/>` do not support {@link #icon icons} and {@link #indicator indicators},
+ *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should only
+ *  be set to `true` when there’s need to support IE6 in a form with multiple buttons.
+ */
+OO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {
+       // Configuration initialization
+       config = $.extend( { type: 'button', useInputTag: false }, config );
+
+       // Properties (must be set before parent constructor, which calls #setValue)
+       this.useInputTag = config.useInputTag;
+
+       // Parent constructor
+       OO.ui.ButtonInputWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { $button: this.$input } ) );
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
+
+       // Initialization
+       if ( !config.useInputTag ) {
+               this.$input.append( this.$icon, this.$label, this.$indicator );
+       }
+       this.$element.addClass( 'oo-ui-buttonInputWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ButtonInputWidget, OO.ui.InputWidget );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.ButtonElement );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.TitledElement );
+
+/* Static Properties */
+
+/**
+ * Disable generating `<label>` elements for buttons. One would very rarely need additional label
+ * for a button, and it's already a big clickable target, and it causes unexpected rendering.
+ */
+OO.ui.ButtonInputWidget.static.supportsSimpleLabel = false;
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {
+       var type;
+       // See InputWidget#reusePreInfuseDOM about config.$input
+       if ( config.$input ) {
+               return config.$input.empty();
+       }
+       type = [ 'button', 'submit', 'reset' ].indexOf( config.type ) !== -1 ? config.type : 'button';
+       return $( '<' + ( config.useInputTag ? 'input' : 'button' ) + ' type="' + type + '">' );
+};
+
+/**
+ * Set label value.
+ *
+ * If #useInputTag is `true`, the label is set as the `value` of the `<input/>` tag.
+ *
+ * @param {jQuery|string|Function|null} label Label nodes, text, a function that returns nodes or
+ *  text, or `null` for no label
+ * @chainable
+ */
+OO.ui.ButtonInputWidget.prototype.setLabel = function ( label ) {
+       OO.ui.mixin.LabelElement.prototype.setLabel.call( this, label );
+
+       if ( this.useInputTag ) {
+               if ( typeof label === 'function' ) {
+                       label = OO.ui.resolveMsg( label );
+               }
+               if ( label instanceof jQuery ) {
+                       label = label.text();
+               }
+               if ( !label ) {
+                       label = '';
+               }
+               this.$input.val( label );
+       }
+
+       return this;
+};
+
+/**
+ * Set the value of the input.
+ *
+ * This method is disabled for button inputs configured as {@link #useInputTag <input/> tags}, as
+ * they do not support {@link #value values}.
+ *
+ * @param {string} value New value
+ * @chainable
+ */
+OO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {
+       if ( !this.useInputTag ) {
+               OO.ui.ButtonInputWidget.parent.prototype.setValue.call( this, value );
+       }
+       return this;
+};
+
+/**
+ * CheckboxInputWidgets, like HTML checkboxes, can be selected and/or configured with a value.
+ * Note that these {@link OO.ui.InputWidget input widgets} are best laid out
+ * in {@link OO.ui.FieldLayout field layouts} that use the {@link OO.ui.FieldLayout#align inline}
+ * alignment. For more information, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
+ *
+ *     @example
+ *     // An example of selected, unselected, and disabled checkbox inputs
+ *     var checkbox1=new OO.ui.CheckboxInputWidget( {
+ *          value: 'a',
+ *          selected: true
+ *     } );
+ *     var checkbox2=new OO.ui.CheckboxInputWidget( {
+ *         value: 'b'
+ *     } );
+ *     var checkbox3=new OO.ui.CheckboxInputWidget( {
+ *         value:'c',
+ *         disabled: true
+ *     } );
+ *     // Create a fieldset layout with fields for each checkbox.
+ *     var fieldset = new OO.ui.FieldsetLayout( {
+ *         label: 'Checkboxes'
+ *     } );
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( checkbox1, { label: 'Selected checkbox', align: 'inline' } ),
+ *         new OO.ui.FieldLayout( checkbox2, { label: 'Unselected checkbox', align: 'inline' } ),
+ *         new OO.ui.FieldLayout( checkbox3, { label: 'Disabled checkbox', align: 'inline' } ),
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is not selected.
+ */
+OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.CheckboxInputWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-checkboxInputWidget' )
+               // Required for pretty styling in MediaWiki theme
+               .append( $( '<span>' ) );
+       this.setSelected( config.selected !== undefined ? config.selected : false );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
+
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CheckboxInputWidget.static.gatherPreInfuseState = function ( node, config ) {
+       var state = OO.ui.CheckboxInputWidget.parent.static.gatherPreInfuseState( node, config );
+       state.checked = config.$input.prop( 'checked' );
+       return state;
+};
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
+       return $( '<input type="checkbox" />' );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
+       var widget = this;
+       if ( !this.isDisabled() ) {
+               // Allow the stack to clear so the value will be updated
+               setTimeout( function () {
+                       widget.setSelected( widget.$input.prop( 'checked' ) );
+               } );
+       }
+};
+
+/**
+ * Set selection state of this checkbox.
+ *
+ * @param {boolean} state `true` for selected
+ * @chainable
+ */
+OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) {
+       state = !!state;
+       if ( this.selected !== state ) {
+               this.selected = state;
+               this.$input.prop( 'checked', this.selected );
+               this.emit( 'change', this.selected );
+       }
+       return this;
+};
+
+/**
+ * Check if this checkbox is selected.
+ *
+ * @return {boolean} Checkbox is selected
+ */
+OO.ui.CheckboxInputWidget.prototype.isSelected = function () {
+       // Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
+       // it, and we won't know unless they're kind enough to trigger a 'change' event.
+       var selected = this.$input.prop( 'checked' );
+       if ( this.selected !== selected ) {
+               this.setSelected( selected );
+       }
+       return this.selected;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {
+       OO.ui.CheckboxInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
+       if ( state.checked !== undefined && state.checked !== this.isSelected() ) {
+               this.setSelected( state.checked );
+       }
+};
+
+/**
+ * DropdownInputWidget is a {@link OO.ui.DropdownWidget DropdownWidget} intended to be used
+ * within a HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
+ * of a hidden HTML `input` tag. Please see the [OOjs UI documentation on MediaWiki][1] for
+ * more information about input widgets.
+ *
+ * A DropdownInputWidget always has a value (one of the options is always selected), unless there
+ * are no options. If no `value` configuration option is provided, the first option is selected.
+ * If you need a state representing no value (no option being selected), use a DropdownWidget.
+ *
+ * This and OO.ui.RadioSelectInputWidget support the same configuration options.
+ *
+ *     @example
+ *     // Example: A DropdownInputWidget with three options
+ *     var dropdownInput = new OO.ui.DropdownInputWidget( {
+ *         options: [
+ *             { data: 'a', label: 'First' },
+ *             { data: 'b', label: 'Second'},
+ *             { data: 'c', label: 'Third' }
+ *         ]
+ *     } );
+ *     $( 'body' ).append( dropdownInput.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
+ * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}
+ */
+OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties (must be done before parent constructor which calls #setDisabled)
+       this.dropdownWidget = new OO.ui.DropdownWidget( config.dropdown );
+
+       // Parent constructor
+       OO.ui.DropdownInputWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TitledElement.call( this, config );
+
+       // Events
+       this.dropdownWidget.getMenu().connect( this, { select: 'onMenuSelect' } );
+
+       // Initialization
+       this.setOptions( config.options || [] );
+       this.$element
+               .addClass( 'oo-ui-dropdownInputWidget' )
+               .append( this.dropdownWidget.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.DropdownInputWidget, OO.ui.InputWidget );
+OO.mixinClass( OO.ui.DropdownInputWidget, OO.ui.mixin.TitledElement );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.DropdownInputWidget.prototype.getInputElement = function ( config ) {
+       // See InputWidget#reusePreInfuseDOM about config.$input
+       if ( config.$input ) {
+               return config.$input.addClass( 'oo-ui-element-hidden' );
+       }
+       return $( '<input type="hidden">' );
+};
+
+/**
+ * Handles menu select events.
+ *
+ * @private
+ * @param {OO.ui.MenuOptionWidget} item Selected menu item
+ */
+OO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) {
+       this.setValue( item.getData() );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {
+       value = this.cleanUpValue( value );
+       this.dropdownWidget.getMenu().selectItemByData( value );
+       OO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.DropdownInputWidget.prototype.setDisabled = function ( state ) {
+       this.dropdownWidget.setDisabled( state );
+       OO.ui.DropdownInputWidget.parent.prototype.setDisabled.call( this, state );
+       return this;
+};
+
+/**
+ * Set the options available for this input.
+ *
+ * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
+ * @chainable
+ */
+OO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) {
+       var
+               value = this.getValue(),
+               widget = this;
+
+       // Rebuild the dropdown menu
+       this.dropdownWidget.getMenu()
+               .clearItems()
+               .addItems( options.map( function ( opt ) {
+                       var optValue = widget.cleanUpValue( opt.data );
+                       return new OO.ui.MenuOptionWidget( {
+                               data: optValue,
+                               label: opt.label !== undefined ? opt.label : optValue
+                       } );
+               } ) );
+
+       // Restore the previous value, or reset to something sensible
+       if ( this.dropdownWidget.getMenu().getItemFromData( value ) ) {
+               // Previous value is still available, ensure consistency with the dropdown
+               this.setValue( value );
+       } else {
+               // No longer valid, reset
+               if ( options.length ) {
+                       this.setValue( options[ 0 ].data );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.DropdownInputWidget.prototype.focus = function () {
+       this.dropdownWidget.getMenu().toggle( true );
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.DropdownInputWidget.prototype.blur = function () {
+       this.dropdownWidget.getMenu().toggle( false );
+       return this;
+};
+
+/**
+ * RadioInputWidget creates a single radio button. Because radio buttons are usually used as a set,
+ * in most cases you will want to use a {@link OO.ui.RadioSelectWidget radio select}
+ * with {@link OO.ui.RadioOptionWidget radio options} instead of this class. For more information,
+ * please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
+ *
+ *     @example
+ *     // An example of selected, unselected, and disabled radio inputs
+ *     var radio1 = new OO.ui.RadioInputWidget( {
+ *         value: 'a',
+ *         selected: true
+ *     } );
+ *     var radio2 = new OO.ui.RadioInputWidget( {
+ *         value: 'b'
+ *     } );
+ *     var radio3 = new OO.ui.RadioInputWidget( {
+ *         value: 'c',
+ *         disabled: true
+ *     } );
+ *     // Create a fieldset layout with fields for each radio button.
+ *     var fieldset = new OO.ui.FieldsetLayout( {
+ *         label: 'Radio inputs'
+ *     } );
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( radio1, { label: 'Selected', align: 'inline' } ),
+ *         new OO.ui.FieldLayout( radio2, { label: 'Unselected', align: 'inline' } ),
+ *         new OO.ui.FieldLayout( radio3, { label: 'Disabled', align: 'inline' } ),
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button is not selected.
+ */
+OO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.RadioInputWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-radioInputWidget' )
+               // Required for pretty styling in MediaWiki theme
+               .append( $( '<span>' ) );
+       this.setSelected( config.selected !== undefined ? config.selected : false );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.RadioInputWidget, OO.ui.InputWidget );
+
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioInputWidget.static.gatherPreInfuseState = function ( node, config ) {
+       var state = OO.ui.RadioInputWidget.parent.static.gatherPreInfuseState( node, config );
+       state.checked = config.$input.prop( 'checked' );
+       return state;
+};
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.RadioInputWidget.prototype.getInputElement = function () {
+       return $( '<input type="radio" />' );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioInputWidget.prototype.onEdit = function () {
+       // RadioInputWidget doesn't track its state.
+};
+
+/**
+ * Set selection state of this radio button.
+ *
+ * @param {boolean} state `true` for selected
+ * @chainable
+ */
+OO.ui.RadioInputWidget.prototype.setSelected = function ( state ) {
+       // RadioInputWidget doesn't track its state.
+       this.$input.prop( 'checked', state );
+       return this;
+};
+
+/**
+ * Check if this radio button is selected.
+ *
+ * @return {boolean} Radio is selected
+ */
+OO.ui.RadioInputWidget.prototype.isSelected = function () {
+       return this.$input.prop( 'checked' );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioInputWidget.prototype.restorePreInfuseState = function ( state ) {
+       OO.ui.RadioInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
+       if ( state.checked !== undefined && state.checked !== this.isSelected() ) {
+               this.setSelected( state.checked );
+       }
+};
+
+/**
+ * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be used
+ * within a HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
+ * of a hidden HTML `input` tag. Please see the [OOjs UI documentation on MediaWiki][1] for
+ * more information about input widgets.
+ *
+ * This and OO.ui.DropdownInputWidget support the same configuration options.
+ *
+ *     @example
+ *     // Example: A RadioSelectInputWidget with three options
+ *     var radioSelectInput = new OO.ui.RadioSelectInputWidget( {
+ *         options: [
+ *             { data: 'a', label: 'First' },
+ *             { data: 'b', label: 'Second'},
+ *             { data: 'c', label: 'Third' }
+ *         ]
+ *     } );
+ *     $( 'body' ).append( radioSelectInput.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
+ */
+OO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Properties (must be done before parent constructor which calls #setDisabled)
+       this.radioSelectWidget = new OO.ui.RadioSelectWidget();
+
+       // Parent constructor
+       OO.ui.RadioSelectInputWidget.parent.call( this, config );
+
+       // Events
+       this.radioSelectWidget.connect( this, { select: 'onMenuSelect' } );
+
+       // Initialization
+       this.setOptions( config.options || [] );
+       this.$element
+               .addClass( 'oo-ui-radioSelectInputWidget' )
+               .append( this.radioSelectWidget.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.RadioSelectInputWidget, OO.ui.InputWidget );
+
+/* Static Properties */
+
+OO.ui.RadioSelectInputWidget.static.supportsSimpleLabel = false;
+
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioSelectInputWidget.static.gatherPreInfuseState = function ( node, config ) {
+       var state = OO.ui.RadioSelectInputWidget.parent.static.gatherPreInfuseState( node, config );
+       state.value = $( node ).find( '.oo-ui-radioInputWidget .oo-ui-inputWidget-input:checked' ).val();
+       return state;
+};
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.RadioSelectInputWidget.prototype.getInputElement = function () {
+       return $( '<input type="hidden">' );
+};
+
+/**
+ * Handles menu select events.
+ *
+ * @private
+ * @param {OO.ui.RadioOptionWidget} item Selected menu item
+ */
+OO.ui.RadioSelectInputWidget.prototype.onMenuSelect = function ( item ) {
+       this.setValue( item.getData() );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) {
+       value = this.cleanUpValue( value );
+       this.radioSelectWidget.selectItemByData( value );
+       OO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, value );
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.RadioSelectInputWidget.prototype.setDisabled = function ( state ) {
+       this.radioSelectWidget.setDisabled( state );
+       OO.ui.RadioSelectInputWidget.parent.prototype.setDisabled.call( this, state );
+       return this;
+};
+
+/**
+ * Set the options available for this input.
+ *
+ * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
+ * @chainable
+ */
+OO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) {
+       var
+               value = this.getValue(),
+               widget = this;
+
+       // Rebuild the radioSelect menu
+       this.radioSelectWidget
+               .clearItems()
+               .addItems( options.map( function ( opt ) {
+                       var optValue = widget.cleanUpValue( opt.data );
+                       return new OO.ui.RadioOptionWidget( {
+                               data: optValue,
+                               label: opt.label !== undefined ? opt.label : optValue
+                       } );
+               } ) );
+
+       // Restore the previous value, or reset to something sensible
+       if ( this.radioSelectWidget.getItemFromData( value ) ) {
+               // Previous value is still available, ensure consistency with the radioSelect
+               this.setValue( value );
+       } else {
+               // No longer valid, reset
+               if ( options.length ) {
+                       this.setValue( options[ 0 ].data );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * TextInputWidgets, like HTML text inputs, can be configured with options that customize the
+ * size of the field as well as its presentation. In addition, these widgets can be configured
+ * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an optional
+ * validation-pattern (used to determine if an input value is valid or not) and an input filter,
+ * which modifies incoming values rather than validating them.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
+ *
+ * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
+ *
+ *     @example
+ *     // Example of a text input widget
+ *     var textInput = new OO.ui.TextInputWidget( {
+ *         value: 'Text input'
+ *     } )
+ *     $( 'body' ).append( textInput.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ * @class
+ * @extends OO.ui.InputWidget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.PendingElement
+ * @mixins OO.ui.mixin.LabelElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [type='text'] The value of the HTML `type` attribute: 'text', 'password', 'search',
+ *  'email' or 'url'. Ignored if `multiline` is true.
+ *
+ *  Some values of `type` result in additional behaviors:
+ *
+ *  - `search`: implies `icon: 'search'` and `indicator: 'clear'`; when clicked, the indicator
+ *    empties the text field
+ * @cfg {string} [placeholder] Placeholder text
+ * @cfg {boolean} [autofocus=false] Use an HTML `autofocus` attribute to
+ *  instruct the browser to focus this widget.
+ * @cfg {boolean} [readOnly=false] Prevent changes to the value of the text input.
+ * @cfg {number} [maxLength] Maximum number of characters allowed in the input.
+ * @cfg {boolean} [multiline=false] Allow multiple lines of text
+ * @cfg {number} [rows] If multiline, number of visible lines in textarea. If used with `autosize`,
+ *  specifies minimum number of rows to display.
+ * @cfg {boolean} [autosize=false] Automatically resize the text input to fit its content.
+ *  Use the #maxRows config to specify a maximum number of displayed rows.
+ * @cfg {boolean} [maxRows] Maximum number of rows to display when #autosize is set to true.
+ *  Defaults to the maximum of `10` and `2 * rows`, or `10` if `rows` isn't provided.
+ * @cfg {string} [labelPosition='after'] The position of the inline label relative to that of
+ *  the value or placeholder text: `'before'` or `'after'`
+ * @cfg {boolean} [required=false] Mark the field as required. Implies `indicator: 'required'`.
+ * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete for this field
+ * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a symbolic name of a
+ *  pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'
+ *  (the value must contain only numbers); when RegExp, a regular expression that must match the
+ *  value for it to be considered valid; when Function, a function receiving the value as parameter
+ *  that must return true, or promise resolving to true, for it to be considered valid.
+ */
+OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
+       // Configuration initialization
+       config = $.extend( {
+               type: 'text',
+               labelPosition: 'after'
+       }, config );
+       if ( config.type === 'search' ) {
+               if ( config.icon === undefined ) {
+                       config.icon = 'search';
+               }
+               // indicator: 'clear' is set dynamically later, depending on value
+       }
+       if ( config.required ) {
+               if ( config.indicator === undefined ) {
+                       config.indicator = 'required';
+               }
+       }
+
+       // Parent constructor
+       OO.ui.TextInputWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$input } ) );
+       OO.ui.mixin.LabelElement.call( this, config );
+
+       // Properties
+       this.type = this.getSaneType( config );
+       this.readOnly = false;
+       this.multiline = !!config.multiline;
+       this.autosize = !!config.autosize;
+       this.minRows = config.rows !== undefined ? config.rows : '';
+       this.maxRows = config.maxRows || Math.max( 2 * ( this.minRows || 0 ), 10 );
+       this.validate = null;
+       this.styleHeight = null;
+       this.scrollWidth = null;
+
+       // Clone for resizing
+       if ( this.autosize ) {
+               this.$clone = this.$input
+                       .clone()
+                       .insertAfter( this.$input )
+                       .attr( 'aria-hidden', 'true' )
+                       .addClass( 'oo-ui-element-hidden' );
+       }
+
+       this.setValidation( config.validate );
+       this.setLabelPosition( config.labelPosition );
+
+       // Events
+       this.$input.on( {
+               keypress: this.onKeyPress.bind( this ),
+               blur: this.onBlur.bind( this )
+       } );
+       this.$input.one( {
+               focus: this.onElementAttach.bind( this )
+       } );
+       this.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );
+       this.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );
+       this.on( 'labelChange', this.updatePosition.bind( this ) );
+       this.connect( this, {
+               change: 'onChange',
+               disable: 'onDisable'
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-textInputWidget oo-ui-textInputWidget-type-' + this.type )
+               .append( this.$icon, this.$indicator );
+       this.setReadOnly( !!config.readOnly );
+       this.updateSearchIndicator();
+       if ( config.placeholder ) {
+               this.$input.attr( 'placeholder', config.placeholder );
+       }
+       if ( config.maxLength !== undefined ) {
+               this.$input.attr( 'maxlength', config.maxLength );
+       }
+       if ( config.autofocus ) {
+               this.$input.attr( 'autofocus', 'autofocus' );
+       }
+       if ( config.required ) {
+               this.$input.attr( 'required', 'required' );
+               this.$input.attr( 'aria-required', 'true' );
+       }
+       if ( config.autocomplete === false ) {
+               this.$input.attr( 'autocomplete', 'off' );
+               // Turning off autocompletion also disables "form caching" when the user navigates to a
+               // different page and then clicks "Back". Re-enable it when leaving. Borrowed from jQuery UI.
+               $( window ).on( {
+                       beforeunload: function () {
+                               this.$input.removeAttr( 'autocomplete' );
+                       }.bind( this ),
+                       pageshow: function () {
+                               // Browsers don't seem to actually fire this event on "Back", they instead just reload the
+                               // whole page... it shouldn't hurt, though.
+                               this.$input.attr( 'autocomplete', 'off' );
+                       }.bind( this )
+               } );
+       }
+       if ( this.multiline && config.rows ) {
+               this.$input.attr( 'rows', config.rows );
+       }
+       if ( this.label || config.autosize ) {
+               this.installParentChangeDetector();
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.PendingElement );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.LabelElement );
+
+/* Static Properties */
+
+OO.ui.TextInputWidget.static.validationPatterns = {
+       'non-empty': /.+/,
+       integer: /^\d+$/
+};
+
+/* Static Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.TextInputWidget.static.gatherPreInfuseState = function ( node, config ) {
+       var state = OO.ui.TextInputWidget.parent.static.gatherPreInfuseState( node, config );
+       if ( config.multiline ) {
+               state.scrollTop = config.$input.scrollTop();
+       }
+       return state;
+};
+
+/* Events */
+
+/**
+ * An `enter` event is emitted when the user presses 'enter' inside the text box.
+ *
+ * Not emitted if the input is multiline.
+ *
+ * @event enter
+ */
+
+/**
+ * A `resize` event is emitted when autosize is set and the widget resizes
+ *
+ * @event resize
+ */
+
+/* Methods */
+
+/**
+ * Handle icon mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ * @fires icon
+ */
+OO.ui.TextInputWidget.prototype.onIconMouseDown = function ( e ) {
+       if ( e.which === OO.ui.MouseButtons.LEFT ) {
+               this.$input[ 0 ].focus();
+               return false;
+       }
+};
+
+/**
+ * Handle indicator mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ * @fires indicator
+ */
+OO.ui.TextInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
+       if ( e.which === OO.ui.MouseButtons.LEFT ) {
+               if ( this.type === 'search' ) {
+                       // Clear the text field
+                       this.setValue( '' );
+               }
+               this.$input[ 0 ].focus();
+               return false;
+       }
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ * @fires enter If enter key is pressed and input is not multiline
+ */
+OO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {
+       if ( e.which === OO.ui.Keys.ENTER && !this.multiline ) {
+               this.emit( 'enter', e );
+       }
+};
+
+/**
+ * Handle blur events.
+ *
+ * @private
+ * @param {jQuery.Event} e Blur event
+ */
+OO.ui.TextInputWidget.prototype.onBlur = function () {
+       this.setValidityFlag();
+};
+
+/**
+ * Handle element attach events.
+ *
+ * @private
+ * @param {jQuery.Event} e Element attach event
+ */
+OO.ui.TextInputWidget.prototype.onElementAttach = function () {
+       // Any previously calculated size is now probably invalid if we reattached elsewhere
+       this.valCache = null;
+       this.adjustSize();
+       this.positionLabel();
+};
+
+/**
+ * Handle change events.
+ *
+ * @param {string} value
+ * @private
+ */
+OO.ui.TextInputWidget.prototype.onChange = function () {
+       this.updateSearchIndicator();
+       this.setValidityFlag();
+       this.adjustSize();
+};
+
+/**
+ * Handle disable events.
+ *
+ * @param {boolean} disabled Element is disabled
+ * @private
+ */
+OO.ui.TextInputWidget.prototype.onDisable = function () {
+       this.updateSearchIndicator();
+};
+
+/**
+ * Check if the input is {@link #readOnly read-only}.
+ *
+ * @return {boolean}
+ */
+OO.ui.TextInputWidget.prototype.isReadOnly = function () {
+       return this.readOnly;
+};
+
+/**
+ * Set the {@link #readOnly read-only} state of the input.
+ *
+ * @param {boolean} state Make input read-only
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {
+       this.readOnly = !!state;
+       this.$input.prop( 'readOnly', this.readOnly );
+       this.updateSearchIndicator();
+       return this;
+};
+
+/**
+ * Support function for making #onElementAttach work across browsers.
+ *
+ * This whole function could be replaced with one line of code using the DOMNodeInsertedIntoDocument
+ * event, but it's not supported by Firefox and allegedly deprecated, so we only use it as fallback.
+ *
+ * Due to MutationObserver performance woes, #onElementAttach is only somewhat reliably called the
+ * first time that the element gets attached to the documented.
+ */
+OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
+       var mutationObserver, onRemove, topmostNode, fakeParentNode,
+               MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
+               widget = this;
+
+       if ( MutationObserver ) {
+               // The new way. If only it wasn't so ugly.
+
+               if ( this.$element.closest( 'html' ).length ) {
+                       // Widget is attached already, do nothing. This breaks the functionality of this function when
+                       // the widget is detached and reattached. Alas, doing this correctly with MutationObserver
+                       // would require observation of the whole document, which would hurt performance of other,
+                       // more important code.
+                       return;
+               }
+
+               // Find topmost node in the tree
+               topmostNode = this.$element[ 0 ];
+               while ( topmostNode.parentNode ) {
+                       topmostNode = topmostNode.parentNode;
+               }
+
+               // We have no way to detect the $element being attached somewhere without observing the entire
+               // DOM with subtree modifications, which would hurt performance. So we cheat: we hook to the
+               // parent node of $element, and instead detect when $element is removed from it (and thus
+               // probably attached somewhere else). If there is no parent, we create a "fake" one. If it
+               // doesn't get attached, we end up back here and create the parent.
+
+               mutationObserver = new MutationObserver( function ( mutations ) {
+                       var i, j, removedNodes;
+                       for ( i = 0; i < mutations.length; i++ ) {
+                               removedNodes = mutations[ i ].removedNodes;
+                               for ( j = 0; j < removedNodes.length; j++ ) {
+                                       if ( removedNodes[ j ] === topmostNode ) {
+                                               setTimeout( onRemove, 0 );
+                                               return;
+                                       }
+                               }
+                       }
+               } );
+
+               onRemove = function () {
+                       // If the node was attached somewhere else, report it
+                       if ( widget.$element.closest( 'html' ).length ) {
+                               widget.onElementAttach();
+                       }
+                       mutationObserver.disconnect();
+                       widget.installParentChangeDetector();
+               };
+
+               // Create a fake parent and observe it
+               fakeParentNode = $( '<div>' ).append( topmostNode )[ 0 ];
+               mutationObserver.observe( fakeParentNode, { childList: true } );
+       } else {
+               // Using the DOMNodeInsertedIntoDocument event is much nicer and less magical, and works for
+               // detachment and reattachment, but it's not supported by Firefox and allegedly deprecated.
+               this.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );
+       }
+};
+
+/**
+ * Automatically adjust the size of the text input.
+ *
+ * This only affects #multiline inputs that are {@link #autosize autosized}.
+ *
+ * @chainable
+ * @fires resize
+ */
+OO.ui.TextInputWidget.prototype.adjustSize = function () {
+       var scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError,
+               idealHeight, newHeight, scrollWidth, property;
+
+       if ( this.multiline && this.$input.val() !== this.valCache ) {
+               if ( this.autosize ) {
+                       this.$clone
+                               .val( this.$input.val() )
+                               .attr( 'rows', this.minRows )
+                               // Set inline height property to 0 to measure scroll height
+                               .css( 'height', 0 );
+
+                       this.$clone.removeClass( 'oo-ui-element-hidden' );
+
+                       this.valCache = this.$input.val();
+
+                       scrollHeight = this.$clone[ 0 ].scrollHeight;
+
+                       // Remove inline height property to measure natural heights
+                       this.$clone.css( 'height', '' );
+                       innerHeight = this.$clone.innerHeight();
+                       outerHeight = this.$clone.outerHeight();
+
+                       // Measure max rows height
+                       this.$clone
+                               .attr( 'rows', this.maxRows )
+                               .css( 'height', 'auto' )
+                               .val( '' );
+                       maxInnerHeight = this.$clone.innerHeight();
+
+                       // Difference between reported innerHeight and scrollHeight with no scrollbars present
+                       // Equals 1 on Blink-based browsers and 0 everywhere else
+                       measurementError = maxInnerHeight - this.$clone[ 0 ].scrollHeight;
+                       idealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );
+
+                       this.$clone.addClass( 'oo-ui-element-hidden' );
+
+                       // Only apply inline height when expansion beyond natural height is needed
+                       // Use the difference between the inner and outer height as a buffer
+                       newHeight = idealHeight > innerHeight ? idealHeight + ( outerHeight - innerHeight ) : '';
+                       if ( newHeight !== this.styleHeight ) {
+                               this.$input.css( 'height', newHeight );
+                               this.styleHeight = newHeight;
+                               this.emit( 'resize' );
+                       }
+               }
+               scrollWidth = this.$input[ 0 ].offsetWidth - this.$input[ 0 ].clientWidth;
+               if ( scrollWidth !== this.scrollWidth ) {
+                       property = this.$element.css( 'direction' ) === 'rtl' ? 'left' : 'right';
+                       // Reset
+                       this.$label.css( { right: '', left: '' } );
+                       this.$indicator.css( { right: '', left: '' } );
+
+                       if ( scrollWidth ) {
+                               this.$indicator.css( property, scrollWidth );
+                               if ( this.labelPosition === 'after' ) {
+                                       this.$label.css( property, scrollWidth );
+                               }
+                       }
+
+                       this.scrollWidth = scrollWidth;
+                       this.positionLabel();
+               }
+       }
+       return this;
+};
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {
+       return config.multiline ?
+               $( '<textarea>' ) :
+               $( '<input type="' + this.getSaneType( config ) + '" />' );
+};
+
+/**
+ * Get sanitized value for 'type' for given config.
+ *
+ * @param {Object} config Configuration options
+ * @return {string|null}
+ * @private
+ */
+OO.ui.TextInputWidget.prototype.getSaneType = function ( config ) {
+       var type = [ 'text', 'password', 'search', 'email', 'url' ].indexOf( config.type ) !== -1 ?
+               config.type :
+               'text';
+       return config.multiline ? 'multiline' : type;
+};
+
+/**
+ * Check if the input supports multiple lines.
+ *
+ * @return {boolean}
+ */
+OO.ui.TextInputWidget.prototype.isMultiline = function () {
+       return !!this.multiline;
+};
+
+/**
+ * Check if the input automatically adjusts its size.
+ *
+ * @return {boolean}
+ */
+OO.ui.TextInputWidget.prototype.isAutosizing = function () {
+       return !!this.autosize;
+};
+
+/**
+ * Focus the input and select a specified range within the text.
+ *
+ * @param {number} from Select from offset
+ * @param {number} [to] Select to offset, defaults to from
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.selectRange = function ( from, to ) {
+       var isBackwards, start, end,
+               input = this.$input[ 0 ];
+
+       to = to || from;
+
+       isBackwards = to < from;
+       start = isBackwards ? to : from;
+       end = isBackwards ? from : to;
+
+       this.focus();
+
+       input.setSelectionRange( start, end, isBackwards ? 'backward' : 'forward' );
+       return this;
+};
+
+/**
+ * Get an object describing the current selection range in a directional manner
+ *
+ * @return {Object} Object containing 'from' and 'to' offsets
+ */
+OO.ui.TextInputWidget.prototype.getRange = function () {
+       var input = this.$input[ 0 ],
+               start = input.selectionStart,
+               end = input.selectionEnd,
+               isBackwards = input.selectionDirection === 'backward';
+
+       return {
+               from: isBackwards ? end : start,
+               to: isBackwards ? start : end
+       };
+};
+
+/**
+ * Get the length of the text input value.
+ *
+ * This could differ from the length of #getValue if the
+ * value gets filtered
+ *
+ * @return {number} Input length
+ */
+OO.ui.TextInputWidget.prototype.getInputLength = function () {
+       return this.$input[ 0 ].value.length;
+};
+
+/**
+ * Focus the input and select the entire text.
+ *
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.select = function () {
+       return this.selectRange( 0, this.getInputLength() );
+};
+
+/**
+ * Focus the input and move the cursor to the start.
+ *
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.moveCursorToStart = function () {
+       return this.selectRange( 0 );
+};
+
+/**
+ * Focus the input and move the cursor to the end.
+ *
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.moveCursorToEnd = function () {
+       return this.selectRange( this.getInputLength() );
+};
+
+/**
+ * Insert new content into the input.
+ *
+ * @param {string} content Content to be inserted
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.insertContent = function ( content ) {
+       var start, end,
+               range = this.getRange(),
+               value = this.getValue();
+
+       start = Math.min( range.from, range.to );
+       end = Math.max( range.from, range.to );
+
+       this.setValue( value.slice( 0, start ) + content + value.slice( end ) );
+       this.selectRange( start + content.length );
+       return this;
+};
+
+/**
+ * Insert new content either side of a selection.
+ *
+ * @param {string} pre Content to be inserted before the selection
+ * @param {string} post Content to be inserted after the selection
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.encapsulateContent = function ( pre, post ) {
+       var start, end,
+               range = this.getRange(),
+               offset = pre.length;
+
+       start = Math.min( range.from, range.to );
+       end = Math.max( range.from, range.to );
+
+       this.selectRange( start ).insertContent( pre );
+       this.selectRange( offset + end ).insertContent( post );
+
+       this.selectRange( offset + start, offset + end );
+       return this;
+};
+
+/**
+ * Set the validation pattern.
+ *
+ * The validation pattern is either a regular expression, a function, or the symbolic name of a
+ * pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer' (the
+ * value must contain only numbers).
+ *
+ * @param {RegExp|Function|string|null} validate Regular expression, function, or the symbolic name
+ *  of a pattern (either ‘integer’ or ‘non-empty’) defined by the class.
+ */
+OO.ui.TextInputWidget.prototype.setValidation = function ( validate ) {
+       if ( validate instanceof RegExp || validate instanceof Function ) {
+               this.validate = validate;
+       } else {
+               this.validate = this.constructor.static.validationPatterns[ validate ] || /.*/;
+       }
+};
+
+/**
+ * Sets the 'invalid' flag appropriately.
+ *
+ * @param {boolean} [isValid] Optionally override validation result
+ */
+OO.ui.TextInputWidget.prototype.setValidityFlag = function ( isValid ) {
+       var widget = this,
+               setFlag = function ( valid ) {
+                       if ( !valid ) {
+                               widget.$input.attr( 'aria-invalid', 'true' );
+                       } else {
+                               widget.$input.removeAttr( 'aria-invalid' );
+                       }
+                       widget.setFlags( { invalid: !valid } );
+               };
+
+       if ( isValid !== undefined ) {
+               setFlag( isValid );
+       } else {
+               this.getValidity().then( function () {
+                       setFlag( true );
+               }, function () {
+                       setFlag( false );
+               } );
+       }
+};
+
+/**
+ * Check if a value is valid.
+ *
+ * This method returns a promise that resolves with a boolean `true` if the current value is
+ * considered valid according to the supplied {@link #validate validation pattern}.
+ *
+ * @deprecated
+ * @return {jQuery.Promise} A promise that resolves to a boolean `true` if the value is valid.
+ */
+OO.ui.TextInputWidget.prototype.isValid = function () {
+       var result;
+
+       if ( this.validate instanceof Function ) {
+               result = this.validate( this.getValue() );
+               if ( result && $.isFunction( result.promise ) ) {
+                       return result.promise();
+               } else {
+                       return $.Deferred().resolve( !!result ).promise();
+               }
+       } else {
+               return $.Deferred().resolve( !!this.getValue().match( this.validate ) ).promise();
+       }
+};
+
+/**
+ * Get the validity of current value.
+ *
+ * This method returns a promise that resolves if the value is valid and rejects if
+ * it isn't. Uses the {@link #validate validation pattern}  to check for validity.
+ *
+ * @return {jQuery.Promise} A promise that resolves if the value is valid, rejects if not.
+ */
+OO.ui.TextInputWidget.prototype.getValidity = function () {
+       var result;
+
+       function rejectOrResolve( valid ) {
+               if ( valid ) {
+                       return $.Deferred().resolve().promise();
+               } else {
+                       return $.Deferred().reject().promise();
+               }
+       }
+
+       if ( this.validate instanceof Function ) {
+               result = this.validate( this.getValue() );
+               if ( result && $.isFunction( result.promise ) ) {
+                       return result.promise().then( function ( valid ) {
+                               return rejectOrResolve( valid );
+                       } );
+               } else {
+                       return rejectOrResolve( result );
+               }
+       } else {
+               return rejectOrResolve( this.getValue().match( this.validate ) );
+       }
+};
+
+/**
+ * Set the position of the inline label relative to that of the value: `‘before’` or `‘after’`.
+ *
+ * @param {string} labelPosition Label position, 'before' or 'after'
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.setLabelPosition = function ( labelPosition ) {
+       this.labelPosition = labelPosition;
+       this.updatePosition();
+       return this;
+};
+
+/**
+ * Update the position of the inline label.
+ *
+ * This method is called by #setLabelPosition, and can also be called on its own if
+ * something causes the label to be mispositioned.
+ *
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.updatePosition = function () {
+       var after = this.labelPosition === 'after';
+
+       this.$element
+               .toggleClass( 'oo-ui-textInputWidget-labelPosition-after', !!this.label && after )
+               .toggleClass( 'oo-ui-textInputWidget-labelPosition-before', !!this.label && !after );
+
+       this.valCache = null;
+       this.scrollWidth = null;
+       this.adjustSize();
+       this.positionLabel();
+
+       return this;
+};
+
+/**
+ * Update the 'clear' indicator displayed on type: 'search' text fields, hiding it when the field is
+ * already empty or when it's not editable.
+ */
+OO.ui.TextInputWidget.prototype.updateSearchIndicator = function () {
+       if ( this.type === 'search' ) {
+               if ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {
+                       this.setIndicator( null );
+               } else {
+                       this.setIndicator( 'clear' );
+               }
+       }
+};
+
+/**
+ * Position the label by setting the correct padding on the input.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.positionLabel = function () {
+       var after, rtl, property;
+       // Clear old values
+       this.$input
+               // Clear old values if present
+               .css( {
+                       'padding-right': '',
+                       'padding-left': ''
+               } );
+
+       if ( this.label ) {
+               this.$element.append( this.$label );
+       } else {
+               this.$label.detach();
+               return;
+       }
+
+       after = this.labelPosition === 'after';
+       rtl = this.$element.css( 'direction' ) === 'rtl';
+       property = after === rtl ? 'padding-left' : 'padding-right';
+
+       this.$input.css( property, this.$label.outerWidth( true ) + ( after ? this.scrollWidth : 0 ) );
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.TextInputWidget.prototype.restorePreInfuseState = function ( state ) {
+       OO.ui.TextInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
+       if ( state.scrollTop !== undefined ) {
+               this.$input.scrollTop( state.scrollTop );
+       }
+};
+
+/**
+ * ComboBoxInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value
+ * can be entered manually) and a {@link OO.ui.MenuSelectWidget menu of options} (from which
+ * a value can be chosen instead). Users can choose options from the combo box in one of two ways:
+ *
+ * - by typing a value in the text input field. If the value exactly matches the value of a menu
+ *   option, that option will appear to be selected.
+ * - by choosing a value from the menu. The value of the chosen option will then appear in the text
+ *   input field.
+ *
+ * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
+ *
+ * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example: A ComboBoxInputWidget.
+ *     var comboBox = new OO.ui.ComboBoxInputWidget( {
+ *         label: 'ComboBoxInputWidget',
+ *         value: 'Option 1',
+ *         menu: {
+ *             items: [
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 1',
+ *                     label: 'Option One'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 2',
+ *                     label: 'Option Two'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 3',
+ *                     label: 'Option Three'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 4',
+ *                     label: 'Option Four'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 5',
+ *                     label: 'Option Five'
+ *                 } )
+ *             ]
+ *         }
+ *     } );
+ *     $( 'body' ).append( comboBox.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.TextInputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
+ * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.FloatingMenuSelectWidget menu select widget}.
+ * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
+ *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
+ *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
+ */
+OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
+       // Configuration initialization
+       config = $.extend( {
+               indicator: 'down'
+       }, config );
+       // For backwards-compatibility with ComboBoxWidget config
+       $.extend( config, config.input );
+
+       // Parent constructor
+       OO.ui.ComboBoxInputWidget.parent.call( this, config );
+
+       // Properties
+       this.$overlay = config.$overlay || this.$element;
+       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
+               {
+                       widget: this,
+                       input: this,
+                       $container: this.$element,
+                       disabled: this.isDisabled()
+               },
+               config.menu
+       ) );
+       // For backwards-compatibility with ComboBoxWidget
+       this.input = this;
+
+       // Events
+       this.$indicator.on( {
+               click: this.onIndicatorClick.bind( this ),
+               keypress: this.onIndicatorKeyPress.bind( this )
+       } );
+       this.connect( this, {
+               change: 'onInputChange',
+               enter: 'onInputEnter'
+       } );
+       this.menu.connect( this, {
+               choose: 'onMenuChoose',
+               add: 'onMenuItemsChange',
+               remove: 'onMenuItemsChange'
+       } );
+
+       // Initialization
+       this.$input.attr( {
+               role: 'combobox',
+               'aria-autocomplete': 'list'
+       } );
+       // Do not override options set via config.menu.items
+       if ( config.options !== undefined ) {
+               this.setOptions( config.options );
+       }
+       // Extra class for backwards-compatibility with ComboBoxWidget
+       this.$element.addClass( 'oo-ui-comboBoxInputWidget oo-ui-comboBoxWidget' );
+       this.$overlay.append( this.menu.$element );
+       this.onMenuItemsChange();
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ComboBoxInputWidget, OO.ui.TextInputWidget );
+
+/* Methods */
+
+/**
+ * Get the combobox's menu.
+ * @return {OO.ui.FloatingMenuSelectWidget} Menu widget
+ */
+OO.ui.ComboBoxInputWidget.prototype.getMenu = function () {
+       return this.menu;
+};
+
+/**
+ * Get the combobox's text input widget.
+ * @return {OO.ui.TextInputWidget} Text input widget
+ */
+OO.ui.ComboBoxInputWidget.prototype.getInput = function () {
+       return this;
+};
+
+/**
+ * Handle input change events.
+ *
+ * @private
+ * @param {string} value New value
+ */
+OO.ui.ComboBoxInputWidget.prototype.onInputChange = function ( value ) {
+       var match = this.menu.getItemFromData( value );
+
+       this.menu.selectItem( match );
+       if ( this.menu.getHighlightedItem() ) {
+               this.menu.highlightItem( match );
+       }
+
+       if ( !this.isDisabled() ) {
+               this.menu.toggle( true );
+       }
+};
+
+/**
+ * Handle mouse click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.ComboBoxInputWidget.prototype.onIndicatorClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.menu.toggle();
+               this.$input[ 0 ].focus();
+       }
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.ComboBoxInputWidget.prototype.onIndicatorKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+               this.menu.toggle();
+               this.$input[ 0 ].focus();
+               return false;
+       }
+};
+
+/**
+ * Handle input enter events.
+ *
+ * @private
+ */
+OO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {
+       if ( !this.isDisabled() ) {
+               this.menu.toggle( false );
+       }
+};
+
+/**
+ * Handle menu choose events.
+ *
+ * @private
+ * @param {OO.ui.OptionWidget} item Chosen item
+ */
+OO.ui.ComboBoxInputWidget.prototype.onMenuChoose = function ( item ) {
+       this.setValue( item.getData() );
+};
+
+/**
+ * Handle menu item change events.
+ *
+ * @private
+ */
+OO.ui.ComboBoxInputWidget.prototype.onMenuItemsChange = function () {
+       var match = this.menu.getItemFromData( this.getValue() );
+       this.menu.selectItem( match );
+       if ( this.menu.getHighlightedItem() ) {
+               this.menu.highlightItem( match );
+       }
+       this.$element.toggleClass( 'oo-ui-comboBoxInputWidget-empty', this.menu.isEmpty() );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ComboBoxInputWidget.prototype.setDisabled = function ( disabled ) {
+       // Parent method
+       OO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.call( this, disabled );
+
+       if ( this.menu ) {
+               this.menu.setDisabled( this.isDisabled() );
+       }
+
+       return this;
+};
+
+/**
+ * Set the options available for this input.
+ *
+ * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
+ * @chainable
+ */
+OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
+       this.getMenu()
+               .clearItems()
+               .addItems( options.map( function ( opt ) {
+                       return new OO.ui.MenuOptionWidget( {
+                               data: opt.data,
+                               label: opt.label !== undefined ? opt.label : opt.data
+                       } );
+               } ) );
+
+       return this;
+};
+
+/**
+ * @class
+ * @deprecated Use OO.ui.ComboBoxInputWidget instead.
+ */
+OO.ui.ComboBoxWidget = OO.ui.ComboBoxInputWidget;
+
+/**
+ * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,
+ * which is a widget that is specified by reference before any optional configuration settings.
+ *
+ * Field layouts can be configured with help text and/or labels. Labels are aligned in one of four ways:
+ *
+ * - **left**: The label is placed before the field-widget and aligned with the left margin.
+ *   A left-alignment is used for forms with many fields.
+ * - **right**: The label is placed before the field-widget and aligned to the right margin.
+ *   A right-alignment is used for long but familiar forms which users tab through,
+ *   verifying the current field with a quick glance at the label.
+ * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms
+ *   that users fill out from top to bottom.
+ * - **inline**: The label is placed after the field-widget and aligned to the left.
+ *   An inline-alignment is best used with checkboxes or radio buttons.
+ *
+ * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for examples and more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Fields_and_Fieldsets
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {OO.ui.Widget} fieldWidget Field widget
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top' or 'inline'
+ * @cfg {Array} [errors] Error messages about the widget, which will be displayed below the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @cfg {Array} [notices] Notices about the widget, which will be displayed below the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
+ *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.
+ *  For important messages, you are advised to use `notices`, as they are always shown.
+ *
+ * @throws {Error} An error is thrown if no widget is specified
+ */
+OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
+       var hasInputWidget, div;
+
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( fieldWidget ) && config === undefined ) {
+               config = fieldWidget;
+               fieldWidget = config.fieldWidget;
+       }
+
+       // Make sure we have required constructor arguments
+       if ( fieldWidget === undefined ) {
+               throw new Error( 'Widget not found' );
+       }
+
+       hasInputWidget = fieldWidget.constructor.static.supportsSimpleLabel;
+
+       // Configuration initialization
+       config = $.extend( { align: 'left' }, config );
+
+       // Parent constructor
+       OO.ui.FieldLayout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
+
+       // Properties
+       this.fieldWidget = fieldWidget;
+       this.errors = [];
+       this.notices = [];
+       this.$field = $( '<div>' );
+       this.$messages = $( '<ul>' );
+       this.$body = $( '<' + ( hasInputWidget ? 'label' : 'div' ) + '>' );
+       this.align = null;
+       if ( config.help ) {
+               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       classes: [ 'oo-ui-fieldLayout-help' ],
+                       framed: false,
+                       icon: 'info'
+               } );
+
+               div = $( '<div>' );
+               if ( config.help instanceof OO.ui.HtmlSnippet ) {
+                       div.html( config.help.toString() );
+               } else {
+                       div.text( config.help );
+               }
+               this.popupButtonWidget.getPopup().$body.append(
+                       div.addClass( 'oo-ui-fieldLayout-help-content' )
+               );
+               this.$help = this.popupButtonWidget.$element;
+       } else {
+               this.$help = $( [] );
+       }
+
+       // Events
+       if ( hasInputWidget ) {
+               this.$label.on( 'click', this.onLabelClick.bind( this ) );
+       }
+       this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-fieldLayout' )
+               .append( this.$help, this.$body );
+       this.$body.addClass( 'oo-ui-fieldLayout-body' );
+       this.$messages.addClass( 'oo-ui-fieldLayout-messages' );
+       this.$field
+               .addClass( 'oo-ui-fieldLayout-field' )
+               .toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
+               .append( this.fieldWidget.$element );
+
+       this.setErrors( config.errors || [] );
+       this.setNotices( config.notices || [] );
+       this.setAlignment( config.align );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.TitledElement );
+
+/* Methods */
+
+/**
+ * Handle field disable events.
+ *
+ * @private
+ * @param {boolean} value Field is disabled
+ */
+OO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {
+       this.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );
+};
+
+/**
+ * Handle label mouse click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.FieldLayout.prototype.onLabelClick = function () {
+       this.fieldWidget.simulateLabelClick();
+       return false;
+};
+
+/**
+ * Get the widget contained by the field.
+ *
+ * @return {OO.ui.Widget} Field widget
+ */
+OO.ui.FieldLayout.prototype.getField = function () {
+       return this.fieldWidget;
+};
+
+/**
+ * @protected
+ * @param {string} kind 'error' or 'notice'
+ * @param {string|OO.ui.HtmlSnippet} text
+ * @return {jQuery}
+ */
+OO.ui.FieldLayout.prototype.makeMessage = function ( kind, text ) {
+       var $listItem, $icon, message;
+       $listItem = $( '<li>' );
+       if ( kind === 'error' ) {
+               $icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element;
+       } else if ( kind === 'notice' ) {
+               $icon = new OO.ui.IconWidget( { icon: 'info' } ).$element;
+       } else {
+               $icon = '';
+       }
+       message = new OO.ui.LabelWidget( { label: text } );
+       $listItem
+               .append( $icon, message.$element )
+               .addClass( 'oo-ui-fieldLayout-messages-' + kind );
+       return $listItem;
+};
+
+/**
+ * Set the field alignment mode.
+ *
+ * @private
+ * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'
+ * @chainable
+ */
+OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
+       if ( value !== this.align ) {
+               // Default to 'left'
+               if ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {
+                       value = 'left';
+               }
+               // Reorder elements
+               if ( value === 'inline' ) {
+                       this.$body.append( this.$field, this.$label );
+               } else {
+                       this.$body.append( this.$label, this.$field );
+               }
+               // Set classes. The following classes can be used here:
+               // * oo-ui-fieldLayout-align-left
+               // * oo-ui-fieldLayout-align-right
+               // * oo-ui-fieldLayout-align-top
+               // * oo-ui-fieldLayout-align-inline
+               if ( this.align ) {
+                       this.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );
+               }
+               this.$element.addClass( 'oo-ui-fieldLayout-align-' + value );
+               this.align = value;
+       }
+
+       return this;
+};
+
+/**
+ * Set the list of error messages.
+ *
+ * @param {Array} errors Error messages about the widget, which will be displayed below the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @chainable
+ */
+OO.ui.FieldLayout.prototype.setErrors = function ( errors ) {
+       this.errors = errors.slice();
+       this.updateMessages();
+       return this;
+};
+
+/**
+ * Set the list of notice messages.
+ *
+ * @param {Array} notices Notices about the widget, which will be displayed below the widget.
+ *  The array may contain strings or OO.ui.HtmlSnippet instances.
+ * @chainable
+ */
+OO.ui.FieldLayout.prototype.setNotices = function ( notices ) {
+       this.notices = notices.slice();
+       this.updateMessages();
+       return this;
+};
+
+/**
+ * Update the rendering of error and notice messages.
+ *
+ * @private
+ */
+OO.ui.FieldLayout.prototype.updateMessages = function () {
+       var i;
+       this.$messages.empty();
+
+       if ( this.errors.length || this.notices.length ) {
+               this.$body.after( this.$messages );
+       } else {
+               this.$messages.remove();
+               return;
+       }
+
+       for ( i = 0; i < this.notices.length; i++ ) {
+               this.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );
+       }
+       for ( i = 0; i < this.errors.length; i++ ) {
+               this.$messages.append( this.makeMessage( 'error', this.errors[ i ] ) );
+       }
+};
+
+/**
+ * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget, a button,
+ * and an optional label and/or help text. The field-widget (e.g., a {@link OO.ui.TextInputWidget TextInputWidget}),
+ * is required and is specified before any optional configuration settings.
+ *
+ * Labels can be aligned in one of four ways:
+ *
+ * - **left**: The label is placed before the field-widget and aligned with the left margin.
+ *   A left-alignment is used for forms with many fields.
+ * - **right**: The label is placed before the field-widget and aligned to the right margin.
+ *   A right-alignment is used for long but familiar forms which users tab through,
+ *   verifying the current field with a quick glance at the label.
+ * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms
+ *   that users fill out from top to bottom.
+ * - **inline**: The label is placed after the field-widget and aligned to the left.
+ *   An inline-alignment is best used with checkboxes or radio buttons.
+ *
+ * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout when help
+ * text is specified.
+ *
+ *     @example
+ *     // Example of an ActionFieldLayout
+ *     var actionFieldLayout = new OO.ui.ActionFieldLayout(
+ *         new OO.ui.TextInputWidget( {
+ *             placeholder: 'Field widget'
+ *         } ),
+ *         new OO.ui.ButtonWidget( {
+ *             label: 'Button'
+ *         } ),
+ *         {
+ *             label: 'An ActionFieldLayout. This label is aligned top',
+ *             align: 'top',
+ *             help: 'This is help text'
+ *         }
+ *     );
+ *
+ *     $( 'body' ).append( actionFieldLayout.$element );
+ *
+ * @class
+ * @extends OO.ui.FieldLayout
+ *
+ * @constructor
+ * @param {OO.ui.Widget} fieldWidget Field widget
+ * @param {OO.ui.ButtonWidget} buttonWidget Button widget
+ */
+OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( fieldWidget ) && config === undefined ) {
+               config = fieldWidget;
+               fieldWidget = config.fieldWidget;
+               buttonWidget = config.buttonWidget;
+       }
+
+       // Parent constructor
+       OO.ui.ActionFieldLayout.parent.call( this, fieldWidget, config );
+
+       // Properties
+       this.buttonWidget = buttonWidget;
+       this.$button = $( '<div>' );
+       this.$input = $( '<div>' );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-actionFieldLayout' );
+       this.$button
+               .addClass( 'oo-ui-actionFieldLayout-button' )
+               .append( this.buttonWidget.$element );
+       this.$input
+               .addClass( 'oo-ui-actionFieldLayout-input' )
+               .append( this.fieldWidget.$element );
+       this.$field
+               .append( this.$input, this.$button );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
+
+/**
+ * FieldsetLayouts are composed of one or more {@link OO.ui.FieldLayout FieldLayouts},
+ * which each contain an individual widget and, optionally, a label. Each Fieldset can be
+ * configured with a label as well. For more information and examples,
+ * please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example of a fieldset layout
+ *     var input1 = new OO.ui.TextInputWidget( {
+ *         placeholder: 'A text input field'
+ *     } );
+ *
+ *     var input2 = new OO.ui.TextInputWidget( {
+ *         placeholder: 'A text input field'
+ *     } );
+ *
+ *     var fieldset = new OO.ui.FieldsetLayout( {
+ *         label: 'Example of a fieldset layout'
+ *     } );
+ *
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( input1, {
+ *             label: 'Field One'
+ *         } ),
+ *         new OO.ui.FieldLayout( input2, {
+ *             label: 'Field Two'
+ *         } )
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Fields_and_Fieldsets
+ *
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset. See OO.ui.FieldLayout for more information about fields.
+ */
+OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.FieldsetLayout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.GroupElement.call( this, config );
+
+       if ( config.help ) {
+               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       classes: [ 'oo-ui-fieldsetLayout-help' ],
+                       framed: false,
+                       icon: 'info'
+               } );
+
+               this.popupButtonWidget.getPopup().$body.append(
+                       $( '<div>' )
+                               .text( config.help )
+                               .addClass( 'oo-ui-fieldsetLayout-help-content' )
+               );
+               this.$help = this.popupButtonWidget.$element;
+       } else {
+               this.$help = $( [] );
+       }
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-fieldsetLayout' )
+               .prepend( this.$help, this.$icon, this.$label, this.$group );
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );
+
+/**
+ * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use browser-based
+ * form submission for the fields instead of handling them in JavaScript. Form layouts can be configured with an
+ * HTML form action, an encoding type, and a method using the #action, #enctype, and #method configs, respectively.
+ * See the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
+ *
+ * Only widgets from the {@link OO.ui.InputWidget InputWidget} family support form submission. It
+ * includes standard form elements like {@link OO.ui.CheckboxInputWidget checkboxes}, {@link
+ * OO.ui.RadioInputWidget radio buttons} and {@link OO.ui.TextInputWidget text fields}, as well as
+ * some fancier controls. Some controls have both regular and InputWidget variants, for example
+ * OO.ui.DropdownWidget and OO.ui.DropdownInputWidget – only the latter support form submission and
+ * often have simplified APIs to match the capabilities of HTML forms.
+ * See the [OOjs UI Inputs documentation on MediaWiki] [2] for more information about InputWidgets.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Forms
+ * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
+ *
+ *     @example
+ *     // Example of a form layout that wraps a fieldset layout
+ *     var input1 = new OO.ui.TextInputWidget( {
+ *         placeholder: 'Username'
+ *     } );
+ *     var input2 = new OO.ui.TextInputWidget( {
+ *         placeholder: 'Password',
+ *         type: 'password'
+ *     } );
+ *     var submit = new OO.ui.ButtonInputWidget( {
+ *         label: 'Submit'
+ *     } );
+ *
+ *     var fieldset = new OO.ui.FieldsetLayout( {
+ *         label: 'A form layout'
+ *     } );
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( input1, {
+ *             label: 'Username',
+ *             align: 'top'
+ *         } ),
+ *         new OO.ui.FieldLayout( input2, {
+ *             label: 'Password',
+ *             align: 'top'
+ *         } ),
+ *         new OO.ui.FieldLayout( submit )
+ *     ] );
+ *     var form = new OO.ui.FormLayout( {
+ *         items: [ fieldset ],
+ *         action: '/api/formhandler',
+ *         method: 'get'
+ *     } )
+ *     $( 'body' ).append( form.$element );
+ *
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [method] HTML form `method` attribute
+ * @cfg {string} [action] HTML form `action` attribute
+ * @cfg {string} [enctype] HTML form `enctype` attribute
+ * @cfg {OO.ui.FieldsetLayout[]} [items] Fieldset layouts to add to the form layout.
+ */
+OO.ui.FormLayout = function OoUiFormLayout( config ) {
+       var action;
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.FormLayout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       // Events
+       this.$element.on( 'submit', this.onFormSubmit.bind( this ) );
+
+       // Make sure the action is safe
+       action = config.action;
+       if ( action !== undefined && !OO.ui.isSafeUrl( action ) ) {
+               action = './' + action;
+       }
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-formLayout' )
+               .attr( {
+                       method: config.method,
+                       action: action,
+                       enctype: config.enctype
+               } );
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.FormLayout, OO.ui.mixin.GroupElement );
+
+/* Events */
+
+/**
+ * A 'submit' event is emitted when the form is submitted.
+ *
+ * @event submit
+ */
+
+/* Static Properties */
+
+OO.ui.FormLayout.static.tagName = 'form';
+
+/* Methods */
+
+/**
+ * Handle form submit events.
+ *
+ * @private
+ * @param {jQuery.Event} e Submit event
+ * @fires submit
+ */
+OO.ui.FormLayout.prototype.onFormSubmit = function () {
+       if ( this.emit( 'submit' ) ) {
+               return false;
+       }
+};
+
+/**
+ * PanelLayouts expand to cover the entire area of their parent. They can be configured with scrolling, padding,
+ * and a frame, and are often used together with {@link OO.ui.StackLayout StackLayouts}.
+ *
+ *     @example
+ *     // Example of a panel layout
+ *     var panel = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true,
+ *         padded: true,
+ *         $content: $( '<p>A panel layout with padding and a frame.</p>' )
+ *     } );
+ *     $( 'body' ).append( panel.$element );
+ *
+ * @class
+ * @extends OO.ui.Layout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [scrollable=false] Allow vertical scrolling
+ * @cfg {boolean} [padded=false] Add padding between the content and the edges of the panel.
+ * @cfg {boolean} [expanded=true] Expand the panel to fill the entire parent element.
+ * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside content.
+ */
+OO.ui.PanelLayout = function OoUiPanelLayout( config ) {
+       // Configuration initialization
+       config = $.extend( {
+               scrollable: false,
+               padded: false,
+               expanded: true,
+               framed: false
+       }, config );
+
+       // Parent constructor
+       OO.ui.PanelLayout.parent.call( this, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-panelLayout' );
+       if ( config.scrollable ) {
+               this.$element.addClass( 'oo-ui-panelLayout-scrollable' );
+       }
+       if ( config.padded ) {
+               this.$element.addClass( 'oo-ui-panelLayout-padded' );
+       }
+       if ( config.expanded ) {
+               this.$element.addClass( 'oo-ui-panelLayout-expanded' );
+       }
+       if ( config.framed ) {
+               this.$element.addClass( 'oo-ui-panelLayout-framed' );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );
+
+/* Methods */
+
+/**
+ * Focus the panel layout
+ *
+ * The default implementation just focuses the first focusable element in the panel
+ */
+OO.ui.PanelLayout.prototype.focus = function () {
+       OO.ui.findFocusable( this.$element ).focus();
+};
+
+/**
+ * HorizontalLayout arranges its contents in a single line (using `display: inline-block` for its
+ * items), with small margins between them. Convenient when you need to put a number of block-level
+ * widgets on a single line next to each other.
+ *
+ * Note that inline elements, such as OO.ui.ButtonWidgets, do not need this wrapper.
+ *
+ *     @example
+ *     // HorizontalLayout with a text input and a label
+ *     var layout = new OO.ui.HorizontalLayout( {
+ *       items: [
+ *         new OO.ui.LabelWidget( { label: 'Label' } ),
+ *         new OO.ui.TextInputWidget( { value: 'Text' } )
+ *       ]
+ *     } );
+ *     $( 'body' ).append( layout.$element );
+ *
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.Widget[]|OO.ui.Layout[]} [items] Widgets or other layouts to add to the layout.
+ */
+OO.ui.HorizontalLayout = function OoUiHorizontalLayout( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.HorizontalLayout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-horizontalLayout' );
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.HorizontalLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css b/resources/lib/oojs-ui/oojs-ui-mediawiki-noimages.css
deleted file mode 100644 (file)
index cd5ef36..0000000
+++ /dev/null
@@ -1,3104 +0,0 @@
-/*!
- * OOjs UI v0.15.1
- * https://www.mediawiki.org/wiki/OOjs_UI
- *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
- * Released under the MIT license
- * http://oojs.mit-license.org
- *
- * Date: 2016-01-26T21:14:25Z
- */
-@-webkit-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@-moz-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-@keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
-}
-/* @noflip */
-.oo-ui-rtl {
-       direction: rtl;
-}
-/* @noflip */
-.oo-ui-ltr {
-       direction: ltr;
-}
-.oo-ui-element-hidden {
-       display: none !important;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       cursor: pointer;
-       display: inline-block;
-       vertical-align: middle;
-       font: inherit;
-       white-space: nowrap;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       display: none;
-}
-.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-frameless {
-       display: inline-block;
-       position: relative;
-}
-.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       display: inline-block;
-       vertical-align: top;
-       text-align: center;
-}
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       font-weight: bold;
-       text-decoration: none;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: 0;
-}
-.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 0.9375em;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-}
-.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 1.875em;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.2);
-       outline: none;
-}
-.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
-       margin-right: 0;
-}
-.oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.25em;
-       margin-right: 0.25em;
-}
-.oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
-       padding-left: 0.25em;
-       padding-right: 0.25em;
-       color: #333333;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #555555;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #444444;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #2962cc;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #347bff;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #1f4999;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #008064;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #00af89;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #005946;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #8c130d;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #d11d13;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #73100a;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       color: #cccccc;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus {
-       box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
-.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
-       padding-left: 2.4em;
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       padding: 0.5em 1em;
-       min-height: 1.2em;
-       min-width: 1em;
-       border-radius: 2px;
-       position: relative;
-       -webkit-transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
-          -moz-transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
-               transition: background 100ms ease, color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
-}
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
-       outline: none;
-}
-.oo-ui-buttonElement-framed > input.oo-ui-buttonElement-button,
-.oo-ui-buttonElement-framed.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       line-height: 1.2em;
-       display: inline-block;
-}
-.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       position: absolute;
-       top: 0.2em;
-       left: 0.5625em;
-}
-.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.3em;
-}
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       display: inline-block;
-}
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-       margin-right: -0.275em;
-}
-.oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       position: relative;
-       left: 0.2em;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       background: #dddddd;
-       color: #ffffff;
-       border: 1px solid #dddddd;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       color: #555555;
-       background-color: #ffffff;
-       border: 1px solid #cccccc;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       background-color: #ebebeb;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       background-color: #d9d9d9;
-       border-color: #d9d9d9;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       color: #347bff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
-       background-color: rgba(52, 123, 255, 0.1);
-       border-color: rgba(31, 73, 153, 0.5);
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #1f4999;
-       border-color: #1f4999;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #1f4999;
-       border-color: #1f4999;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       color: #00af89;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
-       background-color: rgba(0, 171, 137, 0.1);
-       border-color: rgba(0, 89, 70, 0.5);
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #005946;
-       border-color: #005946;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #005946;
-       border-color: #005946;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #d11d13;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
-       background-color: rgba(209, 29, 19, 0.1);
-       border-color: rgba(115, 16, 10, 0.5);
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #73100a;
-       border-color: #73100a;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #73100a;
-       border-color: #73100a;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #347bff;
-       border-color: #347bff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
-       background: #2962cc;
-       border-color: #2962cc;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #347bff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #1f4999;
-       border-color: #1f4999;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #00af89;
-       border-color: #00af89;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
-       background: #008064;
-       border-color: #008064;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #00af89;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #005946;
-       border-color: #005946;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #d11d13;
-       border-color: #d11d13;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
-       background: #8c130d;
-       border-color: #8c130d;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #ffffff;
-       border-color: #d11d13;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       color: #ffffff;
-       background-color: #73100a;
-       border-color: #73100a;
-       box-shadow: none;
-}
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #999999;
-       color: #ffffff;
-}
-.oo-ui-clippableElement-clippable {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-draggableElement {
-       cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
-}
-.oo-ui-draggableElement-dragging {
-       cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
-       background: rgba(0, 0, 0, 0.2);
-       opacity: 0.4;
-}
-.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
-       display: inline-block;
-}
-.oo-ui-draggableGroupElement-placeholder {
-       position: absolute;
-       display: block;
-       background: rgba(0, 0, 0, 0.4);
-}
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
-}
-.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-       overflow-y: hidden;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-       padding: 2em;
-}
-.oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 3em;
-       overflow-y: auto;
-}
-.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-}
-.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
-}
-.oo-ui-bookletLayout-outlinePanel {
-       border-right: 1px solid #dddddd;
-}
-.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 3em;
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 3em;
-}
-.oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 2.75em;
-}
-.oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 2.75em;
-}
-.oo-ui-fieldLayout {
-       display: block;
-       margin-bottom: 1em;
-}
-.oo-ui-fieldLayout:before,
-.oo-ui-fieldLayout:after {
-       content: " ";
-       display: table;
-}
-.oo-ui-fieldLayout:after {
-       clear: both;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: block;
-       float: left;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       text-align: right;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       display: table;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       display: inline-block;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
-       float: right;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
-}
-.oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5em;
-}
-.oo-ui-fieldLayout:last-child {
-       margin-bottom: 0;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.5em;
-       margin-right: 5%;
-       width: 35%;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 60%;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-       margin-bottom: 1.25em;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 1em;
-}
-.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.25em;
-       padding-bottom: 0.5em;
-}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
-}
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       color: #cccccc;
-}
-.oo-ui-fieldLayout-messages {
-       list-style: none none;
-       margin: 0.25em 0 0 0.25em;
-       padding: 0;
-}
-.oo-ui-fieldLayout-messages > li {
-       margin: 0;
-       padding: 0;
-       display: table;
-}
-.oo-ui-fieldLayout-messages .oo-ui-iconWidget {
-       display: table-cell;
-       border-right: 0.5em solid transparent;
-}
-.oo-ui-fieldLayout-messages .oo-ui-labelWidget {
-       display: table-cell;
-       padding: 0;
-       line-height: 1.875em;
-       vertical-align: middle;
-}
-.oo-ui-actionFieldLayout-input,
-.oo-ui-actionFieldLayout-button {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-actionFieldLayout-input {
-       padding-right: 1em;
-}
-.oo-ui-actionFieldLayout-button {
-       width: 1%;
-       white-space: nowrap;
-}
-.oo-ui-fieldsetLayout {
-       position: relative;
-       margin: 0;
-       padding: 0;
-       border: 0;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       display: block;
-       position: absolute;
-}
-.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: inline-block;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
-       float: right;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
-}
-.oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5em;
-}
-.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
-.oo-ui-fieldsetLayout + .oo-ui-formLayout {
-       margin-top: 2em;
-}
-.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
-       font-size: 1.1em;
-       margin-bottom: 0.5em;
-       padding: 0.25em 0;
-       font-weight: bold;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-       padding-left: 2em;
-       line-height: 1.8em;
-}
-.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0.25em;
-       width: 1.875em;
-       height: 1.875em;
-}
-.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
-}
-.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-formLayout + .oo-ui-fieldsetLayout,
-.oo-ui-formLayout + .oo-ui-formLayout {
-       margin-top: 2em;
-}
-.oo-ui-menuLayout {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-menuLayout-menu,
-.oo-ui-menuLayout-content {
-       position: absolute;
-       -webkit-transition: all 200ms ease;
-          -moz-transition: all 200ms ease;
-               transition: all 200ms ease;
-}
-.oo-ui-menuLayout-menu {
-       height: 18em;
-       width: 18em;
-}
-.oo-ui-menuLayout-content {
-       top: 18em;
-       left: 18em;
-       right: 18em;
-       bottom: 18em;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
-       width: 0 !important;
-       height: 0 !important;
-       overflow: hidden;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       left: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       left: 0;
-       top: 0;
-       right: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
-       right: 0 !important;
-       bottom: 0 !important;
-       left: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       top: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
-       bottom: 0 !important;
-       left: 0 !important;
-       top: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       right: 0;
-       bottom: 0;
-       left: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
-       left: 0 !important;
-       top: 0 !important;
-       right: 0 !important;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       bottom: 0;
-       left: 0;
-       top: 0;
-}
-.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
-}
-.oo-ui-panelLayout {
-       position: relative;
-}
-.oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
-}
-.oo-ui-panelLayout-expanded {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-}
-.oo-ui-panelLayout-padded {
-       padding: 1.25em;
-}
-.oo-ui-panelLayout-framed {
-       border: 1px solid #aaaaaa;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
-}
-.oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
-       margin: 1em 0;
-}
-.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-       display: block;
-       position: relative;
-}
-.oo-ui-horizontalLayout > .oo-ui-widget {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout {
-       display: inline-block;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout,
-.oo-ui-horizontalLayout > .oo-ui-widget {
-       margin-right: 0.5em;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout:last-child,
-.oo-ui-horizontalLayout > .oo-ui-widget:last-child {
-       margin-right: 0;
-}
-.oo-ui-horizontalLayout > .oo-ui-layout {
-       margin-bottom: 0;
-}
-.oo-ui-popupTool .oo-ui-popupWidget-popup,
-.oo-ui-popupTool .oo-ui-popupWidget-anchor {
-       z-index: 4;
-}
-.oo-ui-popupTool .oo-ui-popupWidget {
-       /* @noflip */
-       margin-left: 1.25em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
-       border: 0;
-       border-radius: 0;
-       margin: 0;
-}
-.oo-ui-toolGroupTool > .oo-ui-toolGroup {
-       border-right: none;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
-       height: 2.5em;
-       padding: 0.3125em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       height: 2.5em;
-       width: 1.875em;
-}
-.oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.1em;
-}
-.oo-ui-toolGroup {
-       display: inline-block;
-       vertical-align: middle;
-       border-radius: 0;
-       border-right: 1px solid #dddddd;
-}
-.oo-ui-toolGroup-empty {
-       display: none;
-}
-.oo-ui-toolGroup .oo-ui-tool-link {
-       text-decoration: none;
-}
-.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
-       margin-left: 0;
-}
-.oo-ui-toolGroup .oo-ui-toolGroup .oo-ui-widget-enabled {
-       border-right: none !important;
-}
-.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
-.oo-ui-barToolGroup > .oo-ui-labelElement-label {
-       display: none;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       display: inline-block;
-       position: relative;
-       vertical-align: top;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       display: block;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
-       display: none;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: top;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
-       display: none;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
-       display: inline;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link {
-       outline: 0;
-       cursor: default;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       height: 1.875em;
-       padding: 0.625em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
-}
-.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2.1em;
-       padding: 0 0.4em;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-       background-color: #eeeeee;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-tool-title {
-       color: #555555;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.2);
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-       background-color: #e5e5e5;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled:hover {
-       background-color: #eeeeee;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-left-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.7;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.9;
-}
-.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:active {
-       background-color: #e7e7e7;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-popupToolGroup {
-       position: relative;
-       height: 3.125em;
-       min-width: 2em;
-}
-.oo-ui-popupToolGroup-handle {
-       display: block;
-       cursor: pointer;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       position: absolute;
-}
-.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-       outline: 0;
-       cursor: default;
-}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       display: none;
-       position: absolute;
-       z-index: 4;
-}
-.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-       display: block;
-}
-.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-       left: 0;
-}
-.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-       right: 0;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link {
-       display: table;
-       width: 100%;
-       vertical-align: middle;
-       white-space: nowrap;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       text-align: right;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not(:empty) {
-       padding-left: 3em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
-       min-width: 1.875em;
-}
-.oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 3.125em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 2.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 4.375em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 3.75em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.6em;
-       margin: 0 1em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin: 0 0.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 2.5em;
-}
-.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 1.75em;
-}
-.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:hover {
-       background-color: #eeeeee;
-}
-.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:active {
-       background-color: #e5e5e5;
-}
-.oo-ui-popupToolGroup-handle {
-       padding: 0.3125em;
-       height: 2.5em;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 1.625em;
-       margin: 0.78125em 0.5em;
-       top: 0;
-       right: 0;
-       opacity: 0.3;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       right: -0.3125em;
-}
-.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 2.6em;
-       margin: 0.25em;
-       top: 0;
-       left: 0.3125em;
-       opacity: 0.7;
-}
-.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-popupToolGroup-header {
-       line-height: 2.6em;
-       margin: 0 0.6em;
-       font-weight: bold;
-}
-.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
-       border-bottom-left-radius: 0;
-       border-bottom-right-radius: 0;
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-       background-color: #eeeeee;
-}
-.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       top: 3.125em;
-       margin: 0 -1px;
-       border: 1px solid #cccccc;
-       background-color: #ffffff;
-       box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
-       min-width: 16em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link {
-       padding: 0.4em 0.625em;
-       box-sizing: border-box;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 2.5em;
-       width: 1.875em;
-       min-width: 1.875em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       padding-left: 0.5em;
-       color: #555555;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2em;
-}
-.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #888888;
-}
-.oo-ui-listToolGroup .oo-ui-tool {
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-listToolGroup .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-       cursor: default;
-}
-.oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
-       border-color: rgba(0, 0, 0, 0.2);
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-       background-color: #eeeeee;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:active {
-       background-color: #e7e7e7;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.9;
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.1);
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-       background-color: #e5e5e5;
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-top-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
-       background-color: #eeeeee;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #dddddd;
-}
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-listToolGroup.oo-ui-widget-disabled {
-       color: #cccccc;
-}
-.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
-.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-menuToolGroup .oo-ui-tool {
-       display: block;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-link {
-       cursor: pointer;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-       cursor: default;
-}
-.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 10em;
-}
-.oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 8.125em;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: none;
-}
-.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: url("themes/mediawiki/images/icons/check.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check.png");
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: #eeeeee;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #cccccc;
-}
-.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-menuToolGroup.oo-ui-widget-disabled {
-       color: #cccccc;
-}
-.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
-.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
-}
-.oo-ui-toolbar {
-       clear: both;
-}
-.oo-ui-toolbar-bar {
-       line-height: 1em;
-       position: relative;
-}
-.oo-ui-toolbar-actions {
-       float: right;
-}
-.oo-ui-toolbar-actions .oo-ui-toolbar {
-       display: inline-block;
-}
-.oo-ui-toolbar-tools {
-       display: inline;
-       white-space: nowrap;
-}
-.oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
-       white-space: normal;
-}
-.oo-ui-toolbar-tools .oo-ui-tool {
-       white-space: normal;
-}
-.oo-ui-toolbar-tools,
-.oo-ui-toolbar-actions,
-.oo-ui-toolbar-shadow {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-toolbar-actions .oo-ui-popupWidget {
-       -webkit-touch-callout: default;
-       -webkit-user-select: all;
-          -moz-user-select: all;
-           -ms-user-select: all;
-               user-select: all;
-}
-.oo-ui-toolbar-shadow {
-       background-position: left top;
-       background-repeat: repeat-x;
-       position: absolute;
-       width: 100%;
-       pointer-events: none;
-}
-.oo-ui-toolbar-bar {
-       border-bottom: 1px solid #cccccc;
-       background-color: #ffffff;
-       box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-       font-weight: 500;
-       color: #555555;
-}
-.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-       border: 0;
-       background: none;
-       box-shadow: none;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement {
-       margin: 0;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
-       border: 0;
-       border-radius: 0;
-       margin: 0;
-       padding: 0 0.3125em;
-}
-.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin: 0 1em;
-       line-height: 3.125em;
-}
-.oo-ui-optionWidget {
-       position: relative;
-       display: block;
-       padding: 0.25em 0.5em;
-       border: 0;
-}
-.oo-ui-optionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
-}
-.oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
-}
-.oo-ui-optionWidget-highlighted {
-       background-color: #eeeeee;
-}
-.oo-ui-optionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
-}
-.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
-.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-       background-color: #d0d0d0;
-}
-.oo-ui-optionWidget.oo-ui-widget-disabled {
-       color: #cccccc;
-}
-.oo-ui-decoratedOptionWidget {
-       padding: 0.5em 2em 0.5em 3em;
-}
-.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-       position: absolute;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       top: 0;
-       height: 100%;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       width: 1.875em;
-       left: 0.5em;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       right: 0.5em;
-}
-.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-buttonSelectWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 2px;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonSelectWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 2px;
-       border-top-left-radius: 2px;
-       margin-left: 0;
-}
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 2px;
-       border-top-right-radius: 2px;
-}
-.oo-ui-buttonOptionWidget {
-       display: inline-block;
-       padding: 0;
-       background-color: transparent;
-}
-.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       position: relative;
-}
-.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       position: static;
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       margin-top: 0;
-}
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
-}
-.oo-ui-buttonOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
-.oo-ui-buttonOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 1;
-}
-.oo-ui-radioOptionWidget {
-       cursor: default;
-       padding: 0.25em 0;
-       background-color: transparent;
-}
-.oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
-.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
-.oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
-}
-.oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 1em;
-}
-.oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
-       margin-right: 0;
-}
-.oo-ui-labelWidget {
-       display: inline-block;
-}
-.oo-ui-iconWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
-       width: 1.875em;
-       height: 1.875em;
-}
-.oo-ui-iconWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
-}
-.oo-ui-indicatorWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.46875em;
-}
-.oo-ui-indicatorWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
-}
-.oo-ui-buttonWidget {
-       display: inline-block;
-       vertical-align: middle;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 2px;
-       margin-right: 0.5em;
-}
-.oo-ui-buttonGroupWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 2px;
-       border-top-left-radius: 2px;
-       margin-left: 0;
-}
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 2px;
-       border-top-right-radius: 2px;
-}
-.oo-ui-toggleButtonWidget {
-       display: inline-block;
-       vertical-align: middle;
-       margin-right: 0.5em;
-}
-.oo-ui-toggleButtonWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-toggleSwitchWidget {
-       position: relative;
-       display: inline-block;
-       vertical-align: middle;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       -webkit-transform: translateZ(0);
-          -moz-transform: translateZ(0);
-           -ms-transform: translateZ(0);
-               transform: translateZ(0);
-       height: 2em;
-       width: 3.5em;
-       border: 1px solid #777777;
-       border-radius: 1em;
-       background-color: #ffffff;
-       margin-right: 0.5em;
-       -webkit-transition: background-color 100ms ease, border-color 100ms ease;
-          -moz-transition: background-color 100ms ease, border-color 100ms ease;
-               transition: background-color 100ms ease, border-color 100ms ease;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
-       cursor: pointer;
-}
-.oo-ui-toggleSwitchWidget-grip {
-       position: absolute;
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       right: 0;
-       left: 0;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-       display: none;
-}
-.oo-ui-toggleSwitchWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-toggleSwitchWidget:before {
-       content: "";
-       display: block;
-       position: absolute;
-       top: 0;
-       left: 0;
-       bottom: 0;
-       right: 0;
-       border: 1px solid transparent;
-       border-radius: 1em;
-       z-index: 1;
-}
-.oo-ui-toggleSwitchWidget-grip {
-       top: 0.35em;
-       width: 1.2em;
-       height: 1.2em;
-       border-radius: 1.2em;
-       background-color: #555555;
-       -webkit-transition: left 100ms ease, margin-left 100ms ease;
-          -moz-transition: left 100ms ease, margin-left 100ms ease;
-               transition: left 100ms ease, margin-left 100ms ease;
-}
-.oo-ui-toggleSwitchWidget-glow {
-       display: none;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       left: 1.9em;
-       margin-left: -2px;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-       left: 0.4em;
-       margin-left: 0;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on {
-       background-color: #347bff;
-       border-color: #347bff;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       background-color: #ffffff;
-       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover {
-       border-color: #2962cc;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover.oo-ui-toggleWidget-on {
-       background-color: #2962cc;
-       border-color: #2962cc;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus {
-       border-color: #347bff;
-       outline: none;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on {
-       border-color: #347bff;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on:before {
-       border-color: #ffffff;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active,
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover {
-       background-color: #347bff;
-       border-color: #347bff;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active .oo-ui-toggleSwitchWidget-grip,
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover .oo-ui-toggleSwitchWidget-grip {
-       background-color: #ffffff;
-       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-       background: #dddddd;
-       border-color: #dddddd;
-       outline: 0;
-}
-.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled .oo-ui-toggleSwitchWidget-grip {
-       background: #ffffff;
-}
-.oo-ui-progressBarWidget {
-       max-width: 50em;
-       background-color: #ffffff;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-       overflow: hidden;
-}
-.oo-ui-progressBarWidget-bar {
-       height: 1em;
-       background: #dddddd;
-       -webkit-transition: width 200ms, margin-left 200ms;
-          -moz-transition: width 200ms, margin-left 200ms;
-               transition: width 200ms, margin-left 200ms;
-}
-.oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
-       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-       width: 40%;
-       margin-left: -10%;
-       border-left-width: 1px;
-}
-.oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.6;
-}
-.oo-ui-popupWidget {
-       position: absolute;
-       /* @noflip */
-       left: 0;
-}
-.oo-ui-popupWidget-popup {
-       position: relative;
-       overflow: hidden;
-       z-index: 1;
-}
-.oo-ui-popupWidget-anchor {
-       display: none;
-       z-index: 1;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-       display: block;
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-       background-repeat: no-repeat;
-}
-.oo-ui-popupWidget-head {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       float: right;
-}
-.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       float: left;
-       cursor: default;
-}
-.oo-ui-popupWidget-body {
-       clear: both;
-       overflow: hidden;
-}
-.oo-ui-popupWidget-popup {
-       background-color: #ffffff;
-       border: 1px solid #aaaaaa;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-       margin-top: 9px;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       content: "";
-       position: absolute;
-       width: 0;
-       height: 0;
-       border-style: solid;
-       border-color: transparent;
-       border-top: 0;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
-       bottom: -10px;
-       left: -9px;
-       border-bottom-color: #888888;
-       border-width: 10px;
-}
-.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       bottom: -10px;
-       left: -8px;
-       border-bottom-color: #ffffff;
-       border-width: 9px;
-}
-.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
-       -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-          -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-               transition: width 100ms ease, height 100ms ease, left 100ms ease;
-}
-.oo-ui-popupWidget-head {
-       height: 2.5em;
-}
-.oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       margin: 0.25em;
-}
-.oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       margin: 0.75em 1em;
-}
-.oo-ui-popupWidget-body-padded {
-       padding: 0 1em;
-}
-.oo-ui-popupButtonWidget {
-       position: relative;
-}
-.oo-ui-popupButtonWidget .oo-ui-popupWidget {
-       position: absolute;
-       cursor: auto;
-}
-.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1em;
-}
-.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1.75em;
-}
-.oo-ui-inputWidget {
-       margin-right: 0.5em;
-}
-.oo-ui-inputWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-buttonInputWidget {
-       display: inline-block;
-       vertical-align: middle;
-}
-.oo-ui-buttonInputWidget > button,
-.oo-ui-buttonInputWidget > input {
-       border: 0;
-       padding: 0;
-       background-color: transparent;
-}
-.oo-ui-checkboxInputWidget {
-       position: relative;
-       line-height: 1.6em;
-       white-space: nowrap;
-}
-.oo-ui-checkboxInputWidget * {
-       font: inherit;
-       vertical-align: middle;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"] {
-       opacity: 0;
-       z-index: 1;
-       position: relative;
-       cursor: pointer;
-       margin: 0;
-       width: 1.6em;
-       height: 1.6em;
-       max-width: none;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"] + span {
-       -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-          -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-               transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       position: absolute;
-       left: 0;
-       border-radius: 2px;
-       width: 1.6em;
-       height: 1.6em;
-       background-color: white;
-       border: 1px solid #777777;
-       background-image: url("themes/mediawiki/images/icons/check-constructive.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-constructive.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-constructive.png");
-       background-repeat: no-repeat;
-       background-position: center center;
-       background-origin: border-box;
-       background-size: 0 0;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:checked + span {
-       background-size: 100% 100%;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:active + span {
-       background-color: #cccccc;
-       border-color: #cccccc;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:focus + span {
-       border-width: 2px;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:focus:hover + span,
-.oo-ui-checkboxInputWidget input[type="checkbox"]:hover + span {
-       border-bottom-width: 3px;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled {
-       cursor: default;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled + span {
-       background-color: #dddddd;
-       border-color: #dddddd;
-}
-.oo-ui-checkboxInputWidget input[type="checkbox"]:disabled:checked + span {
-       background-image: url("themes/mediawiki/images/icons/check-invert.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check-invert.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check-invert.png");
-}
-.oo-ui-dropdownInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-dropdownInputWidget select {
-       display: inline-block;
-       width: 100%;
-       resize: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dropdownInputWidget select {
-       background-color: #ffffff;
-       height: 2.275em;
-       font-size: inherit;
-       font-family: inherit;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-       padding-left: 1em;
-       vertical-align: middle;
-}
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
-.oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
-       border-color: #aaaaaa;
-       outline: none;
-}
-.oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
-       color: #cccccc;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-radioInputWidget {
-       position: relative;
-       line-height: 1.6em;
-       white-space: nowrap;
-}
-.oo-ui-radioInputWidget * {
-       font: inherit;
-       vertical-align: middle;
-}
-.oo-ui-radioInputWidget input[type="radio"] {
-       opacity: 0;
-       z-index: 1;
-       position: relative;
-       cursor: pointer;
-       margin: 0;
-       width: 1.6em;
-       height: 1.6em;
-       max-width: none;
-}
-.oo-ui-radioInputWidget input[type="radio"] + span {
-       -webkit-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-          -moz-transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-               transition: background-size 200ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       position: absolute;
-       left: 0;
-       border-radius: 100%;
-       width: 1.6em;
-       height: 1.6em;
-       background: white;
-       border: 1px solid #777777;
-       background-image: url("themes/mediawiki/images/icons/circle-constructive.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-constructive.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-constructive.png");
-       background-repeat: no-repeat;
-       background-position: center center;
-       background-origin: border-box;
-       background-size: 0 0;
-}
-.oo-ui-radioInputWidget input[type="radio"]:checked + span {
-       background-size: 100% 100%;
-}
-.oo-ui-radioInputWidget input[type="radio"]:active + span {
-       background-color: #cccccc;
-       border-color: #cccccc;
-}
-.oo-ui-radioInputWidget input[type="radio"]:focus + span {
-       border-width: 2px;
-}
-.oo-ui-radioInputWidget input[type="radio"]:focus:hover + span,
-.oo-ui-radioInputWidget input[type="radio"]:hover + span {
-       border-bottom-width: 3px;
-}
-.oo-ui-radioInputWidget input[type="radio"]:disabled {
-       cursor: default;
-}
-.oo-ui-radioInputWidget input[type="radio"]:disabled + span {
-       background-color: #dddddd;
-       border-color: #dddddd;
-}
-.oo-ui-radioInputWidget input[type="radio"]:disabled:checked + span {
-       background-image: url("themes/mediawiki/images/icons/circle-invert.png");
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/circle-invert.svg");
-       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/circle-invert.png");
-}
-.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
-}
-.oo-ui-textInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
-       display: inline-block;
-       width: 100%;
-       resize: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-textInputWidget textarea {
-       overflow: auto;
-}
-.oo-ui-textInputWidget input[type="search"] {
-       -webkit-appearance: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-ms-clear {
-       display: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-ms-reveal {
-       display: none;
-}
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-decoration,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-cancel-button,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-button,
-.oo-ui-textInputWidget input[type="search"]::-webkit-search-results-decoration {
-       display: none;
-}
-.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       display: none;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       display: block;
-       position: absolute;
-       top: 0;
-       height: 100%;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: text;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
-}
-.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: block;
-}
-.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       position: absolute;
-       top: 0;
-}
-.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
-       right: 0;
-}
-.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
-       left: 0;
-}
-.oo-ui-textInputWidget input,
-.oo-ui-textInputWidget textarea {
-       padding: 0.5em;
-       line-height: 1.275em;
-       margin: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: #ffffff;
-       color: #000000;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
-.oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
-       background-color: transparent;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
-       box-shadow: inset 0 0 0 0.1em #ffffff;
-       -webkit-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-          -moz-transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-               transition: border 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-       outline: none;
-       border-color: #347bff;
-       box-shadow: inset 0 0 0 0.1em #347bff;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-       color: #777777;
-       text-shadow: 0 1px 1px #ffffff;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:focus {
-       border-color: #cccccc;
-       box-shadow: inset 0 0 0 0.1em #cccccc;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-       border-color: #ff0000;
-}
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
-.oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
-       border-color: #ff0000;
-       box-shadow: inset 0 0 0 0.1em #ff0000;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled input,
-.oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       color: #dddddd;
-       text-shadow: 0 1px 1px #ffffff;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement input,
-.oo-ui-textInputWidget.oo-ui-iconElement textarea {
-       padding-left: 2.875em;
-}
-.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       left: 0;
-       width: 1.875em;
-       max-height: 2.375em;
-       margin-left: 0.5em;
-       height: 100%;
-       background-position: right center;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement input,
-.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-       padding-right: 2.4875em;
-}
-.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       max-height: 2.375em;
-       margin: 0 0.775em;
-       height: 100%;
-}
-.oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       padding: 0.4em;
-       line-height: 1.5em;
-       color: #888888;
-}
-.oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       margin-right: 2.0875em;
-}
-.oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-       margin-left: 2.475em;
-}
-.oo-ui-menuSelectWidget {
-       position: absolute;
-       background-color: #ffffff;
-       margin-top: -1px;
-       border: 1px solid #aaaaaa;
-       border-radius: 0 0 2px 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
-}
-.oo-ui-menuSelectWidget input {
-       position: absolute;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       opacity: 0;
-}
-.oo-ui-menuOptionWidget {
-       position: relative;
-       padding: 0.5em 1em;
-}
-.oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
-       display: none;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: transparent;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: block;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #d8e6fe;
-       color: rgba(0, 0, 0, 0.8);
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: none;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: #eeeeee;
-       color: #000000;
-}
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: #d8e6fe;
-}
-.oo-ui-menuSectionOptionWidget {
-       cursor: default;
-       padding: 0.33em 0.75em;
-       color: #888888;
-}
-.oo-ui-dropdownWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       background-color: #ffffff;
-       margin-right: 0.5em;
-}
-.oo-ui-dropdownWidget-handle {
-       width: 100%;
-       display: inline-block;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       position: absolute;
-}
-.oo-ui-dropdownWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
-       cursor: pointer;
-}
-.oo-ui-dropdownWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-dropdownWidget-handle {
-       padding: 0.5em 0;
-       height: 2.275em;
-       line-height: 1.275;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       left: 0.25em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       line-height: 1.275em;
-       margin: 0 1em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       top: 0;
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.775em;
-}
-.oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       top: 0;
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3em;
-}
-.oo-ui-dropdownWidget:hover .oo-ui-dropdownWidget-handle {
-       border-color: #aaaaaa;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
-       outline: 0;
-}
-.oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
-}
-.oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
-}
-.oo-ui-dropdownWidget .oo-ui-selectWidget {
-       border-top-color: #ffffff;
-}
-.oo-ui-selectFileWidget {
-       display: inline-block;
-       vertical-align: middle;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
-}
-.oo-ui-selectFileWidget-selectButton {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       position: relative;
-       overflow: hidden;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > input[type="file"] {
-       position: absolute;
-       margin: 0;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       width: 100%;
-       height: 100%;
-       opacity: 0;
-       z-index: 1;
-       cursor: pointer;
-       padding-top: 100px;
-}
-.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > input[type="file"] {
-       display: none;
-}
-.oo-ui-selectFileWidget-info {
-       width: 100%;
-       display: table-cell;
-       vertical-align: middle;
-       position: relative;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       text-overflow: ellipsis;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
-       float: left;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
-       float: right;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       position: absolute;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       z-index: 2;
-}
-.oo-ui-selectFileWidget-dropTarget {
-       cursor: default;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget {
-       cursor: pointer;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
-       display: none;
-}
-.oo-ui-selectFileWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       margin-left: 0.5em;
-}
-.oo-ui-selectFileWidget-info {
-       height: 2.4em;
-       background-color: #ffffff;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       right: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       left: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
-       line-height: 2.3em;
-       margin: 0;
-       overflow: hidden;
-       white-space: nowrap;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       text-overflow: ellipsis;
-       left: 0.5em;
-       right: 0.5em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
-       color: #888888;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
-       top: 0;
-       width: 1.875em;
-       margin-right: 0;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       height: 2.3em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       top: 0;
-       width: 0.9375em;
-       height: 2.3em;
-       margin-right: 0.775em;
-}
-.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       top: 0;
-       width: 1.875em;
-       height: 2.3em;
-       margin-left: 0.5em;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-       color: #cccccc;
-}
-.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       left: 2.875em;
-}
-.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 2.375em;
-}
-.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
-       right: 0;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 4.4625em;
-}
-.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
-       right: 2.0875em;
-}
-.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 0.5em;
-}
-.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
-.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
-       right: 2em;
-}
-.oo-ui-selectFileWidget-dropTarget {
-       line-height: 3.5em;
-       background-color: #ffffff;
-       border: 1px dashed #cccccc;
-       padding: 0.5em 1em;
-       margin-bottom: 0.5em;
-       text-align: center;
-       vertical-align: middle;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget:hover {
-       background-color: #eeeeee;
-}
-.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop .oo-ui-selectFileWidget-dropTarget {
-       background: rgba(52, 123, 255, 0.1);
-}
-.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
-.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-outlineOptionWidget {
-       position: relative;
-       cursor: pointer;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       font-size: 1.1em;
-       padding: 0.75em;
-}
-.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
-}
-.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget-level-0 {
-       padding-left: 3.5em;
-}
-.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
-       left: 1em;
-}
-.oo-ui-outlineOptionWidget-level-1 {
-       padding-left: 5em;
-}
-.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
-       left: 2.5em;
-}
-.oo-ui-outlineOptionWidget-level-2 {
-       padding-left: 6.5em;
-}
-.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
-       left: 4em;
-}
-.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #d0d0d0;
-       text-shadow: 0 1px 1px #ffffff;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-       font-weight: bold;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
-       font-style: italic;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-       opacity: 0.5;
-}
-.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-       color: #777777;
-}
-.oo-ui-outlineControlsWidget {
-       height: 3em;
-       background-color: #ffffff;
-}
-.oo-ui-outlineControlsWidget-items,
-.oo-ui-outlineControlsWidget-movers {
-       float: left;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       float: left;
-       background-position: right center;
-}
-.oo-ui-outlineControlsWidget-items {
-       float: left;
-}
-.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-       float: left;
-}
-.oo-ui-outlineControlsWidget-movers {
-       float: right;
-}
-.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-       float: right;
-}
-.oo-ui-outlineControlsWidget-items,
-.oo-ui-outlineControlsWidget-movers {
-       height: 2em;
-       margin: 0.5em 0.5em 0.5em 0;
-       padding: 0;
-}
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       width: 1.5em;
-       height: 2em;
-       margin: 0.5em 0 0.5em 0.5em;
-       opacity: 0.2;
-}
-.oo-ui-tabSelectWidget {
-       text-align: left;
-       white-space: nowrap;
-       overflow: hidden;
-       background-color: #dddddd;
-}
-.oo-ui-tabOptionWidget {
-       display: inline-block;
-       vertical-align: bottom;
-       padding: 0.35em 1em;
-       margin: 0.5em 0 0 0.75em;
-       border: 1px solid transparent;
-       border-bottom: none;
-       border-top-left-radius: 2px;
-       border-top-right-radius: 2px;
-       color: #555555;
-       font-weight: bold;
-}
-.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
-       background-color: rgba(255, 255, 255, 0.3);
-}
-.oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
-       background-color: rgba(255, 255, 255, 0.8);
-}
-.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
-}
-.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
-}
-.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
-.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
-       background-color: #ffffff;
-       color: #333333;
-}
-.oo-ui-capsuleMultiSelectWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-}
-.oo-ui-capsuleMultiSelectWidget-handle {
-       width: 100%;
-       display: inline-block;
-       position: relative;
-}
-.oo-ui-capsuleMultiSelectWidget-content {
-       position: relative;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
-       display: none;
-}
-.oo-ui-capsuleMultiSelectWidget-group {
-       display: inline;
-}
-.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-capsuleMultiSelectWidget-handle {
-       background-color: #ffffff;
-       cursor: text;
-       min-height: 2.4em;
-       margin-right: 0.5em;
-       padding: 0.15em 0.25em;
-       border: 1px solid #cccccc;
-       border-radius: 2px;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-capsuleMultiSelectWidget-handle:last-child {
-       margin-right: 0;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
-       position: absolute;
-       background-position: center center;
-       background-repeat: no-repeat;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
-       border: 0;
-       line-height: 1.675em;
-       margin: 0 0 0 0.2em;
-       padding: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: transparent;
-       color: #000000;
-       vertical-align: middle;
-}
-.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
-       outline: none;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-right: 2.4875em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
-       right: 0;
-       top: 0;
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.775em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
-       padding-left: 2.475em;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0;
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3em;
-}
-.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle {
-       border-color: #aaaaaa;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-       cursor: default;
-}
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon,
-.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget {
-       border-top-color: #ffffff;
-}
-.oo-ui-capsuleItemWidget {
-       position: relative;
-       display: inline-block;
-       cursor: default;
-       white-space: nowrap;
-       width: auto;
-       max-width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       vertical-align: middle;
-       padding: 0 0.4em;
-       margin: 0.1em;
-       height: 1.7em;
-       line-height: 1.7em;
-       background-color: #eeeeee;
-       border: 1px solid #cccccc;
-       color: #555555;
-       border-radius: 2px;
-}
-.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon {
-       cursor: pointer;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon {
-       cursor: default;
-}
-.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       text-overflow: ellipsis;
-       overflow: hidden;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       padding-right: 1.3375em;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       position: absolute;
-       right: 0.4em;
-       top: 0;
-       width: 0.9375em;
-       height: 100%;
-       background-repeat: no-repeat;
-}
-.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicator-clear {
-       cursor: pointer;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
-       color: #cccccc;
-       text-shadow: 0 1px 1px #ffffff;
-       border-color: #dddddd;
-       background-color: #f3f3f3;
-}
-.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
-}
-.oo-ui-comboBoxInputWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
-}
-.oo-ui-comboBoxInputWidget > .oo-ui-menuSelectWidget {
-       z-index: 1;
-       width: 100%;
-}
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
-}
-.oo-ui-comboBoxInputWidget-php input::-webkit-calendar-picker-indicator {
-       opacity: 0 !important;
-       position: absolute;
-       right: 0;
-       top: 0;
-       height: 2.5em;
-       width: 2.5em;
-       padding: 0;
-}
-.oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
-       pointer-events: none;
-}
-.oo-ui-comboBoxInputWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-comboBoxInputWidget input,
-.oo-ui-comboBoxInputWidget textarea {
-       height: 2.35em;
-}
-.oo-ui-searchWidget-query {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       width: 100%;
-}
-.oo-ui-searchWidget-results {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       overflow-x: hidden;
-       overflow-y: auto;
-}
-.oo-ui-searchWidget-query {
-       height: 4em;
-       padding: 0 1em;
-       border-bottom: 1px solid #cccccc;
-}
-.oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       margin: 0.75em 0;
-}
-.oo-ui-searchWidget-results {
-       top: 4em;
-       padding: 1em;
-       line-height: 0;
-}
-.oo-ui-numberInputWidget {
-       display: inline-block;
-       position: relative;
-       max-width: 50em;
-}
-.oo-ui-numberInputWidget-field {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
-       display: table-cell;
-       vertical-align: middle;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
-       width: 100%;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
-       white-space: nowrap;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
-       width: 2.5em;
-}
-.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       border-top-right-radius: 0;
-       border-bottom-right-radius: 0;
-       border-right-width: 0;
-}
-.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       border-top-left-radius: 0;
-       border-bottom-left-radius: 0;
-       border-left-width: 0;
-}
-.oo-ui-numberInputWidget .oo-ui-textInputWidget input {
-       border-radius: 0;
-}
-.oo-ui-window {
-       background: transparent;
-}
-.oo-ui-window-frame {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-window-content:focus {
-       outline: none;
-}
-.oo-ui-window-head,
-.oo-ui-window-foot {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-}
-.oo-ui-window-body {
-       margin: 0;
-       padding: 0;
-       background: none;
-}
-.oo-ui-window-overlay {
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-head,
-.oo-ui-dialog-content > .oo-ui-window-body,
-.oo-ui-dialog-content > .oo-ui-window-foot {
-       position: absolute;
-       left: 0;
-       right: 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-}
-.oo-ui-dialog-content > .oo-ui-window-head {
-       overflow: hidden;
-       z-index: 1;
-       top: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-body {
-       overflow: auto;
-       z-index: 2;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-foot {
-       overflow: hidden;
-       z-index: 1;
-       bottom: 0;
-}
-.oo-ui-dialog-content > .oo-ui-window-body {
-       outline: 1px solid #aaaaaa;
-}
-.oo-ui-messageDialog-actions-horizontal {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       display: table-cell;
-       width: 1%;
-}
-.oo-ui-messageDialog-actions-vertical {
-       display: block;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       display: block;
-       overflow: hidden;
-       text-overflow: ellipsis;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       position: relative;
-       text-align: center;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       display: block;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-       position: relative;
-       top: auto;
-       bottom: auto;
-       display: inline;
-       white-space: nowrap;
-}
-.oo-ui-messageDialog-title,
-.oo-ui-messageDialog-message {
-       display: block;
-       text-align: center;
-}
-.oo-ui-messageDialog-title.oo-ui-labelElement,
-.oo-ui-messageDialog-message.oo-ui-labelElement {
-       padding-top: 0.5em;
-}
-.oo-ui-messageDialog-title {
-       font-size: 1.5em;
-       line-height: 1em;
-       color: #000000;
-}
-.oo-ui-messageDialog-message {
-       font-size: 0.9em;
-       line-height: 1.25em;
-       color: #555555;
-}
-.oo-ui-messageDialog-message-verbose {
-       font-size: 1.1em;
-       line-height: 1.5em;
-       text-align: left;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       border-right: 1px solid #e5e5e5;
-       margin: 0;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-       border-right-width: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       border-bottom: 1px solid #e5e5e5;
-       margin: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-       border-bottom-width: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       height: 3.4em;
-       margin-right: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
-       margin-right: 0;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       text-align: center;
-       line-height: 3.4em;
-       padding: 0 2em;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
-}
-.oo-ui-processDialog-location {
-       overflow: hidden;
-       text-overflow: ellipsis;
-       white-space: nowrap;
-}
-.oo-ui-processDialog-title {
-       display: inline;
-       padding: 0;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-       white-space: nowrap;
-}
-.oo-ui-processDialog-actions-safe,
-.oo-ui-processDialog-actions-primary {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-processDialog-actions-safe {
-       left: 0;
-}
-.oo-ui-processDialog-actions-primary {
-       right: 0;
-}
-.oo-ui-processDialog-errors {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       z-index: 2;
-       overflow-x: hidden;
-       overflow-y: auto;
-}
-.oo-ui-processDialog-content .oo-ui-window-head {
-       height: 3.4em;
-}
-.oo-ui-processDialog-content .oo-ui-window-body {
-       top: 3.4em;
-       outline: 1px solid rgba(0, 0, 0, 0.2);
-}
-.oo-ui-processDialog-navigation {
-       position: relative;
-       height: 3.4em;
-       padding: 0 1em;
-}
-.oo-ui-processDialog-location {
-       padding: 0.75em 0;
-       height: 1.875em;
-       cursor: default;
-       text-align: center;
-}
-.oo-ui-processDialog-title {
-       font-weight: bold;
-       line-height: 1.875em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-       margin: 0.5em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
-       margin: 0;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
-       padding: 0.75em 1em;
-       vertical-align: middle;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label {
-       line-height: 1.875em;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover {
-       background-color: rgba(0, 0, 0, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
-}
-.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
-       margin-right: 0;
-}
-.oo-ui-processDialog > .oo-ui-window-frame {
-       min-height: 5em;
-}
-.oo-ui-processDialog-errors {
-       background-color: rgba(255, 255, 255, 0.9);
-       padding: 3em 3em 1.5em 3em;
-       text-align: center;
-}
-.oo-ui-processDialog-errors .oo-ui-buttonWidget {
-       margin: 2em 1em 2em 1em;
-}
-.oo-ui-processDialog-errors-title {
-       font-size: 1.5em;
-       color: #000000;
-       margin-bottom: 2em;
-}
-.oo-ui-processDialog-error {
-       text-align: left;
-       margin: 1em;
-       padding: 1em;
-       border: 1px solid #ff9e9e;
-       background-color: #fff7f7;
-       border-radius: 2px;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog {
-       position: fixed;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
-       width: auto;
-       height: auto;
-       top: 0;
-       right: 0;
-       bottom: 0;
-       left: 0;
-       padding: 1em;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-       position: absolute;
-       right: 0;
-       left: 0;
-       margin: auto;
-       overflow: hidden;
-       max-width: 100%;
-       max-height: 100%;
-}
-.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-       width: 100%;
-       height: 100%;
-       top: 0;
-       bottom: 0;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog {
-       background-color: rgba(255, 255, 255, 0.5);
-       opacity: 0;
-       -webkit-transition: opacity 250ms ease;
-          -moz-transition: opacity 250ms ease;
-               transition: opacity 250ms ease;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       background-color: #ffffff;
-       opacity: 0;
-       -webkit-transform: scale(0.5);
-          -moz-transform: scale(0.5);
-           -ms-transform: scale(0.5);
-               transform: scale(0.5);
-       -webkit-transition: all 250ms ease;
-          -moz-transition: all 250ms ease;
-               transition: all 250ms ease;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-       opacity: 1;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-       opacity: 1;
-       -webkit-transform: scale(1);
-          -moz-transform: scale(1);
-           -ms-transform: scale(1);
-               transform: scale(1);
-}
-.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-       top: 1em;
-       bottom: 1em;
-       border: 1px solid #aaaaaa;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
-}
index ea70fbb..e20b956 100644 (file)
@@ -1,13 +1,17 @@
 /*!
- * OOjs UI v0.15.1
+ * OOjs UI v0.15.2
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2016 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-01-26T21:14:23Z
+ * Date: 2016-02-02T22:07:00Z
  */
+( function ( OO ) {
+
+'use strict';
+
 /**
  * @class
  * @extends OO.ui.Theme
@@ -67,3 +71,5 @@ OO.ui.MediaWikiTheme.prototype.getElementClasses = function ( element ) {
 /* Instantiation */
 
 OO.ui.theme = new OO.ui.MediaWikiTheme();
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css b/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
new file mode 100644 (file)
index 0000000..f433b15
--- /dev/null
@@ -0,0 +1,555 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-ms-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-o-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-popupTool .oo-ui-popupWidget-popup,
+.oo-ui-popupTool .oo-ui-popupWidget-anchor {
+       z-index: 4;
+}
+.oo-ui-popupTool .oo-ui-popupWidget {
+       /* @noflip */
+       margin-left: 1.25em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
+       border: 0;
+       border-radius: 0;
+       margin: 0;
+}
+.oo-ui-toolGroupTool:first-child > .oo-ui-popupToolGroup {
+       border-top-left-radius: 0.3125em;
+       border-bottom-left-radius: 0.3125em;
+}
+.oo-ui-toolGroupTool:last-child > .oo-ui-popupToolGroup {
+       border-top-right-radius: 0.3125em;
+       border-bottom-right-radius: 0.3125em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
+       height: 1.875em;
+       padding: 0.3125em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       height: 1.875em;
+       width: 1.875em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       line-height: 2.1em;
+}
+.oo-ui-toolGroup {
+       display: inline-block;
+       vertical-align: middle;
+       margin: 0.375em;
+       border-radius: 0.3125em;
+       border: 1px solid transparent;
+       -webkit-transition: border-color 250ms ease;
+          -moz-transition: border-color 250ms ease;
+               transition: border-color 250ms ease;
+}
+.oo-ui-toolGroup-empty {
+       display: none;
+}
+.oo-ui-toolGroup .oo-ui-tool-link {
+       text-decoration: none;
+}
+.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
+       margin-left: 0;
+}
+.oo-ui-toolGroup.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
+       color: #000000;
+}
+.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
+.oo-ui-barToolGroup > .oo-ui-labelElement-label {
+       display: none;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
+       display: inline-block;
+       position: relative;
+       vertical-align: top;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       display: block;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
+       display: none;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       display: inline-block;
+       vertical-align: top;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
+       display: none;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
+       display: inline;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link {
+       outline: 0;
+       cursor: default;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
+       margin: -1px 0 -1px -1px;
+       border: 1px solid transparent;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:first-child {
+       border-top-left-radius: 0.3125em;
+       border-bottom-left-radius: 0.3125em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:last-child {
+       margin-right: -1px;
+       border-top-right-radius: 0.3125em;
+       border-bottom-right-radius: 0.3125em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       height: 1.875em;
+       padding: 0.3125em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       height: 1.875em;
+       width: 1.875em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
+       line-height: 2.1em;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled {
+       border-color: rgba(0, 0, 0, 0.2);
+       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+       background-color: #f8fbfd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:         linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-left-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link:focus {
+       outline: 0;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 1;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool:focus {
+       outline: 0;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link:focus {
+       outline: 0;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-popupToolGroup {
+       position: relative;
+       height: 2.5em;
+       min-width: 2.5em;
+}
+.oo-ui-popupToolGroup-handle {
+       display: block;
+       cursor: pointer;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       position: absolute;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
+       outline: 0;
+       cursor: default;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+       display: none;
+       position: absolute;
+       z-index: 4;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
+       display: block;
+}
+.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
+       left: 0;
+}
+.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
+       right: 0;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link {
+       display: table;
+       width: 100%;
+       vertical-align: middle;
+       white-space: nowrap;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
+       text-align: right;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not(:empty) {
+       padding-left: 3em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
+       min-width: 1.875em;
+}
+.oo-ui-popupToolGroup.oo-ui-iconElement {
+       min-width: 3.125em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
+       min-width: 2.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+       min-width: 4.375em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+       min-width: 3.75em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       line-height: 2.6em;
+       margin: 0 1em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin: 0 0.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-left: 3em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-left: 2.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-right: 2.25em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-right: 1.75em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.78125em;
+       top: 0;
+       right: 0;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+       right: -0.3125em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       width: 1.875em;
+       height: 1.875em;
+       margin: 0.3125em;
+       top: 0;
+       left: 0.3125em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-popupToolGroup-header {
+       line-height: 2.6em;
+       margin: 0 0.6em;
+       font-weight: bold;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
+       border-bottom-left-radius: 0;
+       border-bottom-right-radius: 0;
+       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+       background-color: #f8fbfd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:         linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+       top: 2.5em;
+       margin: 0 -1px;
+       border: 1px solid #cccccc;
+       background-color: white;
+       box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link {
+       padding: 0.3125em 0 0.3125em 0.3125em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+       height: 1.875em;
+       width: 1.875em;
+       min-width: 1.875em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       padding-left: 0.5em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       line-height: 2em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
+       color: #888888;
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+       cursor: default;
+}
+.oo-ui-listToolGroup .oo-ui-toolGroup-tools {
+       padding: 0.3125em;
+}
+.oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+       border: 1px solid transparent;
+       margin: -1px 0;
+       padding: 0 0.625em 0 0;
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-color: rgba(0, 0, 0, 0.1);
+       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+       background-color: #f8fbfd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #ffffff 100%);
+       background-image:         linear-gradient(to bottom, #f1f7fb 0, #ffffff 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-top-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 1;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
+       color: #dddddd;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled {
+       color: #cccccc;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-menuToolGroup {
+       border-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-menuToolGroup .oo-ui-tool {
+       display: block;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+       cursor: default;
+}
+.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+       min-width: 10em;
+}
+.oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+       min-width: 8.125em;
+}
+.oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
+       padding: 0.3125em 0 0.3125em 0;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-menuToolGroup.oo-ui-popupToolGroup-active {
+       border-color: rgba(0, 0, 0, 0.25);
+}
+.oo-ui-menuToolGroup .oo-ui-tool {
+       padding: 0 1.25em 0 0.3125em;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+       background-image: none;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
+       background-image: url("themes/apex/images/icons/check.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/apex/images/icons/check.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/apex/images/icons/check.png");
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+       background-color: #e1f3ff;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled {
+       color: #cccccc;
+       border-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-toolbar {
+       clear: both;
+}
+.oo-ui-toolbar-bar {
+       line-height: 1em;
+       position: relative;
+}
+.oo-ui-toolbar-actions {
+       float: right;
+}
+.oo-ui-toolbar-actions .oo-ui-toolbar {
+       display: inline-block;
+}
+.oo-ui-toolbar-tools {
+       display: inline;
+       white-space: nowrap;
+}
+.oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
+       white-space: normal;
+}
+.oo-ui-toolbar-tools .oo-ui-tool {
+       white-space: normal;
+}
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-toolbar-actions .oo-ui-popupWidget {
+       -webkit-touch-callout: default;
+       -webkit-user-select: all;
+          -moz-user-select: all;
+           -ms-user-select: all;
+               user-select: all;
+}
+.oo-ui-toolbar-shadow {
+       background-position: left top;
+       background-repeat: repeat-x;
+       position: absolute;
+       width: 100%;
+       pointer-events: none;
+}
+.oo-ui-toolbar-bar {
+       border-bottom: 1px solid #cccccc;
+       background-color: #f8fbfd;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #f1f7fb));
+       background-image: -webkit-linear-gradient(top, #ffffff 0, #f1f7fb 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0, #f1f7fb 100%);
+       background-image:         linear-gradient(to bottom, #ffffff 0, #f1f7fb 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#fff1f7fb' )";
+}
+.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
+       border: none;
+       background: none;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-framed,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-framed:last-child {
+       margin-top: 0.4em;
+       margin-bottom: 0.4em;
+       margin-right: 0.5em;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement {
+       margin: 0;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button {
+       margin: 0;
+       padding: 0 0.3125em;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
+.oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       margin: 0 1em;
+       line-height: 3.40625em;
+}
+.oo-ui-toolbar-shadow {
+       background-image: /* @embed */ url(themes/apex/images/toolbar-shadow.png);
+       bottom: -9px;
+       height: 9px;
+       opacity: 0.5;
+       -webkit-transition: opacity 500ms ease;
+          -moz-transition: opacity 500ms ease;
+               transition: opacity 500ms ease;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
new file mode 100644 (file)
index 0000000..1f4262c
--- /dev/null
@@ -0,0 +1,483 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-popupTool .oo-ui-popupWidget-popup,
+.oo-ui-popupTool .oo-ui-popupWidget-anchor {
+       z-index: 4;
+}
+.oo-ui-popupTool .oo-ui-popupWidget {
+       /* @noflip */
+       margin-left: 1.25em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
+       border: 0;
+       border-radius: 0;
+       margin: 0;
+}
+.oo-ui-toolGroupTool > .oo-ui-toolGroup {
+       border-right: none;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
+       height: 2.5em;
+       padding: 0.3125em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       height: 2.5em;
+       width: 1.875em;
+}
+.oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       line-height: 2.1em;
+}
+.oo-ui-toolGroup {
+       display: inline-block;
+       vertical-align: middle;
+       border-radius: 0;
+       border-right: 1px solid #dddddd;
+}
+.oo-ui-toolGroup-empty {
+       display: none;
+}
+.oo-ui-toolGroup .oo-ui-tool-link {
+       text-decoration: none;
+}
+.oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
+       margin-left: 0;
+}
+.oo-ui-toolGroup .oo-ui-toolGroup .oo-ui-widget-enabled {
+       border-right: none !important;
+}
+.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
+.oo-ui-barToolGroup > .oo-ui-labelElement-label {
+       display: none;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
+       display: inline-block;
+       position: relative;
+       vertical-align: top;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       display: block;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
+       display: none;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       display: inline-block;
+       vertical-align: top;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
+       display: none;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
+       display: inline;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link {
+       outline: 0;
+       cursor: default;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
+       height: 1.875em;
+       padding: 0.625em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       height: 1.875em;
+       width: 1.875em;
+}
+.oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
+       line-height: 2.1em;
+       padding: 0 0.4em;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+       background-color: #eeeeee;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-tool-title {
+       color: #555555;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled {
+       border-color: rgba(0, 0, 0, 0.2);
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background-color: #e5e5e5;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled:hover {
+       background-color: #eeeeee;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-left-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.7;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.9;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:active {
+       background-color: #e7e7e7;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > a.oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-popupToolGroup {
+       position: relative;
+       height: 3.125em;
+       min-width: 2em;
+}
+.oo-ui-popupToolGroup-handle {
+       display: block;
+       cursor: pointer;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       position: absolute;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
+       outline: 0;
+       cursor: default;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+       display: none;
+       position: absolute;
+       z-index: 4;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
+       display: block;
+}
+.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
+       left: 0;
+}
+.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
+       right: 0;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link {
+       display: table;
+       width: 100%;
+       vertical-align: middle;
+       white-space: nowrap;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
+       text-align: right;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not(:empty) {
+       padding-left: 3em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
+       min-width: 1.875em;
+}
+.oo-ui-popupToolGroup.oo-ui-iconElement {
+       min-width: 3.125em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
+       min-width: 2.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+       min-width: 4.375em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+       min-width: 3.75em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       line-height: 2.6em;
+       margin: 0 1em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin: 0 0.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-left: 3em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-left: 2.5em;
+}
+.oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-right: 2em;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+       margin-right: 1.75em;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:hover {
+       background-color: #eeeeee;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-enabled .oo-ui-popupToolGroup-handle:active {
+       background-color: #e5e5e5;
+}
+.oo-ui-popupToolGroup-handle {
+       padding: 0.3125em;
+       height: 2.5em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+       width: 0.9375em;
+       height: 1.625em;
+       margin: 0.78125em 0.5em;
+       top: 0;
+       right: 0;
+       opacity: 0.3;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+       right: -0.3125em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       width: 1.875em;
+       height: 2.6em;
+       margin: 0.25em;
+       top: 0;
+       left: 0.3125em;
+       opacity: 0.7;
+}
+.oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-popupToolGroup-header {
+       line-height: 2.6em;
+       margin: 0 0.6em;
+       font-weight: bold;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
+       border-bottom-left-radius: 0;
+       border-bottom-right-radius: 0;
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background-color: #eeeeee;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+       top: 3.125em;
+       margin: 0 -1px;
+       border: 1px solid #cccccc;
+       background-color: #ffffff;
+       box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
+       min-width: 16em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link {
+       padding: 0.4em 0.625em;
+       box-sizing: border-box;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+       height: 2.5em;
+       width: 1.875em;
+       min-width: 1.875em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       padding-left: 0.5em;
+       color: #555555;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+       line-height: 2em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
+       color: #888888;
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+       cursor: default;
+}
+.oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+       background-color: #eeeeee;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:active {
+       background-color: #e7e7e7;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.9;
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-color: rgba(0, 0, 0, 0.1);
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background-color: #e5e5e5;
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+       border-top-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
+       border-color: rgba(0, 0, 0, 0.2);
+       background-color: #eeeeee;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
+       color: #dddddd;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled {
+       color: #cccccc;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-menuToolGroup .oo-ui-tool {
+       display: block;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+       cursor: pointer;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+       cursor: default;
+}
+.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+       min-width: 10em;
+}
+.oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+       min-width: 8.125em;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+       background-image: none;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
+       background-image: url("themes/mediawiki/images/icons/check.png");
+       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
+       background-image:         linear-gradient(transparent, transparent), /* @embed */ url("themes/mediawiki/images/icons/check.svg");
+       background-image:      -o-linear-gradient(transparent, transparent), url("themes/mediawiki/images/icons/check.png");
+       background-size: contain;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+       background-color: #eeeeee;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+       color: #cccccc;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled {
+       color: #cccccc;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+       opacity: 0.2;
+}
+.oo-ui-toolbar {
+       clear: both;
+}
+.oo-ui-toolbar-bar {
+       line-height: 1em;
+       position: relative;
+}
+.oo-ui-toolbar-actions {
+       float: right;
+}
+.oo-ui-toolbar-actions .oo-ui-toolbar {
+       display: inline-block;
+}
+.oo-ui-toolbar-tools {
+       display: inline;
+       white-space: nowrap;
+}
+.oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
+       white-space: normal;
+}
+.oo-ui-toolbar-tools .oo-ui-tool {
+       white-space: normal;
+}
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-toolbar-actions .oo-ui-popupWidget {
+       -webkit-touch-callout: default;
+       -webkit-user-select: all;
+          -moz-user-select: all;
+           -ms-user-select: all;
+               user-select: all;
+}
+.oo-ui-toolbar-shadow {
+       background-position: left top;
+       background-repeat: repeat-x;
+       position: absolute;
+       width: 100%;
+       pointer-events: none;
+}
+.oo-ui-toolbar-bar {
+       border-bottom: 1px solid #cccccc;
+       background-color: #ffffff;
+       box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+       font-weight: 500;
+       color: #555555;
+}
+.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
+       border: 0;
+       background: none;
+       box-shadow: none;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement {
+       margin: 0;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
+       border: 0;
+       border-radius: 0;
+       margin: 0;
+       padding: 0 0.3125em;
+}
+.oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+       margin: 0 1em;
+       line-height: 3.125em;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars.js b/resources/lib/oojs-ui/oojs-ui-toolbars.js
new file mode 100644 (file)
index 0000000..a88984a
--- /dev/null
@@ -0,0 +1,2304 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:00Z
+ */
+( function ( OO ) {
+
+'use strict';
+
+/**
+ * Toolbars are complex interface components that permit users to easily access a variety
+ * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional commands that are
+ * part of the toolbar, but not configured as tools.
+ *
+ * Individual tools are customized and then registered with a {@link OO.ui.ToolFactory tool factory}, which creates
+ * the tools on demand. Each tool has a symbolic name (used when registering the tool), a title (e.g., ‘Insert
+ * image’), and an icon.
+ *
+ * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be {@link OO.ui.MenuToolGroup menus}
+ * of tools, {@link OO.ui.ListToolGroup lists} of tools, or a single {@link OO.ui.BarToolGroup bar} of tools.
+ * The arrangement and order of the toolgroups is customized when the toolbar is set up. Tools can be presented in
+ * any order, but each can only appear once in the toolbar.
+ *
+ * The toolbar can be synchronized with the state of the external "application", like a text
+ * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as
+ * active when the text cursor was inside bolded text) or enabled/disabled (e.g. a table caption
+ * tool would be disabled while the user is not editing a table). A state change is signalled by
+ * emitting the {@link #event-updateState 'updateState' event}, which calls Tools'
+ * {@link OO.ui.Tool#onUpdateState onUpdateState method}.
+ *
+ * The following is an example of a basic toolbar.
+ *
+ *     @example
+ *     // Example of a toolbar
+ *     // Create the toolbar
+ *     var toolFactory = new OO.ui.ToolFactory();
+ *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
+ *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
+ *
+ *     // We will be placing status text in this element when tools are used
+ *     var $area = $( '<p>' ).text( 'Toolbar example' );
+ *
+ *     // Define the tools that we're going to place in our toolbar
+ *
+ *     // Create a class inheriting from OO.ui.Tool
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
+ *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
+ *     // of 'icon' and 'title' (displayed icon and text).
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
+ *     // Defines the action that will happen when this tool is selected (clicked).
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
+ *         // Never display this tool as "active" (selected).
+ *         this.setActive( false );
+ *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
+ *     // Make this tool available in our toolFactory and thus our toolbar
+ *     toolFactory.register( SearchTool );
+ *
+ *     // Register two more tools, nothing interesting here
+ *     function SettingsTool() {
+ *         SettingsTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( SettingsTool, OO.ui.Tool );
+ *     SettingsTool.static.name = 'settings';
+ *     SettingsTool.static.icon = 'settings';
+ *     SettingsTool.static.title = 'Change settings';
+ *     SettingsTool.prototype.onSelect = function () {
+ *         $area.text( 'Settings tool clicked!' );
+ *         this.setActive( false );
+ *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( SettingsTool );
+ *
+ *     // Register two more tools, nothing interesting here
+ *     function StuffTool() {
+ *         StuffTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( StuffTool, OO.ui.Tool );
+ *     StuffTool.static.name = 'stuff';
+ *     StuffTool.static.icon = 'ellipsis';
+ *     StuffTool.static.title = 'More stuff';
+ *     StuffTool.prototype.onSelect = function () {
+ *         $area.text( 'More stuff tool clicked!' );
+ *         this.setActive( false );
+ *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( StuffTool );
+ *
+ *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
+ *     // little popup window (a PopupWidget).
+ *     function HelpTool( toolGroup, config ) {
+ *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
+ *             padded: true,
+ *             label: 'Help',
+ *             head: true
+ *         } }, config ) );
+ *         this.popup.$body.append( '<p>I am helpful!</p>' );
+ *     }
+ *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
+ *     HelpTool.static.name = 'help';
+ *     HelpTool.static.icon = 'help';
+ *     HelpTool.static.title = 'Help';
+ *     toolFactory.register( HelpTool );
+ *
+ *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
+ *     // used once (but not all defined tools must be used).
+ *     toolbar.setup( [
+ *         {
+ *             // 'bar' tool groups display tools' icons only, side-by-side.
+ *             type: 'bar',
+ *             include: [ 'search', 'help' ]
+ *         },
+ *         {
+ *             // 'list' tool groups display both the titles and icons, in a dropdown list.
+ *             type: 'list',
+ *             indicator: 'down',
+ *             label: 'More',
+ *             include: [ 'settings', 'stuff' ]
+ *         }
+ *         // Note how the tools themselves are toolgroup-agnostic - the same tool can be displayed
+ *         // either in a 'list' or a 'bar'. There is a 'menu' tool group too, not showcased here,
+ *         // since it's more complicated to use. (See the next example snippet on this page.)
+ *     ] );
+ *
+ *     // Create some UI around the toolbar and place it in the document
+ *     var frame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true
+ *     } );
+ *     var contentFrame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         padded: true
+ *     } );
+ *     frame.$element.append(
+ *         toolbar.$element,
+ *         contentFrame.$element.append( $area )
+ *     );
+ *     $( 'body' ).append( frame.$element );
+ *
+ *     // Here is where the toolbar is actually built. This must be done after inserting it into the
+ *     // document.
+ *     toolbar.initialize();
+ *     toolbar.emit( 'updateState' );
+ *
+ * The following example extends the previous one to illustrate 'menu' toolgroups and the usage of
+ * {@link #event-updateState 'updateState' event}.
+ *
+ *     @example
+ *     // Create the toolbar
+ *     var toolFactory = new OO.ui.ToolFactory();
+ *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
+ *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
+ *
+ *     // We will be placing status text in this element when tools are used
+ *     var $area = $( '<p>' ).text( 'Toolbar example' );
+ *
+ *     // Define the tools that we're going to place in our toolbar
+ *
+ *     // Create a class inheriting from OO.ui.Tool
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
+ *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
+ *     // of 'icon' and 'title' (displayed icon and text).
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
+ *     // Defines the action that will happen when this tool is selected (clicked).
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
+ *         // Never display this tool as "active" (selected).
+ *         this.setActive( false );
+ *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
+ *     // Make this tool available in our toolFactory and thus our toolbar
+ *     toolFactory.register( SearchTool );
+ *
+ *     // Register two more tools, nothing interesting here
+ *     function SettingsTool() {
+ *         SettingsTool.parent.apply( this, arguments );
+ *         this.reallyActive = false;
+ *     }
+ *     OO.inheritClass( SettingsTool, OO.ui.Tool );
+ *     SettingsTool.static.name = 'settings';
+ *     SettingsTool.static.icon = 'settings';
+ *     SettingsTool.static.title = 'Change settings';
+ *     SettingsTool.prototype.onSelect = function () {
+ *         $area.text( 'Settings tool clicked!' );
+ *         // Toggle the active state on each click
+ *         this.reallyActive = !this.reallyActive;
+ *         this.setActive( this.reallyActive );
+ *         // To update the menu label
+ *         this.toolbar.emit( 'updateState' );
+ *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( SettingsTool );
+ *
+ *     // Register two more tools, nothing interesting here
+ *     function StuffTool() {
+ *         StuffTool.parent.apply( this, arguments );
+ *         this.reallyActive = false;
+ *     }
+ *     OO.inheritClass( StuffTool, OO.ui.Tool );
+ *     StuffTool.static.name = 'stuff';
+ *     StuffTool.static.icon = 'ellipsis';
+ *     StuffTool.static.title = 'More stuff';
+ *     StuffTool.prototype.onSelect = function () {
+ *         $area.text( 'More stuff tool clicked!' );
+ *         // Toggle the active state on each click
+ *         this.reallyActive = !this.reallyActive;
+ *         this.setActive( this.reallyActive );
+ *         // To update the menu label
+ *         this.toolbar.emit( 'updateState' );
+ *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( StuffTool );
+ *
+ *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
+ *     // little popup window (a PopupWidget). 'onUpdateState' is also already implemented.
+ *     function HelpTool( toolGroup, config ) {
+ *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
+ *             padded: true,
+ *             label: 'Help',
+ *             head: true
+ *         } }, config ) );
+ *         this.popup.$body.append( '<p>I am helpful!</p>' );
+ *     }
+ *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
+ *     HelpTool.static.name = 'help';
+ *     HelpTool.static.icon = 'help';
+ *     HelpTool.static.title = 'Help';
+ *     toolFactory.register( HelpTool );
+ *
+ *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
+ *     // used once (but not all defined tools must be used).
+ *     toolbar.setup( [
+ *         {
+ *             // 'bar' tool groups display tools' icons only, side-by-side.
+ *             type: 'bar',
+ *             include: [ 'search', 'help' ]
+ *         },
+ *         {
+ *             // 'menu' tool groups display both the titles and icons, in a dropdown menu.
+ *             // Menu label indicates which items are selected.
+ *             type: 'menu',
+ *             indicator: 'down',
+ *             include: [ 'settings', 'stuff' ]
+ *         }
+ *     ] );
+ *
+ *     // Create some UI around the toolbar and place it in the document
+ *     var frame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true
+ *     } );
+ *     var contentFrame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         padded: true
+ *     } );
+ *     frame.$element.append(
+ *         toolbar.$element,
+ *         contentFrame.$element.append( $area )
+ *     );
+ *     $( 'body' ).append( frame.$element );
+ *
+ *     // Here is where the toolbar is actually built. This must be done after inserting it into the
+ *     // document.
+ *     toolbar.initialize();
+ *     toolbar.emit( 'updateState' );
+ *
+ * @class
+ * @extends OO.ui.Element
+ * @mixins OO.EventEmitter
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {OO.ui.ToolFactory} toolFactory Factory for creating tools
+ * @param {OO.ui.ToolGroupFactory} toolGroupFactory Factory for creating toolgroups
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are included
+ *  in the toolbar, but are not configured as tools. By default, actions are displayed on the right side of
+ *  the toolbar.
+ * @cfg {boolean} [shadow] Add a shadow below the toolbar.
+ */
+OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolFactory ) && config === undefined ) {
+               config = toolFactory;
+               toolFactory = config.toolFactory;
+               toolGroupFactory = config.toolGroupFactory;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Toolbar.parent.call( this, config );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+       OO.ui.mixin.GroupElement.call( this, config );
+
+       // Properties
+       this.toolFactory = toolFactory;
+       this.toolGroupFactory = toolGroupFactory;
+       this.groups = [];
+       this.tools = {};
+       this.$bar = $( '<div>' );
+       this.$actions = $( '<div>' );
+       this.initialized = false;
+       this.onWindowResizeHandler = this.onWindowResize.bind( this );
+
+       // Events
+       this.$element
+               .add( this.$bar ).add( this.$group ).add( this.$actions )
+               .on( 'mousedown keydown', this.onPointerDown.bind( this ) );
+
+       // Initialization
+       this.$group.addClass( 'oo-ui-toolbar-tools' );
+       if ( config.actions ) {
+               this.$bar.append( this.$actions.addClass( 'oo-ui-toolbar-actions' ) );
+       }
+       this.$bar
+               .addClass( 'oo-ui-toolbar-bar' )
+               .append( this.$group, '<div style="clear:both"></div>' );
+       if ( config.shadow ) {
+               this.$bar.append( '<div class="oo-ui-toolbar-shadow"></div>' );
+       }
+       this.$element.addClass( 'oo-ui-toolbar' ).append( this.$bar );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Toolbar, OO.ui.Element );
+OO.mixinClass( OO.ui.Toolbar, OO.EventEmitter );
+OO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );
+
+/* Events */
+
+/**
+ * @event updateState
+ *
+ * An 'updateState' event must be emitted on the Toolbar (by calling `toolbar.emit( 'updateState' )`)
+ * every time the state of the application using the toolbar changes, and an update to the state of
+ * tools is required.
+ *
+ * @param {Mixed...} data Application-defined parameters
+ */
+
+/* Methods */
+
+/**
+ * Get the tool factory.
+ *
+ * @return {OO.ui.ToolFactory} Tool factory
+ */
+OO.ui.Toolbar.prototype.getToolFactory = function () {
+       return this.toolFactory;
+};
+
+/**
+ * Get the toolgroup factory.
+ *
+ * @return {OO.Factory} Toolgroup factory
+ */
+OO.ui.Toolbar.prototype.getToolGroupFactory = function () {
+       return this.toolGroupFactory;
+};
+
+/**
+ * Handles mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ */
+OO.ui.Toolbar.prototype.onPointerDown = function ( e ) {
+       var $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),
+               $closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );
+       if ( !$closestWidgetToEvent.length || $closestWidgetToEvent[ 0 ] === $closestWidgetToToolbar[ 0 ] ) {
+               return false;
+       }
+};
+
+/**
+ * Handle window resize event.
+ *
+ * @private
+ * @param {jQuery.Event} e Window resize event
+ */
+OO.ui.Toolbar.prototype.onWindowResize = function () {
+       this.$element.toggleClass(
+               'oo-ui-toolbar-narrow',
+               this.$bar.width() <= this.narrowThreshold
+       );
+};
+
+/**
+ * Sets up handles and preloads required information for the toolbar to work.
+ * This must be called after it is attached to a visible document and before doing anything else.
+ */
+OO.ui.Toolbar.prototype.initialize = function () {
+       if ( !this.initialized ) {
+               this.initialized = true;
+               this.narrowThreshold = this.$group.width() + this.$actions.width();
+               $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );
+               this.onWindowResize();
+       }
+};
+
+/**
+ * Set up the toolbar.
+ *
+ * The toolbar is set up with a list of toolgroup configurations that specify the type of
+ * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or {@link OO.ui.ListToolGroup list})
+ * to add and which tools to include, exclude, promote, or demote within that toolgroup. Please
+ * see {@link OO.ui.ToolGroup toolgroups} for more information about including tools in toolgroups.
+ *
+ * @param {Object.<string,Array>} groups List of toolgroup configurations
+ * @param {Array|string} [groups.include] Tools to include in the toolgroup
+ * @param {Array|string} [groups.exclude] Tools to exclude from the toolgroup
+ * @param {Array|string} [groups.promote] Tools to promote to the beginning of the toolgroup
+ * @param {Array|string} [groups.demote] Tools to demote to the end of the toolgroup
+ */
+OO.ui.Toolbar.prototype.setup = function ( groups ) {
+       var i, len, type, group,
+               items = [],
+               defaultType = 'bar';
+
+       // Cleanup previous groups
+       this.reset();
+
+       // Build out new groups
+       for ( i = 0, len = groups.length; i < len; i++ ) {
+               group = groups[ i ];
+               if ( group.include === '*' ) {
+                       // Apply defaults to catch-all groups
+                       if ( group.type === undefined ) {
+                               group.type = 'list';
+                       }
+                       if ( group.label === undefined ) {
+                               group.label = OO.ui.msg( 'ooui-toolbar-more' );
+                       }
+               }
+               // Check type has been registered
+               type = this.getToolGroupFactory().lookup( group.type ) ? group.type : defaultType;
+               items.push(
+                       this.getToolGroupFactory().create( type, this, group )
+               );
+       }
+       this.addItems( items );
+};
+
+/**
+ * Remove all tools and toolgroups from the toolbar.
+ */
+OO.ui.Toolbar.prototype.reset = function () {
+       var i, len;
+
+       this.groups = [];
+       this.tools = {};
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               this.items[ i ].destroy();
+       }
+       this.clearItems();
+};
+
+/**
+ * Destroy the toolbar.
+ *
+ * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar. Call
+ * this method whenever you are done using a toolbar.
+ */
+OO.ui.Toolbar.prototype.destroy = function () {
+       $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
+       this.reset();
+       this.$element.remove();
+};
+
+/**
+ * Check if the tool is available.
+ *
+ * Available tools are ones that have not yet been added to the toolbar.
+ *
+ * @param {string} name Symbolic name of tool
+ * @return {boolean} Tool is available
+ */
+OO.ui.Toolbar.prototype.isToolAvailable = function ( name ) {
+       return !this.tools[ name ];
+};
+
+/**
+ * Prevent tool from being used again.
+ *
+ * @param {OO.ui.Tool} tool Tool to reserve
+ */
+OO.ui.Toolbar.prototype.reserveTool = function ( tool ) {
+       this.tools[ tool.getName() ] = tool;
+};
+
+/**
+ * Allow tool to be used again.
+ *
+ * @param {OO.ui.Tool} tool Tool to release
+ */
+OO.ui.Toolbar.prototype.releaseTool = function ( tool ) {
+       delete this.tools[ tool.getName() ];
+};
+
+/**
+ * Get accelerator label for tool.
+ *
+ * The OOjs UI library does not contain an accelerator system, but this is the hook for one. To
+ * use an accelerator system, subclass the toolbar and override this method, which is meant to return a label
+ * that describes the accelerator keys for the tool passed (by symbolic name) to the method.
+ *
+ * @param {string} name Symbolic name of tool
+ * @return {string|undefined} Tool accelerator label if available
+ */
+OO.ui.Toolbar.prototype.getToolAccelerator = function () {
+       return undefined;
+};
+
+/**
+ * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute {@link OO.ui.Toolbar toolbars}.
+ * Each tool is configured with a static name, title, and icon and is customized with the command to carry
+ * out when the tool is selected. Tools must also be registered with a {@link OO.ui.ToolFactory tool factory},
+ * which creates the tools on demand.
+ *
+ * Every Tool subclass must implement two methods:
+ *
+ * - {@link #onUpdateState}
+ * - {@link #onSelect}
+ *
+ * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},
+ * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which determine how
+ * the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an example.
+ *
+ * For more information, please see the [OOjs UI documentation on MediaWiki][1].
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {OO.ui.ToolGroup} toolGroup
+ * @param {Object} [config] Configuration options
+ * @cfg {string|Function} [title] Title text or a function that returns text. If this config is omitted, the value of
+ *  the {@link #static-title static title} property is used.
+ *
+ *  The title is used in different ways depending on the type of toolgroup that contains the tool. The
+ *  title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar} toolgroup, or as the label text if the tool is
+ *  part of a {@link OO.ui.ListToolGroup list} or {@link OO.ui.MenuToolGroup menu} toolgroup.
+ *
+ *  For bar toolgroups, a description of the accelerator key is appended to the title if an accelerator key
+ *  is associated with an action by the same name as the tool and accelerator functionality has been added to the application.
+ *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.
+ */
+OO.ui.Tool = function OoUiTool( toolGroup, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
+               config = toolGroup;
+               toolGroup = config.toolGroup;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Tool.parent.call( this, config );
+
+       // Properties
+       this.toolGroup = toolGroup;
+       this.toolbar = this.toolGroup.getToolbar();
+       this.active = false;
+       this.$title = $( '<span>' );
+       this.$accel = $( '<span>' );
+       this.$link = $( '<a>' );
+       this.title = null;
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$link } ) );
+
+       // Events
+       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
+
+       // Initialization
+       this.$title.addClass( 'oo-ui-tool-title' );
+       this.$accel
+               .addClass( 'oo-ui-tool-accel' )
+               .prop( {
+                       // This may need to be changed if the key names are ever localized,
+                       // but for now they are essentially written in English
+                       dir: 'ltr',
+                       lang: 'en'
+               } );
+       this.$link
+               .addClass( 'oo-ui-tool-link' )
+               .append( this.$icon, this.$title, this.$accel )
+               .attr( 'role', 'button' );
+       this.$element
+               .data( 'oo-ui-tool', this )
+               .addClass(
+                       'oo-ui-tool ' + 'oo-ui-tool-name-' +
+                       this.constructor.static.name.replace( /^([^\/]+)\/([^\/]+).*$/, '$1-$2' )
+               )
+               .toggleClass( 'oo-ui-tool-with-label', this.constructor.static.displayBothIconAndLabel )
+               .append( this.$link );
+       this.setTitle( config.title || this.constructor.static.title );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Tool, OO.ui.Widget );
+OO.mixinClass( OO.ui.Tool, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.Tool, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.Tool, OO.ui.mixin.TabIndexedElement );
+
+/* Static Properties */
+
+/**
+ * @static
+ * @inheritdoc
+ */
+OO.ui.Tool.static.tagName = 'span';
+
+/**
+ * Symbolic name of tool.
+ *
+ * The symbolic name is used internally to register the tool with a {@link OO.ui.ToolFactory ToolFactory}. It can
+ * also be used when adding tools to toolgroups.
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.Tool.static.name = '';
+
+/**
+ * Symbolic name of the group.
+ *
+ * The group name is used to associate tools with each other so that they can be selected later by
+ * a {@link OO.ui.ToolGroup toolgroup}.
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.Tool.static.group = '';
+
+/**
+ * Tool title text or a function that returns title text. The value of the static property is overridden if the #title config option is used.
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {string|Function}
+ */
+OO.ui.Tool.static.title = '';
+
+/**
+ * Display both icon and label when the tool is used in a {@link OO.ui.BarToolGroup bar} toolgroup.
+ * Normally only the icon is displayed, or only the label if no icon is given.
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.Tool.static.displayBothIconAndLabel = false;
+
+/**
+ * Add tool to catch-all groups automatically.
+ *
+ * A catch-all group, which contains all tools that do not currently belong to a toolgroup,
+ * can be included in a toolgroup using the wildcard selector, an asterisk (*).
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.Tool.static.autoAddToCatchall = true;
+
+/**
+ * Add tool to named groups automatically.
+ *
+ * By default, tools that are configured with a static ‘group’ property are added
+ * to that group and will be selected when the symbolic name of the group is specified (e.g., when
+ * toolgroups include tools by group name).
+ *
+ * @static
+ * @property {boolean}
+ * @inheritable
+ */
+OO.ui.Tool.static.autoAddToGroup = true;
+
+/**
+ * Check if this tool is compatible with given data.
+ *
+ * This is a stub that can be overridden to provide support for filtering tools based on an
+ * arbitrary piece of information  (e.g., where the cursor is in a document). The implementation
+ * must also call this method so that the compatibility check can be performed.
+ *
+ * @static
+ * @inheritable
+ * @param {Mixed} data Data to check
+ * @return {boolean} Tool can be used with data
+ */
+OO.ui.Tool.static.isCompatibleWith = function () {
+       return false;
+};
+
+/* Methods */
+
+/**
+ * Handle the toolbar state being updated. This method is called when the
+ * {@link OO.ui.Toolbar#event-updateState 'updateState' event} is emitted on the
+ * {@link OO.ui.Toolbar Toolbar} that uses this tool, and should set the state of this tool
+ * depending on application state (usually by calling #setDisabled to enable or disable the tool,
+ * or #setActive to mark is as currently in-use or not).
+ *
+ * This is an abstract method that must be overridden in a concrete subclass.
+ *
+ * @method
+ * @protected
+ * @abstract
+ */
+OO.ui.Tool.prototype.onUpdateState = null;
+
+/**
+ * Handle the tool being selected. This method is called when the user triggers this tool,
+ * usually by clicking on its label/icon.
+ *
+ * This is an abstract method that must be overridden in a concrete subclass.
+ *
+ * @method
+ * @protected
+ * @abstract
+ */
+OO.ui.Tool.prototype.onSelect = null;
+
+/**
+ * Check if the tool is active.
+ *
+ * Tools become active when their #onSelect or #onUpdateState handlers change them to appear pressed
+ * with the #setActive method. Additional CSS is applied to the tool to reflect the active state.
+ *
+ * @return {boolean} Tool is active
+ */
+OO.ui.Tool.prototype.isActive = function () {
+       return this.active;
+};
+
+/**
+ * Make the tool appear active or inactive.
+ *
+ * This method should be called within #onSelect or #onUpdateState event handlers to make the tool
+ * appear pressed or not.
+ *
+ * @param {boolean} state Make tool appear active
+ */
+OO.ui.Tool.prototype.setActive = function ( state ) {
+       this.active = !!state;
+       if ( this.active ) {
+               this.$element.addClass( 'oo-ui-tool-active' );
+       } else {
+               this.$element.removeClass( 'oo-ui-tool-active' );
+       }
+};
+
+/**
+ * Set the tool #title.
+ *
+ * @param {string|Function} title Title text or a function that returns text
+ * @chainable
+ */
+OO.ui.Tool.prototype.setTitle = function ( title ) {
+       this.title = OO.ui.resolveMsg( title );
+       this.updateTitle();
+       return this;
+};
+
+/**
+ * Get the tool #title.
+ *
+ * @return {string} Title text
+ */
+OO.ui.Tool.prototype.getTitle = function () {
+       return this.title;
+};
+
+/**
+ * Get the tool's symbolic name.
+ *
+ * @return {string} Symbolic name of tool
+ */
+OO.ui.Tool.prototype.getName = function () {
+       return this.constructor.static.name;
+};
+
+/**
+ * Update the title.
+ */
+OO.ui.Tool.prototype.updateTitle = function () {
+       var titleTooltips = this.toolGroup.constructor.static.titleTooltips,
+               accelTooltips = this.toolGroup.constructor.static.accelTooltips,
+               accel = this.toolbar.getToolAccelerator( this.constructor.static.name ),
+               tooltipParts = [];
+
+       this.$title.text( this.title );
+       this.$accel.text( accel );
+
+       if ( titleTooltips && typeof this.title === 'string' && this.title.length ) {
+               tooltipParts.push( this.title );
+       }
+       if ( accelTooltips && typeof accel === 'string' && accel.length ) {
+               tooltipParts.push( accel );
+       }
+       if ( tooltipParts.length ) {
+               this.$link.attr( 'title', tooltipParts.join( ' ' ) );
+       } else {
+               this.$link.removeAttr( 'title' );
+       }
+};
+
+/**
+ * Destroy tool.
+ *
+ * Destroying the tool removes all event handlers and the tool’s DOM elements.
+ * Call this method whenever you are done using a tool.
+ */
+OO.ui.Tool.prototype.destroy = function () {
+       this.toolbar.disconnect( this );
+       this.$element.remove();
+};
+
+/**
+ * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a {@link OO.ui.Toolbar toolbar}.
+ * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or {@link OO.ui.MenuToolGroup menu})
+ * to which a tool belongs determines how the tool is arranged and displayed in the toolbar. Toolgroups
+ * themselves are created on demand with a {@link OO.ui.ToolGroupFactory toolgroup factory}.
+ *
+ * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified
+ * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.
+ * The options `exclude`, `promote`, and `demote` support the same formats.
+ *
+ * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in general,
+ * please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {OO.ui.Toolbar} toolbar
+ * @param {Object} [config] Configuration options
+ * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.
+ * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.
+ * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup, see above.
+ * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.
+ *  This setting is particularly useful when tools have been added to the toolgroup
+ *  en masse (e.g., via the catch-all selector).
+ */
+OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
+               config = toolbar;
+               toolbar = config.toolbar;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ToolGroup.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, config );
+
+       // Properties
+       this.toolbar = toolbar;
+       this.tools = {};
+       this.pressed = null;
+       this.autoDisabled = false;
+       this.include = config.include || [];
+       this.exclude = config.exclude || [];
+       this.promote = config.promote || [];
+       this.demote = config.demote || [];
+       this.onCapturedMouseKeyUpHandler = this.onCapturedMouseKeyUp.bind( this );
+
+       // Events
+       this.$element.on( {
+               mousedown: this.onMouseKeyDown.bind( this ),
+               mouseup: this.onMouseKeyUp.bind( this ),
+               keydown: this.onMouseKeyDown.bind( this ),
+               keyup: this.onMouseKeyUp.bind( this ),
+               focus: this.onMouseOverFocus.bind( this ),
+               blur: this.onMouseOutBlur.bind( this ),
+               mouseover: this.onMouseOverFocus.bind( this ),
+               mouseout: this.onMouseOutBlur.bind( this )
+       } );
+       this.toolbar.getToolFactory().connect( this, { register: 'onToolFactoryRegister' } );
+       this.aggregate( { disable: 'itemDisable' } );
+       this.connect( this, { itemDisable: 'updateDisabled' } );
+
+       // Initialization
+       this.$group.addClass( 'oo-ui-toolGroup-tools' );
+       this.$element
+               .addClass( 'oo-ui-toolGroup' )
+               .append( this.$group );
+       this.populate();
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToolGroup, OO.ui.Widget );
+OO.mixinClass( OO.ui.ToolGroup, OO.ui.mixin.GroupElement );
+
+/* Events */
+
+/**
+ * @event update
+ */
+
+/* Static Properties */
+
+/**
+ * Show labels in tooltips.
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.ToolGroup.static.titleTooltips = false;
+
+/**
+ * Show acceleration labels in tooltips.
+ *
+ * Note: The OOjs UI library does not include an accelerator system, but does contain
+ * a hook for one. To use an accelerator system, subclass the {@link OO.ui.Toolbar toolbar} and
+ * override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method, which is
+ * meant to return a label that describes the accelerator keys for a given tool (e.g., 'Ctrl + M').
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.ToolGroup.static.accelTooltips = false;
+
+/**
+ * Automatically disable the toolgroup when all tools are disabled
+ *
+ * @static
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.ToolGroup.static.autoDisable = true;
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ToolGroup.prototype.isDisabled = function () {
+       return this.autoDisabled || OO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ToolGroup.prototype.updateDisabled = function () {
+       var i, item, allDisabled = true;
+
+       if ( this.constructor.static.autoDisable ) {
+               for ( i = this.items.length - 1; i >= 0; i-- ) {
+                       item = this.items[ i ];
+                       if ( !item.isDisabled() ) {
+                               allDisabled = false;
+                               break;
+                       }
+               }
+               this.autoDisabled = allDisabled;
+       }
+       OO.ui.ToolGroup.parent.prototype.updateDisabled.apply( this, arguments );
+};
+
+/**
+ * Handle mouse down and key down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse down or key down event
+ */
+OO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {
+       if (
+               !this.isDisabled() &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.pressed = this.getTargetTool( e );
+               if ( this.pressed ) {
+                       this.pressed.setActive( true );
+                       this.getElementDocument().addEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
+                       this.getElementDocument().addEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
+               }
+               return false;
+       }
+};
+
+/**
+ * Handle captured mouse up and key up events.
+ *
+ * @protected
+ * @param {Event} e Mouse up or key up event
+ */
+OO.ui.ToolGroup.prototype.onCapturedMouseKeyUp = function ( e ) {
+       this.getElementDocument().removeEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
+       this.getElementDocument().removeEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
+       // onMouseKeyUp may be called a second time, depending on where the mouse is when the button is
+       // released, but since `this.pressed` will no longer be true, the second call will be ignored.
+       this.onMouseKeyUp( e );
+};
+
+/**
+ * Handle mouse up and key up events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse up or key up event
+ */
+OO.ui.ToolGroup.prototype.onMouseKeyUp = function ( e ) {
+       var tool = this.getTargetTool( e );
+
+       if (
+               !this.isDisabled() && this.pressed && this.pressed === tool &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.pressed.onSelect();
+               this.pressed = null;
+               return false;
+       }
+
+       this.pressed = null;
+};
+
+/**
+ * Handle mouse over and focus events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse over or focus event
+ */
+OO.ui.ToolGroup.prototype.onMouseOverFocus = function ( e ) {
+       var tool = this.getTargetTool( e );
+
+       if ( this.pressed && this.pressed === tool ) {
+               this.pressed.setActive( true );
+       }
+};
+
+/**
+ * Handle mouse out and blur events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse out or blur event
+ */
+OO.ui.ToolGroup.prototype.onMouseOutBlur = function ( e ) {
+       var tool = this.getTargetTool( e );
+
+       if ( this.pressed && this.pressed === tool ) {
+               this.pressed.setActive( false );
+       }
+};
+
+/**
+ * Get the closest tool to a jQuery.Event.
+ *
+ * Only tool links are considered, which prevents other elements in the tool such as popups from
+ * triggering tool group interactions.
+ *
+ * @private
+ * @param {jQuery.Event} e
+ * @return {OO.ui.Tool|null} Tool, `null` if none was found
+ */
+OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
+       var tool,
+               $item = $( e.target ).closest( '.oo-ui-tool-link' );
+
+       if ( $item.length ) {
+               tool = $item.parent().data( 'oo-ui-tool' );
+       }
+
+       return tool && !tool.isDisabled() ? tool : null;
+};
+
+/**
+ * Handle tool registry register events.
+ *
+ * If a tool is registered after the group is created, we must repopulate the list to account for:
+ *
+ * - a tool being added that may be included
+ * - a tool already included being overridden
+ *
+ * @protected
+ * @param {string} name Symbolic name of tool
+ */
+OO.ui.ToolGroup.prototype.onToolFactoryRegister = function () {
+       this.populate();
+};
+
+/**
+ * Get the toolbar that contains the toolgroup.
+ *
+ * @return {OO.ui.Toolbar} Toolbar that contains the toolgroup
+ */
+OO.ui.ToolGroup.prototype.getToolbar = function () {
+       return this.toolbar;
+};
+
+/**
+ * Add and remove tools based on configuration.
+ */
+OO.ui.ToolGroup.prototype.populate = function () {
+       var i, len, name, tool,
+               toolFactory = this.toolbar.getToolFactory(),
+               names = {},
+               add = [],
+               remove = [],
+               list = this.toolbar.getToolFactory().getTools(
+                       this.include, this.exclude, this.promote, this.demote
+               );
+
+       // Build a list of needed tools
+       for ( i = 0, len = list.length; i < len; i++ ) {
+               name = list[ i ];
+               if (
+                       // Tool exists
+                       toolFactory.lookup( name ) &&
+                       // Tool is available or is already in this group
+                       ( this.toolbar.isToolAvailable( name ) || this.tools[ name ] )
+               ) {
+                       // Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool before
+                       // creating it, but we can't call reserveTool() yet because we haven't created the tool.
+                       this.toolbar.tools[ name ] = true;
+                       tool = this.tools[ name ];
+                       if ( !tool ) {
+                               // Auto-initialize tools on first use
+                               this.tools[ name ] = tool = toolFactory.create( name, this );
+                               tool.updateTitle();
+                       }
+                       this.toolbar.reserveTool( tool );
+                       add.push( tool );
+                       names[ name ] = true;
+               }
+       }
+       // Remove tools that are no longer needed
+       for ( name in this.tools ) {
+               if ( !names[ name ] ) {
+                       this.tools[ name ].destroy();
+                       this.toolbar.releaseTool( this.tools[ name ] );
+                       remove.push( this.tools[ name ] );
+                       delete this.tools[ name ];
+               }
+       }
+       if ( remove.length ) {
+               this.removeItems( remove );
+       }
+       // Update emptiness state
+       if ( add.length ) {
+               this.$element.removeClass( 'oo-ui-toolGroup-empty' );
+       } else {
+               this.$element.addClass( 'oo-ui-toolGroup-empty' );
+       }
+       // Re-add tools (moving existing ones to new locations)
+       this.addItems( add );
+       // Disabled state may depend on items
+       this.updateDisabled();
+};
+
+/**
+ * Destroy toolgroup.
+ */
+OO.ui.ToolGroup.prototype.destroy = function () {
+       var name;
+
+       this.clearItems();
+       this.toolbar.getToolFactory().disconnect( this );
+       for ( name in this.tools ) {
+               this.toolbar.releaseTool( this.tools[ name ] );
+               this.tools[ name ].disconnect( this ).destroy();
+               delete this.tools[ name ];
+       }
+       this.$element.remove();
+};
+
+/**
+ * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools}, {@link OO.ui.PopupTool PopupTools},
+ * and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be registered with a tool factory. Tools are
+ * registered by their symbolic name. See {@link OO.ui.Toolbar toolbars} for an example.
+ *
+ * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @class
+ * @extends OO.Factory
+ * @constructor
+ */
+OO.ui.ToolFactory = function OoUiToolFactory() {
+       // Parent constructor
+       OO.ui.ToolFactory.parent.call( this );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
+
+/* Methods */
+
+/**
+ * Get tools from the factory
+ *
+ * @param {Array|string} [include] Included tools, see #extract for format
+ * @param {Array|string} [exclude] Excluded tools, see #extract for format
+ * @param {Array|string} [promote] Promoted tools, see #extract for format
+ * @param {Array|string} [demote] Demoted tools, see #extract for format
+ * @return {string[]} List of tools
+ */
+OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
+       var i, len, included, promoted, demoted,
+               auto = [],
+               used = {};
+
+       // Collect included and not excluded tools
+       included = OO.simpleArrayDifference( this.extract( include ), this.extract( exclude ) );
+
+       // Promotion
+       promoted = this.extract( promote, used );
+       demoted = this.extract( demote, used );
+
+       // Auto
+       for ( i = 0, len = included.length; i < len; i++ ) {
+               if ( !used[ included[ i ] ] ) {
+                       auto.push( included[ i ] );
+               }
+       }
+
+       return promoted.concat( auto ).concat( demoted );
+};
+
+/**
+ * Get a flat list of names from a list of names or groups.
+ *
+ * Normally, `collection` is an array of tool specifications. Tools can be specified in the
+ * following ways:
+ *
+ * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.
+ * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the
+ *   tool to a group, use OO.ui.Tool.static.group.)
+ *
+ * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the
+ * catch-all selector `'*'`.
+ *
+ * If `used` is passed, tool names that appear as properties in this object will be considered
+ * already assigned, and will not be returned even if specified otherwise. The tool names extracted
+ * by this function call will be added as new properties in the object.
+ *
+ * @private
+ * @param {Array|string} collection List of tools, see above
+ * @param {Object} [used] Object containing information about used tools, see above
+ * @return {string[]} List of extracted tool names
+ */
+OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
+       var i, len, item, name, tool,
+               names = [];
+
+       if ( collection === '*' ) {
+               for ( name in this.registry ) {
+                       tool = this.registry[ name ];
+                       if (
+                               // Only add tools by group name when auto-add is enabled
+                               tool.static.autoAddToCatchall &&
+                               // Exclude already used tools
+                               ( !used || !used[ name ] )
+                       ) {
+                               names.push( name );
+                               if ( used ) {
+                                       used[ name ] = true;
+                               }
+                       }
+               }
+       } else if ( Array.isArray( collection ) ) {
+               for ( i = 0, len = collection.length; i < len; i++ ) {
+                       item = collection[ i ];
+                       // Allow plain strings as shorthand for named tools
+                       if ( typeof item === 'string' ) {
+                               item = { name: item };
+                       }
+                       if ( OO.isPlainObject( item ) ) {
+                               if ( item.group ) {
+                                       for ( name in this.registry ) {
+                                               tool = this.registry[ name ];
+                                               if (
+                                                       // Include tools with matching group
+                                                       tool.static.group === item.group &&
+                                                       // Only add tools by group name when auto-add is enabled
+                                                       tool.static.autoAddToGroup &&
+                                                       // Exclude already used tools
+                                                       ( !used || !used[ name ] )
+                                               ) {
+                                                       names.push( name );
+                                                       if ( used ) {
+                                                               used[ name ] = true;
+                                                       }
+                                               }
+                                       }
+                               // Include tools with matching name and exclude already used tools
+                               } else if ( item.name && ( !used || !used[ item.name ] ) ) {
+                                       names.push( item.name );
+                                       if ( used ) {
+                                               used[ item.name ] = true;
+                                       }
+                               }
+                       }
+               }
+       }
+       return names;
+};
+
+/**
+ * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes must
+ * specify a symbolic name and be registered with the factory. The following classes are registered by
+ * default:
+ *
+ * - {@link OO.ui.BarToolGroup BarToolGroups} (‘bar’)
+ * - {@link OO.ui.MenuToolGroup MenuToolGroups} (‘menu’)
+ * - {@link OO.ui.ListToolGroup ListToolGroups} (‘list’)
+ *
+ * See {@link OO.ui.Toolbar toolbars} for an example.
+ *
+ * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ * @class
+ * @extends OO.Factory
+ * @constructor
+ */
+OO.ui.ToolGroupFactory = function OoUiToolGroupFactory() {
+       var i, l, defaultClasses;
+       // Parent constructor
+       OO.Factory.call( this );
+
+       defaultClasses = this.constructor.static.getDefaultClasses();
+
+       // Register default toolgroups
+       for ( i = 0, l = defaultClasses.length; i < l; i++ ) {
+               this.register( defaultClasses[ i ] );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToolGroupFactory, OO.Factory );
+
+/* Static Methods */
+
+/**
+ * Get a default set of classes to be registered on construction.
+ *
+ * @return {Function[]} Default classes
+ */
+OO.ui.ToolGroupFactory.static.getDefaultClasses = function () {
+       return [
+               OO.ui.BarToolGroup,
+               OO.ui.ListToolGroup,
+               OO.ui.MenuToolGroup
+       ];
+};
+
+/**
+ * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}. Each popup tool is configured
+ * with a static name, title, and icon, as well with as any popup configurations. Unlike other tools, popup tools do not require that developers specify
+ * an #onSelect or #onUpdateState method, as these methods have been implemented already.
+ *
+ *     // Example of a popup tool. When selected, a popup tool displays
+ *     // a popup window.
+ *     function HelpTool( toolGroup, config ) {
+ *        OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
+ *            padded: true,
+ *            label: 'Help',
+ *            head: true
+ *        } }, config ) );
+ *        this.popup.$body.append( '<p>I am helpful!</p>' );
+ *     };
+ *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
+ *     HelpTool.static.name = 'help';
+ *     HelpTool.static.icon = 'help';
+ *     HelpTool.static.title = 'Help';
+ *     toolFactory.register( HelpTool );
+ *
+ * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}. For more information about
+ * toolbars in genreral, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Tool
+ * @mixins OO.ui.mixin.PopupElement
+ *
+ * @constructor
+ * @param {OO.ui.ToolGroup} toolGroup
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.PopupTool = function OoUiPopupTool( toolGroup, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
+               config = toolGroup;
+               toolGroup = config.toolGroup;
+       }
+
+       // Parent constructor
+       OO.ui.PopupTool.parent.call( this, toolGroup, config );
+
+       // Mixin constructors
+       OO.ui.mixin.PopupElement.call( this, config );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-popupTool' )
+               .append( this.popup.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PopupTool, OO.ui.Tool );
+OO.mixinClass( OO.ui.PopupTool, OO.ui.mixin.PopupElement );
+
+/* Methods */
+
+/**
+ * Handle the tool being selected.
+ *
+ * @inheritdoc
+ */
+OO.ui.PopupTool.prototype.onSelect = function () {
+       if ( !this.isDisabled() ) {
+               this.popup.toggle();
+       }
+       this.setActive( false );
+       return false;
+};
+
+/**
+ * Handle the toolbar state being updated.
+ *
+ * @inheritdoc
+ */
+OO.ui.PopupTool.prototype.onUpdateState = function () {
+       this.setActive( false );
+};
+
+/**
+ * A ToolGroupTool is a special sort of tool that can contain other {@link OO.ui.Tool tools}
+ * and {@link OO.ui.ToolGroup toolgroups}. The ToolGroupTool was specifically designed to be used
+ * inside a {@link OO.ui.BarToolGroup bar} toolgroup to provide access to additional tools from
+ * the bar item. Included tools will be displayed in a dropdown {@link OO.ui.ListToolGroup list}
+ * when the ToolGroupTool is selected.
+ *
+ *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2', defined elsewhere.
+ *
+ *     function SettingsTool() {
+ *         SettingsTool.parent.apply( this, arguments );
+ *     };
+ *     OO.inheritClass( SettingsTool, OO.ui.ToolGroupTool );
+ *     SettingsTool.static.name = 'settings';
+ *     SettingsTool.static.title = 'Change settings';
+ *     SettingsTool.static.groupConfig = {
+ *         icon: 'settings',
+ *         label: 'ToolGroupTool',
+ *         include: [  'setting1', 'setting2'  ]
+ *     };
+ *     toolFactory.register( SettingsTool );
+ *
+ * For more information, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * Please note that this implementation is subject to change per [T74159] [2].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars#ToolGroupTool
+ * [2]: https://phabricator.wikimedia.org/T74159
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Tool
+ *
+ * @constructor
+ * @param {OO.ui.ToolGroup} toolGroup
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ToolGroupTool = function OoUiToolGroupTool( toolGroup, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
+               config = toolGroup;
+               toolGroup = config.toolGroup;
+       }
+
+       // Parent constructor
+       OO.ui.ToolGroupTool.parent.call( this, toolGroup, config );
+
+       // Properties
+       this.innerToolGroup = this.createGroup( this.constructor.static.groupConfig );
+
+       // Events
+       this.innerToolGroup.connect( this, { disable: 'onToolGroupDisable' } );
+
+       // Initialization
+       this.$link.remove();
+       this.$element
+               .addClass( 'oo-ui-toolGroupTool' )
+               .append( this.innerToolGroup.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToolGroupTool, OO.ui.Tool );
+
+/* Static Properties */
+
+/**
+ * Toolgroup configuration.
+ *
+ * The toolgroup configuration consists of the tools to include, as well as an icon and label
+ * to use for the bar item. Tools can be included by symbolic name, group, or with the
+ * wildcard selector. Please see {@link OO.ui.ToolGroup toolgroup} for more information.
+ *
+ * @property {Object.<string,Array>}
+ */
+OO.ui.ToolGroupTool.static.groupConfig = {};
+
+/* Methods */
+
+/**
+ * Handle the tool being selected.
+ *
+ * @inheritdoc
+ */
+OO.ui.ToolGroupTool.prototype.onSelect = function () {
+       this.innerToolGroup.setActive( !this.innerToolGroup.active );
+       return false;
+};
+
+/**
+ * Synchronize disabledness state of the tool with the inner toolgroup.
+ *
+ * @private
+ * @param {boolean} disabled Element is disabled
+ */
+OO.ui.ToolGroupTool.prototype.onToolGroupDisable = function ( disabled ) {
+       this.setDisabled( disabled );
+};
+
+/**
+ * Handle the toolbar state being updated.
+ *
+ * @inheritdoc
+ */
+OO.ui.ToolGroupTool.prototype.onUpdateState = function () {
+       this.setActive( false );
+};
+
+/**
+ * Build a {@link OO.ui.ToolGroup toolgroup} from the specified configuration.
+ *
+ * @param {Object.<string,Array>} group Toolgroup configuration. Please see {@link OO.ui.ToolGroup toolgroup} for
+ *  more information.
+ * @return {OO.ui.ListToolGroup}
+ */
+OO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {
+       if ( group.include === '*' ) {
+               // Apply defaults to catch-all groups
+               if ( group.label === undefined ) {
+                       group.label = OO.ui.msg( 'ooui-toolbar-more' );
+               }
+       }
+
+       return this.toolbar.getToolGroupFactory().create( 'list', this.toolbar, group );
+};
+
+/**
+ * BarToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
+ * and {@link OO.ui.ListToolGroup ListToolGroup}). The {@link OO.ui.Tool tools} in a BarToolGroup are
+ * displayed by icon in a single row. The title of the tool is displayed when users move the mouse over
+ * the tool.
+ *
+ * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar is
+ * set up.
+ *
+ *     @example
+ *     // Example of a BarToolGroup with two tools
+ *     var toolFactory = new OO.ui.ToolFactory();
+ *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
+ *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
+ *
+ *     // We will be placing status text in this element when tools are used
+ *     var $area = $( '<p>' ).text( 'Example of a BarToolGroup with two tools.' );
+ *
+ *     // Define the tools that we're going to place in our toolbar
+ *
+ *     // Create a class inheriting from OO.ui.Tool
+ *     function SearchTool() {
+ *         SearchTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( SearchTool, OO.ui.Tool );
+ *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
+ *     // of 'icon' and 'title' (displayed icon and text).
+ *     SearchTool.static.name = 'search';
+ *     SearchTool.static.icon = 'search';
+ *     SearchTool.static.title = 'Search...';
+ *     // Defines the action that will happen when this tool is selected (clicked).
+ *     SearchTool.prototype.onSelect = function () {
+ *         $area.text( 'Search tool clicked!' );
+ *         // Never display this tool as "active" (selected).
+ *         this.setActive( false );
+ *     };
+ *     SearchTool.prototype.onUpdateState = function () {};
+ *     // Make this tool available in our toolFactory and thus our toolbar
+ *     toolFactory.register( SearchTool );
+ *
+ *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
+ *     // little popup window (a PopupWidget).
+ *     function HelpTool( toolGroup, config ) {
+ *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
+ *             padded: true,
+ *             label: 'Help',
+ *             head: true
+ *         } }, config ) );
+ *         this.popup.$body.append( '<p>I am helpful!</p>' );
+ *     }
+ *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
+ *     HelpTool.static.name = 'help';
+ *     HelpTool.static.icon = 'help';
+ *     HelpTool.static.title = 'Help';
+ *     toolFactory.register( HelpTool );
+ *
+ *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
+ *     // used once (but not all defined tools must be used).
+ *     toolbar.setup( [
+ *         {
+ *             // 'bar' tool groups display tools by icon only
+ *             type: 'bar',
+ *             include: [ 'search', 'help' ]
+ *         }
+ *     ] );
+ *
+ *     // Create some UI around the toolbar and place it in the document
+ *     var frame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true
+ *     } );
+ *     var contentFrame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         padded: true
+ *     } );
+ *     frame.$element.append(
+ *         toolbar.$element,
+ *         contentFrame.$element.append( $area )
+ *     );
+ *     $( 'body' ).append( frame.$element );
+ *
+ *     // Here is where the toolbar is actually built. This must be done after inserting it into the
+ *     // document.
+ *     toolbar.initialize();
+ *
+ * For more information about how to add tools to a bar tool group, please see {@link OO.ui.ToolGroup toolgroup}.
+ * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @class
+ * @extends OO.ui.ToolGroup
+ *
+ * @constructor
+ * @param {OO.ui.Toolbar} toolbar
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.BarToolGroup = function OoUiBarToolGroup( toolbar, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
+               config = toolbar;
+               toolbar = config.toolbar;
+       }
+
+       // Parent constructor
+       OO.ui.BarToolGroup.parent.call( this, toolbar, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-barToolGroup' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.BarToolGroup, OO.ui.ToolGroup );
+
+/* Static Properties */
+
+OO.ui.BarToolGroup.static.titleTooltips = true;
+
+OO.ui.BarToolGroup.static.accelTooltips = true;
+
+OO.ui.BarToolGroup.static.name = 'bar';
+
+/**
+ * PopupToolGroup is an abstract base class used by both {@link OO.ui.MenuToolGroup MenuToolGroup}
+ * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup--an overlaid menu or list of tools with an
+ * optional icon and label. This class can be used for other base classes that also use this functionality.
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.ToolGroup
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.ClippableElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {OO.ui.Toolbar} toolbar
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [header] Text to display at the top of the popup
+ */
+OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
+               config = toolbar;
+               toolbar = config.toolbar;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.PopupToolGroup.parent.call( this, toolbar, config );
+
+       // Properties
+       this.active = false;
+       this.dragging = false;
+       this.onBlurHandler = this.onBlur.bind( this );
+       this.$handle = $( '<span>' );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, config );
+       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
+
+       // Events
+       this.$handle.on( {
+               keydown: this.onHandleMouseKeyDown.bind( this ),
+               keyup: this.onHandleMouseKeyUp.bind( this ),
+               mousedown: this.onHandleMouseKeyDown.bind( this ),
+               mouseup: this.onHandleMouseKeyUp.bind( this )
+       } );
+
+       // Initialization
+       this.$handle
+               .addClass( 'oo-ui-popupToolGroup-handle' )
+               .append( this.$icon, this.$label, this.$indicator );
+       // If the pop-up should have a header, add it to the top of the toolGroup.
+       // Note: If this feature is useful for other widgets, we could abstract it into an
+       // OO.ui.HeaderedElement mixin constructor.
+       if ( config.header !== undefined ) {
+               this.$group
+                       .prepend( $( '<span>' )
+                               .addClass( 'oo-ui-popupToolGroup-header' )
+                               .text( config.header )
+                       );
+       }
+       this.$element
+               .addClass( 'oo-ui-popupToolGroup' )
+               .prepend( this.$handle );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PopupToolGroup, OO.ui.ToolGroup );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.ClippableElement );
+OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupToolGroup.prototype.setDisabled = function () {
+       // Parent method
+       OO.ui.PopupToolGroup.parent.prototype.setDisabled.apply( this, arguments );
+
+       if ( this.isDisabled() && this.isElementAttached() ) {
+               this.setActive( false );
+       }
+};
+
+/**
+ * Handle focus being lost.
+ *
+ * The event is actually generated from a mouseup/keyup, so it is not a normal blur event object.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse up or key up event
+ */
+OO.ui.PopupToolGroup.prototype.onBlur = function ( e ) {
+       // Only deactivate when clicking outside the dropdown element
+       if ( $( e.target ).closest( '.oo-ui-popupToolGroup' )[ 0 ] !== this.$element[ 0 ] ) {
+               this.setActive( false );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {
+       // Only close toolgroup when a tool was actually selected
+       if (
+               !this.isDisabled() && this.pressed && this.pressed === this.getTargetTool( e ) &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.setActive( false );
+       }
+       return OO.ui.PopupToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
+};
+
+/**
+ * Handle mouse up and key up events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse up or key up event
+ */
+OO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {
+       if (
+               !this.isDisabled() &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               return false;
+       }
+};
+
+/**
+ * Handle mouse down and key down events.
+ *
+ * @protected
+ * @param {jQuery.Event} e Mouse down or key down event
+ */
+OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {
+       if (
+               !this.isDisabled() &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.setActive( !this.active );
+               return false;
+       }
+};
+
+/**
+ * Switch into 'active' mode.
+ *
+ * When active, the popup is visible. A mouseup event anywhere in the document will trigger
+ * deactivation.
+ */
+OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
+       var containerWidth, containerLeft;
+       value = !!value;
+       if ( this.active !== value ) {
+               this.active = value;
+               if ( value ) {
+                       this.getElementDocument().addEventListener( 'mouseup', this.onBlurHandler, true );
+                       this.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, true );
+
+                       this.$clippable.css( 'left', '' );
+                       // Try anchoring the popup to the left first
+                       this.$element.addClass( 'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left' );
+                       this.toggleClipping( true );
+                       if ( this.isClippedHorizontally() ) {
+                               // Anchoring to the left caused the popup to clip, so anchor it to the right instead
+                               this.toggleClipping( false );
+                               this.$element
+                                       .removeClass( 'oo-ui-popupToolGroup-left' )
+                                       .addClass( 'oo-ui-popupToolGroup-right' );
+                               this.toggleClipping( true );
+                       }
+                       if ( this.isClippedHorizontally() ) {
+                               // Anchoring to the right also caused the popup to clip, so just make it fill the container
+                               containerWidth = this.$clippableScrollableContainer.width();
+                               containerLeft = this.$clippableScrollableContainer.offset().left;
+
+                               this.toggleClipping( false );
+                               this.$element.removeClass( 'oo-ui-popupToolGroup-right' );
+
+                               this.$clippable.css( {
+                                       left: -( this.$element.offset().left - containerLeft ),
+                                       width: containerWidth
+                               } );
+                       }
+               } else {
+                       this.getElementDocument().removeEventListener( 'mouseup', this.onBlurHandler, true );
+                       this.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, true );
+                       this.$element.removeClass(
+                               'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left  oo-ui-popupToolGroup-right'
+                       );
+                       this.toggleClipping( false );
+               }
+       }
+};
+
+/**
+ * ListToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
+ * and {@link OO.ui.BarToolGroup BarToolGroup}). The {@link OO.ui.Tool tools} in a ListToolGroup are displayed
+ * by label in a dropdown menu. The title of the tool is used as the label text. The menu itself can be configured
+ * with a label, icon, indicator, header, and title.
+ *
+ * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a ‘More’ option that
+ * users can select to see the full list of tools. If a collapsed toolgroup is expanded, a ‘Fewer’ option permits
+ * users to collapse the list again.
+ *
+ * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the toolbar is set up. The factory
+ * requires the ListToolGroup's symbolic name, 'list', which is specified along with the other configurations. For more
+ * information about how to add tools to a ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
+ *
+ *     @example
+ *     // Example of a ListToolGroup
+ *     var toolFactory = new OO.ui.ToolFactory();
+ *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
+ *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
+ *
+ *     // Configure and register two tools
+ *     function SettingsTool() {
+ *         SettingsTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( SettingsTool, OO.ui.Tool );
+ *     SettingsTool.static.name = 'settings';
+ *     SettingsTool.static.icon = 'settings';
+ *     SettingsTool.static.title = 'Change settings';
+ *     SettingsTool.prototype.onSelect = function () {
+ *         this.setActive( false );
+ *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( SettingsTool );
+ *     // Register two more tools, nothing interesting here
+ *     function StuffTool() {
+ *         StuffTool.parent.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( StuffTool, OO.ui.Tool );
+ *     StuffTool.static.name = 'stuff';
+ *     StuffTool.static.icon = 'search';
+ *     StuffTool.static.title = 'Change the world';
+ *     StuffTool.prototype.onSelect = function () {
+ *         this.setActive( false );
+ *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( StuffTool );
+ *     toolbar.setup( [
+ *         {
+ *             // Configurations for list toolgroup.
+ *             type: 'list',
+ *             label: 'ListToolGroup',
+ *             indicator: 'down',
+ *             icon: 'ellipsis',
+ *             title: 'This is the title, displayed when user moves the mouse over the list toolgroup',
+ *             header: 'This is the header',
+ *             include: [ 'settings', 'stuff' ],
+ *             allowCollapse: ['stuff']
+ *         }
+ *     ] );
+ *
+ *     // Create some UI around the toolbar and place it in the document
+ *     var frame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true
+ *     } );
+ *     frame.$element.append(
+ *         toolbar.$element
+ *     );
+ *     $( 'body' ).append( frame.$element );
+ *     // Build the toolbar. This must be done after the toolbar has been appended to the document.
+ *     toolbar.initialize();
+ *
+ * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @class
+ * @extends OO.ui.PopupToolGroup
+ *
+ * @constructor
+ * @param {OO.ui.Toolbar} toolbar
+ * @param {Object} [config] Configuration options
+ * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible tools
+ *  will only be displayed if users click the ‘More’ option displayed at the bottom of the list. If
+ *  the list is expanded, a ‘Fewer’ option permits users to collapse the list again. Any tools that
+ *  are included in the toolgroup, but are not designated as collapsible, will always be displayed.
+ *  To open a collapsible list in its expanded state, set #expanded to 'true'.
+ * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as collapsible.
+ *  Unless #expanded is set to true, the collapsible tools will be collapsed when the list is first opened.
+ * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools have
+ *  been designated as collapsible. When expanded is set to true, all tools in the group will be displayed
+ *  when the list is first opened. Users can collapse the list with a ‘Fewer’ option at the bottom.
+ */
+OO.ui.ListToolGroup = function OoUiListToolGroup( toolbar, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
+               config = toolbar;
+               toolbar = config.toolbar;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Properties (must be set before parent constructor, which calls #populate)
+       this.allowCollapse = config.allowCollapse;
+       this.forceExpand = config.forceExpand;
+       this.expanded = config.expanded !== undefined ? config.expanded : false;
+       this.collapsibleTools = [];
+
+       // Parent constructor
+       OO.ui.ListToolGroup.parent.call( this, toolbar, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-listToolGroup' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ListToolGroup, OO.ui.PopupToolGroup );
+
+/* Static Properties */
+
+OO.ui.ListToolGroup.static.name = 'list';
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ListToolGroup.prototype.populate = function () {
+       var i, len, allowCollapse = [];
+
+       OO.ui.ListToolGroup.parent.prototype.populate.call( this );
+
+       // Update the list of collapsible tools
+       if ( this.allowCollapse !== undefined ) {
+               allowCollapse = this.allowCollapse;
+       } else if ( this.forceExpand !== undefined ) {
+               allowCollapse = OO.simpleArrayDifference( Object.keys( this.tools ), this.forceExpand );
+       }
+
+       this.collapsibleTools = [];
+       for ( i = 0, len = allowCollapse.length; i < len; i++ ) {
+               if ( this.tools[ allowCollapse[ i ] ] !== undefined ) {
+                       this.collapsibleTools.push( this.tools[ allowCollapse[ i ] ] );
+               }
+       }
+
+       // Keep at the end, even when tools are added
+       this.$group.append( this.getExpandCollapseTool().$element );
+
+       this.getExpandCollapseTool().toggle( this.collapsibleTools.length !== 0 );
+       this.updateCollapsibleState();
+};
+
+OO.ui.ListToolGroup.prototype.getExpandCollapseTool = function () {
+       var ExpandCollapseTool;
+       if ( this.expandCollapseTool === undefined ) {
+               ExpandCollapseTool = function () {
+                       ExpandCollapseTool.parent.apply( this, arguments );
+               };
+
+               OO.inheritClass( ExpandCollapseTool, OO.ui.Tool );
+
+               ExpandCollapseTool.prototype.onSelect = function () {
+                       this.toolGroup.expanded = !this.toolGroup.expanded;
+                       this.toolGroup.updateCollapsibleState();
+                       this.setActive( false );
+               };
+               ExpandCollapseTool.prototype.onUpdateState = function () {
+                       // Do nothing. Tool interface requires an implementation of this function.
+               };
+
+               ExpandCollapseTool.static.name = 'more-fewer';
+
+               this.expandCollapseTool = new ExpandCollapseTool( this );
+       }
+       return this.expandCollapseTool;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ListToolGroup.prototype.onMouseKeyUp = function ( e ) {
+       // Do not close the popup when the user wants to show more/fewer tools
+       if (
+               $( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length &&
+               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               // HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation (which
+               // hides the popup list when a tool is selected) and call ToolGroup's implementation directly.
+               return OO.ui.ListToolGroup.parent.parent.prototype.onMouseKeyUp.call( this, e );
+       } else {
+               return OO.ui.ListToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
+       }
+};
+
+OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
+       var i, len;
+
+       this.getExpandCollapseTool()
+               .setIcon( this.expanded ? 'collapse' : 'expand' )
+               .setTitle( OO.ui.msg( this.expanded ? 'ooui-toolgroup-collapse' : 'ooui-toolgroup-expand' ) );
+
+       for ( i = 0, len = this.collapsibleTools.length; i < len; i++ ) {
+               this.collapsibleTools[ i ].toggle( this.expanded );
+       }
+};
+
+/**
+ * MenuToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
+ * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.BarToolGroup BarToolGroup}
+ * and {@link OO.ui.ListToolGroup ListToolGroup}). MenuToolGroups contain selectable {@link OO.ui.Tool tools},
+ * which are displayed by label in a dropdown menu. The tool's title is used as the label text, and the
+ * menu label is updated to reflect which tool or tools are currently selected. If no tools are selected,
+ * the menu label is empty. The menu can be configured with an indicator, icon, title, and/or header.
+ *
+ * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar
+ * is set up.
+ *
+ *     @example
+ *     // Example of a MenuToolGroup
+ *     var toolFactory = new OO.ui.ToolFactory();
+ *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
+ *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
+ *
+ *     // We will be placing status text in this element when tools are used
+ *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the dropdown menu.' );
+ *
+ *     // Define the tools that we're going to place in our toolbar
+ *
+ *     function SettingsTool() {
+ *         SettingsTool.parent.apply( this, arguments );
+ *         this.reallyActive = false;
+ *     }
+ *     OO.inheritClass( SettingsTool, OO.ui.Tool );
+ *     SettingsTool.static.name = 'settings';
+ *     SettingsTool.static.icon = 'settings';
+ *     SettingsTool.static.title = 'Change settings';
+ *     SettingsTool.prototype.onSelect = function () {
+ *         $area.text( 'Settings tool clicked!' );
+ *         // Toggle the active state on each click
+ *         this.reallyActive = !this.reallyActive;
+ *         this.setActive( this.reallyActive );
+ *         // To update the menu label
+ *         this.toolbar.emit( 'updateState' );
+ *     };
+ *     SettingsTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( SettingsTool );
+ *
+ *     function StuffTool() {
+ *         StuffTool.parent.apply( this, arguments );
+ *         this.reallyActive = false;
+ *     }
+ *     OO.inheritClass( StuffTool, OO.ui.Tool );
+ *     StuffTool.static.name = 'stuff';
+ *     StuffTool.static.icon = 'ellipsis';
+ *     StuffTool.static.title = 'More stuff';
+ *     StuffTool.prototype.onSelect = function () {
+ *         $area.text( 'More stuff tool clicked!' );
+ *         // Toggle the active state on each click
+ *         this.reallyActive = !this.reallyActive;
+ *         this.setActive( this.reallyActive );
+ *         // To update the menu label
+ *         this.toolbar.emit( 'updateState' );
+ *     };
+ *     StuffTool.prototype.onUpdateState = function () {};
+ *     toolFactory.register( StuffTool );
+ *
+ *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
+ *     // used once (but not all defined tools must be used).
+ *     toolbar.setup( [
+ *         {
+ *             type: 'menu',
+ *             header: 'This is the (optional) header',
+ *             title: 'This is the (optional) title',
+ *             indicator: 'down',
+ *             include: [ 'settings', 'stuff' ]
+ *         }
+ *     ] );
+ *
+ *     // Create some UI around the toolbar and place it in the document
+ *     var frame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         framed: true
+ *     } );
+ *     var contentFrame = new OO.ui.PanelLayout( {
+ *         expanded: false,
+ *         padded: true
+ *     } );
+ *     frame.$element.append(
+ *         toolbar.$element,
+ *         contentFrame.$element.append( $area )
+ *     );
+ *     $( 'body' ).append( frame.$element );
+ *
+ *     // Here is where the toolbar is actually built. This must be done after inserting it into the
+ *     // document.
+ *     toolbar.initialize();
+ *     toolbar.emit( 'updateState' );
+ *
+ * For more information about how to add tools to a MenuToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
+ * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki] [1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
+ *
+ * @class
+ * @extends OO.ui.PopupToolGroup
+ *
+ * @constructor
+ * @param {OO.ui.Toolbar} toolbar
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.MenuToolGroup = function OoUiMenuToolGroup( toolbar, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
+               config = toolbar;
+               toolbar = config.toolbar;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.MenuToolGroup.parent.call( this, toolbar, config );
+
+       // Events
+       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-menuToolGroup' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MenuToolGroup, OO.ui.PopupToolGroup );
+
+/* Static Properties */
+
+OO.ui.MenuToolGroup.static.name = 'menu';
+
+/* Methods */
+
+/**
+ * Handle the toolbar state being updated.
+ *
+ * When the state changes, the title of each active item in the menu will be joined together and
+ * used as a label for the group. The label will be empty if none of the items are active.
+ *
+ * @private
+ */
+OO.ui.MenuToolGroup.prototype.onUpdateState = function () {
+       var name,
+               labelTexts = [];
+
+       for ( name in this.tools ) {
+               if ( this.tools[ name ].isActive() ) {
+                       labelTexts.push( this.tools[ name ].getTitle() );
+               }
+       }
+
+       this.setLabel( labelTexts.join( ', ' ) || ' ' );
+};
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui-widgets-apex.css b/resources/lib/oojs-ui/oojs-ui-widgets-apex.css
new file mode 100644 (file)
index 0000000..252e402
--- /dev/null
@@ -0,0 +1,936 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-ms-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-o-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-draggableElement {
+       cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+}
+.oo-ui-draggableElement-dragging {
+       cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+       background: rgba(0, 0, 0, 0.2);
+       opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+       display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+       position: absolute;
+       display: block;
+       background: rgba(0, 0, 0, 0.4);
+}
+.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
+       overflow-y: hidden;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
+       overflow-y: auto;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
+       padding: 2em;
+}
+.oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 3em;
+       overflow-y: auto;
+}
+.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
+       padding: 1.5em;
+}
+.oo-ui-bookletLayout-outlinePanel {
+       border-right: 1px solid #dddddd;
+}
+.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
+       box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
+       height: 3em;
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-content {
+       top: 3em;
+}
+.oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
+       padding: 1.5em;
+}
+.oo-ui-menuLayout {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-menuLayout-menu,
+.oo-ui-menuLayout-content {
+       position: absolute;
+       -webkit-transition: all 200ms ease;
+          -moz-transition: all 200ms ease;
+               transition: all 200ms ease;
+}
+.oo-ui-menuLayout-menu {
+       height: 18em;
+       width: 18em;
+}
+.oo-ui-menuLayout-content {
+       top: 18em;
+       left: 18em;
+       right: 18em;
+       bottom: 18em;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
+       width: 0 !important;
+       height: 0 !important;
+       overflow: hidden;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
+       top: 0 !important;
+       left: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
+       width: auto !important;
+       left: 0;
+       top: 0;
+       right: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
+       right: 0 !important;
+       bottom: 0 !important;
+       left: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
+       height: auto !important;
+       top: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
+       bottom: 0 !important;
+       left: 0 !important;
+       top: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
+       width: auto !important;
+       right: 0;
+       bottom: 0;
+       left: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
+       left: 0 !important;
+       top: 0 !important;
+       right: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
+       height: auto !important;
+       bottom: 0;
+       left: 0;
+       top: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
+       top: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
+.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
+       display: block;
+       position: relative;
+}
+.oo-ui-buttonSelectWidget {
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 0.3em;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonSelectWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+       border-radius: 0;
+       margin-left: -1px;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
+       border-bottom-left-radius: 0.3em;
+       border-top-left-radius: 0.3em;
+       margin-left: 0;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
+       border-bottom-right-radius: 0.3em;
+       border-top-right-radius: 0.3em;
+}
+.oo-ui-buttonOptionWidget {
+       display: inline-block;
+       padding: 0;
+       background-color: transparent;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+       position: relative;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       position: static;
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+       height: 1.875em;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       margin-top: 0;
+}
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: transparent;
+}
+.oo-ui-toggleButtonWidget {
+       display: inline-block;
+       vertical-align: middle;
+       margin-right: 0.5em;
+}
+.oo-ui-toggleButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-toggleSwitchWidget {
+       position: relative;
+       display: inline-block;
+       vertical-align: middle;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       -webkit-transform: translateZ(0);
+          -moz-transform: translateZ(0);
+           -ms-transform: translateZ(0);
+               transform: translateZ(0);
+       height: 2em;
+       width: 4em;
+       border-radius: 1em;
+       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
+       border: 1px solid #cccccc;
+       margin-right: 0.5em;
+       background-color: #eeeeee;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #dddddd), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #dddddd 0, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #dddddd 0, #ffffff 100%);
+       background-image:         linear-gradient(to bottom, #dddddd 0, #ffffff 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
+       cursor: pointer;
+}
+.oo-ui-toggleSwitchWidget-grip {
+       position: absolute;
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       right: 0;
+       left: 0;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+       display: none;
+}
+.oo-ui-toggleSwitchWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
+       opacity: 0.5;
+}
+.oo-ui-toggleSwitchWidget-grip {
+       top: 0.25em;
+       left: 0.25em;
+       width: 1.5em;
+       height: 1.5em;
+       margin-top: -1px;
+       border-radius: 1em;
+       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
+       border: 1px #c9c9c9 solid;
+       -webkit-transition: left 250ms ease, margin-left 250ms ease;
+          -moz-transition: left 250ms ease, margin-left 250ms ease;
+               transition: left 250ms ease, margin-left 250ms ease;
+       background-color: #eeeeee;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
+       background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:         linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
+       border-color: #aaaaaa;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+       border-radius: 1em;
+       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+       -webkit-transition: opacity 250ms ease;
+          -moz-transition: opacity 250ms ease;
+               transition: opacity 250ms ease;
+       background-color: #cde7f4;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
+       background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+       background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+       background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
+}
+.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow {
+       opacity: 1;
+}
+.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+       left: 2.25em;
+       margin-left: -2px;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+       display: block;
+       opacity: 0;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
+       left: 0.25em;
+       margin-left: 0;
+}
+.oo-ui-progressBarWidget {
+       max-width: 50em;
+       background-color: #ffffff;
+       border: 1px solid #cccccc;
+       border-radius: 0.25em;
+       overflow: hidden;
+}
+.oo-ui-progressBarWidget-bar {
+       height: 1em;
+       border-right: 1px solid #cccccc;
+       -webkit-transition: width 250ms ease, margin-left 250ms ease;
+          -moz-transition: width 250ms ease, margin-left 250ms ease;
+               transition: width 250ms ease, margin-left 250ms ease;
+       background-color: #cde7f4;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
+       background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+       background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+       background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
+}
+.oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
+       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+       width: 40%;
+       margin-left: -10%;
+       border-left: 1px solid #a6cee1;
+}
+.oo-ui-progressBarWidget.oo-ui-widget-disabled {
+       opacity: 0.6;
+}
+.oo-ui-selectFileWidget {
+       display: inline-block;
+       vertical-align: middle;
+       width: 100%;
+       max-width: 50em;
+       margin-right: 0.5em;
+}
+.oo-ui-selectFileWidget-selectButton {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
+       position: relative;
+       overflow: hidden;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > input[type="file"] {
+       position: absolute;
+       margin: 0;
+       top: 0;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       width: 100%;
+       height: 100%;
+       opacity: 0;
+       z-index: 1;
+       cursor: pointer;
+       padding-top: 100px;
+}
+.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > input[type="file"] {
+       display: none;
+}
+.oo-ui-selectFileWidget-info {
+       width: 100%;
+       display: table-cell;
+       vertical-align: middle;
+       position: relative;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       text-overflow: ellipsis;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
+       float: left;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+       float: right;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       position: absolute;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       z-index: 2;
+}
+.oo-ui-selectFileWidget-dropTarget {
+       cursor: default;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget {
+       cursor: pointer;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
+       display: none;
+}
+.oo-ui-selectFileWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
+       margin-left: 0.5em;
+}
+.oo-ui-selectFileWidget-info {
+       height: 2.4em;
+       background-color: #ffffff;
+       border: 1px solid rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
+       line-height: 2.3em;
+       margin: 0;
+       overflow: hidden;
+       white-space: nowrap;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       text-overflow: ellipsis;
+       left: 0.5em;
+       right: 0.5em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+       color: #888888;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       top: 0;
+       width: 1.875em;
+       margin-right: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       height: 2.3em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       top: 0;
+       width: 0.9375em;
+       height: 2.3em;
+       margin-right: 0.775em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
+       top: 0;
+       width: 1.875em;
+       height: 2.3em;
+       margin-left: 0.3em;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
+       color: #cccccc;
+}
+.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       left: 2.475em;
+}
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 2.175em;
+}
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
+       right: 0;
+}
+.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 4.2625em;
+}
+.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
+       right: 2.0875em;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 0.5em;
+}
+.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
+.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 2em;
+}
+.oo-ui-selectFileWidget-dropTarget {
+       line-height: 3.5em;
+       background-color: #ffffff;
+       border: 1px dashed #aaaaaa;
+       padding: 0.5em 1em;
+       margin-bottom: 0.5em;
+       text-align: center;
+       vertical-align: middle;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget:hover,
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop oo-ui-selectfilewidget-droptarget {
+       background-color: #e1f3ff;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-outlineOptionWidget {
+       position: relative;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       font-size: 1.1em;
+       padding: 0.75em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+       padding-right: 1.5em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget-level-0 {
+       padding-left: 3.5em;
+}
+.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
+       left: 1em;
+}
+.oo-ui-outlineOptionWidget-level-1 {
+       padding-left: 5em;
+}
+.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
+       left: 2.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 {
+       padding-left: 6.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
+       left: 4em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+       background-color: #a7dcff;
+       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
+       font-weight: bold;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
+       font-style: italic;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
+       opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
+       color: #777777;
+}
+.oo-ui-outlineControlsWidget {
+       height: 3em;
+       background-color: #ffffff;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+       float: left;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+       float: left;
+       background-position: right center;
+}
+.oo-ui-outlineControlsWidget-items {
+       float: left;
+}
+.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
+       float: left;
+}
+.oo-ui-outlineControlsWidget-movers {
+       float: right;
+}
+.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
+       float: right;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+       height: 2em;
+       margin: 0.5em 0.5em 0.5em 0;
+       padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+       width: 1.5em;
+       height: 2em;
+       margin: 0.5em 0 0.5em 0.5em;
+       opacity: 0.2;
+}
+.oo-ui-tabSelectWidget {
+       text-align: left;
+       white-space: nowrap;
+       overflow: hidden;
+       background-color: #eeeeee;
+       box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
+}
+.oo-ui-tabOptionWidget {
+       display: inline-block;
+       vertical-align: bottom;
+       padding: 0.5em 1em;
+       margin: 0.5em 0 0 0.75em;
+       border: 1px solid transparent;
+       border-bottom: none;
+       border-top-left-radius: 0.5em;
+       border-top-right-radius: 0.5em;
+}
+.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+       padding-right: 1.5em;
+}
+.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       opacity: 0.5;
+}
+.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-pressed {
+       background-color: transparent;
+}
+.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
+       background-color: rgba(255, 255, 255, 0.2);
+       border-color: #dddddd;
+}
+.oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
+       background-color: #ffffff;
+       border-color: #dddddd;
+}
+.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
+       background-color: #ffffff;
+       border-color: #dddddd;
+}
+.oo-ui-capsuleMultiSelectWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-capsuleMultiSelectWidget-handle {
+       width: 100%;
+       display: inline-block;
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget-content {
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
+       display: none;
+}
+.oo-ui-capsuleMultiSelectWidget-group {
+       display: inline;
+}
+.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-capsuleMultiSelectWidget-handle {
+       background-color: #ffffff;
+       cursor: text;
+       min-height: 2.4em;
+       margin-right: 0.5em;
+       padding: 0.15em 0.25em;
+       border: 1px solid rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-capsuleMultiSelectWidget-handle:last-child {
+       margin-right: 0;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
+       border: none;
+       line-height: 1.675em;
+       margin: 0;
+       margin-left: 0.2em;
+       padding: 0;
+       font-size: inherit;
+       font-family: inherit;
+       background-color: transparent;
+       color: black;
+       vertical-align: middle;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
+       outline: none;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
+       padding-right: 2.4875em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
+       right: 0;
+       top: 0;
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.775em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
+       padding-left: 2.475em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
+       left: 0;
+       top: 0;
+       width: 1.875em;
+       height: 1.875em;
+       margin: 0.3em;
+}
+.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle {
+       border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+       cursor: default;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget {
+       border-top-color: #ffffff;
+}
+.oo-ui-capsuleItemWidget {
+       position: relative;
+       display: inline-block;
+       cursor: default;
+       white-space: nowrap;
+       width: auto;
+       max-width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       vertical-align: middle;
+       padding: 0 0.4em;
+       margin: 0.1em;
+       height: 1.7em;
+       line-height: 1.7em;
+       background-color: #eeeeee;
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ffffff), color-stop(100%, #dddddd));
+       background-image: -webkit-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0, #dddddd 100%);
+       background-image:         linear-gradient(to bottom, #ffffff 0, #dddddd 100%);
+       -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+       border: 1px solid #cccccc;
+       color: #555555;
+       border-radius: 0.25em;
+}
+.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon {
+       cursor: pointer;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon {
+       cursor: default;
+}
+.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: block;
+       text-overflow: ellipsis;
+       overflow: hidden;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label {
+       padding-right: 1.3375em;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
+       position: absolute;
+       right: 0.4em;
+       top: 0;
+       width: 0.9375em;
+       height: 100%;
+       background-repeat: no-repeat;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicator-clear {
+       cursor: pointer;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
+       opacity: 0.5;
+       -webkit-transform: translate3d(0, 0, 0);
+       box-shadow: none;
+       color: #333333;
+       background: #eeeeee;
+       border-color: #cccccc;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-searchWidget-query {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+       width: 100%;
+}
+.oo-ui-searchWidget-results {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       overflow-x: hidden;
+       overflow-y: auto;
+}
+.oo-ui-searchWidget-query {
+       height: 4em;
+       padding: 0 1em;
+       box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+       margin: 0.75em 0;
+}
+.oo-ui-searchWidget-results {
+       top: 4em;
+       padding: 1em;
+       line-height: 0;
+}
+.oo-ui-numberInputWidget {
+       display: inline-block;
+       position: relative;
+       max-width: 50em;
+}
+.oo-ui-numberInputWidget-field {
+       display: table;
+       table-layout: fixed;
+       width: 100%;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
+.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+       width: 100%;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
+       white-space: nowrap;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
+       width: 2.25em;
+}
+.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+       border-top-right-radius: 0;
+       border-bottom-right-radius: 0;
+       border-right-width: 0;
+}
+.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+       border-top-left-radius: 0;
+       border-bottom-left-radius: 0;
+       border-left-width: 0;
+}
+.oo-ui-numberInputWidget .oo-ui-textInputWidget input {
+       border-radius: 0;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
new file mode 100644 (file)
index 0000000..d5f8298
--- /dev/null
@@ -0,0 +1,930 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-draggableElement {
+       cursor: -webkit-grab -moz-grab, url(images/grab.cur), move;
+}
+.oo-ui-draggableElement-dragging {
+       cursor: -webkit-grabbing -moz-grabbing, url(images/grabbing.cur), move;
+       background: rgba(0, 0, 0, 0.2);
+       opacity: 0.4;
+}
+.oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement.oo-ui-optionWidget {
+       display: inline-block;
+}
+.oo-ui-draggableGroupElement-placeholder {
+       position: absolute;
+       display: block;
+       background: rgba(0, 0, 0, 0.4);
+}
+.oo-ui-lookupElement > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
+       overflow-y: hidden;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
+       overflow-y: auto;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
+       padding: 2em;
+}
+.oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 3em;
+       overflow-y: auto;
+}
+.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+}
+.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
+       padding: 1.5em;
+}
+.oo-ui-bookletLayout-outlinePanel {
+       border-right: 1px solid #dddddd;
+}
+.oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
+       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
+       height: 3em;
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-content {
+       top: 3em;
+}
+.oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
+       padding: 1.5em;
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-menu {
+       height: 2.75em;
+}
+.oo-ui-indexLayout > .oo-ui-menuLayout-content {
+       top: 2.75em;
+}
+.oo-ui-menuLayout {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-menuLayout-menu,
+.oo-ui-menuLayout-content {
+       position: absolute;
+       -webkit-transition: all 200ms ease;
+          -moz-transition: all 200ms ease;
+               transition: all 200ms ease;
+}
+.oo-ui-menuLayout-menu {
+       height: 18em;
+       width: 18em;
+}
+.oo-ui-menuLayout-content {
+       top: 18em;
+       left: 18em;
+       right: 18em;
+       bottom: 18em;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
+       width: 0 !important;
+       height: 0 !important;
+       overflow: hidden;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
+       top: 0 !important;
+       left: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
+       width: auto !important;
+       left: 0;
+       top: 0;
+       right: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
+       right: 0 !important;
+       bottom: 0 !important;
+       left: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
+       height: auto !important;
+       top: 0;
+       right: 0;
+       bottom: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
+       bottom: 0 !important;
+       left: 0 !important;
+       top: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
+       width: auto !important;
+       right: 0;
+       bottom: 0;
+       left: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
+       left: 0 !important;
+       top: 0 !important;
+       right: 0 !important;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
+       height: auto !important;
+       bottom: 0;
+       left: 0;
+       top: 0;
+}
+.oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
+       top: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
+.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
+       display: block;
+       position: relative;
+}
+.oo-ui-buttonSelectWidget {
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 2px;
+       margin-right: 0.5em;
+}
+.oo-ui-buttonSelectWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+       border-radius: 0;
+       margin-left: -1px;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
+       border-bottom-left-radius: 2px;
+       border-top-left-radius: 2px;
+       margin-left: 0;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
+       border-bottom-right-radius: 2px;
+       border-top-right-radius: 2px;
+}
+.oo-ui-buttonOptionWidget {
+       display: inline-block;
+       padding: 0;
+       background-color: transparent;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+       position: relative;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       position: static;
+       display: inline-block;
+       vertical-align: middle;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       margin-top: 0;
+}
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
+       background-color: transparent;
+}
+.oo-ui-buttonOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+       opacity: 1;
+}
+.oo-ui-toggleButtonWidget {
+       display: inline-block;
+       vertical-align: middle;
+       margin-right: 0.5em;
+}
+.oo-ui-toggleButtonWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-toggleSwitchWidget {
+       position: relative;
+       display: inline-block;
+       vertical-align: middle;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       -webkit-transform: translateZ(0);
+          -moz-transform: translateZ(0);
+           -ms-transform: translateZ(0);
+               transform: translateZ(0);
+       height: 2em;
+       width: 3.5em;
+       border: 1px solid #777777;
+       border-radius: 1em;
+       background-color: #ffffff;
+       margin-right: 0.5em;
+       -webkit-transition: background-color 100ms ease, border-color 100ms ease;
+          -moz-transition: background-color 100ms ease, border-color 100ms ease;
+               transition: background-color 100ms ease, border-color 100ms ease;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
+       cursor: pointer;
+}
+.oo-ui-toggleSwitchWidget-grip {
+       position: absolute;
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       right: 0;
+       left: 0;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+       display: none;
+}
+.oo-ui-toggleSwitchWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-toggleSwitchWidget:before {
+       content: "";
+       display: block;
+       position: absolute;
+       top: 0;
+       left: 0;
+       bottom: 0;
+       right: 0;
+       border: 1px solid transparent;
+       border-radius: 1em;
+       z-index: 1;
+}
+.oo-ui-toggleSwitchWidget-grip {
+       top: 0.35em;
+       width: 1.2em;
+       height: 1.2em;
+       border-radius: 1.2em;
+       background-color: #555555;
+       -webkit-transition: left 100ms ease, margin-left 100ms ease;
+          -moz-transition: left 100ms ease, margin-left 100ms ease;
+               transition: left 100ms ease, margin-left 100ms ease;
+}
+.oo-ui-toggleSwitchWidget-glow {
+       display: none;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+       left: 1.9em;
+       margin-left: -2px;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
+       left: 0.4em;
+       margin-left: 0;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on {
+       background-color: #347bff;
+       border-color: #347bff;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+       background-color: #ffffff;
+       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover {
+       border-color: #2962cc;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover.oo-ui-toggleWidget-on {
+       background-color: #2962cc;
+       border-color: #2962cc;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus {
+       border-color: #347bff;
+       outline: none;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on {
+       border-color: #347bff;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus.oo-ui-toggleWidget-on:before {
+       border-color: #ffffff;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover {
+       background-color: #347bff;
+       border-color: #347bff;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active .oo-ui-toggleSwitchWidget-grip,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover .oo-ui-toggleSwitchWidget-grip {
+       background-color: #ffffff;
+       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
+       background: #dddddd;
+       border-color: #dddddd;
+       outline: 0;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled .oo-ui-toggleSwitchWidget-grip {
+       background: #ffffff;
+}
+.oo-ui-progressBarWidget {
+       max-width: 50em;
+       background-color: #ffffff;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+       overflow: hidden;
+}
+.oo-ui-progressBarWidget-bar {
+       height: 1em;
+       background: #dddddd;
+       -webkit-transition: width 200ms, margin-left 200ms;
+          -moz-transition: width 200ms, margin-left 200ms;
+               transition: width 200ms, margin-left 200ms;
+}
+.oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
+       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+       width: 40%;
+       margin-left: -10%;
+       border-left-width: 1px;
+}
+.oo-ui-progressBarWidget.oo-ui-widget-disabled {
+       opacity: 0.6;
+}
+.oo-ui-selectFileWidget {
+       display: inline-block;
+       vertical-align: middle;
+       width: 100%;
+       max-width: 50em;
+       margin-right: 0.5em;
+}
+.oo-ui-selectFileWidget-selectButton {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
+       position: relative;
+       overflow: hidden;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > input[type="file"] {
+       position: absolute;
+       margin: 0;
+       top: 0;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       width: 100%;
+       height: 100%;
+       opacity: 0;
+       z-index: 1;
+       cursor: pointer;
+       padding-top: 100px;
+}
+.oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > input[type="file"] {
+       display: none;
+}
+.oo-ui-selectFileWidget-info {
+       width: 100%;
+       display: table-cell;
+       vertical-align: middle;
+       position: relative;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       text-overflow: ellipsis;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileName {
+       float: left;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+       float: right;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       position: absolute;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       z-index: 2;
+}
+.oo-ui-selectFileWidget-dropTarget {
+       cursor: default;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget {
+       cursor: pointer;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
+       display: none;
+}
+.oo-ui-selectFileWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
+       margin-left: 0.5em;
+}
+.oo-ui-selectFileWidget-info {
+       height: 2.4em;
+       background-color: #ffffff;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       right: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
+       left: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label {
+       line-height: 2.3em;
+       margin: 0;
+       overflow: hidden;
+       white-space: nowrap;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       text-overflow: ellipsis;
+       left: 0.5em;
+       right: 0.5em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-label > .oo-ui-selectFileWidget-fileType {
+       color: #888888;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton {
+       top: 0;
+       width: 1.875em;
+       margin-right: 0;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+       height: 2.3em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       top: 0;
+       width: 0.9375em;
+       height: 2.3em;
+       margin-right: 0.775em;
+}
+.oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
+       top: 0;
+       width: 1.875em;
+       height: 2.3em;
+       margin-left: 0.5em;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
+       color: #cccccc;
+}
+.oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       left: 2.875em;
+}
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 2.375em;
+}
+.oo-ui-selectFileWidget .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
+       right: 0;
+}
+.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 4.4625em;
+}
+.oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-clearButton {
+       right: 2.0875em;
+}
+.oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 0.5em;
+}
+.oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label,
+.oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-info .oo-ui-selectFileWidget-label {
+       right: 2em;
+}
+.oo-ui-selectFileWidget-dropTarget {
+       line-height: 3.5em;
+       background-color: #ffffff;
+       border: 1px dashed #cccccc;
+       padding: 0.5em 1em;
+       margin-bottom: 0.5em;
+       text-align: center;
+       vertical-align: middle;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropTarget:hover {
+       background-color: #eeeeee;
+}
+.oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop .oo-ui-selectFileWidget-dropTarget {
+       background: rgba(52, 123, 255, 0.1);
+}
+.oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-dropTarget,
+.oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-dropTarget {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-outlineOptionWidget {
+       position: relative;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       font-size: 1.1em;
+       padding: 0.75em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+       padding-right: 1.5em;
+}
+.oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget-level-0 {
+       padding-left: 3.5em;
+}
+.oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
+       left: 1em;
+}
+.oo-ui-outlineOptionWidget-level-1 {
+       padding-left: 5em;
+}
+.oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
+       left: 2.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 {
+       padding-left: 6.5em;
+}
+.oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
+       left: 4em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
+       background-color: #d0d0d0;
+       text-shadow: 0 1px 1px #ffffff;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
+       font-weight: bold;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-placeholder {
+       font-style: italic;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
+       opacity: 0.5;
+}
+.oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
+       color: #777777;
+}
+.oo-ui-outlineControlsWidget {
+       height: 3em;
+       background-color: #ffffff;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+       float: left;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+       float: left;
+       background-position: right center;
+}
+.oo-ui-outlineControlsWidget-items {
+       float: left;
+}
+.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
+       float: left;
+}
+.oo-ui-outlineControlsWidget-movers {
+       float: right;
+}
+.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
+       float: right;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+       height: 2em;
+       margin: 0.5em 0.5em 0.5em 0;
+       padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+       width: 1.5em;
+       height: 2em;
+       margin: 0.5em 0 0.5em 0.5em;
+       opacity: 0.2;
+}
+.oo-ui-tabSelectWidget {
+       text-align: left;
+       white-space: nowrap;
+       overflow: hidden;
+       background-color: #dddddd;
+}
+.oo-ui-tabOptionWidget {
+       display: inline-block;
+       vertical-align: bottom;
+       padding: 0.35em 1em;
+       margin: 0.5em 0 0 0.75em;
+       border: 1px solid transparent;
+       border-bottom: none;
+       border-top-left-radius: 2px;
+       border-top-right-radius: 2px;
+       color: #555555;
+       font-weight: bold;
+}
+.oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
+       background-color: rgba(255, 255, 255, 0.3);
+}
+.oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
+       background-color: rgba(255, 255, 255, 0.8);
+}
+.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+       padding-right: 1.5em;
+}
+.oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+       opacity: 0.5;
+}
+.oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
+       background-color: #ffffff;
+       color: #333333;
+}
+.oo-ui-capsuleMultiSelectWidget {
+       display: inline-block;
+       position: relative;
+       width: 100%;
+       max-width: 50em;
+}
+.oo-ui-capsuleMultiSelectWidget-handle {
+       width: 100%;
+       display: inline-block;
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget-content {
+       position: relative;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-content > input {
+       display: none;
+}
+.oo-ui-capsuleMultiSelectWidget-group {
+       display: inline;
+}
+.oo-ui-capsuleMultiSelectWidget > .oo-ui-menuSelectWidget {
+       z-index: 1;
+       width: 100%;
+}
+.oo-ui-capsuleMultiSelectWidget-handle {
+       background-color: #ffffff;
+       cursor: text;
+       min-height: 2.4em;
+       margin-right: 0.5em;
+       padding: 0.15em 0.25em;
+       border: 1px solid #cccccc;
+       border-radius: 2px;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-capsuleMultiSelectWidget-handle:last-child {
+       margin-right: 0;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator,
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input {
+       border: 0;
+       line-height: 1.675em;
+       margin: 0 0 0 0.2em;
+       padding: 0;
+       font-size: inherit;
+       font-family: inherit;
+       background-color: transparent;
+       color: #000000;
+       vertical-align: middle;
+}
+.oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-capsuleMultiSelectWidget-content > input:focus {
+       outline: none;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle {
+       padding-right: 2.4875em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
+       right: 0;
+       top: 0;
+       width: 0.9375em;
+       height: 0.9375em;
+       margin: 0.775em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle {
+       padding-left: 2.475em;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-iconElement .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon {
+       left: 0;
+       top: 0;
+       width: 1.875em;
+       height: 1.875em;
+       margin: 0.3em;
+}
+.oo-ui-capsuleMultiSelectWidget:hover .oo-ui-capsuleMultiSelectWidget-handle {
+       border-color: #aaaaaa;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+       cursor: default;
+}
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-iconElement-icon,
+.oo-ui-capsuleMultiSelectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiSelectWidget-handle > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-capsuleMultiSelectWidget .oo-ui-selectWidget {
+       border-top-color: #ffffff;
+}
+.oo-ui-capsuleItemWidget {
+       position: relative;
+       display: inline-block;
+       cursor: default;
+       white-space: nowrap;
+       width: auto;
+       max-width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       vertical-align: middle;
+       padding: 0 0.4em;
+       margin: 0.1em;
+       height: 1.7em;
+       line-height: 1.7em;
+       background-color: #eeeeee;
+       border: 1px solid #cccccc;
+       color: #555555;
+       border-radius: 2px;
+}
+.oo-ui-capsuleItemWidget > .oo-ui-iconElement-icon {
+       cursor: pointer;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-iconElement-icon {
+       cursor: default;
+}
+.oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       display: block;
+       text-overflow: ellipsis;
+       overflow: hidden;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-labelElement-label {
+       padding-right: 1.3375em;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
+       position: absolute;
+       right: 0.4em;
+       top: 0;
+       width: 0.9375em;
+       height: 100%;
+       background-repeat: no-repeat;
+}
+.oo-ui-capsuleItemWidget.oo-ui-indicatorElement > .oo-ui-indicator-clear {
+       cursor: pointer;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-disabled > .oo-ui-indicatorElement-indicator {
+       opacity: 0.2;
+}
+.oo-ui-searchWidget-query {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+       width: 100%;
+}
+.oo-ui-searchWidget-results {
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       overflow-x: hidden;
+       overflow-y: auto;
+}
+.oo-ui-searchWidget-query {
+       height: 4em;
+       padding: 0 1em;
+       border-bottom: 1px solid #cccccc;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+       margin: 0.75em 0;
+}
+.oo-ui-searchWidget-results {
+       top: 4em;
+       padding: 1em;
+       line-height: 0;
+}
+.oo-ui-numberInputWidget {
+       display: inline-block;
+       position: relative;
+       max-width: 50em;
+}
+.oo-ui-numberInputWidget-field {
+       display: table;
+       table-layout: fixed;
+       width: 100%;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget,
+.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+       display: table-cell;
+       vertical-align: middle;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-textInputWidget {
+       width: 100%;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
+       white-space: nowrap;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget > .oo-ui-buttonElement-button {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
+       width: 2.5em;
+}
+.oo-ui-numberInputWidget-minusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+       border-top-right-radius: 0;
+       border-bottom-right-radius: 0;
+       border-right-width: 0;
+}
+.oo-ui-numberInputWidget-plusButton.oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
+       border-top-left-radius: 0;
+       border-bottom-left-radius: 0;
+       border-left-width: 0;
+}
+.oo-ui-numberInputWidget .oo-ui-textInputWidget input {
+       border-radius: 0;
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-widgets.js b/resources/lib/oojs-ui/oojs-ui-widgets.js
new file mode 100644 (file)
index 0000000..5dbca20
--- /dev/null
@@ -0,0 +1,5131 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:00Z
+ */
+( function ( OO ) {
+
+'use strict';
+
+/**
+ * DraggableElement is a mixin class used to create elements that can be clicked
+ * and dragged by a mouse to a new position within a group. This class must be used
+ * in conjunction with OO.ui.mixin.DraggableGroupElement, which provides a container for
+ * the draggable elements.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ */
+OO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement() {
+       // Properties
+       this.index = null;
+
+       // Initialize and events
+       this.$element
+               .attr( 'draggable', true )
+               .addClass( 'oo-ui-draggableElement' )
+               .on( {
+                       dragstart: this.onDragStart.bind( this ),
+                       dragover: this.onDragOver.bind( this ),
+                       dragend: this.onDragEnd.bind( this ),
+                       drop: this.onDrop.bind( this )
+               } );
+};
+
+OO.initClass( OO.ui.mixin.DraggableElement );
+
+/* Events */
+
+/**
+ * @event dragstart
+ *
+ * A dragstart event is emitted when the user clicks and begins dragging an item.
+ * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with the mouse.
+ */
+
+/**
+ * @event dragend
+ * A dragend event is emitted when the user drags an item and releases the mouse,
+ * thus terminating the drag operation.
+ */
+
+/**
+ * @event drop
+ * A drop event is emitted when the user drags an item and then releases the mouse button
+ * over a valid target.
+ */
+
+/* Static Properties */
+
+/**
+ * @inheritdoc OO.ui.mixin.ButtonElement
+ */
+OO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;
+
+/* Methods */
+
+/**
+ * Respond to dragstart event.
+ *
+ * @private
+ * @param {jQuery.Event} event jQuery event
+ * @fires dragstart
+ */
+OO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {
+       var dataTransfer = e.originalEvent.dataTransfer;
+       // Define drop effect
+       dataTransfer.dropEffect = 'none';
+       dataTransfer.effectAllowed = 'move';
+       // Support: Firefox
+       // We must set up a dataTransfer data property or Firefox seems to
+       // ignore the fact the element is draggable.
+       try {
+               dataTransfer.setData( 'application-x/OOjs-UI-draggable', this.getIndex() );
+       } catch ( err ) {
+               // The above is only for Firefox. Move on if it fails.
+       }
+       // Add dragging class
+       this.$element.addClass( 'oo-ui-draggableElement-dragging' );
+       // Emit event
+       this.emit( 'dragstart', this );
+       return true;
+};
+
+/**
+ * Respond to dragend event.
+ *
+ * @private
+ * @fires dragend
+ */
+OO.ui.mixin.DraggableElement.prototype.onDragEnd = function () {
+       this.$element.removeClass( 'oo-ui-draggableElement-dragging' );
+       this.emit( 'dragend' );
+};
+
+/**
+ * Handle drop event.
+ *
+ * @private
+ * @param {jQuery.Event} event jQuery event
+ * @fires drop
+ */
+OO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {
+       e.preventDefault();
+       this.emit( 'drop', e );
+};
+
+/**
+ * In order for drag/drop to work, the dragover event must
+ * return false and stop propogation.
+ *
+ * @private
+ */
+OO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {
+       e.preventDefault();
+};
+
+/**
+ * Set item index.
+ * Store it in the DOM so we can access from the widget drag event
+ *
+ * @private
+ * @param {number} Item index
+ */
+OO.ui.mixin.DraggableElement.prototype.setIndex = function ( index ) {
+       if ( this.index !== index ) {
+               this.index = index;
+               this.$element.data( 'index', index );
+       }
+};
+
+/**
+ * Get item index
+ *
+ * @private
+ * @return {number} Item index
+ */
+OO.ui.mixin.DraggableElement.prototype.getIndex = function () {
+       return this.index;
+};
+
+/**
+ * DraggableGroupElement is a mixin class used to create a group element to
+ * contain draggable elements, which are items that can be clicked and dragged by a mouse.
+ * The class is used with OO.ui.mixin.DraggableElement.
+ *
+ * @abstract
+ * @class
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [orientation] Item orientation: 'horizontal' or 'vertical'. The orientation
+ *  should match the layout of the items. Items displayed in a single row
+ *  or in several rows should use horizontal orientation. The vertical orientation should only be
+ *  used when the items are displayed in a single column. Defaults to 'vertical'
+ */
+OO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.mixin.GroupElement.call( this, config );
+
+       // Properties
+       this.orientation = config.orientation || 'vertical';
+       this.dragItem = null;
+       this.itemDragOver = null;
+       this.itemKeys = {};
+       this.sideInsertion = '';
+
+       // Events
+       this.aggregate( {
+               dragstart: 'itemDragStart',
+               dragend: 'itemDragEnd',
+               drop: 'itemDrop'
+       } );
+       this.connect( this, {
+               itemDragStart: 'onItemDragStart',
+               itemDrop: 'onItemDrop',
+               itemDragEnd: 'onItemDragEnd'
+       } );
+       this.$element.on( {
+               dragover: this.onDragOver.bind( this ),
+               dragleave: this.onDragLeave.bind( this )
+       } );
+
+       // Initialize
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+       this.$placeholder = $( '<div>' )
+               .addClass( 'oo-ui-draggableGroupElement-placeholder' );
+       this.$element
+               .addClass( 'oo-ui-draggableGroupElement' )
+               .append( this.$status )
+               .toggleClass( 'oo-ui-draggableGroupElement-horizontal', this.orientation === 'horizontal' )
+               .prepend( this.$placeholder );
+};
+
+/* Setup */
+OO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );
+
+/* Events */
+
+/**
+ * A 'reorder' event is emitted when the order of items in the group changes.
+ *
+ * @event reorder
+ * @param {OO.ui.mixin.DraggableElement} item Reordered item
+ * @param {number} [newIndex] New index for the item
+ */
+
+/* Methods */
+
+/**
+ * Respond to item drag start event
+ *
+ * @private
+ * @param {OO.ui.mixin.DraggableElement} item Dragged item
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {
+       var i, len;
+
+       // Map the index of each object
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               this.items[ i ].setIndex( i );
+       }
+
+       if ( this.orientation === 'horizontal' ) {
+               // Set the height of the indicator
+               this.$placeholder.css( {
+                       height: item.$element.outerHeight(),
+                       width: 2
+               } );
+       } else {
+               // Set the width of the indicator
+               this.$placeholder.css( {
+                       height: 2,
+                       width: item.$element.outerWidth()
+               } );
+       }
+       this.setDragItem( item );
+};
+
+/**
+ * Respond to item drag end event
+ *
+ * @private
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.onItemDragEnd = function () {
+       this.unsetDragItem();
+       return false;
+};
+
+/**
+ * Handle drop event and switch the order of the items accordingly
+ *
+ * @private
+ * @param {OO.ui.mixin.DraggableElement} item Dropped item
+ * @fires reorder
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.onItemDrop = function ( item ) {
+       var toIndex = item.getIndex();
+       // Check if the dropped item is from the current group
+       // TODO: Figure out a way to configure a list of legally droppable
+       // elements even if they are not yet in the list
+       if ( this.getDragItem() ) {
+               // If the insertion point is 'after', the insertion index
+               // is shifted to the right (or to the left in RTL, hence 'after')
+               if ( this.sideInsertion === 'after' ) {
+                       toIndex++;
+               }
+               // Emit change event
+               this.emit( 'reorder', this.getDragItem(), toIndex );
+       }
+       this.unsetDragItem();
+       // Return false to prevent propogation
+       return false;
+};
+
+/**
+ * Handle dragleave event.
+ *
+ * @private
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.onDragLeave = function () {
+       // This means the item was dragged outside the widget
+       this.$placeholder
+               .css( 'left', 0 )
+               .addClass( 'oo-ui-element-hidden' );
+};
+
+/**
+ * Respond to dragover event
+ *
+ * @private
+ * @param {jQuery.Event} event Event details
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.onDragOver = function ( e ) {
+       var dragOverObj, $optionWidget, itemOffset, itemMidpoint, itemBoundingRect,
+               itemSize, cssOutput, dragPosition, itemIndex, itemPosition,
+               clientX = e.originalEvent.clientX,
+               clientY = e.originalEvent.clientY;
+
+       // Get the OptionWidget item we are dragging over
+       dragOverObj = this.getElementDocument().elementFromPoint( clientX, clientY );
+       $optionWidget = $( dragOverObj ).closest( '.oo-ui-draggableElement' );
+       if ( $optionWidget[ 0 ] ) {
+               itemOffset = $optionWidget.offset();
+               itemBoundingRect = $optionWidget[ 0 ].getBoundingClientRect();
+               itemPosition = $optionWidget.position();
+               itemIndex = $optionWidget.data( 'index' );
+       }
+
+       if (
+               itemOffset &&
+               this.isDragging() &&
+               itemIndex !== this.getDragItem().getIndex()
+       ) {
+               if ( this.orientation === 'horizontal' ) {
+                       // Calculate where the mouse is relative to the item width
+                       itemSize = itemBoundingRect.width;
+                       itemMidpoint = itemBoundingRect.left + itemSize / 2;
+                       dragPosition = clientX;
+                       // Which side of the item we hover over will dictate
+                       // where the placeholder will appear, on the left or
+                       // on the right
+                       cssOutput = {
+                               left: dragPosition < itemMidpoint ? itemPosition.left : itemPosition.left + itemSize,
+                               top: itemPosition.top
+                       };
+               } else {
+                       // Calculate where the mouse is relative to the item height
+                       itemSize = itemBoundingRect.height;
+                       itemMidpoint = itemBoundingRect.top + itemSize / 2;
+                       dragPosition = clientY;
+                       // Which side of the item we hover over will dictate
+                       // where the placeholder will appear, on the top or
+                       // on the bottom
+                       cssOutput = {
+                               top: dragPosition < itemMidpoint ? itemPosition.top : itemPosition.top + itemSize,
+                               left: itemPosition.left
+                       };
+               }
+               // Store whether we are before or after an item to rearrange
+               // For horizontal layout, we need to account for RTL, as this is flipped
+               if (  this.orientation === 'horizontal' && this.$element.css( 'direction' ) === 'rtl' ) {
+                       this.sideInsertion = dragPosition < itemMidpoint ? 'after' : 'before';
+               } else {
+                       this.sideInsertion = dragPosition < itemMidpoint ? 'before' : 'after';
+               }
+               // Add drop indicator between objects
+               this.$placeholder
+                       .css( cssOutput )
+                       .removeClass( 'oo-ui-element-hidden' );
+       } else {
+               // This means the item was dragged outside the widget
+               this.$placeholder
+                       .css( 'left', 0 )
+                       .addClass( 'oo-ui-element-hidden' );
+       }
+       // Prevent default
+       e.preventDefault();
+};
+
+/**
+ * Set a dragged item
+ *
+ * @param {OO.ui.mixin.DraggableElement} item Dragged item
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.setDragItem = function ( item ) {
+       this.dragItem = item;
+};
+
+/**
+ * Unset the current dragged item
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.unsetDragItem = function () {
+       this.dragItem = null;
+       this.itemDragOver = null;
+       this.$placeholder.addClass( 'oo-ui-element-hidden' );
+       this.sideInsertion = '';
+};
+
+/**
+ * Get the item that is currently being dragged.
+ *
+ * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is being dragged
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.getDragItem = function () {
+       return this.dragItem;
+};
+
+/**
+ * Check if an item in the group is currently being dragged.
+ *
+ * @return {Boolean} Item is being dragged
+ */
+OO.ui.mixin.DraggableGroupElement.prototype.isDragging = function () {
+       return this.getDragItem() !== null;
+};
+
+/**
+ * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget, such as
+ * the {@link OO.ui.mixin.LookupElement}.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ */
+OO.ui.mixin.RequestManager = function OoUiMixinRequestManager() {
+       this.requestCache = {};
+       this.requestQuery = null;
+       this.requestRequest = null;
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.mixin.RequestManager );
+
+/**
+ * Get request results for the current query.
+ *
+ * @return {jQuery.Promise} Promise object which will be passed response data as the first argument of
+ *   the done event. If the request was aborted to make way for a subsequent request, this promise
+ *   may not be rejected, depending on what jQuery feels like doing.
+ */
+OO.ui.mixin.RequestManager.prototype.getRequestData = function () {
+       var widget = this,
+               value = this.getRequestQuery(),
+               deferred = $.Deferred(),
+               ourRequest;
+
+       this.abortRequest();
+       if ( Object.prototype.hasOwnProperty.call( this.requestCache, value ) ) {
+               deferred.resolve( this.requestCache[ value ] );
+       } else {
+               if ( this.pushPending ) {
+                       this.pushPending();
+               }
+               this.requestQuery = value;
+               ourRequest = this.requestRequest = this.getRequest();
+               ourRequest
+                       .always( function () {
+                               // We need to pop pending even if this is an old request, otherwise
+                               // the widget will remain pending forever.
+                               // TODO: this assumes that an aborted request will fail or succeed soon after
+                               // being aborted, or at least eventually. It would be nice if we could popPending()
+                               // at abort time, but only if we knew that we hadn't already called popPending()
+                               // for that request.
+                               if ( widget.popPending ) {
+                                       widget.popPending();
+                               }
+                       } )
+                       .done( function ( response ) {
+                               // If this is an old request (and aborting it somehow caused it to still succeed),
+                               // ignore its success completely
+                               if ( ourRequest === widget.requestRequest ) {
+                                       widget.requestQuery = null;
+                                       widget.requestRequest = null;
+                                       widget.requestCache[ value ] = widget.getRequestCacheDataFromResponse( response );
+                                       deferred.resolve( widget.requestCache[ value ] );
+                               }
+                       } )
+                       .fail( function () {
+                               // If this is an old request (or a request failing because it's being aborted),
+                               // ignore its failure completely
+                               if ( ourRequest === widget.requestRequest ) {
+                                       widget.requestQuery = null;
+                                       widget.requestRequest = null;
+                                       deferred.reject();
+                               }
+                       } );
+       }
+       return deferred.promise();
+};
+
+/**
+ * Abort the currently pending request, if any.
+ *
+ * @private
+ */
+OO.ui.mixin.RequestManager.prototype.abortRequest = function () {
+       var oldRequest = this.requestRequest;
+       if ( oldRequest ) {
+               // First unset this.requestRequest to the fail handler will notice
+               // that the request is no longer current
+               this.requestRequest = null;
+               this.requestQuery = null;
+               oldRequest.abort();
+       }
+};
+
+/**
+ * Get the query to be made.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @return {string} query to be used
+ */
+OO.ui.mixin.RequestManager.prototype.getRequestQuery = null;
+
+/**
+ * Get a new request object of the current query value.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
+ */
+OO.ui.mixin.RequestManager.prototype.getRequest = null;
+
+/**
+ * Pre-process data returned by the request from #getRequest.
+ *
+ * The return value of this function will be cached, and any further queries for the given value
+ * will use the cache rather than doing API requests.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @param {Mixed} response Response from server
+ * @return {Mixed} Cached result data
+ */
+OO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;
+
+/**
+ * LookupElement is a mixin that creates a {@link OO.ui.FloatingMenuSelectWidget menu} of suggested values for
+ * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
+ * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
+ * from the lookup menu, that value becomes the value of the input field.
+ *
+ * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is
+ * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then
+ * re-enable lookups.
+ *
+ * See the [OOjs UI demos][1] for an example.
+ *
+ * [1]: https://tools.wmflabs.org/oojs-ui/oojs-ui/demos/index.html#widgets-apex-vector-ltr
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning
+ * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
+ * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
+ *  By default, the lookup menu is not generated and displayed until the user begins to type.
+ * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can
+ *  take it over into the input with simply pressing return) automatically or not.
+ */
+OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
+       // Configuration initialization
+       config = $.extend( { highlightFirst: true }, config );
+
+       // Mixin constructors
+       OO.ui.mixin.RequestManager.call( this, config );
+
+       // Properties
+       this.$overlay = config.$overlay || this.$element;
+       this.lookupMenu = new OO.ui.FloatingMenuSelectWidget( {
+               widget: this,
+               input: this,
+               $container: config.$container || this.$element
+       } );
+
+       this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;
+
+       this.lookupsDisabled = false;
+       this.lookupInputFocused = false;
+       this.lookupHighlightFirstItem = config.highlightFirst;
+
+       // Events
+       this.$input.on( {
+               focus: this.onLookupInputFocus.bind( this ),
+               blur: this.onLookupInputBlur.bind( this ),
+               mousedown: this.onLookupInputMouseDown.bind( this )
+       } );
+       this.connect( this, { change: 'onLookupInputChange' } );
+       this.lookupMenu.connect( this, {
+               toggle: 'onLookupMenuToggle',
+               choose: 'onLookupMenuItemChoose'
+       } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-lookupElement' );
+       this.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );
+       this.$overlay.append( this.lookupMenu.$element );
+};
+
+/* Setup */
+
+OO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );
+
+/* Methods */
+
+/**
+ * Handle input focus event.
+ *
+ * @protected
+ * @param {jQuery.Event} e Input focus event
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {
+       this.lookupInputFocused = true;
+       this.populateLookupMenu();
+};
+
+/**
+ * Handle input blur event.
+ *
+ * @protected
+ * @param {jQuery.Event} e Input blur event
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {
+       this.closeLookupMenu();
+       this.lookupInputFocused = false;
+};
+
+/**
+ * Handle input mouse down event.
+ *
+ * @protected
+ * @param {jQuery.Event} e Input mouse down event
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {
+       // Only open the menu if the input was already focused.
+       // This way we allow the user to open the menu again after closing it with Esc
+       // by clicking in the input. Opening (and populating) the menu when initially
+       // clicking into the input is handled by the focus handler.
+       if ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {
+               this.populateLookupMenu();
+       }
+};
+
+/**
+ * Handle input change event.
+ *
+ * @protected
+ * @param {string} value New input value
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {
+       if ( this.lookupInputFocused ) {
+               this.populateLookupMenu();
+       }
+};
+
+/**
+ * Handle the lookup menu being shown/hidden.
+ *
+ * @protected
+ * @param {boolean} visible Whether the lookup menu is now visible.
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {
+       if ( !visible ) {
+               // When the menu is hidden, abort any active request and clear the menu.
+               // This has to be done here in addition to closeLookupMenu(), because
+               // MenuSelectWidget will close itself when the user presses Esc.
+               this.abortLookupRequest();
+               this.lookupMenu.clearItems();
+       }
+};
+
+/**
+ * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.
+ *
+ * @protected
+ * @param {OO.ui.MenuOptionWidget} item Selected item
+ */
+OO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {
+       this.setValue( item.getData() );
+};
+
+/**
+ * Get lookup menu.
+ *
+ * @private
+ * @return {OO.ui.FloatingMenuSelectWidget}
+ */
+OO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {
+       return this.lookupMenu;
+};
+
+/**
+ * Disable or re-enable lookups.
+ *
+ * When lookups are disabled, calls to #populateLookupMenu will be ignored.
+ *
+ * @param {boolean} disabled Disable lookups
+ */
+OO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {
+       this.lookupsDisabled = !!disabled;
+};
+
+/**
+ * Open the menu. If there are no entries in the menu, this does nothing.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {
+       if ( !this.lookupMenu.isEmpty() ) {
+               this.lookupMenu.toggle( true );
+       }
+       return this;
+};
+
+/**
+ * Close the menu, empty it, and abort any pending request.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {
+       this.lookupMenu.toggle( false );
+       this.abortLookupRequest();
+       this.lookupMenu.clearItems();
+       return this;
+};
+
+/**
+ * Request menu items based on the input's current value, and when they arrive,
+ * populate the menu with these items and show the menu.
+ *
+ * If lookups have been disabled with #setLookupsDisabled, this function does nothing.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {
+       var widget = this,
+               value = this.getValue();
+
+       if ( this.lookupsDisabled || this.isReadOnly() ) {
+               return;
+       }
+
+       // If the input is empty, clear the menu, unless suggestions when empty are allowed.
+       if ( !this.allowSuggestionsWhenEmpty && value === '' ) {
+               this.closeLookupMenu();
+       // Skip population if there is already a request pending for the current value
+       } else if ( value !== this.lookupQuery ) {
+               this.getLookupMenuItems()
+                       .done( function ( items ) {
+                               widget.lookupMenu.clearItems();
+                               if ( items.length ) {
+                                       widget.lookupMenu
+                                               .addItems( items )
+                                               .toggle( true );
+                                       widget.initializeLookupMenuSelection();
+                               } else {
+                                       widget.lookupMenu.toggle( false );
+                               }
+                       } )
+                       .fail( function () {
+                               widget.lookupMenu.clearItems();
+                       } );
+       }
+
+       return this;
+};
+
+/**
+ * Highlight the first selectable item in the menu, if configured.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {
+       if ( this.lookupHighlightFirstItem && !this.lookupMenu.getSelectedItem() ) {
+               this.lookupMenu.highlightItem( this.lookupMenu.getFirstSelectableItem() );
+       }
+};
+
+/**
+ * Get lookup menu items for the current query.
+ *
+ * @private
+ * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of
+ *   the done event. If the request was aborted to make way for a subsequent request, this promise
+ *   will not be rejected: it will remain pending forever.
+ */
+OO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {
+       return this.getRequestData().then( function ( data ) {
+               return this.getLookupMenuOptionsFromData( data );
+       }.bind( this ) );
+};
+
+/**
+ * Abort the currently pending lookup request, if any.
+ *
+ * @private
+ */
+OO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {
+       this.abortRequest();
+};
+
+/**
+ * Get a new request object of the current lookup query value.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
+ */
+OO.ui.mixin.LookupElement.prototype.getLookupRequest = null;
+
+/**
+ * Pre-process data returned by the request from #getLookupRequest.
+ *
+ * The return value of this function will be cached, and any further queries for the given value
+ * will use the cache rather than doing API requests.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @param {Mixed} response Response from server
+ * @return {Mixed} Cached result data
+ */
+OO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;
+
+/**
+ * Get a list of menu option widgets from the (possibly cached) data returned by
+ * #getLookupCacheDataFromResponse.
+ *
+ * @protected
+ * @method
+ * @abstract
+ * @param {Mixed} data Cached result data, usually an array
+ * @return {OO.ui.MenuOptionWidget[]} Menu items
+ */
+OO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;
+
+/**
+ * Set the read-only state of the widget.
+ *
+ * This will also disable/enable the lookups functionality.
+ *
+ * @param {boolean} readOnly Make input read-only
+ * @chainable
+ */
+OO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {
+       // Parent method
+       // Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget
+       OO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );
+
+       // During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor
+       if ( this.isReadOnly() && this.lookupMenu ) {
+               this.closeLookupMenu();
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc OO.ui.mixin.RequestManager
+ */
+OO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {
+       return this.getValue();
+};
+
+/**
+ * @inheritdoc OO.ui.mixin.RequestManager
+ */
+OO.ui.mixin.LookupElement.prototype.getRequest = function () {
+       return this.getLookupRequest();
+};
+
+/**
+ * @inheritdoc OO.ui.mixin.RequestManager
+ */
+OO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {
+       return this.getLookupCacheDataFromResponse( response );
+};
+
+/**
+ * CardLayouts are used within {@link OO.ui.IndexLayout index layouts} to create cards that users can select and display
+ * from the index's optional {@link OO.ui.TabSelectWidget tab} navigation. Cards are usually not instantiated directly,
+ * rather extended to include the required content and functionality.
+ *
+ * Each card must have a unique symbolic name, which is passed to the constructor. In addition, the card's tab
+ * item is customized (with a label) using the #setupTabItem method. See
+ * {@link OO.ui.IndexLayout IndexLayout} for an example.
+ *
+ * @class
+ * @extends OO.ui.PanelLayout
+ *
+ * @constructor
+ * @param {string} name Unique symbolic name of card
+ * @param {Object} [config] Configuration options
+ * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] Label for card's tab
+ */
+OO.ui.CardLayout = function OoUiCardLayout( name, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( name ) && config === undefined ) {
+               config = name;
+               name = config.name;
+       }
+
+       // Configuration initialization
+       config = $.extend( { scrollable: true }, config );
+
+       // Parent constructor
+       OO.ui.CardLayout.parent.call( this, config );
+
+       // Properties
+       this.name = name;
+       this.label = config.label;
+       this.tabItem = null;
+       this.active = false;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-cardLayout' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.CardLayout, OO.ui.PanelLayout );
+
+/* Events */
+
+/**
+ * An 'active' event is emitted when the card becomes active. Cards become active when they are
+ * shown in a index layout that is configured to display only one card at a time.
+ *
+ * @event active
+ * @param {boolean} active Card is active
+ */
+
+/* Methods */
+
+/**
+ * Get the symbolic name of the card.
+ *
+ * @return {string} Symbolic name of card
+ */
+OO.ui.CardLayout.prototype.getName = function () {
+       return this.name;
+};
+
+/**
+ * Check if card is active.
+ *
+ * Cards become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is configured to display
+ * only one card at a time. Additional CSS is applied to the card's tab item to reflect the active state.
+ *
+ * @return {boolean} Card is active
+ */
+OO.ui.CardLayout.prototype.isActive = function () {
+       return this.active;
+};
+
+/**
+ * Get tab item.
+ *
+ * The tab item allows users to access the card from the index's tab
+ * navigation. The tab item itself can be customized (with a label, level, etc.) using the #setupTabItem method.
+ *
+ * @return {OO.ui.TabOptionWidget|null} Tab option widget
+ */
+OO.ui.CardLayout.prototype.getTabItem = function () {
+       return this.tabItem;
+};
+
+/**
+ * Set or unset the tab item.
+ *
+ * Specify a {@link OO.ui.TabOptionWidget tab option} to set it,
+ * or `null` to clear the tab item. To customize the tab item itself (e.g., to set a label or tab
+ * level), use #setupTabItem instead of this method.
+ *
+ * @param {OO.ui.TabOptionWidget|null} tabItem Tab option widget, null to clear
+ * @chainable
+ */
+OO.ui.CardLayout.prototype.setTabItem = function ( tabItem ) {
+       this.tabItem = tabItem || null;
+       if ( tabItem ) {
+               this.setupTabItem();
+       }
+       return this;
+};
+
+/**
+ * Set up the tab item.
+ *
+ * Use this method to customize the tab item (e.g., to add a label or tab level). To set or unset
+ * the tab item itself (with a {@link OO.ui.TabOptionWidget tab option} or `null`), use
+ * the #setTabItem method instead.
+ *
+ * @param {OO.ui.TabOptionWidget} tabItem Tab option widget to set up
+ * @chainable
+ */
+OO.ui.CardLayout.prototype.setupTabItem = function () {
+       if ( this.label ) {
+               this.tabItem.setLabel( this.label );
+       }
+       return this;
+};
+
+/**
+ * Set the card to its 'active' state.
+ *
+ * Cards become active when they are shown in a index layout that is configured to display only one card at a time. Additional
+ * CSS is applied to the tab item to reflect the card's active state. Outside of the index
+ * context, setting the active state on a card does nothing.
+ *
+ * @param {boolean} value Card is active
+ * @fires active
+ */
+OO.ui.CardLayout.prototype.setActive = function ( active ) {
+       active = !!active;
+
+       if ( active !== this.active ) {
+               this.active = active;
+               this.$element.toggleClass( 'oo-ui-cardLayout-active', this.active );
+               this.emit( 'active', this.active );
+       }
+};
+
+/**
+ * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that users can select and display
+ * from the booklet's optional {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated directly,
+ * rather extended to include the required content and functionality.
+ *
+ * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the page's outline
+ * item is customized (with a label, outline level, etc.) using the #setupOutlineItem method. See
+ * {@link OO.ui.BookletLayout BookletLayout} for an example.
+ *
+ * @class
+ * @extends OO.ui.PanelLayout
+ *
+ * @constructor
+ * @param {string} name Unique symbolic name of page
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.PageLayout = function OoUiPageLayout( name, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( name ) && config === undefined ) {
+               config = name;
+               name = config.name;
+       }
+
+       // Configuration initialization
+       config = $.extend( { scrollable: true }, config );
+
+       // Parent constructor
+       OO.ui.PageLayout.parent.call( this, config );
+
+       // Properties
+       this.name = name;
+       this.outlineItem = null;
+       this.active = false;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-pageLayout' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.PageLayout, OO.ui.PanelLayout );
+
+/* Events */
+
+/**
+ * An 'active' event is emitted when the page becomes active. Pages become active when they are
+ * shown in a booklet layout that is configured to display only one page at a time.
+ *
+ * @event active
+ * @param {boolean} active Page is active
+ */
+
+/* Methods */
+
+/**
+ * Get the symbolic name of the page.
+ *
+ * @return {string} Symbolic name of page
+ */
+OO.ui.PageLayout.prototype.getName = function () {
+       return this.name;
+};
+
+/**
+ * Check if page is active.
+ *
+ * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is configured to display
+ * only one page at a time. Additional CSS is applied to the page's outline item to reflect the active state.
+ *
+ * @return {boolean} Page is active
+ */
+OO.ui.PageLayout.prototype.isActive = function () {
+       return this.active;
+};
+
+/**
+ * Get outline item.
+ *
+ * The outline item allows users to access the page from the booklet's outline
+ * navigation. The outline item itself can be customized (with a label, level, etc.) using the #setupOutlineItem method.
+ *
+ * @return {OO.ui.OutlineOptionWidget|null} Outline option widget
+ */
+OO.ui.PageLayout.prototype.getOutlineItem = function () {
+       return this.outlineItem;
+};
+
+/**
+ * Set or unset the outline item.
+ *
+ * Specify an {@link OO.ui.OutlineOptionWidget outline option} to set it,
+ * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label or outline
+ * level), use #setupOutlineItem instead of this method.
+ *
+ * @param {OO.ui.OutlineOptionWidget|null} outlineItem Outline option widget, null to clear
+ * @chainable
+ */
+OO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {
+       this.outlineItem = outlineItem || null;
+       if ( outlineItem ) {
+               this.setupOutlineItem();
+       }
+       return this;
+};
+
+/**
+ * Set up the outline item.
+ *
+ * Use this method to customize the outline item (e.g., to add a label or outline level). To set or unset
+ * the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or `null`), use
+ * the #setOutlineItem method instead.
+ *
+ * @param {OO.ui.OutlineOptionWidget} outlineItem Outline option widget to set up
+ * @chainable
+ */
+OO.ui.PageLayout.prototype.setupOutlineItem = function () {
+       return this;
+};
+
+/**
+ * Set the page to its 'active' state.
+ *
+ * Pages become active when they are shown in a booklet layout that is configured to display only one page at a time. Additional
+ * CSS is applied to the outline item to reflect the page's active state. Outside of the booklet
+ * context, setting the active state on a page does nothing.
+ *
+ * @param {boolean} value Page is active
+ * @fires active
+ */
+OO.ui.PageLayout.prototype.setActive = function ( active ) {
+       active = !!active;
+
+       if ( active !== this.active ) {
+               this.active = active;
+               this.$element.toggleClass( 'oo-ui-pageLayout-active', active );
+               this.emit( 'active', this.active );
+       }
+};
+
+/**
+ * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one panel is displayed
+ * at a time, though the stack layout can also be configured to show all contained panels, one after another,
+ * by setting the #continuous option to 'true'.
+ *
+ *     @example
+ *     // A stack layout with two panels, configured to be displayed continously
+ *     var myStack = new OO.ui.StackLayout( {
+ *         items: [
+ *             new OO.ui.PanelLayout( {
+ *                 $content: $( '<p>Panel One</p>' ),
+ *                 padded: true,
+ *                 framed: true
+ *             } ),
+ *             new OO.ui.PanelLayout( {
+ *                 $content: $( '<p>Panel Two</p>' ),
+ *                 padded: true,
+ *                 framed: true
+ *             } )
+ *         ],
+ *         continuous: true
+ *     } );
+ *     $( 'body' ).append( myStack.$element );
+ *
+ * @class
+ * @extends OO.ui.PanelLayout
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel is displayed at a time.
+ * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.
+ */
+OO.ui.StackLayout = function OoUiStackLayout( config ) {
+       // Configuration initialization
+       config = $.extend( { scrollable: true }, config );
+
+       // Parent constructor
+       OO.ui.StackLayout.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
+
+       // Properties
+       this.currentItem = null;
+       this.continuous = !!config.continuous;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-stackLayout' );
+       if ( this.continuous ) {
+               this.$element.addClass( 'oo-ui-stackLayout-continuous' );
+               this.$element.on( 'scroll', OO.ui.debounce( this.onScroll.bind( this ), 250 ) );
+       }
+       if ( Array.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.StackLayout, OO.ui.PanelLayout );
+OO.mixinClass( OO.ui.StackLayout, OO.ui.mixin.GroupElement );
+
+/* Events */
+
+/**
+ * A 'set' event is emitted when panels are {@link #addItems added}, {@link #removeItems removed},
+ * {@link #clearItems cleared} or {@link #setItem displayed}.
+ *
+ * @event set
+ * @param {OO.ui.Layout|null} item Current panel or `null` if no panel is shown
+ */
+
+/**
+ * When used in continuous mode, this event is emitted when the user scrolls down
+ * far enough such that currentItem is no longer visible.
+ *
+ * @event visibleItemChange
+ * @param {OO.ui.PanelLayout} panel The next visible item in the layout
+ */
+
+/* Methods */
+
+/**
+ * Handle scroll events from the layout element
+ *
+ * @param {jQuery.Event} e
+ * @fires visibleItemChange
+ */
+OO.ui.StackLayout.prototype.onScroll = function () {
+       var currentRect,
+               len = this.items.length,
+               currentIndex = this.items.indexOf( this.currentItem ),
+               newIndex = currentIndex,
+               containerRect = this.$element[ 0 ].getBoundingClientRect();
+
+       if ( !containerRect || ( !containerRect.top && !containerRect.bottom ) ) {
+               // Can't get bounding rect, possibly not attached.
+               return;
+       }
+
+       function getRect( item ) {
+               return item.$element[ 0 ].getBoundingClientRect();
+       }
+
+       function isVisible( item ) {
+               var rect = getRect( item );
+               return rect.bottom > containerRect.top && rect.top < containerRect.bottom;
+       }
+
+       currentRect = getRect( this.currentItem );
+
+       if ( currentRect.bottom < containerRect.top ) {
+               // Scrolled down past current item
+               while ( ++newIndex < len ) {
+                       if ( isVisible( this.items[ newIndex ] ) ) {
+                               break;
+                       }
+               }
+       } else if ( currentRect.top > containerRect.bottom ) {
+               // Scrolled up past current item
+               while ( --newIndex >= 0 ) {
+                       if ( isVisible( this.items[ newIndex ] ) ) {
+                               break;
+                       }
+               }
+       }
+
+       if ( newIndex !== currentIndex ) {
+               this.emit( 'visibleItemChange', this.items[ newIndex ] );
+       }
+};
+
+/**
+ * Get the current panel.
+ *
+ * @return {OO.ui.Layout|null}
+ */
+OO.ui.StackLayout.prototype.getCurrentItem = function () {
+       return this.currentItem;
+};
+
+/**
+ * Unset the current item.
+ *
+ * @private
+ * @param {OO.ui.StackLayout} layout
+ * @fires set
+ */
+OO.ui.StackLayout.prototype.unsetCurrentItem = function () {
+       var prevItem = this.currentItem;
+       if ( prevItem === null ) {
+               return;
+       }
+
+       this.currentItem = null;
+       this.emit( 'set', null );
+};
+
+/**
+ * Add panel layouts to the stack layout.
+ *
+ * Panels will be added to the end of the stack layout array unless the optional index parameter specifies a different
+ * insertion point. Adding a panel that is already in the stack will move it to the end of the array or the point specified
+ * by the index.
+ *
+ * @param {OO.ui.Layout[]} items Panels to add
+ * @param {number} [index] Index of the insertion point
+ * @chainable
+ */
+OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
+       // Update the visibility
+       this.updateHiddenState( items, this.currentItem );
+
+       // Mixin method
+       OO.ui.mixin.GroupElement.prototype.addItems.call( this, items, index );
+
+       if ( !this.currentItem && items.length ) {
+               this.setItem( items[ 0 ] );
+       }
+
+       return this;
+};
+
+/**
+ * Remove the specified panels from the stack layout.
+ *
+ * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all panels,
+ * you may wish to use the #clearItems method instead.
+ *
+ * @param {OO.ui.Layout[]} items Panels to remove
+ * @chainable
+ * @fires set
+ */
+OO.ui.StackLayout.prototype.removeItems = function ( items ) {
+       // Mixin method
+       OO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );
+
+       if ( items.indexOf( this.currentItem ) !== -1 ) {
+               if ( this.items.length ) {
+                       this.setItem( this.items[ 0 ] );
+               } else {
+                       this.unsetCurrentItem();
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Clear all panels from the stack layout.
+ *
+ * Cleared panels are detached from the DOM, not removed, so that they may be reused. To remove only
+ * a subset of panels, use the #removeItems method.
+ *
+ * @chainable
+ * @fires set
+ */
+OO.ui.StackLayout.prototype.clearItems = function () {
+       this.unsetCurrentItem();
+       OO.ui.mixin.GroupElement.prototype.clearItems.call( this );
+
+       return this;
+};
+
+/**
+ * Show the specified panel.
+ *
+ * If another panel is currently displayed, it will be hidden.
+ *
+ * @param {OO.ui.Layout} item Panel to show
+ * @chainable
+ * @fires set
+ */
+OO.ui.StackLayout.prototype.setItem = function ( item ) {
+       if ( item !== this.currentItem ) {
+               this.updateHiddenState( this.items, item );
+
+               if ( this.items.indexOf( item ) !== -1 ) {
+                       this.currentItem = item;
+                       this.emit( 'set', item );
+               } else {
+                       this.unsetCurrentItem();
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Update the visibility of all items in case of non-continuous view.
+ *
+ * Ensure all items are hidden except for the selected one.
+ * This method does nothing when the stack is continuous.
+ *
+ * @private
+ * @param {OO.ui.Layout[]} items Item list iterate over
+ * @param {OO.ui.Layout} [selectedItem] Selected item to show
+ */
+OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) {
+       var i, len;
+
+       if ( !this.continuous ) {
+               for ( i = 0, len = items.length; i < len; i++ ) {
+                       if ( !selectedItem || selectedItem !== items[ i ] ) {
+                               items[ i ].$element.addClass( 'oo-ui-element-hidden' );
+                       }
+               }
+               if ( selectedItem ) {
+                       selectedItem.$element.removeClass( 'oo-ui-element-hidden' );
+               }
+       }
+};
+
+/**
+ * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned relative to the content (after, before, top, or bottom)
+ * and its size is customized with the #menuSize config. The content area will fill all remaining space.
+ *
+ *     @example
+ *     var menuLayout = new OO.ui.MenuLayout( {
+ *         position: 'top'
+ *     } ),
+ *         menuPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
+ *         contentPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
+ *         select = new OO.ui.SelectWidget( {
+ *             items: [
+ *                 new OO.ui.OptionWidget( {
+ *                     data: 'before',
+ *                     label: 'Before',
+ *                 } ),
+ *                 new OO.ui.OptionWidget( {
+ *                     data: 'after',
+ *                     label: 'After',
+ *                 } ),
+ *                 new OO.ui.OptionWidget( {
+ *                     data: 'top',
+ *                     label: 'Top',
+ *                 } ),
+ *                 new OO.ui.OptionWidget( {
+ *                     data: 'bottom',
+ *                     label: 'Bottom',
+ *                 } )
+ *              ]
+ *         } ).on( 'select', function ( item ) {
+ *            menuLayout.setMenuPosition( item.getData() );
+ *         } );
+ *
+ *     menuLayout.$menu.append(
+ *         menuPanel.$element.append( '<b>Menu panel</b>', select.$element )
+ *     );
+ *     menuLayout.$content.append(
+ *         contentPanel.$element.append( '<b>Content panel</b>', '<p>Note that the menu is positioned relative to the content panel: top, bottom, after, before.</p>')
+ *     );
+ *     $( 'body' ).append( menuLayout.$element );
+ *
+ * If menu size needs to be overridden, it can be accomplished using CSS similar to the snippet
+ * below. MenuLayout's CSS will override the appropriate values with 'auto' or '0' to display the
+ * menu correctly. If `menuPosition` is known beforehand, CSS rules corresponding to other positions
+ * may be omitted.
+ *
+ *     .oo-ui-menuLayout-menu {
+ *         height: 200px;
+ *         width: 200px;
+ *     }
+ *     .oo-ui-menuLayout-content {
+ *         top: 200px;
+ *         left: 200px;
+ *         right: 200px;
+ *         bottom: 200px;
+ *     }
+ *
+ * @class
+ * @extends OO.ui.Layout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [showMenu=true] Show menu
+ * @cfg {string} [menuPosition='before'] Position of menu: `top`, `after`, `bottom` or `before`
+ */
+OO.ui.MenuLayout = function OoUiMenuLayout( config ) {
+       // Configuration initialization
+       config = $.extend( {
+               showMenu: true,
+               menuPosition: 'before'
+       }, config );
+
+       // Parent constructor
+       OO.ui.MenuLayout.parent.call( this, config );
+
+       /**
+        * Menu DOM node
+        *
+        * @property {jQuery}
+        */
+       this.$menu = $( '<div>' );
+       /**
+        * Content DOM node
+        *
+        * @property {jQuery}
+        */
+       this.$content = $( '<div>' );
+
+       // Initialization
+       this.$menu
+               .addClass( 'oo-ui-menuLayout-menu' );
+       this.$content.addClass( 'oo-ui-menuLayout-content' );
+       this.$element
+               .addClass( 'oo-ui-menuLayout' )
+               .append( this.$content, this.$menu );
+       this.setMenuPosition( config.menuPosition );
+       this.toggleMenu( config.showMenu );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );
+
+/* Methods */
+
+/**
+ * Toggle menu.
+ *
+ * @param {boolean} showMenu Show menu, omit to toggle
+ * @chainable
+ */
+OO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {
+       showMenu = showMenu === undefined ? !this.showMenu : !!showMenu;
+
+       if ( this.showMenu !== showMenu ) {
+               this.showMenu = showMenu;
+               this.$element
+                       .toggleClass( 'oo-ui-menuLayout-showMenu', this.showMenu )
+                       .toggleClass( 'oo-ui-menuLayout-hideMenu', !this.showMenu );
+       }
+
+       return this;
+};
+
+/**
+ * Check if menu is visible
+ *
+ * @return {boolean} Menu is visible
+ */
+OO.ui.MenuLayout.prototype.isMenuVisible = function () {
+       return this.showMenu;
+};
+
+/**
+ * Set menu position.
+ *
+ * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`
+ * @throws {Error} If position value is not supported
+ * @chainable
+ */
+OO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {
+       this.$element.removeClass( 'oo-ui-menuLayout-' + this.menuPosition );
+       this.menuPosition = position;
+       this.$element.addClass( 'oo-ui-menuLayout-' + position );
+
+       return this;
+};
+
+/**
+ * Get menu position.
+ *
+ * @return {string} Menu position
+ */
+OO.ui.MenuLayout.prototype.getMenuPosition = function () {
+       return this.menuPosition;
+};
+
+/**
+ * BookletLayouts contain {@link OO.ui.PageLayout page layouts} as well as
+ * an {@link OO.ui.OutlineSelectWidget outline} that allows users to easily navigate
+ * through the pages and select which one to display. By default, only one page is
+ * displayed at a time and the outline is hidden. When a user navigates to a new page,
+ * the booklet layout automatically focuses on the first focusable element, unless the
+ * default setting is changed. Optionally, booklets can be configured to show
+ * {@link OO.ui.OutlineControlsWidget controls} for adding, moving, and removing items.
+ *
+ *     @example
+ *     // Example of a BookletLayout that contains two PageLayouts.
+ *
+ *     function PageOneLayout( name, config ) {
+ *         PageOneLayout.parent.call( this, name, config );
+ *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on the left)</p>' );
+ *     }
+ *     OO.inheritClass( PageOneLayout, OO.ui.PageLayout );
+ *     PageOneLayout.prototype.setupOutlineItem = function () {
+ *         this.outlineItem.setLabel( 'Page One' );
+ *     };
+ *
+ *     function PageTwoLayout( name, config ) {
+ *         PageTwoLayout.parent.call( this, name, config );
+ *         this.$element.append( '<p>Second page</p>' );
+ *     }
+ *     OO.inheritClass( PageTwoLayout, OO.ui.PageLayout );
+ *     PageTwoLayout.prototype.setupOutlineItem = function () {
+ *         this.outlineItem.setLabel( 'Page Two' );
+ *     };
+ *
+ *     var page1 = new PageOneLayout( 'one' ),
+ *         page2 = new PageTwoLayout( 'two' );
+ *
+ *     var booklet = new OO.ui.BookletLayout( {
+ *         outlined: true
+ *     } );
+ *
+ *     booklet.addPages ( [ page1, page2 ] );
+ *     $( 'body' ).append( booklet.$element );
+ *
+ * @class
+ * @extends OO.ui.MenuLayout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [continuous=false] Show all pages, one after another
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed.
+ * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet.
+ * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
+ */
+OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.BookletLayout.parent.call( this, config );
+
+       // Properties
+       this.currentPageName = null;
+       this.pages = {};
+       this.ignoreFocus = false;
+       this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } );
+       this.$content.append( this.stackLayout.$element );
+       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
+       this.outlineVisible = false;
+       this.outlined = !!config.outlined;
+       if ( this.outlined ) {
+               this.editable = !!config.editable;
+               this.outlineControlsWidget = null;
+               this.outlineSelectWidget = new OO.ui.OutlineSelectWidget();
+               this.outlinePanel = new OO.ui.PanelLayout( { scrollable: true } );
+               this.$menu.append( this.outlinePanel.$element );
+               this.outlineVisible = true;
+               if ( this.editable ) {
+                       this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
+                               this.outlineSelectWidget
+                       );
+               }
+       }
+       this.toggleMenu( this.outlined );
+
+       // Events
+       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
+       if ( this.outlined ) {
+               this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );
+               this.scrolling = false;
+               this.stackLayout.connect( this, { visibleItemChange: 'onStackLayoutVisibleItemChange' } );
+       }
+       if ( this.autoFocus ) {
+               // Event 'focus' does not bubble, but 'focusin' does
+               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
+       }
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-bookletLayout' );
+       this.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );
+       if ( this.outlined ) {
+               this.outlinePanel.$element
+                       .addClass( 'oo-ui-bookletLayout-outlinePanel' )
+                       .append( this.outlineSelectWidget.$element );
+               if ( this.editable ) {
+                       this.outlinePanel.$element
+                               .addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )
+                               .append( this.outlineControlsWidget.$element );
+               }
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );
+
+/* Events */
+
+/**
+ * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the booklet layout.
+ * @event set
+ * @param {OO.ui.PageLayout} page Current page
+ */
+
+/**
+ * An 'add' event is emitted when pages are {@link #addPages added} to the booklet layout.
+ *
+ * @event add
+ * @param {OO.ui.PageLayout[]} page Added pages
+ * @param {number} index Index pages were added at
+ */
+
+/**
+ * A 'remove' event is emitted when pages are {@link #clearPages cleared} or
+ * {@link #removePages removed} from the booklet.
+ *
+ * @event remove
+ * @param {OO.ui.PageLayout[]} pages Removed pages
+ */
+
+/* Methods */
+
+/**
+ * Handle stack layout focus.
+ *
+ * @private
+ * @param {jQuery.Event} e Focusin event
+ */
+OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
+       var name, $target;
+
+       // Find the page that an element was focused within
+       $target = $( e.target ).closest( '.oo-ui-pageLayout' );
+       for ( name in this.pages ) {
+               // Check for page match, exclude current page to find only page changes
+               if ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {
+                       this.setPage( name );
+                       break;
+               }
+       }
+};
+
+/**
+ * Handle visibleItemChange events from the stackLayout
+ *
+ * The next visible page is set as the current page by selecting it
+ * in the outline
+ *
+ * @param {OO.ui.PageLayout} page The next visible page in the layout
+ */
+OO.ui.BookletLayout.prototype.onStackLayoutVisibleItemChange = function ( page ) {
+       // Set a flag to so that the resulting call to #onStackLayoutSet doesn't
+       // try and scroll the item into view again.
+       this.scrolling = true;
+       this.outlineSelectWidget.selectItemByData( page.getName() );
+       this.scrolling = false;
+};
+
+/**
+ * Handle stack layout set events.
+ *
+ * @private
+ * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel
+ */
+OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
+       var layout = this;
+       if ( !this.scrolling && page ) {
+               page.scrollElementIntoView( { complete: function () {
+                       if ( layout.autoFocus ) {
+                               layout.focus();
+                       }
+               } } );
+       }
+};
+
+/**
+ * Focus the first input in the current page.
+ *
+ * If no page is selected, the first selectable page will be selected.
+ * If the focus is already in an element on the current page, nothing will happen.
+ * @param {number} [itemIndex] A specific item to focus on
+ */
+OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) {
+       var page,
+               items = this.stackLayout.getItems();
+
+       if ( itemIndex !== undefined && items[ itemIndex ] ) {
+               page = items[ itemIndex ];
+       } else {
+               page = this.stackLayout.getCurrentItem();
+       }
+
+       if ( !page && this.outlined ) {
+               this.selectFirstSelectablePage();
+               page = this.stackLayout.getCurrentItem();
+       }
+       if ( !page ) {
+               return;
+       }
+       // Only change the focus if is not already in the current page
+       if ( !OO.ui.contains( page.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {
+               page.focus();
+       }
+};
+
+/**
+ * Find the first focusable input in the booklet layout and focus
+ * on it.
+ */
+OO.ui.BookletLayout.prototype.focusFirstFocusable = function () {
+       OO.ui.findFocusable( this.stackLayout.$element ).focus();
+};
+
+/**
+ * Handle outline widget select events.
+ *
+ * @private
+ * @param {OO.ui.OptionWidget|null} item Selected item
+ */
+OO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {
+       if ( item ) {
+               this.setPage( item.getData() );
+       }
+};
+
+/**
+ * Check if booklet has an outline.
+ *
+ * @return {boolean} Booklet has an outline
+ */
+OO.ui.BookletLayout.prototype.isOutlined = function () {
+       return this.outlined;
+};
+
+/**
+ * Check if booklet has editing controls.
+ *
+ * @return {boolean} Booklet is editable
+ */
+OO.ui.BookletLayout.prototype.isEditable = function () {
+       return this.editable;
+};
+
+/**
+ * Check if booklet has a visible outline.
+ *
+ * @return {boolean} Outline is visible
+ */
+OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
+       return this.outlined && this.outlineVisible;
+};
+
+/**
+ * Hide or show the outline.
+ *
+ * @param {boolean} [show] Show outline, omit to invert current state
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
+       if ( this.outlined ) {
+               show = show === undefined ? !this.outlineVisible : !!show;
+               this.outlineVisible = show;
+               this.toggleMenu( show );
+       }
+
+       return this;
+};
+
+/**
+ * Get the page closest to the specified page.
+ *
+ * @param {OO.ui.PageLayout} page Page to use as a reference point
+ * @return {OO.ui.PageLayout|null} Page closest to the specified page
+ */
+OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
+       var next, prev, level,
+               pages = this.stackLayout.getItems(),
+               index = pages.indexOf( page );
+
+       if ( index !== -1 ) {
+               next = pages[ index + 1 ];
+               prev = pages[ index - 1 ];
+               // Prefer adjacent pages at the same level
+               if ( this.outlined ) {
+                       level = this.outlineSelectWidget.getItemFromData( page.getName() ).getLevel();
+                       if (
+                               prev &&
+                               level === this.outlineSelectWidget.getItemFromData( prev.getName() ).getLevel()
+                       ) {
+                               return prev;
+                       }
+                       if (
+                               next &&
+                               level === this.outlineSelectWidget.getItemFromData( next.getName() ).getLevel()
+                       ) {
+                               return next;
+                       }
+               }
+       }
+       return prev || next || null;
+};
+
+/**
+ * Get the outline widget.
+ *
+ * If the booklet is not outlined, the method will return `null`.
+ *
+ * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if the booklet is not outlined
+ */
+OO.ui.BookletLayout.prototype.getOutline = function () {
+       return this.outlineSelectWidget;
+};
+
+/**
+ * Get the outline controls widget.
+ *
+ * If the outline is not editable, the method will return `null`.
+ *
+ * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.
+ */
+OO.ui.BookletLayout.prototype.getOutlineControls = function () {
+       return this.outlineControlsWidget;
+};
+
+/**
+ * Get a page by its symbolic name.
+ *
+ * @param {string} name Symbolic name of page
+ * @return {OO.ui.PageLayout|undefined} Page, if found
+ */
+OO.ui.BookletLayout.prototype.getPage = function ( name ) {
+       return this.pages[ name ];
+};
+
+/**
+ * Get the current page.
+ *
+ * @return {OO.ui.PageLayout|undefined} Current page, if found
+ */
+OO.ui.BookletLayout.prototype.getCurrentPage = function () {
+       var name = this.getCurrentPageName();
+       return name ? this.getPage( name ) : undefined;
+};
+
+/**
+ * Get the symbolic name of the current page.
+ *
+ * @return {string|null} Symbolic name of the current page
+ */
+OO.ui.BookletLayout.prototype.getCurrentPageName = function () {
+       return this.currentPageName;
+};
+
+/**
+ * Add pages to the booklet layout
+ *
+ * When pages are added with the same names as existing pages, the existing pages will be
+ * automatically removed before the new pages are added.
+ *
+ * @param {OO.ui.PageLayout[]} pages Pages to add
+ * @param {number} index Index of the insertion point
+ * @fires add
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
+       var i, len, name, page, item, currentIndex,
+               stackLayoutPages = this.stackLayout.getItems(),
+               remove = [],
+               items = [];
+
+       // Remove pages with same names
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+
+               if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {
+                       // Correct the insertion index
+                       currentIndex = stackLayoutPages.indexOf( this.pages[ name ] );
+                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
+                               index--;
+                       }
+                       remove.push( this.pages[ name ] );
+               }
+       }
+       if ( remove.length ) {
+               this.removePages( remove );
+       }
+
+       // Add new pages
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+               this.pages[ page.getName() ] = page;
+               if ( this.outlined ) {
+                       item = new OO.ui.OutlineOptionWidget( { data: name } );
+                       page.setOutlineItem( item );
+                       items.push( item );
+               }
+       }
+
+       if ( this.outlined && items.length ) {
+               this.outlineSelectWidget.addItems( items, index );
+               this.selectFirstSelectablePage();
+       }
+       this.stackLayout.addItems( pages, index );
+       this.emit( 'add', pages, index );
+
+       return this;
+};
+
+/**
+ * Remove the specified pages from the booklet layout.
+ *
+ * To remove all pages from the booklet, you may wish to use the #clearPages method instead.
+ *
+ * @param {OO.ui.PageLayout[]} pages An array of pages to remove
+ * @fires remove
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
+       var i, len, name, page,
+               items = [];
+
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+               delete this.pages[ name ];
+               if ( this.outlined ) {
+                       items.push( this.outlineSelectWidget.getItemFromData( name ) );
+                       page.setOutlineItem( null );
+               }
+       }
+       if ( this.outlined && items.length ) {
+               this.outlineSelectWidget.removeItems( items );
+               this.selectFirstSelectablePage();
+       }
+       this.stackLayout.removeItems( pages );
+       this.emit( 'remove', pages );
+
+       return this;
+};
+
+/**
+ * Clear all pages from the booklet layout.
+ *
+ * To remove only a subset of pages from the booklet, use the #removePages method.
+ *
+ * @fires remove
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.clearPages = function () {
+       var i, len,
+               pages = this.stackLayout.getItems();
+
+       this.pages = {};
+       this.currentPageName = null;
+       if ( this.outlined ) {
+               this.outlineSelectWidget.clearItems();
+               for ( i = 0, len = pages.length; i < len; i++ ) {
+                       pages[ i ].setOutlineItem( null );
+               }
+       }
+       this.stackLayout.clearItems();
+
+       this.emit( 'remove', pages );
+
+       return this;
+};
+
+/**
+ * Set the current page by symbolic name.
+ *
+ * @fires set
+ * @param {string} name Symbolic name of page
+ */
+OO.ui.BookletLayout.prototype.setPage = function ( name ) {
+       var selectedItem,
+               $focused,
+               page = this.pages[ name ],
+               previousPage = this.currentPageName && this.pages[ this.currentPageName ];
+
+       if ( name !== this.currentPageName ) {
+               if ( this.outlined ) {
+                       selectedItem = this.outlineSelectWidget.getSelectedItem();
+                       if ( selectedItem && selectedItem.getData() !== name ) {
+                               this.outlineSelectWidget.selectItemByData( name );
+                       }
+               }
+               if ( page ) {
+                       if ( previousPage ) {
+                               previousPage.setActive( false );
+                               // Blur anything focused if the next page doesn't have anything focusable.
+                               // This is not needed if the next page has something focusable (because once it is focused
+                               // this blur happens automatically). If the layout is non-continuous, this check is
+                               // meaningless because the next page is not visible yet and thus can't hold focus.
+                               if (
+                                       this.autoFocus &&
+                                       this.stackLayout.continuous &&
+                                       OO.ui.findFocusable( page.$element ).length !== 0
+                               ) {
+                                       $focused = previousPage.$element.find( ':focus' );
+                                       if ( $focused.length ) {
+                                               $focused[ 0 ].blur();
+                                       }
+                               }
+                       }
+                       this.currentPageName = name;
+                       page.setActive( true );
+                       this.stackLayout.setItem( page );
+                       if ( !this.stackLayout.continuous && previousPage ) {
+                               // This should not be necessary, since any inputs on the previous page should have been
+                               // blurred when it was hidden, but browsers are not very consistent about this.
+                               $focused = previousPage.$element.find( ':focus' );
+                               if ( $focused.length ) {
+                                       $focused[ 0 ].blur();
+                               }
+                       }
+                       this.emit( 'set', page );
+               }
+       }
+};
+
+/**
+ * Select the first selectable page.
+ *
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
+       if ( !this.outlineSelectWidget.getSelectedItem() ) {
+               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getFirstSelectableItem() );
+       }
+
+       return this;
+};
+
+/**
+ * IndexLayouts contain {@link OO.ui.CardLayout card layouts} as well as
+ * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the cards and
+ * select which one to display. By default, only one card is displayed at a time. When a user
+ * navigates to a new card, the index layout automatically focuses on the first focusable element,
+ * unless the default setting is changed.
+ *
+ * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication
+ *
+ *     @example
+ *     // Example of a IndexLayout that contains two CardLayouts.
+ *
+ *     function CardOneLayout( name, config ) {
+ *         CardOneLayout.parent.call( this, name, config );
+ *         this.$element.append( '<p>First card</p>' );
+ *     }
+ *     OO.inheritClass( CardOneLayout, OO.ui.CardLayout );
+ *     CardOneLayout.prototype.setupTabItem = function () {
+ *         this.tabItem.setLabel( 'Card one' );
+ *     };
+ *
+ *     var card1 = new CardOneLayout( 'one' ),
+ *         card2 = new CardLayout( 'two', { label: 'Card two' } );
+ *
+ *     card2.$element.append( '<p>Second card</p>' );
+ *
+ *     var index = new OO.ui.IndexLayout();
+ *
+ *     index.addCards ( [ card1, card2 ] );
+ *     $( 'body' ).append( index.$element );
+ *
+ * @class
+ * @extends OO.ui.MenuLayout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [continuous=false] Show all cards, one after another
+ * @cfg {boolean} [expanded=true] Expand the content panel to fill the entire parent element.
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed.
+ */
+OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
+       // Configuration initialization
+       config = $.extend( {}, config, { menuPosition: 'top' } );
+
+       // Parent constructor
+       OO.ui.IndexLayout.parent.call( this, config );
+
+       // Properties
+       this.currentCardName = null;
+       this.cards = {};
+       this.ignoreFocus = false;
+       this.stackLayout = new OO.ui.StackLayout( {
+               continuous: !!config.continuous,
+               expanded: config.expanded
+       } );
+       this.$content.append( this.stackLayout.$element );
+       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
+
+       this.tabSelectWidget = new OO.ui.TabSelectWidget();
+       this.tabPanel = new OO.ui.PanelLayout();
+       this.$menu.append( this.tabPanel.$element );
+
+       this.toggleMenu( true );
+
+       // Events
+       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
+       this.tabSelectWidget.connect( this, { select: 'onTabSelectWidgetSelect' } );
+       if ( this.autoFocus ) {
+               // Event 'focus' does not bubble, but 'focusin' does
+               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
+       }
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-indexLayout' );
+       this.stackLayout.$element.addClass( 'oo-ui-indexLayout-stackLayout' );
+       this.tabPanel.$element
+               .addClass( 'oo-ui-indexLayout-tabPanel' )
+               .append( this.tabSelectWidget.$element );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout );
+
+/* Events */
+
+/**
+ * A 'set' event is emitted when a card is {@link #setCard set} to be displayed by the index layout.
+ * @event set
+ * @param {OO.ui.CardLayout} card Current card
+ */
+
+/**
+ * An 'add' event is emitted when cards are {@link #addCards added} to the index layout.
+ *
+ * @event add
+ * @param {OO.ui.CardLayout[]} card Added cards
+ * @param {number} index Index cards were added at
+ */
+
+/**
+ * A 'remove' event is emitted when cards are {@link #clearCards cleared} or
+ * {@link #removeCards removed} from the index.
+ *
+ * @event remove
+ * @param {OO.ui.CardLayout[]} cards Removed cards
+ */
+
+/* Methods */
+
+/**
+ * Handle stack layout focus.
+ *
+ * @private
+ * @param {jQuery.Event} e Focusin event
+ */
+OO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) {
+       var name, $target;
+
+       // Find the card that an element was focused within
+       $target = $( e.target ).closest( '.oo-ui-cardLayout' );
+       for ( name in this.cards ) {
+               // Check for card match, exclude current card to find only card changes
+               if ( this.cards[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentCardName ) {
+                       this.setCard( name );
+                       break;
+               }
+       }
+};
+
+/**
+ * Handle stack layout set events.
+ *
+ * @private
+ * @param {OO.ui.PanelLayout|null} card The card panel that is now the current panel
+ */
+OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) {
+       var layout = this;
+       if ( card ) {
+               card.scrollElementIntoView( { complete: function () {
+                       if ( layout.autoFocus ) {
+                               layout.focus();
+                       }
+               } } );
+       }
+};
+
+/**
+ * Focus the first input in the current card.
+ *
+ * If no card is selected, the first selectable card will be selected.
+ * If the focus is already in an element on the current card, nothing will happen.
+ * @param {number} [itemIndex] A specific item to focus on
+ */
+OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) {
+       var card,
+               items = this.stackLayout.getItems();
+
+       if ( itemIndex !== undefined && items[ itemIndex ] ) {
+               card = items[ itemIndex ];
+       } else {
+               card = this.stackLayout.getCurrentItem();
+       }
+
+       if ( !card ) {
+               this.selectFirstSelectableCard();
+               card = this.stackLayout.getCurrentItem();
+       }
+       if ( !card ) {
+               return;
+       }
+       // Only change the focus if is not already in the current page
+       if ( !OO.ui.contains( card.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {
+               card.focus();
+       }
+};
+
+/**
+ * Find the first focusable input in the index layout and focus
+ * on it.
+ */
+OO.ui.IndexLayout.prototype.focusFirstFocusable = function () {
+       OO.ui.findFocusable( this.stackLayout.$element ).focus();
+};
+
+/**
+ * Handle tab widget select events.
+ *
+ * @private
+ * @param {OO.ui.OptionWidget|null} item Selected item
+ */
+OO.ui.IndexLayout.prototype.onTabSelectWidgetSelect = function ( item ) {
+       if ( item ) {
+               this.setCard( item.getData() );
+       }
+};
+
+/**
+ * Get the card closest to the specified card.
+ *
+ * @param {OO.ui.CardLayout} card Card to use as a reference point
+ * @return {OO.ui.CardLayout|null} Card closest to the specified card
+ */
+OO.ui.IndexLayout.prototype.getClosestCard = function ( card ) {
+       var next, prev, level,
+               cards = this.stackLayout.getItems(),
+               index = cards.indexOf( card );
+
+       if ( index !== -1 ) {
+               next = cards[ index + 1 ];
+               prev = cards[ index - 1 ];
+               // Prefer adjacent cards at the same level
+               level = this.tabSelectWidget.getItemFromData( card.getName() ).getLevel();
+               if (
+                       prev &&
+                       level === this.tabSelectWidget.getItemFromData( prev.getName() ).getLevel()
+               ) {
+                       return prev;
+               }
+               if (
+                       next &&
+                       level === this.tabSelectWidget.getItemFromData( next.getName() ).getLevel()
+               ) {
+                       return next;
+               }
+       }
+       return prev || next || null;
+};
+
+/**
+ * Get the tabs widget.
+ *
+ * @return {OO.ui.TabSelectWidget} Tabs widget
+ */
+OO.ui.IndexLayout.prototype.getTabs = function () {
+       return this.tabSelectWidget;
+};
+
+/**
+ * Get a card by its symbolic name.
+ *
+ * @param {string} name Symbolic name of card
+ * @return {OO.ui.CardLayout|undefined} Card, if found
+ */
+OO.ui.IndexLayout.prototype.getCard = function ( name ) {
+       return this.cards[ name ];
+};
+
+/**
+ * Get the current card.
+ *
+ * @return {OO.ui.CardLayout|undefined} Current card, if found
+ */
+OO.ui.IndexLayout.prototype.getCurrentCard = function () {
+       var name = this.getCurrentCardName();
+       return name ? this.getCard( name ) : undefined;
+};
+
+/**
+ * Get the symbolic name of the current card.
+ *
+ * @return {string|null} Symbolic name of the current card
+ */
+OO.ui.IndexLayout.prototype.getCurrentCardName = function () {
+       return this.currentCardName;
+};
+
+/**
+ * Add cards to the index layout
+ *
+ * When cards are added with the same names as existing cards, the existing cards will be
+ * automatically removed before the new cards are added.
+ *
+ * @param {OO.ui.CardLayout[]} cards Cards to add
+ * @param {number} index Index of the insertion point
+ * @fires add
+ * @chainable
+ */
+OO.ui.IndexLayout.prototype.addCards = function ( cards, index ) {
+       var i, len, name, card, item, currentIndex,
+               stackLayoutCards = this.stackLayout.getItems(),
+               remove = [],
+               items = [];
+
+       // Remove cards with same names
+       for ( i = 0, len = cards.length; i < len; i++ ) {
+               card = cards[ i ];
+               name = card.getName();
+
+               if ( Object.prototype.hasOwnProperty.call( this.cards, name ) ) {
+                       // Correct the insertion index
+                       currentIndex = stackLayoutCards.indexOf( this.cards[ name ] );
+                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
+                               index--;
+                       }
+                       remove.push( this.cards[ name ] );
+               }
+       }
+       if ( remove.length ) {
+               this.removeCards( remove );
+       }
+
+       // Add new cards
+       for ( i = 0, len = cards.length; i < len; i++ ) {
+               card = cards[ i ];
+               name = card.getName();
+               this.cards[ card.getName() ] = card;
+               item = new OO.ui.TabOptionWidget( { data: name } );
+               card.setTabItem( item );
+               items.push( item );
+       }
+
+       if ( items.length ) {
+               this.tabSelectWidget.addItems( items, index );
+               this.selectFirstSelectableCard();
+       }
+       this.stackLayout.addItems( cards, index );
+       this.emit( 'add', cards, index );
+
+       return this;
+};
+
+/**
+ * Remove the specified cards from the index layout.
+ *
+ * To remove all cards from the index, you may wish to use the #clearCards method instead.
+ *
+ * @param {OO.ui.CardLayout[]} cards An array of cards to remove
+ * @fires remove
+ * @chainable
+ */
+OO.ui.IndexLayout.prototype.removeCards = function ( cards ) {
+       var i, len, name, card,
+               items = [];
+
+       for ( i = 0, len = cards.length; i < len; i++ ) {
+               card = cards[ i ];
+               name = card.getName();
+               delete this.cards[ name ];
+               items.push( this.tabSelectWidget.getItemFromData( name ) );
+               card.setTabItem( null );
+       }
+       if ( items.length ) {
+               this.tabSelectWidget.removeItems( items );
+               this.selectFirstSelectableCard();
+       }
+       this.stackLayout.removeItems( cards );
+       this.emit( 'remove', cards );
+
+       return this;
+};
+
+/**
+ * Clear all cards from the index layout.
+ *
+ * To remove only a subset of cards from the index, use the #removeCards method.
+ *
+ * @fires remove
+ * @chainable
+ */
+OO.ui.IndexLayout.prototype.clearCards = function () {
+       var i, len,
+               cards = this.stackLayout.getItems();
+
+       this.cards = {};
+       this.currentCardName = null;
+       this.tabSelectWidget.clearItems();
+       for ( i = 0, len = cards.length; i < len; i++ ) {
+               cards[ i ].setTabItem( null );
+       }
+       this.stackLayout.clearItems();
+
+       this.emit( 'remove', cards );
+
+       return this;
+};
+
+/**
+ * Set the current card by symbolic name.
+ *
+ * @fires set
+ * @param {string} name Symbolic name of card
+ */
+OO.ui.IndexLayout.prototype.setCard = function ( name ) {
+       var selectedItem,
+               $focused,
+               card = this.cards[ name ],
+               previousCard = this.currentCardName && this.cards[ this.currentCardName ];
+
+       if ( name !== this.currentCardName ) {
+               selectedItem = this.tabSelectWidget.getSelectedItem();
+               if ( selectedItem && selectedItem.getData() !== name ) {
+                       this.tabSelectWidget.selectItemByData( name );
+               }
+               if ( card ) {
+                       if ( previousCard ) {
+                               previousCard.setActive( false );
+                               // Blur anything focused if the next card doesn't have anything focusable.
+                               // This is not needed if the next card has something focusable (because once it is focused
+                               // this blur happens automatically). If the layout is non-continuous, this check is
+                               // meaningless because the next card is not visible yet and thus can't hold focus.
+                               if (
+                                       this.autoFocus &&
+                                       this.stackLayout.continuous &&
+                                       OO.ui.findFocusable( card.$element ).length !== 0
+                               ) {
+                                       $focused = previousCard.$element.find( ':focus' );
+                                       if ( $focused.length ) {
+                                               $focused[ 0 ].blur();
+                                       }
+                               }
+                       }
+                       this.currentCardName = name;
+                       card.setActive( true );
+                       this.stackLayout.setItem( card );
+                       if ( !this.stackLayout.continuous && previousCard ) {
+                               // This should not be necessary, since any inputs on the previous card should have been
+                               // blurred when it was hidden, but browsers are not very consistent about this.
+                               $focused = previousCard.$element.find( ':focus' );
+                               if ( $focused.length ) {
+                                       $focused[ 0 ].blur();
+                               }
+                       }
+                       this.emit( 'set', card );
+               }
+       }
+};
+
+/**
+ * Select the first selectable card.
+ *
+ * @chainable
+ */
+OO.ui.IndexLayout.prototype.selectFirstSelectableCard = function () {
+       if ( !this.tabSelectWidget.getSelectedItem() ) {
+               this.tabSelectWidget.selectItem( this.tabSelectWidget.getFirstSelectableItem() );
+       }
+
+       return this;
+};
+
+/**
+ * ToggleWidget implements basic behavior of widgets with an on/off state.
+ * Please see OO.ui.ToggleButtonWidget and OO.ui.ToggleSwitchWidget for examples.
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [value=false] The toggle’s initial on/off state.
+ *  By default, the toggle is in the 'off' state.
+ */
+OO.ui.ToggleWidget = function OoUiToggleWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ToggleWidget.parent.call( this, config );
+
+       // Properties
+       this.value = null;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-toggleWidget' );
+       this.setValue( !!config.value );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToggleWidget, OO.ui.Widget );
+
+/* Events */
+
+/**
+ * @event change
+ *
+ * A change event is emitted when the on/off state of the toggle changes.
+ *
+ * @param {boolean} value Value representing the new state of the toggle
+ */
+
+/* Methods */
+
+/**
+ * Get the value representing the toggle’s state.
+ *
+ * @return {boolean} The on/off state of the toggle
+ */
+OO.ui.ToggleWidget.prototype.getValue = function () {
+       return this.value;
+};
+
+/**
+ * Set the state of the toggle: `true` for 'on', `false' for 'off'.
+ *
+ * @param {boolean} value The state of the toggle
+ * @fires change
+ * @chainable
+ */
+OO.ui.ToggleWidget.prototype.setValue = function ( value ) {
+       value = !!value;
+       if ( this.value !== value ) {
+               this.value = value;
+               this.emit( 'change', value );
+               this.$element.toggleClass( 'oo-ui-toggleWidget-on', value );
+               this.$element.toggleClass( 'oo-ui-toggleWidget-off', !value );
+               this.$element.attr( 'aria-checked', value.toString() );
+       }
+       return this;
+};
+
+/**
+ * ToggleButtons are buttons that have a state (‘on’ or ‘off’) that is represented by a
+ * Boolean value. Like other {@link OO.ui.ButtonWidget buttons}, toggle buttons can be
+ * configured with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators},
+ * {@link OO.ui.mixin.TitledElement titles}, {@link OO.ui.mixin.FlaggedElement styling flags},
+ * and {@link OO.ui.mixin.LabelElement labels}. Please see
+ * the [OOjs UI documentation][1] on MediaWiki for more information.
+ *
+ *     @example
+ *     // Toggle buttons in the 'off' and 'on' state.
+ *     var toggleButton1 = new OO.ui.ToggleButtonWidget( {
+ *         label: 'Toggle Button off'
+ *     } );
+ *     var toggleButton2 = new OO.ui.ToggleButtonWidget( {
+ *         label: 'Toggle Button on',
+ *         value: true
+ *     } );
+ *     // Append the buttons to the DOM.
+ *     $( 'body' ).append( toggleButton1.$element, toggleButton2.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#Toggle_buttons
+ *
+ * @class
+ * @extends OO.ui.ToggleWidget
+ * @mixins OO.ui.mixin.ButtonElement
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.TitledElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [value=false] The toggle button’s initial on/off
+ *  state. By default, the button is in the 'off' state.
+ */
+OO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ToggleButtonWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ButtonElement.call( this, config );
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
+
+       // Events
+       this.connect( this, { click: 'onAction' } );
+
+       // Initialization
+       this.$button.append( this.$icon, this.$label, this.$indicator );
+       this.$element
+               .addClass( 'oo-ui-toggleButtonWidget' )
+               .append( this.$button );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToggleButtonWidget, OO.ui.ToggleWidget );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.ButtonElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * Handle the button action being triggered.
+ *
+ * @private
+ */
+OO.ui.ToggleButtonWidget.prototype.onAction = function () {
+       this.setValue( !this.value );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {
+       value = !!value;
+       if ( value !== this.value ) {
+               // Might be called from parent constructor before ButtonElement constructor
+               if ( this.$button ) {
+                       this.$button.attr( 'aria-pressed', value.toString() );
+               }
+               this.setActive( value );
+       }
+
+       // Parent method
+       OO.ui.ToggleButtonWidget.parent.prototype.setValue.call( this, value );
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ToggleButtonWidget.prototype.setButtonElement = function ( $button ) {
+       if ( this.$button ) {
+               this.$button.removeAttr( 'aria-pressed' );
+       }
+       OO.ui.mixin.ButtonElement.prototype.setButtonElement.call( this, $button );
+       this.$button.attr( 'aria-pressed', this.value.toString() );
+};
+
+/**
+ * ToggleSwitches are switches that slide on and off. Their state is represented by a Boolean
+ * value (`true` for ‘on’, and `false` otherwise, the default). The ‘off’ state is represented
+ * visually by a slider in the leftmost position.
+ *
+ *     @example
+ *     // Toggle switches in the 'off' and 'on' position.
+ *     var toggleSwitch1 = new OO.ui.ToggleSwitchWidget();
+ *     var toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {
+ *         value: true
+ *     } );
+ *
+ *     // Create a FieldsetLayout to layout and label switches
+ *     var fieldset = new OO.ui.FieldsetLayout( {
+ *        label: 'Toggle switches'
+ *     } );
+ *     fieldset.addItems( [
+ *         new OO.ui.FieldLayout( toggleSwitch1, { label: 'Off', align: 'top' } ),
+ *         new OO.ui.FieldLayout( toggleSwitch2, { label: 'On', align: 'top' } )
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * @class
+ * @extends OO.ui.ToggleWidget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [value=false] The toggle switch’s initial on/off state.
+ *  By default, the toggle switch is in the 'off' position.
+ */
+OO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {
+       // Parent constructor
+       OO.ui.ToggleSwitchWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+
+       // Properties
+       this.dragging = false;
+       this.dragStart = null;
+       this.sliding = false;
+       this.$glow = $( '<span>' );
+       this.$grip = $( '<span>' );
+
+       // Events
+       this.$element.on( {
+               click: this.onClick.bind( this ),
+               keypress: this.onKeyPress.bind( this )
+       } );
+
+       // Initialization
+       this.$glow.addClass( 'oo-ui-toggleSwitchWidget-glow' );
+       this.$grip.addClass( 'oo-ui-toggleSwitchWidget-grip' );
+       this.$element
+               .addClass( 'oo-ui-toggleSwitchWidget' )
+               .attr( 'role', 'checkbox' )
+               .append( this.$glow, this.$grip );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );
+OO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * Handle mouse click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               this.setValue( !this.value );
+       }
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.ToggleSwitchWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+               this.setValue( !this.value );
+               return false;
+       }
+};
+
+/**
+ * OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}.
+ * Controls include moving items up and down, removing items, and adding different kinds of items.
+ *
+ * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.GroupElement
+ * @mixins OO.ui.mixin.IconElement
+ *
+ * @constructor
+ * @param {OO.ui.OutlineSelectWidget} outline Outline to control
+ * @param {Object} [config] Configuration options
+ * @cfg {Object} [abilities] List of abilties
+ * @cfg {boolean} [abilities.move=true] Allow moving movable items
+ * @cfg {boolean} [abilities.remove=true] Allow removing removable items
+ */
+OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( outline ) && config === undefined ) {
+               config = outline;
+               outline = config.outline;
+       }
+
+       // Configuration initialization
+       config = $.extend( { icon: 'add' }, config );
+
+       // Parent constructor
+       OO.ui.OutlineControlsWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, config );
+       OO.ui.mixin.IconElement.call( this, config );
+
+       // Properties
+       this.outline = outline;
+       this.$movers = $( '<div>' );
+       this.upButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               icon: 'collapse',
+               title: OO.ui.msg( 'ooui-outline-control-move-up' )
+       } );
+       this.downButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               icon: 'expand',
+               title: OO.ui.msg( 'ooui-outline-control-move-down' )
+       } );
+       this.removeButton = new OO.ui.ButtonWidget( {
+               framed: false,
+               icon: 'remove',
+               title: OO.ui.msg( 'ooui-outline-control-remove' )
+       } );
+       this.abilities = { move: true, remove: true };
+
+       // Events
+       outline.connect( this, {
+               select: 'onOutlineChange',
+               add: 'onOutlineChange',
+               remove: 'onOutlineChange'
+       } );
+       this.upButton.connect( this, { click: [ 'emit', 'move', -1 ] } );
+       this.downButton.connect( this, { click: [ 'emit', 'move', 1 ] } );
+       this.removeButton.connect( this, { click: [ 'emit', 'remove' ] } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-outlineControlsWidget' );
+       this.$group.addClass( 'oo-ui-outlineControlsWidget-items' );
+       this.$movers
+               .addClass( 'oo-ui-outlineControlsWidget-movers' )
+               .append( this.removeButton.$element, this.upButton.$element, this.downButton.$element );
+       this.$element.append( this.$icon, this.$group, this.$movers );
+       this.setAbilities( config.abilities || {} );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.GroupElement );
+OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.IconElement );
+
+/* Events */
+
+/**
+ * @event move
+ * @param {number} places Number of places to move
+ */
+
+/**
+ * @event remove
+ */
+
+/* Methods */
+
+/**
+ * Set abilities.
+ *
+ * @param {Object} abilities List of abilties
+ * @param {boolean} [abilities.move] Allow moving movable items
+ * @param {boolean} [abilities.remove] Allow removing removable items
+ */
+OO.ui.OutlineControlsWidget.prototype.setAbilities = function ( abilities ) {
+       var ability;
+
+       for ( ability in this.abilities ) {
+               if ( abilities[ ability ] !== undefined ) {
+                       this.abilities[ ability ] = !!abilities[ ability ];
+               }
+       }
+
+       this.onOutlineChange();
+};
+
+/**
+ * @private
+ * Handle outline change events.
+ */
+OO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
+       var i, len, firstMovable, lastMovable,
+               items = this.outline.getItems(),
+               selectedItem = this.outline.getSelectedItem(),
+               movable = this.abilities.move && selectedItem && selectedItem.isMovable(),
+               removable = this.abilities.remove && selectedItem && selectedItem.isRemovable();
+
+       if ( movable ) {
+               i = -1;
+               len = items.length;
+               while ( ++i < len ) {
+                       if ( items[ i ].isMovable() ) {
+                               firstMovable = items[ i ];
+                               break;
+                       }
+               }
+               i = len;
+               while ( i-- ) {
+                       if ( items[ i ].isMovable() ) {
+                               lastMovable = items[ i ];
+                               break;
+                       }
+               }
+       }
+       this.upButton.setDisabled( !movable || selectedItem === firstMovable );
+       this.downButton.setDisabled( !movable || selectedItem === lastMovable );
+       this.removeButton.setDisabled( !removable );
+};
+
+/**
+ * OutlineOptionWidget is an item in an {@link OO.ui.OutlineSelectWidget OutlineSelectWidget}.
+ *
+ * Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}, which contain
+ * {@link OO.ui.PageLayout page layouts}. See {@link OO.ui.BookletLayout BookletLayout}
+ * for an example.
+ *
+ * @class
+ * @extends OO.ui.DecoratedOptionWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {number} [level] Indentation level
+ * @cfg {boolean} [movable] Allow modification from {@link OO.ui.OutlineControlsWidget outline controls}.
+ */
+OO.ui.OutlineOptionWidget = function OoUiOutlineOptionWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.OutlineOptionWidget.parent.call( this, config );
+
+       // Properties
+       this.level = 0;
+       this.movable = !!config.movable;
+       this.removable = !!config.removable;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-outlineOptionWidget' );
+       this.setLevel( config.level );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.OutlineOptionWidget, OO.ui.DecoratedOptionWidget );
+
+/* Static Properties */
+
+OO.ui.OutlineOptionWidget.static.highlightable = false;
+
+OO.ui.OutlineOptionWidget.static.scrollIntoViewOnSelect = true;
+
+OO.ui.OutlineOptionWidget.static.levelClass = 'oo-ui-outlineOptionWidget-level-';
+
+OO.ui.OutlineOptionWidget.static.levels = 3;
+
+/* Methods */
+
+/**
+ * Check if item is movable.
+ *
+ * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
+ *
+ * @return {boolean} Item is movable
+ */
+OO.ui.OutlineOptionWidget.prototype.isMovable = function () {
+       return this.movable;
+};
+
+/**
+ * Check if item is removable.
+ *
+ * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
+ *
+ * @return {boolean} Item is removable
+ */
+OO.ui.OutlineOptionWidget.prototype.isRemovable = function () {
+       return this.removable;
+};
+
+/**
+ * Get indentation level.
+ *
+ * @return {number} Indentation level
+ */
+OO.ui.OutlineOptionWidget.prototype.getLevel = function () {
+       return this.level;
+};
+
+/**
+ * Set movability.
+ *
+ * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
+ *
+ * @param {boolean} movable Item is movable
+ * @chainable
+ */
+OO.ui.OutlineOptionWidget.prototype.setMovable = function ( movable ) {
+       this.movable = !!movable;
+       this.updateThemeClasses();
+       return this;
+};
+
+/**
+ * Set removability.
+ *
+ * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
+ *
+ * @param {boolean} removable Item is removable
+ * @chainable
+ */
+OO.ui.OutlineOptionWidget.prototype.setRemovable = function ( removable ) {
+       this.removable = !!removable;
+       this.updateThemeClasses();
+       return this;
+};
+
+/**
+ * Set indentation level.
+ *
+ * @param {number} [level=0] Indentation level, in the range of [0,#maxLevel]
+ * @chainable
+ */
+OO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) {
+       var levels = this.constructor.static.levels,
+               levelClass = this.constructor.static.levelClass,
+               i = levels;
+
+       this.level = level ? Math.max( 0, Math.min( levels - 1, level ) ) : 0;
+       while ( i-- ) {
+               if ( this.level === i ) {
+                       this.$element.addClass( levelClass + i );
+               } else {
+                       this.$element.removeClass( levelClass + i );
+               }
+       }
+       this.updateThemeClasses();
+
+       return this;
+};
+
+/**
+ * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options}
+ * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget.
+ *
+ * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
+ *
+ * @class
+ * @extends OO.ui.SelectWidget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.OutlineSelectWidget = function OoUiOutlineSelectWidget( config ) {
+       // Parent constructor
+       OO.ui.OutlineSelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+
+       // Events
+       this.$element.on( {
+               focus: this.bindKeyDownListener.bind( this ),
+               blur: this.unbindKeyDownListener.bind( this )
+       } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-outlineSelectWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget );
+OO.mixinClass( OO.ui.OutlineSelectWidget, OO.ui.mixin.TabIndexedElement );
+
+/**
+ * ButtonOptionWidget is a special type of {@link OO.ui.mixin.ButtonElement button element} that
+ * can be selected and configured with data. The class is
+ * used with OO.ui.ButtonSelectWidget to create a selection of button options. Please see the
+ * [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Button_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.DecoratedOptionWidget
+ * @mixins OO.ui.mixin.ButtonElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ButtonOptionWidget = function OoUiButtonOptionWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ButtonOptionWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.ButtonElement.call( this, config );
+       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, {
+               $tabIndexed: this.$button,
+               tabIndex: -1
+       } ) );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-buttonOptionWidget' );
+       this.$button.append( this.$element.contents() );
+       this.$element.append( this.$button );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ButtonOptionWidget, OO.ui.DecoratedOptionWidget );
+OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.ButtonElement );
+OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TitledElement );
+OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TabIndexedElement );
+
+/* Static Properties */
+
+// Allow button mouse down events to pass through so they can be handled by the parent select widget
+OO.ui.ButtonOptionWidget.static.cancelButtonMouseDownEvents = false;
+
+OO.ui.ButtonOptionWidget.static.highlightable = false;
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ButtonOptionWidget.prototype.setSelected = function ( state ) {
+       OO.ui.ButtonOptionWidget.parent.prototype.setSelected.call( this, state );
+
+       if ( this.constructor.static.selectable ) {
+               this.setActive( state );
+       }
+
+       return this;
+};
+
+/**
+ * ButtonSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains
+ * button options and is used together with
+ * OO.ui.ButtonOptionWidget. The ButtonSelectWidget provides an interface for
+ * highlighting, choosing, and selecting mutually exclusive options. Please see
+ * the [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ *     @example
+ *     // Example: A ButtonSelectWidget that contains three ButtonOptionWidgets
+ *     var option1 = new OO.ui.ButtonOptionWidget( {
+ *         data: 1,
+ *         label: 'Option 1',
+ *         title: 'Button option 1'
+ *     } );
+ *
+ *     var option2 = new OO.ui.ButtonOptionWidget( {
+ *         data: 2,
+ *         label: 'Option 2',
+ *         title: 'Button option 2'
+ *     } );
+ *
+ *     var option3 = new OO.ui.ButtonOptionWidget( {
+ *         data: 3,
+ *         label: 'Option 3',
+ *         title: 'Button option 3'
+ *     } );
+ *
+ *     var buttonSelect=new OO.ui.ButtonSelectWidget( {
+ *         items: [ option1, option2, option3 ]
+ *     } );
+ *     $( 'body' ).append( buttonSelect.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
+ *
+ * @class
+ * @extends OO.ui.SelectWidget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ButtonSelectWidget = function OoUiButtonSelectWidget( config ) {
+       // Parent constructor
+       OO.ui.ButtonSelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+
+       // Events
+       this.$element.on( {
+               focus: this.bindKeyDownListener.bind( this ),
+               blur: this.unbindKeyDownListener.bind( this )
+       } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-buttonSelectWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ButtonSelectWidget, OO.ui.SelectWidget );
+OO.mixinClass( OO.ui.ButtonSelectWidget, OO.ui.mixin.TabIndexedElement );
+
+/**
+ * TabOptionWidget is an item in a {@link OO.ui.TabSelectWidget TabSelectWidget}.
+ *
+ * Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}, which contain
+ * {@link OO.ui.CardLayout card layouts}. See {@link OO.ui.IndexLayout IndexLayout}
+ * for an example.
+ *
+ * @class
+ * @extends OO.ui.OptionWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.TabOptionWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-tabOptionWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.TabOptionWidget, OO.ui.OptionWidget );
+
+/* Static Properties */
+
+OO.ui.TabOptionWidget.static.highlightable = false;
+
+/**
+ * TabSelectWidget is a list that contains {@link OO.ui.TabOptionWidget tab options}
+ *
+ * **Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}.**
+ *
+ * @class
+ * @extends OO.ui.SelectWidget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) {
+       // Parent constructor
+       OO.ui.TabSelectWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.TabIndexedElement.call( this, config );
+
+       // Events
+       this.$element.on( {
+               focus: this.bindKeyDownListener.bind( this ),
+               blur: this.unbindKeyDownListener.bind( this )
+       } );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-tabSelectWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget );
+OO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );
+
+/**
+ * CapsuleItemWidgets are used within a {@link OO.ui.CapsuleMultiSelectWidget
+ * CapsuleMultiSelectWidget} to display the selected items.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.ItemWidget
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.LabelElement
+ * @mixins OO.ui.mixin.FlaggedElement
+ * @mixins OO.ui.mixin.TabIndexedElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.CapsuleItemWidget = function OoUiCapsuleItemWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.CapsuleItemWidget.parent.call( this, config );
+
+       // Properties (must be set before mixin constructor calls)
+       this.$indicator = $( '<span>' );
+
+       // Mixin constructors
+       OO.ui.mixin.ItemWidget.call( this );
+       OO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$indicator, indicator: 'clear' } ) );
+       OO.ui.mixin.LabelElement.call( this, config );
+       OO.ui.mixin.FlaggedElement.call( this, config );
+       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$indicator } ) );
+
+       // Events
+       this.$indicator.on( {
+               keydown: this.onCloseKeyDown.bind( this ),
+               click: this.onCloseClick.bind( this )
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-capsuleItemWidget' )
+               .append( this.$indicator, this.$label );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.CapsuleItemWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.ItemWidget );
+OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.LabelElement );
+OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.FlaggedElement );
+OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.TabIndexedElement );
+
+/* Methods */
+
+/**
+ * Handle close icon clicks
+ * @param {jQuery.Event} event
+ */
+OO.ui.CapsuleItemWidget.prototype.onCloseClick = function () {
+       var element = this.getElementGroup();
+
+       if ( !this.isDisabled() && element && $.isFunction( element.removeItems ) ) {
+               element.removeItems( [ this ] );
+               element.focus();
+       }
+};
+
+/**
+ * Handle close keyboard events
+ * @param {jQuery.Event} event Key down event
+ */
+OO.ui.CapsuleItemWidget.prototype.onCloseKeyDown = function ( e ) {
+       if ( !this.isDisabled() && $.isFunction( this.getElementGroup().removeItems ) ) {
+               switch ( e.which ) {
+                       case OO.ui.Keys.ENTER:
+                       case OO.ui.Keys.BACKSPACE:
+                       case OO.ui.Keys.SPACE:
+                               this.getElementGroup().removeItems( [ this ] );
+                               return false;
+               }
+       }
+};
+
+/**
+ * CapsuleMultiSelectWidgets are something like a {@link OO.ui.ComboBoxInputWidget combo box widget}
+ * that allows for selecting multiple values.
+ *
+ * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example: A CapsuleMultiSelectWidget.
+ *     var capsule = new OO.ui.CapsuleMultiSelectWidget( {
+ *         label: 'CapsuleMultiSelectWidget',
+ *         selected: [ 'Option 1', 'Option 3' ],
+ *         menu: {
+ *             items: [
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 1',
+ *                     label: 'Option One'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 2',
+ *                     label: 'Option Two'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 3',
+ *                     label: 'Option Three'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 4',
+ *                     label: 'Option Four'
+ *                 } ),
+ *                 new OO.ui.MenuOptionWidget( {
+ *                     data: 'Option 5',
+ *                     label: 'Option Five'
+ *                 } )
+ *             ]
+ *         }
+ *     } );
+ *     $( 'body' ).append( capsule.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.TabIndexedElement
+ * @mixins OO.ui.mixin.GroupElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if not present in the menu.
+ * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu select widget}.
+ * @cfg {Object} [popup] Configuration options to pass to the {@link OO.ui.PopupWidget popup widget}.
+ *  If specified, this popup will be shown instead of the menu (but the menu
+ *  will still be used for item labels and allowArbitrary=false). The widgets
+ *  in the popup should use this.addItemsFromData() or this.addItems() as necessary.
+ * @cfg {jQuery} [$overlay] Render the menu or popup into a separate layer.
+ *  This configuration is useful in cases where the expanded menu is larger than
+ *  its containing `<div>`. The specified overlay layer is usually on top of
+ *  the containing `<div>` and has a larger area. By default, the menu uses
+ *  relative positioning.
+ */
+OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config ) {
+       var $tabFocus;
+
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.CapsuleMultiSelectWidget.parent.call( this, config );
+
+       // Properties (must be set before mixin constructor calls)
+       this.$input = config.popup ? null : $( '<input>' );
+       this.$handle = $( '<div>' );
+
+       // Mixin constructors
+       OO.ui.mixin.GroupElement.call( this, config );
+       if ( config.popup ) {
+               config.popup = $.extend( {}, config.popup, {
+                       align: 'forwards',
+                       anchor: false
+               } );
+               OO.ui.mixin.PopupElement.call( this, config );
+               $tabFocus = $( '<span>' );
+               OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: $tabFocus } ) );
+       } else {
+               this.popup = null;
+               $tabFocus = null;
+               OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );
+       }
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.IconElement.call( this, config );
+
+       // Properties
+       this.$content = $( '<div>' );
+       this.allowArbitrary = !!config.allowArbitrary;
+       this.$overlay = config.$overlay || this.$element;
+       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
+               {
+                       widget: this,
+                       $input: this.$input,
+                       $container: this.$element,
+                       filterFromInput: true,
+                       disabled: this.isDisabled()
+               },
+               config.menu
+       ) );
+
+       // Events
+       if ( this.popup ) {
+               $tabFocus.on( {
+                       focus: this.onFocusForPopup.bind( this )
+               } );
+               this.popup.$element.on( 'focusout', this.onPopupFocusOut.bind( this ) );
+               if ( this.popup.$autoCloseIgnore ) {
+                       this.popup.$autoCloseIgnore.on( 'focusout', this.onPopupFocusOut.bind( this ) );
+               }
+               this.popup.connect( this, {
+                       toggle: function ( visible ) {
+                               $tabFocus.toggle( !visible );
+                       }
+               } );
+       } else {
+               this.$input.on( {
+                       focus: this.onInputFocus.bind( this ),
+                       blur: this.onInputBlur.bind( this ),
+                       'propertychange change click mouseup keydown keyup input cut paste select focus':
+                               OO.ui.debounce( this.updateInputSize.bind( this ) ),
+                       keydown: this.onKeyDown.bind( this ),
+                       keypress: this.onKeyPress.bind( this )
+               } );
+       }
+       this.menu.connect( this, {
+               choose: 'onMenuChoose',
+               add: 'onMenuItemsChange',
+               remove: 'onMenuItemsChange'
+       } );
+       this.$handle.on( {
+               mousedown: this.onMouseDown.bind( this )
+       } );
+
+       // Initialization
+       if ( this.$input ) {
+               this.$input.prop( 'disabled', this.isDisabled() );
+               this.$input.attr( {
+                       role: 'combobox',
+                       'aria-autocomplete': 'list'
+               } );
+               this.updateInputSize();
+       }
+       if ( config.data ) {
+               this.setItemsFromData( config.data );
+       }
+       this.$content.addClass( 'oo-ui-capsuleMultiSelectWidget-content' )
+               .append( this.$group );
+       this.$group.addClass( 'oo-ui-capsuleMultiSelectWidget-group' );
+       this.$handle.addClass( 'oo-ui-capsuleMultiSelectWidget-handle' )
+               .append( this.$indicator, this.$icon, this.$content );
+       this.$element.addClass( 'oo-ui-capsuleMultiSelectWidget' )
+               .append( this.$handle );
+       if ( this.popup ) {
+               this.$content.append( $tabFocus );
+               this.$overlay.append( this.popup.$element );
+       } else {
+               this.$content.append( this.$input );
+               this.$overlay.append( this.menu.$element );
+       }
+       this.onMenuItemsChange();
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.GroupElement );
+OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.PopupElement );
+OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.TabIndexedElement );
+OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.IconElement );
+
+/* Events */
+
+/**
+ * @event change
+ *
+ * A change event is emitted when the set of selected items changes.
+ *
+ * @param {Mixed[]} datas Data of the now-selected items
+ */
+
+/* Methods */
+
+/**
+ * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data.
+ *
+ * @protected
+ * @param {Mixed} data Custom data of any type.
+ * @param {string} label The label text.
+ * @return {OO.ui.CapsuleItemWidget}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.createItemWidget = function ( data, label ) {
+       return new OO.ui.CapsuleItemWidget( { data: data, label: label } );
+};
+
+/**
+ * Get the data of the items in the capsule
+ * @return {Mixed[]}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.getItemsData = function () {
+       return $.map( this.getItems(), function ( e ) { return e.data; } );
+};
+
+/**
+ * Set the items in the capsule by providing data
+ * @chainable
+ * @param {Mixed[]} datas
+ * @return {OO.ui.CapsuleMultiSelectWidget}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.setItemsFromData = function ( datas ) {
+       var widget = this,
+               menu = this.menu,
+               items = this.getItems();
+
+       $.each( datas, function ( i, data ) {
+               var j, label,
+                       item = menu.getItemFromData( data );
+
+               if ( item ) {
+                       label = item.label;
+               } else if ( widget.allowArbitrary ) {
+                       label = String( data );
+               } else {
+                       return;
+               }
+
+               item = null;
+               for ( j = 0; j < items.length; j++ ) {
+                       if ( items[ j ].data === data && items[ j ].label === label ) {
+                               item = items[ j ];
+                               items.splice( j, 1 );
+                               break;
+                       }
+               }
+               if ( !item ) {
+                       item = widget.createItemWidget( data, label );
+               }
+               widget.addItems( [ item ], i );
+       } );
+
+       if ( items.length ) {
+               widget.removeItems( items );
+       }
+
+       return this;
+};
+
+/**
+ * Add items to the capsule by providing their data
+ * @chainable
+ * @param {Mixed[]} datas
+ * @return {OO.ui.CapsuleMultiSelectWidget}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.addItemsFromData = function ( datas ) {
+       var widget = this,
+               menu = this.menu,
+               items = [];
+
+       $.each( datas, function ( i, data ) {
+               var item;
+
+               if ( !widget.getItemFromData( data ) ) {
+                       item = menu.getItemFromData( data );
+                       if ( item ) {
+                               items.push( widget.createItemWidget( data, item.label ) );
+                       } else if ( widget.allowArbitrary ) {
+                               items.push( widget.createItemWidget( data, String( data ) ) );
+                       }
+               }
+       } );
+
+       if ( items.length ) {
+               this.addItems( items );
+       }
+
+       return this;
+};
+
+/**
+ * Remove items by data
+ * @chainable
+ * @param {Mixed[]} datas
+ * @return {OO.ui.CapsuleMultiSelectWidget}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.removeItemsFromData = function ( datas ) {
+       var widget = this,
+               items = [];
+
+       $.each( datas, function ( i, data ) {
+               var item = widget.getItemFromData( data );
+               if ( item ) {
+                       items.push( item );
+               }
+       } );
+
+       if ( items.length ) {
+               this.removeItems( items );
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.addItems = function ( items ) {
+       var same, i, l,
+               oldItems = this.items.slice();
+
+       OO.ui.mixin.GroupElement.prototype.addItems.call( this, items );
+
+       if ( this.items.length !== oldItems.length ) {
+               same = false;
+       } else {
+               same = true;
+               for ( i = 0, l = oldItems.length; same && i < l; i++ ) {
+                       same = same && this.items[ i ] === oldItems[ i ];
+               }
+       }
+       if ( !same ) {
+               this.emit( 'change', this.getItemsData() );
+               this.menu.position();
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.removeItems = function ( items ) {
+       var same, i, l,
+               oldItems = this.items.slice();
+
+       OO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );
+
+       if ( this.items.length !== oldItems.length ) {
+               same = false;
+       } else {
+               same = true;
+               for ( i = 0, l = oldItems.length; same && i < l; i++ ) {
+                       same = same && this.items[ i ] === oldItems[ i ];
+               }
+       }
+       if ( !same ) {
+               this.emit( 'change', this.getItemsData() );
+               this.menu.position();
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.clearItems = function () {
+       if ( this.items.length ) {
+               OO.ui.mixin.GroupElement.prototype.clearItems.call( this );
+               this.emit( 'change', this.getItemsData() );
+               this.menu.position();
+       }
+       return this;
+};
+
+/**
+ * Get the capsule widget's menu.
+ * @return {OO.ui.MenuSelectWidget} Menu widget
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.getMenu = function () {
+       return this.menu;
+};
+
+/**
+ * Handle focus events
+ *
+ * @private
+ * @param {jQuery.Event} event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onInputFocus = function () {
+       if ( !this.isDisabled() ) {
+               this.menu.toggle( true );
+       }
+};
+
+/**
+ * Handle blur events
+ *
+ * @private
+ * @param {jQuery.Event} event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onInputBlur = function () {
+       if ( this.allowArbitrary && this.$input.val().trim() !== '' ) {
+               this.addItemsFromData( [ this.$input.val() ] );
+       }
+       this.clearInput();
+};
+
+/**
+ * Handle focus events
+ *
+ * @private
+ * @param {jQuery.Event} event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onFocusForPopup = function () {
+       if ( !this.isDisabled() ) {
+               this.popup.setSize( this.$handle.width() );
+               this.popup.toggle( true );
+               this.popup.$element.find( '*' )
+                       .filter( function () { return OO.ui.isFocusableElement( $( this ), true ); } )
+                       .first()
+                       .focus();
+       }
+};
+
+/**
+ * Handles popup focus out events.
+ *
+ * @private
+ * @param {Event} e Focus out event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onPopupFocusOut = function () {
+       var widget = this.popup;
+
+       setTimeout( function () {
+               if (
+                       widget.isVisible() &&
+                       !OO.ui.contains( widget.$element[ 0 ], document.activeElement, true ) &&
+                       ( !widget.$autoCloseIgnore || !widget.$autoCloseIgnore.has( document.activeElement ).length )
+               ) {
+                       widget.toggle( false );
+               }
+       } );
+};
+
+/**
+ * Handle mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onMouseDown = function ( e ) {
+       if ( e.which === OO.ui.MouseButtons.LEFT ) {
+               this.focus();
+               return false;
+       } else {
+               this.updateInputSize();
+       }
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onKeyPress = function ( e ) {
+       var item;
+
+       if ( !this.isDisabled() ) {
+               if ( e.which === OO.ui.Keys.ESCAPE ) {
+                       this.clearInput();
+                       return false;
+               }
+
+               if ( !this.popup ) {
+                       this.menu.toggle( true );
+                       if ( e.which === OO.ui.Keys.ENTER ) {
+                               item = this.menu.getItemFromLabel( this.$input.val(), true );
+                               if ( item ) {
+                                       this.addItemsFromData( [ item.data ] );
+                                       this.clearInput();
+                               } else if ( this.allowArbitrary && this.$input.val().trim() !== '' ) {
+                                       this.addItemsFromData( [ this.$input.val() ] );
+                                       this.clearInput();
+                               }
+                               return false;
+                       }
+
+                       // Make sure the input gets resized.
+                       setTimeout( this.updateInputSize.bind( this ), 0 );
+               }
+       }
+};
+
+/**
+ * Handle key down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onKeyDown = function ( e ) {
+       if ( !this.isDisabled() ) {
+               // 'keypress' event is not triggered for Backspace
+               if ( e.keyCode === OO.ui.Keys.BACKSPACE && this.$input.val() === '' ) {
+                       if ( this.items.length ) {
+                               this.removeItems( this.items.slice( -1 ) );
+                       }
+                       return false;
+               }
+       }
+};
+
+/**
+ * Update the dimensions of the text input field to encompass all available area.
+ *
+ * @private
+ * @param {jQuery.Event} e Event of some sort
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.updateInputSize = function () {
+       var $lastItem, direction, contentWidth, currentWidth, bestWidth;
+       if ( !this.isDisabled() ) {
+               this.$input.css( 'width', '1em' );
+               $lastItem = this.$group.children().last();
+               direction = OO.ui.Element.static.getDir( this.$handle );
+               contentWidth = this.$input[ 0 ].scrollWidth;
+               currentWidth = this.$input.width();
+
+               if ( contentWidth < currentWidth ) {
+                       // All is fine, don't perform expensive calculations
+                       return;
+               }
+
+               if ( !$lastItem.length ) {
+                       bestWidth = this.$content.innerWidth();
+               } else {
+                       bestWidth = direction === 'ltr' ?
+                               this.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :
+                               $lastItem.position().left;
+               }
+               // Some safety margin for sanity, because I *really* don't feel like finding out where the few
+               // pixels this is off by are coming from.
+               bestWidth -= 10;
+               if ( contentWidth > bestWidth ) {
+                       // This will result in the input getting shifted to the next line
+                       bestWidth = this.$content.innerWidth() - 10;
+               }
+               this.$input.width( Math.floor( bestWidth ) );
+
+               this.menu.position();
+       }
+};
+
+/**
+ * Handle menu choose events.
+ *
+ * @private
+ * @param {OO.ui.OptionWidget} item Chosen item
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onMenuChoose = function ( item ) {
+       if ( item && item.isVisible() ) {
+               this.addItemsFromData( [ item.getData() ] );
+               this.clearInput();
+       }
+};
+
+/**
+ * Handle menu item change events.
+ *
+ * @private
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.onMenuItemsChange = function () {
+       this.setItemsFromData( this.getItemsData() );
+       this.$element.toggleClass( 'oo-ui-capsuleMultiSelectWidget-empty', this.menu.isEmpty() );
+};
+
+/**
+ * Clear the input field
+ * @private
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.clearInput = function () {
+       if ( this.$input ) {
+               this.$input.val( '' );
+               this.updateInputSize();
+       }
+       if ( this.popup ) {
+               this.popup.toggle( false );
+       }
+       this.menu.toggle( false );
+       this.menu.selectItem();
+       this.menu.highlightItem();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.setDisabled = function ( disabled ) {
+       var i, len;
+
+       // Parent method
+       OO.ui.CapsuleMultiSelectWidget.parent.prototype.setDisabled.call( this, disabled );
+
+       if ( this.$input ) {
+               this.$input.prop( 'disabled', this.isDisabled() );
+       }
+       if ( this.menu ) {
+               this.menu.setDisabled( this.isDisabled() );
+       }
+       if ( this.popup ) {
+               this.popup.setDisabled( this.isDisabled() );
+       }
+
+       if ( this.items ) {
+               for ( i = 0, len = this.items.length; i < len; i++ ) {
+                       this.items[ i ].updateDisabled();
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Focus the widget
+ * @chainable
+ * @return {OO.ui.CapsuleMultiSelectWidget}
+ */
+OO.ui.CapsuleMultiSelectWidget.prototype.focus = function () {
+       if ( !this.isDisabled() ) {
+               if ( this.popup ) {
+                       this.popup.setSize( this.$handle.width() );
+                       this.popup.toggle( true );
+                       this.popup.$element.find( '*' )
+                               .filter( function () { return OO.ui.isFocusableElement( $( this ), true ); } )
+                               .first()
+                               .focus();
+               } else {
+                       this.updateInputSize();
+                       this.menu.toggle( true );
+                       this.$input.focus();
+               }
+       }
+       return this;
+};
+
+/**
+ * SelectFileWidgets allow for selecting files, using the HTML5 File API. These
+ * widgets can be configured with {@link OO.ui.mixin.IconElement icons} and {@link
+ * OO.ui.mixin.IndicatorElement indicators}.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
+ *
+ *     @example
+ *     // Example of a file select widget
+ *     var selectFile = new OO.ui.SelectFileWidget();
+ *     $( 'body' ).append( selectFile.$element );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.mixin.IconElement
+ * @mixins OO.ui.mixin.IndicatorElement
+ * @mixins OO.ui.mixin.PendingElement
+ * @mixins OO.ui.mixin.LabelElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.
+ * @cfg {string} [placeholder] Text to display when no file is selected.
+ * @cfg {string} [notsupported] Text to display when file support is missing in the browser.
+ * @cfg {boolean} [droppable=true] Whether to accept files by drag and drop.
+ * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be true.
+ * @cfg {boolean} [dragDropUI=false] Deprecated alias for showDropTarget
+ */
+OO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {
+       var dragHandler;
+
+       // TODO: Remove in next release
+       if ( config && config.dragDropUI ) {
+               config.showDropTarget = true;
+       }
+
+       // Configuration initialization
+       config = $.extend( {
+               accept: null,
+               placeholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),
+               notsupported: OO.ui.msg( 'ooui-selectfile-not-supported' ),
+               droppable: true,
+               showDropTarget: false
+       }, config );
+
+       // Parent constructor
+       OO.ui.SelectFileWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.IconElement.call( this, config );
+       OO.ui.mixin.IndicatorElement.call( this, config );
+       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$info } ) );
+       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { autoFitLabel: true } ) );
+
+       // Properties
+       this.$info = $( '<span>' );
+
+       // Properties
+       this.showDropTarget = config.showDropTarget;
+       this.isSupported = this.constructor.static.isSupported();
+       this.currentFile = null;
+       if ( Array.isArray( config.accept ) ) {
+               this.accept = config.accept;
+       } else {
+               this.accept = null;
+       }
+       this.placeholder = config.placeholder;
+       this.notsupported = config.notsupported;
+       this.onFileSelectedHandler = this.onFileSelected.bind( this );
+
+       this.selectButton = new OO.ui.ButtonWidget( {
+               classes: [ 'oo-ui-selectFileWidget-selectButton' ],
+               label: OO.ui.msg( 'ooui-selectfile-button-select' ),
+               disabled: this.disabled || !this.isSupported
+       } );
+
+       this.clearButton = new OO.ui.ButtonWidget( {
+               classes: [ 'oo-ui-selectFileWidget-clearButton' ],
+               framed: false,
+               icon: 'remove',
+               disabled: this.disabled
+       } );
+
+       // Events
+       this.selectButton.$button.on( {
+               keypress: this.onKeyPress.bind( this )
+       } );
+       this.clearButton.connect( this, {
+               click: 'onClearClick'
+       } );
+       if ( config.droppable ) {
+               dragHandler = this.onDragEnterOrOver.bind( this );
+               this.$element.on( {
+                       dragenter: dragHandler,
+                       dragover: dragHandler,
+                       dragleave: this.onDragLeave.bind( this ),
+                       drop: this.onDrop.bind( this )
+               } );
+       }
+
+       // Initialization
+       this.addInput();
+       this.updateUI();
+       this.$label.addClass( 'oo-ui-selectFileWidget-label' );
+       this.$info
+               .addClass( 'oo-ui-selectFileWidget-info' )
+               .append( this.$icon, this.$label, this.clearButton.$element, this.$indicator );
+       this.$element
+               .addClass( 'oo-ui-selectFileWidget' )
+               .append( this.$info, this.selectButton.$element );
+       if ( config.droppable && config.showDropTarget ) {
+               this.$dropTarget = $( '<div>' )
+                       .addClass( 'oo-ui-selectFileWidget-dropTarget' )
+                       .text( OO.ui.msg( 'ooui-selectfile-dragdrop-placeholder' ) )
+                       .on( {
+                               click: this.onDropTargetClick.bind( this )
+                       } );
+               this.$element.prepend( this.$dropTarget );
+       }
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.SelectFileWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IconElement );
+OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IndicatorElement );
+OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.PendingElement );
+OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.LabelElement );
+
+/* Static Properties */
+
+/**
+ * Check if this widget is supported
+ *
+ * @static
+ * @return {boolean}
+ */
+OO.ui.SelectFileWidget.static.isSupported = function () {
+       var $input;
+       if ( OO.ui.SelectFileWidget.static.isSupportedCache === null ) {
+               $input = $( '<input type="file">' );
+               OO.ui.SelectFileWidget.static.isSupportedCache = $input[ 0 ].files !== undefined;
+       }
+       return OO.ui.SelectFileWidget.static.isSupportedCache;
+};
+
+OO.ui.SelectFileWidget.static.isSupportedCache = null;
+
+/* Events */
+
+/**
+ * @event change
+ *
+ * A change event is emitted when the on/off state of the toggle changes.
+ *
+ * @param {File|null} value New value
+ */
+
+/* Methods */
+
+/**
+ * Get the current value of the field
+ *
+ * @return {File|null}
+ */
+OO.ui.SelectFileWidget.prototype.getValue = function () {
+       return this.currentFile;
+};
+
+/**
+ * Set the current value of the field
+ *
+ * @param {File|null} file File to select
+ */
+OO.ui.SelectFileWidget.prototype.setValue = function ( file ) {
+       if ( this.currentFile !== file ) {
+               this.currentFile = file;
+               this.updateUI();
+               this.emit( 'change', this.currentFile );
+       }
+};
+
+/**
+ * Focus the widget.
+ *
+ * Focusses the select file button.
+ *
+ * @chainable
+ */
+OO.ui.SelectFileWidget.prototype.focus = function () {
+       this.selectButton.$button[ 0 ].focus();
+       return this;
+};
+
+/**
+ * Update the user interface when a file is selected or unselected
+ *
+ * @protected
+ */
+OO.ui.SelectFileWidget.prototype.updateUI = function () {
+       var $label;
+       if ( !this.isSupported ) {
+               this.$element.addClass( 'oo-ui-selectFileWidget-notsupported' );
+               this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
+               this.setLabel( this.notsupported );
+       } else {
+               this.$element.addClass( 'oo-ui-selectFileWidget-supported' );
+               if ( this.currentFile ) {
+                       this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
+                       $label = $( [] );
+                       $label = $label.add(
+                               $( '<span>' )
+                                       .addClass( 'oo-ui-selectFileWidget-fileName' )
+                                       .text( this.currentFile.name )
+                       );
+                       if ( this.currentFile.type !== '' ) {
+                               $label = $label.add(
+                                       $( '<span>' )
+                                               .addClass( 'oo-ui-selectFileWidget-fileType' )
+                                               .text( this.currentFile.type )
+                               );
+                       }
+                       this.setLabel( $label );
+               } else {
+                       this.$element.addClass( 'oo-ui-selectFileWidget-empty' );
+                       this.setLabel( this.placeholder );
+               }
+       }
+};
+
+/**
+ * Add the input to the widget
+ *
+ * @private
+ */
+OO.ui.SelectFileWidget.prototype.addInput = function () {
+       if ( this.$input ) {
+               this.$input.remove();
+       }
+
+       if ( !this.isSupported ) {
+               this.$input = null;
+               return;
+       }
+
+       this.$input = $( '<input type="file">' );
+       this.$input.on( 'change', this.onFileSelectedHandler );
+       this.$input.attr( {
+               tabindex: -1
+       } );
+       if ( this.accept ) {
+               this.$input.attr( 'accept', this.accept.join( ', ' ) );
+       }
+       this.selectButton.$button.append( this.$input );
+};
+
+/**
+ * Determine if we should accept this file
+ *
+ * @private
+ * @param {string} File MIME type
+ * @return {boolean}
+ */
+OO.ui.SelectFileWidget.prototype.isAllowedType = function ( mimeType ) {
+       var i, mimeTest;
+
+       if ( !this.accept || !mimeType ) {
+               return true;
+       }
+
+       for ( i = 0; i < this.accept.length; i++ ) {
+               mimeTest = this.accept[ i ];
+               if ( mimeTest === mimeType ) {
+                       return true;
+               } else if ( mimeTest.substr( -2 ) === '/*' ) {
+                       mimeTest = mimeTest.substr( 0, mimeTest.length - 1 );
+                       if ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+};
+
+/**
+ * Handle file selection from the input
+ *
+ * @private
+ * @param {jQuery.Event} e
+ */
+OO.ui.SelectFileWidget.prototype.onFileSelected = function ( e ) {
+       var file = OO.getProp( e.target, 'files', 0 ) || null;
+
+       if ( file && !this.isAllowedType( file.type ) ) {
+               file = null;
+       }
+
+       this.setValue( file );
+       this.addInput();
+};
+
+/**
+ * Handle clear button click events.
+ *
+ * @private
+ */
+OO.ui.SelectFileWidget.prototype.onClearClick = function () {
+       this.setValue( null );
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.SelectFileWidget.prototype.onKeyPress = function ( e ) {
+       if ( this.isSupported && !this.isDisabled() && this.$input &&
+               ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
+       ) {
+               this.$input.click();
+               return false;
+       }
+};
+
+/**
+ * Handle drop target click events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {
+       if ( this.isSupported && !this.isDisabled() && this.$input ) {
+               this.$input.click();
+               return false;
+       }
+};
+
+/**
+ * Handle drag enter and over events
+ *
+ * @private
+ * @param {jQuery.Event} e Drag event
+ */
+OO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {
+       var itemOrFile,
+               droppableFile = false,
+               dt = e.originalEvent.dataTransfer;
+
+       e.preventDefault();
+       e.stopPropagation();
+
+       if ( this.isDisabled() || !this.isSupported ) {
+               this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
+               dt.dropEffect = 'none';
+               return false;
+       }
+
+       // DataTransferItem and File both have a type property, but in Chrome files
+       // have no information at this point.
+       itemOrFile = OO.getProp( dt, 'items', 0 ) || OO.getProp( dt, 'files', 0 );
+       if ( itemOrFile ) {
+               if ( this.isAllowedType( itemOrFile.type ) ) {
+                       droppableFile = true;
+               }
+       // dt.types is Array-like, but not an Array
+       } else if ( Array.prototype.indexOf.call( OO.getProp( dt, 'types' ) || [], 'Files' ) !== -1 ) {
+               // File information is not available at this point for security so just assume
+               // it is acceptable for now.
+               // https://bugzilla.mozilla.org/show_bug.cgi?id=640534
+               droppableFile = true;
+       }
+
+       this.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', droppableFile );
+       if ( !droppableFile ) {
+               dt.dropEffect = 'none';
+       }
+
+       return false;
+};
+
+/**
+ * Handle drag leave events
+ *
+ * @private
+ * @param {jQuery.Event} e Drag event
+ */
+OO.ui.SelectFileWidget.prototype.onDragLeave = function () {
+       this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
+};
+
+/**
+ * Handle drop events
+ *
+ * @private
+ * @param {jQuery.Event} e Drop event
+ */
+OO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {
+       var file = null,
+               dt = e.originalEvent.dataTransfer;
+
+       e.preventDefault();
+       e.stopPropagation();
+       this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
+
+       if ( this.isDisabled() || !this.isSupported ) {
+               return false;
+       }
+
+       file = OO.getProp( dt, 'files', 0 );
+       if ( file && !this.isAllowedType( file.type ) ) {
+               file = null;
+       }
+       if ( file ) {
+               this.setValue( file );
+       }
+
+       return false;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SelectFileWidget.prototype.setDisabled = function ( disabled ) {
+       OO.ui.SelectFileWidget.parent.prototype.setDisabled.call( this, disabled );
+       if ( this.selectButton ) {
+               this.selectButton.setDisabled( disabled );
+       }
+       if ( this.clearButton ) {
+               this.clearButton.setDisabled( disabled );
+       }
+       return this;
+};
+
+/**
+ * Progress bars visually display the status of an operation, such as a download,
+ * and can be either determinate or indeterminate:
+ *
+ * - **determinate** process bars show the percent of an operation that is complete.
+ *
+ * - **indeterminate** process bars use a visual display of motion to indicate that an operation
+ *   is taking place. Because the extent of an indeterminate operation is unknown, the bar does
+ *   not use percentages.
+ *
+ * The value of the `progress` configuration determines whether the bar is determinate or indeterminate.
+ *
+ *     @example
+ *     // Examples of determinate and indeterminate progress bars.
+ *     var progressBar1 = new OO.ui.ProgressBarWidget( {
+ *         progress: 33
+ *     } );
+ *     var progressBar2 = new OO.ui.ProgressBarWidget();
+ *
+ *     // Create a FieldsetLayout to layout progress bars
+ *     var fieldset = new OO.ui.FieldsetLayout;
+ *     fieldset.addItems( [
+ *        new OO.ui.FieldLayout( progressBar1, {label: 'Determinate', align: 'top'}),
+ *        new OO.ui.FieldLayout( progressBar2, {label: 'Indeterminate', align: 'top'})
+ *     ] );
+ *     $( 'body' ).append( fieldset.$element );
+ *
+ * @class
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {number|boolean} [progress=false] The type of progress bar (determinate or indeterminate).
+ *  To create a determinate progress bar, specify a number that reflects the initial percent complete.
+ *  By default, the progress bar is indeterminate.
+ */
+OO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.ProgressBarWidget.parent.call( this, config );
+
+       // Properties
+       this.$bar = $( '<div>' );
+       this.progress = null;
+
+       // Initialization
+       this.setProgress( config.progress !== undefined ? config.progress : false );
+       this.$bar.addClass( 'oo-ui-progressBarWidget-bar' );
+       this.$element
+               .attr( {
+                       role: 'progressbar',
+                       'aria-valuemin': 0,
+                       'aria-valuemax': 100
+               } )
+               .addClass( 'oo-ui-progressBarWidget' )
+               .append( this.$bar );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ProgressBarWidget, OO.ui.Widget );
+
+/* Static Properties */
+
+OO.ui.ProgressBarWidget.static.tagName = 'div';
+
+/* Methods */
+
+/**
+ * Get the percent of the progress that has been completed. Indeterminate progresses will return `false`.
+ *
+ * @return {number|boolean} Progress percent
+ */
+OO.ui.ProgressBarWidget.prototype.getProgress = function () {
+       return this.progress;
+};
+
+/**
+ * Set the percent of the process completed or `false` for an indeterminate process.
+ *
+ * @param {number|boolean} progress Progress percent or `false` for indeterminate
+ */
+OO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {
+       this.progress = progress;
+
+       if ( progress !== false ) {
+               this.$bar.css( 'width', this.progress + '%' );
+               this.$element.attr( 'aria-valuenow', this.progress );
+       } else {
+               this.$bar.css( 'width', '' );
+               this.$element.removeAttr( 'aria-valuenow' );
+       }
+       this.$element.toggleClass( 'oo-ui-progressBarWidget-indeterminate', !progress );
+};
+
+/**
+ * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query,
+ * and a menu of search results, which is displayed beneath the query
+ * field. Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible to the user.
+ * Users can choose an item from the menu or type a query into the text field to search for a matching result item.
+ * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.
+ *
+ * Each time the query is changed, the search result menu is cleared and repopulated. Please see
+ * the [OOjs UI demos][1] for an example.
+ *
+ * [1]: https://tools.wmflabs.org/oojs-ui/oojs-ui/demos/#dialogs-mediawiki-vector-ltr
+ *
+ * @class
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string|jQuery} [placeholder] Placeholder text for query input
+ * @cfg {string} [value] Initial query value
+ */
+OO.ui.SearchWidget = function OoUiSearchWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.SearchWidget.parent.call( this, config );
+
+       // Properties
+       this.query = new OO.ui.TextInputWidget( {
+               icon: 'search',
+               placeholder: config.placeholder,
+               value: config.value
+       } );
+       this.results = new OO.ui.SelectWidget();
+       this.$query = $( '<div>' );
+       this.$results = $( '<div>' );
+
+       // Events
+       this.query.connect( this, {
+               change: 'onQueryChange',
+               enter: 'onQueryEnter'
+       } );
+       this.query.$input.on( 'keydown', this.onQueryKeydown.bind( this ) );
+
+       // Initialization
+       this.$query
+               .addClass( 'oo-ui-searchWidget-query' )
+               .append( this.query.$element );
+       this.$results
+               .addClass( 'oo-ui-searchWidget-results' )
+               .append( this.results.$element );
+       this.$element
+               .addClass( 'oo-ui-searchWidget' )
+               .append( this.$results, this.$query );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget );
+
+/* Methods */
+
+/**
+ * Handle query key down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {
+       var highlightedItem, nextItem,
+               dir = e.which === OO.ui.Keys.DOWN ? 1 : ( e.which === OO.ui.Keys.UP ? -1 : 0 );
+
+       if ( dir ) {
+               highlightedItem = this.results.getHighlightedItem();
+               if ( !highlightedItem ) {
+                       highlightedItem = this.results.getSelectedItem();
+               }
+               nextItem = this.results.getRelativeSelectableItem( highlightedItem, dir );
+               this.results.highlightItem( nextItem );
+               nextItem.scrollElementIntoView();
+       }
+};
+
+/**
+ * Handle select widget select events.
+ *
+ * Clears existing results. Subclasses should repopulate items according to new query.
+ *
+ * @private
+ * @param {string} value New value
+ */
+OO.ui.SearchWidget.prototype.onQueryChange = function () {
+       // Reset
+       this.results.clearItems();
+};
+
+/**
+ * Handle select widget enter key events.
+ *
+ * Chooses highlighted item.
+ *
+ * @private
+ * @param {string} value New value
+ */
+OO.ui.SearchWidget.prototype.onQueryEnter = function () {
+       var highlightedItem = this.results.getHighlightedItem();
+       if ( highlightedItem ) {
+               this.results.chooseItem( highlightedItem );
+       }
+};
+
+/**
+ * Get the query input.
+ *
+ * @return {OO.ui.TextInputWidget} Query input
+ */
+OO.ui.SearchWidget.prototype.getQuery = function () {
+       return this.query;
+};
+
+/**
+ * Get the search results menu.
+ *
+ * @return {OO.ui.SelectWidget} Menu of search results
+ */
+OO.ui.SearchWidget.prototype.getResults = function () {
+       return this.results;
+};
+
+/**
+ * NumberInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value
+ * can be entered manually) and two {@link OO.ui.ButtonWidget button widgets}
+ * (to adjust the value in increments) to allow the user to enter a number.
+ *
+ *     @example
+ *     // Example: A NumberInputWidget.
+ *     var numberInput = new OO.ui.NumberInputWidget( {
+ *         label: 'NumberInputWidget',
+ *         input: { value: 5, min: 1, max: 10 }
+ *     } );
+ *     $( 'body' ).append( numberInput.$element );
+ *
+ * @class
+ * @extends OO.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {Object} [input] Configuration options to pass to the {@link OO.ui.TextInputWidget text input widget}.
+ * @cfg {Object} [minusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget decrementing button widget}.
+ * @cfg {Object} [plusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget incrementing button widget}.
+ * @cfg {boolean} [isInteger=false] Whether the field accepts only integer values.
+ * @cfg {number} [min=-Infinity] Minimum allowed value
+ * @cfg {number} [max=Infinity] Maximum allowed value
+ * @cfg {number} [step=1] Delta when using the buttons or up/down arrow keys
+ * @cfg {number|null} [pageStep] Delta when using the page-up/page-down keys. Defaults to 10 times #step.
+ */
+OO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {
+       // Configuration initialization
+       config = $.extend( {
+               isInteger: false,
+               min: -Infinity,
+               max: Infinity,
+               step: 1,
+               pageStep: null
+       }, config );
+
+       // Parent constructor
+       OO.ui.NumberInputWidget.parent.call( this, config );
+
+       // Properties
+       this.input = new OO.ui.TextInputWidget( $.extend(
+               {
+                       disabled: this.isDisabled()
+               },
+               config.input
+       ) );
+       this.minusButton = new OO.ui.ButtonWidget( $.extend(
+               {
+                       disabled: this.isDisabled(),
+                       tabIndex: -1
+               },
+               config.minusButton,
+               {
+                       classes: [ 'oo-ui-numberInputWidget-minusButton' ],
+                       label: '−'
+               }
+       ) );
+       this.plusButton = new OO.ui.ButtonWidget( $.extend(
+               {
+                       disabled: this.isDisabled(),
+                       tabIndex: -1
+               },
+               config.plusButton,
+               {
+                       classes: [ 'oo-ui-numberInputWidget-plusButton' ],
+                       label: '+'
+               }
+       ) );
+
+       // Events
+       this.input.connect( this, {
+               change: this.emit.bind( this, 'change' ),
+               enter: this.emit.bind( this, 'enter' )
+       } );
+       this.input.$input.on( {
+               keydown: this.onKeyDown.bind( this ),
+               'wheel mousewheel DOMMouseScroll': this.onWheel.bind( this )
+       } );
+       this.plusButton.connect( this, {
+               click: [ 'onButtonClick', +1 ]
+       } );
+       this.minusButton.connect( this, {
+               click: [ 'onButtonClick', -1 ]
+       } );
+
+       // Initialization
+       this.setIsInteger( !!config.isInteger );
+       this.setRange( config.min, config.max );
+       this.setStep( config.step, config.pageStep );
+
+       this.$field = $( '<div>' ).addClass( 'oo-ui-numberInputWidget-field' )
+               .append(
+                       this.minusButton.$element,
+                       this.input.$element,
+                       this.plusButton.$element
+               );
+       this.$element.addClass( 'oo-ui-numberInputWidget' ).append( this.$field );
+       this.input.setValidation( this.validateNumber.bind( this ) );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.NumberInputWidget, OO.ui.Widget );
+
+/* Events */
+
+/**
+ * A `change` event is emitted when the value of the input changes.
+ *
+ * @event change
+ */
+
+/**
+ * An `enter` event is emitted when the user presses 'enter' inside the text box.
+ *
+ * @event enter
+ */
+
+/* Methods */
+
+/**
+ * Set whether only integers are allowed
+ * @param {boolean} flag
+ */
+OO.ui.NumberInputWidget.prototype.setIsInteger = function ( flag ) {
+       this.isInteger = !!flag;
+       this.input.setValidityFlag();
+};
+
+/**
+ * Get whether only integers are allowed
+ * @return {boolean} Flag value
+ */
+OO.ui.NumberInputWidget.prototype.getIsInteger = function () {
+       return this.isInteger;
+};
+
+/**
+ * Set the range of allowed values
+ * @param {number} min Minimum allowed value
+ * @param {number} max Maximum allowed value
+ */
+OO.ui.NumberInputWidget.prototype.setRange = function ( min, max ) {
+       if ( min > max ) {
+               throw new Error( 'Minimum (' + min + ') must not be greater than maximum (' + max + ')' );
+       }
+       this.min = min;
+       this.max = max;
+       this.input.setValidityFlag();
+};
+
+/**
+ * Get the current range
+ * @return {number[]} Minimum and maximum values
+ */
+OO.ui.NumberInputWidget.prototype.getRange = function () {
+       return [ this.min, this.max ];
+};
+
+/**
+ * Set the stepping deltas
+ * @param {number} step Normal step
+ * @param {number|null} pageStep Page step. If null, 10 * step will be used.
+ */
+OO.ui.NumberInputWidget.prototype.setStep = function ( step, pageStep ) {
+       if ( step <= 0 ) {
+               throw new Error( 'Step value must be positive' );
+       }
+       if ( pageStep === null ) {
+               pageStep = step * 10;
+       } else if ( pageStep <= 0 ) {
+               throw new Error( 'Page step value must be positive' );
+       }
+       this.step = step;
+       this.pageStep = pageStep;
+};
+
+/**
+ * Get the current stepping values
+ * @return {number[]} Step and page step
+ */
+OO.ui.NumberInputWidget.prototype.getStep = function () {
+       return [ this.step, this.pageStep ];
+};
+
+/**
+ * Get the current value of the widget
+ * @return {string}
+ */
+OO.ui.NumberInputWidget.prototype.getValue = function () {
+       return this.input.getValue();
+};
+
+/**
+ * Get the current value of the widget as a number
+ * @return {number} May be NaN, or an invalid number
+ */
+OO.ui.NumberInputWidget.prototype.getNumericValue = function () {
+       return +this.input.getValue();
+};
+
+/**
+ * Set the value of the widget
+ * @param {string} value Invalid values are allowed
+ */
+OO.ui.NumberInputWidget.prototype.setValue = function ( value ) {
+       this.input.setValue( value );
+};
+
+/**
+ * Adjust the value of the widget
+ * @param {number} delta Adjustment amount
+ */
+OO.ui.NumberInputWidget.prototype.adjustValue = function ( delta ) {
+       var n, v = this.getNumericValue();
+
+       delta = +delta;
+       if ( isNaN( delta ) || !isFinite( delta ) ) {
+               throw new Error( 'Delta must be a finite number' );
+       }
+
+       if ( isNaN( v ) ) {
+               n = 0;
+       } else {
+               n = v + delta;
+               n = Math.max( Math.min( n, this.max ), this.min );
+               if ( this.isInteger ) {
+                       n = Math.round( n );
+               }
+       }
+
+       if ( n !== v ) {
+               this.setValue( n );
+       }
+};
+
+/**
+ * Validate input
+ * @private
+ * @param {string} value Field value
+ * @return {boolean}
+ */
+OO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {
+       var n = +value;
+       if ( isNaN( n ) || !isFinite( n ) ) {
+               return false;
+       }
+
+       /*jshint bitwise: false */
+       if ( this.isInteger && ( n | 0 ) !== n ) {
+               return false;
+       }
+       /*jshint bitwise: true */
+
+       if ( n < this.min || n > this.max ) {
+               return false;
+       }
+
+       return true;
+};
+
+/**
+ * Handle mouse click events.
+ *
+ * @private
+ * @param {number} dir +1 or -1
+ */
+OO.ui.NumberInputWidget.prototype.onButtonClick = function ( dir ) {
+       this.adjustValue( dir * this.step );
+};
+
+/**
+ * Handle mouse wheel events.
+ *
+ * @private
+ * @param {jQuery.Event} event
+ */
+OO.ui.NumberInputWidget.prototype.onWheel = function ( event ) {
+       var delta = 0;
+
+       // Standard 'wheel' event
+       if ( event.originalEvent.deltaMode !== undefined ) {
+               this.sawWheelEvent = true;
+       }
+       if ( event.originalEvent.deltaY ) {
+               delta = -event.originalEvent.deltaY;
+       } else if ( event.originalEvent.deltaX ) {
+               delta = event.originalEvent.deltaX;
+       }
+
+       // Non-standard events
+       if ( !this.sawWheelEvent ) {
+               if ( event.originalEvent.wheelDeltaX ) {
+                       delta = -event.originalEvent.wheelDeltaX;
+               } else if ( event.originalEvent.wheelDeltaY ) {
+                       delta = event.originalEvent.wheelDeltaY;
+               } else if ( event.originalEvent.wheelDelta ) {
+                       delta = event.originalEvent.wheelDelta;
+               } else if ( event.originalEvent.detail ) {
+                       delta = -event.originalEvent.detail;
+               }
+       }
+
+       if ( delta ) {
+               delta = delta < 0 ? -1 : 1;
+               this.adjustValue( delta * this.step );
+       }
+
+       return false;
+};
+
+/**
+ * Handle key down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.NumberInputWidget.prototype.onKeyDown = function ( e ) {
+       if ( !this.isDisabled() ) {
+               switch ( e.which ) {
+                       case OO.ui.Keys.UP:
+                               this.adjustValue( this.step );
+                               return false;
+                       case OO.ui.Keys.DOWN:
+                               this.adjustValue( -this.step );
+                               return false;
+                       case OO.ui.Keys.PAGEUP:
+                               this.adjustValue( this.pageStep );
+                               return false;
+                       case OO.ui.Keys.PAGEDOWN:
+                               this.adjustValue( -this.pageStep );
+                               return false;
+               }
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {
+       // Parent method
+       OO.ui.NumberInputWidget.parent.prototype.setDisabled.call( this, disabled );
+
+       if ( this.input ) {
+               this.input.setDisabled( this.isDisabled() );
+       }
+       if ( this.minusButton ) {
+               this.minusButton.setDisabled( this.isDisabled() );
+       }
+       if ( this.plusButton ) {
+               this.plusButton.setDisabled( this.isDisabled() );
+       }
+
+       return this;
+};
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui-windows-apex.css b/resources/lib/oojs-ui/oojs-ui-windows-apex.css
new file mode 100644 (file)
index 0000000..788b70d
--- /dev/null
@@ -0,0 +1,449 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-ms-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-o-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-actionWidget.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
+}
+.oo-ui-window {
+       background-color: transparent;
+       background-image: none;
+}
+.oo-ui-window-frame {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-window-content:focus {
+       outline: none;
+}
+.oo-ui-window-head,
+.oo-ui-window-foot {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-window-body {
+       margin: 0;
+       padding: 0;
+       background: none;
+}
+.oo-ui-window-overlay {
+       position: absolute;
+       top: 0;
+       /* @noflip */
+       left: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-head,
+.oo-ui-dialog-content > .oo-ui-window-body,
+.oo-ui-dialog-content > .oo-ui-window-foot {
+       position: absolute;
+       left: 0;
+       right: 0;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dialog-content > .oo-ui-window-head {
+       overflow: hidden;
+       z-index: 1;
+       top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+       overflow: auto;
+       z-index: 2;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-foot {
+       overflow: hidden;
+       z-index: 1;
+       bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+       box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-messageDialog-actions-horizontal {
+       display: table;
+       table-layout: fixed;
+       width: 100%;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+       display: table-cell;
+       width: 1%;
+}
+.oo-ui-messageDialog-actions-vertical {
+       display: block;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+       display: block;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+       position: relative;
+       text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+       display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+       position: relative;
+       top: auto;
+       bottom: auto;
+       display: inline;
+       white-space: nowrap;
+}
+.oo-ui-messageDialog-content .oo-ui-window-body {
+       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+}
+.oo-ui-messageDialog-title,
+.oo-ui-messageDialog-message {
+       display: block;
+       text-align: center;
+}
+.oo-ui-messageDialog-title.oo-ui-labelElement,
+.oo-ui-messageDialog-message.oo-ui-labelElement {
+       padding-top: 0.5em;
+}
+.oo-ui-messageDialog-title {
+       font-size: 1.5em;
+       line-height: 1em;
+       color: #000000;
+}
+.oo-ui-messageDialog-message {
+       font-size: 0.9em;
+       line-height: 1.25em;
+       color: #666666;
+}
+.oo-ui-messageDialog-message-verbose {
+       font-size: 1.1em;
+       line-height: 1.5em;
+       text-align: left;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+       border-right: 1px solid #e5e5e5;
+       margin: 0;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
+       border-right-width: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+       border-bottom: 1px solid #e5e5e5;
+       margin: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+       border-bottom-width: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+       height: 3.4em;
+       margin-right: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       text-align: center;
+       line-height: 3.4em;
+       padding: 0 2em;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
+       background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
+       background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
+       background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
+       background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
+       font-weight: bold;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+       background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+       background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+       background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+       background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-location {
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.oo-ui-processDialog-title {
+       display: inline;
+       padding: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
+       white-space: nowrap;
+}
+.oo-ui-processDialog-actions-safe,
+.oo-ui-processDialog-actions-primary {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-processDialog-actions-safe {
+       left: 0;
+}
+.oo-ui-processDialog-actions-primary {
+       right: 0;
+}
+.oo-ui-processDialog-errors {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       z-index: 2;
+       overflow-x: hidden;
+       overflow-y: auto;
+}
+.oo-ui-processDialog-content .oo-ui-window-head {
+       height: 3.4em;
+}
+.oo-ui-processDialog-content .oo-ui-window-body {
+       top: 3.4em;
+       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+}
+.oo-ui-processDialog-navigation {
+       position: relative;
+       height: 3.4em;
+       padding: 0 1em;
+}
+.oo-ui-processDialog-location {
+       padding: 0.75em 0;
+       height: 1.875em;
+       cursor: default;
+       text-align: center;
+}
+.oo-ui-processDialog-title {
+       font-weight: bold;
+       line-height: 1.875em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
+       min-width: 1.875em;
+       min-height: 1.875em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
+       line-height: 1.875em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+       margin-top: -0.125em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
+       margin: 0.75em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+       padding: 0 1em;
+       vertical-align: middle;
+       margin: -1px;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
+       margin: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
+       padding: 0.75em 1em;
+       vertical-align: middle;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
+       background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active {
+       background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
+       background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
+       background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
+       font-weight: bold;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+       background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+       background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+       background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+       background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
+       margin-right: 0;
+}
+.oo-ui-processDialog > .oo-ui-window-frame {
+       min-height: 5em;
+}
+.oo-ui-processDialog-errors {
+       background-color: rgba(255, 255, 255, 0.9);
+       padding: 3em 3em 1.5em 3em;
+       text-align: center;
+}
+.oo-ui-processDialog-errors .oo-ui-buttonWidget {
+       margin: 2em 1em 2em 1em;
+}
+.oo-ui-processDialog-errors-title {
+       font-size: 1.5em;
+       color: #000000;
+       margin-bottom: 2em;
+}
+.oo-ui-processDialog-error {
+       text-align: left;
+       margin: 1em;
+       padding: 1em;
+       border: 1px solid #ff9e9e;
+       background-color: #fff7f7;
+       border-radius: 0.25em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+       position: fixed;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
+       width: auto;
+       height: auto;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       padding: 1em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+       position: absolute;
+       right: 0;
+       left: 0;
+       margin: auto;
+       overflow: hidden;
+       max-width: 100%;
+       max-height: 100%;
+}
+.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+       background-color: rgba(255, 255, 255, 0.5);
+       opacity: 0;
+       -webkit-transition: opacity 250ms ease;
+          -moz-transition: opacity 250ms ease;
+               transition: opacity 250ms ease;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
+       background-color: #ffffff;
+       opacity: 0;
+       -webkit-transform: scale(0.5);
+          -moz-transform: scale(0.5);
+           -ms-transform: scale(0.5);
+               transform: scale(0.5);
+       -webkit-transition: all 250ms ease;
+          -moz-transition: all 250ms ease;
+               transition: all 250ms ease;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
+       opacity: 1;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+       opacity: 1;
+       -webkit-transform: scale(1);
+          -moz-transform: scale(1);
+           -ms-transform: scale(1);
+               transform: scale(1);
+}
+.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
+       top: 1em;
+       bottom: 1em;
+       border: 1px solid #cccccc;
+       border-radius: 0.5em;
+       box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
new file mode 100644 (file)
index 0000000..ead41ca
--- /dev/null
@@ -0,0 +1,408 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:06Z
+ */
+@-webkit-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@-moz-keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+@keyframes oo-ui-progressBarWidget-slide {
+       from {
+               margin-left: -40%;
+       }
+       to {
+               margin-left: 100%;
+       }
+}
+.oo-ui-window {
+       background: transparent;
+}
+.oo-ui-window-frame {
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-window-content:focus {
+       outline: none;
+}
+.oo-ui-window-head,
+.oo-ui-window-foot {
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+}
+.oo-ui-window-body {
+       margin: 0;
+       padding: 0;
+       background: none;
+}
+.oo-ui-window-overlay {
+       position: absolute;
+       top: 0;
+       /* @noflip */
+       left: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-head,
+.oo-ui-dialog-content > .oo-ui-window-body,
+.oo-ui-dialog-content > .oo-ui-window-foot {
+       position: absolute;
+       left: 0;
+       right: 0;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-dialog-content > .oo-ui-window-head {
+       overflow: hidden;
+       z-index: 1;
+       top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+       overflow: auto;
+       z-index: 2;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-foot {
+       overflow: hidden;
+       z-index: 1;
+       bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+       outline: 1px solid #aaaaaa;
+}
+.oo-ui-messageDialog-actions-horizontal {
+       display: table;
+       table-layout: fixed;
+       width: 100%;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+       display: table-cell;
+       width: 1%;
+}
+.oo-ui-messageDialog-actions-vertical {
+       display: block;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+       display: block;
+       overflow: hidden;
+       text-overflow: ellipsis;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+       position: relative;
+       text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+       display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+       position: relative;
+       top: auto;
+       bottom: auto;
+       display: inline;
+       white-space: nowrap;
+}
+.oo-ui-messageDialog-title,
+.oo-ui-messageDialog-message {
+       display: block;
+       text-align: center;
+}
+.oo-ui-messageDialog-title.oo-ui-labelElement,
+.oo-ui-messageDialog-message.oo-ui-labelElement {
+       padding-top: 0.5em;
+}
+.oo-ui-messageDialog-title {
+       font-size: 1.5em;
+       line-height: 1em;
+       color: #000000;
+}
+.oo-ui-messageDialog-message {
+       font-size: 0.9em;
+       line-height: 1.25em;
+       color: #555555;
+}
+.oo-ui-messageDialog-message-verbose {
+       font-size: 1.1em;
+       line-height: 1.5em;
+       text-align: left;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+       border-right: 1px solid #e5e5e5;
+       margin: 0;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
+       border-right-width: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+       border-bottom: 1px solid #e5e5e5;
+       margin: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+       border-bottom-width: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+       height: 3.4em;
+       margin-right: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
+       margin-right: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+       text-align: center;
+       line-height: 3.4em;
+       padding: 0 2em;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
+       background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
+       background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
+       background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
+       background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
+       font-weight: bold;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+       background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+       background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+       background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+       background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-location {
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
+}
+.oo-ui-processDialog-title {
+       display: inline;
+       padding: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
+       white-space: nowrap;
+}
+.oo-ui-processDialog-actions-safe,
+.oo-ui-processDialog-actions-primary {
+       position: absolute;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-processDialog-actions-safe {
+       left: 0;
+}
+.oo-ui-processDialog-actions-primary {
+       right: 0;
+}
+.oo-ui-processDialog-errors {
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       z-index: 2;
+       overflow-x: hidden;
+       overflow-y: auto;
+}
+.oo-ui-processDialog-content .oo-ui-window-head {
+       height: 3.4em;
+}
+.oo-ui-processDialog-content .oo-ui-window-body {
+       top: 3.4em;
+       outline: 1px solid rgba(0, 0, 0, 0.2);
+}
+.oo-ui-processDialog-navigation {
+       position: relative;
+       height: 3.4em;
+       padding: 0 1em;
+}
+.oo-ui-processDialog-location {
+       padding: 0.75em 0;
+       height: 1.875em;
+       cursor: default;
+       text-align: center;
+}
+.oo-ui-processDialog-title {
+       font-weight: bold;
+       line-height: 1.875em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
+       margin: 0.5em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
+       margin: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
+       padding: 0.75em 1em;
+       vertical-align: middle;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label {
+       line-height: 1.875em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover {
+       background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active {
+       background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover {
+       background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active {
+       background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
+       font-weight: bold;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
+       background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
+       background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover {
+       background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active {
+       background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
+       margin-right: 0;
+}
+.oo-ui-processDialog > .oo-ui-window-frame {
+       min-height: 5em;
+}
+.oo-ui-processDialog-errors {
+       background-color: rgba(255, 255, 255, 0.9);
+       padding: 3em 3em 1.5em 3em;
+       text-align: center;
+}
+.oo-ui-processDialog-errors .oo-ui-buttonWidget {
+       margin: 2em 1em 2em 1em;
+}
+.oo-ui-processDialog-errors-title {
+       font-size: 1.5em;
+       color: #000000;
+       margin-bottom: 2em;
+}
+.oo-ui-processDialog-error {
+       text-align: left;
+       margin: 1em;
+       padding: 1em;
+       border: 1px solid #ff9e9e;
+       background-color: #fff7f7;
+       border-radius: 2px;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+       position: fixed;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
+       width: auto;
+       height: auto;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       padding: 1em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+       position: absolute;
+       right: 0;
+       left: 0;
+       margin: auto;
+       overflow: hidden;
+       max-width: 100%;
+       max-height: 100%;
+}
+.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
+       width: 100%;
+       height: 100%;
+       top: 0;
+       bottom: 0;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+       background-color: rgba(255, 255, 255, 0.5);
+       opacity: 0;
+       -webkit-transition: opacity 250ms ease;
+          -moz-transition: opacity 250ms ease;
+               transition: opacity 250ms ease;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
+       background-color: #ffffff;
+       opacity: 0;
+       -webkit-transform: scale(0.5);
+          -moz-transform: scale(0.5);
+           -ms-transform: scale(0.5);
+               transform: scale(0.5);
+       -webkit-transition: all 250ms ease;
+          -moz-transition: all 250ms ease;
+               transition: all 250ms ease;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
+       opacity: 1;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+       opacity: 1;
+       -webkit-transform: scale(1);
+          -moz-transform: scale(1);
+           -ms-transform: scale(1);
+               transform: scale(1);
+}
+.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
+       top: 1em;
+       bottom: 1em;
+       border: 1px solid #aaaaaa;
+       border-radius: 2px;
+       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+}
diff --git a/resources/lib/oojs-ui/oojs-ui-windows.js b/resources/lib/oojs-ui/oojs-ui-windows.js
new file mode 100644 (file)
index 0000000..1ccd433
--- /dev/null
@@ -0,0 +1,3395 @@
+/*!
+ * OOjs UI v0.15.2
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2016-02-02T22:07:00Z
+ */
+( function ( OO ) {
+
+'use strict';
+
+/**
+ * An ActionWidget is a {@link OO.ui.ButtonWidget button widget} that executes an action.
+ * Action widgets are used with OO.ui.ActionSet, which manages the behavior and availability
+ * of the actions.
+ *
+ * Both actions and action sets are primarily used with {@link OO.ui.Dialog Dialogs}.
+ * Please see the [OOjs UI documentation on MediaWiki] [1] for more information
+ * and examples.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
+ *
+ * @class
+ * @extends OO.ui.ButtonWidget
+ * @mixins OO.ui.mixin.PendingElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [action] Symbolic name of the action (e.g., ‘continue’ or ‘cancel’).
+ * @cfg {string[]} [modes] Symbolic names of the modes (e.g., ‘edit’ or ‘read’) in which the action
+ *  should be made available. See the action set's {@link OO.ui.ActionSet#setMode setMode} method
+ *  for more information about setting modes.
+ * @cfg {boolean} [framed=false] Render the action button with a frame
+ */
+OO.ui.ActionWidget = function OoUiActionWidget( config ) {
+       // Configuration initialization
+       config = $.extend( { framed: false }, config );
+
+       // Parent constructor
+       OO.ui.ActionWidget.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.PendingElement.call( this, config );
+
+       // Properties
+       this.action = config.action || '';
+       this.modes = config.modes || [];
+       this.width = 0;
+       this.height = 0;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-actionWidget' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );
+OO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement );
+
+/* Events */
+
+/**
+ * A resize event is emitted when the size of the widget changes.
+ *
+ * @event resize
+ */
+
+/* Methods */
+
+/**
+ * Check if the action is configured to be available in the specified `mode`.
+ *
+ * @param {string} mode Name of mode
+ * @return {boolean} The action is configured with the mode
+ */
+OO.ui.ActionWidget.prototype.hasMode = function ( mode ) {
+       return this.modes.indexOf( mode ) !== -1;
+};
+
+/**
+ * Get the symbolic name of the action (e.g., ‘continue’ or ‘cancel’).
+ *
+ * @return {string}
+ */
+OO.ui.ActionWidget.prototype.getAction = function () {
+       return this.action;
+};
+
+/**
+ * Get the symbolic name of the mode or modes for which the action is configured to be available.
+ *
+ * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method.
+ * Only actions that are configured to be avaiable in the current mode will be visible. All other actions
+ * are hidden.
+ *
+ * @return {string[]}
+ */
+OO.ui.ActionWidget.prototype.getModes = function () {
+       return this.modes.slice();
+};
+
+/**
+ * Emit a resize event if the size has changed.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.ActionWidget.prototype.propagateResize = function () {
+       var width, height;
+
+       if ( this.isElementAttached() ) {
+               width = this.$element.width();
+               height = this.$element.height();
+
+               if ( width !== this.width || height !== this.height ) {
+                       this.width = width;
+                       this.height = height;
+                       this.emit( 'resize' );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ActionWidget.prototype.setIcon = function () {
+       // Mixin method
+       OO.ui.mixin.IconElement.prototype.setIcon.apply( this, arguments );
+       this.propagateResize();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ActionWidget.prototype.setLabel = function () {
+       // Mixin method
+       OO.ui.mixin.LabelElement.prototype.setLabel.apply( this, arguments );
+       this.propagateResize();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ActionWidget.prototype.setFlags = function () {
+       // Mixin method
+       OO.ui.mixin.FlaggedElement.prototype.setFlags.apply( this, arguments );
+       this.propagateResize();
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ActionWidget.prototype.clearFlags = function () {
+       // Mixin method
+       OO.ui.mixin.FlaggedElement.prototype.clearFlags.apply( this, arguments );
+       this.propagateResize();
+
+       return this;
+};
+
+/**
+ * Toggle the visibility of the action button.
+ *
+ * @param {boolean} [show] Show button, omit to toggle visibility
+ * @chainable
+ */
+OO.ui.ActionWidget.prototype.toggle = function () {
+       // Parent method
+       OO.ui.ActionWidget.parent.prototype.toggle.apply( this, arguments );
+       this.propagateResize();
+
+       return this;
+};
+
+/**
+ * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.
+ * Actions can be made available for specific contexts (modes) and circumstances
+ * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}.
+ *
+ * ActionSets contain two types of actions:
+ *
+ * - Special: Special actions are the first visible actions with special flags, such as 'safe' and 'primary', the default special flags. Additional special flags can be configured in subclasses with the static #specialFlags property.
+ * - Other: Other actions include all non-special visible actions.
+ *
+ * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
+ *
+ *     @example
+ *     // Example: An action set used in a process dialog
+ *     function MyProcessDialog( config ) {
+ *         MyProcessDialog.parent.call( this, config );
+ *     }
+ *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );
+ *     MyProcessDialog.static.title = 'An action set in a process dialog';
+ *     // An action set that uses modes ('edit' and 'help' mode, in this example).
+ *     MyProcessDialog.static.actions = [
+ *         { action: 'continue', modes: 'edit', label: 'Continue', flags: [ 'primary', 'constructive' ] },
+ *         { action: 'help', modes: 'edit', label: 'Help' },
+ *         { modes: 'edit', label: 'Cancel', flags: 'safe' },
+ *         { action: 'back', modes: 'help', label: 'Back', flags: 'safe' }
+ *     ];
+ *
+ *     MyProcessDialog.prototype.initialize = function () {
+ *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
+ *         this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
+ *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, cancel, back) configured with modes. This is edit mode. Click \'help\' to see help mode.</p>' );
+ *         this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
+ *         this.panel2.$element.append( '<p>This is help mode. Only the \'back\' action widget is configured to be visible here. Click \'back\' to return to \'edit\' mode.</p>' );
+ *         this.stackLayout = new OO.ui.StackLayout( {
+ *             items: [ this.panel1, this.panel2 ]
+ *         } );
+ *         this.$body.append( this.stackLayout.$element );
+ *     };
+ *     MyProcessDialog.prototype.getSetupProcess = function ( data ) {
+ *         return MyProcessDialog.parent.prototype.getSetupProcess.call( this, data )
+ *             .next( function () {
+ *                 this.actions.setMode( 'edit' );
+ *             }, this );
+ *     };
+ *     MyProcessDialog.prototype.getActionProcess = function ( action ) {
+ *         if ( action === 'help' ) {
+ *             this.actions.setMode( 'help' );
+ *             this.stackLayout.setItem( this.panel2 );
+ *         } else if ( action === 'back' ) {
+ *             this.actions.setMode( 'edit' );
+ *             this.stackLayout.setItem( this.panel1 );
+ *         } else if ( action === 'continue' ) {
+ *             var dialog = this;
+ *             return new OO.ui.Process( function () {
+ *                 dialog.close();
+ *             } );
+ *         }
+ *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );
+ *     };
+ *     MyProcessDialog.prototype.getBodyHeight = function () {
+ *         return this.panel1.$element.outerHeight( true );
+ *     };
+ *     var windowManager = new OO.ui.WindowManager();
+ *     $( 'body' ).append( windowManager.$element );
+ *     var dialog = new MyProcessDialog( {
+ *         size: 'medium'
+ *     } );
+ *     windowManager.addWindows( [ dialog ] );
+ *     windowManager.openWindow( dialog );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
+ *
+ * @abstract
+ * @class
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ActionSet = function OoUiActionSet( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+
+       // Properties
+       this.list = [];
+       this.categories = {
+               actions: 'getAction',
+               flags: 'getFlags',
+               modes: 'getModes'
+       };
+       this.categorized = {};
+       this.special = {};
+       this.others = [];
+       this.organized = false;
+       this.changing = false;
+       this.changed = false;
+};
+
+/* Setup */
+
+OO.mixinClass( OO.ui.ActionSet, OO.EventEmitter );
+
+/* Static Properties */
+
+/**
+ * Symbolic name of the flags used to identify special actions. Special actions are displayed in the
+ *  header of a {@link OO.ui.ProcessDialog process dialog}.
+ *  See the [OOjs UI documentation on MediaWiki][2] for more information and examples.
+ *
+ *  [2]:https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];
+
+/* Events */
+
+/**
+ * @event click
+ *
+ * A 'click' event is emitted when an action is clicked.
+ *
+ * @param {OO.ui.ActionWidget} action Action that was clicked
+ */
+
+/**
+ * @event resize
+ *
+ * A 'resize' event is emitted when an action widget is resized.
+ *
+ * @param {OO.ui.ActionWidget} action Action that was resized
+ */
+
+/**
+ * @event add
+ *
+ * An 'add' event is emitted when actions are {@link #method-add added} to the action set.
+ *
+ * @param {OO.ui.ActionWidget[]} added Actions added
+ */
+
+/**
+ * @event remove
+ *
+ * A 'remove' event is emitted when actions are {@link #method-remove removed}
+ *  or {@link #clear cleared}.
+ *
+ * @param {OO.ui.ActionWidget[]} added Actions removed
+ */
+
+/**
+ * @event change
+ *
+ * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared},
+ * or {@link #method-remove removed} from the action set or when the {@link #setMode mode} is changed.
+ *
+ */
+
+/* Methods */
+
+/**
+ * Handle action change events.
+ *
+ * @private
+ * @fires change
+ */
+OO.ui.ActionSet.prototype.onActionChange = function () {
+       this.organized = false;
+       if ( this.changing ) {
+               this.changed = true;
+       } else {
+               this.emit( 'change' );
+       }
+};
+
+/**
+ * Check if an action is one of the special actions.
+ *
+ * @param {OO.ui.ActionWidget} action Action to check
+ * @return {boolean} Action is special
+ */
+OO.ui.ActionSet.prototype.isSpecial = function ( action ) {
+       var flag;
+
+       for ( flag in this.special ) {
+               if ( action === this.special[ flag ] ) {
+                       return true;
+               }
+       }
+
+       return false;
+};
+
+/**
+ * Get action widgets based on the specified filter: ‘actions’, ‘flags’, ‘modes’, ‘visible’,
+ *  or ‘disabled’.
+ *
+ * @param {Object} [filters] Filters to use, omit to get all actions
+ * @param {string|string[]} [filters.actions] Actions that action widgets must have
+ * @param {string|string[]} [filters.flags] Flags that action widgets must have (e.g., 'safe')
+ * @param {string|string[]} [filters.modes] Modes that action widgets must have
+ * @param {boolean} [filters.visible] Action widgets must be visible
+ * @param {boolean} [filters.disabled] Action widgets must be disabled
+ * @return {OO.ui.ActionWidget[]} Action widgets matching all criteria
+ */
+OO.ui.ActionSet.prototype.get = function ( filters ) {
+       var i, len, list, category, actions, index, match, matches;
+
+       if ( filters ) {
+               this.organize();
+
+               // Collect category candidates
+               matches = [];
+               for ( category in this.categorized ) {
+                       list = filters[ category ];
+                       if ( list ) {
+                               if ( !Array.isArray( list ) ) {
+                                       list = [ list ];
+                               }
+                               for ( i = 0, len = list.length; i < len; i++ ) {
+                                       actions = this.categorized[ category ][ list[ i ] ];
+                                       if ( Array.isArray( actions ) ) {
+                                               matches.push.apply( matches, actions );
+                                       }
+                               }
+                       }
+               }
+               // Remove by boolean filters
+               for ( i = 0, len = matches.length; i < len; i++ ) {
+                       match = matches[ i ];
+                       if (
+                               ( filters.visible !== undefined && match.isVisible() !== filters.visible ) ||
+                               ( filters.disabled !== undefined && match.isDisabled() !== filters.disabled )
+                       ) {
+                               matches.splice( i, 1 );
+                               len--;
+                               i--;
+                       }
+               }
+               // Remove duplicates
+               for ( i = 0, len = matches.length; i < len; i++ ) {
+                       match = matches[ i ];
+                       index = matches.lastIndexOf( match );
+                       while ( index !== i ) {
+                               matches.splice( index, 1 );
+                               len--;
+                               index = matches.lastIndexOf( match );
+                       }
+               }
+               return matches;
+       }
+       return this.list.slice();
+};
+
+/**
+ * Get 'special' actions.
+ *
+ * Special actions are the first visible action widgets with special flags, such as 'safe' and 'primary'.
+ * Special flags can be configured in subclasses by changing the static #specialFlags property.
+ *
+ * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets.
+ */
+OO.ui.ActionSet.prototype.getSpecial = function () {
+       this.organize();
+       return $.extend( {}, this.special );
+};
+
+/**
+ * Get 'other' actions.
+ *
+ * Other actions include all non-special visible action widgets.
+ *
+ * @return {OO.ui.ActionWidget[]} 'Other' action widgets
+ */
+OO.ui.ActionSet.prototype.getOthers = function () {
+       this.organize();
+       return this.others.slice();
+};
+
+/**
+ * Set the mode  (e.g., ‘edit’ or ‘view’). Only {@link OO.ui.ActionWidget#modes actions} configured
+ * to be available in the specified mode will be made visible. All other actions will be hidden.
+ *
+ * @param {string} mode The mode. Only actions configured to be available in the specified
+ *  mode will be made visible.
+ * @chainable
+ * @fires toggle
+ * @fires change
+ */
+OO.ui.ActionSet.prototype.setMode = function ( mode ) {
+       var i, len, action;
+
+       this.changing = true;
+       for ( i = 0, len = this.list.length; i < len; i++ ) {
+               action = this.list[ i ];
+               action.toggle( action.hasMode( mode ) );
+       }
+
+       this.organized = false;
+       this.changing = false;
+       this.emit( 'change' );
+
+       return this;
+};
+
+/**
+ * Set the abilities of the specified actions.
+ *
+ * Action widgets that are configured with the specified actions will be enabled
+ * or disabled based on the boolean values specified in the `actions`
+ * parameter.
+ *
+ * @param {Object.<string,boolean>} actions A list keyed by action name with boolean
+ *  values that indicate whether or not the action should be enabled.
+ * @chainable
+ */
+OO.ui.ActionSet.prototype.setAbilities = function ( actions ) {
+       var i, len, action, item;
+
+       for ( i = 0, len = this.list.length; i < len; i++ ) {
+               item = this.list[ i ];
+               action = item.getAction();
+               if ( actions[ action ] !== undefined ) {
+                       item.setDisabled( !actions[ action ] );
+               }
+       }
+
+       return this;
+};
+
+/**
+ * Executes a function once per action.
+ *
+ * When making changes to multiple actions, use this method instead of iterating over the actions
+ * manually to defer emitting a #change event until after all actions have been changed.
+ *
+ * @param {Object|null} actions Filters to use to determine which actions to iterate over; see #get
+ * @param {Function} callback Callback to run for each action; callback is invoked with three
+ *   arguments: the action, the action's index, the list of actions being iterated over
+ * @chainable
+ */
+OO.ui.ActionSet.prototype.forEach = function ( filter, callback ) {
+       this.changed = false;
+       this.changing = true;
+       this.get( filter ).forEach( callback );
+       this.changing = false;
+       if ( this.changed ) {
+               this.emit( 'change' );
+       }
+
+       return this;
+};
+
+/**
+ * Add action widgets to the action set.
+ *
+ * @param {OO.ui.ActionWidget[]} actions Action widgets to add
+ * @chainable
+ * @fires add
+ * @fires change
+ */
+OO.ui.ActionSet.prototype.add = function ( actions ) {
+       var i, len, action;
+
+       this.changing = true;
+       for ( i = 0, len = actions.length; i < len; i++ ) {
+               action = actions[ i ];
+               action.connect( this, {
+                       click: [ 'emit', 'click', action ],
+                       resize: [ 'emit', 'resize', action ],
+                       toggle: [ 'onActionChange' ]
+               } );
+               this.list.push( action );
+       }
+       this.organized = false;
+       this.emit( 'add', actions );
+       this.changing = false;
+       this.emit( 'change' );
+
+       return this;
+};
+
+/**
+ * Remove action widgets from the set.
+ *
+ * To remove all actions, you may wish to use the #clear method instead.
+ *
+ * @param {OO.ui.ActionWidget[]} actions Action widgets to remove
+ * @chainable
+ * @fires remove
+ * @fires change
+ */
+OO.ui.ActionSet.prototype.remove = function ( actions ) {
+       var i, len, index, action;
+
+       this.changing = true;
+       for ( i = 0, len = actions.length; i < len; i++ ) {
+               action = actions[ i ];
+               index = this.list.indexOf( action );
+               if ( index !== -1 ) {
+                       action.disconnect( this );
+                       this.list.splice( index, 1 );
+               }
+       }
+       this.organized = false;
+       this.emit( 'remove', actions );
+       this.changing = false;
+       this.emit( 'change' );
+
+       return this;
+};
+
+/**
+ * Remove all action widets from the set.
+ *
+ * To remove only specified actions, use the {@link #method-remove remove} method instead.
+ *
+ * @chainable
+ * @fires remove
+ * @fires change
+ */
+OO.ui.ActionSet.prototype.clear = function () {
+       var i, len, action,
+               removed = this.list.slice();
+
+       this.changing = true;
+       for ( i = 0, len = this.list.length; i < len; i++ ) {
+               action = this.list[ i ];
+               action.disconnect( this );
+       }
+
+       this.list = [];
+
+       this.organized = false;
+       this.emit( 'remove', removed );
+       this.changing = false;
+       this.emit( 'change' );
+
+       return this;
+};
+
+/**
+ * Organize actions.
+ *
+ * This is called whenever organized information is requested. It will only reorganize the actions
+ * if something has changed since the last time it ran.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.ActionSet.prototype.organize = function () {
+       var i, iLen, j, jLen, flag, action, category, list, item, special,
+               specialFlags = this.constructor.static.specialFlags;
+
+       if ( !this.organized ) {
+               this.categorized = {};
+               this.special = {};
+               this.others = [];
+               for ( i = 0, iLen = this.list.length; i < iLen; i++ ) {
+                       action = this.list[ i ];
+                       if ( action.isVisible() ) {
+                               // Populate categories
+                               for ( category in this.categories ) {
+                                       if ( !this.categorized[ category ] ) {
+                                               this.categorized[ category ] = {};
+                                       }
+                                       list = action[ this.categories[ category ] ]();
+                                       if ( !Array.isArray( list ) ) {
+                                               list = [ list ];
+                                       }
+                                       for ( j = 0, jLen = list.length; j < jLen; j++ ) {
+                                               item = list[ j ];
+                                               if ( !this.categorized[ category ][ item ] ) {
+                                                       this.categorized[ category ][ item ] = [];
+                                               }
+                                               this.categorized[ category ][ item ].push( action );
+                                       }
+                               }
+                               // Populate special/others
+                               special = false;
+                               for ( j = 0, jLen = specialFlags.length; j < jLen; j++ ) {
+                                       flag = specialFlags[ j ];
+                                       if ( !this.special[ flag ] && action.hasFlag( flag ) ) {
+                                               this.special[ flag ] = action;
+                                               special = true;
+                                               break;
+                                       }
+                               }
+                               if ( !special ) {
+                                       this.others.push( action );
+                               }
+                       }
+               }
+               this.organized = true;
+       }
+
+       return this;
+};
+
+/**
+ * Errors contain a required message (either a string or jQuery selection) that is used to describe what went wrong
+ * in a {@link OO.ui.Process process}. The error's #recoverable and #warning configurations are used to customize the
+ * appearance and functionality of the error interface.
+ *
+ * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss' and 'Try again' (i.e., the error
+ * is 'recoverable' by default). If the error is not recoverable, the 'Try again' button will not be rendered and the widget
+ * that initiated the failed process will be disabled.
+ *
+ * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button, which will try the
+ * process again.
+ *
+ * For an example of error interfaces, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Processes_and_errors
+ *
+ * @class
+ *
+ * @constructor
+ * @param {string|jQuery} message Description of error
+ * @param {Object} [config] Configuration options
+ * @cfg {boolean} [recoverable=true] Error is recoverable.
+ *  By default, errors are recoverable, and users can try the process again.
+ * @cfg {boolean} [warning=false] Error is a warning.
+ *  If the error is a warning, the error interface will include a
+ *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the warning
+ *  is not triggered a second time if the user chooses to continue.
+ */
+OO.ui.Error = function OoUiError( message, config ) {
+       // Allow passing positional parameters inside the config object
+       if ( OO.isPlainObject( message ) && config === undefined ) {
+               config = message;
+               message = config.message;
+       }
+
+       // Configuration initialization
+       config = config || {};
+
+       // Properties
+       this.message = message instanceof jQuery ? message : String( message );
+       this.recoverable = config.recoverable === undefined || !!config.recoverable;
+       this.warning = !!config.warning;
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.Error );
+
+/* Methods */
+
+/**
+ * Check if the error is recoverable.
+ *
+ * If the error is recoverable, users are able to try the process again.
+ *
+ * @return {boolean} Error is recoverable
+ */
+OO.ui.Error.prototype.isRecoverable = function () {
+       return this.recoverable;
+};
+
+/**
+ * Check if the error is a warning.
+ *
+ * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button.
+ *
+ * @return {boolean} Error is warning
+ */
+OO.ui.Error.prototype.isWarning = function () {
+       return this.warning;
+};
+
+/**
+ * Get error message as DOM nodes.
+ *
+ * @return {jQuery} Error message in DOM nodes
+ */
+OO.ui.Error.prototype.getMessage = function () {
+       return this.message instanceof jQuery ?
+               this.message.clone() :
+               $( '<div>' ).text( this.message ).contents();
+};
+
+/**
+ * Get the error message text.
+ *
+ * @return {string} Error message
+ */
+OO.ui.Error.prototype.getMessageText = function () {
+       return this.message instanceof jQuery ? this.message.text() : this.message;
+};
+
+/**
+ * A Process is a list of steps that are called in sequence. The step can be a number, a jQuery promise,
+ * or a function:
+ *
+ * - **number**: the process will wait for the specified number of milliseconds before proceeding.
+ * - **promise**: the process will continue to the next step when the promise is successfully resolved
+ *  or stop if the promise is rejected.
+ * - **function**: the process will execute the function. The process will stop if the function returns
+ *  either a boolean `false` or a promise that is rejected; if the function returns a number, the process
+ *  will wait for that number of milliseconds before proceeding.
+ *
+ * If the process fails, an {@link OO.ui.Error error} is generated. Depending on how the error is
+ * configured, users can dismiss the error and try the process again, or not. If a process is stopped,
+ * its remaining steps will not be performed.
+ *
+ * @class
+ *
+ * @constructor
+ * @param {number|jQuery.Promise|Function} step Number of miliseconds to wait before proceeding, promise
+ *  that must be resolved before proceeding, or a function to execute. See #createStep for more information. see #createStep for more information
+ * @param {Object} [context=null] Execution context of the function. The context is ignored if the step is
+ *  a number or promise.
+ * @return {Object} Step object, with `callback` and `context` properties
+ */
+OO.ui.Process = function ( step, context ) {
+       // Properties
+       this.steps = [];
+
+       // Initialization
+       if ( step !== undefined ) {
+               this.next( step, context );
+       }
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.Process );
+
+/* Methods */
+
+/**
+ * Start the process.
+ *
+ * @return {jQuery.Promise} Promise that is resolved when all steps have successfully completed.
+ *  If any of the steps return a promise that is rejected or a boolean false, this promise is rejected
+ *  and any remaining steps are not performed.
+ */
+OO.ui.Process.prototype.execute = function () {
+       var i, len, promise;
+
+       /**
+        * Continue execution.
+        *
+        * @ignore
+        * @param {Array} step A function and the context it should be called in
+        * @return {Function} Function that continues the process
+        */
+       function proceed( step ) {
+               return function () {
+                       // Execute step in the correct context
+                       var deferred,
+                               result = step.callback.call( step.context );
+
+                       if ( result === false ) {
+                               // Use rejected promise for boolean false results
+                               return $.Deferred().reject( [] ).promise();
+                       }
+                       if ( typeof result === 'number' ) {
+                               if ( result < 0 ) {
+                                       throw new Error( 'Cannot go back in time: flux capacitor is out of service' );
+                               }
+                               // Use a delayed promise for numbers, expecting them to be in milliseconds
+                               deferred = $.Deferred();
+                               setTimeout( deferred.resolve, result );
+                               return deferred.promise();
+                       }
+                       if ( result instanceof OO.ui.Error ) {
+                               // Use rejected promise for error
+                               return $.Deferred().reject( [ result ] ).promise();
+                       }
+                       if ( Array.isArray( result ) && result.length && result[ 0 ] instanceof OO.ui.Error ) {
+                               // Use rejected promise for list of errors
+                               return $.Deferred().reject( result ).promise();
+                       }
+                       // Duck-type the object to see if it can produce a promise
+                       if ( result && $.isFunction( result.promise ) ) {
+                               // Use a promise generated from the result
+                               return result.promise();
+                       }
+                       // Use resolved promise for other results
+                       return $.Deferred().resolve().promise();
+               };
+       }
+
+       if ( this.steps.length ) {
+               // Generate a chain reaction of promises
+               promise = proceed( this.steps[ 0 ] )();
+               for ( i = 1, len = this.steps.length; i < len; i++ ) {
+                       promise = promise.then( proceed( this.steps[ i ] ) );
+               }
+       } else {
+               promise = $.Deferred().resolve().promise();
+       }
+
+       return promise;
+};
+
+/**
+ * Create a process step.
+ *
+ * @private
+ * @param {number|jQuery.Promise|Function} step
+ *
+ * - Number of milliseconds to wait before proceeding
+ * - Promise that must be resolved before proceeding
+ * - Function to execute
+ *   - If the function returns a boolean false the process will stop
+ *   - If the function returns a promise, the process will continue to the next
+ *     step when the promise is resolved or stop if the promise is rejected
+ *   - If the function returns a number, the process will wait for that number of
+ *     milliseconds before proceeding
+ * @param {Object} [context=null] Execution context of the function. The context is
+ *  ignored if the step is a number or promise.
+ * @return {Object} Step object, with `callback` and `context` properties
+ */
+OO.ui.Process.prototype.createStep = function ( step, context ) {
+       if ( typeof step === 'number' || $.isFunction( step.promise ) ) {
+               return {
+                       callback: function () {
+                               return step;
+                       },
+                       context: null
+               };
+       }
+       if ( $.isFunction( step ) ) {
+               return {
+                       callback: step,
+                       context: context
+               };
+       }
+       throw new Error( 'Cannot create process step: number, promise or function expected' );
+};
+
+/**
+ * Add step to the beginning of the process.
+ *
+ * @inheritdoc #createStep
+ * @return {OO.ui.Process} this
+ * @chainable
+ */
+OO.ui.Process.prototype.first = function ( step, context ) {
+       this.steps.unshift( this.createStep( step, context ) );
+       return this;
+};
+
+/**
+ * Add step to the end of the process.
+ *
+ * @inheritdoc #createStep
+ * @return {OO.ui.Process} this
+ * @chainable
+ */
+OO.ui.Process.prototype.next = function ( step, context ) {
+       this.steps.push( this.createStep( step, context ) );
+       return this;
+};
+
+/**
+ * Window managers are used to open and close {@link OO.ui.Window windows} and control their presentation.
+ * Managed windows are mutually exclusive. If a new window is opened while a current window is opening
+ * or is opened, the current window will be closed and any ongoing {@link OO.ui.Process process} will be cancelled. Windows
+ * themselves are persistent and—rather than being torn down when closed—can be repopulated with the
+ * pertinent data and reused.
+ *
+ * Over the lifecycle of a window, the window manager makes available three promises: `opening`,
+ * `opened`, and `closing`, which represent the primary stages of the cycle:
+ *
+ * **Opening**: the opening stage begins when the window manager’s #openWindow or a window’s
+ * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.
+ *
+ * - an `opening` event is emitted with an `opening` promise
+ * - the #getSetupDelay method is called and the returned value is used to time a pause in execution before
+ *   the window’s {@link OO.ui.Window#getSetupProcess getSetupProcess} method is called on the
+ *   window and its result executed
+ * - a `setup` progress notification is emitted from the `opening` promise
+ * - the #getReadyDelay method is called the returned value is used to time a pause in execution before
+ *   the window’s {@link OO.ui.Window#getReadyProcess getReadyProcess} method is called on the
+ *   window and its result executed
+ * - a `ready` progress notification is emitted from the `opening` promise
+ * - the `opening` promise is resolved with an `opened` promise
+ *
+ * **Opened**: the window is now open.
+ *
+ * **Closing**: the closing stage begins when the window manager's #closeWindow or the
+ * window's {@link OO.ui.Window#close close} methods is used, and the window manager begins
+ * to close the window.
+ *
+ * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted
+ * - the #getHoldDelay method is called and the returned value is used to time a pause in execution before
+ *   the window's {@link OO.ui.Window#getHoldProcess getHoldProces} method is called on the
+ *   window and its result executed
+ * - a `hold` progress notification is emitted from the `closing` promise
+ * - the #getTeardownDelay() method is called and the returned value is used to time a pause in execution before
+ *   the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method is called on the
+ *   window and its result executed
+ * - a `teardown` progress notification is emitted from the `closing` promise
+ * - the `closing` promise is resolved. The window is now closed
+ *
+ * See the [OOjs UI documentation on MediaWiki][1] for more information.
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
+ *
+ * @class
+ * @extends OO.ui.Element
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation
+ *  Note that window classes that are instantiated with a factory must have
+ *  a {@link OO.ui.Dialog#static-name static name} property that specifies a symbolic name.
+ * @cfg {boolean} [modal=true] Prevent interaction outside the dialog
+ */
+OO.ui.WindowManager = function OoUiWindowManager( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.WindowManager.parent.call( this, config );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+
+       // Properties
+       this.factory = config.factory;
+       this.modal = config.modal === undefined || !!config.modal;
+       this.windows = {};
+       this.opening = null;
+       this.opened = null;
+       this.closing = null;
+       this.preparingToOpen = null;
+       this.preparingToClose = null;
+       this.currentWindow = null;
+       this.globalEvents = false;
+       this.$ariaHidden = null;
+       this.onWindowResizeTimeout = null;
+       this.onWindowResizeHandler = this.onWindowResize.bind( this );
+       this.afterWindowResizeHandler = this.afterWindowResize.bind( this );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-windowManager' )
+               .toggleClass( 'oo-ui-windowManager-modal', this.modal );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.WindowManager, OO.ui.Element );
+OO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );
+
+/* Events */
+
+/**
+ * An 'opening' event is emitted when the window begins to be opened.
+ *
+ * @event opening
+ * @param {OO.ui.Window} win Window that's being opened
+ * @param {jQuery.Promise} opening An `opening` promise resolved with a value when the window is opened successfully.
+ *  When the `opening` promise is resolved, the first argument of the value is an 'opened' promise, the second argument
+ *  is the opening data. The `opening` promise emits `setup` and `ready` notifications when those processes are complete.
+ * @param {Object} data Window opening data
+ */
+
+/**
+ * A 'closing' event is emitted when the window begins to be closed.
+ *
+ * @event closing
+ * @param {OO.ui.Window} win Window that's being closed
+ * @param {jQuery.Promise} closing A `closing` promise is resolved with a value when the window
+ *  is closed successfully. The promise emits `hold` and `teardown` notifications when those
+ *  processes are complete. When the `closing` promise is resolved, the first argument of its value
+ *  is the closing data.
+ * @param {Object} data Window closing data
+ */
+
+/**
+ * A 'resize' event is emitted when a window is resized.
+ *
+ * @event resize
+ * @param {OO.ui.Window} win Window that was resized
+ */
+
+/* Static Properties */
+
+/**
+ * Map of the symbolic name of each window size and its CSS properties.
+ *
+ * @static
+ * @inheritable
+ * @property {Object}
+ */
+OO.ui.WindowManager.static.sizes = {
+       small: {
+               width: 300
+       },
+       medium: {
+               width: 500
+       },
+       large: {
+               width: 700
+       },
+       larger: {
+               width: 900
+       },
+       full: {
+               // These can be non-numeric because they are never used in calculations
+               width: '100%',
+               height: '100%'
+       }
+};
+
+/**
+ * Symbolic name of the default window size.
+ *
+ * The default size is used if the window's requested size is not recognized.
+ *
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.WindowManager.static.defaultSize = 'medium';
+
+/* Methods */
+
+/**
+ * Handle window resize events.
+ *
+ * @private
+ * @param {jQuery.Event} e Window resize event
+ */
+OO.ui.WindowManager.prototype.onWindowResize = function () {
+       clearTimeout( this.onWindowResizeTimeout );
+       this.onWindowResizeTimeout = setTimeout( this.afterWindowResizeHandler, 200 );
+};
+
+/**
+ * Handle window resize events.
+ *
+ * @private
+ * @param {jQuery.Event} e Window resize event
+ */
+OO.ui.WindowManager.prototype.afterWindowResize = function () {
+       if ( this.currentWindow ) {
+               this.updateWindowSize( this.currentWindow );
+       }
+};
+
+/**
+ * Check if window is opening.
+ *
+ * @return {boolean} Window is opening
+ */
+OO.ui.WindowManager.prototype.isOpening = function ( win ) {
+       return win === this.currentWindow && !!this.opening && this.opening.state() === 'pending';
+};
+
+/**
+ * Check if window is closing.
+ *
+ * @return {boolean} Window is closing
+ */
+OO.ui.WindowManager.prototype.isClosing = function ( win ) {
+       return win === this.currentWindow && !!this.closing && this.closing.state() === 'pending';
+};
+
+/**
+ * Check if window is opened.
+ *
+ * @return {boolean} Window is opened
+ */
+OO.ui.WindowManager.prototype.isOpened = function ( win ) {
+       return win === this.currentWindow && !!this.opened && this.opened.state() === 'pending';
+};
+
+/**
+ * Check if a window is being managed.
+ *
+ * @param {OO.ui.Window} win Window to check
+ * @return {boolean} Window is being managed
+ */
+OO.ui.WindowManager.prototype.hasWindow = function ( win ) {
+       var name;
+
+       for ( name in this.windows ) {
+               if ( this.windows[ name ] === win ) {
+                       return true;
+               }
+       }
+
+       return false;
+};
+
+/**
+ * Get the number of milliseconds to wait after opening begins before executing the ‘setup’ process.
+ *
+ * @param {OO.ui.Window} win Window being opened
+ * @param {Object} [data] Window opening data
+ * @return {number} Milliseconds to wait
+ */
+OO.ui.WindowManager.prototype.getSetupDelay = function () {
+       return 0;
+};
+
+/**
+ * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’ process.
+ *
+ * @param {OO.ui.Window} win Window being opened
+ * @param {Object} [data] Window opening data
+ * @return {number} Milliseconds to wait
+ */
+OO.ui.WindowManager.prototype.getReadyDelay = function () {
+       return 0;
+};
+
+/**
+ * Get the number of milliseconds to wait after closing has begun before executing the 'hold' process.
+ *
+ * @param {OO.ui.Window} win Window being closed
+ * @param {Object} [data] Window closing data
+ * @return {number} Milliseconds to wait
+ */
+OO.ui.WindowManager.prototype.getHoldDelay = function () {
+       return 0;
+};
+
+/**
+ * Get the number of milliseconds to wait after the ‘hold’ process has finished before
+ * executing the ‘teardown’ process.
+ *
+ * @param {OO.ui.Window} win Window being closed
+ * @param {Object} [data] Window closing data
+ * @return {number} Milliseconds to wait
+ */
+OO.ui.WindowManager.prototype.getTeardownDelay = function () {
+       return this.modal ? 250 : 0;
+};
+
+/**
+ * Get a window by its symbolic name.
+ *
+ * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will be
+ * instantiated and added to the window manager automatically. Please see the [OOjs UI documentation on MediaWiki][3]
+ * for more information about using factories.
+ * [3]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
+ *
+ * @param {string} name Symbolic name of the window
+ * @return {jQuery.Promise} Promise resolved with matching window, or rejected with an OO.ui.Error
+ * @throws {Error} An error is thrown if the symbolic name is not recognized by the factory.
+ * @throws {Error} An error is thrown if the named window is not recognized as a managed window.
+ */
+OO.ui.WindowManager.prototype.getWindow = function ( name ) {
+       var deferred = $.Deferred(),
+               win = this.windows[ name ];
+
+       if ( !( win instanceof OO.ui.Window ) ) {
+               if ( this.factory ) {
+                       if ( !this.factory.lookup( name ) ) {
+                               deferred.reject( new OO.ui.Error(
+                                       'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'
+                               ) );
+                       } else {
+                               win = this.factory.create( name );
+                               this.addWindows( [ win ] );
+                               deferred.resolve( win );
+                       }
+               } else {
+                       deferred.reject( new OO.ui.Error(
+                               'Cannot get unmanaged window: symbolic name unrecognized as a managed window'
+                       ) );
+               }
+       } else {
+               deferred.resolve( win );
+       }
+
+       return deferred.promise();
+};
+
+/**
+ * Get current window.
+ *
+ * @return {OO.ui.Window|null} Currently opening/opened/closing window
+ */
+OO.ui.WindowManager.prototype.getCurrentWindow = function () {
+       return this.currentWindow;
+};
+
+/**
+ * Open a window.
+ *
+ * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
+ * @param {Object} [data] Window opening data
+ * @return {jQuery.Promise} An `opening` promise resolved when the window is done opening.
+ *  See {@link #event-opening 'opening' event}  for more information about `opening` promises.
+ * @fires opening
+ */
+OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
+       var manager = this,
+               opening = $.Deferred();
+
+       // Argument handling
+       if ( typeof win === 'string' ) {
+               return this.getWindow( win ).then( function ( win ) {
+                       return manager.openWindow( win, data );
+               } );
+       }
+
+       // Error handling
+       if ( !this.hasWindow( win ) ) {
+               opening.reject( new OO.ui.Error(
+                       'Cannot open window: window is not attached to manager'
+               ) );
+       } else if ( this.preparingToOpen || this.opening || this.opened ) {
+               opening.reject( new OO.ui.Error(
+                       'Cannot open window: another window is opening or open'
+               ) );
+       }
+
+       // Window opening
+       if ( opening.state() !== 'rejected' ) {
+               // If a window is currently closing, wait for it to complete
+               this.preparingToOpen = $.when( this.closing );
+               // Ensure handlers get called after preparingToOpen is set
+               this.preparingToOpen.done( function () {
+                       if ( manager.modal ) {
+                               manager.toggleGlobalEvents( true );
+                               manager.toggleAriaIsolation( true );
+                       }
+                       manager.currentWindow = win;
+                       manager.opening = opening;
+                       manager.preparingToOpen = null;
+                       manager.emit( 'opening', win, opening, data );
+                       setTimeout( function () {
+                               win.setup( data ).then( function () {
+                                       manager.updateWindowSize( win );
+                                       manager.opening.notify( { state: 'setup' } );
+                                       setTimeout( function () {
+                                               win.ready( data ).then( function () {
+                                                       manager.opening.notify( { state: 'ready' } );
+                                                       manager.opening = null;
+                                                       manager.opened = $.Deferred();
+                                                       opening.resolve( manager.opened.promise(), data );
+                                               }, function () {
+                                                       manager.opening = null;
+                                                       manager.opened = $.Deferred();
+                                                       opening.reject();
+                                                       manager.closeWindow( win );
+                                               } );
+                                       }, manager.getReadyDelay() );
+                               }, function () {
+                                       manager.opening = null;
+                                       manager.opened = $.Deferred();
+                                       opening.reject();
+                                       manager.closeWindow( win );
+                               } );
+                       }, manager.getSetupDelay() );
+               } );
+       }
+
+       return opening.promise();
+};
+
+/**
+ * Close a window.
+ *
+ * @param {OO.ui.Window|string} win Window object or symbolic name of window to close
+ * @param {Object} [data] Window closing data
+ * @return {jQuery.Promise} A `closing` promise resolved when the window is done closing.
+ *  See {@link #event-closing 'closing' event} for more information about closing promises.
+ * @throws {Error} An error is thrown if the window is not managed by the window manager.
+ * @fires closing
+ */
+OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
+       var manager = this,
+               closing = $.Deferred(),
+               opened;
+
+       // Argument handling
+       if ( typeof win === 'string' ) {
+               win = this.windows[ win ];
+       } else if ( !this.hasWindow( win ) ) {
+               win = null;
+       }
+
+       // Error handling
+       if ( !win ) {
+               closing.reject( new OO.ui.Error(
+                       'Cannot close window: window is not attached to manager'
+               ) );
+       } else if ( win !== this.currentWindow ) {
+               closing.reject( new OO.ui.Error(
+                       'Cannot close window: window already closed with different data'
+               ) );
+       } else if ( this.preparingToClose || this.closing ) {
+               closing.reject( new OO.ui.Error(
+                       'Cannot close window: window already closing with different data'
+               ) );
+       }
+
+       // Window closing
+       if ( closing.state() !== 'rejected' ) {
+               // If the window is currently opening, close it when it's done
+               this.preparingToClose = $.when( this.opening );
+               // Ensure handlers get called after preparingToClose is set
+               this.preparingToClose.always( function () {
+                       manager.closing = closing;
+                       manager.preparingToClose = null;
+                       manager.emit( 'closing', win, closing, data );
+                       opened = manager.opened;
+                       manager.opened = null;
+                       opened.resolve( closing.promise(), data );
+                       setTimeout( function () {
+                               win.hold( data ).then( function () {
+                                       closing.notify( { state: 'hold' } );
+                                       setTimeout( function () {
+                                               win.teardown( data ).then( function () {
+                                                       closing.notify( { state: 'teardown' } );
+                                                       if ( manager.modal ) {
+                                                               manager.toggleGlobalEvents( false );
+                                                               manager.toggleAriaIsolation( false );
+                                                       }
+                                                       manager.closing = null;
+                                                       manager.currentWindow = null;
+                                                       closing.resolve( data );
+                                               } );
+                                       }, manager.getTeardownDelay() );
+                               } );
+                       }, manager.getHoldDelay() );
+               } );
+       }
+
+       return closing.promise();
+};
+
+/**
+ * Add windows to the window manager.
+ *
+ * Windows can be added by reference, symbolic name, or explicitly defined symbolic names.
+ * See the [OOjs ui documentation on MediaWiki] [2] for examples.
+ * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
+ *
+ * @param {Object.<string,OO.ui.Window>|OO.ui.Window[]} windows An array of window objects specified
+ *  by reference, symbolic name, or explicitly defined symbolic names.
+ * @throws {Error} An error is thrown if a window is added by symbolic name, but has neither an
+ *  explicit nor a statically configured symbolic name.
+ */
+OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
+       var i, len, win, name, list;
+
+       if ( Array.isArray( windows ) ) {
+               // Convert to map of windows by looking up symbolic names from static configuration
+               list = {};
+               for ( i = 0, len = windows.length; i < len; i++ ) {
+                       name = windows[ i ].constructor.static.name;
+                       if ( typeof name !== 'string' ) {
+                               throw new Error( 'Cannot add window' );
+                       }
+                       list[ name ] = windows[ i ];
+               }
+       } else if ( OO.isPlainObject( windows ) ) {
+               list = windows;
+       }
+
+       // Add windows
+       for ( name in list ) {
+               win = list[ name ];
+               this.windows[ name ] = win.toggle( false );
+               this.$element.append( win.$element );
+               win.setManager( this );
+       }
+};
+
+/**
+ * Remove the specified windows from the windows manager.
+ *
+ * Windows will be closed before they are removed. If you wish to remove all windows, you may wish to use
+ * the #clearWindows method instead. If you no longer need the window manager and want to ensure that it no
+ * longer listens to events, use the #destroy method.
+ *
+ * @param {string[]} names Symbolic names of windows to remove
+ * @return {jQuery.Promise} Promise resolved when window is closed and removed
+ * @throws {Error} An error is thrown if the named windows are not managed by the window manager.
+ */
+OO.ui.WindowManager.prototype.removeWindows = function ( names ) {
+       var i, len, win, name, cleanupWindow,
+               manager = this,
+               promises = [],
+               cleanup = function ( name, win ) {
+                       delete manager.windows[ name ];
+                       win.$element.detach();
+               };
+
+       for ( i = 0, len = names.length; i < len; i++ ) {
+               name = names[ i ];
+               win = this.windows[ name ];
+               if ( !win ) {
+                       throw new Error( 'Cannot remove window' );
+               }
+               cleanupWindow = cleanup.bind( null, name, win );
+               promises.push( this.closeWindow( name ).then( cleanupWindow, cleanupWindow ) );
+       }
+
+       return $.when.apply( $, promises );
+};
+
+/**
+ * Remove all windows from the window manager.
+ *
+ * Windows will be closed before they are removed. Note that the window manager, though not in use, will still
+ * listen to events. If the window manager will not be used again, you may wish to use the #destroy method instead.
+ * To remove just a subset of windows, use the #removeWindows method.
+ *
+ * @return {jQuery.Promise} Promise resolved when all windows are closed and removed
+ */
+OO.ui.WindowManager.prototype.clearWindows = function () {
+       return this.removeWindows( Object.keys( this.windows ) );
+};
+
+/**
+ * Set dialog size. In general, this method should not be called directly.
+ *
+ * Fullscreen mode will be used if the dialog is too wide to fit in the screen.
+ *
+ * @chainable
+ */
+OO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {
+       var isFullscreen;
+
+       // Bypass for non-current, and thus invisible, windows
+       if ( win !== this.currentWindow ) {
+               return;
+       }
+
+       isFullscreen = win.getSize() === 'full';
+
+       this.$element.toggleClass( 'oo-ui-windowManager-fullscreen', isFullscreen );
+       this.$element.toggleClass( 'oo-ui-windowManager-floating', !isFullscreen );
+       win.setDimensions( win.getSizeProperties() );
+
+       this.emit( 'resize', win );
+
+       return this;
+};
+
+/**
+ * Bind or unbind global events for scrolling.
+ *
+ * @private
+ * @param {boolean} [on] Bind global events
+ * @chainable
+ */
+OO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {
+       var scrollWidth, bodyMargin,
+               $body = $( this.getElementDocument().body ),
+               // We could have multiple window managers open so only modify
+               // the body css at the bottom of the stack
+               stackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0 ;
+
+       on = on === undefined ? !!this.globalEvents : !!on;
+
+       if ( on ) {
+               if ( !this.globalEvents ) {
+                       $( this.getElementWindow() ).on( {
+                               // Start listening for top-level window dimension changes
+                               'orientationchange resize': this.onWindowResizeHandler
+                       } );
+                       if ( stackDepth === 0 ) {
+                               scrollWidth = window.innerWidth - document.documentElement.clientWidth;
+                               bodyMargin = parseFloat( $body.css( 'margin-right' ) ) || 0;
+                               $body.css( {
+                                       overflow: 'hidden',
+                                       'margin-right': bodyMargin + scrollWidth
+                               } );
+                       }
+                       stackDepth++;
+                       this.globalEvents = true;
+               }
+       } else if ( this.globalEvents ) {
+               $( this.getElementWindow() ).off( {
+                       // Stop listening for top-level window dimension changes
+                       'orientationchange resize': this.onWindowResizeHandler
+               } );
+               stackDepth--;
+               if ( stackDepth === 0 ) {
+                       $body.css( {
+                               overflow: '',
+                               'margin-right': ''
+                       } );
+               }
+               this.globalEvents = false;
+       }
+       $body.data( 'windowManagerGlobalEvents', stackDepth );
+
+       return this;
+};
+
+/**
+ * Toggle screen reader visibility of content other than the window manager.
+ *
+ * @private
+ * @param {boolean} [isolate] Make only the window manager visible to screen readers
+ * @chainable
+ */
+OO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {
+       isolate = isolate === undefined ? !this.$ariaHidden : !!isolate;
+
+       if ( isolate ) {
+               if ( !this.$ariaHidden ) {
+                       // Hide everything other than the window manager from screen readers
+                       this.$ariaHidden = $( 'body' )
+                               .children()
+                               .not( this.$element.parentsUntil( 'body' ).last() )
+                               .attr( 'aria-hidden', '' );
+               }
+       } else if ( this.$ariaHidden ) {
+               // Restore screen reader visibility
+               this.$ariaHidden.removeAttr( 'aria-hidden' );
+               this.$ariaHidden = null;
+       }
+
+       return this;
+};
+
+/**
+ * Destroy the window manager.
+ *
+ * Destroying the window manager ensures that it will no longer listen to events. If you would like to
+ * continue using the window manager, but wish to remove all windows from it, use the #clearWindows method
+ * instead.
+ */
+OO.ui.WindowManager.prototype.destroy = function () {
+       this.toggleGlobalEvents( false );
+       this.toggleAriaIsolation( false );
+       this.clearWindows();
+       this.$element.remove();
+};
+
+/**
+ * A window is a container for elements that are in a child frame. They are used with
+ * a window manager (OO.ui.WindowManager), which is used to open and close the window and control
+ * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’, ‘medium’,
+ * ‘large’), which is interpreted by the window manager. If the requested size is not recognized,
+ * the window manager will choose a sensible fallback.
+ *
+ * The lifecycle of a window has three primary stages (opening, opened, and closing) in which
+ * different processes are executed:
+ *
+ * **opening**: The opening stage begins when the window manager's {@link OO.ui.WindowManager#openWindow
+ * openWindow} or the window's {@link #open open} methods are used, and the window manager begins to open
+ * the window.
+ *
+ * - {@link #getSetupProcess} method is called and its result executed
+ * - {@link #getReadyProcess} method is called and its result executed
+ *
+ * **opened**: The window is now open
+ *
+ * **closing**: The closing stage begins when the window manager's
+ * {@link OO.ui.WindowManager#closeWindow closeWindow}
+ * or the window's {@link #close} methods are used, and the window manager begins to close the window.
+ *
+ * - {@link #getHoldProcess} method is called and its result executed
+ * - {@link #getTeardownProcess} method is called and its result executed. The window is now closed
+ *
+ * Each of the window's processes (setup, ready, hold, and teardown) can be extended in subclasses
+ * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and #getTeardownProcess
+ * methods. Note that each {@link OO.ui.Process process} is executed in series, so asynchronous
+ * processing can complete. Always assume window processes are executed asynchronously.
+ *
+ * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Element
+ * @mixins OO.EventEmitter
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [size] Symbolic name of the dialog size: `small`, `medium`, `large`, `larger` or
+ *  `full`.  If omitted, the value of the {@link #static-size static size} property will be used.
+ */
+OO.ui.Window = function OoUiWindow( config ) {
+       // Configuration initialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Window.parent.call( this, config );
+
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+
+       // Properties
+       this.manager = null;
+       this.size = config.size || this.constructor.static.size;
+       this.$frame = $( '<div>' );
+       this.$overlay = $( '<div>' );
+       this.$content = $( '<div>' );
+
+       this.$focusTrapBefore = $( '<div>' ).prop( 'tabIndex', 0 );
+       this.$focusTrapAfter = $( '<div>' ).prop( 'tabIndex', 0 );
+       this.$focusTraps = this.$focusTrapBefore.add( this.$focusTrapAfter );
+
+       // Initialization
+       this.$overlay.addClass( 'oo-ui-window-overlay' );
+       this.$content
+               .addClass( 'oo-ui-window-content' )
+               .attr( 'tabindex', 0 );
+       this.$frame
+               .addClass( 'oo-ui-window-frame' )
+               .append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter );
+
+       this.$element
+               .addClass( 'oo-ui-window' )
+               .append( this.$frame, this.$overlay );
+
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Window, OO.ui.Element );
+OO.mixinClass( OO.ui.Window, OO.EventEmitter );
+
+/* Static Properties */
+
+/**
+ * Symbolic name of the window size: `small`, `medium`, `large`, `larger` or `full`.
+ *
+ * The static size is used if no #size is configured during construction.
+ *
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.Window.static.size = 'medium';
+
+/* Methods */
+
+/**
+ * Handle mouse down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Mouse down event
+ */
+OO.ui.Window.prototype.onMouseDown = function ( e ) {
+       // Prevent clicking on the click-block from stealing focus
+       if ( e.target === this.$element[ 0 ] ) {
+               return false;
+       }
+};
+
+/**
+ * Check if the window has been initialized.
+ *
+ * Initialization occurs when a window is added to a manager.
+ *
+ * @return {boolean} Window has been initialized
+ */
+OO.ui.Window.prototype.isInitialized = function () {
+       return !!this.manager;
+};
+
+/**
+ * Check if the window is visible.
+ *
+ * @return {boolean} Window is visible
+ */
+OO.ui.Window.prototype.isVisible = function () {
+       return this.visible;
+};
+
+/**
+ * Check if the window is opening.
+ *
+ * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpening isOpening}
+ * method.
+ *
+ * @return {boolean} Window is opening
+ */
+OO.ui.Window.prototype.isOpening = function () {
+       return this.manager.isOpening( this );
+};
+
+/**
+ * Check if the window is closing.
+ *
+ * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isClosing isClosing} method.
+ *
+ * @return {boolean} Window is closing
+ */
+OO.ui.Window.prototype.isClosing = function () {
+       return this.manager.isClosing( this );
+};
+
+/**
+ * Check if the window is opened.
+ *
+ * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpened isOpened} method.
+ *
+ * @return {boolean} Window is opened
+ */
+OO.ui.Window.prototype.isOpened = function () {
+       return this.manager.isOpened( this );
+};
+
+/**
+ * Get the window manager.
+ *
+ * All windows must be attached to a window manager, which is used to open
+ * and close the window and control its presentation.
+ *
+ * @return {OO.ui.WindowManager} Manager of window
+ */
+OO.ui.Window.prototype.getManager = function () {
+       return this.manager;
+};
+
+/**
+ * Get the symbolic name of the window size (e.g., `small` or `medium`).
+ *
+ * @return {string} Symbolic name of the size: `small`, `medium`, `large`, `larger`, `full`
+ */
+OO.ui.Window.prototype.getSize = function () {
+       var viewport = OO.ui.Element.static.getDimensions( this.getElementWindow() ),
+               sizes = this.manager.constructor.static.sizes,
+               size = this.size;
+
+       if ( !sizes[ size ] ) {
+               size = this.manager.constructor.static.defaultSize;
+       }
+       if ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) {
+               size = 'full';
+       }
+
+       return size;
+};
+
+/**
+ * Get the size properties associated with the current window size
+ *
+ * @return {Object} Size properties
+ */
+OO.ui.Window.prototype.getSizeProperties = function () {
+       return this.manager.constructor.static.sizes[ this.getSize() ];
+};
+
+/**
+ * Disable transitions on window's frame for the duration of the callback function, then enable them
+ * back.
+ *
+ * @private
+ * @param {Function} callback Function to call while transitions are disabled
+ */
+OO.ui.Window.prototype.withoutSizeTransitions = function ( callback ) {
+       // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
+       // Disable transitions first, otherwise we'll get values from when the window was animating.
+       var oldTransition,
+               styleObj = this.$frame[ 0 ].style;
+       oldTransition = styleObj.transition || styleObj.OTransition || styleObj.MsTransition ||
+               styleObj.MozTransition || styleObj.WebkitTransition;
+       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
+               styleObj.MozTransition = styleObj.WebkitTransition = 'none';
+       callback();
+       // Force reflow to make sure the style changes done inside callback really are not transitioned
+       this.$frame.height();
+       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
+               styleObj.MozTransition = styleObj.WebkitTransition = oldTransition;
+};
+
+/**
+ * Get the height of the full window contents (i.e., the window head, body and foot together).
+ *
+ * What consistitutes the head, body, and foot varies depending on the window type.
+ * A {@link OO.ui.MessageDialog message dialog} displays a title and message in its body,
+ * and any actions in the foot. A {@link OO.ui.ProcessDialog process dialog} displays a title
+ * and special actions in the head, and dialog content in the body.
+ *
+ * To get just the height of the dialog body, use the #getBodyHeight method.
+ *
+ * @return {number} The height of the window contents (the dialog head, body and foot) in pixels
+ */
+OO.ui.Window.prototype.getContentHeight = function () {
+       var bodyHeight,
+               win = this,
+               bodyStyleObj = this.$body[ 0 ].style,
+               frameStyleObj = this.$frame[ 0 ].style;
+
+       // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
+       // Disable transitions first, otherwise we'll get values from when the window was animating.
+       this.withoutSizeTransitions( function () {
+               var oldHeight = frameStyleObj.height,
+                       oldPosition = bodyStyleObj.position;
+               frameStyleObj.height = '1px';
+               // Force body to resize to new width
+               bodyStyleObj.position = 'relative';
+               bodyHeight = win.getBodyHeight();
+               frameStyleObj.height = oldHeight;
+               bodyStyleObj.position = oldPosition;
+       } );
+
+       return (
+               // Add buffer for border
+               ( this.$frame.outerHeight() - this.$frame.innerHeight() ) +
+               // Use combined heights of children
+               ( this.$head.outerHeight( true ) + bodyHeight + this.$foot.outerHeight( true ) )
+       );
+};
+
+/**
+ * Get the height of the window body.
+ *
+ * To get the height of the full window contents (the window body, head, and foot together),
+ * use #getContentHeight.
+ *
+ * When this function is called, the window will temporarily have been resized
+ * to height=1px, so .scrollHeight measurements can be taken accurately.
+ *
+ * @return {number} Height of the window body in pixels
+ */
+OO.ui.Window.prototype.getBodyHeight = function () {
+       return this.$body[ 0 ].scrollHeight;
+};
+
+/**
+ * Get the directionality of the frame (right-to-left or left-to-right).
+ *
+ * @return {string} Directionality: `'ltr'` or `'rtl'`
+ */
+OO.ui.Window.prototype.getDir = function () {
+       return OO.ui.Element.static.getDir( this.$content ) || 'ltr';
+};
+
+/**
+ * Get the 'setup' process.
+ *
+ * The setup process is used to set up a window for use in a particular context,
+ * based on the `data` argument. This method is called during the opening phase of the window’s
+ * lifecycle.
+ *
+ * Override this method to add additional steps to the ‘setup’ process the parent method provides
+ * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
+ * of OO.ui.Process.
+ *
+ * To add window content that persists between openings, you may wish to use the #initialize method
+ * instead.
+ *
+ * @param {Object} [data] Window opening data
+ * @return {OO.ui.Process} Setup process
+ */
+OO.ui.Window.prototype.getSetupProcess = function () {
+       return new OO.ui.Process();
+};
+
+/**
+ * Get the ‘ready’ process.
+ *
+ * The ready process is used to ready a window for use in a particular
+ * context, based on the `data` argument. This method is called during the opening phase of
+ * the window’s lifecycle, after the window has been {@link #getSetupProcess setup}.
+ *
+ * Override this method to add additional steps to the ‘ready’ process the parent method
+ * provides using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next}
+ * methods of OO.ui.Process.
+ *
+ * @param {Object} [data] Window opening data
+ * @return {OO.ui.Process} Ready process
+ */
+OO.ui.Window.prototype.getReadyProcess = function () {
+       return new OO.ui.Process();
+};
+
+/**
+ * Get the 'hold' process.
+ *
+ * The hold proccess is used to keep a window from being used in a particular context,
+ * based on the `data` argument. This method is called during the closing phase of the window’s
+ * lifecycle.
+ *
+ * Override this method to add additional steps to the 'hold' process the parent method provides
+ * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
+ * of OO.ui.Process.
+ *
+ * @param {Object} [data] Window closing data
+ * @return {OO.ui.Process} Hold process
+ */
+OO.ui.Window.prototype.getHoldProcess = function () {
+       return new OO.ui.Process();
+};
+
+/**
+ * Get the ‘teardown’ process.
+ *
+ * The teardown process is used to teardown a window after use. During teardown,
+ * user interactions within the window are conveyed and the window is closed, based on the `data`
+ * argument. This method is called during the closing phase of the window’s lifecycle.
+ *
+ * Override this method to add additional steps to the ‘teardown’ process the parent method provides
+ * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
+ * of OO.ui.Process.
+ *
+ * @param {Object} [data] Window closing data
+ * @return {OO.ui.Process} Teardown process
+ */
+OO.ui.Window.prototype.getTeardownProcess = function () {
+       return new OO.ui.Process();
+};
+
+/**
+ * Set the window manager.
+ *
+ * This will cause the window to initialize. Calling it more than once will cause an error.
+ *
+ * @param {OO.ui.WindowManager} manager Manager for this window
+ * @throws {Error} An error is thrown if the method is called more than once
+ * @chainable
+ */
+OO.ui.Window.prototype.setManager = function ( manager ) {
+       if ( this.manager ) {
+               throw new Error( 'Cannot set window manager, window already has a manager' );
+       }
+
+       this.manager = manager;
+       this.initialize();
+
+       return this;
+};
+
+/**
+ * Set the window size by symbolic name (e.g., 'small' or 'medium')
+ *
+ * @param {string} size Symbolic name of size: `small`, `medium`, `large`, `larger` or
+ *  `full`
+ * @chainable
+ */
+OO.ui.Window.prototype.setSize = function ( size ) {
+       this.size = size;
+       this.updateSize();
+       return this;
+};
+
+/**
+ * Update the window size.
+ *
+ * @throws {Error} An error is thrown if the window is not attached to a window manager
+ * @chainable
+ */
+OO.ui.Window.prototype.updateSize = function () {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot update window size, must be attached to a manager' );
+       }
+
+       this.manager.updateWindowSize( this );
+
+       return this;
+};
+
+/**
+ * Set window dimensions. This method is called by the {@link OO.ui.WindowManager window manager}
+ * when the window is opening. In general, setDimensions should not be called directly.
+ *
+ * To set the size of the window, use the #setSize method.
+ *
+ * @param {Object} dim CSS dimension properties
+ * @param {string|number} [dim.width] Width
+ * @param {string|number} [dim.minWidth] Minimum width
+ * @param {string|number} [dim.maxWidth] Maximum width
+ * @param {string|number} [dim.width] Height, omit to set based on height of contents
+ * @param {string|number} [dim.minWidth] Minimum height
+ * @param {string|number} [dim.maxWidth] Maximum height
+ * @chainable
+ */
+OO.ui.Window.prototype.setDimensions = function ( dim ) {
+       var height,
+               win = this,
+               styleObj = this.$frame[ 0 ].style;
+
+       // Calculate the height we need to set using the correct width
+       if ( dim.height === undefined ) {
+               this.withoutSizeTransitions( function () {
+                       var oldWidth = styleObj.width;
+                       win.$frame.css( 'width', dim.width || '' );
+                       height = win.getContentHeight();
+                       styleObj.width = oldWidth;
+               } );
+       } else {
+               height = dim.height;
+       }
+
+       this.$frame.css( {
+               width: dim.width || '',
+               minWidth: dim.minWidth || '',
+               maxWidth: dim.maxWidth || '',
+               height: height || '',
+               minHeight: dim.minHeight || '',
+               maxHeight: dim.maxHeight || ''
+       } );
+
+       return this;
+};
+
+/**
+ * Initialize window contents.
+ *
+ * Before the window is opened for the first time, #initialize is called so that content that
+ * persists between openings can be added to the window.
+ *
+ * To set up a window with new content each time the window opens, use #getSetupProcess.
+ *
+ * @throws {Error} An error is thrown if the window is not attached to a window manager
+ * @chainable
+ */
+OO.ui.Window.prototype.initialize = function () {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot initialize window, must be attached to a manager' );
+       }
+
+       // Properties
+       this.$head = $( '<div>' );
+       this.$body = $( '<div>' );
+       this.$foot = $( '<div>' );
+       this.$document = $( this.getElementDocument() );
+
+       // Events
+       this.$element.on( 'mousedown', this.onMouseDown.bind( this ) );
+
+       // Initialization
+       this.$head.addClass( 'oo-ui-window-head' );
+       this.$body.addClass( 'oo-ui-window-body' );
+       this.$foot.addClass( 'oo-ui-window-foot' );
+       this.$content.append( this.$head, this.$body, this.$foot );
+
+       return this;
+};
+
+/**
+ * Called when someone tries to focus the hidden element at the end of the dialog.
+ * Sends focus back to the start of the dialog.
+ *
+ * @param {jQuery.Event} event Focus event
+ */
+OO.ui.Window.prototype.onFocusTrapFocused = function ( event ) {
+       if ( this.$focusTrapBefore.is( event.target ) ) {
+               OO.ui.findFocusable( this.$content, true ).focus();
+       } else {
+               // this.$content is the part of the focus cycle, and is the first focusable element
+               this.$content.focus();
+       }
+};
+
+/**
+ * Open the window.
+ *
+ * This method is a wrapper around a call to the window manager’s {@link OO.ui.WindowManager#openWindow openWindow}
+ * method, which returns a promise resolved when the window is done opening.
+ *
+ * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.
+ *
+ * @param {Object} [data] Window opening data
+ * @return {jQuery.Promise} Promise resolved with a value when the window is opened, or rejected
+ *  if the window fails to open. When the promise is resolved successfully, the first argument of the
+ *  value is a new promise, which is resolved when the window begins closing.
+ * @throws {Error} An error is thrown if the window is not attached to a window manager
+ */
+OO.ui.Window.prototype.open = function ( data ) {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot open window, must be attached to a manager' );
+       }
+
+       return this.manager.openWindow( this, data );
+};
+
+/**
+ * Close the window.
+ *
+ * This method is a wrapper around a call to the window
+ * manager’s {@link OO.ui.WindowManager#closeWindow closeWindow} method,
+ * which returns a closing promise resolved when the window is done closing.
+ *
+ * The window's #getHoldProcess and #getTeardownProcess methods are called during the closing
+ * phase of the window’s lifecycle and can be used to specify closing behavior each time
+ * the window closes.
+ *
+ * @param {Object} [data] Window closing data
+ * @return {jQuery.Promise} Promise resolved when window is closed
+ * @throws {Error} An error is thrown if the window is not attached to a window manager
+ */
+OO.ui.Window.prototype.close = function ( data ) {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot close window, must be attached to a manager' );
+       }
+
+       return this.manager.closeWindow( this, data );
+};
+
+/**
+ * Setup window.
+ *
+ * This is called by OO.ui.WindowManager during window opening, and should not be called directly
+ * by other systems.
+ *
+ * @param {Object} [data] Window opening data
+ * @return {jQuery.Promise} Promise resolved when window is setup
+ */
+OO.ui.Window.prototype.setup = function ( data ) {
+       var win = this;
+
+       this.toggle( true );
+
+       this.focusTrapHandler = OO.ui.bind( this.onFocusTrapFocused, this );
+       this.$focusTraps.on( 'focus', this.focusTrapHandler );
+
+       return this.getSetupProcess( data ).execute().then( function () {
+               // Force redraw by asking the browser to measure the elements' widths
+               win.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
+               win.$content.addClass( 'oo-ui-window-content-setup' ).width();
+       } );
+};
+
+/**
+ * Ready window.
+ *
+ * This is called by OO.ui.WindowManager during window opening, and should not be called directly
+ * by other systems.
+ *
+ * @param {Object} [data] Window opening data
+ * @return {jQuery.Promise} Promise resolved when window is ready
+ */
+OO.ui.Window.prototype.ready = function ( data ) {
+       var win = this;
+
+       this.$content.focus();
+       return this.getReadyProcess( data ).execute().then( function () {
+               // Force redraw by asking the browser to measure the elements' widths
+               win.$element.addClass( 'oo-ui-window-ready' ).width();
+               win.$content.addClass( 'oo-ui-window-content-ready' ).width();
+       } );
+};
+
+/**
+ * Hold window.
+ *
+ * This is called by OO.ui.WindowManager during window closing, and should not be called directly
+ * by other systems.
+ *
+ * @param {Object} [data] Window closing data
+ * @return {jQuery.Promise} Promise resolved when window is held
+ */
+OO.ui.Window.prototype.hold = function ( data ) {
+       var win = this;
+
+       return this.getHoldProcess( data ).execute().then( function () {
+               // Get the focused element within the window's content
+               var $focus = win.$content.find( OO.ui.Element.static.getDocument( win.$content ).activeElement );
+
+               // Blur the focused element
+               if ( $focus.length ) {
+                       $focus[ 0 ].blur();
+               }
+
+               // Force redraw by asking the browser to measure the elements' widths
+               win.$element.removeClass( 'oo-ui-window-ready' ).width();
+               win.$content.removeClass( 'oo-ui-window-content-ready' ).width();
+       } );
+};
+
+/**
+ * Teardown window.
+ *
+ * This is called by OO.ui.WindowManager during window closing, and should not be called directly
+ * by other systems.
+ *
+ * @param {Object} [data] Window closing data
+ * @return {jQuery.Promise} Promise resolved when window is torn down
+ */
+OO.ui.Window.prototype.teardown = function ( data ) {
+       var win = this;
+
+       return this.getTeardownProcess( data ).execute().then( function () {
+               // Force redraw by asking the browser to measure the elements' widths
+               win.$element.removeClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
+               win.$content.removeClass( 'oo-ui-window-content-setup' ).width();
+               win.$focusTraps.off( 'focus', win.focusTrapHandler );
+               win.toggle( false );
+       } );
+};
+
+/**
+ * The Dialog class serves as the base class for the other types of dialogs.
+ * Unless extended to include controls, the rendered dialog box is a simple window
+ * that users can close by hitting the ‘Esc’ key. Dialog windows are used with OO.ui.WindowManager,
+ * which opens, closes, and controls the presentation of the window. See the
+ * [OOjs UI documentation on MediaWiki] [1] for more information.
+ *
+ *     @example
+ *     // A simple dialog window.
+ *     function MyDialog( config ) {
+ *         MyDialog.parent.call( this, config );
+ *     }
+ *     OO.inheritClass( MyDialog, OO.ui.Dialog );
+ *     MyDialog.prototype.initialize = function () {
+ *         MyDialog.parent.prototype.initialize.call( this );
+ *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
+ *         this.content.$element.append( '<p>A simple dialog window. Press \'Esc\' to close.</p>' );
+ *         this.$body.append( this.content.$element );
+ *     };
+ *     MyDialog.prototype.getBodyHeight = function () {
+ *         return this.content.$element.outerHeight( true );
+ *     };
+ *     var myDialog = new MyDialog( {
+ *         size: 'medium'
+ *     } );
+ *     // Create and append a window manager, which opens and closes the window.
+ *     var windowManager = new OO.ui.WindowManager();
+ *     $( 'body' ).append( windowManager.$element );
+ *     windowManager.addWindows( [ myDialog ] );
+ *     // Open the window!
+ *     windowManager.openWindow( myDialog );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Dialogs
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Window
+ * @mixins OO.ui.mixin.PendingElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.Dialog = function OoUiDialog( config ) {
+       // Parent constructor
+       OO.ui.Dialog.parent.call( this, config );
+
+       // Mixin constructors
+       OO.ui.mixin.PendingElement.call( this );
+
+       // Properties
+       this.actions = new OO.ui.ActionSet();
+       this.attachedActions = [];
+       this.currentAction = null;
+       this.onDialogKeyDownHandler = this.onDialogKeyDown.bind( this );
+
+       // Events
+       this.actions.connect( this, {
+               click: 'onActionClick',
+               resize: 'onActionResize',
+               change: 'onActionsChange'
+       } );
+
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-dialog' )
+               .attr( 'role', 'dialog' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.Dialog, OO.ui.Window );
+OO.mixinClass( OO.ui.Dialog, OO.ui.mixin.PendingElement );
+
+/* Static Properties */
+
+/**
+ * Symbolic name of dialog.
+ *
+ * The dialog class must have a symbolic name in order to be registered with OO.Factory.
+ * Please see the [OOjs UI documentation on MediaWiki] [3] for more information.
+ *
+ * [3]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {string}
+ */
+OO.ui.Dialog.static.name = '';
+
+/**
+ * The dialog title.
+ *
+ * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node, or a function
+ * that will produce a Label node or string. The title can also be specified with data passed to the
+ * constructor (see #getSetupProcess). In this case, the static value will be overridden.
+ *
+ * @abstract
+ * @static
+ * @inheritable
+ * @property {jQuery|string|Function}
+ */
+OO.ui.Dialog.static.title = '';
+
+/**
+ * An array of configured {@link OO.ui.ActionWidget action widgets}.
+ *
+ * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this case, the static
+ * value will be overridden.
+ *
+ * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
+ *
+ * @static
+ * @inheritable
+ * @property {Object[]}
+ */
+OO.ui.Dialog.static.actions = [];
+
+/**
+ * Close the dialog when the 'Esc' key is pressed.
+ *
+ * @static
+ * @abstract
+ * @inheritable
+ * @property {boolean}
+ */
+OO.ui.Dialog.static.escapable = true;
+
+/* Methods */
+
+/**
+ * Handle frame document key down events.
+ *
+ * @private
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.Dialog.prototype.onDialogKeyDown = function ( e ) {
+       if ( e.which === OO.ui.Keys.ESCAPE ) {
+               this.executeAction( '' );
+               e.preventDefault();
+               e.stopPropagation();
+       }
+};
+
+/**
+ * Handle action resized events.
+ *
+ * @private
+ * @param {OO.ui.ActionWidget} action Action that was resized
+ */
+OO.ui.Dialog.prototype.onActionResize = function () {
+       // Override in subclass
+};
+
+/**
+ * Handle action click events.
+ *
+ * @private
+ * @param {OO.ui.ActionWidget} action Action that was clicked
+ */
+OO.ui.Dialog.prototype.onActionClick = function ( action ) {
+       if ( !this.isPending() ) {
+               this.executeAction( action.getAction() );
+       }
+};
+
+/**
+ * Handle actions change event.
+ *
+ * @private
+ */
+OO.ui.Dialog.prototype.onActionsChange = function () {
+       this.detachActions();
+       if ( !this.isClosing() ) {
+               this.attachActions();
+       }
+};
+
+/**
+ * Get the set of actions used by the dialog.
+ *
+ * @return {OO.ui.ActionSet}
+ */
+OO.ui.Dialog.prototype.getActions = function () {
+       return this.actions;
+};
+
+/**
+ * Get a process for taking action.
+ *
+ * When you override this method, you can create a new OO.ui.Process and return it, or add additional
+ * accept steps to the process the parent method provides using the {@link OO.ui.Process#first 'first'}
+ * and {@link OO.ui.Process#next 'next'} methods of OO.ui.Process.
+ *
+ * @param {string} [action] Symbolic name of action
+ * @return {OO.ui.Process} Action process
+ */
+OO.ui.Dialog.prototype.getActionProcess = function ( action ) {
+       return new OO.ui.Process()
+               .next( function () {
+                       if ( !action ) {
+                               // An empty action always closes the dialog without data, which should always be
+                               // safe and make no changes
+                               this.close();
+                       }
+               }, this );
+};
+
+/**
+ * @inheritdoc
+ *
+ * @param {Object} [data] Dialog opening data
+ * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use
+ *  the {@link #static-title static title}
+ * @param {Object[]} [data.actions] List of configuration options for each
+ *   {@link OO.ui.ActionWidget action widget}, omit to use {@link #static-actions static actions}.
+ */
+OO.ui.Dialog.prototype.getSetupProcess = function ( data ) {
+       data = data || {};
+
+       // Parent method
+       return OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data )
+               .next( function () {
+                       var config = this.constructor.static,
+                               actions = data.actions !== undefined ? data.actions : config.actions;
+
+                       this.title.setLabel(
+                               data.title !== undefined ? data.title : this.constructor.static.title
+                       );
+                       this.actions.add( this.getActionWidgets( actions ) );
+
+                       if ( this.constructor.static.escapable ) {
+                               this.$element.on( 'keydown', this.onDialogKeyDownHandler );
+                       }
+               }, this );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.Dialog.prototype.getTeardownProcess = function ( data ) {
+       // Parent method
+       return OO.ui.Dialog.parent.prototype.getTeardownProcess.call( this, data )
+               .first( function () {
+                       if ( this.constructor.static.escapable ) {
+                               this.$element.off( 'keydown', this.onDialogKeyDownHandler );
+                       }
+
+                       this.actions.clear();
+                       this.currentAction = null;
+               }, this );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.Dialog.prototype.initialize = function () {
+       var titleId;
+
+       // Parent method
+       OO.ui.Dialog.parent.prototype.initialize.call( this );
+
+       titleId = OO.ui.generateElementId();
+
+       // Properties
+       this.title = new OO.ui.LabelWidget( {
+               id: titleId
+       } );
+
+       // Initialization
+       this.$content.addClass( 'oo-ui-dialog-content' );
+       this.$element.attr( 'aria-labelledby', titleId );
+       this.setPendingElement( this.$head );
+};
+
+/**
+ * Get action widgets from a list of configs
+ *
+ * @param {Object[]} actions Action widget configs
+ * @return {OO.ui.ActionWidget[]} Action widgets
+ */
+OO.ui.Dialog.prototype.getActionWidgets = function ( actions ) {
+       var i, len, widgets = [];
+       for ( i = 0, len = actions.length; i < len; i++ ) {
+               widgets.push(
+                       new OO.ui.ActionWidget( actions[ i ] )
+               );
+       }
+       return widgets;
+};
+
+/**
+ * Attach action actions.
+ *
+ * @protected
+ */
+OO.ui.Dialog.prototype.attachActions = function () {
+       // Remember the list of potentially attached actions
+       this.attachedActions = this.actions.get();
+};
+
+/**
+ * Detach action actions.
+ *
+ * @protected
+ * @chainable
+ */
+OO.ui.Dialog.prototype.detachActions = function () {
+       var i, len;
+
+       // Detach all actions that may have been previously attached
+       for ( i = 0, len = this.attachedActions.length; i < len; i++ ) {
+               this.attachedActions[ i ].$element.detach();
+       }
+       this.attachedActions = [];
+};
+
+/**
+ * Execute an action.
+ *
+ * @param {string} action Symbolic name of action to execute
+ * @return {jQuery.Promise} Promise resolved when action completes, rejected if it fails
+ */
+OO.ui.Dialog.prototype.executeAction = function ( action ) {
+       this.pushPending();
+       this.currentAction = action;
+       return this.getActionProcess( action ).execute()
+               .always( this.popPending.bind( this ) );
+};
+
+/**
+ * MessageDialogs display a confirmation or alert message. By default, the rendered dialog box
+ * consists of a header that contains the dialog title, a body with the message, and a footer that
+ * contains any {@link OO.ui.ActionWidget action widgets}. The MessageDialog class is the only type
+ * of {@link OO.ui.Dialog dialog} that is usually instantiated directly.
+ *
+ * There are two basic types of message dialogs, confirmation and alert:
+ *
+ * - **confirmation**: the dialog title describes what a progressive action will do and the message provides
+ *  more details about the consequences.
+ * - **alert**: the dialog title describes which event occurred and the message provides more information
+ *  about why the event occurred.
+ *
+ * The MessageDialog class specifies two actions: ‘accept’, the primary
+ * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window,
+ * passing along the selected action.
+ *
+ * For more information and examples, please see the [OOjs UI documentation on MediaWiki][1].
+ *
+ *     @example
+ *     // Example: Creating and opening a message dialog window.
+ *     var messageDialog = new OO.ui.MessageDialog();
+ *
+ *     // Create and append a window manager.
+ *     var windowManager = new OO.ui.WindowManager();
+ *     $( 'body' ).append( windowManager.$element );
+ *     windowManager.addWindows( [ messageDialog ] );
+ *     // Open the window.
+ *     windowManager.openWindow( messageDialog, {
+ *         title: 'Basic message dialog',
+ *         message: 'This is the message'
+ *     } );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Message_Dialogs
+ *
+ * @class
+ * @extends OO.ui.Dialog
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.MessageDialog = function OoUiMessageDialog( config ) {
+       // Parent constructor
+       OO.ui.MessageDialog.parent.call( this, config );
+
+       // Properties
+       this.verticalActionLayout = null;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-messageDialog' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.MessageDialog, OO.ui.Dialog );
+
+/* Static Properties */
+
+OO.ui.MessageDialog.static.name = 'message';
+
+OO.ui.MessageDialog.static.size = 'small';
+
+OO.ui.MessageDialog.static.verbose = false;
+
+/**
+ * Dialog title.
+ *
+ * The title of a confirmation dialog describes what a progressive action will do. The
+ * title of an alert dialog describes which event occurred.
+ *
+ * @static
+ * @inheritable
+ * @property {jQuery|string|Function|null}
+ */
+OO.ui.MessageDialog.static.title = null;
+
+/**
+ * The message displayed in the dialog body.
+ *
+ * A confirmation message describes the consequences of a progressive action. An alert
+ * message describes why an event occurred.
+ *
+ * @static
+ * @inheritable
+ * @property {jQuery|string|Function|null}
+ */
+OO.ui.MessageDialog.static.message = null;
+
+// Note that OO.ui.alert() and OO.ui.confirm() rely on these.
+OO.ui.MessageDialog.static.actions = [
+       { action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' },
+       { action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' }
+];
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.setManager = function ( manager ) {
+       OO.ui.MessageDialog.parent.prototype.setManager.call( this, manager );
+
+       // Events
+       this.manager.connect( this, {
+               resize: 'onResize'
+       } );
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.onActionResize = function ( action ) {
+       this.fitActions();
+       return OO.ui.MessageDialog.parent.prototype.onActionResize.call( this, action );
+};
+
+/**
+ * Handle window resized events.
+ *
+ * @private
+ */
+OO.ui.MessageDialog.prototype.onResize = function () {
+       var dialog = this;
+       dialog.fitActions();
+       // Wait for CSS transition to finish and do it again :(
+       setTimeout( function () {
+               dialog.fitActions();
+       }, 300 );
+};
+
+/**
+ * Toggle action layout between vertical and horizontal.
+ *
+ * @private
+ * @param {boolean} [value] Layout actions vertically, omit to toggle
+ * @chainable
+ */
+OO.ui.MessageDialog.prototype.toggleVerticalActionLayout = function ( value ) {
+       value = value === undefined ? !this.verticalActionLayout : !!value;
+
+       if ( value !== this.verticalActionLayout ) {
+               this.verticalActionLayout = value;
+               this.$actions
+                       .toggleClass( 'oo-ui-messageDialog-actions-vertical', value )
+                       .toggleClass( 'oo-ui-messageDialog-actions-horizontal', !value );
+       }
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {
+       if ( action ) {
+               return new OO.ui.Process( function () {
+                       this.close( { action: action } );
+               }, this );
+       }
+       return OO.ui.MessageDialog.parent.prototype.getActionProcess.call( this, action );
+};
+
+/**
+ * @inheritdoc
+ *
+ * @param {Object} [data] Dialog opening data
+ * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed
+ * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence
+ * @param {boolean} [data.verbose] Message is verbose and should be styled as a long message
+ * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each
+ *   action item
+ */
+OO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {
+       data = data || {};
+
+       // Parent method
+       return OO.ui.MessageDialog.parent.prototype.getSetupProcess.call( this, data )
+               .next( function () {
+                       this.title.setLabel(
+                               data.title !== undefined ? data.title : this.constructor.static.title
+                       );
+                       this.message.setLabel(
+                               data.message !== undefined ? data.message : this.constructor.static.message
+                       );
+                       this.message.$element.toggleClass(
+                               'oo-ui-messageDialog-message-verbose',
+                               data.verbose !== undefined ? data.verbose : this.constructor.static.verbose
+                       );
+               }, this );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) {
+       data = data || {};
+
+       // Parent method
+       return OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data )
+               .next( function () {
+                       // Focus the primary action button
+                       var actions = this.actions.get();
+                       actions = actions.filter( function ( action ) {
+                               return action.getFlags().indexOf( 'primary' ) > -1;
+                       } );
+                       if ( actions.length > 0 ) {
+                               actions[ 0 ].$button.focus();
+                       }
+               }, this );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.getBodyHeight = function () {
+       var bodyHeight, oldOverflow,
+               $scrollable = this.container.$element;
+
+       oldOverflow = $scrollable[ 0 ].style.overflow;
+       $scrollable[ 0 ].style.overflow = 'hidden';
+
+       OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );
+
+       bodyHeight = this.text.$element.outerHeight( true );
+       $scrollable[ 0 ].style.overflow = oldOverflow;
+
+       return bodyHeight;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.setDimensions = function ( dim ) {
+       var $scrollable = this.container.$element;
+       OO.ui.MessageDialog.parent.prototype.setDimensions.call( this, dim );
+
+       // Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced.
+       // Need to do it after transition completes (250ms), add 50ms just in case.
+       setTimeout( function () {
+               var oldOverflow = $scrollable[ 0 ].style.overflow;
+               $scrollable[ 0 ].style.overflow = 'hidden';
+
+               OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );
+
+               $scrollable[ 0 ].style.overflow = oldOverflow;
+       }, 300 );
+
+       return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.initialize = function () {
+       // Parent method
+       OO.ui.MessageDialog.parent.prototype.initialize.call( this );
+
+       // Properties
+       this.$actions = $( '<div>' );
+       this.container = new OO.ui.PanelLayout( {
+               scrollable: true, classes: [ 'oo-ui-messageDialog-container' ]
+       } );
+       this.text = new OO.ui.PanelLayout( {
+               padded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]
+       } );
+       this.message = new OO.ui.LabelWidget( {
+               classes: [ 'oo-ui-messageDialog-message' ]
+       } );
+
+       // Initialization
+       this.title.$element.addClass( 'oo-ui-messageDialog-title' );
+       this.$content.addClass( 'oo-ui-messageDialog-content' );
+       this.container.$element.append( this.text.$element );
+       this.text.$element.append( this.title.$element, this.message.$element );
+       this.$body.append( this.container.$element );
+       this.$actions.addClass( 'oo-ui-messageDialog-actions' );
+       this.$foot.append( this.$actions );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.attachActions = function () {
+       var i, len, other, special, others;
+
+       // Parent method
+       OO.ui.MessageDialog.parent.prototype.attachActions.call( this );
+
+       special = this.actions.getSpecial();
+       others = this.actions.getOthers();
+
+       if ( special.safe ) {
+               this.$actions.append( special.safe.$element );
+               special.safe.toggleFramed( false );
+       }
+       if ( others.length ) {
+               for ( i = 0, len = others.length; i < len; i++ ) {
+                       other = others[ i ];
+                       this.$actions.append( other.$element );
+                       other.toggleFramed( false );
+               }
+       }
+       if ( special.primary ) {
+               this.$actions.append( special.primary.$element );
+               special.primary.toggleFramed( false );
+       }
+
+       if ( !this.isOpening() ) {
+               // If the dialog is currently opening, this will be called automatically soon.
+               // This also calls #fitActions.
+               this.updateSize();
+       }
+};
+
+/**
+ * Fit action actions into columns or rows.
+ *
+ * Columns will be used if all labels can fit without overflow, otherwise rows will be used.
+ *
+ * @private
+ */
+OO.ui.MessageDialog.prototype.fitActions = function () {
+       var i, len, action,
+               previous = this.verticalActionLayout,
+               actions = this.actions.get();
+
+       // Detect clipping
+       this.toggleVerticalActionLayout( false );
+       for ( i = 0, len = actions.length; i < len; i++ ) {
+               action = actions[ i ];
+               if ( action.$element.innerWidth() < action.$label.outerWidth( true ) ) {
+                       this.toggleVerticalActionLayout( true );
+                       break;
+               }
+       }
+
+       // Move the body out of the way of the foot
+       this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
+
+       if ( this.verticalActionLayout !== previous ) {
+               // We changed the layout, window height might need to be updated.
+               this.updateSize();
+       }
+};
+
+/**
+ * ProcessDialog windows encapsulate a {@link OO.ui.Process process} and all of the code necessary
+ * to complete it. If the process terminates with an error, a customizable {@link OO.ui.Error error
+ * interface} alerts users to the trouble, permitting the user to dismiss the error and try again when
+ * relevant. The ProcessDialog class is always extended and customized with the actions and content
+ * required for each process.
+ *
+ * The process dialog box consists of a header that visually represents the ‘working’ state of long
+ * processes with an animation. The header contains the dialog title as well as
+ * two {@link OO.ui.ActionWidget action widgets}:  a ‘safe’ action on the left (e.g., ‘Cancel’) and
+ * a ‘primary’ action on the right (e.g., ‘Done’).
+ *
+ * Like other windows, the process dialog is managed by a {@link OO.ui.WindowManager window manager}.
+ * Please see the [OOjs UI documentation on MediaWiki][1] for more information and examples.
+ *
+ *     @example
+ *     // Example: Creating and opening a process dialog window.
+ *     function MyProcessDialog( config ) {
+ *         MyProcessDialog.parent.call( this, config );
+ *     }
+ *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );
+ *
+ *     MyProcessDialog.static.title = 'Process dialog';
+ *     MyProcessDialog.static.actions = [
+ *         { action: 'save', label: 'Done', flags: 'primary' },
+ *         { label: 'Cancel', flags: 'safe' }
+ *     ];
+ *
+ *     MyProcessDialog.prototype.initialize = function () {
+ *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
+ *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
+ *         this.content.$element.append( '<p>This is a process dialog window. The header contains the title and two buttons: \'Cancel\' (a safe action) on the left and \'Done\' (a primary action)  on the right.</p>' );
+ *         this.$body.append( this.content.$element );
+ *     };
+ *     MyProcessDialog.prototype.getActionProcess = function ( action ) {
+ *         var dialog = this;
+ *         if ( action ) {
+ *             return new OO.ui.Process( function () {
+ *                 dialog.close( { action: action } );
+ *             } );
+ *         }
+ *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );
+ *     };
+ *
+ *     var windowManager = new OO.ui.WindowManager();
+ *     $( 'body' ).append( windowManager.$element );
+ *
+ *     var dialog = new MyProcessDialog();
+ *     windowManager.addWindows( [ dialog ] );
+ *     windowManager.openWindow( dialog );
+ *
+ * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs
+ *
+ * @abstract
+ * @class
+ * @extends OO.ui.Dialog
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ProcessDialog = function OoUiProcessDialog( config ) {
+       // Parent constructor
+       OO.ui.ProcessDialog.parent.call( this, config );
+
+       // Properties
+       this.fitOnOpen = false;
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-processDialog' );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.ProcessDialog, OO.ui.Dialog );
+
+/* Methods */
+
+/**
+ * Handle dismiss button click events.
+ *
+ * Hides errors.
+ *
+ * @private
+ */
+OO.ui.ProcessDialog.prototype.onDismissErrorButtonClick = function () {
+       this.hideErrors();
+};
+
+/**
+ * Handle retry button click events.
+ *
+ * Hides errors and then tries again.
+ *
+ * @private
+ */
+OO.ui.ProcessDialog.prototype.onRetryButtonClick = function () {
+       this.hideErrors();
+       this.executeAction( this.currentAction );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.onActionResize = function ( action ) {
+       if ( this.actions.isSpecial( action ) ) {
+               this.fitLabel();
+       }
+       return OO.ui.ProcessDialog.parent.prototype.onActionResize.call( this, action );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.initialize = function () {
+       // Parent method
+       OO.ui.ProcessDialog.parent.prototype.initialize.call( this );
+
+       // Properties
+       this.$navigation = $( '<div>' );
+       this.$location = $( '<div>' );
+       this.$safeActions = $( '<div>' );
+       this.$primaryActions = $( '<div>' );
+       this.$otherActions = $( '<div>' );
+       this.dismissButton = new OO.ui.ButtonWidget( {
+               label: OO.ui.msg( 'ooui-dialog-process-dismiss' )
+       } );
+       this.retryButton = new OO.ui.ButtonWidget();
+       this.$errors = $( '<div>' );
+       this.$errorsTitle = $( '<div>' );
+
+       // Events
+       this.dismissButton.connect( this, { click: 'onDismissErrorButtonClick' } );
+       this.retryButton.connect( this, { click: 'onRetryButtonClick' } );
+
+       // Initialization
+       this.title.$element.addClass( 'oo-ui-processDialog-title' );
+       this.$location
+               .append( this.title.$element )
+               .addClass( 'oo-ui-processDialog-location' );
+       this.$safeActions.addClass( 'oo-ui-processDialog-actions-safe' );
+       this.$primaryActions.addClass( 'oo-ui-processDialog-actions-primary' );
+       this.$otherActions.addClass( 'oo-ui-processDialog-actions-other' );
+       this.$errorsTitle
+               .addClass( 'oo-ui-processDialog-errors-title' )
+               .text( OO.ui.msg( 'ooui-dialog-process-error' ) );
+       this.$errors
+               .addClass( 'oo-ui-processDialog-errors oo-ui-element-hidden' )
+               .append( this.$errorsTitle, this.dismissButton.$element, this.retryButton.$element );
+       this.$content
+               .addClass( 'oo-ui-processDialog-content' )
+               .append( this.$errors );
+       this.$navigation
+               .addClass( 'oo-ui-processDialog-navigation' )
+               .append( this.$safeActions, this.$location, this.$primaryActions );
+       this.$head.append( this.$navigation );
+       this.$foot.append( this.$otherActions );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.getActionWidgets = function ( actions ) {
+       var i, len, widgets = [];
+       for ( i = 0, len = actions.length; i < len; i++ ) {
+               widgets.push(
+                       new OO.ui.ActionWidget( $.extend( { framed: true }, actions[ i ] ) )
+               );
+       }
+       return widgets;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.attachActions = function () {
+       var i, len, other, special, others;
+
+       // Parent method
+       OO.ui.ProcessDialog.parent.prototype.attachActions.call( this );
+
+       special = this.actions.getSpecial();
+       others = this.actions.getOthers();
+       if ( special.primary ) {
+               this.$primaryActions.append( special.primary.$element );
+       }
+       for ( i = 0, len = others.length; i < len; i++ ) {
+               other = others[ i ];
+               this.$otherActions.append( other.$element );
+       }
+       if ( special.safe ) {
+               this.$safeActions.append( special.safe.$element );
+       }
+
+       this.fitLabel();
+       this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.executeAction = function ( action ) {
+       var process = this;
+       return OO.ui.ProcessDialog.parent.prototype.executeAction.call( this, action )
+               .fail( function ( errors ) {
+                       process.showErrors( errors || [] );
+               } );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.setDimensions = function () {
+       // Parent method
+       OO.ui.ProcessDialog.parent.prototype.setDimensions.apply( this, arguments );
+
+       this.fitLabel();
+};
+
+/**
+ * Fit label between actions.
+ *
+ * @private
+ * @chainable
+ */
+OO.ui.ProcessDialog.prototype.fitLabel = function () {
+       var safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth,
+               size = this.getSizeProperties();
+
+       if ( typeof size.width !== 'number' ) {
+               if ( this.isOpened() ) {
+                       navigationWidth = this.$head.width() - 20;
+               } else if ( this.isOpening() ) {
+                       if ( !this.fitOnOpen ) {
+                               // Size is relative and the dialog isn't open yet, so wait.
+                               this.manager.opening.done( this.fitLabel.bind( this ) );
+                               this.fitOnOpen = true;
+                       }
+                       return;
+               } else {
+                       return;
+               }
+       } else {
+               navigationWidth = size.width - 20;
+       }
+
+       safeWidth = this.$safeActions.is( ':visible' ) ? this.$safeActions.width() : 0;
+       primaryWidth = this.$primaryActions.is( ':visible' ) ? this.$primaryActions.width() : 0;
+       biggerWidth = Math.max( safeWidth, primaryWidth );
+
+       labelWidth = this.title.$element.width();
+
+       if ( 2 * biggerWidth + labelWidth < navigationWidth ) {
+               // We have enough space to center the label
+               leftWidth = rightWidth = biggerWidth;
+       } else {
+               // Let's hope we at least have enough space not to overlap, because we can't wrap the label…
+               if ( this.getDir() === 'ltr' ) {
+                       leftWidth = safeWidth;
+                       rightWidth = primaryWidth;
+               } else {
+                       leftWidth = primaryWidth;
+                       rightWidth = safeWidth;
+               }
+       }
+
+       this.$location.css( { paddingLeft: leftWidth, paddingRight: rightWidth } );
+
+       return this;
+};
+
+/**
+ * Handle errors that occurred during accept or reject processes.
+ *
+ * @private
+ * @param {OO.ui.Error[]|OO.ui.Error} errors Errors to be handled
+ */
+OO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {
+       var i, len, $item, actions,
+               items = [],
+               abilities = {},
+               recoverable = true,
+               warning = false;
+
+       if ( errors instanceof OO.ui.Error ) {
+               errors = [ errors ];
+       }
+
+       for ( i = 0, len = errors.length; i < len; i++ ) {
+               if ( !errors[ i ].isRecoverable() ) {
+                       recoverable = false;
+               }
+               if ( errors[ i ].isWarning() ) {
+                       warning = true;
+               }
+               $item = $( '<div>' )
+                       .addClass( 'oo-ui-processDialog-error' )
+                       .append( errors[ i ].getMessage() );
+               items.push( $item[ 0 ] );
+       }
+       this.$errorItems = $( items );
+       if ( recoverable ) {
+               abilities[ this.currentAction ] = true;
+               // Copy the flags from the first matching action
+               actions = this.actions.get( { actions: this.currentAction } );
+               if ( actions.length ) {
+                       this.retryButton.clearFlags().setFlags( actions[ 0 ].getFlags() );
+               }
+       } else {
+               abilities[ this.currentAction ] = false;
+               this.actions.setAbilities( abilities );
+       }
+       if ( warning ) {
+               this.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-continue' ) );
+       } else {
+               this.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-retry' ) );
+       }
+       this.retryButton.toggle( recoverable );
+       this.$errorsTitle.after( this.$errorItems );
+       this.$errors.removeClass( 'oo-ui-element-hidden' ).scrollTop( 0 );
+};
+
+/**
+ * Hide errors.
+ *
+ * @private
+ */
+OO.ui.ProcessDialog.prototype.hideErrors = function () {
+       this.$errors.addClass( 'oo-ui-element-hidden' );
+       if ( this.$errorItems ) {
+               this.$errorItems.remove();
+               this.$errorItems = null;
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) {
+       // Parent method
+       return OO.ui.ProcessDialog.parent.prototype.getTeardownProcess.call( this, data )
+               .first( function () {
+                       // Make sure to hide errors
+                       this.hideErrors();
+                       this.fitOnOpen = false;
+               }, this );
+};
+
+/**
+ * @class OO.ui
+ */
+
+/**
+ * Lazy-initialize and return a global OO.ui.WindowManager instance, used by OO.ui.alert and
+ * OO.ui.confirm.
+ *
+ * @private
+ * @return {OO.ui.WindowManager}
+ */
+OO.ui.getWindowManager = function () {
+       if ( !OO.ui.windowManager ) {
+               OO.ui.windowManager = new OO.ui.WindowManager();
+               $( 'body' ).append( OO.ui.windowManager.$element );
+               OO.ui.windowManager.addWindows( {
+                       messageDialog: new OO.ui.MessageDialog()
+               } );
+       }
+       return OO.ui.windowManager;
+};
+
+/**
+ * Display a quick modal alert dialog, using a OO.ui.MessageDialog. While the dialog is open, the
+ * rest of the page will be dimmed out and the user won't be able to interact with it. The dialog
+ * has only one action button, labelled "OK", clicking it will simply close the dialog.
+ *
+ * A window manager is created automatically when this function is called for the first time.
+ *
+ *     @example
+ *     OO.ui.alert( 'Something happened!' ).done( function () {
+ *         console.log( 'User closed the dialog.' );
+ *     } );
+ *
+ * @param {jQuery|string} text Message text to display
+ * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
+ * @return {jQuery.Promise} Promise resolved when the user closes the dialog
+ */
+OO.ui.alert = function ( text, options ) {
+       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
+               message: text,
+               verbose: true,
+               actions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]
+       }, options ) ).then( function ( opened ) {
+               return opened.then( function ( closing ) {
+                       return closing.then( function () {
+                               return $.Deferred().resolve();
+                       } );
+               } );
+       } );
+};
+
+/**
+ * Display a quick modal confirmation dialog, using a OO.ui.MessageDialog. While the dialog is open,
+ * the rest of the page will be dimmed out and the user won't be able to interact with it. The
+ * dialog has two action buttons, one to confirm an operation (labelled "OK") and one to cancel it
+ * (labelled "Cancel").
+ *
+ * A window manager is created automatically when this function is called for the first time.
+ *
+ *     @example
+ *     OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {
+ *         if ( confirmed ) {
+ *             console.log( 'User clicked "OK"!' );
+ *         } else {
+ *             console.log( 'User clicked "Cancel" or closed the dialog.' );
+ *         }
+ *     } );
+ *
+ * @param {jQuery|string} text Message text to display
+ * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
+ * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to
+ *  confirm, the promise will resolve to boolean `true`; otherwise, it will resolve to boolean
+ *  `false`.
+ */
+OO.ui.confirm = function ( text, options ) {
+       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
+               message: text,
+               verbose: true
+       }, options ) ).then( function ( opened ) {
+               return opened.then( function ( closing ) {
+                       return closing.then( function ( data ) {
+                               return $.Deferred().resolve( !!( data && data.action === 'accept' ) );
+                       } );
+               } );
+       } );
+};
+
+}( OO ) );
diff --git a/resources/lib/oojs-ui/oojs-ui.js b/resources/lib/oojs-ui/oojs-ui.js
deleted file mode 100644 (file)
index 98d4709..0000000
+++ /dev/null
@@ -1,20149 +0,0 @@
-/*!
- * OOjs UI v0.15.1
- * https://www.mediawiki.org/wiki/OOjs_UI
- *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
- * Released under the MIT license
- * http://oojs.mit-license.org
- *
- * Date: 2016-01-26T21:14:23Z
- */
-( function ( OO ) {
-
-'use strict';
-
-/**
- * Namespace for all classes, static methods and static properties.
- *
- * @class
- * @singleton
- */
-OO.ui = {};
-
-OO.ui.bind = $.proxy;
-
-/**
- * @property {Object}
- */
-OO.ui.Keys = {
-       UNDEFINED: 0,
-       BACKSPACE: 8,
-       DELETE: 46,
-       LEFT: 37,
-       RIGHT: 39,
-       UP: 38,
-       DOWN: 40,
-       ENTER: 13,
-       END: 35,
-       HOME: 36,
-       TAB: 9,
-       PAGEUP: 33,
-       PAGEDOWN: 34,
-       ESCAPE: 27,
-       SHIFT: 16,
-       SPACE: 32
-};
-
-/**
- * Constants for MouseEvent.which
- *
- * @property {Object}
- */
-OO.ui.MouseButtons = {
-       LEFT: 1,
-       MIDDLE: 2,
-       RIGHT: 3
-};
-
-/**
- * @property {Number}
- */
-OO.ui.elementId = 0;
-
-/**
- * Generate a unique ID for element
- *
- * @return {String} [id]
- */
-OO.ui.generateElementId = function () {
-       OO.ui.elementId += 1;
-       return 'oojsui-' + OO.ui.elementId;
-};
-
-/**
- * Check if an element is focusable.
- * Inspired from :focusable in jQueryUI v1.11.4 - 2015-04-14
- *
- * @param {jQuery} element Element to test
- * @return {boolean}
- */
-OO.ui.isFocusableElement = function ( $element ) {
-       var nodeName,
-               element = $element[ 0 ];
-
-       // Anything disabled is not focusable
-       if ( element.disabled ) {
-               return false;
-       }
-
-       // Check if the element is visible
-       if ( !(
-               // This is quicker than calling $element.is( ':visible' )
-               $.expr.filters.visible( element ) &&
-               // Check that all parents are visible
-               !$element.parents().addBack().filter( function () {
-                       return $.css( this, 'visibility' ) === 'hidden';
-               } ).length
-       ) ) {
-               return false;
-       }
-
-       // Check if the element is ContentEditable, which is the string 'true'
-       if ( element.contentEditable === 'true' ) {
-               return true;
-       }
-
-       // Anything with a non-negative numeric tabIndex is focusable.
-       // Use .prop to avoid browser bugs
-       if ( $element.prop( 'tabIndex' ) >= 0 ) {
-               return true;
-       }
-
-       // Some element types are naturally focusable
-       // (indexOf is much faster than regex in Chrome and about the
-       // same in FF: https://jsperf.com/regex-vs-indexof-array2)
-       nodeName = element.nodeName.toLowerCase();
-       if ( [ 'input', 'select', 'textarea', 'button', 'object' ].indexOf( nodeName ) !== -1 ) {
-               return true;
-       }
-
-       // Links and areas are focusable if they have an href
-       if ( ( nodeName === 'a' || nodeName === 'area' ) && $element.attr( 'href' ) !== undefined ) {
-               return true;
-       }
-
-       return false;
-};
-
-/**
- * Find a focusable child
- *
- * @param {jQuery} $container Container to search in
- * @param {boolean} [backwards] Search backwards
- * @return {jQuery} Focusable child, an empty jQuery object if none found
- */
-OO.ui.findFocusable = function ( $container, backwards ) {
-       var $focusable = $( [] ),
-               // $focusableCandidates is a superset of things that
-               // could get matched by isFocusableElement
-               $focusableCandidates = $container
-                       .find( 'input, select, textarea, button, object, a, area, [contenteditable], [tabindex]' );
-
-       if ( backwards ) {
-               $focusableCandidates = Array.prototype.reverse.call( $focusableCandidates );
-       }
-
-       $focusableCandidates.each( function () {
-               var $this = $( this );
-               if ( OO.ui.isFocusableElement( $this ) ) {
-                       $focusable = $this;
-                       return false;
-               }
-       } );
-       return $focusable;
-};
-
-/**
- * Get the user's language and any fallback languages.
- *
- * These language codes are used to localize user interface elements in the user's language.
- *
- * In environments that provide a localization system, this function should be overridden to
- * return the user's language(s). The default implementation returns English (en) only.
- *
- * @return {string[]} Language codes, in descending order of priority
- */
-OO.ui.getUserLanguages = function () {
-       return [ 'en' ];
-};
-
-/**
- * Get a value in an object keyed by language code.
- *
- * @param {Object.<string,Mixed>} obj Object keyed by language code
- * @param {string|null} [lang] Language code, if omitted or null defaults to any user language
- * @param {string} [fallback] Fallback code, used if no matching language can be found
- * @return {Mixed} Local value
- */
-OO.ui.getLocalValue = function ( obj, lang, fallback ) {
-       var i, len, langs;
-
-       // Requested language
-       if ( obj[ lang ] ) {
-               return obj[ lang ];
-       }
-       // Known user language
-       langs = OO.ui.getUserLanguages();
-       for ( i = 0, len = langs.length; i < len; i++ ) {
-               lang = langs[ i ];
-               if ( obj[ lang ] ) {
-                       return obj[ lang ];
-               }
-       }
-       // Fallback language
-       if ( obj[ fallback ] ) {
-               return obj[ fallback ];
-       }
-       // First existing language
-       for ( lang in obj ) {
-               return obj[ lang ];
-       }
-
-       return undefined;
-};
-
-/**
- * Check if a node is contained within another node
- *
- * Similar to jQuery#contains except a list of containers can be supplied
- * and a boolean argument allows you to include the container in the match list
- *
- * @param {HTMLElement|HTMLElement[]} containers Container node(s) to search in
- * @param {HTMLElement} contained Node to find
- * @param {boolean} [matchContainers] Include the container(s) in the list of nodes to match, otherwise only match descendants
- * @return {boolean} The node is in the list of target nodes
- */
-OO.ui.contains = function ( containers, contained, matchContainers ) {
-       var i;
-       if ( !Array.isArray( containers ) ) {
-               containers = [ containers ];
-       }
-       for ( i = containers.length - 1; i >= 0; i-- ) {
-               if ( ( matchContainers && contained === containers[ i ] ) || $.contains( containers[ i ], contained ) ) {
-                       return true;
-               }
-       }
-       return false;
-};
-
-/**
- * Return a function, that, as long as it continues to be invoked, will not
- * be triggered. The function will be called after it stops being called for
- * N milliseconds. If `immediate` is passed, trigger the function on the
- * leading edge, instead of the trailing.
- *
- * Ported from: http://underscorejs.org/underscore.js
- *
- * @param {Function} func
- * @param {number} wait
- * @param {boolean} immediate
- * @return {Function}
- */
-OO.ui.debounce = function ( func, wait, immediate ) {
-       var timeout;
-       return function () {
-               var context = this,
-                       args = arguments,
-                       later = function () {
-                               timeout = null;
-                               if ( !immediate ) {
-                                       func.apply( context, args );
-                               }
-                       };
-               if ( immediate && !timeout ) {
-                       func.apply( context, args );
-               }
-               clearTimeout( timeout );
-               timeout = setTimeout( later, wait );
-       };
-};
-
-/**
- * Proxy for `node.addEventListener( eventName, handler, true )`.
- *
- * @param {HTMLElement} node
- * @param {string} eventName
- * @param {Function} handler
- * @deprecated
- */
-OO.ui.addCaptureEventListener = function ( node, eventName, handler ) {
-       node.addEventListener( eventName, handler, true );
-};
-
-/**
- * Proxy for `node.removeEventListener( eventName, handler, true )`.
- *
- * @param {HTMLElement} node
- * @param {string} eventName
- * @param {Function} handler
- * @deprecated
- */
-OO.ui.removeCaptureEventListener = function ( node, eventName, handler ) {
-       node.removeEventListener( eventName, handler, true );
-};
-
-/**
- * Reconstitute a JavaScript object corresponding to a widget created by
- * the PHP implementation.
- *
- * This is an alias for `OO.ui.Element.static.infuse()`.
- *
- * @param {string|HTMLElement|jQuery} idOrNode
- *   A DOM id (if a string) or node for the widget to infuse.
- * @return {OO.ui.Element}
- *   The `OO.ui.Element` corresponding to this (infusable) document node.
- */
-OO.ui.infuse = function ( idOrNode ) {
-       return OO.ui.Element.static.infuse( idOrNode );
-};
-
-( function () {
-       /**
-        * Message store for the default implementation of OO.ui.msg
-        *
-        * Environments that provide a localization system should not use this, but should override
-        * OO.ui.msg altogether.
-        *
-        * @private
-        */
-       var messages = {
-               // Tool tip for a button that moves items in a list down one place
-               'ooui-outline-control-move-down': 'Move item down',
-               // Tool tip for a button that moves items in a list up one place
-               'ooui-outline-control-move-up': 'Move item up',
-               // Tool tip for a button that removes items from a list
-               'ooui-outline-control-remove': 'Remove item',
-               // Label for the toolbar group that contains a list of all other available tools
-               'ooui-toolbar-more': 'More',
-               // Label for the fake tool that expands the full list of tools in a toolbar group
-               'ooui-toolgroup-expand': 'More',
-               // Label for the fake tool that collapses the full list of tools in a toolbar group
-               'ooui-toolgroup-collapse': 'Fewer',
-               // Default label for the accept button of a confirmation dialog
-               'ooui-dialog-message-accept': 'OK',
-               // Default label for the reject button of a confirmation dialog
-               'ooui-dialog-message-reject': 'Cancel',
-               // Title for process dialog error description
-               'ooui-dialog-process-error': 'Something went wrong',
-               // Label for process dialog dismiss error button, visible when describing errors
-               'ooui-dialog-process-dismiss': 'Dismiss',
-               // Label for process dialog retry action button, visible when describing only recoverable errors
-               'ooui-dialog-process-retry': 'Try again',
-               // Label for process dialog retry action button, visible when describing only warnings
-               'ooui-dialog-process-continue': 'Continue',
-               // Label for the file selection widget's select file button
-               'ooui-selectfile-button-select': 'Select a file',
-               // Label for the file selection widget if file selection is not supported
-               'ooui-selectfile-not-supported': 'File selection is not supported',
-               // Label for the file selection widget when no file is currently selected
-               'ooui-selectfile-placeholder': 'No file is selected',
-               // Label for the file selection widget's drop target
-               'ooui-selectfile-dragdrop-placeholder': 'Drop file here'
-       };
-
-       /**
-        * Get a localized message.
-        *
-        * In environments that provide a localization system, this function should be overridden to
-        * return the message translated in the user's language. The default implementation always returns
-        * English messages.
-        *
-        * After the message key, message parameters may optionally be passed. In the default implementation,
-        * any occurrences of $1 are replaced with the first parameter, $2 with the second parameter, etc.
-        * Alternative implementations of OO.ui.msg may use any substitution system they like, as long as
-        * they support unnamed, ordered message parameters.
-        *
-        * @param {string} key Message key
-        * @param {Mixed...} [params] Message parameters
-        * @return {string} Translated message with parameters substituted
-        */
-       OO.ui.msg = function ( key ) {
-               var message = messages[ key ],
-                       params = Array.prototype.slice.call( arguments, 1 );
-               if ( typeof message === 'string' ) {
-                       // Perform $1 substitution
-                       message = message.replace( /\$(\d+)/g, function ( unused, n ) {
-                               var i = parseInt( n, 10 );
-                               return params[ i - 1 ] !== undefined ? params[ i - 1 ] : '$' + n;
-                       } );
-               } else {
-                       // Return placeholder if message not found
-                       message = '[' + key + ']';
-               }
-               return message;
-       };
-} )();
-
-/**
- * Package a message and arguments for deferred resolution.
- *
- * Use this when you are statically specifying a message and the message may not yet be present.
- *
- * @param {string} key Message key
- * @param {Mixed...} [params] Message parameters
- * @return {Function} Function that returns the resolved message when executed
- */
-OO.ui.deferMsg = function () {
-       var args = arguments;
-       return function () {
-               return OO.ui.msg.apply( OO.ui, args );
-       };
-};
-
-/**
- * Resolve a message.
- *
- * If the message is a function it will be executed, otherwise it will pass through directly.
- *
- * @param {Function|string} msg Deferred message, or message text
- * @return {string} Resolved message
- */
-OO.ui.resolveMsg = function ( msg ) {
-       if ( $.isFunction( msg ) ) {
-               return msg();
-       }
-       return msg;
-};
-
-/**
- * @param {string} url
- * @return {boolean}
- */
-OO.ui.isSafeUrl = function ( url ) {
-       // Keep this function in sync with php/Tag.php
-       var i, protocolWhitelist;
-
-       function stringStartsWith( haystack, needle ) {
-               return haystack.substr( 0, needle.length ) === needle;
-       }
-
-       protocolWhitelist = [
-               'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs',
-               'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh',
-               'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp'
-       ];
-
-       if ( url === '' ) {
-               return true;
-       }
-
-       for ( i = 0; i < protocolWhitelist.length; i++ ) {
-               if ( stringStartsWith( url, protocolWhitelist[ i ] + ':' ) ) {
-                       return true;
-               }
-       }
-
-       // This matches '//' too
-       if ( stringStartsWith( url, '/' ) || stringStartsWith( url, './' ) ) {
-               return true;
-       }
-       if ( stringStartsWith( url, '?' ) || stringStartsWith( url, '#' ) ) {
-               return true;
-       }
-
-       return false;
-};
-
-/**
- * Lazy-initialize and return a global OO.ui.WindowManager instance, used by OO.ui.alert and
- * OO.ui.confirm.
- *
- * @private
- * @return {OO.ui.WindowManager}
- */
-OO.ui.getWindowManager = function () {
-       if ( !OO.ui.windowManager ) {
-               OO.ui.windowManager = new OO.ui.WindowManager();
-               $( 'body' ).append( OO.ui.windowManager.$element );
-               OO.ui.windowManager.addWindows( {
-                       messageDialog: new OO.ui.MessageDialog()
-               } );
-       }
-       return OO.ui.windowManager;
-};
-
-/**
- * Display a quick modal alert dialog, using a OO.ui.MessageDialog. While the dialog is open, the
- * rest of the page will be dimmed out and the user won't be able to interact with it. The dialog
- * has only one action button, labelled "OK", clicking it will simply close the dialog.
- *
- * A window manager is created automatically when this function is called for the first time.
- *
- *     @example
- *     OO.ui.alert( 'Something happened!' ).done( function () {
- *         console.log( 'User closed the dialog.' );
- *     } );
- *
- * @param {jQuery|string} text Message text to display
- * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
- * @return {jQuery.Promise} Promise resolved when the user closes the dialog
- */
-OO.ui.alert = function ( text, options ) {
-       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
-               message: text,
-               verbose: true,
-               actions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]
-       }, options ) ).then( function ( opened ) {
-               return opened.then( function ( closing ) {
-                       return closing.then( function () {
-                               return $.Deferred().resolve();
-                       } );
-               } );
-       } );
-};
-
-/**
- * Display a quick modal confirmation dialog, using a OO.ui.MessageDialog. While the dialog is open,
- * the rest of the page will be dimmed out and the user won't be able to interact with it. The
- * dialog has two action buttons, one to confirm an operation (labelled "OK") and one to cancel it
- * (labelled "Cancel").
- *
- * A window manager is created automatically when this function is called for the first time.
- *
- *     @example
- *     OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {
- *         if ( confirmed ) {
- *             console.log( 'User clicked "OK"!' );
- *         } else {
- *             console.log( 'User clicked "Cancel" or closed the dialog.' );
- *         }
- *     } );
- *
- * @param {jQuery|string} text Message text to display
- * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
- * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to
- *  confirm, the promise will resolve to boolean `true`; otherwise, it will resolve to boolean
- *  `false`.
- */
-OO.ui.confirm = function ( text, options ) {
-       return OO.ui.getWindowManager().openWindow( 'messageDialog', $.extend( {
-               message: text,
-               verbose: true
-       }, options ) ).then( function ( opened ) {
-               return opened.then( function ( closing ) {
-                       return closing.then( function ( data ) {
-                               return $.Deferred().resolve( !!( data && data.action === 'accept' ) );
-                       } );
-               } );
-       } );
-};
-
-/*!
- * Mixin namespace.
- */
-
-/**
- * Namespace for OOjs UI mixins.
- *
- * Mixins are named according to the type of object they are intended to
- * be mixed in to.  For example, OO.ui.mixin.GroupElement is intended to be
- * mixed in to an instance of OO.ui.Element, and OO.ui.mixin.GroupWidget
- * is intended to be mixed in to an instance of OO.ui.Widget.
- *
- * @class
- * @singleton
- */
-OO.ui.mixin = {};
-
-/**
- * PendingElement is a mixin that is used to create elements that notify users that something is happening
- * and that they should wait before proceeding. The pending state is visually represented with a pending
- * texture that appears in the head of a pending {@link OO.ui.ProcessDialog process dialog} or in the input
- * field of a {@link OO.ui.TextInputWidget text input widget}.
- *
- * Currently, {@link OO.ui.ActionWidget Action widgets}, which mix in this class, can also be marked as pending, but only when
- * used in {@link OO.ui.MessageDialog message dialogs}. The behavior is not currently supported for action widgets used
- * in process dialogs.
- *
- *     @example
- *     function MessageDialog( config ) {
- *         MessageDialog.parent.call( this, config );
- *     }
- *     OO.inheritClass( MessageDialog, OO.ui.MessageDialog );
- *
- *     MessageDialog.static.actions = [
- *         { action: 'save', label: 'Done', flags: 'primary' },
- *         { label: 'Cancel', flags: 'safe' }
- *     ];
- *
- *     MessageDialog.prototype.initialize = function () {
- *         MessageDialog.parent.prototype.initialize.apply( this, arguments );
- *         this.content = new OO.ui.PanelLayout( { $: this.$, padded: true } );
- *         this.content.$element.append( '<p>Click the \'Done\' action widget to see its pending state. Note that action widgets can be marked pending in message dialogs but not process dialogs.</p>' );
- *         this.$body.append( this.content.$element );
- *     };
- *     MessageDialog.prototype.getBodyHeight = function () {
- *         return 100;
- *     }
- *     MessageDialog.prototype.getActionProcess = function ( action ) {
- *         var dialog = this;
- *         if ( action === 'save' ) {
- *             dialog.getActions().get({actions: 'save'})[0].pushPending();
- *             return new OO.ui.Process()
- *             .next( 1000 )
- *             .next( function () {
- *                 dialog.getActions().get({actions: 'save'})[0].popPending();
- *             } );
- *         }
- *         return MessageDialog.parent.prototype.getActionProcess.call( this, action );
- *     };
- *
- *     var windowManager = new OO.ui.WindowManager();
- *     $( 'body' ).append( windowManager.$element );
- *
- *     var dialog = new MessageDialog();
- *     windowManager.addWindows( [ dialog ] );
- *     windowManager.openWindow( dialog );
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$pending] Element to mark as pending, defaults to this.$element
- */
-OO.ui.mixin.PendingElement = function OoUiMixinPendingElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.pending = 0;
-       this.$pending = null;
-
-       // Initialisation
-       this.setPendingElement( config.$pending || this.$element );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.PendingElement );
-
-/* Methods */
-
-/**
- * Set the pending element (and clean up any existing one).
- *
- * @param {jQuery} $pending The element to set to pending.
- */
-OO.ui.mixin.PendingElement.prototype.setPendingElement = function ( $pending ) {
-       if ( this.$pending ) {
-               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
-       }
-
-       this.$pending = $pending;
-       if ( this.pending > 0 ) {
-               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
-       }
-};
-
-/**
- * Check if an element is pending.
- *
- * @return {boolean} Element is pending
- */
-OO.ui.mixin.PendingElement.prototype.isPending = function () {
-       return !!this.pending;
-};
-
-/**
- * Increase the pending counter. The pending state will remain active until the counter is zero
- * (i.e., the number of calls to #pushPending and #popPending is the same).
- *
- * @chainable
- */
-OO.ui.mixin.PendingElement.prototype.pushPending = function () {
-       if ( this.pending === 0 ) {
-               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
-               this.updateThemeClasses();
-       }
-       this.pending++;
-
-       return this;
-};
-
-/**
- * Decrease the pending counter. The pending state will remain active until the counter is zero
- * (i.e., the number of calls to #pushPending and #popPending is the same).
- *
- * @chainable
- */
-OO.ui.mixin.PendingElement.prototype.popPending = function () {
-       if ( this.pending === 1 ) {
-               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
-               this.updateThemeClasses();
-       }
-       this.pending = Math.max( 0, this.pending - 1 );
-
-       return this;
-};
-
-/**
- * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them.
- * Actions can be made available for specific contexts (modes) and circumstances
- * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}.
- *
- * ActionSets contain two types of actions:
- *
- * - Special: Special actions are the first visible actions with special flags, such as 'safe' and 'primary', the default special flags. Additional special flags can be configured in subclasses with the static #specialFlags property.
- * - Other: Other actions include all non-special visible actions.
- *
- * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
- *
- *     @example
- *     // Example: An action set used in a process dialog
- *     function MyProcessDialog( config ) {
- *         MyProcessDialog.parent.call( this, config );
- *     }
- *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );
- *     MyProcessDialog.static.title = 'An action set in a process dialog';
- *     // An action set that uses modes ('edit' and 'help' mode, in this example).
- *     MyProcessDialog.static.actions = [
- *         { action: 'continue', modes: 'edit', label: 'Continue', flags: [ 'primary', 'constructive' ] },
- *         { action: 'help', modes: 'edit', label: 'Help' },
- *         { modes: 'edit', label: 'Cancel', flags: 'safe' },
- *         { action: 'back', modes: 'help', label: 'Back', flags: 'safe' }
- *     ];
- *
- *     MyProcessDialog.prototype.initialize = function () {
- *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
- *         this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.panel1.$element.append( '<p>This dialog uses an action set (continue, help, cancel, back) configured with modes. This is edit mode. Click \'help\' to see help mode.</p>' );
- *         this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.panel2.$element.append( '<p>This is help mode. Only the \'back\' action widget is configured to be visible here. Click \'back\' to return to \'edit\' mode.</p>' );
- *         this.stackLayout = new OO.ui.StackLayout( {
- *             items: [ this.panel1, this.panel2 ]
- *         } );
- *         this.$body.append( this.stackLayout.$element );
- *     };
- *     MyProcessDialog.prototype.getSetupProcess = function ( data ) {
- *         return MyProcessDialog.parent.prototype.getSetupProcess.call( this, data )
- *             .next( function () {
- *                 this.actions.setMode( 'edit' );
- *             }, this );
- *     };
- *     MyProcessDialog.prototype.getActionProcess = function ( action ) {
- *         if ( action === 'help' ) {
- *             this.actions.setMode( 'help' );
- *             this.stackLayout.setItem( this.panel2 );
- *         } else if ( action === 'back' ) {
- *             this.actions.setMode( 'edit' );
- *             this.stackLayout.setItem( this.panel1 );
- *         } else if ( action === 'continue' ) {
- *             var dialog = this;
- *             return new OO.ui.Process( function () {
- *                 dialog.close();
- *             } );
- *         }
- *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );
- *     };
- *     MyProcessDialog.prototype.getBodyHeight = function () {
- *         return this.panel1.$element.outerHeight( true );
- *     };
- *     var windowManager = new OO.ui.WindowManager();
- *     $( 'body' ).append( windowManager.$element );
- *     var dialog = new MyProcessDialog( {
- *         size: 'medium'
- *     } );
- *     windowManager.addWindows( [ dialog ] );
- *     windowManager.openWindow( dialog );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
- *
- * @abstract
- * @class
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.ActionSet = function OoUiActionSet( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-
-       // Properties
-       this.list = [];
-       this.categories = {
-               actions: 'getAction',
-               flags: 'getFlags',
-               modes: 'getModes'
-       };
-       this.categorized = {};
-       this.special = {};
-       this.others = [];
-       this.organized = false;
-       this.changing = false;
-       this.changed = false;
-};
-
-/* Setup */
-
-OO.mixinClass( OO.ui.ActionSet, OO.EventEmitter );
-
-/* Static Properties */
-
-/**
- * Symbolic name of the flags used to identify special actions. Special actions are displayed in the
- *  header of a {@link OO.ui.ProcessDialog process dialog}.
- *  See the [OOjs UI documentation on MediaWiki][2] for more information and examples.
- *
- *  [2]:https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs
- *
- * @abstract
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ];
-
-/* Events */
-
-/**
- * @event click
- *
- * A 'click' event is emitted when an action is clicked.
- *
- * @param {OO.ui.ActionWidget} action Action that was clicked
- */
-
-/**
- * @event resize
- *
- * A 'resize' event is emitted when an action widget is resized.
- *
- * @param {OO.ui.ActionWidget} action Action that was resized
- */
-
-/**
- * @event add
- *
- * An 'add' event is emitted when actions are {@link #method-add added} to the action set.
- *
- * @param {OO.ui.ActionWidget[]} added Actions added
- */
-
-/**
- * @event remove
- *
- * A 'remove' event is emitted when actions are {@link #method-remove removed}
- *  or {@link #clear cleared}.
- *
- * @param {OO.ui.ActionWidget[]} added Actions removed
- */
-
-/**
- * @event change
- *
- * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared},
- * or {@link #method-remove removed} from the action set or when the {@link #setMode mode} is changed.
- *
- */
-
-/* Methods */
-
-/**
- * Handle action change events.
- *
- * @private
- * @fires change
- */
-OO.ui.ActionSet.prototype.onActionChange = function () {
-       this.organized = false;
-       if ( this.changing ) {
-               this.changed = true;
-       } else {
-               this.emit( 'change' );
-       }
-};
-
-/**
- * Check if an action is one of the special actions.
- *
- * @param {OO.ui.ActionWidget} action Action to check
- * @return {boolean} Action is special
- */
-OO.ui.ActionSet.prototype.isSpecial = function ( action ) {
-       var flag;
-
-       for ( flag in this.special ) {
-               if ( action === this.special[ flag ] ) {
-                       return true;
-               }
-       }
-
-       return false;
-};
-
-/**
- * Get action widgets based on the specified filter: ‘actions’, ‘flags’, ‘modes’, ‘visible’,
- *  or ‘disabled’.
- *
- * @param {Object} [filters] Filters to use, omit to get all actions
- * @param {string|string[]} [filters.actions] Actions that action widgets must have
- * @param {string|string[]} [filters.flags] Flags that action widgets must have (e.g., 'safe')
- * @param {string|string[]} [filters.modes] Modes that action widgets must have
- * @param {boolean} [filters.visible] Action widgets must be visible
- * @param {boolean} [filters.disabled] Action widgets must be disabled
- * @return {OO.ui.ActionWidget[]} Action widgets matching all criteria
- */
-OO.ui.ActionSet.prototype.get = function ( filters ) {
-       var i, len, list, category, actions, index, match, matches;
-
-       if ( filters ) {
-               this.organize();
-
-               // Collect category candidates
-               matches = [];
-               for ( category in this.categorized ) {
-                       list = filters[ category ];
-                       if ( list ) {
-                               if ( !Array.isArray( list ) ) {
-                                       list = [ list ];
-                               }
-                               for ( i = 0, len = list.length; i < len; i++ ) {
-                                       actions = this.categorized[ category ][ list[ i ] ];
-                                       if ( Array.isArray( actions ) ) {
-                                               matches.push.apply( matches, actions );
-                                       }
-                               }
-                       }
-               }
-               // Remove by boolean filters
-               for ( i = 0, len = matches.length; i < len; i++ ) {
-                       match = matches[ i ];
-                       if (
-                               ( filters.visible !== undefined && match.isVisible() !== filters.visible ) ||
-                               ( filters.disabled !== undefined && match.isDisabled() !== filters.disabled )
-                       ) {
-                               matches.splice( i, 1 );
-                               len--;
-                               i--;
-                       }
-               }
-               // Remove duplicates
-               for ( i = 0, len = matches.length; i < len; i++ ) {
-                       match = matches[ i ];
-                       index = matches.lastIndexOf( match );
-                       while ( index !== i ) {
-                               matches.splice( index, 1 );
-                               len--;
-                               index = matches.lastIndexOf( match );
-                       }
-               }
-               return matches;
-       }
-       return this.list.slice();
-};
-
-/**
- * Get 'special' actions.
- *
- * Special actions are the first visible action widgets with special flags, such as 'safe' and 'primary'.
- * Special flags can be configured in subclasses by changing the static #specialFlags property.
- *
- * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets.
- */
-OO.ui.ActionSet.prototype.getSpecial = function () {
-       this.organize();
-       return $.extend( {}, this.special );
-};
-
-/**
- * Get 'other' actions.
- *
- * Other actions include all non-special visible action widgets.
- *
- * @return {OO.ui.ActionWidget[]} 'Other' action widgets
- */
-OO.ui.ActionSet.prototype.getOthers = function () {
-       this.organize();
-       return this.others.slice();
-};
-
-/**
- * Set the mode  (e.g., ‘edit’ or ‘view’). Only {@link OO.ui.ActionWidget#modes actions} configured
- * to be available in the specified mode will be made visible. All other actions will be hidden.
- *
- * @param {string} mode The mode. Only actions configured to be available in the specified
- *  mode will be made visible.
- * @chainable
- * @fires toggle
- * @fires change
- */
-OO.ui.ActionSet.prototype.setMode = function ( mode ) {
-       var i, len, action;
-
-       this.changing = true;
-       for ( i = 0, len = this.list.length; i < len; i++ ) {
-               action = this.list[ i ];
-               action.toggle( action.hasMode( mode ) );
-       }
-
-       this.organized = false;
-       this.changing = false;
-       this.emit( 'change' );
-
-       return this;
-};
-
-/**
- * Set the abilities of the specified actions.
- *
- * Action widgets that are configured with the specified actions will be enabled
- * or disabled based on the boolean values specified in the `actions`
- * parameter.
- *
- * @param {Object.<string,boolean>} actions A list keyed by action name with boolean
- *  values that indicate whether or not the action should be enabled.
- * @chainable
- */
-OO.ui.ActionSet.prototype.setAbilities = function ( actions ) {
-       var i, len, action, item;
-
-       for ( i = 0, len = this.list.length; i < len; i++ ) {
-               item = this.list[ i ];
-               action = item.getAction();
-               if ( actions[ action ] !== undefined ) {
-                       item.setDisabled( !actions[ action ] );
-               }
-       }
-
-       return this;
-};
-
-/**
- * Executes a function once per action.
- *
- * When making changes to multiple actions, use this method instead of iterating over the actions
- * manually to defer emitting a #change event until after all actions have been changed.
- *
- * @param {Object|null} actions Filters to use to determine which actions to iterate over; see #get
- * @param {Function} callback Callback to run for each action; callback is invoked with three
- *   arguments: the action, the action's index, the list of actions being iterated over
- * @chainable
- */
-OO.ui.ActionSet.prototype.forEach = function ( filter, callback ) {
-       this.changed = false;
-       this.changing = true;
-       this.get( filter ).forEach( callback );
-       this.changing = false;
-       if ( this.changed ) {
-               this.emit( 'change' );
-       }
-
-       return this;
-};
-
-/**
- * Add action widgets to the action set.
- *
- * @param {OO.ui.ActionWidget[]} actions Action widgets to add
- * @chainable
- * @fires add
- * @fires change
- */
-OO.ui.ActionSet.prototype.add = function ( actions ) {
-       var i, len, action;
-
-       this.changing = true;
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               action = actions[ i ];
-               action.connect( this, {
-                       click: [ 'emit', 'click', action ],
-                       resize: [ 'emit', 'resize', action ],
-                       toggle: [ 'onActionChange' ]
-               } );
-               this.list.push( action );
-       }
-       this.organized = false;
-       this.emit( 'add', actions );
-       this.changing = false;
-       this.emit( 'change' );
-
-       return this;
-};
-
-/**
- * Remove action widgets from the set.
- *
- * To remove all actions, you may wish to use the #clear method instead.
- *
- * @param {OO.ui.ActionWidget[]} actions Action widgets to remove
- * @chainable
- * @fires remove
- * @fires change
- */
-OO.ui.ActionSet.prototype.remove = function ( actions ) {
-       var i, len, index, action;
-
-       this.changing = true;
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               action = actions[ i ];
-               index = this.list.indexOf( action );
-               if ( index !== -1 ) {
-                       action.disconnect( this );
-                       this.list.splice( index, 1 );
-               }
-       }
-       this.organized = false;
-       this.emit( 'remove', actions );
-       this.changing = false;
-       this.emit( 'change' );
-
-       return this;
-};
-
-/**
- * Remove all action widets from the set.
- *
- * To remove only specified actions, use the {@link #method-remove remove} method instead.
- *
- * @chainable
- * @fires remove
- * @fires change
- */
-OO.ui.ActionSet.prototype.clear = function () {
-       var i, len, action,
-               removed = this.list.slice();
-
-       this.changing = true;
-       for ( i = 0, len = this.list.length; i < len; i++ ) {
-               action = this.list[ i ];
-               action.disconnect( this );
-       }
-
-       this.list = [];
-
-       this.organized = false;
-       this.emit( 'remove', removed );
-       this.changing = false;
-       this.emit( 'change' );
-
-       return this;
-};
-
-/**
- * Organize actions.
- *
- * This is called whenever organized information is requested. It will only reorganize the actions
- * if something has changed since the last time it ran.
- *
- * @private
- * @chainable
- */
-OO.ui.ActionSet.prototype.organize = function () {
-       var i, iLen, j, jLen, flag, action, category, list, item, special,
-               specialFlags = this.constructor.static.specialFlags;
-
-       if ( !this.organized ) {
-               this.categorized = {};
-               this.special = {};
-               this.others = [];
-               for ( i = 0, iLen = this.list.length; i < iLen; i++ ) {
-                       action = this.list[ i ];
-                       if ( action.isVisible() ) {
-                               // Populate categories
-                               for ( category in this.categories ) {
-                                       if ( !this.categorized[ category ] ) {
-                                               this.categorized[ category ] = {};
-                                       }
-                                       list = action[ this.categories[ category ] ]();
-                                       if ( !Array.isArray( list ) ) {
-                                               list = [ list ];
-                                       }
-                                       for ( j = 0, jLen = list.length; j < jLen; j++ ) {
-                                               item = list[ j ];
-                                               if ( !this.categorized[ category ][ item ] ) {
-                                                       this.categorized[ category ][ item ] = [];
-                                               }
-                                               this.categorized[ category ][ item ].push( action );
-                                       }
-                               }
-                               // Populate special/others
-                               special = false;
-                               for ( j = 0, jLen = specialFlags.length; j < jLen; j++ ) {
-                                       flag = specialFlags[ j ];
-                                       if ( !this.special[ flag ] && action.hasFlag( flag ) ) {
-                                               this.special[ flag ] = action;
-                                               special = true;
-                                               break;
-                                       }
-                               }
-                               if ( !special ) {
-                                       this.others.push( action );
-                               }
-                       }
-               }
-               this.organized = true;
-       }
-
-       return this;
-};
-
-/**
- * Each Element represents a rendering in the DOM—a button or an icon, for example, or anything
- * that is visible to a user. Unlike {@link OO.ui.Widget widgets}, plain elements usually do not have events
- * connected to them and can't be interacted with.
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string[]} [classes] The names of the CSS classes to apply to the element. CSS styles are added
- *  to the top level (e.g., the outermost div) of the element. See the [OOjs UI documentation on MediaWiki][2]
- *  for an example.
- *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#cssExample
- * @cfg {string} [id] The HTML id attribute used in the rendered tag.
- * @cfg {string} [text] Text to insert
- * @cfg {Array} [content] An array of content elements to append (after #text).
- *  Strings will be html-escaped; use an OO.ui.HtmlSnippet to append raw HTML.
- *  Instances of OO.ui.Element will have their $element appended.
- * @cfg {jQuery} [$content] Content elements to append (after #text).
- * @cfg {jQuery} [$element] Wrapper element. Defaults to a new element with #getTagName.
- * @cfg {Mixed} [data] Custom data of any type or combination of types (e.g., string, number, array, object).
- *  Data can also be specified with the #setData method.
- */
-OO.ui.Element = function OoUiElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$ = $;
-       this.visible = true;
-       this.data = config.data;
-       this.$element = config.$element ||
-               $( document.createElement( this.getTagName() ) );
-       this.elementGroup = null;
-       this.debouncedUpdateThemeClassesHandler = OO.ui.debounce( this.debouncedUpdateThemeClasses );
-
-       // Initialization
-       if ( Array.isArray( config.classes ) ) {
-               this.$element.addClass( config.classes.join( ' ' ) );
-       }
-       if ( config.id ) {
-               this.$element.attr( 'id', config.id );
-       }
-       if ( config.text ) {
-               this.$element.text( config.text );
-       }
-       if ( config.content ) {
-               // The `content` property treats plain strings as text; use an
-               // HtmlSnippet to append HTML content.  `OO.ui.Element`s get their
-               // appropriate $element appended.
-               this.$element.append( config.content.map( function ( v ) {
-                       if ( typeof v === 'string' ) {
-                               // Escape string so it is properly represented in HTML.
-                               return document.createTextNode( v );
-                       } else if ( v instanceof OO.ui.HtmlSnippet ) {
-                               // Bypass escaping.
-                               return v.toString();
-                       } else if ( v instanceof OO.ui.Element ) {
-                               return v.$element;
-                       }
-                       return v;
-               } ) );
-       }
-       if ( config.$content ) {
-               // The `$content` property treats plain strings as HTML.
-               this.$element.append( config.$content );
-       }
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.Element );
-
-/* Static Properties */
-
-/**
- * The name of the HTML tag used by the element.
- *
- * The static value may be ignored if the #getTagName method is overridden.
- *
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.Element.static.tagName = 'div';
-
-/* Static Methods */
-
-/**
- * Reconstitute a JavaScript object corresponding to a widget created
- * by the PHP implementation.
- *
- * @param {string|HTMLElement|jQuery} idOrNode
- *   A DOM id (if a string) or node for the widget to infuse.
- * @return {OO.ui.Element}
- *   The `OO.ui.Element` corresponding to this (infusable) document node.
- *   For `Tag` objects emitted on the HTML side (used occasionally for content)
- *   the value returned is a newly-created Element wrapping around the existing
- *   DOM node.
- */
-OO.ui.Element.static.infuse = function ( idOrNode ) {
-       var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, false );
-       // Verify that the type matches up.
-       // FIXME: uncomment after T89721 is fixed (see T90929)
-       /*
-       if ( !( obj instanceof this['class'] ) ) {
-               throw new Error( 'Infusion type mismatch!' );
-       }
-       */
-       return obj;
-};
-
-/**
- * Implementation helper for `infuse`; skips the type check and has an
- * extra property so that only the top-level invocation touches the DOM.
- * @private
- * @param {string|HTMLElement|jQuery} idOrNode
- * @param {jQuery.Promise|boolean} domPromise A promise that will be resolved
- *     when the top-level widget of this infusion is inserted into DOM,
- *     replacing the original node; or false for top-level invocation.
- * @return {OO.ui.Element}
- */
-OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
-       // look for a cached result of a previous infusion.
-       var id, $elem, data, cls, parts, parent, obj, top, state;
-       if ( typeof idOrNode === 'string' ) {
-               id = idOrNode;
-               $elem = $( document.getElementById( id ) );
-       } else {
-               $elem = $( idOrNode );
-               id = $elem.attr( 'id' );
-       }
-       if ( !$elem.length ) {
-               throw new Error( 'Widget not found: ' + id );
-       }
-       data = $elem.data( 'ooui-infused' ) || $elem[ 0 ].oouiInfused;
-       if ( data ) {
-               // cached!
-               if ( data === true ) {
-                       throw new Error( 'Circular dependency! ' + id );
-               }
-               return data;
-       }
-       data = $elem.attr( 'data-ooui' );
-       if ( !data ) {
-               throw new Error( 'No infusion data found: ' + id );
-       }
-       try {
-               data = $.parseJSON( data );
-       } catch ( _ ) {
-               data = null;
-       }
-       if ( !( data && data._ ) ) {
-               throw new Error( 'No valid infusion data found: ' + id );
-       }
-       if ( data._ === 'Tag' ) {
-               // Special case: this is a raw Tag; wrap existing node, don't rebuild.
-               return new OO.ui.Element( { $element: $elem } );
-       }
-       parts = data._.split( '.' );
-       cls = OO.getProp.apply( OO, [ window ].concat( parts ) );
-       if ( cls === undefined ) {
-               // The PHP output might be old and not including the "OO.ui" prefix
-               // TODO: Remove this back-compat after next major release
-               cls = OO.getProp.apply( OO, [ OO.ui ].concat( parts ) );
-               if ( cls === undefined ) {
-                       throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );
-               }
-       }
-
-       // Verify that we're creating an OO.ui.Element instance
-       parent = cls.parent;
-
-       while ( parent !== undefined ) {
-               if ( parent === OO.ui.Element ) {
-                       // Safe
-                       break;
-               }
-
-               parent = parent.parent;
-       }
-
-       if ( parent !== OO.ui.Element ) {
-               throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );
-       }
-
-       if ( domPromise === false ) {
-               top = $.Deferred();
-               domPromise = top.promise();
-       }
-       $elem.data( 'ooui-infused', true ); // prevent loops
-       data.id = id; // implicit
-       data = OO.copy( data, null, function deserialize( value ) {
-               if ( OO.isPlainObject( value ) ) {
-                       if ( value.tag ) {
-                               return OO.ui.Element.static.unsafeInfuse( value.tag, domPromise );
-                       }
-                       if ( value.html ) {
-                               return new OO.ui.HtmlSnippet( value.html );
-                       }
-               }
-       } );
-       // allow widgets to reuse parts of the DOM
-       data = cls.static.reusePreInfuseDOM( $elem[ 0 ], data );
-       // pick up dynamic state, like focus, value of form inputs, scroll position, etc.
-       state = cls.static.gatherPreInfuseState( $elem[ 0 ], data );
-       // rebuild widget
-       // jscs:disable requireCapitalizedConstructors
-       obj = new cls( data );
-       // jscs:enable requireCapitalizedConstructors
-       // now replace old DOM with this new DOM.
-       if ( top ) {
-               // An efficient constructor might be able to reuse the entire DOM tree of the original element,
-               // so only mutate the DOM if we need to.
-               if ( $elem[ 0 ] !== obj.$element[ 0 ] ) {
-                       $elem.replaceWith( obj.$element );
-                       // This element is now gone from the DOM, but if anyone is holding a reference to it,
-                       // let's allow them to OO.ui.infuse() it and do what they expect (T105828).
-                       // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design.
-                       $elem[ 0 ].oouiInfused = obj;
-               }
-               top.resolve();
-       }
-       obj.$element.data( 'ooui-infused', obj );
-       // set the 'data-ooui' attribute so we can identify infused widgets
-       obj.$element.attr( 'data-ooui', '' );
-       // restore dynamic state after the new element is inserted into DOM
-       domPromise.done( obj.restorePreInfuseState.bind( obj, state ) );
-       return obj;
-};
-
-/**
- * Pick out parts of `node`'s DOM to be reused when infusing a widget.
- *
- * This method **must not** make any changes to the DOM, only find interesting pieces and add them
- * to `config` (which should then be returned). Actual DOM juggling should then be done by the
- * constructor, which will be given the enhanced config.
- *
- * @protected
- * @param {HTMLElement} node
- * @param {Object} config
- * @return {Object}
- */
-OO.ui.Element.static.reusePreInfuseDOM = function ( node, config ) {
-       return config;
-};
-
-/**
- * Gather the dynamic state (focus, value of form inputs, scroll position, etc.) of a HTML DOM node
- * (and its children) that represent an Element of the same class and the given configuration,
- * generated by the PHP implementation.
- *
- * This method is called just before `node` is detached from the DOM. The return value of this
- * function will be passed to #restorePreInfuseState after the newly created widget's #$element
- * is inserted into DOM to replace `node`.
- *
- * @protected
- * @param {HTMLElement} node
- * @param {Object} config
- * @return {Object}
- */
-OO.ui.Element.static.gatherPreInfuseState = function () {
-       return {};
-};
-
-/**
- * Get a jQuery function within a specific document.
- *
- * @static
- * @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to
- * @param {jQuery} [$iframe] HTML iframe element that contains the document, omit if document is
- *   not in an iframe
- * @return {Function} Bound jQuery function
- */
-OO.ui.Element.static.getJQuery = function ( context, $iframe ) {
-       function wrapper( selector ) {
-               return $( selector, wrapper.context );
-       }
-
-       wrapper.context = this.getDocument( context );
-
-       if ( $iframe ) {
-               wrapper.$iframe = $iframe;
-       }
-
-       return wrapper;
-};
-
-/**
- * Get the document of an element.
- *
- * @static
- * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for
- * @return {HTMLDocument|null} Document object
- */
-OO.ui.Element.static.getDocument = function ( obj ) {
-       // jQuery - selections created "offscreen" won't have a context, so .context isn't reliable
-       return ( obj[ 0 ] && obj[ 0 ].ownerDocument ) ||
-               // Empty jQuery selections might have a context
-               obj.context ||
-               // HTMLElement
-               obj.ownerDocument ||
-               // Window
-               obj.document ||
-               // HTMLDocument
-               ( obj.nodeType === 9 && obj ) ||
-               null;
-};
-
-/**
- * Get the window of an element or document.
- *
- * @static
- * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for
- * @return {Window} Window object
- */
-OO.ui.Element.static.getWindow = function ( obj ) {
-       var doc = this.getDocument( obj );
-       return doc.defaultView;
-};
-
-/**
- * Get the direction of an element or document.
- *
- * @static
- * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for
- * @return {string} Text direction, either 'ltr' or 'rtl'
- */
-OO.ui.Element.static.getDir = function ( obj ) {
-       var isDoc, isWin;
-
-       if ( obj instanceof jQuery ) {
-               obj = obj[ 0 ];
-       }
-       isDoc = obj.nodeType === 9;
-       isWin = obj.document !== undefined;
-       if ( isDoc || isWin ) {
-               if ( isWin ) {
-                       obj = obj.document;
-               }
-               obj = obj.body;
-       }
-       return $( obj ).css( 'direction' );
-};
-
-/**
- * Get the offset between two frames.
- *
- * TODO: Make this function not use recursion.
- *
- * @static
- * @param {Window} from Window of the child frame
- * @param {Window} [to=window] Window of the parent frame
- * @param {Object} [offset] Offset to start with, used internally
- * @return {Object} Offset object, containing left and top properties
- */
-OO.ui.Element.static.getFrameOffset = function ( from, to, offset ) {
-       var i, len, frames, frame, rect;
-
-       if ( !to ) {
-               to = window;
-       }
-       if ( !offset ) {
-               offset = { top: 0, left: 0 };
-       }
-       if ( from.parent === from ) {
-               return offset;
-       }
-
-       // Get iframe element
-       frames = from.parent.document.getElementsByTagName( 'iframe' );
-       for ( i = 0, len = frames.length; i < len; i++ ) {
-               if ( frames[ i ].contentWindow === from ) {
-                       frame = frames[ i ];
-                       break;
-               }
-       }
-
-       // Recursively accumulate offset values
-       if ( frame ) {
-               rect = frame.getBoundingClientRect();
-               offset.left += rect.left;
-               offset.top += rect.top;
-               if ( from !== to ) {
-                       this.getFrameOffset( from.parent, offset );
-               }
-       }
-       return offset;
-};
-
-/**
- * Get the offset between two elements.
- *
- * The two elements may be in a different frame, but in that case the frame $element is in must
- * be contained in the frame $anchor is in.
- *
- * @static
- * @param {jQuery} $element Element whose position to get
- * @param {jQuery} $anchor Element to get $element's position relative to
- * @return {Object} Translated position coordinates, containing top and left properties
- */
-OO.ui.Element.static.getRelativePosition = function ( $element, $anchor ) {
-       var iframe, iframePos,
-               pos = $element.offset(),
-               anchorPos = $anchor.offset(),
-               elementDocument = this.getDocument( $element ),
-               anchorDocument = this.getDocument( $anchor );
-
-       // If $element isn't in the same document as $anchor, traverse up
-       while ( elementDocument !== anchorDocument ) {
-               iframe = elementDocument.defaultView.frameElement;
-               if ( !iframe ) {
-                       throw new Error( '$element frame is not contained in $anchor frame' );
-               }
-               iframePos = $( iframe ).offset();
-               pos.left += iframePos.left;
-               pos.top += iframePos.top;
-               elementDocument = iframe.ownerDocument;
-       }
-       pos.left -= anchorPos.left;
-       pos.top -= anchorPos.top;
-       return pos;
-};
-
-/**
- * Get element border sizes.
- *
- * @static
- * @param {HTMLElement} el Element to measure
- * @return {Object} Dimensions object with `top`, `left`, `bottom` and `right` properties
- */
-OO.ui.Element.static.getBorders = function ( el ) {
-       var doc = el.ownerDocument,
-               win = doc.defaultView,
-               style = win.getComputedStyle( el, null ),
-               $el = $( el ),
-               top = parseFloat( style ? style.borderTopWidth : $el.css( 'borderTopWidth' ) ) || 0,
-               left = parseFloat( style ? style.borderLeftWidth : $el.css( 'borderLeftWidth' ) ) || 0,
-               bottom = parseFloat( style ? style.borderBottomWidth : $el.css( 'borderBottomWidth' ) ) || 0,
-               right = parseFloat( style ? style.borderRightWidth : $el.css( 'borderRightWidth' ) ) || 0;
-
-       return {
-               top: top,
-               left: left,
-               bottom: bottom,
-               right: right
-       };
-};
-
-/**
- * Get dimensions of an element or window.
- *
- * @static
- * @param {HTMLElement|Window} el Element to measure
- * @return {Object} Dimensions object with `borders`, `scroll`, `scrollbar` and `rect` properties
- */
-OO.ui.Element.static.getDimensions = function ( el ) {
-       var $el, $win,
-               doc = el.ownerDocument || el.document,
-               win = doc.defaultView;
-
-       if ( win === el || el === doc.documentElement ) {
-               $win = $( win );
-               return {
-                       borders: { top: 0, left: 0, bottom: 0, right: 0 },
-                       scroll: {
-                               top: $win.scrollTop(),
-                               left: $win.scrollLeft()
-                       },
-                       scrollbar: { right: 0, bottom: 0 },
-                       rect: {
-                               top: 0,
-                               left: 0,
-                               bottom: $win.innerHeight(),
-                               right: $win.innerWidth()
-                       }
-               };
-       } else {
-               $el = $( el );
-               return {
-                       borders: this.getBorders( el ),
-                       scroll: {
-                               top: $el.scrollTop(),
-                               left: $el.scrollLeft()
-                       },
-                       scrollbar: {
-                               right: $el.innerWidth() - el.clientWidth,
-                               bottom: $el.innerHeight() - el.clientHeight
-                       },
-                       rect: el.getBoundingClientRect()
-               };
-       }
-};
-
-/**
- * Get scrollable object parent
- *
- * documentElement can't be used to get or set the scrollTop
- * property on Blink. Changing and testing its value lets us
- * use 'body' or 'documentElement' based on what is working.
- *
- * https://code.google.com/p/chromium/issues/detail?id=303131
- *
- * @static
- * @param {HTMLElement} el Element to find scrollable parent for
- * @return {HTMLElement} Scrollable parent
- */
-OO.ui.Element.static.getRootScrollableElement = function ( el ) {
-       var scrollTop, body;
-
-       if ( OO.ui.scrollableElement === undefined ) {
-               body = el.ownerDocument.body;
-               scrollTop = body.scrollTop;
-               body.scrollTop = 1;
-
-               if ( body.scrollTop === 1 ) {
-                       body.scrollTop = scrollTop;
-                       OO.ui.scrollableElement = 'body';
-               } else {
-                       OO.ui.scrollableElement = 'documentElement';
-               }
-       }
-
-       return el.ownerDocument[ OO.ui.scrollableElement ];
-};
-
-/**
- * Get closest scrollable container.
- *
- * Traverses up until either a scrollable element or the root is reached, in which case the window
- * will be returned.
- *
- * @static
- * @param {HTMLElement} el Element to find scrollable container for
- * @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either
- * @return {HTMLElement} Closest scrollable container
- */
-OO.ui.Element.static.getClosestScrollableContainer = function ( el, dimension ) {
-       var i, val,
-               // props = [ 'overflow' ] doesn't work due to https://bugzilla.mozilla.org/show_bug.cgi?id=889091
-               props = [ 'overflow-x', 'overflow-y' ],
-               $parent = $( el ).parent();
-
-       if ( dimension === 'x' || dimension === 'y' ) {
-               props = [ 'overflow-' + dimension ];
-       }
-
-       while ( $parent.length ) {
-               if ( $parent[ 0 ] === this.getRootScrollableElement( el ) ) {
-                       return $parent[ 0 ];
-               }
-               i = props.length;
-               while ( i-- ) {
-                       val = $parent.css( props[ i ] );
-                       if ( val === 'auto' || val === 'scroll' ) {
-                               return $parent[ 0 ];
-                       }
-               }
-               $parent = $parent.parent();
-       }
-       return this.getDocument( el ).body;
-};
-
-/**
- * Scroll element into view.
- *
- * @static
- * @param {HTMLElement} el Element to scroll into view
- * @param {Object} [config] Configuration options
- * @param {string} [config.duration] jQuery animation duration value
- * @param {string} [config.direction] Scroll in only one direction, e.g. 'x' or 'y', omit
- *  to scroll in both directions
- * @param {Function} [config.complete] Function to call when scrolling completes
- */
-OO.ui.Element.static.scrollIntoView = function ( el, config ) {
-       var rel, anim, callback, sc, $sc, eld, scd, $win;
-
-       // Configuration initialization
-       config = config || {};
-
-       anim = {};
-       callback = typeof config.complete === 'function' && config.complete;
-       sc = this.getClosestScrollableContainer( el, config.direction );
-       $sc = $( sc );
-       eld = this.getDimensions( el );
-       scd = this.getDimensions( sc );
-       $win = $( this.getWindow( el ) );
-
-       // Compute the distances between the edges of el and the edges of the scroll viewport
-       if ( $sc.is( 'html, body' ) ) {
-               // If the scrollable container is the root, this is easy
-               rel = {
-                       top: eld.rect.top,
-                       bottom: $win.innerHeight() - eld.rect.bottom,
-                       left: eld.rect.left,
-                       right: $win.innerWidth() - eld.rect.right
-               };
-       } else {
-               // Otherwise, we have to subtract el's coordinates from sc's coordinates
-               rel = {
-                       top: eld.rect.top - ( scd.rect.top + scd.borders.top ),
-                       bottom: scd.rect.bottom - scd.borders.bottom - scd.scrollbar.bottom - eld.rect.bottom,
-                       left: eld.rect.left - ( scd.rect.left + scd.borders.left ),
-                       right: scd.rect.right - scd.borders.right - scd.scrollbar.right - eld.rect.right
-               };
-       }
-
-       if ( !config.direction || config.direction === 'y' ) {
-               if ( rel.top < 0 ) {
-                       anim.scrollTop = scd.scroll.top + rel.top;
-               } else if ( rel.top > 0 && rel.bottom < 0 ) {
-                       anim.scrollTop = scd.scroll.top + Math.min( rel.top, -rel.bottom );
-               }
-       }
-       if ( !config.direction || config.direction === 'x' ) {
-               if ( rel.left < 0 ) {
-                       anim.scrollLeft = scd.scroll.left + rel.left;
-               } else if ( rel.left > 0 && rel.right < 0 ) {
-                       anim.scrollLeft = scd.scroll.left + Math.min( rel.left, -rel.right );
-               }
-       }
-       if ( !$.isEmptyObject( anim ) ) {
-               $sc.stop( true ).animate( anim, config.duration || 'fast' );
-               if ( callback ) {
-                       $sc.queue( function ( next ) {
-                               callback();
-                               next();
-                       } );
-               }
-       } else {
-               if ( callback ) {
-                       callback();
-               }
-       }
-};
-
-/**
- * Force the browser to reconsider whether it really needs to render scrollbars inside the element
- * and reserve space for them, because it probably doesn't.
- *
- * Workaround primarily for <https://code.google.com/p/chromium/issues/detail?id=387290>, but also
- * similar bugs in other browsers. "Just" forcing a reflow is not sufficient in all cases, we need
- * to first actually detach (or hide, but detaching is simpler) all children, *then* force a reflow,
- * and then reattach (or show) them back.
- *
- * @static
- * @param {HTMLElement} el Element to reconsider the scrollbars on
- */
-OO.ui.Element.static.reconsiderScrollbars = function ( el ) {
-       var i, len, scrollLeft, scrollTop, nodes = [];
-       // Save scroll position
-       scrollLeft = el.scrollLeft;
-       scrollTop = el.scrollTop;
-       // Detach all children
-       while ( el.firstChild ) {
-               nodes.push( el.firstChild );
-               el.removeChild( el.firstChild );
-       }
-       // Force reflow
-       void el.offsetHeight;
-       // Reattach all children
-       for ( i = 0, len = nodes.length; i < len; i++ ) {
-               el.appendChild( nodes[ i ] );
-       }
-       // Restore scroll position (no-op if scrollbars disappeared)
-       el.scrollLeft = scrollLeft;
-       el.scrollTop = scrollTop;
-};
-
-/* Methods */
-
-/**
- * Toggle visibility of an element.
- *
- * @param {boolean} [show] Make element visible, omit to toggle visibility
- * @fires visible
- * @chainable
- */
-OO.ui.Element.prototype.toggle = function ( show ) {
-       show = show === undefined ? !this.visible : !!show;
-
-       if ( show !== this.isVisible() ) {
-               this.visible = show;
-               this.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );
-               this.emit( 'toggle', show );
-       }
-
-       return this;
-};
-
-/**
- * Check if element is visible.
- *
- * @return {boolean} element is visible
- */
-OO.ui.Element.prototype.isVisible = function () {
-       return this.visible;
-};
-
-/**
- * Get element data.
- *
- * @return {Mixed} Element data
- */
-OO.ui.Element.prototype.getData = function () {
-       return this.data;
-};
-
-/**
- * Set element data.
- *
- * @param {Mixed} Element data
- * @chainable
- */
-OO.ui.Element.prototype.setData = function ( data ) {
-       this.data = data;
-       return this;
-};
-
-/**
- * Check if element supports one or more methods.
- *
- * @param {string|string[]} methods Method or list of methods to check
- * @return {boolean} All methods are supported
- */
-OO.ui.Element.prototype.supports = function ( methods ) {
-       var i, len,
-               support = 0;
-
-       methods = Array.isArray( methods ) ? methods : [ methods ];
-       for ( i = 0, len = methods.length; i < len; i++ ) {
-               if ( $.isFunction( this[ methods[ i ] ] ) ) {
-                       support++;
-               }
-       }
-
-       return methods.length === support;
-};
-
-/**
- * Update the theme-provided classes.
- *
- * @localdoc This is called in element mixins and widget classes any time state changes.
- *   Updating is debounced, minimizing overhead of changing multiple attributes and
- *   guaranteeing that theme updates do not occur within an element's constructor
- */
-OO.ui.Element.prototype.updateThemeClasses = function () {
-       this.debouncedUpdateThemeClassesHandler();
-};
-
-/**
- * @private
- * @localdoc This method is called directly from the QUnit tests instead of #updateThemeClasses, to
- *   make them synchronous.
- */
-OO.ui.Element.prototype.debouncedUpdateThemeClasses = function () {
-       OO.ui.theme.updateElementClasses( this );
-};
-
-/**
- * Get the HTML tag name.
- *
- * Override this method to base the result on instance information.
- *
- * @return {string} HTML tag name
- */
-OO.ui.Element.prototype.getTagName = function () {
-       return this.constructor.static.tagName;
-};
-
-/**
- * Check if the element is attached to the DOM
- * @return {boolean} The element is attached to the DOM
- */
-OO.ui.Element.prototype.isElementAttached = function () {
-       return $.contains( this.getElementDocument(), this.$element[ 0 ] );
-};
-
-/**
- * Get the DOM document.
- *
- * @return {HTMLDocument} Document object
- */
-OO.ui.Element.prototype.getElementDocument = function () {
-       // Don't cache this in other ways either because subclasses could can change this.$element
-       return OO.ui.Element.static.getDocument( this.$element );
-};
-
-/**
- * Get the DOM window.
- *
- * @return {Window} Window object
- */
-OO.ui.Element.prototype.getElementWindow = function () {
-       return OO.ui.Element.static.getWindow( this.$element );
-};
-
-/**
- * Get closest scrollable container.
- */
-OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
-       return OO.ui.Element.static.getClosestScrollableContainer( this.$element[ 0 ] );
-};
-
-/**
- * Get group element is in.
- *
- * @return {OO.ui.mixin.GroupElement|null} Group element, null if none
- */
-OO.ui.Element.prototype.getElementGroup = function () {
-       return this.elementGroup;
-};
-
-/**
- * Set group element is in.
- *
- * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none
- * @chainable
- */
-OO.ui.Element.prototype.setElementGroup = function ( group ) {
-       this.elementGroup = group;
-       return this;
-};
-
-/**
- * Scroll element into view.
- *
- * @param {Object} [config] Configuration options
- */
-OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
-       return OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config );
-};
-
-/**
- * Restore the pre-infusion dynamic state for this widget.
- *
- * This method is called after #$element has been inserted into DOM. The parameter is the return
- * value of #gatherPreInfuseState.
- *
- * @protected
- * @param {Object} state
- */
-OO.ui.Element.prototype.restorePreInfuseState = function () {
-};
-
-/**
- * Layouts are containers for elements and are used to arrange other widgets of arbitrary type in a way
- * that is centrally controlled and can be updated dynamically. Layouts can be, and usually are, combined.
- * See {@link OO.ui.FieldsetLayout FieldsetLayout}, {@link OO.ui.FieldLayout FieldLayout}, {@link OO.ui.FormLayout FormLayout},
- * {@link OO.ui.PanelLayout PanelLayout}, {@link OO.ui.StackLayout StackLayout}, {@link OO.ui.PageLayout PageLayout},
- * {@link OO.ui.HorizontalLayout HorizontalLayout}, and {@link OO.ui.BookletLayout BookletLayout} for more information and examples.
- *
- * @abstract
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.Layout = function OoUiLayout( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.Layout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-layout' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Layout, OO.ui.Element );
-OO.mixinClass( OO.ui.Layout, OO.EventEmitter );
-
-/**
- * Widgets are compositions of one or more OOjs UI elements that users can both view
- * and interact with. All widgets can be configured and modified via a standard API,
- * and their state can change dynamically according to a model.
- *
- * @abstract
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [disabled=false] Disable the widget. Disabled widgets cannot be used and their
- *  appearance reflects this state.
- */
-OO.ui.Widget = function OoUiWidget( config ) {
-       // Initialize config
-       config = $.extend( { disabled: false }, config );
-
-       // Parent constructor
-       OO.ui.Widget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-
-       // Properties
-       this.disabled = null;
-       this.wasDisabled = null;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-widget' );
-       this.setDisabled( !!config.disabled );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Widget, OO.ui.Element );
-OO.mixinClass( OO.ui.Widget, OO.EventEmitter );
-
-/* Static Properties */
-
-/**
- * Whether this widget will behave reasonably when wrapped in a HTML `<label>`. If this is true,
- * wrappers such as OO.ui.FieldLayout may use a `<label>` instead of implementing own label click
- * handling.
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.Widget.static.supportsSimpleLabel = false;
-
-/* Events */
-
-/**
- * @event disable
- *
- * A 'disable' event is emitted when the disabled state of the widget changes
- * (i.e. on disable **and** enable).
- *
- * @param {boolean} disabled Widget is disabled
- */
-
-/**
- * @event toggle
- *
- * A 'toggle' event is emitted when the visibility of the widget changes.
- *
- * @param {boolean} visible Widget is visible
- */
-
-/* Methods */
-
-/**
- * Check if the widget is disabled.
- *
- * @return {boolean} Widget is disabled
- */
-OO.ui.Widget.prototype.isDisabled = function () {
-       return this.disabled;
-};
-
-/**
- * Set the 'disabled' state of the widget.
- *
- * When a widget is disabled, it cannot be used and its appearance is updated to reflect this state.
- *
- * @param {boolean} disabled Disable widget
- * @chainable
- */
-OO.ui.Widget.prototype.setDisabled = function ( disabled ) {
-       var isDisabled;
-
-       this.disabled = !!disabled;
-       isDisabled = this.isDisabled();
-       if ( isDisabled !== this.wasDisabled ) {
-               this.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled );
-               this.$element.toggleClass( 'oo-ui-widget-enabled', !isDisabled );
-               this.$element.attr( 'aria-disabled', isDisabled.toString() );
-               this.emit( 'disable', isDisabled );
-               this.updateThemeClasses();
-       }
-       this.wasDisabled = isDisabled;
-
-       return this;
-};
-
-/**
- * Update the disabled state, in case of changes in parent widget.
- *
- * @chainable
- */
-OO.ui.Widget.prototype.updateDisabled = function () {
-       this.setDisabled( this.disabled );
-       return this;
-};
-
-/**
- * A window is a container for elements that are in a child frame. They are used with
- * a window manager (OO.ui.WindowManager), which is used to open and close the window and control
- * its presentation. The size of a window is specified using a symbolic name (e.g., ‘small’, ‘medium’,
- * ‘large’), which is interpreted by the window manager. If the requested size is not recognized,
- * the window manager will choose a sensible fallback.
- *
- * The lifecycle of a window has three primary stages (opening, opened, and closing) in which
- * different processes are executed:
- *
- * **opening**: The opening stage begins when the window manager's {@link OO.ui.WindowManager#openWindow
- * openWindow} or the window's {@link #open open} methods are used, and the window manager begins to open
- * the window.
- *
- * - {@link #getSetupProcess} method is called and its result executed
- * - {@link #getReadyProcess} method is called and its result executed
- *
- * **opened**: The window is now open
- *
- * **closing**: The closing stage begins when the window manager's
- * {@link OO.ui.WindowManager#closeWindow closeWindow}
- * or the window's {@link #close} methods are used, and the window manager begins to close the window.
- *
- * - {@link #getHoldProcess} method is called and its result executed
- * - {@link #getTeardownProcess} method is called and its result executed. The window is now closed
- *
- * Each of the window's processes (setup, ready, hold, and teardown) can be extended in subclasses
- * by overriding the window's #getSetupProcess, #getReadyProcess, #getHoldProcess and #getTeardownProcess
- * methods. Note that each {@link OO.ui.Process process} is executed in series, so asynchronous
- * processing can complete. Always assume window processes are executed asynchronously.
- *
- * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows
- *
- * @abstract
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [size] Symbolic name of the dialog size: `small`, `medium`, `large`, `larger` or
- *  `full`.  If omitted, the value of the {@link #static-size static size} property will be used.
- */
-OO.ui.Window = function OoUiWindow( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.Window.parent.call( this, config );
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-
-       // Properties
-       this.manager = null;
-       this.size = config.size || this.constructor.static.size;
-       this.$frame = $( '<div>' );
-       this.$overlay = $( '<div>' );
-       this.$content = $( '<div>' );
-
-       this.$focusTrapBefore = $( '<div>' ).prop( 'tabIndex', 0 );
-       this.$focusTrapAfter = $( '<div>' ).prop( 'tabIndex', 0 );
-       this.$focusTraps = this.$focusTrapBefore.add( this.$focusTrapAfter );
-
-       // Initialization
-       this.$overlay.addClass( 'oo-ui-window-overlay' );
-       this.$content
-               .addClass( 'oo-ui-window-content' )
-               .attr( 'tabindex', 0 );
-       this.$frame
-               .addClass( 'oo-ui-window-frame' )
-               .append( this.$focusTrapBefore, this.$content, this.$focusTrapAfter );
-
-       this.$element
-               .addClass( 'oo-ui-window' )
-               .append( this.$frame, this.$overlay );
-
-       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
-       // that reference properties not initialized at that time of parent class construction
-       // TODO: Find a better way to handle post-constructor setup
-       this.visible = false;
-       this.$element.addClass( 'oo-ui-element-hidden' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Window, OO.ui.Element );
-OO.mixinClass( OO.ui.Window, OO.EventEmitter );
-
-/* Static Properties */
-
-/**
- * Symbolic name of the window size: `small`, `medium`, `large`, `larger` or `full`.
- *
- * The static size is used if no #size is configured during construction.
- *
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.Window.static.size = 'medium';
-
-/* Methods */
-
-/**
- * Handle mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- */
-OO.ui.Window.prototype.onMouseDown = function ( e ) {
-       // Prevent clicking on the click-block from stealing focus
-       if ( e.target === this.$element[ 0 ] ) {
-               return false;
-       }
-};
-
-/**
- * Check if the window has been initialized.
- *
- * Initialization occurs when a window is added to a manager.
- *
- * @return {boolean} Window has been initialized
- */
-OO.ui.Window.prototype.isInitialized = function () {
-       return !!this.manager;
-};
-
-/**
- * Check if the window is visible.
- *
- * @return {boolean} Window is visible
- */
-OO.ui.Window.prototype.isVisible = function () {
-       return this.visible;
-};
-
-/**
- * Check if the window is opening.
- *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpening isOpening}
- * method.
- *
- * @return {boolean} Window is opening
- */
-OO.ui.Window.prototype.isOpening = function () {
-       return this.manager.isOpening( this );
-};
-
-/**
- * Check if the window is closing.
- *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isClosing isClosing} method.
- *
- * @return {boolean} Window is closing
- */
-OO.ui.Window.prototype.isClosing = function () {
-       return this.manager.isClosing( this );
-};
-
-/**
- * Check if the window is opened.
- *
- * This method is a wrapper around the window manager's {@link OO.ui.WindowManager#isOpened isOpened} method.
- *
- * @return {boolean} Window is opened
- */
-OO.ui.Window.prototype.isOpened = function () {
-       return this.manager.isOpened( this );
-};
-
-/**
- * Get the window manager.
- *
- * All windows must be attached to a window manager, which is used to open
- * and close the window and control its presentation.
- *
- * @return {OO.ui.WindowManager} Manager of window
- */
-OO.ui.Window.prototype.getManager = function () {
-       return this.manager;
-};
-
-/**
- * Get the symbolic name of the window size (e.g., `small` or `medium`).
- *
- * @return {string} Symbolic name of the size: `small`, `medium`, `large`, `larger`, `full`
- */
-OO.ui.Window.prototype.getSize = function () {
-       var viewport = OO.ui.Element.static.getDimensions( this.getElementWindow() ),
-               sizes = this.manager.constructor.static.sizes,
-               size = this.size;
-
-       if ( !sizes[ size ] ) {
-               size = this.manager.constructor.static.defaultSize;
-       }
-       if ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) {
-               size = 'full';
-       }
-
-       return size;
-};
-
-/**
- * Get the size properties associated with the current window size
- *
- * @return {Object} Size properties
- */
-OO.ui.Window.prototype.getSizeProperties = function () {
-       return this.manager.constructor.static.sizes[ this.getSize() ];
-};
-
-/**
- * Disable transitions on window's frame for the duration of the callback function, then enable them
- * back.
- *
- * @private
- * @param {Function} callback Function to call while transitions are disabled
- */
-OO.ui.Window.prototype.withoutSizeTransitions = function ( callback ) {
-       // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
-       // Disable transitions first, otherwise we'll get values from when the window was animating.
-       var oldTransition,
-               styleObj = this.$frame[ 0 ].style;
-       oldTransition = styleObj.transition || styleObj.OTransition || styleObj.MsTransition ||
-               styleObj.MozTransition || styleObj.WebkitTransition;
-       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
-               styleObj.MozTransition = styleObj.WebkitTransition = 'none';
-       callback();
-       // Force reflow to make sure the style changes done inside callback really are not transitioned
-       this.$frame.height();
-       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
-               styleObj.MozTransition = styleObj.WebkitTransition = oldTransition;
-};
-
-/**
- * Get the height of the full window contents (i.e., the window head, body and foot together).
- *
- * What consistitutes the head, body, and foot varies depending on the window type.
- * A {@link OO.ui.MessageDialog message dialog} displays a title and message in its body,
- * and any actions in the foot. A {@link OO.ui.ProcessDialog process dialog} displays a title
- * and special actions in the head, and dialog content in the body.
- *
- * To get just the height of the dialog body, use the #getBodyHeight method.
- *
- * @return {number} The height of the window contents (the dialog head, body and foot) in pixels
- */
-OO.ui.Window.prototype.getContentHeight = function () {
-       var bodyHeight,
-               win = this,
-               bodyStyleObj = this.$body[ 0 ].style,
-               frameStyleObj = this.$frame[ 0 ].style;
-
-       // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
-       // Disable transitions first, otherwise we'll get values from when the window was animating.
-       this.withoutSizeTransitions( function () {
-               var oldHeight = frameStyleObj.height,
-                       oldPosition = bodyStyleObj.position;
-               frameStyleObj.height = '1px';
-               // Force body to resize to new width
-               bodyStyleObj.position = 'relative';
-               bodyHeight = win.getBodyHeight();
-               frameStyleObj.height = oldHeight;
-               bodyStyleObj.position = oldPosition;
-       } );
-
-       return (
-               // Add buffer for border
-               ( this.$frame.outerHeight() - this.$frame.innerHeight() ) +
-               // Use combined heights of children
-               ( this.$head.outerHeight( true ) + bodyHeight + this.$foot.outerHeight( true ) )
-       );
-};
-
-/**
- * Get the height of the window body.
- *
- * To get the height of the full window contents (the window body, head, and foot together),
- * use #getContentHeight.
- *
- * When this function is called, the window will temporarily have been resized
- * to height=1px, so .scrollHeight measurements can be taken accurately.
- *
- * @return {number} Height of the window body in pixels
- */
-OO.ui.Window.prototype.getBodyHeight = function () {
-       return this.$body[ 0 ].scrollHeight;
-};
-
-/**
- * Get the directionality of the frame (right-to-left or left-to-right).
- *
- * @return {string} Directionality: `'ltr'` or `'rtl'`
- */
-OO.ui.Window.prototype.getDir = function () {
-       return OO.ui.Element.static.getDir( this.$content ) || 'ltr';
-};
-
-/**
- * Get the 'setup' process.
- *
- * The setup process is used to set up a window for use in a particular context,
- * based on the `data` argument. This method is called during the opening phase of the window’s
- * lifecycle.
- *
- * Override this method to add additional steps to the ‘setup’ process the parent method provides
- * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
- * of OO.ui.Process.
- *
- * To add window content that persists between openings, you may wish to use the #initialize method
- * instead.
- *
- * @param {Object} [data] Window opening data
- * @return {OO.ui.Process} Setup process
- */
-OO.ui.Window.prototype.getSetupProcess = function () {
-       return new OO.ui.Process();
-};
-
-/**
- * Get the ‘ready’ process.
- *
- * The ready process is used to ready a window for use in a particular
- * context, based on the `data` argument. This method is called during the opening phase of
- * the window’s lifecycle, after the window has been {@link #getSetupProcess setup}.
- *
- * Override this method to add additional steps to the ‘ready’ process the parent method
- * provides using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next}
- * methods of OO.ui.Process.
- *
- * @param {Object} [data] Window opening data
- * @return {OO.ui.Process} Ready process
- */
-OO.ui.Window.prototype.getReadyProcess = function () {
-       return new OO.ui.Process();
-};
-
-/**
- * Get the 'hold' process.
- *
- * The hold proccess is used to keep a window from being used in a particular context,
- * based on the `data` argument. This method is called during the closing phase of the window’s
- * lifecycle.
- *
- * Override this method to add additional steps to the 'hold' process the parent method provides
- * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
- * of OO.ui.Process.
- *
- * @param {Object} [data] Window closing data
- * @return {OO.ui.Process} Hold process
- */
-OO.ui.Window.prototype.getHoldProcess = function () {
-       return new OO.ui.Process();
-};
-
-/**
- * Get the ‘teardown’ process.
- *
- * The teardown process is used to teardown a window after use. During teardown,
- * user interactions within the window are conveyed and the window is closed, based on the `data`
- * argument. This method is called during the closing phase of the window’s lifecycle.
- *
- * Override this method to add additional steps to the ‘teardown’ process the parent method provides
- * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
- * of OO.ui.Process.
- *
- * @param {Object} [data] Window closing data
- * @return {OO.ui.Process} Teardown process
- */
-OO.ui.Window.prototype.getTeardownProcess = function () {
-       return new OO.ui.Process();
-};
-
-/**
- * Set the window manager.
- *
- * This will cause the window to initialize. Calling it more than once will cause an error.
- *
- * @param {OO.ui.WindowManager} manager Manager for this window
- * @throws {Error} An error is thrown if the method is called more than once
- * @chainable
- */
-OO.ui.Window.prototype.setManager = function ( manager ) {
-       if ( this.manager ) {
-               throw new Error( 'Cannot set window manager, window already has a manager' );
-       }
-
-       this.manager = manager;
-       this.initialize();
-
-       return this;
-};
-
-/**
- * Set the window size by symbolic name (e.g., 'small' or 'medium')
- *
- * @param {string} size Symbolic name of size: `small`, `medium`, `large`, `larger` or
- *  `full`
- * @chainable
- */
-OO.ui.Window.prototype.setSize = function ( size ) {
-       this.size = size;
-       this.updateSize();
-       return this;
-};
-
-/**
- * Update the window size.
- *
- * @throws {Error} An error is thrown if the window is not attached to a window manager
- * @chainable
- */
-OO.ui.Window.prototype.updateSize = function () {
-       if ( !this.manager ) {
-               throw new Error( 'Cannot update window size, must be attached to a manager' );
-       }
-
-       this.manager.updateWindowSize( this );
-
-       return this;
-};
-
-/**
- * Set window dimensions. This method is called by the {@link OO.ui.WindowManager window manager}
- * when the window is opening. In general, setDimensions should not be called directly.
- *
- * To set the size of the window, use the #setSize method.
- *
- * @param {Object} dim CSS dimension properties
- * @param {string|number} [dim.width] Width
- * @param {string|number} [dim.minWidth] Minimum width
- * @param {string|number} [dim.maxWidth] Maximum width
- * @param {string|number} [dim.width] Height, omit to set based on height of contents
- * @param {string|number} [dim.minWidth] Minimum height
- * @param {string|number} [dim.maxWidth] Maximum height
- * @chainable
- */
-OO.ui.Window.prototype.setDimensions = function ( dim ) {
-       var height,
-               win = this,
-               styleObj = this.$frame[ 0 ].style;
-
-       // Calculate the height we need to set using the correct width
-       if ( dim.height === undefined ) {
-               this.withoutSizeTransitions( function () {
-                       var oldWidth = styleObj.width;
-                       win.$frame.css( 'width', dim.width || '' );
-                       height = win.getContentHeight();
-                       styleObj.width = oldWidth;
-               } );
-       } else {
-               height = dim.height;
-       }
-
-       this.$frame.css( {
-               width: dim.width || '',
-               minWidth: dim.minWidth || '',
-               maxWidth: dim.maxWidth || '',
-               height: height || '',
-               minHeight: dim.minHeight || '',
-               maxHeight: dim.maxHeight || ''
-       } );
-
-       return this;
-};
-
-/**
- * Initialize window contents.
- *
- * Before the window is opened for the first time, #initialize is called so that content that
- * persists between openings can be added to the window.
- *
- * To set up a window with new content each time the window opens, use #getSetupProcess.
- *
- * @throws {Error} An error is thrown if the window is not attached to a window manager
- * @chainable
- */
-OO.ui.Window.prototype.initialize = function () {
-       if ( !this.manager ) {
-               throw new Error( 'Cannot initialize window, must be attached to a manager' );
-       }
-
-       // Properties
-       this.$head = $( '<div>' );
-       this.$body = $( '<div>' );
-       this.$foot = $( '<div>' );
-       this.$document = $( this.getElementDocument() );
-
-       // Events
-       this.$element.on( 'mousedown', this.onMouseDown.bind( this ) );
-
-       // Initialization
-       this.$head.addClass( 'oo-ui-window-head' );
-       this.$body.addClass( 'oo-ui-window-body' );
-       this.$foot.addClass( 'oo-ui-window-foot' );
-       this.$content.append( this.$head, this.$body, this.$foot );
-
-       return this;
-};
-
-/**
- * Called when someone tries to focus the hidden element at the end of the dialog.
- * Sends focus back to the start of the dialog.
- *
- * @param {jQuery.Event} event Focus event
- */
-OO.ui.Window.prototype.onFocusTrapFocused = function ( event ) {
-       if ( this.$focusTrapBefore.is( event.target ) ) {
-               OO.ui.findFocusable( this.$content, true ).focus();
-       } else {
-               // this.$content is the part of the focus cycle, and is the first focusable element
-               this.$content.focus();
-       }
-};
-
-/**
- * Open the window.
- *
- * This method is a wrapper around a call to the window manager’s {@link OO.ui.WindowManager#openWindow openWindow}
- * method, which returns a promise resolved when the window is done opening.
- *
- * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.
- *
- * @param {Object} [data] Window opening data
- * @return {jQuery.Promise} Promise resolved with a value when the window is opened, or rejected
- *  if the window fails to open. When the promise is resolved successfully, the first argument of the
- *  value is a new promise, which is resolved when the window begins closing.
- * @throws {Error} An error is thrown if the window is not attached to a window manager
- */
-OO.ui.Window.prototype.open = function ( data ) {
-       if ( !this.manager ) {
-               throw new Error( 'Cannot open window, must be attached to a manager' );
-       }
-
-       return this.manager.openWindow( this, data );
-};
-
-/**
- * Close the window.
- *
- * This method is a wrapper around a call to the window
- * manager’s {@link OO.ui.WindowManager#closeWindow closeWindow} method,
- * which returns a closing promise resolved when the window is done closing.
- *
- * The window's #getHoldProcess and #getTeardownProcess methods are called during the closing
- * phase of the window’s lifecycle and can be used to specify closing behavior each time
- * the window closes.
- *
- * @param {Object} [data] Window closing data
- * @return {jQuery.Promise} Promise resolved when window is closed
- * @throws {Error} An error is thrown if the window is not attached to a window manager
- */
-OO.ui.Window.prototype.close = function ( data ) {
-       if ( !this.manager ) {
-               throw new Error( 'Cannot close window, must be attached to a manager' );
-       }
-
-       return this.manager.closeWindow( this, data );
-};
-
-/**
- * Setup window.
- *
- * This is called by OO.ui.WindowManager during window opening, and should not be called directly
- * by other systems.
- *
- * @param {Object} [data] Window opening data
- * @return {jQuery.Promise} Promise resolved when window is setup
- */
-OO.ui.Window.prototype.setup = function ( data ) {
-       var win = this;
-
-       this.toggle( true );
-
-       this.focusTrapHandler = OO.ui.bind( this.onFocusTrapFocused, this );
-       this.$focusTraps.on( 'focus', this.focusTrapHandler );
-
-       return this.getSetupProcess( data ).execute().then( function () {
-               // Force redraw by asking the browser to measure the elements' widths
-               win.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
-               win.$content.addClass( 'oo-ui-window-content-setup' ).width();
-       } );
-};
-
-/**
- * Ready window.
- *
- * This is called by OO.ui.WindowManager during window opening, and should not be called directly
- * by other systems.
- *
- * @param {Object} [data] Window opening data
- * @return {jQuery.Promise} Promise resolved when window is ready
- */
-OO.ui.Window.prototype.ready = function ( data ) {
-       var win = this;
-
-       this.$content.focus();
-       return this.getReadyProcess( data ).execute().then( function () {
-               // Force redraw by asking the browser to measure the elements' widths
-               win.$element.addClass( 'oo-ui-window-ready' ).width();
-               win.$content.addClass( 'oo-ui-window-content-ready' ).width();
-       } );
-};
-
-/**
- * Hold window.
- *
- * This is called by OO.ui.WindowManager during window closing, and should not be called directly
- * by other systems.
- *
- * @param {Object} [data] Window closing data
- * @return {jQuery.Promise} Promise resolved when window is held
- */
-OO.ui.Window.prototype.hold = function ( data ) {
-       var win = this;
-
-       return this.getHoldProcess( data ).execute().then( function () {
-               // Get the focused element within the window's content
-               var $focus = win.$content.find( OO.ui.Element.static.getDocument( win.$content ).activeElement );
-
-               // Blur the focused element
-               if ( $focus.length ) {
-                       $focus[ 0 ].blur();
-               }
-
-               // Force redraw by asking the browser to measure the elements' widths
-               win.$element.removeClass( 'oo-ui-window-ready' ).width();
-               win.$content.removeClass( 'oo-ui-window-content-ready' ).width();
-       } );
-};
-
-/**
- * Teardown window.
- *
- * This is called by OO.ui.WindowManager during window closing, and should not be called directly
- * by other systems.
- *
- * @param {Object} [data] Window closing data
- * @return {jQuery.Promise} Promise resolved when window is torn down
- */
-OO.ui.Window.prototype.teardown = function ( data ) {
-       var win = this;
-
-       return this.getTeardownProcess( data ).execute().then( function () {
-               // Force redraw by asking the browser to measure the elements' widths
-               win.$element.removeClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
-               win.$content.removeClass( 'oo-ui-window-content-setup' ).width();
-               win.$focusTraps.off( 'focus', win.focusTrapHandler );
-               win.toggle( false );
-       } );
-};
-
-/**
- * The Dialog class serves as the base class for the other types of dialogs.
- * Unless extended to include controls, the rendered dialog box is a simple window
- * that users can close by hitting the ‘Esc’ key. Dialog windows are used with OO.ui.WindowManager,
- * which opens, closes, and controls the presentation of the window. See the
- * [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- *     @example
- *     // A simple dialog window.
- *     function MyDialog( config ) {
- *         MyDialog.parent.call( this, config );
- *     }
- *     OO.inheritClass( MyDialog, OO.ui.Dialog );
- *     MyDialog.prototype.initialize = function () {
- *         MyDialog.parent.prototype.initialize.call( this );
- *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.content.$element.append( '<p>A simple dialog window. Press \'Esc\' to close.</p>' );
- *         this.$body.append( this.content.$element );
- *     };
- *     MyDialog.prototype.getBodyHeight = function () {
- *         return this.content.$element.outerHeight( true );
- *     };
- *     var myDialog = new MyDialog( {
- *         size: 'medium'
- *     } );
- *     // Create and append a window manager, which opens and closes the window.
- *     var windowManager = new OO.ui.WindowManager();
- *     $( 'body' ).append( windowManager.$element );
- *     windowManager.addWindows( [ myDialog ] );
- *     // Open the window!
- *     windowManager.openWindow( myDialog );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Dialogs
- *
- * @abstract
- * @class
- * @extends OO.ui.Window
- * @mixins OO.ui.mixin.PendingElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.Dialog = function OoUiDialog( config ) {
-       // Parent constructor
-       OO.ui.Dialog.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.PendingElement.call( this );
-
-       // Properties
-       this.actions = new OO.ui.ActionSet();
-       this.attachedActions = [];
-       this.currentAction = null;
-       this.onDialogKeyDownHandler = this.onDialogKeyDown.bind( this );
-
-       // Events
-       this.actions.connect( this, {
-               click: 'onActionClick',
-               resize: 'onActionResize',
-               change: 'onActionsChange'
-       } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-dialog' )
-               .attr( 'role', 'dialog' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Dialog, OO.ui.Window );
-OO.mixinClass( OO.ui.Dialog, OO.ui.mixin.PendingElement );
-
-/* Static Properties */
-
-/**
- * Symbolic name of dialog.
- *
- * The dialog class must have a symbolic name in order to be registered with OO.Factory.
- * Please see the [OOjs UI documentation on MediaWiki] [3] for more information.
- *
- * [3]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @abstract
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.Dialog.static.name = '';
-
-/**
- * The dialog title.
- *
- * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node, or a function
- * that will produce a Label node or string. The title can also be specified with data passed to the
- * constructor (see #getSetupProcess). In this case, the static value will be overridden.
- *
- * @abstract
- * @static
- * @inheritable
- * @property {jQuery|string|Function}
- */
-OO.ui.Dialog.static.title = '';
-
-/**
- * An array of configured {@link OO.ui.ActionWidget action widgets}.
- *
- * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this case, the static
- * value will be overridden.
- *
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
- *
- * @static
- * @inheritable
- * @property {Object[]}
- */
-OO.ui.Dialog.static.actions = [];
-
-/**
- * Close the dialog when the 'Esc' key is pressed.
- *
- * @static
- * @abstract
- * @inheritable
- * @property {boolean}
- */
-OO.ui.Dialog.static.escapable = true;
-
-/* Methods */
-
-/**
- * Handle frame document key down events.
- *
- * @private
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.Dialog.prototype.onDialogKeyDown = function ( e ) {
-       if ( e.which === OO.ui.Keys.ESCAPE ) {
-               this.executeAction( '' );
-               e.preventDefault();
-               e.stopPropagation();
-       }
-};
-
-/**
- * Handle action resized events.
- *
- * @private
- * @param {OO.ui.ActionWidget} action Action that was resized
- */
-OO.ui.Dialog.prototype.onActionResize = function () {
-       // Override in subclass
-};
-
-/**
- * Handle action click events.
- *
- * @private
- * @param {OO.ui.ActionWidget} action Action that was clicked
- */
-OO.ui.Dialog.prototype.onActionClick = function ( action ) {
-       if ( !this.isPending() ) {
-               this.executeAction( action.getAction() );
-       }
-};
-
-/**
- * Handle actions change event.
- *
- * @private
- */
-OO.ui.Dialog.prototype.onActionsChange = function () {
-       this.detachActions();
-       if ( !this.isClosing() ) {
-               this.attachActions();
-       }
-};
-
-/**
- * Get the set of actions used by the dialog.
- *
- * @return {OO.ui.ActionSet}
- */
-OO.ui.Dialog.prototype.getActions = function () {
-       return this.actions;
-};
-
-/**
- * Get a process for taking action.
- *
- * When you override this method, you can create a new OO.ui.Process and return it, or add additional
- * accept steps to the process the parent method provides using the {@link OO.ui.Process#first 'first'}
- * and {@link OO.ui.Process#next 'next'} methods of OO.ui.Process.
- *
- * @param {string} [action] Symbolic name of action
- * @return {OO.ui.Process} Action process
- */
-OO.ui.Dialog.prototype.getActionProcess = function ( action ) {
-       return new OO.ui.Process()
-               .next( function () {
-                       if ( !action ) {
-                               // An empty action always closes the dialog without data, which should always be
-                               // safe and make no changes
-                               this.close();
-                       }
-               }, this );
-};
-
-/**
- * @inheritdoc
- *
- * @param {Object} [data] Dialog opening data
- * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use
- *  the {@link #static-title static title}
- * @param {Object[]} [data.actions] List of configuration options for each
- *   {@link OO.ui.ActionWidget action widget}, omit to use {@link #static-actions static actions}.
- */
-OO.ui.Dialog.prototype.getSetupProcess = function ( data ) {
-       data = data || {};
-
-       // Parent method
-       return OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data )
-               .next( function () {
-                       var config = this.constructor.static,
-                               actions = data.actions !== undefined ? data.actions : config.actions;
-
-                       this.title.setLabel(
-                               data.title !== undefined ? data.title : this.constructor.static.title
-                       );
-                       this.actions.add( this.getActionWidgets( actions ) );
-
-                       if ( this.constructor.static.escapable ) {
-                               this.$element.on( 'keydown', this.onDialogKeyDownHandler );
-                       }
-               }, this );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.Dialog.prototype.getTeardownProcess = function ( data ) {
-       // Parent method
-       return OO.ui.Dialog.parent.prototype.getTeardownProcess.call( this, data )
-               .first( function () {
-                       if ( this.constructor.static.escapable ) {
-                               this.$element.off( 'keydown', this.onDialogKeyDownHandler );
-                       }
-
-                       this.actions.clear();
-                       this.currentAction = null;
-               }, this );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.Dialog.prototype.initialize = function () {
-       var titleId;
-
-       // Parent method
-       OO.ui.Dialog.parent.prototype.initialize.call( this );
-
-       titleId = OO.ui.generateElementId();
-
-       // Properties
-       this.title = new OO.ui.LabelWidget( {
-               id: titleId
-       } );
-
-       // Initialization
-       this.$content.addClass( 'oo-ui-dialog-content' );
-       this.$element.attr( 'aria-labelledby', titleId );
-       this.setPendingElement( this.$head );
-};
-
-/**
- * Get action widgets from a list of configs
- *
- * @param {Object[]} actions Action widget configs
- * @return {OO.ui.ActionWidget[]} Action widgets
- */
-OO.ui.Dialog.prototype.getActionWidgets = function ( actions ) {
-       var i, len, widgets = [];
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               widgets.push(
-                       new OO.ui.ActionWidget( actions[ i ] )
-               );
-       }
-       return widgets;
-};
-
-/**
- * Attach action actions.
- *
- * @protected
- */
-OO.ui.Dialog.prototype.attachActions = function () {
-       // Remember the list of potentially attached actions
-       this.attachedActions = this.actions.get();
-};
-
-/**
- * Detach action actions.
- *
- * @protected
- * @chainable
- */
-OO.ui.Dialog.prototype.detachActions = function () {
-       var i, len;
-
-       // Detach all actions that may have been previously attached
-       for ( i = 0, len = this.attachedActions.length; i < len; i++ ) {
-               this.attachedActions[ i ].$element.detach();
-       }
-       this.attachedActions = [];
-};
-
-/**
- * Execute an action.
- *
- * @param {string} action Symbolic name of action to execute
- * @return {jQuery.Promise} Promise resolved when action completes, rejected if it fails
- */
-OO.ui.Dialog.prototype.executeAction = function ( action ) {
-       this.pushPending();
-       this.currentAction = action;
-       return this.getActionProcess( action ).execute()
-               .always( this.popPending.bind( this ) );
-};
-
-/**
- * Window managers are used to open and close {@link OO.ui.Window windows} and control their presentation.
- * Managed windows are mutually exclusive. If a new window is opened while a current window is opening
- * or is opened, the current window will be closed and any ongoing {@link OO.ui.Process process} will be cancelled. Windows
- * themselves are persistent and—rather than being torn down when closed—can be repopulated with the
- * pertinent data and reused.
- *
- * Over the lifecycle of a window, the window manager makes available three promises: `opening`,
- * `opened`, and `closing`, which represent the primary stages of the cycle:
- *
- * **Opening**: the opening stage begins when the window manager’s #openWindow or a window’s
- * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.
- *
- * - an `opening` event is emitted with an `opening` promise
- * - the #getSetupDelay method is called and the returned value is used to time a pause in execution before
- *   the window’s {@link OO.ui.Window#getSetupProcess getSetupProcess} method is called on the
- *   window and its result executed
- * - a `setup` progress notification is emitted from the `opening` promise
- * - the #getReadyDelay method is called the returned value is used to time a pause in execution before
- *   the window’s {@link OO.ui.Window#getReadyProcess getReadyProcess} method is called on the
- *   window and its result executed
- * - a `ready` progress notification is emitted from the `opening` promise
- * - the `opening` promise is resolved with an `opened` promise
- *
- * **Opened**: the window is now open.
- *
- * **Closing**: the closing stage begins when the window manager's #closeWindow or the
- * window's {@link OO.ui.Window#close close} methods is used, and the window manager begins
- * to close the window.
- *
- * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted
- * - the #getHoldDelay method is called and the returned value is used to time a pause in execution before
- *   the window's {@link OO.ui.Window#getHoldProcess getHoldProces} method is called on the
- *   window and its result executed
- * - a `hold` progress notification is emitted from the `closing` promise
- * - the #getTeardownDelay() method is called and the returned value is used to time a pause in execution before
- *   the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method is called on the
- *   window and its result executed
- * - a `teardown` progress notification is emitted from the `closing` promise
- * - the `closing` promise is resolved. The window is now closed
- *
- * See the [OOjs UI documentation on MediaWiki][1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation
- *  Note that window classes that are instantiated with a factory must have
- *  a {@link OO.ui.Dialog#static-name static name} property that specifies a symbolic name.
- * @cfg {boolean} [modal=true] Prevent interaction outside the dialog
- */
-OO.ui.WindowManager = function OoUiWindowManager( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.WindowManager.parent.call( this, config );
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-
-       // Properties
-       this.factory = config.factory;
-       this.modal = config.modal === undefined || !!config.modal;
-       this.windows = {};
-       this.opening = null;
-       this.opened = null;
-       this.closing = null;
-       this.preparingToOpen = null;
-       this.preparingToClose = null;
-       this.currentWindow = null;
-       this.globalEvents = false;
-       this.$ariaHidden = null;
-       this.onWindowResizeTimeout = null;
-       this.onWindowResizeHandler = this.onWindowResize.bind( this );
-       this.afterWindowResizeHandler = this.afterWindowResize.bind( this );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-windowManager' )
-               .toggleClass( 'oo-ui-windowManager-modal', this.modal );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.WindowManager, OO.ui.Element );
-OO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );
-
-/* Events */
-
-/**
- * An 'opening' event is emitted when the window begins to be opened.
- *
- * @event opening
- * @param {OO.ui.Window} win Window that's being opened
- * @param {jQuery.Promise} opening An `opening` promise resolved with a value when the window is opened successfully.
- *  When the `opening` promise is resolved, the first argument of the value is an 'opened' promise, the second argument
- *  is the opening data. The `opening` promise emits `setup` and `ready` notifications when those processes are complete.
- * @param {Object} data Window opening data
- */
-
-/**
- * A 'closing' event is emitted when the window begins to be closed.
- *
- * @event closing
- * @param {OO.ui.Window} win Window that's being closed
- * @param {jQuery.Promise} closing A `closing` promise is resolved with a value when the window
- *  is closed successfully. The promise emits `hold` and `teardown` notifications when those
- *  processes are complete. When the `closing` promise is resolved, the first argument of its value
- *  is the closing data.
- * @param {Object} data Window closing data
- */
-
-/**
- * A 'resize' event is emitted when a window is resized.
- *
- * @event resize
- * @param {OO.ui.Window} win Window that was resized
- */
-
-/* Static Properties */
-
-/**
- * Map of the symbolic name of each window size and its CSS properties.
- *
- * @static
- * @inheritable
- * @property {Object}
- */
-OO.ui.WindowManager.static.sizes = {
-       small: {
-               width: 300
-       },
-       medium: {
-               width: 500
-       },
-       large: {
-               width: 700
-       },
-       larger: {
-               width: 900
-       },
-       full: {
-               // These can be non-numeric because they are never used in calculations
-               width: '100%',
-               height: '100%'
-       }
-};
-
-/**
- * Symbolic name of the default window size.
- *
- * The default size is used if the window's requested size is not recognized.
- *
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.WindowManager.static.defaultSize = 'medium';
-
-/* Methods */
-
-/**
- * Handle window resize events.
- *
- * @private
- * @param {jQuery.Event} e Window resize event
- */
-OO.ui.WindowManager.prototype.onWindowResize = function () {
-       clearTimeout( this.onWindowResizeTimeout );
-       this.onWindowResizeTimeout = setTimeout( this.afterWindowResizeHandler, 200 );
-};
-
-/**
- * Handle window resize events.
- *
- * @private
- * @param {jQuery.Event} e Window resize event
- */
-OO.ui.WindowManager.prototype.afterWindowResize = function () {
-       if ( this.currentWindow ) {
-               this.updateWindowSize( this.currentWindow );
-       }
-};
-
-/**
- * Check if window is opening.
- *
- * @return {boolean} Window is opening
- */
-OO.ui.WindowManager.prototype.isOpening = function ( win ) {
-       return win === this.currentWindow && !!this.opening && this.opening.state() === 'pending';
-};
-
-/**
- * Check if window is closing.
- *
- * @return {boolean} Window is closing
- */
-OO.ui.WindowManager.prototype.isClosing = function ( win ) {
-       return win === this.currentWindow && !!this.closing && this.closing.state() === 'pending';
-};
-
-/**
- * Check if window is opened.
- *
- * @return {boolean} Window is opened
- */
-OO.ui.WindowManager.prototype.isOpened = function ( win ) {
-       return win === this.currentWindow && !!this.opened && this.opened.state() === 'pending';
-};
-
-/**
- * Check if a window is being managed.
- *
- * @param {OO.ui.Window} win Window to check
- * @return {boolean} Window is being managed
- */
-OO.ui.WindowManager.prototype.hasWindow = function ( win ) {
-       var name;
-
-       for ( name in this.windows ) {
-               if ( this.windows[ name ] === win ) {
-                       return true;
-               }
-       }
-
-       return false;
-};
-
-/**
- * Get the number of milliseconds to wait after opening begins before executing the ‘setup’ process.
- *
- * @param {OO.ui.Window} win Window being opened
- * @param {Object} [data] Window opening data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getSetupDelay = function () {
-       return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’ process.
- *
- * @param {OO.ui.Window} win Window being opened
- * @param {Object} [data] Window opening data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getReadyDelay = function () {
-       return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after closing has begun before executing the 'hold' process.
- *
- * @param {OO.ui.Window} win Window being closed
- * @param {Object} [data] Window closing data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getHoldDelay = function () {
-       return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after the ‘hold’ process has finished before
- * executing the ‘teardown’ process.
- *
- * @param {OO.ui.Window} win Window being closed
- * @param {Object} [data] Window closing data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getTeardownDelay = function () {
-       return this.modal ? 250 : 0;
-};
-
-/**
- * Get a window by its symbolic name.
- *
- * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will be
- * instantiated and added to the window manager automatically. Please see the [OOjs UI documentation on MediaWiki][3]
- * for more information about using factories.
- * [3]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @param {string} name Symbolic name of the window
- * @return {jQuery.Promise} Promise resolved with matching window, or rejected with an OO.ui.Error
- * @throws {Error} An error is thrown if the symbolic name is not recognized by the factory.
- * @throws {Error} An error is thrown if the named window is not recognized as a managed window.
- */
-OO.ui.WindowManager.prototype.getWindow = function ( name ) {
-       var deferred = $.Deferred(),
-               win = this.windows[ name ];
-
-       if ( !( win instanceof OO.ui.Window ) ) {
-               if ( this.factory ) {
-                       if ( !this.factory.lookup( name ) ) {
-                               deferred.reject( new OO.ui.Error(
-                                       'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'
-                               ) );
-                       } else {
-                               win = this.factory.create( name );
-                               this.addWindows( [ win ] );
-                               deferred.resolve( win );
-                       }
-               } else {
-                       deferred.reject( new OO.ui.Error(
-                               'Cannot get unmanaged window: symbolic name unrecognized as a managed window'
-                       ) );
-               }
-       } else {
-               deferred.resolve( win );
-       }
-
-       return deferred.promise();
-};
-
-/**
- * Get current window.
- *
- * @return {OO.ui.Window|null} Currently opening/opened/closing window
- */
-OO.ui.WindowManager.prototype.getCurrentWindow = function () {
-       return this.currentWindow;
-};
-
-/**
- * Open a window.
- *
- * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
- * @param {Object} [data] Window opening data
- * @return {jQuery.Promise} An `opening` promise resolved when the window is done opening.
- *  See {@link #event-opening 'opening' event}  for more information about `opening` promises.
- * @fires opening
- */
-OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
-       var manager = this,
-               opening = $.Deferred();
-
-       // Argument handling
-       if ( typeof win === 'string' ) {
-               return this.getWindow( win ).then( function ( win ) {
-                       return manager.openWindow( win, data );
-               } );
-       }
-
-       // Error handling
-       if ( !this.hasWindow( win ) ) {
-               opening.reject( new OO.ui.Error(
-                       'Cannot open window: window is not attached to manager'
-               ) );
-       } else if ( this.preparingToOpen || this.opening || this.opened ) {
-               opening.reject( new OO.ui.Error(
-                       'Cannot open window: another window is opening or open'
-               ) );
-       }
-
-       // Window opening
-       if ( opening.state() !== 'rejected' ) {
-               // If a window is currently closing, wait for it to complete
-               this.preparingToOpen = $.when( this.closing );
-               // Ensure handlers get called after preparingToOpen is set
-               this.preparingToOpen.done( function () {
-                       if ( manager.modal ) {
-                               manager.toggleGlobalEvents( true );
-                               manager.toggleAriaIsolation( true );
-                       }
-                       manager.currentWindow = win;
-                       manager.opening = opening;
-                       manager.preparingToOpen = null;
-                       manager.emit( 'opening', win, opening, data );
-                       setTimeout( function () {
-                               win.setup( data ).then( function () {
-                                       manager.updateWindowSize( win );
-                                       manager.opening.notify( { state: 'setup' } );
-                                       setTimeout( function () {
-                                               win.ready( data ).then( function () {
-                                                       manager.opening.notify( { state: 'ready' } );
-                                                       manager.opening = null;
-                                                       manager.opened = $.Deferred();
-                                                       opening.resolve( manager.opened.promise(), data );
-                                               }, function () {
-                                                       manager.opening = null;
-                                                       manager.opened = $.Deferred();
-                                                       opening.reject();
-                                                       manager.closeWindow( win );
-                                               } );
-                                       }, manager.getReadyDelay() );
-                               }, function () {
-                                       manager.opening = null;
-                                       manager.opened = $.Deferred();
-                                       opening.reject();
-                                       manager.closeWindow( win );
-                               } );
-                       }, manager.getSetupDelay() );
-               } );
-       }
-
-       return opening.promise();
-};
-
-/**
- * Close a window.
- *
- * @param {OO.ui.Window|string} win Window object or symbolic name of window to close
- * @param {Object} [data] Window closing data
- * @return {jQuery.Promise} A `closing` promise resolved when the window is done closing.
- *  See {@link #event-closing 'closing' event} for more information about closing promises.
- * @throws {Error} An error is thrown if the window is not managed by the window manager.
- * @fires closing
- */
-OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
-       var manager = this,
-               closing = $.Deferred(),
-               opened;
-
-       // Argument handling
-       if ( typeof win === 'string' ) {
-               win = this.windows[ win ];
-       } else if ( !this.hasWindow( win ) ) {
-               win = null;
-       }
-
-       // Error handling
-       if ( !win ) {
-               closing.reject( new OO.ui.Error(
-                       'Cannot close window: window is not attached to manager'
-               ) );
-       } else if ( win !== this.currentWindow ) {
-               closing.reject( new OO.ui.Error(
-                       'Cannot close window: window already closed with different data'
-               ) );
-       } else if ( this.preparingToClose || this.closing ) {
-               closing.reject( new OO.ui.Error(
-                       'Cannot close window: window already closing with different data'
-               ) );
-       }
-
-       // Window closing
-       if ( closing.state() !== 'rejected' ) {
-               // If the window is currently opening, close it when it's done
-               this.preparingToClose = $.when( this.opening );
-               // Ensure handlers get called after preparingToClose is set
-               this.preparingToClose.always( function () {
-                       manager.closing = closing;
-                       manager.preparingToClose = null;
-                       manager.emit( 'closing', win, closing, data );
-                       opened = manager.opened;
-                       manager.opened = null;
-                       opened.resolve( closing.promise(), data );
-                       setTimeout( function () {
-                               win.hold( data ).then( function () {
-                                       closing.notify( { state: 'hold' } );
-                                       setTimeout( function () {
-                                               win.teardown( data ).then( function () {
-                                                       closing.notify( { state: 'teardown' } );
-                                                       if ( manager.modal ) {
-                                                               manager.toggleGlobalEvents( false );
-                                                               manager.toggleAriaIsolation( false );
-                                                       }
-                                                       manager.closing = null;
-                                                       manager.currentWindow = null;
-                                                       closing.resolve( data );
-                                               } );
-                                       }, manager.getTeardownDelay() );
-                               } );
-                       }, manager.getHoldDelay() );
-               } );
-       }
-
-       return closing.promise();
-};
-
-/**
- * Add windows to the window manager.
- *
- * Windows can be added by reference, symbolic name, or explicitly defined symbolic names.
- * See the [OOjs ui documentation on MediaWiki] [2] for examples.
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @param {Object.<string,OO.ui.Window>|OO.ui.Window[]} windows An array of window objects specified
- *  by reference, symbolic name, or explicitly defined symbolic names.
- * @throws {Error} An error is thrown if a window is added by symbolic name, but has neither an
- *  explicit nor a statically configured symbolic name.
- */
-OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
-       var i, len, win, name, list;
-
-       if ( Array.isArray( windows ) ) {
-               // Convert to map of windows by looking up symbolic names from static configuration
-               list = {};
-               for ( i = 0, len = windows.length; i < len; i++ ) {
-                       name = windows[ i ].constructor.static.name;
-                       if ( typeof name !== 'string' ) {
-                               throw new Error( 'Cannot add window' );
-                       }
-                       list[ name ] = windows[ i ];
-               }
-       } else if ( OO.isPlainObject( windows ) ) {
-               list = windows;
-       }
-
-       // Add windows
-       for ( name in list ) {
-               win = list[ name ];
-               this.windows[ name ] = win.toggle( false );
-               this.$element.append( win.$element );
-               win.setManager( this );
-       }
-};
-
-/**
- * Remove the specified windows from the windows manager.
- *
- * Windows will be closed before they are removed. If you wish to remove all windows, you may wish to use
- * the #clearWindows method instead. If you no longer need the window manager and want to ensure that it no
- * longer listens to events, use the #destroy method.
- *
- * @param {string[]} names Symbolic names of windows to remove
- * @return {jQuery.Promise} Promise resolved when window is closed and removed
- * @throws {Error} An error is thrown if the named windows are not managed by the window manager.
- */
-OO.ui.WindowManager.prototype.removeWindows = function ( names ) {
-       var i, len, win, name, cleanupWindow,
-               manager = this,
-               promises = [],
-               cleanup = function ( name, win ) {
-                       delete manager.windows[ name ];
-                       win.$element.detach();
-               };
-
-       for ( i = 0, len = names.length; i < len; i++ ) {
-               name = names[ i ];
-               win = this.windows[ name ];
-               if ( !win ) {
-                       throw new Error( 'Cannot remove window' );
-               }
-               cleanupWindow = cleanup.bind( null, name, win );
-               promises.push( this.closeWindow( name ).then( cleanupWindow, cleanupWindow ) );
-       }
-
-       return $.when.apply( $, promises );
-};
-
-/**
- * Remove all windows from the window manager.
- *
- * Windows will be closed before they are removed. Note that the window manager, though not in use, will still
- * listen to events. If the window manager will not be used again, you may wish to use the #destroy method instead.
- * To remove just a subset of windows, use the #removeWindows method.
- *
- * @return {jQuery.Promise} Promise resolved when all windows are closed and removed
- */
-OO.ui.WindowManager.prototype.clearWindows = function () {
-       return this.removeWindows( Object.keys( this.windows ) );
-};
-
-/**
- * Set dialog size. In general, this method should not be called directly.
- *
- * Fullscreen mode will be used if the dialog is too wide to fit in the screen.
- *
- * @chainable
- */
-OO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {
-       var isFullscreen;
-
-       // Bypass for non-current, and thus invisible, windows
-       if ( win !== this.currentWindow ) {
-               return;
-       }
-
-       isFullscreen = win.getSize() === 'full';
-
-       this.$element.toggleClass( 'oo-ui-windowManager-fullscreen', isFullscreen );
-       this.$element.toggleClass( 'oo-ui-windowManager-floating', !isFullscreen );
-       win.setDimensions( win.getSizeProperties() );
-
-       this.emit( 'resize', win );
-
-       return this;
-};
-
-/**
- * Bind or unbind global events for scrolling.
- *
- * @private
- * @param {boolean} [on] Bind global events
- * @chainable
- */
-OO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {
-       var scrollWidth, bodyMargin,
-               $body = $( this.getElementDocument().body ),
-               // We could have multiple window managers open so only modify
-               // the body css at the bottom of the stack
-               stackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0 ;
-
-       on = on === undefined ? !!this.globalEvents : !!on;
-
-       if ( on ) {
-               if ( !this.globalEvents ) {
-                       $( this.getElementWindow() ).on( {
-                               // Start listening for top-level window dimension changes
-                               'orientationchange resize': this.onWindowResizeHandler
-                       } );
-                       if ( stackDepth === 0 ) {
-                               scrollWidth = window.innerWidth - document.documentElement.clientWidth;
-                               bodyMargin = parseFloat( $body.css( 'margin-right' ) ) || 0;
-                               $body.css( {
-                                       overflow: 'hidden',
-                                       'margin-right': bodyMargin + scrollWidth
-                               } );
-                       }
-                       stackDepth++;
-                       this.globalEvents = true;
-               }
-       } else if ( this.globalEvents ) {
-               $( this.getElementWindow() ).off( {
-                       // Stop listening for top-level window dimension changes
-                       'orientationchange resize': this.onWindowResizeHandler
-               } );
-               stackDepth--;
-               if ( stackDepth === 0 ) {
-                       $body.css( {
-                               overflow: '',
-                               'margin-right': ''
-                       } );
-               }
-               this.globalEvents = false;
-       }
-       $body.data( 'windowManagerGlobalEvents', stackDepth );
-
-       return this;
-};
-
-/**
- * Toggle screen reader visibility of content other than the window manager.
- *
- * @private
- * @param {boolean} [isolate] Make only the window manager visible to screen readers
- * @chainable
- */
-OO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {
-       isolate = isolate === undefined ? !this.$ariaHidden : !!isolate;
-
-       if ( isolate ) {
-               if ( !this.$ariaHidden ) {
-                       // Hide everything other than the window manager from screen readers
-                       this.$ariaHidden = $( 'body' )
-                               .children()
-                               .not( this.$element.parentsUntil( 'body' ).last() )
-                               .attr( 'aria-hidden', '' );
-               }
-       } else if ( this.$ariaHidden ) {
-               // Restore screen reader visibility
-               this.$ariaHidden.removeAttr( 'aria-hidden' );
-               this.$ariaHidden = null;
-       }
-
-       return this;
-};
-
-/**
- * Destroy the window manager.
- *
- * Destroying the window manager ensures that it will no longer listen to events. If you would like to
- * continue using the window manager, but wish to remove all windows from it, use the #clearWindows method
- * instead.
- */
-OO.ui.WindowManager.prototype.destroy = function () {
-       this.toggleGlobalEvents( false );
-       this.toggleAriaIsolation( false );
-       this.clearWindows();
-       this.$element.remove();
-};
-
-/**
- * Errors contain a required message (either a string or jQuery selection) that is used to describe what went wrong
- * in a {@link OO.ui.Process process}. The error's #recoverable and #warning configurations are used to customize the
- * appearance and functionality of the error interface.
- *
- * The basic error interface contains a formatted error message as well as two buttons: 'Dismiss' and 'Try again' (i.e., the error
- * is 'recoverable' by default). If the error is not recoverable, the 'Try again' button will not be rendered and the widget
- * that initiated the failed process will be disabled.
- *
- * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button, which will try the
- * process again.
- *
- * For an example of error interfaces, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Processes_and_errors
- *
- * @class
- *
- * @constructor
- * @param {string|jQuery} message Description of error
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [recoverable=true] Error is recoverable.
- *  By default, errors are recoverable, and users can try the process again.
- * @cfg {boolean} [warning=false] Error is a warning.
- *  If the error is a warning, the error interface will include a
- *  'Dismiss' and a 'Continue' button. It is the responsibility of the developer to ensure that the warning
- *  is not triggered a second time if the user chooses to continue.
- */
-OO.ui.Error = function OoUiError( message, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( message ) && config === undefined ) {
-               config = message;
-               message = config.message;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.message = message instanceof jQuery ? message : String( message );
-       this.recoverable = config.recoverable === undefined || !!config.recoverable;
-       this.warning = !!config.warning;
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.Error );
-
-/* Methods */
-
-/**
- * Check if the error is recoverable.
- *
- * If the error is recoverable, users are able to try the process again.
- *
- * @return {boolean} Error is recoverable
- */
-OO.ui.Error.prototype.isRecoverable = function () {
-       return this.recoverable;
-};
-
-/**
- * Check if the error is a warning.
- *
- * If the error is a warning, the error interface will include a 'Dismiss' and a 'Continue' button.
- *
- * @return {boolean} Error is warning
- */
-OO.ui.Error.prototype.isWarning = function () {
-       return this.warning;
-};
-
-/**
- * Get error message as DOM nodes.
- *
- * @return {jQuery} Error message in DOM nodes
- */
-OO.ui.Error.prototype.getMessage = function () {
-       return this.message instanceof jQuery ?
-               this.message.clone() :
-               $( '<div>' ).text( this.message ).contents();
-};
-
-/**
- * Get the error message text.
- *
- * @return {string} Error message
- */
-OO.ui.Error.prototype.getMessageText = function () {
-       return this.message instanceof jQuery ? this.message.text() : this.message;
-};
-
-/**
- * Wraps an HTML snippet for use with configuration values which default
- * to strings.  This bypasses the default html-escaping done to string
- * values.
- *
- * @class
- *
- * @constructor
- * @param {string} [content] HTML content
- */
-OO.ui.HtmlSnippet = function OoUiHtmlSnippet( content ) {
-       // Properties
-       this.content = content;
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.HtmlSnippet );
-
-/* Methods */
-
-/**
- * Render into HTML.
- *
- * @return {string} Unchanged HTML snippet.
- */
-OO.ui.HtmlSnippet.prototype.toString = function () {
-       return this.content;
-};
-
-/**
- * A Process is a list of steps that are called in sequence. The step can be a number, a jQuery promise,
- * or a function:
- *
- * - **number**: the process will wait for the specified number of milliseconds before proceeding.
- * - **promise**: the process will continue to the next step when the promise is successfully resolved
- *  or stop if the promise is rejected.
- * - **function**: the process will execute the function. The process will stop if the function returns
- *  either a boolean `false` or a promise that is rejected; if the function returns a number, the process
- *  will wait for that number of milliseconds before proceeding.
- *
- * If the process fails, an {@link OO.ui.Error error} is generated. Depending on how the error is
- * configured, users can dismiss the error and try the process again, or not. If a process is stopped,
- * its remaining steps will not be performed.
- *
- * @class
- *
- * @constructor
- * @param {number|jQuery.Promise|Function} step Number of miliseconds to wait before proceeding, promise
- *  that must be resolved before proceeding, or a function to execute. See #createStep for more information. see #createStep for more information
- * @param {Object} [context=null] Execution context of the function. The context is ignored if the step is
- *  a number or promise.
- * @return {Object} Step object, with `callback` and `context` properties
- */
-OO.ui.Process = function ( step, context ) {
-       // Properties
-       this.steps = [];
-
-       // Initialization
-       if ( step !== undefined ) {
-               this.next( step, context );
-       }
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.Process );
-
-/* Methods */
-
-/**
- * Start the process.
- *
- * @return {jQuery.Promise} Promise that is resolved when all steps have successfully completed.
- *  If any of the steps return a promise that is rejected or a boolean false, this promise is rejected
- *  and any remaining steps are not performed.
- */
-OO.ui.Process.prototype.execute = function () {
-       var i, len, promise;
-
-       /**
-        * Continue execution.
-        *
-        * @ignore
-        * @param {Array} step A function and the context it should be called in
-        * @return {Function} Function that continues the process
-        */
-       function proceed( step ) {
-               return function () {
-                       // Execute step in the correct context
-                       var deferred,
-                               result = step.callback.call( step.context );
-
-                       if ( result === false ) {
-                               // Use rejected promise for boolean false results
-                               return $.Deferred().reject( [] ).promise();
-                       }
-                       if ( typeof result === 'number' ) {
-                               if ( result < 0 ) {
-                                       throw new Error( 'Cannot go back in time: flux capacitor is out of service' );
-                               }
-                               // Use a delayed promise for numbers, expecting them to be in milliseconds
-                               deferred = $.Deferred();
-                               setTimeout( deferred.resolve, result );
-                               return deferred.promise();
-                       }
-                       if ( result instanceof OO.ui.Error ) {
-                               // Use rejected promise for error
-                               return $.Deferred().reject( [ result ] ).promise();
-                       }
-                       if ( Array.isArray( result ) && result.length && result[ 0 ] instanceof OO.ui.Error ) {
-                               // Use rejected promise for list of errors
-                               return $.Deferred().reject( result ).promise();
-                       }
-                       // Duck-type the object to see if it can produce a promise
-                       if ( result && $.isFunction( result.promise ) ) {
-                               // Use a promise generated from the result
-                               return result.promise();
-                       }
-                       // Use resolved promise for other results
-                       return $.Deferred().resolve().promise();
-               };
-       }
-
-       if ( this.steps.length ) {
-               // Generate a chain reaction of promises
-               promise = proceed( this.steps[ 0 ] )();
-               for ( i = 1, len = this.steps.length; i < len; i++ ) {
-                       promise = promise.then( proceed( this.steps[ i ] ) );
-               }
-       } else {
-               promise = $.Deferred().resolve().promise();
-       }
-
-       return promise;
-};
-
-/**
- * Create a process step.
- *
- * @private
- * @param {number|jQuery.Promise|Function} step
- *
- * - Number of milliseconds to wait before proceeding
- * - Promise that must be resolved before proceeding
- * - Function to execute
- *   - If the function returns a boolean false the process will stop
- *   - If the function returns a promise, the process will continue to the next
- *     step when the promise is resolved or stop if the promise is rejected
- *   - If the function returns a number, the process will wait for that number of
- *     milliseconds before proceeding
- * @param {Object} [context=null] Execution context of the function. The context is
- *  ignored if the step is a number or promise.
- * @return {Object} Step object, with `callback` and `context` properties
- */
-OO.ui.Process.prototype.createStep = function ( step, context ) {
-       if ( typeof step === 'number' || $.isFunction( step.promise ) ) {
-               return {
-                       callback: function () {
-                               return step;
-                       },
-                       context: null
-               };
-       }
-       if ( $.isFunction( step ) ) {
-               return {
-                       callback: step,
-                       context: context
-               };
-       }
-       throw new Error( 'Cannot create process step: number, promise or function expected' );
-};
-
-/**
- * Add step to the beginning of the process.
- *
- * @inheritdoc #createStep
- * @return {OO.ui.Process} this
- * @chainable
- */
-OO.ui.Process.prototype.first = function ( step, context ) {
-       this.steps.unshift( this.createStep( step, context ) );
-       return this;
-};
-
-/**
- * Add step to the end of the process.
- *
- * @inheritdoc #createStep
- * @return {OO.ui.Process} this
- * @chainable
- */
-OO.ui.Process.prototype.next = function ( step, context ) {
-       this.steps.push( this.createStep( step, context ) );
-       return this;
-};
-
-/**
- * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools}, {@link OO.ui.PopupTool PopupTools},
- * and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be registered with a tool factory. Tools are
- * registered by their symbolic name. See {@link OO.ui.Toolbar toolbars} for an example.
- *
- * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @class
- * @extends OO.Factory
- * @constructor
- */
-OO.ui.ToolFactory = function OoUiToolFactory() {
-       // Parent constructor
-       OO.ui.ToolFactory.parent.call( this );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
-
-/* Methods */
-
-/**
- * Get tools from the factory
- *
- * @param {Array|string} [include] Included tools, see #extract for format
- * @param {Array|string} [exclude] Excluded tools, see #extract for format
- * @param {Array|string} [promote] Promoted tools, see #extract for format
- * @param {Array|string} [demote] Demoted tools, see #extract for format
- * @return {string[]} List of tools
- */
-OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
-       var i, len, included, promoted, demoted,
-               auto = [],
-               used = {};
-
-       // Collect included and not excluded tools
-       included = OO.simpleArrayDifference( this.extract( include ), this.extract( exclude ) );
-
-       // Promotion
-       promoted = this.extract( promote, used );
-       demoted = this.extract( demote, used );
-
-       // Auto
-       for ( i = 0, len = included.length; i < len; i++ ) {
-               if ( !used[ included[ i ] ] ) {
-                       auto.push( included[ i ] );
-               }
-       }
-
-       return promoted.concat( auto ).concat( demoted );
-};
-
-/**
- * Get a flat list of names from a list of names or groups.
- *
- * Normally, `collection` is an array of tool specifications. Tools can be specified in the
- * following ways:
- *
- * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.
- * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the
- *   tool to a group, use OO.ui.Tool.static.group.)
- *
- * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the
- * catch-all selector `'*'`.
- *
- * If `used` is passed, tool names that appear as properties in this object will be considered
- * already assigned, and will not be returned even if specified otherwise. The tool names extracted
- * by this function call will be added as new properties in the object.
- *
- * @private
- * @param {Array|string} collection List of tools, see above
- * @param {Object} [used] Object containing information about used tools, see above
- * @return {string[]} List of extracted tool names
- */
-OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
-       var i, len, item, name, tool,
-               names = [];
-
-       if ( collection === '*' ) {
-               for ( name in this.registry ) {
-                       tool = this.registry[ name ];
-                       if (
-                               // Only add tools by group name when auto-add is enabled
-                               tool.static.autoAddToCatchall &&
-                               // Exclude already used tools
-                               ( !used || !used[ name ] )
-                       ) {
-                               names.push( name );
-                               if ( used ) {
-                                       used[ name ] = true;
-                               }
-                       }
-               }
-       } else if ( Array.isArray( collection ) ) {
-               for ( i = 0, len = collection.length; i < len; i++ ) {
-                       item = collection[ i ];
-                       // Allow plain strings as shorthand for named tools
-                       if ( typeof item === 'string' ) {
-                               item = { name: item };
-                       }
-                       if ( OO.isPlainObject( item ) ) {
-                               if ( item.group ) {
-                                       for ( name in this.registry ) {
-                                               tool = this.registry[ name ];
-                                               if (
-                                                       // Include tools with matching group
-                                                       tool.static.group === item.group &&
-                                                       // Only add tools by group name when auto-add is enabled
-                                                       tool.static.autoAddToGroup &&
-                                                       // Exclude already used tools
-                                                       ( !used || !used[ name ] )
-                                               ) {
-                                                       names.push( name );
-                                                       if ( used ) {
-                                                               used[ name ] = true;
-                                                       }
-                                               }
-                                       }
-                               // Include tools with matching name and exclude already used tools
-                               } else if ( item.name && ( !used || !used[ item.name ] ) ) {
-                                       names.push( item.name );
-                                       if ( used ) {
-                                               used[ item.name ] = true;
-                                       }
-                               }
-                       }
-               }
-       }
-       return names;
-};
-
-/**
- * ToolGroupFactories create {@link OO.ui.ToolGroup toolgroups} on demand. The toolgroup classes must
- * specify a symbolic name and be registered with the factory. The following classes are registered by
- * default:
- *
- * - {@link OO.ui.BarToolGroup BarToolGroups} (‘bar’)
- * - {@link OO.ui.MenuToolGroup MenuToolGroups} (‘menu’)
- * - {@link OO.ui.ListToolGroup ListToolGroups} (‘list’)
- *
- * See {@link OO.ui.Toolbar toolbars} for an example.
- *
- * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- * @class
- * @extends OO.Factory
- * @constructor
- */
-OO.ui.ToolGroupFactory = function OoUiToolGroupFactory() {
-       var i, l, defaultClasses;
-       // Parent constructor
-       OO.Factory.call( this );
-
-       defaultClasses = this.constructor.static.getDefaultClasses();
-
-       // Register default toolgroups
-       for ( i = 0, l = defaultClasses.length; i < l; i++ ) {
-               this.register( defaultClasses[ i ] );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToolGroupFactory, OO.Factory );
-
-/* Static Methods */
-
-/**
- * Get a default set of classes to be registered on construction.
- *
- * @return {Function[]} Default classes
- */
-OO.ui.ToolGroupFactory.static.getDefaultClasses = function () {
-       return [
-               OO.ui.BarToolGroup,
-               OO.ui.ListToolGroup,
-               OO.ui.MenuToolGroup
-       ];
-};
-
-/**
- * Theme logic.
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.Theme = function OoUiTheme( config ) {
-       // Configuration initialization
-       config = config || {};
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.Theme );
-
-/* Methods */
-
-/**
- * Get a list of classes to be applied to a widget.
- *
- * The 'on' and 'off' lists combined MUST contain keys for all classes the theme adds or removes,
- * otherwise state transitions will not work properly.
- *
- * @param {OO.ui.Element} element Element for which to get classes
- * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists
- */
-OO.ui.Theme.prototype.getElementClasses = function () {
-       return { on: [], off: [] };
-};
-
-/**
- * Update CSS classes provided by the theme.
- *
- * For elements with theme logic hooks, this should be called any time there's a state change.
- *
- * @param {OO.ui.Element} element Element for which to update classes
- * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists
- */
-OO.ui.Theme.prototype.updateElementClasses = function ( element ) {
-       var $elements = $( [] ),
-               classes = this.getElementClasses( element );
-
-       if ( element.$icon ) {
-               $elements = $elements.add( element.$icon );
-       }
-       if ( element.$indicator ) {
-               $elements = $elements.add( element.$indicator );
-       }
-
-       $elements
-               .removeClass( classes.off.join( ' ' ) )
-               .addClass( classes.on.join( ' ' ) );
-};
-
-/**
- * RequestManager is a mixin that manages the lifecycle of a promise-backed request for a widget, such as
- * the {@link OO.ui.mixin.LookupElement}.
- *
- * @class
- * @abstract
- *
- * @constructor
- */
-OO.ui.mixin.RequestManager = function OoUiMixinRequestManager() {
-       this.requestCache = {};
-       this.requestQuery = null;
-       this.requestRequest = null;
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.RequestManager );
-
-/**
- * Get request results for the current query.
- *
- * @return {jQuery.Promise} Promise object which will be passed response data as the first argument of
- *   the done event. If the request was aborted to make way for a subsequent request, this promise
- *   may not be rejected, depending on what jQuery feels like doing.
- */
-OO.ui.mixin.RequestManager.prototype.getRequestData = function () {
-       var widget = this,
-               value = this.getRequestQuery(),
-               deferred = $.Deferred(),
-               ourRequest;
-
-       this.abortRequest();
-       if ( Object.prototype.hasOwnProperty.call( this.requestCache, value ) ) {
-               deferred.resolve( this.requestCache[ value ] );
-       } else {
-               if ( this.pushPending ) {
-                       this.pushPending();
-               }
-               this.requestQuery = value;
-               ourRequest = this.requestRequest = this.getRequest();
-               ourRequest
-                       .always( function () {
-                               // We need to pop pending even if this is an old request, otherwise
-                               // the widget will remain pending forever.
-                               // TODO: this assumes that an aborted request will fail or succeed soon after
-                               // being aborted, or at least eventually. It would be nice if we could popPending()
-                               // at abort time, but only if we knew that we hadn't already called popPending()
-                               // for that request.
-                               if ( widget.popPending ) {
-                                       widget.popPending();
-                               }
-                       } )
-                       .done( function ( response ) {
-                               // If this is an old request (and aborting it somehow caused it to still succeed),
-                               // ignore its success completely
-                               if ( ourRequest === widget.requestRequest ) {
-                                       widget.requestQuery = null;
-                                       widget.requestRequest = null;
-                                       widget.requestCache[ value ] = widget.getRequestCacheDataFromResponse( response );
-                                       deferred.resolve( widget.requestCache[ value ] );
-                               }
-                       } )
-                       .fail( function () {
-                               // If this is an old request (or a request failing because it's being aborted),
-                               // ignore its failure completely
-                               if ( ourRequest === widget.requestRequest ) {
-                                       widget.requestQuery = null;
-                                       widget.requestRequest = null;
-                                       deferred.reject();
-                               }
-                       } );
-       }
-       return deferred.promise();
-};
-
-/**
- * Abort the currently pending request, if any.
- *
- * @private
- */
-OO.ui.mixin.RequestManager.prototype.abortRequest = function () {
-       var oldRequest = this.requestRequest;
-       if ( oldRequest ) {
-               // First unset this.requestRequest to the fail handler will notice
-               // that the request is no longer current
-               this.requestRequest = null;
-               this.requestQuery = null;
-               oldRequest.abort();
-       }
-};
-
-/**
- * Get the query to be made.
- *
- * @protected
- * @method
- * @abstract
- * @return {string} query to be used
- */
-OO.ui.mixin.RequestManager.prototype.getRequestQuery = null;
-
-/**
- * Get a new request object of the current query value.
- *
- * @protected
- * @method
- * @abstract
- * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
- */
-OO.ui.mixin.RequestManager.prototype.getRequest = null;
-
-/**
- * Pre-process data returned by the request from #getRequest.
- *
- * The return value of this function will be cached, and any further queries for the given value
- * will use the cache rather than doing API requests.
- *
- * @protected
- * @method
- * @abstract
- * @param {Mixed} response Response from server
- * @return {Mixed} Cached result data
- */
-OO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;
-
-/**
- * The TabIndexedElement class is an attribute mixin used to add additional functionality to an
- * element created by another class. The mixin provides a ‘tabIndex’ property, which specifies the
- * order in which users will navigate through the focusable elements via the "tab" key.
- *
- *     @example
- *     // TabIndexedElement is mixed into the ButtonWidget class
- *     // to provide a tabIndex property.
- *     var button1 = new OO.ui.ButtonWidget( {
- *         label: 'fourth',
- *         tabIndex: 4
- *     } );
- *     var button2 = new OO.ui.ButtonWidget( {
- *         label: 'second',
- *         tabIndex: 2
- *     } );
- *     var button3 = new OO.ui.ButtonWidget( {
- *         label: 'third',
- *         tabIndex: 3
- *     } );
- *     var button4 = new OO.ui.ButtonWidget( {
- *         label: 'first',
- *         tabIndex: 1
- *     } );
- *     $( 'body' ).append( button1.$element, button2.$element, button3.$element, button4.$element );
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$tabIndexed] The element that should use the tabindex functionality. By default,
- *  the functionality is applied to the element created by the class ($element). If a different element is specified, the tabindex
- *  functionality will be applied to it instead.
- * @cfg {number|null} [tabIndex=0] Number that specifies the element’s position in the tab-navigation
- *  order (e.g., 1 for the first focusable element). Use 0 to use the default navigation order; use -1
- *  to remove the element from the tab-navigation flow.
- */
-OO.ui.mixin.TabIndexedElement = function OoUiMixinTabIndexedElement( config ) {
-       // Configuration initialization
-       config = $.extend( { tabIndex: 0 }, config );
-
-       // Properties
-       this.$tabIndexed = null;
-       this.tabIndex = null;
-
-       // Events
-       this.connect( this, { disable: 'onTabIndexedElementDisable' } );
-
-       // Initialization
-       this.setTabIndex( config.tabIndex );
-       this.setTabIndexedElement( config.$tabIndexed || this.$element );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * Set the element that should use the tabindex functionality.
- *
- * This method is used to retarget a tabindex mixin so that its functionality applies
- * to the specified element. If an element is currently using the functionality, the mixin’s
- * effect on that element is removed before the new element is set up.
- *
- * @param {jQuery} $tabIndexed Element that should use the tabindex functionality
- * @chainable
- */
-OO.ui.mixin.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed ) {
-       var tabIndex = this.tabIndex;
-       // Remove attributes from old $tabIndexed
-       this.setTabIndex( null );
-       // Force update of new $tabIndexed
-       this.$tabIndexed = $tabIndexed;
-       this.tabIndex = tabIndex;
-       return this.updateTabIndex();
-};
-
-/**
- * Set the value of the tabindex.
- *
- * @param {number|null} tabIndex Tabindex value, or `null` for no tabindex
- * @chainable
- */
-OO.ui.mixin.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {
-       tabIndex = typeof tabIndex === 'number' ? tabIndex : null;
-
-       if ( this.tabIndex !== tabIndex ) {
-               this.tabIndex = tabIndex;
-               this.updateTabIndex();
-       }
-
-       return this;
-};
-
-/**
- * Update the `tabindex` attribute, in case of changes to tab index or
- * disabled state.
- *
- * @private
- * @chainable
- */
-OO.ui.mixin.TabIndexedElement.prototype.updateTabIndex = function () {
-       if ( this.$tabIndexed ) {
-               if ( this.tabIndex !== null ) {
-                       // Do not index over disabled elements
-                       this.$tabIndexed.attr( {
-                               tabindex: this.isDisabled() ? -1 : this.tabIndex,
-                               // Support: ChromeVox and NVDA
-                               // These do not seem to inherit aria-disabled from parent elements
-                               'aria-disabled': this.isDisabled().toString()
-                       } );
-               } else {
-                       this.$tabIndexed.removeAttr( 'tabindex aria-disabled' );
-               }
-       }
-       return this;
-};
-
-/**
- * Handle disable events.
- *
- * @private
- * @param {boolean} disabled Element is disabled
- */
-OO.ui.mixin.TabIndexedElement.prototype.onTabIndexedElementDisable = function () {
-       this.updateTabIndex();
-};
-
-/**
- * Get the value of the tabindex.
- *
- * @return {number|null} Tabindex value
- */
-OO.ui.mixin.TabIndexedElement.prototype.getTabIndex = function () {
-       return this.tabIndex;
-};
-
-/**
- * ButtonElement is often mixed into other classes to generate a button, which is a clickable
- * interface element that can be configured with access keys for accessibility.
- * See the [OOjs UI documentation on MediaWiki] [1] for examples.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#Buttons
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$button] The button element created by the class.
- *  If this configuration is omitted, the button element will use a generated `<a>`.
- * @cfg {boolean} [framed=true] Render the button with a frame
- */
-OO.ui.mixin.ButtonElement = function OoUiMixinButtonElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$button = null;
-       this.framed = null;
-       this.active = false;
-       this.onMouseUpHandler = this.onMouseUp.bind( this );
-       this.onMouseDownHandler = this.onMouseDown.bind( this );
-       this.onKeyDownHandler = this.onKeyDown.bind( this );
-       this.onKeyUpHandler = this.onKeyUp.bind( this );
-       this.onClickHandler = this.onClick.bind( this );
-       this.onKeyPressHandler = this.onKeyPress.bind( this );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-buttonElement' );
-       this.toggleFramed( config.framed === undefined || config.framed );
-       this.setButtonElement( config.$button || $( '<a>' ) );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.ButtonElement );
-
-/* Static Properties */
-
-/**
- * Cancel mouse down events.
- *
- * This property is usually set to `true` to prevent the focus from changing when the button is clicked.
- * Classes such as {@link OO.ui.mixin.DraggableElement DraggableElement} and {@link OO.ui.ButtonOptionWidget ButtonOptionWidget}
- * use a value of `false` so that dragging behavior is possible and mousedown events can be handled by a
- * parent widget.
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.mixin.ButtonElement.static.cancelButtonMouseDownEvents = true;
-
-/* Events */
-
-/**
- * A 'click' event is emitted when the button element is clicked.
- *
- * @event click
- */
-
-/* Methods */
-
-/**
- * Set the button element.
- *
- * This method is used to retarget a button mixin so that its functionality applies to
- * the specified button element instead of the one created by the class. If a button element
- * is already set, the method will remove the mixin’s effect on that element.
- *
- * @param {jQuery} $button Element to use as button
- */
-OO.ui.mixin.ButtonElement.prototype.setButtonElement = function ( $button ) {
-       if ( this.$button ) {
-               this.$button
-                       .removeClass( 'oo-ui-buttonElement-button' )
-                       .removeAttr( 'role accesskey' )
-                       .off( {
-                               mousedown: this.onMouseDownHandler,
-                               keydown: this.onKeyDownHandler,
-                               click: this.onClickHandler,
-                               keypress: this.onKeyPressHandler
-                       } );
-       }
-
-       this.$button = $button
-               .addClass( 'oo-ui-buttonElement-button' )
-               .attr( { role: 'button' } )
-               .on( {
-                       mousedown: this.onMouseDownHandler,
-                       keydown: this.onKeyDownHandler,
-                       click: this.onClickHandler,
-                       keypress: this.onKeyPressHandler
-               } );
-};
-
-/**
- * Handles mouse down events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse down event
- */
-OO.ui.mixin.ButtonElement.prototype.onMouseDown = function ( e ) {
-       if ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {
-               return;
-       }
-       this.$element.addClass( 'oo-ui-buttonElement-pressed' );
-       // Run the mouseup handler no matter where the mouse is when the button is let go, so we can
-       // reliably remove the pressed class
-       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
-       // Prevent change of focus unless specifically configured otherwise
-       if ( this.constructor.static.cancelButtonMouseDownEvents ) {
-               return false;
-       }
-};
-
-/**
- * Handles mouse up events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse up event
- */
-OO.ui.mixin.ButtonElement.prototype.onMouseUp = function ( e ) {
-       if ( this.isDisabled() || e.which !== OO.ui.MouseButtons.LEFT ) {
-               return;
-       }
-       this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
-       // Stop listening for mouseup, since we only needed this once
-       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
-};
-
-/**
- * Handles mouse click events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse click event
- * @fires click
- */
-OO.ui.mixin.ButtonElement.prototype.onClick = function ( e ) {
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               if ( this.emit( 'click' ) ) {
-                       return false;
-               }
-       }
-};
-
-/**
- * Handles key down events.
- *
- * @protected
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.mixin.ButtonElement.prototype.onKeyDown = function ( e ) {
-       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
-               return;
-       }
-       this.$element.addClass( 'oo-ui-buttonElement-pressed' );
-       // Run the keyup handler no matter where the key is when the button is let go, so we can
-       // reliably remove the pressed class
-       this.getElementDocument().addEventListener( 'keyup', this.onKeyUpHandler, true );
-};
-
-/**
- * Handles key up events.
- *
- * @protected
- * @param {jQuery.Event} e Key up event
- */
-OO.ui.mixin.ButtonElement.prototype.onKeyUp = function ( e ) {
-       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
-               return;
-       }
-       this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
-       // Stop listening for keyup, since we only needed this once
-       this.getElementDocument().removeEventListener( 'keyup', this.onKeyUpHandler, true );
-};
-
-/**
- * Handles key press events.
- *
- * @protected
- * @param {jQuery.Event} e Key press event
- * @fires click
- */
-OO.ui.mixin.ButtonElement.prototype.onKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               if ( this.emit( 'click' ) ) {
-                       return false;
-               }
-       }
-};
-
-/**
- * Check if button has a frame.
- *
- * @return {boolean} Button is framed
- */
-OO.ui.mixin.ButtonElement.prototype.isFramed = function () {
-       return this.framed;
-};
-
-/**
- * Render the button with or without a frame. Omit the `framed` parameter to toggle the button frame on and off.
- *
- * @param {boolean} [framed] Make button framed, omit to toggle
- * @chainable
- */
-OO.ui.mixin.ButtonElement.prototype.toggleFramed = function ( framed ) {
-       framed = framed === undefined ? !this.framed : !!framed;
-       if ( framed !== this.framed ) {
-               this.framed = framed;
-               this.$element
-                       .toggleClass( 'oo-ui-buttonElement-frameless', !framed )
-                       .toggleClass( 'oo-ui-buttonElement-framed', framed );
-               this.updateThemeClasses();
-       }
-
-       return this;
-};
-
-/**
- * Set the button's active state.
- *
- * The active state occurs when a {@link OO.ui.ButtonOptionWidget ButtonOptionWidget} or
- * a {@link OO.ui.ToggleButtonWidget ToggleButtonWidget} is pressed. This method does nothing
- * for other button types.
- *
- * @param {boolean} value Make button active
- * @chainable
- */
-OO.ui.mixin.ButtonElement.prototype.setActive = function ( value ) {
-       this.active = !!value;
-       this.$element.toggleClass( 'oo-ui-buttonElement-active', this.active );
-       return this;
-};
-
-/**
- * Check if the button is active
- *
- * @return {boolean} The button is active
- */
-OO.ui.mixin.ButtonElement.prototype.isActive = function () {
-       return this.active;
-};
-
-/**
- * Any OOjs UI widget that contains other widgets (such as {@link OO.ui.ButtonWidget buttons} or
- * {@link OO.ui.OptionWidget options}) mixes in GroupElement. Adding, removing, and clearing
- * items from the group is done through the interface the class provides.
- * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Groups
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$group] The container element created by the class. If this configuration
- *  is omitted, the group element will use a generated `<div>`.
- */
-OO.ui.mixin.GroupElement = function OoUiMixinGroupElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$group = null;
-       this.items = [];
-       this.aggregateItemEvents = {};
-
-       // Initialization
-       this.setGroupElement( config.$group || $( '<div>' ) );
-};
-
-/* Methods */
-
-/**
- * Set the group element.
- *
- * If an element is already set, items will be moved to the new element.
- *
- * @param {jQuery} $group Element to use as group
- */
-OO.ui.mixin.GroupElement.prototype.setGroupElement = function ( $group ) {
-       var i, len;
-
-       this.$group = $group;
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               this.$group.append( this.items[ i ].$element );
-       }
-};
-
-/**
- * Check if a group contains no items.
- *
- * @return {boolean} Group is empty
- */
-OO.ui.mixin.GroupElement.prototype.isEmpty = function () {
-       return !this.items.length;
-};
-
-/**
- * Get all items in the group.
- *
- * The method returns an array of item references (e.g., [button1, button2, button3]) and is useful
- * when synchronizing groups of items, or whenever the references are required (e.g., when removing items
- * from a group).
- *
- * @return {OO.ui.Element[]} An array of items.
- */
-OO.ui.mixin.GroupElement.prototype.getItems = function () {
-       return this.items.slice( 0 );
-};
-
-/**
- * Get an item by its data.
- *
- * Only the first item with matching data will be returned. To return all matching items,
- * use the #getItemsFromData method.
- *
- * @param {Object} data Item data to search for
- * @return {OO.ui.Element|null} Item with equivalent data, `null` if none exists
- */
-OO.ui.mixin.GroupElement.prototype.getItemFromData = function ( data ) {
-       var i, len, item,
-               hash = OO.getHash( data );
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               item = this.items[ i ];
-               if ( hash === OO.getHash( item.getData() ) ) {
-                       return item;
-               }
-       }
-
-       return null;
-};
-
-/**
- * Get items by their data.
- *
- * All items with matching data will be returned. To return only the first match, use the #getItemFromData method instead.
- *
- * @param {Object} data Item data to search for
- * @return {OO.ui.Element[]} Items with equivalent data
- */
-OO.ui.mixin.GroupElement.prototype.getItemsFromData = function ( data ) {
-       var i, len, item,
-               hash = OO.getHash( data ),
-               items = [];
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               item = this.items[ i ];
-               if ( hash === OO.getHash( item.getData() ) ) {
-                       items.push( item );
-               }
-       }
-
-       return items;
-};
-
-/**
- * Aggregate the events emitted by the group.
- *
- * When events are aggregated, the group will listen to all contained items for the event,
- * and then emit the event under a new name. The new event will contain an additional leading
- * parameter containing the item that emitted the original event. Other arguments emitted from
- * the original event are passed through.
- *
- * @param {Object.<string,string|null>} events An object keyed by the name of the event that should be
- *  aggregated  (e.g., ‘click’) and the value of the new name to use (e.g., ‘groupClick’).
- *  A `null` value will remove aggregated events.
-
- * @throws {Error} An error is thrown if aggregation already exists.
- */
-OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
-       var i, len, item, add, remove, itemEvent, groupEvent;
-
-       for ( itemEvent in events ) {
-               groupEvent = events[ itemEvent ];
-
-               // Remove existing aggregated event
-               if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
-                       // Don't allow duplicate aggregations
-                       if ( groupEvent ) {
-                               throw new Error( 'Duplicate item event aggregation for ' + itemEvent );
-                       }
-                       // Remove event aggregation from existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       remove = {};
-                                       remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                                       item.disconnect( this, remove );
-                               }
-                       }
-                       // Prevent future items from aggregating event
-                       delete this.aggregateItemEvents[ itemEvent ];
-               }
-
-               // Add new aggregate event
-               if ( groupEvent ) {
-                       // Make future items aggregate event
-                       this.aggregateItemEvents[ itemEvent ] = groupEvent;
-                       // Add event aggregation to existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       add = {};
-                                       add[ itemEvent ] = [ 'emit', groupEvent, item ];
-                                       item.connect( this, add );
-                               }
-                       }
-               }
-       }
-};
-
-/**
- * Add items to the group.
- *
- * Items will be added to the end of the group array unless the optional `index` parameter specifies
- * a different insertion point. Adding an existing item will move it to the end of the array or the point specified by the `index`.
- *
- * @param {OO.ui.Element[]} items An array of items to add to the group
- * @param {number} [index] Index of the insertion point
- * @chainable
- */
-OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
-       var i, len, item, event, events, currentIndex,
-               itemElements = [];
-
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-
-               // Check if item exists then remove it first, effectively "moving" it
-               currentIndex = this.items.indexOf( item );
-               if ( currentIndex >= 0 ) {
-                       this.removeItems( [ item ] );
-                       // Adjust index to compensate for removal
-                       if ( currentIndex < index ) {
-                               index--;
-                       }
-               }
-               // Add the item
-               if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) {
-                       events = {};
-                       for ( event in this.aggregateItemEvents ) {
-                               events[ event ] = [ 'emit', this.aggregateItemEvents[ event ], item ];
-                       }
-                       item.connect( this, events );
-               }
-               item.setElementGroup( this );
-               itemElements.push( item.$element.get( 0 ) );
-       }
-
-       if ( index === undefined || index < 0 || index >= this.items.length ) {
-               this.$group.append( itemElements );
-               this.items.push.apply( this.items, items );
-       } else if ( index === 0 ) {
-               this.$group.prepend( itemElements );
-               this.items.unshift.apply( this.items, items );
-       } else {
-               this.items[ index ].$element.before( itemElements );
-               this.items.splice.apply( this.items, [ index, 0 ].concat( items ) );
-       }
-
-       return this;
-};
-
-/**
- * Remove the specified items from a group.
- *
- * Removed items are detached (not removed) from the DOM so that they may be reused.
- * To remove all items from a group, you may wish to use the #clearItems method instead.
- *
- * @param {OO.ui.Element[]} items An array of items to remove
- * @chainable
- */
-OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
-       var i, len, item, index, remove, itemEvent;
-
-       // Remove specific items
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-               index = this.items.indexOf( item );
-               if ( index !== -1 ) {
-                       if (
-                               item.connect && item.disconnect &&
-                               !$.isEmptyObject( this.aggregateItemEvents )
-                       ) {
-                               remove = {};
-                               if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
-                                       remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                               }
-                               item.disconnect( this, remove );
-                       }
-                       item.setElementGroup( null );
-                       this.items.splice( index, 1 );
-                       item.$element.detach();
-               }
-       }
-
-       return this;
-};
-
-/**
- * Clear all items from the group.
- *
- * Cleared items are detached from the DOM, not removed, so that they may be reused.
- * To remove only a subset of items from a group, use the #removeItems method.
- *
- * @chainable
- */
-OO.ui.mixin.GroupElement.prototype.clearItems = function () {
-       var i, len, item, remove, itemEvent;
-
-       // Remove all items
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               item = this.items[ i ];
-               if (
-                       item.connect && item.disconnect &&
-                       !$.isEmptyObject( this.aggregateItemEvents )
-               ) {
-                       remove = {};
-                       if ( Object.prototype.hasOwnProperty.call( this.aggregateItemEvents, itemEvent ) ) {
-                               remove[ itemEvent ] = [ 'emit', this.aggregateItemEvents[ itemEvent ], item ];
-                       }
-                       item.disconnect( this, remove );
-               }
-               item.setElementGroup( null );
-               item.$element.detach();
-       }
-
-       this.items = [];
-       return this;
-};
-
-/**
- * DraggableElement is a mixin class used to create elements that can be clicked
- * and dragged by a mouse to a new position within a group. This class must be used
- * in conjunction with OO.ui.mixin.DraggableGroupElement, which provides a container for
- * the draggable elements.
- *
- * @abstract
- * @class
- *
- * @constructor
- */
-OO.ui.mixin.DraggableElement = function OoUiMixinDraggableElement() {
-       // Properties
-       this.index = null;
-
-       // Initialize and events
-       this.$element
-               .attr( 'draggable', true )
-               .addClass( 'oo-ui-draggableElement' )
-               .on( {
-                       dragstart: this.onDragStart.bind( this ),
-                       dragover: this.onDragOver.bind( this ),
-                       dragend: this.onDragEnd.bind( this ),
-                       drop: this.onDrop.bind( this )
-               } );
-};
-
-OO.initClass( OO.ui.mixin.DraggableElement );
-
-/* Events */
-
-/**
- * @event dragstart
- *
- * A dragstart event is emitted when the user clicks and begins dragging an item.
- * @param {OO.ui.mixin.DraggableElement} item The item the user has clicked and is dragging with the mouse.
- */
-
-/**
- * @event dragend
- * A dragend event is emitted when the user drags an item and releases the mouse,
- * thus terminating the drag operation.
- */
-
-/**
- * @event drop
- * A drop event is emitted when the user drags an item and then releases the mouse button
- * over a valid target.
- */
-
-/* Static Properties */
-
-/**
- * @inheritdoc OO.ui.mixin.ButtonElement
- */
-OO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;
-
-/* Methods */
-
-/**
- * Respond to dragstart event.
- *
- * @private
- * @param {jQuery.Event} event jQuery event
- * @fires dragstart
- */
-OO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {
-       var dataTransfer = e.originalEvent.dataTransfer;
-       // Define drop effect
-       dataTransfer.dropEffect = 'none';
-       dataTransfer.effectAllowed = 'move';
-       // Support: Firefox
-       // We must set up a dataTransfer data property or Firefox seems to
-       // ignore the fact the element is draggable.
-       try {
-               dataTransfer.setData( 'application-x/OOjs-UI-draggable', this.getIndex() );
-       } catch ( err ) {
-               // The above is only for Firefox. Move on if it fails.
-       }
-       // Add dragging class
-       this.$element.addClass( 'oo-ui-draggableElement-dragging' );
-       // Emit event
-       this.emit( 'dragstart', this );
-       return true;
-};
-
-/**
- * Respond to dragend event.
- *
- * @private
- * @fires dragend
- */
-OO.ui.mixin.DraggableElement.prototype.onDragEnd = function () {
-       this.$element.removeClass( 'oo-ui-draggableElement-dragging' );
-       this.emit( 'dragend' );
-};
-
-/**
- * Handle drop event.
- *
- * @private
- * @param {jQuery.Event} event jQuery event
- * @fires drop
- */
-OO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {
-       e.preventDefault();
-       this.emit( 'drop', e );
-};
-
-/**
- * In order for drag/drop to work, the dragover event must
- * return false and stop propogation.
- *
- * @private
- */
-OO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {
-       e.preventDefault();
-};
-
-/**
- * Set item index.
- * Store it in the DOM so we can access from the widget drag event
- *
- * @private
- * @param {number} Item index
- */
-OO.ui.mixin.DraggableElement.prototype.setIndex = function ( index ) {
-       if ( this.index !== index ) {
-               this.index = index;
-               this.$element.data( 'index', index );
-       }
-};
-
-/**
- * Get item index
- *
- * @private
- * @return {number} Item index
- */
-OO.ui.mixin.DraggableElement.prototype.getIndex = function () {
-       return this.index;
-};
-
-/**
- * DraggableGroupElement is a mixin class used to create a group element to
- * contain draggable elements, which are items that can be clicked and dragged by a mouse.
- * The class is used with OO.ui.mixin.DraggableElement.
- *
- * @abstract
- * @class
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [orientation] Item orientation: 'horizontal' or 'vertical'. The orientation
- *  should match the layout of the items. Items displayed in a single row
- *  or in several rows should use horizontal orientation. The vertical orientation should only be
- *  used when the items are displayed in a single column. Defaults to 'vertical'
- */
-OO.ui.mixin.DraggableGroupElement = function OoUiMixinDraggableGroupElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.mixin.GroupElement.call( this, config );
-
-       // Properties
-       this.orientation = config.orientation || 'vertical';
-       this.dragItem = null;
-       this.itemDragOver = null;
-       this.itemKeys = {};
-       this.sideInsertion = '';
-
-       // Events
-       this.aggregate( {
-               dragstart: 'itemDragStart',
-               dragend: 'itemDragEnd',
-               drop: 'itemDrop'
-       } );
-       this.connect( this, {
-               itemDragStart: 'onItemDragStart',
-               itemDrop: 'onItemDrop',
-               itemDragEnd: 'onItemDragEnd'
-       } );
-       this.$element.on( {
-               dragover: this.onDragOver.bind( this ),
-               dragleave: this.onDragLeave.bind( this )
-       } );
-
-       // Initialize
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-       this.$placeholder = $( '<div>' )
-               .addClass( 'oo-ui-draggableGroupElement-placeholder' );
-       this.$element
-               .addClass( 'oo-ui-draggableGroupElement' )
-               .append( this.$status )
-               .toggleClass( 'oo-ui-draggableGroupElement-horizontal', this.orientation === 'horizontal' )
-               .prepend( this.$placeholder );
-};
-
-/* Setup */
-OO.mixinClass( OO.ui.mixin.DraggableGroupElement, OO.ui.mixin.GroupElement );
-
-/* Events */
-
-/**
- * A 'reorder' event is emitted when the order of items in the group changes.
- *
- * @event reorder
- * @param {OO.ui.mixin.DraggableElement} item Reordered item
- * @param {number} [newIndex] New index for the item
- */
-
-/* Methods */
-
-/**
- * Respond to item drag start event
- *
- * @private
- * @param {OO.ui.mixin.DraggableElement} item Dragged item
- */
-OO.ui.mixin.DraggableGroupElement.prototype.onItemDragStart = function ( item ) {
-       var i, len;
-
-       // Map the index of each object
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               this.items[ i ].setIndex( i );
-       }
-
-       if ( this.orientation === 'horizontal' ) {
-               // Set the height of the indicator
-               this.$placeholder.css( {
-                       height: item.$element.outerHeight(),
-                       width: 2
-               } );
-       } else {
-               // Set the width of the indicator
-               this.$placeholder.css( {
-                       height: 2,
-                       width: item.$element.outerWidth()
-               } );
-       }
-       this.setDragItem( item );
-};
-
-/**
- * Respond to item drag end event
- *
- * @private
- */
-OO.ui.mixin.DraggableGroupElement.prototype.onItemDragEnd = function () {
-       this.unsetDragItem();
-       return false;
-};
-
-/**
- * Handle drop event and switch the order of the items accordingly
- *
- * @private
- * @param {OO.ui.mixin.DraggableElement} item Dropped item
- * @fires reorder
- */
-OO.ui.mixin.DraggableGroupElement.prototype.onItemDrop = function ( item ) {
-       var toIndex = item.getIndex();
-       // Check if the dropped item is from the current group
-       // TODO: Figure out a way to configure a list of legally droppable
-       // elements even if they are not yet in the list
-       if ( this.getDragItem() ) {
-               // If the insertion point is 'after', the insertion index
-               // is shifted to the right (or to the left in RTL, hence 'after')
-               if ( this.sideInsertion === 'after' ) {
-                       toIndex++;
-               }
-               // Emit change event
-               this.emit( 'reorder', this.getDragItem(), toIndex );
-       }
-       this.unsetDragItem();
-       // Return false to prevent propogation
-       return false;
-};
-
-/**
- * Handle dragleave event.
- *
- * @private
- */
-OO.ui.mixin.DraggableGroupElement.prototype.onDragLeave = function () {
-       // This means the item was dragged outside the widget
-       this.$placeholder
-               .css( 'left', 0 )
-               .addClass( 'oo-ui-element-hidden' );
-};
-
-/**
- * Respond to dragover event
- *
- * @private
- * @param {jQuery.Event} event Event details
- */
-OO.ui.mixin.DraggableGroupElement.prototype.onDragOver = function ( e ) {
-       var dragOverObj, $optionWidget, itemOffset, itemMidpoint, itemBoundingRect,
-               itemSize, cssOutput, dragPosition, itemIndex, itemPosition,
-               clientX = e.originalEvent.clientX,
-               clientY = e.originalEvent.clientY;
-
-       // Get the OptionWidget item we are dragging over
-       dragOverObj = this.getElementDocument().elementFromPoint( clientX, clientY );
-       $optionWidget = $( dragOverObj ).closest( '.oo-ui-draggableElement' );
-       if ( $optionWidget[ 0 ] ) {
-               itemOffset = $optionWidget.offset();
-               itemBoundingRect = $optionWidget[ 0 ].getBoundingClientRect();
-               itemPosition = $optionWidget.position();
-               itemIndex = $optionWidget.data( 'index' );
-       }
-
-       if (
-               itemOffset &&
-               this.isDragging() &&
-               itemIndex !== this.getDragItem().getIndex()
-       ) {
-               if ( this.orientation === 'horizontal' ) {
-                       // Calculate where the mouse is relative to the item width
-                       itemSize = itemBoundingRect.width;
-                       itemMidpoint = itemBoundingRect.left + itemSize / 2;
-                       dragPosition = clientX;
-                       // Which side of the item we hover over will dictate
-                       // where the placeholder will appear, on the left or
-                       // on the right
-                       cssOutput = {
-                               left: dragPosition < itemMidpoint ? itemPosition.left : itemPosition.left + itemSize,
-                               top: itemPosition.top
-                       };
-               } else {
-                       // Calculate where the mouse is relative to the item height
-                       itemSize = itemBoundingRect.height;
-                       itemMidpoint = itemBoundingRect.top + itemSize / 2;
-                       dragPosition = clientY;
-                       // Which side of the item we hover over will dictate
-                       // where the placeholder will appear, on the top or
-                       // on the bottom
-                       cssOutput = {
-                               top: dragPosition < itemMidpoint ? itemPosition.top : itemPosition.top + itemSize,
-                               left: itemPosition.left
-                       };
-               }
-               // Store whether we are before or after an item to rearrange
-               // For horizontal layout, we need to account for RTL, as this is flipped
-               if (  this.orientation === 'horizontal' && this.$element.css( 'direction' ) === 'rtl' ) {
-                       this.sideInsertion = dragPosition < itemMidpoint ? 'after' : 'before';
-               } else {
-                       this.sideInsertion = dragPosition < itemMidpoint ? 'before' : 'after';
-               }
-               // Add drop indicator between objects
-               this.$placeholder
-                       .css( cssOutput )
-                       .removeClass( 'oo-ui-element-hidden' );
-       } else {
-               // This means the item was dragged outside the widget
-               this.$placeholder
-                       .css( 'left', 0 )
-                       .addClass( 'oo-ui-element-hidden' );
-       }
-       // Prevent default
-       e.preventDefault();
-};
-
-/**
- * Set a dragged item
- *
- * @param {OO.ui.mixin.DraggableElement} item Dragged item
- */
-OO.ui.mixin.DraggableGroupElement.prototype.setDragItem = function ( item ) {
-       this.dragItem = item;
-};
-
-/**
- * Unset the current dragged item
- */
-OO.ui.mixin.DraggableGroupElement.prototype.unsetDragItem = function () {
-       this.dragItem = null;
-       this.itemDragOver = null;
-       this.$placeholder.addClass( 'oo-ui-element-hidden' );
-       this.sideInsertion = '';
-};
-
-/**
- * Get the item that is currently being dragged.
- *
- * @return {OO.ui.mixin.DraggableElement|null} The currently dragged item, or `null` if no item is being dragged
- */
-OO.ui.mixin.DraggableGroupElement.prototype.getDragItem = function () {
-       return this.dragItem;
-};
-
-/**
- * Check if an item in the group is currently being dragged.
- *
- * @return {Boolean} Item is being dragged
- */
-OO.ui.mixin.DraggableGroupElement.prototype.isDragging = function () {
-       return this.getDragItem() !== null;
-};
-
-/**
- * IconElement is often mixed into other classes to generate an icon.
- * Icons are graphics, about the size of normal text. They are used to aid the user
- * in locating a control or to convey information in a space-efficient way. See the
- * [OOjs UI documentation on MediaWiki] [1] for a list of icons
- * included in the library.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$icon] The icon element created by the class. If this configuration is omitted,
- *  the icon element will use a generated `<span>`. To use a different HTML tag, or to specify that
- *  the icon element be set to an existing icon instead of the one generated by this class, set a
- *  value using a jQuery selection. For example:
- *
- *      // Use a <div> tag instead of a <span>
- *     $icon: $("<div>")
- *     // Use an existing icon element instead of the one generated by the class
- *     $icon: this.$element
- *     // Use an icon element from a child widget
- *     $icon: this.childwidget.$element
- * @cfg {Object|string} [icon=''] The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of
- *  symbolic names.  A map is used for i18n purposes and contains a `default` icon
- *  name and additional names keyed by language code. The `default` name is used when no icon is keyed
- *  by the user's language.
- *
- *  Example of an i18n map:
- *
- *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
- *  See the [OOjs UI documentation on MediaWiki] [2] for a list of icons included in the library.
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
- * @cfg {string|Function} [iconTitle] A text string used as the icon title, or a function that returns title
- *  text. The icon title is displayed when users move the mouse over the icon.
- */
-OO.ui.mixin.IconElement = function OoUiMixinIconElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$icon = null;
-       this.icon = null;
-       this.iconTitle = null;
-
-       // Initialization
-       this.setIcon( config.icon || this.constructor.static.icon );
-       this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
-       this.setIconElement( config.$icon || $( '<span>' ) );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.IconElement );
-
-/* Static Properties */
-
-/**
- * The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names. A map is used
- * for i18n purposes and contains a `default` icon name and additional names keyed by
- * language code. The `default` name is used when no icon is keyed by the user's language.
- *
- * Example of an i18n map:
- *
- *     { default: 'bold-a', en: 'bold-b', de: 'bold-f' }
- *
- * Note: the static property will be overridden if the #icon configuration is used.
- *
- * @static
- * @inheritable
- * @property {Object|string}
- */
-OO.ui.mixin.IconElement.static.icon = null;
-
-/**
- * The icon title, displayed when users move the mouse over the icon. The value can be text, a
- * function that returns title text, or `null` for no title.
- *
- * The static property will be overridden if the #iconTitle configuration is used.
- *
- * @static
- * @inheritable
- * @property {string|Function|null}
- */
-OO.ui.mixin.IconElement.static.iconTitle = null;
-
-/* Methods */
-
-/**
- * Set the icon element. This method is used to retarget an icon mixin so that its functionality
- * applies to the specified icon element instead of the one created by the class. If an icon
- * element is already set, the mixin’s effect on that element is removed. Generated CSS classes
- * and mixin methods will no longer affect the element.
- *
- * @param {jQuery} $icon Element to use as icon
- */
-OO.ui.mixin.IconElement.prototype.setIconElement = function ( $icon ) {
-       if ( this.$icon ) {
-               this.$icon
-                       .removeClass( 'oo-ui-iconElement-icon oo-ui-icon-' + this.icon )
-                       .removeAttr( 'title' );
-       }
-
-       this.$icon = $icon
-               .addClass( 'oo-ui-iconElement-icon' )
-               .toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );
-       if ( this.iconTitle !== null ) {
-               this.$icon.attr( 'title', this.iconTitle );
-       }
-
-       this.updateThemeClasses();
-};
-
-/**
- * Set icon by symbolic name (e.g., ‘remove’ or ‘menu’). Use `null` to remove an icon.
- * The icon parameter can also be set to a map of icon names. See the #icon config setting
- * for an example.
- *
- * @param {Object|string|null} icon A symbolic icon name, a {@link #icon map of icon names} keyed
- *  by language code, or `null` to remove the icon.
- * @chainable
- */
-OO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {
-       icon = OO.isPlainObject( icon ) ? OO.ui.getLocalValue( icon, null, 'default' ) : icon;
-       icon = typeof icon === 'string' && icon.trim().length ? icon.trim() : null;
-
-       if ( this.icon !== icon ) {
-               if ( this.$icon ) {
-                       if ( this.icon !== null ) {
-                               this.$icon.removeClass( 'oo-ui-icon-' + this.icon );
-                       }
-                       if ( icon !== null ) {
-                               this.$icon.addClass( 'oo-ui-icon-' + icon );
-                       }
-               }
-               this.icon = icon;
-       }
-
-       this.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );
-       this.updateThemeClasses();
-
-       return this;
-};
-
-/**
- * Set the icon title. Use `null` to remove the title.
- *
- * @param {string|Function|null} iconTitle A text string used as the icon title,
- *  a function that returns title text, or `null` for no title.
- * @chainable
- */
-OO.ui.mixin.IconElement.prototype.setIconTitle = function ( iconTitle ) {
-       iconTitle = typeof iconTitle === 'function' ||
-               ( typeof iconTitle === 'string' && iconTitle.length ) ?
-                       OO.ui.resolveMsg( iconTitle ) : null;
-
-       if ( this.iconTitle !== iconTitle ) {
-               this.iconTitle = iconTitle;
-               if ( this.$icon ) {
-                       if ( this.iconTitle !== null ) {
-                               this.$icon.attr( 'title', iconTitle );
-                       } else {
-                               this.$icon.removeAttr( 'title' );
-                       }
-               }
-       }
-
-       return this;
-};
-
-/**
- * Get the symbolic name of the icon.
- *
- * @return {string} Icon name
- */
-OO.ui.mixin.IconElement.prototype.getIcon = function () {
-       return this.icon;
-};
-
-/**
- * Get the icon title. The title text is displayed when a user moves the mouse over the icon.
- *
- * @return {string} Icon title text
- */
-OO.ui.mixin.IconElement.prototype.getIconTitle = function () {
-       return this.iconTitle;
-};
-
-/**
- * IndicatorElement is often mixed into other classes to generate an indicator.
- * Indicators are small graphics that are generally used in two ways:
- *
- * - To draw attention to the status of an item. For example, an indicator might be
- *   used to show that an item in a list has errors that need to be resolved.
- * - To clarify the function of a control that acts in an exceptional way (a button
- *   that opens a menu instead of performing an action directly, for example).
- *
- * For a list of indicators included in the library, please see the
- * [OOjs UI documentation on MediaWiki] [1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$indicator] The indicator element created by the class. If this
- *  configuration is omitted, the indicator element will use a generated `<span>`.
- * @cfg {string} [indicator] Symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
- *  See the [OOjs UI documentation on MediaWiki][2] for a list of indicators included
- *  in the library.
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
- * @cfg {string|Function} [indicatorTitle] A text string used as the indicator title,
- *  or a function that returns title text. The indicator title is displayed when users move
- *  the mouse over the indicator.
- */
-OO.ui.mixin.IndicatorElement = function OoUiMixinIndicatorElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$indicator = null;
-       this.indicator = null;
-       this.indicatorTitle = null;
-
-       // Initialization
-       this.setIndicator( config.indicator || this.constructor.static.indicator );
-       this.setIndicatorTitle( config.indicatorTitle || this.constructor.static.indicatorTitle );
-       this.setIndicatorElement( config.$indicator || $( '<span>' ) );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.IndicatorElement );
-
-/* Static Properties */
-
-/**
- * Symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
- * The static property will be overridden if the #indicator configuration is used.
- *
- * @static
- * @inheritable
- * @property {string|null}
- */
-OO.ui.mixin.IndicatorElement.static.indicator = null;
-
-/**
- * A text string used as the indicator title, a function that returns title text, or `null`
- * for no title. The static property will be overridden if the #indicatorTitle configuration is used.
- *
- * @static
- * @inheritable
- * @property {string|Function|null}
- */
-OO.ui.mixin.IndicatorElement.static.indicatorTitle = null;
-
-/* Methods */
-
-/**
- * Set the indicator element.
- *
- * If an element is already set, it will be cleaned up before setting up the new element.
- *
- * @param {jQuery} $indicator Element to use as indicator
- */
-OO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicator ) {
-       if ( this.$indicator ) {
-               this.$indicator
-                       .removeClass( 'oo-ui-indicatorElement-indicator oo-ui-indicator-' + this.indicator )
-                       .removeAttr( 'title' );
-       }
-
-       this.$indicator = $indicator
-               .addClass( 'oo-ui-indicatorElement-indicator' )
-               .toggleClass( 'oo-ui-indicator-' + this.indicator, !!this.indicator );
-       if ( this.indicatorTitle !== null ) {
-               this.$indicator.attr( 'title', this.indicatorTitle );
-       }
-
-       this.updateThemeClasses();
-};
-
-/**
- * Set the indicator by its symbolic name: ‘alert’, ‘down’, ‘next’, ‘previous’, ‘required’, ‘up’. Use `null` to remove the indicator.
- *
- * @param {string|null} indicator Symbolic name of indicator, or `null` for no indicator
- * @chainable
- */
-OO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {
-       indicator = typeof indicator === 'string' && indicator.length ? indicator.trim() : null;
-
-       if ( this.indicator !== indicator ) {
-               if ( this.$indicator ) {
-                       if ( this.indicator !== null ) {
-                               this.$indicator.removeClass( 'oo-ui-indicator-' + this.indicator );
-                       }
-                       if ( indicator !== null ) {
-                               this.$indicator.addClass( 'oo-ui-indicator-' + indicator );
-                       }
-               }
-               this.indicator = indicator;
-       }
-
-       this.$element.toggleClass( 'oo-ui-indicatorElement', !!this.indicator );
-       this.updateThemeClasses();
-
-       return this;
-};
-
-/**
- * Set the indicator title.
- *
- * The title is displayed when a user moves the mouse over the indicator.
- *
- * @param {string|Function|null} indicator Indicator title text, a function that returns text, or
- *   `null` for no indicator title
- * @chainable
- */
-OO.ui.mixin.IndicatorElement.prototype.setIndicatorTitle = function ( indicatorTitle ) {
-       indicatorTitle = typeof indicatorTitle === 'function' ||
-               ( typeof indicatorTitle === 'string' && indicatorTitle.length ) ?
-                       OO.ui.resolveMsg( indicatorTitle ) : null;
-
-       if ( this.indicatorTitle !== indicatorTitle ) {
-               this.indicatorTitle = indicatorTitle;
-               if ( this.$indicator ) {
-                       if ( this.indicatorTitle !== null ) {
-                               this.$indicator.attr( 'title', indicatorTitle );
-                       } else {
-                               this.$indicator.removeAttr( 'title' );
-                       }
-               }
-       }
-
-       return this;
-};
-
-/**
- * Get the symbolic name of the indicator (e.g., ‘alert’ or  ‘down’).
- *
- * @return {string} Symbolic name of indicator
- */
-OO.ui.mixin.IndicatorElement.prototype.getIndicator = function () {
-       return this.indicator;
-};
-
-/**
- * Get the indicator title.
- *
- * The title is displayed when a user moves the mouse over the indicator.
- *
- * @return {string} Indicator title text
- */
-OO.ui.mixin.IndicatorElement.prototype.getIndicatorTitle = function () {
-       return this.indicatorTitle;
-};
-
-/**
- * LabelElement is often mixed into other classes to generate a label, which
- * helps identify the function of an interface element.
- * See the [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$label] The label element created by the class. If this
- *  configuration is omitted, the label element will use a generated `<span>`.
- * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified
- *  as a plaintext string, a jQuery selection of elements, or a function that will produce a string
- *  in the future. See the [OOjs UI documentation on MediaWiki] [2] for examples.
- *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
- * @cfg {boolean} [autoFitLabel=true] Fit the label to the width of the parent element.
- *  The label will be truncated to fit if necessary.
- */
-OO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$label = null;
-       this.label = null;
-       this.autoFitLabel = config.autoFitLabel === undefined || !!config.autoFitLabel;
-
-       // Initialization
-       this.setLabel( config.label || this.constructor.static.label );
-       this.setLabelElement( config.$label || $( '<span>' ) );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.LabelElement );
-
-/* Events */
-
-/**
- * @event labelChange
- * @param {string} value
- */
-
-/* Static Properties */
-
-/**
- * The label text. The label can be specified as a plaintext string, a function that will
- * produce a string in the future, or `null` for no label. The static value will
- * be overridden if a label is specified with the #label config option.
- *
- * @static
- * @inheritable
- * @property {string|Function|null}
- */
-OO.ui.mixin.LabelElement.static.label = null;
-
-/* Methods */
-
-/**
- * Set the label element.
- *
- * If an element is already set, it will be cleaned up before setting up the new element.
- *
- * @param {jQuery} $label Element to use as label
- */
-OO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {
-       if ( this.$label ) {
-               this.$label.removeClass( 'oo-ui-labelElement-label' ).empty();
-       }
-
-       this.$label = $label.addClass( 'oo-ui-labelElement-label' );
-       this.setLabelContent( this.label );
-};
-
-/**
- * Set the label.
- *
- * An empty string will result in the label being hidden. A string containing only whitespace will
- * be converted to a single `&nbsp;`.
- *
- * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that returns nodes or
- *  text; or null for no label
- * @chainable
- */
-OO.ui.mixin.LabelElement.prototype.setLabel = function ( label ) {
-       label = typeof label === 'function' ? OO.ui.resolveMsg( label ) : label;
-       label = ( ( typeof label === 'string' && label.length ) || label instanceof jQuery || label instanceof OO.ui.HtmlSnippet ) ? label : null;
-
-       this.$element.toggleClass( 'oo-ui-labelElement', !!label );
-
-       if ( this.label !== label ) {
-               if ( this.$label ) {
-                       this.setLabelContent( label );
-               }
-               this.label = label;
-               this.emit( 'labelChange' );
-       }
-
-       return this;
-};
-
-/**
- * Get the label.
- *
- * @return {jQuery|string|Function|null} Label nodes; text; a function that returns nodes or
- *  text; or null for no label
- */
-OO.ui.mixin.LabelElement.prototype.getLabel = function () {
-       return this.label;
-};
-
-/**
- * Fit the label.
- *
- * @chainable
- */
-OO.ui.mixin.LabelElement.prototype.fitLabel = function () {
-       if ( this.$label && this.$label.autoEllipsis && this.autoFitLabel ) {
-               this.$label.autoEllipsis( { hasSpan: false, tooltip: true } );
-       }
-
-       return this;
-};
-
-/**
- * Set the content of the label.
- *
- * Do not call this method until after the label element has been set by #setLabelElement.
- *
- * @private
- * @param {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or
- *  text; or null for no label
- */
-OO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {
-       if ( typeof label === 'string' ) {
-               if ( label.match( /^\s*$/ ) ) {
-                       // Convert whitespace only string to a single non-breaking space
-                       this.$label.html( '&nbsp;' );
-               } else {
-                       this.$label.text( label );
-               }
-       } else if ( label instanceof OO.ui.HtmlSnippet ) {
-               this.$label.html( label.toString() );
-       } else if ( label instanceof jQuery ) {
-               this.$label.empty().append( label );
-       } else {
-               this.$label.empty();
-       }
-};
-
-/**
- * LookupElement is a mixin that creates a {@link OO.ui.FloatingMenuSelectWidget menu} of suggested values for
- * a {@link OO.ui.TextInputWidget text input widget}. Suggested values are based on the characters the user types
- * into the text input field and, in general, the menu is only displayed when the user types. If a suggested value is chosen
- * from the lookup menu, that value becomes the value of the input field.
- *
- * Note that a new menu of suggested items is displayed when a value is chosen from the lookup menu. If this is
- * not the desired behavior, disable lookup menus with the #setLookupsDisabled method, then set the value, then
- * re-enable lookups.
- *
- * See the [OOjs UI demos][1] for an example.
- *
- * [1]: https://tools.wmflabs.org/oojs-ui/oojs-ui/demos/index.html#widgets-apex-vector-ltr
- *
- * @class
- * @abstract
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning
- * @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
- * @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
- *  By default, the lookup menu is not generated and displayed until the user begins to type.
- * @cfg {boolean} [highlightFirst=true] Whether the first lookup result should be highlighted (so, that the user can
- *  take it over into the input with simply pressing return) automatically or not.
- */
-OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
-       // Configuration initialization
-       config = $.extend( { highlightFirst: true }, config );
-
-       // Mixin constructors
-       OO.ui.mixin.RequestManager.call( this, config );
-
-       // Properties
-       this.$overlay = config.$overlay || this.$element;
-       this.lookupMenu = new OO.ui.FloatingMenuSelectWidget( {
-               widget: this,
-               input: this,
-               $container: config.$container || this.$element
-       } );
-
-       this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;
-
-       this.lookupsDisabled = false;
-       this.lookupInputFocused = false;
-       this.lookupHighlightFirstItem = config.highlightFirst;
-
-       // Events
-       this.$input.on( {
-               focus: this.onLookupInputFocus.bind( this ),
-               blur: this.onLookupInputBlur.bind( this ),
-               mousedown: this.onLookupInputMouseDown.bind( this )
-       } );
-       this.connect( this, { change: 'onLookupInputChange' } );
-       this.lookupMenu.connect( this, {
-               toggle: 'onLookupMenuToggle',
-               choose: 'onLookupMenuItemChoose'
-       } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-lookupElement' );
-       this.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );
-       this.$overlay.append( this.lookupMenu.$element );
-};
-
-/* Setup */
-
-OO.mixinClass( OO.ui.mixin.LookupElement, OO.ui.mixin.RequestManager );
-
-/* Methods */
-
-/**
- * Handle input focus event.
- *
- * @protected
- * @param {jQuery.Event} e Input focus event
- */
-OO.ui.mixin.LookupElement.prototype.onLookupInputFocus = function () {
-       this.lookupInputFocused = true;
-       this.populateLookupMenu();
-};
-
-/**
- * Handle input blur event.
- *
- * @protected
- * @param {jQuery.Event} e Input blur event
- */
-OO.ui.mixin.LookupElement.prototype.onLookupInputBlur = function () {
-       this.closeLookupMenu();
-       this.lookupInputFocused = false;
-};
-
-/**
- * Handle input mouse down event.
- *
- * @protected
- * @param {jQuery.Event} e Input mouse down event
- */
-OO.ui.mixin.LookupElement.prototype.onLookupInputMouseDown = function () {
-       // Only open the menu if the input was already focused.
-       // This way we allow the user to open the menu again after closing it with Esc
-       // by clicking in the input. Opening (and populating) the menu when initially
-       // clicking into the input is handled by the focus handler.
-       if ( this.lookupInputFocused && !this.lookupMenu.isVisible() ) {
-               this.populateLookupMenu();
-       }
-};
-
-/**
- * Handle input change event.
- *
- * @protected
- * @param {string} value New input value
- */
-OO.ui.mixin.LookupElement.prototype.onLookupInputChange = function () {
-       if ( this.lookupInputFocused ) {
-               this.populateLookupMenu();
-       }
-};
-
-/**
- * Handle the lookup menu being shown/hidden.
- *
- * @protected
- * @param {boolean} visible Whether the lookup menu is now visible.
- */
-OO.ui.mixin.LookupElement.prototype.onLookupMenuToggle = function ( visible ) {
-       if ( !visible ) {
-               // When the menu is hidden, abort any active request and clear the menu.
-               // This has to be done here in addition to closeLookupMenu(), because
-               // MenuSelectWidget will close itself when the user presses Esc.
-               this.abortLookupRequest();
-               this.lookupMenu.clearItems();
-       }
-};
-
-/**
- * Handle menu item 'choose' event, updating the text input value to the value of the clicked item.
- *
- * @protected
- * @param {OO.ui.MenuOptionWidget} item Selected item
- */
-OO.ui.mixin.LookupElement.prototype.onLookupMenuItemChoose = function ( item ) {
-       this.setValue( item.getData() );
-};
-
-/**
- * Get lookup menu.
- *
- * @private
- * @return {OO.ui.FloatingMenuSelectWidget}
- */
-OO.ui.mixin.LookupElement.prototype.getLookupMenu = function () {
-       return this.lookupMenu;
-};
-
-/**
- * Disable or re-enable lookups.
- *
- * When lookups are disabled, calls to #populateLookupMenu will be ignored.
- *
- * @param {boolean} disabled Disable lookups
- */
-OO.ui.mixin.LookupElement.prototype.setLookupsDisabled = function ( disabled ) {
-       this.lookupsDisabled = !!disabled;
-};
-
-/**
- * Open the menu. If there are no entries in the menu, this does nothing.
- *
- * @private
- * @chainable
- */
-OO.ui.mixin.LookupElement.prototype.openLookupMenu = function () {
-       if ( !this.lookupMenu.isEmpty() ) {
-               this.lookupMenu.toggle( true );
-       }
-       return this;
-};
-
-/**
- * Close the menu, empty it, and abort any pending request.
- *
- * @private
- * @chainable
- */
-OO.ui.mixin.LookupElement.prototype.closeLookupMenu = function () {
-       this.lookupMenu.toggle( false );
-       this.abortLookupRequest();
-       this.lookupMenu.clearItems();
-       return this;
-};
-
-/**
- * Request menu items based on the input's current value, and when they arrive,
- * populate the menu with these items and show the menu.
- *
- * If lookups have been disabled with #setLookupsDisabled, this function does nothing.
- *
- * @private
- * @chainable
- */
-OO.ui.mixin.LookupElement.prototype.populateLookupMenu = function () {
-       var widget = this,
-               value = this.getValue();
-
-       if ( this.lookupsDisabled || this.isReadOnly() ) {
-               return;
-       }
-
-       // If the input is empty, clear the menu, unless suggestions when empty are allowed.
-       if ( !this.allowSuggestionsWhenEmpty && value === '' ) {
-               this.closeLookupMenu();
-       // Skip population if there is already a request pending for the current value
-       } else if ( value !== this.lookupQuery ) {
-               this.getLookupMenuItems()
-                       .done( function ( items ) {
-                               widget.lookupMenu.clearItems();
-                               if ( items.length ) {
-                                       widget.lookupMenu
-                                               .addItems( items )
-                                               .toggle( true );
-                                       widget.initializeLookupMenuSelection();
-                               } else {
-                                       widget.lookupMenu.toggle( false );
-                               }
-                       } )
-                       .fail( function () {
-                               widget.lookupMenu.clearItems();
-                       } );
-       }
-
-       return this;
-};
-
-/**
- * Highlight the first selectable item in the menu, if configured.
- *
- * @private
- * @chainable
- */
-OO.ui.mixin.LookupElement.prototype.initializeLookupMenuSelection = function () {
-       if ( this.lookupHighlightFirstItem && !this.lookupMenu.getSelectedItem() ) {
-               this.lookupMenu.highlightItem( this.lookupMenu.getFirstSelectableItem() );
-       }
-};
-
-/**
- * Get lookup menu items for the current query.
- *
- * @private
- * @return {jQuery.Promise} Promise object which will be passed menu items as the first argument of
- *   the done event. If the request was aborted to make way for a subsequent request, this promise
- *   will not be rejected: it will remain pending forever.
- */
-OO.ui.mixin.LookupElement.prototype.getLookupMenuItems = function () {
-       return this.getRequestData().then( function ( data ) {
-               return this.getLookupMenuOptionsFromData( data );
-       }.bind( this ) );
-};
-
-/**
- * Abort the currently pending lookup request, if any.
- *
- * @private
- */
-OO.ui.mixin.LookupElement.prototype.abortLookupRequest = function () {
-       this.abortRequest();
-};
-
-/**
- * Get a new request object of the current lookup query value.
- *
- * @protected
- * @method
- * @abstract
- * @return {jQuery.Promise} jQuery AJAX object, or promise object with an .abort() method
- */
-OO.ui.mixin.LookupElement.prototype.getLookupRequest = null;
-
-/**
- * Pre-process data returned by the request from #getLookupRequest.
- *
- * The return value of this function will be cached, and any further queries for the given value
- * will use the cache rather than doing API requests.
- *
- * @protected
- * @method
- * @abstract
- * @param {Mixed} response Response from server
- * @return {Mixed} Cached result data
- */
-OO.ui.mixin.LookupElement.prototype.getLookupCacheDataFromResponse = null;
-
-/**
- * Get a list of menu option widgets from the (possibly cached) data returned by
- * #getLookupCacheDataFromResponse.
- *
- * @protected
- * @method
- * @abstract
- * @param {Mixed} data Cached result data, usually an array
- * @return {OO.ui.MenuOptionWidget[]} Menu items
- */
-OO.ui.mixin.LookupElement.prototype.getLookupMenuOptionsFromData = null;
-
-/**
- * Set the read-only state of the widget.
- *
- * This will also disable/enable the lookups functionality.
- *
- * @param {boolean} readOnly Make input read-only
- * @chainable
- */
-OO.ui.mixin.LookupElement.prototype.setReadOnly = function ( readOnly ) {
-       // Parent method
-       // Note: Calling #setReadOnly this way assumes this is mixed into an OO.ui.TextInputWidget
-       OO.ui.TextInputWidget.prototype.setReadOnly.call( this, readOnly );
-
-       // During construction, #setReadOnly is called before the OO.ui.mixin.LookupElement constructor
-       if ( this.isReadOnly() && this.lookupMenu ) {
-               this.closeLookupMenu();
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc OO.ui.mixin.RequestManager
- */
-OO.ui.mixin.LookupElement.prototype.getRequestQuery = function () {
-       return this.getValue();
-};
-
-/**
- * @inheritdoc OO.ui.mixin.RequestManager
- */
-OO.ui.mixin.LookupElement.prototype.getRequest = function () {
-       return this.getLookupRequest();
-};
-
-/**
- * @inheritdoc OO.ui.mixin.RequestManager
- */
-OO.ui.mixin.LookupElement.prototype.getRequestCacheDataFromResponse = function ( response ) {
-       return this.getLookupCacheDataFromResponse( response );
-};
-
-/**
- * PopupElement is mixed into other classes to generate a {@link OO.ui.PopupWidget popup widget}.
- * A popup is a container for content. It is overlaid and positioned absolutely. By default, each
- * popup has an anchor, which is an arrow-like protrusion that points toward the popup’s origin.
- * See {@link OO.ui.PopupWidget PopupWidget} for an example.
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object} [popup] Configuration to pass to popup
- * @cfg {boolean} [popup.autoClose=true] Popup auto-closes when it loses focus
- */
-OO.ui.mixin.PopupElement = function OoUiMixinPopupElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.popup = new OO.ui.PopupWidget( $.extend(
-               { autoClose: true },
-               config.popup,
-               { $autoCloseIgnore: this.$element }
-       ) );
-};
-
-/* Methods */
-
-/**
- * Get popup.
- *
- * @return {OO.ui.PopupWidget} Popup widget
- */
-OO.ui.mixin.PopupElement.prototype.getPopup = function () {
-       return this.popup;
-};
-
-/**
- * The FlaggedElement class is an attribute mixin, meaning that it is used to add
- * additional functionality to an element created by another class. The class provides
- * a ‘flags’ property assigned the name (or an array of names) of styling flags,
- * which are used to customize the look and feel of a widget to better describe its
- * importance and functionality.
- *
- * The library currently contains the following styling flags for general use:
- *
- * - **progressive**:  Progressive styling is applied to convey that the widget will move the user forward in a process.
- * - **destructive**: Destructive styling is applied to convey that the widget will remove something.
- * - **constructive**: Constructive styling is applied to convey that the widget will create something.
- *
- * The flags affect the appearance of the buttons:
- *
- *     @example
- *     // FlaggedElement is mixed into ButtonWidget to provide styling flags
- *     var button1 = new OO.ui.ButtonWidget( {
- *         label: 'Constructive',
- *         flags: 'constructive'
- *     } );
- *     var button2 = new OO.ui.ButtonWidget( {
- *         label: 'Destructive',
- *         flags: 'destructive'
- *     } );
- *     var button3 = new OO.ui.ButtonWidget( {
- *         label: 'Progressive',
- *         flags: 'progressive'
- *     } );
- *     $( 'body' ).append( button1.$element, button2.$element, button3.$element );
- *
- * {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an action, use these flags: **primary** and **safe**.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Flagged
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string|string[]} [flags] The name or names of the flags (e.g., 'constructive' or 'primary') to apply.
- *  Please see the [OOjs UI documentation on MediaWiki] [2] for more information about available flags.
- *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Elements/Flagged
- * @cfg {jQuery} [$flagged] The flagged element. By default,
- *  the flagged functionality is applied to the element created by the class ($element).
- *  If a different element is specified, the flagged functionality will be applied to it instead.
- */
-OO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.flags = {};
-       this.$flagged = null;
-
-       // Initialization
-       this.setFlags( config.flags );
-       this.setFlaggedElement( config.$flagged || this.$element );
-};
-
-/* Events */
-
-/**
- * @event flag
- * A flag event is emitted when the #clearFlags or #setFlags methods are used. The `changes`
- * parameter contains the name of each modified flag and indicates whether it was
- * added or removed.
- *
- * @param {Object.<string,boolean>} changes Object keyed by flag name. A Boolean `true` indicates
- * that the flag was added, `false` that the flag was removed.
- */
-
-/* Methods */
-
-/**
- * Set the flagged element.
- *
- * This method is used to retarget a flagged mixin so that its functionality applies to the specified element.
- * If an element is already set, the method will remove the mixin’s effect on that element.
- *
- * @param {jQuery} $flagged Element that should be flagged
- */
-OO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) {
-       var classNames = Object.keys( this.flags ).map( function ( flag ) {
-               return 'oo-ui-flaggedElement-' + flag;
-       } ).join( ' ' );
-
-       if ( this.$flagged ) {
-               this.$flagged.removeClass( classNames );
-       }
-
-       this.$flagged = $flagged.addClass( classNames );
-};
-
-/**
- * Check if the specified flag is set.
- *
- * @param {string} flag Name of flag
- * @return {boolean} The flag is set
- */
-OO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) {
-       // This may be called before the constructor, thus before this.flags is set
-       return this.flags && ( flag in this.flags );
-};
-
-/**
- * Get the names of all flags set.
- *
- * @return {string[]} Flag names
- */
-OO.ui.mixin.FlaggedElement.prototype.getFlags = function () {
-       // This may be called before the constructor, thus before this.flags is set
-       return Object.keys( this.flags || {} );
-};
-
-/**
- * Clear all flags.
- *
- * @chainable
- * @fires flag
- */
-OO.ui.mixin.FlaggedElement.prototype.clearFlags = function () {
-       var flag, className,
-               changes = {},
-               remove = [],
-               classPrefix = 'oo-ui-flaggedElement-';
-
-       for ( flag in this.flags ) {
-               className = classPrefix + flag;
-               changes[ flag ] = false;
-               delete this.flags[ flag ];
-               remove.push( className );
-       }
-
-       if ( this.$flagged ) {
-               this.$flagged.removeClass( remove.join( ' ' ) );
-       }
-
-       this.updateThemeClasses();
-       this.emit( 'flag', changes );
-
-       return this;
-};
-
-/**
- * Add one or more flags.
- *
- * @param {string|string[]|Object.<string, boolean>} flags A flag name, an array of flag names,
- *  or an object keyed by flag name with a boolean value that indicates whether the flag should
- *  be added (`true`) or removed (`false`).
- * @chainable
- * @fires flag
- */
-OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) {
-       var i, len, flag, className,
-               changes = {},
-               add = [],
-               remove = [],
-               classPrefix = 'oo-ui-flaggedElement-';
-
-       if ( typeof flags === 'string' ) {
-               className = classPrefix + flags;
-               // Set
-               if ( !this.flags[ flags ] ) {
-                       this.flags[ flags ] = true;
-                       add.push( className );
-               }
-       } else if ( Array.isArray( flags ) ) {
-               for ( i = 0, len = flags.length; i < len; i++ ) {
-                       flag = flags[ i ];
-                       className = classPrefix + flag;
-                       // Set
-                       if ( !this.flags[ flag ] ) {
-                               changes[ flag ] = true;
-                               this.flags[ flag ] = true;
-                               add.push( className );
-                       }
-               }
-       } else if ( OO.isPlainObject( flags ) ) {
-               for ( flag in flags ) {
-                       className = classPrefix + flag;
-                       if ( flags[ flag ] ) {
-                               // Set
-                               if ( !this.flags[ flag ] ) {
-                                       changes[ flag ] = true;
-                                       this.flags[ flag ] = true;
-                                       add.push( className );
-                               }
-                       } else {
-                               // Remove
-                               if ( this.flags[ flag ] ) {
-                                       changes[ flag ] = false;
-                                       delete this.flags[ flag ];
-                                       remove.push( className );
-                               }
-                       }
-               }
-       }
-
-       if ( this.$flagged ) {
-               this.$flagged
-                       .addClass( add.join( ' ' ) )
-                       .removeClass( remove.join( ' ' ) );
-       }
-
-       this.updateThemeClasses();
-       this.emit( 'flag', changes );
-
-       return this;
-};
-
-/**
- * TitledElement is mixed into other classes to provide a `title` attribute.
- * Titles are rendered by the browser and are made visible when the user moves
- * the mouse over the element. Titles are not visible on touch devices.
- *
- *     @example
- *     // TitledElement provides a 'title' attribute to the
- *     // ButtonWidget class
- *     var button = new OO.ui.ButtonWidget( {
- *         label: 'Button with Title',
- *         title: 'I am a button'
- *     } );
- *     $( 'body' ).append( button.$element );
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$titled] The element to which the `title` attribute is applied.
- *  If this config is omitted, the title functionality is applied to $element, the
- *  element created by the class.
- * @cfg {string|Function} [title] The title text or a function that returns text. If
- *  this config is omitted, the value of the {@link #static-title static title} property is used.
- */
-OO.ui.mixin.TitledElement = function OoUiMixinTitledElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$titled = null;
-       this.title = null;
-
-       // Initialization
-       this.setTitle( config.title || this.constructor.static.title );
-       this.setTitledElement( config.$titled || this.$element );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.TitledElement );
-
-/* Static Properties */
-
-/**
- * The title text, a function that returns text, or `null` for no title. The value of the static property
- * is overridden if the #title config option is used.
- *
- * @static
- * @inheritable
- * @property {string|Function|null}
- */
-OO.ui.mixin.TitledElement.static.title = null;
-
-/* Methods */
-
-/**
- * Set the titled element.
- *
- * This method is used to retarget a titledElement mixin so that its functionality applies to the specified element.
- * If an element is already set, the mixin’s effect on that element is removed before the new element is set up.
- *
- * @param {jQuery} $titled Element that should use the 'titled' functionality
- */
-OO.ui.mixin.TitledElement.prototype.setTitledElement = function ( $titled ) {
-       if ( this.$titled ) {
-               this.$titled.removeAttr( 'title' );
-       }
-
-       this.$titled = $titled;
-       if ( this.title ) {
-               this.$titled.attr( 'title', this.title );
-       }
-};
-
-/**
- * Set title.
- *
- * @param {string|Function|null} title Title text, a function that returns text, or `null` for no title
- * @chainable
- */
-OO.ui.mixin.TitledElement.prototype.setTitle = function ( title ) {
-       title = typeof title === 'function' ? OO.ui.resolveMsg( title ) : title;
-       title = ( typeof title === 'string' && title.length ) ? title : null;
-
-       if ( this.title !== title ) {
-               if ( this.$titled ) {
-                       if ( title !== null ) {
-                               this.$titled.attr( 'title', title );
-                       } else {
-                               this.$titled.removeAttr( 'title' );
-                       }
-               }
-               this.title = title;
-       }
-
-       return this;
-};
-
-/**
- * Get title.
- *
- * @return {string} Title string
- */
-OO.ui.mixin.TitledElement.prototype.getTitle = function () {
-       return this.title;
-};
-
-/**
- * Element that can be automatically clipped to visible boundaries.
- *
- * Whenever the element's natural height changes, you have to call
- * {@link OO.ui.mixin.ClippableElement#clip} to make sure it's still
- * clipping correctly.
- *
- * The dimensions of #$clippableContainer will be compared to the boundaries of the
- * nearest scrollable container. If #$clippableContainer is too tall and/or too wide,
- * then #$clippable will be given a fixed reduced height and/or width and will be made
- * scrollable. By default, #$clippable and #$clippableContainer are the same element,
- * but you can build a static footer by setting #$clippableContainer to an element that contains
- * #$clippable and the footer.
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$clippable] Node to clip, assigned to #$clippable, omit to use #$element
- * @cfg {jQuery} [$clippableContainer] Node to keep visible, assigned to #$clippableContainer,
- *   omit to use #$clippable
- */
-OO.ui.mixin.ClippableElement = function OoUiMixinClippableElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$clippable = null;
-       this.$clippableContainer = null;
-       this.clipping = false;
-       this.clippedHorizontally = false;
-       this.clippedVertically = false;
-       this.$clippableScrollableContainer = null;
-       this.$clippableScroller = null;
-       this.$clippableWindow = null;
-       this.idealWidth = null;
-       this.idealHeight = null;
-       this.onClippableScrollHandler = this.clip.bind( this );
-       this.onClippableWindowResizeHandler = this.clip.bind( this );
-
-       // Initialization
-       if ( config.$clippableContainer ) {
-               this.setClippableContainer( config.$clippableContainer );
-       }
-       this.setClippableElement( config.$clippable || this.$element );
-};
-
-/* Methods */
-
-/**
- * Set clippable element.
- *
- * If an element is already set, it will be cleaned up before setting up the new element.
- *
- * @param {jQuery} $clippable Element to make clippable
- */
-OO.ui.mixin.ClippableElement.prototype.setClippableElement = function ( $clippable ) {
-       if ( this.$clippable ) {
-               this.$clippable.removeClass( 'oo-ui-clippableElement-clippable' );
-               this.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );
-               OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
-       }
-
-       this.$clippable = $clippable.addClass( 'oo-ui-clippableElement-clippable' );
-       this.clip();
-};
-
-/**
- * Set clippable container.
- *
- * This is the container that will be measured when deciding whether to clip. When clipping,
- * #$clippable will be resized in order to keep the clippable container fully visible.
- *
- * If the clippable container is unset, #$clippable will be used.
- *
- * @param {jQuery|null} $clippableContainer Container to keep visible, or null to unset
- */
-OO.ui.mixin.ClippableElement.prototype.setClippableContainer = function ( $clippableContainer ) {
-       this.$clippableContainer = $clippableContainer;
-       if ( this.$clippable ) {
-               this.clip();
-       }
-};
-
-/**
- * Toggle clipping.
- *
- * Do not turn clipping on until after the element is attached to the DOM and visible.
- *
- * @param {boolean} [clipping] Enable clipping, omit to toggle
- * @chainable
- */
-OO.ui.mixin.ClippableElement.prototype.toggleClipping = function ( clipping ) {
-       clipping = clipping === undefined ? !this.clipping : !!clipping;
-
-       if ( this.clipping !== clipping ) {
-               this.clipping = clipping;
-               if ( clipping ) {
-                       this.$clippableScrollableContainer = $( this.getClosestScrollableElementContainer() );
-                       // If the clippable container is the root, we have to listen to scroll events and check
-                       // jQuery.scrollTop on the window because of browser inconsistencies
-                       this.$clippableScroller = this.$clippableScrollableContainer.is( 'html, body' ) ?
-                               $( OO.ui.Element.static.getWindow( this.$clippableScrollableContainer ) ) :
-                               this.$clippableScrollableContainer;
-                       this.$clippableScroller.on( 'scroll', this.onClippableScrollHandler );
-                       this.$clippableWindow = $( this.getElementWindow() )
-                               .on( 'resize', this.onClippableWindowResizeHandler );
-                       // Initial clip after visible
-                       this.clip();
-               } else {
-                       this.$clippable.css( { width: '', height: '', overflowX: '', overflowY: '' } );
-                       OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
-
-                       this.$clippableScrollableContainer = null;
-                       this.$clippableScroller.off( 'scroll', this.onClippableScrollHandler );
-                       this.$clippableScroller = null;
-                       this.$clippableWindow.off( 'resize', this.onClippableWindowResizeHandler );
-                       this.$clippableWindow = null;
-               }
-       }
-
-       return this;
-};
-
-/**
- * Check if the element will be clipped to fit the visible area of the nearest scrollable container.
- *
- * @return {boolean} Element will be clipped to the visible area
- */
-OO.ui.mixin.ClippableElement.prototype.isClipping = function () {
-       return this.clipping;
-};
-
-/**
- * Check if the bottom or right of the element is being clipped by the nearest scrollable container.
- *
- * @return {boolean} Part of the element is being clipped
- */
-OO.ui.mixin.ClippableElement.prototype.isClipped = function () {
-       return this.clippedHorizontally || this.clippedVertically;
-};
-
-/**
- * Check if the right of the element is being clipped by the nearest scrollable container.
- *
- * @return {boolean} Part of the element is being clipped
- */
-OO.ui.mixin.ClippableElement.prototype.isClippedHorizontally = function () {
-       return this.clippedHorizontally;
-};
-
-/**
- * Check if the bottom of the element is being clipped by the nearest scrollable container.
- *
- * @return {boolean} Part of the element is being clipped
- */
-OO.ui.mixin.ClippableElement.prototype.isClippedVertically = function () {
-       return this.clippedVertically;
-};
-
-/**
- * Set the ideal size. These are the dimensions the element will have when it's not being clipped.
- *
- * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix
- * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix
- */
-OO.ui.mixin.ClippableElement.prototype.setIdealSize = function ( width, height ) {
-       this.idealWidth = width;
-       this.idealHeight = height;
-
-       if ( !this.clipping ) {
-               // Update dimensions
-               this.$clippable.css( { width: width, height: height } );
-       }
-       // While clipping, idealWidth and idealHeight are not considered
-};
-
-/**
- * Clip element to visible boundaries and allow scrolling when needed. Call this method when
- * the element's natural height changes.
- *
- * Element will be clipped the bottom or right of the element is within 10px of the edge of, or
- * overlapped by, the visible area of the nearest scrollable container.
- *
- * @chainable
- */
-OO.ui.mixin.ClippableElement.prototype.clip = function () {
-       var $container, extraHeight, extraWidth, ccOffset,
-               $scrollableContainer, scOffset, scHeight, scWidth,
-               ccWidth, scrollerIsWindow, scrollTop, scrollLeft,
-               desiredWidth, desiredHeight, allotedWidth, allotedHeight,
-               naturalWidth, naturalHeight, clipWidth, clipHeight,
-               buffer = 7; // Chosen by fair dice roll
-
-       if ( !this.clipping ) {
-               // this.$clippableScrollableContainer and this.$clippableWindow are null, so the below will fail
-               return this;
-       }
-
-       $container = this.$clippableContainer || this.$clippable;
-       extraHeight = $container.outerHeight() - this.$clippable.outerHeight();
-       extraWidth = $container.outerWidth() - this.$clippable.outerWidth();
-       ccOffset = $container.offset();
-       $scrollableContainer = this.$clippableScrollableContainer.is( 'html, body' ) ?
-               this.$clippableWindow : this.$clippableScrollableContainer;
-       scOffset = $scrollableContainer.offset() || { top: 0, left: 0 };
-       scHeight = $scrollableContainer.innerHeight() - buffer;
-       scWidth = $scrollableContainer.innerWidth() - buffer;
-       ccWidth = $container.outerWidth() + buffer;
-       scrollerIsWindow = this.$clippableScroller[ 0 ] === this.$clippableWindow[ 0 ];
-       scrollTop = scrollerIsWindow ? this.$clippableScroller.scrollTop() : 0;
-       scrollLeft = scrollerIsWindow ? this.$clippableScroller.scrollLeft() : 0;
-       desiredWidth = ccOffset.left < 0 ?
-               ccWidth + ccOffset.left :
-               ( scOffset.left + scrollLeft + scWidth ) - ccOffset.left;
-       desiredHeight = ( scOffset.top + scrollTop + scHeight ) - ccOffset.top;
-       allotedWidth = Math.ceil( desiredWidth - extraWidth );
-       allotedHeight = Math.ceil( desiredHeight - extraHeight );
-       naturalWidth = this.$clippable.prop( 'scrollWidth' );
-       naturalHeight = this.$clippable.prop( 'scrollHeight' );
-       clipWidth = allotedWidth < naturalWidth;
-       clipHeight = allotedHeight < naturalHeight;
-
-       if ( clipWidth ) {
-               this.$clippable.css( { overflowX: 'scroll', width: Math.max( 0, allotedWidth ) } );
-       } else {
-               this.$clippable.css( { width: this.idealWidth ? this.idealWidth - extraWidth : '', overflowX: '' } );
-       }
-       if ( clipHeight ) {
-               this.$clippable.css( { overflowY: 'scroll', height: Math.max( 0, allotedHeight ) } );
-       } else {
-               this.$clippable.css( { height: this.idealHeight ? this.idealHeight - extraHeight : '', overflowY: '' } );
-       }
-
-       // If we stopped clipping in at least one of the dimensions
-       if ( ( this.clippedHorizontally && !clipWidth ) || ( this.clippedVertically && !clipHeight ) ) {
-               OO.ui.Element.static.reconsiderScrollbars( this.$clippable[ 0 ] );
-       }
-
-       this.clippedHorizontally = clipWidth;
-       this.clippedVertically = clipHeight;
-
-       return this;
-};
-
-/**
- * Element that will stick under a specified container, even when it is inserted elsewhere in the
- * document (for example, in a OO.ui.Window's $overlay).
- *
- * The elements's position is automatically calculated and maintained when window is resized or the
- * page is scrolled. If you reposition the container manually, you have to call #position to make
- * sure the element is still placed correctly.
- *
- * As positioning is only possible when both the element and the container are attached to the DOM
- * and visible, it's only done after you call #togglePositioning. You might want to do this inside
- * the #toggle method to display a floating popup, for example.
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element
- * @cfg {jQuery} [$floatableContainer] Node to position below
- */
-OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$floatable = null;
-       this.$floatableContainer = null;
-       this.$floatableWindow = null;
-       this.$floatableClosestScrollable = null;
-       this.onFloatableScrollHandler = this.position.bind( this );
-       this.onFloatableWindowResizeHandler = this.position.bind( this );
-
-       // Initialization
-       this.setFloatableContainer( config.$floatableContainer );
-       this.setFloatableElement( config.$floatable || this.$element );
-};
-
-/* Methods */
-
-/**
- * Set floatable element.
- *
- * If an element is already set, it will be cleaned up before setting up the new element.
- *
- * @param {jQuery} $floatable Element to make floatable
- */
-OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) {
-       if ( this.$floatable ) {
-               this.$floatable.removeClass( 'oo-ui-floatableElement-floatable' );
-               this.$floatable.css( { left: '', top: '' } );
-       }
-
-       this.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' );
-       this.position();
-};
-
-/**
- * Set floatable container.
- *
- * The element will be always positioned under the specified container.
- *
- * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset
- */
-OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) {
-       this.$floatableContainer = $floatableContainer;
-       if ( this.$floatable ) {
-               this.position();
-       }
-};
-
-/**
- * Toggle positioning.
- *
- * Do not turn positioning on until after the element is attached to the DOM and visible.
- *
- * @param {boolean} [positioning] Enable positioning, omit to toggle
- * @chainable
- */
-OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) {
-       var closestScrollableOfContainer, closestScrollableOfFloatable;
-
-       positioning = positioning === undefined ? !this.positioning : !!positioning;
-
-       if ( this.positioning !== positioning ) {
-               this.positioning = positioning;
-
-               closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] );
-               closestScrollableOfFloatable = OO.ui.Element.static.getClosestScrollableContainer( this.$floatable[ 0 ] );
-               if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) {
-                       // If the scrollable is the root, we have to listen to scroll events
-                       // on the window because of browser inconsistencies (or do we? someone should verify this)
-                       if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) {
-                               closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer );
-                       }
-               }
-
-               if ( positioning ) {
-                       this.$floatableWindow = $( this.getElementWindow() );
-                       this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler );
-
-                       if ( closestScrollableOfContainer !== closestScrollableOfFloatable ) {
-                               this.$floatableClosestScrollable = $( closestScrollableOfContainer );
-                               this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler );
-                       }
-
-                       // Initial position after visible
-                       this.position();
-               } else {
-                       if ( this.$floatableWindow ) {
-                               this.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler );
-                               this.$floatableWindow = null;
-                       }
-
-                       if ( this.$floatableClosestScrollable ) {
-                               this.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler );
-                               this.$floatableClosestScrollable = null;
-                       }
-
-                       this.$floatable.css( { left: '', top: '' } );
-               }
-       }
-
-       return this;
-};
-
-/**
- * Position the floatable below its container.
- *
- * This should only be done when both of them are attached to the DOM and visible.
- *
- * @chainable
- */
-OO.ui.mixin.FloatableElement.prototype.position = function () {
-       var pos;
-
-       if ( !this.positioning ) {
-               return this;
-       }
-
-       pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() );
-
-       // Position under container
-       pos.top += this.$floatableContainer.height();
-       this.$floatable.css( pos );
-
-       // We updated the position, so re-evaluate the clipping state.
-       // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so
-       // will not notice the need to update itself.)
-       // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does
-       // it not listen to the right events in the right places?
-       if ( this.clip ) {
-               this.clip();
-       }
-
-       return this;
-};
-
-/**
- * AccessKeyedElement is mixed into other classes to provide an `accesskey` attribute.
- * Accesskeys allow an user to go to a specific element by using
- * a shortcut combination of a browser specific keys + the key
- * set to the field.
- *
- *     @example
- *     // AccessKeyedElement provides an 'accesskey' attribute to the
- *     // ButtonWidget class
- *     var button = new OO.ui.ButtonWidget( {
- *         label: 'Button with Accesskey',
- *         accessKey: 'k'
- *     } );
- *     $( 'body' ).append( button.$element );
- *
- * @abstract
- * @class
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$accessKeyed] The element to which the `accesskey` attribute is applied.
- *  If this config is omitted, the accesskey functionality is applied to $element, the
- *  element created by the class.
- * @cfg {string|Function} [accessKey] The key or a function that returns the key. If
- *  this config is omitted, no accesskey will be added.
- */
-OO.ui.mixin.AccessKeyedElement = function OoUiMixinAccessKeyedElement( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties
-       this.$accessKeyed = null;
-       this.accessKey = null;
-
-       // Initialization
-       this.setAccessKey( config.accessKey || null );
-       this.setAccessKeyedElement( config.$accessKeyed || this.$element );
-};
-
-/* Setup */
-
-OO.initClass( OO.ui.mixin.AccessKeyedElement );
-
-/* Static Properties */
-
-/**
- * The access key, a function that returns a key, or `null` for no accesskey.
- *
- * @static
- * @inheritable
- * @property {string|Function|null}
- */
-OO.ui.mixin.AccessKeyedElement.static.accessKey = null;
-
-/* Methods */
-
-/**
- * Set the accesskeyed element.
- *
- * This method is used to retarget a AccessKeyedElement mixin so that its functionality applies to the specified element.
- * If an element is already set, the mixin's effect on that element is removed before the new element is set up.
- *
- * @param {jQuery} $accessKeyed Element that should use the 'accesskeyes' functionality
- */
-OO.ui.mixin.AccessKeyedElement.prototype.setAccessKeyedElement = function ( $accessKeyed ) {
-       if ( this.$accessKeyed ) {
-               this.$accessKeyed.removeAttr( 'accesskey' );
-       }
-
-       this.$accessKeyed = $accessKeyed;
-       if ( this.accessKey ) {
-               this.$accessKeyed.attr( 'accesskey', this.accessKey );
-       }
-};
-
-/**
- * Set accesskey.
- *
- * @param {string|Function|null} accesskey Key, a function that returns a key, or `null` for no accesskey
- * @chainable
- */
-OO.ui.mixin.AccessKeyedElement.prototype.setAccessKey = function ( accessKey ) {
-       accessKey = typeof accessKey === 'string' ? OO.ui.resolveMsg( accessKey ) : null;
-
-       if ( this.accessKey !== accessKey ) {
-               if ( this.$accessKeyed ) {
-                       if ( accessKey !== null ) {
-                               this.$accessKeyed.attr( 'accesskey', accessKey );
-                       } else {
-                               this.$accessKeyed.removeAttr( 'accesskey' );
-                       }
-               }
-               this.accessKey = accessKey;
-       }
-
-       return this;
-};
-
-/**
- * Get accesskey.
- *
- * @return {string} accessKey string
- */
-OO.ui.mixin.AccessKeyedElement.prototype.getAccessKey = function () {
-       return this.accessKey;
-};
-
-/**
- * Tools, together with {@link OO.ui.ToolGroup toolgroups}, constitute {@link OO.ui.Toolbar toolbars}.
- * Each tool is configured with a static name, title, and icon and is customized with the command to carry
- * out when the tool is selected. Tools must also be registered with a {@link OO.ui.ToolFactory tool factory},
- * which creates the tools on demand.
- *
- * Every Tool subclass must implement two methods:
- *
- * - {@link #onUpdateState}
- * - {@link #onSelect}
- *
- * Tools are added to toolgroups ({@link OO.ui.ListToolGroup ListToolGroup},
- * {@link OO.ui.BarToolGroup BarToolGroup}, or {@link OO.ui.MenuToolGroup MenuToolGroup}), which determine how
- * the tool is displayed in the toolbar. See {@link OO.ui.Toolbar toolbars} for an example.
- *
- * For more information, please see the [OOjs UI documentation on MediaWiki][1].
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @abstract
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.FlaggedElement
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {OO.ui.ToolGroup} toolGroup
- * @param {Object} [config] Configuration options
- * @cfg {string|Function} [title] Title text or a function that returns text. If this config is omitted, the value of
- *  the {@link #static-title static title} property is used.
- *
- *  The title is used in different ways depending on the type of toolgroup that contains the tool. The
- *  title is used as a tooltip if the tool is part of a {@link OO.ui.BarToolGroup bar} toolgroup, or as the label text if the tool is
- *  part of a {@link OO.ui.ListToolGroup list} or {@link OO.ui.MenuToolGroup menu} toolgroup.
- *
- *  For bar toolgroups, a description of the accelerator key is appended to the title if an accelerator key
- *  is associated with an action by the same name as the tool and accelerator functionality has been added to the application.
- *  To add accelerator key functionality, you must subclass OO.ui.Toolbar and override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method.
- */
-OO.ui.Tool = function OoUiTool( toolGroup, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
-               config = toolGroup;
-               toolGroup = config.toolGroup;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.Tool.parent.call( this, config );
-
-       // Properties
-       this.toolGroup = toolGroup;
-       this.toolbar = this.toolGroup.getToolbar();
-       this.active = false;
-       this.$title = $( '<span>' );
-       this.$accel = $( '<span>' );
-       this.$link = $( '<a>' );
-       this.title = null;
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$link } ) );
-
-       // Events
-       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
-
-       // Initialization
-       this.$title.addClass( 'oo-ui-tool-title' );
-       this.$accel
-               .addClass( 'oo-ui-tool-accel' )
-               .prop( {
-                       // This may need to be changed if the key names are ever localized,
-                       // but for now they are essentially written in English
-                       dir: 'ltr',
-                       lang: 'en'
-               } );
-       this.$link
-               .addClass( 'oo-ui-tool-link' )
-               .append( this.$icon, this.$title, this.$accel )
-               .attr( 'role', 'button' );
-       this.$element
-               .data( 'oo-ui-tool', this )
-               .addClass(
-                       'oo-ui-tool ' + 'oo-ui-tool-name-' +
-                       this.constructor.static.name.replace( /^([^\/]+)\/([^\/]+).*$/, '$1-$2' )
-               )
-               .toggleClass( 'oo-ui-tool-with-label', this.constructor.static.displayBothIconAndLabel )
-               .append( this.$link );
-       this.setTitle( config.title || this.constructor.static.title );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Tool, OO.ui.Widget );
-OO.mixinClass( OO.ui.Tool, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.Tool, OO.ui.mixin.FlaggedElement );
-OO.mixinClass( OO.ui.Tool, OO.ui.mixin.TabIndexedElement );
-
-/* Static Properties */
-
-/**
- * @static
- * @inheritdoc
- */
-OO.ui.Tool.static.tagName = 'span';
-
-/**
- * Symbolic name of tool.
- *
- * The symbolic name is used internally to register the tool with a {@link OO.ui.ToolFactory ToolFactory}. It can
- * also be used when adding tools to toolgroups.
- *
- * @abstract
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.Tool.static.name = '';
-
-/**
- * Symbolic name of the group.
- *
- * The group name is used to associate tools with each other so that they can be selected later by
- * a {@link OO.ui.ToolGroup toolgroup}.
- *
- * @abstract
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.Tool.static.group = '';
-
-/**
- * Tool title text or a function that returns title text. The value of the static property is overridden if the #title config option is used.
- *
- * @abstract
- * @static
- * @inheritable
- * @property {string|Function}
- */
-OO.ui.Tool.static.title = '';
-
-/**
- * Display both icon and label when the tool is used in a {@link OO.ui.BarToolGroup bar} toolgroup.
- * Normally only the icon is displayed, or only the label if no icon is given.
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.Tool.static.displayBothIconAndLabel = false;
-
-/**
- * Add tool to catch-all groups automatically.
- *
- * A catch-all group, which contains all tools that do not currently belong to a toolgroup,
- * can be included in a toolgroup using the wildcard selector, an asterisk (*).
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.Tool.static.autoAddToCatchall = true;
-
-/**
- * Add tool to named groups automatically.
- *
- * By default, tools that are configured with a static ‘group’ property are added
- * to that group and will be selected when the symbolic name of the group is specified (e.g., when
- * toolgroups include tools by group name).
- *
- * @static
- * @property {boolean}
- * @inheritable
- */
-OO.ui.Tool.static.autoAddToGroup = true;
-
-/**
- * Check if this tool is compatible with given data.
- *
- * This is a stub that can be overridden to provide support for filtering tools based on an
- * arbitrary piece of information  (e.g., where the cursor is in a document). The implementation
- * must also call this method so that the compatibility check can be performed.
- *
- * @static
- * @inheritable
- * @param {Mixed} data Data to check
- * @return {boolean} Tool can be used with data
- */
-OO.ui.Tool.static.isCompatibleWith = function () {
-       return false;
-};
-
-/* Methods */
-
-/**
- * Handle the toolbar state being updated. This method is called when the
- * {@link OO.ui.Toolbar#event-updateState 'updateState' event} is emitted on the
- * {@link OO.ui.Toolbar Toolbar} that uses this tool, and should set the state of this tool
- * depending on application state (usually by calling #setDisabled to enable or disable the tool,
- * or #setActive to mark is as currently in-use or not).
- *
- * This is an abstract method that must be overridden in a concrete subclass.
- *
- * @method
- * @protected
- * @abstract
- */
-OO.ui.Tool.prototype.onUpdateState = null;
-
-/**
- * Handle the tool being selected. This method is called when the user triggers this tool,
- * usually by clicking on its label/icon.
- *
- * This is an abstract method that must be overridden in a concrete subclass.
- *
- * @method
- * @protected
- * @abstract
- */
-OO.ui.Tool.prototype.onSelect = null;
-
-/**
- * Check if the tool is active.
- *
- * Tools become active when their #onSelect or #onUpdateState handlers change them to appear pressed
- * with the #setActive method. Additional CSS is applied to the tool to reflect the active state.
- *
- * @return {boolean} Tool is active
- */
-OO.ui.Tool.prototype.isActive = function () {
-       return this.active;
-};
-
-/**
- * Make the tool appear active or inactive.
- *
- * This method should be called within #onSelect or #onUpdateState event handlers to make the tool
- * appear pressed or not.
- *
- * @param {boolean} state Make tool appear active
- */
-OO.ui.Tool.prototype.setActive = function ( state ) {
-       this.active = !!state;
-       if ( this.active ) {
-               this.$element.addClass( 'oo-ui-tool-active' );
-       } else {
-               this.$element.removeClass( 'oo-ui-tool-active' );
-       }
-};
-
-/**
- * Set the tool #title.
- *
- * @param {string|Function} title Title text or a function that returns text
- * @chainable
- */
-OO.ui.Tool.prototype.setTitle = function ( title ) {
-       this.title = OO.ui.resolveMsg( title );
-       this.updateTitle();
-       return this;
-};
-
-/**
- * Get the tool #title.
- *
- * @return {string} Title text
- */
-OO.ui.Tool.prototype.getTitle = function () {
-       return this.title;
-};
-
-/**
- * Get the tool's symbolic name.
- *
- * @return {string} Symbolic name of tool
- */
-OO.ui.Tool.prototype.getName = function () {
-       return this.constructor.static.name;
-};
-
-/**
- * Update the title.
- */
-OO.ui.Tool.prototype.updateTitle = function () {
-       var titleTooltips = this.toolGroup.constructor.static.titleTooltips,
-               accelTooltips = this.toolGroup.constructor.static.accelTooltips,
-               accel = this.toolbar.getToolAccelerator( this.constructor.static.name ),
-               tooltipParts = [];
-
-       this.$title.text( this.title );
-       this.$accel.text( accel );
-
-       if ( titleTooltips && typeof this.title === 'string' && this.title.length ) {
-               tooltipParts.push( this.title );
-       }
-       if ( accelTooltips && typeof accel === 'string' && accel.length ) {
-               tooltipParts.push( accel );
-       }
-       if ( tooltipParts.length ) {
-               this.$link.attr( 'title', tooltipParts.join( ' ' ) );
-       } else {
-               this.$link.removeAttr( 'title' );
-       }
-};
-
-/**
- * Destroy tool.
- *
- * Destroying the tool removes all event handlers and the tool’s DOM elements.
- * Call this method whenever you are done using a tool.
- */
-OO.ui.Tool.prototype.destroy = function () {
-       this.toolbar.disconnect( this );
-       this.$element.remove();
-};
-
-/**
- * Toolbars are complex interface components that permit users to easily access a variety
- * of {@link OO.ui.Tool tools} (e.g., formatting commands) and actions, which are additional commands that are
- * part of the toolbar, but not configured as tools.
- *
- * Individual tools are customized and then registered with a {@link OO.ui.ToolFactory tool factory}, which creates
- * the tools on demand. Each tool has a symbolic name (used when registering the tool), a title (e.g., ‘Insert
- * image’), and an icon.
- *
- * Individual tools are organized in {@link OO.ui.ToolGroup toolgroups}, which can be {@link OO.ui.MenuToolGroup menus}
- * of tools, {@link OO.ui.ListToolGroup lists} of tools, or a single {@link OO.ui.BarToolGroup bar} of tools.
- * The arrangement and order of the toolgroups is customized when the toolbar is set up. Tools can be presented in
- * any order, but each can only appear once in the toolbar.
- *
- * The toolbar can be synchronized with the state of the external "application", like a text
- * editor's editing area, marking tools as active/inactive (e.g. a 'bold' tool would be shown as
- * active when the text cursor was inside bolded text) or enabled/disabled (e.g. a table caption
- * tool would be disabled while the user is not editing a table). A state change is signalled by
- * emitting the {@link #event-updateState 'updateState' event}, which calls Tools'
- * {@link OO.ui.Tool#onUpdateState onUpdateState method}.
- *
- * The following is an example of a basic toolbar.
- *
- *     @example
- *     // Example of a toolbar
- *     // Create the toolbar
- *     var toolFactory = new OO.ui.ToolFactory();
- *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
- *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
- *
- *     // We will be placing status text in this element when tools are used
- *     var $area = $( '<p>' ).text( 'Toolbar example' );
- *
- *     // Define the tools that we're going to place in our toolbar
- *
- *     // Create a class inheriting from OO.ui.Tool
- *     function SearchTool() {
- *         SearchTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( SearchTool, OO.ui.Tool );
- *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
- *     // of 'icon' and 'title' (displayed icon and text).
- *     SearchTool.static.name = 'search';
- *     SearchTool.static.icon = 'search';
- *     SearchTool.static.title = 'Search...';
- *     // Defines the action that will happen when this tool is selected (clicked).
- *     SearchTool.prototype.onSelect = function () {
- *         $area.text( 'Search tool clicked!' );
- *         // Never display this tool as "active" (selected).
- *         this.setActive( false );
- *     };
- *     SearchTool.prototype.onUpdateState = function () {};
- *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( SearchTool );
- *
- *     // Register two more tools, nothing interesting here
- *     function SettingsTool() {
- *         SettingsTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( SettingsTool, OO.ui.Tool );
- *     SettingsTool.static.name = 'settings';
- *     SettingsTool.static.icon = 'settings';
- *     SettingsTool.static.title = 'Change settings';
- *     SettingsTool.prototype.onSelect = function () {
- *         $area.text( 'Settings tool clicked!' );
- *         this.setActive( false );
- *     };
- *     SettingsTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( SettingsTool );
- *
- *     // Register two more tools, nothing interesting here
- *     function StuffTool() {
- *         StuffTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( StuffTool, OO.ui.Tool );
- *     StuffTool.static.name = 'stuff';
- *     StuffTool.static.icon = 'ellipsis';
- *     StuffTool.static.title = 'More stuff';
- *     StuffTool.prototype.onSelect = function () {
- *         $area.text( 'More stuff tool clicked!' );
- *         this.setActive( false );
- *     };
- *     StuffTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( StuffTool );
- *
- *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
- *     // little popup window (a PopupWidget).
- *     function HelpTool( toolGroup, config ) {
- *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
- *             padded: true,
- *             label: 'Help',
- *             head: true
- *         } }, config ) );
- *         this.popup.$body.append( '<p>I am helpful!</p>' );
- *     }
- *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
- *     HelpTool.static.name = 'help';
- *     HelpTool.static.icon = 'help';
- *     HelpTool.static.title = 'Help';
- *     toolFactory.register( HelpTool );
- *
- *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
- *     // used once (but not all defined tools must be used).
- *     toolbar.setup( [
- *         {
- *             // 'bar' tool groups display tools' icons only, side-by-side.
- *             type: 'bar',
- *             include: [ 'search', 'help' ]
- *         },
- *         {
- *             // 'list' tool groups display both the titles and icons, in a dropdown list.
- *             type: 'list',
- *             indicator: 'down',
- *             label: 'More',
- *             include: [ 'settings', 'stuff' ]
- *         }
- *         // Note how the tools themselves are toolgroup-agnostic - the same tool can be displayed
- *         // either in a 'list' or a 'bar'. There is a 'menu' tool group too, not showcased here,
- *         // since it's more complicated to use. (See the next example snippet on this page.)
- *     ] );
- *
- *     // Create some UI around the toolbar and place it in the document
- *     var frame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true
- *     } );
- *     var contentFrame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         padded: true
- *     } );
- *     frame.$element.append(
- *         toolbar.$element,
- *         contentFrame.$element.append( $area )
- *     );
- *     $( 'body' ).append( frame.$element );
- *
- *     // Here is where the toolbar is actually built. This must be done after inserting it into the
- *     // document.
- *     toolbar.initialize();
- *     toolbar.emit( 'updateState' );
- *
- * The following example extends the previous one to illustrate 'menu' toolgroups and the usage of
- * {@link #event-updateState 'updateState' event}.
- *
- *     @example
- *     // Create the toolbar
- *     var toolFactory = new OO.ui.ToolFactory();
- *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
- *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
- *
- *     // We will be placing status text in this element when tools are used
- *     var $area = $( '<p>' ).text( 'Toolbar example' );
- *
- *     // Define the tools that we're going to place in our toolbar
- *
- *     // Create a class inheriting from OO.ui.Tool
- *     function SearchTool() {
- *         SearchTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( SearchTool, OO.ui.Tool );
- *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
- *     // of 'icon' and 'title' (displayed icon and text).
- *     SearchTool.static.name = 'search';
- *     SearchTool.static.icon = 'search';
- *     SearchTool.static.title = 'Search...';
- *     // Defines the action that will happen when this tool is selected (clicked).
- *     SearchTool.prototype.onSelect = function () {
- *         $area.text( 'Search tool clicked!' );
- *         // Never display this tool as "active" (selected).
- *         this.setActive( false );
- *     };
- *     SearchTool.prototype.onUpdateState = function () {};
- *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( SearchTool );
- *
- *     // Register two more tools, nothing interesting here
- *     function SettingsTool() {
- *         SettingsTool.parent.apply( this, arguments );
- *         this.reallyActive = false;
- *     }
- *     OO.inheritClass( SettingsTool, OO.ui.Tool );
- *     SettingsTool.static.name = 'settings';
- *     SettingsTool.static.icon = 'settings';
- *     SettingsTool.static.title = 'Change settings';
- *     SettingsTool.prototype.onSelect = function () {
- *         $area.text( 'Settings tool clicked!' );
- *         // Toggle the active state on each click
- *         this.reallyActive = !this.reallyActive;
- *         this.setActive( this.reallyActive );
- *         // To update the menu label
- *         this.toolbar.emit( 'updateState' );
- *     };
- *     SettingsTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( SettingsTool );
- *
- *     // Register two more tools, nothing interesting here
- *     function StuffTool() {
- *         StuffTool.parent.apply( this, arguments );
- *         this.reallyActive = false;
- *     }
- *     OO.inheritClass( StuffTool, OO.ui.Tool );
- *     StuffTool.static.name = 'stuff';
- *     StuffTool.static.icon = 'ellipsis';
- *     StuffTool.static.title = 'More stuff';
- *     StuffTool.prototype.onSelect = function () {
- *         $area.text( 'More stuff tool clicked!' );
- *         // Toggle the active state on each click
- *         this.reallyActive = !this.reallyActive;
- *         this.setActive( this.reallyActive );
- *         // To update the menu label
- *         this.toolbar.emit( 'updateState' );
- *     };
- *     StuffTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( StuffTool );
- *
- *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
- *     // little popup window (a PopupWidget). 'onUpdateState' is also already implemented.
- *     function HelpTool( toolGroup, config ) {
- *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
- *             padded: true,
- *             label: 'Help',
- *             head: true
- *         } }, config ) );
- *         this.popup.$body.append( '<p>I am helpful!</p>' );
- *     }
- *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
- *     HelpTool.static.name = 'help';
- *     HelpTool.static.icon = 'help';
- *     HelpTool.static.title = 'Help';
- *     toolFactory.register( HelpTool );
- *
- *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
- *     // used once (but not all defined tools must be used).
- *     toolbar.setup( [
- *         {
- *             // 'bar' tool groups display tools' icons only, side-by-side.
- *             type: 'bar',
- *             include: [ 'search', 'help' ]
- *         },
- *         {
- *             // 'menu' tool groups display both the titles and icons, in a dropdown menu.
- *             // Menu label indicates which items are selected.
- *             type: 'menu',
- *             indicator: 'down',
- *             include: [ 'settings', 'stuff' ]
- *         }
- *     ] );
- *
- *     // Create some UI around the toolbar and place it in the document
- *     var frame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true
- *     } );
- *     var contentFrame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         padded: true
- *     } );
- *     frame.$element.append(
- *         toolbar.$element,
- *         contentFrame.$element.append( $area )
- *     );
- *     $( 'body' ).append( frame.$element );
- *
- *     // Here is where the toolbar is actually built. This must be done after inserting it into the
- *     // document.
- *     toolbar.initialize();
- *     toolbar.emit( 'updateState' );
- *
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {OO.ui.ToolFactory} toolFactory Factory for creating tools
- * @param {OO.ui.ToolGroupFactory} toolGroupFactory Factory for creating toolgroups
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [actions] Add an actions section to the toolbar. Actions are commands that are included
- *  in the toolbar, but are not configured as tools. By default, actions are displayed on the right side of
- *  the toolbar.
- * @cfg {boolean} [shadow] Add a shadow below the toolbar.
- */
-OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolFactory ) && config === undefined ) {
-               config = toolFactory;
-               toolFactory = config.toolFactory;
-               toolGroupFactory = config.toolGroupFactory;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.Toolbar.parent.call( this, config );
-
-       // Mixin constructors
-       OO.EventEmitter.call( this );
-       OO.ui.mixin.GroupElement.call( this, config );
-
-       // Properties
-       this.toolFactory = toolFactory;
-       this.toolGroupFactory = toolGroupFactory;
-       this.groups = [];
-       this.tools = {};
-       this.$bar = $( '<div>' );
-       this.$actions = $( '<div>' );
-       this.initialized = false;
-       this.onWindowResizeHandler = this.onWindowResize.bind( this );
-
-       // Events
-       this.$element
-               .add( this.$bar ).add( this.$group ).add( this.$actions )
-               .on( 'mousedown keydown', this.onPointerDown.bind( this ) );
-
-       // Initialization
-       this.$group.addClass( 'oo-ui-toolbar-tools' );
-       if ( config.actions ) {
-               this.$bar.append( this.$actions.addClass( 'oo-ui-toolbar-actions' ) );
-       }
-       this.$bar
-               .addClass( 'oo-ui-toolbar-bar' )
-               .append( this.$group, '<div style="clear:both"></div>' );
-       if ( config.shadow ) {
-               this.$bar.append( '<div class="oo-ui-toolbar-shadow"></div>' );
-       }
-       this.$element.addClass( 'oo-ui-toolbar' ).append( this.$bar );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.Toolbar, OO.ui.Element );
-OO.mixinClass( OO.ui.Toolbar, OO.EventEmitter );
-OO.mixinClass( OO.ui.Toolbar, OO.ui.mixin.GroupElement );
-
-/* Events */
-
-/**
- * @event updateState
- *
- * An 'updateState' event must be emitted on the Toolbar (by calling `toolbar.emit( 'updateState' )`)
- * every time the state of the application using the toolbar changes, and an update to the state of
- * tools is required.
- *
- * @param {Mixed...} data Application-defined parameters
- */
-
-/* Methods */
-
-/**
- * Get the tool factory.
- *
- * @return {OO.ui.ToolFactory} Tool factory
- */
-OO.ui.Toolbar.prototype.getToolFactory = function () {
-       return this.toolFactory;
-};
-
-/**
- * Get the toolgroup factory.
- *
- * @return {OO.Factory} Toolgroup factory
- */
-OO.ui.Toolbar.prototype.getToolGroupFactory = function () {
-       return this.toolGroupFactory;
-};
-
-/**
- * Handles mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- */
-OO.ui.Toolbar.prototype.onPointerDown = function ( e ) {
-       var $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),
-               $closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );
-       if ( !$closestWidgetToEvent.length || $closestWidgetToEvent[ 0 ] === $closestWidgetToToolbar[ 0 ] ) {
-               return false;
-       }
-};
-
-/**
- * Handle window resize event.
- *
- * @private
- * @param {jQuery.Event} e Window resize event
- */
-OO.ui.Toolbar.prototype.onWindowResize = function () {
-       this.$element.toggleClass(
-               'oo-ui-toolbar-narrow',
-               this.$bar.width() <= this.narrowThreshold
-       );
-};
-
-/**
- * Sets up handles and preloads required information for the toolbar to work.
- * This must be called after it is attached to a visible document and before doing anything else.
- */
-OO.ui.Toolbar.prototype.initialize = function () {
-       if ( !this.initialized ) {
-               this.initialized = true;
-               this.narrowThreshold = this.$group.width() + this.$actions.width();
-               $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );
-               this.onWindowResize();
-       }
-};
-
-/**
- * Set up the toolbar.
- *
- * The toolbar is set up with a list of toolgroup configurations that specify the type of
- * toolgroup ({@link OO.ui.BarToolGroup bar}, {@link OO.ui.MenuToolGroup menu}, or {@link OO.ui.ListToolGroup list})
- * to add and which tools to include, exclude, promote, or demote within that toolgroup. Please
- * see {@link OO.ui.ToolGroup toolgroups} for more information about including tools in toolgroups.
- *
- * @param {Object.<string,Array>} groups List of toolgroup configurations
- * @param {Array|string} [groups.include] Tools to include in the toolgroup
- * @param {Array|string} [groups.exclude] Tools to exclude from the toolgroup
- * @param {Array|string} [groups.promote] Tools to promote to the beginning of the toolgroup
- * @param {Array|string} [groups.demote] Tools to demote to the end of the toolgroup
- */
-OO.ui.Toolbar.prototype.setup = function ( groups ) {
-       var i, len, type, group,
-               items = [],
-               defaultType = 'bar';
-
-       // Cleanup previous groups
-       this.reset();
-
-       // Build out new groups
-       for ( i = 0, len = groups.length; i < len; i++ ) {
-               group = groups[ i ];
-               if ( group.include === '*' ) {
-                       // Apply defaults to catch-all groups
-                       if ( group.type === undefined ) {
-                               group.type = 'list';
-                       }
-                       if ( group.label === undefined ) {
-                               group.label = OO.ui.msg( 'ooui-toolbar-more' );
-                       }
-               }
-               // Check type has been registered
-               type = this.getToolGroupFactory().lookup( group.type ) ? group.type : defaultType;
-               items.push(
-                       this.getToolGroupFactory().create( type, this, group )
-               );
-       }
-       this.addItems( items );
-};
-
-/**
- * Remove all tools and toolgroups from the toolbar.
- */
-OO.ui.Toolbar.prototype.reset = function () {
-       var i, len;
-
-       this.groups = [];
-       this.tools = {};
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               this.items[ i ].destroy();
-       }
-       this.clearItems();
-};
-
-/**
- * Destroy the toolbar.
- *
- * Destroying the toolbar removes all event handlers and DOM elements that constitute the toolbar. Call
- * this method whenever you are done using a toolbar.
- */
-OO.ui.Toolbar.prototype.destroy = function () {
-       $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
-       this.reset();
-       this.$element.remove();
-};
-
-/**
- * Check if the tool is available.
- *
- * Available tools are ones that have not yet been added to the toolbar.
- *
- * @param {string} name Symbolic name of tool
- * @return {boolean} Tool is available
- */
-OO.ui.Toolbar.prototype.isToolAvailable = function ( name ) {
-       return !this.tools[ name ];
-};
-
-/**
- * Prevent tool from being used again.
- *
- * @param {OO.ui.Tool} tool Tool to reserve
- */
-OO.ui.Toolbar.prototype.reserveTool = function ( tool ) {
-       this.tools[ tool.getName() ] = tool;
-};
-
-/**
- * Allow tool to be used again.
- *
- * @param {OO.ui.Tool} tool Tool to release
- */
-OO.ui.Toolbar.prototype.releaseTool = function ( tool ) {
-       delete this.tools[ tool.getName() ];
-};
-
-/**
- * Get accelerator label for tool.
- *
- * The OOjs UI library does not contain an accelerator system, but this is the hook for one. To
- * use an accelerator system, subclass the toolbar and override this method, which is meant to return a label
- * that describes the accelerator keys for the tool passed (by symbolic name) to the method.
- *
- * @param {string} name Symbolic name of tool
- * @return {string|undefined} Tool accelerator label if available
- */
-OO.ui.Toolbar.prototype.getToolAccelerator = function () {
-       return undefined;
-};
-
-/**
- * ToolGroups are collections of {@link OO.ui.Tool tools} that are used in a {@link OO.ui.Toolbar toolbar}.
- * The type of toolgroup ({@link OO.ui.ListToolGroup list}, {@link OO.ui.BarToolGroup bar}, or {@link OO.ui.MenuToolGroup menu})
- * to which a tool belongs determines how the tool is arranged and displayed in the toolbar. Toolgroups
- * themselves are created on demand with a {@link OO.ui.ToolGroupFactory toolgroup factory}.
- *
- * Toolgroups can contain individual tools, groups of tools, or all available tools, as specified
- * using the `include` config option. See OO.ui.ToolFactory#extract on documentation of the format.
- * The options `exclude`, `promote`, and `demote` support the same formats.
- *
- * See {@link OO.ui.Toolbar toolbars} for a full example. For more information about toolbars in general,
- * please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @abstract
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {OO.ui.Toolbar} toolbar
- * @param {Object} [config] Configuration options
- * @cfg {Array|string} [include] List of tools to include in the toolgroup, see above.
- * @cfg {Array|string} [exclude] List of tools to exclude from the toolgroup, see above.
- * @cfg {Array|string} [promote] List of tools to promote to the beginning of the toolgroup, see above.
- * @cfg {Array|string} [demote] List of tools to demote to the end of the toolgroup, see above.
- *  This setting is particularly useful when tools have been added to the toolgroup
- *  en masse (e.g., via the catch-all selector).
- */
-OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
-               config = toolbar;
-               toolbar = config.toolbar;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ToolGroup.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, config );
-
-       // Properties
-       this.toolbar = toolbar;
-       this.tools = {};
-       this.pressed = null;
-       this.autoDisabled = false;
-       this.include = config.include || [];
-       this.exclude = config.exclude || [];
-       this.promote = config.promote || [];
-       this.demote = config.demote || [];
-       this.onCapturedMouseKeyUpHandler = this.onCapturedMouseKeyUp.bind( this );
-
-       // Events
-       this.$element.on( {
-               mousedown: this.onMouseKeyDown.bind( this ),
-               mouseup: this.onMouseKeyUp.bind( this ),
-               keydown: this.onMouseKeyDown.bind( this ),
-               keyup: this.onMouseKeyUp.bind( this ),
-               focus: this.onMouseOverFocus.bind( this ),
-               blur: this.onMouseOutBlur.bind( this ),
-               mouseover: this.onMouseOverFocus.bind( this ),
-               mouseout: this.onMouseOutBlur.bind( this )
-       } );
-       this.toolbar.getToolFactory().connect( this, { register: 'onToolFactoryRegister' } );
-       this.aggregate( { disable: 'itemDisable' } );
-       this.connect( this, { itemDisable: 'updateDisabled' } );
-
-       // Initialization
-       this.$group.addClass( 'oo-ui-toolGroup-tools' );
-       this.$element
-               .addClass( 'oo-ui-toolGroup' )
-               .append( this.$group );
-       this.populate();
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToolGroup, OO.ui.Widget );
-OO.mixinClass( OO.ui.ToolGroup, OO.ui.mixin.GroupElement );
-
-/* Events */
-
-/**
- * @event update
- */
-
-/* Static Properties */
-
-/**
- * Show labels in tooltips.
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.ToolGroup.static.titleTooltips = false;
-
-/**
- * Show acceleration labels in tooltips.
- *
- * Note: The OOjs UI library does not include an accelerator system, but does contain
- * a hook for one. To use an accelerator system, subclass the {@link OO.ui.Toolbar toolbar} and
- * override the {@link OO.ui.Toolbar#getToolAccelerator getToolAccelerator} method, which is
- * meant to return a label that describes the accelerator keys for a given tool (e.g., 'Ctrl + M').
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.ToolGroup.static.accelTooltips = false;
-
-/**
- * Automatically disable the toolgroup when all tools are disabled
- *
- * @static
- * @inheritable
- * @property {boolean}
- */
-OO.ui.ToolGroup.static.autoDisable = true;
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.ToolGroup.prototype.isDisabled = function () {
-       return this.autoDisabled || OO.ui.ToolGroup.parent.prototype.isDisabled.apply( this, arguments );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ToolGroup.prototype.updateDisabled = function () {
-       var i, item, allDisabled = true;
-
-       if ( this.constructor.static.autoDisable ) {
-               for ( i = this.items.length - 1; i >= 0; i-- ) {
-                       item = this.items[ i ];
-                       if ( !item.isDisabled() ) {
-                               allDisabled = false;
-                               break;
-                       }
-               }
-               this.autoDisabled = allDisabled;
-       }
-       OO.ui.ToolGroup.parent.prototype.updateDisabled.apply( this, arguments );
-};
-
-/**
- * Handle mouse down and key down events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse down or key down event
- */
-OO.ui.ToolGroup.prototype.onMouseKeyDown = function ( e ) {
-       if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.pressed = this.getTargetTool( e );
-               if ( this.pressed ) {
-                       this.pressed.setActive( true );
-                       this.getElementDocument().addEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
-                       this.getElementDocument().addEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
-               }
-               return false;
-       }
-};
-
-/**
- * Handle captured mouse up and key up events.
- *
- * @protected
- * @param {Event} e Mouse up or key up event
- */
-OO.ui.ToolGroup.prototype.onCapturedMouseKeyUp = function ( e ) {
-       this.getElementDocument().removeEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );
-       this.getElementDocument().removeEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );
-       // onMouseKeyUp may be called a second time, depending on where the mouse is when the button is
-       // released, but since `this.pressed` will no longer be true, the second call will be ignored.
-       this.onMouseKeyUp( e );
-};
-
-/**
- * Handle mouse up and key up events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse up or key up event
- */
-OO.ui.ToolGroup.prototype.onMouseKeyUp = function ( e ) {
-       var tool = this.getTargetTool( e );
-
-       if (
-               !this.isDisabled() && this.pressed && this.pressed === tool &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.pressed.onSelect();
-               this.pressed = null;
-               return false;
-       }
-
-       this.pressed = null;
-};
-
-/**
- * Handle mouse over and focus events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse over or focus event
- */
-OO.ui.ToolGroup.prototype.onMouseOverFocus = function ( e ) {
-       var tool = this.getTargetTool( e );
-
-       if ( this.pressed && this.pressed === tool ) {
-               this.pressed.setActive( true );
-       }
-};
-
-/**
- * Handle mouse out and blur events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse out or blur event
- */
-OO.ui.ToolGroup.prototype.onMouseOutBlur = function ( e ) {
-       var tool = this.getTargetTool( e );
-
-       if ( this.pressed && this.pressed === tool ) {
-               this.pressed.setActive( false );
-       }
-};
-
-/**
- * Get the closest tool to a jQuery.Event.
- *
- * Only tool links are considered, which prevents other elements in the tool such as popups from
- * triggering tool group interactions.
- *
- * @private
- * @param {jQuery.Event} e
- * @return {OO.ui.Tool|null} Tool, `null` if none was found
- */
-OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
-       var tool,
-               $item = $( e.target ).closest( '.oo-ui-tool-link' );
-
-       if ( $item.length ) {
-               tool = $item.parent().data( 'oo-ui-tool' );
-       }
-
-       return tool && !tool.isDisabled() ? tool : null;
-};
-
-/**
- * Handle tool registry register events.
- *
- * If a tool is registered after the group is created, we must repopulate the list to account for:
- *
- * - a tool being added that may be included
- * - a tool already included being overridden
- *
- * @protected
- * @param {string} name Symbolic name of tool
- */
-OO.ui.ToolGroup.prototype.onToolFactoryRegister = function () {
-       this.populate();
-};
-
-/**
- * Get the toolbar that contains the toolgroup.
- *
- * @return {OO.ui.Toolbar} Toolbar that contains the toolgroup
- */
-OO.ui.ToolGroup.prototype.getToolbar = function () {
-       return this.toolbar;
-};
-
-/**
- * Add and remove tools based on configuration.
- */
-OO.ui.ToolGroup.prototype.populate = function () {
-       var i, len, name, tool,
-               toolFactory = this.toolbar.getToolFactory(),
-               names = {},
-               add = [],
-               remove = [],
-               list = this.toolbar.getToolFactory().getTools(
-                       this.include, this.exclude, this.promote, this.demote
-               );
-
-       // Build a list of needed tools
-       for ( i = 0, len = list.length; i < len; i++ ) {
-               name = list[ i ];
-               if (
-                       // Tool exists
-                       toolFactory.lookup( name ) &&
-                       // Tool is available or is already in this group
-                       ( this.toolbar.isToolAvailable( name ) || this.tools[ name ] )
-               ) {
-                       // Hack to prevent infinite recursion via ToolGroupTool. We need to reserve the tool before
-                       // creating it, but we can't call reserveTool() yet because we haven't created the tool.
-                       this.toolbar.tools[ name ] = true;
-                       tool = this.tools[ name ];
-                       if ( !tool ) {
-                               // Auto-initialize tools on first use
-                               this.tools[ name ] = tool = toolFactory.create( name, this );
-                               tool.updateTitle();
-                       }
-                       this.toolbar.reserveTool( tool );
-                       add.push( tool );
-                       names[ name ] = true;
-               }
-       }
-       // Remove tools that are no longer needed
-       for ( name in this.tools ) {
-               if ( !names[ name ] ) {
-                       this.tools[ name ].destroy();
-                       this.toolbar.releaseTool( this.tools[ name ] );
-                       remove.push( this.tools[ name ] );
-                       delete this.tools[ name ];
-               }
-       }
-       if ( remove.length ) {
-               this.removeItems( remove );
-       }
-       // Update emptiness state
-       if ( add.length ) {
-               this.$element.removeClass( 'oo-ui-toolGroup-empty' );
-       } else {
-               this.$element.addClass( 'oo-ui-toolGroup-empty' );
-       }
-       // Re-add tools (moving existing ones to new locations)
-       this.addItems( add );
-       // Disabled state may depend on items
-       this.updateDisabled();
-};
-
-/**
- * Destroy toolgroup.
- */
-OO.ui.ToolGroup.prototype.destroy = function () {
-       var name;
-
-       this.clearItems();
-       this.toolbar.getToolFactory().disconnect( this );
-       for ( name in this.tools ) {
-               this.toolbar.releaseTool( this.tools[ name ] );
-               this.tools[ name ].disconnect( this ).destroy();
-               delete this.tools[ name ];
-       }
-       this.$element.remove();
-};
-
-/**
- * MessageDialogs display a confirmation or alert message. By default, the rendered dialog box
- * consists of a header that contains the dialog title, a body with the message, and a footer that
- * contains any {@link OO.ui.ActionWidget action widgets}. The MessageDialog class is the only type
- * of {@link OO.ui.Dialog dialog} that is usually instantiated directly.
- *
- * There are two basic types of message dialogs, confirmation and alert:
- *
- * - **confirmation**: the dialog title describes what a progressive action will do and the message provides
- *  more details about the consequences.
- * - **alert**: the dialog title describes which event occurred and the message provides more information
- *  about why the event occurred.
- *
- * The MessageDialog class specifies two actions: ‘accept’, the primary
- * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window,
- * passing along the selected action.
- *
- * For more information and examples, please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example: Creating and opening a message dialog window.
- *     var messageDialog = new OO.ui.MessageDialog();
- *
- *     // Create and append a window manager.
- *     var windowManager = new OO.ui.WindowManager();
- *     $( 'body' ).append( windowManager.$element );
- *     windowManager.addWindows( [ messageDialog ] );
- *     // Open the window.
- *     windowManager.openWindow( messageDialog, {
- *         title: 'Basic message dialog',
- *         message: 'This is the message'
- *     } );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Message_Dialogs
- *
- * @class
- * @extends OO.ui.Dialog
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.MessageDialog = function OoUiMessageDialog( config ) {
-       // Parent constructor
-       OO.ui.MessageDialog.parent.call( this, config );
-
-       // Properties
-       this.verticalActionLayout = null;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-messageDialog' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MessageDialog, OO.ui.Dialog );
-
-/* Static Properties */
-
-OO.ui.MessageDialog.static.name = 'message';
-
-OO.ui.MessageDialog.static.size = 'small';
-
-OO.ui.MessageDialog.static.verbose = false;
-
-/**
- * Dialog title.
- *
- * The title of a confirmation dialog describes what a progressive action will do. The
- * title of an alert dialog describes which event occurred.
- *
- * @static
- * @inheritable
- * @property {jQuery|string|Function|null}
- */
-OO.ui.MessageDialog.static.title = null;
-
-/**
- * The message displayed in the dialog body.
- *
- * A confirmation message describes the consequences of a progressive action. An alert
- * message describes why an event occurred.
- *
- * @static
- * @inheritable
- * @property {jQuery|string|Function|null}
- */
-OO.ui.MessageDialog.static.message = null;
-
-// Note that OO.ui.alert() and OO.ui.confirm() rely on these.
-OO.ui.MessageDialog.static.actions = [
-       { action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' },
-       { action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' }
-];
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.setManager = function ( manager ) {
-       OO.ui.MessageDialog.parent.prototype.setManager.call( this, manager );
-
-       // Events
-       this.manager.connect( this, {
-               resize: 'onResize'
-       } );
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.onActionResize = function ( action ) {
-       this.fitActions();
-       return OO.ui.MessageDialog.parent.prototype.onActionResize.call( this, action );
-};
-
-/**
- * Handle window resized events.
- *
- * @private
- */
-OO.ui.MessageDialog.prototype.onResize = function () {
-       var dialog = this;
-       dialog.fitActions();
-       // Wait for CSS transition to finish and do it again :(
-       setTimeout( function () {
-               dialog.fitActions();
-       }, 300 );
-};
-
-/**
- * Toggle action layout between vertical and horizontal.
- *
- * @private
- * @param {boolean} [value] Layout actions vertically, omit to toggle
- * @chainable
- */
-OO.ui.MessageDialog.prototype.toggleVerticalActionLayout = function ( value ) {
-       value = value === undefined ? !this.verticalActionLayout : !!value;
-
-       if ( value !== this.verticalActionLayout ) {
-               this.verticalActionLayout = value;
-               this.$actions
-                       .toggleClass( 'oo-ui-messageDialog-actions-vertical', value )
-                       .toggleClass( 'oo-ui-messageDialog-actions-horizontal', !value );
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.getActionProcess = function ( action ) {
-       if ( action ) {
-               return new OO.ui.Process( function () {
-                       this.close( { action: action } );
-               }, this );
-       }
-       return OO.ui.MessageDialog.parent.prototype.getActionProcess.call( this, action );
-};
-
-/**
- * @inheritdoc
- *
- * @param {Object} [data] Dialog opening data
- * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed
- * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence
- * @param {boolean} [data.verbose] Message is verbose and should be styled as a long message
- * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each
- *   action item
- */
-OO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) {
-       data = data || {};
-
-       // Parent method
-       return OO.ui.MessageDialog.parent.prototype.getSetupProcess.call( this, data )
-               .next( function () {
-                       this.title.setLabel(
-                               data.title !== undefined ? data.title : this.constructor.static.title
-                       );
-                       this.message.setLabel(
-                               data.message !== undefined ? data.message : this.constructor.static.message
-                       );
-                       this.message.$element.toggleClass(
-                               'oo-ui-messageDialog-message-verbose',
-                               data.verbose !== undefined ? data.verbose : this.constructor.static.verbose
-                       );
-               }, this );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) {
-       data = data || {};
-
-       // Parent method
-       return OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data )
-               .next( function () {
-                       // Focus the primary action button
-                       var actions = this.actions.get();
-                       actions = actions.filter( function ( action ) {
-                               return action.getFlags().indexOf( 'primary' ) > -1;
-                       } );
-                       if ( actions.length > 0 ) {
-                               actions[ 0 ].$button.focus();
-                       }
-               }, this );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.getBodyHeight = function () {
-       var bodyHeight, oldOverflow,
-               $scrollable = this.container.$element;
-
-       oldOverflow = $scrollable[ 0 ].style.overflow;
-       $scrollable[ 0 ].style.overflow = 'hidden';
-
-       OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );
-
-       bodyHeight = this.text.$element.outerHeight( true );
-       $scrollable[ 0 ].style.overflow = oldOverflow;
-
-       return bodyHeight;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.setDimensions = function ( dim ) {
-       var $scrollable = this.container.$element;
-       OO.ui.MessageDialog.parent.prototype.setDimensions.call( this, dim );
-
-       // Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced.
-       // Need to do it after transition completes (250ms), add 50ms just in case.
-       setTimeout( function () {
-               var oldOverflow = $scrollable[ 0 ].style.overflow;
-               $scrollable[ 0 ].style.overflow = 'hidden';
-
-               OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );
-
-               $scrollable[ 0 ].style.overflow = oldOverflow;
-       }, 300 );
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.initialize = function () {
-       // Parent method
-       OO.ui.MessageDialog.parent.prototype.initialize.call( this );
-
-       // Properties
-       this.$actions = $( '<div>' );
-       this.container = new OO.ui.PanelLayout( {
-               scrollable: true, classes: [ 'oo-ui-messageDialog-container' ]
-       } );
-       this.text = new OO.ui.PanelLayout( {
-               padded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]
-       } );
-       this.message = new OO.ui.LabelWidget( {
-               classes: [ 'oo-ui-messageDialog-message' ]
-       } );
-
-       // Initialization
-       this.title.$element.addClass( 'oo-ui-messageDialog-title' );
-       this.$content.addClass( 'oo-ui-messageDialog-content' );
-       this.container.$element.append( this.text.$element );
-       this.text.$element.append( this.title.$element, this.message.$element );
-       this.$body.append( this.container.$element );
-       this.$actions.addClass( 'oo-ui-messageDialog-actions' );
-       this.$foot.append( this.$actions );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MessageDialog.prototype.attachActions = function () {
-       var i, len, other, special, others;
-
-       // Parent method
-       OO.ui.MessageDialog.parent.prototype.attachActions.call( this );
-
-       special = this.actions.getSpecial();
-       others = this.actions.getOthers();
-
-       if ( special.safe ) {
-               this.$actions.append( special.safe.$element );
-               special.safe.toggleFramed( false );
-       }
-       if ( others.length ) {
-               for ( i = 0, len = others.length; i < len; i++ ) {
-                       other = others[ i ];
-                       this.$actions.append( other.$element );
-                       other.toggleFramed( false );
-               }
-       }
-       if ( special.primary ) {
-               this.$actions.append( special.primary.$element );
-               special.primary.toggleFramed( false );
-       }
-
-       if ( !this.isOpening() ) {
-               // If the dialog is currently opening, this will be called automatically soon.
-               // This also calls #fitActions.
-               this.updateSize();
-       }
-};
-
-/**
- * Fit action actions into columns or rows.
- *
- * Columns will be used if all labels can fit without overflow, otherwise rows will be used.
- *
- * @private
- */
-OO.ui.MessageDialog.prototype.fitActions = function () {
-       var i, len, action,
-               previous = this.verticalActionLayout,
-               actions = this.actions.get();
-
-       // Detect clipping
-       this.toggleVerticalActionLayout( false );
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               action = actions[ i ];
-               if ( action.$element.innerWidth() < action.$label.outerWidth( true ) ) {
-                       this.toggleVerticalActionLayout( true );
-                       break;
-               }
-       }
-
-       // Move the body out of the way of the foot
-       this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
-
-       if ( this.verticalActionLayout !== previous ) {
-               // We changed the layout, window height might need to be updated.
-               this.updateSize();
-       }
-};
-
-/**
- * ProcessDialog windows encapsulate a {@link OO.ui.Process process} and all of the code necessary
- * to complete it. If the process terminates with an error, a customizable {@link OO.ui.Error error
- * interface} alerts users to the trouble, permitting the user to dismiss the error and try again when
- * relevant. The ProcessDialog class is always extended and customized with the actions and content
- * required for each process.
- *
- * The process dialog box consists of a header that visually represents the ‘working’ state of long
- * processes with an animation. The header contains the dialog title as well as
- * two {@link OO.ui.ActionWidget action widgets}:  a ‘safe’ action on the left (e.g., ‘Cancel’) and
- * a ‘primary’ action on the right (e.g., ‘Done’).
- *
- * Like other windows, the process dialog is managed by a {@link OO.ui.WindowManager window manager}.
- * Please see the [OOjs UI documentation on MediaWiki][1] for more information and examples.
- *
- *     @example
- *     // Example: Creating and opening a process dialog window.
- *     function MyProcessDialog( config ) {
- *         MyProcessDialog.parent.call( this, config );
- *     }
- *     OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog );
- *
- *     MyProcessDialog.static.title = 'Process dialog';
- *     MyProcessDialog.static.actions = [
- *         { action: 'save', label: 'Done', flags: 'primary' },
- *         { label: 'Cancel', flags: 'safe' }
- *     ];
- *
- *     MyProcessDialog.prototype.initialize = function () {
- *         MyProcessDialog.parent.prototype.initialize.apply( this, arguments );
- *         this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
- *         this.content.$element.append( '<p>This is a process dialog window. The header contains the title and two buttons: \'Cancel\' (a safe action) on the left and \'Done\' (a primary action)  on the right.</p>' );
- *         this.$body.append( this.content.$element );
- *     };
- *     MyProcessDialog.prototype.getActionProcess = function ( action ) {
- *         var dialog = this;
- *         if ( action ) {
- *             return new OO.ui.Process( function () {
- *                 dialog.close( { action: action } );
- *             } );
- *         }
- *         return MyProcessDialog.parent.prototype.getActionProcess.call( this, action );
- *     };
- *
- *     var windowManager = new OO.ui.WindowManager();
- *     $( 'body' ).append( windowManager.$element );
- *
- *     var dialog = new MyProcessDialog();
- *     windowManager.addWindows( [ dialog ] );
- *     windowManager.openWindow( dialog );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs
- *
- * @abstract
- * @class
- * @extends OO.ui.Dialog
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.ProcessDialog = function OoUiProcessDialog( config ) {
-       // Parent constructor
-       OO.ui.ProcessDialog.parent.call( this, config );
-
-       // Properties
-       this.fitOnOpen = false;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-processDialog' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ProcessDialog, OO.ui.Dialog );
-
-/* Methods */
-
-/**
- * Handle dismiss button click events.
- *
- * Hides errors.
- *
- * @private
- */
-OO.ui.ProcessDialog.prototype.onDismissErrorButtonClick = function () {
-       this.hideErrors();
-};
-
-/**
- * Handle retry button click events.
- *
- * Hides errors and then tries again.
- *
- * @private
- */
-OO.ui.ProcessDialog.prototype.onRetryButtonClick = function () {
-       this.hideErrors();
-       this.executeAction( this.currentAction );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.onActionResize = function ( action ) {
-       if ( this.actions.isSpecial( action ) ) {
-               this.fitLabel();
-       }
-       return OO.ui.ProcessDialog.parent.prototype.onActionResize.call( this, action );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.initialize = function () {
-       // Parent method
-       OO.ui.ProcessDialog.parent.prototype.initialize.call( this );
-
-       // Properties
-       this.$navigation = $( '<div>' );
-       this.$location = $( '<div>' );
-       this.$safeActions = $( '<div>' );
-       this.$primaryActions = $( '<div>' );
-       this.$otherActions = $( '<div>' );
-       this.dismissButton = new OO.ui.ButtonWidget( {
-               label: OO.ui.msg( 'ooui-dialog-process-dismiss' )
-       } );
-       this.retryButton = new OO.ui.ButtonWidget();
-       this.$errors = $( '<div>' );
-       this.$errorsTitle = $( '<div>' );
-
-       // Events
-       this.dismissButton.connect( this, { click: 'onDismissErrorButtonClick' } );
-       this.retryButton.connect( this, { click: 'onRetryButtonClick' } );
-
-       // Initialization
-       this.title.$element.addClass( 'oo-ui-processDialog-title' );
-       this.$location
-               .append( this.title.$element )
-               .addClass( 'oo-ui-processDialog-location' );
-       this.$safeActions.addClass( 'oo-ui-processDialog-actions-safe' );
-       this.$primaryActions.addClass( 'oo-ui-processDialog-actions-primary' );
-       this.$otherActions.addClass( 'oo-ui-processDialog-actions-other' );
-       this.$errorsTitle
-               .addClass( 'oo-ui-processDialog-errors-title' )
-               .text( OO.ui.msg( 'ooui-dialog-process-error' ) );
-       this.$errors
-               .addClass( 'oo-ui-processDialog-errors oo-ui-element-hidden' )
-               .append( this.$errorsTitle, this.dismissButton.$element, this.retryButton.$element );
-       this.$content
-               .addClass( 'oo-ui-processDialog-content' )
-               .append( this.$errors );
-       this.$navigation
-               .addClass( 'oo-ui-processDialog-navigation' )
-               .append( this.$safeActions, this.$location, this.$primaryActions );
-       this.$head.append( this.$navigation );
-       this.$foot.append( this.$otherActions );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.getActionWidgets = function ( actions ) {
-       var i, len, widgets = [];
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               widgets.push(
-                       new OO.ui.ActionWidget( $.extend( { framed: true }, actions[ i ] ) )
-               );
-       }
-       return widgets;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.attachActions = function () {
-       var i, len, other, special, others;
-
-       // Parent method
-       OO.ui.ProcessDialog.parent.prototype.attachActions.call( this );
-
-       special = this.actions.getSpecial();
-       others = this.actions.getOthers();
-       if ( special.primary ) {
-               this.$primaryActions.append( special.primary.$element );
-       }
-       for ( i = 0, len = others.length; i < len; i++ ) {
-               other = others[ i ];
-               this.$otherActions.append( other.$element );
-       }
-       if ( special.safe ) {
-               this.$safeActions.append( special.safe.$element );
-       }
-
-       this.fitLabel();
-       this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.executeAction = function ( action ) {
-       var process = this;
-       return OO.ui.ProcessDialog.parent.prototype.executeAction.call( this, action )
-               .fail( function ( errors ) {
-                       process.showErrors( errors || [] );
-               } );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.setDimensions = function () {
-       // Parent method
-       OO.ui.ProcessDialog.parent.prototype.setDimensions.apply( this, arguments );
-
-       this.fitLabel();
-};
-
-/**
- * Fit label between actions.
- *
- * @private
- * @chainable
- */
-OO.ui.ProcessDialog.prototype.fitLabel = function () {
-       var safeWidth, primaryWidth, biggerWidth, labelWidth, navigationWidth, leftWidth, rightWidth,
-               size = this.getSizeProperties();
-
-       if ( typeof size.width !== 'number' ) {
-               if ( this.isOpened() ) {
-                       navigationWidth = this.$head.width() - 20;
-               } else if ( this.isOpening() ) {
-                       if ( !this.fitOnOpen ) {
-                               // Size is relative and the dialog isn't open yet, so wait.
-                               this.manager.opening.done( this.fitLabel.bind( this ) );
-                               this.fitOnOpen = true;
-                       }
-                       return;
-               } else {
-                       return;
-               }
-       } else {
-               navigationWidth = size.width - 20;
-       }
-
-       safeWidth = this.$safeActions.is( ':visible' ) ? this.$safeActions.width() : 0;
-       primaryWidth = this.$primaryActions.is( ':visible' ) ? this.$primaryActions.width() : 0;
-       biggerWidth = Math.max( safeWidth, primaryWidth );
-
-       labelWidth = this.title.$element.width();
-
-       if ( 2 * biggerWidth + labelWidth < navigationWidth ) {
-               // We have enough space to center the label
-               leftWidth = rightWidth = biggerWidth;
-       } else {
-               // Let's hope we at least have enough space not to overlap, because we can't wrap the label…
-               if ( this.getDir() === 'ltr' ) {
-                       leftWidth = safeWidth;
-                       rightWidth = primaryWidth;
-               } else {
-                       leftWidth = primaryWidth;
-                       rightWidth = safeWidth;
-               }
-       }
-
-       this.$location.css( { paddingLeft: leftWidth, paddingRight: rightWidth } );
-
-       return this;
-};
-
-/**
- * Handle errors that occurred during accept or reject processes.
- *
- * @private
- * @param {OO.ui.Error[]|OO.ui.Error} errors Errors to be handled
- */
-OO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {
-       var i, len, $item, actions,
-               items = [],
-               abilities = {},
-               recoverable = true,
-               warning = false;
-
-       if ( errors instanceof OO.ui.Error ) {
-               errors = [ errors ];
-       }
-
-       for ( i = 0, len = errors.length; i < len; i++ ) {
-               if ( !errors[ i ].isRecoverable() ) {
-                       recoverable = false;
-               }
-               if ( errors[ i ].isWarning() ) {
-                       warning = true;
-               }
-               $item = $( '<div>' )
-                       .addClass( 'oo-ui-processDialog-error' )
-                       .append( errors[ i ].getMessage() );
-               items.push( $item[ 0 ] );
-       }
-       this.$errorItems = $( items );
-       if ( recoverable ) {
-               abilities[ this.currentAction ] = true;
-               // Copy the flags from the first matching action
-               actions = this.actions.get( { actions: this.currentAction } );
-               if ( actions.length ) {
-                       this.retryButton.clearFlags().setFlags( actions[ 0 ].getFlags() );
-               }
-       } else {
-               abilities[ this.currentAction ] = false;
-               this.actions.setAbilities( abilities );
-       }
-       if ( warning ) {
-               this.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-continue' ) );
-       } else {
-               this.retryButton.setLabel( OO.ui.msg( 'ooui-dialog-process-retry' ) );
-       }
-       this.retryButton.toggle( recoverable );
-       this.$errorsTitle.after( this.$errorItems );
-       this.$errors.removeClass( 'oo-ui-element-hidden' ).scrollTop( 0 );
-};
-
-/**
- * Hide errors.
- *
- * @private
- */
-OO.ui.ProcessDialog.prototype.hideErrors = function () {
-       this.$errors.addClass( 'oo-ui-element-hidden' );
-       if ( this.$errorItems ) {
-               this.$errorItems.remove();
-               this.$errorItems = null;
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ProcessDialog.prototype.getTeardownProcess = function ( data ) {
-       // Parent method
-       return OO.ui.ProcessDialog.parent.prototype.getTeardownProcess.call( this, data )
-               .first( function () {
-                       // Make sure to hide errors
-                       this.hideErrors();
-                       this.fitOnOpen = false;
-               }, this );
-};
-
-/**
- * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,
- * which is a widget that is specified by reference before any optional configuration settings.
- *
- * Field layouts can be configured with help text and/or labels. Labels are aligned in one of four ways:
- *
- * - **left**: The label is placed before the field-widget and aligned with the left margin.
- *   A left-alignment is used for forms with many fields.
- * - **right**: The label is placed before the field-widget and aligned to the right margin.
- *   A right-alignment is used for long but familiar forms which users tab through,
- *   verifying the current field with a quick glance at the label.
- * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms
- *   that users fill out from top to bottom.
- * - **inline**: The label is placed after the field-widget and aligned to the left.
- *   An inline-alignment is best used with checkboxes or radio buttons.
- *
- * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for examples and more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Fields_and_Fieldsets
- * @class
- * @extends OO.ui.Layout
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- *
- * @constructor
- * @param {OO.ui.Widget} fieldWidget Field widget
- * @param {Object} [config] Configuration options
- * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top' or 'inline'
- * @cfg {Array} [errors] Error messages about the widget, which will be displayed below the widget.
- *  The array may contain strings or OO.ui.HtmlSnippet instances.
- * @cfg {Array} [notices] Notices about the widget, which will be displayed below the widget.
- *  The array may contain strings or OO.ui.HtmlSnippet instances.
- * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified, a "help" icon will appear
- *  in the upper-right corner of the rendered field; clicking it will display the text in a popup.
- *  For important messages, you are advised to use `notices`, as they are always shown.
- *
- * @throws {Error} An error is thrown if no widget is specified
- */
-OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
-       var hasInputWidget, div;
-
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( fieldWidget ) && config === undefined ) {
-               config = fieldWidget;
-               fieldWidget = config.fieldWidget;
-       }
-
-       // Make sure we have required constructor arguments
-       if ( fieldWidget === undefined ) {
-               throw new Error( 'Widget not found' );
-       }
-
-       hasInputWidget = fieldWidget.constructor.static.supportsSimpleLabel;
-
-       // Configuration initialization
-       config = $.extend( { align: 'left' }, config );
-
-       // Parent constructor
-       OO.ui.FieldLayout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
-
-       // Properties
-       this.fieldWidget = fieldWidget;
-       this.errors = [];
-       this.notices = [];
-       this.$field = $( '<div>' );
-       this.$messages = $( '<ul>' );
-       this.$body = $( '<' + ( hasInputWidget ? 'label' : 'div' ) + '>' );
-       this.align = null;
-       if ( config.help ) {
-               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
-                       classes: [ 'oo-ui-fieldLayout-help' ],
-                       framed: false,
-                       icon: 'info'
-               } );
-
-               div = $( '<div>' );
-               if ( config.help instanceof OO.ui.HtmlSnippet ) {
-                       div.html( config.help.toString() );
-               } else {
-                       div.text( config.help );
-               }
-               this.popupButtonWidget.getPopup().$body.append(
-                       div.addClass( 'oo-ui-fieldLayout-help-content' )
-               );
-               this.$help = this.popupButtonWidget.$element;
-       } else {
-               this.$help = $( [] );
-       }
-
-       // Events
-       if ( hasInputWidget ) {
-               this.$label.on( 'click', this.onLabelClick.bind( this ) );
-       }
-       this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-fieldLayout' )
-               .append( this.$help, this.$body );
-       this.$body.addClass( 'oo-ui-fieldLayout-body' );
-       this.$messages.addClass( 'oo-ui-fieldLayout-messages' );
-       this.$field
-               .addClass( 'oo-ui-fieldLayout-field' )
-               .toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
-               .append( this.fieldWidget.$element );
-
-       this.setErrors( config.errors || [] );
-       this.setNotices( config.notices || [] );
-       this.setAlignment( config.align );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.FieldLayout, OO.ui.mixin.TitledElement );
-
-/* Methods */
-
-/**
- * Handle field disable events.
- *
- * @private
- * @param {boolean} value Field is disabled
- */
-OO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {
-       this.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );
-};
-
-/**
- * Handle label mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.FieldLayout.prototype.onLabelClick = function () {
-       this.fieldWidget.simulateLabelClick();
-       return false;
-};
-
-/**
- * Get the widget contained by the field.
- *
- * @return {OO.ui.Widget} Field widget
- */
-OO.ui.FieldLayout.prototype.getField = function () {
-       return this.fieldWidget;
-};
-
-/**
- * @protected
- * @param {string} kind 'error' or 'notice'
- * @param {string|OO.ui.HtmlSnippet} text
- * @return {jQuery}
- */
-OO.ui.FieldLayout.prototype.makeMessage = function ( kind, text ) {
-       var $listItem, $icon, message;
-       $listItem = $( '<li>' );
-       if ( kind === 'error' ) {
-               $icon = new OO.ui.IconWidget( { icon: 'alert', flags: [ 'warning' ] } ).$element;
-       } else if ( kind === 'notice' ) {
-               $icon = new OO.ui.IconWidget( { icon: 'info' } ).$element;
-       } else {
-               $icon = '';
-       }
-       message = new OO.ui.LabelWidget( { label: text } );
-       $listItem
-               .append( $icon, message.$element )
-               .addClass( 'oo-ui-fieldLayout-messages-' + kind );
-       return $listItem;
-};
-
-/**
- * Set the field alignment mode.
- *
- * @private
- * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'
- * @chainable
- */
-OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
-       if ( value !== this.align ) {
-               // Default to 'left'
-               if ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {
-                       value = 'left';
-               }
-               // Reorder elements
-               if ( value === 'inline' ) {
-                       this.$body.append( this.$field, this.$label );
-               } else {
-                       this.$body.append( this.$label, this.$field );
-               }
-               // Set classes. The following classes can be used here:
-               // * oo-ui-fieldLayout-align-left
-               // * oo-ui-fieldLayout-align-right
-               // * oo-ui-fieldLayout-align-top
-               // * oo-ui-fieldLayout-align-inline
-               if ( this.align ) {
-                       this.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );
-               }
-               this.$element.addClass( 'oo-ui-fieldLayout-align-' + value );
-               this.align = value;
-       }
-
-       return this;
-};
-
-/**
- * Set the list of error messages.
- *
- * @param {Array} errors Error messages about the widget, which will be displayed below the widget.
- *  The array may contain strings or OO.ui.HtmlSnippet instances.
- * @chainable
- */
-OO.ui.FieldLayout.prototype.setErrors = function ( errors ) {
-       this.errors = errors.slice();
-       this.updateMessages();
-       return this;
-};
-
-/**
- * Set the list of notice messages.
- *
- * @param {Array} notices Notices about the widget, which will be displayed below the widget.
- *  The array may contain strings or OO.ui.HtmlSnippet instances.
- * @chainable
- */
-OO.ui.FieldLayout.prototype.setNotices = function ( notices ) {
-       this.notices = notices.slice();
-       this.updateMessages();
-       return this;
-};
-
-/**
- * Update the rendering of error and notice messages.
- *
- * @private
- */
-OO.ui.FieldLayout.prototype.updateMessages = function () {
-       var i;
-       this.$messages.empty();
-
-       if ( this.errors.length || this.notices.length ) {
-               this.$body.after( this.$messages );
-       } else {
-               this.$messages.remove();
-               return;
-       }
-
-       for ( i = 0; i < this.notices.length; i++ ) {
-               this.$messages.append( this.makeMessage( 'notice', this.notices[ i ] ) );
-       }
-       for ( i = 0; i < this.errors.length; i++ ) {
-               this.$messages.append( this.makeMessage( 'error', this.errors[ i ] ) );
-       }
-};
-
-/**
- * ActionFieldLayouts are used with OO.ui.FieldsetLayout. The layout consists of a field-widget, a button,
- * and an optional label and/or help text. The field-widget (e.g., a {@link OO.ui.TextInputWidget TextInputWidget}),
- * is required and is specified before any optional configuration settings.
- *
- * Labels can be aligned in one of four ways:
- *
- * - **left**: The label is placed before the field-widget and aligned with the left margin.
- *   A left-alignment is used for forms with many fields.
- * - **right**: The label is placed before the field-widget and aligned to the right margin.
- *   A right-alignment is used for long but familiar forms which users tab through,
- *   verifying the current field with a quick glance at the label.
- * - **top**: The label is placed above the field-widget. A top-alignment is used for brief forms
- *   that users fill out from top to bottom.
- * - **inline**: The label is placed after the field-widget and aligned to the left.
- *   An inline-alignment is best used with checkboxes or radio buttons.
- *
- * Help text is accessed via a help icon that appears in the upper right corner of the rendered field layout when help
- * text is specified.
- *
- *     @example
- *     // Example of an ActionFieldLayout
- *     var actionFieldLayout = new OO.ui.ActionFieldLayout(
- *         new OO.ui.TextInputWidget( {
- *             placeholder: 'Field widget'
- *         } ),
- *         new OO.ui.ButtonWidget( {
- *             label: 'Button'
- *         } ),
- *         {
- *             label: 'An ActionFieldLayout. This label is aligned top',
- *             align: 'top',
- *             help: 'This is help text'
- *         }
- *     );
- *
- *     $( 'body' ).append( actionFieldLayout.$element );
- *
- * @class
- * @extends OO.ui.FieldLayout
- *
- * @constructor
- * @param {OO.ui.Widget} fieldWidget Field widget
- * @param {OO.ui.ButtonWidget} buttonWidget Button widget
- */
-OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( fieldWidget ) && config === undefined ) {
-               config = fieldWidget;
-               fieldWidget = config.fieldWidget;
-               buttonWidget = config.buttonWidget;
-       }
-
-       // Parent constructor
-       OO.ui.ActionFieldLayout.parent.call( this, fieldWidget, config );
-
-       // Properties
-       this.buttonWidget = buttonWidget;
-       this.$button = $( '<div>' );
-       this.$input = $( '<div>' );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-actionFieldLayout' );
-       this.$button
-               .addClass( 'oo-ui-actionFieldLayout-button' )
-               .append( this.buttonWidget.$element );
-       this.$input
-               .addClass( 'oo-ui-actionFieldLayout-input' )
-               .append( this.fieldWidget.$element );
-       this.$field
-               .append( this.$input, this.$button );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
-
-/**
- * FieldsetLayouts are composed of one or more {@link OO.ui.FieldLayout FieldLayouts},
- * which each contain an individual widget and, optionally, a label. Each Fieldset can be
- * configured with a label as well. For more information and examples,
- * please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example of a fieldset layout
- *     var input1 = new OO.ui.TextInputWidget( {
- *         placeholder: 'A text input field'
- *     } );
- *
- *     var input2 = new OO.ui.TextInputWidget( {
- *         placeholder: 'A text input field'
- *     } );
- *
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *         label: 'Example of a fieldset layout'
- *     } );
- *
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( input1, {
- *             label: 'Field One'
- *         } ),
- *         new OO.ui.FieldLayout( input2, {
- *             label: 'Field Two'
- *         } )
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Fields_and_Fieldsets
- *
- * @class
- * @extends OO.ui.Layout
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.FieldLayout[]} [items] An array of fields to add to the fieldset. See OO.ui.FieldLayout for more information about fields.
- */
-OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.FieldsetLayout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.GroupElement.call( this, config );
-
-       if ( config.help ) {
-               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
-                       classes: [ 'oo-ui-fieldsetLayout-help' ],
-                       framed: false,
-                       icon: 'info'
-               } );
-
-               this.popupButtonWidget.getPopup().$body.append(
-                       $( '<div>' )
-                               .text( config.help )
-                               .addClass( 'oo-ui-fieldsetLayout-help-content' )
-               );
-               this.$help = this.popupButtonWidget.$element;
-       } else {
-               this.$help = $( [] );
-       }
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-fieldsetLayout' )
-               .prepend( this.$help, this.$icon, this.$label, this.$group );
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.mixin.GroupElement );
-
-/**
- * FormLayouts are used to wrap {@link OO.ui.FieldsetLayout FieldsetLayouts} when you intend to use browser-based
- * form submission for the fields instead of handling them in JavaScript. Form layouts can be configured with an
- * HTML form action, an encoding type, and a method using the #action, #enctype, and #method configs, respectively.
- * See the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
- *
- * Only widgets from the {@link OO.ui.InputWidget InputWidget} family support form submission. It
- * includes standard form elements like {@link OO.ui.CheckboxInputWidget checkboxes}, {@link
- * OO.ui.RadioInputWidget radio buttons} and {@link OO.ui.TextInputWidget text fields}, as well as
- * some fancier controls. Some controls have both regular and InputWidget variants, for example
- * OO.ui.DropdownWidget and OO.ui.DropdownInputWidget – only the latter support form submission and
- * often have simplified APIs to match the capabilities of HTML forms.
- * See the [OOjs UI Inputs documentation on MediaWiki] [2] for more information about InputWidgets.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Layouts/Forms
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- *     @example
- *     // Example of a form layout that wraps a fieldset layout
- *     var input1 = new OO.ui.TextInputWidget( {
- *         placeholder: 'Username'
- *     } );
- *     var input2 = new OO.ui.TextInputWidget( {
- *         placeholder: 'Password',
- *         type: 'password'
- *     } );
- *     var submit = new OO.ui.ButtonInputWidget( {
- *         label: 'Submit'
- *     } );
- *
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *         label: 'A form layout'
- *     } );
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( input1, {
- *             label: 'Username',
- *             align: 'top'
- *         } ),
- *         new OO.ui.FieldLayout( input2, {
- *             label: 'Password',
- *             align: 'top'
- *         } ),
- *         new OO.ui.FieldLayout( submit )
- *     ] );
- *     var form = new OO.ui.FormLayout( {
- *         items: [ fieldset ],
- *         action: '/api/formhandler',
- *         method: 'get'
- *     } )
- *     $( 'body' ).append( form.$element );
- *
- * @class
- * @extends OO.ui.Layout
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [method] HTML form `method` attribute
- * @cfg {string} [action] HTML form `action` attribute
- * @cfg {string} [enctype] HTML form `enctype` attribute
- * @cfg {OO.ui.FieldsetLayout[]} [items] Fieldset layouts to add to the form layout.
- */
-OO.ui.FormLayout = function OoUiFormLayout( config ) {
-       var action;
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.FormLayout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-       // Events
-       this.$element.on( 'submit', this.onFormSubmit.bind( this ) );
-
-       // Make sure the action is safe
-       action = config.action;
-       if ( action !== undefined && !OO.ui.isSafeUrl( action ) ) {
-               action = './' + action;
-       }
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-formLayout' )
-               .attr( {
-                       method: config.method,
-                       action: action,
-                       enctype: config.enctype
-               } );
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.FormLayout, OO.ui.mixin.GroupElement );
-
-/* Events */
-
-/**
- * A 'submit' event is emitted when the form is submitted.
- *
- * @event submit
- */
-
-/* Static Properties */
-
-OO.ui.FormLayout.static.tagName = 'form';
-
-/* Methods */
-
-/**
- * Handle form submit events.
- *
- * @private
- * @param {jQuery.Event} e Submit event
- * @fires submit
- */
-OO.ui.FormLayout.prototype.onFormSubmit = function () {
-       if ( this.emit( 'submit' ) ) {
-               return false;
-       }
-};
-
-/**
- * MenuLayouts combine a menu and a content {@link OO.ui.PanelLayout panel}. The menu is positioned relative to the content (after, before, top, or bottom)
- * and its size is customized with the #menuSize config. The content area will fill all remaining space.
- *
- *     @example
- *     var menuLayout = new OO.ui.MenuLayout( {
- *         position: 'top'
- *     } ),
- *         menuPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
- *         contentPanel = new OO.ui.PanelLayout( { padded: true, expanded: true, scrollable: true } ),
- *         select = new OO.ui.SelectWidget( {
- *             items: [
- *                 new OO.ui.OptionWidget( {
- *                     data: 'before',
- *                     label: 'Before',
- *                 } ),
- *                 new OO.ui.OptionWidget( {
- *                     data: 'after',
- *                     label: 'After',
- *                 } ),
- *                 new OO.ui.OptionWidget( {
- *                     data: 'top',
- *                     label: 'Top',
- *                 } ),
- *                 new OO.ui.OptionWidget( {
- *                     data: 'bottom',
- *                     label: 'Bottom',
- *                 } )
- *              ]
- *         } ).on( 'select', function ( item ) {
- *            menuLayout.setMenuPosition( item.getData() );
- *         } );
- *
- *     menuLayout.$menu.append(
- *         menuPanel.$element.append( '<b>Menu panel</b>', select.$element )
- *     );
- *     menuLayout.$content.append(
- *         contentPanel.$element.append( '<b>Content panel</b>', '<p>Note that the menu is positioned relative to the content panel: top, bottom, after, before.</p>')
- *     );
- *     $( 'body' ).append( menuLayout.$element );
- *
- * If menu size needs to be overridden, it can be accomplished using CSS similar to the snippet
- * below. MenuLayout's CSS will override the appropriate values with 'auto' or '0' to display the
- * menu correctly. If `menuPosition` is known beforehand, CSS rules corresponding to other positions
- * may be omitted.
- *
- *     .oo-ui-menuLayout-menu {
- *         height: 200px;
- *         width: 200px;
- *     }
- *     .oo-ui-menuLayout-content {
- *         top: 200px;
- *         left: 200px;
- *         right: 200px;
- *         bottom: 200px;
- *     }
- *
- * @class
- * @extends OO.ui.Layout
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [showMenu=true] Show menu
- * @cfg {string} [menuPosition='before'] Position of menu: `top`, `after`, `bottom` or `before`
- */
-OO.ui.MenuLayout = function OoUiMenuLayout( config ) {
-       // Configuration initialization
-       config = $.extend( {
-               showMenu: true,
-               menuPosition: 'before'
-       }, config );
-
-       // Parent constructor
-       OO.ui.MenuLayout.parent.call( this, config );
-
-       /**
-        * Menu DOM node
-        *
-        * @property {jQuery}
-        */
-       this.$menu = $( '<div>' );
-       /**
-        * Content DOM node
-        *
-        * @property {jQuery}
-        */
-       this.$content = $( '<div>' );
-
-       // Initialization
-       this.$menu
-               .addClass( 'oo-ui-menuLayout-menu' );
-       this.$content.addClass( 'oo-ui-menuLayout-content' );
-       this.$element
-               .addClass( 'oo-ui-menuLayout' )
-               .append( this.$content, this.$menu );
-       this.setMenuPosition( config.menuPosition );
-       this.toggleMenu( config.showMenu );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );
-
-/* Methods */
-
-/**
- * Toggle menu.
- *
- * @param {boolean} showMenu Show menu, omit to toggle
- * @chainable
- */
-OO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {
-       showMenu = showMenu === undefined ? !this.showMenu : !!showMenu;
-
-       if ( this.showMenu !== showMenu ) {
-               this.showMenu = showMenu;
-               this.$element
-                       .toggleClass( 'oo-ui-menuLayout-showMenu', this.showMenu )
-                       .toggleClass( 'oo-ui-menuLayout-hideMenu', !this.showMenu );
-       }
-
-       return this;
-};
-
-/**
- * Check if menu is visible
- *
- * @return {boolean} Menu is visible
- */
-OO.ui.MenuLayout.prototype.isMenuVisible = function () {
-       return this.showMenu;
-};
-
-/**
- * Set menu position.
- *
- * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`
- * @throws {Error} If position value is not supported
- * @chainable
- */
-OO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {
-       this.$element.removeClass( 'oo-ui-menuLayout-' + this.menuPosition );
-       this.menuPosition = position;
-       this.$element.addClass( 'oo-ui-menuLayout-' + position );
-
-       return this;
-};
-
-/**
- * Get menu position.
- *
- * @return {string} Menu position
- */
-OO.ui.MenuLayout.prototype.getMenuPosition = function () {
-       return this.menuPosition;
-};
-
-/**
- * BookletLayouts contain {@link OO.ui.PageLayout page layouts} as well as
- * an {@link OO.ui.OutlineSelectWidget outline} that allows users to easily navigate
- * through the pages and select which one to display. By default, only one page is
- * displayed at a time and the outline is hidden. When a user navigates to a new page,
- * the booklet layout automatically focuses on the first focusable element, unless the
- * default setting is changed. Optionally, booklets can be configured to show
- * {@link OO.ui.OutlineControlsWidget controls} for adding, moving, and removing items.
- *
- *     @example
- *     // Example of a BookletLayout that contains two PageLayouts.
- *
- *     function PageOneLayout( name, config ) {
- *         PageOneLayout.parent.call( this, name, config );
- *         this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on the left)</p>' );
- *     }
- *     OO.inheritClass( PageOneLayout, OO.ui.PageLayout );
- *     PageOneLayout.prototype.setupOutlineItem = function () {
- *         this.outlineItem.setLabel( 'Page One' );
- *     };
- *
- *     function PageTwoLayout( name, config ) {
- *         PageTwoLayout.parent.call( this, name, config );
- *         this.$element.append( '<p>Second page</p>' );
- *     }
- *     OO.inheritClass( PageTwoLayout, OO.ui.PageLayout );
- *     PageTwoLayout.prototype.setupOutlineItem = function () {
- *         this.outlineItem.setLabel( 'Page Two' );
- *     };
- *
- *     var page1 = new PageOneLayout( 'one' ),
- *         page2 = new PageTwoLayout( 'two' );
- *
- *     var booklet = new OO.ui.BookletLayout( {
- *         outlined: true
- *     } );
- *
- *     booklet.addPages ( [ page1, page2 ] );
- *     $( 'body' ).append( booklet.$element );
- *
- * @class
- * @extends OO.ui.MenuLayout
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [continuous=false] Show all pages, one after another
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed.
- * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet.
- * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
- */
-OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.BookletLayout.parent.call( this, config );
-
-       // Properties
-       this.currentPageName = null;
-       this.pages = {};
-       this.ignoreFocus = false;
-       this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } );
-       this.$content.append( this.stackLayout.$element );
-       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
-       this.outlineVisible = false;
-       this.outlined = !!config.outlined;
-       if ( this.outlined ) {
-               this.editable = !!config.editable;
-               this.outlineControlsWidget = null;
-               this.outlineSelectWidget = new OO.ui.OutlineSelectWidget();
-               this.outlinePanel = new OO.ui.PanelLayout( { scrollable: true } );
-               this.$menu.append( this.outlinePanel.$element );
-               this.outlineVisible = true;
-               if ( this.editable ) {
-                       this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
-                               this.outlineSelectWidget
-                       );
-               }
-       }
-       this.toggleMenu( this.outlined );
-
-       // Events
-       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
-       if ( this.outlined ) {
-               this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );
-               this.scrolling = false;
-               this.stackLayout.connect( this, { visibleItemChange: 'onStackLayoutVisibleItemChange' } );
-       }
-       if ( this.autoFocus ) {
-               // Event 'focus' does not bubble, but 'focusin' does
-               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
-       }
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-bookletLayout' );
-       this.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );
-       if ( this.outlined ) {
-               this.outlinePanel.$element
-                       .addClass( 'oo-ui-bookletLayout-outlinePanel' )
-                       .append( this.outlineSelectWidget.$element );
-               if ( this.editable ) {
-                       this.outlinePanel.$element
-                               .addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )
-                               .append( this.outlineControlsWidget.$element );
-               }
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );
-
-/* Events */
-
-/**
- * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the booklet layout.
- * @event set
- * @param {OO.ui.PageLayout} page Current page
- */
-
-/**
- * An 'add' event is emitted when pages are {@link #addPages added} to the booklet layout.
- *
- * @event add
- * @param {OO.ui.PageLayout[]} page Added pages
- * @param {number} index Index pages were added at
- */
-
-/**
- * A 'remove' event is emitted when pages are {@link #clearPages cleared} or
- * {@link #removePages removed} from the booklet.
- *
- * @event remove
- * @param {OO.ui.PageLayout[]} pages Removed pages
- */
-
-/* Methods */
-
-/**
- * Handle stack layout focus.
- *
- * @private
- * @param {jQuery.Event} e Focusin event
- */
-OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
-       var name, $target;
-
-       // Find the page that an element was focused within
-       $target = $( e.target ).closest( '.oo-ui-pageLayout' );
-       for ( name in this.pages ) {
-               // Check for page match, exclude current page to find only page changes
-               if ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {
-                       this.setPage( name );
-                       break;
-               }
-       }
-};
-
-/**
- * Handle visibleItemChange events from the stackLayout
- *
- * The next visible page is set as the current page by selecting it
- * in the outline
- *
- * @param {OO.ui.PageLayout} page The next visible page in the layout
- */
-OO.ui.BookletLayout.prototype.onStackLayoutVisibleItemChange = function ( page ) {
-       // Set a flag to so that the resulting call to #onStackLayoutSet doesn't
-       // try and scroll the item into view again.
-       this.scrolling = true;
-       this.outlineSelectWidget.selectItemByData( page.getName() );
-       this.scrolling = false;
-};
-
-/**
- * Handle stack layout set events.
- *
- * @private
- * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel
- */
-OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
-       var layout = this;
-       if ( !this.scrolling && page ) {
-               page.scrollElementIntoView( { complete: function () {
-                       if ( layout.autoFocus ) {
-                               layout.focus();
-                       }
-               } } );
-       }
-};
-
-/**
- * Focus the first input in the current page.
- *
- * If no page is selected, the first selectable page will be selected.
- * If the focus is already in an element on the current page, nothing will happen.
- * @param {number} [itemIndex] A specific item to focus on
- */
-OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) {
-       var page,
-               items = this.stackLayout.getItems();
-
-       if ( itemIndex !== undefined && items[ itemIndex ] ) {
-               page = items[ itemIndex ];
-       } else {
-               page = this.stackLayout.getCurrentItem();
-       }
-
-       if ( !page && this.outlined ) {
-               this.selectFirstSelectablePage();
-               page = this.stackLayout.getCurrentItem();
-       }
-       if ( !page ) {
-               return;
-       }
-       // Only change the focus if is not already in the current page
-       if ( !OO.ui.contains( page.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {
-               page.focus();
-       }
-};
-
-/**
- * Find the first focusable input in the booklet layout and focus
- * on it.
- */
-OO.ui.BookletLayout.prototype.focusFirstFocusable = function () {
-       OO.ui.findFocusable( this.stackLayout.$element ).focus();
-};
-
-/**
- * Handle outline widget select events.
- *
- * @private
- * @param {OO.ui.OptionWidget|null} item Selected item
- */
-OO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {
-       if ( item ) {
-               this.setPage( item.getData() );
-       }
-};
-
-/**
- * Check if booklet has an outline.
- *
- * @return {boolean} Booklet has an outline
- */
-OO.ui.BookletLayout.prototype.isOutlined = function () {
-       return this.outlined;
-};
-
-/**
- * Check if booklet has editing controls.
- *
- * @return {boolean} Booklet is editable
- */
-OO.ui.BookletLayout.prototype.isEditable = function () {
-       return this.editable;
-};
-
-/**
- * Check if booklet has a visible outline.
- *
- * @return {boolean} Outline is visible
- */
-OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
-       return this.outlined && this.outlineVisible;
-};
-
-/**
- * Hide or show the outline.
- *
- * @param {boolean} [show] Show outline, omit to invert current state
- * @chainable
- */
-OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
-       if ( this.outlined ) {
-               show = show === undefined ? !this.outlineVisible : !!show;
-               this.outlineVisible = show;
-               this.toggleMenu( show );
-       }
-
-       return this;
-};
-
-/**
- * Get the page closest to the specified page.
- *
- * @param {OO.ui.PageLayout} page Page to use as a reference point
- * @return {OO.ui.PageLayout|null} Page closest to the specified page
- */
-OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
-       var next, prev, level,
-               pages = this.stackLayout.getItems(),
-               index = pages.indexOf( page );
-
-       if ( index !== -1 ) {
-               next = pages[ index + 1 ];
-               prev = pages[ index - 1 ];
-               // Prefer adjacent pages at the same level
-               if ( this.outlined ) {
-                       level = this.outlineSelectWidget.getItemFromData( page.getName() ).getLevel();
-                       if (
-                               prev &&
-                               level === this.outlineSelectWidget.getItemFromData( prev.getName() ).getLevel()
-                       ) {
-                               return prev;
-                       }
-                       if (
-                               next &&
-                               level === this.outlineSelectWidget.getItemFromData( next.getName() ).getLevel()
-                       ) {
-                               return next;
-                       }
-               }
-       }
-       return prev || next || null;
-};
-
-/**
- * Get the outline widget.
- *
- * If the booklet is not outlined, the method will return `null`.
- *
- * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if the booklet is not outlined
- */
-OO.ui.BookletLayout.prototype.getOutline = function () {
-       return this.outlineSelectWidget;
-};
-
-/**
- * Get the outline controls widget.
- *
- * If the outline is not editable, the method will return `null`.
- *
- * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.
- */
-OO.ui.BookletLayout.prototype.getOutlineControls = function () {
-       return this.outlineControlsWidget;
-};
-
-/**
- * Get a page by its symbolic name.
- *
- * @param {string} name Symbolic name of page
- * @return {OO.ui.PageLayout|undefined} Page, if found
- */
-OO.ui.BookletLayout.prototype.getPage = function ( name ) {
-       return this.pages[ name ];
-};
-
-/**
- * Get the current page.
- *
- * @return {OO.ui.PageLayout|undefined} Current page, if found
- */
-OO.ui.BookletLayout.prototype.getCurrentPage = function () {
-       var name = this.getCurrentPageName();
-       return name ? this.getPage( name ) : undefined;
-};
-
-/**
- * Get the symbolic name of the current page.
- *
- * @return {string|null} Symbolic name of the current page
- */
-OO.ui.BookletLayout.prototype.getCurrentPageName = function () {
-       return this.currentPageName;
-};
-
-/**
- * Add pages to the booklet layout
- *
- * When pages are added with the same names as existing pages, the existing pages will be
- * automatically removed before the new pages are added.
- *
- * @param {OO.ui.PageLayout[]} pages Pages to add
- * @param {number} index Index of the insertion point
- * @fires add
- * @chainable
- */
-OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
-       var i, len, name, page, item, currentIndex,
-               stackLayoutPages = this.stackLayout.getItems(),
-               remove = [],
-               items = [];
-
-       // Remove pages with same names
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
-
-               if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {
-                       // Correct the insertion index
-                       currentIndex = stackLayoutPages.indexOf( this.pages[ name ] );
-                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
-                               index--;
-                       }
-                       remove.push( this.pages[ name ] );
-               }
-       }
-       if ( remove.length ) {
-               this.removePages( remove );
-       }
-
-       // Add new pages
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
-               this.pages[ page.getName() ] = page;
-               if ( this.outlined ) {
-                       item = new OO.ui.OutlineOptionWidget( { data: name } );
-                       page.setOutlineItem( item );
-                       items.push( item );
-               }
-       }
-
-       if ( this.outlined && items.length ) {
-               this.outlineSelectWidget.addItems( items, index );
-               this.selectFirstSelectablePage();
-       }
-       this.stackLayout.addItems( pages, index );
-       this.emit( 'add', pages, index );
-
-       return this;
-};
-
-/**
- * Remove the specified pages from the booklet layout.
- *
- * To remove all pages from the booklet, you may wish to use the #clearPages method instead.
- *
- * @param {OO.ui.PageLayout[]} pages An array of pages to remove
- * @fires remove
- * @chainable
- */
-OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
-       var i, len, name, page,
-               items = [];
-
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
-               delete this.pages[ name ];
-               if ( this.outlined ) {
-                       items.push( this.outlineSelectWidget.getItemFromData( name ) );
-                       page.setOutlineItem( null );
-               }
-       }
-       if ( this.outlined && items.length ) {
-               this.outlineSelectWidget.removeItems( items );
-               this.selectFirstSelectablePage();
-       }
-       this.stackLayout.removeItems( pages );
-       this.emit( 'remove', pages );
-
-       return this;
-};
-
-/**
- * Clear all pages from the booklet layout.
- *
- * To remove only a subset of pages from the booklet, use the #removePages method.
- *
- * @fires remove
- * @chainable
- */
-OO.ui.BookletLayout.prototype.clearPages = function () {
-       var i, len,
-               pages = this.stackLayout.getItems();
-
-       this.pages = {};
-       this.currentPageName = null;
-       if ( this.outlined ) {
-               this.outlineSelectWidget.clearItems();
-               for ( i = 0, len = pages.length; i < len; i++ ) {
-                       pages[ i ].setOutlineItem( null );
-               }
-       }
-       this.stackLayout.clearItems();
-
-       this.emit( 'remove', pages );
-
-       return this;
-};
-
-/**
- * Set the current page by symbolic name.
- *
- * @fires set
- * @param {string} name Symbolic name of page
- */
-OO.ui.BookletLayout.prototype.setPage = function ( name ) {
-       var selectedItem,
-               $focused,
-               page = this.pages[ name ],
-               previousPage = this.currentPageName && this.pages[ this.currentPageName ];
-
-       if ( name !== this.currentPageName ) {
-               if ( this.outlined ) {
-                       selectedItem = this.outlineSelectWidget.getSelectedItem();
-                       if ( selectedItem && selectedItem.getData() !== name ) {
-                               this.outlineSelectWidget.selectItemByData( name );
-                       }
-               }
-               if ( page ) {
-                       if ( previousPage ) {
-                               previousPage.setActive( false );
-                               // Blur anything focused if the next page doesn't have anything focusable.
-                               // This is not needed if the next page has something focusable (because once it is focused
-                               // this blur happens automatically). If the layout is non-continuous, this check is
-                               // meaningless because the next page is not visible yet and thus can't hold focus.
-                               if (
-                                       this.autoFocus &&
-                                       this.stackLayout.continuous &&
-                                       OO.ui.findFocusable( page.$element ).length !== 0
-                               ) {
-                                       $focused = previousPage.$element.find( ':focus' );
-                                       if ( $focused.length ) {
-                                               $focused[ 0 ].blur();
-                                       }
-                               }
-                       }
-                       this.currentPageName = name;
-                       page.setActive( true );
-                       this.stackLayout.setItem( page );
-                       if ( !this.stackLayout.continuous && previousPage ) {
-                               // This should not be necessary, since any inputs on the previous page should have been
-                               // blurred when it was hidden, but browsers are not very consistent about this.
-                               $focused = previousPage.$element.find( ':focus' );
-                               if ( $focused.length ) {
-                                       $focused[ 0 ].blur();
-                               }
-                       }
-                       this.emit( 'set', page );
-               }
-       }
-};
-
-/**
- * Select the first selectable page.
- *
- * @chainable
- */
-OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
-       if ( !this.outlineSelectWidget.getSelectedItem() ) {
-               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getFirstSelectableItem() );
-       }
-
-       return this;
-};
-
-/**
- * IndexLayouts contain {@link OO.ui.CardLayout card layouts} as well as
- * {@link OO.ui.TabSelectWidget tabs} that allow users to easily navigate through the cards and
- * select which one to display. By default, only one card is displayed at a time. When a user
- * navigates to a new card, the index layout automatically focuses on the first focusable element,
- * unless the default setting is changed.
- *
- * TODO: This class is similar to BookletLayout, we may want to refactor to reduce duplication
- *
- *     @example
- *     // Example of a IndexLayout that contains two CardLayouts.
- *
- *     function CardOneLayout( name, config ) {
- *         CardOneLayout.parent.call( this, name, config );
- *         this.$element.append( '<p>First card</p>' );
- *     }
- *     OO.inheritClass( CardOneLayout, OO.ui.CardLayout );
- *     CardOneLayout.prototype.setupTabItem = function () {
- *         this.tabItem.setLabel( 'Card one' );
- *     };
- *
- *     var card1 = new CardOneLayout( 'one' ),
- *         card2 = new CardLayout( 'two', { label: 'Card two' } );
- *
- *     card2.$element.append( '<p>Second card</p>' );
- *
- *     var index = new OO.ui.IndexLayout();
- *
- *     index.addCards ( [ card1, card2 ] );
- *     $( 'body' ).append( index.$element );
- *
- * @class
- * @extends OO.ui.MenuLayout
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [continuous=false] Show all cards, one after another
- * @cfg {boolean} [expanded=true] Expand the content panel to fill the entire parent element.
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed.
- */
-OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
-       // Configuration initialization
-       config = $.extend( {}, config, { menuPosition: 'top' } );
-
-       // Parent constructor
-       OO.ui.IndexLayout.parent.call( this, config );
-
-       // Properties
-       this.currentCardName = null;
-       this.cards = {};
-       this.ignoreFocus = false;
-       this.stackLayout = new OO.ui.StackLayout( {
-               continuous: !!config.continuous,
-               expanded: config.expanded
-       } );
-       this.$content.append( this.stackLayout.$element );
-       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
-
-       this.tabSelectWidget = new OO.ui.TabSelectWidget();
-       this.tabPanel = new OO.ui.PanelLayout();
-       this.$menu.append( this.tabPanel.$element );
-
-       this.toggleMenu( true );
-
-       // Events
-       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
-       this.tabSelectWidget.connect( this, { select: 'onTabSelectWidgetSelect' } );
-       if ( this.autoFocus ) {
-               // Event 'focus' does not bubble, but 'focusin' does
-               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
-       }
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-indexLayout' );
-       this.stackLayout.$element.addClass( 'oo-ui-indexLayout-stackLayout' );
-       this.tabPanel.$element
-               .addClass( 'oo-ui-indexLayout-tabPanel' )
-               .append( this.tabSelectWidget.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.IndexLayout, OO.ui.MenuLayout );
-
-/* Events */
-
-/**
- * A 'set' event is emitted when a card is {@link #setCard set} to be displayed by the index layout.
- * @event set
- * @param {OO.ui.CardLayout} card Current card
- */
-
-/**
- * An 'add' event is emitted when cards are {@link #addCards added} to the index layout.
- *
- * @event add
- * @param {OO.ui.CardLayout[]} card Added cards
- * @param {number} index Index cards were added at
- */
-
-/**
- * A 'remove' event is emitted when cards are {@link #clearCards cleared} or
- * {@link #removeCards removed} from the index.
- *
- * @event remove
- * @param {OO.ui.CardLayout[]} cards Removed cards
- */
-
-/* Methods */
-
-/**
- * Handle stack layout focus.
- *
- * @private
- * @param {jQuery.Event} e Focusin event
- */
-OO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) {
-       var name, $target;
-
-       // Find the card that an element was focused within
-       $target = $( e.target ).closest( '.oo-ui-cardLayout' );
-       for ( name in this.cards ) {
-               // Check for card match, exclude current card to find only card changes
-               if ( this.cards[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentCardName ) {
-                       this.setCard( name );
-                       break;
-               }
-       }
-};
-
-/**
- * Handle stack layout set events.
- *
- * @private
- * @param {OO.ui.PanelLayout|null} card The card panel that is now the current panel
- */
-OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) {
-       var layout = this;
-       if ( card ) {
-               card.scrollElementIntoView( { complete: function () {
-                       if ( layout.autoFocus ) {
-                               layout.focus();
-                       }
-               } } );
-       }
-};
-
-/**
- * Focus the first input in the current card.
- *
- * If no card is selected, the first selectable card will be selected.
- * If the focus is already in an element on the current card, nothing will happen.
- * @param {number} [itemIndex] A specific item to focus on
- */
-OO.ui.IndexLayout.prototype.focus = function ( itemIndex ) {
-       var card,
-               items = this.stackLayout.getItems();
-
-       if ( itemIndex !== undefined && items[ itemIndex ] ) {
-               card = items[ itemIndex ];
-       } else {
-               card = this.stackLayout.getCurrentItem();
-       }
-
-       if ( !card ) {
-               this.selectFirstSelectableCard();
-               card = this.stackLayout.getCurrentItem();
-       }
-       if ( !card ) {
-               return;
-       }
-       // Only change the focus if is not already in the current page
-       if ( !OO.ui.contains( card.$element[ 0 ], this.getElementDocument().activeElement, true ) ) {
-               card.focus();
-       }
-};
-
-/**
- * Find the first focusable input in the index layout and focus
- * on it.
- */
-OO.ui.IndexLayout.prototype.focusFirstFocusable = function () {
-       OO.ui.findFocusable( this.stackLayout.$element ).focus();
-};
-
-/**
- * Handle tab widget select events.
- *
- * @private
- * @param {OO.ui.OptionWidget|null} item Selected item
- */
-OO.ui.IndexLayout.prototype.onTabSelectWidgetSelect = function ( item ) {
-       if ( item ) {
-               this.setCard( item.getData() );
-       }
-};
-
-/**
- * Get the card closest to the specified card.
- *
- * @param {OO.ui.CardLayout} card Card to use as a reference point
- * @return {OO.ui.CardLayout|null} Card closest to the specified card
- */
-OO.ui.IndexLayout.prototype.getClosestCard = function ( card ) {
-       var next, prev, level,
-               cards = this.stackLayout.getItems(),
-               index = cards.indexOf( card );
-
-       if ( index !== -1 ) {
-               next = cards[ index + 1 ];
-               prev = cards[ index - 1 ];
-               // Prefer adjacent cards at the same level
-               level = this.tabSelectWidget.getItemFromData( card.getName() ).getLevel();
-               if (
-                       prev &&
-                       level === this.tabSelectWidget.getItemFromData( prev.getName() ).getLevel()
-               ) {
-                       return prev;
-               }
-               if (
-                       next &&
-                       level === this.tabSelectWidget.getItemFromData( next.getName() ).getLevel()
-               ) {
-                       return next;
-               }
-       }
-       return prev || next || null;
-};
-
-/**
- * Get the tabs widget.
- *
- * @return {OO.ui.TabSelectWidget} Tabs widget
- */
-OO.ui.IndexLayout.prototype.getTabs = function () {
-       return this.tabSelectWidget;
-};
-
-/**
- * Get a card by its symbolic name.
- *
- * @param {string} name Symbolic name of card
- * @return {OO.ui.CardLayout|undefined} Card, if found
- */
-OO.ui.IndexLayout.prototype.getCard = function ( name ) {
-       return this.cards[ name ];
-};
-
-/**
- * Get the current card.
- *
- * @return {OO.ui.CardLayout|undefined} Current card, if found
- */
-OO.ui.IndexLayout.prototype.getCurrentCard = function () {
-       var name = this.getCurrentCardName();
-       return name ? this.getCard( name ) : undefined;
-};
-
-/**
- * Get the symbolic name of the current card.
- *
- * @return {string|null} Symbolic name of the current card
- */
-OO.ui.IndexLayout.prototype.getCurrentCardName = function () {
-       return this.currentCardName;
-};
-
-/**
- * Add cards to the index layout
- *
- * When cards are added with the same names as existing cards, the existing cards will be
- * automatically removed before the new cards are added.
- *
- * @param {OO.ui.CardLayout[]} cards Cards to add
- * @param {number} index Index of the insertion point
- * @fires add
- * @chainable
- */
-OO.ui.IndexLayout.prototype.addCards = function ( cards, index ) {
-       var i, len, name, card, item, currentIndex,
-               stackLayoutCards = this.stackLayout.getItems(),
-               remove = [],
-               items = [];
-
-       // Remove cards with same names
-       for ( i = 0, len = cards.length; i < len; i++ ) {
-               card = cards[ i ];
-               name = card.getName();
-
-               if ( Object.prototype.hasOwnProperty.call( this.cards, name ) ) {
-                       // Correct the insertion index
-                       currentIndex = stackLayoutCards.indexOf( this.cards[ name ] );
-                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
-                               index--;
-                       }
-                       remove.push( this.cards[ name ] );
-               }
-       }
-       if ( remove.length ) {
-               this.removeCards( remove );
-       }
-
-       // Add new cards
-       for ( i = 0, len = cards.length; i < len; i++ ) {
-               card = cards[ i ];
-               name = card.getName();
-               this.cards[ card.getName() ] = card;
-               item = new OO.ui.TabOptionWidget( { data: name } );
-               card.setTabItem( item );
-               items.push( item );
-       }
-
-       if ( items.length ) {
-               this.tabSelectWidget.addItems( items, index );
-               this.selectFirstSelectableCard();
-       }
-       this.stackLayout.addItems( cards, index );
-       this.emit( 'add', cards, index );
-
-       return this;
-};
-
-/**
- * Remove the specified cards from the index layout.
- *
- * To remove all cards from the index, you may wish to use the #clearCards method instead.
- *
- * @param {OO.ui.CardLayout[]} cards An array of cards to remove
- * @fires remove
- * @chainable
- */
-OO.ui.IndexLayout.prototype.removeCards = function ( cards ) {
-       var i, len, name, card,
-               items = [];
-
-       for ( i = 0, len = cards.length; i < len; i++ ) {
-               card = cards[ i ];
-               name = card.getName();
-               delete this.cards[ name ];
-               items.push( this.tabSelectWidget.getItemFromData( name ) );
-               card.setTabItem( null );
-       }
-       if ( items.length ) {
-               this.tabSelectWidget.removeItems( items );
-               this.selectFirstSelectableCard();
-       }
-       this.stackLayout.removeItems( cards );
-       this.emit( 'remove', cards );
-
-       return this;
-};
-
-/**
- * Clear all cards from the index layout.
- *
- * To remove only a subset of cards from the index, use the #removeCards method.
- *
- * @fires remove
- * @chainable
- */
-OO.ui.IndexLayout.prototype.clearCards = function () {
-       var i, len,
-               cards = this.stackLayout.getItems();
-
-       this.cards = {};
-       this.currentCardName = null;
-       this.tabSelectWidget.clearItems();
-       for ( i = 0, len = cards.length; i < len; i++ ) {
-               cards[ i ].setTabItem( null );
-       }
-       this.stackLayout.clearItems();
-
-       this.emit( 'remove', cards );
-
-       return this;
-};
-
-/**
- * Set the current card by symbolic name.
- *
- * @fires set
- * @param {string} name Symbolic name of card
- */
-OO.ui.IndexLayout.prototype.setCard = function ( name ) {
-       var selectedItem,
-               $focused,
-               card = this.cards[ name ],
-               previousCard = this.currentCardName && this.cards[ this.currentCardName ];
-
-       if ( name !== this.currentCardName ) {
-               selectedItem = this.tabSelectWidget.getSelectedItem();
-               if ( selectedItem && selectedItem.getData() !== name ) {
-                       this.tabSelectWidget.selectItemByData( name );
-               }
-               if ( card ) {
-                       if ( previousCard ) {
-                               previousCard.setActive( false );
-                               // Blur anything focused if the next card doesn't have anything focusable.
-                               // This is not needed if the next card has something focusable (because once it is focused
-                               // this blur happens automatically). If the layout is non-continuous, this check is
-                               // meaningless because the next card is not visible yet and thus can't hold focus.
-                               if (
-                                       this.autoFocus &&
-                                       this.stackLayout.continuous &&
-                                       OO.ui.findFocusable( card.$element ).length !== 0
-                               ) {
-                                       $focused = previousCard.$element.find( ':focus' );
-                                       if ( $focused.length ) {
-                                               $focused[ 0 ].blur();
-                                       }
-                               }
-                       }
-                       this.currentCardName = name;
-                       card.setActive( true );
-                       this.stackLayout.setItem( card );
-                       if ( !this.stackLayout.continuous && previousCard ) {
-                               // This should not be necessary, since any inputs on the previous card should have been
-                               // blurred when it was hidden, but browsers are not very consistent about this.
-                               $focused = previousCard.$element.find( ':focus' );
-                               if ( $focused.length ) {
-                                       $focused[ 0 ].blur();
-                               }
-                       }
-                       this.emit( 'set', card );
-               }
-       }
-};
-
-/**
- * Select the first selectable card.
- *
- * @chainable
- */
-OO.ui.IndexLayout.prototype.selectFirstSelectableCard = function () {
-       if ( !this.tabSelectWidget.getSelectedItem() ) {
-               this.tabSelectWidget.selectItem( this.tabSelectWidget.getFirstSelectableItem() );
-       }
-
-       return this;
-};
-
-/**
- * PanelLayouts expand to cover the entire area of their parent. They can be configured with scrolling, padding,
- * and a frame, and are often used together with {@link OO.ui.StackLayout StackLayouts}.
- *
- *     @example
- *     // Example of a panel layout
- *     var panel = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true,
- *         padded: true,
- *         $content: $( '<p>A panel layout with padding and a frame.</p>' )
- *     } );
- *     $( 'body' ).append( panel.$element );
- *
- * @class
- * @extends OO.ui.Layout
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [scrollable=false] Allow vertical scrolling
- * @cfg {boolean} [padded=false] Add padding between the content and the edges of the panel.
- * @cfg {boolean} [expanded=true] Expand the panel to fill the entire parent element.
- * @cfg {boolean} [framed=false] Render the panel with a frame to visually separate it from outside content.
- */
-OO.ui.PanelLayout = function OoUiPanelLayout( config ) {
-       // Configuration initialization
-       config = $.extend( {
-               scrollable: false,
-               padded: false,
-               expanded: true,
-               framed: false
-       }, config );
-
-       // Parent constructor
-       OO.ui.PanelLayout.parent.call( this, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-panelLayout' );
-       if ( config.scrollable ) {
-               this.$element.addClass( 'oo-ui-panelLayout-scrollable' );
-       }
-       if ( config.padded ) {
-               this.$element.addClass( 'oo-ui-panelLayout-padded' );
-       }
-       if ( config.expanded ) {
-               this.$element.addClass( 'oo-ui-panelLayout-expanded' );
-       }
-       if ( config.framed ) {
-               this.$element.addClass( 'oo-ui-panelLayout-framed' );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );
-
-/* Methods */
-
-/**
- * Focus the panel layout
- *
- * The default implementation just focuses the first focusable element in the panel
- */
-OO.ui.PanelLayout.prototype.focus = function () {
-       OO.ui.findFocusable( this.$element ).focus();
-};
-
-/**
- * CardLayouts are used within {@link OO.ui.IndexLayout index layouts} to create cards that users can select and display
- * from the index's optional {@link OO.ui.TabSelectWidget tab} navigation. Cards are usually not instantiated directly,
- * rather extended to include the required content and functionality.
- *
- * Each card must have a unique symbolic name, which is passed to the constructor. In addition, the card's tab
- * item is customized (with a label) using the #setupTabItem method. See
- * {@link OO.ui.IndexLayout IndexLayout} for an example.
- *
- * @class
- * @extends OO.ui.PanelLayout
- *
- * @constructor
- * @param {string} name Unique symbolic name of card
- * @param {Object} [config] Configuration options
- * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] Label for card's tab
- */
-OO.ui.CardLayout = function OoUiCardLayout( name, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( name ) && config === undefined ) {
-               config = name;
-               name = config.name;
-       }
-
-       // Configuration initialization
-       config = $.extend( { scrollable: true }, config );
-
-       // Parent constructor
-       OO.ui.CardLayout.parent.call( this, config );
-
-       // Properties
-       this.name = name;
-       this.label = config.label;
-       this.tabItem = null;
-       this.active = false;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-cardLayout' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.CardLayout, OO.ui.PanelLayout );
-
-/* Events */
-
-/**
- * An 'active' event is emitted when the card becomes active. Cards become active when they are
- * shown in a index layout that is configured to display only one card at a time.
- *
- * @event active
- * @param {boolean} active Card is active
- */
-
-/* Methods */
-
-/**
- * Get the symbolic name of the card.
- *
- * @return {string} Symbolic name of card
- */
-OO.ui.CardLayout.prototype.getName = function () {
-       return this.name;
-};
-
-/**
- * Check if card is active.
- *
- * Cards become active when they are shown in a {@link OO.ui.IndexLayout index layout} that is configured to display
- * only one card at a time. Additional CSS is applied to the card's tab item to reflect the active state.
- *
- * @return {boolean} Card is active
- */
-OO.ui.CardLayout.prototype.isActive = function () {
-       return this.active;
-};
-
-/**
- * Get tab item.
- *
- * The tab item allows users to access the card from the index's tab
- * navigation. The tab item itself can be customized (with a label, level, etc.) using the #setupTabItem method.
- *
- * @return {OO.ui.TabOptionWidget|null} Tab option widget
- */
-OO.ui.CardLayout.prototype.getTabItem = function () {
-       return this.tabItem;
-};
-
-/**
- * Set or unset the tab item.
- *
- * Specify a {@link OO.ui.TabOptionWidget tab option} to set it,
- * or `null` to clear the tab item. To customize the tab item itself (e.g., to set a label or tab
- * level), use #setupTabItem instead of this method.
- *
- * @param {OO.ui.TabOptionWidget|null} tabItem Tab option widget, null to clear
- * @chainable
- */
-OO.ui.CardLayout.prototype.setTabItem = function ( tabItem ) {
-       this.tabItem = tabItem || null;
-       if ( tabItem ) {
-               this.setupTabItem();
-       }
-       return this;
-};
-
-/**
- * Set up the tab item.
- *
- * Use this method to customize the tab item (e.g., to add a label or tab level). To set or unset
- * the tab item itself (with a {@link OO.ui.TabOptionWidget tab option} or `null`), use
- * the #setTabItem method instead.
- *
- * @param {OO.ui.TabOptionWidget} tabItem Tab option widget to set up
- * @chainable
- */
-OO.ui.CardLayout.prototype.setupTabItem = function () {
-       if ( this.label ) {
-               this.tabItem.setLabel( this.label );
-       }
-       return this;
-};
-
-/**
- * Set the card to its 'active' state.
- *
- * Cards become active when they are shown in a index layout that is configured to display only one card at a time. Additional
- * CSS is applied to the tab item to reflect the card's active state. Outside of the index
- * context, setting the active state on a card does nothing.
- *
- * @param {boolean} value Card is active
- * @fires active
- */
-OO.ui.CardLayout.prototype.setActive = function ( active ) {
-       active = !!active;
-
-       if ( active !== this.active ) {
-               this.active = active;
-               this.$element.toggleClass( 'oo-ui-cardLayout-active', this.active );
-               this.emit( 'active', this.active );
-       }
-};
-
-/**
- * PageLayouts are used within {@link OO.ui.BookletLayout booklet layouts} to create pages that users can select and display
- * from the booklet's optional {@link OO.ui.OutlineSelectWidget outline} navigation. Pages are usually not instantiated directly,
- * rather extended to include the required content and functionality.
- *
- * Each page must have a unique symbolic name, which is passed to the constructor. In addition, the page's outline
- * item is customized (with a label, outline level, etc.) using the #setupOutlineItem method. See
- * {@link OO.ui.BookletLayout BookletLayout} for an example.
- *
- * @class
- * @extends OO.ui.PanelLayout
- *
- * @constructor
- * @param {string} name Unique symbolic name of page
- * @param {Object} [config] Configuration options
- */
-OO.ui.PageLayout = function OoUiPageLayout( name, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( name ) && config === undefined ) {
-               config = name;
-               name = config.name;
-       }
-
-       // Configuration initialization
-       config = $.extend( { scrollable: true }, config );
-
-       // Parent constructor
-       OO.ui.PageLayout.parent.call( this, config );
-
-       // Properties
-       this.name = name;
-       this.outlineItem = null;
-       this.active = false;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-pageLayout' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PageLayout, OO.ui.PanelLayout );
-
-/* Events */
-
-/**
- * An 'active' event is emitted when the page becomes active. Pages become active when they are
- * shown in a booklet layout that is configured to display only one page at a time.
- *
- * @event active
- * @param {boolean} active Page is active
- */
-
-/* Methods */
-
-/**
- * Get the symbolic name of the page.
- *
- * @return {string} Symbolic name of page
- */
-OO.ui.PageLayout.prototype.getName = function () {
-       return this.name;
-};
-
-/**
- * Check if page is active.
- *
- * Pages become active when they are shown in a {@link OO.ui.BookletLayout booklet layout} that is configured to display
- * only one page at a time. Additional CSS is applied to the page's outline item to reflect the active state.
- *
- * @return {boolean} Page is active
- */
-OO.ui.PageLayout.prototype.isActive = function () {
-       return this.active;
-};
-
-/**
- * Get outline item.
- *
- * The outline item allows users to access the page from the booklet's outline
- * navigation. The outline item itself can be customized (with a label, level, etc.) using the #setupOutlineItem method.
- *
- * @return {OO.ui.OutlineOptionWidget|null} Outline option widget
- */
-OO.ui.PageLayout.prototype.getOutlineItem = function () {
-       return this.outlineItem;
-};
-
-/**
- * Set or unset the outline item.
- *
- * Specify an {@link OO.ui.OutlineOptionWidget outline option} to set it,
- * or `null` to clear the outline item. To customize the outline item itself (e.g., to set a label or outline
- * level), use #setupOutlineItem instead of this method.
- *
- * @param {OO.ui.OutlineOptionWidget|null} outlineItem Outline option widget, null to clear
- * @chainable
- */
-OO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {
-       this.outlineItem = outlineItem || null;
-       if ( outlineItem ) {
-               this.setupOutlineItem();
-       }
-       return this;
-};
-
-/**
- * Set up the outline item.
- *
- * Use this method to customize the outline item (e.g., to add a label or outline level). To set or unset
- * the outline item itself (with an {@link OO.ui.OutlineOptionWidget outline option} or `null`), use
- * the #setOutlineItem method instead.
- *
- * @param {OO.ui.OutlineOptionWidget} outlineItem Outline option widget to set up
- * @chainable
- */
-OO.ui.PageLayout.prototype.setupOutlineItem = function () {
-       return this;
-};
-
-/**
- * Set the page to its 'active' state.
- *
- * Pages become active when they are shown in a booklet layout that is configured to display only one page at a time. Additional
- * CSS is applied to the outline item to reflect the page's active state. Outside of the booklet
- * context, setting the active state on a page does nothing.
- *
- * @param {boolean} value Page is active
- * @fires active
- */
-OO.ui.PageLayout.prototype.setActive = function ( active ) {
-       active = !!active;
-
-       if ( active !== this.active ) {
-               this.active = active;
-               this.$element.toggleClass( 'oo-ui-pageLayout-active', active );
-               this.emit( 'active', this.active );
-       }
-};
-
-/**
- * StackLayouts contain a series of {@link OO.ui.PanelLayout panel layouts}. By default, only one panel is displayed
- * at a time, though the stack layout can also be configured to show all contained panels, one after another,
- * by setting the #continuous option to 'true'.
- *
- *     @example
- *     // A stack layout with two panels, configured to be displayed continously
- *     var myStack = new OO.ui.StackLayout( {
- *         items: [
- *             new OO.ui.PanelLayout( {
- *                 $content: $( '<p>Panel One</p>' ),
- *                 padded: true,
- *                 framed: true
- *             } ),
- *             new OO.ui.PanelLayout( {
- *                 $content: $( '<p>Panel Two</p>' ),
- *                 padded: true,
- *                 framed: true
- *             } )
- *         ],
- *         continuous: true
- *     } );
- *     $( 'body' ).append( myStack.$element );
- *
- * @class
- * @extends OO.ui.PanelLayout
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [continuous=false] Show all panels, one after another. By default, only one panel is displayed at a time.
- * @cfg {OO.ui.Layout[]} [items] Panel layouts to add to the stack layout.
- */
-OO.ui.StackLayout = function OoUiStackLayout( config ) {
-       // Configuration initialization
-       config = $.extend( { scrollable: true }, config );
-
-       // Parent constructor
-       OO.ui.StackLayout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-       // Properties
-       this.currentItem = null;
-       this.continuous = !!config.continuous;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-stackLayout' );
-       if ( this.continuous ) {
-               this.$element.addClass( 'oo-ui-stackLayout-continuous' );
-               this.$element.on( 'scroll', OO.ui.debounce( this.onScroll.bind( this ), 250 ) );
-       }
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.StackLayout, OO.ui.PanelLayout );
-OO.mixinClass( OO.ui.StackLayout, OO.ui.mixin.GroupElement );
-
-/* Events */
-
-/**
- * A 'set' event is emitted when panels are {@link #addItems added}, {@link #removeItems removed},
- * {@link #clearItems cleared} or {@link #setItem displayed}.
- *
- * @event set
- * @param {OO.ui.Layout|null} item Current panel or `null` if no panel is shown
- */
-
-/**
- * When used in continuous mode, this event is emitted when the user scrolls down
- * far enough such that currentItem is no longer visible.
- *
- * @event visibleItemChange
- * @param {OO.ui.PanelLayout} panel The next visible item in the layout
- */
-
-/* Methods */
-
-/**
- * Handle scroll events from the layout element
- *
- * @param {jQuery.Event} e
- * @fires visibleItemChange
- */
-OO.ui.StackLayout.prototype.onScroll = function () {
-       var currentRect,
-               len = this.items.length,
-               currentIndex = this.items.indexOf( this.currentItem ),
-               newIndex = currentIndex,
-               containerRect = this.$element[ 0 ].getBoundingClientRect();
-
-       if ( !containerRect || ( !containerRect.top && !containerRect.bottom ) ) {
-               // Can't get bounding rect, possibly not attached.
-               return;
-       }
-
-       function getRect( item ) {
-               return item.$element[ 0 ].getBoundingClientRect();
-       }
-
-       function isVisible( item ) {
-               var rect = getRect( item );
-               return rect.bottom > containerRect.top && rect.top < containerRect.bottom;
-       }
-
-       currentRect = getRect( this.currentItem );
-
-       if ( currentRect.bottom < containerRect.top ) {
-               // Scrolled down past current item
-               while ( ++newIndex < len ) {
-                       if ( isVisible( this.items[ newIndex ] ) ) {
-                               break;
-                       }
-               }
-       } else if ( currentRect.top > containerRect.bottom ) {
-               // Scrolled up past current item
-               while ( --newIndex >= 0 ) {
-                       if ( isVisible( this.items[ newIndex ] ) ) {
-                               break;
-                       }
-               }
-       }
-
-       if ( newIndex !== currentIndex ) {
-               this.emit( 'visibleItemChange', this.items[ newIndex ] );
-       }
-};
-
-/**
- * Get the current panel.
- *
- * @return {OO.ui.Layout|null}
- */
-OO.ui.StackLayout.prototype.getCurrentItem = function () {
-       return this.currentItem;
-};
-
-/**
- * Unset the current item.
- *
- * @private
- * @param {OO.ui.StackLayout} layout
- * @fires set
- */
-OO.ui.StackLayout.prototype.unsetCurrentItem = function () {
-       var prevItem = this.currentItem;
-       if ( prevItem === null ) {
-               return;
-       }
-
-       this.currentItem = null;
-       this.emit( 'set', null );
-};
-
-/**
- * Add panel layouts to the stack layout.
- *
- * Panels will be added to the end of the stack layout array unless the optional index parameter specifies a different
- * insertion point. Adding a panel that is already in the stack will move it to the end of the array or the point specified
- * by the index.
- *
- * @param {OO.ui.Layout[]} items Panels to add
- * @param {number} [index] Index of the insertion point
- * @chainable
- */
-OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
-       // Update the visibility
-       this.updateHiddenState( items, this.currentItem );
-
-       // Mixin method
-       OO.ui.mixin.GroupElement.prototype.addItems.call( this, items, index );
-
-       if ( !this.currentItem && items.length ) {
-               this.setItem( items[ 0 ] );
-       }
-
-       return this;
-};
-
-/**
- * Remove the specified panels from the stack layout.
- *
- * Removed panels are detached from the DOM, not removed, so that they may be reused. To remove all panels,
- * you may wish to use the #clearItems method instead.
- *
- * @param {OO.ui.Layout[]} items Panels to remove
- * @chainable
- * @fires set
- */
-OO.ui.StackLayout.prototype.removeItems = function ( items ) {
-       // Mixin method
-       OO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );
-
-       if ( items.indexOf( this.currentItem ) !== -1 ) {
-               if ( this.items.length ) {
-                       this.setItem( this.items[ 0 ] );
-               } else {
-                       this.unsetCurrentItem();
-               }
-       }
-
-       return this;
-};
-
-/**
- * Clear all panels from the stack layout.
- *
- * Cleared panels are detached from the DOM, not removed, so that they may be reused. To remove only
- * a subset of panels, use the #removeItems method.
- *
- * @chainable
- * @fires set
- */
-OO.ui.StackLayout.prototype.clearItems = function () {
-       this.unsetCurrentItem();
-       OO.ui.mixin.GroupElement.prototype.clearItems.call( this );
-
-       return this;
-};
-
-/**
- * Show the specified panel.
- *
- * If another panel is currently displayed, it will be hidden.
- *
- * @param {OO.ui.Layout} item Panel to show
- * @chainable
- * @fires set
- */
-OO.ui.StackLayout.prototype.setItem = function ( item ) {
-       if ( item !== this.currentItem ) {
-               this.updateHiddenState( this.items, item );
-
-               if ( this.items.indexOf( item ) !== -1 ) {
-                       this.currentItem = item;
-                       this.emit( 'set', item );
-               } else {
-                       this.unsetCurrentItem();
-               }
-       }
-
-       return this;
-};
-
-/**
- * Update the visibility of all items in case of non-continuous view.
- *
- * Ensure all items are hidden except for the selected one.
- * This method does nothing when the stack is continuous.
- *
- * @private
- * @param {OO.ui.Layout[]} items Item list iterate over
- * @param {OO.ui.Layout} [selectedItem] Selected item to show
- */
-OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) {
-       var i, len;
-
-       if ( !this.continuous ) {
-               for ( i = 0, len = items.length; i < len; i++ ) {
-                       if ( !selectedItem || selectedItem !== items[ i ] ) {
-                               items[ i ].$element.addClass( 'oo-ui-element-hidden' );
-                       }
-               }
-               if ( selectedItem ) {
-                       selectedItem.$element.removeClass( 'oo-ui-element-hidden' );
-               }
-       }
-};
-
-/**
- * HorizontalLayout arranges its contents in a single line (using `display: inline-block` for its
- * items), with small margins between them. Convenient when you need to put a number of block-level
- * widgets on a single line next to each other.
- *
- * Note that inline elements, such as OO.ui.ButtonWidgets, do not need this wrapper.
- *
- *     @example
- *     // HorizontalLayout with a text input and a label
- *     var layout = new OO.ui.HorizontalLayout( {
- *       items: [
- *         new OO.ui.LabelWidget( { label: 'Label' } ),
- *         new OO.ui.TextInputWidget( { value: 'Text' } )
- *       ]
- *     } );
- *     $( 'body' ).append( layout.$element );
- *
- * @class
- * @extends OO.ui.Layout
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.Widget[]|OO.ui.Layout[]} [items] Widgets or other layouts to add to the layout.
- */
-OO.ui.HorizontalLayout = function OoUiHorizontalLayout( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.HorizontalLayout.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-horizontalLayout' );
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.HorizontalLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement );
-
-/**
- * BarToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup}). The {@link OO.ui.Tool tools} in a BarToolGroup are
- * displayed by icon in a single row. The title of the tool is displayed when users move the mouse over
- * the tool.
- *
- * BarToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar is
- * set up.
- *
- *     @example
- *     // Example of a BarToolGroup with two tools
- *     var toolFactory = new OO.ui.ToolFactory();
- *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
- *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
- *
- *     // We will be placing status text in this element when tools are used
- *     var $area = $( '<p>' ).text( 'Example of a BarToolGroup with two tools.' );
- *
- *     // Define the tools that we're going to place in our toolbar
- *
- *     // Create a class inheriting from OO.ui.Tool
- *     function SearchTool() {
- *         SearchTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( SearchTool, OO.ui.Tool );
- *     // Each tool must have a 'name' (used as an internal identifier, see later) and at least one
- *     // of 'icon' and 'title' (displayed icon and text).
- *     SearchTool.static.name = 'search';
- *     SearchTool.static.icon = 'search';
- *     SearchTool.static.title = 'Search...';
- *     // Defines the action that will happen when this tool is selected (clicked).
- *     SearchTool.prototype.onSelect = function () {
- *         $area.text( 'Search tool clicked!' );
- *         // Never display this tool as "active" (selected).
- *         this.setActive( false );
- *     };
- *     SearchTool.prototype.onUpdateState = function () {};
- *     // Make this tool available in our toolFactory and thus our toolbar
- *     toolFactory.register( SearchTool );
- *
- *     // This is a PopupTool. Rather than having a custom 'onSelect' action, it will display a
- *     // little popup window (a PopupWidget).
- *     function HelpTool( toolGroup, config ) {
- *         OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
- *             padded: true,
- *             label: 'Help',
- *             head: true
- *         } }, config ) );
- *         this.popup.$body.append( '<p>I am helpful!</p>' );
- *     }
- *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
- *     HelpTool.static.name = 'help';
- *     HelpTool.static.icon = 'help';
- *     HelpTool.static.title = 'Help';
- *     toolFactory.register( HelpTool );
- *
- *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
- *     // used once (but not all defined tools must be used).
- *     toolbar.setup( [
- *         {
- *             // 'bar' tool groups display tools by icon only
- *             type: 'bar',
- *             include: [ 'search', 'help' ]
- *         }
- *     ] );
- *
- *     // Create some UI around the toolbar and place it in the document
- *     var frame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true
- *     } );
- *     var contentFrame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         padded: true
- *     } );
- *     frame.$element.append(
- *         toolbar.$element,
- *         contentFrame.$element.append( $area )
- *     );
- *     $( 'body' ).append( frame.$element );
- *
- *     // Here is where the toolbar is actually built. This must be done after inserting it into the
- *     // document.
- *     toolbar.initialize();
- *
- * For more information about how to add tools to a bar tool group, please see {@link OO.ui.ToolGroup toolgroup}.
- * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @class
- * @extends OO.ui.ToolGroup
- *
- * @constructor
- * @param {OO.ui.Toolbar} toolbar
- * @param {Object} [config] Configuration options
- */
-OO.ui.BarToolGroup = function OoUiBarToolGroup( toolbar, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
-               config = toolbar;
-               toolbar = config.toolbar;
-       }
-
-       // Parent constructor
-       OO.ui.BarToolGroup.parent.call( this, toolbar, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-barToolGroup' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.BarToolGroup, OO.ui.ToolGroup );
-
-/* Static Properties */
-
-OO.ui.BarToolGroup.static.titleTooltips = true;
-
-OO.ui.BarToolGroup.static.accelTooltips = true;
-
-OO.ui.BarToolGroup.static.name = 'bar';
-
-/**
- * PopupToolGroup is an abstract base class used by both {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup} to provide a popup--an overlaid menu or list of tools with an
- * optional icon and label. This class can be used for other base classes that also use this functionality.
- *
- * @abstract
- * @class
- * @extends OO.ui.ToolGroup
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.ClippableElement
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {OO.ui.Toolbar} toolbar
- * @param {Object} [config] Configuration options
- * @cfg {string} [header] Text to display at the top of the popup
- */
-OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
-               config = toolbar;
-               toolbar = config.toolbar;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.PopupToolGroup.parent.call( this, toolbar, config );
-
-       // Properties
-       this.active = false;
-       this.dragging = false;
-       this.onBlurHandler = this.onBlur.bind( this );
-       this.$handle = $( '<span>' );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, config );
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
-
-       // Events
-       this.$handle.on( {
-               keydown: this.onHandleMouseKeyDown.bind( this ),
-               keyup: this.onHandleMouseKeyUp.bind( this ),
-               mousedown: this.onHandleMouseKeyDown.bind( this ),
-               mouseup: this.onHandleMouseKeyUp.bind( this )
-       } );
-
-       // Initialization
-       this.$handle
-               .addClass( 'oo-ui-popupToolGroup-handle' )
-               .append( this.$icon, this.$label, this.$indicator );
-       // If the pop-up should have a header, add it to the top of the toolGroup.
-       // Note: If this feature is useful for other widgets, we could abstract it into an
-       // OO.ui.HeaderedElement mixin constructor.
-       if ( config.header !== undefined ) {
-               this.$group
-                       .prepend( $( '<span>' )
-                               .addClass( 'oo-ui-popupToolGroup-header' )
-                               .text( config.header )
-                       );
-       }
-       this.$element
-               .addClass( 'oo-ui-popupToolGroup' )
-               .prepend( this.$handle );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PopupToolGroup, OO.ui.ToolGroup );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.ClippableElement );
-OO.mixinClass( OO.ui.PopupToolGroup, OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.PopupToolGroup.prototype.setDisabled = function () {
-       // Parent method
-       OO.ui.PopupToolGroup.parent.prototype.setDisabled.apply( this, arguments );
-
-       if ( this.isDisabled() && this.isElementAttached() ) {
-               this.setActive( false );
-       }
-};
-
-/**
- * Handle focus being lost.
- *
- * The event is actually generated from a mouseup/keyup, so it is not a normal blur event object.
- *
- * @protected
- * @param {jQuery.Event} e Mouse up or key up event
- */
-OO.ui.PopupToolGroup.prototype.onBlur = function ( e ) {
-       // Only deactivate when clicking outside the dropdown element
-       if ( $( e.target ).closest( '.oo-ui-popupToolGroup' )[ 0 ] !== this.$element[ 0 ] ) {
-               this.setActive( false );
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {
-       // Only close toolgroup when a tool was actually selected
-       if (
-               !this.isDisabled() && this.pressed && this.pressed === this.getTargetTool( e ) &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.setActive( false );
-       }
-       return OO.ui.PopupToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
-};
-
-/**
- * Handle mouse up and key up events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse up or key up event
- */
-OO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {
-       if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               return false;
-       }
-};
-
-/**
- * Handle mouse down and key down events.
- *
- * @protected
- * @param {jQuery.Event} e Mouse down or key down event
- */
-OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {
-       if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.setActive( !this.active );
-               return false;
-       }
-};
-
-/**
- * Switch into 'active' mode.
- *
- * When active, the popup is visible. A mouseup event anywhere in the document will trigger
- * deactivation.
- */
-OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
-       var containerWidth, containerLeft;
-       value = !!value;
-       if ( this.active !== value ) {
-               this.active = value;
-               if ( value ) {
-                       this.getElementDocument().addEventListener( 'mouseup', this.onBlurHandler, true );
-                       this.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, true );
-
-                       this.$clippable.css( 'left', '' );
-                       // Try anchoring the popup to the left first
-                       this.$element.addClass( 'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left' );
-                       this.toggleClipping( true );
-                       if ( this.isClippedHorizontally() ) {
-                               // Anchoring to the left caused the popup to clip, so anchor it to the right instead
-                               this.toggleClipping( false );
-                               this.$element
-                                       .removeClass( 'oo-ui-popupToolGroup-left' )
-                                       .addClass( 'oo-ui-popupToolGroup-right' );
-                               this.toggleClipping( true );
-                       }
-                       if ( this.isClippedHorizontally() ) {
-                               // Anchoring to the right also caused the popup to clip, so just make it fill the container
-                               containerWidth = this.$clippableScrollableContainer.width();
-                               containerLeft = this.$clippableScrollableContainer.offset().left;
-
-                               this.toggleClipping( false );
-                               this.$element.removeClass( 'oo-ui-popupToolGroup-right' );
-
-                               this.$clippable.css( {
-                                       left: -( this.$element.offset().left - containerLeft ),
-                                       width: containerWidth
-                               } );
-                       }
-               } else {
-                       this.getElementDocument().removeEventListener( 'mouseup', this.onBlurHandler, true );
-                       this.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, true );
-                       this.$element.removeClass(
-                               'oo-ui-popupToolGroup-active oo-ui-popupToolGroup-left  oo-ui-popupToolGroup-right'
-                       );
-                       this.toggleClipping( false );
-               }
-       }
-};
-
-/**
- * ListToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.MenuToolGroup MenuToolGroup}
- * and {@link OO.ui.BarToolGroup BarToolGroup}). The {@link OO.ui.Tool tools} in a ListToolGroup are displayed
- * by label in a dropdown menu. The title of the tool is used as the label text. The menu itself can be configured
- * with a label, icon, indicator, header, and title.
- *
- * ListToolGroups can be configured to be expanded and collapsed. Collapsed lists will have a ‘More’ option that
- * users can select to see the full list of tools. If a collapsed toolgroup is expanded, a ‘Fewer’ option permits
- * users to collapse the list again.
- *
- * ListToolGroups are created by a {@link OO.ui.ToolGroupFactory toolgroup factory} when the toolbar is set up. The factory
- * requires the ListToolGroup's symbolic name, 'list', which is specified along with the other configurations. For more
- * information about how to add tools to a ListToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
- *
- *     @example
- *     // Example of a ListToolGroup
- *     var toolFactory = new OO.ui.ToolFactory();
- *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
- *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
- *
- *     // Configure and register two tools
- *     function SettingsTool() {
- *         SettingsTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( SettingsTool, OO.ui.Tool );
- *     SettingsTool.static.name = 'settings';
- *     SettingsTool.static.icon = 'settings';
- *     SettingsTool.static.title = 'Change settings';
- *     SettingsTool.prototype.onSelect = function () {
- *         this.setActive( false );
- *     };
- *     SettingsTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( SettingsTool );
- *     // Register two more tools, nothing interesting here
- *     function StuffTool() {
- *         StuffTool.parent.apply( this, arguments );
- *     }
- *     OO.inheritClass( StuffTool, OO.ui.Tool );
- *     StuffTool.static.name = 'stuff';
- *     StuffTool.static.icon = 'search';
- *     StuffTool.static.title = 'Change the world';
- *     StuffTool.prototype.onSelect = function () {
- *         this.setActive( false );
- *     };
- *     StuffTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( StuffTool );
- *     toolbar.setup( [
- *         {
- *             // Configurations for list toolgroup.
- *             type: 'list',
- *             label: 'ListToolGroup',
- *             indicator: 'down',
- *             icon: 'ellipsis',
- *             title: 'This is the title, displayed when user moves the mouse over the list toolgroup',
- *             header: 'This is the header',
- *             include: [ 'settings', 'stuff' ],
- *             allowCollapse: ['stuff']
- *         }
- *     ] );
- *
- *     // Create some UI around the toolbar and place it in the document
- *     var frame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true
- *     } );
- *     frame.$element.append(
- *         toolbar.$element
- *     );
- *     $( 'body' ).append( frame.$element );
- *     // Build the toolbar. This must be done after the toolbar has been appended to the document.
- *     toolbar.initialize();
- *
- * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @class
- * @extends OO.ui.PopupToolGroup
- *
- * @constructor
- * @param {OO.ui.Toolbar} toolbar
- * @param {Object} [config] Configuration options
- * @cfg {Array} [allowCollapse] Allow the specified tools to be collapsed. By default, collapsible tools
- *  will only be displayed if users click the ‘More’ option displayed at the bottom of the list. If
- *  the list is expanded, a ‘Fewer’ option permits users to collapse the list again. Any tools that
- *  are included in the toolgroup, but are not designated as collapsible, will always be displayed.
- *  To open a collapsible list in its expanded state, set #expanded to 'true'.
- * @cfg {Array} [forceExpand] Expand the specified tools. All other tools will be designated as collapsible.
- *  Unless #expanded is set to true, the collapsible tools will be collapsed when the list is first opened.
- * @cfg {boolean} [expanded=false] Expand collapsible tools. This config is only relevant if tools have
- *  been designated as collapsible. When expanded is set to true, all tools in the group will be displayed
- *  when the list is first opened. Users can collapse the list with a ‘Fewer’ option at the bottom.
- */
-OO.ui.ListToolGroup = function OoUiListToolGroup( toolbar, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
-               config = toolbar;
-               toolbar = config.toolbar;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Properties (must be set before parent constructor, which calls #populate)
-       this.allowCollapse = config.allowCollapse;
-       this.forceExpand = config.forceExpand;
-       this.expanded = config.expanded !== undefined ? config.expanded : false;
-       this.collapsibleTools = [];
-
-       // Parent constructor
-       OO.ui.ListToolGroup.parent.call( this, toolbar, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-listToolGroup' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ListToolGroup, OO.ui.PopupToolGroup );
-
-/* Static Properties */
-
-OO.ui.ListToolGroup.static.name = 'list';
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.ListToolGroup.prototype.populate = function () {
-       var i, len, allowCollapse = [];
-
-       OO.ui.ListToolGroup.parent.prototype.populate.call( this );
-
-       // Update the list of collapsible tools
-       if ( this.allowCollapse !== undefined ) {
-               allowCollapse = this.allowCollapse;
-       } else if ( this.forceExpand !== undefined ) {
-               allowCollapse = OO.simpleArrayDifference( Object.keys( this.tools ), this.forceExpand );
-       }
-
-       this.collapsibleTools = [];
-       for ( i = 0, len = allowCollapse.length; i < len; i++ ) {
-               if ( this.tools[ allowCollapse[ i ] ] !== undefined ) {
-                       this.collapsibleTools.push( this.tools[ allowCollapse[ i ] ] );
-               }
-       }
-
-       // Keep at the end, even when tools are added
-       this.$group.append( this.getExpandCollapseTool().$element );
-
-       this.getExpandCollapseTool().toggle( this.collapsibleTools.length !== 0 );
-       this.updateCollapsibleState();
-};
-
-OO.ui.ListToolGroup.prototype.getExpandCollapseTool = function () {
-       var ExpandCollapseTool;
-       if ( this.expandCollapseTool === undefined ) {
-               ExpandCollapseTool = function () {
-                       ExpandCollapseTool.parent.apply( this, arguments );
-               };
-
-               OO.inheritClass( ExpandCollapseTool, OO.ui.Tool );
-
-               ExpandCollapseTool.prototype.onSelect = function () {
-                       this.toolGroup.expanded = !this.toolGroup.expanded;
-                       this.toolGroup.updateCollapsibleState();
-                       this.setActive( false );
-               };
-               ExpandCollapseTool.prototype.onUpdateState = function () {
-                       // Do nothing. Tool interface requires an implementation of this function.
-               };
-
-               ExpandCollapseTool.static.name = 'more-fewer';
-
-               this.expandCollapseTool = new ExpandCollapseTool( this );
-       }
-       return this.expandCollapseTool;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ListToolGroup.prototype.onMouseKeyUp = function ( e ) {
-       // Do not close the popup when the user wants to show more/fewer tools
-       if (
-               $( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               // HACK: Prevent the popup list from being hidden. Skip the PopupToolGroup implementation (which
-               // hides the popup list when a tool is selected) and call ToolGroup's implementation directly.
-               return OO.ui.ListToolGroup.parent.parent.prototype.onMouseKeyUp.call( this, e );
-       } else {
-               return OO.ui.ListToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
-       }
-};
-
-OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () {
-       var i, len;
-
-       this.getExpandCollapseTool()
-               .setIcon( this.expanded ? 'collapse' : 'expand' )
-               .setTitle( OO.ui.msg( this.expanded ? 'ooui-toolgroup-collapse' : 'ooui-toolgroup-expand' ) );
-
-       for ( i = 0, len = this.collapsibleTools.length; i < len; i++ ) {
-               this.collapsibleTools[ i ].toggle( this.expanded );
-       }
-};
-
-/**
- * MenuToolGroups are one of three types of {@link OO.ui.ToolGroup toolgroups} that are used to
- * create {@link OO.ui.Toolbar toolbars} (the other types of groups are {@link OO.ui.BarToolGroup BarToolGroup}
- * and {@link OO.ui.ListToolGroup ListToolGroup}). MenuToolGroups contain selectable {@link OO.ui.Tool tools},
- * which are displayed by label in a dropdown menu. The tool's title is used as the label text, and the
- * menu label is updated to reflect which tool or tools are currently selected. If no tools are selected,
- * the menu label is empty. The menu can be configured with an indicator, icon, title, and/or header.
- *
- * MenuToolGroups are created by a {@link OO.ui.ToolGroupFactory tool group factory} when the toolbar
- * is set up.
- *
- *     @example
- *     // Example of a MenuToolGroup
- *     var toolFactory = new OO.ui.ToolFactory();
- *     var toolGroupFactory = new OO.ui.ToolGroupFactory();
- *     var toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory );
- *
- *     // We will be placing status text in this element when tools are used
- *     var $area = $( '<p>' ).text( 'An example of a MenuToolGroup. Select a tool from the dropdown menu.' );
- *
- *     // Define the tools that we're going to place in our toolbar
- *
- *     function SettingsTool() {
- *         SettingsTool.parent.apply( this, arguments );
- *         this.reallyActive = false;
- *     }
- *     OO.inheritClass( SettingsTool, OO.ui.Tool );
- *     SettingsTool.static.name = 'settings';
- *     SettingsTool.static.icon = 'settings';
- *     SettingsTool.static.title = 'Change settings';
- *     SettingsTool.prototype.onSelect = function () {
- *         $area.text( 'Settings tool clicked!' );
- *         // Toggle the active state on each click
- *         this.reallyActive = !this.reallyActive;
- *         this.setActive( this.reallyActive );
- *         // To update the menu label
- *         this.toolbar.emit( 'updateState' );
- *     };
- *     SettingsTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( SettingsTool );
- *
- *     function StuffTool() {
- *         StuffTool.parent.apply( this, arguments );
- *         this.reallyActive = false;
- *     }
- *     OO.inheritClass( StuffTool, OO.ui.Tool );
- *     StuffTool.static.name = 'stuff';
- *     StuffTool.static.icon = 'ellipsis';
- *     StuffTool.static.title = 'More stuff';
- *     StuffTool.prototype.onSelect = function () {
- *         $area.text( 'More stuff tool clicked!' );
- *         // Toggle the active state on each click
- *         this.reallyActive = !this.reallyActive;
- *         this.setActive( this.reallyActive );
- *         // To update the menu label
- *         this.toolbar.emit( 'updateState' );
- *     };
- *     StuffTool.prototype.onUpdateState = function () {};
- *     toolFactory.register( StuffTool );
- *
- *     // Finally define which tools and in what order appear in the toolbar. Each tool may only be
- *     // used once (but not all defined tools must be used).
- *     toolbar.setup( [
- *         {
- *             type: 'menu',
- *             header: 'This is the (optional) header',
- *             title: 'This is the (optional) title',
- *             indicator: 'down',
- *             include: [ 'settings', 'stuff' ]
- *         }
- *     ] );
- *
- *     // Create some UI around the toolbar and place it in the document
- *     var frame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         framed: true
- *     } );
- *     var contentFrame = new OO.ui.PanelLayout( {
- *         expanded: false,
- *         padded: true
- *     } );
- *     frame.$element.append(
- *         toolbar.$element,
- *         contentFrame.$element.append( $area )
- *     );
- *     $( 'body' ).append( frame.$element );
- *
- *     // Here is where the toolbar is actually built. This must be done after inserting it into the
- *     // document.
- *     toolbar.initialize();
- *     toolbar.emit( 'updateState' );
- *
- * For more information about how to add tools to a MenuToolGroup, please see {@link OO.ui.ToolGroup toolgroup}.
- * For more information about toolbars in general, please see the [OOjs UI documentation on MediaWiki] [1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @class
- * @extends OO.ui.PopupToolGroup
- *
- * @constructor
- * @param {OO.ui.Toolbar} toolbar
- * @param {Object} [config] Configuration options
- */
-OO.ui.MenuToolGroup = function OoUiMenuToolGroup( toolbar, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolbar ) && config === undefined ) {
-               config = toolbar;
-               toolbar = config.toolbar;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.MenuToolGroup.parent.call( this, toolbar, config );
-
-       // Events
-       this.toolbar.connect( this, { updateState: 'onUpdateState' } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-menuToolGroup' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuToolGroup, OO.ui.PopupToolGroup );
-
-/* Static Properties */
-
-OO.ui.MenuToolGroup.static.name = 'menu';
-
-/* Methods */
-
-/**
- * Handle the toolbar state being updated.
- *
- * When the state changes, the title of each active item in the menu will be joined together and
- * used as a label for the group. The label will be empty if none of the items are active.
- *
- * @private
- */
-OO.ui.MenuToolGroup.prototype.onUpdateState = function () {
-       var name,
-               labelTexts = [];
-
-       for ( name in this.tools ) {
-               if ( this.tools[ name ].isActive() ) {
-                       labelTexts.push( this.tools[ name ].getTitle() );
-               }
-       }
-
-       this.setLabel( labelTexts.join( ', ' ) || ' ' );
-};
-
-/**
- * Popup tools open a popup window when they are selected from the {@link OO.ui.Toolbar toolbar}. Each popup tool is configured
- * with a static name, title, and icon, as well with as any popup configurations. Unlike other tools, popup tools do not require that developers specify
- * an #onSelect or #onUpdateState method, as these methods have been implemented already.
- *
- *     // Example of a popup tool. When selected, a popup tool displays
- *     // a popup window.
- *     function HelpTool( toolGroup, config ) {
- *        OO.ui.PopupTool.call( this, toolGroup, $.extend( { popup: {
- *            padded: true,
- *            label: 'Help',
- *            head: true
- *        } }, config ) );
- *        this.popup.$body.append( '<p>I am helpful!</p>' );
- *     };
- *     OO.inheritClass( HelpTool, OO.ui.PopupTool );
- *     HelpTool.static.name = 'help';
- *     HelpTool.static.icon = 'help';
- *     HelpTool.static.title = 'Help';
- *     toolFactory.register( HelpTool );
- *
- * For an example of a toolbar that contains a popup tool, see {@link OO.ui.Toolbar toolbars}. For more information about
- * toolbars in genreral, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars
- *
- * @abstract
- * @class
- * @extends OO.ui.Tool
- * @mixins OO.ui.mixin.PopupElement
- *
- * @constructor
- * @param {OO.ui.ToolGroup} toolGroup
- * @param {Object} [config] Configuration options
- */
-OO.ui.PopupTool = function OoUiPopupTool( toolGroup, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
-               config = toolGroup;
-               toolGroup = config.toolGroup;
-       }
-
-       // Parent constructor
-       OO.ui.PopupTool.parent.call( this, toolGroup, config );
-
-       // Mixin constructors
-       OO.ui.mixin.PopupElement.call( this, config );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-popupTool' )
-               .append( this.popup.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PopupTool, OO.ui.Tool );
-OO.mixinClass( OO.ui.PopupTool, OO.ui.mixin.PopupElement );
-
-/* Methods */
-
-/**
- * Handle the tool being selected.
- *
- * @inheritdoc
- */
-OO.ui.PopupTool.prototype.onSelect = function () {
-       if ( !this.isDisabled() ) {
-               this.popup.toggle();
-       }
-       this.setActive( false );
-       return false;
-};
-
-/**
- * Handle the toolbar state being updated.
- *
- * @inheritdoc
- */
-OO.ui.PopupTool.prototype.onUpdateState = function () {
-       this.setActive( false );
-};
-
-/**
- * A ToolGroupTool is a special sort of tool that can contain other {@link OO.ui.Tool tools}
- * and {@link OO.ui.ToolGroup toolgroups}. The ToolGroupTool was specifically designed to be used
- * inside a {@link OO.ui.BarToolGroup bar} toolgroup to provide access to additional tools from
- * the bar item. Included tools will be displayed in a dropdown {@link OO.ui.ListToolGroup list}
- * when the ToolGroupTool is selected.
- *
- *     // Example: ToolGroupTool with two nested tools, 'setting1' and 'setting2', defined elsewhere.
- *
- *     function SettingsTool() {
- *         SettingsTool.parent.apply( this, arguments );
- *     };
- *     OO.inheritClass( SettingsTool, OO.ui.ToolGroupTool );
- *     SettingsTool.static.name = 'settings';
- *     SettingsTool.static.title = 'Change settings';
- *     SettingsTool.static.groupConfig = {
- *         icon: 'settings',
- *         label: 'ToolGroupTool',
- *         include: [  'setting1', 'setting2'  ]
- *     };
- *     toolFactory.register( SettingsTool );
- *
- * For more information, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * Please note that this implementation is subject to change per [T74159] [2].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Toolbars#ToolGroupTool
- * [2]: https://phabricator.wikimedia.org/T74159
- *
- * @abstract
- * @class
- * @extends OO.ui.Tool
- *
- * @constructor
- * @param {OO.ui.ToolGroup} toolGroup
- * @param {Object} [config] Configuration options
- */
-OO.ui.ToolGroupTool = function OoUiToolGroupTool( toolGroup, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( toolGroup ) && config === undefined ) {
-               config = toolGroup;
-               toolGroup = config.toolGroup;
-       }
-
-       // Parent constructor
-       OO.ui.ToolGroupTool.parent.call( this, toolGroup, config );
-
-       // Properties
-       this.innerToolGroup = this.createGroup( this.constructor.static.groupConfig );
-
-       // Events
-       this.innerToolGroup.connect( this, { disable: 'onToolGroupDisable' } );
-
-       // Initialization
-       this.$link.remove();
-       this.$element
-               .addClass( 'oo-ui-toolGroupTool' )
-               .append( this.innerToolGroup.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToolGroupTool, OO.ui.Tool );
-
-/* Static Properties */
-
-/**
- * Toolgroup configuration.
- *
- * The toolgroup configuration consists of the tools to include, as well as an icon and label
- * to use for the bar item. Tools can be included by symbolic name, group, or with the
- * wildcard selector. Please see {@link OO.ui.ToolGroup toolgroup} for more information.
- *
- * @property {Object.<string,Array>}
- */
-OO.ui.ToolGroupTool.static.groupConfig = {};
-
-/* Methods */
-
-/**
- * Handle the tool being selected.
- *
- * @inheritdoc
- */
-OO.ui.ToolGroupTool.prototype.onSelect = function () {
-       this.innerToolGroup.setActive( !this.innerToolGroup.active );
-       return false;
-};
-
-/**
- * Synchronize disabledness state of the tool with the inner toolgroup.
- *
- * @private
- * @param {boolean} disabled Element is disabled
- */
-OO.ui.ToolGroupTool.prototype.onToolGroupDisable = function ( disabled ) {
-       this.setDisabled( disabled );
-};
-
-/**
- * Handle the toolbar state being updated.
- *
- * @inheritdoc
- */
-OO.ui.ToolGroupTool.prototype.onUpdateState = function () {
-       this.setActive( false );
-};
-
-/**
- * Build a {@link OO.ui.ToolGroup toolgroup} from the specified configuration.
- *
- * @param {Object.<string,Array>} group Toolgroup configuration. Please see {@link OO.ui.ToolGroup toolgroup} for
- *  more information.
- * @return {OO.ui.ListToolGroup}
- */
-OO.ui.ToolGroupTool.prototype.createGroup = function ( group ) {
-       if ( group.include === '*' ) {
-               // Apply defaults to catch-all groups
-               if ( group.label === undefined ) {
-                       group.label = OO.ui.msg( 'ooui-toolbar-more' );
-               }
-       }
-
-       return this.toolbar.getToolGroupFactory().create( 'list', this.toolbar, group );
-};
-
-/**
- * Mixin for OO.ui.Widget subclasses to provide OO.ui.mixin.GroupElement.
- *
- * Use together with OO.ui.mixin.ItemWidget to make disabled state inheritable.
- *
- * @private
- * @abstract
- * @class
- * @extends OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.mixin.GroupWidget = function OoUiMixinGroupWidget( config ) {
-       // Parent constructor
-       OO.ui.mixin.GroupWidget.parent.call( this, config );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.mixin.GroupWidget, OO.ui.mixin.GroupElement );
-
-/* Methods */
-
-/**
- * Set the disabled state of the widget.
- *
- * This will also update the disabled state of child widgets.
- *
- * @param {boolean} disabled Disable widget
- * @chainable
- */
-OO.ui.mixin.GroupWidget.prototype.setDisabled = function ( disabled ) {
-       var i, len;
-
-       // Parent method
-       // Note: Calling #setDisabled this way assumes this is mixed into an OO.ui.Widget
-       OO.ui.Widget.prototype.setDisabled.call( this, disabled );
-
-       // During construction, #setDisabled is called before the OO.ui.mixin.GroupElement constructor
-       if ( this.items ) {
-               for ( i = 0, len = this.items.length; i < len; i++ ) {
-                       this.items[ i ].updateDisabled();
-               }
-       }
-
-       return this;
-};
-
-/**
- * Mixin for widgets used as items in widgets that mix in OO.ui.mixin.GroupWidget.
- *
- * Item widgets have a reference to a OO.ui.mixin.GroupWidget while they are attached to the group. This
- * allows bidirectional communication.
- *
- * Use together with OO.ui.mixin.GroupWidget to make disabled state inheritable.
- *
- * @private
- * @abstract
- * @class
- *
- * @constructor
- */
-OO.ui.mixin.ItemWidget = function OoUiMixinItemWidget() {
-       //
-};
-
-/* Methods */
-
-/**
- * Check if widget is disabled.
- *
- * Checks parent if present, making disabled state inheritable.
- *
- * @return {boolean} Widget is disabled
- */
-OO.ui.mixin.ItemWidget.prototype.isDisabled = function () {
-       return this.disabled ||
-               ( this.elementGroup instanceof OO.ui.Widget && this.elementGroup.isDisabled() );
-};
-
-/**
- * Set group element is in.
- *
- * @param {OO.ui.mixin.GroupElement|null} group Group element, null if none
- * @chainable
- */
-OO.ui.mixin.ItemWidget.prototype.setElementGroup = function ( group ) {
-       // Parent method
-       // Note: Calling #setElementGroup this way assumes this is mixed into an OO.ui.Element
-       OO.ui.Element.prototype.setElementGroup.call( this, group );
-
-       // Initialize item disabled states
-       this.updateDisabled();
-
-       return this;
-};
-
-/**
- * OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}.
- * Controls include moving items up and down, removing items, and adding different kinds of items.
- *
- * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.GroupElement
- * @mixins OO.ui.mixin.IconElement
- *
- * @constructor
- * @param {OO.ui.OutlineSelectWidget} outline Outline to control
- * @param {Object} [config] Configuration options
- * @cfg {Object} [abilities] List of abilties
- * @cfg {boolean} [abilities.move=true] Allow moving movable items
- * @cfg {boolean} [abilities.remove=true] Allow removing removable items
- */
-OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, config ) {
-       // Allow passing positional parameters inside the config object
-       if ( OO.isPlainObject( outline ) && config === undefined ) {
-               config = outline;
-               outline = config.outline;
-       }
-
-       // Configuration initialization
-       config = $.extend( { icon: 'add' }, config );
-
-       // Parent constructor
-       OO.ui.OutlineControlsWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, config );
-       OO.ui.mixin.IconElement.call( this, config );
-
-       // Properties
-       this.outline = outline;
-       this.$movers = $( '<div>' );
-       this.upButton = new OO.ui.ButtonWidget( {
-               framed: false,
-               icon: 'collapse',
-               title: OO.ui.msg( 'ooui-outline-control-move-up' )
-       } );
-       this.downButton = new OO.ui.ButtonWidget( {
-               framed: false,
-               icon: 'expand',
-               title: OO.ui.msg( 'ooui-outline-control-move-down' )
-       } );
-       this.removeButton = new OO.ui.ButtonWidget( {
-               framed: false,
-               icon: 'remove',
-               title: OO.ui.msg( 'ooui-outline-control-remove' )
-       } );
-       this.abilities = { move: true, remove: true };
-
-       // Events
-       outline.connect( this, {
-               select: 'onOutlineChange',
-               add: 'onOutlineChange',
-               remove: 'onOutlineChange'
-       } );
-       this.upButton.connect( this, { click: [ 'emit', 'move', -1 ] } );
-       this.downButton.connect( this, { click: [ 'emit', 'move', 1 ] } );
-       this.removeButton.connect( this, { click: [ 'emit', 'remove' ] } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-outlineControlsWidget' );
-       this.$group.addClass( 'oo-ui-outlineControlsWidget-items' );
-       this.$movers
-               .addClass( 'oo-ui-outlineControlsWidget-movers' )
-               .append( this.removeButton.$element, this.upButton.$element, this.downButton.$element );
-       this.$element.append( this.$icon, this.$group, this.$movers );
-       this.setAbilities( config.abilities || {} );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.GroupElement );
-OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.IconElement );
-
-/* Events */
-
-/**
- * @event move
- * @param {number} places Number of places to move
- */
-
-/**
- * @event remove
- */
-
-/* Methods */
-
-/**
- * Set abilities.
- *
- * @param {Object} abilities List of abilties
- * @param {boolean} [abilities.move] Allow moving movable items
- * @param {boolean} [abilities.remove] Allow removing removable items
- */
-OO.ui.OutlineControlsWidget.prototype.setAbilities = function ( abilities ) {
-       var ability;
-
-       for ( ability in this.abilities ) {
-               if ( abilities[ ability ] !== undefined ) {
-                       this.abilities[ ability ] = !!abilities[ ability ];
-               }
-       }
-
-       this.onOutlineChange();
-};
-
-/**
- * @private
- * Handle outline change events.
- */
-OO.ui.OutlineControlsWidget.prototype.onOutlineChange = function () {
-       var i, len, firstMovable, lastMovable,
-               items = this.outline.getItems(),
-               selectedItem = this.outline.getSelectedItem(),
-               movable = this.abilities.move && selectedItem && selectedItem.isMovable(),
-               removable = this.abilities.remove && selectedItem && selectedItem.isRemovable();
-
-       if ( movable ) {
-               i = -1;
-               len = items.length;
-               while ( ++i < len ) {
-                       if ( items[ i ].isMovable() ) {
-                               firstMovable = items[ i ];
-                               break;
-                       }
-               }
-               i = len;
-               while ( i-- ) {
-                       if ( items[ i ].isMovable() ) {
-                               lastMovable = items[ i ];
-                               break;
-                       }
-               }
-       }
-       this.upButton.setDisabled( !movable || selectedItem === firstMovable );
-       this.downButton.setDisabled( !movable || selectedItem === lastMovable );
-       this.removeButton.setDisabled( !removable );
-};
-
-/**
- * ToggleWidget implements basic behavior of widgets with an on/off state.
- * Please see OO.ui.ToggleButtonWidget and OO.ui.ToggleSwitchWidget for examples.
- *
- * @abstract
- * @class
- * @extends OO.ui.Widget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [value=false] The toggle’s initial on/off state.
- *  By default, the toggle is in the 'off' state.
- */
-OO.ui.ToggleWidget = function OoUiToggleWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ToggleWidget.parent.call( this, config );
-
-       // Properties
-       this.value = null;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-toggleWidget' );
-       this.setValue( !!config.value );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToggleWidget, OO.ui.Widget );
-
-/* Events */
-
-/**
- * @event change
- *
- * A change event is emitted when the on/off state of the toggle changes.
- *
- * @param {boolean} value Value representing the new state of the toggle
- */
-
-/* Methods */
-
-/**
- * Get the value representing the toggle’s state.
- *
- * @return {boolean} The on/off state of the toggle
- */
-OO.ui.ToggleWidget.prototype.getValue = function () {
-       return this.value;
-};
-
-/**
- * Set the state of the toggle: `true` for 'on', `false' for 'off'.
- *
- * @param {boolean} value The state of the toggle
- * @fires change
- * @chainable
- */
-OO.ui.ToggleWidget.prototype.setValue = function ( value ) {
-       value = !!value;
-       if ( this.value !== value ) {
-               this.value = value;
-               this.emit( 'change', value );
-               this.$element.toggleClass( 'oo-ui-toggleWidget-on', value );
-               this.$element.toggleClass( 'oo-ui-toggleWidget-off', !value );
-               this.$element.attr( 'aria-checked', value.toString() );
-       }
-       return this;
-};
-
-/**
- * A ButtonGroupWidget groups related buttons and is used together with OO.ui.ButtonWidget and
- * its subclasses. Each button in a group is addressed by a unique reference. Buttons can be added,
- * removed, and cleared from the group.
- *
- *     @example
- *     // Example: A ButtonGroupWidget with two buttons
- *     var button1 = new OO.ui.PopupButtonWidget( {
- *         label: 'Select a category',
- *         icon: 'menu',
- *         popup: {
- *             $content: $( '<p>List of categories...</p>' ),
- *             padded: true,
- *             align: 'left'
- *         }
- *     } );
- *     var button2 = new OO.ui.ButtonWidget( {
- *         label: 'Add item'
- *     });
- *     var buttonGroup = new OO.ui.ButtonGroupWidget( {
- *         items: [button1, button2]
- *     } );
- *     $( 'body' ).append( buttonGroup.$element );
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.ButtonWidget[]} [items] Buttons to add
- */
-OO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ButtonGroupWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-buttonGroupWidget' );
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ButtonGroupWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.mixin.GroupElement );
-
-/**
- * ButtonWidget is a generic widget for buttons. A wide variety of looks,
- * feels, and functionality can be customized via the class’s configuration options
- * and methods. Please see the [OOjs UI documentation on MediaWiki] [1] for more information
- * and examples.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches
- *
- *     @example
- *     // A button widget
- *     var button = new OO.ui.ButtonWidget( {
- *         label: 'Button with Icon',
- *         icon: 'remove',
- *         iconTitle: 'Remove'
- *     } );
- *     $( 'body' ).append( button.$element );
- *
- * NOTE: HTML form buttons should use the OO.ui.ButtonInputWidget class.
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.ButtonElement
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.FlaggedElement
- * @mixins OO.ui.mixin.TabIndexedElement
- * @mixins OO.ui.mixin.AccessKeyedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [href] Hyperlink to visit when the button is clicked.
- * @cfg {string} [target] The frame or window in which to open the hyperlink.
- * @cfg {boolean} [noFollow] Search engine traversal hint (default: true)
- */
-OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ButtonWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, config );
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
-       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$button } ) );
-
-       // Properties
-       this.href = null;
-       this.target = null;
-       this.noFollow = false;
-
-       // Events
-       this.connect( this, { disable: 'onDisable' } );
-
-       // Initialization
-       this.$button.append( this.$icon, this.$label, this.$indicator );
-       this.$element
-               .addClass( 'oo-ui-buttonWidget' )
-               .append( this.$button );
-       this.setHref( config.href );
-       this.setTarget( config.target );
-       this.setNoFollow( config.noFollow );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ButtonWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.ButtonElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.FlaggedElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TabIndexedElement );
-OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.AccessKeyedElement );
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.ButtonWidget.prototype.onMouseDown = function ( e ) {
-       if ( !this.isDisabled() ) {
-               // Remove the tab-index while the button is down to prevent the button from stealing focus
-               this.$button.removeAttr( 'tabindex' );
-       }
-
-       return OO.ui.mixin.ButtonElement.prototype.onMouseDown.call( this, e );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ButtonWidget.prototype.onMouseUp = function ( e ) {
-       if ( !this.isDisabled() ) {
-               // Restore the tab-index after the button is up to restore the button's accessibility
-               this.$button.attr( 'tabindex', this.tabIndex );
-       }
-
-       return OO.ui.mixin.ButtonElement.prototype.onMouseUp.call( this, e );
-};
-
-/**
- * Get hyperlink location.
- *
- * @return {string} Hyperlink location
- */
-OO.ui.ButtonWidget.prototype.getHref = function () {
-       return this.href;
-};
-
-/**
- * Get hyperlink target.
- *
- * @return {string} Hyperlink target
- */
-OO.ui.ButtonWidget.prototype.getTarget = function () {
-       return this.target;
-};
-
-/**
- * Get search engine traversal hint.
- *
- * @return {boolean} Whether search engines should avoid traversing this hyperlink
- */
-OO.ui.ButtonWidget.prototype.getNoFollow = function () {
-       return this.noFollow;
-};
-
-/**
- * Set hyperlink location.
- *
- * @param {string|null} href Hyperlink location, null to remove
- */
-OO.ui.ButtonWidget.prototype.setHref = function ( href ) {
-       href = typeof href === 'string' ? href : null;
-       if ( href !== null && !OO.ui.isSafeUrl( href ) ) {
-               href = './' + href;
-       }
-
-       if ( href !== this.href ) {
-               this.href = href;
-               this.updateHref();
-       }
-
-       return this;
-};
-
-/**
- * Update the `href` attribute, in case of changes to href or
- * disabled state.
- *
- * @private
- * @chainable
- */
-OO.ui.ButtonWidget.prototype.updateHref = function () {
-       if ( this.href !== null && !this.isDisabled() ) {
-               this.$button.attr( 'href', this.href );
-       } else {
-               this.$button.removeAttr( 'href' );
-       }
-
-       return this;
-};
-
-/**
- * Handle disable events.
- *
- * @private
- * @param {boolean} disabled Element is disabled
- */
-OO.ui.ButtonWidget.prototype.onDisable = function () {
-       this.updateHref();
-};
-
-/**
- * Set hyperlink target.
- *
- * @param {string|null} target Hyperlink target, null to remove
- */
-OO.ui.ButtonWidget.prototype.setTarget = function ( target ) {
-       target = typeof target === 'string' ? target : null;
-
-       if ( target !== this.target ) {
-               this.target = target;
-               if ( target !== null ) {
-                       this.$button.attr( 'target', target );
-               } else {
-                       this.$button.removeAttr( 'target' );
-               }
-       }
-
-       return this;
-};
-
-/**
- * Set search engine traversal hint.
- *
- * @param {boolean} noFollow True if search engines should avoid traversing this hyperlink
- */
-OO.ui.ButtonWidget.prototype.setNoFollow = function ( noFollow ) {
-       noFollow = typeof noFollow === 'boolean' ? noFollow : true;
-
-       if ( noFollow !== this.noFollow ) {
-               this.noFollow = noFollow;
-               if ( noFollow ) {
-                       this.$button.attr( 'rel', 'nofollow' );
-               } else {
-                       this.$button.removeAttr( 'rel' );
-               }
-       }
-
-       return this;
-};
-
-/**
- * An ActionWidget is a {@link OO.ui.ButtonWidget button widget} that executes an action.
- * Action widgets are used with OO.ui.ActionSet, which manages the behavior and availability
- * of the actions.
- *
- * Both actions and action sets are primarily used with {@link OO.ui.Dialog Dialogs}.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for more information
- * and examples.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Process_Dialogs#Action_sets
- *
- * @class
- * @extends OO.ui.ButtonWidget
- * @mixins OO.ui.mixin.PendingElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [action] Symbolic name of the action (e.g., ‘continue’ or ‘cancel’).
- * @cfg {string[]} [modes] Symbolic names of the modes (e.g., ‘edit’ or ‘read’) in which the action
- *  should be made available. See the action set's {@link OO.ui.ActionSet#setMode setMode} method
- *  for more information about setting modes.
- * @cfg {boolean} [framed=false] Render the action button with a frame
- */
-OO.ui.ActionWidget = function OoUiActionWidget( config ) {
-       // Configuration initialization
-       config = $.extend( { framed: false }, config );
-
-       // Parent constructor
-       OO.ui.ActionWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.PendingElement.call( this, config );
-
-       // Properties
-       this.action = config.action || '';
-       this.modes = config.modes || [];
-       this.width = 0;
-       this.height = 0;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-actionWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );
-OO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement );
-
-/* Events */
-
-/**
- * A resize event is emitted when the size of the widget changes.
- *
- * @event resize
- */
-
-/* Methods */
-
-/**
- * Check if the action is configured to be available in the specified `mode`.
- *
- * @param {string} mode Name of mode
- * @return {boolean} The action is configured with the mode
- */
-OO.ui.ActionWidget.prototype.hasMode = function ( mode ) {
-       return this.modes.indexOf( mode ) !== -1;
-};
-
-/**
- * Get the symbolic name of the action (e.g., ‘continue’ or ‘cancel’).
- *
- * @return {string}
- */
-OO.ui.ActionWidget.prototype.getAction = function () {
-       return this.action;
-};
-
-/**
- * Get the symbolic name of the mode or modes for which the action is configured to be available.
- *
- * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method.
- * Only actions that are configured to be avaiable in the current mode will be visible. All other actions
- * are hidden.
- *
- * @return {string[]}
- */
-OO.ui.ActionWidget.prototype.getModes = function () {
-       return this.modes.slice();
-};
-
-/**
- * Emit a resize event if the size has changed.
- *
- * @private
- * @chainable
- */
-OO.ui.ActionWidget.prototype.propagateResize = function () {
-       var width, height;
-
-       if ( this.isElementAttached() ) {
-               width = this.$element.width();
-               height = this.$element.height();
-
-               if ( width !== this.width || height !== this.height ) {
-                       this.width = width;
-                       this.height = height;
-                       this.emit( 'resize' );
-               }
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setIcon = function () {
-       // Mixin method
-       OO.ui.mixin.IconElement.prototype.setIcon.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setLabel = function () {
-       // Mixin method
-       OO.ui.mixin.LabelElement.prototype.setLabel.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.setFlags = function () {
-       // Mixin method
-       OO.ui.mixin.FlaggedElement.prototype.setFlags.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ActionWidget.prototype.clearFlags = function () {
-       // Mixin method
-       OO.ui.mixin.FlaggedElement.prototype.clearFlags.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * Toggle the visibility of the action button.
- *
- * @param {boolean} [show] Show button, omit to toggle visibility
- * @chainable
- */
-OO.ui.ActionWidget.prototype.toggle = function () {
-       // Parent method
-       OO.ui.ActionWidget.parent.prototype.toggle.apply( this, arguments );
-       this.propagateResize();
-
-       return this;
-};
-
-/**
- * PopupButtonWidgets toggle the visibility of a contained {@link OO.ui.PopupWidget PopupWidget},
- * which is used to display additional information or options.
- *
- *     @example
- *     // Example of a popup button.
- *     var popupButton = new OO.ui.PopupButtonWidget( {
- *         label: 'Popup button with options',
- *         icon: 'menu',
- *         popup: {
- *             $content: $( '<p>Additional options here.</p>' ),
- *             padded: true,
- *             align: 'force-left'
- *         }
- *     } );
- *     // Append the button to the DOM.
- *     $( 'body' ).append( popupButton.$element );
- *
- * @class
- * @extends OO.ui.ButtonWidget
- * @mixins OO.ui.mixin.PopupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
-       // Parent constructor
-       OO.ui.PopupButtonWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.PopupElement.call( this, config );
-
-       // Events
-       this.connect( this, { click: 'onAction' } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-popupButtonWidget' )
-               .attr( 'aria-haspopup', 'true' )
-               .append( this.popup.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PopupButtonWidget, OO.ui.ButtonWidget );
-OO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.mixin.PopupElement );
-
-/* Methods */
-
-/**
- * Handle the button action being triggered.
- *
- * @private
- */
-OO.ui.PopupButtonWidget.prototype.onAction = function () {
-       this.popup.toggle();
-};
-
-/**
- * ToggleButtons are buttons that have a state (‘on’ or ‘off’) that is represented by a
- * Boolean value. Like other {@link OO.ui.ButtonWidget buttons}, toggle buttons can be
- * configured with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators},
- * {@link OO.ui.mixin.TitledElement titles}, {@link OO.ui.mixin.FlaggedElement styling flags},
- * and {@link OO.ui.mixin.LabelElement labels}. Please see
- * the [OOjs UI documentation][1] on MediaWiki for more information.
- *
- *     @example
- *     // Toggle buttons in the 'off' and 'on' state.
- *     var toggleButton1 = new OO.ui.ToggleButtonWidget( {
- *         label: 'Toggle Button off'
- *     } );
- *     var toggleButton2 = new OO.ui.ToggleButtonWidget( {
- *         label: 'Toggle Button on',
- *         value: true
- *     } );
- *     // Append the buttons to the DOM.
- *     $( 'body' ).append( toggleButton1.$element, toggleButton2.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Buttons_and_Switches#Toggle_buttons
- *
- * @class
- * @extends OO.ui.ToggleWidget
- * @mixins OO.ui.mixin.ButtonElement
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.FlaggedElement
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [value=false] The toggle button’s initial on/off
- *  state. By default, the button is in the 'off' state.
- */
-OO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ToggleButtonWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, config );
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$button } ) );
-
-       // Events
-       this.connect( this, { click: 'onAction' } );
-
-       // Initialization
-       this.$button.append( this.$icon, this.$label, this.$indicator );
-       this.$element
-               .addClass( 'oo-ui-toggleButtonWidget' )
-               .append( this.$button );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToggleButtonWidget, OO.ui.ToggleWidget );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.ButtonElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.FlaggedElement );
-OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * Handle the button action being triggered.
- *
- * @private
- */
-OO.ui.ToggleButtonWidget.prototype.onAction = function () {
-       this.setValue( !this.value );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {
-       value = !!value;
-       if ( value !== this.value ) {
-               // Might be called from parent constructor before ButtonElement constructor
-               if ( this.$button ) {
-                       this.$button.attr( 'aria-pressed', value.toString() );
-               }
-               this.setActive( value );
-       }
-
-       // Parent method
-       OO.ui.ToggleButtonWidget.parent.prototype.setValue.call( this, value );
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ToggleButtonWidget.prototype.setButtonElement = function ( $button ) {
-       if ( this.$button ) {
-               this.$button.removeAttr( 'aria-pressed' );
-       }
-       OO.ui.mixin.ButtonElement.prototype.setButtonElement.call( this, $button );
-       this.$button.attr( 'aria-pressed', this.value.toString() );
-};
-
-/**
- * CapsuleMultiSelectWidgets are something like a {@link OO.ui.ComboBoxInputWidget combo box widget}
- * that allows for selecting multiple values.
- *
- * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example: A CapsuleMultiSelectWidget.
- *     var capsule = new OO.ui.CapsuleMultiSelectWidget( {
- *         label: 'CapsuleMultiSelectWidget',
- *         selected: [ 'Option 1', 'Option 3' ],
- *         menu: {
- *             items: [
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 1',
- *                     label: 'Option One'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 2',
- *                     label: 'Option Two'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 3',
- *                     label: 'Option Three'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 4',
- *                     label: 'Option Four'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 5',
- *                     label: 'Option Five'
- *                 } )
- *             ]
- *         }
- *     } );
- *     $( 'body' ).append( capsule.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.TabIndexedElement
- * @mixins OO.ui.mixin.GroupElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if not present in the menu.
- * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.MenuSelectWidget menu select widget}.
- * @cfg {Object} [popup] Configuration options to pass to the {@link OO.ui.PopupWidget popup widget}.
- *  If specified, this popup will be shown instead of the menu (but the menu
- *  will still be used for item labels and allowArbitrary=false). The widgets
- *  in the popup should use this.addItemsFromData() or this.addItems() as necessary.
- * @cfg {jQuery} [$overlay] Render the menu or popup into a separate layer.
- *  This configuration is useful in cases where the expanded menu is larger than
- *  its containing `<div>`. The specified overlay layer is usually on top of
- *  the containing `<div>` and has a larger area. By default, the menu uses
- *  relative positioning.
- */
-OO.ui.CapsuleMultiSelectWidget = function OoUiCapsuleMultiSelectWidget( config ) {
-       var $tabFocus;
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.CapsuleMultiSelectWidget.parent.call( this, config );
-
-       // Properties (must be set before mixin constructor calls)
-       this.$input = config.popup ? null : $( '<input>' );
-       this.$handle = $( '<div>' );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupElement.call( this, config );
-       if ( config.popup ) {
-               config.popup = $.extend( {}, config.popup, {
-                       align: 'forwards',
-                       anchor: false
-               } );
-               OO.ui.mixin.PopupElement.call( this, config );
-               $tabFocus = $( '<span>' );
-               OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: $tabFocus } ) );
-       } else {
-               this.popup = null;
-               $tabFocus = null;
-               OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );
-       }
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.IconElement.call( this, config );
-
-       // Properties
-       this.$content = $( '<div>' );
-       this.allowArbitrary = !!config.allowArbitrary;
-       this.$overlay = config.$overlay || this.$element;
-       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
-               {
-                       widget: this,
-                       $input: this.$input,
-                       $container: this.$element,
-                       filterFromInput: true,
-                       disabled: this.isDisabled()
-               },
-               config.menu
-       ) );
-
-       // Events
-       if ( this.popup ) {
-               $tabFocus.on( {
-                       focus: this.onFocusForPopup.bind( this )
-               } );
-               this.popup.$element.on( 'focusout', this.onPopupFocusOut.bind( this ) );
-               if ( this.popup.$autoCloseIgnore ) {
-                       this.popup.$autoCloseIgnore.on( 'focusout', this.onPopupFocusOut.bind( this ) );
-               }
-               this.popup.connect( this, {
-                       toggle: function ( visible ) {
-                               $tabFocus.toggle( !visible );
-                       }
-               } );
-       } else {
-               this.$input.on( {
-                       focus: this.onInputFocus.bind( this ),
-                       blur: this.onInputBlur.bind( this ),
-                       'propertychange change click mouseup keydown keyup input cut paste select focus':
-                               OO.ui.debounce( this.updateInputSize.bind( this ) ),
-                       keydown: this.onKeyDown.bind( this ),
-                       keypress: this.onKeyPress.bind( this )
-               } );
-       }
-       this.menu.connect( this, {
-               choose: 'onMenuChoose',
-               add: 'onMenuItemsChange',
-               remove: 'onMenuItemsChange'
-       } );
-       this.$handle.on( {
-               mousedown: this.onMouseDown.bind( this )
-       } );
-
-       // Initialization
-       if ( this.$input ) {
-               this.$input.prop( 'disabled', this.isDisabled() );
-               this.$input.attr( {
-                       role: 'combobox',
-                       'aria-autocomplete': 'list'
-               } );
-               this.updateInputSize();
-       }
-       if ( config.data ) {
-               this.setItemsFromData( config.data );
-       }
-       this.$content.addClass( 'oo-ui-capsuleMultiSelectWidget-content' )
-               .append( this.$group );
-       this.$group.addClass( 'oo-ui-capsuleMultiSelectWidget-group' );
-       this.$handle.addClass( 'oo-ui-capsuleMultiSelectWidget-handle' )
-               .append( this.$indicator, this.$icon, this.$content );
-       this.$element.addClass( 'oo-ui-capsuleMultiSelectWidget' )
-               .append( this.$handle );
-       if ( this.popup ) {
-               this.$content.append( $tabFocus );
-               this.$overlay.append( this.popup.$element );
-       } else {
-               this.$content.append( this.$input );
-               this.$overlay.append( this.menu.$element );
-       }
-       this.onMenuItemsChange();
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.GroupElement );
-OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.PopupElement );
-OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.TabIndexedElement );
-OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.CapsuleMultiSelectWidget, OO.ui.mixin.IconElement );
-
-/* Events */
-
-/**
- * @event change
- *
- * A change event is emitted when the set of selected items changes.
- *
- * @param {Mixed[]} datas Data of the now-selected items
- */
-
-/* Methods */
-
-/**
- * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data.
- *
- * @protected
- * @param {Mixed} data Custom data of any type.
- * @param {string} label The label text.
- * @return {OO.ui.CapsuleItemWidget}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.createItemWidget = function ( data, label ) {
-       return new OO.ui.CapsuleItemWidget( { data: data, label: label } );
-};
-
-/**
- * Get the data of the items in the capsule
- * @return {Mixed[]}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.getItemsData = function () {
-       return $.map( this.getItems(), function ( e ) { return e.data; } );
-};
-
-/**
- * Set the items in the capsule by providing data
- * @chainable
- * @param {Mixed[]} datas
- * @return {OO.ui.CapsuleMultiSelectWidget}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.setItemsFromData = function ( datas ) {
-       var widget = this,
-               menu = this.menu,
-               items = this.getItems();
-
-       $.each( datas, function ( i, data ) {
-               var j, label,
-                       item = menu.getItemFromData( data );
-
-               if ( item ) {
-                       label = item.label;
-               } else if ( widget.allowArbitrary ) {
-                       label = String( data );
-               } else {
-                       return;
-               }
-
-               item = null;
-               for ( j = 0; j < items.length; j++ ) {
-                       if ( items[ j ].data === data && items[ j ].label === label ) {
-                               item = items[ j ];
-                               items.splice( j, 1 );
-                               break;
-                       }
-               }
-               if ( !item ) {
-                       item = widget.createItemWidget( data, label );
-               }
-               widget.addItems( [ item ], i );
-       } );
-
-       if ( items.length ) {
-               widget.removeItems( items );
-       }
-
-       return this;
-};
-
-/**
- * Add items to the capsule by providing their data
- * @chainable
- * @param {Mixed[]} datas
- * @return {OO.ui.CapsuleMultiSelectWidget}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.addItemsFromData = function ( datas ) {
-       var widget = this,
-               menu = this.menu,
-               items = [];
-
-       $.each( datas, function ( i, data ) {
-               var item;
-
-               if ( !widget.getItemFromData( data ) ) {
-                       item = menu.getItemFromData( data );
-                       if ( item ) {
-                               items.push( widget.createItemWidget( data, item.label ) );
-                       } else if ( widget.allowArbitrary ) {
-                               items.push( widget.createItemWidget( data, String( data ) ) );
-                       }
-               }
-       } );
-
-       if ( items.length ) {
-               this.addItems( items );
-       }
-
-       return this;
-};
-
-/**
- * Remove items by data
- * @chainable
- * @param {Mixed[]} datas
- * @return {OO.ui.CapsuleMultiSelectWidget}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.removeItemsFromData = function ( datas ) {
-       var widget = this,
-               items = [];
-
-       $.each( datas, function ( i, data ) {
-               var item = widget.getItemFromData( data );
-               if ( item ) {
-                       items.push( item );
-               }
-       } );
-
-       if ( items.length ) {
-               this.removeItems( items );
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.addItems = function ( items ) {
-       var same, i, l,
-               oldItems = this.items.slice();
-
-       OO.ui.mixin.GroupElement.prototype.addItems.call( this, items );
-
-       if ( this.items.length !== oldItems.length ) {
-               same = false;
-       } else {
-               same = true;
-               for ( i = 0, l = oldItems.length; same && i < l; i++ ) {
-                       same = same && this.items[ i ] === oldItems[ i ];
-               }
-       }
-       if ( !same ) {
-               this.emit( 'change', this.getItemsData() );
-               this.menu.position();
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.removeItems = function ( items ) {
-       var same, i, l,
-               oldItems = this.items.slice();
-
-       OO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );
-
-       if ( this.items.length !== oldItems.length ) {
-               same = false;
-       } else {
-               same = true;
-               for ( i = 0, l = oldItems.length; same && i < l; i++ ) {
-                       same = same && this.items[ i ] === oldItems[ i ];
-               }
-       }
-       if ( !same ) {
-               this.emit( 'change', this.getItemsData() );
-               this.menu.position();
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.clearItems = function () {
-       if ( this.items.length ) {
-               OO.ui.mixin.GroupElement.prototype.clearItems.call( this );
-               this.emit( 'change', this.getItemsData() );
-               this.menu.position();
-       }
-       return this;
-};
-
-/**
- * Get the capsule widget's menu.
- * @return {OO.ui.MenuSelectWidget} Menu widget
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.getMenu = function () {
-       return this.menu;
-};
-
-/**
- * Handle focus events
- *
- * @private
- * @param {jQuery.Event} event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onInputFocus = function () {
-       if ( !this.isDisabled() ) {
-               this.menu.toggle( true );
-       }
-};
-
-/**
- * Handle blur events
- *
- * @private
- * @param {jQuery.Event} event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onInputBlur = function () {
-       if ( this.allowArbitrary && this.$input.val().trim() !== '' ) {
-               this.addItemsFromData( [ this.$input.val() ] );
-       }
-       this.clearInput();
-};
-
-/**
- * Handle focus events
- *
- * @private
- * @param {jQuery.Event} event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onFocusForPopup = function () {
-       if ( !this.isDisabled() ) {
-               this.popup.setSize( this.$handle.width() );
-               this.popup.toggle( true );
-               this.popup.$element.find( '*' )
-                       .filter( function () { return OO.ui.isFocusableElement( $( this ), true ); } )
-                       .first()
-                       .focus();
-       }
-};
-
-/**
- * Handles popup focus out events.
- *
- * @private
- * @param {Event} e Focus out event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onPopupFocusOut = function () {
-       var widget = this.popup;
-
-       setTimeout( function () {
-               if (
-                       widget.isVisible() &&
-                       !OO.ui.contains( widget.$element[ 0 ], document.activeElement, true ) &&
-                       ( !widget.$autoCloseIgnore || !widget.$autoCloseIgnore.has( document.activeElement ).length )
-               ) {
-                       widget.toggle( false );
-               }
-       } );
-};
-
-/**
- * Handle mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onMouseDown = function ( e ) {
-       if ( e.which === OO.ui.MouseButtons.LEFT ) {
-               this.focus();
-               return false;
-       } else {
-               this.updateInputSize();
-       }
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onKeyPress = function ( e ) {
-       var item;
-
-       if ( !this.isDisabled() ) {
-               if ( e.which === OO.ui.Keys.ESCAPE ) {
-                       this.clearInput();
-                       return false;
-               }
-
-               if ( !this.popup ) {
-                       this.menu.toggle( true );
-                       if ( e.which === OO.ui.Keys.ENTER ) {
-                               item = this.menu.getItemFromLabel( this.$input.val(), true );
-                               if ( item ) {
-                                       this.addItemsFromData( [ item.data ] );
-                                       this.clearInput();
-                               } else if ( this.allowArbitrary && this.$input.val().trim() !== '' ) {
-                                       this.addItemsFromData( [ this.$input.val() ] );
-                                       this.clearInput();
-                               }
-                               return false;
-                       }
-
-                       // Make sure the input gets resized.
-                       setTimeout( this.updateInputSize.bind( this ), 0 );
-               }
-       }
-};
-
-/**
- * Handle key down events.
- *
- * @private
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onKeyDown = function ( e ) {
-       if ( !this.isDisabled() ) {
-               // 'keypress' event is not triggered for Backspace
-               if ( e.keyCode === OO.ui.Keys.BACKSPACE && this.$input.val() === '' ) {
-                       if ( this.items.length ) {
-                               this.removeItems( this.items.slice( -1 ) );
-                       }
-                       return false;
-               }
-       }
-};
-
-/**
- * Update the dimensions of the text input field to encompass all available area.
- *
- * @private
- * @param {jQuery.Event} e Event of some sort
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.updateInputSize = function () {
-       var $lastItem, direction, contentWidth, currentWidth, bestWidth;
-       if ( !this.isDisabled() ) {
-               this.$input.css( 'width', '1em' );
-               $lastItem = this.$group.children().last();
-               direction = OO.ui.Element.static.getDir( this.$handle );
-               contentWidth = this.$input[ 0 ].scrollWidth;
-               currentWidth = this.$input.width();
-
-               if ( contentWidth < currentWidth ) {
-                       // All is fine, don't perform expensive calculations
-                       return;
-               }
-
-               if ( !$lastItem.length ) {
-                       bestWidth = this.$content.innerWidth();
-               } else {
-                       bestWidth = direction === 'ltr' ?
-                               this.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :
-                               $lastItem.position().left;
-               }
-               // Some safety margin for sanity, because I *really* don't feel like finding out where the few
-               // pixels this is off by are coming from.
-               bestWidth -= 10;
-               if ( contentWidth > bestWidth ) {
-                       // This will result in the input getting shifted to the next line
-                       bestWidth = this.$content.innerWidth() - 10;
-               }
-               this.$input.width( Math.floor( bestWidth ) );
-
-               this.menu.position();
-       }
-};
-
-/**
- * Handle menu choose events.
- *
- * @private
- * @param {OO.ui.OptionWidget} item Chosen item
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onMenuChoose = function ( item ) {
-       if ( item && item.isVisible() ) {
-               this.addItemsFromData( [ item.getData() ] );
-               this.clearInput();
-       }
-};
-
-/**
- * Handle menu item change events.
- *
- * @private
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.onMenuItemsChange = function () {
-       this.setItemsFromData( this.getItemsData() );
-       this.$element.toggleClass( 'oo-ui-capsuleMultiSelectWidget-empty', this.menu.isEmpty() );
-};
-
-/**
- * Clear the input field
- * @private
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.clearInput = function () {
-       if ( this.$input ) {
-               this.$input.val( '' );
-               this.updateInputSize();
-       }
-       if ( this.popup ) {
-               this.popup.toggle( false );
-       }
-       this.menu.toggle( false );
-       this.menu.selectItem();
-       this.menu.highlightItem();
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.setDisabled = function ( disabled ) {
-       var i, len;
-
-       // Parent method
-       OO.ui.CapsuleMultiSelectWidget.parent.prototype.setDisabled.call( this, disabled );
-
-       if ( this.$input ) {
-               this.$input.prop( 'disabled', this.isDisabled() );
-       }
-       if ( this.menu ) {
-               this.menu.setDisabled( this.isDisabled() );
-       }
-       if ( this.popup ) {
-               this.popup.setDisabled( this.isDisabled() );
-       }
-
-       if ( this.items ) {
-               for ( i = 0, len = this.items.length; i < len; i++ ) {
-                       this.items[ i ].updateDisabled();
-               }
-       }
-
-       return this;
-};
-
-/**
- * Focus the widget
- * @chainable
- * @return {OO.ui.CapsuleMultiSelectWidget}
- */
-OO.ui.CapsuleMultiSelectWidget.prototype.focus = function () {
-       if ( !this.isDisabled() ) {
-               if ( this.popup ) {
-                       this.popup.setSize( this.$handle.width() );
-                       this.popup.toggle( true );
-                       this.popup.$element.find( '*' )
-                               .filter( function () { return OO.ui.isFocusableElement( $( this ), true ); } )
-                               .first()
-                               .focus();
-               } else {
-                       this.updateInputSize();
-                       this.menu.toggle( true );
-                       this.$input.focus();
-               }
-       }
-       return this;
-};
-
-/**
- * CapsuleItemWidgets are used within a {@link OO.ui.CapsuleMultiSelectWidget
- * CapsuleMultiSelectWidget} to display the selected items.
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.ItemWidget
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.FlaggedElement
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.CapsuleItemWidget = function OoUiCapsuleItemWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.CapsuleItemWidget.parent.call( this, config );
-
-       // Properties (must be set before mixin constructor calls)
-       this.$indicator = $( '<span>' );
-
-       // Mixin constructors
-       OO.ui.mixin.ItemWidget.call( this );
-       OO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$indicator, indicator: 'clear' } ) );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$indicator } ) );
-
-       // Events
-       this.$indicator.on( {
-               keydown: this.onCloseKeyDown.bind( this ),
-               click: this.onCloseClick.bind( this )
-       } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-capsuleItemWidget' )
-               .append( this.$indicator, this.$label );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.CapsuleItemWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.ItemWidget );
-OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.FlaggedElement );
-OO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * Handle close icon clicks
- * @param {jQuery.Event} event
- */
-OO.ui.CapsuleItemWidget.prototype.onCloseClick = function () {
-       var element = this.getElementGroup();
-
-       if ( !this.isDisabled() && element && $.isFunction( element.removeItems ) ) {
-               element.removeItems( [ this ] );
-               element.focus();
-       }
-};
-
-/**
- * Handle close keyboard events
- * @param {jQuery.Event} event Key down event
- */
-OO.ui.CapsuleItemWidget.prototype.onCloseKeyDown = function ( e ) {
-       if ( !this.isDisabled() && $.isFunction( this.getElementGroup().removeItems ) ) {
-               switch ( e.which ) {
-                       case OO.ui.Keys.ENTER:
-                       case OO.ui.Keys.BACKSPACE:
-                       case OO.ui.Keys.SPACE:
-                               this.getElementGroup().removeItems( [ this ] );
-                               return false;
-               }
-       }
-};
-
-/**
- * DropdownWidgets are not menus themselves, rather they contain a menu of options created with
- * OO.ui.MenuOptionWidget. The DropdownWidget takes care of opening and displaying the menu so that
- * users can interact with it.
- *
- * If you want to use this within a HTML form, such as a OO.ui.FormLayout, use
- * OO.ui.DropdownInputWidget instead.
- *
- *     @example
- *     // Example: A DropdownWidget with a menu that contains three options
- *     var dropDown = new OO.ui.DropdownWidget( {
- *         label: 'Dropdown menu: Select a menu option',
- *         menu: {
- *             items: [
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'a',
- *                     label: 'First'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'b',
- *                     label: 'Second'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'c',
- *                     label: 'Third'
- *                 } )
- *             ]
- *         }
- *     } );
- *
- *     $( 'body' ).append( dropDown.$element );
- *
- *     dropDown.getMenu().selectItemByData( 'b' );
- *
- *     dropDown.getMenu().getSelectedItem().getData(); // returns 'b'
- *
- * For more information, please see the [OOjs UI documentation on MediaWiki] [1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object} [menu] Configuration options to pass to {@link OO.ui.FloatingMenuSelectWidget menu select widget}
- * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
- *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
- */
-OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
-       // Configuration initialization
-       config = $.extend( { indicator: 'down' }, config );
-
-       // Parent constructor
-       OO.ui.DropdownWidget.parent.call( this, config );
-
-       // Properties (must be set before TabIndexedElement constructor call)
-       this.$handle = this.$( '<span>' );
-       this.$overlay = config.$overlay || this.$element;
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
-
-       // Properties
-       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend( {
-               widget: this,
-               $container: this.$element
-       }, config.menu ) );
-
-       // Events
-       this.$handle.on( {
-               click: this.onClick.bind( this ),
-               keypress: this.onKeyPress.bind( this )
-       } );
-       this.menu.connect( this, { select: 'onMenuSelect' } );
-
-       // Initialization
-       this.$handle
-               .addClass( 'oo-ui-dropdownWidget-handle' )
-               .append( this.$icon, this.$label, this.$indicator );
-       this.$element
-               .addClass( 'oo-ui-dropdownWidget' )
-               .append( this.$handle );
-       this.$overlay.append( this.menu.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.DropdownWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.DropdownWidget, OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * Get the menu.
- *
- * @return {OO.ui.MenuSelectWidget} Menu of widget
- */
-OO.ui.DropdownWidget.prototype.getMenu = function () {
-       return this.menu;
-};
-
-/**
- * Handles menu select events.
- *
- * @private
- * @param {OO.ui.MenuOptionWidget} item Selected menu item
- */
-OO.ui.DropdownWidget.prototype.onMenuSelect = function ( item ) {
-       var selectedLabel;
-
-       if ( !item ) {
-               this.setLabel( null );
-               return;
-       }
-
-       selectedLabel = item.getLabel();
-
-       // If the label is a DOM element, clone it, because setLabel will append() it
-       if ( selectedLabel instanceof jQuery ) {
-               selectedLabel = selectedLabel.clone();
-       }
-
-       this.setLabel( selectedLabel );
-};
-
-/**
- * Handle mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.DropdownWidget.prototype.onClick = function ( e ) {
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               this.menu.toggle();
-       }
-       return false;
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.DropdownWidget.prototype.onKeyPress = function ( e ) {
-       if ( !this.isDisabled() &&
-               ( ( e.which === OO.ui.Keys.SPACE && !this.menu.isVisible() ) || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.menu.toggle();
-               return false;
-       }
-};
-
-/**
- * SelectFileWidgets allow for selecting files, using the HTML5 File API. These
- * widgets can be configured with {@link OO.ui.mixin.IconElement icons} and {@link
- * OO.ui.mixin.IndicatorElement indicators}.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
- *
- *     @example
- *     // Example of a file select widget
- *     var selectFile = new OO.ui.SelectFileWidget();
- *     $( 'body' ).append( selectFile.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.PendingElement
- * @mixins OO.ui.mixin.LabelElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string[]|null} [accept=null] MIME types to accept. null accepts all types.
- * @cfg {string} [placeholder] Text to display when no file is selected.
- * @cfg {string} [notsupported] Text to display when file support is missing in the browser.
- * @cfg {boolean} [droppable=true] Whether to accept files by drag and drop.
- * @cfg {boolean} [showDropTarget=false] Whether to show a drop target. Requires droppable to be true.
- * @cfg {boolean} [dragDropUI=false] Deprecated alias for showDropTarget
- */
-OO.ui.SelectFileWidget = function OoUiSelectFileWidget( config ) {
-       var dragHandler;
-
-       // TODO: Remove in next release
-       if ( config && config.dragDropUI ) {
-               config.showDropTarget = true;
-       }
-
-       // Configuration initialization
-       config = $.extend( {
-               accept: null,
-               placeholder: OO.ui.msg( 'ooui-selectfile-placeholder' ),
-               notsupported: OO.ui.msg( 'ooui-selectfile-not-supported' ),
-               droppable: true,
-               showDropTarget: false
-       }, config );
-
-       // Parent constructor
-       OO.ui.SelectFileWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$info } ) );
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { autoFitLabel: true } ) );
-
-       // Properties
-       this.$info = $( '<span>' );
-
-       // Properties
-       this.showDropTarget = config.showDropTarget;
-       this.isSupported = this.constructor.static.isSupported();
-       this.currentFile = null;
-       if ( Array.isArray( config.accept ) ) {
-               this.accept = config.accept;
-       } else {
-               this.accept = null;
-       }
-       this.placeholder = config.placeholder;
-       this.notsupported = config.notsupported;
-       this.onFileSelectedHandler = this.onFileSelected.bind( this );
-
-       this.selectButton = new OO.ui.ButtonWidget( {
-               classes: [ 'oo-ui-selectFileWidget-selectButton' ],
-               label: OO.ui.msg( 'ooui-selectfile-button-select' ),
-               disabled: this.disabled || !this.isSupported
-       } );
-
-       this.clearButton = new OO.ui.ButtonWidget( {
-               classes: [ 'oo-ui-selectFileWidget-clearButton' ],
-               framed: false,
-               icon: 'remove',
-               disabled: this.disabled
-       } );
-
-       // Events
-       this.selectButton.$button.on( {
-               keypress: this.onKeyPress.bind( this )
-       } );
-       this.clearButton.connect( this, {
-               click: 'onClearClick'
-       } );
-       if ( config.droppable ) {
-               dragHandler = this.onDragEnterOrOver.bind( this );
-               this.$element.on( {
-                       dragenter: dragHandler,
-                       dragover: dragHandler,
-                       dragleave: this.onDragLeave.bind( this ),
-                       drop: this.onDrop.bind( this )
-               } );
-       }
-
-       // Initialization
-       this.addInput();
-       this.updateUI();
-       this.$label.addClass( 'oo-ui-selectFileWidget-label' );
-       this.$info
-               .addClass( 'oo-ui-selectFileWidget-info' )
-               .append( this.$icon, this.$label, this.clearButton.$element, this.$indicator );
-       this.$element
-               .addClass( 'oo-ui-selectFileWidget' )
-               .append( this.$info, this.selectButton.$element );
-       if ( config.droppable && config.showDropTarget ) {
-               this.$dropTarget = $( '<div>' )
-                       .addClass( 'oo-ui-selectFileWidget-dropTarget' )
-                       .text( OO.ui.msg( 'ooui-selectfile-dragdrop-placeholder' ) )
-                       .on( {
-                               click: this.onDropTargetClick.bind( this )
-                       } );
-               this.$element.prepend( this.$dropTarget );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.SelectFileWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.PendingElement );
-OO.mixinClass( OO.ui.SelectFileWidget, OO.ui.mixin.LabelElement );
-
-/* Static Properties */
-
-/**
- * Check if this widget is supported
- *
- * @static
- * @return {boolean}
- */
-OO.ui.SelectFileWidget.static.isSupported = function () {
-       var $input;
-       if ( OO.ui.SelectFileWidget.static.isSupportedCache === null ) {
-               $input = $( '<input type="file">' );
-               OO.ui.SelectFileWidget.static.isSupportedCache = $input[ 0 ].files !== undefined;
-       }
-       return OO.ui.SelectFileWidget.static.isSupportedCache;
-};
-
-OO.ui.SelectFileWidget.static.isSupportedCache = null;
-
-/* Events */
-
-/**
- * @event change
- *
- * A change event is emitted when the on/off state of the toggle changes.
- *
- * @param {File|null} value New value
- */
-
-/* Methods */
-
-/**
- * Get the current value of the field
- *
- * @return {File|null}
- */
-OO.ui.SelectFileWidget.prototype.getValue = function () {
-       return this.currentFile;
-};
-
-/**
- * Set the current value of the field
- *
- * @param {File|null} file File to select
- */
-OO.ui.SelectFileWidget.prototype.setValue = function ( file ) {
-       if ( this.currentFile !== file ) {
-               this.currentFile = file;
-               this.updateUI();
-               this.emit( 'change', this.currentFile );
-       }
-};
-
-/**
- * Focus the widget.
- *
- * Focusses the select file button.
- *
- * @chainable
- */
-OO.ui.SelectFileWidget.prototype.focus = function () {
-       this.selectButton.$button[ 0 ].focus();
-       return this;
-};
-
-/**
- * Update the user interface when a file is selected or unselected
- *
- * @protected
- */
-OO.ui.SelectFileWidget.prototype.updateUI = function () {
-       var $label;
-       if ( !this.isSupported ) {
-               this.$element.addClass( 'oo-ui-selectFileWidget-notsupported' );
-               this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
-               this.setLabel( this.notsupported );
-       } else {
-               this.$element.addClass( 'oo-ui-selectFileWidget-supported' );
-               if ( this.currentFile ) {
-                       this.$element.removeClass( 'oo-ui-selectFileWidget-empty' );
-                       $label = $( [] );
-                       $label = $label.add(
-                               $( '<span>' )
-                                       .addClass( 'oo-ui-selectFileWidget-fileName' )
-                                       .text( this.currentFile.name )
-                       );
-                       if ( this.currentFile.type !== '' ) {
-                               $label = $label.add(
-                                       $( '<span>' )
-                                               .addClass( 'oo-ui-selectFileWidget-fileType' )
-                                               .text( this.currentFile.type )
-                               );
-                       }
-                       this.setLabel( $label );
-               } else {
-                       this.$element.addClass( 'oo-ui-selectFileWidget-empty' );
-                       this.setLabel( this.placeholder );
-               }
-       }
-};
-
-/**
- * Add the input to the widget
- *
- * @private
- */
-OO.ui.SelectFileWidget.prototype.addInput = function () {
-       if ( this.$input ) {
-               this.$input.remove();
-       }
-
-       if ( !this.isSupported ) {
-               this.$input = null;
-               return;
-       }
-
-       this.$input = $( '<input type="file">' );
-       this.$input.on( 'change', this.onFileSelectedHandler );
-       this.$input.attr( {
-               tabindex: -1
-       } );
-       if ( this.accept ) {
-               this.$input.attr( 'accept', this.accept.join( ', ' ) );
-       }
-       this.selectButton.$button.append( this.$input );
-};
-
-/**
- * Determine if we should accept this file
- *
- * @private
- * @param {string} File MIME type
- * @return {boolean}
- */
-OO.ui.SelectFileWidget.prototype.isAllowedType = function ( mimeType ) {
-       var i, mimeTest;
-
-       if ( !this.accept || !mimeType ) {
-               return true;
-       }
-
-       for ( i = 0; i < this.accept.length; i++ ) {
-               mimeTest = this.accept[ i ];
-               if ( mimeTest === mimeType ) {
-                       return true;
-               } else if ( mimeTest.substr( -2 ) === '/*' ) {
-                       mimeTest = mimeTest.substr( 0, mimeTest.length - 1 );
-                       if ( mimeType.substr( 0, mimeTest.length ) === mimeTest ) {
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-};
-
-/**
- * Handle file selection from the input
- *
- * @private
- * @param {jQuery.Event} e
- */
-OO.ui.SelectFileWidget.prototype.onFileSelected = function ( e ) {
-       var file = OO.getProp( e.target, 'files', 0 ) || null;
-
-       if ( file && !this.isAllowedType( file.type ) ) {
-               file = null;
-       }
-
-       this.setValue( file );
-       this.addInput();
-};
-
-/**
- * Handle clear button click events.
- *
- * @private
- */
-OO.ui.SelectFileWidget.prototype.onClearClick = function () {
-       this.setValue( null );
-       return false;
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.SelectFileWidget.prototype.onKeyPress = function ( e ) {
-       if ( this.isSupported && !this.isDisabled() && this.$input &&
-               ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.$input.click();
-               return false;
-       }
-};
-
-/**
- * Handle drop target click events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {
-       if ( this.isSupported && !this.isDisabled() && this.$input ) {
-               this.$input.click();
-               return false;
-       }
-};
-
-/**
- * Handle drag enter and over events
- *
- * @private
- * @param {jQuery.Event} e Drag event
- */
-OO.ui.SelectFileWidget.prototype.onDragEnterOrOver = function ( e ) {
-       var itemOrFile,
-               droppableFile = false,
-               dt = e.originalEvent.dataTransfer;
-
-       e.preventDefault();
-       e.stopPropagation();
-
-       if ( this.isDisabled() || !this.isSupported ) {
-               this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
-               dt.dropEffect = 'none';
-               return false;
-       }
-
-       // DataTransferItem and File both have a type property, but in Chrome files
-       // have no information at this point.
-       itemOrFile = OO.getProp( dt, 'items', 0 ) || OO.getProp( dt, 'files', 0 );
-       if ( itemOrFile ) {
-               if ( this.isAllowedType( itemOrFile.type ) ) {
-                       droppableFile = true;
-               }
-       // dt.types is Array-like, but not an Array
-       } else if ( Array.prototype.indexOf.call( OO.getProp( dt, 'types' ) || [], 'Files' ) !== -1 ) {
-               // File information is not available at this point for security so just assume
-               // it is acceptable for now.
-               // https://bugzilla.mozilla.org/show_bug.cgi?id=640534
-               droppableFile = true;
-       }
-
-       this.$element.toggleClass( 'oo-ui-selectFileWidget-canDrop', droppableFile );
-       if ( !droppableFile ) {
-               dt.dropEffect = 'none';
-       }
-
-       return false;
-};
-
-/**
- * Handle drag leave events
- *
- * @private
- * @param {jQuery.Event} e Drag event
- */
-OO.ui.SelectFileWidget.prototype.onDragLeave = function () {
-       this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
-};
-
-/**
- * Handle drop events
- *
- * @private
- * @param {jQuery.Event} e Drop event
- */
-OO.ui.SelectFileWidget.prototype.onDrop = function ( e ) {
-       var file = null,
-               dt = e.originalEvent.dataTransfer;
-
-       e.preventDefault();
-       e.stopPropagation();
-       this.$element.removeClass( 'oo-ui-selectFileWidget-canDrop' );
-
-       if ( this.isDisabled() || !this.isSupported ) {
-               return false;
-       }
-
-       file = OO.getProp( dt, 'files', 0 );
-       if ( file && !this.isAllowedType( file.type ) ) {
-               file = null;
-       }
-       if ( file ) {
-               this.setValue( file );
-       }
-
-       return false;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.SelectFileWidget.prototype.setDisabled = function ( disabled ) {
-       OO.ui.SelectFileWidget.parent.prototype.setDisabled.call( this, disabled );
-       if ( this.selectButton ) {
-               this.selectButton.setDisabled( disabled );
-       }
-       if ( this.clearButton ) {
-               this.clearButton.setDisabled( disabled );
-       }
-       return this;
-};
-
-/**
- * IconWidget is a generic widget for {@link OO.ui.mixin.IconElement icons}. In general, IconWidgets should be used with OO.ui.LabelWidget,
- * which creates a label that identifies the icon’s function. See the [OOjs UI documentation on MediaWiki] [1]
- * for a list of icons included in the library.
- *
- *     @example
- *     // An icon widget with a label
- *     var myIcon = new OO.ui.IconWidget( {
- *         icon: 'help',
- *         iconTitle: 'Help'
- *      } );
- *      // Create a label.
- *      var iconLabel = new OO.ui.LabelWidget( {
- *          label: 'Help'
- *      } );
- *      $( 'body' ).append( myIcon.$element, iconLabel.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Icons
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.FlaggedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.IconWidget = function OoUiIconWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.IconWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, $.extend( {}, config, { $icon: this.$element } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
-       OO.ui.mixin.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-iconWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.IconWidget, OO.ui.mixin.FlaggedElement );
-
-/* Static Properties */
-
-OO.ui.IconWidget.static.tagName = 'span';
-
-/**
- * IndicatorWidgets create indicators, which are small graphics that are generally used to draw
- * attention to the status of an item or to clarify the function of a control. For a list of
- * indicators included in the library, please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example of an indicator widget
- *     var indicator1 = new OO.ui.IndicatorWidget( {
- *         indicator: 'alert'
- *     } );
- *
- *     // Create a fieldset layout to add a label
- *     var fieldset = new OO.ui.FieldsetLayout();
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( indicator1, { label: 'An alert indicator:' } )
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Indicators
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.TitledElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.IndicatorWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IndicatorElement.call( this, $.extend( {}, config, { $indicator: this.$element } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$element } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-indicatorWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.mixin.TitledElement );
-
-/* Static Properties */
-
-OO.ui.IndicatorWidget.static.tagName = 'span';
-
-/**
- * InputWidget is the base class for all input widgets, which
- * include {@link OO.ui.TextInputWidget text inputs}, {@link OO.ui.CheckboxInputWidget checkbox inputs},
- * {@link OO.ui.RadioInputWidget radio inputs}, and {@link OO.ui.ButtonInputWidget button inputs}.
- * See the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @abstract
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.FlaggedElement
- * @mixins OO.ui.mixin.TabIndexedElement
- * @mixins OO.ui.mixin.TitledElement
- * @mixins OO.ui.mixin.AccessKeyedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [name=''] The value of the input’s HTML `name` attribute.
- * @cfg {string} [value=''] The value of the input.
- * @cfg {string} [dir] The directionality of the input (ltr/rtl).
- * @cfg {Function} [inputFilter] The name of an input filter function. Input filters modify the value of an input
- *  before it is accepted.
- */
-OO.ui.InputWidget = function OoUiInputWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.InputWidget.parent.call( this, config );
-
-       // Properties
-       this.$input = this.getInputElement( config );
-       this.value = '';
-       this.inputFilter = config.inputFilter;
-
-       // Mixin constructors
-       OO.ui.mixin.FlaggedElement.call( this, config );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
-       OO.ui.mixin.AccessKeyedElement.call( this, $.extend( {}, config, { $accessKeyed: this.$input } ) );
-
-       // Events
-       this.$input.on( 'keydown mouseup cut paste change input select', this.onEdit.bind( this ) );
-
-       // Initialization
-       this.$input
-               .addClass( 'oo-ui-inputWidget-input' )
-               .attr( 'name', config.name )
-               .prop( 'disabled', this.isDisabled() );
-       this.$element
-               .addClass( 'oo-ui-inputWidget' )
-               .append( this.$input );
-       this.setValue( config.value );
-       this.setAccessKey( config.accessKey );
-       if ( config.dir ) {
-               this.setDir( config.dir );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.FlaggedElement );
-OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TabIndexedElement );
-OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.InputWidget, OO.ui.mixin.AccessKeyedElement );
-
-/* Static Properties */
-
-OO.ui.InputWidget.static.supportsSimpleLabel = true;
-
-/* Static Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.InputWidget.static.reusePreInfuseDOM = function ( node, config ) {
-       config = OO.ui.InputWidget.parent.static.reusePreInfuseDOM( node, config );
-       // Reusing $input lets browsers preserve inputted values across page reloads (T114134)
-       config.$input = $( node ).find( '.oo-ui-inputWidget-input' );
-       return config;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.InputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.InputWidget.parent.static.gatherPreInfuseState( node, config );
-       state.value = config.$input.val();
-       // Might be better in TabIndexedElement, but it's awkward to do there because mixins are awkward
-       state.focus = config.$input.is( ':focus' );
-       return state;
-};
-
-/* Events */
-
-/**
- * @event change
- *
- * A change event is emitted when the value of the input changes.
- *
- * @param {string} value
- */
-
-/* Methods */
-
-/**
- * Get input element.
- *
- * Subclasses of OO.ui.InputWidget use the `config` parameter to produce different elements in
- * different circumstances. The element must have a `value` property (like form elements).
- *
- * @protected
- * @param {Object} config Configuration options
- * @return {jQuery} Input element
- */
-OO.ui.InputWidget.prototype.getInputElement = function ( config ) {
-       // See #reusePreInfuseDOM about config.$input
-       return config.$input || $( '<input>' );
-};
-
-/**
- * Handle potentially value-changing events.
- *
- * @private
- * @param {jQuery.Event} e Key down, mouse up, cut, paste, change, input, or select event
- */
-OO.ui.InputWidget.prototype.onEdit = function () {
-       var widget = this;
-       if ( !this.isDisabled() ) {
-               // Allow the stack to clear so the value will be updated
-               setTimeout( function () {
-                       widget.setValue( widget.$input.val() );
-               } );
-       }
-};
-
-/**
- * Get the value of the input.
- *
- * @return {string} Input value
- */
-OO.ui.InputWidget.prototype.getValue = function () {
-       // Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
-       // it, and we won't know unless they're kind enough to trigger a 'change' event.
-       var value = this.$input.val();
-       if ( this.value !== value ) {
-               this.setValue( value );
-       }
-       return this.value;
-};
-
-/**
- * Set the directionality of the input, either RTL (right-to-left) or LTR (left-to-right).
- *
- * @deprecated since v0.13.1, use #setDir directly
- * @param {boolean} isRTL Directionality is right-to-left
- * @chainable
- */
-OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
-       this.setDir( isRTL ? 'rtl' : 'ltr' );
-       return this;
-};
-
-/**
- * Set the directionality of the input.
- *
- * @param {string} dir Text directionality: 'ltr', 'rtl' or 'auto'
- * @chainable
- */
-OO.ui.InputWidget.prototype.setDir = function ( dir ) {
-       this.$input.prop( 'dir', dir );
-       return this;
-};
-
-/**
- * Set the value of the input.
- *
- * @param {string} value New value
- * @fires change
- * @chainable
- */
-OO.ui.InputWidget.prototype.setValue = function ( value ) {
-       value = this.cleanUpValue( value );
-       // Update the DOM if it has changed. Note that with cleanUpValue, it
-       // is possible for the DOM value to change without this.value changing.
-       if ( this.$input.val() !== value ) {
-               this.$input.val( value );
-       }
-       if ( this.value !== value ) {
-               this.value = value;
-               this.emit( 'change', this.value );
-       }
-       return this;
-};
-
-/**
- * Set the input's access key.
- * FIXME: This is the same code as in OO.ui.mixin.ButtonElement, maybe find a better place for it?
- *
- * @param {string} accessKey Input's access key, use empty string to remove
- * @chainable
- */
-OO.ui.InputWidget.prototype.setAccessKey = function ( accessKey ) {
-       accessKey = typeof accessKey === 'string' && accessKey.length ? accessKey : null;
-
-       if ( this.accessKey !== accessKey ) {
-               if ( this.$input ) {
-                       if ( accessKey !== null ) {
-                               this.$input.attr( 'accesskey', accessKey );
-                       } else {
-                               this.$input.removeAttr( 'accesskey' );
-                       }
-               }
-               this.accessKey = accessKey;
-       }
-
-       return this;
-};
-
-/**
- * Clean up incoming value.
- *
- * Ensures value is a string, and converts undefined and null to empty string.
- *
- * @private
- * @param {string} value Original value
- * @return {string} Cleaned up value
- */
-OO.ui.InputWidget.prototype.cleanUpValue = function ( value ) {
-       if ( value === undefined || value === null ) {
-               return '';
-       } else if ( this.inputFilter ) {
-               return this.inputFilter( String( value ) );
-       } else {
-               return String( value );
-       }
-};
-
-/**
- * Simulate the behavior of clicking on a label bound to this input. This method is only called by
- * {@link OO.ui.LabelWidget LabelWidget} and {@link OO.ui.FieldLayout FieldLayout}. It should not be
- * called directly.
- */
-OO.ui.InputWidget.prototype.simulateLabelClick = function () {
-       if ( !this.isDisabled() ) {
-               if ( this.$input.is( ':checkbox, :radio' ) ) {
-                       this.$input.click();
-               }
-               if ( this.$input.is( ':input' ) ) {
-                       this.$input[ 0 ].focus();
-               }
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.InputWidget.prototype.setDisabled = function ( state ) {
-       OO.ui.InputWidget.parent.prototype.setDisabled.call( this, state );
-       if ( this.$input ) {
-               this.$input.prop( 'disabled', this.isDisabled() );
-       }
-       return this;
-};
-
-/**
- * Focus the input.
- *
- * @chainable
- */
-OO.ui.InputWidget.prototype.focus = function () {
-       this.$input[ 0 ].focus();
-       return this;
-};
-
-/**
- * Blur the input.
- *
- * @chainable
- */
-OO.ui.InputWidget.prototype.blur = function () {
-       this.$input[ 0 ].blur();
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.InputWidget.prototype.restorePreInfuseState = function ( state ) {
-       OO.ui.InputWidget.parent.prototype.restorePreInfuseState.call( this, state );
-       if ( state.value !== undefined && state.value !== this.getValue() ) {
-               this.setValue( state.value );
-       }
-       if ( state.focus ) {
-               this.focus();
-       }
-};
-
-/**
- * ButtonInputWidget is used to submit HTML forms and is intended to be used within
- * a OO.ui.FormLayout. If you do not need the button to work with HTML forms, you probably
- * want to use OO.ui.ButtonWidget instead. Button input widgets can be rendered as either an
- * HTML `<button/>` (the default) or an HTML `<input/>` tags. See the
- * [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- *     @example
- *     // A ButtonInputWidget rendered as an HTML button, the default.
- *     var button = new OO.ui.ButtonInputWidget( {
- *         label: 'Input button',
- *         icon: 'check',
- *         value: 'check'
- *     } );
- *     $( 'body' ).append( button.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs#Button_inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- * @mixins OO.ui.mixin.ButtonElement
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.TitledElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [type='button'] The value of the HTML `'type'` attribute: 'button', 'submit' or 'reset'.
- * @cfg {boolean} [useInputTag=false] Use an `<input/>` tag instead of a `<button/>` tag, the default.
- *  Widgets configured to be an `<input/>` do not support {@link #icon icons} and {@link #indicator indicators},
- *  non-plaintext {@link #label labels}, or {@link #value values}. In general, useInputTag should only
- *  be set to `true` when there’s need to support IE6 in a form with multiple buttons.
- */
-OO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {
-       // Configuration initialization
-       config = $.extend( { type: 'button', useInputTag: false }, config );
-
-       // Properties (must be set before parent constructor, which calls #setValue)
-       this.useInputTag = config.useInputTag;
-
-       // Parent constructor
-       OO.ui.ButtonInputWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, $.extend( {}, config, { $button: this.$input } ) );
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
-
-       // Initialization
-       if ( !config.useInputTag ) {
-               this.$input.append( this.$icon, this.$label, this.$indicator );
-       }
-       this.$element.addClass( 'oo-ui-buttonInputWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ButtonInputWidget, OO.ui.InputWidget );
-OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.ButtonElement );
-OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.mixin.TitledElement );
-
-/* Static Properties */
-
-/**
- * Disable generating `<label>` elements for buttons. One would very rarely need additional label
- * for a button, and it's already a big clickable target, and it causes unexpected rendering.
- */
-OO.ui.ButtonInputWidget.static.supportsSimpleLabel = false;
-
-/* Methods */
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {
-       var type;
-       // See InputWidget#reusePreInfuseDOM about config.$input
-       if ( config.$input ) {
-               return config.$input.empty();
-       }
-       type = [ 'button', 'submit', 'reset' ].indexOf( config.type ) !== -1 ? config.type : 'button';
-       return $( '<' + ( config.useInputTag ? 'input' : 'button' ) + ' type="' + type + '">' );
-};
-
-/**
- * Set label value.
- *
- * If #useInputTag is `true`, the label is set as the `value` of the `<input/>` tag.
- *
- * @param {jQuery|string|Function|null} label Label nodes, text, a function that returns nodes or
- *  text, or `null` for no label
- * @chainable
- */
-OO.ui.ButtonInputWidget.prototype.setLabel = function ( label ) {
-       OO.ui.mixin.LabelElement.prototype.setLabel.call( this, label );
-
-       if ( this.useInputTag ) {
-               if ( typeof label === 'function' ) {
-                       label = OO.ui.resolveMsg( label );
-               }
-               if ( label instanceof jQuery ) {
-                       label = label.text();
-               }
-               if ( !label ) {
-                       label = '';
-               }
-               this.$input.val( label );
-       }
-
-       return this;
-};
-
-/**
- * Set the value of the input.
- *
- * This method is disabled for button inputs configured as {@link #useInputTag <input/> tags}, as
- * they do not support {@link #value values}.
- *
- * @param {string} value New value
- * @chainable
- */
-OO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {
-       if ( !this.useInputTag ) {
-               OO.ui.ButtonInputWidget.parent.prototype.setValue.call( this, value );
-       }
-       return this;
-};
-
-/**
- * CheckboxInputWidgets, like HTML checkboxes, can be selected and/or configured with a value.
- * Note that these {@link OO.ui.InputWidget input widgets} are best laid out
- * in {@link OO.ui.FieldLayout field layouts} that use the {@link OO.ui.FieldLayout#align inline}
- * alignment. For more information, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
- *
- *     @example
- *     // An example of selected, unselected, and disabled checkbox inputs
- *     var checkbox1=new OO.ui.CheckboxInputWidget( {
- *          value: 'a',
- *          selected: true
- *     } );
- *     var checkbox2=new OO.ui.CheckboxInputWidget( {
- *         value: 'b'
- *     } );
- *     var checkbox3=new OO.ui.CheckboxInputWidget( {
- *         value:'c',
- *         disabled: true
- *     } );
- *     // Create a fieldset layout with fields for each checkbox.
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *         label: 'Checkboxes'
- *     } );
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( checkbox1, { label: 'Selected checkbox', align: 'inline' } ),
- *         new OO.ui.FieldLayout( checkbox2, { label: 'Unselected checkbox', align: 'inline' } ),
- *         new OO.ui.FieldLayout( checkbox3, { label: 'Disabled checkbox', align: 'inline' } ),
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [selected=false] Select the checkbox initially. By default, the checkbox is not selected.
- */
-OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.CheckboxInputWidget.parent.call( this, config );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-checkboxInputWidget' )
-               // Required for pretty styling in MediaWiki theme
-               .append( $( '<span>' ) );
-       this.setSelected( config.selected !== undefined ? config.selected : false );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
-
-/* Static Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.CheckboxInputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.CheckboxInputWidget.parent.static.gatherPreInfuseState( node, config );
-       state.checked = config.$input.prop( 'checked' );
-       return state;
-};
-
-/* Methods */
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
-       return $( '<input type="checkbox" />' );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
-       var widget = this;
-       if ( !this.isDisabled() ) {
-               // Allow the stack to clear so the value will be updated
-               setTimeout( function () {
-                       widget.setSelected( widget.$input.prop( 'checked' ) );
-               } );
-       }
-};
-
-/**
- * Set selection state of this checkbox.
- *
- * @param {boolean} state `true` for selected
- * @chainable
- */
-OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state ) {
-       state = !!state;
-       if ( this.selected !== state ) {
-               this.selected = state;
-               this.$input.prop( 'checked', this.selected );
-               this.emit( 'change', this.selected );
-       }
-       return this;
-};
-
-/**
- * Check if this checkbox is selected.
- *
- * @return {boolean} Checkbox is selected
- */
-OO.ui.CheckboxInputWidget.prototype.isSelected = function () {
-       // Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
-       // it, and we won't know unless they're kind enough to trigger a 'change' event.
-       var selected = this.$input.prop( 'checked' );
-       if ( this.selected !== selected ) {
-               this.setSelected( selected );
-       }
-       return this.selected;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {
-       OO.ui.CheckboxInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
-       if ( state.checked !== undefined && state.checked !== this.isSelected() ) {
-               this.setSelected( state.checked );
-       }
-};
-
-/**
- * DropdownInputWidget is a {@link OO.ui.DropdownWidget DropdownWidget} intended to be used
- * within a HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
- * of a hidden HTML `input` tag. Please see the [OOjs UI documentation on MediaWiki][1] for
- * more information about input widgets.
- *
- * A DropdownInputWidget always has a value (one of the options is always selected), unless there
- * are no options. If no `value` configuration option is provided, the first option is selected.
- * If you need a state representing no value (no option being selected), use a DropdownWidget.
- *
- * This and OO.ui.RadioSelectInputWidget support the same configuration options.
- *
- *     @example
- *     // Example: A DropdownInputWidget with three options
- *     var dropdownInput = new OO.ui.DropdownInputWidget( {
- *         options: [
- *             { data: 'a', label: 'First' },
- *             { data: 'b', label: 'Second'},
- *             { data: 'c', label: 'Third' }
- *         ]
- *     } );
- *     $( 'body' ).append( dropdownInput.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- * @mixins OO.ui.mixin.TitledElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
- * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}
- */
-OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties (must be done before parent constructor which calls #setDisabled)
-       this.dropdownWidget = new OO.ui.DropdownWidget( config.dropdown );
-
-       // Parent constructor
-       OO.ui.DropdownInputWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TitledElement.call( this, config );
-
-       // Events
-       this.dropdownWidget.getMenu().connect( this, { select: 'onMenuSelect' } );
-
-       // Initialization
-       this.setOptions( config.options || [] );
-       this.$element
-               .addClass( 'oo-ui-dropdownInputWidget' )
-               .append( this.dropdownWidget.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.DropdownInputWidget, OO.ui.InputWidget );
-OO.mixinClass( OO.ui.DropdownInputWidget, OO.ui.mixin.TitledElement );
-
-/* Methods */
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.DropdownInputWidget.prototype.getInputElement = function ( config ) {
-       // See InputWidget#reusePreInfuseDOM about config.$input
-       if ( config.$input ) {
-               return config.$input.addClass( 'oo-ui-element-hidden' );
-       }
-       return $( '<input type="hidden">' );
-};
-
-/**
- * Handles menu select events.
- *
- * @private
- * @param {OO.ui.MenuOptionWidget} item Selected menu item
- */
-OO.ui.DropdownInputWidget.prototype.onMenuSelect = function ( item ) {
-       this.setValue( item.getData() );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.DropdownInputWidget.prototype.setValue = function ( value ) {
-       value = this.cleanUpValue( value );
-       this.dropdownWidget.getMenu().selectItemByData( value );
-       OO.ui.DropdownInputWidget.parent.prototype.setValue.call( this, value );
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.DropdownInputWidget.prototype.setDisabled = function ( state ) {
-       this.dropdownWidget.setDisabled( state );
-       OO.ui.DropdownInputWidget.parent.prototype.setDisabled.call( this, state );
-       return this;
-};
-
-/**
- * Set the options available for this input.
- *
- * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
- * @chainable
- */
-OO.ui.DropdownInputWidget.prototype.setOptions = function ( options ) {
-       var
-               value = this.getValue(),
-               widget = this;
-
-       // Rebuild the dropdown menu
-       this.dropdownWidget.getMenu()
-               .clearItems()
-               .addItems( options.map( function ( opt ) {
-                       var optValue = widget.cleanUpValue( opt.data );
-                       return new OO.ui.MenuOptionWidget( {
-                               data: optValue,
-                               label: opt.label !== undefined ? opt.label : optValue
-                       } );
-               } ) );
-
-       // Restore the previous value, or reset to something sensible
-       if ( this.dropdownWidget.getMenu().getItemFromData( value ) ) {
-               // Previous value is still available, ensure consistency with the dropdown
-               this.setValue( value );
-       } else {
-               // No longer valid, reset
-               if ( options.length ) {
-                       this.setValue( options[ 0 ].data );
-               }
-       }
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.DropdownInputWidget.prototype.focus = function () {
-       this.dropdownWidget.getMenu().toggle( true );
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.DropdownInputWidget.prototype.blur = function () {
-       this.dropdownWidget.getMenu().toggle( false );
-       return this;
-};
-
-/**
- * RadioInputWidget creates a single radio button. Because radio buttons are usually used as a set,
- * in most cases you will want to use a {@link OO.ui.RadioSelectWidget radio select}
- * with {@link OO.ui.RadioOptionWidget radio options} instead of this class. For more information,
- * please see the [OOjs UI documentation on MediaWiki][1].
- *
- * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
- *
- *     @example
- *     // An example of selected, unselected, and disabled radio inputs
- *     var radio1 = new OO.ui.RadioInputWidget( {
- *         value: 'a',
- *         selected: true
- *     } );
- *     var radio2 = new OO.ui.RadioInputWidget( {
- *         value: 'b'
- *     } );
- *     var radio3 = new OO.ui.RadioInputWidget( {
- *         value: 'c',
- *         disabled: true
- *     } );
- *     // Create a fieldset layout with fields for each radio button.
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *         label: 'Radio inputs'
- *     } );
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( radio1, { label: 'Selected', align: 'inline' } ),
- *         new OO.ui.FieldLayout( radio2, { label: 'Unselected', align: 'inline' } ),
- *         new OO.ui.FieldLayout( radio3, { label: 'Disabled', align: 'inline' } ),
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [selected=false] Select the radio button initially. By default, the radio button is not selected.
- */
-OO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.RadioInputWidget.parent.call( this, config );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-radioInputWidget' )
-               // Required for pretty styling in MediaWiki theme
-               .append( $( '<span>' ) );
-       this.setSelected( config.selected !== undefined ? config.selected : false );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.RadioInputWidget, OO.ui.InputWidget );
-
-/* Static Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioInputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.RadioInputWidget.parent.static.gatherPreInfuseState( node, config );
-       state.checked = config.$input.prop( 'checked' );
-       return state;
-};
-
-/* Methods */
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.RadioInputWidget.prototype.getInputElement = function () {
-       return $( '<input type="radio" />' );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioInputWidget.prototype.onEdit = function () {
-       // RadioInputWidget doesn't track its state.
-};
-
-/**
- * Set selection state of this radio button.
- *
- * @param {boolean} state `true` for selected
- * @chainable
- */
-OO.ui.RadioInputWidget.prototype.setSelected = function ( state ) {
-       // RadioInputWidget doesn't track its state.
-       this.$input.prop( 'checked', state );
-       return this;
-};
-
-/**
- * Check if this radio button is selected.
- *
- * @return {boolean} Radio is selected
- */
-OO.ui.RadioInputWidget.prototype.isSelected = function () {
-       return this.$input.prop( 'checked' );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioInputWidget.prototype.restorePreInfuseState = function ( state ) {
-       OO.ui.RadioInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
-       if ( state.checked !== undefined && state.checked !== this.isSelected() ) {
-               this.setSelected( state.checked );
-       }
-};
-
-/**
- * RadioSelectInputWidget is a {@link OO.ui.RadioSelectWidget RadioSelectWidget} intended to be used
- * within a HTML form, such as a OO.ui.FormLayout. The selected value is synchronized with the value
- * of a hidden HTML `input` tag. Please see the [OOjs UI documentation on MediaWiki][1] for
- * more information about input widgets.
- *
- * This and OO.ui.DropdownInputWidget support the same configuration options.
- *
- *     @example
- *     // Example: A RadioSelectInputWidget with three options
- *     var radioSelectInput = new OO.ui.RadioSelectInputWidget( {
- *         options: [
- *             { data: 'a', label: 'First' },
- *             { data: 'b', label: 'Second'},
- *             { data: 'c', label: 'Third' }
- *         ]
- *     } );
- *     $( 'body' ).append( radioSelectInput.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
- */
-OO.ui.RadioSelectInputWidget = function OoUiRadioSelectInputWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties (must be done before parent constructor which calls #setDisabled)
-       this.radioSelectWidget = new OO.ui.RadioSelectWidget();
-
-       // Parent constructor
-       OO.ui.RadioSelectInputWidget.parent.call( this, config );
-
-       // Events
-       this.radioSelectWidget.connect( this, { select: 'onMenuSelect' } );
-
-       // Initialization
-       this.setOptions( config.options || [] );
-       this.$element
-               .addClass( 'oo-ui-radioSelectInputWidget' )
-               .append( this.radioSelectWidget.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.RadioSelectInputWidget, OO.ui.InputWidget );
-
-/* Static Properties */
-
-OO.ui.RadioSelectInputWidget.static.supportsSimpleLabel = false;
-
-/* Static Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioSelectInputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.RadioSelectInputWidget.parent.static.gatherPreInfuseState( node, config );
-       state.value = $( node ).find( '.oo-ui-radioInputWidget .oo-ui-inputWidget-input:checked' ).val();
-       return state;
-};
-
-/* Methods */
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.RadioSelectInputWidget.prototype.getInputElement = function () {
-       return $( '<input type="hidden">' );
-};
-
-/**
- * Handles menu select events.
- *
- * @private
- * @param {OO.ui.RadioOptionWidget} item Selected menu item
- */
-OO.ui.RadioSelectInputWidget.prototype.onMenuSelect = function ( item ) {
-       this.setValue( item.getData() );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioSelectInputWidget.prototype.setValue = function ( value ) {
-       value = this.cleanUpValue( value );
-       this.radioSelectWidget.selectItemByData( value );
-       OO.ui.RadioSelectInputWidget.parent.prototype.setValue.call( this, value );
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioSelectInputWidget.prototype.setDisabled = function ( state ) {
-       this.radioSelectWidget.setDisabled( state );
-       OO.ui.RadioSelectInputWidget.parent.prototype.setDisabled.call( this, state );
-       return this;
-};
-
-/**
- * Set the options available for this input.
- *
- * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
- * @chainable
- */
-OO.ui.RadioSelectInputWidget.prototype.setOptions = function ( options ) {
-       var
-               value = this.getValue(),
-               widget = this;
-
-       // Rebuild the radioSelect menu
-       this.radioSelectWidget
-               .clearItems()
-               .addItems( options.map( function ( opt ) {
-                       var optValue = widget.cleanUpValue( opt.data );
-                       return new OO.ui.RadioOptionWidget( {
-                               data: optValue,
-                               label: opt.label !== undefined ? opt.label : optValue
-                       } );
-               } ) );
-
-       // Restore the previous value, or reset to something sensible
-       if ( this.radioSelectWidget.getItemFromData( value ) ) {
-               // Previous value is still available, ensure consistency with the radioSelect
-               this.setValue( value );
-       } else {
-               // No longer valid, reset
-               if ( options.length ) {
-                       this.setValue( options[ 0 ].data );
-               }
-       }
-
-       return this;
-};
-
-/**
- * TextInputWidgets, like HTML text inputs, can be configured with options that customize the
- * size of the field as well as its presentation. In addition, these widgets can be configured
- * with {@link OO.ui.mixin.IconElement icons}, {@link OO.ui.mixin.IndicatorElement indicators}, an optional
- * validation-pattern (used to determine if an input value is valid or not) and an input filter,
- * which modifies incoming values rather than validating them.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for more information and examples.
- *
- * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
- *
- *     @example
- *     // Example of a text input widget
- *     var textInput = new OO.ui.TextInputWidget( {
- *         value: 'Text input'
- *     } )
- *     $( 'body' ).append( textInput.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Inputs
- *
- * @class
- * @extends OO.ui.InputWidget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- * @mixins OO.ui.mixin.PendingElement
- * @mixins OO.ui.mixin.LabelElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [type='text'] The value of the HTML `type` attribute: 'text', 'password', 'search',
- *  'email' or 'url'. Ignored if `multiline` is true.
- *
- *  Some values of `type` result in additional behaviors:
- *
- *  - `search`: implies `icon: 'search'` and `indicator: 'clear'`; when clicked, the indicator
- *    empties the text field
- * @cfg {string} [placeholder] Placeholder text
- * @cfg {boolean} [autofocus=false] Use an HTML `autofocus` attribute to
- *  instruct the browser to focus this widget.
- * @cfg {boolean} [readOnly=false] Prevent changes to the value of the text input.
- * @cfg {number} [maxLength] Maximum number of characters allowed in the input.
- * @cfg {boolean} [multiline=false] Allow multiple lines of text
- * @cfg {number} [rows] If multiline, number of visible lines in textarea. If used with `autosize`,
- *  specifies minimum number of rows to display.
- * @cfg {boolean} [autosize=false] Automatically resize the text input to fit its content.
- *  Use the #maxRows config to specify a maximum number of displayed rows.
- * @cfg {boolean} [maxRows] Maximum number of rows to display when #autosize is set to true.
- *  Defaults to the maximum of `10` and `2 * rows`, or `10` if `rows` isn't provided.
- * @cfg {string} [labelPosition='after'] The position of the inline label relative to that of
- *  the value or placeholder text: `'before'` or `'after'`
- * @cfg {boolean} [required=false] Mark the field as required. Implies `indicator: 'required'`.
- * @cfg {boolean} [autocomplete=true] Should the browser support autocomplete for this field
- * @cfg {RegExp|Function|string} [validate] Validation pattern: when string, a symbolic name of a
- *  pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer'
- *  (the value must contain only numbers); when RegExp, a regular expression that must match the
- *  value for it to be considered valid; when Function, a function receiving the value as parameter
- *  that must return true, or promise resolving to true, for it to be considered valid.
- */
-OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
-       // Configuration initialization
-       config = $.extend( {
-               type: 'text',
-               labelPosition: 'after'
-       }, config );
-       if ( config.type === 'search' ) {
-               if ( config.icon === undefined ) {
-                       config.icon = 'search';
-               }
-               // indicator: 'clear' is set dynamically later, depending on value
-       }
-       if ( config.required ) {
-               if ( config.indicator === undefined ) {
-                       config.indicator = 'required';
-               }
-       }
-
-       // Parent constructor
-       OO.ui.TextInputWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-       OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$input } ) );
-       OO.ui.mixin.LabelElement.call( this, config );
-
-       // Properties
-       this.type = this.getSaneType( config );
-       this.readOnly = false;
-       this.multiline = !!config.multiline;
-       this.autosize = !!config.autosize;
-       this.minRows = config.rows !== undefined ? config.rows : '';
-       this.maxRows = config.maxRows || Math.max( 2 * ( this.minRows || 0 ), 10 );
-       this.validate = null;
-       this.styleHeight = null;
-       this.scrollWidth = null;
-
-       // Clone for resizing
-       if ( this.autosize ) {
-               this.$clone = this.$input
-                       .clone()
-                       .insertAfter( this.$input )
-                       .attr( 'aria-hidden', 'true' )
-                       .addClass( 'oo-ui-element-hidden' );
-       }
-
-       this.setValidation( config.validate );
-       this.setLabelPosition( config.labelPosition );
-
-       // Events
-       this.$input.on( {
-               keypress: this.onKeyPress.bind( this ),
-               blur: this.onBlur.bind( this )
-       } );
-       this.$input.one( {
-               focus: this.onElementAttach.bind( this )
-       } );
-       this.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );
-       this.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );
-       this.on( 'labelChange', this.updatePosition.bind( this ) );
-       this.connect( this, {
-               change: 'onChange',
-               disable: 'onDisable'
-       } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-textInputWidget oo-ui-textInputWidget-type-' + this.type )
-               .append( this.$icon, this.$indicator );
-       this.setReadOnly( !!config.readOnly );
-       this.updateSearchIndicator();
-       if ( config.placeholder ) {
-               this.$input.attr( 'placeholder', config.placeholder );
-       }
-       if ( config.maxLength !== undefined ) {
-               this.$input.attr( 'maxlength', config.maxLength );
-       }
-       if ( config.autofocus ) {
-               this.$input.attr( 'autofocus', 'autofocus' );
-       }
-       if ( config.required ) {
-               this.$input.attr( 'required', 'required' );
-               this.$input.attr( 'aria-required', 'true' );
-       }
-       if ( config.autocomplete === false ) {
-               this.$input.attr( 'autocomplete', 'off' );
-               // Turning off autocompletion also disables "form caching" when the user navigates to a
-               // different page and then clicks "Back". Re-enable it when leaving. Borrowed from jQuery UI.
-               $( window ).on( {
-                       beforeunload: function () {
-                               this.$input.removeAttr( 'autocomplete' );
-                       }.bind( this ),
-                       pageshow: function () {
-                               // Browsers don't seem to actually fire this event on "Back", they instead just reload the
-                               // whole page... it shouldn't hurt, though.
-                               this.$input.attr( 'autocomplete', 'off' );
-                       }.bind( this )
-               } );
-       }
-       if ( this.multiline && config.rows ) {
-               this.$input.attr( 'rows', config.rows );
-       }
-       if ( this.label || config.autosize ) {
-               this.installParentChangeDetector();
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );
-OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.IndicatorElement );
-OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.PendingElement );
-OO.mixinClass( OO.ui.TextInputWidget, OO.ui.mixin.LabelElement );
-
-/* Static Properties */
-
-OO.ui.TextInputWidget.static.validationPatterns = {
-       'non-empty': /.+/,
-       integer: /^\d+$/
-};
-
-/* Static Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.TextInputWidget.static.gatherPreInfuseState = function ( node, config ) {
-       var state = OO.ui.TextInputWidget.parent.static.gatherPreInfuseState( node, config );
-       if ( config.multiline ) {
-               state.scrollTop = config.$input.scrollTop();
-       }
-       return state;
-};
-
-/* Events */
-
-/**
- * An `enter` event is emitted when the user presses 'enter' inside the text box.
- *
- * Not emitted if the input is multiline.
- *
- * @event enter
- */
-
-/**
- * A `resize` event is emitted when autosize is set and the widget resizes
- *
- * @event resize
- */
-
-/* Methods */
-
-/**
- * Handle icon mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- * @fires icon
- */
-OO.ui.TextInputWidget.prototype.onIconMouseDown = function ( e ) {
-       if ( e.which === OO.ui.MouseButtons.LEFT ) {
-               this.$input[ 0 ].focus();
-               return false;
-       }
-};
-
-/**
- * Handle indicator mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- * @fires indicator
- */
-OO.ui.TextInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
-       if ( e.which === OO.ui.MouseButtons.LEFT ) {
-               if ( this.type === 'search' ) {
-                       // Clear the text field
-                       this.setValue( '' );
-               }
-               this.$input[ 0 ].focus();
-               return false;
-       }
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- * @fires enter If enter key is pressed and input is not multiline
- */
-OO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {
-       if ( e.which === OO.ui.Keys.ENTER && !this.multiline ) {
-               this.emit( 'enter', e );
-       }
-};
-
-/**
- * Handle blur events.
- *
- * @private
- * @param {jQuery.Event} e Blur event
- */
-OO.ui.TextInputWidget.prototype.onBlur = function () {
-       this.setValidityFlag();
-};
-
-/**
- * Handle element attach events.
- *
- * @private
- * @param {jQuery.Event} e Element attach event
- */
-OO.ui.TextInputWidget.prototype.onElementAttach = function () {
-       // Any previously calculated size is now probably invalid if we reattached elsewhere
-       this.valCache = null;
-       this.adjustSize();
-       this.positionLabel();
-};
-
-/**
- * Handle change events.
- *
- * @param {string} value
- * @private
- */
-OO.ui.TextInputWidget.prototype.onChange = function () {
-       this.updateSearchIndicator();
-       this.setValidityFlag();
-       this.adjustSize();
-};
-
-/**
- * Handle disable events.
- *
- * @param {boolean} disabled Element is disabled
- * @private
- */
-OO.ui.TextInputWidget.prototype.onDisable = function () {
-       this.updateSearchIndicator();
-};
-
-/**
- * Check if the input is {@link #readOnly read-only}.
- *
- * @return {boolean}
- */
-OO.ui.TextInputWidget.prototype.isReadOnly = function () {
-       return this.readOnly;
-};
-
-/**
- * Set the {@link #readOnly read-only} state of the input.
- *
- * @param {boolean} state Make input read-only
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {
-       this.readOnly = !!state;
-       this.$input.prop( 'readOnly', this.readOnly );
-       this.updateSearchIndicator();
-       return this;
-};
-
-/**
- * Support function for making #onElementAttach work across browsers.
- *
- * This whole function could be replaced with one line of code using the DOMNodeInsertedIntoDocument
- * event, but it's not supported by Firefox and allegedly deprecated, so we only use it as fallback.
- *
- * Due to MutationObserver performance woes, #onElementAttach is only somewhat reliably called the
- * first time that the element gets attached to the documented.
- */
-OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
-       var mutationObserver, onRemove, topmostNode, fakeParentNode,
-               MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
-               widget = this;
-
-       if ( MutationObserver ) {
-               // The new way. If only it wasn't so ugly.
-
-               if ( this.$element.closest( 'html' ).length ) {
-                       // Widget is attached already, do nothing. This breaks the functionality of this function when
-                       // the widget is detached and reattached. Alas, doing this correctly with MutationObserver
-                       // would require observation of the whole document, which would hurt performance of other,
-                       // more important code.
-                       return;
-               }
-
-               // Find topmost node in the tree
-               topmostNode = this.$element[ 0 ];
-               while ( topmostNode.parentNode ) {
-                       topmostNode = topmostNode.parentNode;
-               }
-
-               // We have no way to detect the $element being attached somewhere without observing the entire
-               // DOM with subtree modifications, which would hurt performance. So we cheat: we hook to the
-               // parent node of $element, and instead detect when $element is removed from it (and thus
-               // probably attached somewhere else). If there is no parent, we create a "fake" one. If it
-               // doesn't get attached, we end up back here and create the parent.
-
-               mutationObserver = new MutationObserver( function ( mutations ) {
-                       var i, j, removedNodes;
-                       for ( i = 0; i < mutations.length; i++ ) {
-                               removedNodes = mutations[ i ].removedNodes;
-                               for ( j = 0; j < removedNodes.length; j++ ) {
-                                       if ( removedNodes[ j ] === topmostNode ) {
-                                               setTimeout( onRemove, 0 );
-                                               return;
-                                       }
-                               }
-                       }
-               } );
-
-               onRemove = function () {
-                       // If the node was attached somewhere else, report it
-                       if ( widget.$element.closest( 'html' ).length ) {
-                               widget.onElementAttach();
-                       }
-                       mutationObserver.disconnect();
-                       widget.installParentChangeDetector();
-               };
-
-               // Create a fake parent and observe it
-               fakeParentNode = $( '<div>' ).append( topmostNode )[ 0 ];
-               mutationObserver.observe( fakeParentNode, { childList: true } );
-       } else {
-               // Using the DOMNodeInsertedIntoDocument event is much nicer and less magical, and works for
-               // detachment and reattachment, but it's not supported by Firefox and allegedly deprecated.
-               this.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );
-       }
-};
-
-/**
- * Automatically adjust the size of the text input.
- *
- * This only affects #multiline inputs that are {@link #autosize autosized}.
- *
- * @chainable
- * @fires resize
- */
-OO.ui.TextInputWidget.prototype.adjustSize = function () {
-       var scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError,
-               idealHeight, newHeight, scrollWidth, property;
-
-       if ( this.multiline && this.$input.val() !== this.valCache ) {
-               if ( this.autosize ) {
-                       this.$clone
-                               .val( this.$input.val() )
-                               .attr( 'rows', this.minRows )
-                               // Set inline height property to 0 to measure scroll height
-                               .css( 'height', 0 );
-
-                       this.$clone.removeClass( 'oo-ui-element-hidden' );
-
-                       this.valCache = this.$input.val();
-
-                       scrollHeight = this.$clone[ 0 ].scrollHeight;
-
-                       // Remove inline height property to measure natural heights
-                       this.$clone.css( 'height', '' );
-                       innerHeight = this.$clone.innerHeight();
-                       outerHeight = this.$clone.outerHeight();
-
-                       // Measure max rows height
-                       this.$clone
-                               .attr( 'rows', this.maxRows )
-                               .css( 'height', 'auto' )
-                               .val( '' );
-                       maxInnerHeight = this.$clone.innerHeight();
-
-                       // Difference between reported innerHeight and scrollHeight with no scrollbars present
-                       // Equals 1 on Blink-based browsers and 0 everywhere else
-                       measurementError = maxInnerHeight - this.$clone[ 0 ].scrollHeight;
-                       idealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );
-
-                       this.$clone.addClass( 'oo-ui-element-hidden' );
-
-                       // Only apply inline height when expansion beyond natural height is needed
-                       // Use the difference between the inner and outer height as a buffer
-                       newHeight = idealHeight > innerHeight ? idealHeight + ( outerHeight - innerHeight ) : '';
-                       if ( newHeight !== this.styleHeight ) {
-                               this.$input.css( 'height', newHeight );
-                               this.styleHeight = newHeight;
-                               this.emit( 'resize' );
-                       }
-               }
-               scrollWidth = this.$input[ 0 ].offsetWidth - this.$input[ 0 ].clientWidth;
-               if ( scrollWidth !== this.scrollWidth ) {
-                       property = this.$element.css( 'direction' ) === 'rtl' ? 'left' : 'right';
-                       // Reset
-                       this.$label.css( { right: '', left: '' } );
-                       this.$indicator.css( { right: '', left: '' } );
-
-                       if ( scrollWidth ) {
-                               this.$indicator.css( property, scrollWidth );
-                               if ( this.labelPosition === 'after' ) {
-                                       this.$label.css( property, scrollWidth );
-                               }
-                       }
-
-                       this.scrollWidth = scrollWidth;
-                       this.positionLabel();
-               }
-       }
-       return this;
-};
-
-/**
- * @inheritdoc
- * @protected
- */
-OO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {
-       return config.multiline ?
-               $( '<textarea>' ) :
-               $( '<input type="' + this.getSaneType( config ) + '" />' );
-};
-
-/**
- * Get sanitized value for 'type' for given config.
- *
- * @param {Object} config Configuration options
- * @return {string|null}
- * @private
- */
-OO.ui.TextInputWidget.prototype.getSaneType = function ( config ) {
-       var type = [ 'text', 'password', 'search', 'email', 'url' ].indexOf( config.type ) !== -1 ?
-               config.type :
-               'text';
-       return config.multiline ? 'multiline' : type;
-};
-
-/**
- * Check if the input supports multiple lines.
- *
- * @return {boolean}
- */
-OO.ui.TextInputWidget.prototype.isMultiline = function () {
-       return !!this.multiline;
-};
-
-/**
- * Check if the input automatically adjusts its size.
- *
- * @return {boolean}
- */
-OO.ui.TextInputWidget.prototype.isAutosizing = function () {
-       return !!this.autosize;
-};
-
-/**
- * Focus the input and select a specified range within the text.
- *
- * @param {number} from Select from offset
- * @param {number} [to] Select to offset, defaults to from
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.selectRange = function ( from, to ) {
-       var isBackwards, start, end,
-               input = this.$input[ 0 ];
-
-       to = to || from;
-
-       isBackwards = to < from;
-       start = isBackwards ? to : from;
-       end = isBackwards ? from : to;
-
-       this.focus();
-
-       input.setSelectionRange( start, end, isBackwards ? 'backward' : 'forward' );
-       return this;
-};
-
-/**
- * Get an object describing the current selection range in a directional manner
- *
- * @return {Object} Object containing 'from' and 'to' offsets
- */
-OO.ui.TextInputWidget.prototype.getRange = function () {
-       var input = this.$input[ 0 ],
-               start = input.selectionStart,
-               end = input.selectionEnd,
-               isBackwards = input.selectionDirection === 'backward';
-
-       return {
-               from: isBackwards ? end : start,
-               to: isBackwards ? start : end
-       };
-};
-
-/**
- * Get the length of the text input value.
- *
- * This could differ from the length of #getValue if the
- * value gets filtered
- *
- * @return {number} Input length
- */
-OO.ui.TextInputWidget.prototype.getInputLength = function () {
-       return this.$input[ 0 ].value.length;
-};
-
-/**
- * Focus the input and select the entire text.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.select = function () {
-       return this.selectRange( 0, this.getInputLength() );
-};
-
-/**
- * Focus the input and move the cursor to the start.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.moveCursorToStart = function () {
-       return this.selectRange( 0 );
-};
-
-/**
- * Focus the input and move the cursor to the end.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.moveCursorToEnd = function () {
-       return this.selectRange( this.getInputLength() );
-};
-
-/**
- * Insert new content into the input.
- *
- * @param {string} content Content to be inserted
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.insertContent = function ( content ) {
-       var start, end,
-               range = this.getRange(),
-               value = this.getValue();
-
-       start = Math.min( range.from, range.to );
-       end = Math.max( range.from, range.to );
-
-       this.setValue( value.slice( 0, start ) + content + value.slice( end ) );
-       this.selectRange( start + content.length );
-       return this;
-};
-
-/**
- * Insert new content either side of a selection.
- *
- * @param {string} pre Content to be inserted before the selection
- * @param {string} post Content to be inserted after the selection
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.encapsulateContent = function ( pre, post ) {
-       var start, end,
-               range = this.getRange(),
-               offset = pre.length;
-
-       start = Math.min( range.from, range.to );
-       end = Math.max( range.from, range.to );
-
-       this.selectRange( start ).insertContent( pre );
-       this.selectRange( offset + end ).insertContent( post );
-
-       this.selectRange( offset + start, offset + end );
-       return this;
-};
-
-/**
- * Set the validation pattern.
- *
- * The validation pattern is either a regular expression, a function, or the symbolic name of a
- * pattern defined by the class: 'non-empty' (the value cannot be an empty string) or 'integer' (the
- * value must contain only numbers).
- *
- * @param {RegExp|Function|string|null} validate Regular expression, function, or the symbolic name
- *  of a pattern (either ‘integer’ or ‘non-empty’) defined by the class.
- */
-OO.ui.TextInputWidget.prototype.setValidation = function ( validate ) {
-       if ( validate instanceof RegExp || validate instanceof Function ) {
-               this.validate = validate;
-       } else {
-               this.validate = this.constructor.static.validationPatterns[ validate ] || /.*/;
-       }
-};
-
-/**
- * Sets the 'invalid' flag appropriately.
- *
- * @param {boolean} [isValid] Optionally override validation result
- */
-OO.ui.TextInputWidget.prototype.setValidityFlag = function ( isValid ) {
-       var widget = this,
-               setFlag = function ( valid ) {
-                       if ( !valid ) {
-                               widget.$input.attr( 'aria-invalid', 'true' );
-                       } else {
-                               widget.$input.removeAttr( 'aria-invalid' );
-                       }
-                       widget.setFlags( { invalid: !valid } );
-               };
-
-       if ( isValid !== undefined ) {
-               setFlag( isValid );
-       } else {
-               this.getValidity().then( function () {
-                       setFlag( true );
-               }, function () {
-                       setFlag( false );
-               } );
-       }
-};
-
-/**
- * Check if a value is valid.
- *
- * This method returns a promise that resolves with a boolean `true` if the current value is
- * considered valid according to the supplied {@link #validate validation pattern}.
- *
- * @deprecated
- * @return {jQuery.Promise} A promise that resolves to a boolean `true` if the value is valid.
- */
-OO.ui.TextInputWidget.prototype.isValid = function () {
-       var result;
-
-       if ( this.validate instanceof Function ) {
-               result = this.validate( this.getValue() );
-               if ( result && $.isFunction( result.promise ) ) {
-                       return result.promise();
-               } else {
-                       return $.Deferred().resolve( !!result ).promise();
-               }
-       } else {
-               return $.Deferred().resolve( !!this.getValue().match( this.validate ) ).promise();
-       }
-};
-
-/**
- * Get the validity of current value.
- *
- * This method returns a promise that resolves if the value is valid and rejects if
- * it isn't. Uses the {@link #validate validation pattern}  to check for validity.
- *
- * @return {jQuery.Promise} A promise that resolves if the value is valid, rejects if not.
- */
-OO.ui.TextInputWidget.prototype.getValidity = function () {
-       var result;
-
-       function rejectOrResolve( valid ) {
-               if ( valid ) {
-                       return $.Deferred().resolve().promise();
-               } else {
-                       return $.Deferred().reject().promise();
-               }
-       }
-
-       if ( this.validate instanceof Function ) {
-               result = this.validate( this.getValue() );
-               if ( result && $.isFunction( result.promise ) ) {
-                       return result.promise().then( function ( valid ) {
-                               return rejectOrResolve( valid );
-                       } );
-               } else {
-                       return rejectOrResolve( result );
-               }
-       } else {
-               return rejectOrResolve( this.getValue().match( this.validate ) );
-       }
-};
-
-/**
- * Set the position of the inline label relative to that of the value: `‘before’` or `‘after’`.
- *
- * @param {string} labelPosition Label position, 'before' or 'after'
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.setLabelPosition = function ( labelPosition ) {
-       this.labelPosition = labelPosition;
-       this.updatePosition();
-       return this;
-};
-
-/**
- * Update the position of the inline label.
- *
- * This method is called by #setLabelPosition, and can also be called on its own if
- * something causes the label to be mispositioned.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.updatePosition = function () {
-       var after = this.labelPosition === 'after';
-
-       this.$element
-               .toggleClass( 'oo-ui-textInputWidget-labelPosition-after', !!this.label && after )
-               .toggleClass( 'oo-ui-textInputWidget-labelPosition-before', !!this.label && !after );
-
-       this.valCache = null;
-       this.scrollWidth = null;
-       this.adjustSize();
-       this.positionLabel();
-
-       return this;
-};
-
-/**
- * Update the 'clear' indicator displayed on type: 'search' text fields, hiding it when the field is
- * already empty or when it's not editable.
- */
-OO.ui.TextInputWidget.prototype.updateSearchIndicator = function () {
-       if ( this.type === 'search' ) {
-               if ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {
-                       this.setIndicator( null );
-               } else {
-                       this.setIndicator( 'clear' );
-               }
-       }
-};
-
-/**
- * Position the label by setting the correct padding on the input.
- *
- * @private
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.positionLabel = function () {
-       var after, rtl, property;
-       // Clear old values
-       this.$input
-               // Clear old values if present
-               .css( {
-                       'padding-right': '',
-                       'padding-left': ''
-               } );
-
-       if ( this.label ) {
-               this.$element.append( this.$label );
-       } else {
-               this.$label.detach();
-               return;
-       }
-
-       after = this.labelPosition === 'after';
-       rtl = this.$element.css( 'direction' ) === 'rtl';
-       property = after === rtl ? 'padding-left' : 'padding-right';
-
-       this.$input.css( property, this.$label.outerWidth( true ) + ( after ? this.scrollWidth : 0 ) );
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.TextInputWidget.prototype.restorePreInfuseState = function ( state ) {
-       OO.ui.TextInputWidget.parent.prototype.restorePreInfuseState.call( this, state );
-       if ( state.scrollTop !== undefined ) {
-               this.$input.scrollTop( state.scrollTop );
-       }
-};
-
-/**
- * ComboBoxInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value
- * can be entered manually) and a {@link OO.ui.MenuSelectWidget menu of options} (from which
- * a value can be chosen instead). Users can choose options from the combo box in one of two ways:
- *
- * - by typing a value in the text input field. If the value exactly matches the value of a menu
- *   option, that option will appear to be selected.
- * - by choosing a value from the menu. The value of the chosen option will then appear in the text
- *   input field.
- *
- * This widget can be used inside a HTML form, such as a OO.ui.FormLayout.
- *
- * For more information about menus and options, please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example: A ComboBoxInputWidget.
- *     var comboBox = new OO.ui.ComboBoxInputWidget( {
- *         label: 'ComboBoxInputWidget',
- *         value: 'Option 1',
- *         menu: {
- *             items: [
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 1',
- *                     label: 'Option One'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 2',
- *                     label: 'Option Two'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 3',
- *                     label: 'Option Three'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 4',
- *                     label: 'Option Four'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'Option 5',
- *                     label: 'Option Five'
- *                 } )
- *             ]
- *         }
- *     } );
- *     $( 'body' ).append( comboBox.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
- *
- * @class
- * @extends OO.ui.TextInputWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
- * @cfg {Object} [menu] Configuration options to pass to the {@link OO.ui.FloatingMenuSelectWidget menu select widget}.
- * @cfg {jQuery} [$overlay] Render the menu into a separate layer. This configuration is useful in cases where
- *  the expanded menu is larger than its containing `<div>`. The specified overlay layer is usually on top of the
- *  containing `<div>` and has a larger area. By default, the menu uses relative positioning.
- */
-OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
-       // Configuration initialization
-       config = $.extend( {
-               indicator: 'down'
-       }, config );
-       // For backwards-compatibility with ComboBoxWidget config
-       $.extend( config, config.input );
-
-       // Parent constructor
-       OO.ui.ComboBoxInputWidget.parent.call( this, config );
-
-       // Properties
-       this.$overlay = config.$overlay || this.$element;
-       this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
-               {
-                       widget: this,
-                       input: this,
-                       $container: this.$element,
-                       disabled: this.isDisabled()
-               },
-               config.menu
-       ) );
-       // For backwards-compatibility with ComboBoxWidget
-       this.input = this;
-
-       // Events
-       this.$indicator.on( {
-               click: this.onIndicatorClick.bind( this ),
-               keypress: this.onIndicatorKeyPress.bind( this )
-       } );
-       this.connect( this, {
-               change: 'onInputChange',
-               enter: 'onInputEnter'
-       } );
-       this.menu.connect( this, {
-               choose: 'onMenuChoose',
-               add: 'onMenuItemsChange',
-               remove: 'onMenuItemsChange'
-       } );
-
-       // Initialization
-       this.$input.attr( {
-               role: 'combobox',
-               'aria-autocomplete': 'list'
-       } );
-       // Do not override options set via config.menu.items
-       if ( config.options !== undefined ) {
-               this.setOptions( config.options );
-       }
-       // Extra class for backwards-compatibility with ComboBoxWidget
-       this.$element.addClass( 'oo-ui-comboBoxInputWidget oo-ui-comboBoxWidget' );
-       this.$overlay.append( this.menu.$element );
-       this.onMenuItemsChange();
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ComboBoxInputWidget, OO.ui.TextInputWidget );
-
-/* Methods */
-
-/**
- * Get the combobox's menu.
- * @return {OO.ui.FloatingMenuSelectWidget} Menu widget
- */
-OO.ui.ComboBoxInputWidget.prototype.getMenu = function () {
-       return this.menu;
-};
-
-/**
- * Get the combobox's text input widget.
- * @return {OO.ui.TextInputWidget} Text input widget
- */
-OO.ui.ComboBoxInputWidget.prototype.getInput = function () {
-       return this;
-};
-
-/**
- * Handle input change events.
- *
- * @private
- * @param {string} value New value
- */
-OO.ui.ComboBoxInputWidget.prototype.onInputChange = function ( value ) {
-       var match = this.menu.getItemFromData( value );
-
-       this.menu.selectItem( match );
-       if ( this.menu.getHighlightedItem() ) {
-               this.menu.highlightItem( match );
-       }
-
-       if ( !this.isDisabled() ) {
-               this.menu.toggle( true );
-       }
-};
-
-/**
- * Handle mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.ComboBoxInputWidget.prototype.onIndicatorClick = function ( e ) {
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               this.menu.toggle();
-               this.$input[ 0 ].focus();
-       }
-       return false;
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.ComboBoxInputWidget.prototype.onIndicatorKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               this.menu.toggle();
-               this.$input[ 0 ].focus();
-               return false;
-       }
-};
-
-/**
- * Handle input enter events.
- *
- * @private
- */
-OO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {
-       if ( !this.isDisabled() ) {
-               this.menu.toggle( false );
-       }
-};
-
-/**
- * Handle menu choose events.
- *
- * @private
- * @param {OO.ui.OptionWidget} item Chosen item
- */
-OO.ui.ComboBoxInputWidget.prototype.onMenuChoose = function ( item ) {
-       this.setValue( item.getData() );
-};
-
-/**
- * Handle menu item change events.
- *
- * @private
- */
-OO.ui.ComboBoxInputWidget.prototype.onMenuItemsChange = function () {
-       var match = this.menu.getItemFromData( this.getValue() );
-       this.menu.selectItem( match );
-       if ( this.menu.getHighlightedItem() ) {
-               this.menu.highlightItem( match );
-       }
-       this.$element.toggleClass( 'oo-ui-comboBoxInputWidget-empty', this.menu.isEmpty() );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.ComboBoxInputWidget.prototype.setDisabled = function ( disabled ) {
-       // Parent method
-       OO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.call( this, disabled );
-
-       if ( this.menu ) {
-               this.menu.setDisabled( this.isDisabled() );
-       }
-
-       return this;
-};
-
-/**
- * Set the options available for this input.
- *
- * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`
- * @chainable
- */
-OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
-       this.getMenu()
-               .clearItems()
-               .addItems( options.map( function ( opt ) {
-                       return new OO.ui.MenuOptionWidget( {
-                               data: opt.data,
-                               label: opt.label !== undefined ? opt.label : opt.data
-                       } );
-               } ) );
-
-       return this;
-};
-
-/**
- * @class
- * @deprecated Use OO.ui.ComboBoxInputWidget instead.
- */
-OO.ui.ComboBoxWidget = OO.ui.ComboBoxInputWidget;
-
-/**
- * LabelWidgets help identify the function of interface elements. Each LabelWidget can
- * be configured with a `label` option that is set to a string, a label node, or a function:
- *
- * - String: a plaintext string
- * - jQuery selection: a jQuery selection, used for anything other than a plaintext label, e.g., a
- *   label that includes a link or special styling, such as a gray color or additional graphical elements.
- * - Function: a function that will produce a string in the future. Functions are used
- *   in cases where the value of the label is not currently defined.
- *
- * In addition, the LabelWidget can be associated with an {@link OO.ui.InputWidget input widget}, which
- * will come into focus when the label is clicked.
- *
- *     @example
- *     // Examples of LabelWidgets
- *     var label1 = new OO.ui.LabelWidget( {
- *         label: 'plaintext label'
- *     } );
- *     var label2 = new OO.ui.LabelWidget( {
- *         label: $( '<a href="default.html">jQuery label</a>' )
- *     } );
- *     // Create a fieldset layout with fields for each example
- *     var fieldset = new OO.ui.FieldsetLayout();
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( label1 ),
- *         new OO.ui.FieldLayout( label2 )
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.LabelElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.InputWidget} [input] {@link OO.ui.InputWidget Input widget} that uses the label.
- *  Clicking the label will focus the specified input field.
- */
-OO.ui.LabelWidget = function OoUiLabelWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.LabelWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { $label: this.$element } ) );
-       OO.ui.mixin.TitledElement.call( this, config );
-
-       // Properties
-       this.input = config.input;
-
-       // Events
-       if ( this.input instanceof OO.ui.InputWidget ) {
-               this.$element.on( 'click', this.onClick.bind( this ) );
-       }
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-labelWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.LabelWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.LabelWidget, OO.ui.mixin.TitledElement );
-
-/* Static Properties */
-
-OO.ui.LabelWidget.static.tagName = 'span';
-
-/* Methods */
-
-/**
- * Handles label mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.LabelWidget.prototype.onClick = function () {
-       this.input.simulateLabelClick();
-       return false;
-};
-
-/**
- * OptionWidgets are special elements that can be selected and configured with data. The
- * data is often unique for each option, but it does not have to be. OptionWidgets are used
- * with OO.ui.SelectWidget to create a selection of mutually exclusive options. For more information
- * and examples, please see the [OOjs UI documentation on MediaWiki][1].
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.FlaggedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.OptionWidget = function OoUiOptionWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.OptionWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ItemWidget.call( this );
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.FlaggedElement.call( this, config );
-
-       // Properties
-       this.selected = false;
-       this.highlighted = false;
-       this.pressed = false;
-
-       // Initialization
-       this.$element
-               .data( 'oo-ui-optionWidget', this )
-               .attr( 'role', 'option' )
-               .attr( 'aria-selected', 'false' )
-               .addClass( 'oo-ui-optionWidget' )
-               .append( this.$label );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.ItemWidget );
-OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.OptionWidget, OO.ui.mixin.FlaggedElement );
-
-/* Static Properties */
-
-OO.ui.OptionWidget.static.selectable = true;
-
-OO.ui.OptionWidget.static.highlightable = true;
-
-OO.ui.OptionWidget.static.pressable = true;
-
-OO.ui.OptionWidget.static.scrollIntoViewOnSelect = false;
-
-/* Methods */
-
-/**
- * Check if the option can be selected.
- *
- * @return {boolean} Item is selectable
- */
-OO.ui.OptionWidget.prototype.isSelectable = function () {
-       return this.constructor.static.selectable && !this.isDisabled() && this.isVisible();
-};
-
-/**
- * Check if the option can be highlighted. A highlight indicates that the option
- * may be selected when a user presses enter or clicks. Disabled items cannot
- * be highlighted.
- *
- * @return {boolean} Item is highlightable
- */
-OO.ui.OptionWidget.prototype.isHighlightable = function () {
-       return this.constructor.static.highlightable && !this.isDisabled() && this.isVisible();
-};
-
-/**
- * Check if the option can be pressed. The pressed state occurs when a user mouses
- * down on an item, but has not yet let go of the mouse.
- *
- * @return {boolean} Item is pressable
- */
-OO.ui.OptionWidget.prototype.isPressable = function () {
-       return this.constructor.static.pressable && !this.isDisabled() && this.isVisible();
-};
-
-/**
- * Check if the option is selected.
- *
- * @return {boolean} Item is selected
- */
-OO.ui.OptionWidget.prototype.isSelected = function () {
-       return this.selected;
-};
-
-/**
- * Check if the option is highlighted. A highlight indicates that the
- * item may be selected when a user presses enter or clicks.
- *
- * @return {boolean} Item is highlighted
- */
-OO.ui.OptionWidget.prototype.isHighlighted = function () {
-       return this.highlighted;
-};
-
-/**
- * Check if the option is pressed. The pressed state occurs when a user mouses
- * down on an item, but has not yet let go of the mouse. The item may appear
- * selected, but it will not be selected until the user releases the mouse.
- *
- * @return {boolean} Item is pressed
- */
-OO.ui.OptionWidget.prototype.isPressed = function () {
-       return this.pressed;
-};
-
-/**
- * Set the option’s selected state. In general, all modifications to the selection
- * should be handled by the SelectWidget’s {@link OO.ui.SelectWidget#selectItem selectItem( [item] )}
- * method instead of this method.
- *
- * @param {boolean} [state=false] Select option
- * @chainable
- */
-OO.ui.OptionWidget.prototype.setSelected = function ( state ) {
-       if ( this.constructor.static.selectable ) {
-               this.selected = !!state;
-               this.$element
-                       .toggleClass( 'oo-ui-optionWidget-selected', state )
-                       .attr( 'aria-selected', state.toString() );
-               if ( state && this.constructor.static.scrollIntoViewOnSelect ) {
-                       this.scrollElementIntoView();
-               }
-               this.updateThemeClasses();
-       }
-       return this;
-};
-
-/**
- * Set the option’s highlighted state. In general, all programmatic
- * modifications to the highlight should be handled by the
- * SelectWidget’s {@link OO.ui.SelectWidget#highlightItem highlightItem( [item] )}
- * method instead of this method.
- *
- * @param {boolean} [state=false] Highlight option
- * @chainable
- */
-OO.ui.OptionWidget.prototype.setHighlighted = function ( state ) {
-       if ( this.constructor.static.highlightable ) {
-               this.highlighted = !!state;
-               this.$element.toggleClass( 'oo-ui-optionWidget-highlighted', state );
-               this.updateThemeClasses();
-       }
-       return this;
-};
-
-/**
- * Set the option’s pressed state. In general, all
- * programmatic modifications to the pressed state should be handled by the
- * SelectWidget’s {@link OO.ui.SelectWidget#pressItem pressItem( [item] )}
- * method instead of this method.
- *
- * @param {boolean} [state=false] Press option
- * @chainable
- */
-OO.ui.OptionWidget.prototype.setPressed = function ( state ) {
-       if ( this.constructor.static.pressable ) {
-               this.pressed = !!state;
-               this.$element.toggleClass( 'oo-ui-optionWidget-pressed', state );
-               this.updateThemeClasses();
-       }
-       return this;
-};
-
-/**
- * DecoratedOptionWidgets are {@link OO.ui.OptionWidget options} that can be configured
- * with an {@link OO.ui.mixin.IconElement icon} and/or {@link OO.ui.mixin.IndicatorElement indicator}.
- * This class is used with OO.ui.SelectWidget to create a selection of mutually exclusive
- * options. For more information about options and selects, please see the
- * [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Decorated options in a select widget
- *     var select = new OO.ui.SelectWidget( {
- *         items: [
- *             new OO.ui.DecoratedOptionWidget( {
- *                 data: 'a',
- *                 label: 'Option with icon',
- *                 icon: 'help'
- *             } ),
- *             new OO.ui.DecoratedOptionWidget( {
- *                 data: 'b',
- *                 label: 'Option with indicator',
- *                 indicator: 'next'
- *             } )
- *         ]
- *     } );
- *     $( 'body' ).append( select.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- *
- * @class
- * @extends OO.ui.OptionWidget
- * @mixins OO.ui.mixin.IconElement
- * @mixins OO.ui.mixin.IndicatorElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.DecoratedOptionWidget = function OoUiDecoratedOptionWidget( config ) {
-       // Parent constructor
-       OO.ui.DecoratedOptionWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.IconElement.call( this, config );
-       OO.ui.mixin.IndicatorElement.call( this, config );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-decoratedOptionWidget' )
-               .prepend( this.$icon )
-               .append( this.$indicator );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.DecoratedOptionWidget, OO.ui.OptionWidget );
-OO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IconElement );
-OO.mixinClass( OO.ui.DecoratedOptionWidget, OO.ui.mixin.IndicatorElement );
-
-/**
- * ButtonOptionWidget is a special type of {@link OO.ui.mixin.ButtonElement button element} that
- * can be selected and configured with data. The class is
- * used with OO.ui.ButtonSelectWidget to create a selection of button options. Please see the
- * [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Button_selects_and_options
- *
- * @class
- * @extends OO.ui.DecoratedOptionWidget
- * @mixins OO.ui.mixin.ButtonElement
- * @mixins OO.ui.mixin.TabIndexedElement
- * @mixins OO.ui.mixin.TitledElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.ButtonOptionWidget = function OoUiButtonOptionWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ButtonOptionWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ButtonElement.call( this, config );
-       OO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );
-       OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, {
-               $tabIndexed: this.$button,
-               tabIndex: -1
-       } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-buttonOptionWidget' );
-       this.$button.append( this.$element.contents() );
-       this.$element.append( this.$button );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ButtonOptionWidget, OO.ui.DecoratedOptionWidget );
-OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.ButtonElement );
-OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TitledElement );
-OO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TabIndexedElement );
-
-/* Static Properties */
-
-// Allow button mouse down events to pass through so they can be handled by the parent select widget
-OO.ui.ButtonOptionWidget.static.cancelButtonMouseDownEvents = false;
-
-OO.ui.ButtonOptionWidget.static.highlightable = false;
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.ButtonOptionWidget.prototype.setSelected = function ( state ) {
-       OO.ui.ButtonOptionWidget.parent.prototype.setSelected.call( this, state );
-
-       if ( this.constructor.static.selectable ) {
-               this.setActive( state );
-       }
-
-       return this;
-};
-
-/**
- * RadioOptionWidget is an option widget that looks like a radio button.
- * The class is used with OO.ui.RadioSelectWidget to create a selection of radio options.
- * Please see the [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Button_selects_and_option
- *
- * @class
- * @extends OO.ui.OptionWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.RadioOptionWidget = function OoUiRadioOptionWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Properties (must be done before parent constructor which calls #setDisabled)
-       this.radio = new OO.ui.RadioInputWidget( { value: config.data, tabIndex: -1 } );
-
-       // Parent constructor
-       OO.ui.RadioOptionWidget.parent.call( this, config );
-
-       // Events
-       this.radio.$input.on( 'focus', this.onInputFocus.bind( this ) );
-
-       // Initialization
-       // Remove implicit role, we're handling it ourselves
-       this.radio.$input.attr( 'role', 'presentation' );
-       this.$element
-               .addClass( 'oo-ui-radioOptionWidget' )
-               .attr( 'role', 'radio' )
-               .attr( 'aria-checked', 'false' )
-               .removeAttr( 'aria-selected' )
-               .prepend( this.radio.$element );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.RadioOptionWidget, OO.ui.OptionWidget );
-
-/* Static Properties */
-
-OO.ui.RadioOptionWidget.static.highlightable = false;
-
-OO.ui.RadioOptionWidget.static.scrollIntoViewOnSelect = true;
-
-OO.ui.RadioOptionWidget.static.pressable = false;
-
-OO.ui.RadioOptionWidget.static.tagName = 'label';
-
-/* Methods */
-
-/**
- * @param {jQuery.Event} e Focus event
- * @private
- */
-OO.ui.RadioOptionWidget.prototype.onInputFocus = function () {
-       this.radio.$input.blur();
-       this.$element.parent().focus();
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioOptionWidget.prototype.setSelected = function ( state ) {
-       OO.ui.RadioOptionWidget.parent.prototype.setSelected.call( this, state );
-
-       this.radio.setSelected( state );
-       this.$element
-               .attr( 'aria-checked', state.toString() )
-               .removeAttr( 'aria-selected' );
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.RadioOptionWidget.prototype.setDisabled = function ( disabled ) {
-       OO.ui.RadioOptionWidget.parent.prototype.setDisabled.call( this, disabled );
-
-       this.radio.setDisabled( this.isDisabled() );
-
-       return this;
-};
-
-/**
- * MenuOptionWidget is an option widget that looks like a menu item. The class is used with
- * OO.ui.MenuSelectWidget to create a menu of mutually exclusive options. Please see
- * the [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options#Menu_selects_and_options
- *
- * @class
- * @extends OO.ui.DecoratedOptionWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.MenuOptionWidget = function OoUiMenuOptionWidget( config ) {
-       // Configuration initialization
-       config = $.extend( { icon: 'check' }, config );
-
-       // Parent constructor
-       OO.ui.MenuOptionWidget.parent.call( this, config );
-
-       // Initialization
-       this.$element
-               .attr( 'role', 'menuitem' )
-               .addClass( 'oo-ui-menuOptionWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );
-
-/* Static Properties */
-
-OO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;
-
-/**
- * MenuSectionOptionWidgets are used inside {@link OO.ui.MenuSelectWidget menu select widgets} to group one or more related
- * {@link OO.ui.MenuOptionWidget menu options}. MenuSectionOptionWidgets cannot be highlighted or selected.
- *
- *     @example
- *     var myDropdown = new OO.ui.DropdownWidget( {
- *         menu: {
- *             items: [
- *                 new OO.ui.MenuSectionOptionWidget( {
- *                     label: 'Dogs'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'corgi',
- *                     label: 'Welsh Corgi'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'poodle',
- *                     label: 'Standard Poodle'
- *                 } ),
- *                 new OO.ui.MenuSectionOptionWidget( {
- *                     label: 'Cats'
- *                 } ),
- *                 new OO.ui.MenuOptionWidget( {
- *                     data: 'lion',
- *                     label: 'Lion'
- *                 } )
- *             ]
- *         }
- *     } );
- *     $( 'body' ).append( myDropdown.$element );
- *
- * @class
- * @extends OO.ui.DecoratedOptionWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.MenuSectionOptionWidget = function OoUiMenuSectionOptionWidget( config ) {
-       // Parent constructor
-       OO.ui.MenuSectionOptionWidget.parent.call( this, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-menuSectionOptionWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuSectionOptionWidget, OO.ui.DecoratedOptionWidget );
-
-/* Static Properties */
-
-OO.ui.MenuSectionOptionWidget.static.selectable = false;
-
-OO.ui.MenuSectionOptionWidget.static.highlightable = false;
-
-/**
- * OutlineOptionWidget is an item in an {@link OO.ui.OutlineSelectWidget OutlineSelectWidget}.
- *
- * Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}, which contain
- * {@link OO.ui.PageLayout page layouts}. See {@link OO.ui.BookletLayout BookletLayout}
- * for an example.
- *
- * @class
- * @extends OO.ui.DecoratedOptionWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {number} [level] Indentation level
- * @cfg {boolean} [movable] Allow modification from {@link OO.ui.OutlineControlsWidget outline controls}.
- */
-OO.ui.OutlineOptionWidget = function OoUiOutlineOptionWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.OutlineOptionWidget.parent.call( this, config );
-
-       // Properties
-       this.level = 0;
-       this.movable = !!config.movable;
-       this.removable = !!config.removable;
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-outlineOptionWidget' );
-       this.setLevel( config.level );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.OutlineOptionWidget, OO.ui.DecoratedOptionWidget );
-
-/* Static Properties */
-
-OO.ui.OutlineOptionWidget.static.highlightable = false;
-
-OO.ui.OutlineOptionWidget.static.scrollIntoViewOnSelect = true;
-
-OO.ui.OutlineOptionWidget.static.levelClass = 'oo-ui-outlineOptionWidget-level-';
-
-OO.ui.OutlineOptionWidget.static.levels = 3;
-
-/* Methods */
-
-/**
- * Check if item is movable.
- *
- * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
- *
- * @return {boolean} Item is movable
- */
-OO.ui.OutlineOptionWidget.prototype.isMovable = function () {
-       return this.movable;
-};
-
-/**
- * Check if item is removable.
- *
- * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
- *
- * @return {boolean} Item is removable
- */
-OO.ui.OutlineOptionWidget.prototype.isRemovable = function () {
-       return this.removable;
-};
-
-/**
- * Get indentation level.
- *
- * @return {number} Indentation level
- */
-OO.ui.OutlineOptionWidget.prototype.getLevel = function () {
-       return this.level;
-};
-
-/**
- * Set movability.
- *
- * Movability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
- *
- * @param {boolean} movable Item is movable
- * @chainable
- */
-OO.ui.OutlineOptionWidget.prototype.setMovable = function ( movable ) {
-       this.movable = !!movable;
-       this.updateThemeClasses();
-       return this;
-};
-
-/**
- * Set removability.
- *
- * Removability is used by {@link OO.ui.OutlineControlsWidget outline controls}.
- *
- * @param {boolean} removable Item is removable
- * @chainable
- */
-OO.ui.OutlineOptionWidget.prototype.setRemovable = function ( removable ) {
-       this.removable = !!removable;
-       this.updateThemeClasses();
-       return this;
-};
-
-/**
- * Set indentation level.
- *
- * @param {number} [level=0] Indentation level, in the range of [0,#maxLevel]
- * @chainable
- */
-OO.ui.OutlineOptionWidget.prototype.setLevel = function ( level ) {
-       var levels = this.constructor.static.levels,
-               levelClass = this.constructor.static.levelClass,
-               i = levels;
-
-       this.level = level ? Math.max( 0, Math.min( levels - 1, level ) ) : 0;
-       while ( i-- ) {
-               if ( this.level === i ) {
-                       this.$element.addClass( levelClass + i );
-               } else {
-                       this.$element.removeClass( levelClass + i );
-               }
-       }
-       this.updateThemeClasses();
-
-       return this;
-};
-
-/**
- * TabOptionWidget is an item in a {@link OO.ui.TabSelectWidget TabSelectWidget}.
- *
- * Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}, which contain
- * {@link OO.ui.CardLayout card layouts}. See {@link OO.ui.IndexLayout IndexLayout}
- * for an example.
- *
- * @class
- * @extends OO.ui.OptionWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.TabOptionWidget.parent.call( this, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-tabOptionWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.TabOptionWidget, OO.ui.OptionWidget );
-
-/* Static Properties */
-
-OO.ui.TabOptionWidget.static.highlightable = false;
-
-/**
- * PopupWidget is a container for content. The popup is overlaid and positioned absolutely.
- * By default, each popup has an anchor that points toward its origin.
- * Please see the [OOjs UI documentation on Mediawiki] [1] for more information and examples.
- *
- *     @example
- *     // A popup widget.
- *     var popup = new OO.ui.PopupWidget( {
- *         $content: $( '<p>Hi there!</p>' ),
- *         padded: true,
- *         width: 300
- *     } );
- *
- *     $( 'body' ).append( popup.$element );
- *     // To display the popup, toggle the visibility to 'true'.
- *     popup.toggle( true );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups
- *
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.LabelElement
- * @mixins OO.ui.mixin.ClippableElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {number} [width=320] Width of popup in pixels
- * @cfg {number} [height] Height of popup in pixels. Omit to use the automatic height.
- * @cfg {boolean} [anchor=true] Show anchor pointing to origin of popup
- * @cfg {string} [align='center'] Alignment of the popup: `center`, `force-left`, `force-right`, `backwards` or `forwards`.
- *  If the popup is forced-left the popup body is leaning towards the left. For force-right alignment, the body of the
- *  popup is leaning towards the right of the screen.
- *  Using 'backwards' is a logical direction which will result in the popup leaning towards the beginning of the sentence
- *  in the given language, which means it will flip to the correct positioning in right-to-left languages.
- *  Using 'forward' will also result in a logical alignment where the body of the popup leans towards the end of the
- *  sentence in the given language.
- * @cfg {jQuery} [$container] Constrain the popup to the boundaries of the specified container.
- *  See the [OOjs UI docs on MediaWiki][3] for an example.
- *  [3]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups#containerExample
- * @cfg {number} [containerPadding=10] Padding between the popup and its container, specified as a number of pixels.
- * @cfg {jQuery} [$content] Content to append to the popup's body
- * @cfg {jQuery} [$footer] Content to append to the popup's footer
- * @cfg {boolean} [autoClose=false] Automatically close the popup when it loses focus.
- * @cfg {jQuery} [$autoCloseIgnore] Elements that will not close the popup when clicked.
- *  This config option is only relevant if #autoClose is set to `true`. See the [OOjs UI docs on MediaWiki][2]
- *  for an example.
- *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Popups#autocloseExample
- * @cfg {boolean} [head] Show a popup header that contains a #label (if specified) and close
- *  button.
- * @cfg {boolean} [padded] Add padding to the popup's body
- */
-OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.PopupWidget.parent.call( this, config );
-
-       // Properties (must be set before ClippableElement constructor call)
-       this.$body = $( '<div>' );
-       this.$popup = $( '<div>' );
-
-       // Mixin constructors
-       OO.ui.mixin.LabelElement.call( this, config );
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, {
-               $clippable: this.$body,
-               $clippableContainer: this.$popup
-       } ) );
-
-       // Properties
-       this.$head = $( '<div>' );
-       this.$footer = $( '<div>' );
-       this.$anchor = $( '<div>' );
-       // If undefined, will be computed lazily in updateDimensions()
-       this.$container = config.$container;
-       this.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;
-       this.autoClose = !!config.autoClose;
-       this.$autoCloseIgnore = config.$autoCloseIgnore;
-       this.transitionTimeout = null;
-       this.anchor = null;
-       this.width = config.width !== undefined ? config.width : 320;
-       this.height = config.height !== undefined ? config.height : null;
-       this.setAlignment( config.align );
-       this.closeButton = new OO.ui.ButtonWidget( { framed: false, icon: 'close' } );
-       this.onMouseDownHandler = this.onMouseDown.bind( this );
-       this.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );
-
-       // Events
-       this.closeButton.connect( this, { click: 'onCloseButtonClick' } );
-
-       // Initialization
-       this.toggleAnchor( config.anchor === undefined || config.anchor );
-       this.$body.addClass( 'oo-ui-popupWidget-body' );
-       this.$anchor.addClass( 'oo-ui-popupWidget-anchor' );
-       this.$head
-               .addClass( 'oo-ui-popupWidget-head' )
-               .append( this.$label, this.closeButton.$element );
-       this.$footer.addClass( 'oo-ui-popupWidget-footer' );
-       if ( !config.head ) {
-               this.$head.addClass( 'oo-ui-element-hidden' );
-       }
-       if ( !config.$footer ) {
-               this.$footer.addClass( 'oo-ui-element-hidden' );
-       }
-       this.$popup
-               .addClass( 'oo-ui-popupWidget-popup' )
-               .append( this.$head, this.$body, this.$footer );
-       this.$element
-               .addClass( 'oo-ui-popupWidget' )
-               .append( this.$popup, this.$anchor );
-       // Move content, which was added to #$element by OO.ui.Widget, to the body
-       if ( config.$content instanceof jQuery ) {
-               this.$body.append( config.$content );
-       }
-       if ( config.$footer instanceof jQuery ) {
-               this.$footer.append( config.$footer );
-       }
-       if ( config.padded ) {
-               this.$body.addClass( 'oo-ui-popupWidget-body-padded' );
-       }
-
-       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
-       // that reference properties not initialized at that time of parent class construction
-       // TODO: Find a better way to handle post-constructor setup
-       this.visible = false;
-       this.$element.addClass( 'oo-ui-element-hidden' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.PopupWidget, OO.ui.Widget );
-OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement );
-OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement );
-
-/* Methods */
-
-/**
- * Handles mouse down events.
- *
- * @private
- * @param {MouseEvent} e Mouse down event
- */
-OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
-       if (
-               this.isVisible() &&
-               !$.contains( this.$element[ 0 ], e.target ) &&
-               ( !this.$autoCloseIgnore || !this.$autoCloseIgnore.has( e.target ).length )
-       ) {
-               this.toggle( false );
-       }
-};
-
-/**
- * Bind mouse down listener.
- *
- * @private
- */
-OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
-       // Capture clicks outside popup
-       this.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, true );
-};
-
-/**
- * Handles close button click events.
- *
- * @private
- */
-OO.ui.PopupWidget.prototype.onCloseButtonClick = function () {
-       if ( this.isVisible() ) {
-               this.toggle( false );
-       }
-};
-
-/**
- * Unbind mouse down listener.
- *
- * @private
- */
-OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
-       this.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );
-};
-
-/**
- * Handles key down events.
- *
- * @private
- * @param {KeyboardEvent} e Key down event
- */
-OO.ui.PopupWidget.prototype.onDocumentKeyDown = function ( e ) {
-       if (
-               e.which === OO.ui.Keys.ESCAPE &&
-               this.isVisible()
-       ) {
-               this.toggle( false );
-               e.preventDefault();
-               e.stopPropagation();
-       }
-};
-
-/**
- * Bind key down listener.
- *
- * @private
- */
-OO.ui.PopupWidget.prototype.bindKeyDownListener = function () {
-       this.getElementWindow().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
-};
-
-/**
- * Unbind key down listener.
- *
- * @private
- */
-OO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {
-       this.getElementWindow().removeEventListener( 'keydown', this.onDocumentKeyDownHandler, true );
-};
-
-/**
- * Show, hide, or toggle the visibility of the anchor.
- *
- * @param {boolean} [show] Show anchor, omit to toggle
- */
-OO.ui.PopupWidget.prototype.toggleAnchor = function ( show ) {
-       show = show === undefined ? !this.anchored : !!show;
-
-       if ( this.anchored !== show ) {
-               if ( show ) {
-                       this.$element.addClass( 'oo-ui-popupWidget-anchored' );
-               } else {
-                       this.$element.removeClass( 'oo-ui-popupWidget-anchored' );
-               }
-               this.anchored = show;
-       }
-};
-
-/**
- * Check if the anchor is visible.
- *
- * @return {boolean} Anchor is visible
- */
-OO.ui.PopupWidget.prototype.hasAnchor = function () {
-       return this.anchor;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.PopupWidget.prototype.toggle = function ( show ) {
-       var change;
-       show = show === undefined ? !this.isVisible() : !!show;
-
-       change = show !== this.isVisible();
-
-       // Parent method
-       OO.ui.PopupWidget.parent.prototype.toggle.call( this, show );
-
-       if ( change ) {
-               if ( show ) {
-                       if ( this.autoClose ) {
-                               this.bindMouseDownListener();
-                               this.bindKeyDownListener();
-                       }
-                       this.updateDimensions();
-                       this.toggleClipping( true );
-               } else {
-                       this.toggleClipping( false );
-                       if ( this.autoClose ) {
-                               this.unbindMouseDownListener();
-                               this.unbindKeyDownListener();
-                       }
-               }
-       }
-
-       return this;
-};
-
-/**
- * Set the size of the popup.
- *
- * Changing the size may also change the popup's position depending on the alignment.
- *
- * @param {number} width Width in pixels
- * @param {number} height Height in pixels
- * @param {boolean} [transition=false] Use a smooth transition
- * @chainable
- */
-OO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {
-       this.width = width;
-       this.height = height !== undefined ? height : null;
-       if ( this.isVisible() ) {
-               this.updateDimensions( transition );
-       }
-};
-
-/**
- * Update the size and position.
- *
- * Only use this to keep the popup properly anchored. Use #setSize to change the size, and this will
- * be called automatically.
- *
- * @param {boolean} [transition=false] Use a smooth transition
- * @chainable
- */
-OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
-       var popupOffset, originOffset, containerLeft, containerWidth, containerRight,
-               popupLeft, popupRight, overlapLeft, overlapRight, anchorWidth,
-               align = this.align,
-               widget = this;
-
-       if ( !this.$container ) {
-               // Lazy-initialize $container if not specified in constructor
-               this.$container = $( this.getClosestScrollableElementContainer() );
-       }
-
-       // Set height and width before measuring things, since it might cause our measurements
-       // to change (e.g. due to scrollbars appearing or disappearing)
-       this.$popup.css( {
-               width: this.width,
-               height: this.height !== null ? this.height : 'auto'
-       } );
-
-       // If we are in RTL, we need to flip the alignment, unless it is center
-       if ( align === 'forwards' || align === 'backwards' ) {
-               if ( this.$container.css( 'direction' ) === 'rtl' ) {
-                       align = ( { forwards: 'force-left', backwards: 'force-right' } )[ this.align ];
-               } else {
-                       align = ( { forwards: 'force-right', backwards: 'force-left' } )[ this.align ];
-               }
-
-       }
-
-       // Compute initial popupOffset based on alignment
-       popupOffset = this.width * ( { 'force-left': -1, center: -0.5, 'force-right': 0 } )[ align ];
-
-       // Figure out if this will cause the popup to go beyond the edge of the container
-       originOffset = this.$element.offset().left;
-       containerLeft = this.$container.offset().left;
-       containerWidth = this.$container.innerWidth();
-       containerRight = containerLeft + containerWidth;
-       popupLeft = popupOffset - this.containerPadding;
-       popupRight = popupOffset + this.containerPadding + this.width + this.containerPadding;
-       overlapLeft = ( originOffset + popupLeft ) - containerLeft;
-       overlapRight = containerRight - ( originOffset + popupRight );
-
-       // Adjust offset to make the popup not go beyond the edge, if needed
-       if ( overlapRight < 0 ) {
-               popupOffset += overlapRight;
-       } else if ( overlapLeft < 0 ) {
-               popupOffset -= overlapLeft;
-       }
-
-       // Adjust offset to avoid anchor being rendered too close to the edge
-       // $anchor.width() doesn't work with the pure CSS anchor (returns 0)
-       // TODO: Find a measurement that works for CSS anchors and image anchors
-       anchorWidth = this.$anchor[ 0 ].scrollWidth * 2;
-       if ( popupOffset + this.width < anchorWidth ) {
-               popupOffset = anchorWidth - this.width;
-       } else if ( -popupOffset < anchorWidth ) {
-               popupOffset = -anchorWidth;
-       }
-
-       // Prevent transition from being interrupted
-       clearTimeout( this.transitionTimeout );
-       if ( transition ) {
-               // Enable transition
-               this.$element.addClass( 'oo-ui-popupWidget-transitioning' );
-       }
-
-       // Position body relative to anchor
-       this.$popup.css( 'margin-left', popupOffset );
-
-       if ( transition ) {
-               // Prevent transitioning after transition is complete
-               this.transitionTimeout = setTimeout( function () {
-                       widget.$element.removeClass( 'oo-ui-popupWidget-transitioning' );
-               }, 200 );
-       } else {
-               // Prevent transitioning immediately
-               this.$element.removeClass( 'oo-ui-popupWidget-transitioning' );
-       }
-
-       // Reevaluate clipping state since we've relocated and resized the popup
-       this.clip();
-
-       return this;
-};
-
-/**
- * Set popup alignment
- * @param {string} align Alignment of the popup, `center`, `force-left`, `force-right`,
- *  `backwards` or `forwards`.
- */
-OO.ui.PopupWidget.prototype.setAlignment = function ( align ) {
-       // Validate alignment and transform deprecated values
-       if ( [ 'left', 'right', 'force-left', 'force-right', 'backwards', 'forwards', 'center' ].indexOf( align ) > -1 ) {
-               this.align = { left: 'force-right', right: 'force-left' }[ align ] || align;
-       } else {
-               this.align = 'center';
-       }
-};
-
-/**
- * Get popup alignment
- * @return {string} align Alignment of the popup, `center`, `force-left`, `force-right`,
- *  `backwards` or `forwards`.
- */
-OO.ui.PopupWidget.prototype.getAlignment = function () {
-       return this.align;
-};
-
-/**
- * Progress bars visually display the status of an operation, such as a download,
- * and can be either determinate or indeterminate:
- *
- * - **determinate** process bars show the percent of an operation that is complete.
- *
- * - **indeterminate** process bars use a visual display of motion to indicate that an operation
- *   is taking place. Because the extent of an indeterminate operation is unknown, the bar does
- *   not use percentages.
- *
- * The value of the `progress` configuration determines whether the bar is determinate or indeterminate.
- *
- *     @example
- *     // Examples of determinate and indeterminate progress bars.
- *     var progressBar1 = new OO.ui.ProgressBarWidget( {
- *         progress: 33
- *     } );
- *     var progressBar2 = new OO.ui.ProgressBarWidget();
- *
- *     // Create a FieldsetLayout to layout progress bars
- *     var fieldset = new OO.ui.FieldsetLayout;
- *     fieldset.addItems( [
- *        new OO.ui.FieldLayout( progressBar1, {label: 'Determinate', align: 'top'}),
- *        new OO.ui.FieldLayout( progressBar2, {label: 'Indeterminate', align: 'top'})
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * @class
- * @extends OO.ui.Widget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {number|boolean} [progress=false] The type of progress bar (determinate or indeterminate).
- *  To create a determinate progress bar, specify a number that reflects the initial percent complete.
- *  By default, the progress bar is indeterminate.
- */
-OO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.ProgressBarWidget.parent.call( this, config );
-
-       // Properties
-       this.$bar = $( '<div>' );
-       this.progress = null;
-
-       // Initialization
-       this.setProgress( config.progress !== undefined ? config.progress : false );
-       this.$bar.addClass( 'oo-ui-progressBarWidget-bar' );
-       this.$element
-               .attr( {
-                       role: 'progressbar',
-                       'aria-valuemin': 0,
-                       'aria-valuemax': 100
-               } )
-               .addClass( 'oo-ui-progressBarWidget' )
-               .append( this.$bar );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ProgressBarWidget, OO.ui.Widget );
-
-/* Static Properties */
-
-OO.ui.ProgressBarWidget.static.tagName = 'div';
-
-/* Methods */
-
-/**
- * Get the percent of the progress that has been completed. Indeterminate progresses will return `false`.
- *
- * @return {number|boolean} Progress percent
- */
-OO.ui.ProgressBarWidget.prototype.getProgress = function () {
-       return this.progress;
-};
-
-/**
- * Set the percent of the process completed or `false` for an indeterminate process.
- *
- * @param {number|boolean} progress Progress percent or `false` for indeterminate
- */
-OO.ui.ProgressBarWidget.prototype.setProgress = function ( progress ) {
-       this.progress = progress;
-
-       if ( progress !== false ) {
-               this.$bar.css( 'width', this.progress + '%' );
-               this.$element.attr( 'aria-valuenow', this.progress );
-       } else {
-               this.$bar.css( 'width', '' );
-               this.$element.removeAttr( 'aria-valuenow' );
-       }
-       this.$element.toggleClass( 'oo-ui-progressBarWidget-indeterminate', !progress );
-};
-
-/**
- * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query,
- * and a menu of search results, which is displayed beneath the query
- * field. Unlike {@link OO.ui.mixin.LookupElement lookup menus}, search result menus are always visible to the user.
- * Users can choose an item from the menu or type a query into the text field to search for a matching result item.
- * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window.
- *
- * Each time the query is changed, the search result menu is cleared and repopulated. Please see
- * the [OOjs UI demos][1] for an example.
- *
- * [1]: https://tools.wmflabs.org/oojs-ui/oojs-ui/demos/#dialogs-mediawiki-vector-ltr
- *
- * @class
- * @extends OO.ui.Widget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string|jQuery} [placeholder] Placeholder text for query input
- * @cfg {string} [value] Initial query value
- */
-OO.ui.SearchWidget = function OoUiSearchWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.SearchWidget.parent.call( this, config );
-
-       // Properties
-       this.query = new OO.ui.TextInputWidget( {
-               icon: 'search',
-               placeholder: config.placeholder,
-               value: config.value
-       } );
-       this.results = new OO.ui.SelectWidget();
-       this.$query = $( '<div>' );
-       this.$results = $( '<div>' );
-
-       // Events
-       this.query.connect( this, {
-               change: 'onQueryChange',
-               enter: 'onQueryEnter'
-       } );
-       this.query.$input.on( 'keydown', this.onQueryKeydown.bind( this ) );
-
-       // Initialization
-       this.$query
-               .addClass( 'oo-ui-searchWidget-query' )
-               .append( this.query.$element );
-       this.$results
-               .addClass( 'oo-ui-searchWidget-results' )
-               .append( this.results.$element );
-       this.$element
-               .addClass( 'oo-ui-searchWidget' )
-               .append( this.$results, this.$query );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget );
-
-/* Methods */
-
-/**
- * Handle query key down events.
- *
- * @private
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) {
-       var highlightedItem, nextItem,
-               dir = e.which === OO.ui.Keys.DOWN ? 1 : ( e.which === OO.ui.Keys.UP ? -1 : 0 );
-
-       if ( dir ) {
-               highlightedItem = this.results.getHighlightedItem();
-               if ( !highlightedItem ) {
-                       highlightedItem = this.results.getSelectedItem();
-               }
-               nextItem = this.results.getRelativeSelectableItem( highlightedItem, dir );
-               this.results.highlightItem( nextItem );
-               nextItem.scrollElementIntoView();
-       }
-};
-
-/**
- * Handle select widget select events.
- *
- * Clears existing results. Subclasses should repopulate items according to new query.
- *
- * @private
- * @param {string} value New value
- */
-OO.ui.SearchWidget.prototype.onQueryChange = function () {
-       // Reset
-       this.results.clearItems();
-};
-
-/**
- * Handle select widget enter key events.
- *
- * Chooses highlighted item.
- *
- * @private
- * @param {string} value New value
- */
-OO.ui.SearchWidget.prototype.onQueryEnter = function () {
-       var highlightedItem = this.results.getHighlightedItem();
-       if ( highlightedItem ) {
-               this.results.chooseItem( highlightedItem );
-       }
-};
-
-/**
- * Get the query input.
- *
- * @return {OO.ui.TextInputWidget} Query input
- */
-OO.ui.SearchWidget.prototype.getQuery = function () {
-       return this.query;
-};
-
-/**
- * Get the search results menu.
- *
- * @return {OO.ui.SelectWidget} Menu of search results
- */
-OO.ui.SearchWidget.prototype.getResults = function () {
-       return this.results;
-};
-
-/**
- * A SelectWidget is of a generic selection of options. The OOjs UI library contains several types of
- * select widgets, including {@link OO.ui.ButtonSelectWidget button selects},
- * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget
- * menu selects}.
- *
- * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For more
- * information, please see the [OOjs UI documentation on MediaWiki][1].
- *
- *     @example
- *     // Example of a select widget with three options
- *     var select = new OO.ui.SelectWidget( {
- *         items: [
- *             new OO.ui.OptionWidget( {
- *                 data: 'a',
- *                 label: 'Option One',
- *             } ),
- *             new OO.ui.OptionWidget( {
- *                 data: 'b',
- *                 label: 'Option Two',
- *             } ),
- *             new OO.ui.OptionWidget( {
- *                 data: 'c',
- *                 label: 'Option Three',
- *             } )
- *         ]
- *     } );
- *     $( 'body' ).append( select.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- *
- * @abstract
- * @class
- * @extends OO.ui.Widget
- * @mixins OO.ui.mixin.GroupWidget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.OptionWidget[]} [items] An array of options to add to the select.
- *  Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See
- *  the [OOjs UI documentation on MediaWiki] [2] for examples.
- *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- */
-OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.SelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.GroupWidget.call( this, $.extend( {}, config, { $group: this.$element } ) );
-
-       // Properties
-       this.pressed = false;
-       this.selecting = null;
-       this.onMouseUpHandler = this.onMouseUp.bind( this );
-       this.onMouseMoveHandler = this.onMouseMove.bind( this );
-       this.onKeyDownHandler = this.onKeyDown.bind( this );
-       this.onKeyPressHandler = this.onKeyPress.bind( this );
-       this.keyPressBuffer = '';
-       this.keyPressBufferTimer = null;
-
-       // Events
-       this.connect( this, {
-               toggle: 'onToggle'
-       } );
-       this.$element.on( {
-               mousedown: this.onMouseDown.bind( this ),
-               mouseover: this.onMouseOver.bind( this ),
-               mouseleave: this.onMouseLeave.bind( this )
-       } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' )
-               .attr( 'role', 'listbox' );
-       if ( Array.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );
-
-// Need to mixin base class as well
-OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupElement );
-OO.mixinClass( OO.ui.SelectWidget, OO.ui.mixin.GroupWidget );
-
-/* Static */
-OO.ui.SelectWidget.static.passAllFilter = function () {
-       return true;
-};
-
-/* Events */
-
-/**
- * @event highlight
- *
- * A `highlight` event is emitted when the highlight is changed with the #highlightItem method.
- *
- * @param {OO.ui.OptionWidget|null} item Highlighted item
- */
-
-/**
- * @event press
- *
- * A `press` event is emitted when the #pressItem method is used to programmatically modify the
- * pressed state of an option.
- *
- * @param {OO.ui.OptionWidget|null} item Pressed item
- */
-
-/**
- * @event select
- *
- * A `select` event is emitted when the selection is modified programmatically with the #selectItem method.
- *
- * @param {OO.ui.OptionWidget|null} item Selected item
- */
-
-/**
- * @event choose
- * A `choose` event is emitted when an item is chosen with the #chooseItem method.
- * @param {OO.ui.OptionWidget} item Chosen item
- */
-
-/**
- * @event add
- *
- * An `add` event is emitted when options are added to the select with the #addItems method.
- *
- * @param {OO.ui.OptionWidget[]} items Added items
- * @param {number} index Index of insertion point
- */
-
-/**
- * @event remove
- *
- * A `remove` event is emitted when options are removed from the select with the #clearItems
- * or #removeItems methods.
- *
- * @param {OO.ui.OptionWidget[]} items Removed items
- */
-
-/* Methods */
-
-/**
- * Handle mouse down events.
- *
- * @private
- * @param {jQuery.Event} e Mouse down event
- */
-OO.ui.SelectWidget.prototype.onMouseDown = function ( e ) {
-       var item;
-
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               this.togglePressed( true );
-               item = this.getTargetItem( e );
-               if ( item && item.isSelectable() ) {
-                       this.pressItem( item );
-                       this.selecting = item;
-                       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
-                       this.getElementDocument().addEventListener( 'mousemove', this.onMouseMoveHandler, true );
-               }
-       }
-       return false;
-};
-
-/**
- * Handle mouse up events.
- *
- * @private
- * @param {jQuery.Event} e Mouse up event
- */
-OO.ui.SelectWidget.prototype.onMouseUp = function ( e ) {
-       var item;
-
-       this.togglePressed( false );
-       if ( !this.selecting ) {
-               item = this.getTargetItem( e );
-               if ( item && item.isSelectable() ) {
-                       this.selecting = item;
-               }
-       }
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT && this.selecting ) {
-               this.pressItem( null );
-               this.chooseItem( this.selecting );
-               this.selecting = null;
-       }
-
-       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
-       this.getElementDocument().removeEventListener( 'mousemove', this.onMouseMoveHandler, true );
-
-       return false;
-};
-
-/**
- * Handle mouse move events.
- *
- * @private
- * @param {jQuery.Event} e Mouse move event
- */
-OO.ui.SelectWidget.prototype.onMouseMove = function ( e ) {
-       var item;
-
-       if ( !this.isDisabled() && this.pressed ) {
-               item = this.getTargetItem( e );
-               if ( item && item !== this.selecting && item.isSelectable() ) {
-                       this.pressItem( item );
-                       this.selecting = item;
-               }
-       }
-       return false;
-};
-
-/**
- * Handle mouse over events.
- *
- * @private
- * @param {jQuery.Event} e Mouse over event
- */
-OO.ui.SelectWidget.prototype.onMouseOver = function ( e ) {
-       var item;
-
-       if ( !this.isDisabled() ) {
-               item = this.getTargetItem( e );
-               this.highlightItem( item && item.isHighlightable() ? item : null );
-       }
-       return false;
-};
-
-/**
- * Handle mouse leave events.
- *
- * @private
- * @param {jQuery.Event} e Mouse over event
- */
-OO.ui.SelectWidget.prototype.onMouseLeave = function () {
-       if ( !this.isDisabled() ) {
-               this.highlightItem( null );
-       }
-       return false;
-};
-
-/**
- * Handle key down events.
- *
- * @protected
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.SelectWidget.prototype.onKeyDown = function ( e ) {
-       var nextItem,
-               handled = false,
-               currentItem = this.getHighlightedItem() || this.getSelectedItem();
-
-       if ( !this.isDisabled() && this.isVisible() ) {
-               switch ( e.keyCode ) {
-                       case OO.ui.Keys.ENTER:
-                               if ( currentItem && currentItem.constructor.static.highlightable ) {
-                                       // Was only highlighted, now let's select it. No-op if already selected.
-                                       this.chooseItem( currentItem );
-                                       handled = true;
-                               }
-                               break;
-                       case OO.ui.Keys.UP:
-                       case OO.ui.Keys.LEFT:
-                               this.clearKeyPressBuffer();
-                               nextItem = this.getRelativeSelectableItem( currentItem, -1 );
-                               handled = true;
-                               break;
-                       case OO.ui.Keys.DOWN:
-                       case OO.ui.Keys.RIGHT:
-                               this.clearKeyPressBuffer();
-                               nextItem = this.getRelativeSelectableItem( currentItem, 1 );
-                               handled = true;
-                               break;
-                       case OO.ui.Keys.ESCAPE:
-                       case OO.ui.Keys.TAB:
-                               if ( currentItem && currentItem.constructor.static.highlightable ) {
-                                       currentItem.setHighlighted( false );
-                               }
-                               this.unbindKeyDownListener();
-                               this.unbindKeyPressListener();
-                               // Don't prevent tabbing away / defocusing
-                               handled = false;
-                               break;
-               }
-
-               if ( nextItem ) {
-                       if ( nextItem.constructor.static.highlightable ) {
-                               this.highlightItem( nextItem );
-                       } else {
-                               this.chooseItem( nextItem );
-                       }
-                       nextItem.scrollElementIntoView();
-               }
-
-               if ( handled ) {
-                       // Can't just return false, because e is not always a jQuery event
-                       e.preventDefault();
-                       e.stopPropagation();
-               }
-       }
-};
-
-/**
- * Bind key down listener.
- *
- * @protected
- */
-OO.ui.SelectWidget.prototype.bindKeyDownListener = function () {
-       this.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );
-};
-
-/**
- * Unbind key down listener.
- *
- * @protected
- */
-OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {
-       this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true );
-};
-
-/**
- * Clear the key-press buffer
- *
- * @protected
- */
-OO.ui.SelectWidget.prototype.clearKeyPressBuffer = function () {
-       if ( this.keyPressBufferTimer ) {
-               clearTimeout( this.keyPressBufferTimer );
-               this.keyPressBufferTimer = null;
-       }
-       this.keyPressBuffer = '';
-};
-
-/**
- * Handle key press events.
- *
- * @protected
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.SelectWidget.prototype.onKeyPress = function ( e ) {
-       var c, filter, item;
-
-       if ( !e.charCode ) {
-               if ( e.keyCode === OO.ui.Keys.BACKSPACE && this.keyPressBuffer !== '' ) {
-                       this.keyPressBuffer = this.keyPressBuffer.substr( 0, this.keyPressBuffer.length - 1 );
-                       return false;
-               }
-               return;
-       }
-       if ( String.fromCodePoint ) {
-               c = String.fromCodePoint( e.charCode );
-       } else {
-               c = String.fromCharCode( e.charCode );
-       }
-
-       if ( this.keyPressBufferTimer ) {
-               clearTimeout( this.keyPressBufferTimer );
-       }
-       this.keyPressBufferTimer = setTimeout( this.clearKeyPressBuffer.bind( this ), 1500 );
-
-       item = this.getHighlightedItem() || this.getSelectedItem();
-
-       if ( this.keyPressBuffer === c ) {
-               // Common (if weird) special case: typing "xxxx" will cycle through all
-               // the items beginning with "x".
-               if ( item ) {
-                       item = this.getRelativeSelectableItem( item, 1 );
-               }
-       } else {
-               this.keyPressBuffer += c;
-       }
-
-       filter = this.getItemMatcher( this.keyPressBuffer, false );
-       if ( !item || !filter( item ) ) {
-               item = this.getRelativeSelectableItem( item, 1, filter );
-       }
-       if ( item ) {
-               if ( item.constructor.static.highlightable ) {
-                       this.highlightItem( item );
-               } else {
-                       this.chooseItem( item );
-               }
-               item.scrollElementIntoView();
-       }
-
-       return false;
-};
-
-/**
- * Get a matcher for the specific string
- *
- * @protected
- * @param {string} s String to match against items
- * @param {boolean} [exact=false] Only accept exact matches
- * @return {Function} function ( OO.ui.OptionItem ) => boolean
- */
-OO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) {
-       var re;
-
-       if ( s.normalize ) {
-               s = s.normalize();
-       }
-       s = exact ? s.trim() : s.replace( /^\s+/, '' );
-       re = '^\\s*' + s.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' ).replace( /\s+/g, '\\s+' );
-       if ( exact ) {
-               re += '\\s*$';
-       }
-       re = new RegExp( re, 'i' );
-       return function ( item ) {
-               var l = item.getLabel();
-               if ( typeof l !== 'string' ) {
-                       l = item.$label.text();
-               }
-               if ( l.normalize ) {
-                       l = l.normalize();
-               }
-               return re.test( l );
-       };
-};
-
-/**
- * Bind key press listener.
- *
- * @protected
- */
-OO.ui.SelectWidget.prototype.bindKeyPressListener = function () {
-       this.getElementWindow().addEventListener( 'keypress', this.onKeyPressHandler, true );
-};
-
-/**
- * Unbind key down listener.
- *
- * If you override this, be sure to call this.clearKeyPressBuffer() from your
- * implementation.
- *
- * @protected
- */
-OO.ui.SelectWidget.prototype.unbindKeyPressListener = function () {
-       this.getElementWindow().removeEventListener( 'keypress', this.onKeyPressHandler, true );
-       this.clearKeyPressBuffer();
-};
-
-/**
- * Visibility change handler
- *
- * @protected
- * @param {boolean} visible
- */
-OO.ui.SelectWidget.prototype.onToggle = function ( visible ) {
-       if ( !visible ) {
-               this.clearKeyPressBuffer();
-       }
-};
-
-/**
- * Get the closest item to a jQuery.Event.
- *
- * @private
- * @param {jQuery.Event} e
- * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found
- */
-OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) {
-       return $( e.target ).closest( '.oo-ui-optionWidget' ).data( 'oo-ui-optionWidget' ) || null;
-};
-
-/**
- * Get selected item.
- *
- * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected
- */
-OO.ui.SelectWidget.prototype.getSelectedItem = function () {
-       var i, len;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               if ( this.items[ i ].isSelected() ) {
-                       return this.items[ i ];
-               }
-       }
-       return null;
-};
-
-/**
- * Get highlighted item.
- *
- * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted
- */
-OO.ui.SelectWidget.prototype.getHighlightedItem = function () {
-       var i, len;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               if ( this.items[ i ].isHighlighted() ) {
-                       return this.items[ i ];
-               }
-       }
-       return null;
-};
-
-/**
- * Toggle pressed state.
- *
- * Press is a state that occurs when a user mouses down on an item, but
- * has not yet let go of the mouse. The item may appear selected, but it will not be selected
- * until the user releases the mouse.
- *
- * @param {boolean} pressed An option is being pressed
- */
-OO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) {
-       if ( pressed === undefined ) {
-               pressed = !this.pressed;
-       }
-       if ( pressed !== this.pressed ) {
-               this.$element
-                       .toggleClass( 'oo-ui-selectWidget-pressed', pressed )
-                       .toggleClass( 'oo-ui-selectWidget-depressed', !pressed );
-               this.pressed = pressed;
-       }
-};
-
-/**
- * Highlight an option. If the `item` param is omitted, no options will be highlighted
- * and any existing highlight will be removed. The highlight is mutually exclusive.
- *
- * @param {OO.ui.OptionWidget} [item] Item to highlight, omit for no highlight
- * @fires highlight
- * @chainable
- */
-OO.ui.SelectWidget.prototype.highlightItem = function ( item ) {
-       var i, len, highlighted,
-               changed = false;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               highlighted = this.items[ i ] === item;
-               if ( this.items[ i ].isHighlighted() !== highlighted ) {
-                       this.items[ i ].setHighlighted( highlighted );
-                       changed = true;
-               }
-       }
-       if ( changed ) {
-               this.emit( 'highlight', item );
-       }
-
-       return this;
-};
-
-/**
- * Fetch an item by its label.
- *
- * @param {string} label Label of the item to select.
- * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches
- * @return {OO.ui.Element|null} Item with equivalent label, `null` if none exists
- */
-OO.ui.SelectWidget.prototype.getItemFromLabel = function ( label, prefix ) {
-       var i, item, found,
-               len = this.items.length,
-               filter = this.getItemMatcher( label, true );
-
-       for ( i = 0; i < len; i++ ) {
-               item = this.items[ i ];
-               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
-                       return item;
-               }
-       }
-
-       if ( prefix ) {
-               found = null;
-               filter = this.getItemMatcher( label, false );
-               for ( i = 0; i < len; i++ ) {
-                       item = this.items[ i ];
-                       if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
-                               if ( found ) {
-                                       return null;
-                               }
-                               found = item;
-                       }
-               }
-               if ( found ) {
-                       return found;
-               }
-       }
-
-       return null;
-};
-
-/**
- * Programmatically select an option by its label. If the item does not exist,
- * all options will be deselected.
- *
- * @param {string} [label] Label of the item to select.
- * @param {boolean} [prefix=false] Allow a prefix match, if only a single item matches
- * @fires select
- * @chainable
- */
-OO.ui.SelectWidget.prototype.selectItemByLabel = function ( label, prefix ) {
-       var itemFromLabel = this.getItemFromLabel( label, !!prefix );
-       if ( label === undefined || !itemFromLabel ) {
-               return this.selectItem();
-       }
-       return this.selectItem( itemFromLabel );
-};
-
-/**
- * Programmatically select an option by its data. If the `data` parameter is omitted,
- * or if the item does not exist, all options will be deselected.
- *
- * @param {Object|string} [data] Value of the item to select, omit to deselect all
- * @fires select
- * @chainable
- */
-OO.ui.SelectWidget.prototype.selectItemByData = function ( data ) {
-       var itemFromData = this.getItemFromData( data );
-       if ( data === undefined || !itemFromData ) {
-               return this.selectItem();
-       }
-       return this.selectItem( itemFromData );
-};
-
-/**
- * Programmatically select an option by its reference. If the `item` parameter is omitted,
- * all options will be deselected.
- *
- * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all
- * @fires select
- * @chainable
- */
-OO.ui.SelectWidget.prototype.selectItem = function ( item ) {
-       var i, len, selected,
-               changed = false;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               selected = this.items[ i ] === item;
-               if ( this.items[ i ].isSelected() !== selected ) {
-                       this.items[ i ].setSelected( selected );
-                       changed = true;
-               }
-       }
-       if ( changed ) {
-               this.emit( 'select', item );
-       }
-
-       return this;
-};
-
-/**
- * Press an item.
- *
- * Press is a state that occurs when a user mouses down on an item, but has not
- * yet let go of the mouse. The item may appear selected, but it will not be selected until the user
- * releases the mouse.
- *
- * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all
- * @fires press
- * @chainable
- */
-OO.ui.SelectWidget.prototype.pressItem = function ( item ) {
-       var i, len, pressed,
-               changed = false;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               pressed = this.items[ i ] === item;
-               if ( this.items[ i ].isPressed() !== pressed ) {
-                       this.items[ i ].setPressed( pressed );
-                       changed = true;
-               }
-       }
-       if ( changed ) {
-               this.emit( 'press', item );
-       }
-
-       return this;
-};
-
-/**
- * Choose an item.
- *
- * Note that ‘choose’ should never be modified programmatically. A user can choose
- * an option with the keyboard or mouse and it becomes selected. To select an item programmatically,
- * use the #selectItem method.
- *
- * This method is identical to #selectItem, but may vary in subclasses that take additional action
- * when users choose an item with the keyboard or mouse.
- *
- * @param {OO.ui.OptionWidget} item Item to choose
- * @fires choose
- * @chainable
- */
-OO.ui.SelectWidget.prototype.chooseItem = function ( item ) {
-       if ( item ) {
-               this.selectItem( item );
-               this.emit( 'choose', item );
-       }
-
-       return this;
-};
-
-/**
- * Get an option by its position relative to the specified item (or to the start of the option array,
- * if item is `null`). The direction in which to search through the option array is specified with a
- * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or
- * `null` if there are no options in the array.
- *
- * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array.
- * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward
- * @param {Function} filter Only consider items for which this function returns
- *  true. Function takes an OO.ui.OptionWidget and returns a boolean.
- * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select
- */
-OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direction, filter ) {
-       var currentIndex, nextIndex, i,
-               increase = direction > 0 ? 1 : -1,
-               len = this.items.length;
-
-       if ( !$.isFunction( filter ) ) {
-               filter = OO.ui.SelectWidget.static.passAllFilter;
-       }
-
-       if ( item instanceof OO.ui.OptionWidget ) {
-               currentIndex = this.items.indexOf( item );
-               nextIndex = ( currentIndex + increase + len ) % len;
-       } else {
-               // If no item is selected and moving forward, start at the beginning.
-               // If moving backward, start at the end.
-               nextIndex = direction > 0 ? 0 : len - 1;
-       }
-
-       for ( i = 0; i < len; i++ ) {
-               item = this.items[ nextIndex ];
-               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() && filter( item ) ) {
-                       return item;
-               }
-               nextIndex = ( nextIndex + increase + len ) % len;
-       }
-       return null;
-};
-
-/**
- * Get the next selectable item or `null` if there are no selectable items.
- * Disabled options and menu-section markers and breaks are not selectable.
- *
- * @return {OO.ui.OptionWidget|null} Item, `null` if there aren't any selectable items
- */
-OO.ui.SelectWidget.prototype.getFirstSelectableItem = function () {
-       var i, len, item;
-
-       for ( i = 0, len = this.items.length; i < len; i++ ) {
-               item = this.items[ i ];
-               if ( item instanceof OO.ui.OptionWidget && item.isSelectable() ) {
-                       return item;
-               }
-       }
-
-       return null;
-};
-
-/**
- * Add an array of options to the select. Optionally, an index number can be used to
- * specify an insertion point.
- *
- * @param {OO.ui.OptionWidget[]} items Items to add
- * @param {number} [index] Index to insert items after
- * @fires add
- * @chainable
- */
-OO.ui.SelectWidget.prototype.addItems = function ( items, index ) {
-       // Mixin method
-       OO.ui.mixin.GroupWidget.prototype.addItems.call( this, items, index );
-
-       // Always provide an index, even if it was omitted
-       this.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index );
-
-       return this;
-};
-
-/**
- * Remove the specified array of options from the select. Options will be detached
- * from the DOM, not removed, so they can be reused later. To remove all options from
- * the select, you may wish to use the #clearItems method instead.
- *
- * @param {OO.ui.OptionWidget[]} items Items to remove
- * @fires remove
- * @chainable
- */
-OO.ui.SelectWidget.prototype.removeItems = function ( items ) {
-       var i, len, item;
-
-       // Deselect items being removed
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-               if ( item.isSelected() ) {
-                       this.selectItem( null );
-               }
-       }
-
-       // Mixin method
-       OO.ui.mixin.GroupWidget.prototype.removeItems.call( this, items );
-
-       this.emit( 'remove', items );
-
-       return this;
-};
-
-/**
- * Clear all options from the select. Options will be detached from the DOM, not removed,
- * so that they can be reused later. To remove a subset of options from the select, use
- * the #removeItems method.
- *
- * @fires remove
- * @chainable
- */
-OO.ui.SelectWidget.prototype.clearItems = function () {
-       var items = this.items.slice();
-
-       // Mixin method
-       OO.ui.mixin.GroupWidget.prototype.clearItems.call( this );
-
-       // Clear selection
-       this.selectItem( null );
-
-       this.emit( 'remove', items );
-
-       return this;
-};
-
-/**
- * ButtonSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains
- * button options and is used together with
- * OO.ui.ButtonOptionWidget. The ButtonSelectWidget provides an interface for
- * highlighting, choosing, and selecting mutually exclusive options. Please see
- * the [OOjs UI documentation on MediaWiki] [1] for more information.
- *
- *     @example
- *     // Example: A ButtonSelectWidget that contains three ButtonOptionWidgets
- *     var option1 = new OO.ui.ButtonOptionWidget( {
- *         data: 1,
- *         label: 'Option 1',
- *         title: 'Button option 1'
- *     } );
- *
- *     var option2 = new OO.ui.ButtonOptionWidget( {
- *         data: 2,
- *         label: 'Option 2',
- *         title: 'Button option 2'
- *     } );
- *
- *     var option3 = new OO.ui.ButtonOptionWidget( {
- *         data: 3,
- *         label: 'Option 3',
- *         title: 'Button option 3'
- *     } );
- *
- *     var buttonSelect=new OO.ui.ButtonSelectWidget( {
- *         items: [ option1, option2, option3 ]
- *     } );
- *     $( 'body' ).append( buttonSelect.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- *
- * @class
- * @extends OO.ui.SelectWidget
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.ButtonSelectWidget = function OoUiButtonSelectWidget( config ) {
-       // Parent constructor
-       OO.ui.ButtonSelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TabIndexedElement.call( this, config );
-
-       // Events
-       this.$element.on( {
-               focus: this.bindKeyDownListener.bind( this ),
-               blur: this.unbindKeyDownListener.bind( this )
-       } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-buttonSelectWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ButtonSelectWidget, OO.ui.SelectWidget );
-OO.mixinClass( OO.ui.ButtonSelectWidget, OO.ui.mixin.TabIndexedElement );
-
-/**
- * RadioSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains radio
- * options and is used together with OO.ui.RadioOptionWidget. The RadioSelectWidget provides
- * an interface for adding, removing and selecting options.
- * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
- *
- * If you want to use this within a HTML form, such as a OO.ui.FormLayout, use
- * OO.ui.RadioSelectInputWidget instead.
- *
- *     @example
- *     // A RadioSelectWidget with RadioOptions.
- *     var option1 = new OO.ui.RadioOptionWidget( {
- *         data: 'a',
- *         label: 'Selected radio option'
- *     } );
- *
- *     var option2 = new OO.ui.RadioOptionWidget( {
- *         data: 'b',
- *         label: 'Unselected radio option'
- *     } );
- *
- *     var radioSelect=new OO.ui.RadioSelectWidget( {
- *         items: [ option1, option2 ]
- *      } );
- *
- *     // Select 'option 1' using the RadioSelectWidget's selectItem() method.
- *     radioSelect.selectItem( option1 );
- *
- *     $( 'body' ).append( radioSelect.$element );
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
-
- *
- * @class
- * @extends OO.ui.SelectWidget
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.RadioSelectWidget = function OoUiRadioSelectWidget( config ) {
-       // Parent constructor
-       OO.ui.RadioSelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TabIndexedElement.call( this, config );
-
-       // Events
-       this.$element.on( {
-               focus: this.bindKeyDownListener.bind( this ),
-               blur: this.unbindKeyDownListener.bind( this )
-       } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-radioSelectWidget' )
-               .attr( 'role', 'radiogroup' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.RadioSelectWidget, OO.ui.SelectWidget );
-OO.mixinClass( OO.ui.RadioSelectWidget, OO.ui.mixin.TabIndexedElement );
-
-/**
- * MenuSelectWidget is a {@link OO.ui.SelectWidget select widget} that contains options and
- * is used together with OO.ui.MenuOptionWidget. It is designed be used as part of another widget.
- * See {@link OO.ui.DropdownWidget DropdownWidget}, {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget},
- * and {@link OO.ui.mixin.LookupElement LookupElement} for examples of widgets that contain menus.
- * MenuSelectWidgets themselves are not instantiated directly, rather subclassed
- * and customized to be opened, closed, and displayed as needed.
- *
- * By default, menus are clipped to the visible viewport and are not visible when a user presses the
- * mouse outside the menu.
- *
- * Menus also have support for keyboard interaction:
- *
- * - Enter/Return key: choose and select a menu option
- * - Up-arrow key: highlight the previous menu option
- * - Down-arrow key: highlight the next menu option
- * - Esc key: hide the menu
- *
- * Please see the [OOjs UI documentation on MediaWiki][1] for more information.
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options
- *
- * @class
- * @extends OO.ui.SelectWidget
- * @mixins OO.ui.mixin.ClippableElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.ui.TextInputWidget} [input] Text input used to implement option highlighting for menu items that match
- *  the text the user types. This config is used by {@link OO.ui.ComboBoxInputWidget ComboBoxInputWidget}
- *  and {@link OO.ui.mixin.LookupElement LookupElement}
- * @cfg {jQuery} [$input] Text input used to implement option highlighting for menu items that match
- *  the text the user types. This config is used by {@link OO.ui.CapsuleMultiSelectWidget CapsuleMultiSelectWidget}
- * @cfg {OO.ui.Widget} [widget] Widget associated with the menu's active state. If the user clicks the mouse
- *  anywhere on the page outside of this widget, the menu is hidden. For example, if there is a button
- *  that toggles the menu's visibility on click, the menu will be hidden then re-shown when the user clicks
- *  that button, unless the button (or its parent widget) is passed in here.
- * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu.
- * @cfg {boolean} [filterFromInput=false] Filter the displayed options from the input
- */
-OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.MenuSelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
-
-       // Properties
-       this.newItems = null;
-       this.autoHide = config.autoHide === undefined || !!config.autoHide;
-       this.filterFromInput = !!config.filterFromInput;
-       this.$input = config.$input ? config.$input : config.input ? config.input.$input : null;
-       this.$widget = config.widget ? config.widget.$element : null;
-       this.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );
-       this.onInputEditHandler = OO.ui.debounce( this.updateItemVisibility.bind( this ), 100 );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-menuSelectWidget' )
-               .attr( 'role', 'menu' );
-
-       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
-       // that reference properties not initialized at that time of parent class construction
-       // TODO: Find a better way to handle post-constructor setup
-       this.visible = false;
-       this.$element.addClass( 'oo-ui-element-hidden' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuSelectWidget, OO.ui.SelectWidget );
-OO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.ClippableElement );
-
-/* Methods */
-
-/**
- * Handles document mouse down events.
- *
- * @protected
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.MenuSelectWidget.prototype.onDocumentMouseDown = function ( e ) {
-       if (
-               !OO.ui.contains( this.$element[ 0 ], e.target, true ) &&
-               ( !this.$widget || !OO.ui.contains( this.$widget[ 0 ], e.target, true ) )
-       ) {
-               this.toggle( false );
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) {
-       var currentItem = this.getHighlightedItem() || this.getSelectedItem();
-
-       if ( !this.isDisabled() && this.isVisible() ) {
-               switch ( e.keyCode ) {
-                       case OO.ui.Keys.LEFT:
-                       case OO.ui.Keys.RIGHT:
-                               // Do nothing if a text field is associated, arrow keys will be handled natively
-                               if ( !this.$input ) {
-                                       OO.ui.MenuSelectWidget.parent.prototype.onKeyDown.call( this, e );
-                               }
-                               break;
-                       case OO.ui.Keys.ESCAPE:
-                       case OO.ui.Keys.TAB:
-                               if ( currentItem ) {
-                                       currentItem.setHighlighted( false );
-                               }
-                               this.toggle( false );
-                               // Don't prevent tabbing away, prevent defocusing
-                               if ( e.keyCode === OO.ui.Keys.ESCAPE ) {
-                                       e.preventDefault();
-                                       e.stopPropagation();
-                               }
-                               break;
-                       default:
-                               OO.ui.MenuSelectWidget.parent.prototype.onKeyDown.call( this, e );
-                               return;
-               }
-       }
-};
-
-/**
- * Update menu item visibility after input changes.
- * @protected
- */
-OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
-       var i, item,
-               len = this.items.length,
-               showAll = !this.isVisible(),
-               filter = showAll ? null : this.getItemMatcher( this.$input.val() );
-
-       for ( i = 0; i < len; i++ ) {
-               item = this.items[ i ];
-               if ( item instanceof OO.ui.OptionWidget ) {
-                       item.toggle( showAll || filter( item ) );
-               }
-       }
-
-       // Reevaluate clipping
-       this.clip();
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.bindKeyDownListener = function () {
-       if ( this.$input ) {
-               this.$input.on( 'keydown', this.onKeyDownHandler );
-       } else {
-               OO.ui.MenuSelectWidget.parent.prototype.bindKeyDownListener.call( this );
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.unbindKeyDownListener = function () {
-       if ( this.$input ) {
-               this.$input.off( 'keydown', this.onKeyDownHandler );
-       } else {
-               OO.ui.MenuSelectWidget.parent.prototype.unbindKeyDownListener.call( this );
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.bindKeyPressListener = function () {
-       if ( this.$input ) {
-               if ( this.filterFromInput ) {
-                       this.$input.on( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
-               }
-       } else {
-               OO.ui.MenuSelectWidget.parent.prototype.bindKeyPressListener.call( this );
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = function () {
-       if ( this.$input ) {
-               if ( this.filterFromInput ) {
-                       this.$input.off( 'keydown mouseup cut paste change input select', this.onInputEditHandler );
-                       this.updateItemVisibility();
-               }
-       } else {
-               OO.ui.MenuSelectWidget.parent.prototype.unbindKeyPressListener.call( this );
-       }
-};
-
-/**
- * Choose an item.
- *
- * When a user chooses an item, the menu is closed.
- *
- * Note that ‘choose’ should never be modified programmatically. A user can choose an option with the keyboard
- * or mouse and it becomes selected. To select an item programmatically, use the #selectItem method.
- * @param {OO.ui.OptionWidget} item Item to choose
- * @chainable
- */
-OO.ui.MenuSelectWidget.prototype.chooseItem = function ( item ) {
-       OO.ui.MenuSelectWidget.parent.prototype.chooseItem.call( this, item );
-       this.toggle( false );
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.addItems = function ( items, index ) {
-       var i, len, item;
-
-       // Parent method
-       OO.ui.MenuSelectWidget.parent.prototype.addItems.call( this, items, index );
-
-       // Auto-initialize
-       if ( !this.newItems ) {
-               this.newItems = [];
-       }
-
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-               if ( this.isVisible() ) {
-                       // Defer fitting label until item has been attached
-                       item.fitLabel();
-               } else {
-                       this.newItems.push( item );
-               }
-       }
-
-       // Reevaluate clipping
-       this.clip();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.removeItems = function ( items ) {
-       // Parent method
-       OO.ui.MenuSelectWidget.parent.prototype.removeItems.call( this, items );
-
-       // Reevaluate clipping
-       this.clip();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.clearItems = function () {
-       // Parent method
-       OO.ui.MenuSelectWidget.parent.prototype.clearItems.call( this );
-
-       // Reevaluate clipping
-       this.clip();
-
-       return this;
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
-       var i, len, change;
-
-       visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
-       change = visible !== this.isVisible();
-
-       // Parent method
-       OO.ui.MenuSelectWidget.parent.prototype.toggle.call( this, visible );
-
-       if ( change ) {
-               if ( visible ) {
-                       this.bindKeyDownListener();
-                       this.bindKeyPressListener();
-
-                       if ( this.newItems && this.newItems.length ) {
-                               for ( i = 0, len = this.newItems.length; i < len; i++ ) {
-                                       this.newItems[ i ].fitLabel();
-                               }
-                               this.newItems = null;
-                       }
-                       this.toggleClipping( true );
-
-                       // Auto-hide
-                       if ( this.autoHide ) {
-                               this.getElementDocument().addEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );
-                       }
-               } else {
-                       this.unbindKeyDownListener();
-                       this.unbindKeyPressListener();
-                       this.getElementDocument().removeEventListener( 'mousedown', this.onDocumentMouseDownHandler, true );
-                       this.toggleClipping( false );
-               }
-       }
-
-       return this;
-};
-
-/**
- * FloatingMenuSelectWidget is a menu that will stick under a specified
- * container, even when it is inserted elsewhere in the document (for example,
- * in a OO.ui.Window's $overlay). This is sometimes necessary to prevent the
- * menu from being clipped too aggresively.
- *
- * The menu's position is automatically calculated and maintained when the menu
- * is toggled or the window is resized.
- *
- * See OO.ui.ComboBoxInputWidget for an example of a widget that uses this class.
- *
- * @class
- * @extends OO.ui.MenuSelectWidget
- * @mixins OO.ui.mixin.FloatableElement
- *
- * @constructor
- * @param {OO.ui.Widget} [inputWidget] Widget to provide the menu for.
- *   Deprecated, omit this parameter and specify `$container` instead.
- * @param {Object} [config] Configuration options
- * @cfg {jQuery} [$container=inputWidget.$element] Element to render menu under
- */
-OO.ui.FloatingMenuSelectWidget = function OoUiFloatingMenuSelectWidget( inputWidget, config ) {
-       // Allow 'inputWidget' parameter and config for backwards compatibility
-       if ( OO.isPlainObject( inputWidget ) && config === undefined ) {
-               config = inputWidget;
-               inputWidget = config.inputWidget;
-       }
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.FloatingMenuSelectWidget.parent.call( this, config );
-
-       // Properties (must be set before mixin constructors)
-       this.inputWidget = inputWidget; // For backwards compatibility
-       this.$container = config.$container || this.inputWidget.$element;
-
-       // Mixins constructors
-       OO.ui.mixin.FloatableElement.call( this, $.extend( {}, config, { $floatableContainer: this.$container } ) );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-floatingMenuSelectWidget' );
-       // For backwards compatibility
-       this.$element.addClass( 'oo-ui-textInputMenuSelectWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.FloatingMenuSelectWidget, OO.ui.MenuSelectWidget );
-OO.mixinClass( OO.ui.FloatingMenuSelectWidget, OO.ui.mixin.FloatableElement );
-
-// For backwards compatibility
-OO.ui.TextInputMenuSelectWidget = OO.ui.FloatingMenuSelectWidget;
-
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.FloatingMenuSelectWidget.prototype.toggle = function ( visible ) {
-       var change;
-       visible = visible === undefined ? !this.isVisible() : !!visible;
-       change = visible !== this.isVisible();
-
-       if ( change && visible ) {
-               // Make sure the width is set before the parent method runs.
-               this.setIdealSize( this.$container.width() );
-       }
-
-       // Parent method
-       // This will call this.clip(), which is nonsensical since we're not positioned yet...
-       OO.ui.FloatingMenuSelectWidget.parent.prototype.toggle.call( this, visible );
-
-       if ( change ) {
-               this.togglePositioning( this.isVisible() );
-       }
-
-       return this;
-};
-
-/**
- * OutlineSelectWidget is a structured list that contains {@link OO.ui.OutlineOptionWidget outline options}
- * A set of controls can be provided with an {@link OO.ui.OutlineControlsWidget outline controls} widget.
- *
- * **Currently, this class is only used by {@link OO.ui.BookletLayout booklet layouts}.**
- *
- * @class
- * @extends OO.ui.SelectWidget
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.OutlineSelectWidget = function OoUiOutlineSelectWidget( config ) {
-       // Parent constructor
-       OO.ui.OutlineSelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TabIndexedElement.call( this, config );
-
-       // Events
-       this.$element.on( {
-               focus: this.bindKeyDownListener.bind( this ),
-               blur: this.unbindKeyDownListener.bind( this )
-       } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-outlineSelectWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget );
-OO.mixinClass( OO.ui.OutlineSelectWidget, OO.ui.mixin.TabIndexedElement );
-
-/**
- * TabSelectWidget is a list that contains {@link OO.ui.TabOptionWidget tab options}
- *
- * **Currently, this class is only used by {@link OO.ui.IndexLayout index layouts}.**
- *
- * @class
- * @extends OO.ui.SelectWidget
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- */
-OO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) {
-       // Parent constructor
-       OO.ui.TabSelectWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TabIndexedElement.call( this, config );
-
-       // Events
-       this.$element.on( {
-               focus: this.bindKeyDownListener.bind( this ),
-               blur: this.unbindKeyDownListener.bind( this )
-       } );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-tabSelectWidget' );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget );
-OO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );
-
-/**
- * NumberInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value
- * can be entered manually) and two {@link OO.ui.ButtonWidget button widgets}
- * (to adjust the value in increments) to allow the user to enter a number.
- *
- *     @example
- *     // Example: A NumberInputWidget.
- *     var numberInput = new OO.ui.NumberInputWidget( {
- *         label: 'NumberInputWidget',
- *         input: { value: 5, min: 1, max: 10 }
- *     } );
- *     $( 'body' ).append( numberInput.$element );
- *
- * @class
- * @extends OO.ui.Widget
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {Object} [input] Configuration options to pass to the {@link OO.ui.TextInputWidget text input widget}.
- * @cfg {Object} [minusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget decrementing button widget}.
- * @cfg {Object} [plusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget incrementing button widget}.
- * @cfg {boolean} [isInteger=false] Whether the field accepts only integer values.
- * @cfg {number} [min=-Infinity] Minimum allowed value
- * @cfg {number} [max=Infinity] Maximum allowed value
- * @cfg {number} [step=1] Delta when using the buttons or up/down arrow keys
- * @cfg {number|null} [pageStep] Delta when using the page-up/page-down keys. Defaults to 10 times #step.
- */
-OO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {
-       // Configuration initialization
-       config = $.extend( {
-               isInteger: false,
-               min: -Infinity,
-               max: Infinity,
-               step: 1,
-               pageStep: null
-       }, config );
-
-       // Parent constructor
-       OO.ui.NumberInputWidget.parent.call( this, config );
-
-       // Properties
-       this.input = new OO.ui.TextInputWidget( $.extend(
-               {
-                       disabled: this.isDisabled()
-               },
-               config.input
-       ) );
-       this.minusButton = new OO.ui.ButtonWidget( $.extend(
-               {
-                       disabled: this.isDisabled(),
-                       tabIndex: -1
-               },
-               config.minusButton,
-               {
-                       classes: [ 'oo-ui-numberInputWidget-minusButton' ],
-                       label: '−'
-               }
-       ) );
-       this.plusButton = new OO.ui.ButtonWidget( $.extend(
-               {
-                       disabled: this.isDisabled(),
-                       tabIndex: -1
-               },
-               config.plusButton,
-               {
-                       classes: [ 'oo-ui-numberInputWidget-plusButton' ],
-                       label: '+'
-               }
-       ) );
-
-       // Events
-       this.input.connect( this, {
-               change: this.emit.bind( this, 'change' ),
-               enter: this.emit.bind( this, 'enter' )
-       } );
-       this.input.$input.on( {
-               keydown: this.onKeyDown.bind( this ),
-               'wheel mousewheel DOMMouseScroll': this.onWheel.bind( this )
-       } );
-       this.plusButton.connect( this, {
-               click: [ 'onButtonClick', +1 ]
-       } );
-       this.minusButton.connect( this, {
-               click: [ 'onButtonClick', -1 ]
-       } );
-
-       // Initialization
-       this.setIsInteger( !!config.isInteger );
-       this.setRange( config.min, config.max );
-       this.setStep( config.step, config.pageStep );
-
-       this.$field = $( '<div>' ).addClass( 'oo-ui-numberInputWidget-field' )
-               .append(
-                       this.minusButton.$element,
-                       this.input.$element,
-                       this.plusButton.$element
-               );
-       this.$element.addClass( 'oo-ui-numberInputWidget' ).append( this.$field );
-       this.input.setValidation( this.validateNumber.bind( this ) );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.NumberInputWidget, OO.ui.Widget );
-
-/* Events */
-
-/**
- * A `change` event is emitted when the value of the input changes.
- *
- * @event change
- */
-
-/**
- * An `enter` event is emitted when the user presses 'enter' inside the text box.
- *
- * @event enter
- */
-
-/* Methods */
-
-/**
- * Set whether only integers are allowed
- * @param {boolean} flag
- */
-OO.ui.NumberInputWidget.prototype.setIsInteger = function ( flag ) {
-       this.isInteger = !!flag;
-       this.input.setValidityFlag();
-};
-
-/**
- * Get whether only integers are allowed
- * @return {boolean} Flag value
- */
-OO.ui.NumberInputWidget.prototype.getIsInteger = function () {
-       return this.isInteger;
-};
-
-/**
- * Set the range of allowed values
- * @param {number} min Minimum allowed value
- * @param {number} max Maximum allowed value
- */
-OO.ui.NumberInputWidget.prototype.setRange = function ( min, max ) {
-       if ( min > max ) {
-               throw new Error( 'Minimum (' + min + ') must not be greater than maximum (' + max + ')' );
-       }
-       this.min = min;
-       this.max = max;
-       this.input.setValidityFlag();
-};
-
-/**
- * Get the current range
- * @return {number[]} Minimum and maximum values
- */
-OO.ui.NumberInputWidget.prototype.getRange = function () {
-       return [ this.min, this.max ];
-};
-
-/**
- * Set the stepping deltas
- * @param {number} step Normal step
- * @param {number|null} pageStep Page step. If null, 10 * step will be used.
- */
-OO.ui.NumberInputWidget.prototype.setStep = function ( step, pageStep ) {
-       if ( step <= 0 ) {
-               throw new Error( 'Step value must be positive' );
-       }
-       if ( pageStep === null ) {
-               pageStep = step * 10;
-       } else if ( pageStep <= 0 ) {
-               throw new Error( 'Page step value must be positive' );
-       }
-       this.step = step;
-       this.pageStep = pageStep;
-};
-
-/**
- * Get the current stepping values
- * @return {number[]} Step and page step
- */
-OO.ui.NumberInputWidget.prototype.getStep = function () {
-       return [ this.step, this.pageStep ];
-};
-
-/**
- * Get the current value of the widget
- * @return {string}
- */
-OO.ui.NumberInputWidget.prototype.getValue = function () {
-       return this.input.getValue();
-};
-
-/**
- * Get the current value of the widget as a number
- * @return {number} May be NaN, or an invalid number
- */
-OO.ui.NumberInputWidget.prototype.getNumericValue = function () {
-       return +this.input.getValue();
-};
-
-/**
- * Set the value of the widget
- * @param {string} value Invalid values are allowed
- */
-OO.ui.NumberInputWidget.prototype.setValue = function ( value ) {
-       this.input.setValue( value );
-};
-
-/**
- * Adjust the value of the widget
- * @param {number} delta Adjustment amount
- */
-OO.ui.NumberInputWidget.prototype.adjustValue = function ( delta ) {
-       var n, v = this.getNumericValue();
-
-       delta = +delta;
-       if ( isNaN( delta ) || !isFinite( delta ) ) {
-               throw new Error( 'Delta must be a finite number' );
-       }
-
-       if ( isNaN( v ) ) {
-               n = 0;
-       } else {
-               n = v + delta;
-               n = Math.max( Math.min( n, this.max ), this.min );
-               if ( this.isInteger ) {
-                       n = Math.round( n );
-               }
-       }
-
-       if ( n !== v ) {
-               this.setValue( n );
-       }
-};
-
-/**
- * Validate input
- * @private
- * @param {string} value Field value
- * @return {boolean}
- */
-OO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {
-       var n = +value;
-       if ( isNaN( n ) || !isFinite( n ) ) {
-               return false;
-       }
-
-       /*jshint bitwise: false */
-       if ( this.isInteger && ( n | 0 ) !== n ) {
-               return false;
-       }
-       /*jshint bitwise: true */
-
-       if ( n < this.min || n > this.max ) {
-               return false;
-       }
-
-       return true;
-};
-
-/**
- * Handle mouse click events.
- *
- * @private
- * @param {number} dir +1 or -1
- */
-OO.ui.NumberInputWidget.prototype.onButtonClick = function ( dir ) {
-       this.adjustValue( dir * this.step );
-};
-
-/**
- * Handle mouse wheel events.
- *
- * @private
- * @param {jQuery.Event} event
- */
-OO.ui.NumberInputWidget.prototype.onWheel = function ( event ) {
-       var delta = 0;
-
-       // Standard 'wheel' event
-       if ( event.originalEvent.deltaMode !== undefined ) {
-               this.sawWheelEvent = true;
-       }
-       if ( event.originalEvent.deltaY ) {
-               delta = -event.originalEvent.deltaY;
-       } else if ( event.originalEvent.deltaX ) {
-               delta = event.originalEvent.deltaX;
-       }
-
-       // Non-standard events
-       if ( !this.sawWheelEvent ) {
-               if ( event.originalEvent.wheelDeltaX ) {
-                       delta = -event.originalEvent.wheelDeltaX;
-               } else if ( event.originalEvent.wheelDeltaY ) {
-                       delta = event.originalEvent.wheelDeltaY;
-               } else if ( event.originalEvent.wheelDelta ) {
-                       delta = event.originalEvent.wheelDelta;
-               } else if ( event.originalEvent.detail ) {
-                       delta = -event.originalEvent.detail;
-               }
-       }
-
-       if ( delta ) {
-               delta = delta < 0 ? -1 : 1;
-               this.adjustValue( delta * this.step );
-       }
-
-       return false;
-};
-
-/**
- * Handle key down events.
- *
- * @private
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.NumberInputWidget.prototype.onKeyDown = function ( e ) {
-       if ( !this.isDisabled() ) {
-               switch ( e.which ) {
-                       case OO.ui.Keys.UP:
-                               this.adjustValue( this.step );
-                               return false;
-                       case OO.ui.Keys.DOWN:
-                               this.adjustValue( -this.step );
-                               return false;
-                       case OO.ui.Keys.PAGEUP:
-                               this.adjustValue( this.pageStep );
-                               return false;
-                       case OO.ui.Keys.PAGEDOWN:
-                               this.adjustValue( -this.pageStep );
-                               return false;
-               }
-       }
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {
-       // Parent method
-       OO.ui.NumberInputWidget.parent.prototype.setDisabled.call( this, disabled );
-
-       if ( this.input ) {
-               this.input.setDisabled( this.isDisabled() );
-       }
-       if ( this.minusButton ) {
-               this.minusButton.setDisabled( this.isDisabled() );
-       }
-       if ( this.plusButton ) {
-               this.plusButton.setDisabled( this.isDisabled() );
-       }
-
-       return this;
-};
-
-/**
- * ToggleSwitches are switches that slide on and off. Their state is represented by a Boolean
- * value (`true` for ‘on’, and `false` otherwise, the default). The ‘off’ state is represented
- * visually by a slider in the leftmost position.
- *
- *     @example
- *     // Toggle switches in the 'off' and 'on' position.
- *     var toggleSwitch1 = new OO.ui.ToggleSwitchWidget();
- *     var toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {
- *         value: true
- *     } );
- *
- *     // Create a FieldsetLayout to layout and label switches
- *     var fieldset = new OO.ui.FieldsetLayout( {
- *        label: 'Toggle switches'
- *     } );
- *     fieldset.addItems( [
- *         new OO.ui.FieldLayout( toggleSwitch1, { label: 'Off', align: 'top' } ),
- *         new OO.ui.FieldLayout( toggleSwitch2, { label: 'On', align: 'top' } )
- *     ] );
- *     $( 'body' ).append( fieldset.$element );
- *
- * @class
- * @extends OO.ui.ToggleWidget
- * @mixins OO.ui.mixin.TabIndexedElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {boolean} [value=false] The toggle switch’s initial on/off state.
- *  By default, the toggle switch is in the 'off' position.
- */
-OO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {
-       // Parent constructor
-       OO.ui.ToggleSwitchWidget.parent.call( this, config );
-
-       // Mixin constructors
-       OO.ui.mixin.TabIndexedElement.call( this, config );
-
-       // Properties
-       this.dragging = false;
-       this.dragStart = null;
-       this.sliding = false;
-       this.$glow = $( '<span>' );
-       this.$grip = $( '<span>' );
-
-       // Events
-       this.$element.on( {
-               click: this.onClick.bind( this ),
-               keypress: this.onKeyPress.bind( this )
-       } );
-
-       // Initialization
-       this.$glow.addClass( 'oo-ui-toggleSwitchWidget-glow' );
-       this.$grip.addClass( 'oo-ui-toggleSwitchWidget-grip' );
-       this.$element
-               .addClass( 'oo-ui-toggleSwitchWidget' )
-               .attr( 'role', 'checkbox' )
-               .append( this.$glow, this.$grip );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );
-OO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.mixin.TabIndexedElement );
-
-/* Methods */
-
-/**
- * Handle mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               this.setValue( !this.value );
-       }
-       return false;
-};
-
-/**
- * Handle key press events.
- *
- * @private
- * @param {jQuery.Event} e Key press event
- */
-OO.ui.ToggleSwitchWidget.prototype.onKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               this.setValue( !this.value );
-               return false;
-       }
-};
-
-}( OO ) );
index c855f16..4db45f4 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index 04c5299..79f644e 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index f5b6693..0c5f6f9 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index dbb3411..54f8aef 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index 2a383df..ffa8905 100644 (file)
@@ -4,20 +4,20 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                },
                "progressive": {
-                       "color": "#347BFF"
+                       "color": "#347bff"
                },
                "constructive": {
-                       "color": "#00AF89"
+                       "color": "#00af89"
                },
                "destructive": {
-                       "color": "#D11D13"
+                       "color": "#d11d13"
                },
                "warning": {
-                       "color": "#FF5D00"
+                       "color": "#ff5d00"
                }
        },
        "images": {
index a8ace26..489d6ca 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index f7d63a1..28188ea 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index d5c0662..c3263e2 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index 47282d9..b713146 100644 (file)
@@ -4,20 +4,20 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                },
                "progressive": {
-                       "color": "#347BFF"
+                       "color": "#347bff"
                },
                "constructive": {
-                       "color": "#00AF89"
+                       "color": "#00af89"
                },
                "destructive": {
-                       "color": "#D11D13"
+                       "color": "#d11d13"
                },
                "warning": {
-                       "color": "#FF5D00"
+                       "color": "#ff5d00"
                }
        },
        "images": {
index 197989b..c53946f 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index ddd95ad..809bc6a 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index cec844c..7029bc2 100644 (file)
@@ -4,20 +4,20 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                },
                "progressive": {
-                       "color": "#347BFF"
+                       "color": "#347bff"
                },
                "constructive": {
-                       "color": "#00AF89"
+                       "color": "#00af89"
                },
                "destructive": {
-                       "color": "#D11D13"
+                       "color": "#d11d13"
                },
                "warning": {
-                       "color": "#FF5D00"
+                       "color": "#ff5d00"
                }
        },
        "images": {
index 2a3a3c5..c216c37 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index 3e74ac6..cf19c6c 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
index 0c3b4eb..c332e3c 100644 (file)
@@ -4,20 +4,20 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                },
                "progressive": {
-                       "color": "#347BFF"
+                       "color": "#347bff"
                },
                "constructive": {
-                       "color": "#00AF89"
+                       "color": "#00af89"
                },
                "destructive": {
-                       "color": "#D11D13"
+                       "color": "#d11d13"
                },
                "warning": {
-                       "color": "#FF5D00"
+                       "color": "#ff5d00"
                }
        },
        "images": {
index dab0bea..0bd0e73 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <g id="add">
         <path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
     </g>
index 35322d0..bedfe5a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="add">
         <path id="plus" d="M13 6h-2v5H6v2h5v5h2v-5h5v-2h-5z"/>
     </g>
index fad6a26..9cf7fab 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 13.44v-2.88l-1.8-.3c-.1-.397-.3-.794-.6-1.39l1.1-1.49-2.1-2.088-1.5 1.093c-.5-.298-1-.497-1.4-.596L13.5 4h-2.9l-.3 1.79c-.5.098-.9.297-1.4.595L7.4 5.292 5.3 7.38l1 1.49c-.3.496-.4.894-.6 1.39l-1.7.2v2.882l1.8.298c.1.497.3.894.6 1.39l-1 1.492 2.1 2.087 1.5-1c.4.2.9.395 1.4.594l.3 1.79h3l.3-1.79c.5-.1.9-.298 1.4-.596l1.5 1.092 2.1-2.08-1.1-1.49c.3-.496.5-.993.6-1.39l1.5-.3zm-8 1.492c-1.7 0-3-1.292-3-2.982 0-1.69 1.3-2.98 3-2.98s3 1.29 3 2.98-1.3 2.982-3 2.982z"/>
 </svg>
index 55621b9..74bb91d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="alert">
         <path id="point" d="M11 16h2v2h-2z"/>
         <path id="stroke" d="M13.516 10h-3L11 15h2z"/>
index bdf0ac2..c5c5687 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FF5D00 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ff5d00 }</style>
     <g id="alert">
         <path id="point" d="M11 16h2v2h-2z"/>
         <path id="stroke" d="M13.516 10h-3L11 15h2z"/>
index fef1152..197e037 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H9c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm-5.5 9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0-12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-center"/>
 </svg>
index 2b0bc65..663ba94 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 9h6c.554 0 1 .446 1 1v5c0 .554-.446 1-1 1H4c-.554 0-1-.446-1-1v-5c0-.554.446-1 1-1zm9.5 0h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm0 3h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1zm-10-9h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1zm0 12h17a.5.5 0 0 1 0 1h-17a.5.5 0 0 1 0-1z" id="align-float-left"/>
 </svg>
index d126163..41be069 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 9h-6c-.554 0-1 .446-1 1v5c0 .554.446 1 1 1h6c.554 0 1-.446 1-1v-5c0-.554-.446-1-1-1zm-9.5 0h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm0 3h-7a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1zm10-9h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1zm0 12h-17a.5.5 0 0 0 0 1h17a.5.5 0 0 0 0-1z" id="align-float-right"/>
 </svg>
index 0351e89..3dc5125 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M13.3 6.3l6.3 5.7-6.3 5.7v-3.8H12c-3.2 0-6.3 1.3-7.6 3.8 0-4.7 2.8-7.6 7.9-7.6h.9V6.3z"/>
 </svg>
index 3bb7096..0e2c2f3 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10.7 6.3L4.4 12l6.3 5.7v-3.8H12c3.2 0 6.3 1.3 7.6 3.8 0-4.7-2.8-7.6-7.9-7.6h-.9V6.3z"/>
 </svg>
index 6dacb76..3c5c48b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 12H6c-1.7 0-3 1.3-3 3h13v3l5-4.5L16 9v3z"/>
 </svg>
index 269de66..da0c6ec 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M8 12h10c1.7 0 3 1.3 3 3H8v3l-5-4.5L8 9v3z"/>
 </svg>
index 19df2c0..80e7992 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 10h4V5h-4v5zm-5 2h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zM5 3h13v16H8c-1.7 0-3-1.3-3-3V3z"/>
 </svg>
index 0fba841..f0a4a6a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 10H7V5h4v5zm5 2H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zm6-2H5v16h10c1.7 0 3-1.3 3-3V3z"/>
 </svg>
index b1636c1..77febef 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 11l-6 7-4-4-1 1 5 5 7-8z"/>
     <path d="M17 14V3H4v13c0 1.7 1.3 3 3 3h5l-3-3H6v-1h2.6l1-1H6v-1h9v1h-2l1 1h2l1-1zM6 5h4v1H6V5zm0 2h4v1H6V7zm0 2h4v1H6V9zm9 3H6v-1h9v1zm-4-2V5h4v5h-4z"/>
 </svg>
index d331123..c80c83f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M5 11l6 7 4-4 1 1-5 5-7-8z"/>
     <path d="M9 14V3h13v13c0 1.7-1.3 3-3 3h-5l3-3h3v-1h-2.6l-1-1H20v-1h-9v1h2l-1 1h-2l-1-1zm11-9h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm-9 3h9v-1h-9v1zm4-2V5h-4v5h4z"/>
 </svg>
index 5317700..0ed1d31 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="article-redirect">
         <path id="arrow" d="M18.1 14.2L23 18l-4.9 4.8v-2.2c-1.7 0-2.9-.2-4.3-1.2-1.2-.8-2.5-2.6-2.3-4.1 1.4 1 2.9 1.5 4.4 1.5.7 0 1.4-.1 2.1-.3l.1-2.3"/>
         <path id="page" d="M5 3v13c0 1.7 1.3 3 3 3h3.375c-.157-.205-.3-.43-.438-.656-.42-.688-.77-1.483-.843-2.344H7v-1h3.125l.125-1H7v-1h3.375l.03-.188.283.188H16v1h-3.906l.22.156c.523.375 1.065.64 1.592.844H16v.406c.208-.013.418-.07.625-.094.068-1.294.125-3.874.125-3.874l1.25.968V3H5zm2 2h4v1H7V5zm5 0h4v5h-4V5zM7 7h4v1H7V7zm0 2h4v1H7V9zm0 2h9v1H7v-1z"/>
index 97bae5a..1a5b22a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="article-redirect">
         <path id="arrow" d="M5.9 14.2L1 18l4.9 4.8v-2.2c1.7 0 2.9-.2 4.3-1.2 1.2-.8 2.5-2.6 2.3-4.1-1.4 1-2.9 1.5-4.4 1.5-.7 0-1.4-.1-2.1-.3l-.1-2.3"/>
         <path id="page" d="M19 3v13c0 1.7-1.3 3-3 3h-3.375c.157-.205.3-.43.438-.656.42-.688.77-1.483.843-2.344H17v-1h-3.125l-.125-1H17v-1h-3.375l-.03-.188-.283.188H8v1h3.906l-.22.156a7.097 7.097 0 0 1-1.592.844H8v.406c-.208-.013-.418-.07-.625-.094a178.903 178.903 0 0 1-.125-3.874L6 12.405V3zm-2 2h-4v1h4zm-5 0H8v5h4zm5 2h-4v1h4zm0 2h-4v1h4zm0 2H8v1h9z"/>
index 545ea93..de091d9 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19.1 18.5c.6-.7.9-1.5.9-2.5 0-2.2-1.8-4-4-4s-4 1.8-4 4 1.8 4 4 4c.7 0 1.3-.1 1.8-.4l2.7 2.7 1.1-1.1-2.5-2.7zm-3.1-.3c-1.2 0-2.2-1-2.2-2.3 0-1.2 1-2.2 2.2-2.2 1.2 0 2.3 1 2.3 2.2-.1 1.3-1.1 2.3-2.3 2.3zM11.8 13c.3-.4.6-.7 1-1H7v-1h9s1.2 0 2 .6V3H5v13c0 1.7 1.3 3 3 3h3.8c-.6-.8-1-1.9-1-3H7v-1h3.9l.3-1H7v-1h4.8zm.2-8h4v5h-4V5zM7 5h4v1H7V5zm0 2h4v1H7V7zm0 2h4v1H7V9z"/>
 </svg>
index b93fd7c..abb7ce7 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7.5 18.5c-.6-.7-.9-1.5-.9-2.5 0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4c-.7 0-1.3-.1-1.8-.4l-2.7 2.7L5 21.2l2.5-2.7zm3.1-.3c1.2 0 2.2-1 2.2-2.3 0-1.2-1-2.2-2.2-2.2-1.2 0-2.3 1-2.3 2.2.1 1.3 1.1 2.3 2.3 2.3zm4.2-5.2c-.3-.4-.6-.7-1-1h5.8v-1h-9s-1.2 0-2 .6V3h13v13c0 1.7-1.3 3-3 3h-3.8c.6-.8 1-1.9 1-3h3.8v-1h-3.9l-.3-1h4.2v-1h-4.8zm-.2-8h-4v5h4V5zm5 0h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9z"/>
 </svg>
index 13f6ede..7ed3635 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17.5 14V9c0-3-2.3-5-5.5-5S6.5 6 6.5 9v5c0 2 0 3-2 3v1h15v-1c-2 0-2-1-2-3zM12 20H9c0 1 1.6 2 3 2s3-1 3-2h-3z"/>
 </svg>
index 7dfcb1c..c032294 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17.8 14.7l1.7-4.7c1-2.8-.5-5.5-3.5-6.6s-5.9 0-6.9 2.8l-1.7 4.7c-.7 1.9-1 2.8-2.9 2.1l-.3 1 14.1 5.1.3-.9c-1.9-.7-1.5-1.6-.8-3.5zM12 19.8l-2.8-1c-.3.9.8 2.4 2.1 2.9s3.2.1 3.5-.9l-2.8-1z"/>
 </svg>
index 83ed027..34ec94b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6.21 14.7L4.51 10c-1-2.8.5-5.5 3.5-6.6 3-1.1 5.9 0 6.9 2.8l1.7 4.7c.7 1.9 1 2.8 2.9 2.1l.3 1-14.1 5.1-.3-.9c1.9-.7 1.5-1.6.8-3.5zm5.8 5.1l2.8-1c.3.9-.8 2.4-2.1 2.9s-3.2.1-3.5-.9l2.8-1z"/>
 </svg>
index 4d8c673..d463577 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 12l-3-2-1 4-1-4-3 2 2-3-4-1 4-1-2-3 3 2 1-4 1 4 3-2-2 3 4 1-4 1 2 3z"/>
 </svg>
index 5058629..2b8ee7a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
 </svg>
index 9b3cdeb..41d644a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
     <g id="up">
         <path id="arrow" d="M15.5 9h7L19 3z"/>
index 3d00d67..4101ddf 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
     <g id="up">
         <path id="arrow" d="M1.5 9h7L5 3z"/>
index 973a140..2cf60bc 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
 </svg>
index 551069e..a2f916e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 4c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm5 9H7v-2h10v2z"/>
 </svg>
index 2848a10..1d41a44 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
 </svg>
index 92994a6..ca592ed 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
 </svg>
index 97f3d2e..519f850 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 18h3L14 6h-3L6 18h3l1.25-3h4.5L16 18zm-4.917-5L12.5 9.6l1.417 3.4h-2.834z" id="bold-a"/>
 </svg>
index 2e11204..e43c4b5 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-arab-ain">
         <path id="arab-ain" d="M9.337 13.616c0 1.35 1.386 2.1 4.16 2.258l2.186-.03.318.045c-.03.12-.25.34-.66.65l-.09.06c-1.233.93-2.42 1.394-3.56 1.394-1.14 0-2.043-.33-2.71-.99-.65-.66-.973-1.56-.973-2.7.006-1.353.567-2.572 1.685-3.657v-.044l-.606-.55a.952.952 0 0 1-.222-.63c0-.49.24-1.11.72-1.863.65-1.045 1.302-1.565 1.957-1.56.886.005 1.618.42 2.194 1.246.325.48-.03.55-1.064.22-.843-.33-1.528-.05-2.055.826l.016.074 1.125.866.05.005c1.405-.497 2.42-.74 3.044-.725-.06.116-.14.36-.244.732a27.75 27.75 0 0 1-.304.982l-.125.372-.386.05c-1.743.24-2.992.716-3.745 1.43-.465.463-.7.972-.704 1.524"/>
     </g>
index e55b63f..7f24cbc 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-arab-dad">
         <path id="arab-dad" d="M16.41 8.232l-1.675-.665L15.43 6l1.687.64-.707 1.592m.775 3.078c-.51-.286-1-.427-1.476-.423-.478 0-.99.205-1.54.616l-.505.38.006.024c1.085.066 1.935.1 2.55.1h.315c.57-.022.994-.065 1.278-.132-.067-.17-.275-.36-.625-.566h-.006M10.38 14.6c-.016-.905-.33-1.87-.937-2.9l1.294-1.73.118.15c.267.337.504.925.713 1.767l.064.05c.496-.007.942-.17 1.338-.484v-.006l1.732-1.53c.68-.6 1.282-.9 1.807-.9.383.003.85.194 1.394.57.55.378.884.697 1 .96.063.15.094.385.094.71 0 .694-.11 1.227-.33 1.596-.193.31-.474.555-.845.734-.438.208-1.55.312-3.333.312-.8 0-1.794-.02-2.982-.064l-.142.43c-.254.67-.463 1.112-.625 1.323-.724.937-1.785 1.405-3.182 1.405-1.71-.006-2.56-.92-2.56-2.74.003-.94.278-1.814.824-2.618.15-.216.298-.367.444-.454.225-.133.288-.09.188.124-.396.862-.596 1.548-.6 2.058.008 1.177.752 1.768 2.232 1.772 1.038-.004 1.803-.182 2.295-.535"/>
     </g>
index 416e0f5..3ad81f5 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-armn-to">
         <path id="armn-to" d="M13.86 16.257c.124 0 .254-.026.39-.078.135-.06.257-.15.367-.28a1.43 1.43 0 0 0 .273-.517c.073-.214.11-.48.11-.798V13h-1.14c-.14 0-.284.026-.43.078a.905.905 0 0 0-.383.258c-.11.125-.2.294-.274.508-.067.213-.1.487-.1.82 0 .34.035.47.108.695.08.21.18.39.29.53.12.13.25.23.39.29.14.05.276.07.406.07m-2.97-7.84a2.67 2.67 0 0 0-.975.45 2.1 2.1 0 0 0-.672.813c-.16.342-.242.78-.242 1.31V18H6v-7.188c0-.776.15-1.455.453-2.04a4.227 4.227 0 0 1 1.234-1.467c.52-.39 1.13-.685 1.83-.883a8.114 8.114 0 0 1 2.225-.297c.526 0 1.04.044 1.54.133.504.088.98.22 1.43.398.447.172.858.388 1.233.65.375.26.698.564.97.913.275.34.49.73.64 1.17.15.43.226 1.09.226 1.61h1.36v2.04h-1.36v1.6c0 .58-.102 1.09-.31 1.54-.21.44-.49.81-.844 1.11-.35.302-.834.53-1.297.687-.465.15-.954.226-1.47.226-.51 0-.997-.08-1.46-.235a3.46 3.46 0 0 1-1.22-.703 3.452 3.452 0 0 1-.836-1.174c-.203-.472-.304-1.027-.304-1.662s.1-1.18.32-1.64c.21-.46.49-.684.85-.976.35-.297.76-.513 1.22-.648.452-.14.93-.21 1.43-.21h1.13c-.01-.49-.04-1.044-.24-1.36a2.26 2.26 0 0 0-.77-.767 3.234 3.234 0 0 0-.986-.427c-.375-.09-.578-.094-1.1-.094-.52 0-.64.02-1.01.102z"/>
     </g>
index 78ab202..2ba09bc 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-b">
         <path id="b" d="M7 18h6c2 0 4-1 4-3 0-1.064.01-1.975-1.99-3 2-.975 1.99-1.935 1.99-3 0-2-2-3-4-3H7v12zm7-8c0 1 0 1-2 1h-2V8h2c2 0 2 0 2 1v1zm-2 6h-2v-3h2c2 0 2 0 2 1v1s0 1-2 1z"/>
     </g>
index 60b6416..3a6ec97 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-cyrl-be">
         <path id="cyrl-be" d="M7 6h9v2h-6v3h2.65c.892 0 1.632.11 2.22.327.587.218 1.087.622 1.5 1.21.42.59.63 1.188.63 1.98 0 .812-.21 1.397-.63 1.976-.418.578-.897.974-1.436 1.187-.533.213-1.295.32-2.286.32h-5.65m4.768-2c.75 0 1.28-.05 1.584-.12.305-.077.57-.247.792-.51.23-.26.343-.472.343-.854 0-.557-.2-.868-.596-1.12-.4-.255-1.07-.397-2.02-.397H10v3"/>
     </g>
index 740dcee..490c615 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-cyrl-te">
         <path id="te" d="M11 18V8H7V6h11v2h-4v10"/>
     </g>
index f0edc48..91f80dc 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-cyrl-zhe">
         <path id="cyrl-zhe" d="M13 6v5.154c.328-.033.537-.18.705-.447.168-.266.4-.873.698-1.82.39-1.242.79-2.034 1.197-2.375.403-.336 1.075-.504 2.014-.504L18 6v1.78l-.386-.008c-.4 0-.69.062-.878.187-.186.112-.337.3-.452.55-.115.25-.286.76-.512 1.533-.12.41-.25.755-.392 1.032-.137.275-.383.536-.738.78.44.156.8.465 1.084.926.288.455.603 1.103.944 1.943L18 18h-2.314l-1.17-3.08-.113-.253-.24-.56c-.247-.57-.45-.933-.61-1.09A.726.726 0 0 0 13 12.78V18h-2v-5.22c-.226 0-.382.077-.546.23-.164.15-.368.517-.612 1.097l-.246.56-.113.253L8.313 18H6l1.33-3.267c.327-.808.635-1.447.923-1.92.293-.476.663-.793 1.11-.95-.355-.244-.603-.5-.745-.772a6.357 6.357 0 0 1-.392-1.04c-.222-.76-.39-1.26-.505-1.52-.11-.25-.26-.44-.45-.57-.18-.12-.49-.18-.912-.18H6V6l.386.008c.953 0 1.63.17 2.034.512.4.347.79 1.136 1.177 2.366.3.954.534 1.564.698 1.83.168.26.377.405.705.438V6.002"/>
     </g>
index 14884f7..1954e93 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-f">
         <path id="f" d="M16 8V6H8v12h3v-5h4v-2h-4V8z"/>
     </g>
index 2f359c7..03f9519 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-g">
         <path id="g" d="M12 14v-2h5v4.203c-.497.475-1.22.894-2.166 1.26A7.994 7.994 0 0 1 11.97 18c-1.23 0-2.303-.253-3.217-.76a4.908 4.908 0 0 1-2.062-2.185A7.008 7.008 0 0 1 6 11.96c0-1.208.26-2.282.77-3.222.518-.94 1.27-1.66 2.26-2.16.754-.386 1.693-.58 2.816-.58 1.46 0 2.6.304 3.418.91.825.603 1.354 1.436 1.59 2.502l-2.36.435a2.433 2.433 0 0 0-.94-1.346c-.454-.34-1.022-.5-1.707-.5-1.038 0-1.864.32-2.48.97-.61.65-.914 1.61-.914 2.89 0 1.375.31 2.41.93 3.1.62.687 1.434 1.03 2.44 1.03.497 0 .995-.095 1.49-.285.505-.196 1.334-.57 1.69-.846v-.868"/>
     </g>
index 391127f..290fd4c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-geor-man">
         <path id="geor-man" d="M13.832 14.06c0-1.714-.394-2.572-1.182-2.572-.868 0-1.302.78-1.302 2.338-.01 1.624.42 2.436 1.295 2.436.793 0 1.19-.734 1.19-2.2m2.167 0C16 16.686 14.884 18 12.65 18 10.218 18 9 16.614 9 13.84c0-2.737 1.217-4.105 3.65-4.105.842 0 1.183.63 1.183.63v-1.58c0-.788-.45-1.183-1.347-1.183-.572 0-.858.374-.858 1.123h-2.34C9.29 6.908 10.35 6 12.462 6 14.83 6 16.01 6.946 16 8.84"/>
     </g>
index 2041445..356145b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-l">
         <path id="l" d="M8 18V6h3v10h5v2"/>
     </g>
index 667bec4..82e1c0b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-n">
         <path id="n" d="M7 18V6h3l4 8V6h3v12h-3l-4-8v8H7"/>
     </g>
index cb1dd89..18aef7b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="bold-v">
         <path id="v" d="M10.5 18L6 6h3l3 8 3-8h3l-4.5 12"/>
     </g>
index 9ff43d3..c383e61 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 7c-1.7 0-3 1.3-3 3 0-1.7-1.3-3-3-3H3v13h6c1.7 0 3 1 3 2 0-1 1.3-2 3-2h6V7h-6zm5 12h-5c-1.7 0-2 .4-2 .4v-8.9C13 9.1 14.1 8 15.5 8H20v11z"/>
 </svg>
index 6b07962..390902f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9 7c1.7 0 3 1.3 3 3 0-1.7 1.3-3 3-3h6v13h-6c-1.7 0-3 1-3 2 0-1-1.3-2-3-2H3V7h6zM4 19h5c1.7 0 2 .4 2 .4v-8.9C11 9.1 9.9 8 8.5 8H4v11z"/>
 </svg>
index bf39564..ea474cb 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 5H8c-1.1 0-2 .9-2 2v3h3v11l4-3 4 3V7c0-1.1-.9-2-2-2zM9 9H7V7c0-.6.4-1 1-1h1v3z"/>
 </svg>
index 729b8c2..9049881 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M8 5h7c1.1 0 2 .9 2 2v3h-3v11l-4-3-4 3V7c0-1.1.9-2 2-2zm6 4h2V7c0-.6-.4-1-1-1h-1v3z"/>
 </svg>
index ae38327..28fac21 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9-.3.3-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4.3.3.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4-.3-.3-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9.3-.3.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8 0-.3.1-.6.3-.8zM12 8c1.7 0 3 1.3 3 3s-1.3 3-3 3-3-1.3-3-3 1.3-3 3-3m0-1c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z"/>
     <path d="M12 8c1.7 0 3 1.3 3 3s-1.3 3-3 3-3-1.3-3-3 1.3-3 3-3m0-1c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z"/>
 </svg>
index 762e641..85c7273 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 6v11c0 1.7 1.3 3 3 3h15V6H3zm2.5 1C6.3 7 7 7.7 7 8.5S6.3 10 5.5 10 4 9.3 4 8.5 4.7 7 5.5 7zM20 19H6c-1.1 0-2-.9-2-2v-6h16v8z"/>
 </svg>
index d6378bf..38778ec 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 6v11c0 1.7-1.3 3-3 3H3V6h18zm-2.5 1c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5S20 9.3 20 8.5 19.3 7 18.5 7zM4 19h14c1.1 0 2-.9 2-2v-6H4v8z"/>
 </svg>
index 5fb8675..f820d7a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 5v10c0 1.7 1.3 3 3 3h14V8c0-1.7-1.3-3-3-3H4zm2 1a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zm4 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2zM5 9h3v2H5V9zm4 0h3v2H9V9zm4 0h3v2h-3V9zm4 0h3v2h-3V9zM5 12h3v2H5v-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2zM5 15h3v2H7c-1.195 0-2-.805-2-2zm4 0h3v2H9v-2zm4 0h3v2h-3v-2zm4 0h3v2h-3v-2z"/>
 </svg>
index 8f06883..e430f0b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 5v10c0 1.7-1.3 3-3 3H4V8c0-1.7 1.3-3 3-3h14zm-2 1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-4 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2zM7 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm13 3h-3v2h3V9zm-4 0h-3v2h3V9zm-4 0H9v2h3V9zM8 9H5v2h3V9zm12 3h-3v2h3v-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2zm12 3h-3v2h1c1.195 0 2-.805 2-2zm-4 0h-3v2h3v-2zm-4 0H9v2h3v-2zm-4 0H5v2h3v-2z"/>
 </svg>
index 919dba4..5970559 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <g id="cancel">
         <path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
     </g>
index 2bf3370..553e9f6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="cancel">
         <path id="circle-with-strike" d="M12 5.022a6.98 6.98 0 0 0-.003 13.956 6.98 6.98 0 0 0-.002-13.956zM6.885 12c0-1.092.572-3.25.93-2.93l7.113 7.114c.487.525-1.838.93-2.93.93A5.113 5.113 0 0 1 6.884 12zm9.298 2.93L9.07 7.815c-.445-.483 1.837-.93 2.93-.93a5.112 5.112 0 0 1 5.114 5.113c0 1.092-.364 3.542-.93 2.93z"/>
     </g>
index b9b6b3a..28490a3 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 13.1l8.9 8.9c.8-.8.8-2 0-2.8l-6.1-6.1 6-6.1c.8-.8.8-2 0-2.8L7 13.1z"/>
 </svg>
index 21c2a33..1a3447e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16.5 13.1L7.6 22c-.8-.8-.8-2 0-2.8l6.1-6.1-6-6.1c-.8-.8-.8-2 0-2.8l8.8 8.9z"/>
 </svg>
index 5e3cfcf..04e6e5e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 16l8.9-8.9c-.8-.8-2-.8-2.8 0L12 13.2l-6.1-6c-.8-.8-2-.8-2.8 0L12 16z"/>
 </svg>
index 3cc20fd..2cbec64 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 6.5l8.9 8.9c-.8.8-2 .8-2.8 0L12 9.3l-6.1 6c-.8.8-2 .8-2.8 0L12 6.5z"/>
 </svg>
index 4bc0ba2..e39d780 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="regular-expression">
         <path id="upper-case" d="M7.53 7L4 17h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 7h-2.12zm1.064 1.53L9.938 13H7.25l1.344-4.47z"/>
         <path id="lower-case" d="M18.55 17l-.184-1.035h-.055c-.35.44-.71.747-1.08.92-.37.167-.85.25-1.44.25-.564 0-.955-.208-1.377-.625-.42-.418-.627-1.012-.627-1.784 0-.808.283-1.403.846-1.784.568-.386 1.193-.607 2.208-.64l1.322-.04v-.335c0-.772-.396-1.158-1.187-1.158-.61 0-1.325.18-2.147.55l-.688-1.4c.877-.46 1.85-.69 2.916-.69 1.024 0 1.59.22 2.134.662.545.445.818 1.12.818 2.03V17h-1.45m-.394-3.527l-.802.027c-.604.018-1.054.127-1.35.327-.294.2-.442.504-.442.912 0 .58.336.87 1.008.87.48 0 .865-.137 1.152-.414.29-.277.436-.645.436-1.103v-.627"/>
index 7dbd0ac..07a5614 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
 </svg>
index 41e7160..eb495e4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
 </svg>
index 0f4ef78..1c198c5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
 </svg>
index fd08148..3084e5a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M17 7.5L9.5 15 6 11.5 4.5 13l5 5L20 7.5c-.706-.706-2.294-.706-3 0z" id="check"/>
 </svg>
index f1291f9..b96e771 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <circle cx="12" cy="12" r="6"/>
 </svg>
index 7cae5db..ddc7b85 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <circle cx="12" cy="12" r="6"/>
 </svg>
index 40d3aab..a6bf1ce 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 12h9v-1H7v1zm0 2h9v-1H7v1zm0 2h9v-1H7v1zm4-9H7v1h4V7zm0 2H7v1h4V9zm0-4H7v1h4V5zm5-2h2v16H8c-1.7 0-3-1.3-3-3V3h8v7l1.5-2 1.5 2V3z"/>
 </svg>
index c0cd449..72472b6 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 12H7v-1h9v1zm0 2H7v-1h9v1zm0 2H7v-1h9v1zm-4-9h4v1h-4V7zm0 2h4v1h-4V9zm0-4h4v1h-4V5zM7 3H5v16h10c1.7 0 3-1.3 3-3V3h-8v7L8.5 8 7 10V3z"/>
 </svg>
index 0738205..7a6b1c0 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="clear">
         <path id="circle-with-cross" d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm4 11l-1 1-3-3-3 3-1-1 3-3-3-3 1-1 3 3 3-3 1 1-3 3 3 3z"/>
     </g>
index a134c65..6eb6e0a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3 12l-4-3V8h2v5l1.7 1.2c1.3.9 1 1.9.3 2.8z"/>
 </svg>
index cd7ce21..072276b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="close">
         <path id="cross" d="M17.4 9.1c.8-.8.8-2 0-2.8L12 11.8 7.4 7.2 6 8.6l4.6 4.6-4 4c-.8.8-.8 2 0 2.8l5.4-5.4 4.6 4.6 1.4-1.4-4.6-4.6z"/>
     </g>
index ee8a82d..19ddef6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="close">
         <path id="cross" d="M6.6 9.1c-.8-.8-.8-2 0-2.8l5.4 5.5 4.6-4.6L18 8.6l-4.6 4.6 4 4c.8.8.8 2 0 2.8L12 14.6l-4.6 4.6L6 17.8l4.6-4.6z"/>
     </g>
index 8d3d37d..3b129c0 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="code">
         <path id="left-bracket" d="M4 12v-1h1c1 0 1 0 1-1V7.614c0-.514.024-.896.073-1.142.054-.252.14-.463.257-.633.204-.28.473-.48.808-.59.335-.11.872-.25 1.835-.25H10v1h-.752c-.457 0-.77.19-.936.406-.167.216-.312.446-.312 1.07v1.856c0 .73-.04 1.18-.244 1.493-.2.307-.562.53-1.09.667.535.155.9.385 1.096.688.2.31.238.76.238 1.49v1.86c0 .62.145.85.312 1.06.166.22.48.41.936.41H10v1H8.973c-.963 0-1.5-.133-1.835-.248a1.578 1.578 0 0 1-.808-.59 1.68 1.68 0 0 1-.257-.626C6.023 16.283 6 15.9 6 15.386V13c0-1 0-1-1-1H4z"/>
         <use transform="matrix(-1 0 0 1 24 0)" id="right-bracket" width="24" height="24" xlink:href="#left-bracket"/>
index 926f98d..239a248 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="collapse">
         <path id="arrow" d="M6.697 15.714L12 10.412l5.303 5.302 1.414-1.414L12 7.583 5.283 14.3z"/>
     </g>
index 8d0c369..c123fd7 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="comment">
         <path id="speech-bubble" d="M15 6H9a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3v3l3-3h3a3 3 0 0 0 3-3V9a3 3 0 0 0-3-3z"/>
     </g>
index 8bac842..92f19bf 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 5H4v12c0 1.6 1.3 3 3 3h12V8c0-1.7-1.4-3-3-3zM7.5 17c-.8 0-1.5-.7-1.5-1.5S6.7 14 7.5 14s1.5.7 1.5 1.5S8.3 17 7.5 17zm0-6C6.7 11 6 10.3 6 9.5S6.7 8 7.5 8 9 8.7 9 9.5 8.3 11 7.5 11zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm4 3c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5zm0-6c-.8 0-1.5-.7-1.5-1.5S14.7 8 15.5 8s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"/>
 </svg>
index 796c176..b7c1c5c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 5h12v12c0 1.6-1.3 3-3 3H4V8c0-1.7 1.4-3 3-3zm8.5 12c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm0-6c.8 0 1.5-.7 1.5-1.5S16.3 8 15.5 8 14 8.7 14 9.5s.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5s-.7-1.5-1.5-1.5-1.5.7-1.5 1.5.7 1.5 1.5 1.5zm-4 3c.8 0 1.5-.7 1.5-1.5S8.3 14 7.5 14 6 14.7 6 15.5 6.7 17 7.5 17zm0-6c.8 0 1.5-.7 1.5-1.5S8.3 8 7.5 8 6 8.7 6 9.5 6.7 11 7.5 11z"/>
 </svg>
index d18ef8b..e4592ed 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 18l8-10H4z"/>
 </svg>
index eef75e1..a1104a8 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 11h-3V4c-1.7 0-3 1.3-3 3v4H7l4.5 5 4.5-5zm1 2v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
 </svg>
index 003faa3..fb82869 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 11h3V4c1.7 0 3 1.3 3 3v4h3l-4.5 5L7 11zm-1 2v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
 </svg>
index ac4418e..7c0fd75 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17 2L5 14l-1 5 5-1L21 6c0-2-2-4-4-4zM7.2 15.5c-.3-.3-.7-.6-1-.8C8.5 12.4 17.5 3.3 17.5 3.3c.4.1.7.3 1 .7L7.2 15.5z"/>
 </svg>
index 72e5856..6dbfe37 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M17 2L5 14l-1 5 5-1L21 6c0-2-2-4-4-4zM7.2 15.5c-.3-.3-.7-.6-1-.8C8.5 12.4 17.5 3.3 17.5 3.3c.4.1.7.3 1 .7L7.2 15.5z"/>
 </svg>
index 801568f..fdfbca5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M8 2l12 12 1 5-5-1L4 6c0-2 2-4 4-4zm9.8 13.5c.3-.3.7-.6 1-.8C16.5 12.4 7.5 3.3 7.5 3.3c-.4.1-.7.3-1 .7l11.3 11.5z"/>
 </svg>
index b241c50..213841d 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M8 2l12 12 1 5-5-1L4 6c0-2 2-4 4-4zm9.8 13.5c.3-.3.7-.6 1-.8C16.5 12.4 7.5 3.3 7.5 3.3c-.4.1-.7.3-1 .7l11.3 11.5z"/>
 </svg>
index 59c2a5d..2f9ab93 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 4V3s0-3-3-3-3 3-3 3v1h-1v6h8V4zm-1.5 0h-3V3s0-1.5 1.5-1.5c1.48.06 1.5 1.5 1.5 1.5zM13 9.6l-6.8 6.9c-.3-.3-.7-.6-1-.8 1.4-1.4 5-5 7.8-7.9V6l-9 9-1 5 5-1 8-8h-3z"/>
 </svg>
index 4f924f8..9d563fb 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 4V3s0-3 3-3 3 3 3 3v1h1v6H3V4zm1.5 0h3V3s0-1.5-1.5-1.5C5.52 1.56 5.5 3 5.5 3zM12 9.6l6.8 6.9c.3-.3.7-.6 1-.8-1.4-1.4-5-5-7.8-7.9V6l9 9 1 5-5-1-8-8h3z"/>
 </svg>
index d5ec132..bdcbb21 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14.9 2.8c.9 0 1.8.2 2.7.6.9.4 1.6.9 1.9 1.6-2.8.1-5 1.1-6.6 3.1l1.3 2-6.7-.3L8 3l1.7 2c1.8-1.5 3.5-2.2 5.2-2.2z"/>
     <path d="M15.2 11.1l-2.6-.1-5.4 5.5c-.3-.3-.7-.6-1-.8.9-.9 2.8-2.8 4.7-4.8H9.1L5 15l-1 5 5-1 7.8-7.8-1.6-.1zM20.6 6c-1.7 0-3.2.5-4.4 1.4l-.9.9.8 1.3.9 1.4 4-4c0-.3-.1-.7-.2-1h-.2z"/>
 </svg>
index 7722bd8..dfe6877 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10.1 2.8c-.9 0-1.8.2-2.7.6-.9.4-1.6.9-1.9 1.6 2.8.1 5 1.1 6.6 3.1l-1.3 2 6.7-.3L17 3l-1.7 2c-1.8-1.5-3.5-2.2-5.2-2.2z"/>
     <path d="M9.8 11.1l2.6-.1 5.4 5.5c.3-.3.7-.6 1-.8-.9-.9-2.8-2.8-4.7-4.8h1.8L20 15l1 5-5-1-7.8-7.8 1.6-.1zM4.4 6c1.7 0 3.2.5 4.4 1.4l.9.9-.8 1.3L8 11 4 7c0-.3.1-.7.2-1h.2z"/>
 </svg>
index 19733aa..b512f82 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M8 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM14 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4zM20 13c0 .6-.2 1-.6 1.4-.4.4-.9.6-1.4.6-.6 0-1-.2-1.4-.6-.4-.4-.6-.9-.6-1.4s.2-1 .6-1.4c.4-.4.9-.6 1.4-.6s1 .2 1.4.6c.4.4.6.9.6 1.4z"/>
 </svg>
index 21f80da..28fb1ef 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="expand">
         <path id="arrow" d="M17.303 8.283L12 13.586 6.697 8.283 5.283 9.697 12 16.414l6.717-6.717z"/>
     </g>
index 0526f75..269d813 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="external">
         <path id="box" d="M4 4h6v2H6v12h12v-4h2v6H4z"/>
         <path id="arrow" d="M12.42 4H20v7.58l-2.84-2.846L12.892 13 11 11.106l4.264-4.266z"/>
index d747aa6..cc06c3a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="external">
         <path id="box" d="M20 4h-6v2h4v12H6v-4H4v6h16z"/>
         <path id="arrow" d="M11.58 4H4v7.58l2.84-2.846L11.108 13 13 11.106 8.736 6.84z"/>
index 31c10e5..9a0dbaa 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 8C7 8 1 14 1 14s6 6 11 6l11-6s-6-6-11-6zm0 10c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
     <circle cx="12" cy="14" r="2"/>
 </svg>
index d8f7dff..3ce3da3 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19.4 12.7c.7-.8 1.2-1.7 1.4-2.7h-1.6c-.9 2.5-3.9 4.4-7.7 4.6h-.1c-3.7-.2-6.8-2.1-7.7-4.6H2.2c.2 1 .8 1.9 1.4 2.7l-2 2 .7.7 2-2c.8.6 1.7 1.2 2.7 1.7l-1 2.8.9.3 1-2.8c1 .3 2 .6 3.1.6v3h1v-3c1.1-.1 2.2-.3 3.1-.6l1 2.8.9-.3-1-2.8c1-.4 1.9-1 2.6-1.7l2 2 .7-.7-1.9-2z"/>
 </svg>
index 405c240..55e6441 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="find">
         <path id="magnifying-glass" d="M13.656 11c-1.92 0-3.5 1.548-3.5 3.47 0 1.92 1.58 3.5 3.5 3.5.75 0 1.432-.253 2-.657l.094.156 2.375 2.37c.19.19.534.15.78-.096s.315-.59.126-.78l-2.37-2.377-.185-.094a3.545 3.545 0 0 0 .655-2.03c0-1.92-1.55-3.47-3.47-3.47zm0 1.656a1.8 1.8 0 0 1 1.813 1.813 1.83 1.83 0 0 1-1.82 1.84c-1.01 0-1.844-.83-1.844-1.847s.832-1.814 1.844-1.814z"/>
         <path id="text" d="M6 5v2h10V5H6zm0 3v2h11V8H6zm0 3v2h3.53a4.443 4.443 0 0 1 1.44-2H6zm0 3v2h3.53c-.177-.48-.28-.99-.28-1.53 0-.16.046-.315.063-.47H6z"/>
index b46f53f..e6c6bb5 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="find">
         <path id="magnifying-glass" d="M11.344 11c1.92 0 3.5 1.548 3.5 3.47 0 1.92-1.58 3.5-3.5 3.5-.75 0-1.432-.253-2-.657l-.094.156-2.375 2.37c-.19.19-.534.15-.78-.096s-.315-.59-.126-.78l2.37-2.377.185-.094a3.545 3.545 0 0 1-.655-2.03c0-1.92 1.55-3.47 3.47-3.47zm0 1.656A1.8 1.8 0 0 0 9.53 14.47c0 1.01.806 1.84 1.818 1.84 1.01 0 1.844-.83 1.844-1.845s-.832-1.814-1.844-1.814z"/>
         <path id="text" d="M19 5v2H9V5zm0 3v2H8V8zm0 3v2h-3.53a4.443 4.443 0 0 0-1.44-2zm0 3v2h-3.53c.177-.48.28-.99.28-1.53 0-.16-.046-.315-.063-.47z"/>
index ab66000..832c44f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14 6.5V5c-1.4-1.5-5.2-1.2-6 0V4H7v15h1v-7c.8-.8 3.4-.9 5-.5V13c1.2 1.5 4.3 1.2 5 0V6c-.7.7-2.7.9-4 .5z"/>
 </svg>
index 025da1f..3946c4a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 6.5V5c1.4-1.5 5.2-1.2 6 0V4h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V13c-1.2 1.5-4.3 1.2-5 0V6c.7.7 2.7.9 4 .5z"/>
 </svg>
index ea95d5f..2cbc539 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14 6.5V5c-1.4-1.5-5.2-1.2-6 0V4H7v15h1v-7c.8-.8 3.4-.9 5-.5V13c1.2 1.5 4.3 1.2 5 0V6c-.7.7-2.7.9-4 .5z"/>
     <path d="M17.997 1.99l.99.99-15.98 15.98-.99-.99z"/>
     <path d="M17 1.016l.99.99-15.98 15.98-.99-.99z" fill="#fff"/>
index dc328a8..1faabf6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 6.5V5c1.4-1.5 5.2-1.2 6 0V4h1v15h-1v-7c-.8-.8-3.4-.9-5-.5V13c-1.2 1.5-4.3 1.2-5 0V6c.7.7 2.7.9 4 .5z"/>
     <path d="M7.003 1.99l-.99.99 15.98 15.98.99-.99z"/>
     <path d="M8 1.016l-.99.99 15.98 15.98.99-.99z" fill="#fff"/>
index 7dfc979..c66c281 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M2 5v15h20V5H2zm15 11H8c-.6 0-1-.4-1-1V9h3l2 1h5v6z"/>
 </svg>
index 6151238..f2d9fab 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M22 5v15H2V5h20zM7 16h9c.6 0 1-.4 1-1V9h-3l-2 1H7v6z"/>
 </svg>
index 40d01b4..00d2695 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 13L5 6h15l-6 7v7c-1.7 0-3-1.3-3-3v-4z"/>
 </svg>
index d960a65..bd2d7de 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14 13l6-7H5l6 7v7c1.7 0 3-1.3 3-3v-4z"/>
 </svg>
index 5e5b88e..95b83c2 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11.4 5.4V2.2c.3 0 .6.1.9.4.3.3.4.5.4.8v2h-1.3zm-5.2-.5c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4-.3-.3-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9.3-.3.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8 0-.3.1-.6.3-.8zM12 7c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm-3 4c0-1.7 1.3-3 3-3v6c-1.7 0-3-1.3-3-3z"/>
 </svg>
index fc78226..7ace9e4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 7c-2 0-3 2-3 2s-1-2-3-2c-2.5 0-4 2-4 4 0 4 5 5 7 8 2-3 7-4 7-8 0-2-1.5-4-4-4z"/>
 </svg>
index 29df251..a43996c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="help">
         <path id="circle" d="M12 2.085c-5.477 0-9.915 4.438-9.915 9.916 0 5.48 4.438 9.92 9.916 9.92 5.48 0 9.92-4.44 9.92-9.913 0-5.477-4.44-9.915-9.913-9.915zm.002 18a8.084 8.084 0 1 1 0-16.168 8.084 8.084 0 0 1 0 16.168z"/>
         <g id="question-mark">
index 552fe9f..0c0368e 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="help">
         <path id="circle" d="M12 2.085c5.477 0 9.915 4.438 9.915 9.916 0 5.48-4.438 9.92-9.916 9.92-5.48 0-9.92-4.44-9.92-9.913 0-5.477 4.44-9.915 9.913-9.915zm-.002 18a8.084 8.084 0 1 0 0-16.168 8.084 8.084 0 0 0 0 16.168z"/>
         <g id="question-mark">
index 4b1fd50..6b46920 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="history">
         <path id="clock-hands" d="M17.26 15.076s-2.385-1.935-4.005-3.062c.72-2.397 1.702-6.56 1.702-6.56s-4.35 5.364-4.877 6.7c-.463 1.168 1.46 2.21 2.346 1.678 1.9.55 4.834 1.244 4.834 1.244z"/>
         <path id="arrow" d="M12.086 2.085C6.608 2.085 2.17 6.523 2.17 12a9.86 9.86 0 0 0 1.3 4.9l-2.22 2.04h5.688v-5.22L4.87 15.616A7.982 7.982 0 0 1 4.004 12a8.084 8.084 0 0 1 16.167.004 8.08 8.08 0 0 1-8.08 8.085 7.975 7.975 0 0 1-3.21-.68L8.05 21.04a9.81 9.81 0 0 0 4.045.874C17.563 21.914 22 17.476 22 12c0-5.477-4.438-9.915-9.914-9.915z"/>
index 9b39350..aeb8984 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="image">
         <path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-11v13H4V6z"/>
     </g>
index f962cbf..8b82c20 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="image">
         <path id="mountains" d="M6 17l3-3 2 1 3-3 4 5zM4 6v13h16V6z"/>
     </g>
index cfcf60d..81b6783 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="imageAdd">
         <path id="mountains" d="M16 17l-3-3-2 1-3-3-4 5zm-1-8v4h3v6H2V6h9v3z"/>
         <path id="add" d="M22 6h-4V2h-2v4h-4v2h4v4h2V8h4z"/>
index 8b20a50..f14a20a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="imageAdd">
         <path id="mountains" d="M8 17l3-3 2 1 3-3 4 5zm1-8v4H6v6h16V6h-9v3z"/>
         <path id="add" d="M2 6h4V2h2v4h4v2H8v4H6V8H2z"/>
index 6758bc7..785bd49 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M2 4v14h2V6h15V4H2zm3 3v13h16V7H5zm6 6l3 3 2-1 3 3H7l4-5z" id="imageGallery"/>
 </svg>
index ff3123f..fe66e4f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 4v14h-2V6H4V4h17zm-3 3v13H2V7h16zm-6 6l-3 3-2-1-3 3h12l-4-5z" id="imageGallery"/>
 </svg>
index b14b67d..5932525 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="imageAdd">
         <path id="mountains" d="M18 17l-3-3-2 1-3-3-4 5zm2-5v7H4V6h8v6z"/>
         <path id="lock" d="M18.5 5h-3V4s0-1.5 1.5-1.5c1.5.06 1.5 1.5 1.5 1.5zM20 5V4s0-3-3-3-3 3-3 3v1h-1v6h8V5z"/>
index 275dfc2..b92b212 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="imageAdd">
         <path id="mountains" d="M7 17l3-3 2 1 3-3 4 5zm-2-5v7h16V6h-8v6z"/>
         <path id="lock" d="M6.5 5h3V4s0-1.5-1.5-1.5C6.5 2.56 6.5 4 6.5 4zM5 5V4s0-3 3-3 3 3 3 3v1h1v6H4V5z"/>
index 0837550..718c2b0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 8v8l5-4-5-4z"/>
 </svg>
index 26e49c7..e6abc95 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zM21 8v8l-5-4 5-4z"/>
 </svg>
index ce4a75d..e519d7e 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="info">
         <path id="circled-i" d="M11.5 17a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11zm0-12a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zm.5 5v4h1v1h-3v-1h1v-3h-1v-1zm-1-2h1v1h-1z"/>
     </g>
index 0fc2eb0..ac33a08 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-a">
         <path id="a" d="M14.667 6h-1.372l-7 12H8l2.333-4h4L15 18h1.667l-2-12zm-3.75 7l2.527-4.333.723 4.333h-3.25z"/>
     </g>
index 63dc4e2..5ea6072 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-arab-keheh-jeem">
         <path id="arab-keheh-jeem" d="M18.125 5.844c-1.695.555-3.297 1.162-4.594 1.938-.49.3-.77.712-.87 1.125a1.26 1.26 0 0 0 .065.78c.19.406.54.575.844.814l.093-.12.53.627c.14.165.345.514.47.94.138.462.08.724 0 1.124h-3.44c-.34 0-.592.007-.766-.02-.34-.053-.256-.21-.234-.34.33-.127.56-.173.934-.14.29-.495.593-.886.906-1.314-.98.037-1.877.015-2.687-.094-.346-.046-.698-.185-1.094-.155-.36.026-.77.24-1.03.72-.25.447-.436.838-.66 1.28l.75-.47c.23-.14.486-.226.72-.218.158.004.276.053.407.093-.234.204-.51.4-.72.56-.3.26-.704.69-.908 1-.403.617-.694 1.086-.875 1.78-.18.69.003 1.34.468 1.75.426.38.846.52 1.28.566.65.064 1.206.092 2-.19.658-.23 1.022-.552 1.5-.97-.882.11-1.816.09-2.53.033-.87-.07-1.268-.386-1.47-.596-.27-.283-.306-.64-.155-1.22a1.44 1.44 0 0 1 .25-.53c.17-.228.363-.435.593-.656.45-.436 1.01-.737 1.46-.94-.042.207-.104.444-.052.69.05.23.25.38.44.47.26.12.506.152.69.153 1.42.01 2.86 0 4.28 0 .246 0 .45-.163.593-.375.14-.21.25-.48.343-.845.13-.5.094-1.062-.094-1.625a4.812 4.812 0 0 0-.72-1.406c-.336-.444-.675-.83-1-1.22 1.256-.815 2.715-1.24 3.97-1.688.12-.452.222-.926.31-1.313zm-9.47 8.438c-.26.394-.583.69-.874 1 .38.286.75.556 1.1.813.336-.303.627-.674.876-.97-.39-.267-.77-.587-1.093-.843z"/>
     </g>
index 5191e7f..5b4cd21 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-arab-meem">
         <path id="arab-meem" d="M16 9.73l-.93 2.19h-4.663c-.48 0-.857.12-1.135.366l-.06.11c-.185 2.016-.503 3.558-.956 4.627a8.31 8.31 0 0 1-1.082 1.833c-.177.226-.22.186-.126-.12l.142-.503.17-.67.234-.87.002-.008.202-1.045.258-1.41.353-1.907c.19-.312.42-.638.692-.98a24.1 24.1 0 0 1 .94-1.09c.13-.092.697-.18 1.705-.266 1.05-.086 1.64-.183 1.765-.293l.065-.128c.01-.11-.01-.24-.052-.394a2.403 2.403 0 0 0-.232-.522c-.22-.428-.438-.64-.654-.64-.294 0-.915.268-1.864.805-.36.208-.378.125-.05-.247 1.555-1.71 2.705-2.566 3.45-2.566.38 0 .67.13.86.394.134.195.25.6.343 1.21l.202 1.2c.105.586.24.895.408.925"/>
     </g>
index c7ba181..44753a9 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-armn-sha">
         <path id="armn-sha" d="M11.564 7.678a3.073 3.073 0 0 0-.93-.268c-.35-.047-.75-.07-1.197-.07h-1.11L8.587 6h1.723c.558 0 1.042.032 1.45.095.416.063.794.173 1.136.33l4.483 2.033-.33 1.67-2.625-1.165a1.867 1.867 0 0 0-.433-.134 2.45 2.45 0 0 0-.576-.06 4.88 4.88 0 0 0-1.663.28c-.526.19-1 .46-1.427.812-.42.35-.776.78-1.07 1.283a5.48 5.48 0 0 0-.63 1.71c-.24 1.255-.15 2.21.27 2.87.424.65 1.19.976 2.292.976.55 0 1.044-.08 1.48-.236a3.488 3.488 0 0 0 1.135-.66c.325-.29.59-.634.795-1.034.21-.4.363-.84.458-1.322l.11-.56h1.6l-.12.59a5.925 5.925 0 0 1-.676 1.844 5.19 5.19 0 0 1-1.214 1.423c-.488.395-1.053.7-1.694.923a6.573 6.573 0 0 1-2.106.324c-.767 0-1.434-.114-2-.34-.568-.226-1.025-.554-1.372-.985-.347-.437-.573-.97-.678-1.608-.105-.64-.078-1.366.08-2.186.125-.66.346-1.274.66-1.836A6.332 6.332 0 0 1 8.792 9.54a5.955 5.955 0 0 1 1.496-1.072 5.87 5.87 0 0 1 1.732-.57l-.465-.23"/>
     </g>
index abc0301..467d12d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-c">
         <path id="c" d="M15.008 13.718l1.48.214c-.467 1.34-1.15 2.354-2.045 3.04a4.835 4.835 0 0 1-3.015 1.03c-1.36 0-2.438-.43-3.237-1.29C7.4 15.85 7 14.618 7 13.012c0-2.09.606-3.817 1.817-5.184C9.897 6.61 11.237 6 12.84 6c1.186 0 2.145.33 2.878.99.738.66 1.165 1.546 1.282 2.66l-1.397.135c-.148-.84-.453-1.464-.916-1.876-.458-.42-1.05-.63-1.78-.63-1.368 0-2.475.63-3.32 1.89-.733 1.087-1.1 2.377-1.1 3.87 0 1.194.283 2.104.848 2.732.565.628 1.3.942 2.206.942.78 0 1.48-.26 2.1-.785.63-.52 1.08-1.26 1.37-2.216"/>
     </g>
index b51d25c..7774790 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-d">
         <path id="d" d="M7 18L9.462 6h3.557c.85 0 1.5.063 1.95.188.642.17 1.192.472 1.65.91.454.43.8.97 1.03 1.62.23.65.344 1.378.344 2.186 0 .966-.146 1.847-.436 2.644-.284.79-.66 1.49-1.127 2.095-.46.6-.946 1.072-1.455 1.416-.504.33-1.1.582-1.794.75-.525.122-1.17.19-1.94.19H7m1.86-1.36h1.866c.842 0 1.59-.08 2.245-.24a3.26 3.26 0 0 0 1.05-.436 4.19 4.19 0 0 0 1.04-.975 6.652 6.652 0 0 0 .975-1.825c.247-.687.37-1.467.37-2.34 0-.97-.166-1.716-.5-2.235-.332-.522-.755-.87-1.27-1.04-.38-.124-.974-.186-1.78-.186H11L9.095 16.64"/>
     </g>
index f6c18e5..da226ae 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-e">
         <path id="e" d="M7 18L9.474 6H18l-.282 1.367H10.77L10.02 11h6.09l-.28 1.367H9.74l-.88 4.273h7.44L16.018 18H7"/>
     </g>
index 3338bef..d848197 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-geor-kan">
         <path id="geor-kan" d="M15.057 14.663C14.617 16.888 13.223 18 10.88 18 8.96 18 8 17.213 8 15.64c0-.298.036-.624.108-.977.083-.43.245-.836.488-1.217l1.24.605-.206.62c-.055.26-.083.497-.083.71 0 .97.52 1.46 1.564 1.46 1.31 0 2.108-.724 2.39-2.17l.058-.33a3.17 3.17 0 0 0 .066-.615c0-.927-.546-1.39-1.64-1.39H10.87l.247-1.26h1.118c1.203-.004 1.91-.55 2.12-1.64.04-.18.057-.355.057-.52 0-1.144-.9-1.715-2.696-1.715L11.94 6C14.646 6 16 6.877 16 8.627c0 .248-.027.516-.082.803-.204 1.092-1.05 1.824-2.54 2.194l-.033.166c1.23.2 1.845.823 1.845 1.872 0 .21-.025.433-.074.67l-.058.332"/>
     </g>
index ecde4b7..3b471d2 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-i">
         <path id="i" d="M12.5 18l.25-.995h-1.5l2.508-10.037h1.5L15.5 6h-5l-.242.968h1.5l-2.51 10.037h-1.5L7.5 18z"/>
     </g>
index 730fb8a..b719095 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-k">
         <path id="k" d="M12.018 10.652L17 6h-2l-5.31 5.234L11 6H9.5l-3 12H8l1.173-4.693 1.54-1.438C11 16 14 18 14 18h2s-4-2-3.982-7.348z"/>
     </g>
index 0ed100f..1cfeb7a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="italic-s">
         <path id="s" d="M16.474 6.59l-.302 1.525a7.36 7.36 0 0 0-1.557-.628 5.432 5.432 0 0 0-1.487-.217c-.935 0-1.68.204-2.23.612-.554.408-.83.95-.83 1.627 0 .37.1.65.302.86.207.19.733.4 1.58.63l.937.23c1.06.274 1.795.622 2.208 1.046.413.42.62 1.007.62 1.766 0 1.167-.46 2.117-1.38 2.85-.913.734-2.12 1.1-3.617 1.1-.615 0-1.232-.06-1.852-.185-.62-.12-1.242-.3-1.867-.55l.31-1.61a7.613 7.613 0 0 0 1.72.805c.58.18 1.155.27 1.73.27.976 0 1.76-.216 2.347-.65.59-.434.883-1 .883-1.697 0-.465-.12-.816-.354-1.054-.233-.242-.737-.46-1.512-.657l-.937-.24c-1.07-.28-1.8-.6-2.19-.964-.39-.368-.584-.88-.584-1.535 0-1.152.442-2.094 1.325-2.828.89-.74 2.043-1.108 3.463-1.108.555 0 1.1.05 1.644.146.542.1 1.085.245 1.627.442"/>
     </g>
index cbcfff0..45b0391 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M16 9V8h-6v1h6zm-2 2v-1h-4v1h4zM6 5h1v16H6V5zm2 0h10v13c0 1.7-1.3 3-3 3H8V5z"/>
 </svg>
index 6ecb10d..77cf757 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M8 9V8h6v1H8zm2 2v-1h4v1h-4zm8-6h-1v16h1V5zm-2 0H6v13c0 1.7 1.3 3 3 3h7V5z"/>
 </svg>
index 131bbdb..988f38e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14.5 4C11.5 4 9 6.5 9 9.5c0 1 .3 1.9.7 2.8L4 18v2h4v-2h2v-2h2l1.2-1.2c.4.1.9.2 1.3.2 3 0 5.5-2.5 5.5-5.5S17.5 4 14.5 4zM16 9c-.8 0-1.5-.7-1.5-1.5S15.2 6 16 6s1.5.7 1.5 1.5S16.8 9 16 9z"/>
 </svg>
index 906ee6e..7ca2f8f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9.5 4c3 0 5.5 2.5 5.5 5.5 0 1-.3 1.9-.7 2.8L20 18v2h-4v-2h-2v-2h-2l-1.2-1.2c-.4.1-.9.2-1.3.2-3 0-5.5-2.5-5.5-5.5S6.5 4 9.5 4zM8 9c.8 0 1.5-.7 1.5-1.5S8.8 6 8 6s-1.5.7-1.5 1.5S7.2 9 8 9z"/>
 </svg>
index 238ca48..b9cbad0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 7v9c0 1.7 1.3 3 3 3h15V7H3zm8 2h2v2h-2V9zm0 3h2v2h-2v-2zM8 9h2v2H8V9zm0 3h2v2H8v-2zm-1 5H6c-.6 0-1-.4-1-1v-1h2v2zm0-3H5v-2h2v2zm0-3H5V9h2v2zm9 6H8v-2h8v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2zm3 6h-2v-2h2v2zm0-3h-2v-2h2v2zm0-3h-2V9h2v2z"/>
 </svg>
index 8248804..d235a35 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 7v9c0 1.7-1.3 3-3 3H3V7h18zm-8 2h-2v2h2V9zm0 3h-2v2h2v-2zm3-3h-2v2h2V9zm0 3h-2v2h2v-2zm1 5h1c.6 0 1-.4 1-1v-1h-2v2zm0-3h2v-2h-2v2zm0-3h2V9h-2v2zm-9 6h8v-2H8v2zm0-3h2v-2H8v2zm0-3h2V9H8v2zm-3 6h2v-2H5v2zm0-3h2v-2H5v2zm0-3h2V9H5v2z"/>
 </svg>
index 3365bb9..19e1e9f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="translation">
         <path id="english" d="M14.34 9l-3.53 10h2.064l.72-2.406h3.624l.72 2.406H20L16.465 9h-2.12zm1.065 1.53L16.75 15h-2.69z"/>
         <path id="chinese" d="M8.97 4.22c-.43.29-.88.616-1.25.874l.186.312c.14.194.275.393.407.594H4.47v1.47h1.593c.43 1.41 1.11 2.624 2.03 3.624-1.008.664-2.192 1.248-3.624 1.75L4 13c.317.487.714.976 1.03 1.375l.25-.094c1.593-.59 2.91-1.263 4.032-2.06.818.63 1.71 1.16 2.657 1.595l.56-1.624a13.21 13.21 0 0 1-1.908-1.063c.284-.28.59-.634.906-1.156.46-.716.776-1.57 1-2.5h1.657V6h-4.063c-.283-.552-.596-1.083-.97-1.53l-.186-.25zM7.72 7.47h3.186c-.32 1.075-.83 1.937-1.53 2.624-.713-.705-1.26-1.568-1.657-2.625zm6.31 5.31l-.467 1.658c.292-.514.577-1.075.812-1.532l-.344-.125z"/>
index ba3770b..123053c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="translation">
         <path id="english" d="M7.53 9L4 19h2.063l.72-2.406h3.624l.72 2.406h2.062L9.65 9H7.53zm1.064 1.53L9.938 15H7.25z"/>
         <path id="chinese" d="M14.594 4.22c-.43.29-.88.616-1.25.874l.187.312c.14.194.28.393.41.594h-3.843v1.47h1.594c.43 1.41 1.11 2.624 2.03 3.624-.662.437-1.413.82-2.25 1.187l.563 1.567a15.882 15.882 0 0 0 2.908-1.625 13.82 13.82 0 0 0 3.97 2.125l.28.094c.293-.514.578-1.075.813-1.532l-.375-.125c-1.38-.49-2.49-1.05-3.375-1.654.284-.28.59-.635.906-1.157.46-.717.775-1.572 1-2.5h1.656V6H15.75c-.283-.552-.596-1.083-.97-1.53l-.186-.25zm-1.25 3.25h3.187c-.315 1.075-.825 1.937-1.53 2.624-.71-.705-1.26-1.568-1.653-2.625zM9.97 12.874L9.624 13c.196.3.406.594.625.875l-.28-1z"/>
index 0ab6bdb..f6e3d8e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20.8 20h-8.1v-.8c.4 0 .8-.1 1.3-.2s.8-.2.8-.4v-.2c0-.1 0-.2-.1-.3L13.4 15H8.3c-.1.3-.2.6-.4 1-.1.4-.3.7-.4 1-.1.4-.2.7-.2.8v.4c0 .2.2.4.5.6.3.2.9.3 1.7.3v.9H3.4v-.8c.2 0 .5-.1.8-.1.3-.1.5-.1.7-.2.3-.2.5-.4.7-.6.2-.3.4-.6.5-.9.8-2 1.6-3.9 2.4-5.9.8-2 1.7-4.1 2.7-6.5h2.1c1.4 3.3 2.4 6 3.2 7.9.8 1.9 1.4 3.6 2 4.8l.3.6c.1.2.3.3.6.5.2.1.4.2.7.3.3.1.5.1.7.1v.8zM13 14l-2.1-5.3L8.8 14H13z"/>
 </svg>
index 0ab6bdb..f6e3d8e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20.8 20h-8.1v-.8c.4 0 .8-.1 1.3-.2s.8-.2.8-.4v-.2c0-.1 0-.2-.1-.3L13.4 15H8.3c-.1.3-.2.6-.4 1-.1.4-.3.7-.4 1-.1.4-.2.7-.2.8v.4c0 .2.2.4.5.6.3.2.9.3 1.7.3v.9H3.4v-.8c.2 0 .5-.1.8-.1.3-.1.5-.1.7-.2.3-.2.5-.4.7-.6.2-.3.4-.6.5-.9.8-2 1.6-3.9 2.4-5.9.8-2 1.7-4.1 2.7-6.5h2.1c1.4 3.3 2.4 6 3.2 7.9.8 1.9 1.4 3.6 2 4.8l.3.6c.1.2.3.3.6.5.2.1.4.2.7.3.3.1.5.1.7.1v.8zM13 14l-2.1-5.3L8.8 14H13z"/>
 </svg>
index a848318..36a8165 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="layout-ltr">
         <path id="text" d="M5 19V5h6v8h8v6H5z"/>
         <path id="float" d="M13 5v6h6V5h-6zm5 5h-4V6h4v4z"/>
index b8c4586..39ba9c4 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="layout-rtl">
         <path id="text" d="M5 19v-6h8V5h6v14H5z"/>
         <path id="float" d="M5 5v6h6V5H5zm1 1h4v4H6V6z"/>
index 4024b6d..5bee6d5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15.387 4.33c-2.1 0-3.6 1.9-5.1 3.3.2 0 .5-.1.8-.1.5 0 1 .1 1.5.3.8-.8 1.6-1.7 2.8-1.7.6 0 1.3.3 1.8.7 1 1 1 2.6 0 3.6l-2.6 2.6c-.4.4-1.2.7-1.8.7-1.4 0-2.1-.9-2.6-2l-1.3 1.3c.8 1.5 2 2.6 3.8 2.6 1.2 0 2.3-.5 3-1.3l2.6-2.6c.9-.9 1.5-2 1.5-3.3-.2-2.2-2.2-4.1-4.4-4.1zm-4.3 12.1l-.9.9c-.4.4-1.2.7-1.8.7-.6 0-1.3-.3-1.8-.7-1-1-1-2.7 0-3.6l2.6-2.6c.4-.4 1.2-.7 1.8-.7 1.4 0 2.1 1 2.6 2l1.3-1.3c-.8-1.5-2-2.6-3.8-2.6-1.2 0-2.3.5-3 1.3l-2.6 2.6c-1.7 1.7-1.7 4.4 0 6 1.6 1.6 4.4 1.7 5.9 0l1.9-1.9c-.3.1-.6.1-.9.1-.5 0-.9 0-1.3-.2z"/>
 </svg>
index 0235bde..8e34361 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9.025 3.6c2.1 0 3.6 1.9 5.1 3.3-.2 0-.5-.1-.8-.1-.5 0-1 .1-1.5.3-.8-.8-1.6-1.7-2.8-1.7-.6 0-1.3.3-1.8.7-1 1-1 2.6 0 3.6l2.6 2.6c.4.4 1.2.7 1.8.7 1.4 0 2.1-.9 2.6-2l1.3 1.3c-.8 1.5-2 2.6-3.8 2.6-1.2 0-2.3-.5-3-1.3l-2.6-2.6c-.9-.9-1.5-2-1.5-3.3.2-2.2 2.2-4.1 4.4-4.1zm4.3 12.1l.9.9c.4.4 1.2.7 1.8.7.6 0 1.3-.3 1.8-.7 1-1 1-2.7 0-3.6l-2.6-2.6c-.4-.4-1.2-.7-1.8-.7-1.4 0-2.1 1-2.6 2l-1.3-1.3c.8-1.5 2-2.6 3.8-2.6 1.2 0 2.3.5 3 1.3l2.6 2.6c1.7 1.7 1.7 4.4 0 6-1.6 1.6-4.4 1.7-5.9 0l-1.9-1.9c.3.1.6.1.9.1.5 0 .9 0 1.3-.2z"/>
 </svg>
index 686a8e7..2eb5329 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 7H9V5h12v2zM7 6c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 12c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm14 7H9v-2h12v2zM7 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2z"/>
 </svg>
index aebe6f2..dcce2ae 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 7h12V5H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 13h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2zM3 19h12v-2H3v2zm14-1c0 1.1.9 2 2 2s2-.9 2-2-.9-2-2-2-2 .9-2 2z"/>
 </svg>
index 58ffe88..1ab3f23 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 7H8V5h13v2zm0 6H8v-2h13v2zm0 6H8v-2h13v2zM4 4h2v4H5V5H4zm-1 6V9h3v3H4v1h2v1H3v-3h2v-1zm3 10H3v-1h2v-1H4v-1h1v-1H3v-1h3z"/>
 </svg>
index 8bec0d5..ab12c83 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 7h13V5H3zm0 6h13v-2H3zm0 6h13v-2H3zM18 4h2v4h-1V5h-1zm0 6V9h3v3h-2v1h2v1h-3v-3h2v-1zm3 10h-3v-1h2v-1h-1v-1h1v-1h-2v-1h3z"/>
 </svg>
index 31fe8ff..e0c482b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
 </svg>
index 03788f1..ee341a9 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 8s0-3-2.5-3S10 8 10 8v1h5zm2 0v1h2v10H9c-1.7 0-3-1.3-3-3V9h2V8s0-5 4.5-5S17 8 17 8z"/>
 </svg>
index 79972de..edc9312 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
 </svg>
index e3fda47..2f8851c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10 8s0-3 2.5-3S15 8 15 8v1h-5zM8 8v1H6v10h10c1.7 0 3-1.3 3-3V9h-2V8s0-5-4.5-5S8 8 8 8z"/>
 </svg>
index 8b10f25..f81d7c4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 14v3l5-4.5L15 8v3H8c0 1.7 1.3 3 3 3h4zm-1-9H4v15h10v-2H6V7h8V5z"/>
 </svg>
index 412cd92..d3fae89 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9 14v3l-5-4.5L9 8v3h7c0 1.7-1.3 3-3 3H9zm1-9h10v15H10v-2h8V7h-8V5z"/>
 </svg>
index a2dcf4e..48eafd4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 6c-3.9 0-7 3.1-7 7s3.1 7 7 7 7-3.1 7-7-3.1-7-7-7zm0 13c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6zm-1.7-4.6c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5zm4 0c-.7 0-1-.4-1-1.2s.3-1.2 1-1.2c.4 0 .6.2.8.6l.9-.5c-.4-.7-1-1-1.9-1-.6 0-1.1.2-1.5.6s-.6.8-.6 1.5.2 1.2.6 1.6c.4.4.9.6 1.5.6.8 0 1.4-.4 1.9-1.1l-.9-.4c-.2.3-.5.5-.8.5z"/>
 </svg>
index ca6d1d2..4794f33 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15.4 7.8c-2-.9-2.3-2.5-2.4-2.8.1.1 2 1 2 1l-3-5-3 5 2-1s0 .8.6 2.1c.8 1.5 2.2 2.2 2.2 2.2s1.6.7 2.2 1.3l-.7.7-.5-.5-.4 1.8 1.8-.4-.5-.5.7-.7c.9 1 1.5 2.3 1.6 3.8h-1V14l-1.5 1 1.5 1v-.8h1c-.1 1.5-.6 2.8-1.6 3.8l-.7-.7.5-.5-1.8-.4.4 1.8.5-.5.7.7c-1 .9-2.3 1.5-3.8 1.6v-1h.8l-1-1.5-1 1.5h.8v1c-1.5-.1-2.8-.6-3.8-1.6l.7-.7.5.5.4-1.8-1.8.4.5.5-.7.7c-.9-1-1.5-2.3-1.6-3.8h1v.8l1.5-1L7 14v.8H6c.1-1.5.6-2.8 1.6-3.8l.7.7-.5.5 1.8.4-.4-1.8-.5.5-.7-.7-1.5-1.4A7.99 7.99 0 0 0 4 15c0 4.4 3.6 8 8 8s8-3.6 8-8c0-3.2-1.9-5.9-4.6-7.2z"/>
     <circle cx="12" cy="15" r="3"/>
 </svg>
index f6c8e74..1fe3277 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M22.3 6.3c0 .2 0 .3-.1.3-.7.1-1.2.5-1.6 1.1-.1.2-.2.4-.3.7l-4.6 10.1c-.1.2-.2.3-.2.3s-.1.1-.2.1c-.2 0-.4-.1-.5-.4L12.2 13l-2.8 5.5c-.1.3-.3.4-.5.4s-.4-.1-.5-.4L4.1 8.4c-.3-.8-.6-1.2-.8-1.4-.2-.2-.5-.3-1-.4-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h4.3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.6.1-1 .2-1.1.4-.1.2 0 .6.3 1.2l3.6 8.2h.1l2.2-4.4L10 8.4c-.3-.7-.6-1.2-.8-1.4s-.5-.3-.9-.4c-.1-.1-.1-.2-.1-.3 0-.2 0-.3.1-.3h3.6c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.4.1-.6.2-.6.4s.1.6.4 1.2l1 1.9 1-1.9c.3-.6.5-.9.5-1.1 0-.2 0-.3-.1-.4-.1-.1-.3-.1-.5-.1l-.1-.3c0-.2 0-.3.1-.3h3c.1.1.1.2.1.3 0 .2 0 .3-.1.3-.5.1-.8.2-1.1.5-.3.3-.6.7-.8 1.3l-1.3 2.8 2.5 5.2h.1l3.7-8.1c.3-.5.3-.9.2-1.2-.1-.3-.5-.4-1.1-.5-.1-.1-.1-.2-.1-.3s0-.3.1-.3h3.7c-.2.1-.2.2-.2.3z"/>
 </svg>
index b988187..2d6d0a0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 6L9 4 3 6v15l6-2 6 2 6-2V4l-6 2zM8.7 18.1L4 19.6V6.7L9 5v12.9l-.3.2zm11.3.2L15 20V7.1l.3-.1L20 5.4v12.9z"/>
 </svg>
index 3e09163..00d3efc 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9 6l6-2 6 2v15l-6-2-6 2-6-2V4l6 2zm6.3 12.1l4.7 1.5V6.7L15 5v12.9l.3.2zM4 18.3L9 20V7.1L8.7 7 4 5.4v12.9z"/>
 </svg>
index 2315072..dc9791e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19 12c0-3.9-3.1-7-7-7s-7 3.1-7 7c0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7zm-7 4c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
 </svg>
index 59814e7..68fe22a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M24 4h-4V0h-2v4h-4v2h4v4h2V6h4z"/>
     <path d="M18 11h-1V7.1l-.1-.1H13V5.1c-.3-.1-.7-.1-1-.1-3.9 0-7 3.1-7 7 0 1.4.4 2.6 1.1 3.7L12 23l5.9-7.3c.7-1.1 1.1-2.3 1.1-3.7 0-.3 0-.7-.1-1H18zm-6 5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>
 </svg>
index 973bfc2..e3ba379 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M0 4h4V0h2v4h4v2H6v4H4V6H0z"/>
     <path d="M6 11h1V7.1l.1-.1H11V5.1c.3-.1.7-.1 1-.1 3.9 0 7 3.1 7 7 0 1.4-.4 2.6-1.1 3.7L12 23l-5.9-7.3C5.4 14.6 5 13.4 5 12c0-.3 0-.7.1-1H6zm6 5c2.2 0 4-1.8 4-4s-1.8-4-4-4-4 1.8-4 4 1.8 4 4 4z"/>
 </svg>
index cd287e4..dbd4a98 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="menu">
         <path id="lines" d="M6 15h12a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1zm-1-4v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1zm0-5v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1z"/>
     </g>
index 300e4df..df72450 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 9c0-1.7-1.3-3-3-3H3v3l9 4 9-4zM3 11v6c0 1.7 1.3 3 3 3h15v-9l-9 4-9-4z"/>
 </svg>
index 629ddac..1bb1dae 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 9c0-1.7 1.3-3 3-3h15v3l-9 4-9-4zm18 2v6c0 1.7-1.3 3-3 3H3v-9l9 4 9-4z"/>
 </svg>
index 0c27ce7..6fce33f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19.1 17.5c-3.3 1.4-7.1-.2-8.5-3.5-1.4-3.3.2-7.1 3.5-8.5.2-.1.5-.2.7-.3-1.6-.4-3.2-.3-4.8.4C6 7.3 4 12 5.7 16c1.7 4.1 6.4 6 10.5 4.3 1.7-.7 3-1.9 3.8-3.4-.3.3-.6.4-.9.6z"/>
 </svg>
index 5c7a766..63c7b4c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 11l-4-3v2h-3V7h2l-3-4-3 4h2v3H8V8l-4 3 4 3v-2h3v3H9l3 4 3-4h-2v-3h3v2z"/>
 </svg>
index fbebf0c..6fdddd8 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="move-ltr">
         <path id="arrow" d="M8.935 7.18l5.302 5.303-5.302 5.303L10.35 19.2l6.715-6.717-6.716-6.716z"/>
     </g>
index 1067738..2f1e91e 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="move-rtl">
         <path id="arrow" d="M15.065 17.786l-5.302-5.303 5.302-5.302-1.415-1.41-6.714 6.72 6.714 6.71z"/>
     </g>
index 18e4118..25cf321 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5l2.5 2.5L11 11c-1.2 1.2-1.2 2.8 0 4l5.5-5.5L19 12V5h-7zm5 12H8c-.6 0-1-.4-1-1V7h3L8 5H5v11c0 1.7 1.3 3 3 3h11v-3l-2-2v3z"/>
 </svg>
index e357be6..cb0a035 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5L9.5 7.5 13 11c1.2 1.2 1.2 2.8 0 4L7.5 9.5 5 12V5h7zM7 17h9c.6 0 1-.4 1-1V7h-3l2-2h3v11c0 1.7-1.3 3-3 3H5v-3l2-2v3z"/>
 </svg>
index 8b4ab65..220450a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17.8 5.7c-.5 0-.9.2-1.2.5s-.5.7-.5 1.2v4.3H11v-4l-6 5.5 6 5.5v-4h8v-9h-1.2z" id="line_return"/>
 </svg>
index 2642261..214aea9 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6.2 5.7c.5 0 .9.2 1.2.5.3.3.5.7.5 1.2v4.3H13v-4l6 5.5-6 5.5v-4H5v-9h1.2z" id="line_return"/>
 </svg>
index 555eb59..171f6e6 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6 7v12c-.6 0-1-.4-1-1V9H4v9c0 1.1.9 2 2 2h15V7H6zm9 11H8v-1h7v1zm0-2H8v-1h7v1zm0-2H8v-1h7v1zm4 4h-3v-5h3v5zm0-7H8V9h11v2z"/>
 </svg>
index 778810c..c161b6e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19 7v12c.6 0 1-.4 1-1V9h1v9c0 1.1-.9 2-2 2H4V7h15zm-9 11h7v-1h-7v1zm0-2h7v-1h-7v1zm0-2h7v-1h-7v1zm-4 4h3v-5H6v5zm0-7h11V9H6v2z"/>
 </svg>
index b541ca5..92882b0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 13l2 2V5h-3v2h1zM3 3L2 4l1 1v14h3v-2H5V7l2 2v10h3v-2H9v-6l6 6h-1v2h3l3 3 1-1-3-3zm7 4V5H7l2 2zm8-2v2h1v10l2 2V5z" id="noWikiText-rtl"/>
 </svg>
index 9ebd6a9..b07a6a1 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9 13l-2 2V5h3v2H9zM21 3l1 1-1 1v14h-3v-2h1V7l-2 2v10h-3v-2h1v-6l-6 6h1v2H7l-3 3-1-1 3-3zm-7 4V5h3l-2 2zM6 5v2H5v10l-2 2V5z" id="noWikiText-rtl"/>
 </svg>
index 871c204..94fd0b8 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8z"/>
 </svg>
index 6ea2ad6..50d4ad6 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="svg3116"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="svg3116"><style>* { fill: #ffffff }</style>
     <path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm-1-5h2V8h-2zm0 3h2v-2h-2z" id="alert"/>
 </svg>
index f95bb00..e8a56bc 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #FFFFFF }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #ffffff }</style>
     <path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
 </svg>
index 7b02ae0..89d2745 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347BFF }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347bff }</style>
     <path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
 </svg>
index 5b1b067..a66123e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #FFFFFF }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #ffffff }</style>
     <path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.332 1.332 0 0 0-.945-.405c-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
 </svg>
index 0d0c46e..d0c3c64 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347BFF }</style>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><style>* { fill: #347bff }</style>
     <path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.332 1.332 0 0 0-.945-.405c-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
 </svg>
index 1695dae..8136cb9 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10 8h9v2h-9V8zm0 3h9v2h-9v-2zm0 3h6v2h-6v-2zm11-8H3V4h18v2zm0 14H3v-2h18v2zM3 12l5 4V8l-5 4z"/>
 </svg>
index d3e794f..4a08f5f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M14 8H5v2h9V8zm0 3H5v2h9v-2zm0 3H8v2h6v-2zM3 6h18V4H3v2zm0 14h18v-2H3v2zm18-8l-5 4V8l5 4z"/>
 </svg>
index 62d78e1..d9d1390 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="outline-ltr">
         <path id="text" d="M5 13h14v6H5v-6z"/>
         <path id="float" d="M5 5v6h6V5H5zm5 5H6V6h4v4z"/>
index b992baf..f1dd2df 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="outline-rtl">
         <path id="text" d="M19 19H5v-6h14v6z"/>
         <path id="float" d="M13 5v6h6V5h-6zm1 1h4v4h-4V6z"/>
index 965697b..ffc0cc0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-2 12V9l6 4-6 4z"/>
 </svg>
index 67143de..9c3220b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 5c4.4 0 8 3.6 8 8s-3.6 8-8 8-8-3.6-8-8 3.6-8 8-8zm2 12V9l-6 4 6 4z"/>
 </svg>
index 08c2c36..4737769 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M18 8h-1V4H7v4H3v6c0 1.7 1.3 3 3 3h1v3h10v-3h4v-6c0-1.7-1.3-3-3-3zM8 5h8v3H8V5zm8 14H8v-6h8v6z"/>
 </svg>
index d431703..14d5bfe 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6 8h1V4h10v4h4v6c0 1.7-1.3 3-3 3h-1v3H7v-3H3v-6c0-1.7 1.3-3 3-3zm10-3H8v3h8V5zM8 19h8v-6H8v6z"/>
 </svg>
index 601d880..fb03c63 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M18 9.9c-.7 0-1.4.3-1.8.9V6h-4c.2-.4.4-.8.4-1.2 0-1.2-1-2.2-2.2-2.2-1.3-.1-2.3.9-2.3 2.2 0 .4.2.8.4 1.2H4.1v3.6l.6-.1c1.4 0 2.5 1.1 2.5 2.5s-1.1 2.5-2.5 2.5c-.2 0-.4 0-.6-.1V18H9c-.5.4-.9 1-.9 1.8 0 1.2 1 2.2 2.3 2.2 1.2 0 2.2-1 2.2-2.2 0-.7-.3-1.4-.9-1.8h4.5v-4.5c.4.5 1 .9 1.8.9 1.2 0 2.2-1 2.2-2.2 0-1.3-1-2.3-2.2-2.3z"/>
 </svg>
index 909fb8e..9f7ce1e 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6.3 9.9c.7 0 1.4.3 1.8.9V6h4c-.2-.4-.4-.8-.4-1.2 0-1.2 1-2.2 2.2-2.2 1.3-.1 2.3.9 2.3 2.2 0 .4-.2.8-.4 1.2h4.4v3.6l-.6-.1c-1.4 0-2.5 1.1-2.5 2.5s1.1 2.5 2.5 2.5c.2 0 .4 0 .6-.1V18h-4.9c.5.4.9 1 .9 1.8 0 1.2-1 2.2-2.3 2.2-1.2 0-2.2-1-2.2-2.2 0-.7.3-1.4.9-1.8H8.1v-4.5c-.4.5-1 .9-1.8.9-1.2 0-2.2-1-2.2-2.2 0-1.3 1-2.3 2.2-2.3z"/>
 </svg>
index 36a8442..17de62b 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="quotes">
         <path id="quote" d="M6.9 8.4c-.446.55-1.974 2.6-1.9 5.7V17h4.7c.9 0 1.6-.7 1.6-1.6V11H8.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
     </g>
index 5b48b87..0ac72cb 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="quotes">
         <path id="quote" d="M17.1 8.4c.446.55 1.9 2.6 1.9 5.7V17h-4.7c-.9 0-1.6-.7-1.6-1.6V11h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
     </g>
index d9e2e06..8953f4d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="quotes-add">
         <path id="quote" d="M5.9 10.4c-.446.55-1.974 2.6-1.9 5.7V19h4.7c.9 0 1.593-.7 1.6-1.6V13H7.2s.05-.74.6-1.4c.453-.543 1-.9 1.6-1.2.2-.1.47-.212.6-.5.127-.282.2-.5.2-.9v-.6c-1 .2-1.744.197-2.6.6-.856.403-1.272.873-1.7 1.4z"/>
         <path id="quote2" d="M15 9.344c-.476.32-.78.677-1.094 1.062A8.76 8.76 0 0 0 12 16.094V19h4.688a1.6 1.6 0 0 0 1.625-1.594V13H15V9.344z"/>
index 63e715a..1ada793 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="quotes-add">
         <path id="quote" d="M18.097 10.4c.446.55 1.974 2.6 1.9 5.7V19h-4.7c-.9 0-1.593-.7-1.6-1.6V13h3.1s-.05-.74-.6-1.4c-.453-.543-1-.9-1.6-1.2-.2-.1-.47-.212-.6-.5-.127-.282-.2-.5-.2-.9v-.6c1 .2 1.744.197 2.6.6.856.403 1.272.873 1.7 1.4z"/>
         <path id="quote2" d="M8.997 9.344c.476.32.782.677 1.094 1.062A8.758 8.758 0 0 1 12 16.094V19H7.31c-.9 0-1.618-.694-1.625-1.594V13h3.312V9.344z"/>
index ae5581c..61b1550 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="regular-expression">
         <path id="left-bracket" d="M3 12.045c0-.99.15-1.915.45-2.777A6.886 6.886 0 0 1 4.764 7H6.23a7.923 7.923 0 0 0-1.25 2.374 8.563 8.563 0 0 0 .007 5.314c.29.85.7 1.622 1.23 2.312h-1.45a6.53 6.53 0 0 1-1.314-2.223 8.126 8.126 0 0 1-.45-2.732"/>
         <path id="dot" d="M10 16a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
index 3a09864..458abd0 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <circle cx="11.5" cy="8.5" r="2.5"/>
     <path d="M16.3 8.7L17 8l-.8-.8.4-.8-1.1-.5.1-.9-1.2-.2-.1-.9-1.2.2-.4-.8-1.1.5L11 3l-.8.8-.9-.4-.5 1.1-.9-.2-.2 1.2-.9.2.2 1.2-.9.4.5 1.1L6 9l.8.8-.4.8 1.1.5-.1.9 1.2.2.1.9 1.2-.2.4.8 1.1-.5.6.8.8-.8.8.4.5-1.1.9.1.2-1.2.9-.1-.2-1.2.8-.4-.4-1zM11.5 12C9.6 12 8 10.4 8 8.5S9.6 5 11.5 5 15 6.6 15 8.5 13.4 12 11.5 12zm.5 3l-.7-.7-1.1.6-.4-.7-.8.3V23l2.5-3 2.5 3v-8.5l-1-.5z"/>
 </svg>
index 992aee9..316ac6d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="search">
         <path id="magnifying-glass" d="M10.5 4a6.5 6.5 0 1 0 2.844 12.344L16 19c1.4 1.4 2.5 1.5 4 0l-4.438-4.438A6.426 6.426 0 0 0 17 10.5 6.5 6.5 0 0 0 10.5 4zm0 2a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9z"/>
     </g>
index 5da62dc..1d36daf 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="search">
         <path id="magnifying-glass" d="M13.5 4a6.5 6.5 0 1 1-2.844 12.344L8 19c-1.4 1.4-2.5 1.5-4 0l4.438-4.438A6.426 6.426 0 0 1 7 10.5 6.5 6.5 0 0 1 13.5 4zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"/>
     </g>
index ed31a41..488e2e2 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="secure">
         <path id="lock" d="M8 5h.02v-.997c0-.057.003-1.41-.833-2.255-.434-.438-.998-.66-1.68-.66s-1.244.222-1.677.66c-.837.846-.833 2.198-.832 2.25V5H3a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1zM3.998 5V3.993c0-.01.005-1 .543-1.543.49-.485 1.45-.487 1.94-.002.543.546.545 1.536.545 1.55V5H3.998z"/>
     </g>
index e67b8f4..543aded 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="settings">
         <path id="gear" d="M3 4h3v2H3zm9 0h9v2h-9zM8 3h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm-5 8h9v2H3zm15 0h3v2h-3zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1zM3 18h6v2H3zm12 0h6v2h-6zm-4-1h2a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1z"/>
     </g>
index 554525a..101e2af 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M0 20h24v1H0v-1zm6-8l-1-1-2 2-2-2-1 1 2 2-2 2 1 1 2-2 2 2 1-1-2-2zm15.6 3.7c-.9-.5-1.9-.5-2.7 0-1.5.9-3.1.4-3.1.4-.4-.2-.8-.4-1.1-.6 2.2-.6 4.4-1.8 6-3.9 1.1-1.2 2.5-3.9.4-6-.7-.7-1.6-1.1-2.7-1-1.4.1-2.8.9-3.9 2.1-.9 1.1-3.1 4.5-2.3 7.5 0 .1 0 .2.1.3-2.3.3-4.2.2-4.4.1v1.5c.7.1 2.7.2 5.1-.2.5.7 1.3 1.2 2.3 1.6.1 0 2.4.8 4.5-.6.5-.3.9-.1 1.1 0 .4.2.7.6.7 1H23c0-.8-.6-1.7-1.4-2.2zm-8-1.7c-.5-2.2 1.1-5.1 2-6.2.8-.9 1.8-1.5 2.8-1.6h.1c.6 0 1.1.2 1.5.6 1.6 1.6-.4 3.9-.5 4-1.5 2-3.7 3-5.8 3.5l-.1-.3z"/>
 </svg>
index 6b30010..67bd738 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M24 20H0v1h24v-1zm-6-8l1-1 2 2 2-2 1 1-2 2 2 2-1 1-2-2-2 2-1-1 2-2zM2.4 15.7c.9-.5 1.9-.5 2.7 0 1.5.9 3.1.4 3.1.4.4-.2.8-.4 1.1-.6-2.2-.6-4.4-1.8-6-3.9-1.1-1.2-2.5-3.9-.4-6 .7-.7 1.6-1.1 2.7-1 1.4.1 2.8.9 3.9 2.1.9 1.1 3.1 4.5 2.3 7.5 0 .1 0 .2-.1.3 2.3.3 4.2.2 4.4.1v1.5c-.7.1-2.7.2-5.1-.2-.5.7-1.3 1.2-2.3 1.6-.1 0-2.4.8-4.5-.6-.5-.3-.9-.1-1.1 0-.4.2-.7.6-.7 1H1c0-.8.6-1.7 1.4-2.2zm8-1.7c.5-2.2-1.1-5.1-2-6.2-.8-.9-1.8-1.5-2.8-1.6h-.1c-.6 0-1.1.2-1.5.6-1.6 1.6.4 3.9.5 4 1.5 2 3.7 3 5.8 3.5l.1-.3z"/>
 </svg>
index 1126dba..ebbc3c1 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
     <g id="down">
         <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
index ffac2da..02a8fe6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
     <g id="down">
         <path id="arrow" d="M9 3L5.5 9 2 3z"/>
index 9f5a2e3..107f5f6 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17.6 20h-5.4v-.5c.2 0 .5-.1.9-.1.3-.1.5-.2.5-.3V19s0-.1-.1-.2l-.8-2H9.3c-.1.2-.2.4-.3.7-.1.3-.2.5-.2.7-.1.3-.1.4-.2.6v.2c0 .1.1.3.3.4.2.1.6.2 1.1.2v.4H6v-.5c.2 0 .3 0 .5-.1.2 0 .3-.1.5-.2s.4-.2.5-.4l.3-.6c.5-1.3 1.1-2.6 1.6-3.9.5-1.3 1.1-2.7 1.8-4.3h1.4c.9 2.2 1.6 4 2.1 5.3.5 1.3 1 2.4 1.3 3.2.1.1.1.3.2.4.1.1.2.2.4.3.1.1.3.1.5.2s.3.1.5.1v.5zm-5.2-4L11 12.4 9.6 16h2.8z"/>
 </svg>
index 09b8413..a290c92 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6 19.5c.1 0 .3 0 .5-.1s.3-.1.5-.2.3-.2.4-.3c.1-.1.2-.2.2-.4.4-.9.8-1.9 1.3-3.2.5-1.3 1.2-3.1 2.1-5.3h1.4c.7 1.6 1.2 3 1.8 4.3.5 1.3 1.1 2.6 1.6 3.9l.3.6c.1.2.3.3.5.4.1.1.3.1.5.2.2 0 .4.1.5.1v.5h-4v-.5c.5 0 .9-.1 1.1-.2.2-.1.3-.2.3-.4v-.2c0-.1-.1-.3-.2-.6-.1-.2-.2-.4-.2-.7-.1-.3-.2-.5-.3-.7h-3.4l-.8 2c0 .1-.1.1-.1.2v.1c0 .1.2.2.5.3.3.1.6.1.9.1v.6H6v-.5zm8-3.5l-1.4-3.6-1.4 3.6H14z"/>
 </svg>
index 30cb63f..43e2606 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="special-character">
         <path id="omega" d="M12 6.708c-.794 0-1.368.103-1.894.31-.525.207-.944.496-1.255.867-.31.366-.53.808-.66 1.327a7.232 7.232 0 0 0-.19 1.7c0 .512.06 1 .18 1.46.12.46.31.87.567 1.23.63.862 1.156 1.138 2.012 1.362L11 18H6v-3h.604l.53 1.353.395.053.6.044.75.035.455.01H10l-.09-.895c-.63-.094-.812-.268-1.337-.522-.525-.26-.98-.59-1.365-.99a4.428 4.428 0 0 1-.89-1.4 4.78 4.78 0 0 1-.32-1.778c0-.82.13-1.537.394-2.15a3.97 3.97 0 0 1 1.163-1.54c.507-.407 1.133-.71 1.878-.912.745-.206 1.6-.31 2.565-.31.96 0 1.81.103 2.556.31.75.2 1.38.504 1.887.912.51.407.9.92 1.16 1.54.27.614.404 1.33.404 2.15a4.79 4.79 0 0 1-.32 1.78 4.35 4.35 0 0 1-.9 1.397c-.38.4-.83.732-1.355.99-.526.255-.708.43-1.337.523l-.092.894h.66l.448-.01.75-.034.606-.044.4-.053.534-1.354H18v3h-5l.246-3.04c1.066-.11 1.337-.698 2.002-1.365.263-.36.452-.77.568-1.23.122-.46.183-.947.183-1.46 0-.62-.07-1.186-.198-1.7a3.175 3.175 0 0 0-.66-1.326c-.31-.37-.73-.66-1.255-.867-.525-.206-1.1-.31-1.894-.31"/>
     </g>
index c4ac930..500bbfb 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19 20H2l3-3V6h17v11c0 1.7-1.3 3-3 3z"/>
 </svg>
index 84fd324..1a9f6c8 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M5 20h17l-3-3V6H2v11c0 1.7 1.3 3 3 3z"/>
 </svg>
index 44f3048..d359edf 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M19 20H2l3-3V6h17v11c0 1.7-1.3 3-3 3z"/>
     <path fill="#fff" d="M13 9h1v7h-1zm-3 3h7v1h-7z"/>
 </svg>
index 61ce8fb..9c21693 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M5 20h17l-3-3V6H2v11c0 1.7 1.3 3 3 3z"/>
     <path d="M11 9h-1v7h1zm3 3H7v1h7z" fill="#fff"/>
 </svg>
index d224d88..090099b 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 9v9l2 2H8V9h12zM3 4h12v4H7v7H1l2-2V4z"/>
 </svg>
index d442be9..1845684 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M3 9v9l-2 2h14V9H3zm17-5H8v4h8v7h6l-2-2V4z"/>
 </svg>
index 9e64bcf..ffe5556 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <path d="M12 7.4l1.7 3.6 4 .5-2.7 2.8.5 3.9-3.5-1.7-3.6 1.7.6-3.9-2.8-2.8 3.9-.5L12 7.4M12 4L9.2 9.6l-6.2.9 4.5 4.4L6.4 21l5.6-3 5.5 3-1-6.2 4.5-4.4-6.3-.9L12 4z"/>
 </svg>
index af06636..c745706 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 7.4l1.7 3.6 4 .5-2.7 2.8.5 3.9-3.5-1.7-3.6 1.7.6-3.9-2.8-2.8 3.9-.5L12 7.4M12 4L9.2 9.6l-6.2.9 4.5 4.4L6.4 21l5.6-3 5.5 3-1-6.2 4.5-4.4-6.3-.9L12 4z"/>
 </svg>
index ef7b7c6..8b49792 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 6c3.9 0 7 3.1 7 7s-3.1 7-7 7-7-3.1-7-7 3.1-7 7-7m0-1c-4.4 0-8 3.6-8 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm-3 5h6v6H9z"/>
 </svg>
index 60b36a8..6f3ab7c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="strikethrough-a">
         <path id="strikethrough" d="M6 11h12v1H6v-1z"/>
         <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
index 27a1740..b3361b1 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="strikethrough-s">
         <path id="strikethrough" d="M6 12h12v1H6v-1z"/>
         <path id="s" d="M12.094 6c-1.133 0-2.076.287-2.75.9-.67.613-1 1.49-1 2.52 0 .89.22 1.602.72 2.13.497.528 1.278.91 2.31 1.14l.813.182v-.03c.656.147 1.128.375 1.375.63.252.256.375.607.375 1.11 0 .573-.172.97-.53 1.26-.36.29-.895.45-1.626.45-.47 0-.962-.074-1.462-.24a7.288 7.288 0 0 1-1.562-.75l-.374-.238v2.158l.156.062c.58.237 1.144.417 1.69.54.548.12 1.07.18 1.56.18 1.287 0 2.298-.293 3-.9.71-.605 1.063-1.486 1.063-2.608 0-.943-.256-1.726-.78-2.312-.522-.592-1.306-1-2.345-1.23l-.812-.18c-.714-.148-1.202-.352-1.404-.54-.206-.202-.313-.484-.313-.934 0-.533.162-.9.5-1.17.342-.27.836-.42 1.53-.42.396 0 .82.052 1.25.18.434.128.91.334 1.407.6l.375.18V6.63s-1.19-.383-1.69-.48c-.5-.097-.983-.15-1.467-.15z"/>
index 50db67b..bdb6528 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="strikethrough-y">
         <path id="strikethrough" d="M6 11h12v1H6v-1z"/>
         <path id="a" d="M7 6h1.724l3.288 4.935L15.276 6H17l-4.194 6.285V18h-1.612v-5.715L7 6"/>
index 97aacad..7eaeea5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 9h12v2H4V9zm0 3h8v2H4v-2zm0-7h16v3H4V5zm16 14H4v-3h16v3z"/>
 </svg>
index 9df2e14..f23d8ab 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 9H8v2h12V9zm0 3h-8v2h8v-2zm0-7H4v3h16V5zM4 19h16v-3H4v3z"/>
 </svg>
index dd27787..5600c60 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 19H4v-2h16v2zM20 15H4v-2h16v2zM20 11H4V9h16v2z"/>
 </svg>
index 41505fb..8f263c0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20 11H4V9h16v2zM4 12h8v2H4v-2z"/>
 </svg>
index 1b7c161..f543b9d 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 11h16V9H4v2zm16 1h-8v2h8v-2z"/>
 </svg>
index 8adc078..52487c4 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
 </svg>
index 9e87ded..7c36776 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M17 13H4v-3h13v3zm-5 6H4v-3h8v3zM4 7V4h16v3H4z"/>
 </svg>
index 9c5adaa..f656017 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
 </svg>
index efc27ab..26a9fc5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M7 13h13v-3H7v3zm5 6h8v-3h-8v3zm8-12V4H4v3h16z"/>
 </svg>
index b5ef54e..4638e31 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
     <path d="M18 13l-1 1v3l1 1h-1l-.527-.46L16 18h-1l1-1v-3l-1-1h1l.485.497L17 13z"/>
 </svg>
index e43eac6..76a8659 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
     <path d="M8 13l1 1v3l-1 1h1l.527-.46L10 18h1l-1-1v-3l1-1h-1l-.485.497L9 13z"/>
 </svg>
index 7f7ef3a..76601ef 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M18.1 5.1c0 .3-.1.6-.3.9l-1.4 1.4-.9-.8 2.2-2.2c.3.1.4.4.4.7zm-.5 5.3h3.2c0 .3-.1.6-.4.9s-.5.4-.8.4h-2v-1.3zm-6.2-5V2.2c.3 0 .6.1.9.4s.4.5.4.8v2h-1.3zm6.4 11.7c-.3 0-.6-.1-.8-.3l-1.4-1.4.8-.8 2.2 2.2c-.2.2-.5.3-.8.3zM6.2 4.9c.3 0 .6.1.8.3l1.4 1.4-.8.9-2.2-2.3c.2-.2.5-.3.8-.3zm5.2 11.7h1.2v3.2c-.3 0-.6-.1-.9-.4s-.4-.5-.4-.8l.1-2zm-7-6.2h2v1.2H3.2c0-.3.1-.6.4-.9s.5-.3.8-.3zM6.2 16l1.4-1.4.8.8-2.2 2.2c-.2-.2-.3-.5-.3-.8s.1-.6.3-.8z"/>
     <circle cx="12" cy="11" r="4"/>
 </svg>
index 7559366..99bed35 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M5.9 5.1c0 .3.1.6.3.9l1.4 1.4.9-.8-2.2-2.2c-.3.1-.4.4-.4.7zm.5 5.3H3.2c0 .3.1.6.4.9.3.3.5.4.8.4h2v-1.3zm6.2-5V2.2c-.3 0-.6.1-.9.4-.3.3-.4.5-.4.8v2h1.3zM6.2 17.1c.3 0 .6-.1.8-.3l1.4-1.4-.8-.8-2.2 2.2c.2.2.5.3.8.3zM17.8 4.9c-.3 0-.6.1-.8.3l-1.4 1.4.8.9 2.2-2.3c-.2-.2-.5-.3-.8-.3zm-5.2 11.7h-1.2v3.2c.3 0 .6-.1.9-.4.3-.3.4-.5.4-.8l-.1-2zm7-6.2h-2v1.2h3.2c0-.3-.1-.6-.4-.9-.3-.3-.5-.3-.8-.3zM17.8 16l-1.4-1.4-.8.8 2.2 2.2c.2-.2.3-.5.3-.8 0-.3-.1-.6-.3-.8z"/>
     <circle cx="12" cy="11" r="4" transform="matrix(-1 0 0 1 24 0)"/>
 </svg>
index 7f95dcf..bd2e11d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="x" d="M14 9l-2.354 3.406L14 16h-1.2L11 13.25 9.2 16H8l2.403-3.662L8 9h1.188l1.857 2.494L12.797 9H14z"/>
     <path d="M18 7l-1 1v3l1 1h-1l-.527-.46L16 12h-1l1-1V8l-1-1h1l.485.497L17 7z"/>
 </svg>
index 468316d..7e0f907 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path id="x" d="M12 9l2.354 3.406L12 16h1.2l1.8-2.75L16.8 16H18l-2.403-3.662L18 9h-1.188l-1.857 2.494L13.203 9H12z"/>
     <path d="M8 7l1 1v3l-1 1h1l.527-.46L10 12h1l-1-1V8l1-1h-1l-.485.497L9 7z"/>
 </svg>
index 3923614..72af30c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-caption">
         <path id="caption" d="M6 6h12v3H6z"/>
         <path id="table" d="M4 10v7h16v-7H4zm1 1h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2zM5 14h4v2H5v-2zm5 0h4v2h-4v-2zm5 0h4v2h-4v-2z"/>
index 1bb2d7e..37449b3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-insert-column-ltr">
         <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
         <path d="M5 5h2v14H5z" id="column"/>
index 8489597..7dbd4f6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-insert-column-rtl">
         <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
         <path d="M17 5h2v14h-2z" id="column"/>
index d0813a6..fdb668f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-insert-row-after">
         <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
         <path d="M5 17h14v2H5z" id="row"/>
index 516078f..38998d4 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-insert-row-before">
         <path d="M13 9h-2v2H9v2h2v2h2v-2h2v-2h-2z" id="plus"/>
         <path d="M5 5h14v2H5z" id="row"/>
index 808d8d8..3866463 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-insert">
         <path id="table" d="M4 6v11h15V6zm1 3h6v3H5zm7 0h6v3h-6zm-7 4h6v3H5zm7 0h6v3h-6z"/>
     </g>
index 06cb4da..bd571af 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="table-merge-cells">
         <g id="merge-cell-left">
             <path id="cell-border" d="M4 7v9h7v-3l-1 .834V15H5V8h5v1.167L11 10V7z"/>
index 5df96fd..9feb601 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index 631c9bc..1058e83 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index 9fc98f7..066801a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index 24c64c2..1526306 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347BFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #347bff }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index 3cbd445..df57de5 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FF5D00 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ff5d00 }</style>
     <path d="M18.748 11.717a1 1 0 0 1 0 1.414l-4.95 4.95a1 1 0 0 1-1.413 0l-6.01-6.01c-.39-.382-.707-1.15-.707-1.7V6c0-.55.45-1 1-1h4.363c.55 0 1.32.318 1.71.707l6.01 6.01zM8.104 7.457a1.477 1.477 0 0 0 0 2.092 1.49 1.49 0 0 0 2.094 0 1.49 1.49 0 0 0 0-2.1 1.484 1.484 0 0 0-2.094 0z" id="tag"/>
 </svg>
index 0ed2901..2f1a02a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="template-add">
         <path id="add" d="M23 7h-4V3h-2v4h-4v2h4v4h2V9h4z"/>
         <path id="template" d="M18 14v4H6c-1.1 0-2-.9-2-2V8h8V7H3v9c0 1.7 1.3 3 3 3h13v-5z"/>
index 3927113..70ce39f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="template-add">
         <path id="add" d="M1 7h4V3h2v4h4v2H7v4H5V9H1z"/>
         <path id="template" d="M6 14v4h12c1.1 0 2-.9 2-2V8h-8V7h9v9c0 1.7-1.3 3-3 3H5v-5z"/>
index 8328910..fb1a466 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M7 7H5V6h2l.47.5L8 6h2v1H8v10h2v1H8l-.5-.53L7 18H5v-1h2zm6.976 9v-2H11v-4h2.976V8.044L20 12.022z" id="text-dir-ltr"/>
 </svg>
index 2218b3a..867e464 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M17 17h2v1h-2l-.47-.5-.53.5h-2v-1h2V7h-2V6h2l.5.53L17 6h2v1h-2zm-6.976-9v2H13v4h-2.976v1.956L4 11.978z" id="text-dir-rtl"/>
 </svg>
index 0367cfe..9a713d9 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="text-style">
         <path id="a" d="M15.296 18h2.79l-1.14-12h-2.79L6 18h2.79l2.038-3h4.183l.29 3zm-3.11-5L14.5 9.6l.323 3.4H12.19z"/>
         <path id="underline" d="M6 19h12v1H6v-1z"/>
index 7ef05a6..7489b7a 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
 </svg>
index 65ba012..90c82f2 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M6 8c0-1.1.9-2 2-2h2l1-1h2l1 1h2c1.1 0 2 .9 2 2H6zm1 1h10l-1 11H8z"/>
 </svg>
index 0c4c20a..70b6f83 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
 </svg>
index e27acd9..d5edf14 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
 </svg>
index 7a6c291..385686c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
 </svg>
index 53c2153..3ac59e0 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 9V7s0-5-4.5-5S3 7 3 7h2s0-3 2.5-3S10 7 10 7v2H7v7c0 1.7 1.3 3 3 3h10V9z"/>
 </svg>
index f2e301c..0f79916 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #D11D13 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #d11d13 }</style>
     <path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
 </svg>
index 0de2e76..d182c6d 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 9V7s0-5 4.5-5S20 7 20 7h-2s0-3-2.5-3S13 7 13 7v2h3v7c0 1.7-1.3 3-3 3H3V9z"/>
 </svg>
index 818f5a7..5e98ccb 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00AF89 }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #00af89 }</style>
     <path d="M21 11l-6-1-3-6-3 6-6 1 4 4-1 6 6-3 6 3-1-6 4-4z"/>
 </svg>
index b66ce2a..73d8054 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M21 11l-6-1-3-6-3 6-6 1 4 4-1 6 6-3 6 3-1-6 4-4z"/>
 </svg>
index 3581c57..79fcbf3 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="underline-a">
         <path id="a" d="M14.424 16H16.5L13.037 6H10.96L7.5 16h2.077l.627-2h3.604l.616 2zm-3.92-3.623L12 7.997l1.51 4.38h-3z"/>
         <path id="underline" d="M7 17h10v1H7v-1z"/>
index f1c82d2..9e7353e 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="underline-u">
         <path id="u" d="M8 6h2v5.96c-.104 1.706.695 2 2 2.04 1.777.062 2.002-.88 2-2.04V6h2v6.123c0 1.28-.338 2.245-1.016 2.898-.672.658-1.666.98-2.98.98-1.32 0-2.32-.32-2.996-.98C8.336 14.37 8 13.41 8 12.13V6"/>
         <path id="underline" d="M7 17h10v1H7v-1z"/>
index b23189f..52223ab 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M12 8l8 10H4z"/>
 </svg>
index 29eca3d..f29501f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M10 13c0 1.7 1.3 3 3 3V9h3l-4.5-5L7 9h3v4zm7 0v5H7c-.6 0-1-.4-1-1v-4H4v4c0 1.9 1.3 3 3 3h12v-7h-2z"/>
 </svg>
index 1f81996..68b8b1f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M13 13c0 1.7-1.3 3-3 3V9H7l4.5-5L16 9h-3v4zm-7 0v5h10c.6 0 1-.4 1-1v-4h2v4c0 1.9-1.3 3-3 3H4v-7h2z"/>
 </svg>
index ed1913a..25923e2 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="viewCompact">
         <circle cx="6" cy="6" r="2"/>
         <circle cx="12" cy="6" r="2"/>
index 7c064cc..4471f59 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="viewDetails">
         <circle cx="5.5" cy="8.5" r="2.5"/>
         <path d="M10 6h12v1H10zm0 2h9v1h-9zm0 2h4v1h-4z"/>
index f4838fe..dad4b91 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="viewDetails">
         <circle cx="18.5" cy="8.5" r="2.5"/>
         <path d="M14 6H2v1h12zm0 2H5v1h9zm0 2h-4v1h4z"/>
index ae0d94e..0e7728f 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M0 10v8h2.3c.3.6 1 1 1.7 1h4c1.5 0 2.7-.8 3-2h2c.3 1.2 1.5 2 3 2h4c.7 0 1.4 0 1.7-1H24v-8zm10 6c0 1-.4 2-2 2H4c-.6 0-1-.4-1-1v-3c0-.6.4-1 1-1h5c.6 0 1 .4 1 1zm11 1c0 .6-.4 1-1 1h-4c-1.6 0-2-1-2-2v-2c0-.6.4-1 1-1h5c.6 0 1 .4 1 1z"/>
 </svg>
index 7545aeb..d52e65c 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M13 14h5v1h-5v-1zm0 3h5v-1h-5v1zm0 1h5v1h-5v-1zm-1-5v3l-5 3 1-6-4-3 6-1 2-5s1.9 5 2 5l6 1-4 3h-4z"/>
 </svg>
index 812ee38..f193915 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M11 14H6v1h5v-1zm0 3H6v-1h5v1zm0 1H6v1h5v-1zm1-5v3l5 3-1-6 4-3-6-1-2-5s-1.9 5-2 5l-6 1 4 3h4z"/>
 </svg>
index ec12d0e..131c83d 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="wikiText">
         <path id="opening-bracket-inner" d="M7 19h3v-2H9V7h1V5H7z"/>
         <path id="closing-bracket-inner" d="M17 19h-3v-2h1V7h-1V5h3z"/>
index dc90fba..df03c66 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M15 9l.7-1.8c.9.4 1.8.7 2.4.9l-.6 1.7v.2L15 9zm-4.3-1.9l.8-1.8c1.2.5 2.6 1.1 3 1.4l-.8 1.8-3-1.4zm-5.9-1c-.8 0-1.4.2-2 .6L1.7 5c.9-.6 1.9-.9 3.1-.9v2zm-4.3.7l1.8.8c-.3.7-.3 1.3-.1 1.8l-1.9.7C0 8.9 0 7.8.5 6.8zm4.2 5.4l-1.3 1.5c-1-1-1.7-1.6-2-2l1.5-1.3c.7.8 1.3 1.4 1.8 1.8zm7.3 4.3c0 1.9-1.6 3.5-3.5 3.5S5 18.4 5 16.5 6.6 13 8.5 13s3.5 1.6 3.5 3.5zM24 8l-1-1-1.5 1.5L20 7l-1 1 1.5 1.5L19 11l1 1 1.5-1.5L23 12l1-1-1.5-1.5z"/>
     <circle cx="8" cy="5" r="2"/>
 </svg>
index 09ac9db..9153a1a 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <path d="M9.095 9l-.7-1.8c-.9.4-1.8.7-2.4.9l.6 1.7v.2l2.5-1zm4.3-1.9l-.8-1.8c-1.2.5-2.6 1.1-3 1.4l.8 1.8 3-1.4zm5.9-1c.8 0 1.4.2 2 .6l1.1-1.7c-.9-.6-1.9-.9-3.1-.9v2zm4.3.7l-1.8.8c.3.7.3 1.3.1 1.8l1.9.7c.3-1.2.3-2.3-.2-3.3zm-4.2 5.4l1.3 1.5c1-1 1.7-1.6 2-2l-1.5-1.3c-.7.8-1.3 1.4-1.8 1.8zm-7.3 4.3c0 1.9 1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5-1.6-3.5-3.5-3.5-3.5 1.6-3.5 3.5zM.095 8l1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5 1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5z"/>
     <circle cx="8" cy="5" r="2" transform="matrix(-1 0 0 1 24.095 0)"/>
 </svg>
index a1d59d5..699d6b9 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #ffffff }</style>
     <g id="window">
         <path id="title" d="M7 10h10v1H7z"/>
         <path id="frame" d="M16 19H8c-2.206 0-4-1.794-4-4V9c0-2.206 1.794-4 4-4h8c2.206 0 4 1.794 4 4v6c0 2.206-1.794 4-4 4zM8 7c-1.103 0-2 .897-2 2v6c0 1.103.897 2 2 2h8c1.103 0 2-.897 2-2V9c0-1.103-.897-2-2-2H8z"/>
index d59e992..0b692e3 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <path d="M6 12A6 6 0 1 1 6 0a6 6 0 0 1 0 12zM5 7h2V2H5zm0 3h2V8H5z" id="alert"/>
 </svg>
index 7567b5d..3f7f447 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="down">
         <path id="arrow" d="M1 4h10L6 9 1 4"/>
     </g>
index 63384fa..01ec154 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="ltr">
         <path id="arrow" d="M4 1v10l5-5-5-5"/>
     </g>
index a9e9ce3..a12a0e7 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="rtl">
         <path id="arrow" d="M8 11V1L3 6l5 5"/>
     </g>
index 2d11d4f..a561ff7 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="up">
         <path id="arrow" d="M1 8h10L6 3 1 8"/>
     </g>
index 5b03054..36b5dd7 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="clear">
         <path id="circle-with-cross" d="M6 0C2.7 0 0 2.7 0 6s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zM3.5 2.5L6 5l2.5-2.5 1 1L7 6l2.5 2.5-1 1L6 7 3.5 9.5l-1-1L5 6 2.5 3.5z"/>
     </g>
index dd6ef78..b3a3745 100644 (file)
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <path d="M5 1h2v10H5zm4.83 1.634l1 1.732-8.66 5-1-1.732zM1.17 4.366l1-1.732 8.66 5-1 1.732z" id="required"/>
 </svg>
index 2ac9647..b16e101 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="search">
         <path id="magnifying-glass" d="M10.37 9.474L7.994 7.1l-.17-.1a3.45 3.45 0 0 0 .644-2.01A3.478 3.478 0 1 0 4.99 8.47c.75 0 1.442-.24 2.01-.648l.098.17 2.375 2.373c.19.188.543.142.79-.105s.293-.6.104-.79zm-5.38-2.27a2.21 2.21 0 1 1 2.21-2.21A2.21 2.21 0 0 1 4.99 7.21z"/>
     </g>
index 0d0ded4..ee8ad61 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #FFFFFF }</style>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><style>* { fill: #ffffff }</style>
     <g id="search">
         <path id="magnifying-glass" d="M1.63 9.474L4.006 7.1l.17-.1a3.45 3.45 0 0 1-.644-2.01A3.478 3.478 0 1 1 7.01 8.47 3.43 3.43 0 0 1 5 7.822l-.098.17-2.375 2.373c-.19.188-.543.142-.79-.105s-.293-.6-.104-.79zm5.378-2.27A2.21 2.21 0 1 0 4.8 4.994 2.21 2.21 0 0 0 7.01 7.21z"/>
     </g>
index 5a83258..876a055 100644 (file)
@@ -4,7 +4,7 @@
        "intro": "@import '../../../../src/styles/common';",
        "variants": {
                "invert": {
-                       "color": "#FFFFFF",
+                       "color": "#ffffff",
                        "global": true
                }
        },
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.css b/resources/src/mediawiki.special/mediawiki.special.apisandbox.css
new file mode 100644 (file)
index 0000000..e52955f
--- /dev/null
@@ -0,0 +1,74 @@
+.mw-apisandbox-fullscreen {
+       overflow: hidden;
+}
+
+.mw-apisandbox-toolbar {
+       text-align: right;
+       padding: 0.5em;
+}
+
+.mw-apisandbox-popup .oo-ui-popupWidget-body > .oo-ui-widget {
+       vertical-align: middle;
+}
+
+/* So DateTimeInputWidget's calendar popup works... */
+.mw-apisandbox-popup .oo-ui-popupWidget-popup,
+.mw-apisandbox-popup .oo-ui-popupWidget-body {
+       overflow: visible;
+}
+
+.mw-apisandbox-fullscreen #mw-apisandbox-ui {
+       position: fixed;
+       top: 0;
+       left: 0;
+       bottom: 0;
+       right: 0;
+       background: #fff;
+       z-index: 100;
+}
+
+.mw-apisandbox-spacer {
+       display: inline-block;
+       height: 1px;
+       width: 5em;
+}
+
+.mw-apisandbox-optionalWidget {
+       width: 100%;
+}
+
+.mw-apisandbox-optionalWidget.oo-ui-widget-disabled {
+       position: relative;
+       z-index: 0; /* New stacking context to prevent the overlay from leaking out */
+}
+
+.mw-apisandbox-optionalWidget-overlay {
+       position: absolute;
+       left: 0;
+       right: 0;
+       top: 0;
+       bottom: 0;
+       z-index: 2;
+       cursor: pointer;
+}
+
+.mw-apisandbox-optionalWidget-fields {
+       display: table;
+       width: 100%;
+}
+
+.mw-apisandbox-optionalWidget-widget,
+.mw-apisandbox-optionalWidget-checkbox {
+       display: table-cell;
+       vertical-align: middle;
+}
+
+.mw-apisandbox-optionalWidget-checkbox {
+       width: 1%; /* Will be expanded by content */
+       white-space: nowrap;
+       padding-left: 0.5em;
+}
+
+.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator.mw-apisandbox-clickable-indicator {
+       cursor: pointer;
+}
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.js b/resources/src/mediawiki.special/mediawiki.special.apisandbox.js
new file mode 100644 (file)
index 0000000..32ccdcd
--- /dev/null
@@ -0,0 +1,1659 @@
+/*global OO */
+( function ( $, mw, OO ) {
+       'use strict';
+       var ApiSandbox, Util, WidgetMethods, Validators,
+               $content, panel, booklet, oldhash, windowManager, fullscreenButton,
+               api = new mw.Api(),
+               bookletPages = [],
+               availableFormats = {},
+               resultPage = null,
+               suppressErrors = true,
+               updatingBooklet = false,
+               pages = {},
+               moduleInfoCache = {};
+
+       WidgetMethods = {
+               textInputWidget: {
+                       getApiValue: function () {
+                               return this.getValue();
+                       },
+                       setApiValue: function ( v ) {
+                               if ( v === undefined ) {
+                                       v = this.paramInfo[ 'default' ];
+                               }
+                               this.setValue( v );
+                       },
+                       apiCheckValid: function () {
+                               var that = this;
+                               return this.isValid().done( function ( ok ) {
+                                       ok = ok || suppressErrors;
+                                       that.setIcon( ok ? null : 'alert' );
+                                       that.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               } );
+                       }
+               },
+
+               dateTimeInputWidget: {
+                       isValid: function () {
+                               var ok = !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '';
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               },
+
+               tokenWidget: {
+                       alertTokenError: function ( code, error ) {
+                               windowManager.openWindow( 'errorAlert', {
+                                       title: mw.message(
+                                               'apisandbox-results-fixtoken-fail', this.paramInfo.tokentype
+                                       ).parse(),
+                                       message: error,
+                                       actions: [
+                                               {
+                                                       action: 'accept',
+                                                       label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                       flags: 'primary'
+                                               }
+                                       ]
+                               } );
+                       },
+                       fetchToken: function () {
+                               this.pushPending();
+                               return api.getToken( this.paramInfo.tokentype )
+                                       .done( this.setApiValue.bind( this ) )
+                                       .fail( this.alertTokenError.bind( this ) )
+                                       .always( this.popPending.bind( this ) );
+                       },
+                       setApiValue: function ( v ) {
+                               WidgetMethods.textInputWidget.setApiValue.call( this, v );
+                               if ( v === '123ABC' ) {
+                                       this.fetchToken();
+                               }
+                       }
+               },
+
+               passwordWidget: {
+                       getApiValueForDisplay: function () {
+                               return '';
+                       }
+               },
+
+               toggleSwitchWidget: {
+                       getApiValue: function () {
+                               return this.getValue() ? 1 : undefined;
+                       },
+                       setApiValue: function ( v ) {
+                               this.setValue( Util.apiBool( v ) );
+                       },
+                       apiCheckValid: function () {
+                               return $.Deferred().resolve( true ).promise();
+                       }
+               },
+
+               dropdownWidget: {
+                       getApiValue: function () {
+                               var item = this.getMenu().getSelectedItem();
+                               return item === null ? undefined : item.getData();
+                       },
+                       setApiValue: function ( v ) {
+                               var menu = this.getMenu();
+
+                               if ( v === undefined ) {
+                                       v = this.paramInfo[ 'default' ];
+                               }
+                               if ( v === undefined ) {
+                                       menu.selectItem();
+                               } else {
+                                       menu.selectItemByData( String( v ) );
+                               }
+                       },
+                       apiCheckValid: function () {
+                               var ok = this.getApiValue() !== undefined || suppressErrors;
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               },
+
+               capsuleWidget: {
+                       getApiValue: function () {
+                               return this.getItemsData().join( '|' );
+                       },
+                       setApiValue: function ( v ) {
+                               this.setItemsFromData( v === undefined || v === '' ? [] : String( v ).split( '|' ) );
+                       },
+                       apiCheckValid: function () {
+                               var ok = this.getApiValue() !== undefined || suppressErrors;
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               },
+
+               optionalWidget: {
+                       getApiValue: function () {
+                               return this.isDisabled() ? undefined : this.widget.getApiValue();
+                       },
+                       setApiValue: function ( v ) {
+                               this.setDisabled( v === undefined );
+                               this.widget.setApiValue( v );
+                       },
+                       apiCheckValid: function () {
+                               if ( this.isDisabled() ) {
+                                       return $.Deferred().resolve( true ).promise();
+                               } else {
+                                       return this.widget.apiCheckValid();
+                               }
+                       }
+               },
+
+               submoduleWidget: {
+                       single: function () {
+                               var v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                               return v === undefined ? [] : [ { value: v, path: this.paramInfo.submodules[ v ] } ];
+                       },
+                       multi: function () {
+                               var map = this.paramInfo.submodules,
+                                       v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                               return v === undefined || v === '' ? [] : $.map( String( v ).split( '|' ), function ( v ) {
+                                       return { value: v, path: map[ v ] };
+                               } );
+                       }
+               },
+
+               uploadWidget: {
+                       getApiValueForDisplay: function () {
+                               return '...';
+                       },
+                       getApiValue: function () {
+                               return this.getValue();
+                       },
+                       setApiValue: function () {
+                               // Can't, sorry.
+                       },
+                       apiCheckValid: function () {
+                               var ok = this.getValue() !== null || suppressErrors;
+                               this.setIcon( ok ? null : 'alert' );
+                               this.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
+                               return $.Deferred().resolve( ok ).promise();
+                       }
+               }
+       };
+
+       Validators = {
+               generic: function () {
+                       return !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '';
+               }
+       };
+
+       /**
+        * @class mw.special.ApiSandbox.Utils
+        * @private
+        */
+       Util = {
+               /**
+                * Fetch API module info
+                *
+                * @param {string} module Module to fetch data for
+                * @return {jQuery.Promise}
+                */
+               fetchModuleInfo: function ( module ) {
+                       var apiPromise,
+                               deferred = $.Deferred();
+
+                       if ( moduleInfoCache.hasOwnProperty( module ) ) {
+                               return deferred
+                                       .resolve( moduleInfoCache[ module ] )
+                                       .promise( { abort: function () {} } );
+                       } else {
+                               apiPromise = api.post( {
+                                       action: 'paraminfo',
+                                       modules: module,
+                                       helpformat: 'html',
+                                       uselang: mw.config.get( 'wgUserLanguage' )
+                               } ).done( function ( data ) {
+                                       var info;
+
+                                       if ( data.warnings && data.warnings.paraminfo ) {
+                                               deferred.reject( '???', data.warnings.paraminfo[ '*' ] );
+                                               return;
+                                       }
+
+                                       info = data.paraminfo.modules;
+                                       if ( !info || info.length !== 1 || info[ 0 ].path !== module ) {
+                                               deferred.reject( '???', 'No module data returned' );
+                                               return;
+                                       }
+
+                                       moduleInfoCache[ module ] = info[ 0 ];
+                                       deferred.resolve( info[ 0 ] );
+                               } ).fail( function ( code, details ) {
+                                       if ( code === 'http' ) {
+                                               details = 'HTTP error: ' + details.exception;
+                                       } else if ( details.error ) {
+                                               details = details.error.info;
+                                       }
+                                       deferred.reject( code, details );
+                               } );
+                               return deferred
+                                       .promise( { abort: apiPromise.abort } );
+                       }
+               },
+
+               /**
+                * Mark all currently-in-use tokens as bad
+                */
+               markTokensBad: function () {
+                       var page, subpages, i,
+                               checkPages = [ pages.main ];
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+
+                               if ( page.tokenWidget ) {
+                                       api.badToken( page.tokenWidget.paramInfo.tokentype );
+                               }
+
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+               },
+
+               /**
+                * Test an API boolean
+                *
+                * @param {Mixed} value
+                * @return {boolean}
+                */
+               apiBool: function ( value ) {
+                       return value !== undefined && value !== false;
+               },
+
+               /**
+                * Create a widget for a parameter.
+                *
+                * @param {Object} pi Parameter info from API
+                * @param {Object} opts Additional options
+                * @return {OO.ui.Widget}
+                */
+               createWidgetForParameter: function ( pi, opts ) {
+                       var widget, innerWidget, finalWidget, items, $button, $content, func,
+                               multiMode = 'none';
+
+                       opts = opts || {};
+
+                       switch ( pi.type ) {
+                               case 'boolean':
+                                       widget = new OO.ui.ToggleSwitchWidget();
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.toggleSwitchWidget );
+                                       pi.required = true; // Avoid wrapping in the non-required widget
+                                       break;
+
+                               case 'string':
+                               case 'user':
+                                       if ( pi.tokentype ) {
+                                               widget = new TextInputWithIndicatorWidget( {
+                                                       input: {
+                                                               indicator: 'previous',
+                                                               indicatorTitle: mw.message( 'apisandbox-fetch-token' ).text(),
+                                                               required: Util.apiBool( pi.required )
+                                                       }
+                                               } );
+                                       } else if ( Util.apiBool( pi.multi ) ) {
+                                               widget = new OO.ui.CapsuleMultiSelectWidget( {
+                                                       allowArbitrary: true
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.capsuleWidget );
+                                       } else {
+                                               widget = new OO.ui.TextInputWidget( {
+                                                       required: Util.apiBool( pi.required )
+                                               } );
+                                       }
+                                       if ( !Util.apiBool( pi.multi ) ) {
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.textInputWidget );
+                                               widget.setValidation( Validators.generic );
+                                       }
+                                       if ( pi.tokentype ) {
+                                               $.extend( widget, WidgetMethods.tokenWidget );
+                                               widget.input.paramInfo = pi;
+                                               $.extend( widget.input, WidgetMethods.textInputWidget );
+                                               $.extend( widget.input, WidgetMethods.tokenWidget );
+                                               widget.on( 'indicator', widget.fetchToken, [], widget );
+                                       }
+                                       break;
+
+                               case 'text':
+                                       widget = new OO.ui.TextInputWidget( {
+                                               multiline: true,
+                                               required: Util.apiBool( pi.required )
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       widget.setValidation( Validators.generic );
+                                       break;
+
+                               case 'password':
+                                       widget = new OO.ui.TextInputWidget( {
+                                               type: 'password',
+                                               required: Util.apiBool( pi.required )
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       $.extend( widget, WidgetMethods.passwordWidget );
+                                       widget.setValidation( Validators.generic );
+                                       multiMode = 'enter';
+                                       break;
+
+                               case 'integer':
+                                       widget = new OO.ui.NumberInputWidget( {
+                                               required: Util.apiBool( pi.required ),
+                                               isInteger: true
+                                       } );
+                                       widget.setIcon = widget.input.setIcon.bind( widget.input );
+                                       widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
+                                       widget.isValid = widget.input.isValid.bind( widget.input );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       if ( Util.apiBool( pi.enforcerange ) ) {
+                                               widget.setRange( pi.min || -Infinity, pi.max || Infinity );
+                                       }
+                                       multiMode = 'enter';
+                                       break;
+
+                               case 'limit':
+                                       widget = new OO.ui.NumberInputWidget( {
+                                               required: Util.apiBool( pi.required ),
+                                               isInteger: true
+                                       } );
+                                       widget.setIcon = widget.input.setIcon.bind( widget.input );
+                                       widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
+                                       widget.isValid = widget.input.isValid.bind( widget.input );
+                                       widget.input.setValidation( function ( value ) {
+                                               return value === 'max' || widget.validateNumber( value );
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       widget.setRange( pi.min || 0, mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max );
+                                       multiMode = 'enter';
+                                       break;
+
+                               case 'timestamp':
+                                       widget = new mw.widgets.datetime.DateTimeInputWidget( {
+                                               formatter: {
+                                                       format: '${year|0}-${month|0}-${day|0}T${hour|0}:${minute|0}:${second|0}${zone|short}'
+                                               },
+                                               required: Util.apiBool( pi.required ),
+                                               clearable: false
+                                       } );
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.textInputWidget );
+                                       $.extend( widget, WidgetMethods.dateTimeInputWidget );
+                                       multiMode = 'indicator';
+                                       break;
+
+                               case 'upload':
+                                       widget = new OO.ui.SelectFileWidget();
+                                       widget.paramInfo = pi;
+                                       $.extend( widget, WidgetMethods.uploadWidget );
+                                       break;
+
+                               case 'namespace':
+                                       items = $.map( mw.config.get( 'wgFormattedNamespaces' ), function ( name, ns ) {
+                                               if ( ns === '0' ) {
+                                                       name = mw.message( 'blanknamespace' ).text();
+                                               }
+                                               return new OO.ui.MenuOptionWidget( { data: ns, label: name } );
+                                       } ).sort( function ( a, b ) {
+                                               return a.data - b.data;
+                                       } );
+                                       if ( Util.apiBool( pi.multi ) ) {
+                                               widget = new OO.ui.CapsuleMultiSelectWidget( {
+                                                       menu: { items: items }
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.capsuleWidget );
+                                       } else {
+                                               widget = new OO.ui.DropdownWidget( {
+                                                       menu: { items: items }
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.dropdownWidget );
+                                       }
+                                       break;
+
+                               default:
+                                       if ( !$.isArray( pi.type ) ) {
+                                               throw new Error( 'Unknown parameter type ' + pi.type );
+                                       }
+
+                                       items = $.map( pi.type, function ( v ) {
+                                               return new OO.ui.MenuOptionWidget( { data: String( v ), label: String( v ) } );
+                                       } );
+                                       if ( Util.apiBool( pi.multi ) ) {
+                                               widget = new OO.ui.CapsuleMultiSelectWidget( {
+                                                       menu: { items: items }
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.capsuleWidget );
+                                               if ( Util.apiBool( pi.submodules ) ) {
+                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.multi;
+                                                       widget.on( 'change', ApiSandbox.updateUI );
+                                               }
+                                       } else {
+                                               widget = new OO.ui.DropdownWidget( {
+                                                       menu: { items: items }
+                                               } );
+                                               widget.paramInfo = pi;
+                                               $.extend( widget, WidgetMethods.dropdownWidget );
+                                               if ( Util.apiBool( pi.submodules ) ) {
+                                                       widget.getSubmodules = WidgetMethods.submoduleWidget.single;
+                                                       widget.getMenu().on( 'choose', ApiSandbox.updateUI );
+                                               }
+                                       }
+
+                                       break;
+                       }
+
+                       if ( Util.apiBool( pi.multi ) && multiMode !== 'none' ) {
+                               innerWidget = widget;
+                               switch ( multiMode ) {
+                                       case 'enter':
+                                               $content = innerWidget.$element;
+                                               break;
+
+                                       case 'indicator':
+                                               $button = innerWidget.$indicator;
+                                               $button.css( 'cursor', 'pointer' );
+                                               $button.attr( 'tabindex', 0 );
+                                               $button.parent().append( $button );
+                                               innerWidget.setIndicator( 'next' );
+                                               $content = innerWidget.$element;
+                                               break;
+
+                                       default:
+                                               throw new Error( 'Unknown multiMode "' + multiMode + '"' );
+                               }
+
+                               widget = new OO.ui.CapsuleMultiSelectWidget( {
+                                       allowArbitrary: true,
+                                       popup: {
+                                               classes: [ 'mw-apisandbox-popup' ],
+                                               $content: $content
+                                       }
+                               } );
+                               widget.paramInfo = pi;
+                               $.extend( widget, WidgetMethods.capsuleWidget );
+
+                               func = function () {
+                                       if ( !innerWidget.isDisabled() ) {
+                                               innerWidget.apiCheckValid().done( function ( ok ) {
+                                                       if ( ok ) {
+                                                               widget.addItemsFromData( [ innerWidget.getApiValue() ] );
+                                                               innerWidget.setApiValue( undefined );
+                                                       }
+                                               } );
+                                               return false;
+                                       }
+                               };
+                               switch ( multiMode ) {
+                                       case 'enter':
+                                               innerWidget.connect( null, { enter: func } );
+                                               break;
+
+                                       case 'indicator':
+                                               $button.on( {
+                                                       click: func,
+                                                       keypress: function ( e ) {
+                                                               if ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) {
+                                                                       func();
+                                                               }
+                                                       }
+                                               } );
+                                               break;
+                               }
+                       }
+
+                       if ( Util.apiBool( pi.required ) || opts.nooptional ) {
+                               finalWidget = widget;
+                       } else {
+                               finalWidget = new OptionalWidget( widget );
+                               finalWidget.paramInfo = pi;
+                               $.extend( finalWidget, WidgetMethods.optionalWidget );
+                               if ( widget.getSubmodules ) {
+                                       finalWidget.getSubmodules = widget.getSubmodules.bind( widget );
+                                       finalWidget.on( 'disable', function () { setTimeout( ApiSandbox.updateUI ); } );
+                               }
+                               finalWidget.setDisabled( true );
+                       }
+
+                       widget.setApiValue( pi[ 'default' ] );
+
+                       return finalWidget;
+               },
+
+               /**
+                * Parse an HTML string, adding target="_blank" to any links
+                *
+                * @param {string} html HTML to parse
+                * @return {jQuery}
+                */
+               parseHTML: function ( html ) {
+                       var $ret = $( $.parseHTML( html ) );
+                       $ret.filter( 'a' ).add( $ret.find( 'a' ) )
+                               .filter( '[href]:not([target])' )
+                               .attr( 'target', '_blank' );
+                       return $ret;
+               }
+       };
+
+       /**
+       * Interface to ApiSandbox UI
+       *
+       * @class mw.special.ApiSandbox
+       */
+       mw.special.ApiSandbox = ApiSandbox = {
+               /**
+                * Initialize the UI
+                *
+                * Automatically called on $.ready()
+                */
+               init: function () {
+                       var $toolbar;
+
+                       $content = $( '#mw-apisandbox' );
+
+                       windowManager = new OO.ui.WindowManager();
+                       $( 'body' ).append( windowManager.$element );
+                       windowManager.addWindows( {
+                               errorAlert: new OO.ui.MessageDialog()
+                       } );
+
+                       fullscreenButton = new OO.ui.ButtonWidget( {
+                               label: mw.message( 'apisandbox-fullscreen' ).text(),
+                               title: mw.message( 'apisandbox-fullscreen-tooltip' ).text()
+                       } ).on( 'click', ApiSandbox.toggleFullscreen );
+
+                       $toolbar = $( '<div>' )
+                               .addClass( 'mw-apisandbox-toolbar' )
+                               .append(
+                                       fullscreenButton.$element,
+                                       new OO.ui.ButtonWidget( {
+                                               label: mw.message( 'apisandbox-submit' ).text(),
+                                               flags: [ 'primary', 'constructive' ]
+                                       } ).on( 'click', ApiSandbox.sendRequest ).$element,
+                                       new OO.ui.ButtonWidget( {
+                                               label: mw.message( 'apisandbox-reset' ).text(),
+                                               flags: 'destructive'
+                                       } ).on( 'click', ApiSandbox.resetUI ).$element
+                               );
+
+                       booklet = new OO.ui.BookletLayout( {
+                               outlined: true,
+                               autoFocus: false
+                       } );
+
+                       panel = new OO.ui.PanelLayout( {
+                               classes: [ 'mw-apisandbox-container' ],
+                               content: [ booklet ],
+                               expanded: false,
+                               framed: true
+                       } );
+
+                       pages.main = new ApiSandbox.PageLayout( { key: 'main', path: 'main' } );
+
+                       // Parse the current hash string
+                       if ( !ApiSandbox.loadFromHash() ) {
+                               ApiSandbox.updateUI();
+                       }
+
+                       // If the hashchange event exists, use it. Otherwise, fake it.
+                       // And, of course, IE has to be dumb.
+                       if ( 'onhashchange' in window &&
+                               ( document.documentMode === undefined || document.documentMode >= 8 )
+                       ) {
+                               $( window ).on( 'hashchange', ApiSandbox.loadFromHash );
+                       } else {
+                               setInterval( function () {
+                                       if ( oldhash !== location.hash ) {
+                                               ApiSandbox.loadFromHash();
+                                       }
+                               }, 1000 );
+                       }
+
+                       $content
+                               .empty()
+                               .append( $( '<p>' ).append( mw.message( 'apisandbox-intro' ).parse() ) )
+                               .append(
+                                       $( '<div>', { id: 'mw-apisandbox-ui' } )
+                                               .append( $toolbar )
+                                               .append( panel.$element )
+                               );
+
+                       $( window ).on( 'resize', ApiSandbox.resizePanel );
+
+                       ApiSandbox.resizePanel();
+               },
+
+               /**
+                * Toggle "fullscreen" mode
+                */
+               toggleFullscreen: function () {
+                       var $body = $( document.body );
+
+                       $body.toggleClass( 'mw-apisandbox-fullscreen' );
+                       if ( $body.hasClass( 'mw-apisandbox-fullscreen' ) ) {
+                               fullscreenButton.setLabel( mw.message( 'apisandbox-unfullscreen' ).text() );
+                               fullscreenButton.setTitle( mw.message( 'apisandbox-unfullscreen-tooltip' ).text() );
+                               $body.append( $( '#mw-apisandbox-ui' ) );
+                       } else {
+                               fullscreenButton.setLabel( mw.message( 'apisandbox-fullscreen' ).text() );
+                               fullscreenButton.setTitle( mw.message( 'apisandbox-fullscreen-tooltip' ).text() );
+                               $content.append( $( '#mw-apisandbox-ui' ) );
+                       }
+                       ApiSandbox.resizePanel();
+               },
+
+               /**
+                * Set the height of the panel based on the current viewport.
+                */
+               resizePanel: function () {
+                       var height = $( window ).height(),
+                               contentTop = $content.offset().top;
+
+                       if ( $( document.body ).hasClass( 'mw-apisandbox-fullscreen' ) ) {
+                               height -= panel.$element.offset().top - $( '#mw-apisandbox-ui' ).offset().top;
+                               panel.$element.height( height - 1 );
+                       } else {
+                               // Subtract the height of the intro text
+                               height -= panel.$element.offset().top - contentTop;
+
+                               panel.$element.height( height - 10 );
+                               $( window ).scrollTop( contentTop - 5 );
+                       }
+               },
+
+               /**
+                * Update the current query when the page hash changes
+                */
+               loadFromHash: function () {
+                       var params, m, re,
+                               hash = location.hash;
+
+                       if ( oldhash === hash ) {
+                               return false;
+                       }
+                       oldhash = hash;
+                       if ( hash === '' ) {
+                               return false;
+                       }
+
+                       // I'm surprised this doesn't seem to exist in jQuery or mw.util.
+                       params = {};
+                       hash = hash.replace( '+', '%20' );
+                       re = /([^&=#]+)=?([^&#]*)/g;
+                       while ( ( m = re.exec( hash ) ) ) {
+                               params[ decodeURIComponent( m[ 1 ] ) ] = decodeURIComponent( m[ 2 ] );
+                       }
+
+                       ApiSandbox.updateUI( params );
+                       return true;
+               },
+
+               /**
+                * Update the pages in the booklet
+                *
+                * @param {Object} [params] Optional query parameters to load
+                */
+               updateUI: function ( params ) {
+                       var i, page, subpages, j, removePages,
+                               addPages = [];
+
+                       if ( !$.isPlainObject( params ) ) {
+                               params = undefined;
+                       }
+
+                       if ( updatingBooklet ) {
+                               return;
+                       }
+                       updatingBooklet = true;
+                       try {
+                               if ( params !== undefined ) {
+                                       pages.main.loadQueryParams( params );
+                               }
+                               addPages.push( pages.main );
+                               if ( resultPage !== null ) {
+                                       addPages.push( resultPage );
+                               }
+                               pages.main.apiCheckValid();
+
+                               i = 0;
+                               while ( addPages.length ) {
+                                       page = addPages.shift();
+                                       if ( bookletPages[ i ] !== page ) {
+                                               for ( j = i; j < bookletPages.length; j++ ) {
+                                                       if ( bookletPages[ j ].getName() === page.getName() ) {
+                                                               bookletPages.splice( j, 1 );
+                                                       }
+                                               }
+                                               bookletPages.splice( i, 0, page );
+                                               booklet.addPages( [ page ], i );
+                                       }
+                                       i++;
+
+                                       if ( page.getSubpages ) {
+                                               subpages = page.getSubpages();
+                                               for ( j = 0; j < subpages.length; j++ ) {
+                                                       if ( !pages.hasOwnProperty( subpages[ j ].key ) ) {
+                                                               subpages[ j ].indentLevel = page.indentLevel + 1;
+                                                               pages[ subpages[ j ].key ] = new ApiSandbox.PageLayout( subpages[ j ] );
+                                                       }
+                                                       if ( params !== undefined ) {
+                                                               pages[ subpages[ j ].key ].loadQueryParams( params );
+                                                       }
+                                                       addPages.splice( j, 0, pages[ subpages[ j ].key ] );
+                                                       pages[ subpages[ j ].key ].apiCheckValid();
+                                               }
+                                       }
+                               }
+
+                               if ( bookletPages.length > i ) {
+                                       removePages = bookletPages.splice( i, bookletPages.length - i );
+                                       booklet.removePages( removePages );
+                               }
+
+                               if ( !booklet.getCurrentPageName() ) {
+                                       booklet.selectFirstSelectablePage();
+                               }
+                       } finally {
+                               updatingBooklet = false;
+                       }
+               },
+
+               /**
+                * Reset button handler
+                */
+               resetUI: function () {
+                       suppressErrors = true;
+                       pages = {
+                               main: new ApiSandbox.PageLayout( { key: 'main', path: 'main' } )
+                       };
+                       resultPage = null;
+                       ApiSandbox.updateUI();
+               },
+
+               /**
+                * Submit button handler
+                */
+               sendRequest: function () {
+                       var page, subpages, i, query, $result,
+                               progress, $progressText, progressLoading,
+                               deferreds = [],
+                               params = {},
+                               displayParams = {},
+                               checkPages = [ pages.main ];
+
+                       suppressErrors = false;
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+                               deferreds.push( page.apiCheckValid() );
+                               page.getQueryParams( params, displayParams );
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+
+                       $.when.apply( $, deferreds ).done( function () {
+                               if ( $.inArray( false, arguments ) !== -1 ) {
+                                       windowManager.openWindow( 'errorAlert', {
+                                               title: mw.message( 'apisandbox-submit-invalid-fields-title' ).parse(),
+                                               message: mw.message( 'apisandbox-submit-invalid-fields-message' ).parse(),
+                                               actions: [
+                                                       {
+                                                               action: 'accept',
+                                                               label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                               flags: 'primary'
+                                                       }
+                                               ]
+                                       } );
+                                       return;
+                               }
+
+                               query = $.param( displayParams );
+
+                               // Force a 'fm' format with wrappedhtml=1, if available
+                               if ( params.format !== undefined ) {
+                                       if ( availableFormats.hasOwnProperty( params.format + 'fm' ) ) {
+                                               params.format = params.format + 'fm';
+                                       }
+                                       if ( params.format.substr( -2 ) === 'fm' ) {
+                                               params.wrappedhtml = 1;
+                                       }
+                               }
+
+                               progressLoading = false;
+                               $progressText = $( '<span>' ).text( mw.message( 'apisandbox-sending-request' ).text() );
+                               progress = new OO.ui.ProgressBarWidget( {
+                                       progress: false,
+                                       $content: $progressText
+                               } );
+
+                               $result = $( '<div>' )
+                                       .append( progress.$element );
+
+                               resultPage = page = new OO.ui.PageLayout( '|results|' );
+                               page.setupOutlineItem = function () {
+                                       this.outlineItem.setLabel( mw.message( 'apisandbox-results' ).text() );
+                               };
+                               page.$element.empty()
+                                       .append(
+                                               new OO.ui.FieldLayout(
+                                                       new OO.ui.TextInputWidget( {
+                                                               readOnly: true,
+                                                               value: mw.util.wikiScript( 'api' ) + '?' + query
+                                                       } ), {
+                                                               label: mw.message( 'apisandbox-request-url-label' ).parse()
+                                                       }
+                                               ).$element,
+                                               $result
+                                       );
+                               ApiSandbox.updateUI();
+                               booklet.setPage( '|results|' );
+
+                               location.href = oldhash = '#' + query;
+
+                               api.post( params, {
+                                       contentType: 'multipart/form-data',
+                                       dataType: 'text',
+                                       xhr: function () {
+                                               var xhr = new window.XMLHttpRequest();
+                                               xhr.upload.addEventListener( 'progress', function ( e ) {
+                                                       if ( !progressLoading ) {
+                                                               if ( e.lengthComputable ) {
+                                                                       progress.setProgress( e.loaded * 100 / e.total );
+                                                               } else {
+                                                                       progress.setProgress( false );
+                                                               }
+                                                       }
+                                               } );
+                                               xhr.addEventListener( 'progress', function ( e ) {
+                                                       if ( !progressLoading ) {
+                                                               progressLoading = true;
+                                                               $progressText.text( mw.message( 'apisandbox-loading-results' ).text() );
+                                                       }
+                                                       if ( e.lengthComputable ) {
+                                                               progress.setProgress( e.loaded * 100 / e.total );
+                                                       } else {
+                                                               progress.setProgress( false );
+                                                       }
+                                               } );
+                                               return xhr;
+                                       }
+                               } )
+                                       .fail( function ( code, data ) {
+                                               var details = 'HTTP error: ' + data.exception;
+                                               $result.empty()
+                                                       .append(
+                                                               new OO.ui.LabelWidget( {
+                                                                       label: mw.message( 'apisandbox-results-error', details ).text(),
+                                                                       classes: [ 'error' ]
+                                                               } ).$element
+                                                       );
+                                       } )
+                                       .done( function ( data, jqXHR ) {
+                                               var m, loadTime, button,
+                                                       ct = jqXHR.getResponseHeader( 'Content-Type' );
+
+                                               $result.empty();
+                                               if ( /^text\/mediawiki-api-prettyprint-wrapped(?:;|$)/.test( ct ) ) {
+                                                       data = $.parseJSON( data );
+                                                       if ( data.modules.length ) {
+                                                               mw.loader.load( data.modules );
+                                                       }
+                                                       $result.append( Util.parseHTML( data.html ) );
+                                                       loadTime = data.time;
+                                               } else if ( ( m = data.match( /<pre[ >][\s\S]*<\/pre>/ ) ) ) {
+                                                       $result.append( Util.parseHTML( m[ 0 ] ) );
+                                                       if ( ( m = data.match( /"wgBackendResponseTime":\s*(\d+)/ ) ) ) {
+                                                               loadTime = parseInt( m[ 1 ], 10 );
+                                                       }
+                                               } else {
+                                                       $( '<pre>' )
+                                                               .addClass( 'api-pretty-content' )
+                                                               .text( data )
+                                                               .appendTo( $result );
+                                               }
+                                               if ( typeof loadTime === 'number' ) {
+                                                       $result.append(
+                                                               $( '<div>' ).append(
+                                                                       new OO.ui.LabelWidget( {
+                                                                               label: mw.message( 'apisandbox-request-time', loadTime ).text()
+                                                                       } ).$element
+                                                               )
+                                                       );
+                                               }
+
+                                               if ( jqXHR.getResponseHeader( 'MediaWiki-API-Error' ) === 'badtoken' ) {
+                                                       // Flush all saved tokens in case one of them is the bad one.
+                                                       Util.markTokensBad();
+                                                       button = new OO.ui.ButtonWidget( {
+                                                               label: mw.message( 'apisandbox-results-fixtoken' ).text()
+                                                       } );
+                                                       button.on( 'click', ApiSandbox.fixTokenAndResend )
+                                                               .on( 'click', button.setDisabled, [ true ], button )
+                                                               .$element.appendTo( $result );
+                                               }
+                                       } );
+                       } );
+               },
+
+               /**
+                * Handler for the "Correct token and resubmit" button
+                *
+                * Used on a 'badtoken' error, it re-fetches token parameters for all
+                * pages and then re-submits the query.
+                */
+               fixTokenAndResend: function () {
+                       var page, subpages, i, k,
+                               ok = true,
+                               tokenWait = { dummy: true },
+                               checkPages = [ pages.main ],
+                               success = function ( k ) {
+                                       delete tokenWait[ k ];
+                                       if ( ok && $.isEmptyObject( tokenWait ) ) {
+                                               ApiSandbox.sendRequest();
+                                       }
+                               },
+                               failure = function ( k ) {
+                                       delete tokenWait[ k ];
+                                       ok = false;
+                               };
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+
+                               if ( page.tokenWidget ) {
+                                       k = page.apiModule + page.tokenWidget.paramInfo.name;
+                                       tokenWait[ k ] = page.tokenWidget.fetchToken()
+                                               .done( success.bind( page.tokenWidget, k ) )
+                                               .fail( failure.bind( page.tokenWidget, k ) );
+                               }
+
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+
+                       success( 'dummy', '' );
+               },
+
+               /**
+                * Reset validity indicators for all widgets
+                */
+               updateValidityIndicators: function () {
+                       var page, subpages, i,
+                               checkPages = [ pages.main ];
+
+                       while ( checkPages.length ) {
+                               page = checkPages.shift();
+                               page.apiCheckValid();
+                               subpages = page.getSubpages();
+                               for ( i = 0; i < subpages.length; i++ ) {
+                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                               checkPages.push( pages[ subpages[ i ].key ] );
+                                       }
+                               }
+                       }
+               }
+       };
+
+       /**
+        * PageLayout for API modules
+        *
+        * @class
+        * @private
+        * @extends OO.ui.PageLayout
+        * @constructor
+        * @param {Object} [config] Configuration options
+        */
+       ApiSandbox.PageLayout = function ( config ) {
+               config = $.extend( { prefix: '' }, config );
+               this.displayText = config.key;
+               this.apiModule = config.path;
+               this.prefix = config.prefix;
+               this.paramInfo = null;
+               this.apiIsValid = true;
+               this.loadFromQueryParams = null;
+               this.widgets = {};
+               this.tokenWidget = null;
+               this.indentLevel = config.indentLevel ? config.indentLevel : 0;
+               ApiSandbox.PageLayout[ 'super' ].call( this, config.key, config );
+               this.loadParamInfo();
+       };
+       OO.inheritClass( ApiSandbox.PageLayout, OO.ui.PageLayout );
+       ApiSandbox.PageLayout.prototype.setupOutlineItem = function () {
+               this.outlineItem.setLevel( this.indentLevel );
+               this.outlineItem.setLabel( this.displayText );
+               this.outlineItem.setIcon( this.apiIsValid || suppressErrors ? null : 'alert' );
+               this.outlineItem.setIconTitle(
+                       this.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
+               );
+       };
+
+       /**
+        * Fetch module information for this page's module, then create UI
+        */
+       ApiSandbox.PageLayout.prototype.loadParamInfo = function () {
+               var dynamicFieldset, dynamicParamNameWidget,
+                       that = this,
+                       addDynamicParamWidget = function () {
+                               var name, layout, widget, button;
+
+                               // Check name is filled in
+                               name = dynamicParamNameWidget.getValue().trim();
+                               if ( name === '' ) {
+                                       dynamicParamNameWidget.focus();
+                                       return;
+                               }
+
+                               if ( that.widgets[ name ] !== undefined ) {
+                                       windowManager.openWindow( 'errorAlert', {
+                                               title: mw.message(
+                                                       'apisandbox-dynamic-error-exists', name
+                                               ).parse(),
+                                               actions: [
+                                                       {
+                                                               action: 'accept',
+                                                               label: OO.ui.msg( 'ooui-dialog-process-dismiss' ),
+                                                               flags: 'primary'
+                                                       }
+                                               ]
+                                       } );
+                                       return;
+                               }
+
+                               widget = Util.createWidgetForParameter( {
+                                       name: name,
+                                       type: 'string',
+                                       'default': ''
+                               }, {
+                                       nooptional: true
+                               } );
+                               button = new OO.ui.ButtonWidget( {
+                                       icon: 'remove',
+                                       flags: 'destructive'
+                               } );
+                               layout = new OO.ui.ActionFieldLayout(
+                                       widget,
+                                       button,
+                                       {
+                                               label: name,
+                                               align: 'left'
+                                       }
+                               );
+                               button.on( 'click', removeDynamicParamWidget, [ name, layout ] );
+                               that.widgets[ name ] = widget;
+                               dynamicFieldset.addItems( [ layout ], dynamicFieldset.getItems().length - 1 );
+                               widget.focus();
+
+                               dynamicParamNameWidget.setValue( '' );
+                       },
+                       removeDynamicParamWidget = function ( name, layout ) {
+                               dynamicFieldset.removeItems( [ layout ] );
+                               delete that.widgets[ name ];
+                       };
+
+               this.$element.empty()
+                       .append( new OO.ui.ProgressBarWidget( {
+                               progress: false,
+                               text: mw.message( 'apisandbox-loading', this.displayText ).text()
+                       } ).$element );
+
+               Util.fetchModuleInfo( this.apiModule )
+                       .done( function ( pi ) {
+                               var prefix, i, j, dl, widget, $widgetLabel, widgetField, helpField, tmp, flag, count,
+                                       items = [],
+                                       deprecatedItems = [],
+                                       buttons = [],
+                                       filterFmModules = function ( v ) {
+                                               return v.substr( -2 ) !== 'fm' ||
+                                                       !availableFormats.hasOwnProperty( v.substr( 0, v.length - 2 ) );
+                                       },
+                                       widgetLabelOnClick = function () {
+                                               var f = this.getField();
+                                               if ( $.isFunction( f.setDisabled ) ) {
+                                                       f.setDisabled( false );
+                                               }
+                                               if ( $.isFunction( f.focus ) ) {
+                                                       f.focus();
+                                               }
+                                       },
+                                       doNothing = function () {};
+
+                               // This is something of a hack. We always want the 'format' and
+                               // 'action' parameters from the main module to be specified,
+                               // and for 'format' we also want to simplify the dropdown since
+                               // we always send the 'fm' variant.
+                               if ( that.apiModule === 'main' ) {
+                                       for ( i = 0; i < pi.parameters.length; i++ ) {
+                                               if ( pi.parameters[ i ].name === 'action' ) {
+                                                       pi.parameters[ i ].required = true;
+                                                       delete pi.parameters[ i ][ 'default' ];
+                                               }
+                                               if ( pi.parameters[ i ].name === 'format' ) {
+                                                       tmp = pi.parameters[ i ].type;
+                                                       for ( j = 0; j < tmp.length; j++ ) {
+                                                               availableFormats[ tmp[ j ] ] = true;
+                                                       }
+                                                       pi.parameters[ i ].type = $.grep( tmp, filterFmModules );
+                                                       pi.parameters[ i ][ 'default' ] = 'json';
+                                                       pi.parameters[ i ].required = true;
+                                               }
+                                       }
+                               }
+
+                               // Hide the 'wrappedhtml' parameter on format modules
+                               if ( pi.group === 'format' ) {
+                                       pi.parameters = $.grep( pi.parameters, function ( p ) {
+                                               return p.name !== 'wrappedhtml';
+                                       } );
+                               }
+
+                               that.paramInfo = pi;
+
+                               items.push( new OO.ui.FieldLayout(
+                                       new OO.ui.Widget( {} ).toggle( false ), {
+                                               align: 'top',
+                                               label: Util.parseHTML( pi.description )
+                                       }
+                               ) );
+
+                               if ( pi.helpurls.length ) {
+                                       buttons.push( new OO.ui.PopupButtonWidget( {
+                                               label: mw.message( 'apisandbox-helpurls' ).text(),
+                                               icon: 'help',
+                                               popup: {
+                                                       $content: $( '<ul>' ).append( $.map( pi.helpurls, function ( link ) {
+                                                               return $( '<li>' ).append( $( '<a>', {
+                                                                       href: link,
+                                                                       target: '_blank',
+                                                                       text: link
+                                                               } ) );
+                                                       } ) )
+                                               }
+                                       } ) );
+                               }
+
+                               if ( pi.examples.length ) {
+                                       buttons.push( new OO.ui.PopupButtonWidget( {
+                                               label: mw.message( 'apisandbox-examples' ).text(),
+                                               icon: 'code',
+                                               popup: {
+                                                       $content: $( '<ul>' ).append( $.map( pi.examples, function ( example ) {
+                                                               var a = $( '<a>', {
+                                                                       href: '#' + example.query,
+                                                                       html: example.description
+                                                               } );
+                                                               a.find( 'a' ).contents().unwrap(); // Can't nest links
+                                                               return $( '<li>' ).append( a );
+                                                       } ) )
+                                               }
+                                       } ) );
+                               }
+
+                               if ( buttons.length ) {
+                                       items.push( new OO.ui.FieldLayout(
+                                               new OO.ui.ButtonGroupWidget( {
+                                                       items: buttons
+                                               } ), { align: 'top' }
+                                       ) );
+                               }
+
+                               if ( pi.parameters.length ) {
+                                       prefix = that.prefix + pi.prefix;
+                                       for ( i = 0; i < pi.parameters.length; i++ ) {
+                                               widget = Util.createWidgetForParameter( pi.parameters[ i ] );
+                                               that.widgets[ prefix + pi.parameters[ i ].name ] = widget;
+                                               if ( pi.parameters[ i ].tokentype ) {
+                                                       that.tokenWidget = widget;
+                                               }
+
+                                               dl = $( '<dl>' );
+                                               dl.append( $( '<dd>', {
+                                                       addClass: 'description',
+                                                       append: Util.parseHTML( pi.parameters[ i ].description )
+                                               } ) );
+                                               if ( pi.parameters[ i ].info && pi.parameters[ i ].info.length ) {
+                                                       for ( j = 0; j < pi.parameters[ i ].info.length; j++ ) {
+                                                               dl.append( $( '<dd>', {
+                                                                       addClass: 'info',
+                                                                       append: Util.parseHTML( pi.parameters[ i ].info[ j ] )
+                                                               } ) );
+                                                       }
+                                               }
+                                               flag = true;
+                                               count = 1e100;
+                                               switch ( pi.parameters[ i ].type ) {
+                                                       case 'namespace':
+                                                               flag = false;
+                                                               count = mw.config.get( 'wgFormattedNamespaces' ).length;
+                                                               break;
+
+                                                       case 'limit':
+                                                               if ( pi.parameters[ i ].highmax !== undefined ) {
+                                                                       dl.append( $( '<dd>', {
+                                                                               addClass: 'info',
+                                                                               append: Util.parseHTML( mw.message(
+                                                                                       'api-help-param-limit2', pi.parameters[ i ].max, pi.parameters[ i ].highmax
+                                                                               ).parse() )
+                                                                       } ) );
+                                                               } else {
+                                                                       dl.append( $( '<dd>', {
+                                                                               addClass: 'info',
+                                                                               append: Util.parseHTML( mw.message(
+                                                                                       'api-help-param-limit', pi.parameters[ i ].max
+                                                                               ).parse() )
+                                                                       } ) );
+                                                               }
+                                                               break;
+
+                                                       case 'integer':
+                                                               tmp = '';
+                                                               if ( pi.parameters[ i ].min !== undefined ) {
+                                                                       tmp += 'min';
+                                                               }
+                                                               if ( pi.parameters[ i ].max !== undefined ) {
+                                                                       tmp += 'max';
+                                                               }
+                                                               if ( tmp !== '' ) {
+                                                                       dl.append( $( '<dd>', {
+                                                                               addClass: 'info',
+                                                                               append: Util.parseHTML( mw.message(
+                                                                                       'api-help-param-integer-' + tmp,
+                                                                                       Util.apiBool( pi.parameters[ i ].multi ) ? 2 : 1,
+                                                                                       pi.parameters[ i ].min, pi.parameters[ i ].max
+                                                                               ).parse() )
+                                                                       } ) );
+                                                               }
+                                                               break;
+
+                                                       default:
+                                                               if ( $.isArray( pi.parameters[ i ].type ) ) {
+                                                                       flag = false;
+                                                                       count = pi.parameters[ i ].type.length;
+                                                               }
+                                                               break;
+                                               }
+                                               if ( Util.apiBool( pi.parameters[ i ].multi ) ) {
+                                                       tmp = [];
+                                                       if ( flag && !( widget instanceof OO.ui.CapsuleMultiSelectWidget ) &&
+                                                               !(
+                                                                       widget instanceof OptionalWidget &&
+                                                                       widget.widget instanceof OO.ui.CapsuleMultiSelectWidget
+                                                               )
+                                                       ) {
+                                                               tmp.push( mw.message( 'api-help-param-multi-separate' ).parse() );
+                                                       }
+                                                       if ( count > pi.parameters[ i ].lowlimit ) {
+                                                               tmp.push(
+                                                                       mw.message( 'api-help-param-multi-max',
+                                                                               pi.parameters[ i ].lowlimit, pi.parameters[ i ].highlimit
+                                                                       ).parse()
+                                                               );
+                                                       }
+                                                       if ( tmp.length ) {
+                                                               dl.append( $( '<dd>', {
+                                                                       addClass: 'info',
+                                                                       append: Util.parseHTML( tmp.join( ' ' ) )
+                                                               } ) );
+                                                       }
+                                               }
+                                               helpField = new OO.ui.FieldLayout(
+                                                       new OO.ui.Widget( {
+                                                               $content: '\xa0',
+                                                               classes: [ 'mw-apisandbox-spacer' ]
+                                                       } ), {
+                                                               align: 'inline',
+                                                               label: dl
+                                                       }
+                                               );
+
+                                               $widgetLabel = $( '<span>' );
+                                               widgetField = new OO.ui.FieldLayout(
+                                                       widget,
+                                                       {
+                                                               align: 'left',
+                                                               label: prefix + pi.parameters[ i ].name,
+                                                               $label: $widgetLabel
+                                                       }
+                                               );
+
+                                               // FieldLayout only does click for InputElement
+                                               // widgets. So supply our own click handler.
+                                               $widgetLabel.on( 'click', widgetLabelOnClick.bind( widgetField ) );
+
+                                               // Don't grey out the label when the field is disabled,
+                                               // it makes it too hard to read and our "disabled"
+                                               // isn't really disabled.
+                                               widgetField.onFieldDisable = doNothing;
+
+                                               if ( Util.apiBool( pi.parameters[ i ].deprecated ) ) {
+                                                       deprecatedItems.push( widgetField, helpField );
+                                               } else {
+                                                       items.push( widgetField, helpField );
+                                               }
+                                       }
+                               }
+
+                               if ( !pi.parameters.length && !Util.apiBool( pi.dynamicparameters ) ) {
+                                       items.push( new OO.ui.FieldLayout(
+                                               new OO.ui.Widget( {} ).toggle( false ), {
+                                                       align: 'top',
+                                                       label: Util.parseHTML( mw.message( 'apisandbox-no-parameters' ).parse() )
+                                               }
+                                       ) );
+                               }
+
+                               that.$element.empty();
+
+                               new OO.ui.FieldsetLayout( {
+                                       label: that.displayText
+                               } ).addItems( items )
+                                       .$element.appendTo( that.$element );
+
+                               if ( Util.apiBool( pi.dynamicparameters ) ) {
+                                       dynamicFieldset = new OO.ui.FieldsetLayout();
+                                       dynamicParamNameWidget = new OO.ui.TextInputWidget( {
+                                               placeholder: mw.message( 'apisandbox-dynamic-parameters-add-placeholder' ).text()
+                                       } ).on( 'enter', addDynamicParamWidget );
+                                       dynamicFieldset.addItems( [
+                                               new OO.ui.FieldLayout(
+                                                       new OO.ui.Widget( {} ).toggle( false ), {
+                                                               align: 'top',
+                                                               label: Util.parseHTML( pi.dynamicparameters )
+                                                       }
+                                               ),
+                                               new OO.ui.ActionFieldLayout(
+                                                       dynamicParamNameWidget,
+                                                       new OO.ui.ButtonWidget( {
+                                                               icon: 'add',
+                                                               flags: 'constructive'
+                                                       } ).on( 'click', addDynamicParamWidget ),
+                                                       {
+                                                               label: mw.message( 'apisandbox-dynamic-parameters-add-label' ).text(),
+                                                               align: 'left'
+                                                       }
+                                               )
+                                       ] );
+                                       $( '<fieldset>' )
+                                               .append(
+                                                       $( '<legend>' ).text( mw.message( 'apisandbox-dynamic-parameters' ).text() ),
+                                                       dynamicFieldset.$element
+                                               )
+                                               .appendTo( that.$element );
+                               }
+
+                               if ( deprecatedItems.length ) {
+                                       tmp = new OO.ui.FieldsetLayout().addItems( deprecatedItems ).toggle( false );
+                                       $( '<fieldset>' )
+                                               .append(
+                                                       $( '<legend>' ).append(
+                                                               new OO.ui.ToggleButtonWidget( {
+                                                                       label: mw.message( 'apisandbox-deprecated-parameters' ).text()
+                                                               } ).on( 'change', tmp.toggle, [], tmp ).$element
+                                                       ),
+                                                       tmp.$element
+                                               )
+                                               .appendTo( that.$element );
+                               }
+
+                               // Load stored params, if any, then update the booklet if we
+                               // have subpages (or else just update our valid-indicator).
+                               tmp = that.loadFromQueryParams;
+                               that.loadFromQueryParams = null;
+                               if ( $.isPlainObject( tmp ) ) {
+                                       that.loadQueryParams( tmp );
+                               }
+                               if ( that.getSubpages().length > 0 ) {
+                                       ApiSandbox.updateUI( tmp );
+                               } else {
+                                       that.apiCheckValid();
+                               }
+                       } ).fail( function ( code, detail ) {
+                               that.$element.empty()
+                                       .append(
+                                               new OO.ui.LabelWidget( {
+                                                       label: mw.message( 'apisandbox-load-error', that.apiModule, detail ).text(),
+                                                       classes: [ 'error' ]
+                                               } ).$element,
+                                               new OO.ui.ButtonWidget( {
+                                                       label: mw.message( 'apisandbox-retry' ).text()
+                                               } ).on( 'click', that.loadParamInfo, [], that ).$element
+                                       );
+                       } );
+       };
+
+       /**
+        * Check that all widgets on the page are in a valid state.
+        *
+        * @return {boolean}
+        */
+       ApiSandbox.PageLayout.prototype.apiCheckValid = function () {
+               var that = this;
+
+               if ( this.paramInfo === null ) {
+                       return $.Deferred().resolve( false ).promise();
+               } else {
+                       return $.when.apply( $, $.map( this.widgets, function ( widget ) {
+                               return widget.apiCheckValid();
+                       } ) ).then( function () {
+                               that.apiIsValid = $.inArray( false, arguments ) === -1;
+                               if ( that.getOutlineItem() ) {
+                                       that.getOutlineItem().setIcon( that.apiIsValid || suppressErrors ? null : 'alert' );
+                                       that.getOutlineItem().setIconTitle(
+                                               that.apiIsValid || suppressErrors ? '' : mw.message( 'apisandbox-alert-page' ).plain()
+                                       );
+                               }
+                               return $.Deferred().resolve( that.apiIsValid ).promise();
+                       } );
+               }
+       };
+
+       /**
+        * Load form fields from query parameters
+        *
+        * @param {Object} params
+        */
+       ApiSandbox.PageLayout.prototype.loadQueryParams = function ( params ) {
+               if ( this.paramInfo === null ) {
+                       this.loadFromQueryParams = params;
+               } else {
+                       $.each( this.widgets, function ( name, widget ) {
+                               var v = params.hasOwnProperty( name ) ? params[ name ] : undefined;
+                               widget.setApiValue( v );
+                       } );
+               }
+       };
+
+       /**
+        * Load query params from form fields
+        *
+        * @param {Object} params Write query parameters into this object
+        * @param {Object} displayParams Write query parameters for display into this object
+        */
+       ApiSandbox.PageLayout.prototype.getQueryParams = function ( params, displayParams ) {
+               $.each( this.widgets, function ( name, widget ) {
+                       var value = widget.getApiValue();
+                       if ( value !== undefined ) {
+                               params[ name ] = value;
+                               if ( $.isFunction( widget.getApiValueForDisplay ) ) {
+                                       value = widget.getApiValueForDisplay();
+                               }
+                               displayParams[ name ] = value;
+                       }
+               } );
+       };
+
+       /**
+        * Fetch a list of subpage names loaded by this page
+        *
+        * @return {Array}
+        */
+       ApiSandbox.PageLayout.prototype.getSubpages = function () {
+               var ret = [];
+               $.each( this.widgets, function ( name, widget ) {
+                       var submodules, i;
+                       if ( $.isFunction( widget.getSubmodules ) ) {
+                               submodules = widget.getSubmodules();
+                               for ( i = 0; i < submodules.length; i++ ) {
+                                       ret.push( {
+                                               key: name + '=' + submodules[ i ].value,
+                                               path: submodules[ i ].path,
+                                               prefix: widget.paramInfo.submoduleparamprefix || ''
+                                       } );
+                               }
+                       }
+               } );
+               return ret;
+       };
+
+       /**
+        * A text input with a clickable indicator
+        *
+        * @class
+        * @private
+        * @constructor
+        * @param {Object} [config] Configuration options
+        */
+       function TextInputWithIndicatorWidget( config ) {
+               var k;
+
+               config = config || {};
+               TextInputWithIndicatorWidget[ 'super' ].call( this, config );
+
+               this.$indicator = $( '<span>' ).addClass( 'mw-apisandbox-clickable-indicator' );
+               OO.ui.mixin.TabIndexedElement.call(
+                       this, $.extend( {}, config, { $tabIndexed: this.$indicator } )
+               );
+
+               this.input = new OO.ui.TextInputWidget( $.extend( {
+                       $indicator: this.$indicator,
+                       disabled: this.isDisabled()
+               }, config.input ) );
+
+               // Forward most methods for convenience
+               for ( k in this.input ) {
+                       if ( $.isFunction( this.input[ k ] ) && !this[ k ] ) {
+                               this[ k ] = this.input[ k ].bind( this.input );
+                       }
+               }
+
+               this.$indicator.on( {
+                       click: this.onIndicatorClick.bind( this ),
+                       keypress: this.onIndicatorKeyPress.bind( this )
+               } );
+
+               this.$element.append( this.input.$element );
+       }
+       OO.inheritClass( TextInputWithIndicatorWidget, OO.ui.Widget );
+       OO.mixinClass( TextInputWithIndicatorWidget, OO.ui.mixin.TabIndexedElement );
+       TextInputWithIndicatorWidget.prototype.onIndicatorClick = function ( e ) {
+               if ( !this.isDisabled() && e.which === 1 ) {
+                       this.emit( 'indicator' );
+               }
+               return false;
+       };
+       TextInputWithIndicatorWidget.prototype.onIndicatorKeyPress = function ( e ) {
+               if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+                       this.emit( 'indicator' );
+                       return false;
+               }
+       };
+       TextInputWithIndicatorWidget.prototype.setDisabled = function ( disabled ) {
+               TextInputWithIndicatorWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
+               if ( this.input ) {
+                       this.input.setDisabled( this.isDisabled() );
+               }
+               return this;
+       };
+
+       /**
+        * A wrapper for a widget that provides an enable/disable button
+        *
+        * @class
+        * @private
+        * @constructor
+        * @param {OO.ui.Widget} widget
+        * @param {Object} [config] Configuration options
+        */
+       function OptionalWidget( widget, config ) {
+               var k;
+
+               config = config || {};
+
+               this.widget = widget;
+               this.$overlay = config.$overlay ||
+                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-overlay' );
+               this.checkbox = new OO.ui.CheckboxInputWidget( config.checkbox )
+                       .on( 'change', this.onCheckboxChange, [], this );
+
+               OptionalWidget[ 'super' ].call( this, config );
+
+               // Forward most methods for convenience
+               for ( k in this.widget ) {
+                       if ( $.isFunction( this.widget[ k ] ) && !this[ k ] ) {
+                               this[ k ] = this.widget[ k ].bind( this.widget );
+                       }
+               }
+
+               this.$overlay.on( 'click', this.onOverlayClick.bind( this ) );
+
+               this.$element
+                       .addClass( 'mw-apisandbox-optionalWidget' )
+                       .append(
+                               this.$overlay,
+                               $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-fields' ).append(
+                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-widget' ).append(
+                                               widget.$element
+                                       ),
+                                       $( '<div>' ).addClass( 'mw-apisandbox-optionalWidget-checkbox' ).append(
+                                               this.checkbox.$element
+                                       )
+                               )
+                       );
+
+               this.setDisabled( widget.isDisabled() );
+       }
+       OO.inheritClass( OptionalWidget, OO.ui.Widget );
+       OptionalWidget.prototype.onCheckboxChange = function ( checked ) {
+               this.setDisabled( !checked );
+       };
+       OptionalWidget.prototype.onOverlayClick = function () {
+               this.setDisabled( false );
+               if ( $.isFunction( this.widget.focus ) ) {
+                       this.widget.focus();
+               }
+       };
+       OptionalWidget.prototype.setDisabled = function ( disabled ) {
+               OptionalWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
+               this.widget.setDisabled( this.isDisabled() );
+               this.checkbox.setSelected( !this.isDisabled() );
+               this.$overlay.toggle( this.isDisabled() );
+               return this;
+       };
+
+       $( ApiSandbox.init );
+
+}( jQuery, mediaWiki, OO ) );
diff --git a/resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css b/resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css
new file mode 100644 (file)
index 0000000..4dc4c27
--- /dev/null
@@ -0,0 +1,3 @@
+.client-js .mw-apisandbox-nojs {
+       display: none;
+}
index dffcbdd..c242b6c 100644 (file)
@@ -21,7 +21,7 @@
         *
         *     $( '#content' ).append( selector.$element );
         *
-        *     selector.setSearchType( [ mw.widgets.CategorySelector.SearchType.SubCategories ] );
+        *     selector.setSearchTypes( [ mw.widgets.CategorySelector.SearchType.SubCategories ] );
         *
         * @class mw.widgets.CategorySelector
         * @uses mw.Api
index bc3d44f..49219d7 100644 (file)
@@ -14,6 +14,7 @@
                 */
                parse: function ( wikitext ) {
                        var apiPromise = this.get( {
+                               formatversion: 2,
                                action: 'parse',
                                contentmodel: 'wikitext',
                                text: wikitext
@@ -21,7 +22,7 @@
 
                        return apiPromise
                                .then( function ( data ) {
-                                       return data.parse.text[ '*' ];
+                                       return data.parse.text;
                                } )
                                .promise( { abort: apiPromise.abort } );
                }
index 3036237..47d80d6 100644 (file)
                 * - It is incompatible with uploads to a foreign wiki using mw.ForeignApi
                 * - You must pass a HTMLInputElement and not a File for it to be possible
                 *
-                * @param {HTMLInputElement|File} file HTML input type=file element with a file already inside
+                * @param {HTMLInputElement|File|Blob} file HTML input type=file element with a file already inside
                 *  of it, or a File object.
                 * @param {Object} data Other upload options, see action=upload API docs for more
                 * @return {jQuery.Promise}
                                throw new Error( 'No file' );
                        }
 
-                       canUseFormData = formDataAvailable() && file instanceof window.File;
+                       // Blobs are allowed in formdata uploads, it turns out
+                       canUseFormData = formDataAvailable() && ( file instanceof window.File || file instanceof window.Blob );
 
                        if ( !isFileInput && !canUseFormData ) {
                                throw new Error( 'Unsupported argument type passed to mw.Api.upload' );
index 8a74ffc..c972f24 100644 (file)
        /**
         * Set the file to be uploaded.
         *
-        * @param {HTMLInputElement|File} file
+        * @param {HTMLInputElement|File|Blob} file
         */
        UP.setFile = function ( file ) {
                this.file = file;
        /**
         * Get the file being uploaded.
         *
-        * @return {HTMLInputElement|File}
+        * @return {HTMLInputElement|File|Blob}
         */
        UP.getFile = function () {
                return this.file;
index fe5e634..99e4569 100644 (file)
@@ -1,4 +1,4 @@
-h1.firstHeading {
+.mw-special-ApiHelp h1.firstHeading {
        display: none;
 }
 
index b04e01c..90b93dc 100644 (file)
                /**
                 * Get a message object.
                 *
-                * Shorcut for `new mw.Message( mw.messages, key, parameters )`.
+                * Shortcut for `new mw.Message( mw.messages, key, parameters )`.
                 *
                 * @see mw.Message
                 * @param {string} key Key of message to get
                         */
 
                        /**
-                        * Write a message the console's warning channel.
+                        * Write a message to the console's warning channel.
                         * Actions not supported by the browser console are silently ignored.
                         *
                         * @param {...string} msg Messages to output to console
                                $.noop;
 
                        /**
-                        * Write a message the console's error channel.
+                        * Write a message to the console's error channel.
                         *
                         * Most browsers provide a stacktrace by default if the argument
                         * is a caught Error object.
                        /**
                         * A module has entered state 'ready', 'error', or 'missing'. Automatically update
                         * pending jobs and modules that depend upon this module. If the given module failed,
-                        * propagate the 'error' state up the dependency tree. Otherwise, go ahead an execute
+                        * propagate the 'error' state up the dependency tree. Otherwise, go ahead and execute
                         * all jobs/modules now having their dependencies satisfied.
                         *
                         * Jobs that depend on a failed module, will have their error callback ran (if any).
                                                                script( $, $ );
                                                                markModuleReady();
                                                        } else if ( typeof script === 'string' ) {
-                                                               // Site and user modules are legacy scripts that run in the global scope.
+                                                               // Site and user modules are legacy scripts that run in the global scope.
                                                                // This is transported as a string instead of a function to avoid needing
                                                                // to use string manipulation to undo the function wrapper.
                                                                if ( module === 'user' ) {
                        }
 
                        /**
-                        * Adds a dependencies to the queue with optional callbacks to be run
+                        * Adds all dependencies to the queue with optional callbacks to be run
                         * when the dependencies are ready or fail
                         *
                         * @private
                                 * When #load or #using requests one or more modules, the server
                                 * response contain calls to this function.
                                 *
-                                * All arguments are required.
-                                *
                                 * @param {string} module Name of module
-                                * @param {Function|Array} script Function with module code or Array of URLs to
+                                * @param {Function|Array} [script] Function with module code or Array of URLs to
                                 *  be used as the src attribute of a new `<script>` tag.
                                 * @param {Object} [style] Should follow one of the following patterns:
                                 *
                                         */
                                        clear: function () {
                                                mw.loader.store.items = {};
-                                               localStorage.removeItem( mw.loader.store.getStoreKey() );
+                                               try {
+                                                       localStorage.removeItem( mw.loader.store.getStoreKey() );
+                                               } catch ( ignored ) {}
                                        },
 
                                        /**
        /**
         * Log a message to window.console, if possible.
         *
-        * Useful to force logging of some  errors that are otherwise hard to detect (i.e., this logs
+        * Useful to force logging of some errors that are otherwise hard to detect (i.e., this logs
         * also in production mode). Gets console references in each invocation instead of caching the
         * reference, so that debugging tools loaded later are supported (e.g. Firebug Lite in IE).
         *
                        msg += ( e ? ':' : '.' );
                        console.log( msg );
 
-                       // If we have an exception object, log it to the error channel to trigger a
-                       // proper stacktraces in browsers that support it. No fallback as we have no browsers
-                       // that don't support error(), but do support log().
+                       // If we have an exception object, log it to the error channel to trigger
+                       // proper stacktraces in browsers that support it. No fallback as we have
+                       // no browsers that don't support error(), but do support log().
                        if ( e && console.error ) {
                                console.error( String( e ), e );
                        }
index 02a90fc..99e9dbe 100644 (file)
@@ -11,6 +11,7 @@
                        api = api || new mw.Api();
 
                        $.data( node, 'request', api.get( {
+                               formatversion: 2,
                                action: 'query',
                                list: 'allusers',
                                // Prefix of list=allusers is case sensitive. Normalise first
index 078fa6c..d4e7119 100644 (file)
@@ -2520,6 +2520,7 @@ Barack Obama <President> of the United States
 </p>
 !! end
 
+## PHP parser discards the "<pre " string
 !! test
 Handle broken pre-like tags (bug 64025)
 !! options
@@ -2530,13 +2531,8 @@ parsoid=wt2html
 <table><pre </table>
 !! html/php
 <pre>x</pre>
-<table>&lt;pre </table>
+<table><pre></pre></table>
 
-!! html/php+tidy
-<pre>
-x
-</pre>
-<p>&lt;pre</p>
 !! html/parsoid
 <pre about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"a":{"&lt;pre":null},"sa":{"&lt;pre":""},"stx":"html","pi":[[{"k":"1","spc":["","","",""]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 
@@ -6334,6 +6330,24 @@ parsoid=wt2html,html2html
 <td data-parsoid='{"startTagSrc":"| ","attrSepSrc":"|","autoInsertedEnd":true}'><a rel="mw:ExtLink" href="ftp://|x||"></a>" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
 !! end
 
+!! test
+! and || in element attributes should not be parsed as <th>/<td>
+!! wikitext
+{|
+| <div style="color: red !important;" data-contrived="put this here ||">hi</div>
+|}
+!! html/php
+<table>
+<tr>
+<td> <div style="color: red !important;" data-contrived="put this here &#124;&#124;">hi</div>
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td> <div style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"stx":"html"}'>hi</div></td></tr>
+</tbody></table>
+!! end
+
 # FIXME: The output seems broken. Filed as T110268.
 !! test
 ! and || in td attributes should not be parsed as <th>/<td>
@@ -10951,8 +10965,6 @@ Un-closed <includeonly>
 !! wikitext
 <includeonly>
 !! html
-<p>&lt;includeonly&gt;
-</p>
 !! end
 
 ## We used to, but no longer wt2wt this test since the default serializer
index 861e3bd..f69e342 100644 (file)
@@ -1026,7 +1026,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         *
         * @since 1.21
         */
-       protected function checkHasDiff3() {
+       protected function markTestSkippedIfNoDiff3() {
                global $wgDiff3;
 
                # This check may also protect against code injection in
index f113b1f..90ee1bb 100644 (file)
@@ -542,7 +542,7 @@ hello
        public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
                $expectedCode, $expectedText, $message = null
        ) {
-               $this->checkHasDiff3();
+               $this->markTestSkippedIfNoDiff3();
 
                // create page
                $ns = $this->getDefaultWikitextNS();
index 56f9746..d174947 100644 (file)
@@ -469,7 +469,7 @@ class GlobalTest extends MediaWikiTestCase {
         * @covers ::wfMerge
         */
        public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) {
-               $this->checkHasDiff3();
+               $this->markTestSkippedIfNoDiff3();
 
                $mergedText = null;
                $isMerged = wfMerge( $old, $mine, $yours, $mergedText );
index d3dc512..ca1ec50 100644 (file)
@@ -317,33 +317,6 @@ class SanitizerTest extends MediaWikiTestCase {
                );
        }
 
-       /**
-        * Test for support or lack of support for specific attributes in the attribute whitelist.
-        */
-       public static function provideAttributeSupport() {
-               /** array( <attributes>, <expected>, <message> ) */
-               return array(
-                       array(
-                               'div',
-                               ' role="presentation"',
-                               ' role="presentation"',
-                               'Support for WAI-ARIA\'s role="presentation".'
-                       ),
-                       array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ),
-               );
-       }
-
-       /**
-        * @dataProvider provideAttributeSupport
-        * @covers Sanitizer::fixTagAttributes
-        */
-       public function testAttributeSupport( $tag, $attributes, $expected, $message ) {
-               $this->assertEquals( $expected,
-                       Sanitizer::fixTagAttributes( $attributes, $tag ),
-                       $message
-               );
-       }
-
        /**
         * @dataProvider provideEscapeHtmlAllowEntities
         * @covers Sanitizer::escapeHtmlAllowEntities
@@ -363,4 +336,28 @@ class SanitizerTest extends MediaWikiTestCase {
                        array( '&lt;script&gt;foo&lt;/script&gt;', '<script>foo</script>' ),
                );
        }
+
+       /**
+        * Test escapeIdReferenceList for consistency with escapeId
+        *
+        * @dataProvider provideEscapeIdReferenceList
+        * @covers Sanitizer::escapeIdReferenceList
+        */
+       public function testEscapeIdReferenceList( $referenceList, $id1, $id2 ) {
+               $this->assertEquals(
+                       Sanitizer::escapeIdReferenceList( $referenceList, 'noninitial' ),
+                       Sanitizer::escapeId( $id1, 'noninitial' )
+                               . ' '
+                               . Sanitizer::escapeId( $id2, 'noninitial' )
+               );
+       }
+
+       public static function provideEscapeIdReferenceList() {
+               /** array( <reference list>, <individual id 1>, <individual id 2> ) */
+               return array(
+                       array( 'foo bar', 'foo', 'bar' ),
+                       array( '#1 #2', '#1', '#2' ),
+                       array( '+1 +2', '+1', '+2' ),
+               );
+       }
 }
index 3945102..35905c5 100644 (file)
@@ -10,7 +10,6 @@
 class ApiCreateAccountTest extends ApiTestCase {
        protected function setUp() {
                parent::setUp();
-               LoginForm::setCreateaccountToken();
                $this->setMwGlobals( array( 'wgEnableEmail' => true ) );
        }
 
@@ -114,7 +113,7 @@ class ApiCreateAccountTest extends ApiTestCase {
        public function testNoName() {
                $this->doApiRequest( array(
                        'action' => 'createaccount',
-                       'token' => LoginForm::getCreateaccountToken(),
+                       'token' => LoginForm::getCreateaccountToken()->toString(),
                        'password' => 'password',
                ) );
        }
@@ -127,7 +126,7 @@ class ApiCreateAccountTest extends ApiTestCase {
                $this->doApiRequest( array(
                        'action' => 'createaccount',
                        'name' => 'testName',
-                       'token' => LoginForm::getCreateaccountToken(),
+                       'token' => LoginForm::getCreateaccountToken()->toString(),
                ) );
        }
 
@@ -139,7 +138,7 @@ class ApiCreateAccountTest extends ApiTestCase {
                $this->doApiRequest( array(
                        'action' => 'createaccount',
                        'name' => 'Apitestsysop',
-                       'token' => LoginForm::getCreateaccountToken(),
+                       'token' => LoginForm::getCreateaccountToken()->toString(),
                        'password' => 'password',
                        'email' => 'test@domain.test',
                ) );
@@ -153,7 +152,7 @@ class ApiCreateAccountTest extends ApiTestCase {
                $this->doApiRequest( array(
                        'action' => 'createaccount',
                        'name' => 'Test User',
-                       'token' => LoginForm::getCreateaccountToken(),
+                       'token' => LoginForm::getCreateaccountToken()->toString(),
                        'password' => 'password',
                        'email' => 'invalid',
                ) );
index 4085925..894feb7 100644 (file)
@@ -14,11 +14,11 @@ class ApiLoginTest extends ApiTestCase {
         */
        public function testApiLoginNoName() {
                $session = array(
-                       'wsLoginToken' => 'foobar'
+                       'wsTokenSecrets' => array( 'login' => 'foobar' ),
                );
                $data = $this->doApiRequest( array( 'action' => 'login',
                        'lgname' => '', 'lgpassword' => self::$users['sysop']->password,
-                       'lgtoken' => 'foobar',
+                       'lgtoken' => (string)( new MediaWiki\Session\Token( 'foobar', '' ) )
                ), $session );
                $this->assertEquals( 'NoName', $data[0]['login']['result'] );
        }
index 25ffcb7..52c9fec 100644 (file)
@@ -148,12 +148,12 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                if ( isset( $session['wsToken'] ) && $session['wsToken'] ) {
                        // @todo Why does this directly mess with the session? Fix that.
                        // add edit token to fake session
-                       $session['wsEditToken'] = $session['wsToken'];
+                       $session['wsTokenSecrets']['default'] = $session['wsToken'];
                        // add token to request parameters
                        $timestamp = wfTimestamp();
                        $params['token'] = hash_hmac( 'md5', $timestamp, $session['wsToken'] ) .
                                dechex( $timestamp ) .
-                               User::EDIT_TOKEN_SUFFIX;
+                               MediaWiki\Session\Token::SUFFIX;
 
                        return $this->doApiRequest( $params, $session, false, $user );
                } else {
index 361238b..6b7a210 100644 (file)
@@ -157,7 +157,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
         * @covers WikitextContentHandler::merge3
         */
        public function testMerge3( $old, $mine, $yours, $expected ) {
-               $this->checkHasDiff3();
+               $this->markTestSkippedIfNoDiff3();
 
                // test merge
                $oldContent = new WikitextContent( $old );
index 25969e6..e0487c2 100644 (file)
@@ -50,6 +50,8 @@ class RequestContextTest extends MediaWikiTestCase {
                $oInfo = $context->exportSession();
                $this->assertEquals( '127.0.0.1', $oInfo['ip'], "Correct initial IP address." );
                $this->assertEquals( 0, $oInfo['userId'], "Correct initial user ID." );
+               $this->assertFalse( MediaWiki\Session\SessionManager::getGlobalSession()->isPersistent(),
+                       'Global session isn\'t persistent to start' );
 
                $user = User::newFromName( 'UnitTestContextUser' );
                $user->addToDatabase();
@@ -109,5 +111,7 @@ class RequestContextTest extends MediaWikiTestCase {
                $this->assertEquals( $oInfo['headers'], $info['headers'], "Correct restored headers." );
                $this->assertEquals( $oInfo['sessionId'], $info['sessionId'], "Correct restored session ID." );
                $this->assertEquals( $oInfo['userId'], $info['userId'], "Correct restored user ID." );
+               $this->assertFalse( MediaWiki\Session\SessionManager::getGlobalSession()->isPersistent(),
+                       'Global session isn\'t persistent after restoring the context' );
        }
 }
index b0df616..b28de57 100644 (file)
@@ -55,13 +55,19 @@ class AvroFormatterTest extends MediaWikiTestCase {
        }
 
        public function testDoesSomethingWhenSchemaAvailable() {
-               $formatter = new AvroFormatter( array( 'string' => array( 'type' => 'string' ) ) );
+               $formatter = new AvroFormatter( array(
+                       'string' => array(
+                               'schema' => array( 'type' => 'string' ),
+                               'revision' => 1010101,
+                       )
+               ) );
                $res = $formatter->format( array(
                        'channel' => 'string',
                        'context' => 'better to be',
                ) );
                $this->assertNotNull( $res );
-               // basically just tell us if avro changes its string encoding
-               $this->assertEquals( base64_decode( 'GGJldHRlciB0byBiZQ==' ), $res );
+               // basically just tell us if avro changes its string encoding, or if
+               // we completely fail to generate a log message.
+               $this->assertEquals( 'AAAAAAAAD2m1GGJldHRlciB0byBiZQ==', base64_encode( $res ) );
        }
 }
diff --git a/tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php b/tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php
new file mode 100644 (file)
index 0000000..3b19c9a
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @group BagOStuff
+ */
+class CachedBagOStuffTest extends PHPUnit_Framework_TestCase {
+
+       public function testGetFromBackend() {
+               $backend = new HashBagOStuff;
+               $cache = new CachedBagOStuff( $backend );
+
+               $backend->set( 'foo', 'bar' );
+               $this->assertEquals( 'bar', $cache->get( 'foo' ) );
+
+               $backend->set( 'foo', 'baz' );
+               $this->assertEquals( 'bar', $cache->get( 'foo' ), 'cached' );
+       }
+
+       public function testSetAndDelete() {
+               $backend = new HashBagOStuff;
+               $cache = new CachedBagOStuff( $backend );
+
+               for ( $i = 0; $i < 10; $i++ ) {
+                       $cache->set( "key$i", 1 );
+                       $this->assertEquals( 1, $cache->get( "key$i" ) );
+                       $this->assertEquals( 1, $backend->get( "key$i" ) );
+                       $cache->delete( "key$i" );
+                       $this->assertEquals( false, $cache->get( "key$i" ) );
+                       $this->assertEquals( false, $backend->get( "key$i" ) );
+               }
+       }
+
+       public function testWriteCacheOnly() {
+               $backend = new HashBagOStuff;
+               $cache = new CachedBagOStuff( $backend );
+
+               $cache->set( 'foo', 'bar', 0, CachedBagOStuff::WRITE_CACHE_ONLY );
+               $this->assertEquals( 'bar', $cache->get( 'foo' ) );
+               $this->assertFalse( $backend->get( 'foo' ) );
+
+               $cache->set( 'foo', 'old' );
+               $this->assertEquals( 'old', $cache->get( 'foo' ) );
+               $this->assertEquals( 'old', $backend->get( 'foo' ) );
+
+               $cache->set( 'foo', 'new', 0, CachedBagOStuff::WRITE_CACHE_ONLY );
+               $this->assertEquals( 'new', $cache->get( 'foo' ) );
+               $this->assertEquals( 'old', $backend->get( 'foo' ) );
+
+               $cache->delete( 'foo', CachedBagOStuff::WRITE_CACHE_ONLY );
+               $this->assertEquals( 'old', $cache->get( 'foo' ) ); // Reloaded from backend
+       }
+}
index e4415ec..d355e17 100644 (file)
@@ -34,7 +34,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 512 ),
                                'Resizing with width set',
@@ -44,7 +44,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 512, 'height' => 768 ),
                                'Resizing with height set too high',
@@ -54,7 +54,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 1024, 'height' => 384 ),
                                'Resizing with height set',
@@ -66,7 +66,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 5, 'height' => 1,
                                        'physicalWidth' => 5, 'physicalHeight' => 1,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 5 ),
                                'Very wide image',
@@ -77,7 +77,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 1, 'height' => 10,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 1 ),
                                'Very high image',
@@ -87,7 +87,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 1, 'height' => 5,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 10, 'height' => 5 ),
                                'Very high image with height set',
@@ -98,11 +98,22 @@ class BitmapScalingTest extends MediaWikiTestCase {
                                array(
                                        'width' => 5000, 'height' => 5000,
                                        'physicalWidth' => 4000, 'physicalHeight' => 4000,
-                                       'page' => 1,
+                                       'page' => 1, 'interlace' => false,
                                ),
                                array( 'width' => 5000 ),
                                'Bigger than max image size but doesn\'t need scaling',
                        ),
+                       /* Max interlace image area */
+                       array(
+                               array( 4000, 4000 ),
+                               array(
+                                       'width' => 5000, 'height' => 5000,
+                                       'physicalWidth' => 4000, 'physicalHeight' => 4000,
+                                       'page' => 1, 'interlace' => false,
+                               ),
+                               array( 'width' => 5000, 'interlace' => true ),
+                               'Interlace bigger than max interlace area',
+                       ),
                );
        }
 
index 7c0dd2e..6d2b398 100644 (file)
@@ -816,7 +816,7 @@ more stuff
 
        /* @todo FIXME: fix this!
        public function testGetUndoText() {
-       $this->checkHasDiff3();
+       $this->markTestSkippedIfNoDiff3();
 
        $text = "one";
        $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
index b940230..1ebba1a 100644 (file)
@@ -48,7 +48,7 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "<noinclude> Foo bar </noinclude>", "<root><ignore>&lt;noinclude&gt;</ignore> Foo bar <ignore>&lt;/noinclude&gt;</ignore></root>" ),
                        array( "<noinclude>\n{{Foo}}\n</noinclude>", "<root><ignore>&lt;noinclude&gt;</ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore>&lt;/noinclude&gt;</ignore></root>" ),
                        array( "<noinclude>\n{{Foo}}\n</noinclude>\n", "<root><ignore>&lt;noinclude&gt;</ignore>\n<template lineStart=\"1\"><title>Foo</title></template>\n<ignore>&lt;/noinclude&gt;</ignore>\n</root>" ),
-                       array( "<gallery>foo bar", "<root>&lt;gallery&gt;foo bar</root>" ),
+                       array( "<gallery>foo bar", "<root><ext><name>gallery</name><attr></attr><inner>foo bar</inner></ext></root>" ),
                        array( "<{{foo}}>", "<root>&lt;<template><title>foo</title></template>&gt;</root>" ),
                        array( "<{{{foo}}}>", "<root>&lt;<tplarg><title>foo</title></tplarg>&gt;</root>" ),
                        array( "<gallery></gallery</gallery>", "<root><ext><name>gallery</name><attr></attr><inner>&lt;/gallery</inner><close>&lt;/gallery&gt;</close></ext></root>" ),
index b683885..9ef2588 100644 (file)
@@ -206,7 +206,6 @@ mw.example();
                                'styles' => array(),
                                'messages' => new XmlJsCode( '{}' ),
                                'templates' => array(),
-                               'title' => 'scripts, styles and messags',
 
                                'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery ) {
 mw.example();
diff --git a/tests/phpunit/includes/search/SearchEnginePrefixTest.php b/tests/phpunit/includes/search/SearchEnginePrefixTest.php
new file mode 100644 (file)
index 0000000..2664fa6
--- /dev/null
@@ -0,0 +1,334 @@
+<?php
+/**
+ * @group Search
+ * @group Database
+ */
+class SearchEnginePrefixTest extends MediaWikiLangTestCase {
+
+       /**
+        * @var SearchEngine
+        */
+       private $search;
+
+       public function addDBData() {
+               if ( !$this->isWikitextNS( NS_MAIN ) ) {
+                       // tests are skipped if NS_MAIN is not wikitext
+                       return;
+               }
+
+               $this->insertPage( 'Sandbox' );
+               $this->insertPage( 'Bar' );
+               $this->insertPage( 'Example' );
+               $this->insertPage( 'Example Bar' );
+               $this->insertPage( 'Example Foo' );
+               $this->insertPage( 'Example Foo/Bar' );
+               $this->insertPage( 'Example/Baz' );
+               $this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
+               $this->insertPage( 'Redirect Test' );
+               $this->insertPage( 'Redirect Test Worse Result' );
+               $this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
+               $this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
+               $this->insertPage( 'Redirect Test2' );
+               $this->insertPage( 'Redirect Test2 Worse Result' );
+
+               $this->insertPage( 'Talk:Sandbox' );
+               $this->insertPage( 'Talk:Example' );
+
+               $this->insertPage( 'User:Example' );
+       }
+
+       protected function setUp() {
+               parent::setUp();
+
+               if ( !$this->isWikitextNS( NS_MAIN ) ) {
+                       $this->markTestSkipped( 'Main namespace does not support wikitext.' );
+               }
+
+               // Avoid special pages from extensions interferring with the tests
+               $this->setMwGlobals( 'wgSpecialPages', array() );
+               $this->search = SearchEngine::create();
+               $this->search->setNamespaces( array() );
+       }
+
+       protected function searchProvision( Array $results = null ) {
+               if ( $results === null ) {
+                       $this->setMwGlobals( 'wgHooks', array() );
+               } else {
+                       $this->setMwGlobals( 'wgHooks', array(
+                               'PrefixSearchBackend' => array(
+                                       function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
+                                               $srchres = $results;
+                                               return false;
+                                       }
+                               ),
+                       ) );
+               }
+       }
+
+       public static function provideSearch() {
+               return array(
+                       array( array(
+                               'Empty string',
+                               'query' => '',
+                               'results' => array(),
+                       ) ),
+                       array( array(
+                               'Main namespace with title prefix',
+                               'query' => 'Ex',
+                               'results' => array(
+                                       'Example',
+                                       'Example/Baz',
+                                       'Example Bar',
+                               ),
+                               // Third result when testing offset
+                               'offsetresult' => array(
+                                       'Example Foo',
+                               ),
+                       ) ),
+                       array( array(
+                               'Talk namespace prefix',
+                               'query' => 'Talk:',
+                               'results' => array(
+                                       'Talk:Example',
+                                       'Talk:Sandbox',
+                               ),
+                       ) ),
+                       array( array(
+                               'User namespace prefix',
+                               'query' => 'User:',
+                               'results' => array(
+                                       'User:Example',
+                               ),
+                       ) ),
+                       array( array(
+                               'Special namespace prefix',
+                               'query' => 'Special:',
+                               'results' => array(
+                                       'Special:ActiveUsers',
+                                       'Special:AllMessages',
+                                       'Special:AllMyFiles',
+                               ),
+                               // Third result when testing offset
+                               'offsetresult' => array(
+                                       'Special:AllMyUploads',
+                               ),
+                       ) ),
+                       array( array(
+                               'Special namespace with prefix',
+                               'query' => 'Special:Un',
+                               'results' => array(
+                                       'Special:Unblock',
+                                       'Special:UncategorizedCategories',
+                                       'Special:UncategorizedFiles',
+                               ),
+                               // Third result when testing offset
+                               'offsetresult' => array(
+                                       'Special:UncategorizedImages',
+                               ),
+                       ) ),
+                       array( array(
+                               'Special page name',
+                               'query' => 'Special:EditWatchlist',
+                               'results' => array(
+                                       'Special:EditWatchlist',
+                               ),
+                       ) ),
+                       array( array(
+                               'Special page subpages',
+                               'query' => 'Special:EditWatchlist/',
+                               'results' => array(
+                                       'Special:EditWatchlist/clear',
+                                       'Special:EditWatchlist/raw',
+                               ),
+                       ) ),
+                       array( array(
+                               'Special page subpages with prefix',
+                               'query' => 'Special:EditWatchlist/cl',
+                               'results' => array(
+                                       'Special:EditWatchlist/clear',
+                               ),
+                       ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideSearch
+        * @covers SearchEngine::defaultPrefixSearch
+        */
+       public function testSearch( Array $case ) {
+               $this->search->setLimitOffset( 3 );
+               $results = $this->search->defaultPrefixSearch( $case['query'] );
+               $results = array_map( function( Title $t ) {
+                       return $t->getPrefixedText();
+               }, $results );
+               $this->assertEquals(
+                       $case['results'],
+                       $results,
+                       $case[0]
+               );
+       }
+
+       /**
+        * @dataProvider provideSearch
+        * @covers SearchEngine::defaultPrefixSearch
+        */
+       public function testSearchWithOffset( Array $case ) {
+               $this->search->setLimitOffset( 3, 1 );
+               $results = $this->search->defaultPrefixSearch( $case['query'] );
+               $results = array_map( function( Title $t ) {
+                       return $t->getPrefixedText();
+               }, $results );
+
+               // We don't expect the first result when offsetting
+               array_shift( $case['results'] );
+               // And sometimes we expect a different last result
+               $expected = isset( $case['offsetresult'] ) ?
+                       array_merge( $case['results'], $case['offsetresult'] ) :
+                       $case['results'];
+
+               $this->assertEquals(
+                       $expected,
+                       $results,
+                       $case[0]
+               );
+       }
+
+       public static function provideSearchBackend() {
+               return array(
+                       array( array(
+                               'Simple case',
+                               'provision' => array(
+                                       'Bar',
+                                       'Barcelona',
+                                       'Barbara',
+                               ),
+                               'query' => 'Bar',
+                               'results' => array(
+                                       'Bar',
+                                       'Barcelona',
+                                       'Barbara',
+                               ),
+                       ) ),
+                       array( array(
+                               'Exact match not on top (bug 70958)',
+                               'provision' => array(
+                                       'Barcelona',
+                                       'Bar',
+                                       'Barbara',
+                               ),
+                               'query' => 'Bar',
+                               'results' => array(
+                                       'Bar',
+                                       'Barcelona',
+                                       'Barbara',
+                               ),
+                       ) ),
+                       array( array(
+                               'Exact match missing (bug 70958)',
+                               'provision' => array(
+                                       'Barcelona',
+                                       'Barbara',
+                                       'Bart',
+                               ),
+                               'query' => 'Bar',
+                               'results' => array(
+                                       'Bar',
+                                       'Barcelona',
+                                       'Barbara',
+                               ),
+                       ) ),
+                       array( array(
+                               'Exact match missing and not existing',
+                               'provision' => array(
+                                       'Exile',
+                                       'Exist',
+                                       'External',
+                               ),
+                               'query' => 'Ex',
+                               'results' => array(
+                                       'Exile',
+                                       'Exist',
+                                       'External',
+                               ),
+                       ) ),
+                       array( array(
+                               "Exact match shouldn't override already found match if " .
+                                       "exact is redirect and found isn't",
+                               'provision' => array(
+                                       // Target of the exact match is low in the list
+                                       'Redirect Test Worse Result',
+                                       'Redirect Test',
+                               ),
+                               'query' => 'redirect test',
+                               'results' => array(
+                                       // Redirect target is pulled up and exact match isn't added
+                                       'Redirect Test',
+                                       'Redirect Test Worse Result',
+                               ),
+                       ) ),
+                       array( array(
+                               "Exact match shouldn't override already found match if " .
+                                       "both exact match and found match are redirect",
+                               'provision' => array(
+                                       // Another redirect to the same target as the exact match
+                                       // is low in the list
+                                       'Redirect Test2 Worse Result',
+                                       'Redirect test2',
+                               ),
+                               'query' => 'redirect TEST2',
+                               'results' => array(
+                                       // Found redirect is pulled to the top and exact match isn't
+                                       // added
+                                       'Redirect test2',
+                                       'Redirect Test2 Worse Result',
+                               ),
+                       ) ),
+                       array( array(
+                               "Exact match should override any already found matches that " .
+                                       "are redirects to it",
+                               'provision' => array(
+                                       // Another redirect to the same target as the exact match
+                                       // is low in the list
+                                       'Redirect Test Worse Result',
+                                       'Redirect test',
+                               ),
+                               'query' => 'Redirect Test',
+                               'results' => array(
+                                       // Found redirect is pulled to the top and exact match isn't
+                                       // added
+                                       'Redirect Test',
+                                       'Redirect Test Worse Result',
+                                       'Redirect test',
+                               ),
+                       ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideSearchBackend
+        * @covers PrefixSearch::searchBackend
+        */
+       public function testSearchBackend( Array $case ) {
+               $search = $stub = $this->getMockBuilder( 'SearchEngine' )
+                       ->setMethods( array( 'completionSearchBackend' ) )->getMock();
+
+               $return = SearchSuggestionSet::fromStrings( $case['provision'] );
+
+               $search->expects( $this->any() )
+                       ->method( 'completionSearchBackend' )
+                       ->will( $this->returnValue( $return ) );
+
+               $search->setLimitOffset( 3 );
+               $results = $search->completionSearch( $case['query'] );
+
+               $results = $results->map( function( SearchSuggestion $s ) {
+                       return $s->getText();
+               } );
+
+               $this->assertEquals(
+                       $case['results'],
+                       $results,
+                       $case[0]
+               );
+       }
+}
diff --git a/tests/phpunit/includes/search/SearchSuggestionSetTest.php b/tests/phpunit/includes/search/SearchSuggestionSetTest.php
new file mode 100644 (file)
index 0000000..60559fc
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * Test for filter utilities.
+ *
+ * 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
+ */
+
+class SearchSuggestionSetTest extends \PHPUnit_Framework_TestCase {
+       /**
+        * Test that adding a new suggestion at the end
+        * will keep proper score ordering
+        */
+       public function testAppend() {
+               $set = SearchSuggestionSet::emptySuggestionSet();
+               $this->assertEquals( 0, $set->getSize() );
+               $set->append( new SearchSuggestion( 3 ) );
+               $this->assertEquals( 3, $set->getWorstScore() );
+               $this->assertEquals( 3, $set->getBestScore() );
+
+               $suggestion = new SearchSuggestion( 4 );
+               $set->append( $suggestion );
+               $this->assertEquals( 2, $set->getWorstScore() );
+               $this->assertEquals( 3, $set->getBestScore() );
+               $this->assertEquals( 2, $suggestion->getScore() );
+
+               $suggestion = new SearchSuggestion( 2 );
+               $set->append( $suggestion );
+               $this->assertEquals( 1, $set->getWorstScore() );
+               $this->assertEquals( 3, $set->getBestScore() );
+               $this->assertEquals( 1, $suggestion->getScore() );
+
+               $scores = $set->map( function( $s ) {
+                       return $s->getScore();
+               } );
+               $sorted = $scores;
+               asort( $sorted );
+               $this->assertEquals( $sorted, $scores );
+       }
+
+       /**
+        * Test that adding a new best suggestion will keep proper score
+        * ordering
+        */
+       public function testInsertBest() {
+               $set = SearchSuggestionSet::emptySuggestionSet();
+               $this->assertEquals( 0, $set->getSize() );
+               $set->prepend( new SearchSuggestion( 3 ) );
+               $this->assertEquals( 3, $set->getWorstScore() );
+               $this->assertEquals( 3, $set->getBestScore() );
+
+               $suggestion = new SearchSuggestion( 4 );
+               $set->prepend( $suggestion );
+               $this->assertEquals( 3, $set->getWorstScore() );
+               $this->assertEquals( 4, $set->getBestScore() );
+               $this->assertEquals( 4, $suggestion->getScore() );
+
+               $suggestion = new SearchSuggestion( 0 );
+               $set->prepend( $suggestion );
+               $this->assertEquals( 3, $set->getWorstScore() );
+               $this->assertEquals( 5, $set->getBestScore() );
+               $this->assertEquals( 5, $suggestion->getScore() );
+
+               $suggestion = new SearchSuggestion( 2 );
+               $set->prepend( $suggestion );
+               $this->assertEquals( 3, $set->getWorstScore() );
+               $this->assertEquals( 6, $set->getBestScore() );
+               $this->assertEquals( 6, $suggestion->getScore() );
+
+               $scores = $set->map( function( $s ) {
+                       return $s->getScore();
+               } );
+               $sorted = $scores;
+               asort( $sorted );
+               $this->assertEquals( $sorted, $scores );
+       }
+
+       public function testShrink() {
+               $set = SearchSuggestionSet::emptySuggestionSet();
+               for ( $i = 0; $i < 100; $i++ ) {
+                       $set->append( new SearchSuggestion( 0 ) );
+               }
+               $set->shrink( 10 );
+               $this->assertEquals( 10, $set->getSize() );
+
+               $set->shrink( 0 );
+               $this->assertEquals( 0, $set->getSize() );
+       }
+
+       // TODO: test for fromTitles
+}
index 702f556..9ba67df 100644 (file)
@@ -184,7 +184,9 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                $this->assertNotNull( $info );
                $this->assertSame( $params['priority'], $info->getPriority() );
                $this->assertSame( $sessionId, $info->getId() );
-               $this->assertNull( $info->getUserInfo() );
+               $this->assertNotNull( $info->getUserInfo() );
+               $this->assertSame( 0, $info->getUserInfo()->getId() );
+               $this->assertNull( $info->getUserInfo()->getName() );
                $this->assertFalse( $info->forceHTTPS() );
 
                // User, no session key
@@ -350,7 +352,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                $provider->setManager( SessionManager::singleton() );
 
                $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
-               $store = new \HashBagOStuff();
+               $store = new TestBagOStuff();
                $user = User::newFromName( 'UTSysop' );
                $anon = new User;
 
@@ -448,7 +450,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                                'persisted' => true,
                                'idIsSafe' => true,
                        ) ),
-                       new \EmptyBagOStuff(),
+                       new TestBagOStuff(),
                        new \Psr\Log\NullLogger(),
                        10
                );
@@ -540,7 +542,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                $provider->setManager( SessionManager::singleton() );
 
                $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
-               $store = new \HashBagOStuff();
+               $store = new TestBagOStuff();
                $user = User::newFromName( 'UTSysop' );
                $anon = new User;
 
index e06dfd5..95f8e01 100644 (file)
@@ -204,7 +204,7 @@ class ImmutableSessionProviderWithCookieTest extends MediaWikiTestCase {
                                'userInfo' => UserInfo::newFromUser( $user, true ),
                                'idIsSafe' => true,
                        ) ),
-                       new \EmptyBagOStuff(),
+                       new TestBagOStuff(),
                        new \Psr\Log\NullLogger(),
                        10
                );
index 125e1b6..3044aa7 100644 (file)
@@ -78,7 +78,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                ini_set( 'session.use_cookies', 1 );
                ini_set( 'session.use_trans_sid', 1 );
 
-               $store = new \HashBagOStuff();
+               $store = new TestBagOStuff();
                $logger = new \TestLogger();
                $manager = new SessionManager( array(
                        'store' => $store,
@@ -112,7 +112,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                        'wgObjectCacheSessionExpiry' => 2,
                ) );
 
-               $store = new \HashBagOStuff();
+               $store = new TestBagOStuff();
                $logger = new \TestLogger( true, function ( $m ) {
                        return preg_match( '/^SessionBackend a{32} /', $m ) ? null : $m;
                } );
index d06706b..f08a07d 100644 (file)
@@ -468,6 +468,8 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertInternalType( 'array', $metadata );
                $this->assertArrayHasKey( '???', $metadata );
                $this->assertSame( '!!!', $metadata['???'] );
+               $this->assertFalse( $this->store->getSessionFromBackend( self::SESSIONID ),
+                       'making sure it didn\'t save to backend' );
 
                // Persistent, not dirty
                $this->provider = $neverProvider;
@@ -516,6 +518,8 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertInternalType( 'array', $metadata );
                $this->assertArrayHasKey( '???', $metadata );
                $this->assertSame( '!!!', $metadata['???'] );
+               $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
+                       'making sure it did save to backend' );
 
                $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
@@ -538,6 +542,8 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertInternalType( 'array', $metadata );
                $this->assertArrayHasKey( '???', $metadata );
                $this->assertSame( '!!!', $metadata['???'] );
+               $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
+                       'making sure it did save to backend' );
 
                $this->provider = $this->getMock( 'DummySessionProvider', array( 'persistSession' ) );
                $this->provider->expects( $this->atLeastOnce() )->method( 'persistSession' );
@@ -559,6 +565,8 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertInternalType( 'array', $metadata );
                $this->assertArrayHasKey( '???', $metadata );
                $this->assertSame( '!!!', $metadata['???'] );
+               $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
+                       'making sure it did save to backend' );
 
                // Not marked dirty, but dirty data
                $this->provider = $neverProvider;
@@ -581,6 +589,8 @@ class SessionBackendTest extends MediaWikiTestCase {
                $this->assertInternalType( 'array', $metadata );
                $this->assertArrayHasKey( '???', $metadata );
                $this->assertSame( '!!!', $metadata['???'] );
+               $this->assertNotSame( false, $this->store->getSessionFromBackend( self::SESSIONID ),
+                       'making sure it did save to backend' );
 
                // Bad hook
                $this->provider = null;
index 083223e..bb00121 100644 (file)
@@ -300,7 +300,6 @@ class SessionManagerTest extends MediaWikiTestCase {
 
        public function testGetSessionById() {
                $manager = $this->getManager();
-
                try {
                        $manager->getSessionById( 'bad' );
                        $this->fail( 'Expected exception not thrown' );
@@ -597,7 +596,6 @@ class SessionManagerTest extends MediaWikiTestCase {
                        'Bar' => array( 'X', 'Bar1', 3 => 'Bar2' ),
                        'Quux' => array( 'Quux' ),
                        'Baz' => array(),
-                       'Quux' => array( 'Quux' ),
                );
 
                $this->assertEquals( $expect, $manager->getVaryHeaders() );
@@ -763,7 +761,7 @@ class SessionManagerTest extends MediaWikiTestCase {
 
                $that = $this;
 
-               \ObjectCache::$instances[__METHOD__] = new \HashBagOStuff();
+               \ObjectCache::$instances[__METHOD__] = new TestBagOStuff();
                $this->setMwGlobals( array( 'wgMainCacheType' => __METHOD__ ) );
 
                $this->stashMwGlobals( array( 'wgGroupPermissions' ) );
@@ -1064,12 +1062,8 @@ class SessionManagerTest extends MediaWikiTestCase {
                        $this->objectCacheDef( $provider1 ),
                ) );
 
-               $user = User::newFromName( 'UTSysop' );
-               $token = $user->getToken( true );
-
                $this->assertFalse( $manager->isUserSessionPrevented( 'UTSysop' ) );
                $manager->preventSessionsForUser( 'UTSysop' );
-               $this->assertNotEquals( $token, User::newFromName( 'UTSysop' )->getToken() );
                $this->assertTrue( $manager->isUserSessionPrevented( 'UTSysop' ) );
        }
 
@@ -1604,6 +1598,38 @@ class SessionManagerTest extends MediaWikiTestCase {
                $this->assertTrue( $info->forceHTTPS() );
                $this->assertSame( array(), $logger->getBuffer() );
 
+               // "Persist" flag from session
+               $this->store->setSessionMeta( $id, $metadata );
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+                       'provider' => $provider,
+                       'id' => $id,
+                       'userInfo' => $userInfo
+               ) );
+               $this->assertTrue( $loadSessionInfoFromStore( $info ) );
+               $this->assertFalse( $info->wasPersisted() );
+               $this->assertSame( array(), $logger->getBuffer() );
+
+               $this->store->setSessionMeta( $id, array( 'persisted' => true ) + $metadata );
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+                       'provider' => $provider,
+                       'id' => $id,
+                       'userInfo' => $userInfo
+               ) );
+               $this->assertTrue( $loadSessionInfoFromStore( $info ) );
+               $this->assertTrue( $info->wasPersisted() );
+               $this->assertSame( array(), $logger->getBuffer() );
+
+               $this->store->setSessionMeta( $id, array( 'persisted' => false ) + $metadata );
+               $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
+                       'provider' => $provider,
+                       'id' => $id,
+                       'userInfo' => $userInfo,
+                       'persisted' => true
+               ) );
+               $this->assertTrue( $loadSessionInfoFromStore( $info ) );
+               $this->assertTrue( $info->wasPersisted() );
+               $this->assertSame( array(), $logger->getBuffer() );
+
                // Provider refreshSessionInfo() returning false
                $info = new SessionInfo( SessionInfo::MIN_PRIORITY, array(
                        'provider' => $provider3,
index efc92f7..858996d 100644 (file)
@@ -199,4 +199,51 @@ class SessionTest extends MediaWikiTestCase {
                $this->assertTrue( $backend->dirty );
        }
 
+       public function testTokens() {
+               $rc = new \ReflectionClass( 'MediaWiki\\Session\\Session' );
+               if ( !method_exists( $rc, 'newInstanceWithoutConstructor' ) ) {
+                       $this->markTestSkipped(
+                               'ReflectionClass::newInstanceWithoutConstructor isn\'t available'
+                       );
+               }
+
+               // Instead of actually constructing the Session, we use reflection to
+               // bypass the constructor and plug a mock SessionBackend into the
+               // private fields to avoid having to actually create a SessionBackend.
+               $backend = new DummySessionBackend;
+               $session = $rc->newInstanceWithoutConstructor();
+               $priv = \TestingAccessWrapper::newFromObject( $session );
+               $priv->backend = $backend;
+               $priv->index = 42;
+
+               $token = \TestingAccessWrapper::newFromObject( $session->getToken() );
+               $this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
+               $this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
+               $secret = $backend->data['wsTokenSecrets']['default'];
+               $this->assertSame( $secret, $token->secret );
+               $this->assertSame( '', $token->salt );
+               $this->assertTrue( $token->wasNew() );
+
+               $token = \TestingAccessWrapper::newFromObject( $session->getToken( 'foo' ) );
+               $this->assertSame( $secret, $token->secret );
+               $this->assertSame( 'foo', $token->salt );
+               $this->assertFalse( $token->wasNew() );
+
+               $backend->data['wsTokenSecrets']['secret'] = 'sekret';
+               $token = \TestingAccessWrapper::newFromObject(
+                       $session->getToken( array( 'bar', 'baz' ), 'secret' )
+               );
+               $this->assertSame( 'sekret', $token->secret );
+               $this->assertSame( 'bar|baz', $token->salt );
+               $this->assertFalse( $token->wasNew() );
+
+               $session->resetToken( 'secret' );
+               $this->assertArrayHasKey( 'wsTokenSecrets', $backend->data );
+               $this->assertArrayHasKey( 'default', $backend->data['wsTokenSecrets'] );
+               $this->assertArrayNotHasKey( 'secret', $backend->data['wsTokenSecrets'] );
+
+               $session->resetAllTokens();
+               $this->assertArrayNotHasKey( 'wsTokenSecrets', $backend->data );
+
+       }
 }
index e674e7b..8d1b544 100644 (file)
@@ -5,7 +5,11 @@ namespace MediaWiki\Session;
 /**
  * BagOStuff with utility functions for MediaWiki\\Session\\* testing
  */
-class TestBagOStuff extends \HashBagOStuff {
+class TestBagOStuff extends \CachedBagOStuff {
+
+       public function __construct() {
+               parent::__construct( new \HashBagOStuff );
+       }
 
        /**
         * @param string $id Session ID
@@ -68,6 +72,14 @@ class TestBagOStuff extends \HashBagOStuff {
                return $this->get( wfMemcKey( 'MWSession', $id ) );
        }
 
+       /**
+        * @param string $id Session ID
+        * @return mixed
+        */
+       public function getSessionFromBackend( $id ) {
+               return $this->backend->get( wfMemcKey( 'MWSession', $id ) );
+       }
+
        /**
         * @param string $id Session ID
         */
diff --git a/tests/phpunit/includes/session/TokenTest.php b/tests/phpunit/includes/session/TokenTest.php
new file mode 100644 (file)
index 0000000..113f409
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+namespace MediaWiki\Session;
+
+use MediaWikiTestCase;
+
+/**
+ * @group Session
+ * @covers MediaWiki\Session\Token
+ */
+class TokenTest extends MediaWikiTestCase {
+
+       public function testBasics() {
+               $token = $this->getMockBuilder( 'MediaWiki\\Session\\Token' )
+                       ->setMethods( array( 'toStringAtTimestamp' ) )
+                       ->setConstructorArgs( array( 'sekret', 'salty', true ) )
+                       ->getMock();
+               $token->expects( $this->any() )->method( 'toStringAtTimestamp' )
+                       ->will( $this->returnValue( 'faketoken+\\' ) );
+
+               $this->assertSame( 'faketoken+\\', $token->toString() );
+               $this->assertSame( 'faketoken+\\', (string)$token );
+               $this->assertTrue( $token->wasNew() );
+
+               $token = new Token( 'sekret', 'salty', false );
+               $this->assertFalse( $token->wasNew() );
+       }
+
+       public function testToStringAtTimestamp() {
+               $token = \TestingAccessWrapper::newFromObject( new Token( 'sekret', 'salty', false ) );
+
+               $this->assertSame(
+                       'd9ade0c7d4349e9df9094e61c33a5a0d5644fde2+\\',
+                       $token->toStringAtTimestamp( 1447362018 )
+               );
+               $this->assertSame(
+                       'ee2f7a2488dea9176c224cfb400d43be5644fdea+\\',
+                       $token->toStringAtTimestamp( 1447362026 )
+               );
+       }
+
+       public function testGetTimestamp() {
+               $this->assertSame(
+                       1447362018, Token::getTimestamp( 'd9ade0c7d4349e9df9094e61c33a5a0d5644fde2+\\' )
+               );
+               $this->assertSame(
+                       1447362026, Token::getTimestamp( 'ee2f7a2488dea9176c224cfb400d43be5644fdea+\\' )
+               );
+               $this->assertNull( Token::getTimestamp( 'ee2f7a2488dea9176c224cfb400d43be5644fdea-\\' ) );
+               $this->assertNull( Token::getTimestamp( 'ee2f7a2488dea9176c224cfb400d43be+\\' ) );
+
+               $this->assertNull( Token::getTimestamp( 'ee2f7a2488dea9x76c224cfb400d43be5644fdea+\\' ) );
+       }
+
+       public function testMatch() {
+               $token = \TestingAccessWrapper::newFromObject( new Token( 'sekret', 'salty', false ) );
+
+               $test = $token->toStringAtTimestamp( time() - 10 );
+               $this->assertTrue( $token->match( $test ) );
+               $this->assertTrue( $token->match( $test, 12 ) );
+               $this->assertFalse( $token->match( $test, 8 ) );
+
+               $this->assertFalse( $token->match( 'ee2f7a2488dea9176c224cfb400d43be5644fdea-\\' ) );
+       }
+
+}
index 121bb72..c38edd6 100644 (file)
@@ -19,7 +19,7 @@ class UserInfoTest extends MediaWikiTestCase {
                $this->assertTrue( $userinfo->isVerified() );
                $this->assertSame( 0, $userinfo->getId() );
                $this->assertSame( null, $userinfo->getName() );
-               $this->assertSame( null, $userinfo->getToken() );
+               $this->assertSame( '', $userinfo->getToken() );
                $this->assertNotNull( $userinfo->getUser() );
                $this->assertSame( $userinfo, $userinfo->verified() );
                $this->assertSame( '<anon>', (string)$userinfo );
@@ -102,7 +102,7 @@ class UserInfoTest extends MediaWikiTestCase {
                $this->assertFalse( $userinfo->isVerified() );
                $this->assertSame( $user->getId(), $userinfo->getId() );
                $this->assertSame( $user->getName(), $userinfo->getName() );
-               $this->assertSame( null, $userinfo->getToken() );
+               $this->assertSame( '', $userinfo->getToken() );
                $this->assertInstanceOf( 'User', $userinfo->getUser() );
                $userinfo2 = $userinfo->verified();
                $this->assertNotSame( $userinfo2, $userinfo );
@@ -112,7 +112,7 @@ class UserInfoTest extends MediaWikiTestCase {
                $this->assertTrue( $userinfo2->isVerified() );
                $this->assertSame( $user->getId(), $userinfo2->getId() );
                $this->assertSame( $user->getName(), $userinfo2->getName() );
-               $this->assertSame( null, $userinfo2->getToken() );
+               $this->assertSame( '', $userinfo2->getToken() );
                $this->assertInstanceOf( 'User', $userinfo2->getUser() );
                $this->assertSame( $userinfo2, $userinfo2->verified() );
                $this->assertSame( "<+:{$user->getId()}:{$user->getName()}>", (string)$userinfo2 );
@@ -157,7 +157,7 @@ class UserInfoTest extends MediaWikiTestCase {
                $this->assertFalse( $userinfo->isVerified() );
                $this->assertSame( $user->getId(), $userinfo->getId() );
                $this->assertSame( $user->getName(), $userinfo->getName() );
-               $this->assertSame( null, $userinfo->getToken() );
+               $this->assertSame( '', $userinfo->getToken() );
                $this->assertSame( $user, $userinfo->getUser() );
                $userinfo2 = $userinfo->verified();
                $this->assertNotSame( $userinfo2, $userinfo );
@@ -167,7 +167,7 @@ class UserInfoTest extends MediaWikiTestCase {
                $this->assertTrue( $userinfo2->isVerified() );
                $this->assertSame( $user->getId(), $userinfo2->getId() );
                $this->assertSame( $user->getName(), $userinfo2->getName() );
-               $this->assertSame( null, $userinfo2->getToken() );
+               $this->assertSame( '', $userinfo2->getToken() );
                $this->assertSame( $user, $userinfo2->getUser() );
                $this->assertSame( $userinfo2, $userinfo2->verified() );
                $this->assertSame( "<+:{$user->getId()}:{$user->getName()}>", (string)$userinfo2 );
index d2f96dc..5cf75bd 100644 (file)
@@ -33,6 +33,9 @@ class ApiDocumentationTest extends MediaWikiTestCase {
                if ( !self::$main ) {
                        self::$main = new ApiMain( RequestContext::getMain() );
                        self::$main->getContext()->setLanguage( 'en' );
+                       self::$main->getContext()->setTitle(
+                               Title::makeTitle( NS_SPECIAL, 'Badtitle/dummy title for ApiDocumentationTest' )
+                       );
                }
                return self::$main;
        }
index e7b45bd..07e6f26 100644 (file)
         * Configuration
         */
 
-       // When a test() indicates asynchronicity with stop(),
-       // allow 30 seconds to pass before killing the test(),
-       // and assuming failure.
-       QUnit.config.testTimeout = 30 * 1000;
+       // For each test() that is asynchronous, allow this time to pass before
+       // killing the test and assuming timeout failure.
+       QUnit.config.testTimeout = 60 * 1000;
 
        QUnit.config.requireExpects = true;
 
index cd0db7c..f2865eb 100644 (file)
@@ -16,7 +16,7 @@
 
                this.server.respondWith( /action=parse.*&text='''Hello\+world'''/, function ( request ) {
                        request.respond( 200, { 'Content-Type': 'application/json' },
-                               '{ "parse": { "text": { "*": "<p><b>Hello world</b></p>" } } }'
+                               '{ "parse": { "text": "<p><b>Hello world</b></p>" } }'
                        );
                } );
 
index 43b324e..07eddbf 100644 (file)
        /**
         * @param {Function[]} tasks List of functions that perform tasks
         *  that may be asynchronous. Invoke the callback parameter when done.
-        * @param {Function} complete Called when all tasks are done, or when the sequence is aborted.
         */
-       function process( tasks, complete ) {
+       function process( tasks ) {
                /*jshint latedef:false */
                function abort() {
                        tasks.splice( 0, tasks.length );
                        } else {
                                // Remove tasks list to indicate the process is final.
                                tasks = null;
-                               complete();
                        }
                }
                next();
                mw.messages.set( mw.libs.phpParserData.messages );
                var tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
                        return function ( next, abort ) {
+                               var done = assert.async();
                                getMwLanguage( test.lang )
                                        .then( function ( langClass ) {
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                        }, function () {
                                                assert.ok( false, 'Language "' + test.lang + '" failed to load.' );
                                        } )
+                                       .then( done, done )
                                        .then( next, abort );
                        };
                } );
 
-               QUnit.stop();
-               process( tasks, QUnit.start );
+               process( tasks );
        } );
 
        QUnit.test( 'Links', 14, function ( assert ) {
                mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
                var queue = $.map( formatnumTests, function ( test ) {
                        return function ( next, abort ) {
+                               var done = assert.async();
                                getMwLanguage( test.lang )
                                        .then( function ( langClass ) {
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                        }, function () {
                                                assert.ok( false, 'Language "' + test.lang + '" failed to load' );
                                        } )
+                                       .then( done, done )
                                        .then( next, abort );
                        };
                } );
-               QUnit.stop();
-               process( queue, QUnit.start );
+               process( queue );
        } );
 
        // HTML in wikitext
index ed3f2cd..fe5530b 100644 (file)
                } );
        } );
 
+       QUnit.test( 'mw.loader.implement( empty )', 1, function ( assert ) {
+               mw.loader.implement( 'test.empty' );
+               assert.strictEqual( mw.loader.getState( 'test.empty' ), 'ready' );
+       } );
+
        QUnit.test( 'mw.loader with broken indirect dependency', 4, function ( assert ) {
                // don't emit an error event
                this.sandbox.stub( mw, 'track' );