From: jenkins-bot allow_url_fopen
ist niet verfüchbar.",
diff --git a/includes/installer/i18n/hu.json b/includes/installer/i18n/hu.json
index 10011ba802..d9b6108a04 100644
--- a/includes/installer/i18n/hu.json
+++ b/includes/installer/i18n/hu.json
@@ -287,7 +287,6 @@
"config-install-interwiki-exists": "'''Figyelmeztetés''': Ãgy tűnik, hogy az interwiki táblában már vannak bejegyzések.\nAlapértelmezett lista kihagyása.",
"config-install-stats": "Statisztika inicializálása",
"config-install-keys": "Titkos kulcsok generálása",
- "config-insecure-keys": "'''Figyelmeztetés:''' A telepÃtés során generált $1 {{PLURAL:$2|biztonsági kulcs|biztonsági kulcsok}} nem teljesen $1 {{PLURAL:$2|biztonságos|biztonságosak}}. Ãrdemes {{PLURAL:$2||Åket}} manuálisan megváltoztatni.",
"config-install-updates": "Nem szükséges frissÃtések futtatásának megakadályozása",
"config-install-sysop": "Az adminisztrátor felhasználói fiókjának létrehozása",
"config-install-subscribe-fail": "Nem sikerült feliratkozni a mediawiki-announce levelezÅlistára: $1",
diff --git a/includes/installer/i18n/ia.json b/includes/installer/i18n/ia.json
index 9ba487ca5e..e71a6bb37e 100644
--- a/includes/installer/i18n/ia.json
+++ b/includes/installer/i18n/ia.json
@@ -292,7 +292,6 @@
"config-install-interwiki-exists": "'''Aviso''': Le tabella interwiki pare jam haber entratas.\nLe lista predefinite es saltate.",
"config-install-stats": "Initialisation del statisticas",
"config-install-keys": "Generation de claves secrete",
- "config-insecure-keys": "'''Attention:''' {{PLURAL:$2|Un clave|Alcun claves}} secur ($1) generate durante le installation non es completemente secur. Considera cambiar {{PLURAL:$2|lo|los}} manualmente.",
"config-install-updates": "Impedir le execution de actualisationes innecessari",
"config-install-updates-failed": "Error: Le insertion de claves de actualisation in le tabellas ha fallite con le error sequente: $1",
"config-install-sysop": "Crea conto de usator pro administrator",
diff --git a/includes/installer/i18n/id.json b/includes/installer/i18n/id.json
index 5cae96561c..eb6f51c7e1 100644
--- a/includes/installer/i18n/id.json
+++ b/includes/installer/i18n/id.json
@@ -300,7 +300,6 @@
"config-install-interwiki-exists": "'''Peringatan''': Tabel antarwiki tampaknya sudah memiliki entri.\nMengabaikan daftar bawaan.",
"config-install-stats": "Inisialisasi statistik",
"config-install-keys": "Membuat kunci rahasia",
- "config-insecure-keys": "'''Peringatan:''' {{PLURAL:$2|Suatu|Beberapa}} kunci aman ($1) yang dibuat selama instalasi {{PLURAL:$2|tidak|tidak}} benar-benar aman. Pertimbangkan untuk mengubah {{PLURAL:$2|kunci|kunci-kunci}} tersebut secara manual.",
"config-install-updates": "Cegah jalannya pembaruan yang tidak dibutuhkan",
"config-install-updates-failed": "Kesalahan: Memasukkan kunci pembaruan ke dalam tabel gagal dengan kode kesalahan: $1",
"config-install-sysop": "Membuat akun pengguna pengurus",
diff --git a/includes/installer/i18n/it.json b/includes/installer/i18n/it.json
index 79845cf609..b9b52b62f2 100644
--- a/includes/installer/i18n/it.json
+++ b/includes/installer/i18n/it.json
@@ -305,7 +305,6 @@
"config-install-interwiki-exists": "'''Attenzione:''' la tabella interwiki sembra che contiene già elementi.\nSalto l'elenco predefinito.",
"config-install-stats": "Inizializzazione delle statistiche",
"config-install-keys": "Generazione delle chiavi segrete",
- "config-insecure-keys": "'''Attenzione:''' {{PLURAL:$2|Una chiave sicura|Delle chiavi sicure}} ($1) {{PLURAL:$2|generata|generate}} durante l'installazione non {{PLURAL:$2|è|sono}} completamente {{PLURAL:$2|sicura|sicure}}. Considera di {{PLURAL:$2|cambiarla|cambiarle}} manualmente.",
"config-install-updates": "Impedire l'esecuzione di aggiornamenti non necessari",
"config-install-updates-failed": "Errore: l'inserimento delle chiavi di aggiornamento nelle tabelle non è riuscito con il seguente errore: $1",
"config-install-sysop": "Creazione dell'account utente per l'amministratore",
diff --git a/includes/installer/i18n/ja.json b/includes/installer/i18n/ja.json
index 8b6a78a1d4..f5e65a5efc 100644
--- a/includes/installer/i18n/ja.json
+++ b/includes/installer/i18n/ja.json
@@ -311,7 +311,6 @@
"config-install-interwiki-exists": "è¦å: ã¦ã£ãéãã¼ãã«ã¯æ¢ã«ç»é²ããã¦ããããã§ãã\næ¢å®ã®ãã¼ãã«ãç¡è¦ãã¾ãã",
"config-install-stats": "çµ±è¨æ
å ±ã®åæå",
"config-install-keys": "ç§å¯éµã®çæ",
- "config-insecure-keys": "è¦å: ã¤ã³ã¹ãã¼ã«ä¸ã«çæãããã»ãã¥ã¢ãã¼ ($1) ã¯å®ç§ã«å®å
¨ã§ã¯ããã¾ãããæåã§å¤æ´ãããã¨ãæ¤è¨ãã¦ãã ããã",
"config-install-updates": "ä¸è¦ãªæ´æ°ãå®è¡ããã®ãé²ã",
"config-install-updates-failed": "ã¨ã©ã¼: æ´æ°ãã¼ããã¼ãã«ã«æ¿å
¥ããéã«å¤±æãã¾ããã以ä¸ã®ã¨ã©ã¼ãèµ·ãã£ã¦ãã¾ã: $1",
"config-install-sysop": "管çè
ã¢ã«ã¦ã³ãã®ä½æ",
diff --git a/includes/installer/i18n/ko.json b/includes/installer/i18n/ko.json
index 5e8d4dcda8..e0a9c8ba0e 100644
--- a/includes/installer/i18n/ko.json
+++ b/includes/installer/i18n/ko.json
@@ -124,8 +124,8 @@
"config-support-info": "미ëì´ìí¤ë ë¤ìì ë°ì´í°ë² ì´ì¤ ìì¤í
ì ì§ìí©ëë¤:\n\n$1\n\në°ì´í°ë² ì´ì¤ ìì¤í
ì´ íìëì§ ìì ë ìëì ëì´ë ë¤ì ì§ìì íì±ííë ¤ë©´ ìì ë§í¬ë ì§ìì ë°ë¼ ì¤ì¹í´ë³¼ ì ììµëë¤.",
"config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]ì 미ëì´ìí¤ì 기본 ëìì´ë©° ê°ì¥ ì ì§ìë©ëë¤. 미ëì´ìí¤ë ëí MySQLì í¸íëë [{{int:version-db-mariadb-url}} MariaDB]ì [{{int:version-db-percona-url}} Percona ìë²]ììë ìëí©ëë¤. ([https://secure.php.net/manual/en/mysql.installation.php MySQL ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²])",
"config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]ì MySQLì ëìì¼ë¡ì ì¸ê¸° ìë ì¤í ìì¤ ë°ì´í°ë² ì´ì¤ ìì¤í
ì
ëë¤. ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²])",
- "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]ë ë§¤ì° ì ì§ìëê³ ê°ë²¼ì´ ë°ì´í°ë² ì´ì¤ ìì¤í
ì
ëë¤. ([http://www.php.net/manual/en/pdo.installation.php SQLite ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²], PDO ì¬ì©)",
- "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]ì ìì© ê¸°ì
ë°ì´í°ë² ì´ì¤ì
ëë¤. ([http://www.php.net/manual/en/oci8.installation.php OCI8 ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²])",
+ "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]ë ë§¤ì° ì ì§ìëê³ ê°ë²¼ì´ ë°ì´í°ë² ì´ì¤ ìì¤í
ì
ëë¤. ([https://secure.php.net/manual/en/pdo.installation.php SQLite ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²], PDO ì¬ì©)",
+ "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]ì ìì© ê¸°ì
ë°ì´í°ë² ì´ì¤ì
ëë¤. ([https://secure.php.net/manual/en/oci8.installation.php OCI8 ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²])",
"config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL ìë²]ë Windowsì© ìì© ê¸°ì
ë°ì´í°ë² ì´ì¤ì
ëë¤. ([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRV ì§ìì¼ë¡ PHP를 ì»´íì¼íë ë°©ë²])",
"config-header-mysql": "MySQL ì¤ì ",
"config-header-postgres": "PostgreSQL ì¤ì ",
@@ -298,7 +298,6 @@
"config-install-interwiki-exists": "ê²½ê³ : ì¸í°ìí¤ í
ì´ë¸ì´ ì´ë¯¸ í목ì ê°ê³ ìë ê² ê°ìµëë¤.\n기본 목ë¡ì ê±´ëëëë¤.",
"config-install-stats": "íµê³ë¥¼ ì´ê¸°ííë ì¤",
"config-install-keys": "ë³´ì í¤ë¥¼ ë§ëë ì¤",
- "config-insecure-keys": "ê²½ê³ : ì¤ì¹ ì¤ì ìì±í {{PLURAL:$2|ë³´ì í¤}} ($1)ë ìì í ìì íì§ {{PLURAL:$2|ììµëë¤}}. ì§ì ë°ê¾¸ë ê²ì ê³ ë ¤íì¸ì.",
"config-install-updates": "ë¶íìí ì
ë°ì´í¸ ì¤í ë°©ì§",
"config-install-updates-failed": "ì¤ë¥: ë¤ì ì¤ë¥ë¡ í
ì´ë¸ ìì ì
ë°ì´í¸ í¤ë¥¼ ë£ê¸°ì ì¤í¨íìµëë¤: $1",
"config-install-sysop": "ê´ë¦¬ì ì¬ì©ì ê³ì ì ë§ëë ì¤",
diff --git a/includes/installer/i18n/ksh.json b/includes/installer/i18n/ksh.json
index 33ccabdfd3..5ac7ec607a 100644
--- a/includes/installer/i18n/ksh.json
+++ b/includes/installer/i18n/ksh.json
@@ -289,7 +289,6 @@
"config-install-interwiki-exists": "'''OpjepaÃ''': En der Engewiki-Tabäll schingk alt jät dren ze shtonn.\nDoh dom_mer nix dobei.",
"config-install-stats": "De Shtatestek-Zahle wääde op Aanfang jeshtallt.",
"config-install-keys": "Jeheime SchlöÃel wääde opjebout.",
- "config-insecure-keys": "'''OpjepaÃ:''' {{PLURAL:$2|Ene jeheime SchlöÃel|Jeheim SchlöÃele|Keine jeheime SchlöÃel}} ($1) {{PLURAL:$2|es|sin|es}} automattesch aanjelaat woode. {{PLURAL:$2|Dä es|Di sin|Hä es}} ävver nit onbedengk janz sescher. Ãvverlääsch Der, {{PLURAL:$2|dä|di|en}} norr_ens vun Hand ze ändere.",
"config-install-updates": "Donn kein onnühdeje Ãnderonge maache.",
"config-install-updates-failed": "Dä: SchlöÃÃelle för et Ãndere en Tabälle bränge es donävve jajange. Jemäldt wood: $1",
"config-install-sysop": "Dä Zohjang för der Wiki-Köbes weed aanjelaat.",
diff --git a/includes/installer/i18n/lij.json b/includes/installer/i18n/lij.json
index 8d05b79613..69821ec428 100644
--- a/includes/installer/i18n/lij.json
+++ b/includes/installer/i18n/lij.json
@@ -285,7 +285,6 @@
"config-install-interwiki-exists": "'''Atençion:''' pâ che inta tabella interwiki ghe segge za di elementi.\nA lista predefinia a se sata.",
"config-install-stats": "Iniçializaçion de statisteghe",
"config-install-keys": "Generaçion de ciave segrette",
- "config-insecure-keys": "'''Atençion:''' {{PLURAL:$2|Una ciave segûa|De ciave segûe}} ($1) {{PLURAL:$2|generâ|generæ}} durante l'instalaçion {{PLURAL:$2|a|}} no {{PLURAL:$2|l'è|son}} completamente {{PLURAL:$2|segûa|segûe}}. Consciddera de cangiâ{{PLURAL:$2|la|le}} manoalmente.",
"config-install-updates": "Impedî l'esecuçion di agiornamenti non necessai",
"config-install-updates-failed": "Erô: l'inseimento de ciave de agiornamento inte tabelle o no l'è ariescio pe-o seguente erô: $1",
"config-install-sysop": "Creaçion de l'utença pe l'aministratô",
diff --git a/includes/installer/i18n/mk.json b/includes/installer/i18n/mk.json
index 1e712b0f71..303e82ef15 100644
--- a/includes/installer/i18n/mk.json
+++ b/includes/installer/i18n/mk.json
@@ -292,7 +292,6 @@
"config-install-interwiki-exists": "'''ÐÑедÑпÑедÑваÑе''': ТабелаÑа Ñо инÑеÑвикиÑа веÑе ÑодÑжи ÑÑавки.\nÐо пÑеÑкокнÑвам оÑновно-Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð¸Ð¾Ñ ÑпиÑок.",
"config-install-stats": "Ðи подгоÑвÑвам ÑÑаÑиÑÑикиÑе",
"config-install-keys": "СоздаваÑе на ÑаÑни клÑÑеви",
- "config-insecure-keys": "'''ÐÑедÑпÑедÑваÑе:''' {{PLURAL:$2|ÐезбедноÑÐ½Ð¸Ð¾Ñ ÐºÐ»ÑÑ $1 Ñоздаден во ÑÐµÐºÐ¾Ñ Ð½Ð° воÑпоÑÑавкаÑа не е ÑоÑем безбеден|ÐезбедноÑниÑе клÑÑеви $1 Ñоздадени во ÑÐµÐºÐ¾Ñ Ð½Ð° воÑпоÑÑавкаÑа не Ñе ÑоÑем безбедни}}. Ðи пÑепоÑаÑÑваме да {{PLURAL:$2|го|ги}} ÑмениÑе ÑаÑно.",
"config-install-updates": "СпÑеÑи вÑÑеÑе на непоÑÑебни поднови",
"config-install-updates-failed": "ÐÑеÑка: ÐмеÑнÑваÑеÑо на подновни клÑÑеви во ÑабелиÑе не ÑÑпеа, Ñо Ñледнава гÑеÑка: $1",
"config-install-sysop": "СоздаваÑе на админиÑÑÑаÑоÑÑка коÑиÑниÑка ÑмеÑка",
diff --git a/includes/installer/i18n/ms.json b/includes/installer/i18n/ms.json
index 28b497f78c..334d3a00da 100644
--- a/includes/installer/i18n/ms.json
+++ b/includes/installer/i18n/ms.json
@@ -140,7 +140,6 @@
"config-install-interwiki-list": "Fail interwiki.list
tidak dapat dibaca.",
"config-install-interwiki-exists": "Amaran: Jadual antara wiki nampaknya sudah ada entri. Senarai asali dilangkau.",
"config-install-keys": "Menjana kunci-kunci rahsia",
- "config-insecure-keys": "Amaran: {{PLURAL:$2|Kunci keselamatan|Kunci-kunci keselamatan}} ($1) yang dihasilkan sewaktu pemasangan itu {{PLURAL:$2|adalah}} tidak selamat sepenuhnya. Oleh itu, {{PLURAL:$2|ia}} wajar ditukar secara manual.",
"config-install-sysop": "Membuka akaun pengguna pentadbir",
"config-install-mainpage": "Mewujudkan laman utama dengan kandungan lalai",
"config-help": "bantuan",
diff --git a/includes/installer/i18n/nap.json b/includes/installer/i18n/nap.json
index 2f2ae1e8e3..797742736f 100644
--- a/includes/installer/i18n/nap.json
+++ b/includes/installer/i18n/nap.json
@@ -284,7 +284,6 @@
"config-install-interwiki-exists": "'''Attenziò:''' 'a tabbella interwiki pare ca cuntenesse già elemente.\nZumpann' 'a lista predefinita.",
"config-install-stats": "Inizializzaziona d' 'e statistiche",
"config-install-keys": "Generaziona d' 'e chiave segrete",
- "config-insecure-keys": "'''Attenziò:''' {{PLURAL:$2|Na chiave sicura|'E chiave sicure}} ($1) {{PLURAL:$2|generata|generate}} pe' tramente ca se fà l'installazione nun {{PLURAL:$2|è|songo}} completamente {{PLURAL:$2|sicura|sicure}}. Cunziderate d' {{PLURAL:$2|'a|'e}} cagnà manualmente.",
"config-install-updates": "Mpiccià ll'agghiurnamiente ca nun fossero necessarie",
"config-install-updates-failed": "Errore: l'inserimento d' 'e chiave 'agghiurnamiento dint' 'e tabbelle nun è asciuto pecché se cunfermaje l'errore ccà annanze: $1",
"config-install-sysop": "Crianno nu cunto utente ammenistratore",
diff --git a/includes/installer/i18n/nb.json b/includes/installer/i18n/nb.json
index c67d04e9ca..a3d69c9cd8 100644
--- a/includes/installer/i18n/nb.json
+++ b/includes/installer/i18n/nb.json
@@ -297,7 +297,6 @@
"config-install-interwiki-exists": "Advarsel: Interwiki-tabellen ser allerede ut til å ha innhold.\nLegger derfor ikke inn standardlisten.",
"config-install-stats": "Initialiserer statisikk",
"config-install-keys": "Genererer hemmelige nøkler",
- "config-insecure-keys": "Advarsel: {{PLURAL:$2|En sikker nøkkel|Sikre nøkler}} ($1) generert under installeringen er ikke helt {{PLURAL:$2|trygg|trygge}}. Vurder å endre {{PLURAL:$2|den|dem}} manuelt.",
"config-install-updates": "Forhindre unødvendige oppdateringer",
"config-install-updates-failed": "Feil: Innsetting av oppdateringsnøkler i tabellene mislyktes med følgende feilmelding: $1",
"config-install-sysop": "Oppretter brukerkonto for administrator",
diff --git a/includes/installer/i18n/nl.json b/includes/installer/i18n/nl.json
index 7bcd391b0b..6011a8b77b 100644
--- a/includes/installer/i18n/nl.json
+++ b/includes/installer/i18n/nl.json
@@ -309,7 +309,6 @@
"config-install-interwiki-exists": "'''Waarschuwing''': de interwikitabel heeft al inhoud.\nDe standaardlijst wordt overgeslagen.",
"config-install-stats": "Statistieken initialiseren",
"config-install-keys": "Bezig met aanmaken van geheime sleutels",
- "config-insecure-keys": "'''Waarschuwing:''' De {{PLURAL:$2|sleutel die is aangemaakt|sleutels die zijn aangemaakt}} ($1) tijdens de installatie {{PLURAL:$2|is|zijn}} niet volledig veilig. Overweeg deze handmatig te wijzigen.",
"config-install-updates": "Voorkomen dat updates onnodig worden uitgevoerd",
"config-install-updates-failed": "Fout: het toevoegen van updatesleutels aan tabellen is mislukt met de volgende fout: $1",
"config-install-sysop": "Account voor beheerder aanmaken",
diff --git a/includes/installer/i18n/pl.json b/includes/installer/i18n/pl.json
index d395f831b4..0f70dfbc86 100644
--- a/includes/installer/i18n/pl.json
+++ b/includes/installer/i18n/pl.json
@@ -309,7 +309,6 @@
"config-install-interwiki-exists": "'''Uwaga''' â wyglÄ
da na to, że tabela interwiki ma już jakieÅ wpisy.\nTworzenie domyÅlnej listy pominiÄto.",
"config-install-stats": "Inicjowanie statystyki",
"config-install-keys": "Generowanie tajnych kluczy",
- "config-insecure-keys": "'''Ostrzeżenie:''' {{PLURAL:$2|Klucz bezpieczeÅstwa|Klucze bezpieczeÅstwa|Klucze bezpieczeÅstwa}} ($1) utworzone podczas instalacji {{PLURAL:$2|utworzony podczas instalacji nie jest|utworzone podczas instalacji nie sÄ
|utworzone podczas instalacji nie sÄ
}} w peÅni bezpieczne. ByÄ może warto wygenerowaÄ {{PLURAL:$2|wÅasny klucz|wÅasne klucze|wÅasne klucze}}.",
"config-install-updates": "Zapobieganie uruchamianiu niepotrzebnych aktualizacji",
"config-install-updates-failed": "BÅÄ
d: Wstawianie kluczy aktualizacji d0 tabeli nie powiodÅo siÄ z powodu nastÄpujÄ
cego bÅÄdu: $1",
"config-install-sysop": "Tworzenie konta administratora",
diff --git a/includes/installer/i18n/pms.json b/includes/installer/i18n/pms.json
index bcdf1a77d2..a06e0443e1 100644
--- a/includes/installer/i18n/pms.json
+++ b/includes/installer/i18n/pms.json
@@ -267,7 +267,6 @@
"config-install-interwiki-exists": "'''Avis''': La tà ula interwiki a smija ch'a l'abia già dj'element.\nPër stà ndard, la lista a sarà sautà .",
"config-install-stats": "Inissialisassion dle statìstiche",
"config-install-keys": "Generassion ëd le ciav segrete",
- "config-insecure-keys": "'''Avis:''' {{PLURAL:$2|Na ciav sigura|Dle ciav sigure}} ($1) generà durant l'istalassion {{PLURAL:$2|a l'é|a son}} pa completament sigure. Ch'a consìdera ëd modifiche{{PLURAL:$2|la|je}} manualment.",
"config-install-sysop": "Creassion dël cont ëd l'utent aministrator",
"config-install-subscribe-fail": "As peul pa sot-scrivse mediawiki-announce: $1",
"config-install-subscribe-notpossible": "cURL a l'é pa istalà e allow_url_fopen
a l'é pa disponìbil.",
diff --git a/includes/installer/i18n/pt-br.json b/includes/installer/i18n/pt-br.json
index 60898d9bb0..e0216b36d0 100644
--- a/includes/installer/i18n/pt-br.json
+++ b/includes/installer/i18n/pt-br.json
@@ -310,7 +310,6 @@
"config-install-interwiki-exists": "Aviso: A tabela de interwiki parece já ter entradas.\\NPulando lista padrão.",
"config-install-stats": "Inicializando estatÃsticas",
"config-install-keys": "Gerando senhas secretas",
- "config-insecure-keys": "Aviso: {{PLURAL:$2|Uma chave segura gerada|Algumas chaves seguras geradas}} ($1) durante a instalação {{PLURAL:$2|não é completamente segura|não são completamente seguras}}. Considere mudar {{PLURAL:$2|ela|elas}} manualmente.",
"config-install-updates": "Impedir a execução de atualizações desnecessárias",
"config-install-updates-failed": "Error: A inserção de chaves de atualização em tabelas falhou com o seguinte erro: $1",
"config-install-sysop": "Criando conta de usuário administrador",
diff --git a/includes/installer/i18n/pt.json b/includes/installer/i18n/pt.json
index 9593ebe97f..c1fc5d8263 100644
--- a/includes/installer/i18n/pt.json
+++ b/includes/installer/i18n/pt.json
@@ -308,7 +308,6 @@
"config-install-interwiki-exists": "Aviso: A tabela de interwikis parece já conter entradas.\nO preenchimento padrão desta tabela será saltado.",
"config-install-stats": "A inicializar as estatÃsticas",
"config-install-keys": "A gerar as chaves secretas",
- "config-insecure-keys": "Aviso: {{PLURAL:$2|Uma chave segura|Chaves seguras}} ($1) {{PLURAL:$2|gerada durante a instalação não é completamente segura|geradas durante a instalação não são completamente seguras}}. Considere a possibilidade de {{PLURAL:$2|alterá-la|alterá-las}} manualmente.",
"config-install-updates": "Evitar executar atualizações desnecessárias",
"config-install-updates-failed": "Erro: A inserção de chaves de atualização nas tabelas falhou com o seguinte erro: $1",
"config-install-sysop": "A criar a conta de administrador",
diff --git a/includes/installer/i18n/qqq.json b/includes/installer/i18n/qqq.json
index 0779204613..d9edde5d13 100644
--- a/includes/installer/i18n/qqq.json
+++ b/includes/installer/i18n/qqq.json
@@ -308,7 +308,6 @@
"config-install-interwiki-exists": "Error notice during the installation saying that one of the database tables is already set up, so it's continuing without taking that step.",
"config-install-stats": "*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
"config-install-keys": "*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
- "config-insecure-keys": "Parameters:\n* $1 - A list of names of the secret keys that were generated.\n* $2 - the number of items in the list $1, to be used with PLURAL.",
"config-install-updates": "Message indicating that the updatelog table is filled with keys of updates that won't be run when running database updates.\n\nSee also:\n*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-updates}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
"config-install-updates-failed": "Used as error message. Parameters:\n* $1 - detailed error message",
"config-install-sysop": "Message indicates that the administrator user account is being created\n\nSee also:\n*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
diff --git a/includes/installer/i18n/ru.json b/includes/installer/i18n/ru.json
index aeda43a719..ef38b51231 100644
--- a/includes/installer/i18n/ru.json
+++ b/includes/installer/i18n/ru.json
@@ -313,7 +313,6 @@
"config-install-interwiki-exists": "'''ÐÑедÑпÑеждение''': в инÑеÑвики-ÑаблиÑе, кажеÑÑÑ, Ñже еÑÑÑ Ð·Ð°Ð¿Ð¸Ñи.\nСоздание ÑÑандаÑÑного ÑпиÑка пÑопÑÑено.",
"config-install-stats": "СÑаÑиÑÑика иниÑиализаÑии",
"config-install-keys": "Создание ÑекÑеÑнÑÑ
клÑÑей",
- "config-insecure-keys": "'''ÐÑедÑпÑеждение.''' {{PLURAL:$2|1=ÐлÑÑ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑÑи $1, ÑозданнÑй во вÑÐµÐ¼Ñ ÑÑÑановки, недоÑÑаÑоÑно надÑжен|ÐлÑÑи безопаÑноÑÑи $1, ÑозданнÑе во вÑÐµÐ¼Ñ ÑÑÑановки, недоÑÑаÑоÑно надÑжнÑ}}. РаÑÑмоÑÑиÑе возможноÑÑÑ {{PLURAL:$2|1=его|иÑ
}} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑÑÑнÑÑ.",
"config-install-updates": "ÐÑедоÑвÑаÑение запÑÑка ненÑжнÑÑ
обновлений",
"config-install-updates-failed": "ÐÑибка: ÐÑÑавка клÑÑей Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð² ÑаблиÑÑ Ð·Ð°Ð²ÐµÑÑилаÑÑ Ñо ÑледÑÑÑей оÑибкой: $1",
"config-install-sysop": "Создание ÑÑÑÑной запиÑи админиÑÑÑаÑоÑа",
diff --git a/includes/installer/i18n/sco.json b/includes/installer/i18n/sco.json
index 5b60540346..b489ca34d0 100644
--- a/includes/installer/i18n/sco.json
+++ b/includes/installer/i18n/sco.json
@@ -286,7 +286,6 @@
"config-install-interwiki-exists": "Warnishment: The interwiki buird awreadie seems tae hae entries.\nSkippin defaut let.",
"config-install-stats": "Ineetializin stateestics",
"config-install-keys": "Generatin hidlins keys",
- "config-insecure-keys": "Warnishment: {{PLURAL:$2|Ae secure key|Secure keys}} ($1) generated durin instawation {{PLURAL:$2|is|ar}} naw compleatelie safe. Consider chyngin {{PLURAL:$2|it|theim}} manuallie.",
"config-install-updates": "Hinder the runnin o onneedit updates.",
"config-install-updates-failed": "Mistak: Insertin update keys intae the buirds failed wi the folleain mistak: $1",
"config-install-sysop": "Makin admeenistrâter uiser accoont",
diff --git a/includes/installer/i18n/sv.json b/includes/installer/i18n/sv.json
index a691824e1b..c0ae4f0cf2 100644
--- a/includes/installer/i18n/sv.json
+++ b/includes/installer/i18n/sv.json
@@ -294,7 +294,6 @@
"config-install-interwiki-exists": "Varning: Interwiki-tabellen verkar redan innehålla poster.\nHoppar över standardlistan.",
"config-install-stats": "Initierar statistik",
"config-install-keys": "Genererar hemliga nycklar",
- "config-insecure-keys": "'''Varning:''' {{PLURAL:$2|En säkerhetsnyckel|Säkerhetsnycklar}} ($1) som generades under installationen är inte helt {{PLURAL:$2|säker|säkra}} . Ãverväg att ändra {{PLURAL:$2|den|dem}} manuellt.",
"config-install-updates": "Förhindra att onödiga uppdateringar körs",
"config-install-updates-failed": "Fel: Infogning av uppdateringsnycklar i tabeller misslyckades med följande fel:$1",
"config-install-sysop": "Skapar administratörskonto",
diff --git a/includes/installer/i18n/tl.json b/includes/installer/i18n/tl.json
index 6298cb7bf9..0249bae527 100644
--- a/includes/installer/i18n/tl.json
+++ b/includes/installer/i18n/tl.json
@@ -272,7 +272,6 @@
"config-install-interwiki-exists": "'''Babala''': Tila may mga laman na ang talahanayan ng interwiki.\nNilalaktawan ang likas na nakatakdang talaan.",
"config-install-stats": "Sinisimulan ang estadistika",
"config-install-keys": "Ginagawa ang lihim na mga susi",
- "config-insecure-keys": "'''Babala:''' Nalikha ang {{PLURAL:$2|A secure key|ligtas na mga susi}} ($1) habang ang pagluluklok {{PLURAL:$2|ay|ay}} hindi pa lubos na ligtas. Isaalang-alang ang kinakamay na pagbago {{PLURAL:$2|nito|ng mga ito}}.",
"config-install-sysop": "Nililikha ang account ng tagagamit na tagapangasiwa",
"config-install-subscribe-fail": "Hindi nagawang magpasipi mula sa mediawiki-announce: $1",
"config-install-subscribe-notpossible": "Hindi nakalagak ang cURL at hindi makukuha ang allow_url_fopen
",
diff --git a/includes/installer/i18n/uk.json b/includes/installer/i18n/uk.json
index b1e69df8ae..a40bf1bbc3 100644
--- a/includes/installer/i18n/uk.json
+++ b/includes/installer/i18n/uk.json
@@ -298,7 +298,6 @@
"config-install-interwiki-exists": "'''Увага''': ТаблиÑÑ ÑнÑеÑвÑÐºÑ Ñже, здаÑÑÑÑÑ, Ð¼Ð°Ñ Ð·Ð°Ð¿Ð¸Ñи.\nСÑвоÑÐµÐ½Ð½Ñ ÑÑандаÑÑного ÑпиÑÐºÑ Ð¿ÑопÑÑкаÑÑÑÑÑ.",
"config-install-stats": "ÐнÑÑÑалÑзаÑÑÑ ÑÑаÑиÑÑики",
"config-install-keys": "ÐенеÑаÑÑÑ ÑекÑеÑниÑ
клÑÑÑв",
- "config-insecure-keys": "'''Увага:''' {{PLURAL:$2|1=СекÑеÑний клÑÑ|СекÑеÑÐ½Ñ ÐºÐ»ÑÑÑ}} ($1), {{PLURAL:$2|1=згенеÑований в пÑоÑеÑÑ Ð²ÑÑановленнÑ, недоÑÑаÑнÑо надÑйний|згенеÑÐ¾Ð²Ð°Ð½Ñ Ð² пÑоÑеÑÑ Ð²ÑÑановленнÑ, недоÑÑаÑнÑо надÑйнÑ}}. РозглÑнÑÑе можливÑÑÑÑ {{PLURAL:$2|1=його|ÑÑ
}} замÑни вÑÑÑнÑ.",
"config-install-updates": "ÐапобÑгÑи запÑÑÐºÑ Ð½ÐµÐ¿Ð¾ÑÑÑбниÑ
оновленÑ",
"config-install-updates-failed": "Ðомилка: ÐÑÑавка оновленниÑ
клÑÑÑв в ÑаблиÑÑ Ð½Ðµ вдалоÑÑ ÑеÑез ÑÐ°ÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ:$1",
"config-install-sysop": "СÑвоÑÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñкового запиÑÑ Ð°Ð´Ð¼ÑнÑÑÑÑаÑоÑа",
diff --git a/includes/installer/i18n/vi.json b/includes/installer/i18n/vi.json
index 0ecd6889e1..d69a260b12 100644
--- a/includes/installer/i18n/vi.json
+++ b/includes/installer/i18n/vi.json
@@ -292,7 +292,6 @@
"config-install-interwiki-exists": "'''Cảnh báo:''' Hình nhÆ° Äã có mục trong bảng liên wiki.\nÄã bá» qua danh sách mặc Äá»nh.",
"config-install-stats": "Äang khá»i tạo các thá»ng kê",
"config-install-keys": "Tạo ra các chìa khóa bà máºt",
- "config-insecure-keys": "Cảnh báo: {{PLURAL:$2|Má»t khóa an toà n|Khóa an toà n}} ($1) Äược tạo ra trong quá trình cà i Äặt {{PLURAL:$2}}không phải an toà n hẳn. Hãy cân nhắc viá»c thay Äá»i {{PLURAL:$2|nó|chúng}} thủ công.",
"config-install-updates": "Tránh các cáºp nháºt không cần thiết",
"config-install-updates-failed": "Lá»i: Chèn phÃm cáºp nháºt và o các bảng không thà nh công vá»i các lá»i sau:1$",
"config-install-sysop": "Äang má» tà i khoản ngÆ°á»i dùng bảo quản viên",
diff --git a/includes/installer/i18n/zh-hans.json b/includes/installer/i18n/zh-hans.json
index d22c56658c..c46478da65 100644
--- a/includes/installer/i18n/zh-hans.json
+++ b/includes/installer/i18n/zh-hans.json
@@ -307,7 +307,6 @@
"config-install-interwiki-exists": "è¦åï¼è·¨wikiæ°æ®è¡¨ä¼¼ä¹å·²æå
容ï¼è·³è¿é»è®¤å表ã",
"config-install-stats": "åå§åç»è®¡",
"config-install-keys": "çæå¯é¥ä¸",
- "config-insecure-keys": "è¦åï¼å¨å®è£
è¿ç¨ä¸çæç{{PLURAL:$2|å®å
¨å¯é¥}}ï¼$1ï¼{{PLURAL:$2|并}}ä¸ä¸å®å®å
¨ã请èèæå¨æ´æ¹{{PLURAL:$2|å®|å®ä»¬}}ã",
"config-install-updates": "é²æ¢è¿è¡ä¸éè¦çæ´æ°",
"config-install-updates-failed": "é误ï¼è¡¨æ ¼ä¸æå
¥æ´æ°å
³é®å失败并åºç°å¦ä¸é误ï¼$1",
"config-install-sysop": "æ£å¨å建管çåç¨æ·å¸å·",
diff --git a/includes/installer/i18n/zh-hant.json b/includes/installer/i18n/zh-hant.json
index a54f66bd74..4854877b28 100644
--- a/includes/installer/i18n/zh-hant.json
+++ b/includes/installer/i18n/zh-hant.json
@@ -306,7 +306,6 @@
"config-install-interwiki-exists": "è¦åï¼ interwiki è³æ表å
§å·²æè³æï¼ç¥é建ç«é è¨è³æã",
"config-install-stats": "åå§åçµ±è¨è³è¨",
"config-install-keys": "ç¢çç§å¯éé°ä¸",
- "config-insecure-keys": "è¦åï¼å¨å®è£éç¨ä¸æç¢çç $2 çµå®å
¨éé°($1)並ä¸å®å
¨å®å
¨ãè«èæ
®æåæ´æ¹ã",
"config-install-updates": "ç¥éå·è¡ä¸éè¦çæ´æ°",
"config-install-updates-failed": "é¯èª¤ï¼ æå
¥æ´æ°éµå¼è³è³æ表失æï¼ä¸¦åºç¾ä»¥ä¸é¯èª¤ï¼$1",
"config-install-sysop": "æ£å¨å»ºç«ç®¡çå¡ä½¿ç¨è
帳è",
diff --git a/includes/json/FormatJson.php b/includes/json/FormatJson.php
index b99b0b826c..1ab17a06f5 100644
--- a/includes/json/FormatJson.php
+++ b/includes/json/FormatJson.php
@@ -38,7 +38,7 @@ class FormatJson {
* HTML and XML.
*
* @warning Do not use this option for JSON that could end up in inline scripts.
- * - HTML5, §4.3.1.2 Restrictions for contents of script elements
+ * - HTML 5.2, §4.12.1.3 Restrictions for contents of script elements
* - XML 1.0 (5th Ed.), §2.4 Character Data and Markup
*
* @since 1.22
@@ -52,19 +52,18 @@ class FormatJson {
*
* @since 1.22
*/
- const ALL_OK = 3;
+ const ALL_OK = self::UTF8_OK | self::XMLMETA_OK;
/**
- * If set, treat json objects '{...}' as associative arrays. Without this option,
- * json objects will be converted to stdClass.
- * The value is set to 1 to be backward compatible with 'true' that was used before.
+ * If set, treat JSON objects '{...}' as associative arrays. Without this option,
+ * JSON objects will be converted to stdClass.
*
* @since 1.24
*/
const FORCE_ASSOC = 0x100;
/**
- * If set, attempts to fix invalid json.
+ * If set, attempt to fix invalid JSON.
*
* @since 1.24
*/
@@ -130,18 +129,16 @@ class FormatJson {
return false;
}
- if ( $pretty !== false ) {
- if ( $pretty !== ' ' ) {
- // Change the four-space indent to a tab indent
- $json = str_replace( "\n ", "\n\t", $json );
- while ( strpos( $json, "\t " ) !== false ) {
- $json = str_replace( "\t ", "\t\t", $json );
- }
+ if ( $pretty !== false && $pretty !== ' ' ) {
+ // Change the four-space indent to a tab indent
+ $json = str_replace( "\n ", "\n\t", $json );
+ while ( strpos( $json, "\t " ) !== false ) {
+ $json = str_replace( "\t ", "\t\t", $json );
+ }
- if ( $pretty !== "\t" ) {
- // Change the tab indent to the provided indent
- $json = str_replace( "\t", $pretty, $json );
- }
+ if ( $pretty !== "\t" ) {
+ // Change the tab indent to the provided indent
+ $json = str_replace( "\t", $pretty, $json );
}
}
if ( $escaping & self::UTF8_OK ) {
@@ -243,7 +240,7 @@ class FormatJson {
/**
* Remove multiline and single line comments from an otherwise valid JSON
- * input string. This can be used as a preprocessor for to allow JSON
+ * input string. This can be used as a preprocessor, to allow JSON
* formatted configuration files to contain comments.
*
* @param string $json
diff --git a/includes/libs/ArrayUtils.php b/includes/libs/ArrayUtils.php
index 0413ea0d5a..e23888779f 100644
--- a/includes/libs/ArrayUtils.php
+++ b/includes/libs/ArrayUtils.php
@@ -120,8 +120,8 @@ class ArrayUtils {
$max = $valueCount;
do {
$mid = $min + ( ( $max - $min ) >> 1 );
- $item = call_user_func( $valueCallback, $mid );
- $comparison = call_user_func( $comparisonCallback, $target, $item );
+ $item = $valueCallback( $mid );
+ $comparison = $comparisonCallback( $target, $item );
if ( $comparison > 0 ) {
$min = $mid;
} elseif ( $comparison == 0 ) {
@@ -133,8 +133,8 @@ class ArrayUtils {
} while ( $min < $max - 1 );
if ( $min == 0 ) {
- $item = call_user_func( $valueCallback, $min );
- $comparison = call_user_func( $comparisonCallback, $target, $item );
+ $item = $valueCallback( $min );
+ $comparison = $comparisonCallback( $target, $item );
if ( $comparison < 0 ) {
// Before the first item
return false;
@@ -168,7 +168,7 @@ class ArrayUtils {
$args[] = $array[$key];
}
}
- $valueret = call_user_func_array( __METHOD__, $args );
+ $valueret = self::arrayDiffAssocRecursive( ...$args );
if ( count( $valueret ) ) {
$ret[$key] = $valueret;
}
diff --git a/includes/libs/CryptHKDF.php b/includes/libs/CryptHKDF.php
index c41aab339c..0478a33700 100644
--- a/includes/libs/CryptHKDF.php
+++ b/includes/libs/CryptHKDF.php
@@ -99,22 +99,14 @@ class CryptHKDF {
'whirlpool' => 64,
];
- /**
- * @var CryptRand
- */
- private $cryptRand;
-
/**
* @param string $secretKeyMaterial
* @param string $algorithm Name of hashing algorithm
* @param BagOStuff $cache
* @param string|array $context Context to mix into HKDF context
- * @param CryptRand $cryptRand
* @throws InvalidArgumentException if secret key material is too short
*/
- public function __construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context,
- CryptRand $cryptRand
- ) {
+ public function __construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context ) {
if ( strlen( $secretKeyMaterial ) < 16 ) {
throw new InvalidArgumentException( "secret was too short." );
}
@@ -122,7 +114,6 @@ class CryptHKDF {
$this->algorithm = $algorithm;
$this->cache = $cache;
$this->context = is_array( $context ) ? $context : [ $context ];
- $this->cryptRand = $cryptRand;
// To prevent every call from hitting the same memcache server, pick
// from a set of keys to use. mt_rand is only use to pick a random
@@ -150,12 +141,12 @@ class CryptHKDF {
$lastSalt = $this->cache->get( $this->cacheKey );
if ( $lastSalt === false ) {
// If we don't have a previous value to use as our salt, we use
- // 16 bytes from CryptRand, which will use a small amount of
+ // 16 bytes from random_bytes(), which will use a small amount of
// entropy from our pool. Note, "XTR may be deterministic or keyed
// via an optional âsalt valueâ (i.e., a non-secret random
// value)..." - http://eprint.iacr.org/2010/264.pdf. However, we
// use a strongly random value since we can.
- $lastSalt = $this->cryptRand->generate( 16 );
+ $lastSalt = random_bytes( 16 );
}
// Get a binary string that is hashLen long
$this->salt = hash( $this->algorithm, $lastSalt, true );
diff --git a/includes/libs/CryptRand.php b/includes/libs/CryptRand.php
index f7702dd3ac..a1bbd099c4 100644
--- a/includes/libs/CryptRand.php
+++ b/includes/libs/CryptRand.php
@@ -23,187 +23,54 @@
* @author Daniel Friesen
* @file
*/
-use Psr\Log\LoggerInterface;
+/**
+ * @deprecated since 1.32, use random_bytes()/random_int()
+ */
class CryptRand {
/**
- * Minimum number of iterations we want to make in our drift calculations.
+ * @deprecated since 1.32, unused
*/
const MIN_ITERATIONS = 1000;
/**
- * Number of milliseconds we want to spend generating each separate byte
- * of the final generated bytes.
- * This is used in combination with the hash length to determine the duration
- * we should spend doing drift calculations.
+ * @deprecated since 1.32, unused
*/
const MSEC_PER_BYTE = 0.5;
/**
- * A boolean indicating whether the previous random generation was done using
- * cryptographically strong random number generator or not.
- */
- protected $strong = null;
-
- /**
- * List of functions to call to generate some random state
+ * Initialize an initial random state based off of whatever we can find
*
- * @var callable[]
- */
- protected $randomFuncs = [];
-
- /**
- * List of files to generate some random state from
+ * @deprecated since 1.32, unused and does nothing
*
- * @var string[]
- */
- protected $randomFiles = [];
-
- /**
- * @var LoggerInterface
- */
- protected $logger;
-
- public function __construct( array $randomFuncs, array $randomFiles, LoggerInterface $logger ) {
- $this->randomFuncs = $randomFuncs;
- $this->randomFiles = $randomFiles;
- $this->logger = $logger;
- }
-
- /**
- * Initialize an initial random state based off of whatever we can find
* @return string
*/
protected function initialRandomState() {
- // $_SERVER contains a variety of unstable user and system specific information
- // It'll vary a little with each page, and vary even more with separate users
- // It'll also vary slightly across different machines
- $state = serialize( $_SERVER );
-
- // Try to gather a little entropy from the different php rand sources
- $state .= rand() . uniqid( mt_rand(), true );
-
- // Include some information about the filesystem's current state in the random state
- $files = $this->randomFiles;
-
- // We know this file is here so grab some info about ourselves
- $files[] = __FILE__;
-
- // We must also have a parent folder, and with the usual file structure, a grandparent
- $files[] = __DIR__;
- $files[] = dirname( __DIR__ );
-
- foreach ( $files as $file ) {
- Wikimedia\suppressWarnings();
- $stat = stat( $file );
- Wikimedia\restoreWarnings();
- if ( $stat ) {
- // stat() duplicates data into numeric and string keys so kill off all the numeric ones
- foreach ( $stat as $k => $v ) {
- if ( is_numeric( $k ) ) {
- unset( $k );
- }
- }
- // The absolute filename itself will differ from install to install so don't leave it out
- $path = realpath( $file );
- if ( $path !== false ) {
- $state .= $path;
- } else {
- $state .= $file;
- }
- $state .= implode( '', $stat );
- } else {
- // The fact that the file isn't there is worth at least a
- // minuscule amount of entropy.
- $state .= '0';
- }
- }
-
- // Try and make this a little more unstable by including the varying process
- // id of the php process we are running inside of if we are able to access it
- if ( function_exists( 'getmypid' ) ) {
- $state .= getmypid();
- }
-
- // If available try to increase the instability of the data by throwing in
- // the precise amount of memory that we happen to be using at the moment.
- if ( function_exists( 'memory_get_usage' ) ) {
- $state .= memory_get_usage( true );
- }
-
- foreach ( $this->randomFuncs as $randomFunc ) {
- $state .= call_user_func( $randomFunc );
- }
-
- return $state;
+ return '';
}
/**
* Randomly hash data while mixing in clock drift data for randomness
*
+ * @deprecated since 1.32, unused and does nothing
+ *
* @param string $data The data to randomly hash.
* @return string The hashed bytes
* @author Tim Starling
*/
protected function driftHash( $data ) {
- // Minimum number of iterations (to avoid slow operations causing the
- // loop to gather little entropy)
- $minIterations = self::MIN_ITERATIONS;
- // Duration of time to spend doing calculations (in seconds)
- $duration = ( self::MSEC_PER_BYTE / 1000 ) * MWCryptHash::hashLength();
- // Create a buffer to use to trigger memory operations
- $bufLength = 10000000;
- $buffer = str_repeat( ' ', $bufLength );
- $bufPos = 0;
-
- // Iterate for $duration seconds or at least $minIterations number of iterations
- $iterations = 0;
- $startTime = microtime( true );
- $currentTime = $startTime;
- while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
- // Trigger some memory writing to trigger some bus activity
- // This may create variance in the time between iterations
- $bufPos = ( $bufPos + 13 ) % $bufLength;
- $buffer[$bufPos] = ' ';
- // Add the drift between this iteration and the last in as entropy
- $nextTime = microtime( true );
- $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
- $data .= $delta;
- // Every 100 iterations hash the data and entropy
- if ( $iterations % 100 === 0 ) {
- $data = sha1( $data );
- }
- $currentTime = $nextTime;
- $iterations++;
- }
- $timeTaken = $currentTime - $startTime;
- $data = MWCryptHash::hash( $data );
-
- $this->logger->debug( "Clock drift calculation " .
- "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
- "iterations=$iterations, " .
- "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)" );
-
- return $data;
+ return '';
}
/**
* Return a rolling random state initially build using data from unstable sources
+ *
+ * @deprecated since 1.32, unused and does nothing
+ *
* @return string A new weak random state
*/
protected function randomState() {
- static $state = null;
- if ( is_null( $state ) ) {
- // Initialize the state with whatever unstable data we can find
- // It's important that this data is hashed right afterwards to prevent
- // it from being leaked into the output stream
- $state = MWCryptHash::hash( $this->initialRandomState() );
- }
- // Generate a new random state based on the initial random state or previous
- // random state by combining it with clock drift
- $state = $this->driftHash( $state );
-
- return $state;
+ return '';
}
/**
@@ -211,191 +78,36 @@ class CryptRand {
* random bytes generation in the previously run generate* call
* was cryptographically strong.
*
- * @return bool Returns true if the source was strong, false if not.
+ * @deprecated since 1.32, always returns true
+ *
+ * @return bool Always true
*/
public function wasStrong() {
- if ( is_null( $this->strong ) ) {
- throw new RuntimeException( __METHOD__ . ' called before generation of random data' );
- }
-
- return $this->strong;
+ return true;
}
/**
- * Generate a run of (ideally) cryptographically random data and return
+ * Generate a run of cryptographically random data and return
* it in raw binary form.
* You can use CryptRand::wasStrong() if you wish to know if the source used
* was cryptographically strong.
*
* @param int $bytes The number of bytes of random data to generate
- * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
- * strong sources of entropy even if reading from them may steal
- * more entropy from the system than optimal.
* @return string Raw binary random data
*/
- public function generate( $bytes, $forceStrong = false ) {
+ public function generate( $bytes ) {
$bytes = floor( $bytes );
- static $buffer = '';
- if ( is_null( $this->strong ) ) {
- // Set strength to false initially until we know what source data is coming from
- $this->strong = true;
- }
-
- if ( strlen( $buffer ) < $bytes ) {
- // If available make use of PHP 7's random_bytes
- // On Linux, getrandom syscall will be used if available.
- // On Windows CryptGenRandom will always be used
- // On other platforms, /dev/urandom will be used.
- // Avoids polyfills from before php 7.0
- // All error situations will throw Exceptions and or Errors
- if ( PHP_VERSION_ID >= 70000
- || ( defined( 'HHVM_VERSION_ID' ) && HHVM_VERSION_ID >= 31101 )
- ) {
- $rem = $bytes - strlen( $buffer );
- $buffer .= random_bytes( $rem );
- }
- if ( strlen( $buffer ) >= $bytes ) {
- $this->strong = true;
- }
- }
-
- if ( strlen( $buffer ) < $bytes && function_exists( 'mcrypt_create_iv' ) ) {
- // If available make use of mcrypt_create_iv URANDOM source to generate randomness
- // On unix-like systems this reads from /dev/urandom but does it without any buffering
- // and bypasses openbasedir restrictions, so it's preferable to reading directly
- // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
- // entropy so this is also preferable to just trying to read urandom because it may work
- // on Windows systems as well.
- $rem = $bytes - strlen( $buffer );
- $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
- if ( $iv === false ) {
- $this->logger->debug( "mcrypt_create_iv returned false." );
- } else {
- $buffer .= $iv;
- $this->logger->debug( "mcrypt_create_iv generated " . strlen( $iv ) .
- " bytes of randomness." );
- }
- }
-
- if ( strlen( $buffer ) < $bytes && function_exists( 'openssl_random_pseudo_bytes' ) ) {
- $rem = $bytes - strlen( $buffer );
- $openssl_strong = false;
- $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
- if ( $openssl_bytes === false ) {
- $this->logger->debug( "openssl_random_pseudo_bytes returned false." );
- } else {
- $buffer .= $openssl_bytes;
- $this->logger->debug( "openssl_random_pseudo_bytes generated " .
- strlen( $openssl_bytes ) . " bytes of " .
- ( $openssl_strong ? "strong" : "weak" ) . " randomness." );
- }
- if ( strlen( $buffer ) >= $bytes ) {
- // openssl tells us if the random source was strong, if some of our data was generated
- // using it use it's say on whether the randomness is strong
- $this->strong = !!$openssl_strong;
- }
- }
-
- // Only read from urandom if we can control the buffer size or were passed forceStrong
- if ( strlen( $buffer ) < $bytes &&
- ( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
- ) {
- $rem = $bytes - strlen( $buffer );
- if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
- $this->logger->debug( "Was forced to read from /dev/urandom " .
- "without control over the buffer size." );
- }
- // /dev/urandom is generally considered the best possible commonly
- // available random source, and is available on most *nix systems.
- Wikimedia\suppressWarnings();
- $urandom = fopen( "/dev/urandom", "rb" );
- Wikimedia\restoreWarnings();
-
- // Attempt to read all our random data from urandom
- // php's fread always does buffered reads based on the stream's chunk_size
- // so in reality it will usually read more than the amount of data we're
- // asked for and not storing that risks depleting the system's random pool.
- // If stream_set_read_buffer is available set the chunk_size to the amount
- // of data we need. Otherwise read 8k, php's default chunk_size.
- if ( $urandom ) {
- // php's default chunk_size is 8k
- $chunk_size = 1024 * 8;
- if ( function_exists( 'stream_set_read_buffer' ) ) {
- // If possible set the chunk_size to the amount of data we need
- stream_set_read_buffer( $urandom, $rem );
- $chunk_size = $rem;
- }
- $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
- $buffer .= $random_bytes;
- fclose( $urandom );
- $this->logger->debug( "/dev/urandom generated " . strlen( $random_bytes ) .
- " bytes of randomness." );
-
- if ( strlen( $buffer ) >= $bytes ) {
- // urandom is always strong, set to true if all our data was generated using it
- $this->strong = true;
- }
- } else {
- $this->logger->debug( "/dev/urandom could not be opened." );
- }
- }
-
- // If we cannot use or generate enough data from a secure source
- // use this loop to generate a good set of pseudo random data.
- // This works by initializing a random state using a pile of unstable data
- // and continually shoving it through a hash along with a variable salt.
- // We hash the random state with more salt to avoid the state from leaking
- // out and being used to predict the /randomness/ that follows.
- if ( strlen( $buffer ) < $bytes ) {
- $this->logger->debug( __METHOD__ .
- ": Falling back to using a pseudo random state to generate randomness." );
- }
- while ( strlen( $buffer ) < $bytes ) {
- $buffer .= MWCryptHash::hmac( $this->randomState(), strval( mt_rand() ) );
- // This code is never really cryptographically strong, if we use it
- // at all, then set strong to false.
- $this->strong = false;
- }
-
- // Once the buffer has been filled up with enough random data to fulfill
- // the request shift off enough data to handle the request and leave the
- // unused portion left inside the buffer for the next request for random data
- $generated = substr( $buffer, 0, $bytes );
- $buffer = substr( $buffer, $bytes );
-
- $this->logger->debug( strlen( $buffer ) .
- " bytes of randomness leftover in the buffer." );
-
- return $generated;
+ return random_bytes( $bytes );
}
/**
- * Generate a run of (ideally) cryptographically random data and return
+ * Generate a run of cryptographically random data and return
* it in hexadecimal string format.
- * You can use CryptRand::wasStrong() if you wish to know if the source used
- * was cryptographically strong.
*
* @param int $chars The number of hex chars of random data to generate
- * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
- * strong sources of entropy even if reading from them may steal
- * more entropy from the system than optimal.
* @return string Hexadecimal random data
*/
- public function generateHex( $chars, $forceStrong = false ) {
- // hex strings are 2x the length of raw binary so we divide the length in half
- // odd numbers will result in a .5 that leads the generate() being 1 character
- // short, so we use ceil() to ensure that we always have enough bytes
- $bytes = ceil( $chars / 2 );
- // Generate the data and then convert it to a hex string
- $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
-
- // A bit of paranoia here, the caller asked for a specific length of string
- // here, and it's possible (eg when given an odd number) that we may actually
- // have at least 1 char more than they asked for. Just in case they made this
- // call intending to insert it into a database that does truncation we don't
- // want to give them too much and end up with their database and their live
- // code having two different values because part of what we gave them is truncated
- // hence, we strip out any run of characters longer than what we were asked for.
- return substr( $hex, 0, $chars );
+ public function generateHex( $chars ) {
+ return MWCryptRand::generateHex( $chars );
}
}
diff --git a/includes/libs/MemoizedCallable.php b/includes/libs/MemoizedCallable.php
index 14462f1d9f..e9d1fc1ca3 100644
--- a/includes/libs/MemoizedCallable.php
+++ b/includes/libs/MemoizedCallable.php
@@ -123,7 +123,7 @@ class MemoizedCallable {
$success = false;
$result = $this->fetchResult( $key, $success );
if ( !$success ) {
- $result = call_user_func_array( $this->callable, $args );
+ $result = ( $this->callable )( ...$args );
$this->storeResult( $key, $result );
}
diff --git a/includes/libs/StatusValue.php b/includes/libs/StatusValue.php
index 6f348c2b96..3bdafe1282 100644
--- a/includes/libs/StatusValue.php
+++ b/includes/libs/StatusValue.php
@@ -68,7 +68,7 @@ class StatusValue {
public static function newFatal( $message /*, parameters...*/ ) {
$params = func_get_args();
$result = new static();
- call_user_func_array( [ &$result, 'fatal' ], $params );
+ $result->fatal( ...$params );
return $result;
}
diff --git a/includes/libs/StringUtils.php b/includes/libs/StringUtils.php
index 7915ccf191..d91ac85adb 100644
--- a/includes/libs/StringUtils.php
+++ b/includes/libs/StringUtils.php
@@ -206,7 +206,7 @@ class StringUtils {
} elseif ( $tokenType == 'end' ) {
if ( $foundStart ) {
# Found match
- $output .= call_user_func( $callback, [
+ $output .= $callback( [
substr( $subject, $outputPos, $tokenOffset + $tokenLength - $outputPos ),
substr( $subject, $contentPos, $tokenOffset - $contentPos )
] );
diff --git a/includes/libs/filebackend/FileBackend.php b/includes/libs/filebackend/FileBackend.php
index 2d4a772b7e..785cb72655 100644
--- a/includes/libs/filebackend/FileBackend.php
+++ b/includes/libs/filebackend/FileBackend.php
@@ -1590,7 +1590,7 @@ abstract class FileBackend implements LoggerAwareInterface {
final protected function newStatus() {
$args = func_get_args();
if ( count( $args ) ) {
- $sv = call_user_func_array( [ StatusValue::class, 'newFatal' ], $args );
+ $sv = StatusValue::newFatal( ...$args );
} else {
$sv = StatusValue::newGood();
}
diff --git a/includes/libs/filebackend/SwiftFileBackend.php b/includes/libs/filebackend/SwiftFileBackend.php
index 3cd973ea48..2f7bc1ef8f 100644
--- a/includes/libs/filebackend/SwiftFileBackend.php
+++ b/includes/libs/filebackend/SwiftFileBackend.php
@@ -1103,7 +1103,7 @@ class SwiftFileBackend extends FileBackendStore {
if ( empty( $params['allowOB'] ) ) {
// Cancel output buffering and gzipping if set
- call_user_func( $this->obResetFunc );
+ ( $this->obResetFunc )();
}
$handle = fopen( 'php://output', 'wb' );
@@ -1317,7 +1317,7 @@ class SwiftFileBackend extends FileBackendStore {
foreach ( $httpReqs as $index => $httpReq ) {
// Run the callback for each request of this operation
$callback = $fileOpHandles[$index]->callback;
- call_user_func_array( $callback, [ $httpReq, $statuses[$index] ] );
+ $callback( $httpReq, $statuses[$index] );
// On failure, abort all remaining requests for this operation
// (e.g. abort the DELETE request if the COPY request fails for a move)
if ( !$statuses[$index]->isOK() ) {
diff --git a/includes/libs/jsminplus.php b/includes/libs/jsminplus.php
index e3c2d75863..08e9d690db 100644
--- a/includes/libs/jsminplus.php
+++ b/includes/libs/jsminplus.php
@@ -909,7 +909,7 @@ class JSParser
}
else
{
- $n->setup = $n2 ? $n2 : null;
+ $n->setup = $n2 ?: null;
$this->t->mustMatch(OP_SEMICOLON);
$n->condition = $this->t->peek() == OP_SEMICOLON ? null : $this->Expression($x);
$this->t->mustMatch(OP_SEMICOLON);
@@ -1656,7 +1656,7 @@ class JSNode
{
if ($token = $t->currentToken())
{
- $this->type = $type ? $type : $token->type;
+ $this->type = $type ?: $token->type;
$this->value = $token->value;
$this->lineno = $token->lineno;
$this->start = $token->start;
@@ -1752,7 +1752,7 @@ class JSTokenizer
public function init($source, $filename = '', $lineno = 1)
{
$this->source = $source;
- $this->filename = $filename ? $filename : '[inline]';
+ $this->filename = $filename ?: '[inline]';
$this->lineno = $lineno;
$this->cursor = 0;
diff --git a/includes/libs/lockmanager/DBLockManager.php b/includes/libs/lockmanager/DBLockManager.php
index 564616dd97..aec9f25b9f 100644
--- a/includes/libs/lockmanager/DBLockManager.php
+++ b/includes/libs/lockmanager/DBLockManager.php
@@ -82,7 +82,7 @@ abstract class DBLockManager extends QuorumLockManager {
$this->lockExpiry = $config['lockExpiry'];
} else {
$met = ini_get( 'max_execution_time' );
- $this->lockExpiry = $met ? $met : 60; // use some sane amount if 0
+ $this->lockExpiry = $met ?: 60; // use some sane amount if 0
}
$this->safeDelay = ( $this->lockExpiry <= 0 )
? 60 // pick a safe-ish number to match DB timeout default
diff --git a/includes/libs/lockmanager/MemcLockManager.php b/includes/libs/lockmanager/MemcLockManager.php
index ebd72de894..f1f749faa0 100644
--- a/includes/libs/lockmanager/MemcLockManager.php
+++ b/includes/libs/lockmanager/MemcLockManager.php
@@ -89,7 +89,7 @@ class MemcLockManager extends QuorumLockManager {
$memc = $this->getCache( $lockSrv );
// List of affected paths
- $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+ $paths = array_merge( ...array_values( $pathsByType ) );
$paths = array_unique( $paths );
// List of affected lock record keys
$keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
@@ -164,7 +164,7 @@ class MemcLockManager extends QuorumLockManager {
$memc = $this->getCache( $lockSrv );
// List of affected paths
- $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+ $paths = array_merge( ...array_values( $pathsByType ) );
$paths = array_unique( $paths );
// List of affected lock record keys
$keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
diff --git a/includes/libs/lockmanager/RedisLockManager.php b/includes/libs/lockmanager/RedisLockManager.php
index ea9dde7f2a..a624f0a971 100644
--- a/includes/libs/lockmanager/RedisLockManager.php
+++ b/includes/libs/lockmanager/RedisLockManager.php
@@ -76,7 +76,7 @@ class RedisLockManager extends QuorumLockManager {
protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
$status = StatusValue::newGood();
- $pathList = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+ $pathList = array_merge( ...array_values( $pathsByType ) );
$server = $this->lockServers[$lockSrv];
$conn = $this->redisPool->getConnection( $server, $this->logger );
@@ -171,7 +171,7 @@ LUA;
protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
$status = StatusValue::newGood();
- $pathList = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+ $pathList = array_merge( ...array_values( $pathsByType ) );
$server = $this->lockServers[$lockSrv];
$conn = $this->redisPool->getConnection( $server, $this->logger );
diff --git a/includes/libs/mime/IEContentAnalyzer.php b/includes/libs/mime/IEContentAnalyzer.php
index e9fb11f7a8..802ed2decb 100644
--- a/includes/libs/mime/IEContentAnalyzer.php
+++ b/includes/libs/mime/IEContentAnalyzer.php
@@ -500,13 +500,13 @@ class IEContentAnalyzer {
< ( $counters['ctrl'] + $counters['high'] ) * 16
) {
$kindOfBinary = true;
- $type = $binaryType ? $binaryType : $textType;
+ $type = $binaryType ?: $textType;
if ( $type === false ) {
$type = 'application/octet-stream';
}
} else {
$kindOfBinary = false;
- $type = $textType ? $textType : $binaryType;
+ $type = $textType ?: $binaryType;
if ( $type === false ) {
$type = 'text/plain';
}
diff --git a/includes/libs/objectcache/CachedBagOStuff.php b/includes/libs/objectcache/CachedBagOStuff.php
index ae434c1738..dbab593915 100644
--- a/includes/libs/objectcache/CachedBagOStuff.php
+++ b/includes/libs/objectcache/CachedBagOStuff.php
@@ -87,11 +87,11 @@ class CachedBagOStuff extends HashBagOStuff {
}
public function makeKey( $class, $component = null ) {
- return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
+ return $this->backend->makeKey( ...func_get_args() );
}
public function makeGlobalKey( $class, $component = null ) {
- return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
+ return $this->backend->makeGlobalKey( ...func_get_args() );
}
// These just call the backend (tested elsewhere)
diff --git a/includes/libs/objectcache/MultiWriteBagOStuff.php b/includes/libs/objectcache/MultiWriteBagOStuff.php
index b03052267a..edd5fbca19 100644
--- a/includes/libs/objectcache/MultiWriteBagOStuff.php
+++ b/includes/libs/objectcache/MultiWriteBagOStuff.php
@@ -195,16 +195,15 @@ class MultiWriteBagOStuff extends BagOStuff {
if ( $i == 0 || !$asyncWrites ) {
// First store or in sync mode: write now and get result
- if ( !call_user_func_array( [ $cache, $method ], $args ) ) {
+ if ( !$cache->$method( ...$args ) ) {
$ret = false;
}
} else {
// Secondary write in async mode: do not block this HTTP request
$logger = $this->logger;
- call_user_func(
- $this->asyncHandler,
+ ( $this->asyncHandler )(
function () use ( $cache, $method, $args, $logger ) {
- if ( !call_user_func_array( [ $cache, $method ], $args ) ) {
+ if ( !$cache->$method( ...$args ) ) {
$logger->warning( "Async $method op failed" );
}
}
@@ -235,10 +234,10 @@ class MultiWriteBagOStuff extends BagOStuff {
}
public function makeKey( $class, $component = null ) {
- return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
+ return $this->caches[0]->makeKey( ...func_get_args() );
}
public function makeGlobalKey( $class, $component = null ) {
- return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
+ return $this->caches[0]->makeGlobalKey( ...func_get_args() );
}
}
diff --git a/includes/libs/objectcache/WANObjectCache.php b/includes/libs/objectcache/WANObjectCache.php
index 97e0456e42..927a1e30b1 100644
--- a/includes/libs/objectcache/WANObjectCache.php
+++ b/includes/libs/objectcache/WANObjectCache.php
@@ -1603,7 +1603,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
* @since 1.27
*/
public function makeKey( $class, $component = null ) {
- return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
+ return $this->cache->makeKey( ...func_get_args() );
}
/**
@@ -1614,7 +1614,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
* @since 1.27
*/
public function makeGlobalKey( $class, $component = null ) {
- return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
+ return $this->cache->makeGlobalKey( ...func_get_args() );
}
/**
diff --git a/includes/libs/rdbms/database/DBConnRef.php b/includes/libs/rdbms/database/DBConnRef.php
index dedf6eab98..b414a2a02a 100644
--- a/includes/libs/rdbms/database/DBConnRef.php
+++ b/includes/libs/rdbms/database/DBConnRef.php
@@ -46,7 +46,7 @@ class DBConnRef implements IDatabase {
$this->conn = $this->lb->getConnection( $db, $groups, $wiki, $flags );
}
- return call_user_func_array( [ $this->conn, $name ], $arguments );
+ return $this->conn->$name( ...$arguments );
}
public function getServerInfo() {
diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php
index 16e654fe7c..57e5907a52 100644
--- a/includes/libs/rdbms/database/Database.php
+++ b/includes/libs/rdbms/database/Database.php
@@ -1214,13 +1214,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
$startTime = microtime( true );
if ( $this->profiler ) {
- call_user_func( [ $this->profiler, 'profileIn' ], $queryProf );
+ $this->profiler->profileIn( $queryProf );
}
$this->affectedRowCount = null;
$ret = $this->doQuery( $commentedSql );
$this->affectedRowCount = $this->affectedRows();
if ( $this->profiler ) {
- call_user_func( [ $this->profiler, 'profileOut' ], $queryProf );
+ $this->profiler->profileOut( $queryProf );
}
$queryRuntime = max( microtime( true ) - $startTime, 0.0 );
@@ -3230,7 +3230,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
$e = null;
do {
try {
- $retVal = call_user_func_array( $function, $args );
+ $retVal = $function( ...$args );
break;
} catch ( DBQueryError $e ) {
if ( $this->wasDeadlock() ) {
@@ -3310,7 +3310,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
// No transaction is active nor will start implicitly, so make one for this callback
$this->startAtomic( __METHOD__, self::ATOMIC_CANCELABLE );
try {
- call_user_func( $callback, $this );
+ $callback( $this );
$this->endAtomic( __METHOD__ );
} catch ( Exception $e ) {
$this->cancelAtomic( __METHOD__ );
@@ -3486,9 +3486,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
try {
++$count;
list( $phpCallback ) = $callback;
- call_user_func( $phpCallback, $this );
+ $phpCallback( $this );
} catch ( Exception $ex ) {
- call_user_func( $this->errorLogger, $ex );
+ $this->errorLogger( $ex );
$e = $e ?: $ex;
}
}
@@ -3522,7 +3522,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
try {
$phpCallback( $trigger, $this );
} catch ( Exception $ex ) {
- call_user_func( $this->errorLogger, $ex );
+ ( $this->errorLogger )( $ex );
$e = $e ?: $ex;
}
}
@@ -3723,7 +3723,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
) {
$sectionId = $this->startAtomic( $fname, $cancelable );
try {
- $res = call_user_func_array( $callback, [ $this, $fname ] );
+ $res = $callback( $this, $fname );
} catch ( Exception $e ) {
$this->cancelAtomic( $fname, $sectionId );
@@ -4249,7 +4249,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
$cmd = $this->replaceVars( $cmd );
if ( $inputCallback ) {
- $callbackResult = call_user_func( $inputCallback, $cmd );
+ $callbackResult = $inputCallback( $cmd );
if ( is_string( $callbackResult ) || !$callbackResult ) {
$cmd = $callbackResult;
@@ -4260,7 +4260,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
$res = $this->query( $cmd, $fname );
if ( $resultCallback ) {
- call_user_func( $resultCallback, $res, $this );
+ $resultCallback( $res, $this );
}
if ( false === $res ) {
diff --git a/includes/libs/rdbms/database/DatabaseSqlite.php b/includes/libs/rdbms/database/DatabaseSqlite.php
index 2125c70fd5..4b925e6413 100644
--- a/includes/libs/rdbms/database/DatabaseSqlite.php
+++ b/includes/libs/rdbms/database/DatabaseSqlite.php
@@ -865,7 +865,7 @@ class DatabaseSqlite extends Database {
$args = func_get_args();
$function = array_shift( $args );
- return call_user_func_array( $function, $args );
+ return $function( ...$args );
}
/**
diff --git a/includes/libs/rdbms/lbfactory/LBFactory.php b/includes/libs/rdbms/lbfactory/LBFactory.php
index 52c2df7a26..130a097c78 100644
--- a/includes/libs/rdbms/lbfactory/LBFactory.php
+++ b/includes/libs/rdbms/lbfactory/LBFactory.php
@@ -202,7 +202,7 @@ abstract class LBFactory implements ILBFactory {
protected function forEachLBCallMethod( $methodName, array $args = [] ) {
$this->forEachLB(
function ( ILoadBalancer $loadBalancer, $methodName, array $args ) {
- call_user_func_array( [ $loadBalancer, $methodName ], $args );
+ $loadBalancer->$methodName( ...$args );
},
[ $methodName, $args ]
);
@@ -650,14 +650,14 @@ abstract class LBFactory implements ILBFactory {
/**
* @param string $value Possible result of LBFactory::makeCookieValueFromCPIndex()
- * @param int $minTimestamp Lowest UNIX timestamp of non-expired values (if present)
+ * @param int $minTimestamp Lowest UNIX timestamp that a non-expired value can have
* @return array (index: int or null, clientId: string or null)
* @since 1.32
*/
public static function getCPInfoFromCookieValue( $value, $minTimestamp ) {
static $placeholder = [ 'index' => null, 'clientId' => null ];
- if ( !preg_match( '/^(\d+)(?:@(\d+))?(?:#([0-9a-f]{32}))?$/', $value, $m ) ) {
+ if ( !preg_match( '/^(\d+)@(\d+)#([0-9a-f]{32})$/', $value, $m ) ) {
return $placeholder; // invalid
}
diff --git a/includes/libs/rdbms/lbfactory/LBFactoryMulti.php b/includes/libs/rdbms/lbfactory/LBFactoryMulti.php
index cfa26479bb..30074eca27 100644
--- a/includes/libs/rdbms/lbfactory/LBFactoryMulti.php
+++ b/includes/libs/rdbms/lbfactory/LBFactoryMulti.php
@@ -422,10 +422,10 @@ class LBFactoryMulti extends LBFactory {
*/
public function forEachLB( $callback, array $params = [] ) {
foreach ( $this->mainLBs as $lb ) {
- call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+ $callback( $lb, ...$params );
}
foreach ( $this->extLBs as $lb ) {
- call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+ $callback( $lb, ...$params );
}
}
}
diff --git a/includes/libs/rdbms/lbfactory/LBFactorySimple.php b/includes/libs/rdbms/lbfactory/LBFactorySimple.php
index 0d7b812da7..6a6bb8d17a 100644
--- a/includes/libs/rdbms/lbfactory/LBFactorySimple.php
+++ b/includes/libs/rdbms/lbfactory/LBFactorySimple.php
@@ -149,10 +149,10 @@ class LBFactorySimple extends LBFactory {
*/
public function forEachLB( $callback, array $params = [] ) {
if ( isset( $this->mainLB ) ) {
- call_user_func_array( $callback, array_merge( [ $this->mainLB ], $params ) );
+ $callback( $this->mainLB, ...$params );
}
foreach ( $this->extLBs as $lb ) {
- call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+ $callback( $lb, ...$params );
}
}
}
diff --git a/includes/libs/rdbms/lbfactory/LBFactorySingle.php b/includes/libs/rdbms/lbfactory/LBFactorySingle.php
index 587ab23c02..2c1a782a53 100644
--- a/includes/libs/rdbms/lbfactory/LBFactorySingle.php
+++ b/includes/libs/rdbms/lbfactory/LBFactorySingle.php
@@ -103,7 +103,7 @@ class LBFactorySingle extends LBFactory {
*/
public function forEachLB( $callback, array $params = [] ) {
if ( isset( $this->lb ) ) { // may not be set during _destruct()
- call_user_func_array( $callback, array_merge( [ $this->lb ], $params ) );
+ $callback( $this->lb, ...$params );
}
}
}
diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php
index 221bca4269..6b271a7708 100644
--- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php
+++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php
@@ -864,7 +864,7 @@ class LoadBalancer implements ILoadBalancer {
$this->connLogger->debug( __METHOD__ . ': calling initLB() before first connection.' );
// Load any "waitFor" positions before connecting so that doWait() is triggered
$this->connectionAttempted = true;
- call_user_func( $this->chronologyCallback, $this );
+ ( $this->chronologyCallback )( $this );
}
// Check if an auto-commit connection is being requested. If so, it will not reuse the
@@ -1370,7 +1370,7 @@ class LoadBalancer implements ILoadBalancer {
try {
$conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
} catch ( DBError $e ) {
- call_user_func( $this->errorLogger, $e );
+ ( $this->errorLogger )( $e );
$failures[] = "{$conn->getServer()}: {$e->getMessage()}";
}
}
@@ -1723,8 +1723,7 @@ class LoadBalancer implements ILoadBalancer {
foreach ( $this->conns as $connsByServer ) {
foreach ( $connsByServer as $serverConns ) {
foreach ( $serverConns as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}
@@ -1736,8 +1735,7 @@ class LoadBalancer implements ILoadBalancer {
if ( isset( $connsByServer[$masterIndex] ) ) {
/** @var IDatabase $conn */
foreach ( $connsByServer[$masterIndex] as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}
@@ -1750,8 +1748,7 @@ class LoadBalancer implements ILoadBalancer {
continue; // skip master
}
foreach ( $serverConns as $conn ) {
- $mergedParams = array_merge( [ $conn ], $params );
- call_user_func_array( $callback, $mergedParams );
+ $callback( $conn, ...$params );
}
}
}
diff --git a/includes/libs/redis/RedisConnRef.php b/includes/libs/redis/RedisConnRef.php
index ede35fa2ee..bbcb267791 100644
--- a/includes/libs/redis/RedisConnRef.php
+++ b/includes/libs/redis/RedisConnRef.php
@@ -133,10 +133,10 @@ class RedisConnRef implements LoggerAwareInterface {
private function tryCall( $method, $arguments ) {
$this->conn->clearLastError();
try {
- $res = call_user_func_array( [ $this->conn, $method ], $arguments );
+ $res = $this->conn->$method( ...$arguments );
$authError = $this->checkAuthentication();
if ( $authError === self::AUTH_ERROR_TEMPORARY ) {
- $res = call_user_func_array( [ $this->conn, $method ], $arguments );
+ $res = $this->conn->$method( ...$arguments );
}
if ( $authError === self::AUTH_ERROR_PERMANENT ) {
throw new RedisException( "Failure reauthenticating to Redis." );
diff --git a/includes/linker/LinkRenderer.php b/includes/linker/LinkRenderer.php
index 87d7e0a4a7..d096b001ea 100644
--- a/includes/linker/LinkRenderer.php
+++ b/includes/linker/LinkRenderer.php
@@ -204,7 +204,7 @@ class LinkRenderer {
$realHtml = $html = null;
}
if ( !Hooks::run( 'LinkBegin',
- [ $dummy, $title, &$html, &$extraAttribs, &$query, &$options, &$ret ] )
+ [ $dummy, $title, &$html, &$extraAttribs, &$query, &$options, &$ret ], '1.28' )
) {
return $ret;
}
@@ -373,7 +373,7 @@ class LinkRenderer {
$title = Title::newFromLinkTarget( $target );
$options = $this->getLegacyOptions( $isKnown );
if ( !Hooks::run( 'LinkEnd',
- [ $dummy, $title, $options, &$html, &$attribs, &$ret ] )
+ [ $dummy, $title, $options, &$html, &$attribs, &$ret ], '1.28' )
) {
return $ret;
}
diff --git a/includes/logging/LogEventsList.php b/includes/logging/LogEventsList.php
index 9e4a630bd0..40498cd558 100644
--- a/includes/logging/LogEventsList.php
+++ b/includes/logging/LogEventsList.php
@@ -553,7 +553,7 @@ class LogEventsList extends ContextSource {
}
$permissionlist = implode( ', ', $permissions );
wfDebug( "Checking for $permissionlist due to $field match on $bitfield\n" );
- return call_user_func_array( [ $user, 'isAllowedAny' ], $permissions );
+ return $user->isAllowedAny( ...$permissions );
}
return true;
}
diff --git a/includes/logging/TagLogFormatter.php b/includes/logging/TagLogFormatter.php
index 230d13b60b..8458e0b40a 100644
--- a/includes/logging/TagLogFormatter.php
+++ b/includes/logging/TagLogFormatter.php
@@ -30,6 +30,45 @@
* @since 1.25
*/
class TagLogFormatter extends LogFormatter {
+
+ protected function getMessageParameters() {
+ $params = parent::getMessageParameters();
+
+ $isRevLink = !empty( $params[3] );
+ if ( $isRevLink ) {
+ $id = $params[3];
+ $target = $this->entry->getTarget();
+ $query = [
+ 'oldid' => $id,
+ 'diff' => 'prev'
+ ];
+ } else {
+ $id = $params[4];
+ $target = SpecialPage::getTitleValueFor( 'Log' );
+ $query = [
+ 'logid' => $id,
+ ];
+ }
+
+ $formattedNumber = $this->context->getLanguage()->formatNum( $id, true );
+ if ( $this->plaintext ) {
+ $link = $formattedNumber;
+ } elseif ( !$isRevLink || $target->exists() ) {
+ $link = $this->getLinkRenderer()->makeKnownLink(
+ $target, $formattedNumber, [], $query );
+ } else {
+ $link = htmlspecialchars( $formattedNumber );
+ }
+
+ if ( $isRevLink ) {
+ $params[3] = Message::rawParam( $link );
+ } else {
+ $params[4] = Message::rawParam( $link );
+ }
+
+ return $params;
+ }
+
protected function getMessageKey() {
$key = parent::getMessageKey();
$params = $this->getMessageParameters();
@@ -50,4 +89,5 @@ class TagLogFormatter extends LogFormatter {
return $key;
}
+
}
diff --git a/includes/media/BitmapHandler.php b/includes/media/BitmapHandler.php
index cda037c16d..e2d32cfbe1 100644
--- a/includes/media/BitmapHandler.php
+++ b/includes/media/BitmapHandler.php
@@ -228,7 +228,7 @@ class BitmapHandler extends TransformationalImageHandler {
$rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
- $cmd = call_user_func_array( 'wfEscapeShellArg', array_merge(
+ $cmd = wfEscapeShellArg( ...array_merge(
[ $wgImageMagickConvertCommand ],
$quality,
// Specify white background color, will be used for transparent images
@@ -449,7 +449,7 @@ class BitmapHandler extends TransformationalImageHandler {
return $this->getMediaTransformError( $params, $errMsg );
}
- $src_image = call_user_func( $loader, $params['srcPath'] );
+ $src_image = $loader( $params['srcPath'] );
$rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ?
$this->getRotation( $image ) :
@@ -489,7 +489,7 @@ class BitmapHandler extends TransformationalImageHandler {
if ( $useQuality && isset( $params['quality'] ) ) {
$funcParams[] = $params['quality'];
}
- call_user_func_array( $saveType, $funcParams );
+ $saveType( ...$funcParams );
imagedestroy( $dst_image );
imagedestroy( $src_image );
diff --git a/includes/media/SvgHandler.php b/includes/media/SvgHandler.php
index a589dbf3fb..a9c7b4fe89 100644
--- a/includes/media/SvgHandler.php
+++ b/includes/media/SvgHandler.php
@@ -291,12 +291,16 @@ class SvgHandler extends ImageHandler {
if ( is_array( $wgSVGConverters[$wgSVGConverter] ) ) {
// This is a PHP callable
$func = $wgSVGConverters[$wgSVGConverter][0];
- $args = array_merge( [ $srcPath, $dstPath, $width, $height, $lang ],
- array_slice( $wgSVGConverters[$wgSVGConverter], 1 ) );
if ( !is_callable( $func ) ) {
throw new MWException( "$func is not callable" );
}
- $err = call_user_func_array( $func, $args );
+ $err = $func( $srcPath,
+ $dstPath,
+ $width,
+ $height,
+ $lang,
+ ...array_slice( $wgSVGConverters[$wgSVGConverter], 1 )
+ );
$retval = (bool)$err;
} else {
// External command
diff --git a/includes/page/Article.php b/includes/page/Article.php
index c865d4ed53..1abf97470f 100644
--- a/includes/page/Article.php
+++ b/includes/page/Article.php
@@ -279,8 +279,8 @@ class Article implements Page {
if ( $this->mRevision !== null ) {
// Revision title doesn't match the page title given?
if ( $this->mPage->getId() != $this->mRevision->getPage() ) {
- $function = [ get_class( $this->mPage ), 'newFromID' ];
- $this->mPage = call_user_func( $function, $this->mRevision->getPage() );
+ $function = get_class( $this->mPage ). '::newFromID';
+ $this->mPage = $function( $this->mRevision->getPage() );
}
}
}
diff --git a/includes/parser/CoreParserFunctions.php b/includes/parser/CoreParserFunctions.php
index 7f6dbe530e..42d5db70b8 100644
--- a/includes/parser/CoreParserFunctions.php
+++ b/includes/parser/CoreParserFunctions.php
@@ -449,7 +449,7 @@ class CoreParserFunctions {
$parser->mOutput->setDisplayTitle( $text );
}
if ( $old !== false && $old !== $text && !$arg ) {
- $converter = $parser->getConverterLanguage()->getConverter();
+ $converter = $parser->getTargetLanguage()->getConverter();
return '' .
wfMessage( 'duplicate-displaytitle',
// Message should be parsed, but these params should only be escaped.
@@ -461,7 +461,7 @@ class CoreParserFunctions {
return '';
}
} else {
- $converter = $parser->getConverterLanguage()->getConverter();
+ $converter = $parser->getTargetLanguage()->getConverter();
$parser->getOutput()->addWarning(
wfMessage( 'restricted-displaytitle',
// Message should be parsed, but this param should only be escaped.
@@ -882,7 +882,7 @@ class CoreParserFunctions {
* Unicode-safe str_pad with the restriction that $length is forced to be <= 500
* @param Parser $parser
* @param string $string
- * @param int $length
+ * @param string $length
* @param string $padding
* @param int $direction
* @return string
@@ -897,7 +897,12 @@ class CoreParserFunctions {
}
# The remaining length to add counts down to 0 as padding is added
- $length = min( $length, 500 ) - mb_strlen( $string );
+ $length = min( (int)$length, 500 ) - mb_strlen( $string );
+ if ( $length <= 0 ) {
+ // Nothing to add
+ return $string;
+ }
+
# $finalPadding is just $padding repeated enough times so that
# mb_strlen( $string ) + mb_strlen( $finalPadding ) == $length
$finalPadding = '';
@@ -977,7 +982,7 @@ class CoreParserFunctions {
if ( $old === false || $old == $text || $arg ) {
return '';
} else {
- $converter = $parser->getConverterLanguage()->getConverter();
+ $converter = $parser->getTargetLanguage()->getConverter();
return '' .
wfMessage( 'duplicate-defaultsort',
// Message should be parsed, but these params should only be escaped.
diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php
index 8df5b5ba09..38bc95e802 100644
--- a/includes/parser/Parser.php
+++ b/includes/parser/Parser.php
@@ -460,11 +460,11 @@ class Parser {
|| isset( $this->mDoubleUnderscores['notitleconvert'] )
|| $this->mOutput->getDisplayTitle() !== false )
) {
- $convruletitle = $this->getConverterLanguage()->getConvRuleTitle();
+ $convruletitle = $this->getTargetLanguage()->getConvRuleTitle();
if ( $convruletitle ) {
$this->mOutput->setTitleText( $convruletitle );
} else {
- $titleText = $this->getConverterLanguage()->convertTitle( $title );
+ $titleText = $this->getTargetLanguage()->convertTitle( $title );
$this->mOutput->setTitleText( $titleText );
}
}
@@ -897,6 +897,7 @@ class Parser {
/**
* Get the language object for language conversion
+ * @deprecated since 1.32, just use getTargetLanguage()
* @return Language|null
*/
public function getConverterLanguage() {
@@ -1380,7 +1381,7 @@ class Parser {
# The position of the convert() call should not be changed. it
# assumes that the links are all replaced and the only thing left
# is the " . implode( '', $hits ) . "
";
diff --git a/includes/widget/search/SimpleSearchResultSetWidget.php b/includes/widget/search/SimpleSearchResultSetWidget.php
index d0c259fea2..248099ada0 100644
--- a/includes/widget/search/SimpleSearchResultSetWidget.php
+++ b/includes/widget/search/SimpleSearchResultSetWidget.php
@@ -56,12 +56,10 @@ class SimpleSearchResultSetWidget implements SearchResultSetWidget {
$iwResults = [];
foreach ( $resultSets as $resultSet ) {
- $result = $resultSet->next();
- while ( $result ) {
+ foreach ( $resultSet as $result ) {
if ( !$result->isBrokenTitle() ) {
$iwResults[$result->getTitle()->getInterwiki()][] = $result;
}
- $result = $resultSet->next();
}
}
diff --git a/languages/Language.php b/languages/Language.php
index 321d5f895a..d762a5752c 100644
--- a/languages/Language.php
+++ b/languages/Language.php
@@ -3152,7 +3152,7 @@ class Language {
return;
}
$this->mMagicHookDone = true;
- Hooks::run( 'LanguageGetMagic', [ &$this->mMagicExtensions, $this->getCode() ] );
+ Hooks::run( 'LanguageGetMagic', [ &$this->mMagicExtensions, $this->getCode() ], '1.16' );
}
/**
@@ -3208,7 +3208,7 @@ class Language {
$this->mExtendedSpecialPageAliases =
self::$dataCache->getItem( $this->mCode, 'specialPageAliases' );
Hooks::run( 'LanguageGetSpecialPageAliases',
- [ &$this->mExtendedSpecialPageAliases, $this->getCode() ] );
+ [ &$this->mExtendedSpecialPageAliases, $this->getCode() ], '1.16' );
}
return $this->mExtendedSpecialPageAliases;
@@ -4321,13 +4321,18 @@ class Language {
* the "raw" tag (-{R| }-) to prevent conversion.
*
* This function is called "markNoConversion" for historical
- * reasons.
+ * reasons *BUT DIFFERS SIGNIFICANTLY* from
+ * LanguageConverter::markNoConversion(), with which it is easily
+ * confused.
*
* @param string $text Text to be used for external link
* @param bool $noParse Wrap it without confirming it's a real URL first
* @return string The tagged text
+ * @deprecated since 1.32, use LanguageConverter::markNoConversion()
+ * instead.
*/
public function markNoConversion( $text, $noParse = false ) {
+ wfDeprecated( __METHOD__, '1.32' );
// Excluding protocal-relative URLs may avoid many false positives.
if ( $noParse || preg_match( '/^(?:' . wfUrlProtocolsWithoutProtRel() . ')/', $text ) ) {
return $this->mConverter->markNoConversion( $text );
diff --git a/languages/data/Names.php b/languages/data/Names.php
index af844ee5e3..3a96283fc6 100644
--- a/languages/data/Names.php
+++ b/languages/data/Names.php
@@ -469,6 +469,7 @@ class Names {
'yue' => 'ç²µèª', # Cantonese
'za' => 'Vahcuengh', # Zhuang
'zea' => 'Zeêuws', # Zeeuws/Zeaws
+ 'zgh' => 'âµâ´°âµâ´°âµ£âµâµâµ âµâ´°âµâ´°âµ¡â´°âµ¢âµ', # Moroccan Amazigh (multiple scripts - defaults to Neo-Tifinagh)
'zh' => 'ä¸æ', # (ZhÅng Wén) - Chinese
'zh-classical' => 'æè¨', # Classical Chinese/Literary Chinese -- (see T10217)
'zh-cn' => "ä¸æï¼ä¸å½å¤§éï¼\u{200E}", # Chinese (PRC)
diff --git a/languages/i18n/ace.json b/languages/i18n/ace.json
index e6a615e130..0ee0da0e2b 100644
--- a/languages/i18n/ace.json
+++ b/languages/i18n/ace.json
@@ -429,6 +429,11 @@
"retypenew": "Pasoë lom lageuëm barô:",
"resetpass_submit": "Atô lageuëm rahsia lheuëh nyan tamöng",
"changepassword-success": "Lageuëm rahsia droëneuh meuhasé geugantoë!",
+ "botpasswords-label-create": "Peugöt",
+ "botpasswords-label-update": "Peubarô",
+ "botpasswords-label-cancel": "Pubateue",
+ "botpasswords-label-delete": "Sampôh",
+ "botpasswords-label-resetpassword": "Atô keulayi lageuem rahsia",
"resetpass_forbidden": "Lageuëm rahsia h'an jeuët geugantoë",
"resetpass_forbidden-reason": "Lageuëm rahsia h`an jeuët geugantoë: $1",
"resetpass-no-info": "Droëneuh suwah neutamöng mangat jeuët neu'eu laman nyoë",
diff --git a/languages/i18n/be-tarask.json b/languages/i18n/be-tarask.json
index 363502595f..cd958cf07e 100644
--- a/languages/i18n/be-tarask.json
+++ b/languages/i18n/be-tarask.json
@@ -1532,11 +1532,11 @@
"filetype-unwanted-type": "«.$1» â Ð½ÐµÐ¿Ð°Ð¶Ð°Ð´Ð°Ð½Ñ ÑÑп Ñайла.\n{{PLURAL:$3|1=ÐажаданÑм ÑÑпам Ñайла зÑÑÑлÑеÑÑа|ÐажаданÑÐ¼Ñ ÑÑÐ¿Ð°Ð¼Ñ ÑÐ°Ð¹Ð»Ð°Ñ Ð·ÑÑÑлÑÑÑÑа:}} $2.",
"filetype-banned-type": "«.$1» â {{PLURAL:$4|1=забаÑÐ¾Ð½ÐµÐ½Ñ ÑÑп ÑайлаÑ|забаÑоненÑÑ ÑÑÐ¿Ñ ÑайлаÑ}}.\n{{PLURAL:$3|1=ÐÐ°Ð·Ð²Ð¾Ð»ÐµÐ½Ñ ÑÑп ÑайлаÑ|ÐазволенÑÑ ÑÑÐ¿Ñ ÑайлаÑ}}: $2.",
"filetype-missing": "Файл Ð½Ñ Ð¼Ð°Ðµ паÑÑÑÑнÑÐ½Ñ (напÑÑклад, «.jpg»).",
- "empty-file": "ÐаÑÐ»Ð°Ð½Ñ ÐÐ°Ð¼Ñ Ñайл пÑÑÑÑ.",
- "file-too-large": "ÐаÑÐ»Ð°Ð½Ñ ÐÐ°Ð¼Ñ Ñайл занадÑа вÑлÑкÑ.",
- "filename-tooshort": "Ðазва Ñайла занадÑа каÑоÑкаÑ.",
- "filetype-banned": "ÐÑÑÑ ÑÑп Ñайла забаÑоненÑ.",
- "verification-error": "ÐÑÑÑ Ñайл не пÑайÑÐ¾Ñ Ð²ÑÑÑÑÑкаÑÑÑ.",
+ "empty-file": "ÐаÑÐ»Ð°Ð½Ñ Ð²Ð°Ð¼Ñ Ñайл пÑÑÑÑ.",
+ "file-too-large": "ÐаÑÐ»Ð°Ð½Ñ Ð²Ð°Ð¼Ñ Ñайл занадÑа вÑлÑкÑ.",
+ "filename-tooshort": "Ðазва ÑÐ°Ð¹Ð»Ñ Ð·Ð°Ð½Ð°Ð´Ñа каÑоÑкаÑ.",
+ "filetype-banned": "ÐÑÑÑ ÑÑп ÑÐ°Ð¹Ð»Ñ Ð·Ð°Ð±Ð°ÑоненÑ.",
+ "verification-error": "ÐÑÑÑ Ñайл не пÑайÑÐ¾Ñ Ð¿ÑавеÑкÑ.",
"hookaborted": "ÐÑÐ°Ð¿Ð°Ð½Ð°Ð²Ð°Ð½Ð°Ñ ÐÐ°Ð¼Ñ Ð·Ñмена бÑла адÑ
ÑÐ»ÐµÐ½Ð°Ñ Ð°Ð¿ÑаÑоÑÑÑÑкам паÑÑÑÑнÑнÑ.",
"illegal-filename": "ÐÐµÐ´Ð°Ð·Ð²Ð¾Ð»ÐµÐ½Ð°Ñ Ð½Ð°Ð·Ð²Ð° Ñайла.",
"overwrite": "Ðамена ÑÑнÑÑÑага Ñайла забаÑоненаÑ.",
diff --git a/languages/i18n/be.json b/languages/i18n/be.json
index aaaf4ae162..f8c87a1739 100644
--- a/languages/i18n/be.json
+++ b/languages/i18n/be.json
@@ -621,7 +621,7 @@
"image_sample": "ÐапÑÑклад.jpg",
"image_tip": "Файл Ñ ÑÑкÑÑе",
"media_sample": "ÐапÑÑклад.ogg",
- "media_tip": "СпаÑÑлка на медÑÑ-Ñайл",
+ "media_tip": "СпаÑÑлка на медÑÑÑайл",
"sig_tip": "ÐÐ°Ñ Ð¿Ð¾Ð´Ð¿ÑÑ Ñ Ð°Ð´Ð·Ð½Ð°ÑÐ°Ð½Ñ ÑаÑ",
"hr_tip": "ÐаÑÑзанÑалÑÐ½Ð°Ñ ÑÑÑа (не злоÑжÑвайÑе гÑÑÑм)",
"summary": "ТлÑмаÑÑнне:",
diff --git a/languages/i18n/bg.json b/languages/i18n/bg.json
index 21fefcb921..ade421bb49 100644
--- a/languages/i18n/bg.json
+++ b/languages/i18n/bg.json
@@ -3693,5 +3693,13 @@
"edit-error-short": "ÐÑеÑка: $1",
"edit-error-long": "ÐÑеÑки:\n\n$1",
"revid": "веÑÑÐ¸Ñ $1",
- "pagedata-bad-title": "Ðевалидно заглавие: $1."
+ "pagedata-bad-title": "Ðевалидно заглавие: $1.",
+ "passwordpolicies": "ÐÑавила за паÑолиÑе",
+ "passwordpolicies-summary": "Това е ÑпиÑÑкÑÑ Ð½Ð° дейÑÑваÑиÑе пÑавила за паÑолиÑе на поÑÑебиÑелÑкиÑе гÑÑпи деÑиниÑани в Ñова Ñики.",
+ "passwordpolicies-policy-minimalpasswordlength": "ÐаÑолаÑа ÑÑÑбва да бÑде Ð¾Ñ Ð¿Ð¾Ð½Ðµ $1 {{PLURAL:$1|знак|знака}}",
+ "passwordpolicies-policy-minimumpasswordlengthtologin": "ÐаÑолаÑа ÑÑÑбва да бÑде поне $1 {{PLURAL:$1|знак|знака}} за да можеÑе да влезеÑе",
+ "passwordpolicies-policy-passwordcannotmatchusername": "ÐаÑолаÑа не може да бÑде ÑÑÑаÑа каÑо поÑÑебиÑелÑкоÑо име",
+ "passwordpolicies-policy-passwordcannotmatchblacklist": "ÐаÑолаÑа не може да ÑÑвпада Ñ Ð¿Ð°Ñоли Ð¾Ñ ÑеÑÐ½Ð¸Ñ ÑпиÑÑк",
+ "passwordpolicies-policy-maximalpasswordlength": "ÐаÑолаÑа ÑÑÑбва да бÑде по-малко Ð¾Ñ $1 {{PLURAL:$1|знак|знака}}",
+ "passwordpolicies-policy-passwordcannotbepopular": "ÐаÑолаÑа не може да бÑде {{PLURAL:$1|най-попÑлÑÑнаÑа Ñакава|Ð¾Ñ ÑпиÑÑка на най-попÑлÑÑниÑе $1 паÑоли}}"
}
diff --git a/languages/i18n/bn.json b/languages/i18n/bn.json
index 7e76d0e5ea..db59cc7272 100644
--- a/languages/i18n/bn.json
+++ b/languages/i18n/bn.json
@@ -787,6 +787,8 @@
"expansion-depth-exceeded-warning": "পাতাà¦à¦¿ à¦à¦à§à¦¸à§à¦ªà¦¶à¦¨ সà§à¦®à¦¾à¦¨à¦¾ à¦
তিà¦à§à¦°à¦® à¦à¦°à§à¦à§",
"parser-unstrip-loop-warning": "তà§à¦°à§à¦à¦¿à¦ªà§à¦°à§à¦£ লà§à¦ª à¦à§à¦à¦à§ পাà¦à¦¯à¦¼à¦¾ à¦à¦¿à¦¯à¦¼à§à¦à§",
"unstrip-depth-warning": "লà§à¦ª রিà¦à¦¾à¦°à¦¶à¦¨ সà§à¦®à¦¾à¦¨à¦¾ à¦
তিà¦à§à¦°à¦® à¦à¦°à§à¦à§ ($1)",
+ "unstrip-depth-category": "পাতাà¦à§à¦²à¦¿ যà§à¦à¦¾à¦¨à§ unstrip à¦à¦à§à¦°à¦¤à¦¾à¦° সà§à¦®à¦¾ à¦
তিà¦à§à¦°à¦® à¦à¦°à§à¦à§à¦¨",
+ "unstrip-size-warning": "Unstrip à¦à¦à¦¾à¦°à§à¦° সà§à¦®à¦¾ à¦
তিà¦à§à¦°à¦® à¦à¦°à§à¦à§ ($1)",
"converter-manual-rule-error": "মà§à¦¯à¦¾à¦¨à§à¦¯à¦¼à¦¾à¦² à¦à¦¾à¦·à¦¾ রà§à¦ªà¦¾à¦¨à§à¦¤à¦° নিয়মৠতà§à¦°à§à¦à¦¿ পাà¦à¦¯à¦¼à¦¾ à¦à¦¿à¦¯à¦¼à§à¦à§",
"undo-success": "সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦à¦¿ বাতিল à¦à¦°à¦¾ যাবà§à¥¤ à¦
নà§à¦à§à¦°à¦¹ à¦à¦°à§ নিà¦à§à¦° তà§à¦²à¦¨à¦¾à¦à¦¿ পরà§à¦à§à¦·à¦¾ à¦à¦°à§ দà§à¦à§à¦¨ ঠনিশà§à¦à¦¿à¦¤ à¦à¦°à§à¦¨ যৠà¦à¦à¦¾à¦ à¦à¦ªà¦¨à¦¿ à¦à¦°à¦¤à§ à¦à¦¾à¦¨, à¦à¦¬à¦ তারপর নিà¦à§à¦° সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦à§à¦²à¦¿ সà¦à¦°à¦à§à¦·à¦£ à¦à¦°à§ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦à¦¿à¦° বাতিল পà§à¦°à¦à§à¦°à¦¿à¦¯à¦¼à¦¾ সমাপà§à¦¤ à¦à¦°à§à¦¨à¥¤",
"undo-failure": "ঠসমà§à¦ªà¦¾à¦¦à¦¨à¦¾ মধà§à¦¯à¦¬à¦°à§à¦¤à§ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦¸à¦®à§à¦¹à§à¦° à¦à¦¾à¦°à¦£à§ পà§à¦°à§à¦¬à¦¾à¦¬à¦¸à§à¦¥à¦¾à¦¯à¦¼ ফিরিয়ৠনà§à¦à¦¯à¦¼à¦¾ যাবৠনা।",
@@ -1939,6 +1941,7 @@
"protectedtitles-submit": "শিরà§à¦¨à¦¾à¦® পà§à¦°à¦¦à¦°à§à¦¶à¦¨ à¦à¦°à§à¦¨",
"listusers": "বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦à¦¾à¦°à§à¦° তালিà¦à¦¾",
"listusers-editsonly": "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° à¦à¦®à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦à¦¾à¦°à§à¦¦à§à¦° দà§à¦à¦¾à¦ যাদà§à¦° à¦
বদান à¦à¦à§",
+ "listusers-temporarygroupsonly": "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° à¦
সà§à¦¥à¦¾à¦¯à¦¼à§ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦à¦¾à¦°à§ দলà§à¦° বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦à¦¾à¦°à§à¦¦à§à¦° দà§à¦à¦¾à¦¨",
"listusers-creationsort": "তà§à¦°à¦¿à¦° তারিঠà¦
নà§à¦¸à¦¾à¦°à§ সাà¦à¦¾à¦",
"listusers-desc": "বড় থà§à¦à§ à¦à§à¦ à¦à§à¦°à¦® à¦
নà§à¦¯à¦¾à¦¯à¦¼à§ সাà¦à¦¾à¦",
"usereditcount": "$1 {{PLURAL:$1|সমà§à¦ªà¦¾à¦¦à¦¨à¦¾|সমà§à¦ªà¦¾à¦¦à¦¨à¦¾}}",
diff --git a/languages/i18n/ca.json b/languages/i18n/ca.json
index 2ba5bc6d6c..fdadfc5438 100644
--- a/languages/i18n/ca.json
+++ b/languages/i18n/ca.json
@@ -96,7 +96,7 @@
"tog-watchlisthideminor": "Amaga les edicions menors de la llista de seguiment",
"tog-watchlisthideliu": "Amaga a la llista les edicions d'usuaris registrats",
"tog-watchlistreloadautomatically": "Recarrega la llista de seguiment automà ticament sempre que canviï un filtre (cal JavaScript)",
- "tog-watchlistunwatchlinks": "Afegeix enllaços directes per a seguir o deixar de seguir les entrades de la llista de seguiment (cal Javascript per a la funcionalitat d'alternar)",
+ "tog-watchlistunwatchlinks": "Afegeix marcadors directes ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) per a les pà gines en seguiment amb canvis (cal Javascript per a la funcionalitat d'alternar)",
"tog-watchlisthideanons": "Amaga a la llista les edicions d'usuaris anònims",
"tog-watchlisthidepatrolled": "Amaga edicions patrullades de la llista de seguiment",
"tog-watchlisthidecategorization": "Amaga la categorització de les pà gines",
@@ -410,6 +410,7 @@
"cascadeprotected": "Aquesta pà gina està protegida i no es pot modificar perquè està inclosa en {{PLURAL:$1|la següent pà gina, que té|les següents pà gines, que tenen}} activada l'opció de «protecció en cascada»:\n$2",
"namespaceprotected": "No teniu permÃs per a modificar pà gines en l'espai de noms '''$1'''.",
"customcssprotected": "No teniu permisos per editar la pà gina CSS perquè conté els parà metres personals d'un altre usuari.",
+ "customjsonprotected": "No teniu permisos per editar aquesta pà gina JSON perquè conté configuracions personals d'un altre usuari.",
"customjsprotected": "No teniu permisos per editar la pà gina JavaScript perquè conté els parà metres personals d'un altre usuari.",
"mycustomcssprotected": "No tens permÃs per editar aquesta pà gina CSS.",
"mycustomjsonprotected": "No teniu permisos per editar aquesta pà gina JSON.",
@@ -508,12 +509,12 @@
"wrongpasswordempty": "La contrasenya que s'ha introduït estava en blanc. Torneu-ho a provar.",
"passwordtooshort": "La contrasenya ha de tenir un mÃnim {{PLURAL:$1|d'un carà cter|de $1 carà cters}}.",
"passwordtoolong": "La contrasenya ha de tenir un mà xim {{PLURAL:$1|d'un carà cter|de $1 carà cters}}.",
- "passwordtoopopular": "No poden utilitzar-se contrasenyes d'ús habitual. Trieu-ne una més única.",
+ "passwordtoopopular": "No poden utilitzar-se contrasenyes d'ús habitual. Trieu una contrasenya que sigui més difÃcil d'endevinir.",
"password-name-match": "La contrasenya ha de ser diferent del vostre nom d'usuari.",
"password-login-forbidden": "No és permès d'utilitzar aquest nom d'usuari i contrasenya.",
"mailmypassword": "Restableix la contrasenya",
"passwordremindertitle": "Nova contrasenya temporal per al projecte {{SITENAME}}",
- "passwordremindertext": "Algú (vós mateix segurament, des de l'adreça IP $1) ha sol·licitat que us enviéssim una nova contrasenya per a iniciar la sessió en el projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si la vostra intenció era aquesta, ara haurÃeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquà a {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla contrasenya antiga.",
+ "passwordremindertext": "Algú (des de l'adreça IP $1) ha sol·licitat una nova contrasenya per al projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si la vostra intenció era aquesta, ara haurÃeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquà a {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla contrasenya antiga.",
"noemail": "No hi ha cap adreça electrònica registrada de l'usuari «$1».",
"noemailcreate": "Heu dâindicar una adreça electrònica và lida.",
"passwordsent": "S'ha enviat una nova contrasenya a l'adreça electrònica registrada per «$1».\nInicieu una sessió després que la rebeu.",
@@ -564,6 +565,7 @@
"botpasswords-existing": "Contrasenyes de bot existents",
"botpasswords-createnew": "Crea una contrasenya de bot nova",
"botpasswords-editexisting": "Edita una contrasenya de bot existent",
+ "botpasswords-label-needsreset": "(cal reiniciar la contrasenya)",
"botpasswords-label-appid": "Nom del bot:",
"botpasswords-label-create": "Crea",
"botpasswords-label-update": "Actualitza",
@@ -683,8 +685,8 @@
"subject-preview": "Previsualització de lâassumpte:",
"previewerrortext": "S'ha produït un error quan es provava de previsualitzar els canvis.",
"blockedtitle": "L'usuari està blocat",
- "blockedtext": "'''S'ha procedit al blocatge del vostre compte d'usuari o la vostra adreça IP.'''\n\nEl blocatge l'ha dut a terme l'usuari $1.\nEl motiu donat és ''$2''.\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Compte blocat: $7\n\nPodeu contactar amb $1 o un dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir-ho.\n\nTingueu en compte que no podeu fer servir el formulari d'enviament de missatges de correu electrònic a cap usuari, a menys que tingueu una adreça de correu và lida registrada a les vostres [[Special:Preferences|preferències d'usuari]] i no ho tingueu tampoc blocat.\n\nLa vostra adreça IP actual és $3, i el número d'identificació del blocatge és #$5.\nSi us plau, incloeu aquestes dades en totes les consultes que feu.",
- "autoblockedtext": "La vostra adreça IP ha estat blocada automà ticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:$2\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «Envia un missatge de correu electrònic a aquest usuari» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
+ "blockedtext": "S'ha procedit al blocatge del vostre compte d'usuari o la vostra adreça IP.\n\nEl blocatge l'ha dut a terme l'usuari $1.\nEl motiu donat és $2.\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Compte blocat: $7\n\nPodeu contactar amb $1 o un dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir-ho.\n\nTingueu en compte que no podeu fer servir la funció «{{int:emailuser}}» a menys que tingueu una adreça de correu và lida registrada a les vostres [[Special:Preferences|preferències d'usuari]] i no ho tingueu tampoc blocat.\n\nLa vostra adreça IP actual és $3, i el número d'identificació del blocatge és #$5.\nSi us plau, incloeu aquestes dades en totes les consultes que feu.",
+ "autoblockedtext": "La vostra adreça IP ha estat blocada automà ticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:$2\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «{{int:emailuser}}» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
"systemblockedtext": "El vostre nom d'usuari o adreça IP ha estat blocada automà ticament pel MediaWiki.\nEl motiu donat és:\n\n:$2\n\n* Inici del blocatge: $8\n* Caducitat del blocatge: $6\n* Destinatari del blocatge: $7\n\nLa vostra adreça IP actual és $3.\nAfegiu les dades de més amunt en qualsevol consulta que feu al respecte.",
"blockednoreason": "no s'ha donat cap motiu",
"whitelistedittext": "Heu de $1 per modificar pà gines.",
@@ -707,6 +709,7 @@
"blocked-notice-logextract": "En aquests moments aquest compte d'usuari es troba blocat.\nPer més detalls, la darrera entrada del registre es mostra a continuació:",
"clearyourcache": "Nota: Després de desar, possiblement necessitareu refrescar la memòria cau del vostre navegador per a veure'n els canvis.\n* Firefox / Safari: Premeu Shift i alhora cliqueu el botó Actualitza, o pressioneu Ctrl+F5 o Ctrl+R (â+R en un Mac)\n* Google Chrome: Premeu Ctrl+Shift+R (â+Shift+R en un Mac)\n* Internet Explorer: Premeu Ctrl i alhora cliqueu a Actualitza o pressioneu Ctrl+F5\n* Opera: Aneu a Menú â Preferències (Opera â Preferències en un Mac) i llavors a Privadesa i seguretat â Neteja dades de navegació â Imatges i fitxers en memòria cau.",
"usercssyoucanpreview": "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou CSS abans de desar-lo.",
+ "userjsonyoucanpreview": "Consell: Utilitzeu el botó «{{int:showpreview}}» per provar el nou JSON abans de desar-lo.",
"userjsyoucanpreview": "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou JavaScript abans de desar-lo.",
"usercsspreview": "'''Recordeu que esteu previsualitzant el vostre CSS d'usuari.'''\n'''Encara no s'ha desat!'''",
"userjspreview": "'''Recordeu que només estau provant/previsualitzant el vostre JavaScript, encara no ho heu desat!'''",
@@ -739,7 +742,7 @@
"longpageerror": "'''Error: El text que heu introduït és {{PLURAL:$1|d'un kilobyte|de $1 kilobytes}} i sobrepassa el mà xim permès de {{PLURAL:$2|one kilobyte|$2 kilobytes}}.'''\nNo es pot desar.",
"readonlywarning": "AvÃs: La base de dades està blocada per manteniment, de manera que no podreu desar els canvis ara mateix.\nÃs possible que vulgueu copiar i enganxar el text en un arxiu de text i desar-ho més tard.\n\nL'administrador de sistema que l'ha blocada ha donat la següent explicació: $1",
"protectedpagewarning": "'''ATENCIÃ: Aquesta pà gina està protegida i només els usuaris amb drets d'administrador la poden modificar.\nA continuació es mostra la darrera entrada del registre com a referència:",
- "semiprotectedpagewarning": "'''AvÃs:''' Aquesta pà gina està blocada i només pot ser modificada per usuaris registrats.\nA continuació es mostra la darrera entrada del registre com a referència:",
+ "semiprotectedpagewarning": "AvÃs: Aquesta pà gina està blocada i només pot ser modificada per usuaris autoconfirmats.\nA continuació es mostra la darrera entrada del registre com a referència:",
"cascadeprotectedwarning": "Atenció: Aquesta pà gina està protegida de forma que només la poden modificar usuaris amb [[Special:ListGroupRights|permisos especÃfics]], ja que està inclosa a {{PLURAL:$1|la següent pà gina|les següents pà gines}} amb l'opció de «protecció en cascada» activada:",
"titleprotectedwarning": "'''ATENCIÃ: Aquesta pà gina està protegida de tal manera que es necessiten uns [[Special:ListGroupRights|drets especÃfics]] per a poder crear-la.'''\nA continuació es mostra la darrera entrada del registre com a referència:",
"templatesused": "Aquesta pà gina fa servir {{PLURAL:$1|la següent plantilla|les següents plantilles}}:",
@@ -801,6 +804,7 @@
"parser-template-loop-warning": "S'ha detectat un bucle de plantilla: [[$1]]",
"template-loop-category": "PÃ gines amb bucles de plantilla",
"template-loop-category-desc": "La pà gina conté un bucle de plantilles, és a dir, una plantilla que s'inclou a si mateixa recursivament.",
+ "template-loop-warning": "AvÃs: Aquesta pà gina crida [[:$1]] provocant un bucle de plantilles (una crida recursiva infinita).",
"parser-template-recursion-depth-warning": "S'ha excedit el lÃmit de recursivitat de plantilles ($1)",
"language-converter-depth-warning": "S'ha excedit el lÃmit de profunditat del convertidor d'idiomes ($1)",
"node-count-exceeded-category": "PÃ gines on s'ha excedit el recompte de nodes",
@@ -1051,8 +1055,8 @@
"stub-threshold-disabled": "Inhabilitat",
"recentchangesdays": "Dies a mostrar en els canvis recents:",
"recentchangesdays-max": "(mà xim $1 {{PLURAL:$1|dia|dies}})",
- "recentchangescount": "Nombre d'edicions a mostrar per defecte:",
- "prefs-help-recentchangescount": "Inclou els canvis recents, els historials de pà gines i els registres.",
+ "recentchangescount": "Nombre d'edicions a mostrar per defecte en canvis recents, historials de pà gines i registres:",
+ "prefs-help-recentchangescount": "Nombre mà xim: 1000",
"prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, aixà que no la compartiu.\nSi és necessari, [[Special:ResetTokens|la podeu restaurar]].",
"savedprefs": "Sâhan desat les vostres preferències.",
"savedrights": "S'han desat els grups d'usuari de {{GENDER:$1|$1}}.",
@@ -1073,6 +1077,7 @@
"timezoneregion-indian": "Oceà Ãndic",
"timezoneregion-pacific": "Oceà PacÃfic",
"allowemail": "Permet que altres usuaris m'enviïn missatges per correu electrònic",
+ "email-allow-new-users-label": "Permet correus electrònics d'usuaris novells",
"email-blacklist-label": "Prohibeix a aquests usuaris que m'enviïn correus electrònics:",
"prefs-searchoptions": "Cerca",
"prefs-namespaces": "Espais de noms",
@@ -1081,7 +1086,7 @@
"prefs-custom-css": "CSS personalitzat",
"prefs-custom-json": "JSON personalitzat",
"prefs-custom-js": "JS personalitzat",
- "prefs-common-config": "CSS/JS compartit per tots els skins:",
+ "prefs-common-config": "CSS/JSON/JavaScript compartit per a totes les aparences:",
"prefs-reset-intro": "Podeu usar aquesta pà gina per a restablir les vostres preferències als valors per defecte.\nNo es podrà desfer el canvi.",
"prefs-emailconfirm-label": "Confirmació de correu electrònic:",
"youremail": "Correu electrònic:",
@@ -1263,8 +1268,8 @@
"grant-createaccount": "Crea comptes",
"grant-createeditmovepage": "Crea, modifica i reanomena pà gines",
"grant-delete": "Suprimeix pà gines, revisions i entrades de registre",
- "grant-editinterface": "Modifica l'espai de noms MediaWiki i els CSS/JavaScript d'usuari",
- "grant-editmycssjs": "Modifiqueu el vostre CSS/JavaScript d'usuari",
+ "grant-editinterface": "Modifica l'espai de noms MediaWiki i els CSS/JSON/JavaScript d'usuari",
+ "grant-editmycssjs": "Modifiqueu el vostre CSS/JSON/JavaScript d'usuari",
"grant-editmyoptions": "Editeu les vostres preferències d'usuari",
"grant-editmywatchlist": "Modifica la llista de seguiment",
"grant-editpage": "Modifica les pà gines existents",
@@ -1517,7 +1522,7 @@
"recentchangeslinked-feed": "Canvis relacionats",
"recentchangeslinked-toolbox": "Canvis relacionats",
"recentchangeslinked-title": "Canvis relacionats amb «$1»",
- "recentchangeslinked-summary": "Introduïu un nom de pà gina per veure els canvis en les pà gines enllaçades des de o cap a aquesta pà gina (per veure els membres d'una categoria, introduïu Categoria:Nom de la categoria).\nEls canvis en pà gines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en negreta.",
+ "recentchangeslinked-summary": "Introduïu un nom de pà gina per veure els canvis en les pà gines enllaçades des de o cap a aquesta pà gina (per veure els membres d'una categoria, introduïu {{ns:category}}:Nom de la categoria).\nEls canvis en pà gines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en negreta.",
"recentchangeslinked-page": "Nom de la pà gina:",
"recentchangeslinked-to": "Mostra els canvis de les pà gines enllaçades amb la pà gina donada",
"recentchanges-page-added-to-category": "[[:$1]] afegida a la categoria",
@@ -3732,7 +3737,7 @@
"expandtemplates": "Expansió de plantilles",
"expand_templates_intro": "Aquesta pà gina especial expandeix de forma recursiva totes les plantilles d'un text donat.\nTambé expandeix les funcions sintà ctiques, com ara
, i les variables predefinides, com
—de fet, gairebé tot que estigui entre claus dobles.",
"expand_templates_title": "TÃtol per contextualitzar ({{FULLPAGENAME}}, etc):",
- "expand_templates_input": "El vostre text:",
+ "expand_templates_input": "Wikitext d'entrada:",
"expand_templates_output": "Resultat:",
"expand_templates_xml_output": "Sortida XML",
"expand_templates_html_output": "Sortida en HTML sense filtrar",
@@ -3744,7 +3749,7 @@
"expand_templates_preview": "Previsualitza",
"expand_templates_preview_fail_html": "Atès que {{SITENAME}} té HTML cru habilitat i s'ha produït una pèrdua de dades de la sessió, s'ha amagat la vista prèvia com a mesura de precaució contra atacs en JavaScript.\n\nSi això és un intent de previsualització legÃtim, torneu-ho a provar.\nSi encara no funciona, intenteu [[Special:UserLogout|finalitzar la sessió]] i comproveu si el vostre navegador permet galetes d'aquest lloc.",
"expand_templates_preview_fail_html_anon": "Atès que {{SITENAME}} té l'HTML cru habilitat i no heu iniciat una sessió, s'ha amagat la previsualització com a prevenció d'atacs en JavaScript.\n\nSi això és un intent de previsualització legÃtim, [[Special:UserLogin|inicieu una sessió]] i torneu-ho a provar.",
- "expand_templates_input_missing": "Cal que proporcioneu al menys algun text d'entrada.",
+ "expand_templates_input_missing": "Cal que proporcioneu al menys algun wikitext d'entrada.",
"pagelanguage": "Canvia l'idioma de la pà gina",
"pagelang-name": "PÃ gina",
"pagelang-language": "Idioma",
@@ -3952,5 +3957,10 @@
"gotointerwiki-external": "Esteu a punt dâabandonar {{SITENAME}} per a visitar [[$2]], un lloc web diferent.\n\n'''[$1 Continua a $1]'''",
"undelete-cantedit": "Com que no podeu editar aquesta pà gina, no en podeu desfer la supressió.",
"pagedata-title": "Dades de la pà gina",
- "pagedata-bad-title": "TÃtol no và lid: $1"
+ "pagedata-bad-title": "TÃtol no và lid: $1",
+ "passwordpolicies": "PolÃtiques de contrasenya",
+ "passwordpolicies-group": "Grup",
+ "passwordpolicies-policies": "PolÃtiques",
+ "passwordpolicies-policy-minimalpasswordlength": "La contrasenya ha de tenir un mÃnim {{PLURAL:$1|d'un carà cter|de $1 carà cters}}",
+ "passwordpolicies-policy-passwordcannotmatchusername": "La contrasenya no pot ser igual que el nom d'usuari"
}
diff --git a/languages/i18n/ce.json b/languages/i18n/ce.json
index 14deacc541..b703394d0d 100644
--- a/languages/i18n/ce.json
+++ b/languages/i18n/ce.json
@@ -558,7 +558,7 @@
"nowiki_sample": "ÐÑ
Ñза Ñ
ÓоÑÑаде Ñ
ийÑа оÑÑÑÑ Ð´Ð¾ÑÑ Ð¹Ð¾Ð·Ð°",
"nowiki_tip": "ТеÑгал Ñа бо вики-бáÑамÑ
lоÑÑоÑ",
"image_sample": "Example.jpg",
- "image_tip": "ЧоÑ
Ñ Ð¹Ð¾Ð»Ñ Ñайл",
+ "image_tip": "Файл ÑÑйиллаÑ",
"media_sample": "Example.ogg",
"media_tip": "Ð¥ÑажоÑг медиа-Ñайлан ÑÓе",
"sig_tip": "Ð¥Ñан кÑÑгÑаlÐ¾Ñ Ð°Ñ Ñ
lоÑÑина Ñ
ан",
@@ -688,6 +688,10 @@
"expansion-depth-exceeded-category": "СÑ
ÑаеллаÑан кÓоÑгалла ÑÓеÑ
даÑккÑ
ина агÓонаÑ",
"expansion-depth-exceeded-warning": "ÐгÓонгаÑ
Ñ ÑÑйиÑ
ÐºÐ°Ñ ÑÓеÑ
даÑккÑ
ина",
"parser-unstrip-loop-warning": "ÐÓаÑÓагÓанÑа pre каÑина",
+ "unstrip-depth-warning": "РекÑÑÑи ($1) доза ÑÓеÑ
даÑлла",
+ "unstrip-depth-category": "ÐÓоÑгалла ÑагÑÑ Ð¹Ð¾Ð»Ñ Ð°Ð³ÓонаÑ",
+ "unstrip-size-warning": "Unstrip ÑекÑÑÑи ($1) доза ÑÓеÑ
даÑлла",
+ "unstrip-size-category": "ÐÐ¸Ð»Ð³Ð°Ð»Ð´Ð°Ñ ÑагÑÑ Ð´Ð¾Ð»Ñ Ð°Ð³ÓонаÑ",
"undo-success": "ÐиÑйинаÑг а Ñlе ÑалаÑа мега. ÐеÑ
Ð°Ñ Ð´Ð¾, Ñ
Ñажа ÑÑ
ÑаÑеÑÑа йÑй баÑÑ
о, ÑеÑна Ñ
ила, баккÑалла иза Ñ
ийÑам бÑйÑе Ñ
ÑÑна безаÑг, ÑlакÑ
а Ñlе Ñаlайе «дlайазйе агlо», Ñ
ийÑам Ñ
lоÑÑа ба.",
"undo-failure": "ЮккÑеÑа Ñ
ийÑÐ°Ð¼Ð°Ñ Ð±Ð°Ñ
ÑнеÑ
Ñ Ð½Ð¸ÑÐ´Ð°Ñ ÑÑ
адаккÑ
а Ð¹Ð¸Ñ ÑÑ.",
"undo-norev": "ÐиÑÐ´Ð°Ñ ÑÑ
адаккÑ
а Ñало, иза доÑÑ Ð´ÐµÐ»Ð»Ð° Ñ Ð´ÓаÑÑккÑ
ина дела.",
@@ -1362,6 +1366,7 @@
"uploaddisabled": "ЧÑÑккÑ
Ð°Ñ Ð¼Ð°Ð³Ð¸Ð¹Ð½Ð° даÑ",
"copyuploaddisabled": "URL ÑÓеÑа ÑÑÑккÑ
Ð°Ñ Ð´Óадайина дÑ.",
"uploaddisabledtext": "Ð¤Ð°Ð¹Ð»Ð°Ñ ÑÑÑÑ
Ð°Ñ Ð´Óадайина дÑ.",
+ "uploaded-href-attribute-svg": "ÐлеменÑÐ°Ñ ÑÓеÑовжа (href) мега data: (Ñайл ÑÑйиллаÑ) ÑÓе, Ñ
ÑажоÑг http:// Ñ https:// Ñ ÑÑÐ°Ð³Ð¼ÐµÐ½Ñ (#, оÑÑ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ ÑÓеÑ
Ñ). ÐÑ
еÑÑ ÑлеменÑаÑна, маÑала <$1 $2=\"$3\">
.",
"uploadscriptednamespace": "Ð¥ÓокÑ
Ñ SVG-Ñайлан ÑÓеÑийн меÑÑиг нийÑа ÑÑ '
кÑ
оÑÑÑ Ð´Ð°Ð½ Ñайп\n
.",
"expand_templates_title": "ÐгÓона {{FULLPAGENAME}} коÑÑа кÑ
ин а:",
diff --git a/languages/i18n/cv.json b/languages/i18n/cv.json
index 35a0f30cea..3a3478c11f 100644
--- a/languages/i18n/cv.json
+++ b/languages/i18n/cv.json
@@ -1022,7 +1022,8 @@
"specialpages-group-media": "Ðедиа-маÑеÑиалÑемпе ÑÑлÑаÑÄÑÑем",
"specialpages-group-users": "Ð¥ÑÑÑÄнаканÑем ÑаÑа пÑаваÑем",
"specialpages-group-highuse": "ÐÑмай ÑÑÄ ÐºÑÑакан ÑÑÑаниÑÄÑем",
- "tag-list-wrapper": "([[Special:Tags|$1 меÑка]]: $2)",
+ "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Тег|ТегÑем}}]]: $2)",
+ "tags-title": "ТегÑем",
"compare-submit": "ТанлаÑÑаÑ",
"htmlform-selectorother-other": "УÑÄÑ
Ñ
и",
"htmlform-no": "ÃÑк",
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index fcf2e25721..ee098ddc6c 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -1400,7 +1400,7 @@
"rcfilters-savedqueries-rename": "Rename",
"rcfilters-savedqueries-setdefault": "Set as default",
"rcfilters-savedqueries-unsetdefault": "Remove as default",
- "rcfilters-savedqueries-remove": "Remove",
+ "rcfilters-savedqueries-remove": "Delete",
"rcfilters-savedqueries-new-name-label": "Name",
"rcfilters-savedqueries-new-name-placeholder": "Describe the purpose of the filter",
"rcfilters-savedqueries-apply-label": "Create filter",
@@ -1416,7 +1416,7 @@
"rcfilters-empty-filter": "No active filters. All contributions are shown.",
"rcfilters-filterlist-title": "Filters",
"rcfilters-filterlist-whatsthis": "How do these work?",
- "rcfilters-filterlist-feedbacklink": "Tell us what you think about these (new) filtering tools",
+ "rcfilters-filterlist-feedbacklink": "Tell us what you think about these filtering tools",
"rcfilters-highlightbutton-title": "Highlight results",
"rcfilters-highlightmenu-title": "Select a color",
"rcfilters-highlightmenu-help": "Select a color to highlight this property",
diff --git a/languages/i18n/eo.json b/languages/i18n/eo.json
index c7019d8833..6d77b1085a 100644
--- a/languages/i18n/eo.json
+++ b/languages/i18n/eo.json
@@ -891,7 +891,7 @@
"revdelete-edit-reasonlist": "Redakti kialojn por forigo",
"revdelete-offender": "AÅtoro de revizio:",
"suppressionlog": "Protokolo pri subigado",
- "suppressionlogtext": "Malsupre estas listo de forigoj kaj forbaroj pri enhavo kaÅita de administrantoj.\nRigardu la [[Special:BlockList|forbarliston]] por la listo de nune operaciaj forbaroj kaj forigoj.",
+ "suppressionlogtext": "Jen listo de forigoj kaj forbaroj pri enhavo kaÅita per administrantoj.\nVidi la [[Special:BlockList|forbarliston]] por la listo de forigoj kaj forbaroj aktuale operaciaj.",
"mergehistory": "Kunigi historiojn de paÄoj",
"mergehistory-header": "Äi tiu paÄo permesas al vi kunigi versiojn de la historio de unu fonta paÄo en pli novan paÄon.\nCertigu ke Äi tiu ÅanÄo tenos kontinuecon de la historia paÄo.",
"mergehistory-box": "Kunigi versiojn de du paÄoj:",
diff --git a/languages/i18n/eu.json b/languages/i18n/eu.json
index 4816efafb8..db373b5b9a 100644
--- a/languages/i18n/eu.json
+++ b/languages/i18n/eu.json
@@ -694,7 +694,7 @@
"explainconflict": "Zu orrialdea aldatzen hasi ondoren beste norbaitek ere aldaketak egin ditu.\nGoiko testu koadroan ikus daiteke orrialdeak uneotan duen edukia.\nZure aldaketak beheko testu koadroan ikus daitezke.\nZure testua dagoenarekin elkartu beharko duzu.\nOrrialdea gordetzeko erabakitzen duzun unean goiko koadroko edukia '''bakarrik''' gordeko da.",
"yourtext": "Zure testua",
"storedversion": "Gordetako bertsioa",
- "editingold": "'''KONTUZ: Artikulu honen bertsio zahar bat aldatzen ari zara. Gorde egiten baduzu, azkenengo aldaketa baino lehenagoko aldakuntzak, ezabatuak izango dira.'''",
+ "editingold": "KONTUZ: Artikulu honen bertsio zahar bat aldatzen ari zara. Gordetzen baduzu, bertsio hau baino geroago egindako aldaketa guztiak ezabatuko dira.",
"unicode-support-fail": "Zure nabigatzaileak Unicode onartzen ez duela dirudi. Orrialdeak editatu behar dira, beraz, edizioa ez da gorde.",
"yourdiff": "Ezberdintasunak",
"copyrightwarning": "Kontuan izan ezazu {{SITENAME}} webgunean egindako ekarpen guztiak $2 lizentziaren pean argitaratzen direla (xehetasunetarako, ikus $1). Zuk idatzitakoa libreki aldatua eta banatua izatea nahi ez baduzu, ez ezazu hemen jarri.
\nEra berean, hitzematen ari zara hau zuk zeuk idatzia dela, edo jabari publikotik nahiz askea den beste ituri batetik kopiatu duzula.\n'''Ez erabili copyright eskubideek babestutako lanik, baimenik gabe!'''",
diff --git a/languages/i18n/fa.json b/languages/i18n/fa.json
index 8f28907bd6..0d44d82952 100644
--- a/languages/i18n/fa.json
+++ b/languages/i18n/fa.json
@@ -433,7 +433,7 @@
"logouttext": "'''اکÙÙÙ Ø´Ù
ا ثبت خرÙج کردÙâاÛد.'''\nتÙج٠داشت٠باشÛد ک٠تا ØاÙظÙÙ ÙÙا٠Ù
رÙرگرتا٠را پاک ÙÚ©ÙÛØ¯Ø Ø¨Ø¹Ø¶Û Ø§Ø² صÙØات Ù
Ù
ک٠است ÙÙ
ÚÙا٠ب٠گÙÙÙâØ§Û ÙÙ
اÛØ´ ÛابÙد ک٠اÙگار Ùارد شدÙâاÛد.",
"cannotlogoutnow-title": "اÙا٠اÙ
کا٠خرÙج از ساÙ
اÙÙ ÙÛست",
"cannotlogoutnow-text": "در زÙ
ا٠استÙاد٠از $1 اÙ
کا٠خرÙج از ساÙ
اÙÙ ÙجÙد Ùدارد.",
- "welcomeuser": "$1 ب٠{{SITENAME}} Ø®ÙØ´âØ¢Ù
دÛد!",
+ "welcomeuser": "Ø®ÙشاÙ
دÛد $1!",
"welcomecreation-msg": "Øساب Ú©Ø§Ø±Ø¨Ø±Û Ø´Ù
ا اÛجاد شد٠است.\nÙراÙ
ÙØ´ ÙÚ©ÙÛد Ú©Ù [[Special:Preferences|ترجÛØات {{SITENAME}}]] Ø®Ùد را تغÛÛر دÙÛد.",
"yourname": "ÙاÙ
کاربرÛ:",
"userlogin-yourname": "ÙاÙ
کاربرÛ",
@@ -1919,7 +1919,7 @@
"unusedcategories": "ردÙâÙØ§Û Ø§Ø³ØªÙادÙâÙشدÙ",
"unusedimages": "پرÙÙدÙâÙØ§Û Ø§Ø³ØªÙادÙâÙشدÙ",
"wantedcategories": "ردÙâÙØ§Û Ù
Ùرد ÙÛاز",
- "wantedpages": "برگÙâÙØ§Û Ù
Ùرد ÙÛاز",
+ "wantedpages": "صÙØÙâÙØ§Û Ù
Ùرد ÙÛاز",
"wantedpages-summary": "ÙÙرست صÙØÙâÙØ§Û ÙاÙ
ÙجÙد با بÛشترÛÙ Ù¾ÛÙÙد ب٠آÙÙØ§Ø Ø¨Ù Ø§Ø³ØªØ«ÙØ§Û ØµÙØÙâÙاÛÛ Ú©Ù ÙÙØ· تغÛÛرÙ
سÛر ب٠آÙÙا دارÙد. Ø¨Ø±Ø§Û ÛÚ© ÙÙرست از صÙØÙâÙØ§Û ÙاÙ
ÙجÙد ک٠تغÛÛرÙ
سÛر ب٠آÙÙا دارÙØ¯Ø [[{{#special:BrokenRedirects}}|ÙÙرست تغÛÛرÙ
سÛرÙØ§Û Ø´Ú©Ø³ØªÙ]] را ببÛÙÛد.",
"wantedpages-badtitle": "عÙÙا٠ÙاÙ
جاز در Ù
جÙ
ÙعÙÙ ÙتاÛج: $1",
"wantedfiles": "پرÙÙدÙâÙØ§Û Ù
Ùرد ÙÛاز",
diff --git a/languages/i18n/fi.json b/languages/i18n/fi.json
index 2484110197..060a61b87a 100644
--- a/languages/i18n/fi.json
+++ b/languages/i18n/fi.json
@@ -1469,6 +1469,10 @@
"rcfilters-watchlist-showupdated": "Muutokset sivuihin, joilla et ole vieraillut sen jälkeen kun muutokset on tehty, on lihavoitu ja värimerkitty.",
"rcfilters-preference-label": "Piilota tuoreiden muutosten parannettu versio",
"rcfilters-preference-help": "Peruuttaa vuoden 2017 käyttöliittymän uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
+ "rcfilters-watchlist-preference-label": "Piilota tarkkailulistan parannettu versio",
+ "rcfilters-watchlist-preference-help": "Poistaa käytöstä vuoden 2017 ulkoasun uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
+ "rcfilters-filter-showlinkedfrom-option-label": "Sivut, joihin linkitetään valitulta sivulta",
+ "rcfilters-filter-showlinkedto-option-label": "Sivut, jotka linkittävät valitulle sivulle",
"rcfilters-target-page-placeholder": "Anna sivun nimi (tai luokka)",
"rcnotefrom": "Alla ovat muutokset $3, $4 lähtien. (Enintään $1 näytetään.)",
"rclistfromreset": "Tyhjennä ajankohdan valinta",
@@ -4034,9 +4038,13 @@
"pagedata-not-acceptable": "Vastaavaa muotoa ei löytynyt. Tuetut MIME-tyypit: $1",
"pagedata-bad-title": "Virheellinen otsikko: $1.",
"passwordpolicies": "Salasanakäytännöt",
+ "passwordpolicies-summary": "Tämä on luettelo käytössä olevista salasanakäytännöistä tämän wikin käyttäjäryhmille.",
"passwordpolicies-group": "Ryhmä",
"passwordpolicies-policies": "Käytännöt",
"passwordpolicies-policy-minimalpasswordlength": "Salasanan on oltava ainakin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä",
+ "passwordpolicies-policy-minimumpasswordlengthtologin": "Salasanassa on oltava vähintään $1 {{PLURAL:$1|merkki|merkkiä}} pystyäksesi kirjautumaan",
"passwordpolicies-policy-passwordcannotmatchusername": "Salasana ei voi olla sama kuin käyttäjänimi",
- "passwordpolicies-policy-maximalpasswordlength": "Salasanan on oltava vähemmän kuin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä"
+ "passwordpolicies-policy-passwordcannotmatchblacklist": "Salasana ei voi vastata mustalla listalla olevia salasanoja",
+ "passwordpolicies-policy-maximalpasswordlength": "Salasanan on oltava vähemmän kuin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä",
+ "passwordpolicies-policy-passwordcannotbepopular": "Salasana ei voi olla {{PLURAL:$1|suosittu salasana|$1 suositun salasanan listalla}}"
}
diff --git a/languages/i18n/fr.json b/languages/i18n/fr.json
index 4614b74f9d..d5590ef9aa 100644
--- a/languages/i18n/fr.json
+++ b/languages/i18n/fr.json
@@ -1603,6 +1603,7 @@
"rcfilters-preference-label": "Masquer la version améliorée des modifications récentes",
"rcfilters-preference-help": "Désactive la version 2017 de l'interface ainsi que de tous les outils ajoutés alors et depuis.",
"rcfilters-watchlist-preference-label": "Masquer la version améliorée de la liste de suivi",
+ "rcfilters-watchlist-preference-help": "Annuler la nouvelle conception de lâinterface 2017 et tous les outils ajoutés alors et depuis.",
"rcfilters-filter-showlinkedfrom-label": "Montrer les modifications des pages liées depuis",
"rcfilters-filter-showlinkedfrom-option-label": "Pages liées depuis la page sélectionnée",
"rcfilters-filter-showlinkedto-label": "Montrer les modifications des pages pointant vers",
diff --git a/languages/i18n/gcr.json b/languages/i18n/gcr.json
index 126208a5ca..af466660c4 100644
--- a/languages/i18n/gcr.json
+++ b/languages/i18n/gcr.json
@@ -141,7 +141,7 @@
"newwindow": "(Ka ouvri so kò andan roun nouvèl finèt)",
"cancel": "Anilé",
"moredotdotdot": "Plis...",
- "morenotlisted": "Sa lis pé sa enkonplèt",
+ "morenotlisted": "Sa lis pouvé fika enkonplèt",
"mypage": "Paj",
"mytalk": "Diskisyon",
"anontalk": "Diskisyon",
@@ -293,7 +293,7 @@
"databaseerror-function": "Fonksyon : $1",
"databaseerror-error": "Ãrò : $1",
"transaction-duration-limit-exceeded": "Pou évité roun tròp fò ogmantasyon di délè di réplikasyon, sa tranzaksyon té anilé piskétan douré di ékritir ($1) dépasé limit-a di $2 ségonn. Si zòt ka sasé modifyé oun gran nonm di éléman similtanéman, éséyé plito di éfèktchwé opérasyon-an an plizyò étap pli piti.",
- "laggedslavemode": "Panga, sa paj pa pé kontni tout dannyé modifikasyon éfèktchwé",
+ "laggedslavemode": "Panga, sa paj pa pouvé kontni tout dannyé modifikasyon éfèktchwé",
"readonly": "Baz di doné vérouyé",
"enterlockreason": "Endiké rézon-an di vérouyaj ensi ki roun èstimasyon di so douré",
"readonlytext": "Ajou ké mizajou di baz di doné sa atchwèlman bloké, probabman pou pèrmèt mentnans di baz-a, aprè sa, tout bagaj ké rantré andan lòrd.\n\nAdministratò sistèm ki vérouyé baz di doné té fourni èksplikasyon swivant :
$1",
@@ -314,7 +314,7 @@
"filenotfound": "Enposib di trouvé fiché-a « $1 ».",
"unexpected": "Valò ki pa nòrmal : « $1 » = « $2 ».",
"formerror": "Ãrò : enposib di soumèt fòrmilèr-a.",
- "badarticleerror": "Sa aksyon pa pé sa éfèktchwé asou sa paj.",
+ "badarticleerror": "Sa aksyon pa pouvé fika éfèktchwé asou sa paj.",
"cannotdelete": "Enposib di souprimé paj-a oben fiché-a « $1 ».\nSouprésyon-an pitèt ja té éfèktchwé pa rounòt moun.",
"cannotdelete-title": "Enposib di souprimé paj-a « $1 »",
"delete-hook-aborted": "Souprésyon anilé pa roun ègstansyon.\nPyès èksplikasyon té bay.",
@@ -324,7 +324,7 @@
"title-invalid-empty": "Tit di paj doumandé sa vid oben ka kontni sèlman non-an di roun lèspas di non.",
"title-invalid-utf8": "Tit di paj doumandé ka kontni roun sékans UTF-8 envalid.",
"title-invalid-interwiki": "Paj sib ka kontni roun lyen interwiki ki nou pa pouvé itilizé annan tit-ya.",
- "title-invalid-talk-namespace": "Tit di paj doumandé ka fè référans à roun paj di diskisyon ki pa pé ègzisté.",
+ "title-invalid-talk-namespace": "Tit di paj doumandé ka fè référans à roun paj di diskisyon ki pa pouvé ègzisté.",
"title-invalid-characters": "Tit di paj doumandé ka kontni dé karaktèr ki pa valid : « $1 ».",
"title-invalid-relative": "Tit ka kontni oun chimen roulatif. Tit-ya ki ka référansé dé paj roulativ (./, ../) pa valid pas li sa souvan itilizé pa navigatò di itilizatò-a.",
"title-invalid-magic-tilde": "Tit di paj doumandé ka kontni roun sékans di tilde majik ki pa valid (
ا٠Ù
تغÛرÙÙÙ ÙÚ©Ù
ÙÙ
سر٠ÙÚÙÙÙ â Ù¾Ù ÙاÙعÛت Ú©ÛØ Ø¯ ÚÙ٠دÙÙÙ Ùر Ú
Ù. دا خپÙ٠د Ù
ÙÚÙاÙÙک٠پ٠اÚÙÙد٠Ù
رØÙÙ Ú©ÙÙ٠سر٠ترسر٠کÙÚÙ.",
diff --git a/languages/i18n/pt-br.json b/languages/i18n/pt-br.json
index 2f08a4e179..ca356b66eb 100644
--- a/languages/i18n/pt-br.json
+++ b/languages/i18n/pt-br.json
@@ -1617,7 +1617,7 @@
"uploadlogpagetext": "Segue listagem dos uploads de arquivos mais recentes.\nA [[Special:NewFiles|galeria de arquivos novos]] oferece uma listagem mais visual.",
"filename": "Nome do arquivo",
"filedesc": "Descrição do arquivo",
- "fileuploadsummary": "Sumário:",
+ "fileuploadsummary": "Resumo:",
"filereuploadsummary": "Alterações no arquivo:",
"filestatus": "Status dos direitos autorais:",
"filesource": "Fonte:",
@@ -1646,7 +1646,7 @@
"tmp-write-error": "Erro ao alterar arquivo temporário.",
"large-file": "à recomendável que os arquivos não sejam maiores que $1;\neste possui $2.",
"largefileserver": "Este arquivo é maior do que o servidor está configurado para permitir.",
- "emptyfile": "O arquivo enviado parece estar vazio.\nIsso pode ter ocorrido por um erro de digitação no nome do arquivo.\nVerifique se você realmente deseja enviar este arquivo.",
+ "emptyfile": "O arquivo enviado parece estar vazio.\nIsso pode ter ocorrido por um erro de digitação no nome.\nVerifique se você realmente deseja enviá-lo.",
"windows-nonascii-filename": "O wiki não aceita nomes de arquivos com caracteres especiais.",
"fileexists": "Já existe um arquivo com este nome.\nVerifique [[:$1]] caso não tenha certeza se deseja alterar o arquivo atual.\n[[$1|thumb]]",
"filepageexists": "A página de descrição deste arquivo já foi criada em [[:$1]], mas atualmente não existe nenhum arquivo com este nome.\nO sumário que você inseriu não aparecerá na página de descrição.\nPara que ele apareça, será necessário editá-lo manualmente.\n[[$1|thumb]]",
@@ -2141,7 +2141,7 @@
"categories-submit": "Exibir",
"categoriespagetext": "{{PLURAL:$1|A seguinte categoria contém|As seguintes contém}} páginas ou mÃdia.\n[[Special:UnusedCategories|Categorias não utilizadas]] não são mostradas aqui.\nVeja também [[Special:WantedCategories|categorias pedidas]].",
"categoriesfrom": "Listar categorias começando por:",
- "deletedcontributions": "Edições eliminadas",
+ "deletedcontributions": "Contribuições eliminadas",
"deletedcontributions-title": "Contribuições eliminadas",
"sp-deletedcontributions-contribs": "contribuições",
"linksearch": "Pesquisa de links externos",
@@ -2512,7 +2512,7 @@
"ipbcreateaccount": "Prevenir a criação de contas",
"ipbemailban": "Impedir usuário(a) de enviar e-mail",
"ipbenableautoblock": "Bloquear automaticamente o endereço de IP mais recente usado por este(a) usuário(a) e todos os IPs subsequentes dos quais ele(a) tentar editar",
- "ipbsubmit": "Bloquear este(a) usuário(a)",
+ "ipbsubmit": "Bloquear",
"ipbother": "Outro perÃodo:",
"ipboptions": "2 horas:2 hours,1 dia:1 day,3 dias:3 days,1 semana:1 week,2 semanas:2 weeks,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year,indefinido:infinite",
"ipbhidename": "Ocultar nome de usuário em edições e listas",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index f7038628d9..94ffcf6ab2 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -1600,7 +1600,7 @@
"rcfilters-savedqueries-rename": "Label for the menu option that edits a quick filter in [[Special:RecentChanges]]\n{{Identical|Rename}}",
"rcfilters-savedqueries-setdefault": "Label for the menu option that sets a quick filter as default in [[Special:RecentChanges]]",
"rcfilters-savedqueries-unsetdefault": "Label for the menu option that unsets a quick filter as default in [[Special:RecentChanges]]",
- "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]\n{{Identical|Remove}}",
+ "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]\n{{Identical|Delete}}",
"rcfilters-savedqueries-new-name-label": "Label for the input that holds the name of the new saved filters in [[Special:RecentChanges]]\n{{Identical|Name}}",
"rcfilters-savedqueries-new-name-placeholder": "Placeholder for the input that holds the name of the new saved filters in [[Special:RecentChanges]]",
"rcfilters-savedqueries-apply-label": "Label for the button to apply saving a new filter setting in [[Special:RecentChanges]]. This is for a small popup, please try to use a short string.",
diff --git a/languages/i18n/ru.json b/languages/i18n/ru.json
index 87c820f940..2b86286c57 100644
--- a/languages/i18n/ru.json
+++ b/languages/i18n/ru.json
@@ -886,9 +886,9 @@
"expansion-depth-exceeded-warning": "Ðа ÑÑÑаниÑе пÑевÑÑен пÑедел вложенноÑÑи",
"parser-unstrip-loop-warning": "ÐбнаÑÑжен незакÑÑÑÑй pre",
"unstrip-depth-warning": "ÐÑевÑÑен пÑедел ÑекÑÑÑии ($1)",
- "unstrip-depth-category": "СÑÑаниÑÑ Ð³Ð´Ðµ незамеÑÐ½Ð°Ñ Ð³Ð»Ñбина пÑевÑÑена",
- "unstrip-size-warning": "Unstrip пÑевÑÑен пÑедел ÑекÑÑÑии ($1)",
- "unstrip-size-category": "СÑÑаниÑÑ Ð³Ð´Ðµ незамеÑÐ½Ð°Ñ ÑазмеÑка пÑевÑÑена",
+ "unstrip-depth-category": "СÑÑаниÑÑ Ñ Ð¿ÑевÑÑеннÑм лимиÑом глÑÐ±Ð¸Ð½Ñ Unstrip",
+ "unstrip-size-warning": "ÐÑевÑÑен Ð»Ð¸Ð¼Ð¸Ñ ÑазмеÑа Unstrip ($1)",
+ "unstrip-size-category": "СÑÑаниÑÑ Ñ Ð¿ÑевÑÑеннÑм лимиÑом ÑазмеÑа Unstrip",
"converter-manual-rule-error": "ÐÑибка в ÑÑÑном пÑавиле пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑзÑка",
"undo-success": "ÐÑавка Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ñменена. ÐожалÑйÑÑа, пÑоÑмоÑÑиÑе ÑÑавнение веÑÑий, ÑÑÐ¾Ð±Ñ ÑбедиÑÑÑÑ, ÑÑо ÑÑо именно Ñе изменениÑ, коÑоÑÑе Ð²Ð°Ñ Ð¸Ð½ÑеÑеÑÑÑÑ, и нажмиÑе «ÐапиÑаÑÑ ÑÑÑаниÑÑ», ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑÑÑпили в ÑилÑ.",
"undo-failure": "ÐÑавка не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ñменена из-за неÑовмеÑÑимоÑÑи пÑомежÑÑоÑнÑÑ
изменений.",
@@ -1131,7 +1131,7 @@
"recentchangesdays": "ÐолиÑеÑÑво дней, за коÑоÑÑе показÑваÑÑ Ñвежие пÑавки:",
"recentchangesdays-max": "(не более $1 {{PLURAL:$1|днÑ|дней}})",
"recentchangescount": "ÐолиÑеÑÑво пÑавок, по ÑмолÑÐ°Ð½Ð¸Ñ Ð¾ÑобÑажаемое в ÑпиÑке ÑвежиÑ
пÑавок, иÑÑоÑии ÑÑÑÐ°Ð½Ð¸Ñ Ð¸ в жÑÑналаÑ
:",
- "prefs-help-recentchangescount": "ÐаиболÑÑее знаÑение: 1000",
+ "prefs-help-recentchangescount": "ÐакÑималÑное знаÑение: 1000",
"prefs-help-watchlist-token2": "ÐÑо ÑекÑеÑнÑй клÑÑ Ð´Ð»Ñ Ð²ÐµÐ±-канала ваÑего ÑпиÑка наблÑдений.\nÐÑбой, кÑо Ð·Ð½Ð°ÐµÑ ÐµÐ³Ð¾, ÑÐ¼Ð¾Ð¶ÐµÑ ÑиÑаÑÑ Ð²Ð°Ñ ÑпиÑок наблÑдениÑ, поÑÑÐ¾Ð¼Ñ Ð½Ðµ ÑообÑайÑе его дÑÑгим.\nÐÑли необÑ
одимо, [[Special:ResetTokens|Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑбÑоÑиÑÑ ÐµÐ³Ð¾]].",
"prefs-help-tokenmanagement": "ÐÑ Ð¼Ð¾Ð¶ÐµÑе пÑоÑмоÑÑеÑÑ Ð¸ ÑбÑоÑиÑÑ Ð´Ð»Ñ Ñвоей ÑÑÑÑной запиÑи ÑекÑеÑнÑй клÑÑ, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к веб-ÐºÐ°Ð½Ð°Ð»Ñ Ð²Ð°Ñего ÑпиÑка наблÑдениÑ. ÐÑбой, кÑо Ð·Ð½Ð°ÐµÑ ÐºÐ»ÑÑ, ÑÐ¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑиÑаÑÑ Ð²Ð°Ñ ÑпиÑок наблÑдениÑ, поÑÑÐ¾Ð¼Ñ Ð½Ðµ делиÑеÑÑ Ð¸Ð¼ ни Ñ ÐºÐµÐ¼.",
"savedprefs": "ÐаÑÑÑойки ÑоÑ
ÑаненÑ.",
@@ -1560,7 +1560,7 @@
"rcfilters-view-namespaces-tooltip": "РезÑлÑÑаÑÑ ÑилÑÑÑа по пÑоÑÑÑанÑÑвам имÑн",
"rcfilters-view-tags-tooltip": "ФилÑÑÑоваÑÑ ÑезÑлÑÑаÑÑ, иÑполÑзÑÑ Ð¼ÐµÑки пÑавок",
"rcfilters-view-return-to-default-tooltip": "ÐеÑнÑÑÑÑÑ Ð² главное Ð¼ÐµÐ½Ñ ÑилÑÑÑов",
- "rcfilters-view-tags-help-icon-tooltip": "УзнаÑÑ Ð±Ð¾Ð»ÑÑе о ÑедакÑоÑе Ñегов",
+ "rcfilters-view-tags-help-icon-tooltip": "ÐодÑобнее о пÑавкаÑ
Ñ Ð¼ÐµÑками",
"rcfilters-liveupdates-button": "ÐбновлÑÑÑ Ð°Ð²ÑомаÑиÑеÑки",
"rcfilters-liveupdates-button-title-on": "ÐÑклÑÑиÑÑ Ð°Ð²ÑомаÑиÑеÑкие обновлениÑ",
"rcfilters-liveupdates-button-title-off": "ÐоказÑваÑÑ Ð½Ð¾Ð²Ñе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле иÑ
поÑвлениÑ",
@@ -2367,8 +2367,8 @@
"editcomment": "ÐÑло дано опиÑание изменениÑ: $1.",
"revertpage": "ÐÑÐºÐ°Ñ Ð¿Ñавок [[Special:Contributions/$2|$2]] ([[User talk:$2|обÑÑждение]]) к веÑÑии [[User:$1|$1]]",
"revertpage-nouser": "ÐÑÐºÐ°Ñ Ð¿Ñавок (Ð¸Ð¼Ñ ÑÑаÑÑника ÑкÑÑÑо) к веÑÑии {{GENDER:$1|[[User:$1|$1]]}}",
- "rollback-success": "ÐÑÐºÐ°Ñ Ð¿Ñавок {{GENDER:$3|$1}}; возвÑÐ°Ñ Ðº веÑÑии {{GENDER:$4|$2}}.",
- "rollback-success-notify": "ÐÑÐºÐ°Ñ Ð¿Ñавок $1; возвÑÐ°Ñ Ðº веÑÑии $2. [$3 ÐоказаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ]",
+ "rollback-success": "ÐÑкаÑÐµÐ½Ñ Ð¿Ñавки {{GENDER:$3|$1}}; возвÑаÑена поÑледнÑÑ Ð²ÐµÑÑÐ¸Ñ {{GENDER:$4|$2}}.",
+ "rollback-success-notify": "ÐÑкаÑÐµÐ½Ñ Ð¿Ñавки $1; возвÑаÑена поÑледнÑÑ Ð²ÐµÑÑÐ¸Ñ $2. [$3 ÐоказаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ]",
"sessionfailure-title": "ÐÑибка ÑеанÑа",
"sessionfailure": "ÐоÑ
оже, возникли пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ ÑекÑÑим ÑеанÑом ÑабоÑÑ;\nÑÑо дейÑÑвие бÑло оÑменено в ÑелÑÑ
пÑедоÑвÑаÑÐµÐ½Ð¸Ñ Â«Ð·Ð°Ñ
ваÑа ÑеанÑа».\nÐожалÑйÑÑа, пеÑеоÑпÑавÑÑе ÑоÑмÑ.",
"changecontentmodel": "РедакÑиÑование конÑенÑной модели ÑÑÑаниÑÑ",
@@ -2647,7 +2647,7 @@
"ip_range_invalid": "ÐедопÑÑÑимÑй диапазон IP-адÑеÑов.",
"ip_range_toolarge": "ÐлокиÑовки диапазонов ÑвÑÑе /$1 запÑеÑенÑ.",
"ip_range_exceeded": "IP-диапазон пÑевÑÑÐ°ÐµÑ Ð¼Ð°ÐºÑималÑнÑй диапазон. ÐопÑÑÑимÑй диапазон: /$1.",
- "ip_range_toolow": "ÐÐ¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ IP не ÑазÑеÑенÑ.",
+ "ip_range_toolow": "ÐÐ¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ IP по ÑÑÑи запÑеÑенÑ.",
"proxyblocker": "ÐлокиÑовка пÑокÑи",
"proxyblockreason": "ÐÐ°Ñ IP-адÑÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñован поÑомÑ, ÑÑо ÑÑо оÑкÑÑÑÑй пÑокÑи-ÑеÑвеÑ. ÐожалÑйÑÑа, ÑвÑжиÑеÑÑ Ñо Ñвоиим инÑеÑнеÑ-пÑовайдеÑом или ÑлÑжбой поддеÑжки, и ÑообÑиÑе им об ÑÑой ÑеÑÑÑзной пÑоблеме безопаÑноÑÑи.",
"sorbs": "DNSBL",
@@ -4080,7 +4080,7 @@
"limitreport-expansiondepth-value": "$1/$2",
"limitreport-expensivefunctioncount": "ÐолиÑеÑÑво «доÑогиÑ
» ÑÑнкÑий анализаÑоÑа",
"limitreport-expensivefunctioncount-value": "$1/$2",
- "limitreport-unstrip-depth": "ÐлÑÐ±Ð¸Ð½Ð½Ð°Ñ ÑекÑÑÑÐ¸Ñ Unstrip",
+ "limitreport-unstrip-depth": "ÐлÑбина ÑекÑÑÑии Unstrip",
"limitreport-unstrip-depth-value": "$1/$2",
"limitreport-unstrip-size": "Ð Ð°Ð·Ð¼ÐµÑ Unstrip поÑле ÑаÑкÑÑÑÐ¸Ñ Ð²ÐºÐ»ÑÑений",
"limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|байÑ|байÑа|байÑ}}",
diff --git a/languages/i18n/sa.json b/languages/i18n/sa.json
index 9880c2c493..513e64df22 100644
--- a/languages/i18n/sa.json
+++ b/languages/i18n/sa.json
@@ -24,7 +24,8 @@
"Macofe",
"Matma Rex",
"à°°à°¹à±à°®à°¾à°¨à±à°¦à±à°¦à±à°¨à±",
- "Fitoschido"
+ "Fitoschido",
+ "Charunandan16"
]
},
"tog-underline": "परिसनà¥à¤§à¥à¤ à¤
धॠरà¥à¤à¤¾à¤à¥à¤à¤¨à¤®à¥:",
@@ -1746,6 +1747,7 @@
"dellogpage": "à¤
पाà¤à¤°à¤£à¤¾à¤¨à¤¾à¤®à¥ à¤à¤µà¤²à¤¿à¤",
"dellogpagetext": "सदà¥à¤¯à¤ à¤à¤¾à¤²à¥à¤¨à¤¾à¤ªà¤®à¤°à¥à¤à¤¿à¤¤à¤ªà¥à¤à¤¾à¤¨à¤¾à¤®à¥ à¤à¤µà¤²à¥ à¤
धठà¤
सà¥à¤¤à¤¿ ।",
"deletionlog": "à¤
पमरà¥à¤à¤¨à¤¸à¥à¤à¤¿à¤à¤¾ ।",
+ "log-description-create": "नवà¥à¤¨à¤¤à¤®à¤¾à¤¨à¤¾à¤ पà¥à¤·à¥à¤ रà¤à¤¨à¤¾à¤¨à¤¾à¤®à¥ à¤à¤¯à¤®à¥ à¤à¤µà¤²à¥",
"reverted": "पà¥à¤°à¤¾à¤à¥à¤¨à¤ªà¥à¤¨à¤°à¤¾à¤µà¥à¤¤à¥à¤¤à¤¿à¤ पà¥à¤°à¥à¤µà¤µà¤¤à¥ à¤à¥à¤¤à¤¾ ।",
"deletecomment": "à¤à¤¾à¤°à¤£à¤®à¥ :",
"deleteotherreason": "à¤
परà¤/à¤
तिरिà¤à¥à¤¤à¤ à¤à¤¾à¤°à¤£à¤®à¥ :",
diff --git a/languages/i18n/shn.json b/languages/i18n/shn.json
index 6447d1363a..10e1ac24a9 100644
--- a/languages/i18n/shn.json
+++ b/languages/i18n/shn.json
@@ -1074,7 +1074,7 @@
"nchanges": "$1 {{PLURAL:$1|áá
áµáºááá¢áá|á¸áá°ááºá¸áá
áµáºááá¢áá}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|á¸áµááºááá°ááºá áµáááá¢á
ááºááá½áµáºááµááºá¸ááá¯á¼áºá¸}}",
"enhancedrc-history": "ááá¯á¼áºá¸",
- "recentchanges": "áá®á¸áá½ááºááá
áµáºááá¢áááááááá¯ááº",
+ "recentchanges": "áá½ááºááá
áµáºááá¢áááááºááááºá",
"recentchanges-legend": "áµá¼áºááá°áµáºááá¢ááºá áá½ááºááá
áµáºááá¢ááá¢á¼áºáá°á¼áºáááá¸",
"recentchanges-summary": "á¸á½ááºá¸áá°áºáºá¸áá½áḠá¢á¼áºááµá¼áºáµá¢á¼áº ááá¯áµáºááááá
áµáºááá¢áááµááá áá½á¼áºááááá¼áááááµáºá áá®áá¶á®áá¼ááá",
"recentchanges-noresult": "á¼ááºá¸áµááá¶á¢ááºá¸áá¢ááºá¸ á¢á¼áºáá¼áºááá ááááµáá¯áµáºá¸áá°áºáºá¸ ááá°ááºáá
áµáºáááááá
ááºá¸áááºá¸á¼á¼áºá á¢ááºááá¼áºáá®á¸ áá½ááºááá
áµáºááá¢áááááºá",
diff --git a/languages/i18n/sq.json b/languages/i18n/sq.json
index 489667218c..c1be4c365c 100644
--- a/languages/i18n/sq.json
+++ b/languages/i18n/sq.json
@@ -37,7 +37,8 @@
"Fanjiayi",
"Fitoschido",
"Luanibraj",
- "MatÄj Suchánek"
+ "MatÄj Suchánek",
+ "Bjakupi"
]
},
"tog-underline": "Nënvizimi i lidhjes:",
@@ -1360,6 +1361,8 @@
"rcfilters-watchlist-markseen-button": "Shenjo të gjitha ndryshimet si të para",
"rcfilters-watchlist-edit-watchlist-button": "Redakto listën tuaj të faqeve të mbikëqyrura",
"rcfilters-preference-label": "Fshih versionin e përmirësuar të Ndryshimeve të Fundit",
+ "rcfilters-watchlist-preference-label": "Fshehni versionin e permiresuar te Listes-vrojtuese",
+ "rcfilters-watchlist-preference-help": "E kthen nderfaqen e ri-dizajnit te 2017 dhe te gjitha mjetet atehere dhe qe nga ai moment.",
"rcfilters-target-page-placeholder": "Shto një emër faqeje (ose kategorie)",
"rcnotefrom": "Më poshtë {{PLURAL:$5|është shfaqur ndryshimi|janë shfaqur ndryshimet}} që nga $3, $4 (deri në $1).",
"rclistfromreset": "Anulo përzgjedhjen e datës",
@@ -2016,6 +2019,9 @@
"dellogpage": "Regjistri i grisjeve",
"dellogpagetext": "Më poshtë është një listë e grisjeve më të fundit.",
"deletionlog": "regjistrin e grisjeve",
+ "log-name-create": "Krijimi i faqes logjike",
+ "log-description-create": "Me poshte eshte nje liste e krimit te faqeve me te fundit",
+ "logentry-create-create": "$1{{GENDER:$2|created}} faqe $3",
"reverted": "Kthehu tek një version i vjetër",
"deletecomment": "Arsyeja:",
"deleteotherreason": "Arsye tjetër:",
diff --git a/languages/i18n/sr-ec.json b/languages/i18n/sr-ec.json
index 1f30cdea31..b634673900 100644
--- a/languages/i18n/sr-ec.json
+++ b/languages/i18n/sr-ec.json
@@ -652,7 +652,7 @@
"subject-preview": "ÐÑеглед Ñеме:",
"previewerrortext": "Ðогодила Ñе гÑеÑка пÑиликом пÑиказиваÑа ваÑиÑ
измена.",
"blockedtitle": "ÐоÑиÑник Ñе блокиÑан",
- "blockedtext": "ÐаÑе коÑиÑниÑко име или IP адÑеÑа Ñе блокиÑана.\n\nÐлокиÑаÑе Ñе {{GENDER:$4|извÑÑио|извÑÑила}} $1.\nРазлог Ñе $2.\n\n* ÐаÑÑм блокиÑаÑа: $8\n* ÐлокиÑаÑе иÑÑиÑе: $6\n* Ðме коÑиÑника: $7\n\nÐбÑаÑиÑе Ñе {{GENDER:$4|коÑиÑникÑ|коÑиÑниÑи}} $1 или [[{{MediaWiki:Grouppage-sysop}}|админиÑÑÑаÑоÑÑ]] да ÑазÑаÑниÑе ÑÑваÑ.\nÐе можеÑе коÑиÑÑиÑи могÑÑноÑÑ âÐоÑаÑи имеÑл овом коÑиÑникÑâ ако ниÑÑе Ñнели иÑпÑÐ°Ð²Ð½Ñ Ð¸Ð¼ÐµÑл адÑеÑÑ Ñ [[Special:Preferences|подеÑаваÑима]].\nÐаÑа блокиÑана IP адÑеÑа Ñе $3, а ID блокиÑаÑа $5.\nÐаведиÑе Ñве подаÑке изнад пÑи ÑÑваÑаÑÑ Ð±Ð¸Ð»Ð¾ каквиÑ
ÑпиÑа.",
+ "blockedtext": "ÐаÑе коÑиÑниÑко име или IP адÑеÑа Ñе блокиÑана.\n\nÐлокиÑаÑе Ñе {{GENDER:$4|извÑÑио|извÑÑила}} $1.\nРазлог Ñе $2.\n\n* ÐоÑеÑак блокиÑаÑа: $8\n* ÐÑÑек блокиÑаÑа: $6\n* ÐлокиÑани: $7\n\nÐожеÑе да Ñе обÑаÑиÑе {{GENDER:$4|коÑиÑникÑ|коÑиÑниÑи}} $1 или [[{{MediaWiki:Grouppage-sysop}}|админиÑÑÑаÑоÑÑ]] Ñади диÑкÑÑиÑе о блокиÑаÑÑ.\nÐе можеÑе да коÑиÑÑиÑе могÑÑноÑÑ â{{int:emailuser}}â оÑим ако ÑÑе Ñнели Ð²Ð°Ð»Ð¸Ð´Ð½Ñ Ð¸Ð¼ÐµÑл адÑеÑÑ Ñ ÑвоÑим [[Special:Preferences|подеÑаваÑима]] налога и ниÑÑе блокиÑани од коÑиÑÑеÑа иÑÑе.\nÐаÑа ÑÑенÑÑна IP адÑеÑа Ñе $3, а ID блокиÑаÑа #$5.\nÐаведиÑе Ñве инÑоÑмаÑиÑе одозго пÑи ÑÑваÑаÑÑ Ð±Ð¸Ð»Ð¾ каквиÑ
ÑпиÑа.",
"autoblockedtext": "ÐаÑа IP адÑеÑа Ñе блокиÑана ÑÐµÑ ÑÑ Ñе ÑпоÑÑебÑавао дÑÑги коÑиÑник, кога Ñе {{GENDER:$4|блокиÑао|блокиÑала}} $1.\nРазлог:\n\n:$2\n\n* ÐаÑÑм блокиÑаÑа: $8\n* ÐлокиÑаÑе иÑÑиÑе: $6\n* Ðме коÑиÑника: $7\n\nÐбÑаÑиÑе Ñе {{GENDER:$4|коÑиÑникÑ|коÑиÑниÑи}} $1 или [[{{MediaWiki:Grouppage-sysop}}|админиÑÑÑаÑоÑÑ]] да ÑазÑаÑниÑе ÑÑваÑ.\n\nÐе можеÑе коÑиÑÑиÑи могÑÑноÑÑ âÐоÑаÑи имеÑл овом коÑиÑникÑâ ако ниÑÑе Ñнели иÑпÑÐ°Ð²Ð½Ñ Ð¸Ð¼ÐµÑл адÑеÑÑ Ñ [[Special:Preferences|подеÑаваÑима]].\n\nÐаÑа блокиÑана IP адÑеÑа Ñе $3, а ID $5.\nÐаведиÑе Ñве подаÑке изнад пÑи ÑÑваÑаÑÑ Ð±Ð¸Ð»Ð¾ каквиÑ
ÑпиÑа.",
"blockednoreason": "Ñазлог ниÑе наведен",
"whitelistedittext": "Ðа ÑÑеÑиваÑе ÑÑÑаниÑе Ñе поÑÑебно да бÑдеÑе $1.",
@@ -1498,7 +1498,7 @@
"recentchangeslinked-feed": "СÑодне измене",
"recentchangeslinked-toolbox": "СÑодне измене",
"recentchangeslinked-title": "СÑодне измене Ñа â$1â",
- "recentchangeslinked-summary": "УнеÑиÑе име ÑÑÑаниÑе да биÑÑе видели пÑомене на ÑÑÑаниÑама коÑе ÑÑ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñа или Ñа Ñе ÑÑÑаниÑе. (Ðа биÑÑе видели Ñланове неке каÑегоÑиÑе, ÑнеÑиÑе ÐаÑегоÑиÑа:Ðазив каÑегоÑиÑе). ÐÑомене на ÑÑÑаниÑама коÑе ÑÑ Ð½Ð° [[Special:Watchlist|ваÑем ÑпиÑÐºÑ Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñа]] ÑÑ '''подебÑане'''.",
+ "recentchangeslinked-summary": "УнеÑиÑе име ÑÑÑаниÑе да биÑÑе видели пÑомене на ÑÑÑаниÑама коÑе ÑÑ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñа или Ñа Ñе ÑÑÑаниÑе. (Ðа биÑÑе видели Ñланове каÑегоÑиÑе, ÑнеÑиÑе {{ns:category}}:Ðме каÑегоÑиÑе). ÐÑомене на ÑÑÑаниÑама коÑе ÑÑ Ð½Ð° [[Special:Watchlist|ÐаÑем ÑпиÑÐºÑ Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñа]] ÑÑ Ð¿Ð¾Ð´ÐµÐ±Ñане.",
"recentchangeslinked-page": "Ðазив ÑÑÑаниÑе:",
"recentchangeslinked-to": "ÐÑикажи измене ÑÑÑаниÑа коÑе ÑÑ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñ Ð´Ð°Ñом ÑÑÑаниÑом",
"recentchanges-page-added-to-category": "[[:$1]] Ñе додаÑа Ñ ÐºÐ°ÑегоÑиÑÑ",
@@ -2720,7 +2720,7 @@
"tooltip-ca-nstab-category": "ÐогледаÑÑе ÑÑÑаниÑÑ ÐºÐ°ÑегоÑиÑа",
"tooltip-minoredit": "ÐзнаÑиÑе Ð¾Ð²Ñ Ð¸Ð·Ð¼ÐµÐ½Ñ ÐºÐ°Ð¾ маÑÑ",
"tooltip-save": "СаÑÑваÑÑе ÑвоÑе измене",
- "tooltip-publish": "ÐбÑавиÑе ÐаÑе измене",
+ "tooltip-publish": "ÐбÑавиÑе ÑвоÑе измене",
"tooltip-preview": "ÐÑегледаÑÑе ÑвоÑе измене. ÐоÑиÑÑиÑе ово дÑгме пÑе ÑÑваÑа.",
"tooltip-diff": "ÐогледаÑÑе коÑе измене ÑÑе напÑавили на ÑекÑÑÑ",
"tooltip-compareselectedversions": "ÐогледаjÑе Ñазлике измеÑÑ Ð´Ð²Ðµ изабÑане измене ове ÑÑÑаниÑе.",
diff --git a/languages/i18n/tr.json b/languages/i18n/tr.json
index e0083a597e..c10b50bfa0 100644
--- a/languages/i18n/tr.json
+++ b/languages/i18n/tr.json
@@ -448,6 +448,7 @@
"cascadeprotected": "Bu sayfa deÄiÅiklik yapılması engellenmiÅtir, çünkü \"kademeli\" seçeneÄi aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfalarda}} kullanılmaktadır:\n$2",
"namespaceprotected": "'''$1''' alandındaki sayfaları düzenlemeye izniniz bulunmamaktadır.",
"customcssprotected": "Bu sayfayı deÄiÅtirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa baÅka bir kullanıcının kiÅisel ayarlarını içermektedir.",
+ "customjsonprotected": "BaÅka bir kullanıcının kiÅisel ayarlarını içerdiÄi için bu JSON sayfasını düzenleme izniniz yok.",
"customjsprotected": "Bu Java Script sayfasını deÄiÅtirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa baÅka bir kullanıcının kiÅisel ayarlarını içermektedir.",
"mycustomcssprotected": "Bu CSS sayfasını deÄiÅtirmeye yetkiniz yok.",
"mycustomjsonprotected": "Bu JSON sayfasını düzenleme izniniz yok.",
@@ -609,6 +610,7 @@
"botpasswords-label-delete": "Sil",
"botpasswords-label-resetpassword": "Parolayı sıfırla",
"botpasswords-label-grants": "Geçerli ayrıcalıklar:",
+ "botpasswords-help-grants": "Hibeler, kullanıcı hesabınızın sahip olduÄu haklara eriÅim izni verir. Burada bir hibe saÄlamak, kullanıcı hesabınızın sahip olamayacaÄı herhangi bir haklara eriÅim saÄlamaz. Daha fazla bilgi için [[Special:ListGrants|hibe tablosuna]] bakınız.",
"botpasswords-label-grants-column": "Verilen",
"botpasswords-bad-appid": "Bot ismi \"$1\" geçerli deÄil.",
"botpasswords-insert-failed": "Bot adı \"$1\" eklenemedi. Zaten eklenmiŠolmalı?",
@@ -618,11 +620,12 @@
"botpasswords-updated-title": "Bot parolası güncellendi",
"botpasswords-updated-body": "\"$2\" adlı {{GENDER:$2|kullanıcının}} \"$1\" adlı botunun bot parolası güncellendi.",
"botpasswords-deleted-title": "Bot parolası silindi",
- "botpasswords-deleted-body": "\"$2\" adlı kullanıcının \"$1\" adlı botunun bot parolası silindi.",
- "botpasswords-newpassword": "$1 ile oturum açmak için yeni Åifre: $2. Ä°lerde baÅvurmak için lütfen kaydedin.",
+ "botpasswords-deleted-body": "\"$2\" adlı {{GENDER:$2|kullanıcının}} \"$1\" adlı botunun bot parolası silindi.",
+ "botpasswords-newpassword": "$1 ile giriÅ yapılan yeni parola: $2. Lütfen bunu ileride baÅvurmak için kaydedin.
(Kullanıcı adının, nihai kullanıcı adıyla aynı olmasını gerektiren eski botlar için kullanıcı adı olarak $3 ve Åifre olarak da $4 kullanabilirsiniz.)",
"botpasswords-no-provider": "BotPasswordsSessionProvider kullanılamaz.",
"botpasswords-restriction-failed": "Bot parolası kısıtlamaları bu oturum açma iÅlemini önlemektedir.",
"botpasswords-invalid-name": "Belirtilen kullanıcı adı bot parolası ayırıcısı içermiyor (\"$1\").",
+ "botpasswords-not-exist": "\"$1\" kullanıcısının \"$2\" adında bir bot Åifresine sahip deÄil.",
"botpasswords-needs-reset": "\"$1\" {{GENDER:$1|kullanıcısına}} ait \"$2\" adlı bot için bot parolası sıfırlanmalı.",
"resetpass_forbidden": "Parolalar deÄiÅtirilememektedir",
"resetpass_forbidden-reason": "Parolalar deÄiÅtirilemez: $1",
@@ -651,6 +654,9 @@
"passwordreset-emailelement": "Kullanıcı adı: \n$1\n\nGeçici Åifre: \n$2",
"passwordreset-emailsentemail": "EÄer bu e-posta adresi hesabınızın baÄlı olduÄu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
"passwordreset-emailsentusername": "EÄer bu e-posta adresi hesabınızın baÄlı olduÄu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
+ "passwordreset-nocaller": "Bir ziyaretçi saÄlanmalıdır",
+ "passwordreset-nosuchcaller": "Ziyaretçi mevcut deÄil: $1",
+ "passwordreset-ignored": "Åifre sıfırlama iÅlenmedi. Belki de herhangi bir saÄlayıcı yapılandırılmadı?",
"passwordreset-invalidemail": "Geçersiz e-posta adresi",
"passwordreset-nodata": "Ne bir kullanıcı adı ne de bir e-posta adresi verildi.",
"changeemail": "E-posta adresini deÄiÅtir veya çıkar",
@@ -717,7 +723,8 @@
"previewerrortext": "YaptıÄınız deÄiÅikliklerin önizlemesi sırasında bir hata oluÅtu.",
"blockedtitle": "Kullanıcı eriÅimi engellendi.",
"blockedtext": "Kullanıcı adı veya IP adresiniz engellenmiÅtir.\n\nSizi engelleyen hizmetli: $1.
\nEngelleme sebebi: $2.\n\n* Engellenmenin baÅlangıcı: $8\n* Engellenmenin bitiÅi: $6\n* Engellenme süresi: $7\n\nBelirtilen nedene göre engellenmenizin uygun olmadıÄını düÅünüyorsanız, $1 ya da baÅka bir [[{{MediaWiki:Grouppage-sysop}}|hizmetli]] ile bu durumu görüÅebilirsiniz. [[Special:Preferences|Tercihlerim]] kısmında geçerli bir e-posta adresi girmediyseniz \"Kullanıcıya e-posta gönder\" özelliÄini kullanamazsınız, tercihlerinize e-posta adresinizi eklediÄinizde e-posta gönderme hakkına sahip olacaksınız.\n
Åu anki IP adresiniz $3, engellenme numaranız #$5.\n
Bir hizmetliden durumunuz hakkında bilgi almak istediÄinizde veya herhangi bir sorguda bu bilgiler gerekecektir, lütfen not ediniz.",
- "autoblockedtext": "IP adresiniz otomatik olarak engellendi, çünkü $1 tarafından engellenmiÅ baÅka bir kullanıcı tarafından kullanılmaktaydı.\nBelirtilen sebep Åudur:\n\n:''$2''\n\n* Engellemenin baÅlangıcı: $8\n* Engellemenin bitiÅi: $6\n* Bloke edilmesi istenen: $7\n\nEngelleme hakkında tartıÅmak için $1 ile veya diÄer [[{{MediaWiki:Grouppage-sysop}}|hizmetlilerden]] biriyle irtibata geçebilirsiniz.\n\nNot, [[Special:Preferences|kullanıcı tercihlerinize]] geçerli bir e-posta adresi kaydetmediyseniz \"kullanıcıya e-posta gönder\" özelliÄinden faydalanamayabilirsiniz ve bu özelliÄi kullanmaktan engellenmediniz.\n\nÅu anki IP numaranız $3 ve engellenme ID'niz #$5.\nLütfen yapacaÄınız herhangi bir sorguda yukarıdaki bütün detayları bulundurun.",
+ "autoblockedtext": "IP adresiniz otomatik olarak engellendi, çünkü $1 tarafından engellenmiÅ baÅka bir kullanıcı tarafından kullanılmaktaydı.\nBelirtilen sebep Åudur:\n\n:$2\n\n* Engellemenin baÅlangıcı: $8\n* Engellemenin bitiÅi: $6\n* Bloke edilmesi istenen: $7\n\nEngelleme hakkında tartıÅmak için $1 ile veya diÄer [[{{MediaWiki:Grouppage-sysop}}|hizmetlilerden]] biriyle irtibata geçebilirsiniz.\n\nNot, [[Special:Preferences|kullanıcı tercihlerinize]] geçerli bir e-posta adresi kaydetmediyseniz \"{{int:emailuser}}\" özelliÄinden faydalanamayabilirsiniz ve bu özelliÄi kullanmaktan engellenmediniz.\n\nÅu anki IP numaranız $3 ve engellenme ID'niz #$5.\nLütfen yapacaÄınız herhangi bir sorguda yukarıdaki bütün detayları bulundurun.",
+ "systemblockedtext": "Kullanıcı adınız veya IP adresiniz MediaWiki tarafından otomatik olarak engellendi.\nSebebi:\n\n:$2\n\n* Engelin baÅlangıcı: $8\n* Engelin süresi: $6\n* Engellenmesi istenen: $7\n\nMevcut IP adresiniz $3.\nLütfen yukarıdaki tüm ayrıntıları, yaptıÄınız sorgularda belirtin.",
"blockednoreason": "sebep verilmedi",
"whitelistedittext": "DeÄiÅiklik yapabilmek için $1.",
"confirmedittext": "Sayfa deÄiÅtirmeden önce e-posta adresinizi onaylamalısınız. Lütfen [[Special:Preferences|tercihler]] kısmından e-postanızı ekleyin ve onaylayın.",
@@ -739,19 +746,22 @@
"blocked-notice-logextract": "Bu kullanıcı Åuanda engellenmiÅ.\nSon engelleme günlüÄü girdisi referans için aÅaÄıda saÄlanmıÅtır:",
"clearyourcache": "Note: Kaydettikten sonra deÄiÅiklikleri görmek için tarayıcınızın önbelleÄini temizlemeniz gerekebilir.\n* Firefox / Safari: Shift tuÅuna basılıyken Yeniden yükle'ye tıklayın ya da Ctrl-F5 ya da Ctrl-R yapın (Mac için â-R).\n* Google Chrome: Ctrl-Shift-R'ye basın. (Mac için â-Shift-R)\n* Internet Explorer: Ctrl basılıyken Yenile'ye tıklayın ya da Ctrl-F5 yapın.\n* Opera: Araçlar â Tercihler'den önbelliÄi temizleyin.",
"usercssyoucanpreview": "'''İpucu:''' Kaydetmeden önce \"{{int:showpreview}}\"e tıklayarak yeni CSSinizi deneyin.",
+ "userjsonyoucanpreview": "İpucu: kaydetmeden önce yeni JSON'unuzu test etmek için \"{{int:showpreview}}\" butonunu kullanın.",
"userjsyoucanpreview": "'''İpucu:''' Kaydetmeden önce \"{{int:showpreview}}\"e tıklayarak yeni JavaScript'inizi test edin.",
"usercsspreview": "'''Sadece kullanıcı CSS dosyanızın önizlemesini görüyorsun.''' '''Kullanıcı CSS dosyası henüz kaydolmadı!'''",
+ "userjsonpreview": "Sadece kullanıcı JSON yapılandırmanızı test ettiÄiniz/önizleme yaptıÄınızı unutmayın.\nHenüz kaydedilmedi!",
"userjspreview": "'''Sadece test ediyorsun ya da önizleme görüyorsun - kullanıcı JavaScript'i henüz kaydolmadı.'''",
"sitecsspreview": "'''Sadece kullanıcı CSS dosyanızın önizlemesini görüyorsunuz.''' \n'''Henüz kaydedilmedi!'''",
+ "sitejsonpreview": "Sadece bu JSON yapılandırmasını önizlediÄinizi unutmayın.\nHenüz kaydedilmedi!",
"sitejspreview": "'''Sadece kullanıcı JavaScript kod dosyanızın önizlemesini görüyorsunuz.''' \n'''Henüz kaydedilmedi!'''",
- "userinvalidconfigtitle": "'''Uyarı:''' \"$1\" adında bir tema yoktur. Ãzel .css ve .js sayfalarının adlarını küçük harf ile yazın, örneÄin; \"{{ns:user}}:Ãrnek/Vector.css\" yerine \"{{ns:user}}:Ãrnek/vector.css\" yazın.",
+ "userinvalidconfigtitle": "Uyarı: \"$1\" adında bir tema yoktur. Ãzel .css, .json ve .js sayfalarının adlarını küçük harf ile yazın, örneÄin; \"{{ns:user}}:Ãrnek/Vector.css\" yerine \"{{ns:user}}:Ãrnek/vector.css\" yazın.",
"updated": "(Güncellendi)",
"note": "'''Not: '''",
"previewnote": "'''Bunun yalnızca bir ön izleme olduÄunu unutmayın.'''\nYaptıÄınız deÄiÅiklikler henüz kaydedilmedi!",
"continue-editing": "Düzenlemeye devam et",
"previewconflict": "Bu önizleme metin düzenleme kutucuÄunun üstünde, maddenin eÄer deÄiÅikliklerinizi kaydetmeyi seçerseniz nasıl görüneceÄini yansıtır.",
"session_fail_preview": "Ãzür dileriz. Oturum verisi kaybından dolayı deÄiÅikliÄinizi kaydedemedik.\n\nOturumunuzu kapatmıŠolabilirsiniz. Lütfen oturumunuzun açık olduÄunu doÄrulayıp tekrar deneyiniz.\nEÄer sorun devam ederse, [[Special:UserLogout|oturumu kapatıp]] tekrar giriÅ yapmayı deneyin ve tarayıcınızın bu siteden çerezlere izin verip vermediÄini kontrol edin.",
- "session_fail_preview_html": "'''Ãzgünüz! Oturum verisinin kaybolmasından dolayı düzenlemenizi iÅleme geçiremeyeceÄiz.'''\n\n''Ãünkü {{SITENAME}} sitesinde raw HTML etkindir, önizleme JavaScript saldırılarına önlem olarak gizlenmiÅtir.''\n\n'''EÄer bu haklı bir düzenleme giriÅimiyse, lütfen yeniden deneyin. EÄer hala çalıÅmazsa, [[Special:UserLogout|çıkıŠyapıp]] yeniden oturum açmayı deneyin.'''",
+ "session_fail_preview_html": "Ãzgünüz! Düzenleme iÅleminiz, oturum verisi kaybı nedeniyle iÅlenemedi.\n\n{{SITENAME}} sayfasında ham HTML özelliÄi etkin olduÄundan önizleme, JavaScript saldırılarına karÅı bir önlem olarak gizlenir.\n\nBu yasal bir düzenleme giriÅimi ise lütfen tekrar deneyin.\nHâlâ çalıÅmıyorsa [[Special:UserLogout|çıkıŠyapmayı]] ve ardından tekrar giriÅ yapmayı deneyin ve tarayıcınızın bu sitedeki çerezlere izin verdiÄini kontrol edin.",
"token_suffix_mismatch": "'''DeÄiÅikliÄiniz geri çevrildi çünkü alıcınız düzenleme kutucuÄundaki noktalama iÅaretlerini bozdu.\nDeÄiÅikliÄiniz, sayfa metninde bozulmayı önlemek için geri çevrildi.\nEÄer sorunlu bir web-tabanlı anonim proksi servisi kullanıyorsanız bu olay bazen gerçekleÅebilir.'''",
"edit_form_incomplete": "'''DeÄiÅiklik formu için bazı sunuculara eriÅilemedi; yaptıÄınız deÄiÅiklikler bozulmamıÅtır, gözden geçirip tekrar deneyiniz.'''",
"editing": "\"$1\" sayfasını deÄiÅtirmektesiniz",
@@ -763,15 +773,16 @@
"yourtext": "Sizin metniniz",
"storedversion": "KaydedilmiÅ metin",
"editingold": "'''Uyarı: Sayfanın eski bir sürümünde deÄiÅiklik yapmaktasınız.'''\nKaydettiÄinizde bu tarihli sürümden günümüze kadar olan deÄiÅiklikler yok olacaktır.",
+ "unicode-support-fail": "GörünüÅe göre tarayıcınız Unicode'u desteklemiyor. Sayfaları düzenlemek için bu desteÄe ihtiyacınız var. Bundan ötürü düzenlemeniz kaydedilmedi.",
"yourdiff": "KarÅılaÅtırma",
"copyrightwarning": "'''Lütfen dikkat:''' {{SITENAME}} sitesine yapılan bütün katkılar $2 sözleÅmesi kapsamındadır (ayrıntılar için $1'a bakınız).\nYaptıÄınız katkının baÅka katılımcılar tarafından acımasızca deÄiÅtirilmesini ve sınırsızca baÅka yerlere daÄıtılmasını istemiyorsanız, katkıda bulunmayınız.
\nAyrıca buraya katkıda bulunarak, bu katkının kendiniz tarafından yazıldıÄına ya da kamuya açık bir kaynaktan ya da baÅka bir özgür/ücretsiz kaynaktan kopyalandıÄına güvence vermiÅ oluyorsunuz. '''Buraya, telif sahibinin izni olmadan telif hakkı ile korunan eserleri eklemeyiz! '''",
"copyrightwarning2": "Lütfen, {{SITENAME}} sitesine bulunacaÄınız tüm katkıların diÄer üyeler tarafından düzenlenebileceÄini, deÄiÅtirilebileceÄini ya da silinebileceÄini hatırlayın. Yazılarınızın merhametsizce deÄiÅtirilebilmesine rıza göstermiyorsanız buraya katkıda bulunmayın.
\nAyrıca bu ekleyeceÄiniz yazıyı sizin yazdıÄınızı ya da serbest kopyalama izni veren bir kaynaktan kopyaladıÄınızı bize taahhüt etmektesiniz (ayrıntılar için referans: $1).",
"editpage-cannot-use-custom-model": "Bu sayfanın içerik modeli deÄiÅtirilemez.",
"longpageerror": "'''Hata: GirdiÄiniz metnin uzunluÄu kabul edilebilir en fazla uzunluk olan {{PLURAL:$2|bir kilobayt|$2 kilobayt}}tan fazladır ve {{PLURAL:$1|bir kilobayt|$1 kilobayt}} büyüklüÄündedir.'''\nDeÄiÅikliÄiniz kaydedilemez.",
- "readonlywarning": "'''Uyarı: Bakım nedeniyle veritabanı Åu anda kilitlenmiÅtir. Bu yüzden Åu anda düzenlemelerinizi kaydetmek mümkün deÄildir.''' \nYaptıÄınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptıÄınız düzenlemeleri bir metin dosyasına ya da herhangi bir Åeye kopyala yapıÅtır yaparak saklayınız.\n\nKilitlemeyi yapan yetkili Åu açıklamayı eklemiÅtir: $1",
+ "readonlywarning": "Uyarı: Bakım nedeniyle veritabanı Åu anda kilitlenmiÅtir. Bu yüzden Åu anda düzenlemelerinizi kaydetmek mümkün deÄildir. \nYaptıÄınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptıÄınız düzenlemeleri bir metin dosyasına ya da herhangi bir Åeye kopyala yapıÅtır yaparak saklayınız.\n\nKilitlemeyi yapan sistem yetkilisi Åu açıklamayı eklemiÅtir: $1",
"protectedpagewarning": "'''Uyarı: Bu sayfa koruma altına alınmıÅtır ve yalnızca hizmetli olanlar tarafından deÄiÅtirilebilir.'''\nSon günlük girdisi referans amaçlı aÅaÄıda verilmiÅtir:",
- "semiprotectedpagewarning": "'''Not:''' Bu sayfa sadece kayıtlı kullanıcı olanlar tarafından deÄiÅtirilebilir.\nSon günlük girdisi referans amaçlı aÅaÄıda verilmiÅtir:",
- "cascadeprotectedwarning": "'''UYARI:''' Bu sayfa sadece hizmetlilik yetkileri olan kullanıcıların deÄiÅiklik yapabileceÄi Åekilde koruma altına alınmıÅtır. Ãünkü \"kademeli\" seçeneÄi aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfada}} kullanılmaktadır:",
+ "semiprotectedpagewarning": "Not: Bu sayfa sadece otomatik onaylanmıŠkullanıcılar tarafından deÄiÅtirilebilir.\nSon günlük girdisi referans amaçlı aÅaÄıda verilmiÅtir:",
+ "cascadeprotectedwarning": "Uyarı: Bu sayfa, yalnızca [[Special:ListGroupRights|belirli haklara]] sahip kullanıcıların bunu düzenleyebilmesi için korunmuÅtur çünkü \"kademeli\" seçeneÄi aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfada}} kullanılmaktadır:",
"titleprotectedwarning": "'''Uyarı: Bu sayfa [[Special:ListGroupRights|özel hakları]] olanların oluÅturabilmeleri için kilitlenmiÅtir.'''\nSon günlük girdisi referans amaçlı aÅaÄıda verilmiÅtir:",
"templatesused": "Bu sayfada kullanılan {{PLURAL:$1|Åablon|Åablonlar}}:",
"templatesusedpreview": "Bu önizlemede kullanılan {{PLURAL:$1|Åablon|Åablonlar}}:",
@@ -787,8 +798,10 @@
"permissionserrors": "İzin hatası",
"permissionserrorstext": "AÅaÄıdaki {{PLURAL:$1|sebep|sebepler}}den dolayı, bunu yapmaya yetkiniz yok:",
"permissionserrorstext-withaction": "AÅaÄıdaki {{PLURAL:$1|neden|nedenler}}den dolayı $2 yetkiniz yok:",
+ "contentmodelediterror": "Bu revizyonu, içerik modeli $1
olduÄu için düzenleyemezsiniz. $2
sayfasının güncel içerik modelinden farklıdır",
"recreate-moveddeleted-warn": "Uyarı: Daha önceden silinmiÅ bir sayfayı tekrar oluÅturuyorsunuz.\n\nBu sayfayı düzenlemeye devam etmenin uygun olup olmadıÄını düÅünmelisiniz.\nBu sayfanın silme ve taÅıma günlüÄü kolaylık için burada verilmiÅtir:",
"moveddeleted-notice": "Bu sayfa silinmiÅ.\nSayfanın silme, koruma ve taÅıma kaydı referans için aÅaÄıda verilmiÅtir.",
+ "moveddeleted-notice-recent": "Ãzgünüz, bu sayfa yakın zamanda silinmiÅtir (son 24 saat içinde).\nSayfa için silme, koruma ve taÅıma kaydı referans amacıyla aÅaÄıda verilmiÅtir.",
"log-fulllog": "Tam günlüÄü gör",
"edit-hook-aborted": "DeÄiÅiklik çengelle durduruldu.\nBir açıklama verilmedi.",
"edit-gone-missing": "Sayfa güncellenemiyor.\nSilinmiŠgörünüyor.",
@@ -815,6 +828,7 @@
"content-json-empty-object": "BoÅ nesne",
"content-json-empty-array": "BoÅ dizi",
"deprecated-self-close-category": "KendiliÄinden geçersiz HTML etiketlerini kullanan sayfalar",
+ "deprecated-self-close-category-desc": "Sayfa, <b/>
veya <span/>
gibi kendiliÄinden geçersiz HTML etiketleri içeriyor. Bunların davranıÅları yakında HTML5 belirtimiyle tutarlı olacak Åekilde deÄiÅecektir, bu nedenle wikitext'deki kullanımları, kullanımdan kaldırılır.",
"duplicate-args-warning": "Uyarı:[[:$1]] [[:$2]] Åablonunu \"$3\" parametresi için birden fazla deÄerle çaÄırıyor. Sadece saÄlanan son deÄer kullanılacak.",
"duplicate-args-category": "Yinelenen Åablon deÄiÅkenleri kullanan sayfalar",
"duplicate-args-category-desc": "Sayfada içeren Åablonları çaÄırmak için bu terimler kullanılır
or
.",
@@ -826,6 +840,8 @@
"post-expand-template-argument-category": "Geçersiz Åablon deÄiÅtirgenleri içeren sayfalar",
"parser-template-loop-warning": "Åablon düÄümü tespit edildi: [[$1]]",
"template-loop-category": "Åablon döngülü sayfalar",
+ "template-loop-category-desc": "Sayfa bir Åablon döngüsü içermektedir. ÃrneÄin, kendini sürekli olarak çaÄıran bir Åablon.",
+ "template-loop-warning": "Uyarı: Bu sayfa, bir Åablon döngüsüne (sonsuz yinelemeli çaÄrı) neden olan [[:$1]] Åablonunu çaÄırmaktadır.",
"parser-template-recursion-depth-warning": "Åablon özyineleme yoÄunluÄu sınırı aÅıldı ($1)",
"language-converter-depth-warning": "Dil çevirici derinlik sınırı aÅıldı ($1)",
"node-count-exceeded-category": "DüÄüm sayısı aÅılan sayfalar",
@@ -836,6 +852,7 @@
"expansion-depth-exceeded-warning": "Sayfa geniÅletme derinliÄi aÅıldı",
"parser-unstrip-loop-warning": "Yineleme döngüsü algılandı",
"unstrip-depth-warning": "($1) yineleme sınırı aÅıldı",
+ "unstrip-depth-category": "Sızıntı derinliÄi sınırının aÅıldıÄı sayfalar",
"converter-manual-rule-error": "Elle yapılandırma dil dönüÅüm kuralı hatası tespit edildi",
"undo-success": "Bu deÄiÅiklik geri alınabilir. Lütfen aÅaÄıdaki karÅılaÅtırmayı kontrol edin, gerçekten bu deÄiÅikliÄi yapmak istediÄinizden emin olun ve sayfayı kaydederek bir önceki deÄiÅikliÄi geriye alın.",
"undo-failure": "DeÄiÅikliklerin çakıÅması nedeniyle geri alma iÅlemi baÅarısız oldu.",
diff --git a/languages/i18n/yi.json b/languages/i18n/yi.json
index 25b82770d7..edde6a15fe 100644
--- a/languages/i18n/yi.json
+++ b/languages/i18n/yi.json
@@ -624,7 +624,7 @@
"previewerrortext": "× ×¤×¢×ער ××× ×¤×ס××¨× ×××× ×¤×¨××××¨× ×¤×ר××סק××§× ×ײַערע ×¢× ×ער×× ××¢×.",
"blockedtitle": "××Ö·× ×צער ××× ×××ק×ר×",
"blockedtext": "'''×××ער ××× ×צער × ×××¢× ××ער IP ××רעס ××× ××¢××××¨× ×××ק×ר×.'''\n\n××¢× ×××ק ××× $1 ××¢×××× ×¤×× ×××¢×× ''$2''.\n\n* ×××ק××¨× ××××× ××: $8\n* ×××ק××¨× ×××× ×××ס: $6\n* ×××ק ××××× ×¦×: $7\n\n××ר ×§×¢× × ××× ×××¢× ×× ×¦× $1 ××ער ×¦× ×× ×ערע [[{{MediaWiki:Grouppage-sysop}}|××××× ×ס×ר×××ר×]] ×××ר×צ×רע×× ××¢× ×××ק.\n\n××× ××× ×× ××ר ×§×¢× × × ××©× × ××¦× ×× \"ש××§× ××¢× ××× ×צער × ×¢-פ×ס×\" ××××× ×§××× ×××× ××× ××ר × ××©× ×××× ×עש××¢×× ××× ×××ערע [[Special:Preferences|ק×× ××¢ ×¤×¨×¢×¤×¢×¨×¢× ×¦×]] × ××××××§× ×××צפ××¡× ××רעס××ס ××ער ××ר ××¢× × ×××ק××¨× ×¤×× ×©××§× ×××צפ×ס×.\n\n×××ער IP ××רעס ××× $3, ××× ×ער ×××ק ××× × ××ער #$5. ××××¢ ש××§× ×××× ×¢× ×¤×× ×× ×¦×××× (××ער ××× ×××××¢) ×××¢× ××ר ×××¢× ×× ××× ×¦× ×× ××××× ×ס×ר×××ר×.",
- "autoblockedtext": "×ײַער [[IP ××רעס|×ײַ־פּ×Ö¾×Ö·×רעס]] ××× ×××ָק××¨× ××¢×°×Ö¸×¨× ××±××Ö¸××Ö·××ש, צ×××× ××¢× ×°×ָס ×Ö·× ×Ö·× ×ער ××Ö·× ×צער ×°×ָס ××× ×××ָק××¨× ××¢×°×Ö¸×¨× ×××¨× $1 ××Ö¸× ××× ××¢× ××¦× ××¢× ××Ö¸×××§× ×ײַ־פּ×.\n×× ××ר××Ö·× ×¤Ö¿×× ×ער ×××ָק×ר×× × ×××:\n\n:'''$2'''\n\n* ×× ×××× ×¤×× ×ער ×××ק×ר×× ×: $8\n* ×¢× ××¢ פ×× ×ער ×××ָק×ר×× ×: $6\n* ×××¢××¢× ×××ק×ר×: Ö´$7\n\n××ר ×§×¢× × ××× ×¤Ö¿×ַר××× ×× ××ר×× ×××צ×ר××° ××× $1 ×Ö¸×ער ××× ××¢×× ×Ö·× ××¢×¨× [[{{MediaWiki:Grouppage-sysop}}|ס×ס×ָפּ]] ×¦× ××סק××××¨× ×°×¢×× ×ער ×××ָק×ר×× ×.\n\n××±× ××Ö¸× ××ר × ×× ×Ö·×¨×²Ö·× ×עק××Ö·×¤Ö¼× ×ײַער ×××צפּ×ָס×Ö¾×Ö·×רעס ××× ×ײַערע [[Special:Preferences|×¤Ö¼×¨×¢×¤Ö¿×¢×¨×¢× ×¦×]] ××ער ××ר ××¢× × ×××ק××¨× ×¤×× ×©××§× ×××צפ×ס×, ×§×¢× × ××ר ××× ''× ×ש×'' × ××¦× ×× ×פצ××¢ \"ש××§× ××¢× ××× ×צער ×× ×¢-פ×ס×\".\n\n×××ער ×עצ×××ער IP ××רעס ××× $3, ××× ×ער ×××ָק×ר×× ×Ö¾× ××ער ××× #$5.\n××××¢ צײ×× × ×¢×¡ ×Ö¸× ×שעת ××ר ×°×¢× ×× ××× ×¦× ×× ×¡×ס×ָפּ×.",
+ "autoblockedtext": "×ײַער IP ××רעס ××× ×××ָק××¨× ××¢×°×Ö¸×¨× ××±××Ö¸××Ö·××ש, צ×××× ××¢× ×°×ָס ×Ö·× ×Ö·× ×ער ××Ö·× ×צער ×°×ָס ××× ×××ָק××¨× ××¢×°×Ö¸×¨× ×××¨× $1 ××Ö¸× ××× ××¢× ××¦× ××¢× ××Ö¸×××§× ×ײַ־פּ×.\n×× ××ר××Ö·× ×¤Ö¿×× ×ער ×××ָק×ר×× × ×××:\n\n:$2\n\n* ×× ×××× ×¤×× ×ער ×××ק×ר×× ×: $8\n* ×¢× ××¢ פ×× ×ער ×××ָק×ר×× ×: $6\n* ×××¢××¢× ×××ק×ר×: Ö´$7\n\n××ר ×§×¢× × ××× ×¤Ö¿×ַר××× ×× ××ר×× ×××צ×ר××° ××× $1 ×Ö¸×ער ××× ××¢×× ×Ö·× ××¢×¨× [[{{MediaWiki:Grouppage-sysop}}|ס×ס×ָפּ]] ×¦× ××סק××××¨× ×°×¢×× ×ער ×××ָק×ר×× ×.\n\n××ר ×××¨× × ××©× × ××¦× ×× \"{{int:emailuser}}\" פֿ×× ×§×¦××¢ × ×ר ×××¢× ××ר ××× × ××××××× ×¢Ö¾×¤××¡× ××רעס ×××× ×עשר××× ××× ×××ערע [[Special:Preferences|××× ×צער ×¤×¨×¢×¤Ö¿×¢×¨×¢× ×¦×]] ××× ××ר ××¢× × × ××©× ××¢××××¨× ×××ק××¨× ×¤×× × ××¦× ×××.\n\n×××ער ×עצ×××ער IP ××רעס ××× $3, ××× ×ער ×××ָק×ר×× ×Ö¾× ××ער ××× #$5.\n××××¢ צײ×× × ×¢×¡ ×Ö¸× ×שעת ××ר ×°×¢× ×× ××× ×¦× ×× ×¡×ס×ָפּ×.",
"blockednoreason": "ק××× ××¢× × ××©× ××¢××¢××",
"whitelistedittext": "××ר ×ר×××× ×¦× $1 ×¦× ×¢× ××¢×¨× ×××¢×ער.",
"confirmedittext": "××××£ ×××× ×××× ×§××× ×× ×¤Ö¿×××× ×¦× ××ש××¢×××× ×××ער ע־פ××¡× ××רעס ××××ער ××ר רע××ַק×××¨× ×××¢×ער.\n××××¢ ש××¢×× ××× ××ש××¢×××× ×××ער ע־פ××¡× ××רעס ×××¨× ×××ערע [[Special:Preferences|××Ö·× ×צער ×¤×¨×¢×¤Ö¿×¢×¨×¢× ×¦×]] .",
@@ -1365,7 +1365,7 @@
"recentchangeslinked-feed": "פֿ×ַר××× ××¢× ×¢ ×¢× ×ער×× ××¢×",
"recentchangeslinked-toolbox": "פֿ×ַר××× ××¢× ×¢ ×¢× ×ער×× ××¢×",
"recentchangeslinked-title": "×¢× ×ער×× ××¢× ×¤Ö¿×ר××× ×× ××× $1",
- "recentchangeslinked-summary": "××× ×ר××× × ××××× ×××¢× ×¦× ××¢× ×¢× ×ער×× ××¢× ×¦× ×××¢×ער פ×ר××× ×× ×¦× ××ער פ×× ××¢× ×¢× ××××. (×¦× ××¢× ××××××× ×××¢×ער פ×× × ×§×××¢××ר××¢ ××× ×ר××× ×´×§×××¢××ר××¢:× ×××¢× ×¤×× ×§×××¢××ר××¢×´). ×¢× ×ער×× ××¢× ×¦× ×××¢×ער ××××£ [[Special:Watchlist|×××ער ×××פפ×ס×× × ××ס××¢]] ××¢× ×¢× ××¢××××× ××ק.",
+ "recentchangeslinked-summary": "××× ×ר××× × ××××× ×××¢× ×¦× ××¢× ×¢× ×ער×× ××¢× ×¦× ×××¢×ער פ×ר××× ×× ×¦× ××ער פ×× ××¢× ×¢× ××××. (×¦× ××¢× ××××××× ×××¢×ער פ×× × ×§×××¢××ר××¢ ××× ×ר××× ×´{{ns:category}}:× ×××¢× ×¤×× ×§×××¢××ר××¢×´). ×¢× ×ער×× ××¢× ×¦× ×××¢×ער ××××£ [[Special:Watchlist|×××ער ×××פפ×ס×× × ××ס××¢]] ××¢× ×¢× ××¢××××× ××ק.",
"recentchangeslinked-page": "×××Ö·× × ×Ö¸××¢×:",
"recentchangeslinked-to": "צ××× ×¢× ×ער×× ××¢× ×¦× ×××¢×ער פ×ר××× ×× ×¦× ××¢× ×××× ×× ×©×××",
"recentchanges-page-added-to-category": "[[:$1]] צ×××¢××××× ×¦× ×§×××¢××ר××¢",
diff --git a/languages/messages/MessagesKo.php b/languages/messages/MessagesKo.php
index 42cc676e1f..5db206237d 100644
--- a/languages/messages/MessagesKo.php
+++ b/languages/messages/MessagesKo.php
@@ -78,6 +78,7 @@ $specialPageAliases = [
'Allpages' => [ '모ë 문ì' ],
'ApiHelp' => [ 'Apiëìë§' ],
'Ancientpages' => [ 'ì¤ëë문ì' ],
+ 'AutoblockList' => [ 'ìëì°¨ë¨ëª©ë¡' ],
'Badtitle' => [ 'ì못ëì 목', 'ì¸ìë¶ê°ì 목', 'ì못ëì´ë¦', 'ì¸ìë¶ê°ì´ë¦' ],
'Blankpage' => [ 'ë¹ë¬¸ì' ],
'Block' => [ 'ì°¨ë¨', 'IPì°¨ë¨', 'ì¬ì©ìì°¨ë¨' ],
@@ -113,7 +114,7 @@ $specialPageAliases = [
'LinkSearch' => [ 'ë§í¬ê²ì', 'ë§í¬ì°¾ê¸°' ],
'Listadmins' => [ 'ê´ë¦¬ì', 'ê´ë¦¬ì목ë¡' ],
'Listbots' => [ 'ë´', 'ë´ëª©ë¡' ],
- 'Listfiles' => [ 'íì¼', '그림', 'íì¼ëª©ë¡', '그림목ë¡' ],
+ 'Listfiles' => [ 'íì¼ëª©ë¡', '그림목ë¡', 'íì¼', '그림' ],
'Listgrouprights' => [ 'ì¬ì©ìê¶í목ë¡', 'ì¬ì©ìê¶í', 'ê¶í목ë¡' ],
'Listgrants' => [ 'ê¶íë¶ì¬ëª©ë¡' ],
'Listredirects' => [ 'ë겨주기목ë¡' ],
@@ -142,7 +143,9 @@ $specialPageAliases = [
'Newimages' => [ 'ìíì¼', 'ì그림' ],
'Newpages' => [ 'ì문ì' ],
'PagesWithProp' => [ 'ìì±ë³ë¬¸ì' ],
+ 'PageData' => [ '문ìë°ì´í°' ],
'PageLanguage' => [ '문ìì¸ì´' ],
+ 'PasswordPolicies' => [ 'ë¹ë°ë²í¸ì ì±
' ],
'PasswordReset' => [ 'ë¹ë°ë²í¸ì¬ì¤ì ', 'ë¹ë°ë²í¸ì´ê¸°í' ],
'PermanentLink' => [ 'ê³ ì ë§í¬', 'ì구ë§í¬' ],
'Preferences' => [ 'íê²½ì¤ì ' ],
diff --git a/languages/messages/MessagesZgh.php b/languages/messages/MessagesZgh.php
new file mode 100644
index 0000000000..720b591a5a
--- /dev/null
+++ b/languages/messages/MessagesZgh.php
@@ -0,0 +1,11 @@
+getID();
$content = $revision->getContent( Revision::RAW );
- $id = $id ? $id : '';
+ $id = $id ?: '';
if ( $content === null ) {
echo "Revision $id is broken, we have no content available\n";
diff --git a/maintenance/storage/recompressTracked.php b/maintenance/storage/recompressTracked.php
index 49b8e0a69d..271cbf3dd6 100644
--- a/maintenance/storage/recompressTracked.php
+++ b/maintenance/storage/recompressTracked.php
@@ -226,7 +226,7 @@ class RecompressTracked {
}
$cmd .= ' --child' .
' --wiki ' . wfEscapeShellArg( wfWikiID() ) .
- ' ' . call_user_func_array( 'wfEscapeShellArg', $this->destClusters );
+ ' ' . wfEscapeShellArg( ...$this->destClusters );
$this->replicaPipes = $this->replicaProcs = [];
for ( $i = 0; $i < $this->numProcs; $i++ ) {
@@ -426,12 +426,12 @@ class RecompressTracked {
$args = array_slice( $ids, 0, $this->orphanBatchSize );
$ids = array_slice( $ids, $this->orphanBatchSize );
array_unshift( $args, 'doOrphanList' );
- call_user_func_array( [ $this, 'dispatch' ], $args );
+ $this->dispatch( ...$args );
}
if ( count( $ids ) ) {
$args = $ids;
array_unshift( $args, 'doOrphanList' );
- call_user_func_array( [ $this, 'dispatch' ], $args );
+ $this->dispatch( ...$args );
}
$this->report( 'orphans', $i, $numOrphans );
diff --git a/package.json b/package.json
index 2d425dd62e..36328e0a85 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"qunit": "grunt qunit",
"doc": "jsduck",
"postdoc": "grunt copy:jsduck",
- "selenium": "./tests/selenium/selenium.sh",
+ "selenium": "bash ./tests/selenium/selenium.sh",
"selenium-test": "wdio ./tests/selenium/wdio.conf.js"
},
"devDependencies": {
diff --git a/profileinfo.php b/profileinfo.php
index 9ebd57b7a2..8bd37dd4cb 100644
--- a/profileinfo.php
+++ b/profileinfo.php
@@ -396,8 +396,8 @@ if ( isset( $_REQUEST['filter'] ) ) {
return htmlspecialchars(
'?' .
wfArrayToCgi( [
- 'filter' => $_filter ? $_filter : $filter,
- 'sort' => $_sort ? $_sort : $sort,
+ 'filter' => $_filter ?: $filter,
+ 'sort' => $_sort ?: $sort,
'expand' => implode( ',', array_keys( $_expand ) )
] )
);
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
index 09d223e584..11972de06c 100644
--- a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
+++ b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
@@ -5,7 +5,7 @@
@rcfilters-spinner-size: 12px;
@rcfilters-head-min-height: 210px;
@rcfilters-head-margin-bottom: 20px;
-@rcfilters-wl-head-min-height: 300px;
+@rcfilters-wl-head-min-height: 270px;
// Corrections for the standard special page
.client-js {
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js
index 060ead02d7..c13c2f79ac 100644
--- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js
@@ -56,7 +56,7 @@
} ),
new OO.ui.MenuOptionWidget( {
data: 'delete',
- icon: 'close',
+ icon: 'trash',
label: mw.msg( 'rcfilters-savedqueries-remove' )
} ),
new OO.ui.MenuOptionWidget( {
diff --git a/resources/src/mediawiki.ui/components/inputs.less b/resources/src/mediawiki.ui/components/inputs.less
index bbfd528204..4b8b1ee2ac 100644
--- a/resources/src/mediawiki.ui/components/inputs.less
+++ b/resources/src/mediawiki.ui/components/inputs.less
@@ -103,7 +103,6 @@ textarea.mw-ui-input {
//
//
// Styleguide 1.2.
-input[ type='number' ],
.mw-ui-input-inline {
display: inline-block;
width: auto;
diff --git a/tests/common/TestsAutoLoader.php b/tests/common/TestsAutoLoader.php
index a79867913e..2cc56419e6 100644
--- a/tests/common/TestsAutoLoader.php
+++ b/tests/common/TestsAutoLoader.php
@@ -184,6 +184,10 @@ $wgAutoloadClasses += [
=> "$testDir/phpunit/mocks/session/DummySessionBackend.php",
'DummySessionProvider' => "$testDir/phpunit/mocks/session/DummySessionProvider.php",
'MockMessageLocalizer' => "$testDir/phpunit/mocks/MockMessageLocalizer.php",
+ 'MockCompletionSearchEngine' => "$testDir/phpunit/mocks/search/MockCompletionSearchEngine.php",
+ 'MockSearchEngine' => "$testDir/phpunit/mocks/search/MockSearchEngine.php",
+ 'MockSearchResultSet' => "$testDir/phpunit/mocks/search/MockSearchResultSet.php",
+ 'MockSearchResult' => "$testDir/phpunit/mocks/search/MockSearchResult.php",
# tests/suites
'ParserTestFileSuite' => "$testDir/phpunit/suites/ParserTestFileSuite.php",
diff --git a/tests/parser/DjVuSupport.php b/tests/parser/DjVuSupport.php
index 73d4a47f82..eede54e0f2 100644
--- a/tests/parser/DjVuSupport.php
+++ b/tests/parser/DjVuSupport.php
@@ -31,10 +31,10 @@ class DjVuSupport {
public function __construct() {
global $wgDjvuRenderer, $wgDjvuDump, $wgDjvuToXML, $wgFileExtensions, $wgDjvuTxt;
- $wgDjvuRenderer = $wgDjvuRenderer ? $wgDjvuRenderer : '/usr/bin/ddjvu';
- $wgDjvuDump = $wgDjvuDump ? $wgDjvuDump : '/usr/bin/djvudump';
- $wgDjvuToXML = $wgDjvuToXML ? $wgDjvuToXML : '/usr/bin/djvutoxml';
- $wgDjvuTxt = $wgDjvuTxt ? $wgDjvuTxt : '/usr/bin/djvutxt';
+ $wgDjvuRenderer = $wgDjvuRenderer ?: '/usr/bin/ddjvu';
+ $wgDjvuDump = $wgDjvuDump ?: '/usr/bin/djvudump';
+ $wgDjvuToXML = $wgDjvuToXML ?: '/usr/bin/djvutoxml';
+ $wgDjvuTxt = $wgDjvuTxt ?: '/usr/bin/djvutxt';
if ( !in_array( 'djvu', $wgFileExtensions ) ) {
$wgFileExtensions[] = 'djvu';
diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt
index b109e3967d..afddd78553 100644
--- a/tests/parser/parserTests.txt
+++ b/tests/parser/parserTests.txt
@@ -24649,6 +24649,17 @@ abc
abc
abcdef +abcdef +
+!! end + !!test Special parser function !! wikitext diff --git a/tests/phan/config.php b/tests/phan/config.php index 5f712876c8..61d86bd658 100644 --- a/tests/phan/config.php +++ b/tests/phan/config.php @@ -305,8 +305,6 @@ return [ "PhanDeprecatedProperty", // approximate error count: 17 "PhanNonClassMethodCall", - // approximate error count: 11 - "PhanParamReqAfterOpt", // approximate error count: 888 "PhanParamSignatureMismatch", // approximate error count: 7 diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 6bcbd938d8..5fddc3d71b 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -1023,7 +1023,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { * Should be called from addDBData(). * * @since 1.25 ($namespace in 1.28) - * @param string|title $pageName Page name or title + * @param string|Title $pageName Page name or title * @param string $text Page's content * @param int $namespace Namespace id (name cannot already contain namespace) * @return array Title object and page id diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index f9e2cc1733..4c508e3851 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -1,6 +1,5 @@ hideDeprecated( 'LinkBegin hook (used in hook-LinkBegin-closure)' ); $this->setMwGlobals( [ 'wgArticlePath' => '/wiki/$1', 'wgServer' => '//example.org', @@ -417,6 +417,7 @@ class LinkerTest extends MediaWikiLangTestCase { * @dataProvider provideLinkEndHook */ public function testLinkEndHook( $callback, $expected ) { + $this->hideDeprecated( 'LinkEnd hook (used in hook-LinkEnd-closure)' ); $this->setMwGlobals( [ 'wgArticlePath' => '/wiki/$1', ] ); @@ -427,54 +428,4 @@ class LinkerTest extends MediaWikiLangTestCase { $out = Linker::link( $title ); $this->assertEquals( $expected, $out ); } - - /** - * @covers Linker::getLinkColour - */ - public function testGetLinkColour() { - $this->hideDeprecated( 'Linker::getLinkColour' ); - $linkCache = MediaWikiServices::getInstance()->getLinkCache(); - $foobarTitle = Title::makeTitle( NS_MAIN, 'FooBar' ); - $redirectTitle = Title::makeTitle( NS_MAIN, 'Redirect' ); - $userTitle = Title::makeTitle( NS_USER, 'Someuser' ); - $linkCache->addGoodLinkObj( - 1, // id - $foobarTitle, - 10, // len - 0 // redir - ); - $linkCache->addGoodLinkObj( - 2, // id - $redirectTitle, - 10, // len - 1 // redir - ); - - $linkCache->addGoodLinkObj( - 3, // id - $userTitle, - 10, // len - 0 // redir - ); - - $this->assertEquals( - '', - Linker::getLinkColour( $foobarTitle, 0 ) - ); - - $this->assertEquals( - 'stub', - Linker::getLinkColour( $foobarTitle, 20 ) - ); - - $this->assertEquals( - 'mw-redirect', - Linker::getLinkColour( $redirectTitle, 0 ) - ); - - $this->assertEquals( - '', - Linker::getLinkColour( $userTitle, 20 ) - ); - } } diff --git a/tests/phpunit/includes/MediaWikiTest.php b/tests/phpunit/includes/MediaWikiTest.php index a8d1e33950..7d7e637673 100644 --- a/tests/phpunit/includes/MediaWikiTest.php +++ b/tests/phpunit/includes/MediaWikiTest.php @@ -154,4 +154,53 @@ class MediaWikiTest extends MediaWikiTestCase { $context->getOutput()->getRedirect() ); } + + /** + * Test a post-send job can not set cookies (T191537). + */ + public function testPostSendJobDoesNotSetCookie() { + // Prevent updates from running + $this->setMwGlobals( 'wgCommandLineMode', false ); + + $response = new WebResponse; + + // A job that attempts to set a cookie + $jobHasRun = false; + DeferredUpdates::addCallableUpdate( function () use ( $response, &$jobHasRun ) { + $jobHasRun = true; + $response->setCookie( 'JobCookie', 'yes' ); + $response->header( 'Foo: baz' ); + } ); + + $hookWasRun = false; + $this->setTemporaryHook( 'WebResponseSetCookie', function () use ( &$hookWasRun ) { + $hookWasRun = true; + return true; + } ); + + $logger = new TestLogger(); + $logger->setCollect( true ); + $this->setLogger( 'cookie', $logger ); + $this->setLogger( 'header', $logger ); + + $mw = new MediaWiki(); + $mw->doPostOutputShutdown(); + // restInPeace() might have been registered to a callback of + // register_postsend_function() and thus can not be triggered from + // PHPUnit. + if ( $jobHasRun === false ) { + $mw->restInPeace(); + } + + $this->assertTrue( $jobHasRun, 'post-send job has run' ); + $this->assertFalse( $hookWasRun, + 'post-send job must not trigger WebResponseSetCookie hook' ); + $this->assertEquals( + [ + [ 'info', 'ignored post-send cookie {cookie}' ], + [ 'info', 'ignored post-send header {header}' ], + ], + $logger->getBuffer() + ); + } } diff --git a/tests/phpunit/includes/Storage/RevisionStoreTest.php b/tests/phpunit/includes/Storage/RevisionStoreTest.php index 3749f294bf..61d0512542 100644 --- a/tests/phpunit/includes/Storage/RevisionStoreTest.php +++ b/tests/phpunit/includes/Storage/RevisionStoreTest.php @@ -29,9 +29,9 @@ class RevisionStoreTest extends MediaWikiTestCase { $WANObjectCache = null ) { return new RevisionStore( - $loadBalancer ? $loadBalancer : $this->getMockLoadBalancer(), - $blobStore ? $blobStore : $this->getMockSqlBlobStore(), - $WANObjectCache ? $WANObjectCache : $this->getHashWANObjectCache(), + $loadBalancer ?: $this->getMockLoadBalancer(), + $blobStore ?: $this->getMockSqlBlobStore(), + $WANObjectCache ?: $this->getHashWANObjectCache(), MediaWikiServices::getInstance()->getCommentStore(), MediaWikiServices::getInstance()->getActorMigration() ); diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index 4e342447c4..6600aa23c7 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -842,18 +842,23 @@ class TitlePermissionTest extends MediaWikiLangTestCase { * @covers Title::checkUserBlock */ public function testUserBlock() { - global $wgEmailConfirmToEdit, $wgEmailAuthentication; - $wgEmailConfirmToEdit = true; - $wgEmailAuthentication = true; + $this->setMwGlobals( [ + 'wgEmailConfirmToEdit' => true, + 'wgEmailAuthentication' => true, + ] ); $this->setUserPerm( [ "createpage", "move" ] ); $this->setTitle( NS_HELP, "test page" ); - # $short - $this->assertEquals( [ [ 'confirmedittext' ] ], + # $wgEmailConfirmToEdit only applies to 'edit' action + $this->assertEquals( [], $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $wgEmailConfirmToEdit = false; - $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) ); + $this->assertContains( [ 'confirmedittext' ], + $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); + + $this->setMwGlobals( 'wgEmailConfirmToEdit', false ); + $this->assertNotContains( [ 'confirmedittext' ], + $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' $this->assertEquals( [], diff --git a/tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php b/tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php new file mode 100644 index 0000000000..749f154604 --- /dev/null +++ b/tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php @@ -0,0 +1,58 @@ +setMwGlobals( [ + 'wgSearchType' => MockCompletionSearchEngine::class, + ] ); + MockCompletionSearchEngine::clearMockResults(); + $results = []; + foreach ( range( 0, 10 ) as $i ) { + $title = "Search_Result_$i"; + $results[] = $title; + $this->editPage( $title, 'hi there' ); + } + MockCompletionSearchEngine::addMockResults( self::TEST_QUERY, $results ); + } + + public function offsetContinueProvider() { + return [ + 'no offset' => [ 2, 2, 0, 2 ], + 'with offset' => [ 7, 2, 5, 2 ], + 'past end, no offset' => [ null, 11, 0, 20 ], + 'past end, with offset' => [ null, 5, 6, 10 ], + ]; + } + + /** + * @dataProvider offsetContinueProvider + */ + public function testOffsetContinue( $expectedOffset, $expectedResults, $offset, $limit ) { + $response = $this->doApiRequest( [ + 'action' => 'query', + 'list' => 'prefixsearch', + 'pssearch' => self::TEST_QUERY, + 'psoffset' => $offset, + 'pslimit' => $limit, + ] ); + $result = $response[0]; + $this->assertArrayNotHasKey( 'warnings', $result ); + $suggestions = $result['query']['prefixsearch']; + $this->assertCount( $expectedResults, $suggestions ); + if ( $expectedOffset == null ) { + $this->assertArrayNotHasKey( 'continue', $result ); + } else { + $this->assertArrayHasKey( 'continue', $result ); + $this->assertEquals( $expectedOffset, $result['continue']['psoffset'] ); + } + } +} diff --git a/tests/phpunit/includes/api/ApiQuerySearchTest.php b/tests/phpunit/includes/api/ApiQuerySearchTest.php new file mode 100644 index 0000000000..0700cf77de --- /dev/null +++ b/tests/phpunit/includes/api/ApiQuerySearchTest.php @@ -0,0 +1,109 @@ + [ [], [] ], + 'has search results' => [ + [ 'Zomg' ], + [ $this->mockResult( 'Zomg' ) ], + ], + 'filters broken search results' => [ + [ 'A', 'B' ], + [ + $this->mockResult( 'a' ), + $this->mockResult( 'Zomg' )->setBrokenTitle( true ), + $this->mockResult( 'b' ), + ], + ], + 'filters results with missing revision' => [ + [ 'B', 'A' ], + [ + $this->mockResult( 'Zomg' )->setMissingRevision( true ), + $this->mockResult( 'b' ), + $this->mockResult( 'a' ), + ], + ], + ]; + } + + /** + * @dataProvider provideSearchResults + */ + public function testSearchResults( $expect, $hits, array $params = [] ) { + MockSearchEngine::addMockResults( 'my query', $hits ); + list( $response, $request ) = $this->doApiRequest( $params + [ + 'action' => 'query', + 'list' => 'search', + 'srsearch' => 'my query', + ] ); + $titles = []; + foreach ( $response['query']['search'] as $result ) { + $titles[] = $result['title']; + } + $this->assertEquals( $expect, $titles ); + } + + public function provideInterwikiResults() { + return [ + 'empty' => [ [], [] ], + 'one wiki response' => [ + [ 'utwiki' => [ 'Qwerty' ] ], + [ + SearchResultSet::SECONDARY_RESULTS => [ + 'utwiki' => new MockSearchResultSet( [ + $this->mockResult( 'Qwerty' )->setInterwikiPrefix( 'utwiki' ), + ] ), + ], + ] + ], + ]; + } + + /** + * @dataProvider provideInterwikiResults + */ + public function testInterwikiResults( $expect, $hits, array $params = [] ) { + MockSearchEngine::setMockInterwikiResults( $hits ); + list( $response, $request ) = $this->doApiRequest( $params + [ + 'action' => 'query', + 'list' => 'search', + 'srsearch' => 'my query', + 'srinterwiki' => true, + ] ); + if ( !$expect ) { + $this->assertArrayNotHasKey( 'interwikisearch', $response['query'] ); + return; + } + $results = []; + $this->assertArrayHasKey( 'interwikisearchinfo', $response['query'] ); + foreach ( $response['query']['interwikisearch'] as $wiki => $wikiResults ) { + $results[$wiki] = []; + foreach ( $wikiResults as $wikiResult ) { + $results[$wiki][] = $wikiResult['title']; + } + } + $this->assertEquals( $expect, $results ); + } + + public function setUp() { + parent::setUp(); + MockSearchEngine::clearMockResults(); + $this->registerMockSearchEngine(); + } + + private function registerMockSearchEngine() { + $this->setMwGlobals( [ + 'wgSearchType' => MockSearchEngine::class, + ] ); + } + + private function mockResult( $title ) { + return MockSearchResult::newFromtitle( Title::newFromText( $title ) ); + } + +} diff --git a/tests/phpunit/includes/db/LBFactoryTest.php b/tests/phpunit/includes/db/LBFactoryTest.php index fac34867d8..82ca66a5fb 100644 --- a/tests/phpunit/includes/db/LBFactoryTest.php +++ b/tests/phpunit/includes/db/LBFactoryTest.php @@ -630,35 +630,41 @@ class LBFactoryTest extends MediaWikiTestCase { '1@542#c47dcfb0566e7d7bc110a6128a45c93a', LBFactory::makeCookieValueFromCPIndex( 1, 542, $agentId ) ); + $this->assertSame( - 5, - LBFactory::getCPInfoFromCookieValue( "5", $time - 10 )['index'], + null, + LBFactory::getCPInfoFromCookieValue( "5#$agentId", $time - 10 )['index'], 'No time set' ); $this->assertSame( null, - LBFactory::getCPInfoFromCookieValue( "0", $time - 10 )['index'], + LBFactory::getCPInfoFromCookieValue( "5@$time", $time - 10 )['index'], + 'No agent set' + ); + $this->assertSame( + null, + LBFactory::getCPInfoFromCookieValue( "0@$time#$agentId", $time - 10 )['index'], 'Bad index' ); $this->assertSame( 2, - LBFactory::getCPInfoFromCookieValue( "2@$time", $time - 10 )['index'], + LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time - 10 )['index'], 'Fresh' ); $this->assertSame( 2, - LBFactory::getCPInfoFromCookieValue( "2@$time", $time + 9 - 10 )['index'], + LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time + 9 - 10 )['index'], 'Almost stale' ); $this->assertSame( null, - LBFactory::getCPInfoFromCookieValue( "0@$time", $time + 9 - 10 )['index'], + LBFactory::getCPInfoFromCookieValue( "0@$time#$agentId", $time + 9 - 10 )['index'], 'Almost stale; bad index' ); $this->assertSame( null, - LBFactory::getCPInfoFromCookieValue( "2@$time", $time + 11 - 10 )['index'], + LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time + 11 - 10 )['index'], 'Stale' ); @@ -669,7 +675,7 @@ class LBFactoryTest extends MediaWikiTestCase { ); $this->assertSame( null, - LBFactory::getCPInfoFromCookieValue( "5@$time", $time + 11 - 10 )['clientId'], + LBFactory::getCPInfoFromCookieValue( "5@$time#$agentId", $time + 11 - 10 )['clientId'], 'Stale (client ID)' ); } diff --git a/tests/phpunit/includes/linker/LinkRendererTest.php b/tests/phpunit/includes/linker/LinkRendererTest.php index 6d096c208b..c758ba62ee 100644 --- a/tests/phpunit/includes/linker/LinkRendererTest.php +++ b/tests/phpunit/includes/linker/LinkRendererTest.php @@ -131,6 +131,11 @@ class LinkRendererTest extends MediaWikiLangTestCase { . '(page does not exist)">', $linkRenderer->makeLink( $foobar, new HtmlArmor( '' ) ) ); + + $this->assertEquals( + 'fragment', + $linkRenderer->makeLink( Title::newFromText( '#fragment' ) ) + ); } public function testGetLinkClasses() { diff --git a/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php b/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php index 4d98773890..fa4d804ee8 100644 --- a/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php +++ b/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php @@ -103,11 +103,6 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase { $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' ); } - /** - * Seems to fail sometimes (T176097). - * - * @group Broken - */ public function testGetBlobCached() { $module = $this->makeModule( [ 'example' ] ); $rl = new ResourceLoader(); diff --git a/tests/phpunit/includes/search/SearchEnginePrefixTest.php b/tests/phpunit/includes/search/SearchEnginePrefixTest.php index 3f59295ab6..83df61a4bc 100644 --- a/tests/phpunit/includes/search/SearchEnginePrefixTest.php +++ b/tests/phpunit/includes/search/SearchEnginePrefixTest.php @@ -45,6 +45,9 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { $this->insertPage( 'Talk:Example' ); $this->insertPage( 'User:Example' ); + $this->insertPage( 'Barcelona' ); + $this->insertPage( 'Barbara' ); + $this->insertPage( 'External' ); } protected function setUp() { @@ -238,7 +241,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { ], ] ], [ [ - 'Exact match not on top (T72958)', + 'Exact match not in first result should be moved to the first result (T72958)', 'provision' => [ 'Barcelona', 'Bar', @@ -252,7 +255,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { ], ] ], [ [ - 'Exact match missing (T72958)', + 'Exact match missing from results should be added as first result (T72958)', 'provision' => [ 'Barcelona', 'Barbara', @@ -266,7 +269,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { ], ] ], [ [ - 'Exact match missing and not existing', + 'Exact match missing and not existing pages should be dropped', 'provision' => [ 'Exile', 'Exist', @@ -274,8 +277,6 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { ], 'query' => 'Ex', 'results' => [ - 'Exile', - 'Exist', 'External', ], ] ], @@ -329,6 +330,21 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { 'Redirect test', ], ] ], + [ [ + "Extra results must not be returned", + 'provision' => [ + 'Example', + 'Example Bar', + 'Example Foo', + 'Example Foo/Bar' + ], + 'query' => 'foo', + 'results' => [ + 'Example', + 'Example Bar', + 'Example Foo', + ], + ] ], ]; } @@ -337,16 +353,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { * @covers PrefixSearch::searchBackend */ public function testSearchBackend( array $case ) { - $search = $stub = $this->getMockBuilder( SearchEngine::class ) - ->setMethods( [ 'completionSearchBackend' ] )->getMock(); - - $return = SearchSuggestionSet::fromStrings( $case['provision'] ); - - $search->expects( $this->any() ) - ->method( 'completionSearchBackend' ) - ->will( $this->returnValue( $return ) ); - - $search->setLimitOffset( 3 ); + $search = $this->mockSearchWithResults( $case['provision'] ); $results = $search->completionSearch( $case['query'] ); $results = $results->map( function ( SearchSuggestion $s ) { @@ -359,4 +366,43 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase { $case[0] ); } + + public function paginationProvider() { + $res = [ 'Example', 'Example Bar', 'Example Foo', 'Example Foo/Bar' ]; + return [ + 'With less than requested results no pagination' => [ + false, array_slice( $res, 0, 2 ), + ], + 'With same as requested results no pagination' => [ + false, array_slice( $res, 0, 3 ), + ], + 'With extra result returned offer pagination' => [ + true, $res, + ], + ]; + } + + /** + * @dataProvider paginationProvider + */ + public function testPagination( $hasMoreResults, $provision ) { + $search = $this->mockSearchWithResults( $provision ); + $results = $search->completionSearch( 'irrelevant' ); + + $this->assertEquals( $hasMoreResults, $results->hasMoreResults() ); + } + + private function mockSearchWithResults( $titleStrings, $limit = 3 ) { + $search = $stub = $this->getMockBuilder( SearchEngine::class ) + ->setMethods( [ 'completionSearchBackend' ] )->getMock(); + + $return = SearchSuggestionSet::fromStrings( $titleStrings ); + + $search->expects( $this->any() ) + ->method( 'completionSearchBackend' ) + ->will( $this->returnValue( $return ) ); + + $search->setLimitOffset( $limit ); + return $search; + } } diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php index e8077769e1..5884d19343 100644 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ b/tests/phpunit/includes/search/SearchEngineTest.php @@ -84,10 +84,8 @@ class SearchEngineTest extends MediaWikiLangTestCase { $this->assertTrue( is_object( $results ) ); $matches = []; - $row = $results->next(); - while ( $row ) { + foreach ( $results as $row ) { $matches[] = $row->getTitle()->getPrefixedText(); - $row = $results->next(); } $results->free(); # Search is not guaranteed to return results in a certain order; @@ -173,7 +171,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { public function testPhraseSearchHighlight() { $phrase = "smithee is one who smiths"; $res = $this->search->searchText( "\"$phrase\"" ); - $match = $res->next(); + $match = $res->getIterator()->current(); $snippet = "A " . $phrase . ""; $this->assertStringStartsWith( $snippet, $match->getTextSnippet( $res->termMatches() ), @@ -277,7 +275,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'SearchResultsAugment' => [ [ $this, 'addAugmentors' ] ] ] ); $this->search->augmentSearchResults( $resultSet ); - for ( $result = $resultSet->next(); $result; $result = $resultSet->next() ) { + foreach ( $resultSet as $result ) { $id = $result->getTitle()->getArticleID(); $augmentData = "Result:$id:" . $result->getTitle()->getText(); $augmentData2 = "Result2:$id:" . $result->getTitle()->getText(); @@ -292,11 +290,10 @@ class SearchEngineTest extends MediaWikiLangTestCase { ->method( 'augmentAll' ) ->willReturnCallback( function ( SearchResultSet $resultSet ) { $data = []; - for ( $result = $resultSet->next(); $result; $result = $resultSet->next() ) { + foreach ( $resultSet as $result ) { $id = $result->getTitle()->getArticleID(); $data[$id] = "Result:$id:" . $result->getTitle()->getText(); } - $resultSet->rewind(); return $data; } ); $setAugmentors['testSet'] = $setAugmentor; @@ -310,4 +307,37 @@ class SearchEngineTest extends MediaWikiLangTestCase { } ); $rowAugmentors['testRow'] = $rowAugmentor; } + + public function testFiltersMissing() { + $availableResults = []; + foreach ( range( 0, 11 ) as $i ) { + $title = "Search_Result_$i"; + $availableResults[] = $title; + // pages not created must be filtered + if ( $i % 2 == 0 ) { + $this->editPage( $title ); + } + } + MockCompletionSearchEngine::addMockResults( 'foo', $availableResults ); + + $engine = new MockCompletionSearchEngine(); + $engine->setLimitOffset( 10, 0 ); + $results = $engine->completionSearch( 'foo' ); + $this->assertEquals( 5, $results->getSize() ); + $this->assertTrue( $results->hasMoreResults() ); + + $engine->setLimitOffset( 10, 10 ); + $results = $engine->completionSearch( 'foo' ); + $this->assertEquals( 1, $results->getSize() ); + $this->assertFalse( $results->hasMoreResults() ); + } + + private function editPage( $title ) { + $page = WikiPage::factory( Title::newFromText( $title ) ); + $page->doEditContent( + new WikitextContent( 'UTContent' ), + 'UTPageSummary', + EDIT_NEW | EDIT_SUPPRESS_RC + ); + } } diff --git a/tests/phpunit/includes/search/SearchNearMatchResultSetTest.php b/tests/phpunit/includes/search/SearchNearMatchResultSetTest.php new file mode 100644 index 0000000000..67493c4243 --- /dev/null +++ b/tests/phpunit/includes/search/SearchNearMatchResultSetTest.php @@ -0,0 +1,15 @@ +assertEquals( 0, $resultSet->numRows() ); + + $resultSet = new SearchNearMatchResultSet( Title::newMainPage() ); + $this->assertEquals( 1, $resultSet->numRows() ); + } +} diff --git a/tests/phpunit/includes/search/SearchResultSetTest.php b/tests/phpunit/includes/search/SearchResultSetTest.php new file mode 100644 index 0000000000..26a0672922 --- /dev/null +++ b/tests/phpunit/includes/search/SearchResultSetTest.php @@ -0,0 +1,61 @@ +assertEquals( 1, $resultSet->numRows() ); + $count = 0; + foreach ( $resultSet as $iterResult ) { + $this->assertEquals( $result, $iterResult ); + $count++; + } + $this->assertEquals( 1, $count ); + + $this->hideDeprecated( 'SearchResultSet::rewind' ); + $this->hideDeprecated( 'SearchResultSet::next' ); + $resultSet->rewind(); + $count = 0; + while ( false !== ( $iterResult = $resultSet->next() ) ) { + $this->assertEquals( $result, $iterResult ); + $count++; + } + $this->assertEquals( 1, $count ); + } + + /** + * @covers SearchResultSet::augmentResult + * @covers SearchResultSet::setAugmentedData + */ + public function testDelayedResultAugment() { + $result = SearchResult::newFromTitle( Title::newMainPage() ); + $resultSet = new MockSearchResultSet( [ $result ] ); + $resultSet->augmentResult( $result ); + $this->assertEquals( [], $result->getExtensionData() ); + $resultSet->setAugmentedData( 'foo', [ + $result->getTitle()->getArticleID() => 'bar' + ] ); + $this->assertEquals( [ 'foo' => 'bar' ], $result->getExtensionData() ); + } + + /** + * @covers SearchResultSet::shrink + * @covers SearchResultSet::count + * @covers SearchResultSet::hasMoreResults + */ + public function testHasMoreResults() { + $result = SearchResult::newFromTitle( Title::newMainPage() ); + $resultSet = new MockSearchResultSet( array_fill( 0, 3, $result ) ); + $this->assertEquals( 3, count( $resultSet ) ); + $this->assertFalse( $resultSet->hasMoreResults() ); + $resultSet->shrink( 3 ); + $this->assertFalse( $resultSet->hasMoreResults() ); + $resultSet->shrink( 2 ); + $this->assertTrue( $resultSet->hasMoreResults() ); + } +} diff --git a/tests/phpunit/includes/search/SearchResultTest.php b/tests/phpunit/includes/search/SearchResultTest.php new file mode 100644 index 0000000000..0e1e24c089 --- /dev/null +++ b/tests/phpunit/includes/search/SearchResultTest.php @@ -0,0 +1,38 @@ +assertEquals( [], $result->getExtensionData(), 'starts empty' ); + + $data = [ 'hello' => 'world' ]; + $result->setExtensionData( function () use ( &$data ) { + return $data; + } ); + $this->assertEquals( $data, $result->getExtensionData(), 'can set extension data' ); + $data['this'] = 'that'; + $this->assertEquals( $data, $result->getExtensionData(), 'refetches from callback' ); + } + + /** + * @covers SearchResult::getExtensionData + * @covers SearchResult::setExtensionData + */ + public function testExtensionDataArrayBC() { + $result = SearchResult::newFromTitle( Title::newMainPage() ); + $data = [ 'hello' => 'world' ]; + $this->hideDeprecated( 'SearchResult::setExtensionData with array argument' ); + $this->assertEquals( [], $result->getExtensionData(), 'starts empty' ); + $result->setExtensionData( $data ); + $this->assertEquals( $data, $result->getExtensionData(), 'can set extension data' ); + $data['this'] = 'that'; + $this->assertNotEquals( $data, $result->getExtensionData(), 'shouldnt hold any reference' ); + + $result->setExtensionData( $data ); + $this->assertEquals( $data, $result->getExtensionData(), 'can replace extension data' ); + } +} diff --git a/tests/phpunit/includes/session/SessionTest.php b/tests/phpunit/includes/session/SessionTest.php index f84d435f77..a74056d0ca 100644 --- a/tests/phpunit/includes/session/SessionTest.php +++ b/tests/phpunit/includes/session/SessionTest.php @@ -358,7 +358,7 @@ class SessionTest extends MediaWikiTestCase { $logger->clearBuffer(); // Unserializable data - $iv = \MWCryptRand::generate( 16, true ); + $iv = random_bytes( 16 ); list( $encKey, $hmacKey ) = TestingAccessWrapper::newFromObject( $session )->getSecretKeys(); $ciphertext = openssl_encrypt( 'foobar', 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, $iv ); $sealed = base64_encode( $iv ) . '.' . base64_encode( $ciphertext ); diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php index f0a5726699..196321caed 100644 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ b/tests/phpunit/includes/specials/SpecialSearchTest.php @@ -262,8 +262,8 @@ class SpecialSearchTestMockResultSet extends SearchResultSet { $this->containedSyntax = $containedSyntax; } - public function numRows() { - return count( $this->results ); + public function expandResults() { + return $this->results; } public function getTotalHits() { diff --git a/tests/phpunit/languages/SpecialPageAliasTest.php b/tests/phpunit/languages/SpecialPageAliasTest.php index 0bb6a4d293..d406c88933 100644 --- a/tests/phpunit/languages/SpecialPageAliasTest.php +++ b/tests/phpunit/languages/SpecialPageAliasTest.php @@ -7,12 +7,14 @@ * @group SpecialPageAliases * @group SystemTest * @group medium + * @todo This should be a structure test * * @author Katie Filbert < aude.wiki@gmail.com > */ class SpecialPageAliasTest extends MediaWikiTestCase { /** + * @coversNothing * @dataProvider validSpecialPageAliasesProvider */ public function testValidSpecialPageAliases( $code, $specialPageAliases ) { diff --git a/tests/phpunit/mocks/MockMessageLocalizer.php b/tests/phpunit/mocks/MockMessageLocalizer.php index 143a419f05..4d35930730 100644 --- a/tests/phpunit/mocks/MockMessageLocalizer.php +++ b/tests/phpunit/mocks/MockMessageLocalizer.php @@ -37,7 +37,7 @@ class MockMessageLocalizer implements MessageLocalizer { $args = func_get_args(); /** @var Message $message */ - $message = call_user_func_array( 'wfMessage', $args ); + $message = wfMessage( ...$args ); if ( $this->languageCode !== null ) { $message->inLanguage( $this->languageCode ); diff --git a/tests/phpunit/mocks/search/MockCompletionSearchEngine.php b/tests/phpunit/mocks/search/MockCompletionSearchEngine.php new file mode 100644 index 0000000000..ac8a5dc702 --- /dev/null +++ b/tests/phpunit/mocks/search/MockCompletionSearchEngine.php @@ -0,0 +1,42 @@ +getText(); + self::$results[$normalized] = $result; + } + + public function completionSearchBackend( $search ) { + if ( !isset( self::$results[$search] ) ) { + return SearchSuggestionSet::emptySuggestionSet(); + } + $results = array_slice( self::$results[$search], $this->offset, $this->limit ); + + return SearchSuggestionSet::fromStrings( $results ); + } +} diff --git a/tests/phpunit/mocks/search/MockSearchEngine.php b/tests/phpunit/mocks/search/MockSearchEngine.php new file mode 100644 index 0000000000..2b7ea4760a --- /dev/null +++ b/tests/phpunit/mocks/search/MockSearchEngine.php @@ -0,0 +1,45 @@ +getLinkCache(); + foreach ( $results as $result ) { + // TODO: better page ids? Does it matter? + $lc->addGoodLinkObj( mt_rand(), $result->getTitle() ); + } + } + + /** + * @param SearchResultSet[][] $interwikiResults + */ + public static function setMockInterwikiResults( array $interwikiResults ) { + self::$interwikiResults = $interwikiResults; + } + + protected function doSearchText( $term ) { + if ( isset( self::$results[ $term ] ) ) { + $results = array_slice( self::$results[ $term ], $this->offset, $this->limit ); + } else { + $results = []; + } + return new MockSearchResultSet( $results, self::$interwikiResults ); + } +} diff --git a/tests/phpunit/mocks/search/MockSearchResult.php b/tests/phpunit/mocks/search/MockSearchResult.php new file mode 100644 index 0000000000..d92d39a634 --- /dev/null +++ b/tests/phpunit/mocks/search/MockSearchResult.php @@ -0,0 +1,32 @@ +isMissingRevision; + } + public function setMissingRevision( $isMissingRevision ) { + $this->isMissingRevision = $isMissingRevision; + return $this; + } + + public function isBrokenTitle() { + return $this->isBrokenTitle; + } + + public function setBrokenTitle( $isBrokenTitle ) { + $this->isBrokenTitle = $isBrokenTitle; + return $this; + } + + public function getInterwikiPrefix() { + return $this->interwikiPrefix; + } + + public function setInterwikiPrefix( $interwikiPrefix ) { + $this->interwikiPrefix = $interwikiPrefix; + return $this; + } +} diff --git a/tests/phpunit/mocks/search/MockSearchResultSet.php b/tests/phpunit/mocks/search/MockSearchResultSet.php new file mode 100644 index 0000000000..20e2a9fb68 --- /dev/null +++ b/tests/phpunit/mocks/search/MockSearchResultSet.php @@ -0,0 +1,37 @@ +results = $results; + $this->interwikiResults = $interwikiResults; + } + + public function numRows() { + return count( $this->results ); + } + + public function hasInterwikiResults( $type = self::SECONDARY_RESULTS ) { + return isset( $this->interwikiResults[$type] ) && + count( $this->interwikiResults[$type] ) > 0; + } + + public function getInterwikiResults( $type = self::SECONDARY_RESULTS ) { + if ( $this->hasInterwikiResults( $type ) ) { + return $this->interwikiResults[$type]; + } else { + return null; + } + } +} diff --git a/tests/phpunit/structure/AvailableRightsTest.php b/tests/phpunit/structure/AvailableRightsTest.php index 6c2ff024e1..ea132e9a7b 100644 --- a/tests/phpunit/structure/AvailableRightsTest.php +++ b/tests/phpunit/structure/AvailableRightsTest.php @@ -35,6 +35,9 @@ class AvailableRightsTest extends PHPUnit\Framework\TestCase { return $rights; } + /** + * @coversNothing + */ public function testAvailableRights() { $missingRights = array_diff( $this->getAllVisibleRights(), diff --git a/tests/phpunit/structure/ContentHandlerSanityTest.php b/tests/phpunit/structure/ContentHandlerSanityTest.php index c8bcd60de3..c75a9d02a3 100644 --- a/tests/phpunit/structure/ContentHandlerSanityTest.php +++ b/tests/phpunit/structure/ContentHandlerSanityTest.php @@ -32,6 +32,7 @@ class ContentHandlerSanityTest extends MediaWikiTestCase { } /** + * @coversNothing * @dataProvider provideHandlers * @param ContentHandler $handler */ diff --git a/tests/phpunit/structure/ExtensionJsonValidationTest.php b/tests/phpunit/structure/ExtensionJsonValidationTest.php index 60c97ccfac..dea8f5a541 100644 --- a/tests/phpunit/structure/ExtensionJsonValidationTest.php +++ b/tests/phpunit/structure/ExtensionJsonValidationTest.php @@ -19,6 +19,8 @@ /** * Validates all loaded extensions and skins using the ExtensionRegistry * against the extension.json schema in the docs/ folder. + * + * @coversNothing */ class ExtensionJsonValidationTest extends PHPUnit\Framework\TestCase { diff --git a/tests/phpunit/structure/ResourcesTest.php b/tests/phpunit/structure/ResourcesTest.php index 62ddacebfe..2090e29b77 100644 --- a/tests/phpunit/structure/ResourcesTest.php +++ b/tests/phpunit/structure/ResourcesTest.php @@ -11,6 +11,7 @@ * @copyright © 2012, Niklas Laxström * @copyright © 2012, Santhosh Thottingal * @copyright © 2012, Timo Tijhof + * @coversNothing */ class ResourcesTest extends MediaWikiTestCase { diff --git a/tests/phpunit/structure/StructureTest.php b/tests/phpunit/structure/StructureTest.php index 4df791ecd8..82302b1758 100644 --- a/tests/phpunit/structure/StructureTest.php +++ b/tests/phpunit/structure/StructureTest.php @@ -9,6 +9,7 @@ class StructureTest extends MediaWikiTestCase { * Verify all files that appear to be tests have file names ending in * Test. If the file names do not end in Test, they will not be run. * @group medium + * @coversNothing */ public function testUnitTestFileNamesEndWithTest() { if ( wfIsWindows() ) { diff --git a/tests/phpunit/suites/ExtensionsTestSuite.php b/tests/phpunit/suites/ExtensionsTestSuite.php index 02934fa7bd..7d1d3311d6 100644 --- a/tests/phpunit/suites/ExtensionsTestSuite.php +++ b/tests/phpunit/suites/ExtensionsTestSuite.php @@ -45,6 +45,9 @@ class ExtensionsTestSuite extends PHPUnit_Framework_TestSuite { * when no extensions with tests are used. */ class DummyExtensionsTest extends MediaWikiTestCase { + /** + * @coversNothing + */ public function testNothing() { $this->assertTrue( true ); } diff --git a/tests/selenium/selenium.sh b/tests/selenium/selenium.sh index 4a5c254839..f6bb944e0b 100755 --- a/tests/selenium/selenium.sh +++ b/tests/selenium/selenium.sh @@ -3,10 +3,13 @@ set -euo pipefail # Check the command before running in background so # that it can actually fail and have a descriptive error hash chromedriver -chromedriver --url-base=/wd/hub --port=4444 & +chromedriver --url-base=wd/hub --port=4444 & +CHROME_DRIVER_PID=$! +echo chromedriver running with PID $CHROME_DRIVER_PID # Make sure it is killed to prevent file descriptors leak function kill_chromedriver() { - killall chromedriver > /dev/null + # Use kill instead of killall to increase chances of this working on Windows + kill $CHROME_DRIVER_PID > /dev/null } trap kill_chromedriver EXIT npm run selenium-test diff --git a/tests/selenium/specs/page.js b/tests/selenium/specs/page.js index dfc6fa1ae8..069a6aa3fd 100644 --- a/tests/selenium/specs/page.js +++ b/tests/selenium/specs/page.js @@ -10,8 +10,8 @@ describe( 'Page', function () { var content, name; - function getTestString() { - return Math.random().toString() + '-öäü-â â£â¥â¦'; + function getTestString( suffix = 'defaultsuffix' ) { + return Math.random().toString() + '-Iñtërnâtiônà lizætiønâ-' + suffix; } before( function () { @@ -22,8 +22,8 @@ describe( 'Page', function () { beforeEach( function () { browser.deleteCookie(); - content = getTestString(); - name = getTestString(); + content = getTestString( 'beforeEach-content' ); + name = getTestString( 'beforeEach-name' ); } ); it( 'should be creatable', function () { @@ -36,7 +36,7 @@ describe( 'Page', function () { } ); it( 'should be re-creatable', function () { - let initialContent = getTestString(); + let initialContent = getTestString( 'initialContent' ); // create browser.call( function () { @@ -63,11 +63,12 @@ describe( 'Page', function () { } ); // edit - EditPage.edit( name, content ); + let editContent = getTestString( 'editContent' ); + EditPage.edit( name, editContent ); // check assert.strictEqual( EditPage.heading.getText(), name ); - assert.strictEqual( EditPage.displayedContent.getText(), content ); + assert.strictEqual( EditPage.displayedContent.getText(), editContent ); } ); it( 'should have history', function () {