Merge "Move the Ukrainian grammar rules from PHP and JS to JSON"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 18 Dec 2016 23:04:48 +0000 (23:04 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 18 Dec 2016 23:04:48 +0000 (23:04 +0000)
43 files changed:
RELEASE-NOTES-1.29
autoload.php
includes/DefaultSettings.php
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/lb.json
includes/api/i18n/lt.json
includes/api/i18n/pl.json
includes/api/i18n/sv.json
includes/filerepo/FileRepo.php
includes/filerepo/TempFileRepo.php [new file with mode: 0644]
includes/htmlform/HTMLForm.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/VFormHTMLForm.php
includes/htmlform/fields/HTMLButtonField.php
includes/htmlform/fields/HTMLFormFieldCloner.php
includes/installer/i18n/zh-hant.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/diq.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/ia.json
languages/i18n/lo.json
languages/i18n/lt.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/sd.json
languages/i18n/sv.json
languages/i18n/th.json
languages/i18n/udm.json
languages/i18n/zh-hant.json
maintenance/importImages.inc [deleted file]
maintenance/importImages.php
resources/src/mediawiki/htmlform/hide-if.js
resources/src/mediawiki/htmlform/styles.css
tests/phpunit/includes/specials/SpecialEditWatchlistTest.php

index ef9d734..3af1654 100644 (file)
@@ -25,6 +25,8 @@ production.
 * $wgUserEmailUseReplyTo is now true by default to work around restrictive DMARC policies.
 * Subpages are now enabled by default in the Template namespace. Set
   $wgNamespacesWithSubpages[NS_TEMPLATE] to false to keep the old behavior.
+* $wgRunJobsAsync is now false by default (T142751). This change only affects
+  wikis with $wgJobRunRate > 0.
 
 === New features in 1.29 ===
 * (T5233) A cookie can now be set when a user is autoblocked, to track that user if
index e1b808a..941b335 100644 (file)
@@ -616,6 +616,7 @@ $wgAutoloadLocalClasses = [
        'ImageListPager' => __DIR__ . '/includes/specials/pagers/ImageListPager.php',
        'ImagePage' => __DIR__ . '/includes/page/ImagePage.php',
        'ImageQueryPage' => __DIR__ . '/includes/specialpage/ImageQueryPage.php',
+       'ImportImages' => __DIR__ . '/maintenance/importImages.php',
        'ImportLogFormatter' => __DIR__ . '/includes/logging/ImportLogFormatter.php',
        'ImportReporter' => __DIR__ . '/includes/specials/SpecialImport.php',
        'ImportSiteScripts' => __DIR__ . '/maintenance/importSiteScripts.php',
@@ -1424,7 +1425,7 @@ $wgAutoloadLocalClasses = [
        'TablePager' => __DIR__ . '/includes/pager/TablePager.php',
        'TagLogFormatter' => __DIR__ . '/includes/logging/TagLogFormatter.php',
        'TempFSFile' => __DIR__ . '/includes/libs/filebackend/fsfile/TempFSFile.php',
-       'TempFileRepo' => __DIR__ . '/includes/filerepo/FileRepo.php',
+       'TempFileRepo' => __DIR__ . '/includes/filerepo/TempFileRepo.php',
        'TemplateParser' => __DIR__ . '/includes/TemplateParser.php',
        'TemplatesOnThisPageFormatter' => __DIR__ . '/includes/TemplatesOnThisPageFormatter.php',
        'TestFileOpPerformance' => __DIR__ . '/maintenance/fileOpPerfTest.php',
index 09ea958..f419b77 100644 (file)
@@ -8105,10 +8105,7 @@ $wgJobRunRate = 1;
  *
  * @since 1.23
  */
-$wgRunJobsAsync = (
-       !function_exists( 'register_postsend_function' ) &&
-       !function_exists( 'fastcgi_finish_request' )
-);
+$wgRunJobsAsync = false;
 
 /**
  * Number of rows to update per job
index 0480a64..4cd662b 100644 (file)
@@ -44,6 +44,7 @@
        "apihelp-main-param-uselang": "El idioma que se utilizará para las traducciones de mensajes. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> con <kbd>siprop=languages</kbd> devuelve una lista de códigos de idiomas. También puedes introducir <kbd>user</kbd> para usar la preferencia de idioma del usuario actual, o <kbd>content</kbd> para usar el idioma de contenido de este wiki.",
        "apihelp-block-description": "Bloquear a un usuario.",
        "apihelp-block-param-user": "El nombre de usuario, dirección IP o intervalo de IP que quieres bloquear.",
+       "apihelp-block-param-userid": "ID de usuario para bloquear. No se puede utilizar junto con <var>$1user</var>.",
        "apihelp-block-param-expiry": "Fecha de expiración. Puede ser relativa (por ejemplo, <kbd>5 months</kbd> o <kbd>2 weeks</kbd>) o absoluta (por ejemplo, <kbd>2014-09-18T12:34:56Z</kbd>). Si se establece en <kbd>infinite</kbd>, <kbd>indefinite</kbd>, o <kbd>never</kbd>, el bloqueo será permanente.",
        "apihelp-block-param-reason": "Razón para el bloqueo.",
        "apihelp-block-param-anononly": "Bloquear solo usuarios anónimos (es decir, desactivar ediciones anónimas de esta dirección IP).",
        "apihelp-options-description": "Cambiar preferencias del usuario actual.\n\nSolo se pueden establecer opciones que estén registradas en el núcleo o en una de las extensiones instaladas u opciones con claves predefinidas con <code>userjs-</code> (diseñadas para utilizarse con scripts de usuario).",
        "apihelp-options-param-reset": "Restablece las preferencias de la página web a sus valores predeterminados.",
        "apihelp-options-param-resetkinds": "Lista de tipos de opciones a restablecer cuando la opción <var>$1reset</var> esté establecida.",
-       "apihelp-options-param-change": "Lista de cambios con el formato name=value (por ejemplo: skin=vector). El valor no puede contener caracteres de barras verticales. Si no se da ningún valor (ni siquiera un signo de igual), por ejemplo: optionname|otheroption|..., la opción se restablecerá a sus valores predeterminados.",
+       "apihelp-options-param-change": "Lista de cambios con el formato nombre=valor (por ejemplo: skin=vector). Si no se da ningún valor (ni siquiera un signo de igual), por ejemplo: optionname|otheroption|..., la opción se restablecerá a sus valores predeterminados. Si algún valor contiene el carácter tubería (<kbd>|</kbd>), se debe utilizar el [[Special:ApiHelp/main#main/datatypes|separador alternativo de múltiples valores]] para que las operaciones se realicen correctamente.",
        "apihelp-options-param-optionname": "El nombre de la opción que debe establecerse en el valor dado por <var>$1optionvalue</var>.",
        "apihelp-options-param-optionvalue": "El valor de la opción especificada por <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Restablecer todas las preferencias",
        "apihelp-options-example-change": "Cambiar las preferencias <kbd>skin</kbd> y <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Restablecer todas las preferencias y establecer <kbd>skin</kbd> y <kbd>nickname</kbd>.",
        "apihelp-paraminfo-description": "Obtener información acerca de los módulos de la API.",
-       "apihelp-paraminfo-param-modules": "Lista de los nombres de los módulos (valores de los parámetros <var>action</var> y <var>format</var> o <kbd>main</kbd>). Se pueden especificar los submódulos con un <kbd>+</kbd>.",
+       "apihelp-paraminfo-param-modules": "Lista de los nombres de los módulos (valores de los parámetros <var>action</var> y <var>format</var> o <kbd>main</kbd>). Se pueden especificar submódulos con un <kbd>+</kbd>, todos los submódulos con <kbd>+*</kbd> o todos los submódulos recursivamente con <kbd>+**</kbd>.",
        "apihelp-paraminfo-param-helpformat": "Formato de las cadenas de ayuda.",
        "apihelp-paraminfo-param-querymodules": "Lista de los nombres de los módulos de consulta (valor de los parámetros <var>prop</var>, <var>meta</var> or <var>list</var>). Utiliza <kbd>$1modules=query+foo</kbd> en vez de <kbd>$1querymodules=foo</kbd>.",
        "apihelp-paraminfo-param-mainmodule": "Obtener también información sobre el módulo principal (primer nivel). Utilizar <kbd>$1modules=main</kbd> en su lugar.",
        "apihelp-paraminfo-param-pagesetmodule": "Obtener también información sobre el módulo PageSet (Proporcionar títulos= y amigos).",
        "apihelp-paraminfo-param-formatmodules": "Lista de los nombres del formato de los módulos (valor del parámetro <var>format</var>). Utiliza <var>$1modules</var> en su lugar.",
        "apihelp-paraminfo-example-1": "Mostrar información para <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> y <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+       "apihelp-paraminfo-example-2": "Mostrar información para todos los submódulos de <kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
        "apihelp-parse-param-title": "Título de la página a la que pertenece el texto. Si se omite se debe especificar <var>$1contentmodel</var> y se debe utilizar el [[API]] como título.",
        "apihelp-parse-param-text": "Texto a analizar. Utiliza <var>$1title</var> or <var>$1contentmodel</var> para controlar el modelo del contenido.",
        "apihelp-parse-param-summary": "Resumen a analizar.",
        "apihelp-query+categorymembers-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
        "apihelp-query+categorymembers-paramvalue-prop-type": "Añade el tipo en el que se categorizó la página (<samp>page</samp>, <samp>subcat</samp> or <samp>file</samp>).",
        "apihelp-query+categorymembers-paramvalue-prop-timestamp": "Añade la marca de tiempo del momento en que se incluyó la página.",
+       "apihelp-query+categorymembers-param-limit": "Número máximo de páginas que devolver.",
        "apihelp-query+categorymembers-param-sort": "Propiedad por la que realizar la ordenación.",
        "apihelp-query+categorymembers-param-dir": "Dirección en la que desea ordenar.",
        "apihelp-query+categorymembers-param-startsortkey": "Utilizar $1starthexsortkey en su lugar.",
        "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los archivos.",
        "apihelp-query+embeddedin-description": "Encuentra todas las páginas que transcluyen el título dado.",
        "apihelp-query+embeddedin-param-title": "Título a buscar. No puede usarse en conjunto con $1pageid.",
+       "apihelp-query+embeddedin-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+embeddedin-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+embeddedin-param-filterredir": "Cómo filtrar las redirecciones.",
        "apihelp-query+embeddedin-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+exturlusage-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
        "apihelp-query+exturlusage-paramvalue-prop-url": "Añade el URL utilizado en la página.",
        "apihelp-query+exturlusage-param-protocol": "Protocolo del URL. Si está vacío y se establece <var>$1query</var>, el protocolo es <kbd>http</kbd>. Deja vacío esto y <var>$1query</var> para listar todos los enlaces externos.",
+       "apihelp-query+exturlusage-param-namespace": "Los espacios de nombres que enumerar.",
        "apihelp-query+exturlusage-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+exturlusage-example-simple": "Mostrar páginas que enlacen con <kbd>http://www.mediawiki.org</kbd>.",
        "apihelp-query+filearchive-param-from": "El título de imagen para comenzar la enumeración",
        "apihelp-query+filearchive-param-to": "El título de imagen para detener la enumeración.",
        "apihelp-query+filearchive-param-prefix": "Buscar todos los títulos de las imágenes que comiencen con este valor.",
+       "apihelp-query+filearchive-param-limit": "Número de imágenes que devolver en total.",
        "apihelp-query+filearchive-param-dir": "La dirección en que ordenar la lista.",
+       "apihelp-query+filearchive-param-sha1": "Hash SHA1 de la imagen. Reemplaza $1sha1base36.",
+       "apihelp-query+filearchive-param-sha1base36": "Hash SHA1 de la imagen en base 36 (utilizado en MediaWiki).",
        "apihelp-query+filearchive-param-prop": "Qué información de imagen se obtendrá:",
+       "apihelp-query+filearchive-paramvalue-prop-sha1": "Añade el hash SHA-1 para la imagen.",
        "apihelp-query+filearchive-paramvalue-prop-timestamp": "Añade la marca de tiempo de la versión subida.",
        "apihelp-query+filearchive-paramvalue-prop-user": "Agrega el usuario que subió la versión de la imagen.",
        "apihelp-query+filearchive-paramvalue-prop-size": "Agrega el tamaño de la imagen en bytes y la altura, la anchura y el número de páginas (si es aplicable).",
        "apihelp-query+filearchive-paramvalue-prop-parseddescription": "Analizar la descripción de la versión.",
        "apihelp-query+filearchive-paramvalue-prop-mime": "Añade el MIME de la imagen.",
        "apihelp-query+filearchive-paramvalue-prop-mediatype": "Añade el tipo multimedia de la imagen.",
+       "apihelp-query+filearchive-paramvalue-prop-bitdepth": "Añade la profundidad de bit de la versión.",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Añade el nombre de archivo de la versión archivada para las versiones que no son las últimas.",
        "apihelp-query+filearchive-example-simple": "Mostrar una lista de todos los archivos eliminados.",
        "apihelp-query+filerepoinfo-example-simple": "Obtener información acerca de los repositorios de archivos.",
        "apihelp-query+imageinfo-param-prop": "Qué información del archivo se obtendrá:",
        "apihelp-query+imageinfo-paramvalue-prop-user": "Añade el usuario que subió cada versión del archivo.",
        "apihelp-query+imageinfo-paramvalue-prop-userid": "Añade la ID de usuario que subió cada versión del archivo.",
+       "apihelp-query+imageinfo-paramvalue-prop-comment": "Comentarios sobre la versión.",
+       "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Analizar el comentario de la versión.",
        "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Agrega el título canónico del archivo.",
+       "apihelp-query+imageinfo-paramvalue-prop-sha1": "Añade el hash SHA-1 para la imagen.",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "Añade el tipo MIME del archivo.",
+       "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "Añade el tipo MIME de la miniatura de la imagen (se requiere la URL y el parámetro $1urlwidth).",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Añade el tipo multimedia de la imagen.",
        "apihelp-query+imageinfo-param-limit": "Cuántos revisiones de archivos se devolverán por perfil.",
        "apihelp-query+imageinfo-param-urlheight": "Similar a $1urlwidth.",
        "apihelp-query+imageinfo-param-extmetadatafilter": "Si se especifica y no vacío, sólo estas claves serán devueltos por $1prop=extmetadata.",
        "apihelp-query+info-example-protection": "Obtén información general y protección acerca de la página <kbd>Main Page</kbd>.",
        "apihelp-query+iwbacklinks-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+iwbacklinks-param-prop": "Qué propiedades se obtendrán:",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "Añade el prefijo del interwiki.",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Añade el título del interwiki.",
        "apihelp-query+iwbacklinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+iwbacklinks-example-simple": "Obtener las páginas enlazadas a [[wikibooks:Test]]",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Etiquetas para la revisión.",
        "apihelp-query+search-param-info": "Qué metadatos devolver.",
        "apihelp-query+search-param-prop": "Qué propiedades se devolverán:",
+       "apihelp-query+search-paramvalue-prop-size": "Añade el tamaño de la página en bytes.",
+       "apihelp-query+search-paramvalue-prop-wordcount": "Añade el número de palabras de la página.",
+       "apihelp-query+search-paramvalue-prop-timestamp": "Añade la marca de tiempo de la última edición de la página.",
+       "apihelp-query+search-paramvalue-prop-snippet": "Añade un fragmento analizado de la página.",
+       "apihelp-query+search-paramvalue-prop-titlesnippet": "Añade un fragmento analizado del título de la página.",
+       "apihelp-query+search-paramvalue-prop-redirectsnippet": "Añade un fragmento analizado del título de la redirección.",
        "apihelp-query+search-paramvalue-prop-redirecttitle": "Añade el título de la redirección coincidente.",
+       "apihelp-query+search-paramvalue-prop-sectionsnippet": "Añade un fragmento analizado del título de la sección correspondiente.",
+       "apihelp-query+search-paramvalue-prop-sectiontitle": "Añade el título de la sección correspondiente.",
+       "apihelp-query+search-paramvalue-prop-categorysnippet": "Añade un fragmento analizado de la categoría correspondiente.",
+       "apihelp-query+search-paramvalue-prop-isfilematch": "Añade un booleano que indica si la búsqueda corresponde al contenido del archivo.",
        "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">Desaconsejado e ignorado.</span>",
        "apihelp-query+search-paramvalue-prop-hasrelated": "<span class=\"apihelp-deprecated\">Desaconsejado e ignorado.</span>",
        "apihelp-query+search-param-limit": "Cuántas páginas en total se devolverán.",
        "apihelp-query+search-param-interwiki": "Incluir resultados interwiki en la búsqueda, si es posible.",
+       "apihelp-query+search-param-backend": "Qué servidor de búsqueda utilizar, si no es el servidor por defecto.",
+       "apihelp-query+search-param-enablerewrites": "Habilita la reescritura de consultas internas. Algunos servidores de búsqueda pueden reescribir la consulta a una que considere que da mejores resultados, por ejemplo, corrigiendo las faltas ortográficas.",
        "apihelp-query+search-example-simple": "Buscar <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Buscar <kbd>meaning</kbd> en los textos.",
        "apihelp-query+search-example-generator": "Obtener información acerca de las páginas devueltas por una búsqueda de <kbd>meaning</kbd>.",
        "apihelp-query+transcludedin-param-namespace": "Incluir solo las páginas en estos espacios de nombres.",
        "apihelp-query+transcludedin-param-limit": "Cuántos se devolverán.",
        "apihelp-query+transcludedin-example-simple": "Obtener una lista de páginas transcluyendo <kbd>Main Page</kbd>.",
+       "apihelp-query+usercontribs-description": "Obtener todas las ediciones realizadas por un usuario.",
        "apihelp-query+usercontribs-param-limit": "Número máximo de contribuciones que se devolverán.",
        "apihelp-query+usercontribs-param-prop": "Incluir piezas adicionales de información:",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "Añade el identificador de página y el de revisión.",
        "apihelp-query+usercontribs-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
        "apihelp-query+usercontribs-paramvalue-prop-timestamp": "Añade fecha y hora de la edición.",
        "apihelp-query+usercontribs-paramvalue-prop-comment": "Añade el comentario de la edición.",
+       "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "Añade el comentario analizado de la edición.",
+       "apihelp-query+usercontribs-paramvalue-prop-size": "Añade el nuevo tamaño de la edición.",
+       "apihelp-query+usercontribs-paramvalue-prop-sizediff": "Añade la diferencia de tamaño de la edición respecto de su progenitora.",
        "apihelp-query+usercontribs-paramvalue-prop-patrolled": "Etiqueta ediciones verificadas.",
        "apihelp-query+usercontribs-paramvalue-prop-tags": "Lista las etiquetas para la edición.",
        "apihelp-query+usercontribs-param-show": "Mostrar solo los elementos que coinciden con estos criterios. Por ejemplo, solo ediciones no menores: <kbd>$2show=!minor</kbd>.\n\nSi se establece <kbd>$2show=patrolled</kbd> o <kbd>$2show=!patrolled</kbd>, las revisiones más antiguas que <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|segundo|segundos}}) no se mostrarán.",
        "apihelp-query+watchlist-paramvalue-prop-user": "Añade el usuario que hizo la edición.",
        "apihelp-query+watchlist-paramvalue-prop-userid": "Añade el identificador de usuario de quien hizo la edición.",
        "apihelp-query+watchlist-paramvalue-prop-comment": "Añade el comentario de la edición.",
+       "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "Añade el comentario analizado de la edición.",
        "apihelp-query+watchlist-paramvalue-prop-timestamp": "Añade fecha y hora de la edición.",
        "apihelp-query+watchlist-paramvalue-prop-patrol": "Etiqueta las ediciones que están verificadas.",
        "apihelp-query+watchlist-paramvalue-prop-sizes": "Añade la longitud vieja y la nueva de la página.",
        "apihelp-query+watchlistraw-param-fromtitle": "Título (con el prefijo de espacio de nombres) desde el que se empezará a enumerar.",
        "apihelp-query+watchlistraw-param-totitle": "Título (con el prefijo de espacio de nombres) desde el que se dejará de enumerar.",
        "apihelp-query+watchlistraw-example-simple": "Listar las páginas de la lista de seguimiento del usuario actual.",
+       "apihelp-resetpassword-description": "Enviar un email de reinicialización de la contraseña a un usuario.",
        "apihelp-revisiondelete-description": "Eliminar y restaurar revisiones",
        "apihelp-revisiondelete-param-hide": "Qué ocultar en cada revisión.",
        "apihelp-revisiondelete-param-show": "Qué mostrar en cada revisión.",
        "apihelp-revisiondelete-param-reason": "Motivo de la eliminación o restauración.",
        "apihelp-rollback-param-summary": "Resumen de edición personalizado. Si se deja vacío se utilizará el predeterminado.",
+       "apihelp-rsd-description": "Exportar un esquema RSD (Really Simple Discovery; Descubrimiento Muy Simple).",
+       "apihelp-rsd-example-simple": "Exportar el esquema RSD.",
        "apihelp-stashedit-param-title": "Título de la página que se está editando.",
        "apihelp-stashedit-param-section": "Número de la sección. <kbd>0</kbd> para una sección superior, <kbd>new</kbd> para una sección nueva.",
        "apihelp-stashedit-param-sectiontitle": "El título de una sección nueva.",
        "apihelp-unblock-param-reason": "Motivo del desbloqueo.",
        "apihelp-unblock-example-id": "Desbloquear el bloqueo de ID #<kbd>105</kbd>",
        "apihelp-unblock-example-user": "Desbloquear al usuario <kbd>Bob</kbd> con el motivo <kbd>Sorry Bob</kbd>",
+       "apihelp-undelete-param-title": "Título de la página que restaurar.",
        "apihelp-undelete-param-reason": "Motivo de la restauración.",
        "apihelp-undelete-example-revisions": "Restaurar dos revisiones de la página <kbd>Main Page</kbd>.",
        "apihelp-upload-param-tags": "Cambiar etiquetas para aplicar a la entrada del registro de subidas y a la revisión de página de archivo.",
        "apihelp-upload-param-watch": "Vigilar la página.",
        "apihelp-upload-param-ignorewarnings": "Ignorar las advertencias.",
+       "apihelp-upload-param-file": "Contenido del archivo.",
+       "apihelp-upload-param-url": "URL de la que obtener el archivo.",
        "apihelp-upload-example-url": "Subir desde una URL.",
        "apihelp-userrights-param-user": "Nombre de usuario.",
        "apihelp-userrights-param-userid": "ID de usuario.",
        "apihelp-rawfm-description": "Extraer los datos de salida, incluidos los elementos de depuración, en formato JSON (embellecido en HTML).",
        "apihelp-xml-param-xslt": "Si se especifica, añade la página nombrada como una hoja de estilo XSL. El valor debe ser un título en el espacio de nombres {{ns:MediaWiki}} que termine en <code>.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "Si se especifica, añade un espacio de nombres XML.",
+       "api-format-title": "Resultado de la API de MediaWiki",
+       "api-format-prettyprint-status": "Esta respuesta se devolvería con el estado HTTP $1 $2.",
+       "api-help-title": "Ayuda de la API de MediaWiki",
+       "api-help-lead": "Esta es una página de documentación autogenerada de la API de MediaWiki.\n\nDocumentación y ejemplos: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "Módulo principal",
        "api-help-flag-deprecated": "Este módulo está en desuso.",
+       "api-help-flag-internal": "<strong>Este módulo es interno o inestable.</strong> Su funcionamiento puede cambiar sin previo aviso.",
        "api-help-flag-readrights": "Este módulo requiere permisos de lectura.",
        "api-help-flag-writerights": "Este módulo requiere permisos de escritura.",
        "api-help-flag-mustbeposted": "Este módulo solo acepta solicitudes POST.",
        "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:",
        "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Concedido a|Concedidos a}}: $2",
+       "apierror-assertbotfailed": "La aserción de que el usuario tiene el derecho <code>bot</code> falló.",
+       "apierror-assertnameduserfailed": "La aserción de que el usuario es «$1» falló.",
+       "apierror-assertuserfailed": "La aserción de que el usuario está conectado falló.",
+       "apierror-autoblocked": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por un usuario bloqueado.",
+       "apierror-badconfig-resulttoosmall": "El valor de <code>$wgAPIMaxResultSize</code> en este wiki es demasiado pequeño como para contener información básica de resultados.",
+       "apierror-badgenerator-notgenerator": "El módulo <kbd>$1</kbd> no puede utilizarse como un generador.",
+       "apierror-badgenerator-unknown": "<kbd>generator=$1</kbd> desconocido.",
        "apierror-badip": "El parámetro IP no es válido.",
+       "apierror-badmd5": "El hash MD5 suministrado es incorrecto.",
+       "apierror-badmodule-badsubmodule": "El módulo <kbd>$1</kbd> no tiene un submódulo \"$2\".",
+       "apierror-badmodule-nosubmodules": "El módulo <kbd>$1</kbd> no tiene submódulos.",
+       "apierror-badparameter": "Valor no válido para el parámetro <var>$1</var>.",
+       "apierror-badquery": "La consulta no es válida.",
+       "apierror-badtimestamp": "Valor no válido \"$2\" para el parámetro de marca de tiempo <var>$1</var>.",
+       "apierror-blockedfrommail": "Se te ha bloqueado de enviar email.",
+       "apierror-blocked": "Se te ha bloqueado de editar.",
+       "apierror-cantblock-email": "No tienes permiso para bloquear a los usuarios el envío de correo electrónico a través de la wiki.",
+       "apierror-cantblock": "No tienes permiso para bloquear usuarios.",
+       "apierror-cantchangecontentmodel": "No tienes permiso para cambiar el modelo de contenido de una página.",
+       "apierror-canthide": "No tienes permiso para ocultar nombres de usuario del registro de bloqueos.",
+       "apierror-cantimport-upload": "No tienes permiso para importar páginas subidas.",
+       "apierror-cantimport": "No tienes permiso para importar páginas.",
        "apierror-invalidtitle": "Título incorrecto \"$1\".",
        "apierror-revwrongpage": "r$1 no es una revisión de $2.",
        "apierror-unknownerror-nocode": "Error desconocido.",
index a19a2d5..3886443 100644 (file)
        "apierror-stashpathinvalid": "La clé du fichier n'a pas le bon format ou est invalide: $1 .",
        "apierror-stashwrongowner": "Erreur de propriétaire: $1",
        "apierror-stashzerolength": "Fichier est de longueur nulle, et n'a pas pu être mis dans la réserve: $1.",
+       "apierror-systemblocked": "Vous avez été bloqué automatiquement par MediaWiki.",
        "apierror-templateexpansion-notwikitext": "Le développement du modèle n'est effectif que sur un contenu wikitext. $1 utilise le modèle de contenu $2.",
        "apierror-toofewexpiries": "$1 {{PLURAL:$1|horodatage d’expiration a été fourni|horodatages d’expiration ont été fournis}} alors que $2 {{PLURAL:$2|était attendu|étaient attendus}}.",
        "apierror-unknownaction": "L'action spécifiée, <kbd>$1</kbd>, n'est pas reconnue.",
index 836af02..ac16bfa 100644 (file)
        "apierror-readonly": "D'Wiki kann elo just geliest ginn.",
        "apierror-revwrongpage": "r$1 ass keng Versioun vu(n) $2.",
        "apierror-stashwrongowner": "Falsche Besëtzer: $1",
+       "apierror-systemblocked": "Dir gouft automatesch vu MediaWiki gespaart.",
        "apierror-unknownerror-editpage": "Onbekannten EditPage-Feeler: $1",
        "apierror-unknownerror-nocode": "Onbekannte Feeler.",
        "apierror-unknownerror": "Onbekannte Feeler: \"$1\".",
index a5414c4..79c3e63 100644 (file)
        "apihelp-options-example-complex": "Nustatyti visus pageidavimus iš naujo, tada nustatyti <kbd>skin</kbd> ir <kbd>nickname</kbd>.",
        "apihelp-paraminfo-description": "Gauti informaciją apie API modulius.",
        "apihelp-protect-example-protect": "Apsaugoti puslapį.",
+       "apihelp-query-param-list": "Kurios sąrašus gauti.",
+       "apihelp-query-param-meta": "Kokius metaduomenis gauti.",
        "apihelp-query+allcategories-param-dir": "Rūšiavimo kryptis.",
        "apihelp-query+allcategories-param-min": "Gražinti tik kategorijas, kuriuose yra bent tiek narių.",
        "apihelp-query+allcategories-param-max": "Gražinti tik kategorijas, kuriuose yra iki tiek narių.",
        "apihelp-query+allcategories-param-limit": "Kiek kategorijų gražinti.",
        "apihelp-query+allcategories-paramvalue-prop-size": "Prideda puslapių kategorijoje skaičių.",
+       "apihelp-query+alldeletedrevisions-param-from": "Pradėti sąrašą šiuo pavadinimu.",
+       "apihelp-query+alldeletedrevisions-param-to": "Sustabdyti sąrašą ties šiuo pavadinimu.",
        "apihelp-query+alldeletedrevisions-example-user": "Sąrašas paskutinių 50 ištrintų indėlių pagal vartotoją\n<kbd>Pavyzdys</kbd>.",
        "apihelp-query+allfileusages-paramvalue-prop-title": "Prideda failo pavadinimą.",
        "apihelp-query+allfileusages-param-limit": "Kiek iš viso gražinti objektų.",
+       "apihelp-query+allfileusages-example-unique": "Pateikti unikalius failų pavadinimus.",
+       "apihelp-query+allfileusages-example-unique-generator": "Gauna visus failų pavadinimus, paženklinant trūkstamus.",
        "apihelp-query+allfileusages-example-generator": "Gauti puslapius, kuriuose yra failai.",
+       "apihelp-query+allimages-param-sort": "Pagal ką rūšiuoti.",
        "apihelp-query+allimages-param-limit": "Kiek iš viso gražinti paveikslėlių.",
        "apihelp-query+allimages-example-B": "Rodyti failų sąrašą, pradedant raide <kbd>B</kbd>.",
        "apihelp-query+allimages-example-recent": "Rodyti neseniai įkeltų failų sąrašą, panašu į [[Special:NewFiles]].",
        "apihelp-query+logevents-param-prop": "Kurias savybes gauti:",
        "apihelp-query+logevents-paramvalue-prop-ids": "Prideda žurnalo įvykio ID.",
        "apihelp-query+logevents-paramvalue-prop-type": "Prideda žurnalo įvykio tipą.",
+       "apihelp-query+transcludedin-paramvalue-prop-pageid": "Kiekvieno puslapio ID.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "Kiekvieno puslapio pavadinimas.",
+       "apihelp-query+transcludedin-param-limit": "Kiek gražinti.",
+       "apihelp-query+usercontribs-description": "Gauti visus vartotojo keitimus.",
+       "apihelp-query+usercontribs-param-limit": "Maksimalus gražinamų įnašų skaičius.",
+       "apihelp-query+usercontribs-paramvalue-prop-comment": "Prideda keitimo komentarą.",
+       "apihelp-query+usercontribs-paramvalue-prop-size": "Prideda naują keitimo dydį.",
+       "apihelp-query+userinfo-paramvalue-prop-realname": "Prideda vartotojo tikrą vardą.",
+       "apihelp-query+userinfo-example-simple": "Gauti informacijos apie dabartinį vartotoją.",
+       "apihelp-query+userinfo-example-data": "Gauti papildomos informacijos apie dabartinį vartotoją.",
+       "apihelp-query+users-description": "Gauti informacijos apie vartotojų sąrašą.",
+       "apihelp-query+users-param-prop": "Kokią informaciją įtraukti:",
+       "apihelp-query+users-paramvalue-prop-blockinfo": "Pažymi ar vartotojas užblokuotas, kas tai padarė ir dėl kokios priežasties.",
+       "apihelp-query+users-paramvalue-prop-groups": "Nurodo grupes, kurioms priklauso kiekvienas vartotojas.",
+       "apihelp-query+users-paramvalue-prop-implicitgroups": "Nurodo visas grupes, kuriuose vartotojas yra automatiškai kaip narys.",
+       "apihelp-query+users-paramvalue-prop-rights": "Nurodo visas teises, kurias turi kiekvienas vartotojas.",
+       "apihelp-query+users-paramvalue-prop-editcount": "Prideda vartotojo keitimų skaičių.",
+       "apihelp-query+users-paramvalue-prop-registration": "Prideda vartotojo registracijos laiko žymę.",
+       "apihelp-query+users-param-users": "Sąrašas vartotojų, kurių informaciją gauti.",
        "apihelp-query+users-param-userids": "Vartotojų ID sąrašas, kurių informaciją gauti:",
+       "apihelp-query+users-param-token": "Vietoj to naudoti <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+       "apihelp-query+users-example-simple": "Gražinti informaciją apie vartotoją <kbd>Example</kbd>.",
+       "apihelp-query+watchlist-param-user": "Nurodyti tik pakeitimus, atliktus šio vartotojo.",
+       "apihelp-query+watchlist-param-excludeuser": "Nenurodyti pakeitimų, kuriuos atliko šis vartotojas.",
+       "apihelp-query+watchlist-param-limit": "Kiek viso rezultatų gražinti vienai užklausai.",
+       "apihelp-query+watchlist-param-prop": "Kokias papildomas savybes gauti:",
+       "apihelp-query+watchlist-paramvalue-prop-title": "Prideda puslapio pavadinimą.",
+       "apihelp-query+watchlist-paramvalue-prop-user": "Prideda naują vartotoją, kuris atliko pakeitimą.",
+       "apihelp-query+watchlist-paramvalue-prop-userid": "Prideda vartotojo ID, kuris atliko pakeitimą.",
+       "apihelp-query+watchlist-paramvalue-prop-comment": "Prideda keitimo komentarą.",
+       "apihelp-query+watchlist-paramvalue-prop-timestamp": "Prideda keitimo laiko žymę.",
+       "apihelp-query+watchlist-paramvalue-prop-sizes": "Prideda naują ir seną puslapio ilgius.",
+       "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "Prideda laiko žymę, kada vartotojui buvo pranešta apie pakeitimą.",
+       "apihelp-query+watchlist-paramvalue-prop-loginfo": "Prideda žurnalo informaciją, kai reikia.",
+       "apihelp-query+watchlist-param-type": "Kokios keitimų tipus rodyti:",
        "apihelp-query+watchlist-paramvalue-type-external": "Išoriniai keitimai.",
        "apihelp-query+watchlist-paramvalue-type-new": "Puslapio sukūrimai.",
+       "apihelp-query+watchlist-paramvalue-type-log": "Žurnalo įrašai.",
+       "apihelp-resetpassword-param-user": "Iš naujo nustatomas vartotojas.",
+       "apihelp-resetpassword-param-email": "Iš naujo nustatomo vartotojo el. pašto adresas.",
        "apihelp-stashedit-param-title": "Puslapio pavadinimas buvo redaguotas.",
        "apihelp-stashedit-param-sectiontitle": "Naujo skyriaus pavadinimas.",
        "apihelp-stashedit-param-text": "Puslapio turinys.",
+       "apihelp-stashedit-param-summary": "Keisti santrauką.",
+       "apihelp-tag-param-reason": "Keitimo priežastis.",
+       "apihelp-unblock-description": "Atblokuoti naudotoją.",
+       "apihelp-unblock-param-reason": "Atblokavimo priežastis.",
+       "apihelp-unblock-example-id": "Atblokuoti blokavimo ID #<kbd>105</kbd>.",
+       "apihelp-unblock-example-user": "Atblokuoti vartoją <kbd>Bob</kbd> su priežastimi <kbd>Sorry Bob</kbd>.",
+       "apihelp-undelete-param-title": "Atkuriamo puslapio pavadinimas.",
+       "apihelp-undelete-param-reason": "Atkūrimo priežastis.",
+       "apihelp-undelete-example-page": "Atkurti puslapį <kbd>Main Page</kbd>.",
+       "apihelp-upload-param-watch": "Stebėti šį puslapį.",
+       "apihelp-upload-param-ignorewarnings": "Ignuoruoti bet kokius įspėjimus.",
+       "apihelp-upload-param-file": "Failo turinys.",
+       "apihelp-upload-param-url": "URL, iš kurio gauti failą.",
+       "apihelp-upload-example-url": "Įkelti iš URL.",
+       "apihelp-upload-example-filekey": "Baigti įkėlimą, kuris nepavyko dėl įspėjimų.",
+       "apihelp-userrights-description": "Keisti vartotoju grupės narystę.",
+       "apihelp-userrights-param-user": "Vartotojo vardas.",
+       "apihelp-userrights-param-userid": "Vartotojo ID.",
+       "apihelp-userrights-param-add": "Pridėti vartotoją į šias grupes.",
+       "apihelp-userrights-param-remove": "Pašalinti vartotoją iš šių grupių.",
+       "apihelp-userrights-param-reason": "Keitimo priežastis.",
+       "apihelp-watch-description": "Pridėti ar pašalinti puslapius iš dabartinio vartotojo stebimųjų sąrašo.",
+       "apihelp-watch-example-watch": "Stebėti puslapį <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-unwatch": "Nebestebėti puslapio <kbd>Main Page</kbd>.",
+       "api-format-title": "MedijaViki API rezultatas",
        "api-format-prettyprint-status": "Šis atsakymas būtų gražintas su HTTP statusu $1 $2.",
+       "api-help-title": "MedijaViki API pagalba",
+       "api-help-main-header": "Pagrindinis modulis",
+       "api-help-source": "Šaltinis: $1",
+       "api-help-source-unknown": "Šaltinis: <span class=\"apihelp-unknown\">nežinomas</span>",
+       "api-help-license": "Licencija: [[$1|$2]]",
+       "api-help-license-noname": "Licencija: [[$1|Žiūrėti nuorodą]]",
+       "api-help-license-unknown": "Licencija: <span class=\"apihelp-unknown\">nežinoma</span>",
+       "api-help-parameters": "{{PLURAL:$1|Parametras|Parametrai}}:",
+       "api-help-param-required": "Šis parametras yra reikalingas.",
+       "api-help-datatypes-header": "Duomenų tipai",
+       "api-help-param-limit": "Leidžiama ne daugiau nei $1.",
+       "api-help-param-limit2": "Leidžiama ne daugiau nei $1 ($2 robotams).",
+       "api-help-param-default": "Numatytasis: $1",
+       "api-help-param-default-empty": "Numatytasis: <span class=\"apihelp-empty\">(tuščia)</span>",
+       "api-help-param-no-description": "<span class=\"apihelp-empty\">(nėra aprašymo)</span>",
+       "api-help-examples": "{{PLURAL:$1|Pavyzdys|Pavyzdžiai}}:",
+       "api-help-permissions": "{{PLURAL:$1|Leidimas|Leidimai}}:",
+       "api-help-permissions-granted-to": "{{PLURAL:$1|Suteikta}}: $2",
        "apierror-articleexists": "Straipsnis, kurį bandėte sukurti, jau yra sukurtas.",
        "apierror-autoblocked": "Jūsų IP adresas buvo automatiškai užblokuotas, nes jis buvo naudojamas užblokuoto vartotojo.",
        "apierror-badgenerator-unknown": "Nežinomas <kbd>generator=$1</kbd>.",
        "apierror-badip": "IP parametras negalimas.",
+       "apierror-badquery": "Negalima užklausa.",
        "apierror-badurl": "Negalima reikšmė „$2“ URL parametrui <var>$1</var>.",
        "apierror-blockedfrommail": "Jus buvote užblokuotas nuo el. laiško siuntimo.",
+       "apierror-blocked": "Jus buvote užblokuotas nuo redagavimo.",
        "apierror-botsnotsupported": "Ši sąsaja negali būti palaikoma robotams.",
        "apierror-cannotreauthenticate": "Veiksmas negalimas, nes jūsų tapatybė negali būti patvirtinta.",
+       "apierror-cannotviewtitle": "Jūs negalite peržiūrėti $1.",
+       "apierror-cantblock": "Neturite teisės blokuoti vartotojus.",
+       "apierror-cantchangecontentmodel": "Neturite teisės pakeisti puslapio turinio modelį.",
+       "apierror-cantimport-upload": "Neturite teisės importuoti įkeltų puslapių.",
        "apierror-cantimport": "Neturite teisės importuoti puslapių.",
        "apierror-copyuploadbadurl": "Įkėlimas neleidžiamas iš šio URL.",
        "apierror-databaseerror": "[$1] Duomenų bazės užklausos klaida.",
        "apierror-emptynewsection": "Neįmanoma kurti naujų tuščių skyrių.",
+       "apierror-filedoesnotexist": "Failas neegzistuoja.",
        "apierror-filetypecannotberotated": "Failo tipas negali būti pasuktas.",
        "apierror-import-unknownerror": "Nežinoma klaida importuojant: $1.",
        "apierror-invalidcategory": "Kategorijos pavadinimas, kurį įvedėte, yra negalimas.",
        "apierror-multpages": "<var>$1</var> gali būti naudojamas tik su vienu puslapiu.",
        "apierror-mustbeloggedin-generic": "Turite būti prisijungęs.",
        "apierror-mustbeloggedin-linkaccounts": "Turite būti prisijungęs, kad galėtumėte susieti paskyras.",
+       "apierror-mustbeloggedin": "Turite būti prisijungęs, kad $1.",
        "apierror-nochanges": "Neprašyta jokių keitimų.",
+       "apierror-noedit-anon": "Anoniminiai vartotojai negali redaguoti puslapių.",
        "apierror-noedit": "Neturite teisės redaguoti puslapius.",
+       "apierror-nosuchlogid": "Nėra žurnalo įrašo su ID $1.",
+       "apierror-nosuchpageid": "Nėra puslapio su ID $1.",
+       "apierror-nosuchsection": "Nėra skyriaus $1.",
        "apierror-nosuchsection-what": "$2 nėra sekcijos $1.",
        "apierror-nosuchuserid": "Nėra vartotojo su ID $1.",
        "apierror-paramempty": "Parametras <var>$1</var> negali būti tusčiau.",
        "apiwarn-tokennotallowed": "Veiksmas „$1“ nėra leidžiamas dabartiniam vartotojui.",
        "apiwarn-validationfailed-badpref": "negalimas nustatymas.",
        "apiwarn-validationfailed": "Patvirtinimo klaida skirta <kbd>$1</kbd>: $2",
-       "api-feed-error-title": "Klaida ($1)"
+       "api-feed-error-title": "Klaida ($1)",
+       "api-credits-header": "Kreditai"
 }
index 573c3f8..d3fc2f3 100644 (file)
@@ -29,7 +29,7 @@
        "apihelp-main-param-curtimestamp": "Dołącz obecny znacznik czasu do wyniku.",
        "apihelp-main-param-uselang": "Język, w którym mają być pokazywane tłumaczenia wiadomości. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> z <kbd>siprop=languages</kbd> zwróci listę języków lub ustaw jako <kbd>user</kbd>, aby pobrać z preferencji zalogowanego użytkownika lub <kbd>content</kbd>, aby wykorzystać język zawartości tej wiki.",
        "apihelp-block-description": "Zablokuj użytkownika.",
-       "apihelp-block-param-user": "Nazwa użytkownika, adres IP lub zakres adresów IP, które chcesz zablokować.",
+       "apihelp-block-param-user": "Nazwa użytkownika, adres IP albo zakres adresów IP, które chcesz zablokować. Nie można używać razem z <var>$1userid</var>.",
        "apihelp-block-param-expiry": "Czas trwania. Może być względny (np. <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) lub konkretny (np. <kbd>2014-09-18T12:34:56Z</kbd>). Jeśli jest ustawiony na <kbd>infinite</kbd>, <kbd>indefinite</kbd>, lub <kbd>never</kbd>, blokada nigdy nie wygaśnie.",
        "apihelp-block-param-reason": "Powód blokady.",
        "apihelp-block-param-anononly": "Blokuj tylko anonimowych użytkowników (blokuje anonimowe edycje z tego adresu IP).",
        "apihelp-stashedit-param-text": "Zawartość strony.",
        "apihelp-tag-param-reason": "Powód zmiany.",
        "apihelp-unblock-description": "Odblokuj użytkownika.",
+       "apihelp-unblock-param-user": "Nazwa użytkownika, adres IP albo zakres adresów IP, które chcesz odblokować. Nie można używać jednocześnie z <var>$1id</var> lub <var>$luserid</var>.",
        "apihelp-unblock-param-reason": "Powód odblokowania.",
        "apihelp-undelete-param-reason": "Powód przywracania.",
        "apihelp-upload-param-filename": "Nazwa pliku docelowego.",
index b3253a5..a9ae29d 100644 (file)
        "api-help-param-limit2": "Inte mer än $1 ($2 för robotar) tillåts.",
        "api-help-param-multi-separate": "Separera värden med <kbd>|</kbd> eller [[Special:ApiHelp/main#main/datatypes|alternativ]].",
        "apierror-articleexists": "Artikeln du försökte skapa har redan skapats.",
+       "apierror-nosuchuserid": "Det finns ingen användare med ID $1.",
        "apierror-protect-invalidaction": "Ogiltig skyddstyp \"$1\".",
+       "apierror-systemblocked": "Du har blockerats automatiskt av MediaWiki.",
        "apierror-unknownformat": "Okänt format \"$1\".",
        "api-feed-error-title": "Fel ($1)"
 }
index 41f5281..be37011 100644 (file)
@@ -1924,12 +1924,3 @@ class FileRepo {
                return $this->supportsSha1URLs;
        }
 }
-
-/**
- * FileRepo for temporary files created via FileRepo::getTempRepo()
- */
-class TempFileRepo extends FileRepo {
-       public function getTempRepo() {
-               throw new MWException( "Cannot get a temp repo from a temp repo." );
-       }
-}
diff --git a/includes/filerepo/TempFileRepo.php b/includes/filerepo/TempFileRepo.php
new file mode 100644 (file)
index 0000000..c9a6b59
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+/**
+ * FileRepo for temporary files created via FileRepo::getTempRepo()
+ */
+class TempFileRepo extends FileRepo {
+       public function getTempRepo() {
+               throw new MWException( "Cannot get a temp repo from a temp repo." );
+       }
+}
index 71ccaa3..5c5a9a7 100644 (file)
@@ -1047,6 +1047,7 @@ class HTMLForm extends ContextSource {
                        : 'application/x-www-form-urlencoded';
                # Attributes
                $attribs = [
+                       'class' => 'mw-htmlform',
                        'action' => $this->getAction(),
                        'method' => $this->getMethod(),
                        'enctype' => $encType,
@@ -1079,7 +1080,7 @@ class HTMLForm extends ContextSource {
 
                return Html::rawElement(
                        'form',
-                       $this->getFormAttributes() + [ 'class' => 'visualClear' ],
+                       $this->getFormAttributes(),
                        $html
                );
        }
index 46b570d..54bdf04 100644 (file)
@@ -275,7 +275,7 @@ class OOUIHTMLForm extends HTMLForm {
 
        public function wrapForm( $html ) {
                $form = new OOUI\FormLayout( $this->getFormAttributes() + [
-                       'classes' => [ 'mw-htmlform-ooui' ],
+                       'classes' => [ 'mw-htmlform', 'mw-htmlform-ooui' ],
                        'content' => new OOUI\HtmlSnippet( $html ),
                ] );
 
index 5d9f7a0..325526b 100644 (file)
@@ -67,7 +67,7 @@ class VFormHTMLForm extends HTMLForm {
 
        protected function getFormAttributes() {
                $attribs = parent::getFormAttributes();
-               $attribs['class'] = [ 'mw-ui-vform', 'mw-ui-container', 'visualClear' ];
+               $attribs['class'] = [ 'mw-htmlform', 'mw-ui-vform', 'mw-ui-container' ];
                return $attribs;
        }
 
index 500b502..a19bd5a 100644 (file)
@@ -13,6 +13,9 @@
  *   of the value from 'default'. Overrides 'buttonlabel-raw'.
  * - buttonlabel-raw: HTMLto display for the button display text, instead
  *   of the value from 'default'.
+ * - formnovalidate: Set to true if clicking this button should suppress
+ *   client-side form validation. Used in HTMLFormFieldCloner for add/remove
+ *   buttons.
  *
  * Note that the buttonlabel parameters are not supported on IE6 and IE7 due to
  * bugs in those browsers. If detected, they will be served buttons using the
@@ -27,12 +30,18 @@ class HTMLButtonField extends HTMLFormField {
        /** @var array $mFlags Flags to add to OOUI Button widget */
        protected $mFlags = [];
 
+       protected $mFormnovalidate = false;
+
        public function __construct( $info ) {
                $info['nodata'] = true;
                if ( isset( $info['flags'] ) ) {
                        $this->mFlags = $info['flags'];
                }
 
+               if ( isset( $info['formnovalidate'] ) ) {
+                       $this->mFormnovalidate = $info['formnovalidate'];
+               }
+
                # Generate the label from a message, if possible
                if ( isset( $info['buttonlabel-message'] ) ) {
                        $this->buttonLabel = $this->getMessage( $info['buttonlabel-message'] )->parse();
@@ -71,6 +80,7 @@ class HTMLButtonField extends HTMLFormField {
                        'type' => $this->buttonType,
                        'name' => $this->mName,
                        'value' => $this->getDefault(),
+                       'formnovalidate' => $this->mFormnovalidate,
                ] + $this->getAttributes( [ 'disabled', 'tabindex' ] );
 
                if ( $this->isBadIE() ) {
index a871584..8fb840a 100644 (file)
@@ -57,6 +57,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                if ( isset( $this->mParams['fields']['delete'] ) ) {
                        $class = 'mw-htmlform-cloner-delete-button';
                        $info = $this->mParams['fields']['delete'] + [
+                               'formnovalidate' => true,
                                'cssclass' => $class
                        ];
                        unset( $info['name'], $info['class'] );
@@ -96,6 +97,17 @@ class HTMLFormFieldCloner extends HTMLFormField {
                        } else {
                                $info['id'] = Sanitizer::escapeId( "{$this->mID}--$key--$fieldname" );
                        }
+                       // Copy the hide-if rules to "child" fields, so that the JavaScript code handling them
+                       // (resources/src/mediawiki/htmlform/hide-if.js) doesn't have to handle nested fields.
+                       if ( $this->mHideIf ) {
+                               if ( isset( $info['hide-if'] ) ) {
+                                       // Hide child field if either its rules say it's hidden, or parent's rules say it's hidden
+                                       $info['hide-if'] = [ 'OR', $info['hide-if'], $this->mHideIf ];
+                               } else {
+                                       // Hide child field if parent's rules say it's hidden
+                                       $info['hide-if'] = $this->mHideIf;
+                               }
+                       }
                        $field = HTMLForm::loadInputFromParameters( $name, $info, $this->mParent );
                        $fields[$fieldname] = $field;
                }
@@ -299,6 +311,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                : 'htmlform-cloner-delete';
                        $field = HTMLForm::loadInputFromParameters( $name, [
                                'type' => 'submit',
+                               'formnovalidate' => true,
                                'name' => $name,
                                'id' => Sanitizer::escapeId( "{$this->mID}--$key--delete" ),
                                'cssclass' => 'mw-htmlform-cloner-delete-button',
@@ -371,6 +384,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                        : 'htmlform-cloner-create';
                $field = HTMLForm::loadInputFromParameters( $name, [
                        'type' => 'submit',
+                       'formnovalidate' => true,
                        'name' => $name,
                        'id' => Sanitizer::escapeId( "{$this->mID}--create" ),
                        'cssclass' => 'mw-htmlform-cloner-create-button',
index b977af5..e7f69d3 100644 (file)
        "config-admin-password-mismatch": "兩次輸入的密碼並不相同。",
        "config-admin-email": "電子郵件地址:",
        "config-admin-email-help": "在此輸入的電子郵件信箱可用來接收 Wiki 上其他使用者所傳送的訊息、重設您的密碼與通知監視清單中頁面更動。您可將此欄位留空。",
-       "config-admin-error-user": "建立管理員帳號 \"<nowiki>$1</nowiki>\" 時發內部錯誤。",
-       "config-admin-error-password": "設定管理員 \"<nowiki>$1</nowiki>\" 的密碼時發內部錯誤:<pre>$2</pre>",
+       "config-admin-error-user": "建立管理員帳號 \"<nowiki>$1</nowiki>\" 時發內部錯誤。",
+       "config-admin-error-password": "設定管理員 \"<nowiki>$1</nowiki>\" 的密碼時發內部錯誤:<pre>$2</pre>",
        "config-admin-error-bademail": "您輸入了不正確的電子郵件地址。",
        "config-subscribe": "訂閱 [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce 發佈公告郵寄清單]。",
        "config-subscribe-help": "這是一個用於發佈公告的低郵件量郵寄清單,內容包括重要的安全公告。\n您應該訂閱它並在 MediaWiki 發佈新版的時候更新系統。",
index 71daeed..7dde2b0 100644 (file)
@@ -18,7 +18,7 @@
        "tog-hideminor": "Къайладаха жима нисдарш керла могӀам юкъара",
        "tog-hidepatrolled": "Къайладаха гӀаролладина нисдарш оц могӀама керла нисдаршкахь",
        "tog-newpageshidepatrolled": "Къайлаяха гӀароллайина агӀонаш оьцу могӀама керла агӀонашкахь",
-       "tog-hidecategorization": "Ð\9aÑ\8aайлаÑ\8fÑ\85а Ð°Ð³Ó\80онийн ÐºÐ°Ñ\82егоÑ\80еÑ\88",
+       "tog-hidecategorization": "Ð\90гÓ\80онаÑ\88на Ñ\82Ó\80е ÐºÐ°Ñ\82егоÑ\80еÑ\88 Ñ\82оÑ\85аÑ\80 ÐºÑ\8aайладаккÑ\85а",
        "tog-extendwatchlist": "Шорбина тӀехьажарна могӀам, ша беригге а, хийцамаш чубогӀуш, тӀехьаббина боцурш а",
        "tog-usenewrc": "Лелабе дика могӀам керла чу хийцамашна (оьшу JavaScript)",
        "tog-numberheadings": "Ша шех хlитто терахь корташна",
@@ -29,6 +29,7 @@
        "tog-watchdefault": "ТӀетоха ас нисйина агӀонаш тергаме могӀам чу",
        "tog-watchmoves": "ТӀетоха ас цӀерш хийцина агӀонаш тергаме могӀам чу",
        "tog-watchdeletion": "ТӀетоха ас дӀаяьхна агӀонаш тергаме могӀанан чу",
+       "tog-watchuploads": "Аса чуяьхна файлаш тергаме могӀам юкъатоха",
        "tog-watchrollback": "Аса нисдар юхудаькхина агӀо сан тергаме могӀанан тӀетуху",
        "tog-minordefault": "Къастам бе нисйиначарн хlумцадеш кегийра долушсанна",
        "tog-previewontop": "Чуяккха хьалххьажар тадаран кора хьалха",
        "tog-watchlisthidebots": "Къайладаха тергаме могӀам чура ботан нисдинарш",
        "tog-watchlisthideminor": "Къайладаха кегийра нисдарш тергаме могӀам чура",
        "tog-watchlisthideliu": "Къайладаха бовзийтина болу декъашхойн нисдарш тергаме могӀам чура",
+       "tog-watchlistreloadautomatically": "Литтарна хийцам хилча авто-карлабаккха тергаме могӀам (оьшу JavaScript)",
        "tog-watchlisthideanons": "Къайладаха къайлаха болу декъашхойн нисдарш тергаме могӀам чура",
        "tog-watchlisthidepatrolled": "Къайладаха хьаьжина долу нисдарш тергаме могӀам чура",
+       "tog-watchlisthidecategorization": "АгӀонашна тӀе категореш тохар къайладаккха",
        "tog-ccmeonemails": "Дlадахьийта суна исанна кехат, аса дохьуьйтуш долу кхечу декъашхошна.",
        "tog-diffonly": "Ма гайта агlон чулацам шина башхонца цхьатерра йолуш",
        "tog-showhiddencats": "Гайта къайлаха йолу категореш",
        "prefs-personal": "Долахь болу хаамаш",
        "prefs-rc": "Керла нисдарш",
        "prefs-watchlist": "Тергаме могӀам",
+       "prefs-editwatchlist": "Тергаме могӀаман хийцам",
+       "prefs-editwatchlist-label": "Сан тергаме могӀаман чура дӀаяздаршна хийцам:",
+       "prefs-editwatchlist-edit": "Сан тергаме могӀамам чура цӀерш дӀаяхар а, хьажар а",
+       "prefs-editwatchlist-raw": "Тергаме могӀам йоза санна нисбан",
+       "prefs-editwatchlist-clear": "Тергаме могӀам цӀанбан",
        "prefs-watchlist-days": "Денойн дукхалла:",
        "prefs-watchlist-days-max": "Къезиг $1 {{PLURAL:$1|дена}}",
        "prefs-watchlist-edits": "Тергаме могӀам чохь гойтучу нисдарийн максимум дукхалла:",
        "autosumm-newblank": "Кхоьллина еса агӀо",
        "lag-warn-normal": "{{PLURAL:$1|$1 Секунд}} хьалха бина хийцамаш хӀокху могӀамехь гуш ца хилла мега.",
        "lag-warn-high": "Сервераш синхронизаци еш тӀехьайисарна, {{PLURAL:$1|$1 секунд}} хьалха бина хийцамаш хӀокху могӀамехь гуш ца хилла мега.",
-       "watchlistedit-normal-title": "ТеÑ\80гаме Ð¼Ð¾Ð³Ó\80анийн Ñ\85ийÑ\86амаÑ\88",
+       "watchlistedit-normal-title": "ТеÑ\80гаме Ð¼Ð¾Ð³Ó\80аман Ñ\85ийÑ\86ам",
        "watchlistedit-normal-legend": "Тергаме могӀам юкъар дӀаяккхар",
        "watchlistedit-normal-explain": "Лахахь гойту хьан тергаме могӀамехь йолу агӀонаш.\nДӀаяздарш дӀадаха билгалде уьш такха тӀетаӀе кнопка «{{int:Watchlistedit-normal-submit}}».\nКхин хьа йиш ю [[Special:EditWatchlist/raw|йозан кепар могӀом нисба ]].",
        "watchlistedit-normal-submit": "ДӀадаха дӀаяздарш",
index 18887a3..0d9d219 100644 (file)
        "loginerror": "ھەڵەی چوونەژوورەوە",
        "createacct-error": "ھەڵە لە دروستکردنی ھەژمار",
        "createaccounterror": "ناتوانیت هەژماری بەکارهێنەر دروست بکەیت: $1",
-       "nocookiesnew": "ھەژماری بەکارھێنەر دروست‌کرا، بەڵام بە سەرکەوتوویی نەچوویتەوە ژوورەوە.\n{{SITENAME}} بۆ چوونەوە ژوورەوەی بەکارھێنەر لە شەکرۆکە کەڵک وەردەگرێت.\nتۆ شەکرۆکەکەت لەکارخستووە.\nتکایە شەکرۆکەکە کارا بکە و پاشان بە ناوی بەکارھێنەر و تێپەڕوشە بچۆ ژوورەوە.",
+       "nocookiesnew": "ھەژماری بەکارھێنەری دروست کرا، بەڵام نەچوویتەوە ژوورەوە.\n{{SITENAME}} بۆ چوونەوە ژوورەوەی بەکارھێنەر کوکی بەکاردەھێنێت.\nتۆ کوکییەکەکەت لەکارخستووە.\nتکایە کوکییەکە کارا بکە، پاشان بە ناوی بەکارھێنەری و تێپەڕوشەکەت بچۆ ژوورەوە.",
        "nocookieslogin": "{{SITENAME}} بۆ چوونەژوورەوە لە کووکی‌یەکان کەڵک وەرئەگرێت.\nڕێگەت نەداوە بە کووکی‌یەکان.\nڕێگەیان پێ بدەو و دیسان تێبکۆشە.",
        "nocookiesfornew": "ھەژماری بەکارھێنەری دروست نەکرا، چون ناتوانین سەرچاوەکەی پشتڕاست بکەینەوە.\nدڵنیا بە کوکییەکانت چالاک کردووە، پەڕەکە بار بکەوە و دیسان ھەوڵ بدە.",
        "noname": "ناوی بەکارهێنەرییەکی گۆنجاوت دیاری نەکردووه.",
index 9e1c688..5360972 100644 (file)
        "withoutinterwiki-summary": "Tyto stránky neobsahují žádný mezijazykový odkaz:",
        "withoutinterwiki-legend": "Prefix",
        "withoutinterwiki-submit": "Zobrazit",
-       "fewestrevisions": "Stránky s nejméně verzemi",
+       "fewestrevisions": "Stránky s nejméně editacemi",
        "nbytes": "$1 {{PLURAL:$1|bajt|bajty|bajtů}}",
        "ncategories": "$1 {{PLURAL:$1|kategorie|kategorie|kategorií}}",
        "ninterwikis": "$1 {{PLURAL:$1|mezijazykový odkaz|mezijazykové odkazy|mezijazykových odkazů}}",
        "rollback-success-notify": "Editace uživatele $1 byly vráceny;\nobnovena poslední verze od uživatele $2. [$3 Zobrazit změny]",
        "sessionfailure-title": "Chyba relace",
        "sessionfailure": "Zřejmě je nějaký problém s vaším přihlášením;\nvámi požadovaná činnost byla stornována jako prevence před neoprávněným přístupem.\nStiskněte tlačítko „zpět“, obnovte stránku, ze které jste přišli, a zkuste činnost znovu.",
-       "changecontentmodel": "Změna modelu obsahu stránky",
+       "changecontentmodel": "Změnit model obsahu stránky",
        "changecontentmodel-legend": "Změnit model obsahu",
        "changecontentmodel-title-label": "Název stránky",
        "changecontentmodel-model-label": "Nový model obsahu",
index 20d8652..218c40e 100644 (file)
        "history": "Tarixê pele",
        "history_short": "Tarix",
        "updatedmarker": "cıkewtena mına peyêne ra dıme biyo rocane",
-       "printableversion": "Çap bıyaye versiyon",
+       "printableversion": "Versiyono nuşterniyaye",
        "permalink": "Gıreyo bêpeyni",
        "print": "Çap ke",
        "view": "Bıvêne",
        "tooltip-t-emailuser": "Ena karber ri yew email bırış",
        "tooltip-t-upload": "Dosyeyan bar ke",
        "tooltip-t-specialpages": "Yew lista pelanê xasanê pêroyinan",
-       "tooltip-t-print": "Versiyonê peleyo ke şeno çap bıkeriyo.",
+       "tooltip-t-print": "Versiyono perre ro ke nuşterniyaye.",
        "tooltip-t-permalink": "Gırêyo daimi be ena versiyonê pele",
        "tooltip-ca-nstab-main": "Pela zerreki bıvêne",
        "tooltip-ca-nstab-user": "Pela karberi bıvêne",
index 6120b5c..e469138 100644 (file)
        "qbfind": "Buscar",
        "qbbrowse": "Navegar",
        "qbedit": "Editar",
-       "qbpageoptions": "Opciones de página",
+       "qbpageoptions": "Esta página",
        "qbmyoptions": "Mis páginas",
        "faq": "Preguntas frecuentes",
        "faqpage": "Project:Preguntas frecuentes",
        "editusergroup": "Cargar grupos de usuarios",
        "editinguser": "Cambio de los permisos {{GENDER:$1|del usuario|de la usuaria}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Modificar grupos {{GENDER:$1|del usuario| de la usuaria}}",
+       "userrights-viewusergroup": "Ver grupos de usuarios",
        "saveusergroups": "Guardar grupos {{GENDER:$1|del usuario|de la usuaria}}",
        "userrights-groupsmember": "Miembro de:",
        "userrights-groupsmember-auto": "Miembro implícito de:",
        "apisandbox-continue-clear": "Vaciar",
        "apisandbox-param-limit": "Escribe <kbd>max</kbd> para usar el límite máximo.",
        "apisandbox-multivalue-all-namespaces": "$1 (Todos los espacios de nombres)",
+       "apisandbox-multivalue-all-values": "$1 (Todos los valores)",
        "booksources": "Fuentes de libros",
        "booksources-search-legend": "Buscar fuentes de libros",
        "booksources-search": "Buscar",
        "pageinfo-length": "Longitud de la página (en bytes)",
        "pageinfo-article-id": "Identificador de la página",
        "pageinfo-language": "Idioma de la página",
+       "pageinfo-language-change": "cambiar",
        "pageinfo-content-model": "Modelo de contenido de la página",
        "pageinfo-content-model-change": "cambiar",
        "pageinfo-robot-policy": "Indización por robots",
        "mw-widgets-dateinput-no-date": "Ninguna fecha seleccionada",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
+       "mw-widgets-mediasearch-input-placeholder": "Buscar multimedia",
+       "mw-widgets-mediasearch-noresults": "No se han encontrado resultados.",
        "mw-widgets-titleinput-description-new-page": "la página aún no existe",
        "mw-widgets-titleinput-description-redirect": "redirigir a $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Agregar una categoría...",
index 872451b..38f21c0 100644 (file)
        "watchlistedit-clear-done": "Sinu jälgimisloend on tühjendatud.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Üks pealkiri|$1 pealkirja}} eemaldati:",
        "watchlistedit-too-many": "Pealkirju on siin kuvamiseks liiga palju.",
-       "watchlisttools-clear": "Tühjenda jälgimisloend",
+       "watchlisttools-clear": "tühjenda jälgimisloend",
        "watchlisttools-view": "näita vastavaid muudatusi",
        "watchlisttools-edit": "vaata ja redigeeri jälgimisloendit",
        "watchlisttools-raw": "redigeeri jälgimisloendi toorandmeid",
index 6370801..f35ac7f 100644 (file)
        "blockedtitle": "L’utilisateur est bloqué.",
        "blockedtext": "<strong>Votre compte utilisateur ou votre adresse IP a été bloqué.</strong>\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : <em>$2</em>.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité n’a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez préciser ces indications dans toutes les requêtes que vous ferez.",
        "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n:<em>$2:</em>\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité d’envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n’a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez préciser ces indications dans toutes les requêtes que vous ferez.",
+       "systemblockedtext": "Votre nom d'utilisateur ou votre adresse IP ont été bloqués par MediaWiki.\nLa raison donnée est la suivante:\n\n:<em>$2</em>\n\n* Le début du blocage: $8\n* Expiration d'un délai de blocage: $6\n* Elément concerné: $7\n\nVotre adresse IP actuelle est de $3.\nVeuillez inclure tous les détails ci-dessus dans chacune des requêtes que vous faites.",
        "blockednoreason": "aucune raison donnée",
        "whitelistedittext": "Vous devez vous $1 pour avoir la permission de modifier le contenu.",
        "confirmedittext": "Vous devez confirmer votre adresse de courriel avant de modifier les pages.\nVeuillez entrer et valider votre adresse de courriel dans vos [[Special:Preferences|préférences]].",
        "pageinfo-length": "Taille de la page (en octets)",
        "pageinfo-article-id": "Numéro de la page",
        "pageinfo-language": "Langue du contenu de la page",
+       "pageinfo-language-change": "modifier",
        "pageinfo-content-model": "Modèle de contenu de la page",
        "pageinfo-content-model-change": "modifier",
        "pageinfo-robot-policy": "Indexation par robots",
index e261808..090acde 100644 (file)
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] eliminada da categoría [[Special:WhatLinksHere/$1||esta páxina está incluída noutras páxinas]]",
        "autochange-username": "Cambio automático de MediaWiki",
        "upload": "Subir un ficheiro",
-       "uploadbtn": "Subir o ficheiro",
+       "uploadbtn": "Subir un ficheiro",
        "reuploaddesc": "Cancelar a subida e volver ao formulario de subidas",
        "upload-tryagain": "Enviar a descrición do ficheiro modificada",
        "uploadnologin": "Non accedeu ao sistema",
index face238..6eed285 100644 (file)
        "blockedtitle": "Le usator es blocate",
        "blockedtext": "'''Tu nomine de usator o adresse IP ha essite blocate.'''\n\nLe blocada esseva facite per $1.\nLe motivo presentate es ''$2''.\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Le blocato intendite: $7\n\nTu pote contactar $1 o un altere [[{{MediaWiki:Grouppage-sysop}}|administrator]] pro discuter le blocada.\nTu non pote usar le function 'inviar e-mail a iste usator' salvo que un adresse de e-mail valide es specificate in le\n[[Special:Preferences|preferentias de tu conto]] e que tu non ha essite blocate de usar lo.\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
        "autoblockedtext": "Tu adresse de IP ha essite automaticamente blocate proque un altere usator lo usava qui esseva blocate per $1.\nLe motivo presentate es:\n\n:''$2''\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Blocato intendite: $7\n\nTu pote contactar $1 o un del altere [[{{MediaWiki:Grouppage-sysop}}|administratores]] pro discuter le blocada.\n\nNota que tu non pote utilisar le function \"inviar e-mail a iste usator\" salvo que tu ha registrate un adresse de e-mail valide in tu [[Special:Preferences|preferentias de usator]] e que tu non ha essite blocate de usar lo.\n\nTu adresse IP actual es $3, e le ID del blocada es #$5.\nPer favor include tote le detalios supra specificate in omne correspondentia.",
+       "systemblockedtext": "Tu nomine de usator o adresse IP ha essite blocate automaticamente per MediaWiki.\nLe motivo presentate es:\n\n:<em>$2</em>\n\n* Initio del blocada: $8\n* Expiration del blocada: $6\n* Blocato intendite: $7\n\nTu adresse IP actual es $3.\nPer favor, include tote le detalios enumerate hic supra in omne questiones que tu pone.",
        "blockednoreason": "nulle motivo specificate",
        "whitelistedittext": "Tu debe $1 pro poter modificar paginas.",
        "confirmedittext": "Tu debe confirmar tu adresse de e-mail pro poter modificar paginas.\nPer favor entra e valida tu adresse de e-mail per medio de tu [[Special:Preferences|preferentias de usator]].",
        "emailccsubject": "Copia de tu message a $1: $2",
        "emailsent": "E-mail inviate",
        "emailsenttext": "Tu message de e-mail ha essite inviate.",
-       "emailuserfooter": "Iste e-mail ha essite {{GENDER:$1|inviate}} per $1 a {{GENDER:$2|$2}} con le function \"{{int:emailuser}}\" in {{SITENAME}}.",
+       "emailuserfooter": "Iste e-mail ha essite {{GENDER:$1|inviate}} per $1 a {{GENDER:$2|$2}} con le function \"{{int:emailuser}}\" in {{SITENAME}}.\n{{GENDER:$2|Le}} message ha essite inviate directemente al {{GENDER:$1|expeditor|expeditrice}} original, revelante {{GENDER:$2|tu}} adresse de e-mail a {{GENDER:$1|ille|illa}}.",
        "usermessage-summary": "Lassante un message de systema.",
        "usermessage-editor": "Messagero del systema",
        "watchlist": "Observatorio",
        "pageinfo-length": "Dimension del pagina (in bytes)",
        "pageinfo-article-id": "ID del pagina",
        "pageinfo-language": "Lingua del contento del pagina",
+       "pageinfo-language-change": "cambiar",
        "pageinfo-content-model": "Modello de contento de pagina",
        "pageinfo-content-model-change": "cambiar",
        "pageinfo-robot-policy": "Indexation per robots",
        "restrictionsfield-badip": "Adresse o intervallo IP non valide: $1",
        "restrictionsfield-label": "Intervallos IP permittite:",
        "restrictionsfield-help": "Un adresse IP o intervallo CIDR per linea. Pro activar toto, usa<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "revid": "version $1",
        "pageid": "ID de pagina $1"
 }
index 47791ce..31d3584 100644 (file)
@@ -33,6 +33,7 @@
        "tog-enotifminoredits": "ອີເມລຫາເຊັ່ນກັນສຳລັບການແກ້ໄຂໜ້າແລະໄຟລ໌ເລັກນ້ອຍ",
        "tog-enotifrevealaddr": "ເປີດເຜີຍທີ່ຢູ່ອີເມລຂອງຂ້ອຍໃນອີເມລແຈ້ງເຕືອນ",
        "tog-shownumberswatching": "ສະແດງຈຳນວນຜູ້ໃຊ້ທີ່ຕິດຕາມ",
+       "tog-oldsig": "ລາຍເຊັນຂອງທ່ານທີ່ມີຢູ່:",
        "tog-fancysig": "ຖືລາຍເຊັນເປັນຂໍ້ຄວາມວິກິ (ໂດຍບໍ່ມີລິງຄ໌ອັດຕະໂນມັດ)",
        "tog-uselivepreview": "ໃຊ້ການສະແດງໂຕຢ່າງແບບສົດ",
        "tog-forceeditsummary": "ເຕືອນເມື່ອຊ່ອງຄຳອະທິບາຍໂດຍຫຍໍ້ວ່າງເປົ່າ",
        "talk": "ສົນທະນາ",
        "views": "ເທື່ອເບິ່ງ",
        "toolbox": "ເຄື່ອງມື",
+       "tool-link-emailuser": "ສົ່ງອີເມວຫາ{{GENDER:$1|ຜູ້ໃຊ້}}ນີ້",
        "userpage": "ເບິ່ງໜ້າສົນທະນາຂອງຜູ້ໃຊ້",
        "projectpage": "ເບິ່ງໝ້າໂຄງການ",
        "mediawikipage": "ເບິ່ງ ໝ້າຂໍ້ຄວາມ",
        "privacy": "ນະໂຍບາຍຄວາມເປັນສ່ວນຕົວ",
        "privacypage": "Project:ນະໂຍບາຍຄວາມເປັນສ່ວນຕົວ",
        "badaccess": "ການອະນຸມັດບໍ່ຖືກຕ້ອງ",
-       "badaccess-group0": "ທ່ານ ບໍ່ໄດ້ຮັບອະນຸຍາດ ໃຫ້ປະຕິບັດການ ທີ່ ທ່ານ ສັ່ງ.",
+       "badaccess-group0": "ທ່ານບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ປະຕິບັດການຕາມທີ່ທ່ານຮ້ອງຂໍໄວ້.",
        "versionrequired": "ຕ້ອງການເວີຣ໌ຊັ່ນ $1 ຂອງມີເດຍວິກິ",
        "ok": "ຕົກລົງ",
        "retrievedfrom": "ດຶງຂໍ້ມູນຈາກ \"$1\"",
        "readonly": "ຖານຂໍ້ມູນຖືກລອັກ",
        "enterlockreason": "ກະລຸນາຂຽນເຫດຜົນໃນການລອັກ, ລວມທັງ ປະມານເວລາທີ່ຈະປົດລອັກ",
        "missingarticle-diff": "(ສ່ວນຕ່າງ: $1, $2)",
+       "readonly_lag": "ຖານຂໍ້ມຸນໄດ້ຖືກລັອກແລ້ວໂດຍອັດຕະໂນມັດຂະນະທີ່ເຊີເວີ slave database ຖືກຈັບໃຫ້ອັນຫຼັກ",
        "internalerror": "ມີຄວາມຜິດພາດພາຍໃນ",
        "filerenameerror": "ບໍ່ສາມາດ ປ່ຽນ ຊື່ໄຟລ໌  \"$1\" ໄປເປັນ  \"$2\" ໄດ້.",
        "cannotdelete": "ບໍ່ສາມາດລຶບໜ້າຫຼືໄຟລ໌ \"$1\" ໄດ້.\nມັນອາດຈະຖືກລຶບໂດຍໃຜຜູ້ໜຶ່ງແລ້ວ.",
index 1d1d5a9..e69632a 100644 (file)
        "views": "Peržiūros",
        "toolbox": "Įrankiai",
        "tool-link-userrights": "Keisti {{GENDER:$1|naudotojo|naudotojos}} grupes",
+       "tool-link-userrights-readonly": "Žiūrėti {{GENDER:$1|vartotojo|vartotojos}} grupes",
        "tool-link-emailuser": "Siųsti {{GENDER:$1|šiam naudotojui|šiai naudotojai}} el. laišką",
        "userpage": "Rodyti naudotojo puslapį",
        "projectpage": "Rodyti projekto puslapį",
        "ok": "Gerai",
        "retrievedfrom": "Gauta iš „$1“",
        "youhavenewmessages": "Jūs turite $1 ($2).",
-       "youhavenewmessagesfromusers": "Jūs gavote $1 nuo {{PLURAL:$3|kito naudotojo|$3 naudotojų}} ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Jūs gavote}} $1 iš {{PLURAL:$3|kito naudotojo|$3 naudotojų}} ($2).",
        "youhavenewmessagesmanyusers": "Jūs turite $1 iš daugelio vartotojų ( $2 ) .",
        "newmessageslinkplural": "{{PLURAL:$1|nauja žinutė|999=naujos žinutės}}",
        "newmessagesdifflinkplural": "paskutinis {{PLURAL:$1|pakeitimas|999=pakeitimai}}",
        "editusergroup": "Redaguoti {{GENDER:$1|naudotojo}} grupes",
        "editinguser": "Redaguojamos {{GENDER:$1|naudotojo}} <strong>[[User:$1|$1]]</strong> $2 teisės",
        "userrights-editusergroup": "Redaguoti naudotojų grupes",
+       "userrights-viewusergroup": "Žiūrėti naudotojo grupes",
        "saveusergroups": "Saugoti {{GENDER:$1|naudotojo}} grupes",
        "userrights-groupsmember": "Narys:",
        "userrights-groupsmember-auto": "Narys automatiškai:",
        "action-deletelogentry": "trinti žurnalo įrašus",
        "action-deletedhistory": "žiūrėti puslapio ištrintą istoriją",
        "action-browsearchive": "ieškoti ištrintų puslapių",
-       "action-undelete": "atkurti šį puslapį",
+       "action-undelete": "atkurti puslapius",
        "action-suppressrevision": "peržiūrėti ir atkurti šią paslėptą versiją",
        "action-suppressionlog": "peržiūrėti šį privatų registrą",
        "action-block": "neleisti šiam naudotojui redaguoti",
        "apisandbox-alert-field": "Šio lauko reikšmė yra neteisinga.",
        "apisandbox-continue": "Tęsti",
        "apisandbox-continue-clear": "Išvalyti",
+       "apisandbox-multivalue-all-values": "$1 (Visos reikšmės)",
        "booksources": "Knygų šaltiniai",
        "booksources-search-legend": "Knygų šaltinių paieška",
        "booksources-search": "Ieškoti",
        "pageinfo-length": "Puslapio ilgis (baitais)",
        "pageinfo-article-id": "Puslapio ID",
        "pageinfo-language": "Puslapio turinio kalba",
+       "pageinfo-language-change": "keisti",
        "pageinfo-content-model": "Puslapio turinio modelis",
        "pageinfo-content-model-change": "keisti",
        "pageinfo-robot-policy": "Robotų indeksavimas",
        "special-characters-title-emdash": "em brūkšnys",
        "special-characters-title-minus": "minuso ženklas",
        "mw-widgets-dateinput-no-date": "Nepasirinkta data",
+       "mw-widgets-mediasearch-noresults": "Rezultatų nerasta.",
        "mw-widgets-titleinput-description-new-page": "puslapis dar neegzistuoja",
        "mw-widgets-titleinput-description-redirect": "nukreipti į $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Pridėti kategoriją...",
        "sessionmanager-tie": "Negalima kombinuoti kelių užklausų autentikacijos tipų: $1.",
        "sessionprovider-generic": "$1 sesijos",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sesijos su slapukais",
        "authprovider-resetpass-skip-help": "Praleisti slaptažodžio perstatymą.",
        "specialpage-securitylevel-not-allowed-title": "Neleidžiama",
        "specialpage-securitylevel-not-allowed": "Apgailestaujame, tačiau jūs negalite naudotis šiuo puslapiu, nes nepavyko patvirtinti jūsų tapatybės.",
+       "authpage-cannot-login": "Negalima pradėti prisijungimo.",
+       "authpage-cannot-login-continue": "Negalima tęsti prisijungimo. Greičiausiai baigėsi jūsų sesijos laikas.",
+       "authpage-cannot-create": "Nepavyko pradėti paskyros kūrimo.",
+       "authpage-cannot-create-continue": "Negalima tęsti paskyros kūrimo. Greičiausiai baigėsi jūsų sesijos laikas.",
+       "authpage-cannot-link": "Nepavyko pradėti paskyros susiejimo.",
+       "authpage-cannot-link-continue": "Negalima tęsti paskyros susiejimo. Greičiausiai baigėsi jūsų sesijos laikas.",
        "cannotauth-not-allowed-title": "Teisė nesuteikta",
        "cannotauth-not-allowed": "Jūs negalite naudotis šiuo puslapiu",
        "credentialsform-account": "Paskyros vardas:",
        "linkaccounts-submit": "Susieti paskyras",
        "unlinkaccounts": "Atsieti paskyras",
        "unlinkaccounts-success": "Paskyra buvo atsieta.",
-       "revid": "apžvalga $1"
+       "revid": "apžvalga $1",
+       "pageid": "puslapio ID $1"
 }
index 4f46076..7abc8fb 100644 (file)
        "search-external": "Extern zoeken",
        "searchdisabled": "Zoeken in {{SITENAME}} is niet mogelijk.\nU kunt gebruik maken van Google.\nDe gegevens over {{SITENAME}} zijn mogelijk niet bijgewerkt.",
        "search-error": "Er is een fout opgetreden tijdens het zoeken: $1",
+       "search-warning": "Een waarschuwing is opgetreden tijdens het zoeken: $1",
        "preferences": "Voorkeuren",
        "mypreferences": "Voorkeuren",
        "prefs-edits": "Aantal bewerkingen:",
        "userrights-user-editname": "Voer een gebruikersnaam in:",
        "editusergroup": "Gebruikersgroepen wijzigen",
        "editinguser": "Bezig met wijzigen van de gebruikersrechten van gebruiker '''[[User:$1|$1]]''' $2",
+       "viewinguserrights": "Gebruikersrechten bekijken van {{GENDER:$1|gebruiker}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Gebruikersgroepen wijzigen",
+       "userrights-viewusergroup": "Toon gebruikersgroepen",
        "saveusergroups": "{{GENDER:$1|Gebruikersgroepen}} opslaan",
        "userrights-groupsmember": "Lid van:",
        "userrights-groupsmember-auto": "Impliciet lid van:",
        "emailccsubject": "Kopie van uw bericht aan $1: $2",
        "emailsent": "E-mail verzonden",
        "emailsenttext": "Uw e-mail is verzonden.",
-       "emailuserfooter": "Deze e-mail is {{GENDER:$1|verstuurd}} door $1 aan {{GENDER:$2|$2}} door de functie \"{{int:emailuser}}\" van {{SITENAME}}. {{GENDER:$2|Uw}} e-mail wordt direct naar de {{GENDER:$1|oorspronkelijke afzender}} verstuurd, waardoor {{GENDER:$2|uw}} e-mailadres aan {{GENDER:$1|hun}} onthult wordt.",
+       "emailuserfooter": "Deze e-mail is door $1 aan {{GENDER:$2|$2}} {{GENDER:$1|verstuurd}} middels de functie \"{{int:emailuser}}\" van {{SITENAME}}. {{GENDER:$2|Uw}} e-mail wordt direct naar de {{GENDER:$1|oorspronkelijke afzender}} verstuurd, waardoor {{GENDER:$2|uw}} e-mailadres aan {{GENDER:$1|hem|haar|hem of haar}} onthuld wordt.",
        "usermessage-summary": "Systeembericht achtergelaten",
        "usermessage-editor": "Systeembericht",
        "watchlist": "Volglijst",
        "pageinfo-length": "Paginalengte (in bytes)",
        "pageinfo-article-id": "Paginanummer",
        "pageinfo-language": "Taal voor de pagina",
-       "pageinfo-language-change": "wijziging",
+       "pageinfo-language-change": "wijzigen",
        "pageinfo-content-model": "Paginainhoudmodel",
        "pageinfo-content-model-change": "wijzigen",
        "pageinfo-robot-policy": "Indexering door robots",
        "confirmemail_body_set": "Iemand, waarschijnlijk u, met het IP-adres $1,\nheeft het e-mailadres voor gebruiker \"$2\" op {{SITENAME}} ingesteld op dit e-mailadres.\n\nOpen de volgende koppeling in uw webbrowser om te bevestigen dat u deze gebruiker bent en om de e-mailmogelijkheden op {{SITENAME}} opnieuw te activeren:\n\n$3\n\nAls deze gebruiker *niet* aan u toebehoort, klik dan op de volgende koppeling om de bevestiging van uw e-mailadres te annuleren:\n\n$5\n\nDe bevestigingscode vervalt op $4.",
        "confirmemail_invalidated": "De e-mailbevestiging is geannuleerd",
        "invalidateemail": "E-mailbevestiging annuleren",
+       "notificationemail_body_changed": "Iemand, waarschijnlijk u, met het IP-adres $1, heeft het e-mailadres van de gebruiker \"$2\" op {{SITENAME}} gewijzigd naar \"$3\". \n\nAls u dit niet was, neem dan onmiddellijk contact op met een sitebeheerder.",
        "notificationemail_body_removed": "Iemand, waarschijnlijk u, met het IP-adres $1, heeft het e-mailadres geregistreerd voor gebruiker \"$2\" verwijderd op {{SITENAME}}. \n\nAls u dit niet was, neem dan onmiddellijk contact op met een sitebeheerder.",
        "scarytranscludedisabled": "[Interwiki-invoeging van sjablonen is uitgeschakeld]",
        "scarytranscludefailed": "[De sjabloon $1 kon niet opgehaald worden]",
        "tags-delete-not-found": "Het label \"$1\" bestaat niet.",
        "tags-delete-too-many-uses": "Het label \"$1\" is toegepast op meer dan $2 {{PLURAL:$2|versies}}. Daardoor kan het niet verwijderd worden.",
        "tags-delete-warnings-after-delete": "Het label \"$1\" is verwijderd, maar de volgende {{PLURAL:$2|waarschuwing is|waarschuwingen zijn}} opgetreden:",
+       "tags-delete-no-permission": "U hebt geen rechten om wijzigingslabels te verwijderen.",
        "tags-activate-title": "Label activeren",
        "tags-activate-question": "U activeert het label \"$1\".",
        "tags-activate-reason": "Reden:",
        "feedback-useragent": "Useragent:",
        "searchsuggest-search": "Doorzoek {{SITENAME}}",
        "searchsuggest-containing": "bevat...",
+       "api-error-autoblocked": "Uw IP-adres is automatisch geblokeerd, omdat het gebruikt is door een geblokkeerde gebruiker.",
        "api-error-badaccess-groups": "U mag geen bestanden uploaden in deze wiki.",
        "api-error-badtoken": "Interne fout: het token klopt niet.",
        "api-error-blocked": "U bent geblokkeerd en kunt niet bewerken.",
        "mw-widgets-dateinput-no-date": "Geen datum geselecteerd",
        "mw-widgets-dateinput-placeholder-day": "JJJJ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
+       "mw-widgets-mediasearch-noresults": "Geen resultaten gevonden.",
        "mw-widgets-titleinput-description-new-page": "pagina bestaat nog niet",
        "mw-widgets-titleinput-description-redirect": "doorverwijzing naar $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Voeg een categorie toe...",
        "sessionmanager-tie": "Het is niet mogelijk om meerdere authenticatietypen voor verzoeken te combineren: $1.",
        "sessionprovider-generic": "$1-sessies",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "op cookies gebaseerde sessies",
        "linkaccounts-success-text": "Het account is gekoppeld.",
        "linkaccounts-submit": "Accounts koppelen",
        "unlinkaccounts": "Accounts ontkoppelen",
-       "unlinkaccounts-success": "Het account is ontkoppeld."
+       "unlinkaccounts-success": "Het account is ontkoppeld.",
+       "revid": "versie $1",
+       "pageid": "Pagina-ID $1"
 }
index 9ae24b4..a89870c 100644 (file)
        "pageinfo-length": "Długość strony (w bajtach)",
        "pageinfo-article-id": "Identyfikator strony",
        "pageinfo-language": "Język zawartości strony",
+       "pageinfo-language-change": "zmień",
        "pageinfo-content-model": "Model zawartości",
        "pageinfo-content-model-change": "zmień",
        "pageinfo-robot-policy": "Indeksowanie przez roboty",
index 1563f88..15ac91a 100644 (file)
        "emailccsubject": "Used in [[Special:EmailUser]].\n\nSubject of the carbon-copied email for the sender sent through MediaWiki.\n\nParameters:\n* $1 - target username\n* $2 - email subject",
        "emailsent": "Title of [[Special:EmailUser]] when it says you it sent an email",
        "emailsenttext": "Confirmation page: when you send an email, [[Special:EmailUser]] says you this (Your email has been sent).\n\nParameters:\n* $1 - (Optional) the recipient's username, for local customizations",
-       "emailuserfooter": "This message is appended to every email sent through the \"Email user\" function. Parameters:\n* $1 - username of the sender\n* $2 - username of the recipient",
+       "emailuserfooter": "This message is appended to every email sent through the \"Email user\" function. Parameters:\n* $1 - username of the sender\n* $2 - username of the recipient\n\n{{doc-singularthey}}",
        "usermessage-summary": "This message is used as an edit summary for any message that is posted because of a system event. Translate \"leaving a message\" in the sense of: to give a message to someone; to deliver a message somewhere; to deposit.",
        "usermessage-editor": "The user name for the user that is the editor of system messages. See [{{canonicalurl:Thread:Support/Message_info_please}} discussion on Support].",
        "usermessage-template": "{{optional}}",
index 296c3cc..ea3367c 100644 (file)
        "blockedtitle": "Участник заблокирован",
        "blockedtext": "'''Ваша учётная запись или IP-адрес заблокированы.'''\n\nБлокировка произведена администратором $1.\nУказана следующая причина: «''$2''».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\nОбратите внимание, что не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\nВаш IP-адрес — $3, идентификатор блокировки — $5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
        "autoblockedtext": "Ваш IP-адрес автоматически заблокирован в связи с тем, что он ранее использовался кем-то из участников, заблокированных {{GENDER:$4|участником|участницей}} $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Пожалуйста, указывайте эти сведения в любых своих обращениях.",
+       "systemblockedtext": "Ваше имя участника или IP-адрес были автоматически заблокированы MediaWiki.\nУказана следующая причина:\n\n:<em>$2</em>\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВаш текущий IP-адрес $3.\nПожалуйста, указывайте все эти сведения в любых своих обращениях.",
        "blockednoreason": "причина не указана",
        "whitelistedittext": "Вы должны $1 для изменения страниц.",
        "confirmedittext": "Вы должны подтвердить свой адрес электронной почты перед правкой страниц.\nПожалуйста, введите и подтвердите свой адрес электронной почты в своих [[Special:Preferences|персональных настройках]].",
        "wlshowhidemine": "мои правки",
        "wlshowhidecategorization": "категоризацию страниц",
        "watchlist-options": "Настройки списка наблюдения",
-       "watchlist-mark-all-visited": "Вы уверены, что хотите сбросить непросмотренные изменения списка наблюдения, отметив все страницы как посещённые?",
        "watching": "Добавление в список наблюдения…",
        "unwatching": "Удаление из списка наблюдения…",
        "watcherrortext": "Произошла ошибка при изменении настройки наблюдения для «$1».",
        "pageinfo-length": "Длина страницы (в байтах)",
        "pageinfo-article-id": "Идентификатор страницы",
        "pageinfo-language": "Язык страницы",
+       "pageinfo-language-change": "изменить",
        "pageinfo-content-model": "Модель содержимого страницы",
        "pageinfo-content-model-change": "изменить",
        "pageinfo-robot-policy": "Индексация поисковыми роботами",
        "restrictionsfield-badip": "Недопустимый IP-адрес или диапазон адресов: $1",
        "restrictionsfield-label": "Разрешённые диапазоны IP-адресов:",
        "restrictionsfield-help": "По одному IP-адресу или CIDR-диапазону в строке. Чтобы разрешить всё, используйте <br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "revid": "версия $1",
        "pageid": "ID страницы $1"
 }
index 65eb76a..6b7779b 100644 (file)
        "timezone-local": "Олохтоох",
        "duplicate-defaultsort": "Болҕой: Наардааһын «$2» күлүүһэ урукку «$1» күлүүһү сабар (Ключ сортировки переопределяет прежний ключ).",
        "duplicate-displaytitle": "<strong>Болҕой:</strong> Көрдөрүллүбүт «$2» аат урут көрдөрүллүбүт «$1» ааты уларытар.",
+       "restricted-displaytitle": "<strong>Болҕой:</strong> Суруллубут «$1» диэн аат ылыныллыбатах, тоҕо диэтэххэ сирэй билиҥҥи аатыгар сөп түбэспэт.",
        "invalid-indicator-name": "<strong>Алҕас:Сирэй туругун көрдөрөр индикатор </strong> атрибута <code>name</code> кураанах буолуо суохтаах.",
        "version": "MediaWiki барыла (биэрсийэтэ)",
        "version-extensions": "Туруоруллубут расширениялар",
        "tags-deactivate-not-allowed": "\"$1\" тиэги араарар табыллыбат.",
        "tags-deactivate-submit": "араар",
        "tags-apply-no-permission": "Бэйэҥ уларытыыгар уларытыы тиэгин туруорар кыаҕыҥ суох эбит.",
-       "tags-apply-blocked": "Хааччахтана сылдьар кэмҥэр көннөрүүлэриҥ тиэгин уларытарыҥ табыллыбат.",
+       "tags-apply-blocked": "Хааччахтана сылдьар {{GENDER:$1|кэмҥэр}} көннөрүүлэриҥ тиэгин уларытарыҥ табыллыбат.",
        "tags-apply-not-allowed-one": "«$1» тиэги илииннэн туруорар табыллыбат эбит.",
        "tags-apply-not-allowed-multi": "Маннык {{PLURAL:$2|тиэк илиинэн угуллубат|тиэктэр илиинэн угуллубаттар}}: $1",
        "tags-update-no-permission": "Сурунаал тус-туспа торумнарын уонна суруктарын тиэгин эбэр уонна уларытар кыаҕыҥ суох эбит.",
-       "tags-update-blocked": "Хааччахтаммыт буолаҥҥын уларытыы тиэктэрин уларытар кыаҕыҥ суох.",
+       "tags-update-blocked": "Хааччахтаммыт {{GENDER:$1|буолаҥҥын}} уларытыы тиэктэрин уларытар кыаҕыҥ суох.",
        "tags-update-add-not-allowed-one": "«$1» тиэги илииннэн туруорар табыллыбат эбит.",
        "tags-update-add-not-allowed-multi": "Маннык {{PLURAL:$2|тиэк илиинэн угуллубат|тиэктэр илиинэн угуллубаттар}}: $1",
        "tags-update-remove-not-allowed-one": "«$1» тиэги сотор табыллыбат эбит.",
        "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
        "htmlform-date-invalid": "Суруйбутуҥ күнү-дьылы бэлиэтээһиҥҥэ майгыннаабат. Маннык көрүҥү туһан: СССС-ЫЫ-КК.",
        "htmlform-time-invalid": "Суруйбутуҥ кэми бэлиэтээһиҥҥэ майгыннаабат. Маннык көрүҥү туһан: ЧЧ-ММ-СС.",
+       "htmlform-datetime-invalid": "Суруйбутуҥ күнү-дьылы уонна кэми бэлиэтээһиҥҥэ майгыннаабат. Маннык көрүҥү туһан: СССС-ЫЫ-КК ЧЧ-ММ-СС.",
+       "htmlform-date-toolow": "Ыйбыт кэмиҥ муҥутуур кылгас кэмтэн кылгас эбит — $1.",
+       "htmlform-date-toohigh": "Ыйбыт кэмиҥ муҥутуур болдьохтон хойут эбит — $1.",
+       "htmlform-time-toolow": "Ыйбыт кэмиҥ болдьохтон кылгас — $1.",
+       "htmlform-time-toohigh": "Ыйбыт кэмиҥ болдьохтон уһун — $1.",
+       "htmlform-datetime-toolow": "Ыйбыт кэмиҥ анаммыт ыйтан-күнтэн уонна кэмтэн эрдэ буолан хаалбыт — $1.",
+       "htmlform-datetime-toohigh": "Ыйбыт кэмиҥ анаммыт күнтэн-дьылтан уонна кэмтэн хойут буолан хаалбыт — $1.",
        "htmlform-title-badnamespace": "[[:$1]] бу аат далыгар киирбэт эбит «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» оҥоһуллар сирэй аата буолбатах",
        "htmlform-title-not-exists": "$1 суох.",
        "htmlform-user-not-exists": "<strong>$1</strong> суох.",
        "htmlform-user-not-valid": "<strong>$1</strong> — маннык аат сатаммат.",
        "logentry-delete-delete": "$3 сирэйи $1 соппут",
+       "logentry-delete-delete_redir": "$1 кыттааччы $3 утаарыыны хос суруйуу көмөтүнэн {{GENDER:$2|соппут}}",
        "logentry-delete-restore": "$3 сирэйи $1 сөргүппүт",
        "logentry-delete-event": "Сурунаал $5 суругун көстүүтүн манна $3 $1 уларыппыт: $4",
        "logentry-delete-revision": "$3 сирэй $5 барылын көстүүтүн бу сирэйгэ $1 уларыппыт: $4",
index 4683271..037258d 100644 (file)
        "sp-deletedcontributions-contribs": "ڀاڱيداريون",
        "linksearch-ns": "نانءُپولار",
        "linksearch-ok": "ڳوليو",
+       "listusersfrom": "تي شروع ڪندڙ يوزر ڏيکاريو:",
        "listusers-submit": "ڏيکاريو",
        "listusers-noresult": "ڪو بہ يُوزر نہ لڌو",
        "listusers-blocked": "(بندشيل)",
        "activeusers": "سرگرم يُوزرس جي فهرست",
+       "activeusers-groups": "گروھن سان تعلق رکندڙ يوزرس ڏيکاريو:",
+       "activeusers-excludegroups": "گروھن سان تعلق رکندڙ گروھ ڇڏيو:",
        "activeusers-noresult": "ڪي بہ يُوزرس نہ لڌا.",
        "activeusers-submit": "سرگرم يُوزرس ڏيکاريو",
        "listgrouprights": "يوزر گروپ جا حق",
index 0c9783c..cd7588f 100644 (file)
        "blockedtitle": "Användaren är blockerad",
        "blockedtext": "'''Din IP-adress eller ditt användarnamn är blockerat.'''\n\nBlockeringen utfördes av $1 med motiveringen: ''$2''.\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6.\n* Blockeringen var avsedd för: $7.\n\nDu kan kontakta $1 eller någon annan av [[{{MediaWiki:Grouppage-sysop}}|administratörerna]] för att diskutera blockeringen.\nOm du är inloggad och har uppgivit en e-postadress i dina [[Special:Preferences|inställningar]] så kan du använda funktionen 'Skicka e-post till den här användaren', såvida du inte blivit blockerad från funktionen.\n\nDin IP-adress är $3 och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
        "autoblockedtext": "Din IP-adress har blockerats automatiskt eftersom den har använts av en annan användare som blockerats av $1.\nMotiveringen av blockeringen var:\n\n:''$2''\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDu kan kontakta $1 eller någon annan [[{{MediaWiki:Grouppage-sysop}}|administratör]] för att diskutera blockeringen.\n\nObservera att du inte kan använda dig av funktionen \"skicka e-post till användare\" om du inte har registrerat en giltig e-postadress i [[Special:Preferences|dina inställningar]] eller om du har blivit blockerad från att skicka e-post.\n\nDin nuvarande IP-adress är $3, och blockerings-ID är #$5.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
+       "systemblockedtext": "Ditt användarnamn eller IP-adress h    ar blockerats automatiskt av MediaWiki.\n\nMotiveringen av blockeringen var:\n\n:<em>$2</em>\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDin nuvarande IP-adress är $3.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
        "blockednoreason": "ingen motivering angavs",
        "whitelistedittext": "Vänligen $1 för att redigera sidor.",
        "confirmedittext": "Du måste bekräfta din e-postadress innan du kan redigera sidor. Var vänlig ställ in och validera din e-postadress genom dina [[Special:Preferences|användarinställningar]].",
        "emailccsubject": "Kopia av ditt meddelande till $1: $2",
        "emailsent": "E-post har nu skickats",
        "emailsenttext": "Ditt e-postmeddelande har skickats",
-       "emailuserfooter": "Detta e-postmeddelande {{GENDER:$1|skickades}} av $1 till {{GENDER:$2|$2}} med funktionen \"{{int:emailuser}}\" på {{SITENAME}}. {{GENDER:$2|Ditt}} e-postmeddelande kommer att skickas direkt till {{GENDER:$1|den ursprungliga avsändaren}}, vilket kommer avslöja {{GENDER:$2|din}} e-postadress för {{GENDER:$1|dem}}.",
+       "emailuserfooter": "Detta e-postmeddelande {{GENDER:$1|skickades}} av $1 till {{GENDER:$2|$2}} med funktionen \"{{int:emailuser}}\" på {{SITENAME}}. {{GENDER:$2|Ditt}} e-postmeddelande kommer att skickas direkt till {{GENDER:$1|den ursprungliga avsändaren}}, vilket kommer avslöja {{GENDER:$2|din}} e-postadress för {{GENDER:$1|honom|henne|hen}}.",
        "usermessage-summary": "Lämnar systemmeddelande.",
        "usermessage-editor": "Systemmeddelare",
        "watchlist": "Bevakningslista",
        "wlshowhidemine": "mina redigeringar",
        "wlshowhidecategorization": "kategorisering av sidor",
        "watchlist-options": "Alternativ för bevakningslistan",
-       "watchlist-mark-all-visited": "Är du säker på att du vill återställa osedda förändringar i bevakningslistan genom att markera alla sidor som besökta?",
        "watching": "Bevakar...",
        "unwatching": "Avbevakar...",
        "watcherrortext": "Ett fel inträffade när du ändrade dina bevakningsinställningarna för \"$1\".",
        "pageinfo-length": "Sidlängd (i byte)",
        "pageinfo-article-id": "Sid-ID",
        "pageinfo-language": "Språk för sidinnehåll",
+       "pageinfo-language-change": "ändra",
        "pageinfo-content-model": "Sidinnehållsmodell",
        "pageinfo-content-model-change": "ändra",
        "pageinfo-robot-policy": "Indexering av robotar",
        "restrictionsfield-badip": "Ogiltig IP-adress eller intervall: $1",
        "restrictionsfield-label": "Tillåtna IP-intervall:",
        "restrictionsfield-help": "En IP-adress eller CIDR-intervall per rad. För att aktivera allting, använd<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "revid": "sidversion $1",
        "pageid": "sid-ID $1"
 }
index bf81066..ad5535e 100644 (file)
@@ -39,7 +39,7 @@
        "tog-usenewrc": "จัดกลุ่มการเปลี่ยนแปลงแบ่งตามหน้าในรายการปรับปรุงล่าสุดและรายการเฝ้าดู",
        "tog-numberheadings": "กำหนดเลขหัวเรื่องอัตโนมัติ",
        "tog-showtoolbar": "แสดงแถบเครื่องมือแก้ไข",
-       "tog-editondblclick": "à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¹\80มืà¹\88อà¸\94ัà¸\9aà¹\80à¸\9aิลà¸\84ลิà¸\81",
+       "tog-editondblclick": "à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¹\80มืà¹\88อà¸\84ลิà¸\81สอà¸\87à¸\84รัà¹\89à¸\87",
        "tog-editsectiononrightclick": "เปิดใช้งานการแก้ไขส่วนโดยคลิกขวาที่ชื่อเรื่องของส่วนนั้น",
        "tog-watchcreations": "เพิ่มหน้าที่ฉันสร้างและไฟล์ที่ฉันอัปโหลดเข้ารายการเฝ้าดู",
        "tog-watchdefault": "เพิ่มหน้าและไฟล์ที่ฉันแก้ไขเข้ารายการเฝ้าดู",
        "delete": "ลบ",
        "deletethispage": "ลบหน้านี้",
        "undeletethispage": "กู้คืนหน้านี้",
-       "undelete_short": "กู้คืน $1 การแก้ไข",
+       "undelete_short": "กู้คืนการแก้ไข $1 ครั้ง",
        "viewdeleted_short": "ดู $1 การแก้ไขที่ถูกลบ",
        "protect": "ล็อก",
        "protect_change": "เปลี่ยน",
        "mycustomjsprotected": "คุณไม่มีสิทธิแก้ไขหน้าจาวาสคริปต์นี้",
        "myprivateinfoprotected": "คุณไม่มีสิทธิแก้ไขข้อมูลส่วนตัวของคุณ",
        "mypreferencesprotected": "คุณไม่มีสิทธิแก้ไขการตั้งค่าของคุณ",
-       "ns-specialprotected": "ไม่สามารถแก้ไขหน้าพิเศษ",
+       "ns-specialprotected": "ไม่สามารถแก้ไขหน้าพิเศษได้",
        "titleprotected": "ชื่อเรื่องนี้ถูก [[User:$1|$1]] ป้องกันมิให้สร้าง\nเหตุผลที่ให้ไว้คือ <em>$2</em>",
        "filereadonlyerror": "ไม่สามารถแก้ไขไฟล์ \"$1\" เพราะที่เก็บไฟล์ \"$2\" อยู่ในภาวะอ่านอย่างเดียว\n\nผู้ดูแลระบบที่ล็อกให้คำอธิบายว่า: \"$3\"",
        "invalidtitle-knownnamespace": "ชื่อเรื่องที่มีเนมสเปซ \"$2\" กับข้อความ \"$3\" ไม่ถูกต้อง",
        "previewnote": "<strong>พึงระลึกว่านี่เป็นเพียงการแสดงตัวอย่าง</strong>\nยังไม่ได้บันทึกการเปลี่ยนแปลงของคุณ!",
        "continue-editing": "ไปพื้นที่แก้ไข",
        "previewconflict": "ตัวอย่างนี้สะท้อนข้อความในพื้นที่แก้ไขข้อความส่วนบนซึ่งจะปรากฏหากคุณเลือกบันทึก",
-       "session_fail_preview": "<strong>ขออภัย! ไม่สามารถดำเนินการแก้ไขของคุณได้ เนื่องจากข้อมูลช่วงเวลาสื่อสารสูญหาย</strong>\nโปรดลองอีกครั้ง \nหากยังเสียอยู่ ลอง[[Special:UserLogout|ล็อกเอาต์]]และล็อกอินกลับมา",
-       "session_fail_preview_html": "<strong>ขออภัย! ไม่สามารถดำเนินการแก้ไขของคุณต่อได้ เนื่องจากข้อมูลช่วงเวลาสื่อสารสูญหาย</strong>\n\n<em>เนื่องจาก {{SITENAME}} เปิดใช้งานเอชทีเอ็มแอลล้วน การแสดงตัวอย่างจะถูกซ่อนไว้เพื่อป้องกันการโจมตีด้วยจาวาสคริปต์</em>\n\n<strong>หากนี่เป็นความพยายามแก้ไขโดยชอบ โปรดลองอีกครั้งหนึ่ง</strong> \nหากยังเสียอยู่ ลอง[[Special:UserLogout|ล็อกเอาต์]]และล็อกอินกลับมา",
+       "session_fail_preview": "ขออภัย! เราไม่สามารถดำเนินการแก้ไขของคุณได้ เนื่องจากข้อมูลช่วงเวลาสื่อสารสูญหาย\n\nคุณอาจล็อกเอาต์ไปแล้ว <strong>โปรดตรวจดูให้แน่ใจว่าคุณล็อกอินอยู่ แล้วลองอีกครั้ง</strong> \nหากยังเสียอยู่ ลอง[[Special:UserLogout|ล็อกเอาต์]]และล็อกอินกลับมา แล้วตรวจดูว่าเบราว์เซอร์ที่คุณใช้อนุญาตคุกกี้จากไซต์นี้",
+       "session_fail_preview_html": "ขออภัย! ไม่สามารถดำเนินการแก้ไขของคุณต่อได้ เนื่องจากข้อมูลช่วงเวลาสื่อสารสูญหาย\n\n<em>เนื่องจาก {{SITENAME}} เปิดใช้งานเอชทีเอ็มแอลล้วน การแสดงตัวอย่างจะถูกซ่อนไว้เพื่อป้องกันการโจมตีด้วยจาวาสคริปต์</em>\n\n<strong>หากนี่เป็นความพยายามแก้ไขโดยชอบ โปรดลองอีกครั้งหนึ่ง</strong> \nหากยังเสียอยู่ ลอง[[Special:UserLogout|ล็อกเอาต์]]และล็อกอินกลับมา และตรวจดูให้แน่ใจว่าเบราว์เซอร์ที่คุณใช้อนุญาตคุกกี้จากไซต์นี้",
        "token_suffix_mismatch": "<strong>การแก้ไขของคุณถูกปฏิเสธ เนื่องจากเครื่องลูกข่ายของคุณทำให้อักขระเครื่องหมายวรรคตอนในโทเค็นการแก้ไขเสีย</strong>\nการแก้ไขนี้ถูกปฏิเสธเพื่อป้องกันการวิบัติของข้อความหน้า\nบางครั้งเกิดปัญหานี้ขึ้นเมื่อคุณใช้บริการเว็บพร็อกซีนิรนามที่มีจุดบกพร่อง",
        "edit_form_incomplete": "<strong>แบบแก้ไขบางส่วนไปไม่ถึงเซิร์ฟเวอร์ ตรวจสอบอีกครั้งว่าการแก้ไขของคุณยังอยู่และลองอีกครั้ง</strong>",
        "editing": "กำลังแก้ไข $1",
        "prefswarning-warning": "คุณเปลี่ยนแปลงการตั้งค่าของคุณที่ยังไม่ได้บันทึก\nหากคุณออกจากหน้านี้โดยไม่คลิก \"$1\" จะไม่ปรับการตั้งค่าของคุณ",
        "prefs-tabs-navigation-hint": "แนะนำ: คุณสามารถใช้แป้นลูกศรซ้ายและขวาเพื่อนำทางระหว่างแถบในรายการแถบได้",
        "userrights": "การบริหารสิทธิผู้ใช้",
-       "userrights-lookup-user": "à¸\9aริหารà¸\81ลุà¹\88มผู้ใช้",
+       "userrights-lookup-user": "à¹\80ลือà¸\81ผู้ใช้",
        "userrights-user-editname": "ใส่ชื่อผู้ใช้:",
-       "editusergroup": "à¹\81à¸\81à¹\89à¹\84à¸\82à¸\81ลุà¹\88ม{{GENDER:$1|à¸\9cูà¹\89à¹\83à¸\8aà¹\89}}",
+       "editusergroup": "à¹\82หลà¸\94à¸\81ลุà¹\88มà¸\9cูà¹\89à¹\83à¸\8aà¹\89",
        "editinguser": "กำลังเปลี่ยนสิทธิผู้ใช้ของผู้ใช้ <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "แก้ไขกลุ่มผู้ใช้",
        "saveusergroups": "บันทึกกลุ่ม{{GENDER:$1|ผู้ใช้}}",
        "rightslogtext": "นี่คือปูมการเปลี่ยนแปลงสิทธิผู้ใช้",
        "action-read": "อ่านหน้านี้",
        "action-edit": "แก้ไขหน้านี้",
-       "action-createpage": "สร้างหน้า",
-       "action-createtalk": "สร้างหน้าอภิปราย",
+       "action-createpage": "สร้างหน้านี้",
+       "action-createtalk": "สร้างหน้าอภิปรายนี้",
        "action-createaccount": "สร้างบัญชีผู้ใช้นี้",
        "action-history": "ดูประวัติหน้านี้",
        "action-minoredit": "ทำเครื่องหมายการแก้ไขนี้เป็นการแก้ไขเล็กน้อย",
        "action-upload_by_url": "อัปโหลดไฟล์นี้จากยูอาร์แอล",
        "action-writeapi": "ใช้การเขียนเอพีไอ",
        "action-delete": "ลบหน้านี้",
-       "action-deleterevision": "ลบรุ่นปรับปรุงนี้",
-       "action-deletedhistory": "à¸\94ูà¸\9bระวัà¸\95ิà¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¸\82อà¸\87หà¸\99à¹\89าà¸\99ีà¹\89",
+       "action-deleterevision": "ลบรุ่นปรับปรุง",
+       "action-deletedhistory": "à¸\94ูà¸\9bระวัà¸\95ิà¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9aà¸\82อà¸\87หà¸\99à¹\89าà¹\83à¸\94หà¸\99à¹\89าหà¸\99ึà¹\88à¸\87",
        "action-browsearchive": "ค้นหาหน้าที่ถูกลบ",
-       "action-undelete": "กู้คืนหน้านี้",
-       "action-suppressrevision": "à¸\97à¸\9aà¸\97วà¸\99à¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99รุà¹\88à¸\99à¸\9bรัà¸\9aà¸\9bรุà¸\87à¸\97ีà¹\88à¸\8bà¹\88อà¸\99อยูà¹\88à¸\99ีà¹\89",
+       "action-undelete": "กู้คืนหน้า",
+       "action-suppressrevision": "à¸\95รวà¸\88à¸\97าà¸\99à¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99รุà¹\88à¸\99à¸\9bรัà¸\9aà¸\9bรุà¸\87à¸\97ีà¹\88à¸\8bà¹\88อà¸\99อยูà¹\88",
        "action-suppressionlog": "ดูปูมส่วนตัวนี้",
        "action-block": "บล็อกผู้ใช้นี้มิให้แก้ไข",
        "action-protect": "เปลี่ยนระดับการล็อกสำหรับหน้านี้",
        "recentchangeslinked-page": "ชื่อหน้า:",
        "recentchangeslinked-to": "แสดงการเปลี่ยนแปลงไปหน้าซึ่งโยงไปหน้าที่ระบุแทน",
        "recentchanges-page-added-to-category": "[[:$1]] ถูกเพิ่มเข้าหมวดหมู่",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] à¹\81ละ $2 à¸«à¸\99à¹\89าà¸\96ูà¸\81à¹\80à¸\9eิà¹\88มà¹\80à¸\82à¹\89าหมวà¸\94หมูà¹\88",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] à¸\96ูà¸\81à¹\80à¸\9eิà¹\88มà¹\80à¸\82à¹\89าหมวà¸\94หมูà¹\88à¹\81ลà¹\89ว [[Special:WhatLinksHere/$1|หà¸\99à¹\89าà¸\99ีà¹\89รวมà¸\96ึà¸\87ภายà¹\83à¸\99หà¸\99à¹\89าอืà¹\88à¸\99à¹\86 à¸\94à¹\89วย]]",
        "recentchanges-page-removed-from-category": "[[:$1]] ถูกลบจากหมวดหมู่",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] à¹\81ละ $2 à¸«à¸\99à¹\89าà¸\96ูà¸\81ลà¸\9aà¸\88าà¸\81หมวà¸\94หมูà¹\88",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] à¸\96ูà¸\81ลà¸\9aà¸\88าà¸\81หมวà¸\94หมูà¹\88à¹\81ลà¹\89ว [[Special:WhatLinksHere/$1|หà¸\99à¹\89าà¸\99ีà¹\89รวมà¸\96ึà¸\87ภายà¹\83à¸\99หà¸\99à¹\89าอืà¹\88à¸\99à¹\86 à¸\94à¹\89วย]]",
        "autochange-username": "การเปลี่ยนแปลงอัตโนมัติมีเดียวิกิ",
        "upload": "อัปโหลดไฟล์",
        "uploadbtn": "อัปโหลดไฟล์",
        "filedelete-maintenance": "ปิดใช้งานการลบและกู้คืนไฟล์ชั่วคราวระหว่างการบำรุงรักษา",
        "filedelete-maintenance-title": "ไม่สามารถลบไฟล์",
        "mimesearch": "ค้นหาไมม์",
-       "mimesearch-summary": "หน้านี้แสดงไฟล์ตามการแบ่งของชนิดไมม์ของแต่ละไฟล์ \nใส่ค่า: contenttype/subtype เช่น <code>image/jpeg</code>",
+       "mimesearch-summary": "หà¸\99à¹\89าà¸\99ีà¹\89à¹\81สà¸\94à¸\87à¹\84à¸\9fลà¹\8cà¸\95ามà¸\81ารà¹\81à¸\9aà¹\88à¸\87à¸\82อà¸\87à¸\8aà¸\99ิà¸\94à¹\84มมà¹\8cà¸\82อà¸\87à¹\81à¸\95à¹\88ละà¹\84à¸\9fลà¹\8c \nà¹\83สà¹\88à¸\84à¹\88า: contenttype/subtype à¸«à¸£à¸·à¸­ contenttype/* à¹\80à¸\8aà¹\88à¸\99 <code>image/jpeg</code>",
        "mimetype": "ชนิดไมม์:",
        "download": "ดาวน์โหลด",
        "unwatchedpages": "หน้าที่ไม่มีผู้เฝ้าดู",
index 6316d17..be43628 100644 (file)
        "createacct-yourpasswordagain": "Пароль юнматэ",
        "createacct-yourpasswordagain-ph": "Гожтэ паролез эшшо одӥг пол",
        "userlogin-remembermypassword": "Кылем сӧзнэтэз",
-       "cannotcreateaccount-title": "Уг быгатиськы гожъян кылдӥз учётной",
+       "cannotcreateaccount-title": "Учётной записьёсты кылдытыны уг луы",
        "yourdomainname": "Тӥ доменэн:",
        "login": "Пырыны",
        "nav-login-createaccount": "Нимдэс вераны / Регистрациез ортчытыны",
        "createacct-benefit-body3": "{{PLURAL:$1|викиавтор}} берло дыре",
        "loginerror": "Янгышъёс пырон",
        "createacct-error": "Янгышъёс бордын учётной книга кылдытыны",
-       "createaccounterror": "Уг быгатиськы гожъян учётной кылдоз: $1",
+       "createaccounterror": "Учётной запись кылдытыны уг луы: $1",
        "nocookiesnew": "Книга кылдытыны учётной пользователь вал, нош система тон уд пыры.\n{{SITENAME}} пользователь cookies пырон понна кутыны.\nDisconnect cookies тонэ дорам.\nПожалуйста, со гожтӥське, нош собере выльысь пырыны логин но пароль.",
        "nocookieslogin": "{{SITENAME}} пользователь cookies пырон понна кутыны.\nDisconnect cookies тонэ дорам.\nПожалуйста, соосты утчано, выльысь гожтыны.",
        "blocked-mailpassword": "Тон IP-адрес заблокировать-ысь редактировать карон. Злоупотребление предотвращение понна, та понна кутыны ӧз лэзиське пароль-ысь восстановление IP-адрес.",
        "showpreview": "Бамез эскерон",
        "showdiff": "Пыртэм воштонъёс",
        "anoneditwarning": "<strong>Сак луэ!</strong> Тӥ сайтэ ӧд пырелэ. Тӥ котькыӵе тупатонъёсыз лэсьтоды бере, тӥляд IP-адресты ваньмызлы адӟытӥськоз. Тӥ <strong>[$1 пыроды]</strong> яке <strong>[$2 учётной записез кылдытоды]</strong> бере, тӥляд тупатонъёсты герӟаськозы нимдылы, мукет пайдаосын ӵош.",
-       "blockedtitle": "Ð\97аблокиÑ\80оваÑ\82Ñ\8c Ð¿Ñ\8bÑ\80иÑ\81Ñ\8cкиÑ\81Ñ\8cÑ\91Ñ\81",
+       "blockedtitle": "Ð\92икиавÑ\82оÑ\80 Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80оваÑ\82Ñ\8c ÐºÐ°Ñ\80емÑ\8bн",
        "blockedtext": "<strong>Тӥляд учётной записьты яке IP-адресты заблокировать каремын вал.</strong>\n\nБлокировкаез лэсьтӥз $1.\nПусъем мугез: <em>$2</em>.\n\n* Блокировка кутскиз: $8\n* Блокировка йылпумъяськоз: $6\n* Блокировкалэн ужпумез: $7\n\nТӥ блокировка сярысь вераськыны быгатӥськоды $1 яке котькин мукет [[{{MediaWiki:Grouppage-sysop}}|администратор]] доры герӟаськыса.\n[[Special:Preferences|Настройкаосады]] электрон почталэн ужась адресэз ӧвӧл дыръя, тӥ «Викиавторлы гожтэт» функциез уже кутыны уд быгатӥське, сое тӥленыды уже кутон дугдытэмын ӧвӧл ке.\nТӥляд али IP-адресты луэ $3, но блокировка идентификатор — #$5.\nТауна пыртэ вань та пыр-поч сведениосыз асьтэлэн куронъёсады.",
        "autoblockedtext": "Тӥляд IP-адресты автоматически заблокировать каремын вал, малы ке шуоно со кутӥськиз вал мукет викиавторен, кинзэ $1 заблокировать кариз.\nБлокировкалэн пусъем мугез:\n\n:<em>$2</em>\n\n* Блокировка кутскиз: $8\n* Блокировка йылпумъяськоз: $6\n* Блокировкалэн ужпумез: $7\n\nТӥ блокировка сярысь вераськыны быгатӥськоды $1 яке мукет [[{{MediaWiki:Grouppage-sysop}}|администраторъёс]] пӧлысь огез доры герӟаськыса.\n\nСак луэ, тӥ «Викиавторлы гожтэт» функциез уже кутыны уд быгатӥське [[Special:Preferences|асьтэлэн настройкаосады]] электрон почталэсь шонер адрессэ гожтытозь яке юнматытозь, либо блокировкады сыӵе амалэн гожтэтъёсыз ыстыны уг лэзьы ке.\n\nТӥляд али IP-адресты луэ $3, но блокировка идентификатор — #$5.\nТауна пыртэ вань та пыр-поч сведениосыз асьтэлэн куронъёсады.",
-       "blockednoreason": "мÑ\83гезлÑ\8b Ñ\8dн Ð²Ð¾Ð·Ñ\8cмалÑ\8d",
+       "blockednoreason": "пÑ\83кÑ\82Ñ\8dм Ð¼Ñ\83г Ó§Ð²Ó§Ð»",
        "whitelistedittext": "Тон кулэ $1 бам воштон понна.",
        "loginreqtitle": "Авторизация кулэ",
        "loginreqlink": "пырыны",
        "newarticletext": "Тон бам ссылкаос вылэ выжыса, со кема уз улы.\nСоос мед кылдозы, текст бичась укноос, улазы интыяськемын (умой-умой см. [$1 бам справочной]).\nЯнгыш-а тон татын луысалыд ке, кнопказэ зӥбиз гинэ <strong>берлань</strong> асьтэлэсь браузеръёстэс.",
        "noarticletext": "Али дыре та бамын текст ӧвӧл. \nТӥ быгатоды [[Special:Search/{{PAGENAME}}|шедьтыны со сярысь кыӵе ке ивор]] мукет бамъёсысь,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} шедьтыны журналъёсысь гожъямъёсыз], \nяке [{{fullurl:{{FULLPAGENAME}}|action=edit}} сыӵе нимын бам кылдытыны]</span>.",
        "noarticletext-nopermission": "Али дыре та бам вылын кылкуэт ӧвӧл.\nТон быгатӥськод [[Special:Search/{{PAGENAME}}|сётэм йыръянъёс шедьто упоминание]] мукет бам вылын,\nяке <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} соответствующий журнал книгаез шедьтыны].</span> Тӥ дорын сётӥське юаськыны кылдӥз бам ӧвӧл.",
-       "blocked-notice-logextract": "Ð\9fолÑ\8cзоваÑ\82елÑ\8c Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80ован Ñ\81Ñ\91Ñ\82ӥз Ñ\82а Ñ\83Ñ\87Ñ\8bÑ\80лÑ\8b.\nСпÑ\80авка Ð¿Ð¾Ð½Ð½Ð° Ñ\80адÑ\8aÑ\8fÑ\81Ñ\8cкÑ\8bлӥÑ\81Ñ\8c Ð¶Ñ\83Ñ\80нал Ð±Ð»Ð¾ÐºÐ¸Ñ\80овка Ð»Ð°Ð¿ÐµÐ³ Ð±ÐµÑ\80пÑ\83меÑ\82Ó¥ Ð³Ð¾Ð¶Ñ\82Ñ\8dÑ\82:",
+       "blocked-notice-logextract": "Та Ð²Ð¸ÐºÐ¸Ð°Ð²Ñ\82оÑ\80 Ð°Ð»Ð¸ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80оваÑ\82Ñ\8c ÐºÐ°Ñ\80емÑ\8bн.\nÐ\91локиÑ\80овкаоÑ\81Ñ\8bн Ð¶Ñ\83Ñ\80налÑ\8bÑ\81Ñ\8c Ð±ÐµÑ\80пÑ\83м Ð³Ð¾Ð¶Ñ\8aÑ\8fм Ñ\83лӥ Ð²Ð¾Ð·Ñ\8cмаÑ\82Ñ\8dмÑ\8bн:",
        "continue-editing": "Тупатъянэз азьланьтоно",
        "editing": "Тупатон: $1",
        "creating": "«$1» бамез кылдытон",
        "moveddeleted-notice": "Та бам быдтэмын вал.\nБыдтонъёсын но ним воштонъёсын журналъёсысь ярано записьёс чӧлсконлы улӥ возьматэмын.",
        "content-model-wikitext": "викитекст",
        "undo-summary": "Шонертон вошъян $1, лэсьтӥзы {{GENDER:$2|участник|куакеч}} [[Special:Contributions/$2|$2]] ([[User talk:$2|обс.]])",
-       "cantcreateaccount-text": "Та книгаез кылдытонлы учётной IP-адрес (<strong>$1</strong>) заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
-       "cantcreateaccount-range-text": "Учётной кылдытон - гожъян IP-адрес диапазонын <strong>$1</strong>, Тон пыриське со IP-адрес (<strong>$4</strong>), заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
+       "cantcreateaccount-text": "Та IP-адресысь (<strong>$1</strong>) учётной записьёсты кылдытон заблокировать каремын вал [[User:$3|$3]] викиавторен.\n\n$3 пусйиз таӵе мугез: <em>$2</em>.",
+       "cantcreateaccount-range-text": "[[User:$3|$3]] викиавтор дугдытӥз учётной записьёсты кылдытыны <strong>$1</strong> радлэн IP-адресъёсысьтыз, кудъёсыз пӧлы пыре тӥляд IP-адресты (<strong>$4</strong>).\n\n$3 пусйиз таӵе мугез: <em>$2</em>.",
        "viewpagelogs": "Та бамлы журналъёсыз возьматыны",
        "currentrev-asof": "Алиез версия $1",
        "revisionasof": "Версия $1",
        "categories-submit": "Возьматыны",
        "sp-deletedcontributions-contribs": "тупатонъёсыз",
        "listusers-submit": "Возьматыны",
-       "listusers-blocked": "(заблокиÑ\80оваÑ\82Ñ\8c{{GENDER:$1||а}})",
+       "listusers-blocked": "(блокиÑ\80оваÑ\82Ñ\8c ÐºÐ°Ñ\80емÑ\8bн)",
        "listgrouprights": "Право группае пыриськисьёс",
        "listgrouprights-summary": "Та группае пырисьёс возьматыны кулэ вики список улӥзы, право соответствующийгес солы возьматоно кариськиз. Оло, ас [[{{MediaWiki:Listgrouprights-helppage}}|кожазы ватсаса ивортодэт]] улыны эрикрадэз сярысь.",
        "listgrouprights-members": "(список пыриськисьёс)",
        "whatlinkshere-hidetrans": "$1 пыртонъёсты",
        "whatlinkshere-hidelinks": "$1 чӧлсконъёсты",
        "whatlinkshere-filters": "Фильтръёс",
-       "block": "Ð\91локиÑ\80овка Ð¿Ñ\8bÑ\80иÑ\81Ñ\8cкиÑ\81Ñ\8cÑ\91Ñ\81",
-       "blockip": "Заблокировать {{GENDER:$1|пыриськисьёс}}",
+       "block": "Ð\92икиавÑ\82оÑ\80ез Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80оваÑ\82Ñ\8c ÐºÐ°Ñ\80Ñ\8bнÑ\8b",
+       "blockip": "{{GENDER:$1|Викиавторез}} заблокировать карыны",
        "blockip-legend": "Блокировка пыриськисьёс",
        "blockiptext": "Формазэ уже кутыса, кулэ луэмезъя мед заблокировать гожъян IP-адрес яке пыриськисьёслэн нимъёссы.\nТа понна гинэ но соя гинэ лэсьтэмын луыны быгатоз вандализм предотвращение с [[{{MediaWiki:Policy-url}}|правилоосты]].\nМугез возьматись улӥзы членъёсын (кылсярысь, куд-ог тодметъёссэ вандализм цитировать кароно бам).\nТӥ быгатӥськоды диапазонэз заблокировать IP-адрес, уже кутыны [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]-синтаксис. Максимально диапазонэз допустимый — /$1 протокол понна IPv4 но /$2 протокол понна IPv6.",
        "ipbreason-dropdown": "* Блокировка мугез кабес\n** Полы информациез оскизы\n** Вордскем палэнэ бам\n** Спам-сайтъя педпал чӧлскон\n** Текстлэсь визьем ватсан/жуг-жаг\n** Кышкытлыклэсь, пыриськыны уйиськон\n** Злоупотребление кӧня ке книга учётной\n** Пыриськисьёслэн нимъёссы пыриськисьёс",
        "ipbsubmit": "Адресъёсын та заблокировать/пыриськисьёс",
        "ipboptions": "2 час:2 hours,1 нуналлы:1 day,3 нуналлы:3 days,1 арняезлы:1 week,2 арняяз:2 weeks,1 толэзь:1 month,3 толэзь:3 months,6 толэзь:6 months,1 арлэн:1 year,ноку:infinite",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} гожтэмъёсы",
-       "unblocked": "[[User:$1|$1]] разблокировать",
-       "unblocked-id": "Блокировка $1 басьтоно луиз",
-       "blocklist-target": "Ужпумъёс",
+       "unblocked": "[[User:$1|$1]] разблокировать каремын.",
+       "unblocked-id": "$1 номеро блокировка палэнтэмын вал.",
+       "blocklist-target": "Ужпумез",
        "blocklist-reason": "Мугез",
        "infiniteblock": "ноку",
        "expiringblock": "йылпумъяськиз $1-ысь $2",
        "contribslink": "тупатонъёсыз",
        "autoblocker": "Автоблокировка, малы ке шуоно «[[User:$1|$1]]» тӥлесьтыд IP-адрестэс алигес уже кутӥз.\n$1 блокировкалэн мугез: «$2»",
        "blocklogpage": "Блокировкаосын журнал",
-       "blocklogentry": "заблокировать [[$1]] дыр $2 $3",
-       "reblock-logentry": "блокиÑ\80овка Ð²Ð¾Ñ\88Ñ\82ӥз [[$1]] Ð´Ñ\8bÑ\80 $2 $3",
-       "blocklogtext": "Ð\91локиÑ\80овка Ð½Ð¾ Ñ\82а Ð¶Ñ\83Ñ\80наллÑ\8dн Ñ\83жезлÑ\8b Ñ\80азблокиÑ\80ование Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8c.\nÐ\97аблокиÑ\80оваÑ\82Ñ\8c Ð\90вÑ\82омаÑ\82иÑ\87еÑ\81ки IP-адÑ\80еÑ\81 Ñ\83г Ð²Ð¾Ð·Ñ\8cма.\nÐ\9fÑ\80оизведениоÑ\81Ñ\8bз Ð¿ÐµÑ\87аÑ\82лаÑ\81Ñ\8cко Ñ\8dÑ\81Ñ\82ониÑ\8bн [[Special:BlockList|Ñ\81Ñ\8cӧд Ñ\81пиÑ\81окÑ\8bн]], Ð±Ð°Ð½ Ñ\81пиÑ\81ок Ð±Ð»Ð¾ÐºÑ\8aÑ\91Ñ\81 Ð»Ñ\8dÑ\81Ñ\8cÑ\82Ñ\8bнÑ\8b.",
-       "unblocklogentry": "разблокировать $1",
+       "blocklogentry": "заблокировать кариз [[$1]] дырлы: $2 $3",
+       "reblock-logentry": "воÑ\88Ñ\82ӥз Ð±Ð»Ð¾ÐºÐ¸Ñ\80овкалÑ\8dÑ\81Ñ\8c Ð¹Ñ\8bлпÑ\83мÑ\8aÑ\8fнзÑ\8d [[$1]] Ð¿Ð¾Ð½Ð½Ð° Ð´Ñ\8bÑ\80лÑ\8b: $2 $3",
+       "blocklogtext": "Ð\92икиавÑ\82оÑ\80Ñ\8aÑ\91Ñ\81Ñ\82Ñ\8b Ð±Ð»Ð¾ÐºÐ¸Ñ\80овкаоÑ\81Ñ\8bн Ð½Ð¾ Ñ\80азблокиÑ\80овкаоÑ\81Ñ\8bн Ð¶Ñ\83Ñ\80нал.\nÐ\90вÑ\82омаÑ\82иÑ\87еÑ\81ки Ð±Ð»Ð¾ÐºÐ¸Ñ\80оваÑ\82Ñ\8c ÐºÐ°Ñ\80иÑ\81Ñ\8cкиÑ\81Ñ\8c IP-адÑ\80еÑ\81Ñ\8aÑ\91Ñ\81 Ñ\82аÑ\82Ñ\8bн Ñ\83г Ð°Ð´Ó\9fÑ\8bÑ\82Ó¥Ñ\81Ñ\8cко.\nУÑ\87ке [[Special:BlockList|Ñ\81пиÑ\81окез Ð°Ð»Ð¸ ÐºÑ\83Ñ\82Ó¥Ñ\81Ñ\8cкиÑ\81Ñ\8c Ð±Ð»Ð¾ÐºÐ¸Ñ\80овкаоÑ\81лÑ\8b]].",
+       "unblocklogentry": "разблокировать кариз $1",
        "block-log-flags-anononly": "пользователь гинэ нимтултэм",
        "block-log-flags-nocreate": "регистрация учётной книгая ужъёсты быдэстон",
        "block-log-flags-noemail": "лэзьымтэ гожтэт ыстон",
        "logentry-upload-upload": "$1 {{GENDER:$2|понӥз}} $3",
        "searchsuggest-search": "Утчано {{SITENAME}}",
        "searchsuggest-containing": "кудъёсаз вань...",
-       "api-error-autoblocked": "Тон IP-адрес заблокировать эрказ луи, малы ке шуоно со заблокировать пользователь кутыны луоз.",
-       "api-error-blocked": "РедакÑ\82иÑ\80ование Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80оваÑ\82Ñ\8c Ð²Ð°Ð» Ñ\82ӥлеÑ\81Ñ\8cÑ\82Ñ\8bд.",
+       "api-error-autoblocked": "Тӥляд IP-адресты автоматически заблокировать каремын вал, малы ке шуоно со кутӥськиз заблокировать карем викиавторен.",
+       "api-error-blocked": "Тӥ Ñ\82Ñ\83паÑ\82Ñ\8aÑ\8fнлÑ\8dÑ\81Ñ\8c Ð¿Ð°Ð»Ñ\8dнÑ\82Ñ\8dмÑ\8bн Ð²Ð°Ð».",
        "expand_templates_preview": "Эскерон",
        "log-action-filter-all": "Ваньзэ"
 }
index d1e7caa..2eebf7d 100644 (file)
        "log-action-filter-newusers-create": "由匿名使用者建立",
        "log-action-filter-newusers-create2": "由註冊使用者建立",
        "log-action-filter-newusers-autocreate": "自動建立",
-       "log-action-filter-newusers-byemail": "使用電子郵件送密碼建立",
+       "log-action-filter-newusers-byemail": "使用電子郵件送密碼建立",
        "log-action-filter-patrol-patrol": "手動巡查",
        "log-action-filter-patrol-autopatrol": "自動巡查",
        "log-action-filter-protect-protect": "保護",
diff --git a/maintenance/importImages.inc b/maintenance/importImages.inc
deleted file mode 100644 (file)
index fc9428d..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-/**
- * Support functions for the importImages.php script
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- * @author Rob Church <robchur@gmail.com>
- * @author Mij <mij@bitchx.it>
- */
-
-/**
- * Search a directory for files with one of a set of extensions
- *
- * @param string $dir Path to directory to search
- * @param array $exts Array of extensions to search for
- * @param bool $recurse Search subdirectories recursively
- * @return array|bool Array of filenames on success, or false on failure
- */
-function findFiles( $dir, $exts, $recurse = false ) {
-       if ( is_dir( $dir ) ) {
-               $dhl = opendir( $dir );
-               if ( $dhl ) {
-                       $files = [];
-                       while ( ( $file = readdir( $dhl ) ) !== false ) {
-                               if ( is_file( $dir . '/' . $file ) ) {
-                                       list( /* $name */, $ext ) = splitFilename( $dir . '/' . $file );
-                                       if ( array_search( strtolower( $ext ), $exts ) !== false ) {
-                                               $files[] = $dir . '/' . $file;
-                                       }
-                               } elseif ( $recurse && is_dir( $dir . '/' . $file ) && $file !== '..' && $file !== '.' ) {
-                                       $files = array_merge( $files, findFiles( $dir . '/' . $file, $exts, true ) );
-                               }
-                       }
-
-                       return $files;
-               } else {
-                       return [];
-               }
-       } else {
-               return [];
-       }
-}
-
-/**
- * Split a filename into filename and extension
- *
- * @param string $filename Filename
- * @return array
- */
-function splitFilename( $filename ) {
-       $parts = explode( '.', $filename );
-       $ext = $parts[count( $parts ) - 1];
-       unset( $parts[count( $parts ) - 1] );
-       $fname = implode( '.', $parts );
-
-       return [ $fname, $ext ];
-}
-
-/**
- * Find an auxilliary file with the given extension, matching
- * the give base file path. $maxStrip determines how many extensions
- * may be stripped from the original file name before appending the
- * new extension. For example, with $maxStrip = 1 (the default),
- * file files acme.foo.bar.txt and acme.foo.txt would be auxilliary
- * files for acme.foo.bar and the extension ".txt". With $maxStrip = 2,
- * acme.txt would also be acceptable.
- *
- * @param string $file Base path
- * @param string $auxExtension The extension to be appended to the base path
- * @param int $maxStrip The maximum number of extensions to strip from the base path (default: 1)
- * @return string|bool
- */
-function findAuxFile( $file, $auxExtension, $maxStrip = 1 ) {
-       if ( strpos( $auxExtension, '.' ) !== 0 ) {
-               $auxExtension = '.' . $auxExtension;
-       }
-
-       $d = dirname( $file );
-       $n = basename( $file );
-
-       while ( $maxStrip >= 0 ) {
-               $f = $d . '/' . $n . $auxExtension;
-
-               if ( file_exists( $f ) ) {
-                       return $f;
-               }
-
-               $idx = strrpos( $n, '.' );
-               if ( !$idx ) {
-                       break;
-               }
-
-               $n = substr( $n, 0, $idx );
-               $maxStrip -= 1;
-       }
-
-       return false;
-}
-
-# @todo FIXME: Access the api in a saner way and performing just one query
-# (preferably batching files too).
-function getFileCommentFromSourceWiki( $wiki_host, $file ) {
-       $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
-               . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=comment';
-       $body = Http::get( $url, [], __METHOD__ );
-       if ( preg_match( '#<ii comment="([^"]*)" />#', $body, $matches ) == 0 ) {
-               return false;
-       }
-
-       return html_entity_decode( $matches[1] );
-}
-
-function getFileUserFromSourceWiki( $wiki_host, $file ) {
-       $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
-               . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=user';
-       $body = Http::get( $url, [], __METHOD__ );
-       if ( preg_match( '#<ii user="([^"]*)" />#', $body, $matches ) == 0 ) {
-               return false;
-       }
-
-       return html_entity_decode( $matches[1] );
-}
index 5a4ab39..7f2a9e1 100644 (file)
  * @author Mij <mij@bitchx.it>
  */
 
-$optionsWithArgs = [
-       'extensions', 'comment', 'comment-file', 'comment-ext', 'summary', 'user',
-       'license', 'sleep', 'limit', 'from', 'source-wiki-url', 'timestamp',
-];
+require_once __DIR__ . '/Maintenance.php';
+
+class ImportImages extends Maintenance {
+
+       public function __construct() {
+               parent::__construct();
+
+               $this->addDescription( 'Imports images and other media files into the wiki' );
+               $this->addArg( 'dir', 'Path to the directory containing images to be imported' );
+
+               $this->addOption( 'extensions',
+                       'Comma-separated list of allowable extensions, defaults to $wgFileExtensions',
+                       false,
+                       true
+               );
+               $this->addOption( 'overwrite',
+                       'Overwrite existing images with the same name (default is to skip them)' );
+               $this->addOption( 'limit',
+                       'Limit the number of images to process. Ignored or skipped images are not counted',
+                       false,
+                       true
+               );
+               $this->addOption( 'from',
+                       "Ignore all files until the one with the given name. Useful for resuming aborted "
+                               . "imports. The name should be the file's canonical database form.",
+                       false,
+                       true
+               );
+               $this->addOption( 'skip-dupes',
+                       'Skip images that were already uploaded under a different name (check SHA1)' );
+               $this->addOption( 'search-recursively', 'Search recursively for files in subdirectories' );
+               $this->addOption( 'sleep',
+                       'Sleep between files. Useful mostly for debugging',
+                       false,
+                       true
+               );
+               $this->addOption( 'user',
+                       "Set username of uploader, default 'Maintenance script'",
+                       false,
+                       true
+               );
+               // This parameter can optionally have an argument. If none specified, getOption()
+               // returns 1 which is precisely what we need.
+               $this->addOption( 'check-userblock', 'Check if the user got blocked during import' );
+               $this->addOption( 'comment',
+                       "Set file description, default 'Importing file'",
+                       false,
+                       true
+               );
+               $this->addOption( 'comment-file',
+                       'Set description to the content of this file',
+                       false,
+                       true
+               );
+               $this->addOption( 'comment-ext',
+                       'Causes the description for each file to be loaded from a file with the same name, but '
+                               . 'the extension provided. If a global description is also given, it is appended.',
+                       false,
+                       true
+               );
+               $this->addOption( 'summary',
+                       'Upload summary, description will be used if not provided',
+                       false,
+                       true
+               );
+               $this->addOption( 'license',
+                       'Use an optional license template',
+                       false,
+                       true
+               );
+               $this->addOption( 'timestamp',
+                       'Override upload time/date, all MediaWiki timestamp formats are accepted',
+                       false,
+                       true
+               );
+               $this->addOption( 'protect',
+                       'Specify the protect value (autoconfirmed,sysop)',
+                       false,
+                       true
+               );
+               $this->addOption( 'unprotect', 'Unprotects all uploaded images' );
+               $this->addOption( 'source-wiki-url',
+                       'If specified, take User and Comment data for each imported file from this URL. '
+                               . 'For example, --source-wiki-url="http://en.wikipedia.org/',
+                       false,
+                       true
+               );
+               $this->addOption( 'dry', "Dry run, don't import anything" );
+       }
 
-$optionsWithoutArgs = [
-       'protect', 'unprotect', 'search-recursively', 'check-userblock', 'overwrite',
-       'skip-dupes', 'dry'
-];
+       public function execute() {
+               global $wgFileExtensions, $wgUser, $wgRestrictionLevels;
 
-require_once __DIR__ . '/commandLine.inc';
-require_once __DIR__ . '/importImages.inc';
-$processed = $added = $ignored = $skipped = $overwritten = $failed = 0;
+               $processed = $added = $ignored = $skipped = $overwritten = $failed = 0;
 
-echo "Import Images\n\n";
+               $this->output( "Import Images\n\n" );
 
-# Need a path
-if ( count( $args ) == 0 ) {
-       showUsage();
-}
+               $dir = $this->getArg( 0 );
 
-$dir = $args[0];
+               # Check Protection
+               if ( $this->hasOption( 'protect' ) && $this->hasOption( 'unprotect' ) ) {
+                       $this->error( "Cannot specify both protect and unprotect.  Only 1 is allowed.\n", 1 );
+               }
 
-# Check Protection
-if ( isset( $options['protect'] ) && isset( $options['unprotect'] ) ) {
-       die( "Cannot specify both protect and unprotect.  Only 1 is allowed.\n" );
-}
+               if ( $this->hasOption( 'protect' ) && trim( $this->getOption( 'protect' ) ) ) {
+                       $this->error( "You must specify a protection option.\n", 1 );
+               }
 
-if ( isset( $options['protect'] ) && $options['protect'] == 1 ) {
-       die( "You must specify a protection option.\n" );
-}
+               # Prepare the list of allowed extensions
+               $extensions = $this->hasOption( 'extensions' )
+                       ? explode( ',', strtolower( $this->getOption( 'extensions' ) ) )
+                       : $wgFileExtensions;
 
-# Prepare the list of allowed extensions
-global $wgFileExtensions;
-$extensions = isset( $options['extensions'] )
-       ? explode( ',', strtolower( $options['extensions'] ) )
-       : $wgFileExtensions;
-
-# Search the path provided for candidates for import
-$files = findFiles( $dir, $extensions, isset( $options['search-recursively'] ) );
-
-# Initialise the user for this operation
-$user = isset( $options['user'] )
-       ? User::newFromName( $options['user'] )
-       : User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
-if ( !$user instanceof User ) {
-       $user = User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
-}
-$wgUser = $user;
-
-# Get block check. If a value is given, this specified how often the check is performed
-if ( isset( $options['check-userblock'] ) ) {
-       if ( !$options['check-userblock'] ) {
-               $checkUserBlock = 1;
-       } else {
-               $checkUserBlock = (int)$options['check-userblock'];
-       }
-} else {
-       $checkUserBlock = false;
-}
+               # Search the path provided for candidates for import
+               $files = $this->findFiles( $dir, $extensions, $this->hasOption( 'search-recursively' ) );
 
-# Get --from
-MediaWiki\suppressWarnings();
-$from = $options['from'];
-MediaWiki\restoreWarnings();
+               # Initialise the user for this operation
+               $user = $this->hasOption( 'user' )
+                       ? User::newFromName( $this->getOption( 'user' ) )
+                       : User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
+               if ( !$user instanceof User ) {
+                       $user = User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
+               }
+               $wgUser = $user;
+
+               # Get block check. If a value is given, this specified how often the check is performed
+               $checkUserBlock = (int)$this->getOption( 'check-userblock' );
+
+               $from = $this->getOption( 'from' );
+               $sleep = (int)$this->getOption( 'sleep' );
+               $limit = (int)$this->getOption( 'limit' );
+               $timestamp = $this->getOption( 'timestamp', false );
+
+               # Get the upload comment. Provide a default one in case there's no comment given.
+               $commentFile = $this->getOption( 'comment-file' );
+               if ( $commentFile !== null ) {
+                       $comment = file_get_contents( $commentFile );
+                       if ( $comment === false || $comment === null ) {
+                               $this->error( "failed to read comment file: {$commentFile}\n", 1 );
+                       }
+               } else {
+                       $comment = $this->getOption( 'comment', 'Importing file' );
+               }
+               $commentExt = $this->getOption( 'comment-ext' );
+               $summary = $this->getOption( 'summary', '' );
 
-# Get sleep time.
-MediaWiki\suppressWarnings();
-$sleep = $options['sleep'];
-MediaWiki\restoreWarnings();
+               $license = $this->getOption( 'license', '' );
 
-if ( $sleep ) {
-       $sleep = (int)$sleep;
-}
+               $sourceWikiUrl = $this->getOption( 'source-wiki-url' );
 
-# Get limit number
-MediaWiki\suppressWarnings();
-$limit = $options['limit'];
-MediaWiki\restoreWarnings();
+               # Batch "upload" operation
+               $count = count( $files );
+               if ( $count > 0 ) {
 
-if ( $limit ) {
-       $limit = (int)$limit;
-}
+                       foreach ( $files as $file ) {
+                               $base = UtfNormal\Validator::cleanUp( wfBaseName( $file ) );
 
-$timestamp = isset( $options['timestamp'] ) ? $options['timestamp'] : false;
+                               # Validate a title
+                               $title = Title::makeTitleSafe( NS_FILE, $base );
+                               if ( !is_object( $title ) ) {
+                                       $this->output(
+                                               "{$base} could not be imported; a valid title cannot be produced\n" );
+                                       continue;
+                               }
 
-# Get the upload comment. Provide a default one in case there's no comment given.
-$comment = 'Importing file';
+                               if ( $from ) {
+                                       if ( $from == $title->getDBkey() ) {
+                                               $from = null;
+                                       } else {
+                                               $ignored++;
+                                               continue;
+                                       }
+                               }
 
-if ( isset( $options['comment-file'] ) ) {
-       $comment = file_get_contents( $options['comment-file'] );
-       if ( $comment === false || $comment === null ) {
-               die( "failed to read comment file: {$options['comment-file']}\n" );
-       }
-} elseif ( isset( $options['comment'] ) ) {
-       $comment = $options['comment'];
-}
+                               if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) {
+                                       $user->clearInstanceCache( 'name' ); // reload from DB!
+                                       if ( $user->isBlocked() ) {
+                                               $this->output( $user->getName() . " was blocked! Aborting.\n" );
+                                               break;
+                                       }
+                               }
 
-$commentExt = isset( $options['comment-ext'] ) ? $options['comment-ext'] : false;
+                               # Check existence
+                               $image = wfLocalFile( $title );
+                               if ( $image->exists() ) {
+                                       if ( $this->hasOption( 'overwrite' ) ) {
+                                               $this->output( "{$base} exists, overwriting..." );
+                                               $svar = 'overwritten';
+                                       } else {
+                                               $this->output( "{$base} exists, skipping\n" );
+                                               $skipped++;
+                                               continue;
+                                       }
+                               } else {
+                                       if ( $this->hasOption( 'skip-dupes' ) ) {
+                                               $repo = $image->getRepo();
+                                               # XXX: we end up calculating this again when actually uploading. that sucks.
+                                               $sha1 = FSFile::getSha1Base36FromPath( $file );
+
+                                               $dupes = $repo->findBySha1( $sha1 );
+
+                                               if ( $dupes ) {
+                                                       $this->output(
+                                                               "{$base} already exists as {$dupes[0]->getName()}, skipping\n" );
+                                                       $skipped++;
+                                                       continue;
+                                               }
+                                       }
 
-$summary = isset( $options['summary'] ) ? $options['summary'] : '';
+                                       $this->output( "Importing {$base}..." );
+                                       $svar = 'added';
+                               }
 
-# Get the license specifier
-$license = isset( $options['license'] ) ? $options['license'] : '';
+                               if ( $sourceWikiUrl ) {
+                                       /* find comment text directly from source wiki, through MW's API */
+                                       $real_comment = $this->getFileCommentFromSourceWiki( $sourceWikiUrl, $base );
+                                       if ( $real_comment === false ) {
+                                               $commentText = $comment;
+                                       } else {
+                                               $commentText = $real_comment;
+                                       }
 
-# Batch "upload" operation
-$count = count( $files );
-if ( $count > 0 ) {
+                                       /* find user directly from source wiki, through MW's API */
+                                       $real_user = $this->getFileUserFromSourceWiki( $sourceWikiUrl, $base );
+                                       if ( $real_user === false ) {
+                                               $wgUser = $user;
+                                       } else {
+                                               $wgUser = User::newFromName( $real_user );
+                                               if ( $wgUser === false ) {
+                                                       # user does not exist in target wiki
+                                                       $this->output(
+                                                               "failed: user '$real_user' does not exist in target wiki." );
+                                                       continue;
+                                               }
+                                       }
+                               } else {
+                                       # Find comment text
+                                       $commentText = false;
+
+                                       if ( $commentExt ) {
+                                               $f = $this->findAuxFile( $file, $commentExt );
+                                               if ( !$f ) {
+                                                       $this->output( " No comment file with extension {$commentExt} found "
+                                                                . "for {$file}, using default comment. " );
+                                               } else {
+                                                       $commentText = file_get_contents( $f );
+                                                       if ( !$commentText ) {
+                                                               $this->output(
+                                                                       " Failed to load comment file {$f}, using default comment. " );
+                                                       }
+                                               }
+                                       }
 
-       foreach ( $files as $file ) {
-               $base = UtfNormal\Validator::cleanUp( wfBaseName( $file ) );
+                                       if ( !$commentText ) {
+                                               $commentText = $comment;
+                                       }
+                               }
 
-               # Validate a title
-               $title = Title::makeTitleSafe( NS_FILE, $base );
-               if ( !is_object( $title ) ) {
-                       echo "{$base} could not be imported; a valid title cannot be produced\n";
-                       continue;
-               }
+                               # Import the file
+                               if ( $this->hasOption( 'dry' ) ) {
+                                       $this->output(
+                                               " publishing {$file} by '{$wgUser->getName()}', comment '$commentText'... "
+                                       );
+                               } else {
+                                       $mwProps = new MWFileProps( MimeMagic::singleton() );
+                                       $props = $mwProps->getPropsFromPath( $file, true );
+                                       $flags = 0;
+                                       $publishOptions = [];
+                                       $handler = MediaHandler::getHandler( $props['mime'] );
+                                       if ( $handler ) {
+                                               $publishOptions['headers'] = $handler->getStreamHeaders( $props['metadata'] );
+                                       } else {
+                                               $publishOptions['headers'] = [];
+                                       }
+                                       $archive = $image->publish( $file, $flags, $publishOptions );
+                                       if ( !$archive->isGood() ) {
+                                               $this->output( "failed. (" .
+                                                        $archive->getWikiText( false, false, 'en' ) .
+                                                        ")\n" );
+                                               $failed++;
+                                               continue;
+                                       }
+                               }
 
-               if ( $from ) {
-                       if ( $from == $title->getDBkey() ) {
-                               $from = null;
-                       } else {
-                               $ignored++;
-                               continue;
-                       }
-               }
+                               $commentText = SpecialUpload::getInitialPageText( $commentText, $license );
+                               if ( !$this->hasOption( 'summary' ) ) {
+                                       $summary = $commentText;
+                               }
 
-               if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) {
-                       $user->clearInstanceCache( 'name' ); // reload from DB!
-                       if ( $user->isBlocked() ) {
-                               echo $user->getName() . " was blocked! Aborting.\n";
-                               break;
-                       }
-               }
+                               if ( $this->hasOption( 'dry' ) ) {
+                                       $this->output( "done.\n" );
+                               } elseif ( $image->recordUpload2(
+                                       $archive->value,
+                                       $summary,
+                                       $commentText,
+                                       $props,
+                                       $timestamp
+                               ) ) {
+                                       # We're done!
+                                       $this->output( "done.\n" );
 
-               # Check existence
-               $image = wfLocalFile( $title );
-               if ( $image->exists() ) {
-                       if ( isset( $options['overwrite'] ) ) {
-                               echo "{$base} exists, overwriting...";
-                               $svar = 'overwritten';
-                       } else {
-                               echo "{$base} exists, skipping\n";
-                               $skipped++;
-                               continue;
-                       }
-               } else {
-                       if ( isset( $options['skip-dupes'] ) ) {
-                               $repo = $image->getRepo();
-                               # XXX: we end up calculating this again when actually uploading. that sucks.
-                               $sha1 = FSFile::getSha1Base36FromPath( $file );
+                                       $doProtect = false;
 
-                               $dupes = $repo->findBySha1( $sha1 );
+                                       $protectLevel = $this->getOption( 'protect' );
 
-                               if ( $dupes ) {
-                                       echo "{$base} already exists as " . $dupes[0]->getName() . ", skipping\n";
-                                       $skipped++;
-                                       continue;
+                                       if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) {
+                                               $doProtect = true;
+                                       }
+                                       if ( $this->hasOption( 'unprotect' ) ) {
+                                               $protectLevel = '';
+                                               $doProtect = true;
+                                       }
+
+                                       if ( $doProtect ) {
+                                               # Protect the file
+                                               $this->output( "\nWaiting for replica DBs...\n" );
+                                               // Wait for replica DBs.
+                                               sleep( 2.0 ); # Why this sleep?
+                                               wfWaitForSlaves();
+
+                                               $this->output( "\nSetting image restrictions ... " );
+
+                                               $cascade = false;
+                                               $restrictions = [];
+                                               foreach ( $title->getRestrictionTypes() as $type ) {
+                                                       $restrictions[$type] = $protectLevel;
+                                               }
+
+                                               $page = WikiPage::factory( $title );
+                                               $status = $page->doUpdateRestrictions( $restrictions, [], $cascade, '', $user );
+                                               $this->output( ( $status->isOK() ? 'done' : 'failed' ) . "\n" );
+                                       }
+                               } else {
+                                       $this->output( "failed. (at recordUpload stage)\n" );
+                                       $svar = 'failed';
                                }
-                       }
 
-                       echo "Importing {$base}...";
-                       $svar = 'added';
-               }
+                               $$svar++;
+                               $processed++;
 
-               if ( isset( $options['source-wiki-url'] ) ) {
-                       /* find comment text directly from source wiki, through MW's API */
-                       $real_comment = getFileCommentFromSourceWiki( $options['source-wiki-url'], $base );
-                       if ( $real_comment === false ) {
-                               $commentText = $comment;
-                       } else {
-                               $commentText = $real_comment;
+                               if ( $limit && $processed >= $limit ) {
+                                       break;
+                               }
+
+                               if ( $sleep ) {
+                                       sleep( $sleep );
+                               }
                        }
 
-                       /* find user directly from source wiki, through MW's API */
-                       $real_user = getFileUserFromSourceWiki( $options['source-wiki-url'], $base );
-                       if ( $real_user === false ) {
-                               $wgUser = $user;
-                       } else {
-                               $wgUser = User::newFromName( $real_user );
-                               if ( $wgUser === false ) {
-                                       # user does not exist in target wiki
-                                       echo "failed: user '$real_user' does not exist in target wiki.";
-                                       continue;
+                       # Print out some statistics
+                       $this->output( "\n" );
+                       foreach (
+                               [
+                                       'count' => 'Found',
+                                       'limit' => 'Limit',
+                                       'ignored' => 'Ignored',
+                                       'added' => 'Added',
+                                       'skipped' => 'Skipped',
+                                       'overwritten' => 'Overwritten',
+                                       'failed' => 'Failed'
+                               ] as $var => $desc
+                       ) {
+                               if ( $$var > 0 ) {
+                                       $this->output( "{$desc}: {$$var}\n" );
                                }
                        }
                } else {
-                       # Find comment text
-                       $commentText = false;
-
-                       if ( $commentExt ) {
-                               $f = findAuxFile( $file, $commentExt );
-                               if ( !$f ) {
-                                       echo " No comment file with extension {$commentExt} found "
-                                               . "for {$file}, using default comment. ";
-                               } else {
-                                       $commentText = file_get_contents( $f );
-                                       if ( !$commentText ) {
-                                               echo " Failed to load comment file {$f}, using default comment. ";
+                       $this->output( "No suitable files could be found for import.\n" );
+               }
+       }
+
+       /**
+        * Search a directory for files with one of a set of extensions
+        *
+        * @param string $dir Path to directory to search
+        * @param array $exts Array of extensions to search for
+        * @param bool $recurse Search subdirectories recursively
+        * @return array|bool Array of filenames on success, or false on failure
+        */
+       private function findFiles( $dir, $exts, $recurse = false ) {
+               if ( is_dir( $dir ) ) {
+                       $dhl = opendir( $dir );
+                       if ( $dhl ) {
+                               $files = [];
+                               while ( ( $file = readdir( $dhl ) ) !== false ) {
+                                       if ( is_file( $dir . '/' . $file ) ) {
+                                               list( /* $name */, $ext ) = $this->splitFilename( $dir . '/' . $file );
+                                               if ( array_search( strtolower( $ext ), $exts ) !== false ) {
+                                                       $files[] = $dir . '/' . $file;
+                                               }
+                                       } elseif ( $recurse && is_dir( $dir . '/' . $file ) && $file !== '..' && $file !== '.' ) {
+                                               $files = array_merge( $files, $this->findFiles( $dir . '/' . $file, $exts, true ) );
                                        }
                                }
-                       }
-
-                       if ( !$commentText ) {
-                               $commentText = $comment;
-                       }
-               }
 
-               # Import the file
-               if ( isset( $options['dry'] ) ) {
-                       echo " publishing {$file} by '" . $wgUser->getName() . "', comment '$commentText'... ";
-               } else {
-                       $mwProps = new MWFileProps( MimeMagic::singleton() );
-                       $props = $mwProps->getPropsFromPath( $file, true );
-                       $flags = 0;
-                       $publishOptions = [];
-                       $handler = MediaHandler::getHandler( $props['mime'] );
-                       if ( $handler ) {
-                               $publishOptions['headers'] = $handler->getStreamHeaders( $props['metadata'] );
+                               return $files;
                        } else {
-                               $publishOptions['headers'] = [];
+                               return [];
                        }
-                       $archive = $image->publish( $file, $flags, $publishOptions );
-                       if ( !$archive->isGood() ) {
-                               echo "failed. (" .
-                                       $archive->getWikiText( false, false, 'en' ) .
-                                       ")\n";
-                               $failed++;
-                               continue;
-                       }
-               }
-
-               $commentText = SpecialUpload::getInitialPageText( $commentText, $license );
-               if ( !isset( $options['summary'] ) ) {
-                       $summary = $commentText;
+               } else {
+                       return [];
                }
+       }
 
-               if ( isset( $options['dry'] ) ) {
-                       echo "done.\n";
-               } elseif ( $image->recordUpload2(
-                       $archive->value,
-                       $summary,
-                       $commentText,
-                       $props,
-                       $timestamp
-               ) ) {
-                       # We're done!
-                       echo "done.\n";
+       /**
+        * Split a filename into filename and extension
+        *
+        * @param string $filename Filename
+        * @return array
+        */
+       private function splitFilename( $filename ) {
+               $parts = explode( '.', $filename );
+               $ext = $parts[count( $parts ) - 1];
+               unset( $parts[count( $parts ) - 1] );
+               $fname = implode( '.', $parts );
+
+               return [ $fname, $ext ];
+       }
 
-                       $doProtect = false;
+       /**
+        * Find an auxilliary file with the given extension, matching
+        * the give base file path. $maxStrip determines how many extensions
+        * may be stripped from the original file name before appending the
+        * new extension. For example, with $maxStrip = 1 (the default),
+        * file files acme.foo.bar.txt and acme.foo.txt would be auxilliary
+        * files for acme.foo.bar and the extension ".txt". With $maxStrip = 2,
+        * acme.txt would also be acceptable.
+        *
+        * @param string $file Base path
+        * @param string $auxExtension The extension to be appended to the base path
+        * @param int $maxStrip The maximum number of extensions to strip from the base path (default: 1)
+        * @return string|bool
+        */
+       private function findAuxFile( $file, $auxExtension, $maxStrip = 1 ) {
+               if ( strpos( $auxExtension, '.' ) !== 0 ) {
+                       $auxExtension = '.' . $auxExtension;
+               }
 
-                       global $wgRestrictionLevels;
+               $d = dirname( $file );
+               $n = basename( $file );
 
-                       $protectLevel = isset( $options['protect'] ) ? $options['protect'] : null;
+               while ( $maxStrip >= 0 ) {
+                       $f = $d . '/' . $n . $auxExtension;
 
-                       if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) {
-                               $doProtect = true;
-                       }
-                       if ( isset( $options['unprotect'] ) ) {
-                               $protectLevel = '';
-                               $doProtect = true;
+                       if ( file_exists( $f ) ) {
+                               return $f;
                        }
 
-                       if ( $doProtect ) {
-                               # Protect the file
-                               echo "\nWaiting for replica DBs...\n";
-                               // Wait for replica DBs.
-                               sleep( 2.0 ); # Why this sleep?
-                               wfWaitForSlaves();
-
-                               echo "\nSetting image restrictions ... ";
-
-                               $cascade = false;
-                               $restrictions = [];
-                               foreach ( $title->getRestrictionTypes() as $type ) {
-                                       $restrictions[$type] = $protectLevel;
-                               }
-
-                               $page = WikiPage::factory( $title );
-                               $status = $page->doUpdateRestrictions( $restrictions, [], $cascade, '', $user );
-                               echo ( $status->isOK() ? 'done' : 'failed' ) . "\n";
+                       $idx = strrpos( $n, '.' );
+                       if ( !$idx ) {
+                               break;
                        }
-               } else {
-                       echo "failed. (at recordUpload stage)\n";
-                       $svar = 'failed';
-               }
 
-               $$svar++;
-               $processed++;
-
-               if ( $limit && $processed >= $limit ) {
-                       break;
+                       $n = substr( $n, 0, $idx );
+                       $maxStrip -= 1;
                }
 
-               if ( $sleep ) {
-                       sleep( $sleep );
-               }
+               return false;
        }
 
-       # Print out some statistics
-       echo "\n";
-       foreach (
-               [
-                       'count' => 'Found',
-                       'limit' => 'Limit',
-                       'ignored' => 'Ignored',
-                       'added' => 'Added',
-                       'skipped' => 'Skipped',
-                       'overwritten' => 'Overwritten',
-                       'failed' => 'Failed'
-               ] as $var => $desc
-       ) {
-               if ( $$var > 0 ) {
-                       echo "{$desc}: {$$var}\n";
+       # @todo FIXME: Access the api in a saner way and performing just one query
+       # (preferably batching files too).
+       private function getFileCommentFromSourceWiki( $wiki_host, $file ) {
+               $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
+                          . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=comment';
+               $body = Http::get( $url, [], __METHOD__ );
+               if ( preg_match( '#<ii comment="([^"]*)" />#', $body, $matches ) == 0 ) {
+                       return false;
                }
+
+               return html_entity_decode( $matches[1] );
        }
-} else {
-       echo "No suitable files could be found for import.\n";
-}
 
-exit( 0 );
+       private function getFileUserFromSourceWiki( $wiki_host, $file ) {
+               $url = $wiki_host . '/api.php?action=query&format=xml&titles=File:'
+                          . rawurlencode( $file ) . '&prop=imageinfo&&iiprop=user';
+               $body = Http::get( $url, [], __METHOD__ );
+               if ( preg_match( '#<ii user="([^"]*)" />#', $body, $matches ) == 0 ) {
+                       return false;
+               }
 
-function showUsage( $reason = false ) {
-       if ( $reason ) {
-               echo $reason . "\n";
+               return html_entity_decode( $matches[1] );
        }
 
-       echo <<<TEXT
-Imports images and other media files into the wiki
-USAGE: php importImages.php [options] <dir>
-
-<dir> : Path to the directory containing images to be imported
-
-Options:
---extensions=<exts>     Comma-separated list of allowable extensions, defaults
-                        to \$wgFileExtensions.
---overwrite             Overwrite existing images with the same name (default
-                        is to skip them).
---limit=<num>           Limit the number of images to process. Ignored or
-                        skipped images are not counted.
---from=<name>           Ignore all files until the one with the given name.
-                        Useful for resuming aborted imports. <name> should be
-                        the file's canonical database form.
---skip-dupes            Skip images that were already uploaded under a different
-                        name (check SHA1).
---search-recursively    Search recursively for files in subdirectories.
---sleep=<sec>           Sleep between files. Useful mostly for debugging.
---user=<username>       Set username of uploader, default 'Maintenance script'.
---check-userblock       Check if the user got blocked during import.
---comment=<text>        Set file description, default 'Importing file'.
---comment-file=<file>   Set description to the content of <file>.
---comment-ext=<ext>     Causes the description for each file to be loaded from a
-                        file with the same name, but the extension <ext>. If a
-                        global description is also given, it is appended.
---license=<code>        Use an optional license template.
---dry                   Dry run, don't import anything.
---protect=<protect>     Specify the protect value (autoconfirmed,sysop).
---summary=<summary>     Upload summary, description will be used if not
-                        provided.
---timestamp=<timestamp> Override upload time/date, all MediaWiki timestamp
-                        formats are accepted.
---unprotect             Unprotects all uploaded images.
---source-wiki-url       If specified, take User and Comment data for each
-                        imported file from this URL. For example,
-                        --source-wiki-url="http://en.wikipedia.org/."
-
-TEXT;
-       exit( 1 );
 }
+
+$maintClass = 'ImportImages';
+require_once RUN_MAINTENANCE_IF_MAIN;
index 5f60097..f9cb5de 100644 (file)
        }
 
        mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
-               $root.find( '.mw-htmlform-hide-if' ).each( function () {
-                       var v, i, fields, test, func, spec, self, modules, data, extraModules,
-                               $el = $( this );
-
+               var
+                       $fields = $root.find( '.mw-htmlform-hide-if' ),
+                       $oouiFields = $fields.filter( '[data-ooui]' ),
                        modules = [];
-                       if ( $el.is( '[data-ooui]' ) ) {
-                               modules.push( 'mediawiki.htmlform.ooui' );
+
+               if ( $oouiFields.length ) {
+                       modules.push( 'mediawiki.htmlform.ooui' );
+                       $oouiFields.each( function () {
+                               var data, extraModules,
+                                       $el = $( this );
+
                                data = $el.data( 'mw-modules' );
                                if ( data ) {
                                        // We can trust this value, 'data-mw-*' attributes are banned from user content in Sanitizer
                                        extraModules = data.split( ',' );
                                        modules.push.apply( modules, extraModules );
                                }
-                       }
+                       } );
+               }
+
+               mw.loader.using( modules ).done( function () {
+                       $fields.each( function () {
+                               var v, i, fields, test, func, spec, self,
+                                       $el = $( this );
 
-                       mw.loader.using( modules ).done( function () {
                                if ( $el.is( '[data-ooui]' ) ) {
                                        // self should be a FieldLayout that mixes in mw.htmlform.Element
                                        self = OO.ui.FieldLayout.static.infuse( $el );
                                test = v[ 1 ];
                                // The .toggle() method works mostly the same for jQuery objects and OO.ui.Widget
                                func = function () {
-                                       self.toggle( !test() );
+                                       var shouldHide = test();
+                                       self.toggle( !shouldHide );
+
+                                       // It is impossible to submit a form with hidden fields failing validation, e.g. one that
+                                       // is required. However, validity is not checked for disabled fields, as these are not
+                                       // submitted with the form. So we should also disable fields when hiding them.
+                                       if ( self instanceof jQuery ) {
+                                               // This also finds elements inside any nested fields (in case of HTMLFormFieldCloner),
+                                               // which is problematic. But it works because:
+                                               // * HTMLFormFieldCloner::createFieldsForKey() copies 'hide-if' rules to nested fields
+                                               // * jQuery collections like $fields are in document order, so we register event
+                                               //   handlers for parents first
+                                               // * Event handlers are fired in the order they were registered, so even if the handler
+                                               //   for parent messed up the child, the handle for child will run next and fix it
+                                               self.find( 'input, textarea, select' ).each( function () {
+                                                       var $this = $( this );
+                                                       if ( shouldHide ) {
+                                                               if ( $this.data( 'was-disabled' ) === undefined ) {
+                                                                       $this.data( 'was-disabled', $this.prop( 'disabled' ) );
+                                                               }
+                                                               $this.prop( 'disabled', true );
+                                                       } else {
+                                                               $this.prop( 'disabled', $this.data( 'was-disabled' ) );
+                                                       }
+                                               } );
+                                       } else {
+                                               // self is a OO.ui.FieldLayout
+                                               if ( shouldHide ) {
+                                                       if ( self.wasDisabled === undefined ) {
+                                                               self.wasDisabled = self.fieldWidget.isDisabled();
+                                                       }
+                                                       self.fieldWidget.setDisabled( false );
+                                               } else if ( self.wasDisabled !== undefined ) {
+                                                       self.fieldWidget.setDisabled( self.wasDisabled );
+                                               }
+                                       }
                                };
                                for ( i = 0; i < fields.length; i++ ) {
                                        // The .on() method works mostly the same for jQuery objects and OO.ui.Widget
index 1603130..1b9d2fb 100644 (file)
@@ -1,5 +1,9 @@
 /* HTMLForm styles */
 
+.mw-htmlform {
+       clear: both;
+}
+
 table.mw-htmlform-nolabel td.mw-label {
        display: none;
 }
index cd84d79..ab3ac55 100644 (file)
@@ -33,7 +33,7 @@ class SpecialEditWatchlistTest extends SpecialPageTestBase {
                $user = new TestUser( __METHOD__ );
                list( $html, ) = $this->executeSpecialPage( 'clear', null, 'qqx', $user->getUser() );
                $this->assertRegExp(
-                       '/<form action=".*?Special:EditWatchlist\/clear" method="post" class="visualClear">/',
+                       '/<form class="mw-htmlform" action=".*?Special:EditWatchlist\/clear" method="post">/',
                        $html
                );
        }