diff --git a/dist-persist/wbstack/src/Settings/LocalSettings.php b/dist-persist/wbstack/src/Settings/LocalSettings.php index a3ec099be..55f4f3155 100644 --- a/dist-persist/wbstack/src/Settings/LocalSettings.php +++ b/dist-persist/wbstack/src/Settings/LocalSettings.php @@ -360,6 +360,8 @@ wfLoadExtension( 'DeleteBatch' ); wfLoadExtension( 'MultimediaViewer' ); wfLoadExtension( 'WikiHiero' ); +wfLoadExtension( 'WikibaseQualityConstraints' ); + # ConfirmAccount (only loaded when the setting is on) if( $wikiInfo->getSetting('wwExtEnableConfirmAccount') ) { diff --git a/dist/extensions/WikibaseQualityConstraints/.coveralls.yml b/dist/extensions/WikibaseQualityConstraints/.coveralls.yml new file mode 100644 index 000000000..29d884bde --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/.coveralls.yml @@ -0,0 +1,2 @@ +coverage_clover: build/logs/clover.xml +service_name: travis-ci diff --git a/dist/extensions/WikibaseQualityConstraints/.mailmap b/dist/extensions/WikibaseQualityConstraints/.mailmap new file mode 100644 index 000000000..4722218b4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/.mailmap @@ -0,0 +1,18 @@ +Aleksey Bekh-Ivanov +Amir E. Aharoni +Andreas Burmeister +Dimitri Schmidt +Dominic Sauer +Jan Zerebecki +Jeroen De Dauw +Jonas Keutel +Jonas Kress +Katie Filbert +Lucas Werkmeister +Olga Bode +Sam Reed +Sören Oldag +Tamara Slosarek +Thiemo Kreuz +Thiemo Kreuz +Timo Tijhof diff --git a/dist/extensions/WikibaseQualityConstraints/CODE_OF_CONDUCT.md b/dist/extensions/WikibaseQualityConstraints/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..498acf76f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/CODE_OF_CONDUCT.md @@ -0,0 +1 @@ +The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Special:MyLanguage/Code_of_Conduct). diff --git a/dist/extensions/WikibaseQualityConstraints/COPYING b/dist/extensions/WikibaseQualityConstraints/COPYING new file mode 100644 index 000000000..3335e501b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/COPYING @@ -0,0 +1,369 @@ +== License and copyright information == + +=== License === + +WikibaseQualityConstraints is licensed under the terms of the GNU General Public License, +version 2 or later. Derivative works and later versions of the code must be +free software licensed under the same or a compatible license. + +For the full text of version 2 of the license, see +https://www.gnu.org/licenses/gpl-2.0.html or '''GNU General Public License''' +below. + +=== Developers === + +* Andreas Burmeister +* Jonas Keutel +* Sören Oldag +* Dominic Sauer +* Dimitri Schmidt +* Tamara Slosarek + +=== Additional license information === + +Some components of WikibaseQualityConstraints imported from other projects may be under other +Free and Open Source, or Free Culture, licenses. Specific details of their +licensing information can be found in those components. + +== GNU GENERAL PUBLIC LICENSE == + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +=== Preamble === + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +== TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION == + +'''0.''' This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +'''1.''' You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +'''2.''' You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + '''a)''' You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + '''b)''' You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + '''c)''' If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +'''3.''' You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + '''a)''' Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + '''b)''' Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + '''c)''' Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +'''4.''' You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +'''5.''' You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +'''6.''' Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +'''7.''' If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +'''8.''' If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +'''9.''' The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +'''10.''' If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +=== NO WARRANTY === + +'''11.''' BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +'''12.''' IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + '''END OF TERMS AND CONDITIONS''' + +== How to Apply These Terms to Your New Programs == + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/dist/extensions/WikibaseQualityConstraints/README.md b/dist/extensions/WikibaseQualityConstraints/README.md new file mode 100644 index 000000000..9770d0ca5 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/README.md @@ -0,0 +1,254 @@ +# Wikibase Quality Constraints +[![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer] + +Extension to Wikibase Repository that performs constraint checks. + +[scrutinizer-badge]: https://scrutinizer-ci.com/g/wikimedia/mediawiki-extensions-WikibaseQualityConstraints/badges/quality-score.png?b=master +[scrutinizer]: https://scrutinizer-ci.com/g/wikimedia/mediawiki-extensions-WikibaseQualityConstraints/?branch=master + +## Installation + +* Clone `WikibaseQualityConstraints` inside the `extensions/` directory of your MediaWiki installations. + + ``` sh + cd .../extensions/ + git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints + ``` + +* Install dependencies. + The simplest way is to set up [composer-merge-plugin](https://www.mediawiki.org/wiki/Composer#Using_composer-merge-plugin) + and then run `composer install` in the MediaWiki base directory; + alternatively, you can run `composer install` inside the `WikibaseQualityConstraints` directory. + +* Load the extension. + + ```php + wfLoadExtension( 'WikibaseQualityConstraints' ); + ``` + +* Run `php maintenance/update.php --quick`. + +* Configure the extension. + You can find the configuration settings with documentation in `extension.json`. + (Note that the variable name for `LocalSettings.php` always begins with `wg`, + e. g. `$wgWBQualityConstraintsClassId` for the `WBQualityConstraintsClassId` setting.) + + * Specify the entity IDs of entities that are used to define constraints. + See the “Data import” section for an automatic way to do this. + + * If you have a SPARQL endpoint, configure it in `WBQualityConstraintsSparqlEndpoint`. + + * Alternatively, to check “format” constraints without running a full SPARQL server, + you can use the [minisparql] server. + +* Run `php maintenance/runScript.php extensions/WikibaseQualityConstraints/maintenance/ImportConstraintStatements.php`. + +[minisparql]: https://github.com/lucaswerkmeister/minisparql + +### Client-side script + +The extension includes a client-side script that checks constraints on entity pages and displays violations on statements. +It is loaded by default for all logged-in users; +anonymous users can load it on a page by entering the following code into the web console: + +```js +mw.loader.load( 'wikibase.quality.constraints.gadget' ); +``` + +### Data import + +For local development, it’s easiest to import some data from Wikidata. +You can use the `ImportConstraintEntities` maintenance script script to do this; +it will import all the required entities from Wikidata that don’t exist in your local wiki yet +and then print a config snippet which you can append to your `LocalSettings.php`. + +```sh +# working directory should be the MediaWiki installation folder, i.e. where LocalSettings.php is +php extensions/WikibaseQualityConstraints/maintenance/ImportConstraintEntities.php | tee -a LocalSettings.php +``` + +(The new entities will not show up in your wiki’s recent changes until they have been processed in the job queue; +try running the `maintenance/runJobs.php` script if it doesn’t happen automatically.) + +### Running the tests + +#### PHP + +There are two ways to run the tests of this extension: + +- Using the included configuration file: + + ```sh + # from the MediaWiki installation folder + php tests/phpunit/phpunit.php -c extensions/WikibaseQualityConstraints/phpunit.xml.dist + ``` + + This creates test coverage reports + (in `tests/coverage/` and `build/logs/clover.xml`) + and is therefore fairly slow. + +- Without the configuration file: + + ```sh + # from the MediaWiki installation folder + php tests/phpunit/phpunit.php extensions/WikibaseQualityConstraints/tests/phpunit/ + ``` + + This runs the tests without coverage report + and is therefore much faster. + +#### Javascript + +You can run the tests, combined with linting and few other tools for asserting code quality by + +```sh + # from this extension's folder + npm install + grunt test +``` + +### Adding a new constraint type + +To add a new constraint type, the following steps are necessary: + +* Define the constraint checker class. + * It should be defined in a new file in `src/ConstraintCheck/Checker/`, + named after the class name. + It should be in the `WikibaseQuality\ConstraintReport\ConstraintCheck\Checker` namespace. + * The class name should follow the constraint type name (in English), ending in “Checker”. + * The class must implement the `ConstraintChecker` interface. + * It should have at least the following class-level documentation comment: + ```php + /** + * @author YOUR NAME HERE + * @license GPL-2.0-or-later + */ + ``` + * Any services you need (`Config`, `EntityLookup`, …) should be injected as constructor parameters. + * If the constraint has parameters, + add support for parsing them to `ConstraintParameterParser` + (add a config setting for the associated property in `extension.json` + and a method to parse the parameter in `ConstraintParameterParser`), + and then add tests for them in `ConstraintParameterParserTest`. + This should be done in a separate commit. +* Define new messages (at least a violation message for the constraint type). + * Define the message in `i18n/en.json`. + A violation message should have a key like `wbqc-violation-message-constraintType`. + * Document the message in `i18n/qqq.json`. + Use the same message key, + and insert the documentation in the same location where you also added the message in `en.json` + (that is, `en.json` and `qqq.json` should contain message keys in the same order). +* Add a configuration setting for the constraint type item ID. + * Configuration settings are defined in `extension.json`, + as members of the `config` object. + * It should be added right after the current last `…ConstraintId` entry. + * It should be named after the constraint type item’s English label, + following the pattern `WBQualityConstraints…ConstraintId`. + * The default value should be the item ID on Wikidata, + so that no extra configuration is required for Wikidata + and importing the constraint type item (see “Data import” section) works. + * The first part of the description can be copied from similar settings, + the rest should contain a short description of the constraint type. + * The ID can always be public (`"public": true`). +* Register the new constraint type checker. + * In `ConstraintCheckerServices.php`, add a constant like + ```php + public const …_CHECKER = 'WBQC_…Checker'; + ``` + at the end of the list of constants. + The value should be `'WBQC_'` followed by the class name, + and the constant name should be the class name converted to all caps separated by underscores. + * Also in `ConstraintCheckerServices.php`, add a method like + ```php + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function get…Checker( MediaWikiServices $services = null ) { + return self::getService( $services, self::…_CHECKER ); + } + ``` + at the end of the class. + * In `ServiceWiring-ConstraintCheckers.php`, append a new function like + ```php + ConstraintCheckerServices::…_CHECKER => function( MediaWikiServices $services ) { + return new …Checker( + // injected services + ); + }, + ``` + to the array of services. + * In `ServiceWiring.php`, append a new entry like + ```php + $config->get( 'WBQualityConstraints…ConstraintId' ) + => ConstraintCheckerServices::get…Checker( $services ), + ``` + to the `$checkerMap` array in the `DELEGATING_CONSTRAINT_CHECKER` function. + * In `ServicesTest.php`, append a new entry like + ```php + [ …Checker::class ], + ``` + to the array in `provideConstraintCheckerServiceClasses()`. +* Add tests for the new constraint checker. + * The test class name should be the same as the checker class name, + with an additional suffix `Test` (i. e., `…CheckerTest`). + * The test class should be placed somewhere in `tests/phpunit/Checker/`, + either in the most suitable subdirectory + or directly in that directory if none of the subdirectories are suitable. + (The division into subdirectories there is dubious anyways, + and we may get rid of it in the future.) + * It should have at least the following class-level documentation comment: + ```php + /** + * @covers WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\…Checker + * + * @group WikibaseQualityConstraints + * + * @author YOUR NAME HERE + * @license GPL-2.0-or-later + */ + ``` + * It should have at least one test for compliance with a constraint, + one test for a constraint violation, + one test for behavior on a deprecated statement, + and one test for the `checkConstraintParameters` method. + * Use the `ResultAssertions` trait’s methods to check constraint check results. + * Use the `NewItem` and `NewStatement` builders to construct test data. + (You might see `JsonFileEntityLookup` and separate JSON files used in some existing tests, + but that’s a lot less readable.) + * If the checker uses a `Config`, use the `DefaultConfig` trait. + * If the constraint has parameters, + add methods for them to the `ConstraintParameters` trait and use it in the tests. + * You can copy+paste a `getConstraintMock` function from one of the existing tests, + adjusting the `getConstraintTypeItemId` mocked return value. + (Hopefully we’ll improve this in the future.) +* Update the tests for `DelegatingConstraintChecker`. + * In `DelegatingConstraintCheckerTest`, + add an entry for your constraint type to the `$constraints` array in `addDBData()`. + * The `constraint_guid` should be `P1$`, + followed by a new UUID (e. g. `cat /proc/sys/kernel/random/uuid` or `journalctl --new-id128`). + * The `pid` should be `1`. (Not `'1'`!) + * The `constraint_type_qid` should be `$this->getConstraintTypeItemId( '…' )`, + where `…` is just the `…` part of the `WBQualityConstraints…ConstraintId` `extension.json` config key. + * The `constraint_parameters` should be a valid JSON serialization of constraint parameters. + If the constraint type doesn’t have any parameters, you can pass `{}`, + otherwise there should ideally be methods to create the parameters in the `ConstraintParameters` trait + so that you can use `json_encode( $this->…Parameter( … ) )` + (perhaps with `array_merge` if there are multiple parameters). +* Ask someone with grafana-admin access to update the “constraint types” panel + in the [wikidata-quality board](https://grafana.wikimedia.org/dashboard/db/wikidata-quality) + to add the new constraint type. + +### Adding a new allowed entity type + +* Start by adding an Item reference to `extension.json`. For example: + ``` + "WBQualityConstraintsMediaInfoId": { + "value": "Q3898244", + "description": "The item ID of the 'MediaInfo' item, which represents the 'mediainfo' entity type for 'allowed entity types' constraints.", + "public": true + } + * The next step takes place inside `src/ConstraintCheck/Helper/ConstraintParameterParser.php`. The new allowed entity type + should be added to the switch/case within the method `parseEntityTypeItem()`. + Don't forget to add it to the default case as well! + * To be able to test the newly added allowed entity type locally, please perform the steps described in section "Data import". diff --git a/dist/extensions/WikibaseQualityConstraints/WikibaseQualityConstraints.alias.php b/dist/extensions/WikibaseQualityConstraints/WikibaseQualityConstraints.alias.php new file mode 100644 index 000000000..5c4a8ac57 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/WikibaseQualityConstraints.alias.php @@ -0,0 +1,15 @@ + [ 'ConstraintReport', 'Constraint Report' ], +]; diff --git a/dist/extensions/WikibaseQualityConstraints/composer.json b/dist/extensions/WikibaseQualityConstraints/composer.json new file mode 100644 index 000000000..abdf461fd --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/composer.json @@ -0,0 +1,55 @@ +{ + "name": "wikibase/constraints", + "type": "mediawiki-extension", + "description": "Extension to manage constraints in Wikibase.", + "keywords": [ + "quality", + "trust", + "violation", + "constraint", + "wikibase", + "wikidata" + ], + "homepage": "https://www.mediawiki.org/wiki/Wikibase_Quality_Extensions", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "BP2014N1" + } + ], + "support": { + "issues": "https://phabricator.wikimedia.org/project/profile/1202/" + }, + "require": { + "php": ">=7.2.0", + "serialization/serialization": "^3.2.1|^4.0.0", + "data-values/data-values": "^2.0.0|^1.0.0", + "data-values/common": "^0.4.0|^0.3.0", + "data-values/geo": "^4.2.1|^3.0.1|^2.1.2", + "data-values/number": "^0.11.0", + "data-values/time": "^1.0.1", + "data-values/serialization": "^1.2.1", + "wikimedia/purtle": "^1.0.7" + }, + "require-dev": { + "mediawiki/mediawiki-codesniffer": "39.0.0", + "mediawiki/mediawiki-phan-config": "0.11.1", + "mediawiki/minus-x": "1.1.1", + "php-parallel-lint/php-console-highlighter": "1.0.0", + "php-parallel-lint/php-parallel-lint": "1.3.2" + }, + "scripts": { + "fix": [ + "minus-x fix .", + "phpcbf" + ], + "test": [ + "composer validate --no-interaction", + "parallel-lint . --exclude vendor --exclude node_modules", + "@phpcs", + "minus-x check ." + ], + "phan": "phan -d . --long-progress-bar --allow-polyfill-parser", + "phpcs": "phpcs -sp --cache" + } +} diff --git a/dist/extensions/WikibaseQualityConstraints/extension.json b/dist/extensions/WikibaseQualityConstraints/extension.json new file mode 100644 index 000000000..9b7e3b80c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/extension.json @@ -0,0 +1,691 @@ +{ + "load_composer_autoloader": true, + "name": "WikibaseQualityConstraints", + "author": [ + "BP2014N1", + "Lucas Werkmeister" + ], + "url": "https://www.mediawiki.org/wiki/Extension:WikibaseQualityConstraints", + "descriptionmsg": "wbqc-desc", + "version": "1.0.0", + "license-name": "GPL-2.0-or-later", + "type": "wikibase", + "requires": { + "MediaWiki": ">= 1.39.0" + }, + "MessagesDirs": { + "WikibaseQualityConstraints": [ + "i18n", + "i18n/api" + ] + }, + "ExtensionMessagesFiles": { + "WikibaseQualityConstraintsAlias": "WikibaseQualityConstraints.alias.php" + }, + "ServiceWiringFiles": [ + "src/ServiceWiring.php", + "src/ServiceWiring-ConstraintCheckers.php", + "src/ServiceWiring-Wikibase.php" + ], + "Hooks": { + "LoadExtensionSchemaUpdates": "WikibaseQuality\\ConstraintReport\\WikibaseQualityConstraintsHooks::onCreateSchema", + "WikibaseChangeNotification": "WikibaseQuality\\ConstraintReport\\WikibaseQualityConstraintsHooks::onWikibaseChange", + "ArticlePurge": "WikibaseQuality\\ConstraintReport\\WikibaseQualityConstraintsHooks::onArticlePurge", + "BeforePageDisplay": "WikibaseQuality\\ConstraintReport\\WikibaseQualityConstraintsHooks::onBeforePageDisplay" + }, + "SpecialPages": { + "ConstraintReport": { + "class": "WikibaseQuality\\ConstraintReport\\Specials\\SpecialConstraintReport", + "factory": "WikibaseQuality\\ConstraintReport\\Specials\\SpecialConstraintReport::factory", + "services": [ + "MainConfig", + "StatsdDataFactory", + "WikibaseRepo.EntityIdHtmlLinkFormatterFactory", + "WikibaseRepo.EntityIdParser", + "WikibaseRepo.EntityTitleLookup", + "WikibaseRepo.ValueFormatterFactory", + "WBQC_EntityLookup", + "WBQC_DelegatingConstraintChecker" + ] + } + }, + "APIModules": { + "wbcheckconstraints": { + "class": "WikibaseQuality\\ConstraintReport\\Api\\CheckConstraints", + "factory": "WikibaseQuality\\ConstraintReport\\Api\\CheckConstraints::factory", + "services": [ + "MainConfig", + "StatsdDataFactory", + "WikibaseRepo.ApiHelperFactory", + "WikibaseRepo.EntityIdHtmlLinkFormatterFactory", + "WikibaseRepo.EntityIdParser", + "WikibaseRepo.EntityTitleLookup", + "WikibaseRepo.StatementGuidValidator", + "WikibaseRepo.ValueFormatterFactory", + "WBQC_ResultsSource" + ] + }, + "wbcheckconstraintparameters": { + "class": "WikibaseQuality\\ConstraintReport\\Api\\CheckConstraintParameters", + "factory": "WikibaseQuality\\ConstraintReport\\Api\\CheckConstraintParameters::newFromGlobalState", + "services": [ + "MainConfig", + "StatsdDataFactory", + "WikibaseRepo.ApiHelperFactory", + "WikibaseRepo.EntityIdHtmlLinkFormatterFactory", + "WikibaseRepo.StatementGuidParser", + "WikibaseRepo.ValueFormatterFactory", + "WBQC_DelegatingConstraintChecker" + ] + } + }, + "Actions": { + "constraintsrdf": [ + "WikibaseQuality\\ConstraintReport\\Api\\CheckConstraintsRdf", + "newFromGlobalState" + ] + }, + "ResourceFileModulePaths": { + "localBasePath": "modules", + "remoteExtPath": "WikibaseQualityConstraints/modules" + }, + "ResourceModules": { + "SpecialConstraintReportPage": { + "styles": "SpecialConstraintReportPage.less", + "scripts": "SpecialConstraintReportPage.js", + "dependencies": [ + "oojs-ui-core.styles" + ] + }, + "wikibase.quality.constraints.icon": { + "class": "ResourceLoaderImageModule", + "selector": ".oo-ui-icon-{name}", + "images": { + "mandatory-constraint-violation": "icon/mandatory-constraint-violation.svg", + "non-mandatory-constraint-violation": "icon/non-mandatory-constraint-violation.svg", + "suggestion-constraint-violation": "icon/suggestion-constraint-violation.svg" + } + }, + "wikibase.quality.constraints.ui": { + "dependencies": [ + "oojs-ui-core", + "oojs-ui-widgets", + "jquery.makeCollapsible", + "wikibase" + ], + "messages": [ + "wbqc-issues-short", + "wbqc-issues-long", + "wbqc-potentialissues-short", + "wbqc-potentialissues-long", + "wbqc-suggestions-short", + "wbqc-suggestions-long", + "wbqc-badparameters-short", + "wbqc-badparameters-long", + "wbqc-parameterissues-short", + "wbqc-parameterissues-long", + "wbqc-constrainttypehelp-short", + "wbqc-constrainttypehelp-long", + "wbqc-constraintdiscuss-short", + "wbqc-constraintdiscuss-long", + "wbqc-cached-generic", + "wbqc-cached-minutes", + "wbqc-cached-hours", + "wbqc-cached-days" + ], + "scripts": [ + "ui/module.js", + "ui/ConstraintReportPanel.js", + "ui/ConstraintReportGroup.js", + "ui/ConstraintReportList.js" + ], + "styles": [ + "ui/ConstraintReportPanel.less", + "ui/ConstraintReportGroup.less" + ], + "targets": [ + "mobile", + "desktop" + ] + }, + "wikibase.quality.constraints.gadget": { + "scripts": "gadget.js", + "styles": "gadget.less", + "dependencies": [ + "mediawiki.api", + "oojs-ui-core", + "oojs-ui-widgets", + "oojs-ui.styles.icons-alerts", + "wikibase.quality.constraints.icon", + "wikibase.quality.constraints.ui" + ], + "skipFunction": "gadget-skip.js" + }, + "wikibase.quality.constraints.suggestions": { + "packageFiles": [ + "suggestions.js", + "suggestions/EntitySelectorHookHandlerFactory.js", + { + "name": "config.json", + "config": [ + "WBQualityConstraintsPropertyConstraintId", + "WBQualityConstraintsOneOfConstraintId", + "WBQualityConstraintsAllowedQualifiersConstraintId", + "WBQualityConstraintsPropertyId", + "WBQualityConstraintsQualifierOfPropertyConstraintId" + ] + } + ], + "dependencies": [ + "jquery.wikibase.entityselector" + ] + } + }, + "JobClasses": { + "constraintsTableUpdate": "WikibaseQuality\\ConstraintReport\\Job\\UpdateConstraintsTableJob::newFromGlobalState", + "constraintsRunCheck": "WikibaseQuality\\ConstraintReport\\Job\\CheckConstraintsJob" + }, + "config": { + "WBQualityConstraintsTypeCheckMaxEntities": { + "value": 1000, + "description": "The maximum number of entities that are accessed when checking type or subtype relations.", + "public": true + }, + "WBQualityConstraintsCheckDurationInfoSeconds": { + "value": 1.0, + "description": "The maximum time that a single constraint check should usually take, in seconds. Any constraint check that takes longer than this time is logged at ‘info’ level. Specifying `null` disables this logging.", + "public": true + }, + "WBQualityConstraintsCheckDurationWarningSeconds": { + "value": 10.0, + "description": "The maximum time that a single constraint check should ever take, in seconds. Any constraint check that takes longer than this time is logged at ‘warning’ level. Specifying `null` disables this logging.", + "public": true + }, + "WBQualityConstraintsCheckOnEntityDurationInfoSeconds": { + "value": 5.0, + "description": "The maximum time that a full constraint check on an entity should usually take, in seconds. Any entity constraint check that takes longer than this time is logged at ‘info’ level. Specifying `null` disables this logging.", + "public": true + }, + "WBQualityConstraintsCheckOnEntityDurationWarningSeconds": { + "value": 55.0, + "description": "The maximum time that a full constraint check on an entity should ever take, in seconds. Any entity constraint check that takes longer than this time is logged at ‘warning’ level. Specifying `null` disables this logging.", + "public": true + }, + "WBQualityConstraintsEnableConstraintsImportFromStatements": { + "value": true, + "description": "Whether to import property constraint statements into the constraint database or not.", + "public": true + }, + "WBQualityConstraintsEnableConstraintsCheckJobs": { + "value": false, + "description": "Whether to automatically run constraint checks in jobs.", + "public": true + }, + "WBQualityConstraintsEnableConstraintsCheckJobsRatio": { + "value": 0, + "description": "Percentage (0%-100%) of edits that trigger a constraint check", + "public": true + }, + "WBQualityConstraintsCheckQualifiers": { + "value": true, + "description": "Whether to check constraints on qualifiers.", + "public": true + }, + "WBQualityConstraintsCheckReferences": { + "value": true, + "description": "Whether to check constraints on references.", + "public": true + }, + "WBQualityConstraintsSparqlEndpoint": { + "value": "", + "description": "The URL of the SPARQL endpoint. Should accept the URL parameters 'query', 'format' and 'maxQueryTimeMillis'. Set to '' (empty string, default) to disable SPARQL functionality.", + "public": true + }, + "WBQualityConstraintsSparqlMaxMillis": { + "value": 10000, + "description": "The maximum runtime for queries on the configured SPARQL endpoint, in milliseconds.", + "public": true + }, + "WBQualityConstraintsSparqlThrottlingFallbackDuration": { + "value": 10, + "description": "The default duration in seconds, which prevents requests to the SPARQL endpoint, if the endpoint response with a 'try-later' (Responsecode 429). This field will only be used, if the endpoint sends a incorrect or incomplete response. The value must be a integer, which is greater than zero.", + "public": true + }, + "WBQualityConstraintsSparqlTimeoutExceptionClasses": { + "value": [ + "com.bigdata.bop.engine.QueryTimeoutException", + "java.util.concurrent.TimeoutException" + ], + "description": "Strings that, when they occur inside an error response of the SPARQL endpoint, indicate that the error is a query timeout. On the Wikidata Query Service, these are fully qualified names of exception classes.", + "public": true + }, + "WBQualityConstraintsSparqlHasWikibaseSupport": { + "value": false, + "description": "Whether the SPARQL endpoint has special Wikibase support, i. e. whether it is an installation of the Wikibase RDF Query server. If this is enabled, prefixes are not included in SPARQL queries, since the server already defines them by default (which reduces network traffic), and some queries include BlazeGraph-specific query hints. Otherwise, the queries should be suitable for any SPARQL server.", + "public": true + }, + "WBQualityConstraintsCheckFormatConstraint": { + "value": true, + "description": "Whether or not to check the 'format' constraint. If this flag is set to false, any check of the 'format' constraint will return a 'todo' status with the 'wbqc-violation-message-security-reason' message.", + "public": true + }, + "WBQualityConstraintsFormatCacheMapSize": { + "value": 100, + "description": "Size of the per-regex cache map for format/regex check results. For each regex, up to this many values will have cached whether they match the regex or not, on a least-recently-used basis.", + "public": true + }, + "WBQualityConstraintsCacheCheckConstraintsResults": { + "value": true, + "description": "Whether to a caching service while running constraint checks. Results are only cached for constraint checks on full entities, and only when the set of constraints to be checked is not specified (i. e. the constraintid parameter is unset).", + "public": true + }, + "WBQualityConstraintsCacheCheckConstraintsTTLSeconds": { + "value": 86400, + "description": "The time-to-live, in seconds, of cached results of the wbcheckconstraints API action. Ignored if WBQualityConstraintsCacheCheckConstraintsResults is not true.", + "public": true + }, + "WBQualityConstraintsCacheCheckConstraintsMaximumRevisionIds": { + "value": 10000, + "description": "The maximum number of revision IDs to load when checking whether a cached wbcheckconstraints result is still fresh. Results that depend on more entity IDs than this limit are not cached.", + "public": true + }, + "WBQualityConstraintsInstanceOfId": { + "value": "P31", + "description": "The property ID of the 'instance of' property (data type: item), which specifies the class(es) of an item.", + "public": true + }, + "WBQualityConstraintsSubclassOfId": { + "value": "P279", + "description": "The property ID of the 'subclass of' property (data type: item), which specifies the superclass(es) of an item.", + "public": true + }, + "WBQualityConstraintsPropertyConstraintId": { + "value": "P2302", + "description": "The property ID of the 'property constraint' property (data type: item), which specifies the various constraints of a property.", + "public": true + }, + "WBQualityConstraintsExceptionToConstraintId": { + "value": "P2303", + "description": "The property ID of the 'exception to constraint' property (data type: item), which specifies the exceptions of a constraint.", + "public": true + }, + "WBQualityConstraintsConstraintStatusId": { + "value": "P2316", + "description": "The property ID of the 'constraint status' property (data type: item), which specifies the constraint status of a constraint statement. Currently, only one constraint status is known (see WBQualityConstraintsMandatoryConstraintId), and the default status is signified by the absence of a 'constraint status' qualifier.", + "public": true + }, + "WBQualityConstraintsMandatoryConstraintId": { + "value": "Q21502408", + "description": "The item ID of the 'mandatory constraint' item, which, when used in a 'constraint status' qualifier of a 'property constraint' statement on a property, indicates that the constraint is mandatory and should have no violations except for the known exceptions.", + "public": true + }, + "WBQualityConstraintsSuggestionConstraintId": { + "value": "Q62026391", + "description": "The item ID of the 'suggestion constraint' item, which, when used in a 'constraint status' qualifier of a 'property constraint' statement on a property, indicates that the constraint is merely a suggestion for improvement and violations need not be taken very seriously.", + "public": true + }, + "WBQualityConstraintsDistinctValuesConstraintId": { + "value": "Q21502410", + "description": "The item ID of the 'distinct values constraint' item, which, when used in a 'property constraint' statement on a property, indicates that all values for this property should differ from each other, or, equivalently, that each value for this property should be unique to one item.", + "public": true + }, + "WBQualityConstraintsMultiValueConstraintId": { + "value": "Q21510857", + "description": "The item ID of the 'multi-value constraint' item, which, when used in a 'property constraint' statement on a property, indicates that a property should have more than one value per entity.", + "public": true + }, + "WBQualityConstraintsUsedAsQualifierConstraintId": { + "value": "Q21510863", + "description": "The item ID of the 'used as qualifier constraint' item, which, when used in a 'property constraint' statement on a property, indicates that a property should only be used as a qualifier.", + "public": true + }, + "WBQualityConstraintsSingleValueConstraintId": { + "value": "Q19474404", + "description": "The item ID of the 'single value constraint' item, which, when used in a 'property constraint' statement on a property, indicates that a property should have no more than one value per entity.", + "public": true + }, + "WBQualityConstraintsSymmetricConstraintId": { + "value": "Q21510862", + "description": "The item ID of the 'symmetric constraint' item, which, when used in a 'property constraint' statement on a property, indicates that a referenced entity should refer back to the original entity.", + "public": true + }, + "WBQualityConstraintsTypeConstraintId": { + "value": "Q21503250", + "description": "The item ID of the 'type constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the subject entity should have a certain type, with the relation and type given in the parameters.", + "public": true + }, + "WBQualityConstraintsValueTypeConstraintId": { + "value": "Q21510865", + "description": "The item ID of the 'value type constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the referenced entity should have a certain type, with the class and relation given in the parameters.", + "public": true + }, + "WBQualityConstraintsInverseConstraintId": { + "value": "Q21510855", + "description": "The item ID of the 'inverse constraint' item, which, when used in a 'property constraint' statement on a property, indicates that a referenced entity should refer back to the original entity with the property given in the parameters.", + "public": true + }, + "WBQualityConstraintsItemRequiresClaimConstraintId": { + "value": "Q21503247", + "description": "The item ID of the 'item requires claim constraint' item, which, when used in a 'property constraint' statement on a property, indicates that an entity with a given statement should also have certain other statements.", + "public": true + }, + "WBQualityConstraintsValueRequiresClaimConstraintId": { + "value": "Q21510864", + "description": "The item ID of the 'value requires claim constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the target/value entity of a given statement should have certain statements.", + "public": true + }, + "WBQualityConstraintsConflictsWithConstraintId": { + "value": "Q21502838", + "description": "The item ID of the 'conflicts-with constraint' item, which, when used in a 'property constraint' statement on a property, indicates that an entity with a given statement should not have certain other statements.", + "public": true + }, + "WBQualityConstraintsOneOfConstraintId": { + "value": "Q21510859", + "description": "The item ID of the 'one-of constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should be one of a given set of values.", + "public": true + }, + "WBQualityConstraintsMandatoryQualifierConstraintId": { + "value": "Q21510856", + "description": "The item ID of the 'mandatory qualifier' item, which, when used in a 'property constraint' statement on a property, indicates a given statement should have the given qualifier.", + "public": true + }, + "WBQualityConstraintsAllowedQualifiersConstraintId": { + "value": "Q21510851", + "description": "The item ID of the 'allowed qualifiers constraint' item, which, when used in a 'property constraint' statement on a property, indicates a given statement should only have the given qualifiers.", + "public": true + }, + "WBQualityConstraintsRangeConstraintId": { + "value": "Q21510860", + "description": "The item ID of the 'range constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should be within a given range.", + "public": true + }, + "WBQualityConstraintsDifferenceWithinRangeConstraintId": { + "value": "Q21510854", + "description": "The item ID of the 'difference within range constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the difference value of a given statement and of another given statement should be within a given range.", + "public": true + }, + "WBQualityConstraintsCommonsLinkConstraintId": { + "value": "Q21510852", + "description": "The item ID of the 'commons link constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should be a valid link to Wikimedia Commons.", + "public": true + }, + "WBQualityConstraintsContemporaryConstraintId": { + "value": "Q25796498", + "description": "The item ID of the 'contemporary constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the entities which are linked through this property should be contemporary according to their start and end time values.", + "public": true + }, + "WBQualityConstraintsFormatConstraintId": { + "value": "Q21502404", + "description": "The item ID of the 'format constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should conform to a given pattern.", + "public": true + }, + "WBQualityConstraintsUsedForValuesOnlyConstraintId": { + "value": "Q21528958", + "description": "The item ID of the 'used for values only constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used for the main value of a statement, not for qualifiers or references.", + "public": true + }, + "WBQualityConstraintsUsedAsReferenceConstraintId": { + "value": "Q21528959", + "description": "The item ID of the 'used as reference constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used for references, not for the main value of a statement or for qualifiers.", + "public": true + }, + "WBQualityConstraintsNoBoundsConstraintId": { + "value": "Q51723761", + "description": "The item ID of the 'no bounds constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used with no bounded quantity as its value.", + "public": true + }, + "WBQualityConstraintsAllowedUnitsConstraintId": { + "value": "Q21514353", + "description": "The item ID for the 'allowed units constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should only have certain units.", + "public": true + }, + "WBQualityConstraintsSingleBestValueConstraintId": { + "value": "Q52060874", + "description": "The item ID for the 'single best value constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should have a single, distinguished best value per item.", + "public": true + }, + "WBQualityConstraintsAllowedEntityTypesConstraintId": { + "value": "Q52004125", + "description": "The item ID for the 'allowed entity types constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property can be used only in certain entity types (e.g. only items).", + "public": true + }, + "WBQualityConstraintsCitationNeededConstraintId": { + "value": "Q54554025", + "description": "The item ID of the 'citation needed constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should have at least one reference for its values.", + "public": true + }, + "WBQualityConstraintsPropertyScopeConstraintId": { + "value": "Q53869507", + "description": "The item ID of the 'property scope constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used in some locations (main value, qualifiers, and/or references, but not all of them).", + "public": true + }, + "WBQualityConstraintsLexemeLanguageConstraintId": { + "value": "Q55819106", + "description": "The item ID of the 'lexeme language constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used in lexeme that have the given language set.", + "public": true + }, + "WBQualityConstraintsLabelInLanguageConstraintId": { + "value": "Q108139345", + "description": "The item ID of the 'label in language constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the property should only be used in entities that have label in the given languages.", + "public": true + }, + "WBQualityConstraintsLanguagePropertyId": { + "value": "P424", + "description": "The property ID of the 'Wikimedia language code' property (data type: string), which specifies the language code of a 'label in language' constraint.", + "public": true + }, + "WBQualityConstraintsClassId": { + "value": "P2308", + "description": "The property ID of the 'class' property (data type: item), which specifies the class/type of a 'type' or 'value type' constraint.", + "public": true + }, + "WBQualityConstraintsRelationId": { + "value": "P2309", + "description": "The property ID of the 'relation' property (data type: item), which specifies the relation ('instance of' or 'subclass of') of a 'type' or 'value type' constraint.", + "public": true + }, + "WBQualityConstraintsInstanceOfRelationId": { + "value": "Q21503252", + "description": "The item ID of the 'instance of' item, which, when used in a 'relation' qualifier of a 'property constraint' statement on a property, indicates that the 'type' or 'value type' constraint defined in this statement demands an 'instance' relation.", + "public": true + }, + "WBQualityConstraintsSubclassOfRelationId": { + "value": "Q21514624", + "description": "The item ID of the 'subclass of' item, which, when used in a 'relation' qualifier of a 'property constraint' statement on a property, indicates that the 'type' or 'value type' constraint defined in this statement demands a 'subclass' relation.", + "public": true + }, + "WBQualityConstraintsInstanceOrSubclassOfRelationId": { + "value": "Q30208840", + "description": "The item ID of the 'instance or subclass of' item, which, when used in a 'relation' qualifier of a 'property constraint' statement on a property, indicates that the 'type' or 'value type' constraint defined in this statement demands a 'instance or subclass' relation.", + "public": true + }, + "WBQualityConstraintsPropertyId": { + "value": "P2306", + "description": "The property ID of the 'property' property (data type: property), which specifies the property parameter of an 'inverse', 'item requires claim', 'value requires claim', 'difference within range', 'mandatory qualifiers', or 'qualifiers' constraint.", + "public": true + }, + "WBQualityConstraintsQualifierOfPropertyConstraintId": { + "value": "P2305", + "description": "The property ID of the 'qualifier of property constraint' property (data type: item), which specifies the item parameter of an 'item requires claim', 'value requires claim', or 'one of' constraint.", + "public": true + }, + "WBQualityConstraintsMinimumQuantityId": { + "value": "P2313", + "description": "The property ID of the 'minimum quantity' property (data type: quantity), which specifies the minimum quantity parameter of a 'range' or 'diff within range' constraint.", + "public": true + }, + "WBQualityConstraintsMaximumQuantityId": { + "value": "P2312", + "description": "The property ID of the 'maximum quantity' property (data type: quantity), which specifies the maximum quantity parameter of a 'range' or 'diff within range' constraint.", + "public": true + }, + "WBQualityConstraintsMinimumDateId": { + "value": "P2310", + "description": "The property ID of the 'minimum date' property (data type: point in time), which specifies the minimum date parameter of a 'range' or 'diff within range' constraint.", + "public": true + }, + "WBQualityConstraintsMaximumDateId": { + "value": "P2311", + "description": "The property ID of the 'maximum date' property (data type: point in time), which specifies the maximum date parameter of a 'range' or 'diff within range' constraint.", + "public": true + }, + "WBQualityConstraintsNamespaceId": { + "value": "P2307", + "description": "The property ID of the 'namespace' property (data type: string), which specifies the namespace parameter of a 'commons link' constraint.", + "public": true + }, + "WBQualityConstraintsFormatAsARegularExpressionId": { + "value": "P1793", + "description": "The property ID of the 'format as a regular expression' property (data type: string), which specifies the format parameter of a 'format' constraint.", + "public": true + }, + "WBQualityConstraintsSyntaxClarificationId": { + "value": "P2916", + "description": "The property ID of the 'syntax clarification' property (data type: monolingual text), which specifies human-readable explanations of a 'format' constraint.", + "public": true + }, + "WBQualityConstraintsConstraintScopeId": { + "value": "P4680", + "description": "The property ID of the 'constraint scope' property (data type: item), which specifies the context(s) in which a constraint is checked.", + "public": true + }, + "WBQualityConstraintsConstraintEntityTypesId": { + "value": "P4680", + "description": "The property ID of the property (data type: item) which specifies the entity types on which a constraint is checked. By default, this is the same as the 'constraint scope' property, but may also be set to a different one. The recognized values (items representing entity types) are the same as for the 'allowed entity types' constraint.", + "public": true + }, + "WBQualityConstraintsSeparatorId": { + "value": "P4155", + "description": "The property ID of the 'separator' property (data type: property), which specifies the allowed separator(s) for “single value” and “single best value” constraints.", + "public": true + }, + "WBQualityConstraintsConstraintCheckedOnMainValueId": { + "value": "Q46466787", + "description": "The item ID of the 'constraint checked on main value' item, which, when used in a 'constraint scope' qualifier of a 'property constraint' statement on a property, indicates that the constraint should be checked on the main snak of a statement.", + "public": true + }, + "WBQualityConstraintsConstraintCheckedOnQualifiersId": { + "value": "Q46466783", + "description": "The item ID of the 'constraint checked on qualifiers' item, which, when used in a 'constraint scope' qualifier of a 'property constraint' statement on a property, indicates that the constraint should be checked on the qualifier snaks of a statement.", + "public": true + }, + "WBQualityConstraintsConstraintCheckedOnReferencesId": { + "value": "Q46466805", + "description": "The item ID of the 'constraint checked on references' item, which, when used in a 'constraint scope' qualifier of a 'property constraint' statement on a property, indicates that the constraint should be checked on the reference snaks of a statement.", + "public": true + }, + "WBQualityConstraintsNoneOfConstraintId": { + "value": "Q52558054", + "description": "The item ID of the 'none-of constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should not be one of a given set of values.", + "public": true + }, + "WBQualityConstraintsIntegerConstraintId": { + "value": "Q52848401", + "description": "The item ID of the 'integer constraint' item, which, when used in a 'property constraint' statement on a property, indicates that the value of a given statement should have only integer values.", + "public": true + }, + "WBQualityConstraintsWikibaseItemId": { + "value": "Q29934200", + "description": "The item ID of the 'wikibase item' item, which represents the 'item' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsWikibasePropertyId": { + "value": "Q29934218", + "description": "The item ID of the 'wikibase property' item, which represents the 'property' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsWikibaseLexemeId": { + "value": "Q51885771", + "description": "The item ID of the 'wikibase lexeme' item, which represents the 'lexeme' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsWikibaseFormId": { + "value": "Q54285143", + "description": "The item ID of the 'wikibase form' item, which represents the 'form' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsWikibaseSenseId": { + "value": "Q54285715", + "description": "The item ID of the 'wikibase sense' item, which represents the 'sense' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsWikibaseMediaInfoId": { + "value": "Q59712033", + "description": "The item ID of the 'wikibase MediaInfo' item, which represents the 'mediainfo' entity type for 'allowed entity types' constraints.", + "public": true + }, + "WBQualityConstraintsPropertyScopeId": { + "value": "P5314", + "description": "The property ID of the 'property scope' property, which specifies the scope parameter of a 'scope' constraint.", + "public": true + }, + "WBQualityConstraintsAsMainValueId": { + "value": "Q54828448", + "description": "The item ID of the 'as main value' item, which, when used in a 'property scope' parameter of a 'scope' constraint, signifies that a property may be used for the main snaks of statements.", + "public": true + }, + "WBQualityConstraintsAsQualifiersId": { + "value": "Q54828449", + "description": "The item ID of the 'as qualifiers' item, which, when used in a 'property scope' parameter of a 'scope' constraint, signifies that a property may be used for qualifiers of statements.", + "public": true + }, + "WBQualityConstraintsAsReferencesId": { + "value": "Q54828450", + "description": "The item ID of the 'as references' item, which, when used in a 'property scope' parameter of a 'scope' constraint, signifies that a property may be used for references of statements.", + "public": true + }, + "WBQualityConstraintsPropertiesWithViolatingQualifiers": { + "value": [], + "description": "Property IDs of statements whose qualifiers are expected to violate constraints, and where constraints checks are therefore skipped, as if the subject entity was an exception to the constraints defined on the qualifier properties.", + "public": true + }, + "WBQualityConstraintsStartTimePropertyIds": { + "value": [ + "P569", + "P571", + "P580", + "P585" + ], + "description": "Property IDs of statements whose minimum value defines the start time of an entity, which is used by 'contemporary' contraints.", + "public": true + }, + "WBQualityConstraintsEndTimePropertyIds": { + "value": [ + "P570", + "P576", + "P582", + "P585" + ], + "description": "Property IDs of statements whose maximum value defines the end time of an entity, which is used by 'contemporary' contraints.", + "public": true + }, + "WBQualityConstraintsYearUnit": { + "value": "http://www.wikidata.org/entity/Q577", + "description": "The unit used for a quantity that represents a difference between two dates, in years. Note that for entity units, the full concept URI must be used, not just the entity ID.", + "public": true + }, + "WBQualityConstraintsSecondUnit": { + "value": "http://www.wikidata.org/entity/Q11574", + "description": "The unit used for a quantity that represents a difference between two dates, in seconds. Note that for entity units, the full concept URI must be used, not just the entity ID.", + "public": true + }, + "WBQualityConstraintsEnableSuggestionConstraintStatus": { + "value": false, + "description": "Whether to enable the 'constraint suggestion' constraint status or not. This is a temporary configuration that will be removed once constraint suggestions are permanently enabled on Wikidata.", + "public": true + }, + "WBQualityConstraintsFormatCheckerShellboxRatio": { + "value": 0, + "description": "Float value between 0 and 1 determining ratio of requests made to shellbox (vs. WDQS) in FormatChecker in evaluating regexes. Zero disables requesting to shellbox (all going to WDQS) and one means all requests will go to shellbox.", + "public": true + } + }, + "AutoloadNamespaces": { + "WikibaseQuality\\ConstraintReport\\": "src/", + "WikibaseQuality\\ConstraintReport\\Maintenance\\": "maintenance/" + }, + "TestAutoloadNamespaces": { + "WikibaseQuality\\ConstraintReport\\Tests\\": "tests/phpunit/" + }, + "manifest_version": 2 +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ady-cyrl.json b/dist/extensions/WikibaseQualityConstraints/i18n/ady-cyrl.json new file mode 100644 index 000000000..c36ecd832 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ady-cyrl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Bedynokue.nart" + ] + }, + "wbqc-constraintreport-no-parameter": "зи" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/an.json b/dist/extensions/WikibaseQualityConstraints/i18n/an.json new file mode 100644 index 000000000..fa4f9422d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/an.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Fitoschido" + ] + }, + "wbqc-constrainttypehelp-short": "Aduya" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/ar.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/ar.json new file mode 100644 index 000000000..7e034039c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/ar.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "Meno25", + "Mr. Ibrahem", + "ديفيد" + ] + }, + "apihelp-wbcheckconstraints-description": "إجراء عملية تحقق للمحددات على أي عنصر تريد وإرجاع النتيجة.", + "apihelp-wbcheckconstraints-summary": "إجراء عملية تحقق للمحددات على أي عنصر تريد وإرجاع النتيجة.", + "apihelp-wbcheckconstraints-param-id": "معرف العناصر للحصول على البيانات منه. قيم منفصلة بـ '|'.", + "apihelp-wbcheckconstraints-param-claimid": "قائمة غويد تحدد إدعاء للتحقق من تقرير المحددات. قيم منفصلة مع '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "مرشح اختياري لإرجاع المحددات/القيود التي تحتوي على معرف القيد المحدد فقط.", + "apihelp-wbcheckconstraints-param-status": "عامل تصفية اختياري لإرجاع نتائج التحقق مع الحالات المحددة فقط.\n\nلاحظ أن النتائج فقط لحالات \"الانتهاك\" و \"التحذير\" و \"الاقتراح\" و \"المعلمات السيئة\" يتم تخزينها مؤقتًا ، لذا فإن الطلبات التي تحدد أيًا الحالات التي تتجاوز تلك الأربعة لا تستفيد من التخزين المؤقت.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "البيان يطابق القيد.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "البيان ينتهك القيد.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "الكيان موضوع البيان هو استثناء معروف لدى القيد.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "لم يتم تنفيذ القيد.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "وسائط القيد معطوبة.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "لم يتم التحقق من القيد بسبب إهمال البيان.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "البيان ينتهك القيد، ولكن القيد ليس إلزاميا.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "البيان ينتهك القيد، لكن القيد هو مجرد اقتراح.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "لا يتم التحقق من القيد على هذا النوع من البيانات ''snak'' (''main snak''، وتصفية ''qualifier'' أو مرجع)، لذلك تم تخطي اختبار القيد.", + "apihelp-wbcheckconstraintparameters-summary": "تحقق من معلمات المحددات للبيانات المحددات.", + "apihelp-wbcheckconstraintparameters-extended-description": "إما واحدة من property وconstraintid أو كليهما قد يكون محدداً؛ سيتم التحقق من جميع المحددات التي تم اختيارها بواسطة أي معلمة.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "قائمة معرفات الخواص للتحقق. سيتم فحص جميع بيانات المحددات لهذه الخواص.\nإذا تم تحديد هذه المعلمة، لا يجب أن تكون فارغة.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "قائمة معرفات القيد (المعرفات الفريدة العمومية لبيان القيد) للتحقق.\n\nإذا تم تحديد هذه المعلمة، يجب أن يكون غير فارغ.", + "apihelp-wbcheckconstraints-example-1": "تحقق من جميع القيود على العناصر Q5 و Q42.", + "apihelp-wbcheckconstraints-example-2": "تحقق من جميع القيود على بيان واحد.", + "apihelp-wbcheckconstraints-example-3": "تحقق من قيود معينة على العنصر Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "تحقق من معلمات القيد لجميع القيود على خاصية.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "تحقق من معلمات القيد لقيدين معينين." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/be-tarask.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/be-tarask.json new file mode 100644 index 000000000..47dfc3200 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/be-tarask.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Red Winged Duck", + "Renessaince" + ] + }, + "apihelp-wbcheckconstraints-description": "Выконвае праверкі абмежаваньня для любой патрэбнай вам сутнасьці і выводзіць вынік.", + "apihelp-wbcheckconstraints-summary": "Выконвае праверкі абмежаваньня для любой патрэбнай вам сутнасьці і выводзіць вынік.", + "apihelp-wbcheckconstraints-param-id": "Сьпіс ідэнтыфікатараў сутнасьцяў, зь якіх трэба атрымаць зьвесткі. Аддзяляйце значэньні з дапамогай «|» ці чагосьці падобнага.", + "apihelp-wbcheckconstraints-param-claimid": "Сьпіс GUID, які вызначае запіс, у якім трэба выканаць праверку абмежаваньня. Аддзяляйце значэньні з дапамогай «|».", + "apihelp-wbcheckconstraints-param-constraintid": "Неабавязковы фільтар дзеля вяртаньня толькі тых абмежаваньняў, якія маюць вызначаны ідэнтыфікатар абмежаваньня.", + "apihelp-wbcheckconstraints-param-status": "Зьвярніце ўвагу, што кэшуюцца толькі вынікі для статусаў «парушэньне», «папярэджаньне», «прапанова» і «хібныя парамэтры», таму запыты, якія выбіраюць іншыя статусы, не атрымліваюць паскарэньня ад кэшаваньня.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Сьцьверджаньне адпавядае абмежаваньню.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Сьцьверджаньне парушае абмежаваньне.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Прадмет сутнасьці сьцьверджаньня — вядомы вынятак для абмежаваньня.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Абмежаваньне не прымененае.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Парамэтры абмежаваньня сапсаваныя.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Праверка абмежаваньня не адбылася, бо сьцьверджаньне састарэлае.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Сьцьверджаньне парушае абмежаваньне, аднак гэтае абмежаваньне неабавязковае.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Сьцьверджаньне парушае абмежаваньне, аднак гэтае абмежаваньне зьяўляецца толькі прапановай.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Абмежаваньне на гэтым відзе снэку (галоўнага снэку, кваліфікатара ці крыніцы) ня ўключанае, таму праверка абмежаваньня прапушчаная.", + "apihelp-wbcheckconstraintparameters-summary": "Правярае парамэтры сьцьверджаньняў абмежаваньня.", + "apihelp-wbcheckconstraintparameters-extended-description": "Можна пазначыць любы ці абодва парамэтраў уласьцівасьць ці ідэнтыфікатар_абмежаваньня; будуць правераныя ўсе абмежаваньні, выбраныя любым з парамэтраў.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Сьпіс ідэнтыфікатараў уласьцівасьцей для праверкі. Будуць правераныя ўсе сьцьверджаньні абмежаваньняў гэтых уласьцівасьцей.\n\nКалі гэты парамэтар пазначаны, ён ня можа быць пустым.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Сьпіс ідэнтыфікатараў абмежаваньняў (GUID сьцьверджаньняў абмежаваньняў) для праверкі.\n\nКалі гэты парамэтар пазначаны, ён ня можа быць пустым.", + "apihelp-wbcheckconstraints-example-1": "Праверыць усе абмежаваньні ў элемэнтах Q5 і Q42.", + "apihelp-wbcheckconstraints-example-2": "Праверыць усе абмежаваньні ў адным сьцьверджаньні.", + "apihelp-wbcheckconstraints-example-3": "Праверыць адно канкрэтнае абмежаваньне ў элемэнце Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Праверыць парамэтры ўсіх абмежаваньняў уласьцівасьці.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Праверыць парамэтры двух канкрэтных абмежаваньняў." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/de.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/de.json new file mode 100644 index 000000000..df5e48b0e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/de.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "Metalhead64", + "Umherirrender", + "Nw520" + ] + }, + "apihelp-wbcheckconstraints-description": "Führt Beschränkungsprüfungen zu jeder gewünschten Entität aus und gibt das Ergebnis zurück.", + "apihelp-wbcheckconstraints-summary": "Führt Beschränkungsprüfungen für jedes beliebige Objekt durch und gibt das Ergebnis aus.", + "apihelp-wbcheckconstraints-param-id": "Kennung der Objektliste, von der die Daten abgerufen werden sollen. Mehrere Werte mit „|“ oder Ähnlichem trennen.", + "apihelp-wbcheckconstraints-param-claimid": "GUID-Liste, die eine Behauptung erkennt, um einen Beschränkungsbericht zu prüfen. Mehrere Werte mit „|“ trennen.", + "apihelp-wbcheckconstraints-param-constraintid": "Optionaler Filter, um nur die Beschränkungen zurückzugeben, die die angegebenen Beschränkungskennungen haben.", + "apihelp-wbcheckconstraints-param-status": "Optionaler Filter, der nur Prüfergebnisse mit den ausgewählten Status zurückgibt.\n\nBeachte, dass nur Ergebnisse für die Status „violation“, „warning“, „suggestion“ und „bad-parameters“ zwischengespeichert werden.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Die Aussage hält die Beschränkung ein.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Die Aussage verletzt die Beschränkung.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Der Themendatensatz der Aussage ist eine bekannte Ausnahme der Beschränkung.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Die Beschränkung ist nicht implementiert.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Die Beschränkungsparameter sind defekt.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Die Beschränkung wurde nicht geprüft, da die Aussage veraltet ist.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Die Aussage verletzt die Beschränkung, die Beschränkung ist jedoch nicht verpflichtend.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Die Aussage verletzt die Beschränkung, die Beschränkung ist jedoch nur ein Vorschlag.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Die Einschränkung wird bei dieser Art von Snak (Haupt-Snak, Qualifier oder Referenz) nicht geprüft, so dass die Einschränkungsprüfung übersprungen wird.", + "apihelp-wbcheckconstraintparameters-summary": "Überprüft die Beschränkungsparameter der Beschränkungsaussagen.", + "apihelp-wbcheckconstraintparameters-extended-description": "Einer oder beide der Parameter property und constraintid können angegeben werden; alle Einschränkungen, die durch einen der beiden Parameter ausgewählt wurden, werden überprüft.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Liste der zu prüfenden Eigenschafts-IDs. Es werden alle Constraint-Anweisungen dieser Eigenschaften geprüft.\n\nWenn dieser Parameter angegeben wird, darf er nicht leer sein.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Liste der zu prüfenden Constraint-IDs (GUIDs von Constraint-Anweisungen).\n\nWenn dieser Parameter angegeben wird, darf er nicht leer sein.", + "apihelp-wbcheckconstraints-example-1": "Überprüft alle Beschränkungen der Objekte Q5 und Q42.", + "apihelp-wbcheckconstraints-example-2": "Überprüft alle Beschränkungen einer einzelnen Aussage.", + "apihelp-wbcheckconstraints-example-3": "Überprüft eine bestimmte Beschränkung des Objekts Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Überprüft Beschränkungsparameter aller Beschränkungen einer Eigenschaft.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Überprüft Parameter zwei spezieller Beschränkungen." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/en.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/en.json new file mode 100644 index 000000000..18772a213 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/en.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "BP2014N1", + "Andreas Burmeister" + ] + }, + "apihelp-wbcheckconstraints-description": "Performs constraint checks on any entity you want and returns the result.", + "apihelp-wbcheckconstraints-summary": "Performs constraint checks on any entity you want and returns the result.", + "apihelp-wbcheckconstraints-param-id": "ID list of the entities to get the data from. Separate values with '|' or alternative.", + "apihelp-wbcheckconstraints-param-claimid": "GUID list identifying a claim to check a constraint report. Separate values with '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Optional filter to return only the constraints that have the specified constraint ID.", + "apihelp-wbcheckconstraints-param-status": "Optional filter to return only check results with the selected statuses.\n\nNote that only results for the 'violation', 'warning', 'suggestion' and 'bad-parameters' statuses are cached, so requests that select any statuses beyond those four do not benefit from caching.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "The statement satisfies the constraint.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "The statement violates the constraint.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "The subject entity of the statement is a known exception to the constraint.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "The constraint is not implemented.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "The constraint parameters are broken.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "The constraint has not been checked because the statement is deprecated.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "The statement violates the constraint, but the constraint is not mandatory.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "The statement violates the constraint, but the constraint is just a suggestion.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "The constraint is not checked on this kind of snak (main snak, qualifier or reference), so the constraint check is skipped.", + "apihelp-wbcheckconstraintparameters-summary": "Checks the constraint parameters of constraint statements.", + "apihelp-wbcheckconstraintparameters-extended-description": "Either or both of the property and constraintid parameters may be specified; all constraints selected by either parameter will be checked.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "List of property IDs to check. All constraint statements of these properties will be checked.\n\nIf this parameter is specified, it must be nonempty.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "List of constraint IDs (constraint statement GUIDs) to check.\n\nIf this parameter is specified, it must be nonempty.", + "apihelp-wbcheckconstraints-example-1": "Check all constraints on the items Q5 and Q42.", + "apihelp-wbcheckconstraints-example-2": "Check all constraints on a single statement.", + "apihelp-wbcheckconstraints-example-3": "Check one particular constraint on the item Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Check constraint parameters of all constraints on a property.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Check constraint parameters of two particular constraints." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/es.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/es.json new file mode 100644 index 000000000..08e441de3 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/es.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "Agabi10", + "Ciencia Al Poder", + "Dgstranz", + "Fitoschido" + ] + }, + "apihelp-wbcheckconstraints-description": "Realiza comprobaciones de restricciones en cualquier entidad y devuelve el resultado.", + "apihelp-wbcheckconstraints-summary": "Realiza comprobaciones de restricciones en cualquier entidad y devuelve el resultado.", + "apihelp-wbcheckconstraints-param-id": "Lista de identificadores de las entidades de las que se obtendrán datos. Separa los valores con «|» u otra alternativa.", + "apihelp-wbcheckconstraints-param-claimid": "Lista de GUID que identifica una afirmación para verificar un informe de restricción. Separe los valores con '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Filtro opcional para devolver solo las restricciones que tengan el identificador de restricción especificado.", + "apihelp-wbcheckconstraints-param-status": "Filtro opcional para devolver solo resultados de la comprobación con los estados seleccionados.\n\nObserva que solo se almacenan en antememoria los resultados con los estados «violation», «warning», «suggestion» y «bad-parameters», de modo que las solicitudes que seleccionen otros estados no se beneficiarán de la antememoria.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "La declaración satisface la restricción.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "La declaración viola la restricción.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "La entidad sujeto de la declaración es una excepción conocida de la restricción.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "La restricción no está implementada.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Los parámetros de la restricción son defectuosos.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "No se ha comprobado la restricción porque la declaración es obsoleta.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "La declaración viola la restricción, pero esta última no es obligatoria.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "La declaración viola la restricción, pero la restricción es sólo una sugerencia.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "La restricción no se comprueba en este tipo de snak (snak principal, calificador o referencia), por lo que se omite la comprobación de la restricción.", + "apihelp-wbcheckconstraintparameters-summary": "Verifica los parámetros de restricción de las declaraciones de restricción.", + "apihelp-wbcheckconstraintparameters-extended-description": "Se pueden especificar uno o ambos parámetros de property y constraintid; se comprobarán todas las restricciones seleccionadas por cualquiera de los parámetros.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Lista de identificadores de propiedades a comprobar. Se comprobarán todas las declaraciones de restricciones de estas propiedades.\n\nSi se especifica el parámetro, este no puede estar vacío.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Lista de identificadores de restricciones (GUIDs de declaración de restricciones) a comprobar.\n\nSi se especifica este parámetro, no deberá estar vacío.", + "apihelp-wbcheckconstraints-example-1": "Verificar todas las restricciones en los elementos Q5 y Q42.", + "apihelp-wbcheckconstraints-example-2": "Verificar todas las restricciones en una sola declaración.", + "apihelp-wbcheckconstraints-example-3": "Verificar una restricción particular en el elemento Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Verificar los parámetros de restricción de todas las restricciones de una propiedad.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Verificar los parámetros de restricción de dos restricciones específicas." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/eu.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/eu.json new file mode 100644 index 000000000..c47c13fd4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/eu.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Mikel Ibaiba" + ] + }, + "apihelp-wbcheckconstraintparameters-extended-description": "property eta constraintid, bata edo biak, parametroak zehaztu behar dira: aukeratutako mugaketa guztiak parametroek aztertuko dituzte.", + "apihelp-wbcheckconstraints-example-3": "Q2 artikuluan murrizketa zehatz bat egiaztatu.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Jabetzeko murrizte guztien murrizte parametroak aztertu.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Bi murrizte zehatzen murrizte parametroak aztertu." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/fr.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/fr.json new file mode 100644 index 000000000..a62d7d5ae --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/fr.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "Gomoko", + "Thibaut120094", + "Verdy p", + "Wladek92" + ] + }, + "apihelp-wbcheckconstraints-description": "Réalise des vérifications de contraintes sur toute entité que vous désirez et renvoie le résultat.", + "apihelp-wbcheckconstraints-summary": "Réalise des vérifications de contraintes sur toute entité que vous désirez et renvoie le résultat.", + "apihelp-wbcheckconstraints-param-id": "Liste d’identifiants des entités pour lesquelles obtenir les données. Séparez les valeurs par « | » ou similaire.", + "apihelp-wbcheckconstraints-param-claimid": "Liste des GUID identifiant une déclaration à vérifier pour générer un rapport sur leur contraintes. Séparez les valeurs par « | ».", + "apihelp-wbcheckconstraints-param-constraintid": "Filtre facultatif pour ne retourner que les contraintes qui ont l’identifiant de contrainte spécifié.", + "apihelp-wbcheckconstraints-param-status": "Filtre facultatif pour ne renvoyer que les résultats avec les états sélectionnés.\n\nNoter que seuls les résultats pour les états « violation », « avertissement », « suggestion » et « mauvais-paramètres » sont mis en cache, donc les requêtes qui sélectionnent un état autre que ces quatre là ne bénéficient pas du cache.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "La déclaration satisfait la contrainte.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "La déclaration viole la contrainte.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "L’entité sujet de la déclaration est une exception connue à la contrainte.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "La contrainte n’est pas mise en œuvre.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Les paramètres de la contrainte sont erronés.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "La contrainte n’a pas été vérifiée parce que la déclaration est obsolète.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "La déclaration viole la contrainte, mais la contrainte n’est pas exigée.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "La déclaration viole la contrainte, mais la contrainte n’est qu’une suggestion.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "La contrainte n’est pas vérifiée sur ce type d’élément (valeur principale, qualificateur ou référence), donc la vérification de la contrainte est sautée.", + "apihelp-wbcheckconstraintparameters-summary": "Vérifie les paramètres des déclarations de contrainte.", + "apihelp-wbcheckconstraintparameters-extended-description": "Un des deux paramètres property ou constraintid au moins doit être spécifié ; toutes les contraintes sélectionnées par chacun des paramètres seront vérifiées.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Liste des identifiants de propriété à vérifier. Toutes les déclarations de contrainte de ces propriétés seront vérifiées.\n\nSi ce paramètre est spécifié, il doit être non vide.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Liste des identifiants de contrainte (GUID de déclaration de contrainte) à vérifier.\n\nSi ce paramètre est spécifié, il doit être non vide.", + "apihelp-wbcheckconstraints-example-1": "Vérifier toutes les contraintes sur les éléments Q5 et Q42.", + "apihelp-wbcheckconstraints-example-2": "Vérifier toutes les contraintes sur une seule déclaration.", + "apihelp-wbcheckconstraints-example-3": "Vérifier une contrainte particulière sur l’élément Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Vérifier les paramètres de toutes les contraintes d’une propriété.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Vérifier les paramètres de deux contraintes particulières." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/gl.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/gl.json new file mode 100644 index 000000000..f45af036a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/gl.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Elisardojm" + ] + }, + "apihelp-wbcheckconstraints-param-constraintid": "Filtro opcional para devolver só as constantes que teñen o ID de constante especificado.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "A declaración satisfai a restrición.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "A declaración viola a restrición.", + "apihelp-wbcheckconstraints-example-1": "Verificar tódalas constantes sobre os elementos Q5 e Q42.", + "apihelp-wbcheckconstraints-example-2": "Verificar tódalas constantes nunha soa instrucción.", + "apihelp-wbcheckconstraints-example-3": "Verificar unha restrición en particular sobre o obxecto Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Verificar os parámetros de restrición de tódalas restricións dunha propiedade.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Verificar os parámetros de restrición de dúas restricións en particular." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/he.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/he.json new file mode 100644 index 000000000..e95c799ce --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/he.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Guycn2" + ] + }, + "apihelp-wbcheckconstraints-description": "ביצוע בדיקות אילוצים על ישות כלשהי והחזרת התוצאה.", + "apihelp-wbcheckconstraints-summary": "ביצוע בדיקת אילוצים על כל ישות והחזרת התוצאה.", + "apihelp-wbcheckconstraints-param-id": "רשימת מזהי ישויות שמהן צריך לקבל נתונים. יש להפריד את הערכים בתו '|' או חלופות.", + "apihelp-wbcheckconstraints-param-claimid": "רשימת GUID־ים שמזהים טענה שצריך לבדוק אל מול דו\"ח אילוצים. יש להפריד ערכים בתו '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "מסנן אופציונלי שיחזיר רק את האילוצים שיש להם מזה אילוץ שצוין.", + "apihelp-wbcheckconstraints-param-status": "מסנן אופציונלי להחזרת תוצאות בדיקה עם מצבים מסוימים בלבד.\n\nנא לשים לב לכך שרק תוצאות עם המצבים \"violation\"‏, \"warning\"‏, \"suggestion\" ו־\"bad-parameters\" נשמרות במטמון, כך שבקשות שבוחרות כל מצב אחרת מלבד ארבעת אלה אינן מקבלות שום תועלת מהמטמון.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "הקביעה תואמת לאילוץ.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "הקביעה מפרה את האילוץ.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "ישות הנושא של הקביעה היא חריגה ידועה של האילוץ.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "האילוץ אינו מיושם.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "הפרמטרים של האילוץ אינם תקינים.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "האילוץ לא נבדק משום שהקביעה הוכרזה כירודה.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "הקביעה מפרה את האילוץ, אבל האילוץ אינו חובה.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "הקביעה הזאת מפרה את האילוץ, אבל האילוץ הוא רק הצעה.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "האילוץ אינו נבדק בסוג הסנאק הזה (סנאק ראשי, מבחין או מקור), ולכן דילגנו על בדיקת האילוץ הזה.", + "apihelp-wbcheckconstraintparameters-summary": "בדיקת הפרמטרים של קביעות האילוצים.", + "apihelp-wbcheckconstraintparameters-extended-description": "ניתן לציין את אחד הפרמטרים property ו־constraintid או את שניהם; כל האילוצים שנבחרו לפי אחד הפרמטרים ייבדקו.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "רשימה של מזהי המאפיינים שייבדקו. כל קביעות האילוצים של המאפיינים האלה תיבדקנה.\n\nאם הפרמטר הזה מצוין, הוא לא יכול להיות ריק.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "רשימה של מזהי האילוצים (ה־GUID של קביעות האילוצים) שייבדקו.\n\nאם הפרמטר הזה מצוין, הוא לא יכול להיות ריק.", + "apihelp-wbcheckconstraints-example-1": "בדיקה של כל האילוצים על הפריטים Q5 ו־Q42.", + "apihelp-wbcheckconstraints-example-2": "בדיקת כל האילוצים על טענה בודדת.", + "apihelp-wbcheckconstraints-example-3": "בדיקת אילוץ ייחודי בפריט Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "בדיקת הפרמטרים של כל האילוצים במאפיין.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "בדיקת הפרמטרים של שני אילוצים ייחודיים." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/hu.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/hu.json new file mode 100644 index 000000000..1cce58397 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/hu.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Tacsipacsi" + ] + }, + "apihelp-wbcheckconstraints-description": "Kikötések ellenőrzése egy megadott entitáson, és az eredmények visszaadása.", + "apihelp-wbcheckconstraints-summary": "Kikötések ellenőrzése egy megadott entitáson, és az eredmények visszaadása.", + "apihelp-wbcheckconstraints-param-id": "A lekérdezendő entitások azonosítóinak listája.", + "apihelp-wbcheckconstraints-param-constraintid": "Opcionális szűrő, csak a megadott kikötésazonosítóval rendelkező kikötések visszaadása.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Az állítás megfelel a kikötésnek.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Az állítás megszegi a kikötést.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Az állítás tárgya ismert kivétel a kikötés alól.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "A kikötés nincs megvalósítva.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "A kikötés paraméterei hibásak.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "A kikötés nincs ellenőrizve, mert az állítás elavult.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Az állítás megszegi a kikötést, de a kikötés nem kötelező.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Az állítás megszegi a kikötést, de a kikötés csak egy javaslat.", + "apihelp-wbcheckconstraintparameters-summary": "A kikötésállítások paramétereinek ellenőrzése.", + "apihelp-wbcheckconstraintparameters-extended-description": "A property és constraintid paraméterek közül akár bármelyik, akár mindkettő megadható; ha mindkettő meg van adva, akkor a kettő uniója lesz ellenőrizve.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Az ellenőrizendő tulajdonságok azonosítói. A tulajdonságok összes kikötésállítása ellenőrizve lesz.\n\nHa meg van adva a paraméter, akkor nem lehet üres.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Az ellenőrizendő kikötések azonosítói (kikötésállítások GUID-i).\n\nHa meg van adva a paraméter, akkor nem lehet üres.", + "apihelp-wbcheckconstraints-example-1": "Az összes állítás ellenőrzése a Q5 és Q42 elemeken.", + "apihelp-wbcheckconstraints-example-2": "Összes kikötés ellenőrzése egyetlen állításon.", + "apihelp-wbcheckconstraints-example-3": "Egy adott kikötés ellenőrzése a Q2 elemen.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "A kikötésparaméterek ellenőrzése egy tulajdonság összes kikötésén.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "A kikötésparaméterek ellenőrzése két adott kikötésen." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/ia.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/ia.json new file mode 100644 index 000000000..da0929737 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/ia.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "apihelp-wbcheckconstraints-description": "Executa verificationes de restrictiones sur qualcunque entitate que tu vole e restitue le resultato.", + "apihelp-wbcheckconstraints-summary": "Executa verificationes de restrictiones sur qualcunque entitate que tu vole e restitue le resultato.", + "apihelp-wbcheckconstraints-param-id": "Lista de IDs del entitates pro le quales obtener datos. Separa valores con '|' o alternative.", + "apihelp-wbcheckconstraints-param-claimid": "Lista de GUIDs identificante un assertion pro verificar un reporto de restrictiones. Separa valores con '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Filtro optional pro restituer solmente le restrictiones que ha le ID de restriction specificate.", + "apihelp-wbcheckconstraints-param-status": "Filtro optional pro restituer solmente resultatos de verificationes con le statos seligite.\n\nNota que solmente resultatos pro le statos 'violation', 'warning', 'suggestion' e 'bad-parameters' es immagazinate in cache, de modo que requestas que selige qualcunque statos ultra iste quatro non beneficia del cache.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Le declaration satisface le restriction.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Le declaration viola le restriction.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Le entitate de subjecto del declaration es un exception cognoscite al restriction.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Le restriction non es implementate.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Le parametros del restriction es defectuose.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Le restriction non ha essite verificate perque le declaration es obsolescente.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Le declaration viola le restriction, ma le restriction non es obligatori.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Le declaration viola le restriction, ma le restriction solo es un suggestion.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Le restriction non es verificate sur iste typo de snak (snak principal, qualificator o referentia), dunque le controlo del restriction es saltate.", + "apihelp-wbcheckconstraintparameters-summary": "Verifica le parametros de restriction de declarationes de restriction.", + "apihelp-wbcheckconstraintparameters-extended-description": "Un o le duo del parametros property e constraintid pote esser specificate; tote le restrictiones seligite per cata parametro essera verificate.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Lista de identificatores de proprietate a verificar. Tote le declarationes de restriction de iste proprietates essera verificate.\n\nSi iste parametro es specificate, illo debe esser non vacue.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Lista de identificatores de restriction (GUIDs de declaration de restriction) a verificar.\n\nSi iste parametro es specificate, illo debe esser non vacue.", + "apihelp-wbcheckconstraints-example-1": "Verificar tote le restrictiones sur le elementos Q5 e Q42.", + "apihelp-wbcheckconstraints-example-2": "Verificar tote le restrictiones sur un singule declaration.", + "apihelp-wbcheckconstraints-example-3": "Verificar un restriction particular sur le elemento Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Verifica le parametros de restriction de tote le restrictiones sur un proprietate.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Verificar le parametros de restriction de duo restrictiones particular." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/id.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/id.json new file mode 100644 index 000000000..1dca921e1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/id.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Daud I.F. Argana" + ] + }, + "apihelp-wbcheckconstraints-description": "Melakukan pemeriksaan pewatas di entitas apa pun yang Anda inginkan dan mengembalikan hasilnya.", + "apihelp-wbcheckconstraints-summary": "Melakukan pemeriksaan pewatas di entitas apa pun yang Anda inginkan dan mengembalikan hasilnya.", + "apihelp-wbcheckconstraints-param-id": "Daftar ID dari entitas-entitas yang Anda ambil datanya. Pisahkan nilai-nilai dengan '|' atau cara lain.", + "apihelp-wbcheckconstraints-param-constraintid": "Penyaring opsional agar hanya mengembalikan pewatas yang memiliki ID pewatas yang ditentukan.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Pernyataan ini memenuhi pewatas.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Pernyataan ini melanggar pewatas.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Entitas subjek dari pernyataan diketahui merupakan pengecualian dari pewatas.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Pewatas ini tidak diimplementasikan.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Parameter pewatas rusak.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Pewatas belum diperiksa karena pernyataannya sudah usang.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Pernyataan ini melanggar pewatas, tetapi pewatasnya tidak bersifat wajib.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Pernyataan ini melanggar pewatas, tetapi pewatasnya hanya merupakan saran.", + "apihelp-wbcheckconstraintparameters-summary": "Memeriksa parameter pewatas dari pernyataan pewatas.", + "apihelp-wbcheckconstraintparameters-extended-description": "Salah satu dari parameter property dan constraintid atau keduanya boleh ditentukan; semua pewatas yang dipilih oleh parameter tersebut akan diperiksa.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Daftar ID atribut yang akan diperiksa. Semua pernyataan pewatas dari atribut ini akan diperiksa.\n\nJika parameter ini ditentukan, isinya tidak boleh kosong.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Daftar ID pewatas (GUID pernyataan pewatas) yang ingin diperiksa.\n\nJika parameter ini ditentukan, isinya tidak boleh kosong.", + "apihelp-wbcheckconstraints-example-1": "Memeriksa semua pewatas di butir Q5 dan Q42.", + "apihelp-wbcheckconstraints-example-2": "Memeriksa semua pewatas di satu pernyataan.", + "apihelp-wbcheckconstraints-example-3": "Memeriksa satu pewatas tertentu di butir Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Memeriksa parameter pewatas di semua pewatas di suatu atribut.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Memeriksa parameter pewatas dari dua pewatas tertentu." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/it.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/it.json new file mode 100644 index 000000000..0e0767aa2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/it.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Beta16" + ] + }, + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "La dichiarazione soddisfa il vincolo.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "La dichiarazione viola il vincolo.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Il soggetto dell'entità della dichiarazione è un'eccezione nota al vincolo.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Il vincolo non è implementato.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Il vincolo non è stato controllato perché la dichiarazione è deprecata.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "La dichiarazione viola il vincolo, ma il vincolo non è obbligatorio.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Il vincolo non viene controllato su questo tipo di snak (snak principale, qualificatore o riferimento), quindi il controllo dei vincoli viene saltato." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/kab.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/kab.json new file mode 100644 index 000000000..eb68289bb --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/kab.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Belkacem77" + ] + }, + "apihelp-wbcheckconstraintparameters-param-propertyid": "Ma yettwammel usebdad-agi, ur yessef ara ad yili d ilem." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/ko.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/ko.json new file mode 100644 index 000000000..d41af269d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/ko.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Ykhwong" + ] + }, + "apihelp-wbcheckconstraints-param-status": "선택된 상태의 결과만 반환하기 위한 선택적 필터입니다.\n\n'위반', '경고', '잘못된 변수' 상태의 결과만 캐시 처리되므로 이 세 가지를 벗어나는 상태를 선택한 요청은 캐시로 이득을 보지 않습니다.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "이 문은 제약 조건을 충족합니다.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "이 제약 조건은 구현되지 않았습니다.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "제약 조건의 변수가 깨져 있습니다.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "이 문은 제약 조건을 위반하지만 이 제약 조건은 필수가 아닙니다.", + "apihelp-wbcheckconstraints-example-1": "Q5, Q42 항목의 모든 제약 조건을 검사합니다.", + "apihelp-wbcheckconstraints-example-2": "하나의 문에 대한 모든 제약 조건을 검사합니다." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/lb.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/lb.json new file mode 100644 index 000000000..633a6fcb7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/lb.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Robby" + ] + }, + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "D'Ausso respektéiert d'Limitatioun.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "D'Ausso respektéiert d'Limitatioun net.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "D'Limitatioun ass net implementéiert.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "D'Parameter vun der Limitatioun si falsch.", + "apihelp-wbcheckconstraints-example-2": "Kuckt all Limitatiounen op enger eenzeler Ausso no." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/mk.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/mk.json new file mode 100644 index 000000000..a8fde9fe8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/mk.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06" + ] + }, + "apihelp-wbcheckconstraints-description": "Проверува услови за било која единица и дава исход.", + "apihelp-wbcheckconstraints-summary": "Проверува услови за било која единица и дава исход.", + "apihelp-wbcheckconstraints-param-id": "Назнака на единиците за кои ги барате податоците. Одделете ги вредностите со права црта (|) или нешто друго.", + "apihelp-wbcheckconstraints-param-claimid": "GUID-список што пронаоѓа тврдење за проверка на извод од услови. Одделете ги вредностите со права црта (|).", + "apihelp-wbcheckconstraints-param-constraintid": "Филтер (по избор) што ги дава само условите со укажаната назнака.", + "apihelp-wbcheckconstraints-param-status": "Незадолжителен филтер за исход од проверка само со избраните состојби.\n\nИмајте на ум дека се меѓускладираат само исходите од состојбите „violation“, „warning“, „suggestion“ и „bad-parameters“, така што полза од меѓускладирање нема да имаат барањата што бираат состојби вон тие четири.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Исказот го задоволува условот.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Исказот го нарушува условот.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Предметната единица на исказот е познат исклучок од условот.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Условот не е спроведен.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Нарушени се условните параметри.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Условот не е проверен бидејќи исказот е застарен.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Исказот го нарушува условот, но условот не е задолжителен.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Исказот го нарушува условот, но условот е само предлог.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Условот не е проверен за ваква спојница (главна, определница или навод), и затоа проверката е изоставена.", + "apihelp-wbcheckconstraintparameters-summary": "Ги проверува условните параметри на условни искази.", + "apihelp-wbcheckconstraintparameters-extended-description": "Треба да е укажан параметарот property или constraintid или обете; ќе бидат проверени сите услови избрани по еден од параметрите.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Список на назнаки за својства за проерка. Ќе се проверат сите условни искази на тие својства.\n\nАко овој параметар е укажан, мора да не биде празен.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Список на условни назнаки (GUID на условни искази) за проверка.\n\nАко овој параметар е укажан, мора да не биде празен.", + "apihelp-wbcheckconstraints-example-1": "Провери ги сите услови за предметите Q5 и Q42.", + "apihelp-wbcheckconstraints-example-2": "Провери ги сите услови за еден исказ.", + "apihelp-wbcheckconstraints-example-3": "Провери извесен услов за предметот Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Провери условни параметри за сите услови за својството.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Провери ги условните параметри за два услова." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/nb.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/nb.json new file mode 100644 index 000000000..212407e94 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/nb.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Jon Harald Søby" + ] + }, + "apihelp-wbcheckconstraints-description": "Utfører begrensningssjekk på de entitetene du ønsker og returnerer resultatet.", + "apihelp-wbcheckconstraints-summary": "Utfører begrensningssjekk på de entitetene du ønsker og returnerer resultatet.", + "apihelp-wbcheckconstraints-param-id": "ID-liste over entiteter du ønsker å hente data fra. Atskill verdier med «|» eller alternativer.", + "apihelp-wbcheckconstraints-param-claimid": "GUID-liste som identifiserer en påstand for å sjekke en begrensningsrapport. Atskill verdier med «|».", + "apihelp-wbcheckconstraints-param-constraintid": "Valgfritt filter for å returnere bare begrensningene som har den gitte begrensnings-ID-en.", + "apihelp-wbcheckconstraints-param-status": "Valgfritt filter for kun å sjekke resultater med de valgte statusene.\n\nMerk at kun resultater for statusene «violation», «warning», «suggestion» og «bad-parameters» mellomlagres, så forespørsler som velger andre statuser drar ikke nytte av mellomlagringen.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Påstanden oppfyller begrensningen.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Påstanden bryter med begrensningen.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Subjektentiteten til påstanden er et kjent unntak fra begrensningen.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Begrensningen er ikke implementert.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Begrensningsparameterne er ødelagte.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Begrensningen har ikke blitt sjekket fordi påstanden er foreldet.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Påstanden bryter med begrensningen, men begrensningen er ikke obligatorisk.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Påstanden bryter med begrensningen, men begrensningen er bare et forslag.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Påstanden sjekkes ikke for denne snaktypen (hovedsnak, kvalifikator eller referanse), så begrensningssjekken hoppes over.", + "apihelp-wbcheckconstraintparameters-summary": "Sjekker begrensningsparametre for begrensningspåstander.", + "apihelp-wbcheckconstraintparameters-extended-description": "Én eller begge av parameterne property og constraintid må angis; alle begrensninger valgt av én av parameterne blir sjekket.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Liste over egenskaps-ID-er som skal sjekkes. Alle begrensningspåstander for disse egenskapene blir sjekket.\n\nHvis denne parameteren er angitt må den ikke være tom.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Liste over begrensnings-ID-er (begrensningspåstands-GUID-er) som skal sjekkes.\n\nHvis denne parameteren er angitt må den ikke være tom.", + "apihelp-wbcheckconstraints-example-1": "Sjekk alle begrensninger for elementene Q5 og Q42.", + "apihelp-wbcheckconstraints-example-2": "Sjekk alle begrensninger for én enkel påstand.", + "apihelp-wbcheckconstraints-example-3": "Sjekk én bestemt begrensning på elementet Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Sjekk begrensningsparametre for alle begrensninger i en egenskap.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Sjekk begrensningsparametre for to bestemte begrensninger." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/nl.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/nl.json new file mode 100644 index 000000000..721c67896 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/nl.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "Mainframe98", + "Sjoerddebruin", + "McDutchie" + ] + }, + "apihelp-wbcheckconstraints-description": "Voert een beperkingen controle uit op de gewenste entiteit en toont het resultaat.", + "apihelp-wbcheckconstraints-summary": "Voert een beperkingencontrole uit op de gewenste entiteit en retourneert het resultaat.", + "apihelp-wbcheckconstraints-param-id": "ID-lijst van de entiteiten waaruit de gegevens moeten worden opgehaald. Scheid waarden met ‘|’ of een alternatief.", + "apihelp-wbcheckconstraints-param-claimid": "GUID-lijst die een verklaring identificeert om een beperkingsrapport te controleren. Scheid waarden met ‘|’.", + "apihelp-wbcheckconstraints-param-constraintid": "Optioneel filter om alleen de beperkingen te retourneren die de opgegeven beperkings-ID hebben.", + "apihelp-wbcheckconstraints-param-status": "Optioneel filter om alleen controleresultaten met de geselecteerde statussen te retourneren.\n\nHoud er rekening mee dat alleen resultaten voor de statussen ‘violation’, ‘warning’, ‘suggestion’ en ‘bad-parameters’ in de cache worden opgeslagen. Aanvragen die een status buiten deze vier selecteren, worden niet in de cache geplaatst.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "De verklaring voldoet aan de beperking.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "De verklaring is in strijd met de beperking.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "De onderwerpentiteit van de verklaring is een bekende uitzondering op de beperking.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "De beperking is niet geïmplementeerd.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "De beperkingsparameters zijn onjuist.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "De beperking is niet gecontroleerd omdat de verklaring verouderd is.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "De verklaring is in strijd met de beperking, maar de beperking is niet verplicht.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "De verklaring is in strijd met de beperking, maar de beperking is slechts een suggestie.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "De beperking wordt niet gecontroleerd op dit soort snak (hoofdsnak, kwalificatie of referentie), dus de controle op de beperking wordt overgeslagen.", + "apihelp-wbcheckconstraintparameters-summary": "Controleert de beperkingsparameters van beperkingsverklaringen.", + "apihelp-wbcheckconstraintparameters-extended-description": "Van de parameters property en constraintid mag één of mogen beide worden opgegeven. Alle door één van beide parameters geselecteerde beperkingen worden gecontroleerd.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Lijst met te controleren eigenschaps-ID’s. Alle beperkingsverklaringen van deze eigenschappen worden gecontroleerd.\n\nEenmaal opgegeven mag deze parameter niet leeg zijn.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Lijst met te controleren beperkings-ID’s (GUID’s van beperkingsverklaringen).\n\nEenmaal opgegeven mag deze parameter niet leeg zijn.", + "apihelp-wbcheckconstraints-example-1": "Alle beperkingen voor de items Q5 en Q42 controleren.", + "apihelp-wbcheckconstraints-example-2": "Alle beperkingen voor een losse verklaring controleren.", + "apihelp-wbcheckconstraints-example-3": "Controleer één specifieke beperking op item Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Controleer de beperkingsparameters van alle op een eigenschap van toepassing zijnde beperkingen.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Controleer de beperkingsparameters van twee specifieke beperkingen." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/pt-br.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/pt-br.json new file mode 100644 index 000000000..710b49da1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/pt-br.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "Eduardo Addad de Oliveira", + "Eduardoaddad", + "Felipe L. Ewald" + ] + }, + "apihelp-wbcheckconstraints-description": "Executa verificações de restrição em qualquer entidade que deseja e retorna o resultado.", + "apihelp-wbcheckconstraints-summary": "Executa verificações de restrição em qualquer entidade que deseja e retorna o resultado.", + "apihelp-wbcheckconstraints-param-id": "Lista de ID das entidades para obter os dados. Separar valores com '|' ou alternativa.", + "apihelp-wbcheckconstraints-param-claimid": "Uma lista GUID identificando uma reivindicação para verificar um relatório de restrição. Separar valores com '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Filtro opcional para devolver só as restrições que têm o identificador de restrição especificado.", + "apihelp-wbcheckconstraints-param-status": "Filtro opcional para devolver só resultados com os estados selecionados.\n\nNote que só são armazenados na cache os resultados para os estados 'violation' (violação), 'warning' (aviso) e 'bad-parameters' (parâmetros incorretos), por isso os pedidos que selecionarem outros estados além destes três não beneficiam do armazenamento na cache.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "A declaração satisfaz a restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "A declaração viola a restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "A entidade da declaração é uma exceção conhecida à restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "A restrição não está implementada.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Os parâmetros da restrição estão incorretos.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "A restrição não foi verificada porque a declaração foi descontinuada.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "A declaração viola a restrição, mas a restrição não é obrigatória.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "A declaração viola a restrição, mas a restrição é apenas uma sugestão.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "A restrição não é verificada neste tipo de asserção (asserção principal, qualificador ou referência) portanto a verificação da restrição é omitida.", + "apihelp-wbcheckconstraintparameters-summary": "Verifica os parâmetros de restrição das instruções de restrição.", + "apihelp-wbcheckconstraintparameters-extended-description": "Podem ser especificados os dois parâmetros property e constraintid; Todas as restrições selecionadas por qualquer dos parâmetros serão verificadas.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Lista de IDs de propriedade para verificar. Todas as instruções de restrição dessas propriedades serão verificadas.\n\nSe este parâmetro for especificado, ele não deve ser vazio.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Lista de IDs de restrição (declaração de restrição GUIDs) para verificar.\n\nSe esse parâmetro for especificado, ele não deve ser vazio.", + "apihelp-wbcheckconstraints-example-1": "Verifique todas as restrições sobre os itens Q5 e Q42.", + "apihelp-wbcheckconstraints-example-2": "Verifique todas as restrições em uma única declaração.", + "apihelp-wbcheckconstraints-example-3": "Verifique uma restrição particular no item Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Verifique os parâmetros de restrição de todas as restrições em uma propriedade.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Verifique os parâmetros de restrição de duas restrições específicas." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/pt.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/pt.json new file mode 100644 index 000000000..e9feb3818 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/pt.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Athena in Wonderland", + "Hamilton Abreu" + ] + }, + "apihelp-wbcheckconstraints-description": "Realiza a verificação das restrições de qualquer entidade que queira e devolve o resultado.", + "apihelp-wbcheckconstraints-summary": "Realiza a verificação das restrições de qualquer entidade que queira e devolve o resultado.", + "apihelp-wbcheckconstraints-param-id": "Lista de identificadores das entidades de que serão obtidos os dados. Separar os valores com '|' ou alternativa.", + "apihelp-wbcheckconstraints-param-claimid": "Lista de identificadores únicos globais (GUID) que identificam uma alegação para verificar um relatório de restrições. Separar os valores com '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Filtro opcional para devolver só as restrições que têm o identificador de restrição especificado.", + "apihelp-wbcheckconstraints-param-status": "Filtro opcional para devolver só resultados com os estados selecionados.\n\nNote que só são armazenados na cache os resultados para os estados 'violation' (violação), 'warning' (aviso), 'suggestion' (sugestão) e 'bad-parameters' (parâmetros incorretos), por isso os pedidos que selecionarem outros estados além destes não beneficiam do armazenamento na cache.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "A declaração satisfaz a restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "A declaração viola a restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "A entidade da declaração é uma exceção conhecida à restrição.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "A restrição não está implementada.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Os parâmetros da restrição estão incorretos.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "A restrição não foi verificada porque a declaração foi descontinuada.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "A declaração viola a restrição, mas a restrição não é obrigatória.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "A declaração viola a restrição, mas a restrição é só uma sugestão.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "A restrição não é verificada neste tipo de asserção (asserção principal, qualificador ou referência) portanto a verificação da restrição é omitida.", + "apihelp-wbcheckconstraintparameters-summary": "Verifica os parâmetros de restrição das declarações de restrições.", + "apihelp-wbcheckconstraintparameters-extended-description": "Pode ser especificado qualquer, ou ambos, os parâmetros property e constraintid; serão verificadas todas as restrições selecionadas por qualquer dos parâmetros.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Lista dos identificadores de propriedades a serem verificados. Serão verificadas todas as declarações de restrições destas propriedades.\n\nSe este parâmetro for especificado, não pode estar vazio.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Lista dos identificadores de restrições (identificadores únicos globais (GUID) de declarações de restrições) a serem verificados.\n\nSe este parâmetro for especificado, não pode estar vazio.", + "apihelp-wbcheckconstraints-example-1": "Verificar todas as restrições sobre os objetos Q5 e Q42.", + "apihelp-wbcheckconstraints-example-2": "Verificar todas as restrições sobre uma só declaração.", + "apihelp-wbcheckconstraints-example-3": "Verificar uma restrição em particular sobre o objeto Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Verificar os parâmetros de restrição de todas as restrições de uma propriedade.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Verificar os parâmetros de restrição de duas restrições em particular." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/qqq.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/qqq.json new file mode 100644 index 000000000..85bd07967 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/qqq.json @@ -0,0 +1,39 @@ +{ + "@metadata": { + "authors": [ + "Abián", + "Alifakoor", + "Amire80", + "Liuxinyu970226", + "Lucas Werkmeister (WMDE)", + "Metalhead64", + "Raymond", + "Robby", + "Verdy p" + ] + }, + "apihelp-wbcheckconstraints-description": "{{Doc-apihelp-description|wbcheckconstraints}}", + "apihelp-wbcheckconstraints-summary": "{{Doc-apihelp-summary|wbcheckconstraints}}", + "apihelp-wbcheckconstraints-param-id": "{{Doc-apihelp-param|wbcheckconstraints|id}}", + "apihelp-wbcheckconstraints-param-claimid": "{{Doc-apihelp-param|wbcheckconstraints|claimid}}", + "apihelp-wbcheckconstraints-param-constraintid": "{{Doc-apihelp-param|wbcheckconstraints|constraintid}}", + "apihelp-wbcheckconstraints-param-status": "{{Doc-apihelp-param|wbcheckconstraints|status}}", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|compliance}}", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|violation}}", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|exception}}", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|todo}}", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|bad-parameters}}", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|deprecated}}", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|warning}}", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|suggestion}}", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "{{Doc-apihelp-paramvalue|wbcheckconstraints|status|not-in-scope}}", + "apihelp-wbcheckconstraintparameters-summary": "{{Doc-apihelp-summary|wbcheckconstraintparameters}}", + "apihelp-wbcheckconstraintparameters-extended-description": "{{Doc-apihelp-extended-description|wbcheckconstraintparameters}}", + "apihelp-wbcheckconstraintparameters-param-propertyid": "{{Doc-apihelp-param|wbcheckconstraintparameters|propertyid}}", + "apihelp-wbcheckconstraintparameters-param-constraintid": "{{Doc-apihelp-param|wbcheckconstraintparameters|constraintid}}", + "apihelp-wbcheckconstraints-example-1": "{{Doc-apihelp-example|wbcheckconstraints}}", + "apihelp-wbcheckconstraints-example-2": "{{Doc-apihelp-example|wbcheckconstraints}}", + "apihelp-wbcheckconstraints-example-3": "{{Doc-apihelp-example|wbcheckconstraints}}", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "{{Doc-apihelp-example|wbcheckconstraintparameters}}", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "{{Doc-apihelp-example|wbcheckconstraintparameters}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/roa-tara.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/roa-tara.json new file mode 100644 index 000000000..3dbbd3b98 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/roa-tara.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "apihelp-wbcheckconstraints-description": "Face le condrolle de vingole sus a tutte le endità ca vuè ccu tuèrne jndr'à 'u resultate.", + "apihelp-wbcheckconstraints-summary": "Face le condrolle de vingole sus a tutte le endità ca vuè ccu tuèrne jndr'à 'u resultate.", + "apihelp-wbcheckconstraints-param-id": "ID de l'elenghe de l'endità da addò pigghià le date. Valore separate cu '|' o 'n'otre simbole.", + "apihelp-wbcheckconstraints-param-claimid": "L'elenghe de GUID idendifichescene 'na richieste da condrollà jndr'à 'nu reipiloghe de vingole. Valore separate cu '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Filtre opzionale torne sulamende le vingole ca onne l'ID d'u vingole specificate.", + "apihelp-wbcheckconstraints-param-status": "'U filtre opzionale torne sulamende le resultate condrollate de le state scacchiate.\n\nNote ca sulamende le resultate pe le state 'violation', 'warning', 'suggestion' e 'bad-parameters' avènene memorizzate, accussì le richieste ca scacchie ogne state rrete a chiste e quattre non ge onne 'u benefice d'a cache.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "'A dichiarazione soddisfe 'u vingole.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "'A dichiarazione viole 'u vingole.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "L'endità oggette d'a dichiarazzione jè 'n'eccezzione canusciute a 'u vingole.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "'U vingole non g'è 'mblemendate.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Le parametre d'u vingole so scuasciate.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "'U vingole non g'ha state condrollate purcé 'a dichiarazione jè sconzigliate.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "'A dichiarazzione viole 'u vingole, ma 'u vingole non g'è obbligatorije.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "'A dichiarazzione viole 'u vingole, ma 'u vingole jè sulamende 'nu suggerimende.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "'U vingole non g'è condrollate sus a stu tipe de snak (snak prengepàle, qualificatore o referimende), accussì 'u condrolle d'u vingole jè zumbate.", + "apihelp-wbcheckconstraintparameters-summary": "Condrolle le parametre d'u vingole de le dichiaraziune d'u vingole.", + "apihelp-wbcheckconstraintparameters-extended-description": "Tutte e doje le parametre property e constraintid ponne essere specificate; tutte le vingole scacchiate da tutte e doje le parametre avènene condrollate.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Elenghe de le ID de le probbietà da condrollà. Tutte le dichiarazziune de le vingole de ste probbietà avènene condrollate.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Elenghe de le ID de le vingole (dichiarazzione d'a GUI d'u vingole) da condrollà.\n\nCe stu parametre jè specificate, non g'adda essere vacande.", + "apihelp-wbcheckconstraints-example-1": "Condrolle tutte le vingole sus a le vôsce Q5 e Q42.", + "apihelp-wbcheckconstraints-example-2": "Condrolle tutte le vingole sus a 'na dichiarazione singole.", + "apihelp-wbcheckconstraints-example-3": "Condrolle 'nu vingole particolare sus a 'a vôsce Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Condrolle le parametre d'u vingole de tutte le vingole de 'na probbietà.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Condrolle le parametre de 'nu vingole de doje vingole particulare." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/ru.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/ru.json new file mode 100644 index 000000000..e3b77e0e9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/ru.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "DDPAT", + "Ice bulldog", + "Kaganer", + "Movses" + ] + }, + "apihelp-wbcheckconstraints-param-status": "Дополнительный фильтр для возврата результатов проверки только с выбранными состояниями.\n\nОбратите внимание: кешируются только результаты для статусов «нарушение», «предупреждение», «предположение» и «плохие параметры». Все остальные статусы — не кешируются.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Утверждение удовлетворяет ограничению.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Утверждение нарушает ограничение." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/sl.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/sl.json new file mode 100644 index 000000000..43e8c5b72 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/sl.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Janezdrilc", + "Eleassar" + ] + }, + "apihelp-wbcheckconstraints-description": "Izvede preverjanje omejitev katerekoli želene stvari in izpiše rezultat.", + "apihelp-wbcheckconstraints-summary": "Izvede preverjanje omejitev katerekoli želene stvari in izpiše rezultat.", + "apihelp-wbcheckconstraints-param-id": "Seznam ID-jev entitet, katerih podatki naj se pridobijo. Vrednosti ločite z »|« ali podobnim.", + "apihelp-wbcheckconstraints-param-claimid": "Seznam GUID, ki identificira zahtevek za preverjanje poročila o omejitvah. Vrednosti ločite z »|«.", + "apihelp-wbcheckconstraints-param-constraintid": "Izbirni filter za vrnitev samo tistih omejitev, ki imajo določen ID omejitve.", + "apihelp-wbcheckconstraints-param-status": "Izbirni filter za vrnitev samo zadetkov preverjanja z izbranimi statusi.\n\nUpoštevajte, da so predpomnjeni samo zadetki za stanja »violation«, »warning«, »suggestion« in »bad-parameters«, zato zahtevki, ki izberejo katera koli stanja, ki presegajo ta štiri, nso podprti s predpomnjenjem.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Izjava je v skladu z omejitvijo.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Ta izjava krši omejitev.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Entiteta teme izjave je znana izjema od te omejitve.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Omejitev ni sprogramirana.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Parametri omejitve so pokvarjeni.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Omejitev ni bila preverjena, ker je izjava opuščena.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Ta izjava krši omejitev, ki sicer ni obvezna.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Izjava ne upošteva omejitve, čeprav slednja velja zgolj kot predlog.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Omejitev se pri tej vrsti določila (glavno določilo, kvalifikator ali sklic) ne preveri, zato se preverjanje omejitve preskoči.", + "apihelp-wbcheckconstraintparameters-summary": "Preveri parametre v izjavah omejitev.", + "apihelp-wbcheckconstraintparameters-extended-description": "Določiti je mogoče enega ali oba parametra property in parametra contraintid; preverjene bodo vse omejitve, izbrane s katerim koli parametrom.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Seznam ID-jev lastnosti, ki jih je treba preveriti. Preverjene bodo vse izjave o omejitvah teh lastnosti.\n\nČe je ta parameter predložen, ne sme biti prazen.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Seznam ID-jev omejitev (GUID-jev omejitvenih izjav), ki jih je treba preveriti.\n\nČe je ta parameter predložen, ne sme biti prazen.", + "apihelp-wbcheckconstraints-example-1": "Preveri vse omejitve objektov Q5 in Q42.", + "apihelp-wbcheckconstraints-example-2": "Preveri vse omejitve ene izjave.", + "apihelp-wbcheckconstraints-example-3": "Preveri določeno omejitev objekta Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Preveri parametre vseh omejitev pri lastnosti.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Preveri parametre dveh določenih omejitev." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-ec.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-ec.json new file mode 100644 index 000000000..1f4a39b79 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-ec.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "BadDog", + "Obsuser", + "Zoranzoki21", + "Милан Јелисавчић", + "Zenfiric" + ] + }, + "apihelp-wbcheckconstraints-description": "Извођење провера забране на ентитету који одаберете и враћање резултата.", + "apihelp-wbcheckconstraints-param-id": "ID списак ентитета из којих ће се узимати подаци. Раздвојити вредности са '|' или др.", + "apihelp-wbcheckconstraints-param-claimid": "GUID списак за идентификацију тврдње за проверу извештаја забране. Раздвојити вредности са '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Изборни филтер за враћање само ограничења која имају одређени ID ограничења.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Изјава задовољава ограничење.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Изјава крши ограничење.", + "apihelp-wbcheckconstraintparameters-extended-description": "Могуће је навести било који или оба property и constraintid; сва одабрана ограничења по било ком параметру биће проверена.", + "apihelp-wbcheckconstraints-example-1": "Проверите сва ограничења за ставке Q5 и Q42.", + "apihelp-wbcheckconstraints-example-2": "Проверите сва ограничења за једну изјаву.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Проверите параметре ограничења свих ограничења својства.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Проверите ограничења параметара два посебна ограничења." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-el.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-el.json new file mode 100644 index 000000000..32780a875 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/sr-el.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [] + }, + "apihelp-wbcheckconstraints-description": "Izvođenje provera zabrane na entitetu koji odaberete i vraćanje rezultata.", + "apihelp-wbcheckconstraints-param-id": "ID spisak entiteta iz kojih će se uzimati podaci. Razdvojiti vrednosti sa '|' ili dr.", + "apihelp-wbcheckconstraints-param-claimid": "GUID spisak za identifikaciju tvrdnje za proveru izveštaja zabrane. Razdvojiti vrednosti sa '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Izborni filter za vraćanje samo ograničenja koja imaju određeni ID ograničenja.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Izjava zadovoljava ograničenje.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Izjava krši ograničenje.", + "apihelp-wbcheckconstraintparameters-extended-description": "Moguće je navesti bilo koji ili oba property i constraintid; sva odabrana ograničenja po bilo kom parametru biće proverena.", + "apihelp-wbcheckconstraints-example-1": "Proverite sva ograničenja za stavke Q5 i Q42.", + "apihelp-wbcheckconstraints-example-2": "Proverite sva ograničenja za jednu izjavu.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Proverite parametre ograničenja svih ograničenja svojstva.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Proverite ograničenja parametara dva posebna ograničenja." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/sv.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/sv.json new file mode 100644 index 000000000..8c71dca13 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/sv.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "Sabelöga", + "WikiPhoenix" + ] + }, + "apihelp-wbcheckconstraints-description": "Utför begränsningskontroller på alla entiteter du vill och returnerar resultatet.", + "apihelp-wbcheckconstraints-summary": "Utför begränsningskontroller på alla entiteter du vill och returnerar resultatet.", + "apihelp-wbcheckconstraints-param-id": "ID-lista över entiteterna att hämta data från. Separera värden med \"|\" eller alternativa.", + "apihelp-wbcheckconstraints-param-constraintid": "Valfritt filter för att endast returnera begränsningarna som har det angivna begränsnings-ID:et.", + "apihelp-wbcheckconstraints-param-status": "Valfritt filter för att endast returnera kontrollresultat med valda statusar.\n\nObservera att endast resultat för statusarna \"violation\", \"warning\", \"suggestion\" och \"bad-parameters\" cachelagras, så förfrågor som väljer statusar förutom dessa fyra drar inte nytta från cachelagringen.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Uttalet uppfyller begränsningen.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Uttalet bryter mot begränsningen.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Begränsningen är inte implementerad.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Begränsningens parametrar är trasiga.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Begränsningen har inte kontrollerats eftersom uttalandet är föråldrat.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Uttalandet bryter mot begränsningen, men begränsningen är inte nödvändig.", + "apihelp-wbcheckconstraintparameters-summary": "Kontrollerar begränsningsparametrarna för begränsningsuttalanden.", + "apihelp-wbcheckconstraints-example-1": "Kontrollera alla begränsningar på objekten Q5 och Q42.", + "apihelp-wbcheckconstraints-example-2": "Kontrollera alla begränsningar på ett enda uttal.", + "apihelp-wbcheckconstraints-example-3": "Kontrollera en specifik begränsning på objektet Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Kontrollera begränsningsparametrar för alla begränsningar på en egenskap.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Kontrollera begränsningsparametrar för två specifika begränsningar." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/tr.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/tr.json new file mode 100644 index 000000000..13eb36458 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/tr.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "BaRaN6161 TURK", + "Incelemeelemani", + "SaldırganSincap", + "Sezgin İbiş" + ] + }, + "apihelp-wbcheckconstraints-description": "İstediğiniz varlık üzerinde kısıtlama kontrollerini yapar ve sonucunu döndürür.", + "apihelp-wbcheckconstraints-summary": "İstediğiniz varlık üzerinde kısıtlama kontrollerini yapar ve sonucunu döndürür.", + "apihelp-wbcheckconstraints-param-id": "Verilerin alınacağı varlıkların kimlik listesi. Birden fazla varlık için '|' veya alternatifi değer kullanın.", + "apihelp-wbcheckconstraints-param-claimid": "Bir kısıtlama raporunu kontrol etme talebini tanımlayan GUID listesi. '|' ile değerleri ayırın.", + "apihelp-wbcheckconstraints-param-constraintid": "Yalnızca belirtilen kısıtlama kimliğine sahip kısıtlamaları döndürmek için isteğe bağlı filtre.", + "apihelp-wbcheckconstraints-param-status": "İsteğe bağlı filtre yalnızca sonuçları seçilen durumlarla kontrol etmek için döndürür.\n\nYalnızca 'violation', 'warning', 'suggestion' ve 'bad-parameters' durumları için sonuçların önbelleğe alındığını, dolayısıyla bu dördünün dışındaki durumları seçen isteklerin önbelleğe alma işleminden faydalanmadığını unutmayın.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Bu ifade kısıtlamayı yerine getirir.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Bu ifade kısıtlamayı ihlal ediyor.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "İfadenin özniteliği, kısıtlamanın bilinen bir istisnasıdır.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Kısıtlama uygulanmadı.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Kısıtlama parametreleri bozuldu.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "İfade onaylanmadığından kısıtlama kontrol edilmedi.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Bu ifade kısıtlamayı ihlal ediyor, ancak kısıtlama zorunlu değil.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Bu ifade kısıtlamayı ihlal ediyor, ancak kısıtlama sadece bir öneri.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Kısıtlama bu tür bir yılan üzerinde (ana yılan, niteleyici veya referans) kontrol edilmez, bu nedenle sınırlama kontrolü atlanır.", + "apihelp-wbcheckconstraintparameters-summary": "Kısıtlama ifadelerinin kısıtlama parametrelerini kontrol eder.", + "apihelp-wbcheckconstraintparameters-extended-description": "property ve constraintid parametrelerinin biri veya ikisi belirtilebilir; Her iki parametre tarafından seçilen tüm kısıtlamalar kontrol edilecektir.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Kontrol edilecek mülkiyet kimlikleri listesi. Bu özelliklerin tüm kısıtlama beyanları kontrol edilecektir.\n\nBu parametre belirtilmişse boş olmamalıdır.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Denetlenecek kısıtlama kimlikleri listesi (kısıtlama ifadesi GUID'leri).\n\nBu parametre belirtilmişse boş olmamalıdır.", + "apihelp-wbcheckconstraints-example-1": "Q5 ve Q42 maddeleri üzerindeki tüm kısıtlamaları kontrol edin.", + "apihelp-wbcheckconstraints-example-2": "Tüm kısıtlamaları tek bir açıklamada kontrol edin.", + "apihelp-wbcheckconstraints-example-3": "Q2 maddesindeki belirli bir kısıtlamayı kontrol edin.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Bir özellikteki tüm kısıtlamaların kısıtlama parametrelerini kontrol edin.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "İki belirli kısıtlamanın kısıtlama parametrelerini kontrol edin." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/uk.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/uk.json new file mode 100644 index 000000000..28d9f5ec9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/uk.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "DDPAT", + "Ice bulldog", + "Piramidion", + "Vlad5250" + ] + }, + "apihelp-wbcheckconstraints-description": "Виконує перевірки обмежень для будь-якої сутності за Вашим бажанням, і виводить результат.", + "apihelp-wbcheckconstraints-summary": "Виконує перевірки обмежень у будь-якій сутності за Вашим бажання, і виводить результат.", + "apihelp-wbcheckconstraints-param-id": "Список ідентифікаторів сутностей, з яких слід отримати дані. Відокремлюйте значення за допомогою '|' чи чогось подібного.", + "apihelp-wbcheckconstraints-param-claimid": "Список GUID, який визначає запис, щодо якого слід виконати перевірку й отримати звіт щодо обмежень. Відокремлюйте значення за допомогою '|'.", + "apihelp-wbcheckconstraints-param-constraintid": "Необов'язковий фільтр для повернення лише тих обмежень, які мають вказаний ідентифікатор обмеження.", + "apihelp-wbcheckconstraints-param-status": "Необов'язковий фільтр для повернення лише тих результатів перевірки, які мають вибрані статуси.\n\nЗверніть увагу, що кешуються лише результати зі статусами 'violation', 'warning', 'suggestion' і 'bad-parameters', тож запити, в яких вибрано якісь інші статуси окрім чотирьох наведених, не матимуть користі від кешування.", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "Твердження задовольняє обмеження.", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "Твердження порушує обмеження.", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "Суб'єктна сутність твердження є відомим винятком до обмеження.", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "Це обмеження не впроваджено.", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "Параметри обмеження зламані.", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "Обмеження не було перевірено, оскільки твердження є застарілим.", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "Твердження порушує обмеження, але це обмеження не є обов'язковим.", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "Твердження порушує обмеження, але це обмеження є лише пропозицією.", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "Обмеження не перевіряються на цьому типі подробиць (головна подробиця, уточнення або посилання на джерело), тож перевірку обмежень пропущено.", + "apihelp-wbcheckconstraintparameters-summary": "Перевіряє параметри тверджень обмежень.", + "apihelp-wbcheckconstraintparameters-extended-description": "Можна вказати обидва або один з параметрів property та constraintid; перевірені будуть усі обмеження, вибрані іншим параметром.", + "apihelp-wbcheckconstraintparameters-param-propertyid": "Список ідентифікаторів властивостей, які слід перевірити. Всі твердження обмежень цих властивостей буде перевірено.\n\nЯкщо цей параметр вказано, він не повинен бути порожнім.", + "apihelp-wbcheckconstraintparameters-param-constraintid": "Список ідентифікаторів обмежень (GUID тверджень обмежень), які слід перевірити.\n\nЯкщо цей параметр вказано, він не повинен бути порожнім.", + "apihelp-wbcheckconstraints-example-1": "Перевірити всі обмеження в елементах Q5 та Q42.", + "apihelp-wbcheckconstraints-example-2": "Перевірити всі обмеження в одному твердженні.", + "apihelp-wbcheckconstraints-example-3": "Перевірити одне конкретне обмеження в елементі Q2.", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "Перевірити параметри усіх обмежень у властивості.", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "Перевірити параметри двох конкретних обмежень." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hans.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hans.json new file mode 100644 index 000000000..a1f9413e9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hans.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "A Chinese Wikipedian", + "GuoPC", + "Liuxinyu970226", + "Shizhao" + ] + }, + "apihelp-wbcheckconstraints-description": "在任何您希望执行检查的实体上,执行约束检查并返回结果。", + "apihelp-wbcheckconstraints-summary": "在任何您希望执行的实体上执行约束检查,并返回结果。", + "apihelp-wbcheckconstraints-param-id": "要获取数据的实体ID列表。使用“|”或替代字符分隔值。", + "apihelp-wbcheckconstraints-param-claimid": "识别要检查约束报告的声明的GUID列表。使用“|”分隔值。", + "apihelp-wbcheckconstraints-param-constraintid": "可选的过滤器,只返回有指定约束ID的约束。", + "apihelp-wbcheckconstraints-param-status": "可选过滤器,只返回具有选定状态的检查结果。\n\n注意只有“violation”、“warning”、“suggestion”和“bad-parameters”状态的结果会被缓存,所以选择任何不属于这4种状态的请求都将不会得到缓存。", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "该陈述符合约束条件。", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "该陈述违反了约束限定值。", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "陈述的对象实体是约束的已知例外。", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "约束未实施。", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "约束参数损坏。", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "约束未检查,因为陈述已弃用。", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "陈述违反约束,但约束并非强制。", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "该陈述违反了约束,但约束只是一个建议。", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "约束未在此类型snak中检查(主snak、修饰符或参考文献),因此约束检查被跳过。", + "apihelp-wbcheckconstraintparameters-summary": "检查约束陈述的约束参数。", + "apihelp-wbcheckconstraintparameters-extended-description": "可指定propertyconstraintid参数中的任意一个,或二者皆可;两个参数选择的所有约束都将接受检查。", + "apihelp-wbcheckconstraintparameters-param-propertyid": "要检查的属性ID列表。这些属性的所有约束陈述都将接受检查。\n\n如果指定了该参数,它必须为非空值。", + "apihelp-wbcheckconstraintparameters-param-constraintid": "要检查的约束ID(约束声明GUID)列表。\n\n如果指定了该参数,它必须为非空值。", + "apihelp-wbcheckconstraints-example-1": "检查项目Q5和Q42的所有约束。", + "apihelp-wbcheckconstraints-example-2": "检查单个陈述上的所有约束。", + "apihelp-wbcheckconstraints-example-3": "在项目Q2上检查某个特定约束。", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "检查某一属性上所有约束的约束参数。", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "检查两个特定约束的约束参数。" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hant.json b/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hant.json new file mode 100644 index 000000000..213d0ab0c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/api/zh-hant.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Kly" + ] + }, + "apihelp-wbcheckconstraints-description": "在任何您所想要並回傳結果的實體上執行限制檢查。", + "apihelp-wbcheckconstraints-summary": "在任何您所想要並回傳結果的實體上執行限制檢查。", + "apihelp-wbcheckconstraints-param-id": "要取得資料的實體 ID 清單。以 '|' 或其它替代符號來分隔。", + "apihelp-wbcheckconstraints-param-claimid": "識別聲稱來檢查限制報告的 GUID 清單。請以 '|' 符號分隔。", + "apihelp-wbcheckconstraints-param-constraintid": "選用的篩選條件,只回傳含有指定限制 ID 的限制。", + "apihelp-wbcheckconstraints-param-status": "回傳的選用篩選,僅會檢查帶有已選狀態的結果。\n\n請注意僅有「violation」、「warning」、「suggestion」、「bad-parameters」狀態會被快取下來,因此選擇不在這四種狀態的請求並不會從快取裡獲得效益。", + "apihelp-wbcheckconstraints-paramvalue-status-compliance": "聲明符合限制。", + "apihelp-wbcheckconstraints-paramvalue-status-violation": "聲明違反限制。", + "apihelp-wbcheckconstraints-paramvalue-status-exception": "聲明的主題實體是對於限制的已知例外。", + "apihelp-wbcheckconstraints-paramvalue-status-todo": "限制未實行。", + "apihelp-wbcheckconstraints-paramvalue-status-bad-parameters": "限制參數損毀。", + "apihelp-wbcheckconstraints-paramvalue-status-deprecated": "因聲明已棄用,限制未被檢查。", + "apihelp-wbcheckconstraints-paramvalue-status-warning": "聲明違反限制,但限制並非強制要求。", + "apihelp-wbcheckconstraints-paramvalue-status-suggestion": "聲明違反限制,但該限制純為建議。", + "apihelp-wbcheckconstraints-paramvalue-status-not-in-scope": "限制未在此敘述(主要敘述、限定詞或參考文獻)裡被檢查,因此限制檢查會被跳過。", + "apihelp-wbcheckconstraintparameters-summary": "檢查限制聲明的限制參數。", + "apihelp-wbcheckconstraintparameters-extended-description": "可指定 propertyconstraintid 兩者參數其一或全部,將會檢查兩者任一參數所有已選的限制。", + "apihelp-wbcheckconstraintparameters-param-propertyid": "要檢查的屬性 ID 清單,將會檢查所有這些屬性的限制聲明。\n\n若指定了參數則不可為空。", + "apihelp-wbcheckconstraintparameters-param-constraintid": "要檢查的限制 ID(限制聲明 GUID)清單。\n\n若有指定參數則不可留空。", + "apihelp-wbcheckconstraints-example-1": "檢查在項目 Q5 與 Q42 上的所有限制。", + "apihelp-wbcheckconstraints-example-2": "檢查在單一聲明上的所有限制。", + "apihelp-wbcheckconstraints-example-3": "檢查在項目 Q2 上的某一特定限制。", + "apihelp-wbcheckconstraintparameters-example-propertyid-1": "檢查在屬性上所有限制的限制參數。", + "apihelp-wbcheckconstraintparameters-example-constraintid-2": "檢查兩個特定限制的限制參數。" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ar.json b/dist/extensions/WikibaseQualityConstraints/i18n/ar.json new file mode 100644 index 000000000..845b1c76c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ar.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "Azouz.anis", + "BAB ZAA", + "Meno25", + "Mr. Ibrahem", + "ديفيد", + "Michel Bakni" + ] + }, + "wbqc-constraintreport": "تقرير المحدد", + "wbqc-desc": "التحقق من المحددات على كل من العناصر والخواص وعرض النتائج في صفحة خاصة", + "wbqc-constraintreport-explanation-part-one": "هذه الصفحة الخاصة تقوم بتدقيق القيود المفروضة على الخواص المستخدمة في أي عنصر ويكي بيانات ترغب بفحصه، أي قيمة يتم إصلاحها سيتم إزالتها من القائمة فوراً.", + "wbqc-constraintreport-explanation-part-two": "يتم تحليل المحددات من البيانات على الخواص في كل مرة يتم تحرير هذه البيانات، وعادة يتم ذلك في غضون بضع دقائق.", + "wbqc-constraintreport-form-section": "تحقق من قيود عنصر", + "wbqc-constraintreport-form-submit-label": "فحص", + "wbqc-constraintreport-form-entityid-label": "معرف العنصر:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx أو Pxx", + "wbqc-constraintreport-result-headline": "النتيجة لـ", + "wbqc-constraintreport-invalid-entity-id": "معرف الكيان غير صالح.", + "wbqc-constraintreport-not-existent-entity": "الكيان غير موجود.", + "wbqc-constraintreport-empty-result": "لا توجد قيود محددة على هذا الكيان.", + "wbqc-constraintreport-status-violation": "مخالف", + "wbqc-constraintreport-status-compliance": "مطابق", + "wbqc-constraintreport-status-exception": "استثناء", + "wbqc-constraintreport-status-todo": "بحاجة للعمل", + "wbqc-constraintreport-status-bad-parameters": "معلمات سيئة", + "wbqc-constraintreport-status-deprecated": "مستغنى عنه", + "wbqc-constraintreport-status-warning": "تحذير", + "wbqc-constraintreport-status-suggestion": "اقتراح", + "wbqc-constraintreport-status-not-in-scope": "ليس في نطاق", + "wbqc-constraintreport-result-table-header-status": "الحالة", + "wbqc-constraintreport-result-table-header-property": "الخاصية", + "wbqc-constraintreport-result-table-header-message": "الرسالة", + "wbqc-constraintreport-result-table-header-constraint": "محددات", + "wbqc-constraintreport-result-link-to-claim": "اذهب إلى الادعاء", + "wbqc-constraintreport-result-link-to-constraint": "اذهب إلى المحددات", + "wbqc-constraintreport-no-parameter": "لا شيء", + "wbqc-issues-short": "قضايا", + "wbqc-issues-long": "هذا البيان لديه بعض القضايا.", + "wbqc-potentialissues-short": "قضايا محتملة", + "wbqc-potentialissues-long": "يحتوي هذا البيان على بعض القضايا المحتملة.", + "wbqc-suggestions-short": "اقتراحات", + "wbqc-suggestions-long": "هناك بعض الاقتراحات لتحسين هذا البيان.", + "wbqc-badparameters-short": "معلمات سيئة", + "wbqc-badparameters-long": "يحتوي بيان المحددات على بعض المعلمات غير صالحة.", + "wbqc-parameterissues-short": "قضايا متقدمة", + "wbqc-parameterissues-long": "هذه القضايا هي مشاكل مع تعريف المحددات على الخواص، وليس مع هذا البيان.", + "wbqc-constrainttypehelp-short": "مساعدة", + "wbqc-constrainttypehelp-long": "صفحة المساعدة لهذا النوع من المحددات", + "wbqc-constraintdiscuss-short": "ناقش", + "wbqc-constraintdiscuss-long": "صفحة النقاش حول هذا القيد", + "wbqc-cached-generic": "هذه النتيجة مخزنة مؤقتاً وقد تكون قديمة.", + "wbqc-cached-minutes": "هذه النتيجة مخزنة مؤقتًا وقد تكون متقادمة، منذ {{PLURAL:$1|1=دقيقة واحدة|$1 دقائق}}.", + "wbqc-cached-hours": "هذه النتيجة مخزنة مؤقتًا وقد تكون متقادمة، منذ {{PLURAL:$1|1=دقيقة واحدة|$1 دقائق}}.", + "wbqc-cached-days": "هذه النتيجة مخزنة مؤقتًا وقد تكون متقادمة، منذ {{PLURAL:$1|1=دقيقة واحدة|$1 دقائق}}.", + "wbqc-dataValueType-wikibase-entityid": "معرف الكيان", + "wbq-subextension-name-wbqc": "محددات", + "wbqc-violation-header-parameters": "المعلمات:", + "wbqc-violations-group": "محددات", + "wbqc-violation-message": "أشار فحص القيود إلى انتهاك. يرجى النقر على الأيقونة لمزيد من المعلومات.", + "wbqc-violation-message-not-yet-implemented": "لأسباب فنية، لم يتم بعد التحقق من القيد \"$1\".", + "wbqc-violation-message-security-reason": "لأسباب أمنية، لا يمكن التحقق من قيد \"$1\" في الوقت الراهن. نحن نعمل على حل.", + "wbqc-violation-message-value-needed-of-type": "الخواص مع القيد \"$1\" تحتاج إلى أن تكون القيم من نوع \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "الخواص مع القيد \"$1\" في حاجة الى قيم من نوع \"$2\" أو \"$3\".", + "wbqc-violation-message-parameter-needed": "الخصائص مع القيد \"$1\" في حاجة الى المعلمة \"$2\".", + "wbqc-violation-message-parameters-needed-3": "الخصائص مع القيد \"$1\" في حاجة الى الوسائط \"$2\" و\"$3\" و\"$4\".", + "wbqc-violation-message-target-entity-must-exist": "العنصر الهدف يجب أن يكون موجوداً.", + "wbqc-violation-message-value-entity-must-exist": "قيمة الكيان يجب أن تكون موجودة.", + "wbqc-violation-message-parameter-value": "المعلمة \"$1\" يجب أن تحتوي على قيمة موجودة، وليس لا قيمة \"no value\" أو قيمة مجهولة \"unknown value\".", + "wbqc-violation-message-parameter-value-or-novalue": "المعلمة \"$1\" يجب أن تحتوي على قيمة موجودة أو لا قيمة \"no value\"، ولكن ليس قيمة مجهولة \"unknown value\".", + "wbqc-violation-message-parameter-entity": "قيمة المعلمة \"$1\" يجب أن يكون كيانا، وليس \"$2\".", + "wbqc-violation-message-parameter-item": "قيمة الوسيط \"$1\" يجب أن تكون عنصرا وليس \"$2\".", + "wbqc-violation-message-parameter-property": "قيمة الوسيط \"$1\" يجب أن تكون خاصية وليس \"$2\".", + "wbqc-violation-message-parameter-string": "قيمة الوسيط \"$1\" يجب أن تكون سطرا نصيا وليس \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "قيمة المعلمة \"$1\" يجب أن يكون نصا أحادي اللغة، وليس \"$2\".", + "wbqc-violation-message-parameter-single": "قيمة المعلمة \"$1\" يجب أن تحتوي قيمة واحدة فقط.", + "wbqc-violation-message-parameter-single-per-language": "يجب أن تحتوي المعلمة \"$1\" على قيمة واحدة فقط لكل لغة، ولكن لها قيم متعددة بقيمة $2 ($3).", + "wbqc-violation-message-parameter-oneof": "الوسيط \"$1\" يجب أن يكون {{PLURAL:$2|1=$4.|2=إما $4 أو $5.|واحدة من التالي:$3}}", + "wbqc-violation-message-parameter-regex": "$1 ليس تعبيراً نمطياً صالحاً.", + "wbqc-violation-message-sparql-error": "نتيجة استعلام سباركل خاطئة.", + "wbqc-violation-message-parameters-error-unknown": "تعذر استيراد معلمات هذه المحددات.", + "wbqc-violation-message-parameters-error-toolong": "لا يمكن استيراد معلمات هذه المحددات لأنها طويلة جداً.", + "wbqc-violation-message-invalid-scope": "$1 ليس نطاقا صالحا لنوع القيد $2؛ {{PLURAL:$3|النطاق الصالح|النطاقات الصالحة}} لهذا النوع من القيود {{PLURAL:$3|هو $5.|2=هي $5 و$6.|هي: $4}}", + "wbqc-violation-message-commons-link-no-existent": "يجب أن تكون وصلة كومنز موجودة.", + "wbqc-violation-message-commons-link-not-well-formed": "ينبغي أن تكون وصلة كومنز جيدة التشكيل.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "التحقق من نطاق \"$1\" لم يتم تنفيذه بعد.", + "wbqc-violation-message-conflicts-with-property": "لا ينبغي أن يكون لدى الكيان بيانات لكلا $1 و $2.", + "wbqc-violation-message-conflicts-with-claim": "لا ينبغي أن يكون لدى الكيان بيان لـ $1 إذا كان لديه أيضا بيان لـ $2 وقيمته $3.", + "wbqc-violation-message-contemporary-subject-earlier": "يجب أن يكون الكيانان $1 و$3 معاصرين ليتم ربطهما من خلال $2، لكن القيمة النهائية الأحدث لـ$1 $4 وأول قيمة لبدء $3 هي $5.", + "wbqc-violation-message-contemporary-value-earlier": "يجب أن يكون الكيانان $1 و$3 معاصرين ليتم ربطهما من خلال $2، لكن القيمة النهائية الأخيرة لـ$3 هي $4 وأول قيمة لبدء $1 هي $5.", + "wbqc-violation-message-diff-within-range": "الفرق بين $3 ($4) و$1 ($2) يجب أن يكون بين $5 و $6.", + "wbqc-violation-message-diff-within-range-leftopen": "الفرق بين $3 ($4) و$1 ($2) ينبغي أن يكون أكثر من $5.", + "wbqc-violation-message-diff-within-range-rightopen": "الفرق بين $3 ($4) و $1 ($2) يجب أن لا يقل عن $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "الخاصية المعرفة في المعلمات يجب أن يكون لها قيمة من نفس نوع هذه الخاصية", + "wbqc-violation-message-format": "القيمة $1 ($2) يجب أن تتطابق مع التعبير النمطي $3.", + "wbqc-violation-message-format-clarification": "قيمة $1 ($2) يجب أن تطابق “$4” (التعبير النمطي: $3).", + "wbqc-violation-message-inverse": "$1 ينبغي أن يكون لها أيضا بيان عكسي $2 $3.", + "wbqc-violation-message-item": "الكيان الذي يستخدم $1 يجب أن يحتوي على {{PLURAL:$3|0=بيان $2.|1=بيان $2 $5.|بيان لـ $2 مع واحدة من القيم التالية:$4}}", + "wbqc-violation-message-mandatory-qualifier": "يفتقد بيان $1 لتصفية $2.", + "wbqc-violation-message-multi-value": "هذه الخاصية يجب أن تحتوي على قيم متعددة.", + "wbqc-violation-message-multi-value-separators": "يجب أن تحتوي هذه الخاصية على قيم متعددة بنفس {{PLURAL:$2|1=تصفية $4.|مجموعة التصفيات هذه: $3}}", + "wbqc-violation-message-one-of": "قيمة $1 يجب أن تكون {{PLURAL:$2|1=$4.|2=إما $4 أو $5.|واحدة من الآتي:$3}}", + "wbqc-violation-message-qualifier": "هذه الخاصية يجب أن تستخدم كتصفية فقط.", + "wbqc-violation-message-no-qualifiers": "$1 لا ينبغي أن يكون للبيانات أي تصفيات.", + "wbqc-violation-message-qualifiers": "$2 ليست تصفية صالحة لـ $1 – التصفيات الصالحة {{PLURAL:$3|1=هي $5.|2=هي $5 و$6.|هي:$4}}", + "wbqc-violation-message-range-parameters-needed": "الخواص ذات قيم من النوع \"$1\" ومحدد \"$4\" بحاجة إلى الوسيط \"$2\" و\"$3\".", + "wbqc-violation-message-range-parameters-one-year": "نقاط النهاية لنطاق وحدة زمنية يجب أن تكون الوحدة المستخدمة لها \"سنة\" لأن سنوات في كلاهما ولا تكون في إحداهما، لأنه لا يمكن تحويلها دون فقدان ثواني", + "wbqc-violation-message-range-parameters-same": "يجب أن تكون بداية النطاق ($1) ونقطة النهاية للنطاق ($2) هي نفسها.", + "wbqc-violation-message-range-quantity-closed": "قيمة $1 ($2) يجب أن تكون بين $3 و$4.", + "wbqc-violation-message-range-quantity-leftopen": "قيمة $1 ($2) لا يجب أن تكون أكثر من $3.", + "wbqc-violation-message-range-quantity-rightopen": "لا يجب أن تكون قيمة $1 ($2) أقل من $3.", + "wbqc-violation-message-range-time-closed": "قيمة $1 ($2) يجب أن تكون بين $3 و$4.", + "wbqc-violation-message-range-time-closed-leftnow": "قيمة $1 ($2) يجب أن يكون في المستقبل، ولكن ليس بعد $3.", + "wbqc-violation-message-range-time-closed-rightnow": "قيمة $1 ($2) ينبغي أن يكون في الماضي، ولكن ليس قبل $3.", + "wbqc-violation-message-range-time-leftopen": "قيمة $1 ($2) لا ينبغي أن تكون بعد $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "قيمة $1 ($2) لا ينبغي أن تكون في المستقبل.", + "wbqc-violation-message-range-time-rightopen": "قيمة $1 ($2) لا ينبغي أن تكون قبل $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "قيمة $1 ($2) لا ينبغي أن تكون في الماضي.", + "wbqc-violation-message-single-value": "هذه الخاصية يجب أن تحتوي على قيمة واحدة فقط.", + "wbqc-violation-message-single-value-separators": "يجب أن تحتوي هذه الخاصية على قيمة منفردة فقط ولها {{PLURAL:$2|1=تصفية $4.|تصفيات من هذه الخاصيات: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "يجب أن تحتوي هذه الخاصية على قيمة \"أفضل\" واحدة، من بين القيم المتعددة الحالية، يجب تعليم واحدة بالترتيب \"المفضل\".", + "wbqc-violation-message-single-best-value-no-preferred-separators": "يجب أن تحتوي هذه الخاصية على قيمة ”مفضلة“ منفردة فقط ولها {{PLURAL:$2|1=تصفية $4.|تصفيات من هذه الخاصيات: $3}} من القيم المتعددة الحالية، يجب وضع علامة واحدة على الترتيب ”المفضل“.", + "wbqc-violation-message-single-best-value-multi-preferred": "يجب أن تحتوي هذه الخاصية على قيمة \"أفضل\" واحدة، يجب ألا يكون هناك أكثر من قيمة واحدة مع الترتيب \"المفضل\".", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "يجب أن تحتوي هذه الخاصية على قيمة ”مفضلة“ منفردة فقط ولها {{PLURAL:$2|1=تصفية $4.|تصفيات من هذه الخاصيات: $3}} يجب ألا تكون هناك أكثر من قيمة واحدة للترتيب ”المفضل“.", + "wbqc-violation-message-symmetric": "$1 ينبغي أن يكون لها أيضا بيان متماثل $2 $3.", + "wbqc-violation-message-type-instance": "الكيانات التي تستخدم خاصية $1 ينبغي أن تكون نموذجا من {{PLURAL:$3|1=$5|2=$5 أو $6|الأصناف التالية}} (أو {{PLURAL:$3|1=صنفا فرعيا منها|2=صنفا فرعيا منهم|أصنافها الفرعية}})، لكن حالياً $2 {{PLURAL:$3|1=ليست كذلك|2=ليسو كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-type-subclass": "الكيانات التي تستخدم خاصية $1 ينبغي أن تكون صنفا فرعيا من {{PLURAL:$3|1=$5|2=$5 أو $6|واحدة من الأصناف التالية}} (أو {{PLURAL:$3|1=صنفا فرعيا منها|2=صنفا فرعيا منهما|صنفا فرعيا من أصنافها الفرعية}})، لكن حالياً $2 {{PLURAL:$3|1=ليست كذلك|2=ليستا كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "الكيانات التي تستخدم خاصية $1 ينبغي أن تكون نموذجا من/صنفا فرعيا من {{PLURAL:$3|1=$5|2=$5 أو $6|واحد من الأصناف التالية}} (أو {{PLURAL:$3|1=صنف فرعي منها|2=صنف فرعي منهم|صنفا فرعيا من أصنافها الفرعية}})، لكن حالياً $2 {{PLURAL:$3|1=ليست كذلك|2=ليست كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-valueType-instance": "يجب أن تكون قيم بيانات $1 نموذجا من {{PLURAL:$3|1=$5|2=$5 أو $6|واحدة من الأصناف التالية}} (أو {{PLURAL:$3|1=صنفا فرعيا منها|2=صنفا فرعيا منهم|صنفا فرعيا من أصنافها الفرعية}})، لكن حاليا $2 {{PLURAL:$3|1=ليست كذلك|2=ليست كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-valueType-subclass": "يجب أن تكون قيم بيانات $1 نموذجا من {{PLURAL:$3|1=$5|2=$5 أو $6|واحدة من الأصناف التالية}} (أو {{PLURAL:$3|1=صنفا فرعيا منها|2=صنفا فرعيا منهم|صنفا فرعيا من أصنافها الفرعية}})، لكن حاليا $2 {{PLURAL:$3|1=ليست كذلك|2=ليست كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "يجب أن تكون قيم بيانات $1، نموذجا من أو صنفا فرعيا من {{PLURAL:$3|1=$5|2=$5 أو $6|واحدة من الأصناف التالية}} (أو {{PLURAL:$3|1=صنفا فرعيا منها|2=صنفا فرعيا منهما|صنفا فرعيا من أصنافها الفرعية}})، لكن حاليا $2 {{PLURAL:$3|1=ليست كذلك|2=ليست كذلك|ليست كذلك: $4}}", + "wbqc-violation-message-target-required-claim": "$1 يجب أن تحتوي على {{PLURAL:$3|0=بيان $2.|1=بيان $2 $5.|بيان $2 مع واحدة من القيم التالية:$4}}", + "wbqc-violation-message-unique-value": "ينبغي ألا تكون قيمة هذه الخاصية موجودة على أي عنصر آخر، ولكنها موجودة أيضاً في {{PLURAL:$1|1=$3.|2=$3 و$4.|العناصر التالية: $2}}", + "wbqc-violation-message-valueOnly": "يجب أن تستخدم هذه الخاصية كقيمة رئيسية للبيان، وليس للتصفيات أو المراجع.", + "wbqc-violation-message-reference": "يجب أن تستخدم هذه الخاصية في المراجع، وليس كقيمة رئيسية للبيان أو في التصفيات.", + "wbqc-violation-message-noBounds": "يجب ألا تحتوي قيم $1 على أية حدود.", + "wbqc-violation-message-units-none": "يجب ألا تحتوي قيمة $1 على وحدة.", + "wbqc-violation-message-units": "يجب أن تحتوي القيمة $1 على {{PLURAL:$2|1=الوحدة $4.|2=الوحدة $4 أو $5.|إحدى الوحدات التالية: $3}}", + "wbqc-violation-message-units-or-none": "يجب أن تحتوي القيمة $1 على {{PLURAL:$2|1=الوحدة $4.|2=الوحدة $4 أو $5.|إحدى الوحدات التالية: $3}} أو أن تكون {{PLURAL:$2|1=بدون وحدات.|2=بدون وحدات.|بدون وحدات: $3}}", + "wbqc-violation-message-entityType": "يجب عدم استخدام الخاصية $1 على هذا النوع من الكيانان; {{PLURAL:$2|1=النوع الوحيد للكيان هو $4.|2= أنواع الكيانات الوحيدة هي $4 و$5.|أنواع الكيانات الوحيدة هي: $3}}", + "wbqc-violation-message-none-of": "يجب ألا تكون قيمة $1 {{PLURAL:$2|1=$4.|2=إما $4 أو $5.|إحدى ما يلي:$3}}", + "wbqc-violation-message-integer": "يجب أن تكون قيم $1 عددا صحيحا، لكن يحتوي $2 على جزء كسري.", + "wbqc-violation-message-integer-bounds": "يجب أن تكون قيم $1 عددا صحيحا، لكن حدود $2 بها جزء كسري.", + "wbqc-violation-message-citationNeeded": "يجب أن تحتوي بيانات $1 على مرجع واحد على الأقل.", + "wbqc-violation-message-language": "يجب أن تكون بيانات $1 على Lexemes فقط مع ضبط اللغة على {{PLURAL:$2| 1 = $4 . | 2 = إما $4 $5 . | أحد الخيارات التالية: $3 }}", + "wbqc-violation-message-label-lacking": "الكيانات التي تحتوي على كشوف حساب $1 يجب أن يكون لها تصنيف على الأقل في {{PLURAL:$2| 1 = $4 . | أي من اللغات التالية: $3 }}", + "wbqc-violation-message-property-scope": "يجب عدم استخدام الخاصية $1 في هذا الموقع ($2); {{PLURAL:$3|الموقع الصالح الوحيد|المواقع الصالحة الوحيدة}} لهذه الخاصية {{PLURAL:$3|هو $5.|هي: $4}}", + "wbqc-violation-message-exception": "هذا الكيان استثناء معروف لدى القيد وتم وضع علامة عليه على هذا النحو." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/arq.json b/dist/extensions/WikibaseQualityConstraints/i18n/arq.json new file mode 100644 index 000000000..8a7c7e668 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/arq.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Oldstoneage" + ] + }, + "wbqc-constraintreport-not-existent-entity": "هاد الحاجة ما كايناش!", + "wbqc-constraintreport-result-table-header-status": "الحالة", + "wbqc-violations-group": "حتمات" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ary.json b/dist/extensions/WikibaseQualityConstraints/i18n/ary.json new file mode 100644 index 000000000..4adac5957 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ary.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Ideophagous" + ] + }, + "wbqc-constrainttypehelp-short": "معاونة" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ast.json b/dist/extensions/WikibaseQualityConstraints/i18n/ast.json new file mode 100644 index 000000000..e0d16306f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ast.json @@ -0,0 +1,75 @@ +{ + "@metadata": { + "authors": [ + "Xuacu" + ] + }, + "wbqc-constraintreport": "Informe de torgues", + "wbqc-desc": "Comprueba les torgues nos elementos y propiedaes y amuesa los resultaos n'una páxina especial", + "wbqc-constraintreport-explanation-part-one": "Esta páxina especial fai comprobaciones de torgues na entidá que quieras. Les entidaes sáquense del sistema real, de mou que cada violación de torgues qu'igües desaniciaráse nel intre d'esta llista.", + "wbqc-constraintreport-explanation-part-two": "Les torgues analícense dende les declaraciones de les propiedaes cada vegada que s'editen eses declaraciones, de vezu a los pocos minutos.", + "wbqc-constraintreport-form-section": "Comprobar les torgues d'entidá", + "wbqc-constraintreport-form-submit-label": "Comprobar", + "wbqc-constraintreport-form-entityid-label": "ID de la entidá:", + "wbqc-constraintreport-result-headline": "Resultáu pa", + "wbqc-constraintreport-invalid-entity-id": "ID d'entidá inválidu.", + "wbqc-constraintreport-not-existent-entity": "La entidá nun esiste.", + "wbqc-constraintreport-empty-result": "Nun hai torgues definíes nesta entidá.", + "wbqc-constraintreport-status-violation": "Violación", + "wbqc-constraintreport-status-compliance": "Cumple", + "wbqc-constraintreport-status-exception": "Esceición", + "wbqc-constraintreport-status-todo": "Pendiente", + "wbqc-constraintreport-status-bad-parameters": "Parámetros incorreutos", + "wbqc-constraintreport-status-deprecated": "Desusao", + "wbqc-constraintreport-status-warning": "Avisu", + "wbqc-constraintreport-status-not-in-scope": "Fora del ámbitu", + "wbqc-constraintreport-result-table-header-status": "Estáu", + "wbqc-constraintreport-result-table-header-property": "Propiedá", + "wbqc-constraintreport-result-table-header-message": "Mensaxe", + "wbqc-constraintreport-result-table-header-constraint": "Torga", + "wbqc-constraintreport-result-link-to-claim": "dir a declaración", + "wbqc-constraintreport-result-link-to-constraint": "dir a torga", + "wbqc-constraintreport-no-parameter": "nengunu", + "wbqc-issues-short": "Problemes", + "wbqc-issues-long": "Esta declaración tien dellos problemes.", + "wbqc-potentialissues-short": "Problemes en potencia", + "wbqc-potentialissues-long": "Esta declaración tien posibles incidencies.", + "wbqc-badparameters-short": "Parámetros incorreutos", + "wbqc-badparameters-long": "Esta declaración de torga tien dellos parámetros inválidos.", + "wbqc-parameterissues-short": "Incidencies avanzaes", + "wbqc-constrainttypehelp-short": "Ayuda", + "wbqc-constrainttypehelp-long": "Páxina d'ayuda pa esta triba de torga", + "wbqc-constraintdiscuss-short": "Alderique", + "wbqc-constraintdiscuss-long": "Páxina d'alderique sobre esta restricción", + "wbqc-dataValueType-wikibase-entityid": "ID de la entidá", + "wbq-subextension-name-wbqc": "Torgues", + "wbqc-violation-header-parameters": "Parámetros:", + "wbqc-violations-group": "Torgues", + "wbqc-violation-message": "La comprobación de torgues señaló una violación. Fai click nel iconu pa más información.", + "wbqc-violation-message-not-yet-implemented": "Por razones téuniques, la comprobación de la torga «$1» inda nun ta desendolcada.", + "wbqc-violation-message-security-reason": "Por motivos de seguridá, nun ye posible comprobar la torga «$1» nesti momentu. Tamos trabayando n'una solución.", + "wbqc-violation-message-value-needed-of-type": "Les propiedaes cola torga «$1» han tener valores de tipu «$2».", + "wbqc-violation-message-parameter-needed": "Les propiedaes cola torga «$1» necesiten un parámetru «$2».", + "wbqc-violation-message-target-entity-must-exist": "La entidá de destín tien d'esistir.", + "wbqc-violation-message-value-entity-must-exist": "La entidá valor tien d'esistir.", + "wbqc-violation-message-commons-link-no-existent": "L'enllaz a Commons tendría d'esistir.", + "wbqc-violation-message-commons-link-not-well-formed": "L'enllaz a Commons tien de tar bien formáu.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "La comprobación pal espaciu de nomes «$1» inda nun ta desendolcada.", + "wbqc-violation-message-conflicts-with-property": "Una entidá nun habría de tener declaraciones pa $1 nin pa $2.", + "wbqc-violation-message-conflicts-with-claim": "Una entidá nun habría de tener declaraciones pa $1 si tamién tien una declaración pa $2 con valor $3.", + "wbqc-violation-message-diff-within-range": "La diferencia ente $3 ($4) y $1 ($2) habría de tar ente $5 y $6.", + "wbqc-violation-message-diff-within-range-leftopen": "La diferencia ente $3 ($4) y $1 ($2) nun tendría de ser mayor que $5.", + "wbqc-violation-message-diff-within-range-rightopen": "La diferencia ente $3 ($4) y $1 ($2) nun tendría de ser menor que $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "La propiedá definida nos parámetros tien de tener un valor del mesmu tipu qu'esta propiedá.", + "wbqc-violation-message-format": "El valor de $1 ($2) tien de coincidir cola espresión regular $3.", + "wbqc-violation-message-inverse": "$1 habría de tener tamién la declaración inversa $2 $3.", + "wbqc-violation-message-item": "Una entidá con $1 habría de tener tamién {{PLURAL:$3|0=una declaración $2|1=una declaración $2 $5|una declaración pa $2 con un valor de los siguientes:$4}}.", + "wbqc-violation-message-multi-value": "Esta propiedá tendría de contener valores múltiples.", + "wbqc-violation-message-one-of": "El valor de $1 tendría de ser {{PLURAL:$2|1=$4|2=o $4 o $5|unu de los elementos siguientes:$3}}.", + "wbqc-violation-message-qualifier": "La propiedá solo tendría d'usase como calificador.", + "wbqc-violation-message-no-qualifiers": "Les declaraciones $1 nun habríen de tener calificadores.", + "wbqc-violation-message-qualifiers": "$2 nun ye un calificador válidu pa $1 – {{PLURAL:$3|1=l'únicu calificador válidu ye $5|2=los únicos calificadores válidos son $5 y $6|los únicos calificadores válidos son:$4}}.", + "wbqc-violation-message-range-parameters-needed": "Les propiedaes con valores de tipu «$1» cola torga «$4» necesiten los parámetros «$2» y «$3».", + "wbqc-violation-message-single-value": "Esta propiedá sólo habría de contener un únicu valor.", + "wbqc-violation-message-symmetric": "$1 habría de tener tamién la declaración simétrica $2 $3." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/av.json b/dist/extensions/WikibaseQualityConstraints/i18n/av.json new file mode 100644 index 000000000..0f8721384 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/av.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Augustus A C" + ] + }, + "wbqc-constrainttypehelp-short": "Квеки" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/az.json b/dist/extensions/WikibaseQualityConstraints/i18n/az.json new file mode 100644 index 000000000..d8c85b9f7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/az.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "NMW03", + "Neriman2003", + "Toghrul Rahimli", + "Wertuose", + "Nemoralis" + ] + }, + "wbqc-potentialissues-short": "Mümkün problemlər", + "wbqc-suggestions-short": "Təkliflər", + "wbqc-constrainttypehelp-short": "Kömək", + "wbqc-constrainttypehelp-long": "Bu məhdudiyyət növünün kömək səhifəsi", + "wbqc-constraintdiscuss-short": "Müzakirə", + "wbqc-constraintdiscuss-long": "Bu məhdudiyyət barədə müzakirə səhifəsi", + "wbqc-violation-message-type-instanceOrSubclass": "$1 parametri istifadə edilmiş müddəaların anlayış sinifləri və ya alt sinifləri {{PLURAL:$3|1=$5|2=$5 və ya $6|aşağıdakı siniflərdən biri}} (və ya {{PLURAL:$3|1=alt sinfi|2=onların alt sinfi|alt siniflərindən biri}}) olmalıdır, amma $2 hazırda {{PLURAL:$3|1=belə deyil.|2=belə deyil.|$4 deyil.}}", + "wbqc-violation-message-target-required-claim": "$1 {{PLURAL:$3|0=$2 müddəasına|1=$2 $5 müddəasına|$2 müddəası $4 dəyərlərindən birinə}} malik olmalıdır.", + "wbqc-violation-message-citationNeeded": "$1 üçün ən azı bir istinad tələb olunur." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/bcl.json b/dist/extensions/WikibaseQualityConstraints/i18n/bcl.json new file mode 100644 index 000000000..daf69321a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/bcl.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Geopoet" + ] + }, + "wbqc-constraintreport-result-headline": "Resulta para sa", + "wbqc-constraintreport-not-existent-entity": "An entidad bakong eksistido!", + "wbqc-constraintreport-status-exception": "Kalaenan", + "wbqc-constraintreport-result-table-header-status": "Kamugtakan", + "wbqc-violations-group": "Mga Nakakapagpugol" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/be-tarask.json b/dist/extensions/WikibaseQualityConstraints/i18n/be-tarask.json new file mode 100644 index 000000000..5f1c4b406 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/be-tarask.json @@ -0,0 +1,147 @@ +{ + "@metadata": { + "authors": [ + "Red Winged Duck", + "Renessaince" + ] + }, + "wbqc-constraintreport": "Справаздача пра абмежаваньне", + "wbqc-desc": "Правярае абмежаваньні як для элемэнтаў, так і ўласьцівасьцяў, і выводзіць вынікі на асобнай старонцы", + "wbqc-constraintreport-explanation-part-one": "Гэтая спэцыяльная старонка выконвае праверку абмежаваньняў для патрэбнай вам сутнасьці. Сутнасьці абіраюцца з рабочай сыстэмы, таму кожнае выпраўленьне хібнага абмежаваньня будзе адразу выдаленае з гэтага сьпісу.", + "wbqc-constraintreport-explanation-part-two": "Абмежаваньні разьбіраюцца зь сьцьверджаньняў на ўласьцівасьцях кожным разам, калі гэтыя сьцьверджаньні рэдагуюцца, звычайна цягам некалькіх хвілінаў.", + "wbqc-constraintreport-form-section": "Праверыць абмежаваньні для сутнасьці", + "wbqc-constraintreport-form-submit-label": "Праверыць", + "wbqc-constraintreport-form-entityid-label": "Ідэнтыфікатар сутнасьці:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx або Pxx", + "wbqc-constraintreport-result-headline": "Вынік для", + "wbqc-constraintreport-invalid-entity-id": "Памылковы ідэнтыфікатар сутнасьці.", + "wbqc-constraintreport-not-existent-entity": "Сутнасьці не існуе.", + "wbqc-constraintreport-empty-result": "Для гэтай сутнасьці абмежаваньні ня вызначаныя.", + "wbqc-constraintreport-status-violation": "Парушэньне", + "wbqc-constraintreport-status-compliance": "Адпаведнасьць", + "wbqc-constraintreport-status-exception": "Вынятак", + "wbqc-constraintreport-status-todo": "Зрабіць", + "wbqc-constraintreport-status-bad-parameters": "Хібныя парамэтры", + "wbqc-constraintreport-status-deprecated": "Састарэлы", + "wbqc-constraintreport-status-warning": "Папярэджаньне", + "wbqc-constraintreport-status-suggestion": "Прапанова", + "wbqc-constraintreport-status-not-in-scope": "Па-за вобласьцю дзеяньня", + "wbqc-constraintreport-result-table-header-status": "Статус", + "wbqc-constraintreport-result-table-header-property": "Уласьцівасьць", + "wbqc-constraintreport-result-table-header-message": "Паведамленьне", + "wbqc-constraintreport-result-table-header-constraint": "Абмежаваньне", + "wbqc-constraintreport-result-link-to-claim": "перайсьці да сьцьверджаньня", + "wbqc-constraintreport-result-link-to-constraint": "перайсьці да абмежаваньня", + "wbqc-constraintreport-no-parameter": "няма", + "wbqc-issues-short": "Праблемы", + "wbqc-issues-long": "Гэтае сьцьверджаньне мае пэўныя праблемы.", + "wbqc-potentialissues-short": "Магчымыя праблемы", + "wbqc-potentialissues-long": "Гэтае сьцьверджаньне мае пэўныя магчымыя праблемы.", + "wbqc-suggestions-short": "Прапановы", + "wbqc-suggestions-long": "Ёсьць некалькі прапановаў паляпшэньня гэтага сьцьверджаньня.", + "wbqc-badparameters-short": "Хібныя парамэтры", + "wbqc-badparameters-long": "Гэтае абмежаваньне сьцьверджаньня мае пэўныя хібныя парамэтры.", + "wbqc-parameterissues-short": "Складаныя праблемы", + "wbqc-parameterissues-long": "Гэтыя праблемы тычацца вызначэньня абмежаваньня ўласьцівасьці, а ня сьцьверджаньня.", + "wbqc-constrainttypehelp-short": "Дапамога", + "wbqc-constrainttypehelp-long": "Старонка дапамогі для гэтага тыпу абмежаваньня", + "wbqc-constraintdiscuss-short": "Абмеркаваць", + "wbqc-constraintdiscuss-long": "Старонка абмеркаваньня гэтага абмежаваньня", + "wbqc-cached-generic": "Гэты вынік кэшаваны і можа быць састарэлым.", + "wbqc-cached-minutes": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|1=адну хвіліну|$1 хвіліны|$1 хвілінаў}}.", + "wbqc-cached-hours": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|1=адну гадзіну|$1 гадзіны|$1 гадзінаў}}.", + "wbqc-cached-days": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|1=адзін дзень|$1 дні|$1 дзён}}.", + "wbqc-dataValueType-wikibase-entityid": "Ідэнтыфікатар сутнасьці", + "wbq-subextension-name-wbqc": "Абмежаваньні", + "wbqc-violation-header-parameters": "Парамэтры:", + "wbqc-violations-group": "Абмежаваньні", + "wbqc-violation-message": "Праверка абмежаваньняў выявіла парушэньне. Калі ласка, націсьніце на іконку для падрабязнай інфармацыі.", + "wbqc-violation-message-not-yet-implemented": "З тэхнічных прычынаў праверка абмежаваньня «$1» яшчэ не была ўведзеная.", + "wbqc-violation-message-security-reason": "З пытаньняў бясьпекі ў дадзены час немагчыма праверыць абмежаваньне «$1». Мы працуем над рашэньнем.", + "wbqc-violation-message-value-needed-of-type": "Уласьцівасьці з абмежаваньнем «$1» мусяць мець значэньні тыпу «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Уласьцівасьці з абмежаваньнем «$1» мусяць мець значэньні тыпу «$2» ці «$3».", + "wbqc-violation-message-parameter-needed": "Уласьцівасьці з абмежаваньнем «$1» патрабуюць парамэтру «$2».", + "wbqc-violation-message-parameters-needed-3": "Уласьцівасьці з абмежаваньнем «$1» патрабуюць парамэтраў «$2», «$3» ды «$4».", + "wbqc-violation-message-target-entity-must-exist": "Мэтавая сутнасьць мусіць існаваць.", + "wbqc-violation-message-value-entity-must-exist": "Сутнасьць для значэньня мусіць існаваць.", + "wbqc-violation-message-parameter-value": "Парамэтар «$1» мусіць мець нестандартнае значэньне, не «без значэньня» ці «невядомае значэньне».", + "wbqc-violation-message-parameter-value-or-novalue": "Парамэтар «$1» мусіць мець нестандартнае значэньне ці «без значэньня», але не «невядомае значэньне».", + "wbqc-violation-message-parameter-entity": "Значэньне парамэтру «$1» мусіць быць сутнасьцю, а не «$2».", + "wbqc-violation-message-parameter-item": "Значэньне парамэтру «$1» мусіць быць элемэнтам, а не «$2».", + "wbqc-violation-message-parameter-property": "Значэньне парамэтру «$1» мусіць быць уласьцівасьцю, а не «$2».", + "wbqc-violation-message-parameter-string": "Значэньне парамэтру «$1» мусіць быць радком, а не «$2».", + "wbqc-violation-message-parameter-monolingualtext": "Значэньне парамэтру «$1» мусіць быць аднамоўным тэкстам, а не «$2».", + "wbqc-violation-message-parameter-single": "Парамэтар «$1» мусіць мець толькі адно значэньне.", + "wbqc-violation-message-parameter-single-per-language": "Парамэтар «$1» мусіць мець адно значэньне для мовы, аднак мае множныя значэньні для «$2» ($3).", + "wbqc-violation-message-parameter-oneof": "Парамэтар «$1» мусіць быць {{PLURAL:$2|1=$4.|2=ці $4, ці $5.|адным з наступных: $3}}", + "wbqc-violation-message-parameter-regex": "$1 — няслушны рэгулярны выраз.", + "wbqc-violation-message-sparql-error": "Запыт SPARQL выдаў памылку.", + "wbqc-violation-message-parameters-error-unknown": "Парамэтры гэтага абмежаваньня ня могуць быць імпартаваныя.", + "wbqc-violation-message-parameters-error-toolong": "Парамэтры гэтага абмежаваньня ня могуць быць імпартаваныя, бо надта доўгія.", + "wbqc-violation-message-invalid-scope": "$1 — няслушная вобласьць выкарыстаньня для тыпу абмежаваньня $2; {{PLURAL:$3|адзінай слушнай вобласьцю|адзінымі слушнымі абласьцямі}} для гэтага тыпу абмежаваньня ёсьць {{PLURAL:$3|$5.|2=$5 і $6.|: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Павінна існаваць спасылка на Вікісховішча.", + "wbqc-violation-message-commons-link-not-well-formed": "Спасылка на Вікісховішча мусіць быць правільна пазначанай.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Праверка для прасторы назваў «$1» яшчэ не рэалізаваная.", + "wbqc-violation-message-conflicts-with-property": "Сутнасьць ня мусіць мець сьцьверджаньняў адначасна для $1 і $2.", + "wbqc-violation-message-conflicts-with-claim": "Сутнасьць ня мусіць мець сьцьверджаньня для $1, калі яна мае сьцьверджаньне для $2 са значэньнем $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Сутнасьці $1 і $3 мусяць быць адначасна зьвязаныя праз $2, аднак найпазьнейшае значэньне канца пэрыяду для $1 — $4, а найранейшае значэньне пачатку пэрыяду для $3 — $5.", + "wbqc-violation-message-contemporary-value-earlier": "Сутнасьці $1 і $3 мусяць быць адначасна зьвязаныя праз $2, аднак найпазьнейшае значэньне канца пэрыяду для $3 — $4, а найранейшае значэньне пачатку пэрыяду для $1 — $5.", + "wbqc-violation-message-diff-within-range": "Розьніца паміж $3 ($4) і $1 ($2) мусіць знаходзіцца паміж $5 і $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Розьніца паміж $3 ($4) і $1 ($2) ня мусіць быць большай за $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Розьніца паміж $3 ($4) і $1 ($2) ня мусіць быць меншай за $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Уласьцівасьць, вызначаная ў парамэтрах, мусіць мець значэньне таго ж тыпу, што і гэтая ўласьцівасьць.", + "wbqc-violation-message-format": "Значэньне для $1 ($2) мусіць адпавядаць рэгулярнаму выразу $3.", + "wbqc-violation-message-format-clarification": "Значэньне для $1 ($2) мусіць адпавядаць «$4» (рэгулярны выраз: $3).", + "wbqc-violation-message-inverse": "$1 мусіць таксама мець адваротнае сьцьверджаньне $2 $3.", + "wbqc-violation-message-item": "Элемэнт з $1 таксама мусіць мець {{PLURAL:$3|0=сьцьверджаньне $2.|1=сьцьверджаньне $2 $5.|сьцьверджаньне для $2 з адным з наступных значэньняў: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Гэтае сьцьверджаньне $1 ня мае кваліфікатара $2.", + "wbqc-violation-message-multi-value": "Гэтая ўласьцівасьць мусіць мець некалькі значэньняў.", + "wbqc-violation-message-multi-value-separators": "Гэтая ўласьцівасьць мусіць мець некалькі значэньняў з {{PLURAL:$2|1=тым самым кваліфікатарам $4|наборам кваліфікатараў для гэтых уласьцівасьцей: $3}}.", + "wbqc-violation-message-one-of": "Значэньне для $1 мусіць быць {{PLURAL:$2|1=$4|2=або, $4 або $5.|адным з наступных: $3}}.", + "wbqc-violation-message-qualifier": "Уласьцівасьць мусіць выкарыстоўвацца толькі як кваліфікатар.", + "wbqc-violation-message-no-qualifiers": "Сьцьверджаньні $1 ня мусяць мець кваліфікатараў.", + "wbqc-violation-message-qualifiers": "$2 — няслушны кваліфікатар для $1. {{PLURAL:$3|1=Адзіны слушны кваліфікатар — $5.|2=Адзіныя слушныя кваліфікатары — $5 і $6.|Адзіныя слушныя кваліфікатары: $4}}", + "wbqc-violation-message-range-parameters-needed": "Уласьцівасьць з значэньнямі тыпу «$1» з абмежаваньнем «$4» патрабуюць парамэтраў «$2» і «$3».", + "wbqc-violation-message-range-parameters-one-year": "Канцавыя пункты часавага дыяпазону мусяць ці ня мець, ці абодва мець адзінку «год», паколькі гады немажліва беспамылкова сканвэртаваць у сэкунды.", + "wbqc-violation-message-range-parameters-same": "Пачатковы ($1) і канчатковы ($2) пункты дыяпазону ня могуць быць аднолькавымі.", + "wbqc-violation-message-range-quantity-closed": "Значэньне для $1 ($2) мусіць знаходзіцца паміж $3 і $4.", + "wbqc-violation-message-range-quantity-leftopen": "Значэньне для $1 ($2) ня мусіць перавышаць $3.", + "wbqc-violation-message-range-quantity-rightopen": "Значэньне для $1 ($2) ня мусіць быць меншым за $3.", + "wbqc-violation-message-range-time-closed": "Значэньне для $1 ($2) мусіць знаходзіцца паміж $3 і $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Значэньне для $1 ($2) мусіць быць у будучыні, але не пазьней за $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Значэньне для $1 ($2) мусіць быць у мінулым, але не раней за $3.", + "wbqc-violation-message-range-time-leftopen": "Значэньне для $1 ($2) ня мусіць быць пазьней за $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Значэньне для $1 ($2) ня мусіць быць у будучыні.", + "wbqc-violation-message-range-time-rightopen": "Значэньне для $1 ($2) ня мусіць быць раней за $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Значэньне для $1 ($2) ня мусіць быць у мінулым.", + "wbqc-violation-message-single-value": "Гэтая ўласьцівасьць мусіць мець толькі адно значэньне.", + "wbqc-violation-message-single-value-separators": "Гэтая ўласьцівасьць мусіць мець толькі адно значэньне з тым самым {{PLURAL:$2|1=кваліфікатарам $4|наборам кваліфікатараў для гэтых уласьцівасьцей: $3}}.", + "wbqc-violation-message-single-best-value-no-preferred": "Гэтая ўласьцівасьць мусіць мець адно «найлепшае» значэньне. Адно зь цяперашніх шматлікіх значэньняў трэба пазначыць «пераважным» рангам.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Гэтая ўласьцівасьць мусіць мець адно «найлепшае» значэньне з тым самым {{PLURAL:$2|1=кваліфікатарам $4|наборам кваліфікатараў для гэтых уласьцівасьцей: $3}}. Адно зь цяперашніх шматлікіх значэньняў трэба пазначыць «пераважным» рангам.", + "wbqc-violation-message-single-best-value-multi-preferred": "Гэтая ўласьцівасьць мусіць мець адно «найлепшае» значэньне. Значэньне зь «пераважным» рангам мусіць быць ня больш за адно.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Гэтая ўласьцівасьць мусіць мець адно «найлепшае» значэньне з тым самым {{PLURAL:$2|1=кваліфікатарам $4|наборам кваліфікатараў для гэтых уласьцівасьцей: $3}}. Значэньне зь «пераважным» рангам мусіць быць ня больш за адно.", + "wbqc-violation-message-symmetric": "$1 мусіць таксама мець сымэтрычнае сьцьверджаньне $2 $3.", + "wbqc-violation-message-type-instance": "Сутнасьці, якія выкарыстоўваюць уласьцівасьць $1, маюць быць экзэмплярамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных клясаў}} (або {{PLURAL:$3|1=ягонага падклясу|2=іхняга падклясу|аднаго зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-type-subclass": "Сутнасьці, якія выкарыстоўваюць уласьцівасьць $1, маюць быць падклясамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных клясаў}} (або {{PLURAL:$3|1=ягонага падклясу|2=іхняга падклясу|аднаго зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Сутнасьці, якія выкарыстоўваюць уласьцівасьць $1, маюць быць экзэмплярамі ці падклясамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных клясаў}} (або {{PLURAL:$3|1=ягонага падклясу|2=іхняга падклясу|аднаго зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-valueType-instance": "Значэньні сьцьверджаньняў $1 маюць быць экзэмплярамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных клясаў}} (або {{PLURAL:$3|1=ягонага падклясу|2=іхняга падклясу|аднаго зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-valueType-subclass": "Значэньні сьцьверджаньняў $1 маюць быць падклясамі {{PLURAL:$3|1=$5|2=$5 або $6|адной з наступных клясаў}} (або {{PLURAL:$3|1=ягонай падклясы|2=іхняй падклясы|адной зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Значэньні сьцьверджаньняў $1 маюць быць экзэмплярамі ці падклясамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных клясаў}} (або {{PLURAL:$3|1=ягонага падклясу|2=іхняга падклясу|аднаго зь іхніх падклясаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не зьяўляецца.|2=такім не зьяўляецца.|такім не зьяўляецца: $4}}", + "wbqc-violation-message-target-required-claim": "$1 мусіць мець {{PLURAL:$3|0=сьцьверджаньне $2.|1=сьцьверджаньне $2 $5.|сьцьверджаньне для $2 з адным з наступных значэньняў: $4}}", + "wbqc-violation-message-unique-value": "Значэньне гэтай уласьцівасьці ня мусіць прысутнічаць на будзь-якім іншым элемэнце, аднак прысутнічае на {{PLURAL:$1|1=$3.|2=$3 і $4.|наступных элемэнтах: $2}}", + "wbqc-violation-message-valueOnly": "Гэтая ўласьцівасьць мусіць выкарыстоўвацца толькі для асноўнага значэньня сьцьверджаньня, а не для кваліфікатараў ці крыніцаў.", + "wbqc-violation-message-reference": "Гэтая ўласьцівасьць мусіць выкарыстоўвацца толькі ў крыніцах, а не для асноўнага значэньня сьцьверджаньня ці для кваліфікатара.", + "wbqc-violation-message-noBounds": "Значэньні для $1 ня мусяць мець ніякіх дыяпазонаў.", + "wbqc-violation-message-units-none": "Значэньне для $1 ня мусіць мець адзінкі вымярэньня.", + "wbqc-violation-message-units": "Значэньне для $1 мусіць мець {{PLURAL:$2|1=адзінку вымярэньня $4.|2=адзінку вымярэньня $4 або $5.|адну з адзінак вымярэньня: $3}}", + "wbqc-violation-message-units-or-none": "Значэньне для $1 мусіць мець {{PLURAL:$2|1=адзінку вымярэньня $4.|2=адзінку вымярэньня $4 або $5.|адну з адзінак вымярэньня: $3}} альбо {{PLURAL:$2|1=ня мець адзінкі вымярэньня.|2=ня мець адзінкі вымярэньня.|ня мець адзінкі вымярэньня: $3}}", + "wbqc-violation-message-entityType": "Уласьцівасьць $1 ня мусіць выкарыстоўвацца з гэтым тыпам сутнасьці; {{PLURAL:$2|1=адзіны слушны тып сутнасьці — $4.|2=адзіныя слушныя тыпы сутнасьці — $4 і $5.|адзіныя слушныя тыпы сутнасьці: $3}}", + "wbqc-violation-message-none-of": "Значэньне для $1 ня мусіць быць {{PLURAL:$2|1=$4|2=ні $4, ні $5.|адным з наступных: $3}}.", + "wbqc-violation-message-integer": "Значэньні для $1 мусяць быць цэлымі, аднак $2 мае дробную частку.", + "wbqc-violation-message-integer-bounds": "Значэньні для $1 мусяць быць цэлымі, аднак граніцы $2 маюць дробную частку.", + "wbqc-violation-message-citationNeeded": "Сьцьверджаньні для $1 мусяць мець прынамсі адну крыніцу.", + "wbqc-violation-message-language": "Сьцьверджаньні для $1 мусяць быць толькі на лексэмах з {{PLURAL:$2|1=$4 мовай.|2=альбо $4, альбо $5 мовай.|адной з гэтых моваў: $3}}", + "wbqc-violation-message-label-lacking": "Існасьці з сьцьверджаньнямі для $1 мусяць таксама мець метку прынамсі {{PLURAL:$2|1=$4 мовай.|адной з гэткіх моваў: $3}}", + "wbqc-violation-message-property-scope": "Уласьцівасьць $1 ня мусіць выкарыстоўвацца ў гэтай мясцовасьці ($2). {{PLURAL:$3|Адзіная слушная мясцовасьць|Адзіныя слушныя мясцовасьці}} для гэтай уласьцівасьці{{PLURAL:$3| — $5.|: $4}}", + "wbqc-violation-message-exception": "Гэтая сутнасьць — вядомы вынятак для дадзенага абмежаваньня і пазначаная такой." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/be.json b/dist/extensions/WikibaseQualityConstraints/i18n/be.json new file mode 100644 index 000000000..ac3a4f319 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/be.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "Artsiom91", + "Chadyka", + "Da voli", + "No Sleep till Krupki", + "Tomato Cream", + "Maksim L." + ] + }, + "wbqc-constraintreport": "Справаздача пра абмежаванні", + "wbqc-desc": "Правярае абмежаванні як для элементаў, так і ўласцівасцяў, і выводзіць вынікі на адмысловай старонцы", + "wbqc-constraintreport-explanation-part-one": "Гэтая адмысловая старонка выконвае праверку абмежаванняў для патрэбнай вам сутнасці. Сутнасці абіраюцца з рабочай сістэмы, таму кожнае выпраўленне абмежавання будзе адразу выдаленае з гэтага спісу.", + "wbqc-constraintreport-explanation-part-two": "Абмежаванні разбіраюцца з сцверджанняў на ўласцівасцях кожным разам, калі гэтыя сцверджанні правяцца, звычайна цягам некалькіх хвілінаў.", + "wbqc-constraintreport-form-section": "Праверыць абмежаванні для сутнасці", + "wbqc-constraintreport-form-submit-label": "Праверыць", + "wbqc-constraintreport-form-entityid-label": "Ідэнтыфікатар сутнасці:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx або Pxx", + "wbqc-constraintreport-result-headline": "Вынік для", + "wbqc-constraintreport-invalid-entity-id": "Няслушны ідэнтыфікатар сутнасці.", + "wbqc-constraintreport-not-existent-entity": "Такой сутнасці няма.", + "wbqc-constraintreport-empty-result": "Для гэтай сутнасці абмежаванні не вызначаныя.", + "wbqc-constraintreport-status-violation": "Парушэнне", + "wbqc-constraintreport-status-compliance": "Адпаведнасць", + "wbqc-constraintreport-status-exception": "Вынятак", + "wbqc-constraintreport-status-todo": "Зрабіць", + "wbqc-constraintreport-status-bad-parameters": "Дрэнныя параметры", + "wbqc-constraintreport-status-deprecated": "Састарэла", + "wbqc-constraintreport-status-warning": "Папярэджанне", + "wbqc-constraintreport-status-suggestion": "Прапанова", + "wbqc-constraintreport-status-not-in-scope": "Па-за вобласцю дзеяння", + "wbqc-constraintreport-result-table-header-status": "Стан", + "wbqc-constraintreport-result-table-header-property": "Уласцівасць", + "wbqc-constraintreport-result-table-header-message": "Паведамленне", + "wbqc-constraintreport-result-table-header-constraint": "Абмежаванне", + "wbqc-constraintreport-result-link-to-claim": "перайсці да сцверджання", + "wbqc-constraintreport-result-link-to-constraint": "перайсці да абмежавання", + "wbqc-constraintreport-no-parameter": "няма", + "wbqc-issues-short": "Праблемы", + "wbqc-issues-long": "У гэтага сцверджання ёсць шэраг праблем.", + "wbqc-potentialissues-short": "Магчымыя праблемы", + "wbqc-potentialissues-long": "У гэтага сцвярджэння выяўлены шэраг магчымых праблем.", + "wbqc-suggestions-short": "Прапановы", + "wbqc-suggestions-long": "Прапановы для паляпшэння гэтага сцверджання.", + "wbqc-badparameters-short": "Дрэнныя параметры", + "wbqc-badparameters-long": "Гэтае абмежаванне сцверджання мае няправільныя параметры.", + "wbqc-parameterissues-short": "Спецыяльныя праблемы", + "wbqc-parameterissues-long": "Гэтыя праблемы маюць месца з вызначэннем абмежавання для уласцівасці, а не са сцверджаннем.", + "wbqc-constrainttypehelp-short": "Даведка", + "wbqc-constrainttypehelp-long": "Старонка даведкі для гэтага тыпу абмежавання", + "wbqc-constraintdiscuss-short": "Абмеркаваць", + "wbqc-constraintdiscuss-long": "Старонка абмеркавання гэтага абмежавання", + "wbqc-cached-generic": "Гэты вынік кэшаваны і можа быць ужо неактуальным.", + "wbqc-cached-minutes": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|$1  хвіліну|$1 хвіліны|$1 хвілінаў|1=адну хвіліну}}.", + "wbqc-cached-hours": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|$1  гадзіну|$1 гадзіны|$1 гадзінаў|1=адну гадзіну}}.", + "wbqc-cached-days": "Гэты вынік кэшаваны і можа быць састарэлым ужо {{PLURAL:$1|$1 дзень|$1 дні|$1 дзён|1=адзін дзень}}.", + "wbqc-dataValueType-wikibase-entityid": "Ідэнтыфікатар сутнасці", + "wbq-subextension-name-wbqc": "Абмежаванні", + "wbqc-violation-header-parameters": "Параметры:", + "wbqc-violations-group": "Абмежаванні", + "wbqc-violation-message": "Праверка абмежаванняў выявіла парушэнне. Калі ласка, націсніце на іконку для падрабязнай інфармацыі.", + "wbqc-violation-message-not-yet-implemented": "З тэхнічных прычынаў праверка абмежавання «$1» яшчэ не была ўведзеная.", + "wbqc-violation-message-security-reason": "З прычынаў бяспекі ў дадзены час немагчыма праверыць абмежаванне «$1». Мы працуем над рашэннем.", + "wbqc-violation-message-value-needed-of-type": "Уласцівасці з абмежаваннем «$1» мусяць мець значэнні тыпу «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Уласцівасці з абмежаваннем «$1» мусяць мець значэнні тыпу «$2» ці «$3».", + "wbqc-violation-message-parameter-needed": "Уласцівасці з абмежаваннем \"$1\" патрабуюць параметр \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Уласцівасці з абмежаваннем «$1» патрабуюць параметраў «$2», «$3» ды «$4».", + "wbqc-violation-message-target-entity-must-exist": "Мэтавая сутнасць мусіць існаваць.", + "wbqc-violation-message-value-entity-must-exist": "Сутнасць значэння мусіць існаваць.", + "wbqc-violation-message-parameter-value": "Параметр \"$1\" павінен мець карыстальніцкае значэнне, не «няма значэння» або «невядомае значэнне».", + "wbqc-violation-message-parameter-value-or-novalue": "Параметр \"$1\" павінен мець карыстальніцкае значэнне або «няма значэння», але ніяк не «невядомае значэнне».", + "wbqc-violation-message-parameter-entity": "Значэнне параметра \"$1\" павінна быць сутнасцю, не \"$2\".", + "wbqc-violation-message-parameter-item": "Значэнне парамэтру «$1» мусіць быць элементам, а не «$2».", + "wbqc-violation-message-parameter-property": "Значэнне парамэтру «$1» мусіць быць уласцівасцю, а не «$2».", + "wbqc-violation-message-parameter-string": "Значэнне парамэтру «$1» мусіць быць радком, а не «$2».", + "wbqc-violation-message-parameter-monolingualtext": "Значэнне парамэтру «$1» мусіць быць аднамоўным тэкстам, а не «$2».", + "wbqc-violation-message-parameter-single": "Параметр \"$1\" павінен мець толькі адзінае значэнне.", + "wbqc-violation-message-parameter-single-per-language": "Параметр \"$1\" павінен мець толькі адно значэнне для кожнай мовы, але мае множныя значэнні для $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Параметр \"$1\" павінен быць {{PLURAL:$2|1=$4.|2=$4 або $5.|адным з наступных:$3}}", + "wbqc-violation-message-parameter-regex": "$1 — няслушны рэгулярны выраз.", + "wbqc-violation-message-sparql-error": "Запыт SPARQL выдаў памылку.", + "wbqc-violation-message-parameters-error-unknown": "Параметры гэтага абмежавання не могуць быць імпартаваныя.", + "wbqc-violation-message-parameters-error-toolong": "Параметры гэтага абмежавання не могуць быць імпартаваныя, бо яны надта доўгія.", + "wbqc-violation-message-invalid-scope": "$1 не з’яўляецца дапушчальнай вобласцю дзеяння для тыпу абмежавання $2; {{PLURAL:$3|дапушчальнай вобласцю дзеяння|дапушчальнымі абласцямі дзеяння}} для гэтага тыпу абмежавання {{PLURAL:$3|з’яўляецца толькі $5.|2=з’яўляюцца $5 і $6.|з’яўляюцца: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Павінна існаваць спасылка на Вікісховішча.", + "wbqc-violation-message-commons-link-not-well-formed": "Спасылка на Вікісховішча павінна быць карэктнай.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Праверка для прасторы \"$1\" яшчэ не рэалізавана.", + "wbqc-violation-message-conflicts-with-property": "Сутнасць не павінна мець сцверджанні адначасова для $1 і $2.", + "wbqc-violation-message-conflicts-with-claim": "Сутнасць не павінна мець сцверджання $1, калі яна ўжо мае сцверджанне $2 са значэннем $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Сутнасці $1 і $3 мусяць быць сучаснікамі, каб быць звязанымі праз $2, аднак апошнім канцавым значэннем для $1 з’яўляецца $4, а першым пачатковым значэннем для $3 з’яўляецца $5.", + "wbqc-violation-message-contemporary-value-earlier": "Сутнасці $1 і $3 мусяць быць сучаснікамі, каб быць звязанымі праз $2, аднак апошнім канцавым значэннем для $3 з’яўляецца $4, а першым пачатковым значэннем для $1 з’яўляецца $5.", + "wbqc-violation-message-diff-within-range": "Розніца паміж $3 ($4) і $1 ($2) павінна знаходзіцца паміж $5 і $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Розніца паміж $3 ($4) і $1 ($2) павінна быць не больш за $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Розніца паміж $3 ($4) і $1 ($2) павінна быць не менш за $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Уласцівасць, аб’яўленая ў параметрах, павінна мець значэнне таго ж тыпу, што і гэтая ўласцівасць.", + "wbqc-violation-message-format": "Значэнне для ўласцівасці $1 ($2) павінна адпавядаць рэгулярнаму выразу $3.", + "wbqc-violation-message-format-clarification": "Значэнне для ўласцівасці $1 ($2) павінна адпавядаць «$4» (рэгулярны выраз: $3).", + "wbqc-violation-message-inverse": "Элемент $1 павінен мець адваротнае сцверджанне $2 $3.", + "wbqc-violation-message-item": "Сутнасць з $1 павінна таксама мець {{PLURAL:$3|0=сцверджанне $2.|1=сцверджанне $2 $5.|сцверджанне для $2 з адным з наступных значэнняў:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Сцверджанне $1 не мае кваліфікатара $2.", + "wbqc-violation-message-multi-value": "Гэтая ўласцівасць мусіць мець некалькі значэнняў.", + "wbqc-violation-message-multi-value-separators": "Гэтая ўласцівасць мусіць мець некалькі значэнняў з {{PLURAL:$2|1=тым самым кваліфікатарам $4.|наборам кваліфікатараў для гэтых уласцівасцей: $3}}", + "wbqc-violation-message-one-of": "Значэнне для $1 мусіць быць {{PLURAL:$2|1=$4|2=або $4 або $5.|адным з наступных: $3}}", + "wbqc-violation-message-qualifier": "Уласцівасць павінна выкарыстоўвацца толькі ў якасці кваліфікатара.", + "wbqc-violation-message-no-qualifiers": "Сцверджанні $1 не павінны мець кваліфікатараў.", + "wbqc-violation-message-qualifiers": "$2 не з’яўляецца дапушчальным кваліфікатарам для $1 – {{PLURAL:$3|1=дапушчальны толькі кваліфікатар $5.|2=дапушчальныя толькі кваліфікатары $5 і $6.|дапушчальныя толькі наступныя кваліфікатары:$4}}", + "wbqc-violation-message-range-parameters-needed": "Уласцівасць з значэннямі тыпу «$1» з абмежаваннем «$4» патрабуюць параметры «$2» і «$3».", + "wbqc-violation-message-range-parameters-one-year": "Канчатковыя кропкі дыяпазону адзінак часу мусяць ці зусім не мець, ці абедзве мець адзінку «год», паколькі гады немажліва ператварыць без страт у сэкунды.", + "wbqc-violation-message-range-parameters-same": "Пачатковая ($1) і канчатковая ($2) кропкі дыяпазону не могуць быць аднолькавымі.", + "wbqc-violation-message-range-quantity-closed": "Значэнне для $1 ($2) павінна знаходзіцца паміж $3 і $4.", + "wbqc-violation-message-range-quantity-leftopen": "Значэнне для $1 ($2) павінна быць не болей за $3.", + "wbqc-violation-message-range-quantity-rightopen": "Значэнне для $1 ($2) павінна быць не меней за $3.", + "wbqc-violation-message-range-time-closed": "Значэнне для $1 ($2) павінна знаходзіцца паміж $3 і $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Значэнне для $1 ($2) павінна быць у будучыні, але не пазней за $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Значэнне для $1 ($2) павінна быць у мінулым, але не раней за $3.", + "wbqc-violation-message-range-time-leftopen": "Значэнне для $1 ($2) павінна быць не пазней за $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Значэнне для $1 ($2) не павінна быць у будучыні.", + "wbqc-violation-message-range-time-rightopen": "Значэнне для $1 ($2) павінна быць не раней за $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Значэнне для $1 ($2) не павінна быць у мінулым.", + "wbqc-violation-message-single-value": "Гэтая ўласцівасць павінна змяшчаць толькі адно значэнне.", + "wbqc-violation-message-single-value-separators": "Гэта ўласцівасць павінна мець адзінае значэнне з такім жа {{PLURAL:$2|1=кваліфікатарам $4.|наборам кваліфікатараў для гэтых уласцівасцей: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Гэта ўласцівасць павінна змяшчаць адно «найлепшае» значэнне. Адно з цяперашніх множных значэнняў мусіць мець «пераважны» ранг.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Гэта ўласцівасць павінна змяшчаць адно «найлепшае» значэнне з тым жа {{PLURAL:$2|1=кваліфікатарам $4.|наборам кваліфікатараў для ўласцівасцей: $3}} Адно з цяперашніх множных значэнняў мусіць мець «пераважны» ранг.", + "wbqc-violation-message-single-best-value-multi-preferred": "Гэтая ўласцівасць мусіць мець адно «найлепшае» значэнне. Значэнне з «пераважным» рангам мусіць быць не больш за адно.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Гэтая ўласцівасць мусіць мець адно «найлепшае» значэнне з тым самым {{PLURAL:$2|1=кваліфікатарам $4|наборам кваліфікатараў для гэтых уласцівасцей: $3}}. Значэнне з «пераважным» рангам мусіць быць не больш за адно.", + "wbqc-violation-message-symmetric": "Сутнасць $1 павінна таксама мець сіметрычнае сцвярджэнне $2 $3.", + "wbqc-violation-message-type-instance": "Сутнасці, якія выкарыстоўваюць уласцівасць $1, павінны быць экзэмплярамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (ці {{PLURAL:$3|1=яго падкласа|2=іх падкласаў|аднаго з іх падкласаў}}), але $2 зараз {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-type-subclass": "Сутнасці, якія выкарыстоўваюць уласцівасць $1, павінны быць падкласамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (ці {{PLURAL:$3|1=яго падкласа|2=іх падкласаў|аднаго з іх падкласаў}}), але $2 зараз {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Сутнасці, якія выкарыстоўваюць уласцівасць $1, павінны быць экзэмплярамі ці падкласамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (ці {{PLURAL:$3|1=яго падкласа|2=іх падкласаў|аднаго з іх падкласаў}}), але $2 зараз {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-valueType-instance": "Значэнні сцверджанняў $1 павінны быць экзэмплярамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (ці {{PLURAL:$3|1=яго падкласа|2=іх падкласаў|аднаго з іх падкласаў}}), але $2 зараз {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-valueType-subclass": "Значэнні сцверджанняў $1 маюць быць падкласамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (або {{PLURAL:$3|1=ягонага падкласу|2=іхняга падкласу|аднаго з іхніх падкласаў}}), аднак $2 цяпер {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Значэнні сцверджанняў $1 павінны быць экзэмплярамі або падкласамі {{PLURAL:$3|1=$5|2=$5 або $6|аднаго з наступных класаў}} (ці {{PLURAL:$3|1=яго падкласа|2=іх падкласаў|аднаго з іх падкласаў}}), але $2 зараз {{PLURAL:$3|1=такім не з’яўляецца.|2=такім не з’яўляецца.|такім не з’яўляецца: $4}}", + "wbqc-violation-message-target-required-claim": "Элемент $1 павінен мець {{PLURAL:$3|0=сцверджанне $2.|1=сцверджанне $2 $5.|сцверджанне для $2 з адным з наступных значэнняў:$4}}", + "wbqc-violation-message-unique-value": "Значэнне ўласцівасці не павінна сустракацца ні ў якіх іншых элементах, але яно таксама прысутнічае ў {{PLURAL:$1|1=элеменце $3.|2=элементах $3 і $4.|наступных элементах: $2}}", + "wbqc-violation-message-valueOnly": "Уласцівасць павінна выкарыстоўвацца толькі ў якасці асноўнага значэння, не ў якасці кваліфікатара ці ў раздзеле крыніц.", + "wbqc-violation-message-reference": "Уласцівасць павінна выкарыстоўвацца толькі ў раздзеле крыніц, не ў якасці асноўнага значэння ці кваліфікатара.", + "wbqc-violation-message-noBounds": "Значэнні для $1 не павінны мець ніякіх дыяпазонаў.", + "wbqc-violation-message-units-none": "Значэнне для $1 не мусіць мець адзінкі вымярэння.", + "wbqc-violation-message-units": "Значэнне сцвярджэння $1 павінна мець {{PLURAL:$2|1=адзінку вымярэння $4.|2=адзінку вымярэння $4 або $5.|адну з наступных адзінак вымярэння: $3}}", + "wbqc-violation-message-units-or-none": "Значэнне сцвярджэння $1 павінна мець {{PLURAL:$2|1=адзінку вымярэння $4|2=адзінку вымярэння $4 або $5|адну з наступных адзінак вымярэння}} або {{PLURAL:$2|1=не мець адзінкі вымярэння.|2=не мець адзінкі вымярэння.|не мець адзінкі вымярэння: $3}}", + "wbqc-violation-message-entityType": "Уласцівасць $1 не мусіць выкарыстоўвацца з гэтым тыпам сутнасці; {{PLURAL:$2|1=адзіны слушны тып сутнасці — $4.|2=адзіныя слушныя тыпы сутнасці — $4 і $5.|адзіныя слушныя тыпы сутнасці: $3}}", + "wbqc-violation-message-none-of": "Значэнне для $1 не мусіць быць {{PLURAL:$2|1=$4|2=ні $4, ні $5.|адным з наступных: $3}}.", + "wbqc-violation-message-integer": "Значэнні для $1 мусяць быць цэлымі, аднак $2 мае дробную частку.", + "wbqc-violation-message-integer-bounds": "Значэнні для $1 мусяць быць цэлымі, аднак граніцы $2 маюць дробную частку.", + "wbqc-violation-message-citationNeeded": "Сцвярджэнні для ўласцівасці $1 павінны мець найменей адну крыніцу.", + "wbqc-violation-message-language": "Сцверджання для $1 павінны быць толькі на Лексемах, дзе мова — {{PLURAL:$2|1=$4.|$4 ці $5|адна з: $3}}", + "wbqc-violation-message-label-lacking": "Сутнасці з сцверджаннямі для $1 павінны таксама мець метку прынамсі на {{PLURAL:$2|1=мове $4.|адной з наступных моў: $3}}", + "wbqc-violation-message-property-scope": "Уласцівасць $1 не можа быць выкарыстана ў гэтым месцы ($2). {{PLURAL:$3|Адзіным магчымым месцам|Магчымымі месцамі}} для гэтай уласцівасці {{PLURAL:$3|з’яўляецца $5.|з’яўляюцца: $4}}", + "wbqc-violation-message-exception": "Гэтая сутнасць — вядомы вынятак для дадзенага абмежавання і пазначаная такой." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/bg.json b/dist/extensions/WikibaseQualityConstraints/i18n/bg.json new file mode 100644 index 000000000..1f9004910 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/bg.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "StanProg", + "Vlad5250" + ] + }, + "wbqc-constraintreport-result-table-header-message": "Съобщение", + "wbqc-violation-message-sparql-error": "Заявката на SPARQL върна грешка." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/blk.json b/dist/extensions/WikibaseQualityConstraints/i18n/blk.json new file mode 100644 index 000000000..16fd1fe2a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/blk.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "咽頭べさ" + ] + }, + "wbqc-suggestions-short": "ဖေႏကျံႏညဏ်ႏမုꩻဖိုင်ႏ" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/bn.json b/dist/extensions/WikibaseQualityConstraints/i18n/bn.json new file mode 100644 index 000000000..87c0c7f7f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/bn.json @@ -0,0 +1,39 @@ +{ + "@metadata": { + "authors": [ + "Aftabuzzaman", + "আফতাবুজ্জামান" + ] + }, + "wbqc-constraintreport": "সীমাবদ্ধতার প্রতিবেদন", + "wbqc-constraintreport-form-submit-label": "পরীক্ষা করুন", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx বা Pxx", + "wbqc-constraintreport-result-headline": "এর জন্য ফলাফল", + "wbqc-constraintreport-status-violation": "লঙ্ঘন", + "wbqc-constraintreport-status-compliance": "সম্মতি", + "wbqc-constraintreport-status-exception": "ব্যতিক্রম", + "wbqc-constraintreport-status-todo": "করণীয়", + "wbqc-constraintreport-status-warning": "সতর্কীকরণ", + "wbqc-constraintreport-status-suggestion": "পরামর্শ", + "wbqc-constraintreport-result-table-header-status": "অবস্থা", + "wbqc-constraintreport-result-table-header-property": "বৈশিষ্ট্য", + "wbqc-constraintreport-result-table-header-message": "বার্তা", + "wbqc-constraintreport-result-table-header-constraint": "সীমাবদ্ধতা", + "wbqc-constraintreport-result-link-to-claim": "দাবিতে যান", + "wbqc-constraintreport-result-link-to-constraint": "সীমাবদ্ধতায় যান", + "wbqc-constraintreport-no-parameter": "কিছু নয়", + "wbqc-issues-short": "সমস্যা", + "wbqc-issues-long": "এই বিবৃতির কিছু সমস্যা রয়েছে।", + "wbqc-potentialissues-short": "সম্ভাব্য সমস্যা", + "wbqc-potentialissues-long": "এই বিবৃতির কিছু সম্ভাব্য সমস্যা রয়েছে।", + "wbqc-suggestions-short": "পরামর্শসমূহ", + "wbqc-suggestions-long": "এই বিবৃতিটি উন্নত করার জন্য এখানে কিছু পরামর্শ রয়েছে।", + "wbqc-badparameters-short": "খারাপ প্যারামিটার", + "wbqc-constrainttypehelp-short": "সাহায্য", + "wbqc-constraintdiscuss-short": "আলোচনা", + "wbqc-constraintdiscuss-long": "এই সীমাবদ্ধতা সম্পর্কে আলোচনার পাতা", + "wbqc-violation-message-commons-link-no-existent": "কমন্সের সংযোগ বিদ্যমান থাকা উচিত।", + "wbqc-violation-message-commons-link-not-well-formed": "কমন্সের সংযোগ সঠিক-বিন্যাসকৃত হতে হবে।", + "wbqc-violation-message-item": "$1 যুক্ত ভুক্তির {{PLURAL:$3|0=$2 বিবৃতি থাকা উচিত।|1=$2 $5 বিবৃতি থাকা উচিত।|নিন্মলিখিত মানগুলির একটি সহ $2-এর জন্য একটি বিবৃতি থাকা উচিত:$4}}", + "wbqc-violation-message-unique-value": "এই বৈশিষ্ট্যের মান অন্য কোন আইটেমে উপস্থিত থাকতে পারবে না, কিন্তু এটি {{PLURAL:$1|1=$3 এ উপস্থিত রয়েছে।|2=$3 ও $4 এ উপস্থিত রয়েছে।|নিম্নলিখিত আইটেমে উপস্থিত রয়েছে: $2}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/br.json b/dist/extensions/WikibaseQualityConstraints/i18n/br.json new file mode 100644 index 000000000..bb8decd98 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/br.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Dishual" + ] + }, + "wbqc-constraintdiscuss-short": "Kaozeadennoù" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/bs.json b/dist/extensions/WikibaseQualityConstraints/i18n/bs.json new file mode 100644 index 000000000..7a81728c2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/bs.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Emir Mujadzic" + ] + }, + "wbqc-constraintreport-status-exception": "Izuzetak" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/btm.json b/dist/extensions/WikibaseQualityConstraints/i18n/btm.json new file mode 100644 index 000000000..8d0f1a9e8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/btm.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Simartampua" + ] + }, + "wbqc-violation-message-entityType": "Properti $1 inda tola ipake i entitas on should not be used on this type of entity, sada-sadana na valid {{PLURAL:$2|1=tipe entitas ima $4.|2=tipe entitas ima $4 dot $5.|tipe entitas ima: $3}}", + "wbqc-violation-message-none-of": "Nilai ni $1 angkon manjadi {{PLURAL:$2|1=$4.|2=either $4 or $5.|sada tingon na onan:$3}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ca.json b/dist/extensions/WikibaseQualityConstraints/i18n/ca.json new file mode 100644 index 000000000..dec335b8b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ca.json @@ -0,0 +1,90 @@ +{ + "@metadata": { + "authors": [ + "Annamerida", + "Arnaugir", + "F3RaN", + "Fitoschido", + "Jmarchn", + "Macofe", + "Mguix" + ] + }, + "wbqc-constraintreport-explanation-part-one": "Aquesta pàgina especial comprova les restriccions de qualsevol entitat que desitgeu. Les entitats s'obtenen del sistema actiu, de manera que cada infracció de restriccions que corregiu s'eliminarà instantàniament d'aquesta llista.", + "wbqc-constraintreport-explanation-part-two": "Les restriccions s'analitzen a partir d'instruccions sobre propietats cada vegada que s'editen aquestes declaracions, normalment en pocs minuts.", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx o Pxx", + "wbqc-constraintreport-result-headline": "Resultat de", + "wbqc-constraintreport-status-violation": "Violació", + "wbqc-constraintreport-status-exception": "Excepció", + "wbqc-constraintreport-status-suggestion": "Suggeriment", + "wbqc-constraintreport-result-table-header-status": "Estat", + "wbqc-constraintreport-result-table-header-property": "Propietat", + "wbqc-constraintreport-result-table-header-message": "Missatge", + "wbqc-constraintreport-no-parameter": "cap", + "wbqc-potentialissues-short": "Possibles problemes", + "wbqc-suggestions-short": "Suggeriments", + "wbqc-constrainttypehelp-short": "Ajuda", + "wbqc-constraintdiscuss-short": "Discussió", + "wbqc-cached-generic": "Aquest resultat està emmagatzemat a la memòria cau i pot estar desactualitzat.", + "wbqc-cached-minutes": "Aquest resultat està emmagatzemat a la memòria cau i pot estar desactualitzat fins a {{PLURAL:$1|1=un minut|$1 minuts}}.", + "wbqc-cached-hours": "Aquest resultat està emmagatzemat a la memòria cau i pot estar desactualitzat fins a {{PLURAL:$1|1=una hora|$1 hores}}.", + "wbqc-cached-days": "Aquest resultat està emmagatzemat a la memòria cau i pot estar desactualitzat fins a {{PLURAL:$1|1=un dia|$1 dies}}.", + "wbqc-dataValueType-wikibase-entityid": "Id. d’entitat", + "wbqc-violation-header-parameters": "Paràmetres:", + "wbqc-violations-group": "Restriccions", + "wbqc-violation-message-not-yet-implemented": "Per raons tècniques, la comprovació de la restricció \"$1\" encara no ha estat implementada.", + "wbqc-violation-message-parameter-entity": "El valor del paràmetres \"$1\" ha de ser una entitat, no \"$2\".", + "wbqc-violation-message-parameter-item": "El valor del paràmetre \"$1\" ha de ser un element, no \"$2\".", + "wbqc-violation-message-parameter-property": "El valor del paràmetre \"$1\" ha de ser una propietat, no \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "El valor del paràmetre \"$1\" ha de ser un text monolingüe, no \"$2\".", + "wbqc-violation-message-parameter-single": "El paràmetre \"$1\" ha de tenir un sol valor.", + "wbqc-violation-message-parameter-single-per-language": "El paràmetre \"$1\" ha de tenir només un sol valor per idioma, però té múltiples valors per $2 ($3).", + "wbqc-violation-message-parameter-oneof": "El paràmetre \"$1\" ha de ser {{PLURAL:$2|1=$4.|2=o $4 o bé $5.|un dels següents: $3}}", + "wbqc-violation-message-parameter-regex": "$1 no és una expressió regular vàlida.", + "wbqc-violation-message-invalid-scope": "$1 no és un abast vàlid pel tipus de restricció $2; {{PLURAL:$3|l'únic abast vàlid|els únics abasts vàlids}} per aquest tipus de restricció {{PLURAL:$3|és $5.|2=són $5 i$6.|són: $4}}", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "La verificació de l'espai de noms \"$1\" encara no ha sigut implementada.", + "wbqc-violation-message-conflicts-with-property": "Una entitat no hauria de tenir declaracions per $1 i $2 alhora.", + "wbqc-violation-message-conflicts-with-claim": "Una entitat no hauria de tenir una declaració per $1 si també té una declaració per $2 amb valor $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Les entitats $1 i $3 haurien de ser contemporànies per estar enllaçades mitjançant $2, però el valor final més tardà de $1 és $4, i el més valor inicial més primerenc de $3 és $5.", + "wbqc-violation-message-contemporary-value-earlier": "Les entitats $1 i $3 haurien de ser contemporànies per estar enllaçades mitjançant $2, però el valor final més tardà de $3 és $4, i el més valor inicial més primerenc de $1 és $5.", + "wbqc-violation-message-diff-within-range": "La diferència entre $3 ($4) i $1 ($2) hauria de ser entre $5 i $6.", + "wbqc-violation-message-diff-within-range-leftopen": "La diferència entre $3 ($4) i $1 ($2) no hauria de ser més de $5.", + "wbqc-violation-message-diff-within-range-rightopen": "La diferència entre $3 ($4) i $1 ($2) hauria de ser menor que $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "La propietat definida en els paràmetres ha de tenir un valor del mateix tipus que aquesta propietat.", + "wbqc-violation-message-format": "El valor de $1 ($2) hauria de complir l'expressió regular $3.", + "wbqc-violation-message-format-clarification": "El valor de $1 ($2) hauria de complir “$4” (expressió regular: $3).", + "wbqc-violation-message-inverse": "$1 també hauria de tenir la declaració inversa $2 $3.", + "wbqc-violation-message-item": "Una entitat amb $1 també hauria de tenir {{PLURAL:$3|0=una declaració $2.|1=una declaració $2 $5.|una declaració per $2 amb un dels següents valors: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Falta el qualificador $2 d'aquesta declaració $1.", + "wbqc-violation-message-multi-value": "Aquesta propietat hauria de contenir múltiples valors.", + "wbqc-violation-message-one-of": "El valor de $1 hauria de ser {{PLURAL:$2|1=$4.|2=o $4 o bé $5.|un dels següents: $3}}", + "wbqc-violation-message-qualifier": "La propietat només hauria de ser utilitzada com a qualificador.", + "wbqc-violation-message-no-qualifiers": "Les declaracions de $1 no haurien de tenir cap qualificador.", + "wbqc-violation-message-qualifiers": "$2 no és un qualificador vàlid de $1; {{PLURAL:$3|1=l'únic qualificador vàlid és $5.|2=els únics qualificadors vàlids són $5 i $6.|els únics qualificadors vàlids són: $4}}", + "wbqc-violation-message-range-quantity-closed": "El valor de $1 ($2) ha d'estar entre $3 i $4.", + "wbqc-violation-message-range-time-closed-rightnow": "El valor de $1 ($2) hauria de situar-se en el passat, però no pas abans de $3.", + "wbqc-violation-message-single-value": "Aquesta propietat només hauria de contenir un sol valor.", + "wbqc-violation-message-single-value-separators": "Aquesta propietat només hauria de tenir un sol valor amb {{PLURAL:$2|1=el mateix qualificador $4.|el mateix conjunt de qualificadors per aquestes propietats: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Aquesta propietat hauria de contenir un sol valor «principal». De tots els múltiples valors actuals, un s'hauria de marcar amb rang «preferit».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Aquesta propietat hauria de contenir un sol valor «principal» amb el mateix {{PLURAL:$2|1=qualificador $4.|conjunt de qualificadors per aquestes propietats: $3}}. De tots els múltiples valors actuals, només un hauria d'estar marcat amb el rang «preferit».", + "wbqc-violation-message-single-best-value-multi-preferred": "Aquesta propietat hauria de contenir un sol valor «principal». No hi hauria d'haver més d'un valor amb rang «preferit».", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Aquesta propietat hauria de contenir un sol valor «principal» amb el mateix {{PLURAL:$2|1=qualificador $4.|conjunt de qualificadors per aquestes propietats: $3}}. No hi hauria d'haver més d'un valor amb el rang «preferit».", + "wbqc-violation-message-symmetric": "$1 també hauria de tenir la declaració simètrica $2 $3.", + "wbqc-violation-message-type-instance": "Les entitats que utilitzin la propietat $1 haurien de ser instàncies {{PLURAL:$3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:$3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-type-subclass": "Les entitats que utilitzin la propietat $1 haurien de ser subclasses {{PLURAL:de $3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:de $3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Les entitats que utilitzin la propietat $1 haurien de ser instàncies o subclasses {{PLURAL:$3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:$3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-valueType-instance": "Els valors de les declaracions de $1 haurien de ser instàncies {{PLURAL:de $3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:de $3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-valueType-subclass": "Els valors de les declaracions de $1 haurien de ser subclasses {{PLURAL:$3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:$3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Els valors de les declaracions de $1 haurien de ser instàncies o subclasses {{PLURAL:de $3|1=de $5|2=de $5 o $6|d'una de les següents classes}} (o {{PLURAL:de $3|1=d'una subclasse seva|2=d'una subclasse seva|d'una de les seves subclasses}}), però $2 ara mateix {{PLURAL:$3|1=no ho és.|2=no ho és.|no ho és: $4}}", + "wbqc-violation-message-target-required-claim": "$1 hauria de tenir {{PLURAL:$3|0=una declaració $2.|1=una declaració $2 $5.|una declaració per $2 amb un dels següents valors: $4}}", + "wbqc-violation-message-unique-value": "El valor d'aquesta propietat no pot estar present en cap altre element, però també està present {{PLURAL:$1|1=a $3.|2=a $3 i $4.|als elements següents: $2}}", + "wbqc-violation-message-valueOnly": "Aquesta propietat només hauria de ser utilitzada pel valor principal d'una declaració, no pas per qualificadors o referències.", + "wbqc-violation-message-reference": "La propietat només s'hauria de fer servir en referències, no pel valor principal d'una declaració o qualificador.", + "wbqc-violation-message-noBounds": "Els valors de $1 no haurien de tenir límits.", + "wbqc-violation-message-units": "El valor de $1 hauria de tenir {{PLURAL:$2|1=la unitat $4.|2=les unitats $4 o $5.|una de les següents unitats: $3}}", + "wbqc-violation-message-units-or-none": "El valor de $1 hauria de tenir {{PLURAL:$2|1=la unitat $4|2=les unitats $4 o $5|una de les següents unitats}} o {{PLURAL:$2|1=no tenir-ne.|2=no tenir-ne.|no tenir-ne: $3}}", + "wbqc-violation-message-entityType": "La propietat $1 no s'hauria d'utilitzar en aquest tipus d'entitat, {{PLURAL:$2|1=l'únic tipus d'entitat vàlid és $4.|2=els únics tipus d'entitat vàlids són $4 i $5.|els únics tipus d'entitat vàlids són: $3}}", + "wbqc-violation-message-citationNeeded": "Les declaracions de $1 haurien de tenir com a mínim una referència.", + "wbqc-violation-message-property-scope": "La propietat $1 no s'hauria d'utilitzar aquí ($2). {{PLURAL:$3|L'únic lloc vàlid|Els únics llocs vàlids}} per aquesta propietat {{PLURAL:$3|és $5.|són: $4}}", + "wbqc-violation-message-exception": "Aquesta entitat és una excepció coneguda d'aquesta restricció i ha estat marcada com a tal." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ce.json b/dist/extensions/WikibaseQualityConstraints/i18n/ce.json new file mode 100644 index 000000000..d7c0fbc36 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ce.json @@ -0,0 +1,146 @@ +{ + "@metadata": { + "authors": [ + "Умар" + ] + }, + "wbqc-constraintreport": "Дозанаш тохарах отчет", + "wbqc-desc": "Элементийн а, билгалонийн а тӀехь а дехкарш дуйла хьожу, жамӀ гойту белхан агӀонан тӀехь.", + "wbqc-constraintreport-explanation-part-one": "ХӀокху билхан агӀоно муьлхха а луш йолчу духан дехкарш таллар кхочушдо. Духаш дийна дӀайуьзна йу, цундела нисдина низамаш дохор сихха дӀадер ду оцу могӀам тӀера.", + "wbqc-constraintreport-explanation-part-two": "Дехкарш кхочушдо дӀахьедаршкара билгалонан агӀонаш тӀехь уьш хийца ма делехь — дукхахьолахь масех минотехь дӀадоьду.", + "wbqc-constraintreport-form-section": "Духан дехкарш толла", + "wbqc-constraintreport-form-submit-label": "Талла", + "wbqc-constraintreport-form-entityid-label": "Духан идентификатор:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx йа Pxx", + "wbqc-constraintreport-result-headline": "ЖамӀ", + "wbqc-constraintreport-invalid-entity-id": "Духан нийса йоцу идентификатор.", + "wbqc-constraintreport-not-existent-entity": "Иштта хӀума йац.", + "wbqc-constraintreport-empty-result": "ХӀокху духан дехкарш билгалдаьхна дац.", + "wbqc-constraintreport-status-violation": "Дохор", + "wbqc-constraintreport-status-compliance": "Цхьаьнадар", + "wbqc-constraintreport-status-exception": "Йукъардакхар", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Нийса йоцу параметраш", + "wbqc-constraintreport-status-deprecated": "Ширйелла", + "wbqc-constraintreport-status-warning": "ДӀахьедар", + "wbqc-constraintreport-status-suggestion": "Хьехам", + "wbqc-constraintreport-status-not-in-scope": "Ардамашна арахьа", + "wbqc-constraintreport-result-table-header-status": "Статус", + "wbqc-constraintreport-result-table-header-property": "Башхалла", + "wbqc-constraintreport-result-table-header-message": "Хаам", + "wbqc-constraintreport-result-table-header-constraint": "Дозатохарш", + "wbqc-constraintreport-result-link-to-claim": "тӀечӀагӀдаре гӀо", + "wbqc-constraintreport-result-link-to-constraint": "дозатохаре гӀо", + "wbqc-constraintreport-no-parameter": "хӀан-хӀа", + "wbqc-issues-short": "Проблемаш", + "wbqc-issues-long": "Цхьа могӀа проблемаш йу оцу дӀахьедарца.", + "wbqc-potentialissues-short": "Хила тарлуш йолу проблемаш", + "wbqc-potentialissues-long": "Цхьа могӀа проблемаш хила тарло оцу дӀахьедарца.", + "wbqc-suggestions-short": "Кховдийнарш", + "wbqc-suggestions-long": "ХӀара дӀахьедар тодаран хьехамаш.", + "wbqc-badparameters-short": "Нийса йоцу параметраш", + "wbqc-badparameters-long": "ХӀокху дехкаран цхьайолу параметраш нийса ца хӀиттийна.", + "wbqc-parameterissues-short": "Кхин а проблемаш", + "wbqc-parameterissues-long": "ХӀара проблемаш йоьзна йу билгалонан агӀонан тӀехь дехкар билгалдаккхарца, хӀокху дӀахьедарца йоьзна йац.", + "wbqc-constrainttypehelp-short": "ГӀо", + "wbqc-constrainttypehelp-long": "ХӀокху тайпана кхачамбацаршна гӀоьналлин агӀо", + "wbqc-constraintdiscuss-short": "Дийцаре дилла", + "wbqc-constraintdiscuss-long": "ХӀокху дозатохаран дийцарийн агӀо", + "wbqc-cached-generic": "ЖамӀ кэшехь ду, тӀаьхьа дуьсуш хила тарло.", + "wbqc-cached-minutes": "ЖамӀ кэшехь ду, {{PLURAL:$1|1=цхьа минот|$1 минот}} тӀаьхьа диса тарло.", + "wbqc-cached-hours": "ЖамӀ кэшехь ду, {{PLURAL:$1|1=цхьа сахьт|$1 минот}} тӀаьхьа диса тарло.", + "wbqc-cached-days": "ЖамӀ кэшехь ду, {{PLURAL:$1|1=цхьа де|$1 де}} тӀаьхьа диса тарло.", + "wbqc-dataValueType-wikibase-entityid": "Духан идентификатор", + "wbq-subextension-name-wbqc": "Дозатохарш", + "wbqc-violation-header-parameters": "Параметраш:", + "wbqc-violations-group": "Дозатохарш", + "wbqc-violation-message": "Дозатохар толлуш талхор гучудаьлла. Кхин тӀе информаци веназин тӀетаӀийна хьажа.", + "wbqc-violation-message-not-yet-implemented": "Техникин бахьанашца, «$1» дозатохар толлуш хӀинца а кхочушдина дац.", + "wbqc-violation-message-security-reason": "Кхерамазаллин бахьанашца, «$1» дозатохар хӀинца тӀекхочуш дац. И проблема дӀайоккхуш болх беш ду тхо.", + "wbqc-violation-message-value-needed-of-type": "«$1» дехкарш долу билгалонаш «$2» тайпанан маьӀна долуш хила йеза.", + "wbqc-violation-message-value-needed-of-types-2": "«$1» дехкарш долу билгалонаш «$2» йа «$3» тайпанан маьӀнаш долуш хила йеза.", + "wbqc-violation-message-parameter-needed": "Дехкарш долу «$1» билгалонашна оьшу «$2» параметр.", + "wbqc-violation-message-parameters-needed-3": "Дехкарш долу «$1» билгалонашна оьшу «$2», «$3», «$4». параметраш.", + "wbqc-violation-message-target-entity-must-exist": "Ӏалашонан хӀума хила йезаш йу.", + "wbqc-violation-message-value-entity-must-exist": "МаьӀнан хӀума хила йезаш йу.", + "wbqc-violation-message-parameter-value": "«$1» параметран маьӀна хӀоттийна хила деза, «маьӀна дац» йа «маьӀна девзаш дац» хӀотто ца деза.", + "wbqc-violation-message-parameter-value-or-novalue": "«$1» параметран маьӀна йаздина йа хӀоттина хила деза «маьӀна дац» аьлла, хила ца деза «маьӀна девза дац».", + "wbqc-violation-message-parameter-entity": "«$1» параметран маьӀна хӀума хила деза, «$2» хила ца деза.", + "wbqc-violation-message-parameter-item": "«$1» параметран маьӀна элемент хила деза, «$2» хила ца деза.", + "wbqc-violation-message-parameter-property": "«$1» параметран маьӀна башхалла хила деза, «$2» хила ца деза.", + "wbqc-violation-message-parameter-string": "«$1» параметран маьӀна могӀанан хила деза, «$2» хила ца деза.", + "wbqc-violation-message-parameter-monolingualtext": "«$1» параметран маьӀна текст йеза, «$2» хила ца йеза.", + "wbqc-violation-message-parameter-single": "«$1» параметран чохь цхьа маьӀна хила деза.", + "wbqc-violation-message-parameter-single-per-language": "«$1» параметрехь цхьа маьӀна хила деза хӀора маттахь, амма $2 маттана ($3) масех маьӀна билгалдаьккхина ду.", + "wbqc-violation-message-parameter-oneof": "«$1» параметран {{PLURAL:$2|1=$4 маьӀна хила деза.|2=$4 йа $5 маьӀна хила деза.|рогӀерчу маьӀнехь цхьаъ хила деза:$3}}", + "wbqc-violation-message-parameter-regex": "$1 нийса рогӀера алар дац.", + "wbqc-violation-message-sparql-error": "SPARQL хаттаро гӀалат делла.", + "wbqc-violation-message-parameters-error-unknown": "ХӀокху дехкаран параметраш импорт йан аьтто ца баьлла.", + "wbqc-violation-message-parameters-error-toolong": "ХӀокху дехкаран параметраш импорт йан аьтто ца баьлла, уьш тӀех йеха хиларна.", + "wbqc-violation-message-invalid-scope": "$1 - $2 тайпанна дехкаран нийса ардамийн меттиг йац; оцу тайпана {{PLURAL:$3|мегаш ду}} {{PLURAL:$3|$5 ардамийн меттигаш.|2=$5 а, $6 а ардамийн меттигаш.|рогӀера ардамийн меттигаш: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Викилармин тӀе хьажорг хила йеза.", + "wbqc-violation-message-commons-link-not-well-formed": "Викилармин тӀе хьажорг нийса кечйина хила йеза.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "«$1» цӀерийн меттигийн таллам хӀинца а кхочушбина бац.", + "wbqc-violation-message-conflicts-with-property": "ХӀуманехь цхьана хенахь хила ца деза $1 а, $2 а дӀахьедарш.", + "wbqc-violation-message-conflicts-with-claim": "Духан чохь хила ца деза $1 чӀагӀдар, нагахь санна $2 чӀагӀдар билгалдаьккхина делахь $3 маьӀна долуш.", + "wbqc-violation-message-contemporary-subject-earlier": "$1 а, $3 а хӀуманаш цхьана хенахь хила йеза $2-ца зӀе латто, амма $1 чекхдолу $4-ца, $3 дӀадолало $5-ца.", + "wbqc-violation-message-contemporary-value-earlier": "$1 а, $3 а хӀуманаш цхьана хенахь хила йеза $2-ца зӀе латто, амма $3 чекхдолу $4-ца, $1 дӀадолало $5-ца.", + "wbqc-violation-message-diff-within-range": "$3 ($4) а, $1 ($2) а йукъахь йолу башхалла $5-$6 диапазонехь хила йеза.", + "wbqc-violation-message-diff-within-range-leftopen": "$3 ($4) а, $1 ($2) а йукъахь йолу башхалла $5 сов хила ца йеза.", + "wbqc-violation-message-diff-within-range-rightopen": "$3 ($4) а, $1 ($2) а йукъахь йолу башхалла $5 лахара хила ца йеза.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Параметрашкахь йукъайалийна башхалла цхьана тайпана хила йеза хӀокху башхаллонца.", + "wbqc-violation-message-format": "$1 ($2) маьӀна нийса хила деза $3 рогӀера аларца.", + "wbqc-violation-message-format-clarification": "$1 ($2) маьӀна нийса хила деза «$4» (рогӀера алар: $3).", + "wbqc-violation-message-inverse": "$1 тӀехь хила деза йуханехьа $2 тӀечӀагӀдар $3 маьӀанца.", + "wbqc-violation-message-item": "$1 билгало йолучу духан хила деза {{PLURAL:$3|0=$2 дӀахьедар.|1=$2 дӀахьедар $5 маьӀна долу.|$2 дӀахьедар рогӀера маьӀнех цхьаъ долуш:$4}}", + "wbqc-violation-message-mandatory-qualifier": "ХӀокху $1 дӀахьедарехь йац $2 квалификатор.", + "wbqc-violation-message-multi-value": "ХӀара билгало масех маьӀна долуш хила йеза.", + "wbqc-violation-message-multi-value-separators": "ХӀокху билгалонан йукъахь масех маьӀна хила деза цхьатерра {{PLURAL:$2|1=$4 квалификатор йолуш.|квалификаторийн тоба йолуш: $3}}", + "wbqc-violation-message-one-of": "$1 билгалонан хила деза {{PLURAL:$2|1=$4 маьӀна.|2=$4 йа $5 маьӀна.|рогӀера маьӀнех цхаъ:$3}}", + "wbqc-violation-message-qualifier": "ХӀара башхалла лело йеза квалификатор санна.", + "wbqc-violation-message-no-qualifiers": "«$1» дӀахьедарна лерина квалификацеш йац.", + "wbqc-violation-message-qualifiers": "«$2» — нийса йоцу квалификатор йу «$1»; {{PLURAL:$3|1=\"$5\" бен нийса хира йац.|2=«$5» а, «$6» а бен нийса хира йац.|нийса квалификацеш:$4}}", + "wbqc-violation-message-range-parameters-needed": "«$1» тайпана маьӀнаш долу а, «$4» дехкарш долу а билгалонийн «$2» а, «$3» а параметраш хила йеза.", + "wbqc-violation-message-range-parameters-one-year": "Хенан диапазонан дозанашкахь йа шинне а хила деза барамийн цхьаьнакхетаралла «шо», йа шинне а хила ца деза иза, хӀунда аьлча шераш секундашка дерзо йиш йац, нийсалла ца дойуш.", + "wbqc-violation-message-range-parameters-same": "Диапазонан йуьхь ($1) а, чаккхе ($2) а цхьатерра хила ца йеза.", + "wbqc-violation-message-range-quantity-closed": "$1 ($2) маьӀна $3-$4 диапазонехь хила деза.", + "wbqc-violation-message-range-quantity-leftopen": "$1 ($2) маьӀна $3 сов хила ца деза.", + "wbqc-violation-message-range-quantity-rightopen": "$1 ($2) маьӀна $3 лахара хила ца деза.", + "wbqc-violation-message-range-time-closed": "$1 ($2) маьӀна $3-$4 диапазонехь хила деза.", + "wbqc-violation-message-range-time-closed-leftnow": "$1 ($2) маьӀна тӀейогӀучу хенахь хила деза, амма $3 тӀаьхьа хила ца деза.", + "wbqc-violation-message-range-time-closed-rightnow": "$1 ($2) маьӀна дӀайаханчу хенахь хила деза, амма $3 хьалха хила ца деза.", + "wbqc-violation-message-range-time-leftopen": "$1 ($2) маьӀна $3 тӀаьхьа хила ца деза.", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1 ($2) маьӀна тӀейогӀучу хенахь хила ца деза.", + "wbqc-violation-message-range-time-rightopen": "$1 ($2) маьӀна $3 хьалха хила ца деза.", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1 ($2) маьӀна дӀайаханчу хенахь хила ца деза.", + "wbqc-violation-message-single-value": "ХӀокху билгалонан цхьа маьӀна бен хила деза.", + "wbqc-violation-message-single-value-separators": "ХӀокху билгалонан масех маьӀна хила йиш йац цхьатерра {{PLURAL:$2|1=$4 квалификатор йолуш.|квалификаторийн тоба йолуш: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "ХӀокху билгалонан цхьа «уггаре а дика» маьӀна хила деза. «ГӀоле хета ранг» дӀайала йеза карарчу хенахь долчу цхьанна маьӀанан.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "ХӀокху билгалонан цхьа «уггаре дика» маьӀна хила деза хӀора {{PLURAL:$2|1=$4 квалификаторна.|квалификаторан тобана: $3}} «ГӀоле хета ранг» дӀайала йеза карарчу хенахь долчу маьӀнийн йукъара цхьанна.", + "wbqc-violation-message-single-best-value-multi-preferred": "ХӀокху билгалонан цхьа «уггаре а дика» маьӀна хила деза. «ГӀоле хета ранг» йолу масех маьӀна тӀекхочуш дац.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "ХӀокху билгалонан цхьа «уггаре дика» маьӀна хила деза хӀора {{PLURAL:$2|1=$4 квалификаторна.|квалификаторан тобана: $3}} «ГӀоле хета ранг» йоллу массех маьӀна тӀекхочуш дац.", + "wbqc-violation-message-symmetric": "$1 а хила деза $2 тера дӀахьедар $3 маьӀна долуш.", + "wbqc-violation-message-type-instance": "$1 чӀагӀдар долу хӀуманаш хила йеза {{PLURAL:$3|1=$5|2=$5 йа $6|рогӀера классех цхьаъ}} тайпа (йа {{PLURAL:$3|1=цуьнан бухара классаш|2=цуьнан бухара классаш|церан цхьаъ бухара класс}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг дац.|2=ишттаниг дац.|царех цхьанна а йукъа ца догӀу: $4}}", + "wbqc-violation-message-type-subclass": "$1 чӀагӀдар долу хӀуманаш хила йеза {{PLURAL:$3|1=$5|2=$5 йа $6|хӀокху классех цхьанна}} бухара класс (йа {{PLURAL:$3|1=цуьнан бухара классех|2=цуьнан бухара классех|церан бухара классех цхьаъ}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг дац.|2=ишттаниг дац.|цхьанна а йукъа ца догӀу: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "$1 чӀагӀдар долу хӀуманаш хила йеза тайпа йа бухара класс {{PLURAL:$3|1=$5|2=$5 йа $6|рогӀера классех цхьанна}} (йа {{PLURAL:$3|1=цуьнан бухара классаш|2= цуьнан бухара классаш|церан бухара классех цхьаъ}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг йац.|2=ишттаниг йац.|царех цхьанна а йукъа ца йогӀу: $4}}", + "wbqc-violation-message-valueType-instance": "$1 чӀагӀдаран маьӀна хила деза {{PLURAL:$3|1=$5|2=$5 йа $6|рогӀера классех цхьаъ}} тайпа (йа {{PLURAL:$3|1=цуьнан бухара классаш|2=цуьнан бухара классаш|церан цхьаъ бухара класс}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг дац.|2=ишттаниг дац.|царех цхьанна а йукъа ца догӀу: $4}}", + "wbqc-violation-message-valueType-subclass": "$1 чӀагӀдаран маьӀна хила деза {{PLURAL:$3|1=$5|2=$5 йа $6|хӀокху классех цхьанна}} бухара класс (йа {{PLURAL:$3|1=цуьнан бухара классех|2=цуьнан бухара классех|церан бухара классех цхьаъ}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг дац.|2=ишттаниг дац.|цхьанна а йукъа ца догӀу: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "$1 чӀагӀдаран маьӀна хила йеза элемент йа бухара класс {{PLURAL:$3|1=$5|2=$5 йа $6|рогӀера классех цхьанна}} (йа {{PLURAL:$3|1=цуьнан бухара классаш|2= цуьнан бухара классаш|церан бухара классех цхьаъ}}), амма $2 хӀинца {{PLURAL:$3|1=ишттаниг йац.|2=ишттаниг йац.|царех цхьанна а йукъа ца йогӀу: $4}}", + "wbqc-violation-message-target-required-claim": "«$1» элементехь хила деза {{PLURAL:$3|0=«$2» башхалла йолу дӀахьедар.|1=«$2» башхалла йолу дӀахьедар а, «$5» маьӀна а.|«$2» башхалла йолу дӀахьедар а, цхьаъ маьӀна а:$4}}", + "wbqc-violation-message-unique-value": "ХӀокху билгалонан маьӀна кхечу элементашца цхьатерра хила дезаш дац, амма иза иштта хӀоттийна {{PLURAL:$1|1=$3.|2=$3 а, $4.|рогӀерчу элементашкахь: $2}}", + "wbqc-violation-message-valueOnly": "ХӀара билгало лело йеза коьрта чӀагӀдар санна, квалификатор йа хьост санна лело ца йеза.", + "wbqc-violation-message-reference": "ХӀара билгало лело йеза хьост санна, коьрта дӀахьедар йа квалификатор санна лело ца йеза.", + "wbqc-violation-message-noBounds": "$1 маьӀнан билгалдаьхна дозанаш хила ца деза.", + "wbqc-violation-message-units-none": "$1 маьӀанан барамийн цхьаьнакхетаралла билгалдаккха ца деза.", + "wbqc-violation-message-units": "$1 маьӀнан хила деза {{PLURAL:$2|1=$4 барамийн цхьаьнакхетаралла.|2=$4 ийа $5 барамийн цхьаьнакхетаралла.|рогӀера барамийн цхьаьнакхетараллех цхьаъ: $3}}", + "wbqc-violation-message-units-or-none": "$1 маьӀна барам боцуш хила деза, йа хила деза {{PLURAL:$2|1=$4 барамийн цхьаьнакхетаралла.|2=$4 йа $5 барамийн цхьаьнакхетаралла.|рогӀера барамийн цхьаьнакхетараллех цхьаъ: $3}}", + "wbqc-violation-message-entityType": "$1 билгало лело ца йеза хӀокху тайпанан хӀуманаш тӀехь, {{PLURAL:$2|1=магош долу тайпа $4 бен дац.|2=$4 а, $5 а тайпанаш бен магош дац.|рогӀера тайпанаш магош ду: $3}}", + "wbqc-violation-message-none-of": "$1 билгалонан хила ца деза {{PLURAL:$2|1=$4 маьӀна.|2=$4 йа $5 маьӀна.|рогӀера маьӀнех цхьаа:$3}}", + "wbqc-violation-message-integer": "$1 маьӀна дийнатерахьан хила деза, амма $2 тӀехь доькъуш дакъа ду.", + "wbqc-violation-message-integer-bounds": "$1 маьӀна дийнатерахьан хила деза, амма $2 дозанийн доькъуш дакъа ду.", + "wbqc-violation-message-citationNeeded": "$1 дӀахьедарш цхьана хьостан мукъане тӀетоьвжаш хила деза.", + "wbqc-violation-message-language": "$1 дӀахьедарш {{PLURAL:$2|1=$4 меттан.|2=$4 йа $5 меттан.|рогӀера меттанийн цхьана: $3}} лексемашкахь бен магош дац", + "wbqc-violation-message-label-lacking": "$1 дӀахьедар долчу хӀуманашна йукъахь хила йеза цӀе а {{PLURAL:$2|1=маттахь: $4.|рогӀерчу меттанийн йукъара цхьана маттахь мукъане а: $3}}", + "wbqc-violation-message-property-scope": "$1 билгало лело ца йеза кху ($2) меттигехь. Магийна {{PLURAL:$3|меттиг|меттигаш}} хӀокху билгалонан {{PLURAL:$3|$5 йу.|йу: $4}}", + "wbqc-violation-message-exception": "ХӀара хӀума — хӀокху дехкаран тӀера девзаш долу йукъарадаккхар ду, иштта билгалйаьккхина а йу." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ckb.json b/dist/extensions/WikibaseQualityConstraints/i18n/ckb.json new file mode 100644 index 000000000..4d460658d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ckb.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Arya sarhan", + "Sarchia" + ] + }, + "wbqc-constraintreport-no-parameter": "ھیچیان" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/cs.json b/dist/extensions/WikibaseQualityConstraints/i18n/cs.json new file mode 100644 index 000000000..e9fe1077b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/cs.json @@ -0,0 +1,152 @@ +{ + "@metadata": { + "authors": [ + "Cvanca", + "Danny B.", + "Dvorapa", + "Ilimanaq29", + "Matěj Suchánek", + "Meliganai", + "Mormegil" + ] + }, + "wbqc-constraintreport": "Zpráva o omezeních", + "wbqc-desc": "Kontroluje omezení na položkách a vlastnostech a na speciální stránce zobrazuje výsledky.", + "wbqc-constraintreport-explanation-part-one": "Tato speciální stránka provádí kontrolu omezení na libovolné požadované entitě. Entity se načítají z živého systému, takže každé porušení omezení, které opravíte, se z tohoto seznamu okamžitě odebere.", + "wbqc-constraintreport-explanation-part-two": "Omezení se z výroků u vlastností načítají pokaždé, když jsou upraveny, obvykle do několika minut.", + "wbqc-constraintreport-form-section": "Zkontrolovat omezení u entity", + "wbqc-constraintreport-form-submit-label": "Zkontrolovat", + "wbqc-constraintreport-form-entityid-label": "ID entity:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx nebo Pxx", + "wbqc-constraintreport-result-headline": "Výsledky pro", + "wbqc-constraintreport-invalid-entity-id": "Chybné ID entity.", + "wbqc-constraintreport-not-existent-entity": "Entita neexistuje.", + "wbqc-constraintreport-empty-result": "Pro tuto entitu nejsou definována žádná omezení.", + "wbqc-constraintreport-status-violation": "Porušení", + "wbqc-constraintreport-status-compliance": "Splnění", + "wbqc-constraintreport-status-exception": "Výjimka", + "wbqc-constraintreport-status-todo": "Chybí", + "wbqc-constraintreport-status-bad-parameters": "Nesprávné parametry", + "wbqc-constraintreport-status-deprecated": "Zavržené", + "wbqc-constraintreport-status-warning": "Upozornění", + "wbqc-constraintreport-status-suggestion": "Návrh", + "wbqc-constraintreport-status-not-in-scope": "Mimo rámec", + "wbqc-constraintreport-result-table-header-status": "Stav", + "wbqc-constraintreport-result-table-header-property": "Vlastnost", + "wbqc-constraintreport-result-table-header-message": "Hlášení", + "wbqc-constraintreport-result-table-header-constraint": "Omezení", + "wbqc-constraintreport-result-link-to-claim": "přejít na tvrzení", + "wbqc-constraintreport-result-link-to-constraint": "přejít na omezení", + "wbqc-constraintreport-no-parameter": "není", + "wbqc-issues-short": "Problémy", + "wbqc-issues-long": "Tento výrok má určité problémy.", + "wbqc-potentialissues-short": "Možné problémy", + "wbqc-potentialissues-long": "Toto tvrzení může mít určité problémy.", + "wbqc-suggestions-short": "Návrhy", + "wbqc-suggestions-long": "Jsou k dispozici návrhy pro vylepšení tohoto tvrzení.", + "wbqc-badparameters-short": "Chybné parametry", + "wbqc-badparameters-long": "Některé parametry tohoto tvrzení o omezení jsou neplatné.", + "wbqc-parameterissues-short": "Pokročilé nedostatky", + "wbqc-parameterissues-long": "Tyto nedostatky jsou problémy definice omezení na vlastnosti, nikoli tohoto výroku.", + "wbqc-constrainttypehelp-short": "Nápověda", + "wbqc-constrainttypehelp-long": "Stránka s nápovědou pro tento typ omezení", + "wbqc-constraintdiscuss-short": "Diskuse", + "wbqc-constraintdiscuss-long": "Diskusní stránka k tomuto omezení", + "wbqc-cached-generic": "Tento výsledek pochází z cache a nemusí být aktuální.", + "wbqc-cached-minutes": "Tato odpověď pochází z cache a může být až {{PLURAL:$1|minutu|$1 minuty|$1 minut}} neaktuální.", + "wbqc-cached-hours": "Tento výsledek je cachovaný a může být až {{PLURAL:$1|1=jednu hodinu|$1 hodiny|$1 hodin}} neaktuální.", + "wbqc-cached-days": "Tento výsledek je cachovaný a může být až {{PLURAL:$1|1=jeden den|$1 dny|$1 dní}} neaktuální.", + "wbqc-dataValueType-wikibase-entityid": "ID entity", + "wbq-subextension-name-wbqc": "Omezení", + "wbqc-violation-header-parameters": "Parametry:", + "wbqc-violations-group": "Omezení", + "wbqc-violation-message": "Kontrola omezení objevila porušení. Více informací získáte kliknutím na ikonku.", + "wbqc-violation-message-not-yet-implemented": "Z technických důvodů nebyla kontrola omezení „$1“ dosud implementována.", + "wbqc-violation-message-security-reason": "Omezení „$1“ momentálně z bezpečnostních důvodů nelze kontrolovat. Pracujeme na řešení.", + "wbqc-violation-message-value-needed-of-type": "Vlastnosti s omezením „$1“ musí mít hodnoty typu „$2“.", + "wbqc-violation-message-value-needed-of-types-2": "Vlastnosti s omezením „$1“ potřebují hodnoty typu „$2“ nebo „$3“.", + "wbqc-violation-message-parameter-needed": "Vlastnosti s omezením „$1“ potřebují parametr „$2“.", + "wbqc-violation-message-parameters-needed-3": "Vlastnosti s omezením „$1“ potřebují parametry „$2“, „$3“ a „$4“.", + "wbqc-violation-message-target-entity-must-exist": "Cílová entita musí existovat.", + "wbqc-violation-message-value-entity-must-exist": "Entita v hodnotě musí existovat.", + "wbqc-violation-message-parameter-value": "Parametr „$1“ musí mít nastavenou hodnotu, nikoliv „žádnou“ nebo „neznámou hodnotu“.", + "wbqc-violation-message-parameter-value-or-novalue": "Parametr „$1“ musí mít nastavenou hodnotu nebo „žádnou“ hodnotu, nikdy „neznámou hodnotu“.", + "wbqc-violation-message-parameter-entity": "Hodnota parametru „$1“ musí být entita, nikoliv „$2“.", + "wbqc-violation-message-parameter-item": "Hodnota parametru „$1“ musí být položka, ne „$2“.", + "wbqc-violation-message-parameter-property": "Hodnota parametru „$1“ musí být vlastnost, nikoliv „$2“.", + "wbqc-violation-message-parameter-string": "Hodnota parametru „$1“ musí být řetězec, ne „$2“.", + "wbqc-violation-message-parameter-monolingualtext": "Hodnota parametru „$1“ musí být jednojazyčný text, nikoli „$2“.", + "wbqc-violation-message-parameter-single": "Parametr „$1“ může mít pouze jednu hodnotu.", + "wbqc-violation-message-parameter-single-per-language": "Parametr „$1“ musí mít pro každý jazyk jedinou hodnotu, ale pro jazyk $2 ($3) má hodnot více.", + "wbqc-violation-message-parameter-oneof": "Parametr „$1“ musí být {{PLURAL:$2|1=$4.|2=buď $4, nebo $5.|jedno z následujících:$3}}", + "wbqc-violation-message-parameter-regex": "$1 není platný regulární výraz.", + "wbqc-violation-message-sparql-error": "SPARQL dotaz ukončila chyba.", + "wbqc-violation-message-parameters-error-unknown": "Parametry tohoto omezení se nepodařilo naimportovat.", + "wbqc-violation-message-parameters-error-toolong": "Parametry tohoto omezení se nepodařilo naimportovat, protože jsou příliš velké.", + "wbqc-violation-message-invalid-scope": "$1 není platný rámec pro typ omezení $2; {{PLURAL:$3|jediným platným rámcem|jedinými platnými rámci}} pro tento typ omezení {{PLURAL:$3|je $5.|2=jsou $5 a $6.|jsou: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Cíl odkazu na Commons by měl existovat.", + "wbqc-violation-message-commons-link-not-well-formed": "Odkaz na Commons by měl být ve správném formátu.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Kontrola pro jmenný prostor „$1“ dosud nebyla implementována.", + "wbqc-violation-message-conflicts-with-property": "Entita nemůže mít současně tvrzení vlastností $1 a $2.", + "wbqc-violation-message-conflicts-with-claim": "Entita nemůže mít tvrzení vlastnosti $1, pokud má současně tvrzení vlastnosti $2 s hodnotou $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entity $1 a $3 by měly být současníky, pokud mají být propojeny pomocí $2, ale nejpozdější hodnota konce $1 je $4 a nejdřívější hodnota počátku $3 je $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entity $1 a $3 by měly být současníky, pokud mají být propojeny pomocí $2, ale nejpozdější hodnota konce $3 je $4 a nejdřívější hodnota počátku $1 je $5.", + "wbqc-violation-message-diff-within-range": "Rozdíl mezi vlastnostmi $3 ($4) a $1 ($2) by se měl nacházet v intervalu od $5 do $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Rozdíl mezi vlastnostmi $3 ($4) a $1 ($2) by neměl být větší než $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Rozdíl mezi vlastnostmi $3 ($4) a $1 ($2) by neměl být menší než $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Vlastnost definovaná v parametrech musí mít hodnotu stejného typu jako tato vlastnost.", + "wbqc-violation-message-format": "Hodnota vlastnosti $1 ($2) musí odpovídat regulárnímu výrazu $3.", + "wbqc-violation-message-format-clarification": "Hodnota vlastnosti $1 ($2) musí odpovídat „$4“ (regulární výraz: $3).", + "wbqc-violation-message-inverse": "$1 by také měla mít opačné tvrzení $2 $3.", + "wbqc-violation-message-item": "Entita s vlastností $1 by také měla mít {{PLURAL:$3|0=tvrzení vlastnosti $2.|1=tvrzení vlastnosti $2 s hodnotou $5.|tvrzení vlasnosti $2 s jednou z následujících hodnot:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Tomuto tvrzení ($1) chybí vymezení $2.", + "wbqc-violation-message-multi-value": "Tato vlastnost by měla obsahovat víc hodnot.", + "wbqc-violation-message-multi-value-separators": "Tato vlastnost by měla obsahovat víc hodnot se {{PLURAL:$2|1=stejným vymezením $4.|stejnou sadou těchto vymezení: $3}}", + "wbqc-violation-message-one-of": "Hodnota vlastnosti $1 by měla být {{PLURAL:$2|1=$4.|2=buď $4, nebo $5.|jedna z následujících:$3}}", + "wbqc-violation-message-qualifier": "Tato vlastnost by měla být používána pouze jako vymezení.", + "wbqc-violation-message-no-qualifiers": "Tvrzení vlastnosti $1 by nemělo mít žádná vymezení.", + "wbqc-violation-message-qualifiers": "$2 není platné vymezení vlastnosti $1 – {{PLURAL:$3|1=jediné platné vymezení je $5.|2=jediná platná vymezení jsou $5 a $6.|jediná platná vymezení jsou:$4}}", + "wbqc-violation-message-range-parameters-needed": "Vlastnosti s hodnotami typu „$1“ a omezením „$4“ potřebují parametry „$2“ a „$3“.", + "wbqc-violation-message-range-parameters-one-year": "Krajní body definující časový rozsah musí buď oba, nebo ani jeden používat jednotku „rok“, protože roky nelze jednoznačně převádět na sekundy.", + "wbqc-violation-message-range-parameters-same": "Začáteční ($1) a konečný bod ($2) rozsahu nemohou být stejné.", + "wbqc-violation-message-range-quantity-closed": "Hodnota vlastnosti $1 ($2) by měla být mezi $3 a $4.", + "wbqc-violation-message-range-quantity-leftopen": "Hodnota vlastnosti $1 ($2) by neměla být větší než $3.", + "wbqc-violation-message-range-quantity-rightopen": "Hodnota vlastnosti $1 ($2) by neměla být menší než $3.", + "wbqc-violation-message-range-time-closed": "Hodnota vlastnosti $1 ($2) by měla být mezi $3 a $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Hodnota $1 ($2) by měla existovat v budoucnosti, ale ne po $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Hodnota $1 ($2) by měla existovat v minulosti, ale ne před $3.", + "wbqc-violation-message-range-time-leftopen": "Hodnota vlastnosti $1 ($2) by neměla být po $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Hodnota $1 ($2) by neměla existovat v budouctosti.", + "wbqc-violation-message-range-time-rightopen": "Hodnota vlastnosti $1 ($2) by neměla být před $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Hodnota $1 ($2) by neměla existovat v minulosti.", + "wbqc-violation-message-single-value": "Tato vlastnost by měla obsahovat pouze jednu hodnotu.", + "wbqc-violation-message-single-value-separators": "Tato vlastnost by měla obsahovat pouze jednu hodnotu se {{PLURAL:$2|1=stejným vymezením $4.|stejnou sadou těchto vymezení: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Tato vlastnost by měla obsahovat jedinou „nejlepší“ hodnotu. Z několika stávajících hodnot by měla mít jedna nastaveno „preferované postavení“.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Tato vlastnost by měla obsahovat jedinou „nejlepší“ hodnotu se {{PLURAL:$2|1=stejným vymezením $4.|stejnou sadou těchto vymezení: $3}} Z několika stávajících hodnot by měla mít jedna nastaveno „preferované postavení“.", + "wbqc-violation-message-single-best-value-multi-preferred": "Tato vlastnost by měla obsahovat jedinou „nejlepší“ hodnotu. Neměla by existovat více než jedna hodnota s „preferovaným postavením“.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Tato vlastnost by měla obsahovat jedinou „nejlepší“ hodnotu se {{PLURAL:$2|1=stejným vymezením $4.|stejnou sadou těchto vymezení: $3}} Neměla by existovat více než jedna hodnota s „preferovaným postavením“.", + "wbqc-violation-message-symmetric": "$1 by také měla mít symetrické tvrzení $2 $3.", + "wbqc-violation-message-type-instance": "Entity s vlastností $1 by měly být instancemi {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-type-subclass": "Entity s vlastností $1 by měly být podtřídami {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entity s vlastností $1 by měly být instancemi nebo podtřídami {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-valueType-instance": "Hodnoty tvrzení vlastnosti $1 by měly být instancemi {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-valueType-subclass": "Hodnoty tvrzení vlastnosti $1 by měly být podtřídami {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Hodnoty tvrzení vlastnosti $1 by měly být instancemi nebo podtřídami {{PLURAL:$3|1=třídy $5|2=tříd $5 nebo $6|jedné z následujících tříd}} (nebo {{PLURAL:$3|její podtřídy|jejich podtříd}}), což ale $2 {{PLURAL:$3|1=není.|2=není.|není: $4}}", + "wbqc-violation-message-target-required-claim": "$1 by také měla mít {{PLURAL:$3|0=tvrzení vlastnosti $2.|1=tvrzení vlastnosti $2 s hodnotou $5.|tvrzení vlasnosti $2 s jednou z následujících hodnot:$4}}", + "wbqc-violation-message-unique-value": "Hodnota této vlastnosti by neměla být použita v žádné jiné položce, použitá je ale i v {{PLURAL:$1|1=položce $3.|2=položkách $3 a $4.|následujících položkách: $2}}", + "wbqc-violation-message-valueOnly": "Tato vlastnost by se měla používat pouze jako hlavní hodnota výroku, nikoli jako vymezení či v referencích.", + "wbqc-violation-message-reference": "Tato vlastnost by se měla používat pouze v referencích, nikoli jako hlavní hodnota výroku či jako vymezení.", + "wbqc-violation-message-noBounds": "Hodnota vlastnosti $1 by neměla mít meze.", + "wbqc-violation-message-units-none": "Hodnota vlastnosti $1 by neměla mít jednotku.", + "wbqc-violation-message-units": "Hodnota vlastnosti $1 by měla mít {{PLURAL:$2|1=jednotku $4.|2=jednotku $4 nebo $5.|jednu z následujících jednotek: $3}}", + "wbqc-violation-message-units-or-none": "Hodnota vlastnosti $1 by měla mít {{PLURAL:$2|1=jednotku $4.|2=jednotku $4 nebo $5.|jednu z následujících jednotek}} nebo nemít žádnou {{PLURAL:$2|1=jednotku.|2=jednotku.|jednotku: $3}}", + "wbqc-violation-message-entityType": "Vlastnost $1 by se neměla používat na tomto typu entity, {{PLURAL:$2|1=jediným platným typem entity je $4.|2=jedinými platnými typy entit jsou $4 a $5.|jedinými platnými typy entity jsou: $3}}", + "wbqc-violation-message-none-of": "Hodnota vlastnosti $1 by neměla být {{PLURAL:$2|1=$4.|2=$4 ani $5.|žádná z následujících:$3}}", + "wbqc-violation-message-integer": "Hodnoty vlastnosti $1 by měly být celá čísla, ale $2 má desetinnou část.", + "wbqc-violation-message-integer-bounds": "Hodnoty vlastnosti $1 by měly být celá čísla, ale $2 má meze s desetinnou částí.", + "wbqc-violation-message-citationNeeded": "Tvrzení vlastnosti $1 by měla mít alespoň jednu referenci.", + "wbqc-violation-message-language": "Výroky pro $1 by měly být pouze na lexémech s {{PLURAL:$2|1=jazykem $4.|2=jazykem $4 nebo $5.|jedním z následujících jazyků: $3}}", + "wbqc-violation-message-label-lacking": "Entity s výrokem pro $1 by také měly mít štítek přinejmenším v {{PLURAL:$2|1=jazyce $4.|některém z následujících jazyků: $3}}", + "wbqc-violation-message-property-scope": "Vlastnost $1 by neměla být používána na tomto místě ($2). {{PLURAL:$3|Jediným platným místem|Jedinými platnými místy}} pro tuto vlastnost {{PLURAL:$3|je $5.|jsou: $4}}", + "wbqc-violation-message-exception": "Tato vlastnost je u tohoto omezení uvedena jako známá výjimka, takže tak byla označena." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/csb.json b/dist/extensions/WikibaseQualityConstraints/i18n/csb.json new file mode 100644 index 000000000..695e6417f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/csb.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Kaszeba" + ] + }, + "wbqc-constrainttypehelp-short": "Pòmòc" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/cy.json b/dist/extensions/WikibaseQualityConstraints/i18n/cy.json new file mode 100644 index 000000000..f8265824d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/cy.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Afalau", + "Ceirios" + ] + }, + "wbqc-constraintreport-form-entityid-placeholder": "Qxx neu Pxx", + "wbqc-constraintreport-status-todo": "I'w gwneud", + "wbqc-constraintreport-result-table-header-status": "Statws", + "wbqc-constraintreport-result-table-header-property": "Priodwedd", + "wbqc-constraintreport-result-table-header-message": "Neges", + "wbqc-suggestions-short": "Awgrymiadau", + "wbqc-constrainttypehelp-short": "Cymorth", + "wbqc-constraintdiscuss-short": "Trafod" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/da.json b/dist/extensions/WikibaseQualityConstraints/i18n/da.json new file mode 100644 index 000000000..a7f147d14 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/da.json @@ -0,0 +1,60 @@ +{ + "@metadata": { + "authors": [ + "Jorn Ari", + "Saederup92", + "Dipsacus fullonum" + ] + }, + "wbqc-constraintreport": "Begrænsningsrapport", + "wbqc-desc": "Kontrollerer begrænsninger på både emner og egenskaber og viser resultaterne på en specialside", + "wbqc-constraintreport-explanation-part-one": "Denne specialside udfører kontrol af begrænsninger på de enheder som du vælger. Enhederne hentes fra live-systemet, så overtrædelser af begrænsninger, som du retter der, vil øjeblikkeligt blive fjernet fra denne liste.", + "wbqc-constraintreport-explanation-part-two": "Begrænsningerne udtrækkes fra udsagn for egenskaber hver gang disse udsagn redigeres, normalt inden for et par minutter.", + "wbqc-constraintreport-form-section": "Tjek begrænsninger for enhed", + "wbqc-constraintreport-form-submit-label": "Tjek", + "wbqc-constraintreport-form-entityid-label": "Entitets-ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx eller Pxx", + "wbqc-constraintreport-result-headline": "Resultat for", + "wbqc-constraintreport-invalid-entity-id": "Ugyldigt entitets-ID.", + "wbqc-constraintreport-not-existent-entity": "Enheden findes ikke.", + "wbqc-constraintreport-empty-result": "Der er ingen begrænsninger defineret for denne enhed.", + "wbqc-constraintreport-status-violation": "Overtrædelse", + "wbqc-constraintreport-status-compliance": "Overholdelse", + "wbqc-constraintreport-status-exception": "Undtagelse", + "wbqc-constraintreport-status-todo": "Mangler", + "wbqc-constraintreport-status-bad-parameters": "Dårlige parametre", + "wbqc-constraintreport-status-deprecated": "Forældet", + "wbqc-constraintreport-status-warning": "Advarsel", + "wbqc-constraintreport-status-suggestion": "Forslag", + "wbqc-constraintreport-status-not-in-scope": "Ikke omfattet", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Egenskab", + "wbqc-constraintreport-result-table-header-message": "Besked", + "wbqc-constraintreport-result-table-header-constraint": "Begrænsning", + "wbqc-constraintreport-result-link-to-claim": "gå til påstand", + "wbqc-constraintreport-result-link-to-constraint": "gå til begrænsing", + "wbqc-constraintreport-no-parameter": "ingen", + "wbqc-issues-short": "Problemer", + "wbqc-issues-long": "Dette udsagn har problemer.", + "wbqc-potentialissues-short": "Mulige problemer", + "wbqc-potentialissues-long": "Dette udsagn har nogle potentielle problemer.", + "wbqc-suggestions-short": "Forslag", + "wbqc-suggestions-long": "Det er forslag til at forbedre denne påstand.", + "wbqc-badparameters-short": "Dårlige parametre", + "wbqc-badparameters-long": "Denne begrænsningspåstand har ugyldige parametre.", + "wbqc-parameterissues-short": "Videregående problemer", + "wbqc-parameterissues-long": "Dette er problemer med egenskabens begrænsningsdefinition, ikke med denne påstand.", + "wbqc-constrainttypehelp-short": "Hjælp", + "wbqc-constrainttypehelp-long": "Hjælpeside for denne begrænsningstype", + "wbqc-constraintdiscuss-short": "Diskuter", + "wbqc-constraintdiscuss-long": "Diskussionsside for denne begrænsning", + "wbqc-cached-generic": "Dette resultat er mellemlagret og kan være forældet.", + "wbqc-cached-minutes": "Dette resultat er mellemlagret og kan være op til {{PLURAL:$1| 1=et minut|$1 minutter}} forældet.", + "wbqc-cached-hours": "Dette resultat er mellemlagret og kan være op til {{PLURAL:$1| 1=en time|$1 timer}} forældet.", + "wbqc-cached-days": "Dette resultat er mellemlagret og kan være op til {{PLURAL:$1| 1=et døgn|$1 døgn}} forældet.", + "wbqc-dataValueType-wikibase-entityid": "Entitets-ID", + "wbq-subextension-name-wbqc": "Begrænsninger", + "wbqc-violation-header-parameters": "Parametre:", + "wbqc-violations-group": "Begrænsninger", + "wbqc-violation-message-parameters-error-toolong": "Parametrene til denne begrænsning kunne ikke importeres fordi de er for lange." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/de.json b/dist/extensions/WikibaseQualityConstraints/i18n/de.json new file mode 100644 index 000000000..c3989fb73 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/de.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "Inkowik", + "Metalhead64", + "Purodha", + "Brettchenweber", + "Nw520", + "Amire80" + ] + }, + "wbqc-constraintreport": "Beschränkungsbericht", + "wbqc-desc": "Ermöglicht die Überprüfung von Beschränkungen bei Objekten und Eigenschaften und zeigt die Ergebnisse auf einer Spezialseite an", + "wbqc-constraintreport-explanation-part-one": "Diese Spezialseite führt Beschränkungsprüfungen zu einer beliebigen Entität durch. Die vom Live-System abgerufenen Entitäten und jede behobene Beschränkungsverletzung werden sofort von dieser Liste entfernt.", + "wbqc-constraintreport-explanation-part-two": "Die Beschränkungen werden von den Aussagen der Eigenschaften jedes Mal geparst, wenn diese Aussagen bearbeitet werden, für gewöhnlich innerhalb weniger Minuten.", + "wbqc-constraintreport-form-section": "Beschränkungen für die Entität überprüfen", + "wbqc-constraintreport-form-submit-label": "Überprüfen", + "wbqc-constraintreport-form-entityid-label": "Entitätskennung:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx oder Pxx", + "wbqc-constraintreport-result-headline": "Ergebnis für", + "wbqc-constraintreport-invalid-entity-id": "Ungültige Entitätskennung.", + "wbqc-constraintreport-not-existent-entity": "Das Objekt ist nicht vorhanden!", + "wbqc-constraintreport-empty-result": "Es gibt keine zu dieser Entität definierten Beschränkungen.", + "wbqc-constraintreport-status-violation": "Verletzung", + "wbqc-constraintreport-status-compliance": "Übereinstimmung", + "wbqc-constraintreport-status-exception": "Ausnahme", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Ungültige Parameter", + "wbqc-constraintreport-status-deprecated": "Veraltet", + "wbqc-constraintreport-status-warning": "Warnung", + "wbqc-constraintreport-status-suggestion": "Vorschlag", + "wbqc-constraintreport-status-not-in-scope": "Nicht im Geltungsbereich", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Eigenschaft", + "wbqc-constraintreport-result-table-header-message": "Nachricht", + "wbqc-constraintreport-result-table-header-constraint": "Beschränkung", + "wbqc-constraintreport-result-link-to-claim": "gehe zu Behauptung", + "wbqc-constraintreport-result-link-to-constraint": "gehe zu Beschränkung", + "wbqc-constraintreport-no-parameter": "keine", + "wbqc-issues-short": "Probleme", + "wbqc-issues-long": "Diese Aussage hat einige Probleme.", + "wbqc-potentialissues-short": "Potenzielle Probleme", + "wbqc-potentialissues-long": "Diese Aussage hat einige potenzielle Probleme.", + "wbqc-suggestions-short": "Vorschläge", + "wbqc-suggestions-long": "Für die Verbesserung dieser Aussage gibt es einige Vorschläge.", + "wbqc-badparameters-short": "Ungültige Parameter", + "wbqc-badparameters-long": "Diese Beschränkungsaussage hat einige ungültige Parameter.", + "wbqc-parameterissues-short": "Erweiterte Probleme", + "wbqc-parameterissues-long": "Dies sind Probleme mit der Beschränkungsdefinition zu der Eigenschaft, nicht mit dieser Aussage.", + "wbqc-constrainttypehelp-short": "Hilfe", + "wbqc-constrainttypehelp-long": "Hilfeseite für diesen Beschränkungstyp", + "wbqc-constraintdiscuss-short": "Diskussion", + "wbqc-constraintdiscuss-long": "Diskussionsseite über diese Beschränkung", + "wbqc-cached-generic": "Dieses Ergebnis ist gecacht und könnte veraltet sein.", + "wbqc-cached-minutes": "Dieses Ergebnis ist gecacht und könnte bis zu {{PLURAL:$1|1=einer Minute|$1 Minuten}} alt sein.", + "wbqc-cached-hours": "Dieses Ergebnis stammt aus dem Cache und kann bis zu {{PLURAL:$1|1=eine Stunde|$1 Stunden}} alt sein.", + "wbqc-cached-days": "Dieses Ergebnis stammt aus dem Cache und kann bis zu {{PLURAL:$1|1=einen Tag|$1 Tage}} alt sein.", + "wbqc-dataValueType-wikibase-entityid": "Entitätskennung", + "wbq-subextension-name-wbqc": "Beschränkungen", + "wbqc-violation-header-parameters": "Parameter:", + "wbqc-violations-group": "Beschränkungen", + "wbqc-violation-message": "Die Beschränkungsprüfung hat einen Verstoß aufgezeigt. Bitte klicke auf das Symbol, um weitere Informationen zu bekommen.", + "wbqc-violation-message-not-yet-implemented": "Aus technischen Gründen wurde die Prüfung für die Beschränkung „$1“ noch nicht implementiert.", + "wbqc-violation-message-security-reason": "Aus Sicherheitsgründen ist es derzeit nicht möglich, die Beschränkung „$1“ zu überprüfen. Wir arbeiten an einer Lösung.", + "wbqc-violation-message-value-needed-of-type": "Eigenschaften mit der Beschränkung „$1“ müssen Werte des Typs „$2“ haben.", + "wbqc-violation-message-value-needed-of-types-2": "Eigenschaften mit der Beschränkung „$1“ müssen Werte der Typen „$2“ oder „$3“ haben.", + "wbqc-violation-message-parameter-needed": "Eigenschaften mit der Beschränkung „$1“ benötigen einen Parameter „$2“.", + "wbqc-violation-message-parameters-needed-3": "Eigenschaften mit der Beschränkung „$1“ benötigen die Parameter „$2“, „$3“ und „$4“.", + "wbqc-violation-message-target-entity-must-exist": "Der Zieldatensatz muss vorhanden sein.", + "wbqc-violation-message-value-entity-must-exist": "Das Werteobjekt muss vorhanden sein.", + "wbqc-violation-message-parameter-value": "Der Parameter „$1“ muss einen benutzerdefinierten Wert haben und nicht „keinen Wert“ oder einen „unbekannten Wert“.", + "wbqc-violation-message-parameter-value-or-novalue": "Der Parameter „$1“ muss einen benutzerdefinierten Wert oder „keinen Wert“ haben, jedoch niemals einen „unbekannten Wert“.", + "wbqc-violation-message-parameter-entity": "Der Wert für den Parameter „$1“ muss eine Entität sein, nicht „$2“.", + "wbqc-violation-message-parameter-item": "Der Wert für den Parameter „$1“ muss ein Objekt sein, nicht „$2“.", + "wbqc-violation-message-parameter-property": "Der Wert für den Parameter „$1“ muss eine Eigenschaft sein, nicht „$2“.", + "wbqc-violation-message-parameter-string": "Der Wert für den Parameter „$1“ muss eine Zeichenfolge sein, nicht „$2“.", + "wbqc-violation-message-parameter-monolingualtext": "Der Wert für den Parameter „$1“ muss ein einsprachiger Text sein, nicht „$2“.", + "wbqc-violation-message-parameter-single": "Der Parameter „$1“ darf nur einen einzigen Wert haben.", + "wbqc-violation-message-parameter-single-per-language": "Der Parameter „$1“ darf nur einen einzigen Wert pro Sprache haben, er hat jedoch mehrere Werte für $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Der Parameter „$1“ muss {{PLURAL:$2|1=$4 sein.|2=entweder $4 oder $5 sein.|eines der folgenden Werte sein: $3.}}", + "wbqc-violation-message-parameter-regex": "$1 ist kein gültiger regulärer Ausdruck.", + "wbqc-violation-message-sparql-error": "Die SPARQL-Abfrage hat einen Fehler ausgegeben.", + "wbqc-violation-message-parameters-error-unknown": "Die Parameter dieser Beschränkung konnten nicht importiert werden.", + "wbqc-violation-message-parameters-error-toolong": "Die Parameter dieser Beschränkung konnten nicht importiert werden, da sie zu lang waren.", + "wbqc-violation-message-invalid-scope": "$1 ist kein gültiger Geltungsbereich für den Beschränkungstyp $2. {{PLURAL:$3|Der einzige gültige Geltungsbereich|Die einzigen gültigen Geltungsbereiche}} für diese Beschränkung {{PLURAL:$3|ist $5.|2=sind $5 und $6.|sind: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Der Commons-Link sollte vorhanden sein.", + "wbqc-violation-message-commons-link-not-well-formed": "Der Commons-Link sollte wohlgeformt sein.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Die Prüfung für den Namensraum „$1“ ist noch nicht implementiert.", + "wbqc-violation-message-conflicts-with-property": "Ein Objekt sollte keine Aussagen sowohl für $1 als auch $2 haben.", + "wbqc-violation-message-conflicts-with-claim": "Ein Objekt sollte keine Aussage für $1 haben, falls es auch eine Aussage für $2 mit dem Wert $3 hat.", + "wbqc-violation-message-contemporary-subject-earlier": "Die Objekte $1 und $3 sollten aktuell sein, um durch $2 verlinkt zu werden, aber der aktuellste Endwert von $1 ist $4 und der früheste Startwert von $3 ist $5.", + "wbqc-violation-message-contemporary-value-earlier": "Die Objekte $1 und $3 sollten aktuell sein, um durch $2 verlinkt zu werden, aber der aktuellste Endwert von $3 ist $4 und der früheste Startwert von $1 ist $5.", + "wbqc-violation-message-diff-within-range": "Der Unterschied zwischen $3 ($4) und $1 ($2) sollte zwischen $5 und $6 liegen.", + "wbqc-violation-message-diff-within-range-leftopen": "Der Unterschied zwischen $3 ($4) und $1 ($2) sollte nicht mehr als $5 betragen.", + "wbqc-violation-message-diff-within-range-rightopen": "Der Unterschied zwischen $3 ($4) und $1 ($2) sollte nicht weniger als $5 betragen.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Die in den Parametern definierte Eigenschaft muss einen Wert des gleichen Typs wie diese Eigenschaft haben.", + "wbqc-violation-message-format": "Der Wert für $1 ($2) sollte dem regulären Ausdruck $3 entsprechen.", + "wbqc-violation-message-format-clarification": "Der Wert für $1 ($2) sollte „$4“ entsprechen (regulärer Ausdruck: $3).", + "wbqc-violation-message-inverse": "$1 sollte auch die umgekehrte Aussage $2 $3 haben.", + "wbqc-violation-message-item": "Eine Entität mit $1 sollte auch {{PLURAL:$3|0=eine Aussage $2 haben.|1=eine Aussage $2 $5 haben.|eine Aussage für $2 mit einem der folgenden Werte haben: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Dieser $1-Aussage fehlt der Qualifikator $2.", + "wbqc-violation-message-multi-value": "Diese Eigenschaft sollte mehrere Werte enthalten.", + "wbqc-violation-message-multi-value-separators": "Diese Eigenschaft sollte mehrere Werte mit dem gleichen {{PLURAL:$2|1=Qualifikator $4 enthalten.|Satz an Qualifikatoren für diese Eigenschaften enthalten: $3}}", + "wbqc-violation-message-one-of": "Der Wert für $1 sollte {{PLURAL:$2|1=$4 sein.|2=entweder $4 oder $5 sein.|einer der folgenden sein: $3.}}", + "wbqc-violation-message-qualifier": "Die Eigenschaft sollte nur als Qualifikator verwendet werden.", + "wbqc-violation-message-no-qualifiers": "„$1“-Aussagen sollten keine Qualifikatoren haben.", + "wbqc-violation-message-qualifiers": "$2 ist kein gültiger Qualifikator für $1 – {{PLURAL:$3|1=Der einzige gültige Qualifikator ist $5.|2=Die einzigen gültigen Qualifikatoren sind $5 und $6.|Die einzigen gültigen Qualifikatoren sind: $4}}", + "wbqc-violation-message-range-parameters-needed": "Eigenschaften mit Werten des Typs „$1“ und der Beschränkung „$4“ benötigen die Parameter „$2“ und „$3“.", + "wbqc-violation-message-range-parameters-one-year": "Endpunkte eines Zeiteinheitenbereiches müssen entweder beide oder nicht die Einheit „Jahr“ haben, da Jahre nicht verlustlos in Sekunden konvertiert werden können.", + "wbqc-violation-message-range-parameters-same": "Die Start- ($1) und Endpunkte ($2) eines Bereichs dürfen nicht die gleichen sein.", + "wbqc-violation-message-range-quantity-closed": "Der Wert für $1 ($2) sollte zwischen $3 und $4 liegen.", + "wbqc-violation-message-range-quantity-leftopen": "Der Wert für $1 ($2) sollte nicht höher als $3 sein.", + "wbqc-violation-message-range-quantity-rightopen": "Der Wert für $1 ($2) sollte nicht niedriger als $3 sein.", + "wbqc-violation-message-range-time-closed": "Der Wert für $1 ($2) sollte zwischen $3 und $4 liegen.", + "wbqc-violation-message-range-time-closed-leftnow": "Der Wert für $1 ($2) sollte in der Zukunft liegen, jedoch nicht nach $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Der Wert für $1 ($2) sollte in der Vergangenheit liegen, jedoch nicht vor $3.", + "wbqc-violation-message-range-time-leftopen": "Der Wert für $1 ($2) sollte nicht hinter $3 liegen.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Der Wert für $1 ($2) sollte nicht in der Zukunft liegen.", + "wbqc-violation-message-range-time-rightopen": "Der Wert für $1 ($2) sollte nicht vor $3 liegen.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Der Wert für $1 ($2) sollte nicht in der Vergangenheit liegen.", + "wbqc-violation-message-single-value": "Diese Eigenschaft sollte nur einen einzigen Wert enthalten.", + "wbqc-violation-message-single-value-separators": "Diese Eigenschaft sollte nur einen einzigen Wert mit dem gleichen {{PLURAL:$2|1=Qualifikator $4 haben.|Satz an Qualifikatoren für diese Eigenschaften haben: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Diese Eigenschaft sollte einen einzigen „besten“ Wert enthalten. Von den derzeitigen mehreren Werten sollte ein Wert mit einem „bevorzugten“ Rang markiert werden.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Diese Eigenschaft sollte einen einzigen „besten“ Wert mit dem gleichen {{PLURAL:$2|1=Qualifikator $4 enthalten.|Satz an Qualifikatoren für diese Eigenschaften enthalten: $3.}} Von den derzeitigen mehreren Werten sollte ein Wert mit einem „bevorzugten“ Rang markiert werden.", + "wbqc-violation-message-single-best-value-multi-preferred": "Diese Eigenschaft sollte einen einzigen „besten“ Wert enthalten. Es sollte nicht mehr als einen Wert mit einem „bevorzugten“ Rang geben.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Diese Eigenschaft sollte einen einzigen „besten“ Wert mit dem gleichen {{PLURAL:$2|1=Qualifikator $4 enthalten.|Satz an Qualifikatoren für diese Eigenschaften enthalten: $3.}} Es sollte nicht mehr als einen Wert mit einem „bevorzugten“ Rang geben.", + "wbqc-violation-message-symmetric": "$1 sollte auch die symmetrische Aussage $2 $3 haben.", + "wbqc-violation-message-type-instance": "Entitäten, die die Eigenschaft $1 verwenden, sollten Instanzen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer ihrer Unterklasse|2=einer ihrer Unterklasse|einer ihrer Unterklassen}}), aber $2 ist sie derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4.}}", + "wbqc-violation-message-type-subclass": "Entitäten, die die Eigenschaft $1 verwenden, sollten Unterklassen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer ihrer Unterklasse|2=einer ihrer Unterklasse|einer ihrer Unterklassen}}), aber $2 ist sie derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4.}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entitäten, die die Eigenschaft $1 verwenden, sollten Instanzen oder Unterklassen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer Unterklasse von ihr|2=einer Unterklasse von ihnen|einer ihrer Unterklassen}}), aber $2 ist es derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4}}", + "wbqc-violation-message-valueType-instance": "Werte der Aussagen $1 sollten Instanzen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer ihrer Unterklasse|2=einer ihrer Unterklasse|einer ihrer Unterklassen}}), aber $2 hat sie derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4.}}", + "wbqc-violation-message-valueType-subclass": "Werte der Aussagen $1 sollten Unterklassen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer ihrer Unterklassen|2=einer ihrer Unterklasse|einer ihrer Unterklassen}}), aber $2 hat sie derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4.}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Werte der Aussagen $1 sollten Instanzen oder Unterklassen von {{PLURAL:$3|1=$5|2=$5 oder $6|einer der folgenden Klassen}} sein (oder von {{PLURAL:$3|1=einer Unterklasse von ihr|2=einer Unterklasse von ihnen|einer ihrer Unterklassen}}), aber $2 ist es derzeit {{PLURAL:$3|1=nicht.|2=nicht.|nicht: $4}}", + "wbqc-violation-message-target-required-claim": "$1 sollte {{PLURAL:$3|0=eine Aussage $2 haben.|1=eine Aussage $2 $5 haben.|eine Aussage für $2 mit einem der folgenden Werte haben: $4}}", + "wbqc-violation-message-unique-value": "Der Wert dieser Eigenschaft sollte nicht in einem anderen Objekt vorhanden sein, er ist aber auch auf {{PLURAL:$1|1=$3 vorhanden.|2=$3 und $4 vorhanden.|den folgenden Objekten vorhanden: $2.}}", + "wbqc-violation-message-valueOnly": "Diese Eigenschaft sollte nur für den Hauptwert einer Aussage verwendet werden, nicht für Qualifikatoren oder Fundstellen.", + "wbqc-violation-message-reference": "Die Eigenschaft sollte nur in Fundstellen verwendet werden, nicht für den Hauptwert einer Aussage oder für einen Qualifikator.", + "wbqc-violation-message-noBounds": "Werte für $1 sollten keine Begrenzungen haben.", + "wbqc-violation-message-units-none": "Der Wert für $1 sollte keine Einheit haben.", + "wbqc-violation-message-units": "Der Wert für $1 sollte {{PLURAL:$2|1=die Einheit $4 haben.|2=die Einheit $4 oder $5 haben.|eine der folgenden Einheiten haben: $3}}", + "wbqc-violation-message-units-or-none": "Der Wert für $1 sollte {{PLURAL:$2|1=die Einheit $4|2=die Einheit $4 oder $5|eine der folgenden Einheiten}} haben oder {{PLURAL:$2|1=ohne Einheit sein.|2=ohne Einheit sein.|ohne Einheit sein: $3}}", + "wbqc-violation-message-entityType": "Die Eigenschaft $1 sollte nicht auf dieser Art von Entität verwendet werden, {{PLURAL:$2|1=der einzig gültige Entitätstyp ist $4.|2=die einzig gültigen Entitätstypen sind $4 und $5.|die einzig gültigen Entitätstypen sind: $3}}", + "wbqc-violation-message-none-of": "Der Wert für $1 sollte nicht {{PLURAL:$2|1=$4 sein.|2=entweder $4 oder $5 sein.|einer der folgenden sein: $3}}", + "wbqc-violation-message-integer": "Werte für $1 sollten Ganzzahlen sein, $2 hat jedoch einen Bruchteil.", + "wbqc-violation-message-integer-bounds": "Werte für $1 sollten Ganzzahlen sein, aber die Begrenzungen von $2 haben einen Bruchteil.", + "wbqc-violation-message-citationNeeded": "Aussagen für $1 sollten mindestens eine Fundstelle haben.", + "wbqc-violation-message-language": "Aussagen für $1 sollten nur auf Lexemen mit {{PLURAL:$2|1=der Spracheinstellung $4.|2=den Spracheinstellungen $4 oder $5.|eine der folgenden Spracheinstellungen: $3}}", + "wbqc-violation-message-label-lacking": "Objekte mit Aussagen für $1 sollten auch eine Bezeichnung mindestens in {{PLURAL:$2|1=der Sprache $4 haben|einer der folgenden Sprachen haben: $3}}.", + "wbqc-violation-message-property-scope": "Die Eigenschaft $1 sollte nicht an diesem Ort verwendet werden ($2). {{PLURAL:$3|Der einzig gültige Ort|Die einzig gültigen Orte}} für diese Eigenschaft {{PLURAL:$3|ist $5.|sind: $4}}", + "wbqc-violation-message-exception": "Diese Entität ist eine bekannte Ausnahme für diese Beschränkung und wurde als solche markiert." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/diq.json b/dist/extensions/WikibaseQualityConstraints/i18n/diq.json new file mode 100644 index 000000000..539533477 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/diq.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Mirzali", + "Orbot707" + ] + }, + "wbqc-constraintreport-status-violation": "İxlal", + "wbqc-constraintreport-status-exception": "İstisna", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Parametreyo xırab", + "wbqc-constraintreport-status-deprecated": "Wedariyaye", + "wbqc-constraintreport-status-warning": "Tembe kem", + "wbqc-constraintreport-status-suggestion": "Teklif", + "wbqc-constraintreport-result-table-header-status": "Weziyet", + "wbqc-constraintreport-result-table-header-property": "Xısusiyet", + "wbqc-constraintreport-result-table-header-message": "Mesac", + "wbqc-constraintreport-no-parameter": "çıniyo", + "wbqc-issues-short": "Meseleyi", + "wbqc-suggestions-short": "Teklifi", + "wbqc-constrainttypehelp-short": "Peşti", + "wbqc-violation-header-parameters": "Parametreyi:" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/el.json b/dist/extensions/WikibaseQualityConstraints/i18n/el.json new file mode 100644 index 000000000..3d0e2d719 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/el.json @@ -0,0 +1,55 @@ +{ + "@metadata": { + "authors": [ + "Glavkos", + "KATRINE1992", + "NikosLikomitros", + "Nikosgranturismogt", + "Philocypros", + "Xaris333", + "McDutchie" + ] + }, + "wbqc-constraintreport-result-table-header-property": "Ιδιότητα", + "wbqc-constraintreport-result-table-header-message": "Μήνυμα", + "wbqc-issues-short": "Ζητήματα.", + "wbqc-issues-long": "Αυτή η δήλωση έχει μερικά ζητήματα.", + "wbqc-potentialissues-short": "Πιθανά ζητήματα.", + "wbqc-potentialissues-long": "Αυτή η δήλωση έχει μερικά πιθανά ζητήματα.", + "wbqc-suggestions-short": "Εισηγήσεις", + "wbqc-suggestions-long": "Υπάρχουν κάποιες εισηγήσεις για βελτίωση αυτής της δήλωσης.", + "wbqc-constrainttypehelp-short": "Βοήθεια", + "wbqc-constrainttypehelp-long": "Σελίδα βοήθειας για αυτόν τον τύπο περιορισμού.", + "wbqc-constraintdiscuss-short": "Συζήτηση", + "wbqc-constraintdiscuss-long": "Σελίδα συζήτησης για αυτό τον περιορισμό.", + "wbqc-cached-generic": "Το αποτέλεσμα έχει χαθεί και μπορεί να είναι εκτός προθεσμίας", + "wbqc-cached-minutes": "Αυτό το αποτέλεσμα έχει χαθεί και μπορεί να είναι εκτός προθεσμίας μέχρι {{PLURAL:$1|1=ένα λεπτό|$1 λεπτά}}.", + "wbqc-cached-hours": "Αυτό το αποτέλεσμα είναι προσωρινά αποθηκευμένο και μπορεί να μην έχει ενημερωθεί μέχρι και {{PLURAL:$1|1=μία ώρα|$1 ώρες}}.", + "wbqc-cached-days": "Αυτό το αποτέλεσμα είναι προσωρινά αποθηκευμένο και μπορεί να μην έχει ενημερωθεί μέχρι {{PLURAL:$1|1=μια ημέρα|$1 ημέρες}}.", + "wbqc-violation-message-conflicts-with-property": "Μια οντότητα δεν πρέπει να έχει δηλώσεις και για τις δύο ιδιότητες $1 και $2.", + "wbqc-violation-message-conflicts-with-claim": "Μια οντότητα δεν πρέπει να έχει δήλωση για την ιδιότητα $1 εάν έχει δήλωση για την ιδιότητα $2 με τιμή $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Οι οντότητες $1 και $3 πρέπει να είναι σύγχρονες για να συνδεθούν μέσω $2, αλλά η τελευταία τελική τιμή του $1 είναι $4 και η αρχική τιμή εκκίνησης του $3 είναι $5.", + "wbqc-violation-message-contemporary-value-earlier": "Οι οντότητες $1 και $3 πρέπει να είναι σύγχρονες για να συνδεθούν μέσω $2, αλλά η τελευταία τελική τιμή του $3 είναι $4 και η αρχική τιμή εκκίνησης του $1 είναι $5.", + "wbqc-violation-message-diff-within-range": "Η διαφορά μεταξύ $3 ($4) και $1 ($2) πρέπει να είναι μεταξύ $5 και $6.", + "wbqc-violation-message-format": "Η τιμή για $1 ($2) θα πρέπει να ταιριάζει με την κανονική έκφραση $3.", + "wbqc-violation-message-inverse": "$1 πρέπει επίσης να έχει την αντίστροφη δήλωση $2 $3.", + "wbqc-violation-message-item": "Μια οντότητα με $1 πρέπει επίσης να έχει {{PLURAL:$3|0=μια δήλωση $2.|1=μια δήλωση $2 $5.|μια δήλωση για $2 με μια από τις ακόλουθες τιμές:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Στη δήλωση $1 λείπει ο προσδιοριστής $2.", + "wbqc-violation-message-multi-value": "Αυτή η ιδιότητα πρέπει να περιέχει πολλαπλές τιμές.", + "wbqc-violation-message-qualifier": "Αυτή η ιδιότητα πρέπει να χρησιμοποιείται μόνο σαν προσδιοριστής.", + "wbqc-violation-message-qualifiers": "$2 δεν είναι κατάλληλος προσδιοριστής για $1 – {{PLURAL:$3|1=ο μόνος κατάλληλος προσδιοριστής είναι $5.|2=οι μόνοι κατάλληλοι προσδιοριστές είναι $5 και $6.|προσδιοριστές είναι:$4}}", + "wbqc-violation-message-range-time-closed-rightnow": "Η τιμή για $1 ($2) πρέπει να αναφέρεται στο παρελθόν, αλλά όχι πριν τις $3.", + "wbqc-violation-message-single-value": "Αυτή η ιδιότητα πρέπει να περιέχει μόνο μία τιμή. Δηλαδή, θα πρέπει να υπάρχει μόνο μία δήλωση που χρησιμοποιεί αυτή την ιδιότητα.", + "wbqc-violation-message-single-value-separators": "Αυτή η ιδιότητα πρέπει να έχει μόνο μια μοναδική τιμή με ίδιο {{PLURAL:$2|1=$4 προσδιοριστή.|σύνολο προσδιοριστών για αυτές τις ιδιότητες: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Αυτή η ιδιότητα πρέπει να περιέχει μόνο μία «προτιμώμενη» τιμή. Από τις τρέχουσες πολλαπλές τιμές, πρέπει μία να δηλωθεί με «προτιμώμενη βαθμίδα».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Αυτή η ιδιότητα πρέπει να περιέχει μόνο μία «προτιμώμενη» τιμή με {{PLURAL:$2|1=$4 τον ίδιο προσδιοριστή.|τους ίδιους προσδιοριστές για αυτές τις ιδιότητες: $3}}. Από τις τρέχουσες πολλαπλές τιμές, πρέπει μία να δηλωθεί με «προτιμώμενη βαθμίδα».", + "wbqc-violation-message-symmetric": "$1 πρέπει επίσης να έχει τη συμμετρική δήλωση $2 $3.", + "wbqc-violation-message-type-instance": "Οι οντότητες που χρησιμοποιούν την ιδιότητα $1 πρέπει να είναι παραδείγματα {{PLURAL:$3|1=$5|2=$5 ή $6|μιας εκ των ακόλουθων τάξεων}} (ή {{PLURAL:$3|1=μιας υποκλάσης αυτής|2=μιας υποκλάσης αυτών|μιας εκ των υποκλάσεων τους}}), αλλά $2 αυτή τη στιγμή {{PLURAL:$3|1=δεν είναι.|2=δεν είναι.|δεν είναι: $4}}", + "wbqc-violation-message-valueType-instance": "Οι τιμές για τη δήλωση $1 πρέπει να είναι παραδείγματα ή υποκλάσεις {{PLURAL:$3|1=$5|2=$5 ή $6|μιας από τις ακόλουθες κλάσεις}} (ή {{PLURAL:$3|1=a subclass of it|2=μιας υποκλάσης αυτών|μιας από τις υποκλάσεις αυτών}}), αλλά η παρούσα τιμή $2 {{PLURAL:$3|1=δεν είναι|2=δεν είναι|δεν είναι: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Οι τιμές για τη δήλωση $1 πρέπει να είναι παραδείγματα ή υποκλάσεις {{PLURAL:$3|1=$5|2=$5 ή $6|μιας από τις ακόλουθες κλάσεις}} (ή {{PLURAL:$3|1=a subclass of it|2=μιας υποκλάσης αυτών|μιας από τις υποκλάσεις αυτών}}), αλλά η παρούσα τιμή $2 {{PLURAL:$3|1=δεν είναι|2=δεν είναι|δεν είναι: $4}}", + "wbqc-violation-message-target-required-claim": "$1 πρέπει να έχει {{PLURAL:$3|0=μια δήλωση $2.|1=μια δήλωση $2 $5.|μια δήλωση για $2 με μία από τις ακόλουθες τιμές:$4}}", + "wbqc-violation-message-unique-value": "Η τιμή αυτής της ιδιότητας δεν πρέπει να παρουσιάζεται σε άλλα αντικείμενα, ωστόσο χρησιμοποιείται στα {{PLURAL:$1|1=$3.|2=$3 και $4.|ακόλουθα αντικείμενα: $2}}", + "wbqc-violation-message-valueOnly": "Αυτή η ιδιότητα πρέπει να χρησιμοποιείται μόνο για την κύρια τιμή μιας δήλωσης, όχι για προσδιοριστές ή παραπομπές.", + "wbqc-violation-message-units-none": "Η τιμή για το $1 δεν πρέπει να έχει μια μονάδα.", + "wbqc-violation-message-citationNeeded": "Οι δηλώσεις για $1 πρέπει να έχουν τουλάχιστον μία παραπομπή." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/en.json b/dist/extensions/WikibaseQualityConstraints/i18n/en.json new file mode 100644 index 000000000..7fa236189 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/en.json @@ -0,0 +1,147 @@ +{ + "@metadata": { + "authors": [ + "BP2014N1", + "Andreas Burmeister" + ] + }, + "wbqc-constraintreport": "Constraint report", + "wbqc-desc": "Checks constraints on both items and properties and displays the results on a special page", + "wbqc-constraintreport-explanation-part-one": "This special page performs constraint checks on any entity you want. The entities are fetched from the live system, so every constraint violation you fix there will be instantly removed from this list.", + "wbqc-constraintreport-explanation-part-two": "The constraints are parsed from statements on properties each time those statements are edited, usually within a few minutes.", + "wbqc-constraintreport-form-section": "Check constraints for entity", + "wbqc-constraintreport-form-submit-label": "Check", + "wbqc-constraintreport-form-entityid-label": "Entity ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx or Pxx", + "wbqc-constraintreport-result-headline": "Result for", + "wbqc-constraintreport-invalid-entity-id": "Invalid entity ID.", + "wbqc-constraintreport-not-existent-entity": "Entity does not exist.", + "wbqc-constraintreport-empty-result": "There are no constraints defined on this entity.", + "wbqc-constraintreport-status-violation": "Violation", + "wbqc-constraintreport-status-compliance": "Compliance", + "wbqc-constraintreport-status-exception": "Exception", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Bad parameters", + "wbqc-constraintreport-status-deprecated": "Deprecated", + "wbqc-constraintreport-status-warning": "Warning", + "wbqc-constraintreport-status-suggestion": "Suggestion", + "wbqc-constraintreport-status-not-in-scope": "Not in scope", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Property", + "wbqc-constraintreport-result-table-header-message": "Message", + "wbqc-constraintreport-result-table-header-constraint": "Constraint", + "wbqc-constraintreport-result-link-to-claim": "go to claim", + "wbqc-constraintreport-result-link-to-constraint": "go to constraint", + "wbqc-constraintreport-no-parameter": "none", + "wbqc-issues-short": "Issues", + "wbqc-issues-long": "This statement has some issues.", + "wbqc-potentialissues-short": "Potential issues", + "wbqc-potentialissues-long": "This statement has some potential issues.", + "wbqc-suggestions-short": "Suggestions", + "wbqc-suggestions-long": "There are some suggestions for improving this statement.", + "wbqc-badparameters-short": "Bad parameters", + "wbqc-badparameters-long": "This constraint statement has some invalid parameters.", + "wbqc-parameterissues-short": "Advanced issues", + "wbqc-parameterissues-long": "These issues are problems with the constraint definition on the property, not with this statement.", + "wbqc-constrainttypehelp-short": "Help", + "wbqc-constrainttypehelp-long": "Help page for this constraint type", + "wbqc-constraintdiscuss-short": "Discuss", + "wbqc-constraintdiscuss-long": "Discussion page about this constraint", + "wbqc-cached-generic": "This result is cached and might be out of date.", + "wbqc-cached-minutes": "This result is cached and might be out of date by up to {{PLURAL:$1|1=one minute|$1 minutes}}.", + "wbqc-cached-hours": "This result is cached and might be out of date by up to {{PLURAL:$1|1=one hour|$1 hours}}.", + "wbqc-cached-days": "This result is cached and might be out of date by up to {{PLURAL:$1|1=one day|$1 days}}.", + "wbqc-dataValueType-wikibase-entityid": "Entity ID", + "wbq-subextension-name-wbqc": "Constraints", + "wbqc-violation-header-parameters": "Parameters:", + "wbqc-violations-group": "Constraints", + "wbqc-violation-message": "Constraint check has pointed out a violation. Please click on icon for further information.", + "wbqc-violation-message-not-yet-implemented": "For technical reasons, the check for the constraint \"$1\" has not yet been implemented.", + "wbqc-violation-message-security-reason": "For security reasons, it is not possible to check the \"$1\" constraint at the moment. We are working on a solution.", + "wbqc-violation-message-value-needed-of-type": "Properties with constraint \"$1\" need to have values of type \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Properties with constraint \"$1\" need to have values of type \"$2\" or \"$3\".", + "wbqc-violation-message-parameter-needed": "Properties with constraint \"$1\" need a parameter \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Properties with constraint \"$1\" need parameters \"$2\", \"$3\", and \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "The target entity must exist.", + "wbqc-violation-message-value-entity-must-exist": "The value entity must exist.", + "wbqc-violation-message-parameter-value": "The parameter \"$1\" must have a custom value, not \"no value\" or \"unknown value\".", + "wbqc-violation-message-parameter-value-or-novalue": "The parameter \"$1\" must have a custom value or \"no value\", but never \"unknown value\".", + "wbqc-violation-message-parameter-entity": "The value for the parameter \"$1\" must be an entity, not \"$2\".", + "wbqc-violation-message-parameter-item": "The value for the parameter \"$1\" must be an item, not \"$2\".", + "wbqc-violation-message-parameter-property": "The value for the parameter \"$1\" must be a property, not \"$2\".", + "wbqc-violation-message-parameter-string": "The value for the parameter \"$1\" must be a string, not \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "The value for the parameter \"$1\" must be a monolingual text, not \"$2\".", + "wbqc-violation-message-parameter-single": "The parameter \"$1\" must only have a single value.", + "wbqc-violation-message-parameter-single-per-language": "The parameter \"$1\" must only have a single value per language, but has multiple values for $2 ($3).", + "wbqc-violation-message-parameter-oneof": "The parameter \"$1\" must be {{PLURAL:$2|1=$4.|2=either $4 or $5.|one of the following:$3}}", + "wbqc-violation-message-parameter-regex": "$1 is not a valid regular expression.", + "wbqc-violation-message-sparql-error": "The SPARQL query resulted in an error.", + "wbqc-violation-message-parameters-error-unknown": "The parameters of this constraint could not be imported.", + "wbqc-violation-message-parameters-error-toolong": "The parameters of this constraint could not be imported because they were too long.", + "wbqc-violation-message-invalid-scope": "$1 is not a valid scope for the constraint type $2; the only valid {{PLURAL:$3|scope|scopes}} for this constraint type {{PLURAL:$3|is $5.|2=are $5 and $6.|are: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Commons link should exist.", + "wbqc-violation-message-commons-link-not-well-formed": "Commons link should be well-formed.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Check for namespace \"$1\" is not yet implemented.", + "wbqc-violation-message-conflicts-with-property": "An entity should not have statements for both $1 and $2.", + "wbqc-violation-message-conflicts-with-claim": "An entity should not have a statement for $1 if it also has a statement for $2 with value $3.", + "wbqc-violation-message-contemporary-subject-earlier": "The entities $1 and $3 should be contemporary to be linked through $2, but the latest end value of $1 is $4 and the earliest start value of $3 is $5.", + "wbqc-violation-message-contemporary-value-earlier": "The entities $1 and $3 should be contemporary to be linked through $2, but the latest end value of $3 is $4 and the earliest start value of $1 is $5.", + "wbqc-violation-message-diff-within-range": "The difference between $3 ($4) and $1 ($2) should be between $5 and $6.", + "wbqc-violation-message-diff-within-range-leftopen": "The difference between $3 ($4) and $1 ($2) should be no more than $5.", + "wbqc-violation-message-diff-within-range-rightopen": "The difference between $3 ($4) and $1 ($2) should be no less than $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "The property defined in the parameters must have a value of the same type as this property.", + "wbqc-violation-message-format": "The value for $1 ($2) should match the regex $3.", + "wbqc-violation-message-format-clarification": "The value for $1 ($2) should match “$4” (regex: $3).", + "wbqc-violation-message-inverse": "$1 should also have the inverse statement $2 $3.", + "wbqc-violation-message-item": "An entity with $1 should also have {{PLURAL:$3|0=a statement $2.|1=a statement $2 $5.|a statement for $2 with one of the following values:$4}}", + "wbqc-violation-message-mandatory-qualifier": "This $1 statement is missing a qualifier $2.", + "wbqc-violation-message-multi-value": "This property should contain multiple values.", + "wbqc-violation-message-multi-value-separators": "This property should contain multiple values with the same {{PLURAL:$2|1=$4 qualifier.|set of qualifiers for these properties: $3}}", + "wbqc-violation-message-one-of": "The value for $1 should be {{PLURAL:$2|1=$4.|2=either $4 or $5.|one of the following:$3}}", + "wbqc-violation-message-qualifier": "The property should only be used as a qualifier.", + "wbqc-violation-message-no-qualifiers": "$1 statements should not have any qualifiers.", + "wbqc-violation-message-qualifiers": "$2 is not a valid qualifier for $1 – the only valid {{PLURAL:$3|1=qualifier is $5.|2=qualifiers are $5 and $6.|qualifiers are:$4}}", + "wbqc-violation-message-range-parameters-needed": "Properties with values of type \"$1\" with constraint \"$4\" need the parameters \"$2\" and \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Endpoints of a time-unit range must either both or neither have the unit \"year\" because years cannot be converted losslessly to seconds.", + "wbqc-violation-message-range-parameters-same": "The start ($1) and end point ($2) of a range must not be the same.", + "wbqc-violation-message-range-quantity-closed": "The value for $1 ($2) should be between $3 and $4.", + "wbqc-violation-message-range-quantity-leftopen": "The value for $1 ($2) should be no more than $3.", + "wbqc-violation-message-range-quantity-rightopen": "The value for $1 ($2) should be no less than $3.", + "wbqc-violation-message-range-time-closed": "The value for $1 ($2) should be between $3 and $4.", + "wbqc-violation-message-range-time-closed-leftnow": "The value for $1 ($2) should be in the future, but not after $3.", + "wbqc-violation-message-range-time-closed-rightnow": "The value for $1 ($2) should be in the past, but not before $3.", + "wbqc-violation-message-range-time-leftopen": "The value for $1 ($2) should not be after $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "The value for $1 ($2) should not be in the future.", + "wbqc-violation-message-range-time-rightopen": "The value for $1 ($2) should not be before $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "The value for $1 ($2) should not be in the past.", + "wbqc-violation-message-single-value": "This property should only contain a single value.", + "wbqc-violation-message-single-value-separators": "This property should only have a single value with the same {{PLURAL:$2|1=$4 qualifier.|set of qualifiers for these properties: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "This property should contain a single “best” value. Of the current multiple values, one should be marked with “preferred” rank.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "This property should contain a single “best” value with the same {{PLURAL:$2|1=$4 qualifier.|set of qualifiers for these properties: $3}} Of the current multiple values, one should be marked with “preferred” rank.", + "wbqc-violation-message-single-best-value-multi-preferred": "This property should contain a single “best” value. There should not be more than one value with “preferred” rank.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "This property should contain a single “best” value with the same {{PLURAL:$2|1=$4 qualifier.|set of qualifiers for these properties: $3}} There should not be more than one value with “preferred” rank.", + "wbqc-violation-message-symmetric": "$1 should also have the symmetric statement $2 $3.", + "wbqc-violation-message-type-instance": "Entities using the $1 property should be instances of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-type-subclass": "Entities using the $1 property should be subclasses of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entities using the $1 property should be instances or subclasses of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-valueType-instance": "Values of $1 statements should be instances of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-valueType-subclass": "Values of $1 statements should be subclasses of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Values of $1 statements should be instances or subclasses of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't: $4}}", + "wbqc-violation-message-target-required-claim": "$1 should have {{PLURAL:$3|0=a statement $2.|1=a statement $2 $5.|a statement for $2 with one of the following values:$4}}", + "wbqc-violation-message-unique-value": "This property's value should not be present on any other item, but is also present on {{PLURAL:$1|1=$3.|2=$3 and $4.|the following items: $2}}", + "wbqc-violation-message-valueOnly": "This property should only be used for the main value of a statement, not for qualifiers or references.", + "wbqc-violation-message-reference": "The property should only be used in references, not for the main value of a statement or for a qualifier.", + "wbqc-violation-message-noBounds": "Values for $1 should not have any bounds.", + "wbqc-violation-message-units-none": "The value for $1 should not have a unit.", + "wbqc-violation-message-units": "The value for $1 should have {{PLURAL:$2|1=the unit $4.|2=the unit $4 or $5.|one of the following units: $3}}", + "wbqc-violation-message-units-or-none": "The value for $1 should have {{PLURAL:$2|1=the unit $4|2=the unit $4 or $5|one of the following units}} or be {{PLURAL:$2|1=unitless.|2=unitless.|unitless: $3}}", + "wbqc-violation-message-entityType": "The property $1 should not be used on this type of entity, the only valid {{PLURAL:$2|1=entity type is $4.|2=entity types are $4 and $5.|entity types are: $3}}", + "wbqc-violation-message-none-of": "The value for $1 should not be {{PLURAL:$2|1=$4.|2=either $4 or $5.|one of the following:$3}}", + "wbqc-violation-message-integer": "Values for $1 should be integer, but $2 has a fractional part.", + "wbqc-violation-message-integer-bounds": "Values for $1 should be integer, but the bounds of $2 have a fractional part.", + "wbqc-violation-message-citationNeeded": "Statements for $1 should have at least one reference.", + "wbqc-violation-message-language": "Statements for $1 should be only on Lexemes with language set to {{PLURAL:$2|1=$4.|2=either $4 or $5.|one of the following: $3}}", + "wbqc-violation-message-label-lacking": "Entities with statements for $1 should also have a label at least in {{PLURAL:$2|1=$4 language.|any of the following languages: $3}}", + "wbqc-violation-message-property-scope": "The property $1 should not be used in this location ($2). The only valid {{PLURAL:$3|location|locations}} for this property {{PLURAL:$3|is $5.|are: $4}}", + "wbqc-violation-message-exception": "This entity is a known exception for this constraint and has been marked as such." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/eo.json b/dist/extensions/WikibaseQualityConstraints/i18n/eo.json new file mode 100644 index 000000000..c891f27e6 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/eo.json @@ -0,0 +1,39 @@ +{ + "@metadata": { + "authors": [ + "Mirin", + "Robin van der Vliet" + ] + }, + "wbqc-constraintreport": "Raporto pri limigo", + "wbqc-constraintreport-form-section": "Kontroli limigojn de ento", + "wbqc-constraintreport-form-submit-label": "Kontroli", + "wbqc-constraintreport-form-entityid-label": "Identigilo de ento:", + "wbqc-constraintreport-result-headline": "Rezulto por", + "wbqc-constraintreport-invalid-entity-id": "Ne valida identigilo de ento.", + "wbqc-constraintreport-not-existent-entity": "Ento ne ekzistas.", + "wbqc-constraintreport-empty-result": "Ne estas limigoj difinitaj por ĉi tiu ento.", + "wbqc-constraintreport-status-exception": "Escepto", + "wbqc-constraintreport-status-bad-parameters": "Malĝustaj parametroj", + "wbqc-constraintreport-status-warning": "Averto", + "wbqc-constraintreport-result-table-header-status": "Stato", + "wbqc-constraintreport-result-table-header-property": "Eco", + "wbqc-constraintreport-result-table-header-message": "Mesaĝo", + "wbqc-constraintreport-result-table-header-constraint": "Limigo", + "wbqc-constraintreport-no-parameter": "nenio", + "wbqc-issues-short": "Problemoj", + "wbqc-potentialissues-short": "Eblaj problemoj", + "wbqc-suggestions-short": "Sugestoj", + "wbqc-badparameters-short": "Malĝustaj parametroj", + "wbqc-parameterissues-short": "Altnivelaj problemoj", + "wbqc-constrainttypehelp-short": "Helpo", + "wbqc-constraintdiscuss-short": "Diskuto", + "wbqc-dataValueType-wikibase-entityid": "Identigilo de Ento", + "wbq-subextension-name-wbqc": "Limigoj", + "wbqc-violation-header-parameters": "Parametroj:", + "wbqc-violations-group": "Limigoj", + "wbqc-violation-message-target-entity-must-exist": "La cela ento devas ekzisti.", + "wbqc-violation-message-value-entity-must-exist": "La valoro-ento devas ekzisti.", + "wbqc-violation-message-parameter-regex": "$1 ne estas valida regula esprimo.", + "wbqc-violation-message-commons-link-no-existent": "Ligilo al Komunejo devas ekzisti." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/es.json b/dist/extensions/WikibaseQualityConstraints/i18n/es.json new file mode 100644 index 000000000..cbf753e4e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/es.json @@ -0,0 +1,156 @@ +{ + "@metadata": { + "authors": [ + "2axterix2", + "Agabi10", + "Ciencia Al Poder", + "Csbotero", + "Danniel07", + "DannyS712", + "Dgstranz", + "Fitoschido", + "KATRINE1992", + "Macofe", + "MarcoAurelio", + "Themasterriot", + "Tiberius1701", + "No se" + ] + }, + "wbqc-constraintreport": "Informe de restricción", + "wbqc-desc": "Comprueba las restricciones en elementos y propiedades y muestra el resultado en una página especial", + "wbqc-constraintreport-explanation-part-one": "Esta página especial realiza comprobaciones de restricciones en cualquier entidad que quieras. Las entidades se recogen del sistema en tiempo real, por lo que cualquier violación que arregles será eliminada de esta lista instantáneamente.", + "wbqc-constraintreport-explanation-part-two": "Las restricciones se obtienen de las declaraciones de las propiedades cada vez que esas declaraciones son editadas, generalmente con un margen de pocos minutos.", + "wbqc-constraintreport-form-section": "Verificar las restricciones para la entidad", + "wbqc-constraintreport-form-submit-label": "Verificar", + "wbqc-constraintreport-form-entityid-label": "Identificador de entidad:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx o Pxx", + "wbqc-constraintreport-result-headline": "Resultado de", + "wbqc-constraintreport-invalid-entity-id": "Identificador de entidad no válido.", + "wbqc-constraintreport-not-existent-entity": "La entidad no existe.", + "wbqc-constraintreport-empty-result": "No hay restricciones definidas en esta entidad.", + "wbqc-constraintreport-status-violation": "Violación", + "wbqc-constraintreport-status-compliance": "Conformidad", + "wbqc-constraintreport-status-exception": "Excepción", + "wbqc-constraintreport-status-todo": "Pendiente", + "wbqc-constraintreport-status-bad-parameters": "Parámetros incorrectos", + "wbqc-constraintreport-status-deprecated": "En desuso", + "wbqc-constraintreport-status-warning": "Advertencia", + "wbqc-constraintreport-status-suggestion": "Sugerencia", + "wbqc-constraintreport-status-not-in-scope": "Fuera del ámbito", + "wbqc-constraintreport-result-table-header-status": "Estado", + "wbqc-constraintreport-result-table-header-property": "Propiedad", + "wbqc-constraintreport-result-table-header-message": "Mensaje", + "wbqc-constraintreport-result-table-header-constraint": "Restricción", + "wbqc-constraintreport-result-link-to-claim": "ir a la afirmación", + "wbqc-constraintreport-result-link-to-constraint": "ir a la restricción", + "wbqc-constraintreport-no-parameter": "ninguno", + "wbqc-issues-short": "Problemas", + "wbqc-issues-long": "Esta declaración presenta algunos problemas.", + "wbqc-potentialissues-short": "Problemas posibles", + "wbqc-potentialissues-long": "Esta declaración tiene problemas potenciales.", + "wbqc-suggestions-short": "Sugerencias", + "wbqc-suggestions-long": "Hay algunas sugerencias para mejorar esta declaración.", + "wbqc-badparameters-short": "Parámetros incorrectos", + "wbqc-badparameters-long": "Esta declaración de restricción incluye algunos parámetros no válidos.", + "wbqc-parameterissues-short": "Incidencias avanzadas", + "wbqc-parameterissues-long": "Estos problemas radican en la definición de la restricción en la propiedad, no en esta declaración.", + "wbqc-constrainttypehelp-short": "Ayuda", + "wbqc-constrainttypehelp-long": "Página de ayuda sobre este tipo de restricción", + "wbqc-constraintdiscuss-short": "Discutir", + "wbqc-constraintdiscuss-long": "Página de discusión sobre esta restricción", + "wbqc-cached-generic": "Este resultado está prealmacenado y puede estar desfasado.", + "wbqc-cached-minutes": "Este resultado está prealmacenado y puede estar desfasado por hasta {{PLURAL:$1|1=un minuto|$1 minutos}}.", + "wbqc-cached-hours": "Este resultado está prealmacenado y puede estar desactualizado por hasta {{PLURAL:$1|1=una hora|$1 horas}}.", + "wbqc-cached-days": "Este resultado está prealmacenado y puede estar desactualizado por hasta {{PLURAL:$1|1=un día|$1 días}}.", + "wbqc-dataValueType-wikibase-entityid": "Id. de entidad", + "wbq-subextension-name-wbqc": "Restricciones", + "wbqc-violation-header-parameters": "Parámetros:", + "wbqc-violations-group": "Restricciones", + "wbqc-violation-message": "La verificación de restricciones ha señalado una violación. Pulsa el icono para obtener más información.", + "wbqc-violation-message-not-yet-implemented": "Por motivos técnicos, aún no se ha implementado la comprobación de la restricción «$1».", + "wbqc-violation-message-security-reason": "Por motivos de seguridad, en este momento no es posible comprobar la restricción «$1». Estamos trabajando en una solución.", + "wbqc-violation-message-value-needed-of-type": "Las propiedades con la restricción «$1» deben tener valores del tipo «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Las propiedades con la restricción «$1» deben tener valores del tipo «$2» o el tipo «$3».", + "wbqc-violation-message-parameter-needed": "Las propiedades con la restricción «$1» necesitan el parámetro «$2».", + "wbqc-violation-message-parameters-needed-3": "Las propiedades con la restricción «$1» necesitan los parámetros «$2», «$3» y «$4».", + "wbqc-violation-message-target-entity-must-exist": "La entidad de destino debe existir.", + "wbqc-violation-message-value-entity-must-exist": "La entidad de valor debe existir.", + "wbqc-violation-message-parameter-value": "El parámetro \"$1\" debería tener un valor personalizado, no \"sin valor\" o \"valor desconocido\".", + "wbqc-violation-message-parameter-value-or-novalue": "El parámetro $1 debería tener un valor personalizado o \"sin valor\", pero nunca \"valor desconocido\".", + "wbqc-violation-message-parameter-entity": "El valor del parámetro «$1» debe ser una entidad, no «$2».", + "wbqc-violation-message-parameter-item": "El valor del parámetro «$1» debe ser un elemento, no «$2».", + "wbqc-violation-message-parameter-property": "El valor del parámetro «$1» debe ser una propiedad, no «$2».", + "wbqc-violation-message-parameter-string": "El valor del parámetro «$1» debe ser una cadena, no «$2».", + "wbqc-violation-message-parameter-monolingualtext": "El valor del parámetro «$1» debe ser un texto monolingüe, no «$2».", + "wbqc-violation-message-parameter-single": "El parámetro «$1» solo debe contar con un valor.", + "wbqc-violation-message-parameter-single-per-language": "El parámetro «$1» debe poseer únicamente un valor por idioma, pero posee varios valores para $2 ($3).", + "wbqc-violation-message-parameter-oneof": "El parámetro «$1» debe ser {{PLURAL:$2|1=$4.|2=o $4 o $5.|uno de los siguientes:$3}}", + "wbqc-violation-message-parameter-regex": "$1 no es una expresión regular válida.", + "wbqc-violation-message-sparql-error": "La consulta SPARQL produjo un error.", + "wbqc-violation-message-parameters-error-unknown": "No se pudieron importar los parámetros de esta restricción.", + "wbqc-violation-message-parameters-error-toolong": "No se pudieron importar los parámetros de esta restricción porque eran demasiado largos.", + "wbqc-violation-message-invalid-scope": "$1 no es un ámbito válido para el tipo de restricción $2; {{PLURAL:$3|el único ámbito válido|los únicos ámbitos válidos}} para este tipo de restricción {{PLURAL:$3|es $5.|2=son $5 y $6.|son: $4}}", + "wbqc-violation-message-commons-link-no-existent": "El enlace a Commons debería existir.", + "wbqc-violation-message-commons-link-not-well-formed": "El enlace a Commons debería estar bien formado.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "La verificación para el espacio de nombres \"$1\" todavía no está implementada.", + "wbqc-violation-message-conflicts-with-property": "Las entidades no deben incluir declaraciones para $1 y $2 a la vez.", + "wbqc-violation-message-conflicts-with-claim": "Una entidad no debería tener una declaración para $1 si también contiene una declaración $2 con valor $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Las entidades $1 y $3 deberían ser contemporáneas para poder ser enlazadas con $2, pero el último valor de final de $1 es $4 y el primer valor de inicio de $3 es $5.", + "wbqc-violation-message-contemporary-value-earlier": "Las entidades $1 y $3 deberían ser contemporáneas para poder ser enlazadas con $2, pero el último valor de final de $3 es $4 y el primer valor de inicio de $1 es $5.", + "wbqc-violation-message-diff-within-range": "La diferencia entre $3 ($4) y $1 ($2) debe ser de entre $5 y $6.", + "wbqc-violation-message-diff-within-range-leftopen": "La diferencia entre $3 ($4) y $1 ($2) no debe ser mayor de $5.", + "wbqc-violation-message-diff-within-range-rightopen": "La diferencia entre $3 ($4) y $1 ($2) no debe ser menor de $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "La propiedad definida en los parámetros debe tener un valor del mismo tipo que esta propiedad.", + "wbqc-violation-message-format": "El valor de $1 ($2) debería coincidir con la expresión regular $3.", + "wbqc-violation-message-format-clarification": "El valor de $1 ($2) debería coincidir con «$4» (regex: $3).", + "wbqc-violation-message-inverse": "$1 también debería tener la declaración inversa $2 $3.", + "wbqc-violation-message-item": "Las entidades que incluyan $1 deben contar también con {{PLURAL:$3|0=una declaración $2.|1=una declaración $2 $5.|una declaración para $2 con uno de los valores siguientes: $4}}", + "wbqc-violation-message-mandatory-qualifier": "A esta declaración $1 le falta un calificativo $2", + "wbqc-violation-message-multi-value": "Esta propiedad debe contener varios valores.", + "wbqc-violation-message-multi-value-separators": "Esta propiedad debería tener múltiples valores con el mismo {{PLURAL:$2|1=calificador $4.|grupo de calificadores con las propiedades: $3}}", + "wbqc-violation-message-one-of": "El valor para $1 debería ser {{PLURAL:$2|1=$4.|2=$4 o $5.|uno de los siguientes:$3}}", + "wbqc-violation-message-qualifier": "La propiedad debería utilizarse solo como un calificativo.", + "wbqc-violation-message-no-qualifiers": "Las declaraciones $1 no deberían tener calificadores.", + "wbqc-violation-message-qualifiers": "$2 no es un calificativo válido para $1. {{PLURAL:$3|1=El único calificativo válido es $5.|2=Los únicos calificativos válidos son $5 y $6.|Los únicos calificativos válidos son: $4}}", + "wbqc-violation-message-range-parameters-needed": "Las propiedades con valores del tipo «$1» que tengan la restricción «$4» necesitan los parámetros «$2» y «$3».", + "wbqc-violation-message-range-parameters-same": "Los puntos inicial ($1) y final ($2) de un intervalo no deben coincidir.", + "wbqc-violation-message-range-quantity-closed": "El valor de $1 ($2) debe estar entre $3 y $4.", + "wbqc-violation-message-range-quantity-leftopen": "El valor de $1 ($2) no debe ser mayor que $3.", + "wbqc-violation-message-range-quantity-rightopen": "El valor de $1 ($2) no debe ser menor que $3.", + "wbqc-violation-message-range-time-closed": "El valor de $1 ($2) debe estar entre $3 y $4.", + "wbqc-violation-message-range-time-closed-leftnow": "El valor de $1 ($2) debe estar en el futuro pero no después de $3.", + "wbqc-violation-message-range-time-closed-rightnow": "El valor de $1 ($2) debe estar en el pasado pero no antes de $3.", + "wbqc-violation-message-range-time-leftopen": "El valor de $1 ($2) no debe ser posterior a $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "El valor de $1 ($2) no debe estar en el futuro.", + "wbqc-violation-message-range-time-rightopen": "El valor de $1 ($2) no debe ser anterior a $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "El valor de $1 ($2) no debe estar en el pasado.", + "wbqc-violation-message-single-value": "Esta propiedad debería contener un único valor.", + "wbqc-violation-message-single-value-separators": "Esta propiedad debería tener un único valor con el mismo {{PLURAL:$2|1=calificador $4.|grupo de calificadores con las propiedades: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Esta propiedad debe contener un único valor «mejor». De los múltiples valores actuales, uno debe estar marcado con el rango «preferido».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Esta propiedad debe contener un único valor «mejor» con el mismo {{PLURAL:$2|1=calificador $4.|conjunto de calificadores para las propiedades: $3}} De los valores múltiples actuales, uno debe estar marcado con rango «preferido».", + "wbqc-violation-message-single-best-value-multi-preferred": "Esta propiedad debe contener un único valor «mejor». No debe haber más de un valor con rango «preferido».", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Esta propiedad debe contener un único valor «mejor» con el mismo {{PLURAL:$2|1=calificador $4.|conjunto de calificadores para las propiedades: $3}} No debe haber más de un valor con el rango «preferido».", + "wbqc-violation-message-symmetric": "$1 también debería tener la declaración simétrica $2 $3.", + "wbqc-violation-message-type-instance": "Las entidades que utilicen la propiedad $1 deberían ser instancias de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-type-subclass": "Las entidades que utilicen la propiedad $1 deberían ser subclases de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Las entidades que utilicen la propiedad $1 deberían ser instancias o subclases de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-valueType-instance": "Los valores de declaraciones $1 deberían ser instancias de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-valueType-subclass": "Los valores de declaraciones $1 deberían ser subclases de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Los valores de declaraciones $1 deberían ser instancias o subclases de {{PLURAL:$3|1=$5|2=$5 o $6|una de las siguientes clases}} (o de {{PLURAL:$3|1=una subclase suya|2=una subclase suya|una de sus subclases}}), pero actualmente $2 {{PLURAL:$3|no lo es.|2=no lo es.|no lo es: $4}}", + "wbqc-violation-message-target-required-claim": "$1 debería tener {{PLURAL:$3|0=una declaración $2.|1=una declaración $2 $5.|una declaración para $2 con uno de los siguientes valores:$4}}", + "wbqc-violation-message-unique-value": "El valor de esta propiedad no debe estar presente en ningún otro elemento, pero existe también en {{PLURAL:$1|1=$3.|2=$3 y $4.|los elementos siguientes: $2}}", + "wbqc-violation-message-valueOnly": "Esta propiedad sólo debería utilizarse para el valor principal de la declaración, no para calificadores o referencias.", + "wbqc-violation-message-reference": "Esta propiedad solo debería usarse para referencias, no para el valor principal de la declaración o calificativos.", + "wbqc-violation-message-noBounds": "Los valores de $1 no deberían tener límites.", + "wbqc-violation-message-units-none": "El valor de $1 no debe incluir una unidad.", + "wbqc-violation-message-units": "El valor para $1 debería tener {{PLURAL:$2|1=como unidad $4.|2=como unidad $4 o $5.|una de las siguientes unidades:$3}}", + "wbqc-violation-message-units-or-none": "El valor para $1 debería tener {{PLURAL:$2|1=de unidad $4|2=de unidad $4 o $5|una de las siguientes unidades}} o no tener unidad {{PLURAL:$2|1=definida.|2=definida.|definida: $3}}", + "wbqc-violation-message-entityType": "La propiedad $1 no debe utilizarse en este tipo de entidad, {{plural:$2|1=el único tipo de entidad válido es $4.|los únicos tipos de entidad válidos son $4 y $5.|los tipos de entidad son: $3}}", + "wbqc-violation-message-integer": "Los valores de $1 deberían ser enteros, pero $2 tiene una parte fraccional.", + "wbqc-violation-message-integer-bounds": "Los valores de $1 deberían ser enteros, pero los límites de $2 tienen una parte fraccional.", + "wbqc-violation-message-citationNeeded": "Las declaraciones de $1 deberían tener al menos una referencia.", + "wbqc-violation-message-label-lacking": "Entidades con declaraciones para $1 deben también tener una etiqueta por lo menos en {{PLURAL:$2|1=idioma $4.|cualquiera de los siguientes idiomas: $3}}", + "wbqc-violation-message-property-scope": "La propiedad $1 no debe utilizarse en esta ubicación ($2). L{{plural:$3|a única ubicación válida|as únicas ubicaciones válidas}} para esta propiedad {{plural:$3|es $5.|son: $4}}", + "wbqc-violation-message-exception": "Esta entidad es una excepción conocida a esta restricción y ha sido marcada como tal." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/et.json b/dist/extensions/WikibaseQualityConstraints/i18n/et.json new file mode 100644 index 000000000..ad8c7c50e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/et.json @@ -0,0 +1,129 @@ +{ + "@metadata": { + "authors": [ + "Pikne" + ] + }, + "wbqc-constraintreport": "Kitsenduste aruanne", + "wbqc-desc": "Kontrollib nii üksuste kui ka omaduste kitsendusi ja kuvab tulemused erileheküljel.", + "wbqc-constraintreport-explanation-part-one": "See erilehekülg kontrollib kitsendusi ükskõik millise olemi suhtes. Olemid laaditakse sellisel kujul nagu nad süsteemis praegu esinevad. Seega iga kitsenduse rikkumine, mille parandad, eemaldatakse kohe loetelust.", + "wbqc-constraintreport-explanation-part-two": "Kitsendused parsitakse omaduste kohta käivatest avaldustest iga kord, kui neid omadusi redigeeritakse, seda harilikult mõne minuti jooksul.", + "wbqc-constraintreport-form-section": "Kitsenduste kontrollimine olemi suhtes", + "wbqc-constraintreport-form-submit-label": "Kontrolli", + "wbqc-constraintreport-form-entityid-label": "Olemi identifikaator:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx või Pxx", + "wbqc-constraintreport-result-headline": "Tulemused:", + "wbqc-constraintreport-invalid-entity-id": "Vigane olemi identifikaator.", + "wbqc-constraintreport-not-existent-entity": "Olemit ei ole olemas.", + "wbqc-constraintreport-empty-result": "Selle olemiga pole seotud ükski kitsendus.", + "wbqc-constraintreport-status-violation": "Rikkumine", + "wbqc-constraintreport-status-compliance": "Vastavus", + "wbqc-constraintreport-status-exception": "Erand", + "wbqc-constraintreport-status-bad-parameters": "Vigased parameetrid", + "wbqc-constraintreport-status-deprecated": "Vananenud", + "wbqc-constraintreport-status-warning": "Hoiatus", + "wbqc-constraintreport-status-suggestion": "Soovitus", + "wbqc-constraintreport-status-not-in-scope": "Ebasobiv kasutusviis", + "wbqc-constraintreport-result-table-header-status": "Olek", + "wbqc-constraintreport-result-table-header-property": "Omadus", + "wbqc-constraintreport-result-table-header-message": "Sõnum", + "wbqc-constraintreport-result-table-header-constraint": "Kitsendus", + "wbqc-issues-short": "Probleemid", + "wbqc-issues-long": "Sellel avaldusel on mõned probleemid.", + "wbqc-potentialissues-short": "Võimalikud probleemid", + "wbqc-potentialissues-long": "Sellel avaldusel on mõned võimalikud probleemid.", + "wbqc-suggestions-short": "Soovitused", + "wbqc-suggestions-long": "Selle avalduse täiustamise kohta on soovitusi.", + "wbqc-parameterissues-short": "Kaudselt seotud probleemid", + "wbqc-parameterissues-long": "Need probleemid on seotud kitsenduse määratluse ja omaduse endaga, mitte selle avaldusega.", + "wbqc-constrainttypehelp-short": "Abi", + "wbqc-constrainttypehelp-long": "Seda tüüpi kitsenduse abileht", + "wbqc-constraintdiscuss-short": "Arutelu", + "wbqc-constraintdiscuss-long": "Arutelulehekülg selle kitsenduse kohta", + "wbqc-cached-generic": "See tulemus on puhverdatud ja võib olla iganenud.", + "wbqc-cached-minutes": "See tulemus on puhverdatud ja võib olla iganenud kuni {{PLURAL:$1|1=üks minut|$1 minutit}}.", + "wbqc-cached-hours": "See tulemus on puhverdatud ja võib olla iganenud kuni {{PLURAL:$1|1=üks tund|$1 tundi}}.", + "wbqc-cached-days": "See tulemus on puhverdatud ja võib olla iganenud kuni {{PLURAL:$1|1=üks päev|$1 päeva}}.", + "wbqc-violation-message-value-needed-of-type": "Omadused kitsendusega \"$1\" vajavad väärtusi tüübiga \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Omadused kitsendusega \"$1\" vajavad väärtusi tüübiga \"$2\" või \"$3\".", + "wbqc-violation-message-parameter-needed": "Omadused kitsendusega \"$1\" vajavad parameetrit \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Omadused kitsendusega \"$1\" vajavad parameetreid \"$2\", \"$3\" ja \"$4\".", + "wbqc-violation-message-parameter-value": "Parameetril \"$1\" peab olema kohandatud väärtus, mitte \"väärtus puudub\" ega \"väärtus teadmata\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parameetril \"$1\" peab olema kohandatud väärtus või \"väärtus puudub\", mitte \"väärtus teadmata\".", + "wbqc-violation-message-parameter-entity": "Parameetri \"$1\" väärtus peab olema olem, mitte \"$2\".", + "wbqc-violation-message-parameter-item": "Parameetri \"$1\" väärtus peab olema üksus, mitte \"$2\".", + "wbqc-violation-message-parameter-property": "Parameetri \"$1\" väärtus peab olema omadus, mitte \"$2\".", + "wbqc-violation-message-parameter-string": "Parameetri \"$1\" väärtus peab olema sõne, mitte \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Parameetri \"$1\" väärtus peab olema ühekeelne tekst, mitte \"$2\".", + "wbqc-violation-message-parameter-single": "Parameetril \"$1\" peab olema ainult üks väärtus.", + "wbqc-violation-message-parameter-single-per-language": "Parameetril \"$1\" peab olema keele kohta ainult üks väärtus, aga sellel on keeles $2 ($3) mitu väärtust.", + "wbqc-violation-message-parameter-oneof": "Parameeter \"$1\" peab olema {{PLURAL:$2|1=$4.|2=kas $4 või $5.|üks järgmistest:$3}}", + "wbqc-violation-message-parameter-regex": "$1 pole õige regulaaravaldis.", + "wbqc-violation-message-parameters-error-unknown": "Selle kitsenduse parameetreid ei õnnestunud importida.", + "wbqc-violation-message-parameters-error-toolong": "Selle kitsenduse parameetreid ei õnnestunud importida, sest need on liiga pikad.", + "wbqc-violation-message-invalid-scope": "$1 ei ole tüübi $2 kitsendusele sobiv kasutusviis. Seda tüüpi kitsenduse {{PLURAL:$3|ainus sobiv kasutusviis|ainsad sobivad kasutusviisid}} {{PLURAL:$3|on $5.|2=on $5 ja $6.|on järgmised: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Commonsi link peaks olemas olema.", + "wbqc-violation-message-commons-link-not-well-formed": "Commonsi link peaks olema reeglipärasel kujul.", + "wbqc-violation-message-conflicts-with-property": "Olemil ei peaks olema korraga avaldusi omaduste $1 ja $2 kohta.", + "wbqc-violation-message-conflicts-with-claim": "Olemil ei peaks olema avaldust omaduse $1 kohta, kui tal on ka avaldus omaduse $2 kohta väärtusega $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Olemid $1 ja $3 peaks olema kaasaegsed, et olla seotud omaduse $2 kaudu, aga olemi $1 hiliseim lõppväärtus on $4 ja olemi $3 varaseim algusväärtus on $5.", + "wbqc-violation-message-contemporary-value-earlier": "Olemid $1 ja $3 peaks olema kaasaegsed, et olla seotud omaduse $2 kaudu, aga olemi $3 hiliseim lõppväärtus on $4 ja olemi $1 varaseim algusväärtus on $5.", + "wbqc-violation-message-diff-within-range": "Erinevus omaduste $3 ($4) ja $1 ($2) vahel peaks olema piiride $5 ja $6 vahel.", + "wbqc-violation-message-diff-within-range-leftopen": "Erinevus omaduste $3 ($4) ja $1 ($2) vahel ei peaks olema suurem kui $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Erinevus omaduste $3 ($4) ja $1 ($2) vahel ei peaks olema väiksem kui $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Sellel omadusel ja parameetrites määratud omadusel peab olema sama tüüpi väärtus.", + "wbqc-violation-message-format": "Omaduse $1 väärtus ($2) peaks vastama regulaaravaldisele $3.", + "wbqc-violation-message-format-clarification": "Omaduse $1 väärtus ($2) peaks vastama järgmisele selgitusele: \"$4\" (regulaaravaldis: $3).", + "wbqc-violation-message-inverse": "Olemil $1 peaks samuti olema ümberpööratud avaldus $2 $3.", + "wbqc-violation-message-item": "Olemil avaldusega $1 peaks olema ka {{PLURAL:$3|0=avaldus $2.|1=avaldus $2 $5.|avaldus $2 ühega järgmistest väärtustest:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Avalduselt $1 puudub täpsustus $2.", + "wbqc-violation-message-multi-value": "Sellel omadusel peaks olema mitu väärtust.", + "wbqc-violation-message-multi-value-separators": "Sellel omadusel peaks olema mitu väärtust sama {{PLURAL:$2|1=täpsustusega $4.|täpsustuste komplektiga, mis koosneb neist omadustest: $3}}", + "wbqc-violation-message-one-of": "Omaduse $1 väärtus peaks olema {{PLURAL:$2|1=$4.|2=kas $4 või $5.|üks järgmistest:$3}}", + "wbqc-violation-message-qualifier": "Seda omadust tuleks kasutada ainult täpsustusena.", + "wbqc-violation-message-no-qualifiers": "Avaldusel $1 ei peaks olema ühtegi täpsustust.", + "wbqc-violation-message-qualifiers": "$2 ei ole avaldusele $1 sobiv täpsustus. {{PLURAL:$3|1=Ainus sobiv täpsustus on $5.|2=Ainsad sobivad täpsustused on $5 ja $6.|Ainsad sobivad täpsustused on järgmised:$4}}", + "wbqc-violation-message-range-parameters-needed": "Omadused, mille väärtuse tüüp on \"$1\" ja kitsendus \"$4\", vajavad parameetreid \"$2\" ja \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Ajaühikuga vahemiku mõlemad piirid peavad olema kas ühikuga \"aasta\" või kumbki neist ei saa olla selle ühikuga, sest aastaid ei saa kadudeta sekunditesse teisendada.", + "wbqc-violation-message-range-parameters-same": "Vahemiku algus ($1) ja lõpp ($2) ei tohi olla sama.", + "wbqc-violation-message-range-quantity-closed": "Omaduse $1 ($2) väärtus peaks olema piiride $3 ja $4 vahel.", + "wbqc-violation-message-range-quantity-leftopen": "Omaduse $1 ($2) väärtus ei peaks olema suurem kui $3.", + "wbqc-violation-message-range-quantity-rightopen": "Omaduse $1 ($2) väärtus ei peaks olema väiksem kui $3.", + "wbqc-violation-message-range-time-closed": "Omaduse $1 ($2) väärtus peaks olema piiride $3 ja $4 vahel.", + "wbqc-violation-message-range-time-closed-leftnow": "Omaduse $1 ($2) väärtus peaks olema tulevikus, aga mitte pärast piiri $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Omaduse $1 ($2) väärtus peaks olema minevikus, aga mitte enne piiri $3.", + "wbqc-violation-message-range-time-leftopen": "Omaduse $1 ($2) väärtus ei peaks olema pärast piiri $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Omaduse $1 ($2) väärtus ei peaks olema tulevikus.", + "wbqc-violation-message-range-time-rightopen": "Omaduse $1 ($2) väärtus ei peaks olema enne piiri $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Omaduse $1 ($2) väärtus ei peaks olema minevikus.", + "wbqc-violation-message-single-value": "Sellel omadusel peaks olema ainult üks väärtus.", + "wbqc-violation-message-single-value-separators": "Sellel omadusel peaks olema ainult üks väärtus, millel on sama {{PLURAL:$2|1=väärtusega täpsustus $4.|täpsustuste komplekt, milles järgmistel omadustel on samad väärtused. $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Omadusel peaks olema üks \"parim\" väärtus. Praegusest mitmest väärtusest tuleks üks märkida eelisjärku.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Omadusel peaks olema üks \"parim\" väärtus sama {{PLURAL:$2|1=täpsustusega $4.|täpsustuste komplektiga, mis koosneb järgmistest omadustest: $3}} Praegusest mitmest väärtusest tuleks üks märkida eelisjärku.", + "wbqc-violation-message-single-best-value-multi-preferred": "Omadusel peaks olema üks \"parim\" väärtus. Eelisjärguga ei peaks olema rohkem kui üks väärtus.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Omadusel peaks olema üks \"parim\" väärtus sama {{PLURAL:$2|1=täpsustusega $4.|täpsustuste komplektiga, mis koosneb järgmistest omadustest: $3}} Eelisjärguga ei peaks olema rohkem kui üks väärtus.", + "wbqc-violation-message-symmetric": "Olemil $1 peaks samuti olema sümmeetriline avaldus $2 $3.", + "wbqc-violation-message-type-instance": "Olemid, mis kasutavad omadust $1, peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) üksikjuhud, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-type-subclass": "Olemid, mis kasutavad omadust $1, peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) alamklassid, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Olemid, mis kasutavad omadust $1, peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) üksikjuhud või alamklassid, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-valueType-instance": "Avalduse $1 väärtused peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) üksikjuhud, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-valueType-subclass": "Avalduse $1 väärtused peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) alamklassid, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Avalduse $1 väärtused peaks olema {{PLURAL:$3|1=klassi $5|2=klasside $5 või $6|järgmistest klassidest ühe}} (või {{PLURAL:$3|1=selle alamklassi|2=nende alamklassi|nende ühe alamklassi}}) üksikjuhud või alamklassid, aga $2 ei ole {{PLURAL:$3|1=praegu.|2=praegu.|praegu. $4}}", + "wbqc-violation-message-target-required-claim": "Olemil $1 peaks olema {{PLURAL:$3|0=avaldus $2.|1=avaldus $2 $5.|avaldus $2 ühega järgmisest väärtustest:$4}}", + "wbqc-violation-message-unique-value": "Selle omaduse väärtus ei tohiks esineda üheski teises üksuses, aga see esineb ka {{PLURAL:$1|1=üksuses $3.|2=üksustes $3 ja $4.|järgmistes üksustes: $2}}", + "wbqc-violation-message-valueOnly": "Seda omadust tuleks kasutada ainult avalduse põhiväärtuse jaoks, mitte täpsustustes ega viidetes.", + "wbqc-violation-message-reference": "Seda omadust tuleks kasutada ainult viidetes, mitte avalduse põhiväärtuse jaoks ega täpsustuses.", + "wbqc-violation-message-noBounds": "Omaduse $1 väärtustel ei peaks olema piire.", + "wbqc-violation-message-units-none": "Omaduse $1 väärtusel ei peaks olema ühikut.", + "wbqc-violation-message-units": "Omaduse $1 väärtusel peaks olema {{PLURAL:$2|1=ühik $4.|2=ühik $4 või $5.|üks järgmistest ühikutest: $3}}", + "wbqc-violation-message-units-or-none": "Omaduse $1 väärtusel peaks olema {{PLURAL:$2|1=ühik $4.|2=ühik $4 või $5.|üks järgmistest ühikutest}} või see peaks olema {{PLURAL:$2|1=ühikuta.|2=ühikuta.|ühikuta. $3}}", + "wbqc-violation-message-entityType": "Omadust $1 ei peaks seda tüüpi olemi korral kasutama, {{PLURAL:$2|1=ainus lubatud olemitüüp on $4.|2=ainsad lubatud olemitüübid on $4 ja $5.|ainsad lubatud olemitüübid on järgmised: $3}}", + "wbqc-violation-message-none-of": "Omaduse $1 väärtus ei peaks olema {{PLURAL:$2|1=$4.|2=$4 ega $5.|ükski järgmistest:$3}}", + "wbqc-violation-message-integer": "Omaduse $1 väärtus peaks olema täisarv, aga väärtusel $2 on murdosa.", + "wbqc-violation-message-integer-bounds": "Omaduse $1 väärtus peaks olema täisarv, aga väärtuse $2 piiridel on murdosa.", + "wbqc-violation-message-citationNeeded": "Avaldusel omaduse $1 kohta peaks olema vähemalt üks viide.", + "wbqc-violation-message-language": "Avaldus omadusega $1 peaks olema ainult lekseemil, mille keeleks on määratud {{PLURAL:$2|1=$4.|2=kas $4 või $5.|üks järgmistest: $3}}", + "wbqc-violation-message-label-lacking": "Olemil omadusega $1 peaks olema ka silt vähemalt {{PLURAL:$2|1=selles keeles: $4.|ühes järgmistest keeltest: $3}}", + "wbqc-violation-message-property-scope": "Omadust $1 ei peaks kasutama selles kohas ($2). {{PLURAL:$3|Seda omadust sobib kasutada ainult $5.|Ainsad sobivad kohad sellele omadusele on järgmised: $4}}", + "wbqc-violation-message-exception": "See olem on selle kitsenduse teadaolev erand ja see on erandina märgitud." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/eu.json b/dist/extensions/WikibaseQualityConstraints/i18n/eu.json new file mode 100644 index 000000000..d79fab400 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/eu.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Fitoschido", + "Mikel Ibaiba", + "Subi" + ] + }, + "wbqc-constraintreport-explanation-part-two": "Mugaketak esaldien jabetzaren arabera aztertzen dira, aldi bakoitzean hauek aldatu egiten dira, gehienetan minutu gutxitan.", + "wbqc-constraintreport-status-bad-parameters": "Parametro txarrak", + "wbqc-constraintreport-status-deprecated": "Zaharkitua", + "wbqc-constraintreport-status-warning": "Oharra", + "wbqc-constraintreport-result-table-header-status": "Egoera", + "wbqc-issues-short": "Arazoak", + "wbqc-badparameters-short": "Parametro txarrak", + "wbqc-parameterissues-short": "Aurreratutako kontuak", + "wbqc-constrainttypehelp-short": "Laguntza", + "wbqc-violation-header-parameters": "Parametroak:", + "wbqc-violation-message-parameter-string": "\"$1\" parametroaren balioa string bat izan behar da, ez \"$2\".", + "wbqc-violation-message-parameter-regex": "$1 ez da onartzen esamolde erregular gisa.", + "wbqc-violation-message-diff-within-range-leftopen": "$3 ($4)ren eta $1 ($2)ren arteko aldea ez da $5 ((−∞; $5]) baino gehiagokoa izan behar.", + "wbqc-violation-message-diff-within-range-rightopen": "$3 ($4)ren eta $1 ($2)ren arteko aldea ezin da $5 ([$5; ∞)) baino txikiagoa izan.", + "wbqc-violation-message-format": "$1 ($2)ren balioak $3ren patroia jarraitu beharko luke.", + "wbqc-violation-message-range-quantity-closed": "$1 ($2) balioa $3 eta $4 ([$3; $4]) artekoa izan behar da.", + "wbqc-violation-message-range-quantity-leftopen": "$1 ($2) balioa ez da $3 ((−∞; $3]) baino gehiagokoa izan behar.", + "wbqc-violation-message-range-quantity-rightopen": "$1 ($2)ren balioa ez da $3 ([$3; ∞)) baino txikiagoa izan behar.", + "wbqc-violation-message-range-time-closed": "$1 ($2) balioa $3 eta $4 artekoa izan behar da.", + "wbqc-violation-message-range-time-leftopen": "$1 ($2)ren balioa ezin da izan $3 baino gehiagokoa.", + "wbqc-violation-message-range-time-rightopen": "$1 ($2)ren balioa ezin da $3 baino txikiagoa izan.", + "wbqc-violation-message-unique-value": "Propietare honen balioa ezin du beste baliorik aurkeztu, baina {{PLURAL:$1|1=$3.|2=$3 and $4.|the following items: $2}}en ere agertzen da." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/fa.json b/dist/extensions/WikibaseQualityConstraints/i18n/fa.json new file mode 100644 index 000000000..955cb10a4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/fa.json @@ -0,0 +1,57 @@ +{ + "@metadata": { + "authors": [ + "Beginneruser", + "FarsiNevis", + "Ladsgroup", + "Reza1615", + "Rtemis", + "Ebraminio", + "Ebrahim" + ] + }, + "wbqc-constraintreport": "محدوده گزارش", + "wbqc-desc": "ایتدا محدودیت‌ها را هم برای آیتم‌ها و هم برای خصوصیت‌ها بررسی کرده و سپس نتایج را به صورت یک صفحۀ ویژه به شما نشان می‌دهد", + "wbqc-constraintreport-explanation-part-one": "این صفحه محدویت‌های کنترلی بر روی هر ورودی‌ای که شما می‌خواهید اعمال می‌کند. ورودی‌ها از سامانه‌های زنده گرفته می‌شوند در نتیجه هر محدودیت خرابکاری که شما اینجا تعمیر می‌کنید از این فهرست حذف می‌شود.", + "wbqc-constraintreport-explanation-part-two": "محدودیت‌ها از صفحهٔ بحث خصوصیت‌ها هفته‌ای یک بار گرفته می‌شود. در نتیجه اگر یکی از آنها را حذف/اضافه/ویرایش کرده‌اید یک هفته زمان می‌برد تا در گزارش محدودیت‌ها بیاید. ر حال حاضر در حال انتقال دادن محدودیت‌ها از اظهارها به خصوصیت‌ها و فعال‌سازی صفحهٔ ویژه برای چک کردن زنده آنها هستیم.", + "wbqc-constraintreport-form-submit-label": "بررسی", + "wbqc-constraintreport-form-entityid-label": "شناسهٔ ورودی:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx/Pxx", + "wbqc-constraintreport-result-headline": "نتیجه برای", + "wbqc-constraintreport-invalid-entity-id": "شناسهٔ نادرست ورودی.", + "wbqc-constraintreport-not-existent-entity": "ورودی وجود ندارد.", + "wbqc-constraintreport-empty-result": "هیچ محدودیتی برای این ورودی (جوهره) تعریف نشده است.", + "wbqc-constraintreport-status-violation": "خرابکاری", + "wbqc-constraintreport-status-compliance": "مطلوبیت", + "wbqc-constraintreport-status-exception": "استثنا", + "wbqc-constraintreport-status-todo": "برای انجام", + "wbqc-constraintreport-status-bad-parameters": "پارامترهای بد", + "wbqc-constraintreport-status-deprecated": "توصیه", + "wbqc-constraintreport-status-warning": "هشدار", + "wbqc-constraintreport-status-suggestion": "پیشنهاد", + "wbqc-constraintreport-status-not-in-scope": "در محدوده نیست", + "wbqc-constraintreport-result-table-header-status": "وضعیت", + "wbqc-constraintreport-result-table-header-property": "ویژگی", + "wbqc-constraintreport-result-table-header-message": "پیام", + "wbqc-constraintreport-result-table-header-constraint": "محدودیت", + "wbqc-constraintreport-result-link-to-claim": "رفتن به اظهارات", + "wbqc-constraintreport-result-link-to-constraint": "رفتن به محدودیت", + "wbqc-constraintreport-no-parameter": "هیچ‌کدام", + "wbqc-issues-short": "موضوع‌ها", + "wbqc-issues-long": "این اظهار مشکلاتی دارد.", + "wbqc-potentialissues-short": "مشکلات بالقوه", + "wbqc-potentialissues-long": "این اظهار مشکلاتی دارد.", + "wbqc-suggestions-short": "پیشنهادها", + "wbqc-badparameters-short": "پارامترهای بد", + "wbqc-parameterissues-short": "مشکلات پیشرفته", + "wbqc-constrainttypehelp-short": "کمک", + "wbqc-constraintdiscuss-short": "بحث", + "wbqc-dataValueType-wikibase-entityid": "شناسه موجودیت", + "wbq-subextension-name-wbqc": "محدودیت‌ها", + "wbqc-violation-header-parameters": "پارامترها:", + "wbqc-violations-group": "محدودیت‌ها", + "wbqc-violation-message-commons-link-no-existent": "پیوند به انبار باید وجود داشته باشد.", + "wbqc-violation-message-noBounds": "مقدار برای $1 نباید محدود باشد", + "wbqc-violation-message-units-none": "مقدار برای $1 باید یکا داشته باشد", + "wbqc-violation-message-citationNeeded": "اظهار $1 باید حداقل یک منبع داشته باشد." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/fi.json b/dist/extensions/WikibaseQualityConstraints/i18n/fi.json new file mode 100644 index 000000000..ac7fe6a28 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/fi.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "McSalama", + "Moj", + "Nike", + "Pyscowicz", + "Samoasambia", + "Amire80" + ] + }, + "wbqc-constraintreport": "Rajoiteraportti", + "wbqc-desc": "Tarkistaa rajoitteet sekä kohteissa että ominaisuuksissa ja näyttää tulokset toimintosivulla", + "wbqc-constraintreport-explanation-part-one": "Tämä toimintosivu tarkastaa haluamasi entiteetin rajoitteet. Entiteetit haetaan live-järjestelmästä, joten jokainen korjaamasi rajoiterikkomus poistetaan tästä luettelosta välittömästi.", + "wbqc-constraintreport-explanation-part-two": "Rajoitukset jäsennetään ominaisuuksien esityksistä aina, kun niitä on muokattu, yleensä muutaman minuutin sisällä.", + "wbqc-constraintreport-form-section": "Tarkasta rajoitteet entiteetille", + "wbqc-constraintreport-form-submit-label": "Tarkasta", + "wbqc-constraintreport-form-entityid-label": "Entiteetin tunniste", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx tai Pxx", + "wbqc-constraintreport-result-headline": "Tulos kohteelle", + "wbqc-constraintreport-invalid-entity-id": "Virheellinen entiteettitunniste.", + "wbqc-constraintreport-not-existent-entity": "Entiteettiä ei ole olemassa.", + "wbqc-constraintreport-empty-result": "Tälle entiteetille ei ole määritelty rajoitteita.", + "wbqc-constraintreport-status-violation": "Rikkomus", + "wbqc-constraintreport-status-compliance": "Noudattaa", + "wbqc-constraintreport-status-exception": "Poikkeus", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Kelvottomat parametrit", + "wbqc-constraintreport-status-deprecated": "Vanhentunut", + "wbqc-constraintreport-status-warning": "Varoitus", + "wbqc-constraintreport-status-suggestion": "Ehdotus", + "wbqc-constraintreport-status-not-in-scope": "Ei kuulu soveltamisalaan", + "wbqc-constraintreport-result-table-header-status": "Tila", + "wbqc-constraintreport-result-table-header-property": "Ominaisuus", + "wbqc-constraintreport-result-table-header-message": "Viesti", + "wbqc-constraintreport-result-table-header-constraint": "Rajoite", + "wbqc-constraintreport-result-link-to-claim": "mene esitykseen", + "wbqc-constraintreport-result-link-to-constraint": "mene rajoitteeseen", + "wbqc-constraintreport-no-parameter": "ei mitään", + "wbqc-issues-short": "Ongelmat", + "wbqc-issues-long": "Tässä esityksessä on jotain ongelmia.", + "wbqc-potentialissues-short": "Mahdollisia ongelmia", + "wbqc-potentialissues-long": "Tässä esityksessä on mahdollisesti ongelmia.", + "wbqc-suggestions-short": "Ehdotukset", + "wbqc-suggestions-long": "Tässä on ehdotuksia esityksen parantamiseksi.", + "wbqc-badparameters-short": "Kelvottomat parametrit", + "wbqc-badparameters-long": "Tässä rajoite-esityksessä on virheellisiä parametreja.", + "wbqc-parameterissues-short": "Edistyneemmät ongelmat", + "wbqc-parameterissues-long": "Nämä ongelmat liittyvät ominaisuuden rajoitemääritelmiin, eivät tähän esitykseen.", + "wbqc-constrainttypehelp-short": "Ohje", + "wbqc-constrainttypehelp-long": "Ohjesivu tälle rajoitetyypille", + "wbqc-constraintdiscuss-short": "Keskustele", + "wbqc-constraintdiscuss-long": "Keskustelusivu tästä rajoitteesta", + "wbqc-cached-generic": "Tämä tulos on välimuistista ja saattaa todellisuudessa vastata sivun vanhaa versiota.", + "wbqc-cached-minutes": "Tämä tulos on välimuistista ja saattaa todellisuudessa vastata sivun versiota {{PLURAL:$1|1=minuutti|$1 minuuttia}} sitten.", + "wbqc-cached-hours": "Tämä tulos on välimuistista ja saattaa todellisuudessa vastata sivun versiota {{PLURAL:$1|1=tunti|$1 tuntia}} sitten.", + "wbqc-cached-days": "Tämä tulos on välimuistista ja saattaa todellisuudessa vastata sivun versiota {{PLURAL:$1|1=päivä|$1 päivää}} sitten.", + "wbqc-dataValueType-wikibase-entityid": "Entiteetin ID", + "wbq-subextension-name-wbqc": "Rajoitteet", + "wbqc-violation-header-parameters": "Parametrit:", + "wbqc-violations-group": "Rajoitteet", + "wbqc-violation-message": "Rajoitetarkitus on huomannut rikkomuksen. Klikkaa kuvaketta saadaksesi lisätietoja.", + "wbqc-violation-message-not-yet-implemented": "Teknisistä syistä rajoitteen ”$1” tarkistusta ei ole vielä otettu käyttöön.", + "wbqc-violation-message-security-reason": "Turvallisuussyistä ei ole mahdollista tarkistaa rajoitetta ”$1” tällä hetkellä. Työskentelemme ratkaisun eteen.", + "wbqc-violation-message-value-needed-of-type": "Ominaisuuksien, joissa on rajoite ”$1”, arvojen tulee olla arvotyyppiä ”$2”.", + "wbqc-violation-message-value-needed-of-types-2": "Ominaisuuksien, joissa on rajoite ”$1”, arvojen tulee olla arvotyyppiä ”$2” tai ”$3”.", + "wbqc-violation-message-parameter-needed": "Ominaisuudet, joissa on rajoite ”$1”, tarvitsevat parametrin ”$2”.", + "wbqc-violation-message-parameters-needed-3": "Ominaisuudet, joissa on rajoite ”$1”, tarvitsevat parametrit ”$2”, ”$3” ja ”$4”.", + "wbqc-violation-message-target-entity-must-exist": "Kohde-entiteetin tulee olla olemassa.", + "wbqc-violation-message-value-entity-must-exist": "Arvoentiteetin tulee olla olemassa.", + "wbqc-violation-message-parameter-value": "Parametrilla \"$1\" on oltava mukautettu arvo, ei \"ei arvoa\" tai \"tuntematon arvo\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parametrilla \"$1\" on oltava mukautettu arvo tai \"ei arvoa\", mutta ei koskaan \"tuntematonta arvoa\".", + "wbqc-violation-message-parameter-entity": "Parametrin \"$1\" arvon on oltava entiteetti, ei \"$2\".", + "wbqc-violation-message-parameter-item": "Parametrin \"$1\" arvon on oltava kohde, ei \"$2\".", + "wbqc-violation-message-parameter-property": "Parametrin \"$1\" arvon on oltava ominaisuus, ei \"$2\".", + "wbqc-violation-message-parameter-string": "Parametrin \"$1\" arvon on oltava merkkkijono, ei \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Parametrin \"$1\" arvon on oltava yksikielinen teksti, ei \"$2\".", + "wbqc-violation-message-parameter-single": "Parametrilla \"$1\" on oltava ainoastaan yksi arvo.", + "wbqc-violation-message-parameter-single-per-language": "Parametrilla \"$1\" on oltava ainoastaan yksi arvo per kieli, mutta sillä on useampi arvo kielellä $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Parametrin $1 arvon tulee olla {{PLURAL:$2|1=$4.|2=joko $4 tai $5.|jokin seuraavista:$3}}", + "wbqc-violation-message-parameter-regex": "$1 ei ole kelvollinen säännöllinen lauseke.", + "wbqc-violation-message-sparql-error": "SPARQL-kysely päättyi virheeseen.", + "wbqc-violation-message-parameters-error-unknown": "Tämän rajoitteen parametreja ei voitu tuoda.", + "wbqc-violation-message-parameters-error-toolong": "Tämän rajoitteen parametreja ei voitu tuoda, koska ne ovat liian pitkiä.", + "wbqc-violation-message-invalid-scope": "$1 ei ole kelvollinen rajoitealue rajoitetyypille $2; {{PLURAL:$3|ainoa kelvollinen alue|ainoat kelvolliset alueet}} tällä rajoitetyypille {{PLURAL:$3|on $5.|2=ovat $5 ja $6.|ovat: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Commons-linkki täytyy olla.", + "wbqc-violation-message-commons-link-not-well-formed": "Commons-linkin täytyy olla kelvollinen.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Tarkastusta nimiavaruudelle ”$1” ei ole vielä toteutettu.", + "wbqc-violation-message-conflicts-with-property": "Entiteetin ei tulisi sisältää esityksiä sekä ominaisuudesta $1 että ominaisuudesta $2.", + "wbqc-violation-message-conflicts-with-claim": "Entiteetin ei tulisi sisältää esitystä ominaisuudesta $1, jos siinä on myös esitys ominaisuudesta $2 arvolla $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entiteettien $1 ja $3 tulisi olla samanaikaisia voidakseen olla linkitettyjä ominaisuudella $2, mutta entiteetin $1 viimeisin päättymisajankohta on $4 ja entiteetin $3 aikaisin alkamisajankohta on $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entiteettien $1 ja $3 tulisi olla samanaikaisia voidakseen olla linkitettyjä ominaisuudella $2, mutta entiteetin $3 viimeisin päättymisajankohta on $4 ja entiteetin $1 aikaisin alkamisajankohta on $5.", + "wbqc-violation-message-diff-within-range": "Ominaisuuksien $3 ($4) ja $1 ($2) arvojen erotus tulisi olla välillä $5–$6.", + "wbqc-violation-message-diff-within-range-leftopen": "Ominaisuuksien $3 ($4) ja $1 ($2) arvojen erotus ei tulisi olla suurempi kuin $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Ominaisuuksien $3 ($4) ja $1 ($2) arvojen erotus ei tulisi olla pienempi kuin $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Parametreissa määritellyssä ominaisuudessa tulee olla samaa tyyppiä oleva arvo kuin tämä ominaisuus.", + "wbqc-violation-message-format": "Ominaisuuden $1 arvo ($2) tulisi täsmätä säännöllisen lausekkeen $3 kanssa.", + "wbqc-violation-message-format-clarification": "Ominaisuuden $1 arvo ($2) tulisi täsmätä \"$4\" (säännöllinen lauseke: $3).", + "wbqc-violation-message-inverse": "$1 tulisi sisältää käänteinen esitys $2 arvolla $3.", + "wbqc-violation-message-item": "Entiteetin, jossa on ominaisuus $1, tulisi sisältää myös {{PLURAL:$3|0=esitys ominaisuudesta $2.|1=esitys ominaisuudesta $2 $5.|esitys ominaisuudesta $2 seuraavilla arvoilla:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Tästä ominaisuuden $1 esityksestä puuttuu tarkenne $2.", + "wbqc-violation-message-multi-value": "Tämän ominaisuuden tulisi sisältää useita arvoja.", + "wbqc-violation-message-multi-value-separators": "Tämän ominaisuuden tulisi sisältää useita arvoja {{PLURAL:$2|1= tarkenteen $4 kanssa.|seuraavien tarkenteiden kanssa: $3}}", + "wbqc-violation-message-one-of": "Ominaisuuden $1 arvo tulisi olla {{PLURAL:$2|1=$4.|2=joko $4 tai $5.|jokin seuraavista:$3}}", + "wbqc-violation-message-qualifier": "Tätä ominaisuutta tulisi käyttää vain tarkenteena.", + "wbqc-violation-message-no-qualifiers": "Esitysten ominaisuudesta $1 ei tulisi sisältää tarkenteita.", + "wbqc-violation-message-qualifiers": "$2 ei ole kelvollinen tarkenne ominaisuudelle $1 – {{PLURAL:$3|1=ainoa kelvollinen tarkenne on $5.|2=ainoat kelvolliset tarkenteet ovat $5 ja $6.|ainoat kelvolliset tarkenteet ovat:$4}}", + "wbqc-violation-message-range-parameters-needed": "Ominaisuudet, joissa on rajoite ”$4” ja arvoja tietotyypillä ”$1”, tarvitsevat parametrit ”$2” ja ”$3”.", + "wbqc-violation-message-range-parameters-one-year": "Aikayksikköalueen päätepisteissä joko molemmilla tulee olla yksikkönä ”vuosi” tai ei kummallakaan, koska vuosia ei voida muuntaa häviöttömästi sekunneiksi.", + "wbqc-violation-message-range-parameters-same": "Arvoalueen alkupiste ($1) ja loppupiste ($2) eivät saa olla sama.", + "wbqc-violation-message-range-quantity-closed": "Ominaisuuden $1 arvo ($2) tulisi olla välillä $3–$4.", + "wbqc-violation-message-range-quantity-leftopen": "Ominaisuuden $1 arvo ($2) ei tulisi olla suurempi kuin $3.", + "wbqc-violation-message-range-quantity-rightopen": "Ominaisuuden $1 arvo ($2) ei tulisi olla pienempi kuin $3.", + "wbqc-violation-message-range-time-closed": "Ominaisuuden $1 arvo ($2) tulisi olla välillä $3–$4.", + "wbqc-violation-message-range-time-closed-leftnow": "Ominaisuuden $1 arvo ($2) tulisi olla tulevaisuudessa, mutta ei $3 jälkeen.", + "wbqc-violation-message-range-time-closed-rightnow": "Ominaisuuden $1 arvo ($2) tulisi olla menneisyydessä, mutta ei ennen $3.", + "wbqc-violation-message-range-time-leftopen": "Ominaisuuden $1 arvo ($2) ei tulisi olla $3 jälkeen.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Ominaisuuden $1 arvo ($2) ei tulisi tulevaisuudessa.", + "wbqc-violation-message-range-time-rightopen": "Ominaisuuden $1 arvo ($2) ei tulisi olla ennen $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Ominaisuuden $1 arvo ($2) ei tulisi olla menneisyydessä.", + "wbqc-violation-message-single-value": "Tämän ominaisuuden tulisi sisältää vain yksi arvo.", + "wbqc-violation-message-single-value-separators": "Tällä ominaisuudelle tulisi olla vain yksi arvo {{PLURAL:$2|samalla tarkenteen $4 arvolla.|samoilla seuraavien tarkenteiden arvoilla: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Tämän ominaisuuden tulisi sisältää yksi ”paras” arvo. Nykyisistä useista arvoista yksi tulisi asettaa ”suosittuun” asemaan.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Tämän ominaisuuden tulisi sisältää yksi ”paras” arvo {{PLURAL:$2|samalla tarkenteen $4 arvolla.|samoilla seuraavien tarkenteiden arvoilla: $3}} Nykyisistä useista arvoista yksi tulisi asettaa ”suosittuun” asemaan.", + "wbqc-violation-message-single-best-value-multi-preferred": "Tämän ominaisuuden tulisi sisältää yksi ”paras” arvo. Vain yhdellä arvoista tulisi olla ”suosittu” asema.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Tämän ominaisuuden tulisi sisältää yksi ”paras” arvo {{PLURAL:$2|samalla tarkenteen $4 arvolla.|samoilla seuraavien tarkenteiden arvoilla: $3}} Vain yhdellä arvoista tulisi olla ”suosittu” asema.", + "wbqc-violation-message-symmetric": "$1 tulisi sisältää symmetrinen esitys $2 $3.", + "wbqc-violation-message-type-instance": "Ominaisuutta $1 käyttävien entiteettien tulisi olla esiintymiä {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-type-subclass": "Ominaisuutta $1 käyttävien entiteettien tulisi olla alaluokkia {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Ominaisuutta $1 käyttävien entiteettien tulisi olla esiintymiä tai alaluokkia {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-valueType-instance": "Ominaisuuden $1 arvojen tulisi olla esiintymiä {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-valueType-subclass": "Ominaisuuden $1 arvojen tulisi olla alaluokkia {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Ominaisuuden $1 arvojen tulisi olla esiintymiä tai alaluokkia {{PLURAL:$3|1=kohteesta $5|2=kohteesta $5 tai $6|joistain seuraavista luokista}} (tai {{PLURAL:$3|1=sen alaluokasta|2=niiden alaluokasta|joistain niiden alaluokista}}), mutta tällä hetkellä $2 {{PLURAL:$3|1=ei ole.|2=ei ole.|ei ole: $4}}", + "wbqc-violation-message-target-required-claim": "Entiteetillä $1 tulisi olla {{PLURAL:$3|0=esitys ominaisuudesta $2.|1=esitys ominaisuudesta $2 arvolla $5.|esitys ominaisuudesta $2 jollain seuraavista arvoista:$4}}", + "wbqc-violation-message-unique-value": "Tämän ominaisuuden arvon ei tulisi esiintyä missään muussa kohteessa, mutta se esiintyy myös {{PLURAL:$1|1=kohteessa $3.|2=kohteissa $3 ja $4.|seuraavissa kohteissa: $2}}", + "wbqc-violation-message-valueOnly": "Tätä ominaisuutta tulisi käyttää ainoastaan esityksen pääarvoissa, ei tarkenteissa tai lähteissä.", + "wbqc-violation-message-reference": "Tätä ominaisuutta tulisi käyttää ainoastaan lähteissä, ei esityksen pääarvoissa tai tarkenteissa.", + "wbqc-violation-message-noBounds": "Ominaisuuden $1 arvoilla ei tulisi olla raja-arvoja.", + "wbqc-violation-message-units-none": "Ominaisuuden $1 arvolla ei tulisi olla yksikköä.", + "wbqc-violation-message-units": "Ominaisuuden $1 arvolla tulisi olla {{PLURAL:$2|1=yksikkö $4.|2=yksikkö $4 tai $5.|yksi seuraavista yksiköistä: $3}}", + "wbqc-violation-message-units-or-none": "Ominaisuuden $1 arvolla tulisi olla {{PLURAL:$2|1=yksikkö $4.|2=yksikkö $4 tai $5.|yksi seuraavista yksiköistä}} tai olla {{PLURAL:$2|1=yksikötön.|2=yksikötön.|yksikötön: $3}}", + "wbqc-violation-message-entityType": "Ominaisuutta $1 ei tulisi käyttää tämän tyyppisessä entiteetissä, {{PLURAL:$2|1=ainoa kelvollinen entiteettityyppi on $4.|2=ainoat kelvolliset entiteettityypit ovat $4 ja $5.|ainoat kelvolliset entiteettityypit ovat: $3}}", + "wbqc-violation-message-none-of": "Ominaisuuden $1 arvo ei tule olla {{PLURAL:$2|1=$4.|2=$4 eikä $5.|mikään seuraavista:$3}}", + "wbqc-violation-message-integer": "Ominaisuuden $1 arvojen tulisi olla kokonaislukuja, mutta $2 sisältää murto-osia.", + "wbqc-violation-message-integer-bounds": "Ominaisuuden $1 arvojen tulisi olla kokonaislukuja, mutta arvon $2 raja-arvot sisältävät murto-osia.", + "wbqc-violation-message-citationNeeded": "Ominaisuuden $1 esityksissä tulisi olla vähintään yksi lähde.", + "wbqc-violation-message-language": "Ominaisuuden $1 esityksiä tulisi olla ainoastaan lekseemeissä, joiden {{PLURAL:$2|kieleksi|kieliksi}} on asetettu {{PLURAL:$2|1=$4.|2=$4 tai $5.|jokin seuraavista: $3}}", + "wbqc-violation-message-label-lacking": "Entiteettien, joissa on esityksiä ominaisuudesta $1, tulisi myös sisältää nimi ainakin {{PLURAL:$2|1=kielellä $4.|joillain seuraavista kielistä: $3}}", + "wbqc-violation-message-property-scope": "Ominaisuutta $1 ei tulisi käyttää tässä sijainnissa ($2). {{PLURAL:$3|Ainoa kelvollinen sijainti|Ainoat kelvolliset sijainnit}} tälle ominaisuudelle {{PLURAL:$3|on $5.|ovat: $4}}", + "wbqc-violation-message-exception": "Tämä entiteetti on tunnettu poikkeus rajoitteeseen ja on merkitty sellaiseksi." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/fr.json b/dist/extensions/WikibaseQualityConstraints/i18n/fr.json new file mode 100644 index 000000000..9e3c06790 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/fr.json @@ -0,0 +1,157 @@ +{ + "@metadata": { + "authors": [ + "Ayack", + "Eihel", + "Envlh", + "Framawiki", + "Gomoko", + "Macofe", + "Pamputt", + "Thibaut120094", + "Urhixidur", + "Verdy p", + "Wladek92", + "Yzelf" + ] + }, + "wbqc-constraintreport": "Rapport de contrainte", + "wbqc-desc": "Vérifie les contraintes à la fois sur les éléments ainsi que les propriétés et affiche les résultats sur une page spéciale", + "wbqc-constraintreport-explanation-part-one": "Cette page spéciale effectue les vérifications de contraintes sur n’importe quelle entité de votre choix. Les entités sont extraites du système en direct, de sorte que chaque violation de contrainte que vous corrigez maintenant sera immédiatement retirée de cette liste.", + "wbqc-constraintreport-explanation-part-two": "Les contraintes sont analysées à partir des déclarations sur les propriétés chaque fois que ces déclarations sont modifiées, en général en quelques minutes.", + "wbqc-constraintreport-form-section": "Vérifier les contraintes pour l’entité", + "wbqc-constraintreport-form-submit-label": "Vérifier", + "wbqc-constraintreport-form-entityid-label": "Identifiant de l’entité :", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx ou Pxx", + "wbqc-constraintreport-result-headline": "Résultats pour", + "wbqc-constraintreport-invalid-entity-id": "Identifiant d’entité non valide.", + "wbqc-constraintreport-not-existent-entity": "L’entité n’existe pas.", + "wbqc-constraintreport-empty-result": "Il n’y a aucune contrainte définie sur cette entité.", + "wbqc-constraintreport-status-violation": "Violation", + "wbqc-constraintreport-status-compliance": "Conformité", + "wbqc-constraintreport-status-exception": "Exception", + "wbqc-constraintreport-status-todo": "À faire", + "wbqc-constraintreport-status-bad-parameters": "Mauvais paramètres", + "wbqc-constraintreport-status-deprecated": "Désuet", + "wbqc-constraintreport-status-warning": "Avertissement", + "wbqc-constraintreport-status-suggestion": "Suggestion", + "wbqc-constraintreport-status-not-in-scope": "Hors périmètre", + "wbqc-constraintreport-result-table-header-status": "État", + "wbqc-constraintreport-result-table-header-property": "Propriété", + "wbqc-constraintreport-result-table-header-message": "Message", + "wbqc-constraintreport-result-table-header-constraint": "Contrainte", + "wbqc-constraintreport-result-link-to-claim": "aller à la déclaration", + "wbqc-constraintreport-result-link-to-constraint": "aller à la contrainte", + "wbqc-constraintreport-no-parameter": "aucune", + "wbqc-issues-short": "Problèmes", + "wbqc-issues-long": "Cette déclaration a quelques problèmes.", + "wbqc-potentialissues-short": "Problèmes potentiels", + "wbqc-potentialissues-long": "Cette instruction présente des problèmes potentiels.", + "wbqc-suggestions-short": "Suggestions", + "wbqc-suggestions-long": "Il y a quelques suggestions pour améliorer cette déclaration.", + "wbqc-badparameters-short": "Mauvais paramètres", + "wbqc-badparameters-long": "Cette déclaration de contrainte a certains paramètres non valides.", + "wbqc-parameterissues-short": "Problèmes complexes", + "wbqc-parameterissues-long": "Ces problèmes sont relatifs à la définition de la contrainte sur la propriété, et non à cette déclaration.", + "wbqc-constrainttypehelp-short": "Aide", + "wbqc-constrainttypehelp-long": "Page d’aide pour ce type de contrainte", + "wbqc-constraintdiscuss-short": "Discuter", + "wbqc-constraintdiscuss-long": "Page de discussion concernant cette contrainte", + "wbqc-cached-generic": "Ce résultat est en cache et peut ne pas être à jour.", + "wbqc-cached-minutes": "Ce résultat est en cache et peut prendre {{PLURAL:$1|1=une minute|$1 minutes}} avant d’être mis à jour.", + "wbqc-cached-hours": "Ce résultat est en cache et peut prendre {{PLURAL:$1|1=une heure|$1 heures}} avant d’être mis à jour.", + "wbqc-cached-days": "Ce résultat est en cache et peut prendre {{PLURAL:$1|1=un jour|$1 jours}} avant d’être mis à jour.", + "wbqc-dataValueType-wikibase-entityid": "Identifiant de l’entité", + "wbq-subextension-name-wbqc": "Contraintes", + "wbqc-violation-header-parameters": "Paramètres :", + "wbqc-violations-group": "Contraintes", + "wbqc-violation-message": "La vérification de contrainte a identifié une violation. Veuillez cliquer sur l’icône pour plus d’informations.", + "wbqc-violation-message-not-yet-implemented": "Pour des raisons techniques, la vérification de la contrainte « $1 » n’a pas encore été mise en œuvre.", + "wbqc-violation-message-security-reason": "Pour des raisons de sécurité, il n’est pas possible de vérifier la contrainte « $1 » pour l’instant. Nous travaillons à résoudre cela.", + "wbqc-violation-message-value-needed-of-type": "Les propriétés avec la contrainte « $1 » doivent avoir des valeurs de type « $2 ».", + "wbqc-violation-message-value-needed-of-types-2": "Les propriétés avec la contrainte « $1 » doivent avoir des valeurs de type « $2 » ou « $3 ».", + "wbqc-violation-message-parameter-needed": "Les propriétés avec la contrainte « $1 » doivent indiquer le paramètre « $2 ».", + "wbqc-violation-message-parameters-needed-3": "Les propriétés avec la contrainte « $1 » doivent indiquer les trois paramètres « $2 », « $3 » et « $4 ».", + "wbqc-violation-message-target-entity-must-exist": "L’entité cible doit exister.", + "wbqc-violation-message-value-entity-must-exist": "L’entité indiquée en valeur doit exister.", + "wbqc-violation-message-parameter-value": "Le paramètre « $1 » doit avoir une valeur spécifique et non « aucune valeur », ni une « valeur inconnue ».", + "wbqc-violation-message-parameter-value-or-novalue": "Le paramètre « $1 » doit avoir une valeur spécifique et non une « valeur inconnue ».", + "wbqc-violation-message-parameter-entity": "La valeur pour le paramètre « $1 » doit être une entité et non pas « $2 ».", + "wbqc-violation-message-parameter-item": "La valeur pour le paramètre « $1 » doit être un élément et non pas « $2 ».", + "wbqc-violation-message-parameter-property": "La valeur pour le paramètre « $1 » doit être une propriété et non pas « $2 ».", + "wbqc-violation-message-parameter-string": "La valeur pour le paramètre « $1 » doit être une chaîne de caractères et non pas « $2 ».", + "wbqc-violation-message-parameter-monolingualtext": "La valeur du paramètre « $1 » doit être un texte monolingue et non pas « $2 ».", + "wbqc-violation-message-parameter-single": "Le paramètre « $1 » ne doit avoir qu’une valeur simple.", + "wbqc-violation-message-parameter-single-per-language": "Le paramètre « $1 » doit avoir une seule valeur par langue, mais il a plusieurs valeurs pour $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Le paramètre « $1 » doit avoir {{PLURAL:$2|1=la valeur $4|2=la valeur $4 ou $5|une des valeurs suivantes : $3}}.", + "wbqc-violation-message-parameter-regex": "$1 n’est pas une expression rationnelle valide.", + "wbqc-violation-message-sparql-error": "La requête SPARQL a retourné une erreur.", + "wbqc-violation-message-parameters-error-unknown": "Les paramètres de cette contrainte n’ont pas pu être importés.", + "wbqc-violation-message-parameters-error-toolong": "Les paramètres de cette contrainte n’ont pas pu être importés parce qu’ils sont trop longs.", + "wbqc-violation-message-invalid-scope": "$1 n’est pas un domaine d’action pour le type de contrainte $2 ; {{PLURAL:$3|le seul domaine valide|les seuls domaines valides}} pour ce type de contrainte {{PLURAL:$3|est $5.|2=sont $5 et $6.|sont : $4}}", + "wbqc-violation-message-commons-link-no-existent": "Le lien vers Wikimedia Commons devrait exister.", + "wbqc-violation-message-commons-link-not-well-formed": "Le lien vers Commons devrait être bien formaté.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "La vérification pour l’espace de noms « $1 » n’est pas encore prise en charge.", + "wbqc-violation-message-conflicts-with-property": "Une entité ne doit pas avoir de déclaration à la fois pour $1 et $2.", + "wbqc-violation-message-conflicts-with-claim": "Une entité ne doit pas avoir de déclaration pour $1 si elle en a une autre pour $2 avec la valeur $3.", + "wbqc-violation-message-contemporary-subject-earlier": "L’entité $1 doit être contemporaine de l’entité $3 liée par la propriété $2, mais $1 déclare ne pas exister après $4 alors que $3 déclare ne pas exister avant $5.", + "wbqc-violation-message-contemporary-value-earlier": "L’entité $1 doit être contemporaine de l’entité $3 liée par la propriété $2, mais $1 déclare ne pas exister avant $5 alors que $3 déclare ne pas exister après $4.", + "wbqc-violation-message-diff-within-range": "La différence entre entre les propriétés $3 ($4) et $1 ($2) devrait être comprise entre $5 et $6.", + "wbqc-violation-message-diff-within-range-leftopen": "La différence entre entre les propriétés $3 ($4) et $1 ($2) ne doit pas excéder $5.", + "wbqc-violation-message-diff-within-range-rightopen": "La différence entre les propriétés $3 ($4) et $1 ($2) ne doit pas être inférieure à $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "La propriété définie dans les paramètres doit avoir une valeur du même type que cette propriété.", + "wbqc-violation-message-format": "La valeur de la propriété $1 ($2) doit correspondre à l’expression rationnelle $3.", + "wbqc-violation-message-format-clarification": "La valeur de la propriété $1 ($2) doit correspondre à « $4 » (expression rationnelle : $3).", + "wbqc-violation-message-inverse": "$1 doit également avoir la déclaration de la propriété inverse $2 $3.", + "wbqc-violation-message-item": "Une entité déclarée avec la propriété $1 devrait également déclarer une propriété {{PLURAL:$3|0=$2.|$2 de valeur $5.|$2 avec une des valeurs suivantes : $4}}", + "wbqc-violation-message-mandatory-qualifier": "La propriété « $1 » doit être déclarée avec un qualificateur « $2 ».", + "wbqc-violation-message-multi-value": "Cette propriété doit être déclarée avec plusieurs valeurs.", + "wbqc-violation-message-multi-value-separators": "Cette propriété doit déclarée avec plusieurs valeurs pour le même {{PLURAL:$2|qualificatif $4.|ensemble de qualificatifs : $3}}", + "wbqc-violation-message-one-of": "La propriété $1 doit être déclarée avec {{PLURAL:$2|la valeur $4.|2=une valeur $4 ou $5.|une des valeurs suivantes : $3}}", + "wbqc-violation-message-qualifier": "La propriété doit être utilisée uniquement comme qualificatif.", + "wbqc-violation-message-no-qualifiers": "Les propriétés $1 déclarées ne doivent comporter aucun qualificatif.", + "wbqc-violation-message-qualifiers": "$2 n’est pas un qualificatif valable pour la propriété $1 – {{PLURAL:$3|le seul qualificatif valide est $5.|2=les seuls qualificatifs valides sont $5 et $6.|les seuls qualificatifs valides sont : $4}}", + "wbqc-violation-message-range-parameters-needed": "Les propriétés déclarées avec des valeurs de type « $1 » avec la contrainte « $4 » doivent indiquer les paramètres « $2 » et « $3 ».", + "wbqc-violation-message-range-parameters-one-year": "Les bornes d’une plage de durée ne peuvent être indiquées en années que toutes les deux ou aucune des deux, car les années ne peuvent être converties en secondes sans écart de précision.", + "wbqc-violation-message-range-parameters-same": "Les bornes de début ($1) et de fin ($2) d’une plage ne doivent pas être identiques.", + "wbqc-violation-message-range-quantity-closed": "La valeur de $1 ($2) doit être entre $3 et $4.", + "wbqc-violation-message-range-quantity-leftopen": "La valeur de $1 ($2) ne doit pas excéder $3.", + "wbqc-violation-message-range-quantity-rightopen": "La valeur de $1 ($2) ne doit pas être inférieure à $3.", + "wbqc-violation-message-range-time-closed": "La valeur de $1 ($2) doit être entre $3 et $4.", + "wbqc-violation-message-range-time-closed-leftnow": "La valeur pour $1 ($2) doit être dans le futur, mais pas postérieure à $3.", + "wbqc-violation-message-range-time-closed-rightnow": "La valeur pour $1 ($2) doit être dans le passé, mais pas antérieure à $3.", + "wbqc-violation-message-range-time-leftopen": "La valeur de $1 ($2) ne doit pas être supérieure à $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "La valeur pour $1 ($2) ne doit pas être dans le futur.", + "wbqc-violation-message-range-time-rightopen": "La valeur de $1 ($2) ne doit pas être inférieure à $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "La valeur pour $1 ($2) ne doit pas être dans le passé.", + "wbqc-violation-message-single-value": "Cette propriété ne doit avoir qu’une seule valeur.", + "wbqc-violation-message-single-value-separators": "Cette propriété ne doit avoir qu’une seule valeur avec le même {{PLURAL:$2|qualificatif $4.|ensemble de qualificatifs : $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Cette propriété doit avoir une seule « meilleure » valeur. Parmi les différentes valeurs actuelles, une d’elles doit être marquée avec un rang « préféré ».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Cette propriété doit avoir une seule « meilleure » valeur avec le même {{PLURAL:$2|qualificatif $4.|ensemble de qualificatifs : $3}} Parmi les valeurs différentes actuelles, une d’elles doit être marquée avec le rang « préféré ».", + "wbqc-violation-message-single-best-value-multi-preferred": "Cette propriété doit avoir une seule « meilleure » valeur. Il ne doit pas y avoir plus d’une valeur avec le rang « préféré ».", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Cette propriété doit avoir une seule « meilleure » valeur avec le même {{PLURAL:$2|qualificatif $4.|ensemble de qualificatifs : $3}} Il ne doit pas y avoir plus d’une valeur avec le rang « préféré ».", + "wbqc-violation-message-symmetric": "$1 doit également avoir la déclaration symétrique $2 $3.", + "wbqc-violation-message-type-instance": "Les entités qui déclarent la propriété $1 doivent être des instances {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|1=.|2=.| : $4}}", + "wbqc-violation-message-type-subclass": "Les entités qui déclarent la propriété $1 doivent être des sous-classes {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|.|2=.| : $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Les entités qui déclarent la propriété $1 doivent être des instances ou des sous-classes {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|.|2=.| : $4}}", + "wbqc-violation-message-valueType-instance": "Les valeurs déclarées de la propriété $1 doivent être des instances {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|.|2=.| : $4}}", + "wbqc-violation-message-valueType-subclass": "Les valeurs déclarées de la propriété $1 doivent être des sous-classes {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|.|2=.| : $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Les valeurs déclarées de la propriété $1 doivent être des instances ou des sous-classes {{PLURAL:$3|de $5|2=de $5 ou $6|d’une des classes suivantes}} (ou d’une de {{PLURAL:$3|ses|leurs}} sous-classes), mais $2 ne l’est pas actuellement{{PLURAL:$3|.|2=.| : $4}}", + "wbqc-violation-message-target-required-claim": "$1 doit déclarer la propriété {{PLURAL:$3|0=$2.|$2 de valeur $5.|$2 avec une des valeurs suivantes : $4}}", + "wbqc-violation-message-unique-value": "Cette valeur de propriété ne devrait être déclarée dans aucun autre élément, mais figure également dans {{PLURAL:$1|l’élément $3.|2=les éléments $3 et $4.|les éléments suivants : $2}}", + "wbqc-violation-message-valueOnly": "Cette propriété ne doit être utilisée que pour les déclarations de valeurs principales, pas pour les qualificateurs, ni pour les références.", + "wbqc-violation-message-reference": "Cette propriété ne doit être utilisée que pour les références, pas pour les déclarations de valeurs principales, ni pour les qualificatifs.", + "wbqc-violation-message-noBounds": "La propriété $1 ne doit prendre que des valeurs exactes sans intervalle de précision.", + "wbqc-violation-message-units-none": "La valeur de la propriété $1 ne doit indiquer aucune unité.", + "wbqc-violation-message-units": "La valeur de la propriété $1 doit indiquer {{PLURAL:$2|l’unité $4.|2=l’unité $4 ou $5.|une des unités suivantes : $3}}", + "wbqc-violation-message-units-or-none": "La valeur de la propriété $1 doit indiquer {{PLURAL:$2|l’unité $4|2=l’unité $4 ou $5|une des unités suivantes}} ou n’en indiquer aucune{{PLURAL:$2|.|2=.| : $3}}", + "wbqc-violation-message-entityType": "La propriété $1 ne doit pas être utilisée sur ce type d’entité, {{PLURAL:$2|le seul type d’entité valide est $4.|2=les seuls types d’entités valides sont $4 et $5.|les seuls types d’entités valides sont : $3}}", + "wbqc-violation-message-none-of": "La propriété $1 ne doit {{PLURAL:$2|pas prendre la valeur $4.|2=pas prendre la valeur $4 ou $5.|prendre aucune des valeurs suivantes : $3}}", + "wbqc-violation-message-integer": "La propriété $1 doit prendre une valeur entière, mais $2 a une partie fractionnaire.", + "wbqc-violation-message-integer-bounds": "La propriété $1 doit prendre une valeur entière, mais les limites de précision données dans $2 comportent une partie fractionnaire.", + "wbqc-violation-message-citationNeeded": "La propriété $1 doit mentionner au moins une référence dans ses valeurs déclarées.", + "wbqc-violation-message-language": "La propriété $1 ne peut s’appliquer qu’aux lexèmes définis {{PLURAL:$2|1=en $4|2=en $4 ou en $5.|dans une des langues suivantes : $3}}.", + "wbqc-violation-message-label-lacking": "Les entités qui déclarent une propriété $1 doivent aussi comporter au moins un libellé {{PLURAL:$2|en $4.|dans une des langues suivantes : $3}}", + "wbqc-violation-message-property-scope": "La propriété $1 ne doit plus être utilisée à cet endroit ($2). {{PLURAL:$3|Le seul emplacement valide|Les seuls emplacements valides}} pour cette propriété {{PLURAL:$3|est $5.|sont : $4}}", + "wbqc-violation-message-exception": "Cette entité est une exception connue pour cette contrainte et a été marquée comme telle." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/gcr.json b/dist/extensions/WikibaseQualityConstraints/i18n/gcr.json new file mode 100644 index 000000000..ed46e99c3 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/gcr.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "LeGuyanaisPure" + ] + }, + "wbqc-constraintreport-result-headline": "Rézilta pou" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/gl.json b/dist/extensions/WikibaseQualityConstraints/i18n/gl.json new file mode 100644 index 000000000..8be79d375 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/gl.json @@ -0,0 +1,106 @@ +{ + "@metadata": { + "authors": [ + "ArenaL5", + "Athena in Wonderland", + "Banjo", + "Elisardojm", + "Maria zaos", + "Toliño" + ] + }, + "wbqc-constraintreport": "Informe de restrición", + "wbqc-desc": "Comproba as restricións nos elementos e nas propiedades e amosa os resultados nunha páxina especial", + "wbqc-constraintreport-explanation-part-one": "Esta páxina especial realiza revisións de restrición nas entidades que queira. As entidades búscanse no sistema real, polo que cada violación de restrición que amañe será eliminada instantaneamente desta lista.", + "wbqc-constraintreport-explanation-part-two": "As restricións desde as afirmacións ás propiedades son analizadas cada vez que estas son editadas, normalmente nuns minutos.", + "wbqc-constraintreport-form-section": "Revisar restriccións para entidade", + "wbqc-constraintreport-form-submit-label": "Comprobar", + "wbqc-constraintreport-form-entityid-label": "Identificador de entidade:", + "wbqc-constraintreport-result-headline": "Resultado para", + "wbqc-constraintreport-invalid-entity-id": "Identificador de entidade non válido.", + "wbqc-constraintreport-not-existent-entity": "A entidade non existe!", + "wbqc-constraintreport-empty-result": "Non hai restricións definidas nesta entidade.", + "wbqc-constraintreport-status-violation": "Violación", + "wbqc-constraintreport-status-compliance": "Cumpre", + "wbqc-constraintreport-status-exception": "Excepción", + "wbqc-constraintreport-status-todo": "Pendente", + "wbqc-constraintreport-status-bad-parameters": "Parámetros incorrectos", + "wbqc-constraintreport-status-deprecated": "Obsoleto", + "wbqc-constraintreport-status-warning": "Aviso", + "wbqc-constraintreport-status-not-in-scope": "Fóra do ámbito", + "wbqc-constraintreport-result-table-header-status": "Estado", + "wbqc-constraintreport-result-table-header-property": "Propiedade", + "wbqc-constraintreport-result-table-header-message": "Mensaxe", + "wbqc-constraintreport-result-table-header-constraint": "Restrición", + "wbqc-constraintreport-result-link-to-claim": "ir a afirmación", + "wbqc-constraintreport-result-link-to-constraint": "ir a restrición", + "wbqc-constraintreport-no-parameter": "ningún", + "wbqc-issues-short": "Problemas", + "wbqc-issues-long": "Esta declaración ten algúns problemas.", + "wbqc-potentialissues-short": "Problemas potenciais", + "wbqc-potentialissues-long": "Esta declaración pode ter algún problema.", + "wbqc-badparameters-short": "Parámetros incorrectos", + "wbqc-badparameters-long": "Esta declaración de restrición ten algúns parámetros non válidos.", + "wbqc-parameterissues-short": "Problemas complexos", + "wbqc-constrainttypehelp-short": "Axuda", + "wbqc-constrainttypehelp-long": "Páxina de axuda para este tipo de restrición", + "wbqc-constraintdiscuss-short": "Conversar", + "wbqc-constraintdiscuss-long": "Páxina de conversa sobre esta restrición", + "wbqc-cached-generic": "Este resultado vén da caché e pode estar desfasado.", + "wbqc-cached-minutes": "Este resultado vén da caché e pode estar desfasado ata un máximo {{PLURAL:$1|1=dun minuto|de $1 minutos}}.", + "wbqc-cached-hours": "Este resultado vén da caché e pode estar desactualizado ata un máximo {{PLURAL:$1|1=dunha hora| de $1 horas}}.", + "wbqc-cached-days": "Este resultado vén da caché e pode estar desactualizado ata un máximo {{PLURAL:$1|1=dun día|de $1 días}}.", + "wbqc-dataValueType-wikibase-entityid": "Id. da entidade", + "wbq-subextension-name-wbqc": "Restricións", + "wbqc-violation-header-parameters": "Parámetros:", + "wbqc-violations-group": "Restricións", + "wbqc-violation-message": "A verificación de restricións detectou unha violación. Prema a icona para obter máis información.", + "wbqc-violation-message-not-yet-implemented": "Por razóns técnicas, a verificación da constante \"$1\" aínda non está desenvolvida.", + "wbqc-violation-message-security-reason": "Por motivos de seguridade, non é posible comprobar a restrición \"$1\" neste momento. Estamos traballando nunha solución.", + "wbqc-violation-message-value-needed-of-type": "As propiedades coa restricción \"$1\" deben ter valores do tipo \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "As propiedades con constante \"$1\" precisan ter valores de tipo \"$2\" ou \"$3\".", + "wbqc-violation-message-parameter-needed": "As propiedades coa restricción \"$1\" necesitan un parámetro \"$2\".", + "wbqc-violation-message-parameters-needed-3": "As propiedades con constante \"$1\" precisan os parámetros \"$2\", \"$3\" e \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "A entidade obxectivo debe existir.", + "wbqc-violation-message-value-entity-must-exist": "O valor entidade debe existir.", + "wbqc-violation-message-parameter-value": "O parámetro \"$1\" debe ter un valor propio, non pode conter \"no value\" (sen valor) nin \"unknown value\" (valor descoñecido).", + "wbqc-violation-message-parameter-value-or-novalue": "O parámetro \"$1\" debe ter un valor propio ou \"no value\" (sen valor), pero nunca \"unknown value\" (valor descoñecido).", + "wbqc-violation-message-parameter-entity": "O valor para o parámetro \"$1\" debe ser unha entidade, non \"$2\".", + "wbqc-violation-message-parameter-item": "O valor para o parámetro \"$1\" debe ser un obxecto, non \"$2\".", + "wbqc-violation-message-parameter-property": "O valor para o parámetro \"$1\" debe ser unha propiedade, non \"$2\".", + "wbqc-violation-message-parameter-string": "O valor para o parámetro \"$1\" debe ser unha cadea de texto, non \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "O valor do parámetro «$1» debe ser un texto monolingüe, non «$2».", + "wbqc-violation-message-parameter-single": "O parámetro \"$1\" debe ter só un valor.", + "wbqc-violation-message-parameter-regex": "$1 non é unha expresión regular válida.", + "wbqc-violation-message-sparql-error": "A consulta SPARQL produciu un erro.", + "wbqc-violation-message-parameters-error-unknown": "Os parámetros desta restrición non puideron importarse.", + "wbqc-violation-message-parameters-error-toolong": "Os parámetros desta restrición non puideron importarse porque eran demasiado longos.", + "wbqc-violation-message-commons-link-no-existent": "A ligazón a Commons debería existir.", + "wbqc-violation-message-commons-link-not-well-formed": "A ligazón a Commons debería estar ben formada.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "O chequeo para o espazo de nomes \"$1\" aínda non está desenvolvido.", + "wbqc-violation-message-conflicts-with-property": "Unha entidade non debería ter ó mesmo tempo declaracións para $1 e para $2.", + "wbqc-violation-message-conflicts-with-claim": "Unha entidade non debería ter unha declaración para $1 se xa ten unha declaración para $2 con valor $3.", + "wbqc-violation-message-diff-within-range": "A diferenza entre $3 ($4) e $1 ($2) debería ser a mesma que entre $5 e $6 ([$5; $6]).", + "wbqc-violation-message-diff-within-range-leftopen": "A diferenza entre $3 ($4) e $1 ($2) non debería exceder a $5 ((−∞; $5]).", + "wbqc-violation-message-diff-within-range-rightopen": "A difereɳa entre $3 ($4) e $1 ($2) non debería ser inferior a $5 ([$5; ∞)).", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "A propiedade definida nos parámetros debe ter un valor do mesmo tipo que esta propiedade.", + "wbqc-violation-message-format": "O valor para $1 ($2) debería coincidir coa expresión regular $3.", + "wbqc-violation-message-format-clarification": "O valor de $1 ($2) debería coincidir con \"$4\" (expresión regular: $3).", + "wbqc-violation-message-inverse": "$1 debería tener tamén a declaración inversa $2 $3.", + "wbqc-violation-message-item": "As entidades que inclúan $1 deben contar tamén con {{PLURAL:$3|0=unha declaración $2.|1=unha declaración $2 $5.|unha declaración para $2 cun dos valores seguintes: $4}}", + "wbqc-violation-message-multi-value": "Esta propiedade debería ter valores múltiples. Isto é, debería haber máis dunha declaración usando esta propiedade.", + "wbqc-violation-message-one-of": "O valor da propiedade debe ser {PLURAL:$2|1=$4.|2=either $4 or $5.|un dos seguintes:$3}}", + "wbqc-violation-message-qualifier": "A propiedade só debería ser usada como cualificador.", + "wbqc-violation-message-no-qualifiers": "As declaracións para $1 non deberían conter ningún calificador.", + "wbqc-violation-message-qualifiers": "A propiedade só debe usarse cos (non outras que) cualificadores definidos nos parámetros.", + "wbqc-violation-message-range-parameters-needed": "As propiedades con valores de tipo \"$1\" con constante \"Range\" precisan os parámetros \"$2\" e \"$3\".", + "wbqc-violation-message-range-quantity-closed": "O valor para $1 ($2) debe estar entre $3 e $4.", + "wbqc-violation-message-range-quantity-leftopen": "O valor de $1 ($2) non debe ser maior de $3.", + "wbqc-violation-message-range-quantity-rightopen": "O valor de $1 ($2) non debe ser menor de $3.", + "wbqc-violation-message-range-time-closed": "O valor para $1 ($2) debe estar entre $3 e $4", + "wbqc-violation-message-range-time-leftopen": "O valor para $1 ($2) non debe estar despois de $3.", + "wbqc-violation-message-range-time-rightopen": "O valor para $1 ($2) non debe estar antes de $3.", + "wbqc-violation-message-single-value": "Esta propiedade só debe ter un valor.", + "wbqc-violation-message-symmetric": "$1 debería ter tamén a declaración simétrica $2 $3.", + "wbqc-violation-message-unique-value": "Este valor de propiedade non debe estar presente en ningún outro elemento, pero está presente {{PLURAL:$1|1=$3.|2=$3 and $4.|nos seguintes elementos: $2}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/gom-deva.json b/dist/extensions/WikibaseQualityConstraints/i18n/gom-deva.json new file mode 100644 index 000000000..b60dbc927 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/gom-deva.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Vaishali Parab" + ] + }, + "wbqc-constraintreport-no-parameter": "कांय ना" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/gom-latn.json b/dist/extensions/WikibaseQualityConstraints/i18n/gom-latn.json new file mode 100644 index 000000000..7c220327c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/gom-latn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "The Discoverer" + ] + }, + "wbqc-constraintreport-no-parameter": "Kai na" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/he.json b/dist/extensions/WikibaseQualityConstraints/i18n/he.json new file mode 100644 index 000000000..c300a8634 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/he.json @@ -0,0 +1,148 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Guycn2", + "פוילישער" + ] + }, + "wbqc-constraintreport": "דו\"ח אילוצים", + "wbqc-desc": "בדיקת אילוצים גם בפריטים וגם במאפיינים והצגת התוצאות בדף מיוחד", + "wbqc-constraintreport-explanation-part-one": "הדף המיוחד הזה מבצע בדיקות אילוצים על כל ישות שברצונך לבדוק. הישויות מאוחזרות מהמערכת החיה, כך שכל הפרת אילוץ שמתוקנת שם תוסר מהרשימה הזאת מייד.", + "wbqc-constraintreport-explanation-part-two": "האילוצים מפוענחים מקביעות על מאפיינים בכל פעם שהקביעות האלה נערכות, בדרך־כלל אחרי כמה דקות.", + "wbqc-constraintreport-form-section": "בדיקת אילוצים של ישות", + "wbqc-constraintreport-form-submit-label": "לבדוק", + "wbqc-constraintreport-form-entityid-label": "מזהה ישות:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx או Pxx", + "wbqc-constraintreport-result-headline": "תוצאה עבור", + "wbqc-constraintreport-invalid-entity-id": "מזהה ישות בלתי־תקין.", + "wbqc-constraintreport-not-existent-entity": "הישות אינה קיימת.", + "wbqc-constraintreport-empty-result": "אין אילוצים מוגדרים לישות הזאת.", + "wbqc-constraintreport-status-violation": "הפרה", + "wbqc-constraintreport-status-compliance": "התאמה", + "wbqc-constraintreport-status-exception": "יוצא־דופן", + "wbqc-constraintreport-status-todo": "מטלות", + "wbqc-constraintreport-status-bad-parameters": "פרמטרים גרועים", + "wbqc-constraintreport-status-deprecated": "מיושן", + "wbqc-constraintreport-status-warning": "אזהרה", + "wbqc-constraintreport-status-suggestion": "הצעה", + "wbqc-constraintreport-status-not-in-scope": "לא בטווח", + "wbqc-constraintreport-result-table-header-status": "מצב", + "wbqc-constraintreport-result-table-header-property": "מאפיין", + "wbqc-constraintreport-result-table-header-message": "הודעה", + "wbqc-constraintreport-result-table-header-constraint": "אילוץ", + "wbqc-constraintreport-result-link-to-claim": "ללכת אל טענה", + "wbqc-constraintreport-result-link-to-constraint": "ללכת על אילוץ", + "wbqc-constraintreport-no-parameter": "אין", + "wbqc-issues-short": "סוגיות", + "wbqc-issues-long": "בקביעה הזאת יש סוגיות אפשריות.", + "wbqc-potentialissues-short": "סוגיות אפשריות", + "wbqc-potentialissues-long": "בקביעה הזאת יש סוגיות אפשריות.", + "wbqc-suggestions-short": "הצעות", + "wbqc-suggestions-long": "יש כמה הצעות לשיפור הקביעה הזאת.", + "wbqc-badparameters-short": "פרמטרים גרועים", + "wbqc-badparameters-long": "לקביעת האילוץ הזאת יש כמה פרמטרים בלתי־תקינים.", + "wbqc-parameterissues-short": "סוגיות מתקדמות", + "wbqc-parameterissues-long": "הסוגיות האלו הן בעיות עם הגדרת האילוצים על המאפיין, לא עם הקביעה הזאת.", + "wbqc-constrainttypehelp-short": "עזרה", + "wbqc-constrainttypehelp-long": "דף עזרה עבור סוג האילוץ הזה", + "wbqc-constraintdiscuss-short": "דיון", + "wbqc-constraintdiscuss-long": "דף דיונים על האילוץ הזה", + "wbqc-cached-generic": "התוצאה הזאת מוטמנת וייתכן שהיא מיושנת.", + "wbqc-cached-minutes": "התוצאה הזאת מוטמנת וייתכן שהיא מיושנת {{PLURAL:$1|בדקה אחת|ב־$1 דקות}}.", + "wbqc-cached-hours": "התוצאה הזאת מוטמנת וייתכן שהיא מיושנת {{PLURAL:$1|בשעה אחת|בשעתיים|ב־$1 שעות}}.", + "wbqc-cached-days": "התוצאה הזאת מוטמנת וייתכן שהיא מיושנת {{PLURAL:$1|ביום אחד|ביומיים|ב־$1 ימים}}.", + "wbqc-dataValueType-wikibase-entityid": "מזהה ישות", + "wbq-subextension-name-wbqc": "אילוצים", + "wbqc-violation-header-parameters": "פרמטרים:", + "wbqc-violations-group": "אילוצים", + "wbqc-violation-message": "בדיקת אילוצים הצביעה על הפרה. נא ללחוץ על הסמל למידע נוסף.", + "wbqc-violation-message-not-yet-implemented": "מסיבות טכניות הבדיקה של האילוץ \"$1\" עוד לא מומשה.", + "wbqc-violation-message-security-reason": "מסיבות של אבטחה, לא ניתן לבדוק את האילוץ \"$1\" כרגע. אנחנו עובדים על פתרון.", + "wbqc-violation-message-value-needed-of-type": "למאפיינים עם האילוץ \"$1\" צריכים להיות ערכים מסוג \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "למאפיינים עם האילוץ \"$1\" צריכים להיות ערכים מסוג \"$2\" או \"$3\".", + "wbqc-violation-message-parameter-needed": "מאפיינים עם האילוץ \"$1\" צריכים פרמטר \"$2\".", + "wbqc-violation-message-parameters-needed-3": "למאפיינים עם האילוץ \"$1\" צריכים להיות הפרמטרים \"$2\"‏, \"$3\"‏, \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "ישות יעד צריכה להתקיים.", + "wbqc-violation-message-value-entity-must-exist": "ישות הערך צריכה להתקיים.", + "wbqc-violation-message-parameter-value": "לפרמטר \"$1\" צריך להיות ערך מותאם אישית, לא \"no value\" או \"unknown value\".", + "wbqc-violation-message-parameter-value-or-novalue": "לפרמטר \"$1\" צריך להיות ערך מותאם אישית או \"no value\", אבל לעולם לא \"unknown value\".", + "wbqc-violation-message-parameter-entity": "הערך עבור הפרמטר \"$1\" צריך להיות ישות, לא \"$2\".", + "wbqc-violation-message-parameter-item": "הערך עבור הפרמטר \"$1\" צריך להיות פריט, לא \"$2\".", + "wbqc-violation-message-parameter-property": "הערך עבור הפרמטר \"$1\" צריך להיות מאפיין, לא \"$2\".", + "wbqc-violation-message-parameter-string": "הערך עבור הפרמטר \"$1\" צריך להיות מחרוזת, לא \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "הערך עבור הפרמטר \"$1\" צריך להיות טקסט בשפה בודדת, לא \"$2\".", + "wbqc-violation-message-parameter-single": "לפרמטר \"$1\" צריך להיות ערך יחיד.", + "wbqc-violation-message-parameter-single-per-language": "לפרמטר \"$1\" צריך להיות רק ערך אחד לכל שפה, אבל יש לו ערכים מרובים עבור $2 (קוד $3)", + "wbqc-violation-message-parameter-oneof": "הפרמטר \"$1\" צריך להיות {{PLURAL:$2|1=$4.|2=$4 או $5.|אחד מהבאים: $3}}", + "wbqc-violation-message-parameter-regex": "$1 הוא לא ביטוי רגולרי תקין.", + "wbqc-violation-message-sparql-error": "שאילתת ה־SPARQL הסתיימה בשגיאה.", + "wbqc-violation-message-parameters-error-unknown": "לא היה אפשר לייבא את הפרמטרים של האילוץ הזה.", + "wbqc-violation-message-parameters-error-toolong": "לא היה אפשר לייבא את הפרמטרים של האילוץ הזה כי הם ארוכים מדי.", + "wbqc-violation-message-invalid-scope": "$1 אינו טווח תקין עבור אילוץ מסוג $2; {{PLURAL:$3|הטווח היחיד|הטווחים היחידים}} עבור האילוץ הזה {{PLURAL:$3|הוא $5|הם $5 או $6|הם: $4}}.", + "wbqc-violation-message-commons-link-no-existent": "קישור לוויקישיתוף אמור להתקיים.", + "wbqc-violation-message-commons-link-not-well-formed": "קישור לוויקישיתוף אמור להיות תקני", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "בדיקה למרחב השם \"$1\" עדיין אינה ממומשת.", + "wbqc-violation-message-conflicts-with-property": "לישות לא אמורות להיות קביעות עבור $1 וגם $2.", + "wbqc-violation-message-conflicts-with-claim": "לישות לא אמורה להיות קביעה עבור $1 אם יש לה גם קביעה עבור $2 עם הערך $3.", + "wbqc-violation-message-contemporary-subject-earlier": "הישות $1 והישרות $3 אמורות להיות שייכות לאותה תקופה כדי להיות מקושרות דרך $2, אבל ערך הסוף המאוחר ביותר של $1 הוא $4 וערך ההתחלה המוקדם ביותר של $3 הוא $5.", + "wbqc-violation-message-contemporary-value-earlier": "הישות $1 והישות $3 אמורות להיות שייכות לאותה תקופה כדי להיות מקושרות דרך $2, אבל ערך הסוף המאוחר ביותר של $3 הוא $4 וערך ההתחלה המוקדם ביותר של $1 הוא $5.", + "wbqc-violation-message-diff-within-range": "ההבדל בין $3 (כעת: $4) לבין $1 (כעת: $2) אמור להיות בין $5 לבין $6.", + "wbqc-violation-message-diff-within-range-leftopen": "ההבדל בין $3 (כעת: $4) לבין $1 (כעת: $2) אמור להיות לא יותר מ־$5.", + "wbqc-violation-message-diff-within-range-rightopen": "ההבדל בין $3 (כעת: $4) לבין $1 (כעת: $2) אמור להיות לא פחות מ־$5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "למאפיין שהוגדר בפרמטרים צריך להיות ערך מאותו הסוג כמו למאפיין הזה.", + "wbqc-violation-message-format": "הערך של $1 (כעת: $2) אמור להתאים לביטוי הרגולרי $3.", + "wbqc-violation-message-format-clarification": "הערך $2 עבור המאפיין $1 אמור להתאים לתבנית \"$4\" (ביטוי רגולרי: $3)", + "wbqc-violation-message-inverse": "לישות $1 אמורה להיות גם הקביעה ההפוכה $2 $3.", + "wbqc-violation-message-item": "לישות עם $1 אמורה להיות גם {{PLURAL:$3|0=הקביעה $2.|1=הקביעה $2 $5.|הקביעה עבור $2 עם אחד מהערכים הבאים: $4}}", + "wbqc-violation-message-mandatory-qualifier": "בקביעת $1 הזאת חסר המבחין $2.", + "wbqc-violation-message-multi-value": "המאפיין הזה אמור להכיל ערכים מרובים.", + "wbqc-violation-message-multi-value-separators": "המאפיין הזה צריך להכיל כמה ערכים עם {{PLURAL:$2|1=אותו המבחין $4.|אותם המבחינים עבור המאפיינים האלה: $3}}", + "wbqc-violation-message-one-of": "הערך של $1 אמור להיות {{PLURAL:$2|1=$4.|2=$4 או $5.|אחד מהבאים: $3}}", + "wbqc-violation-message-qualifier": "המאפיין הזה אמור לשמש רק כמבחין.", + "wbqc-violation-message-no-qualifiers": "לקביעות $1 לא אמורים להיות מבחינים.", + "wbqc-violation-message-qualifiers": "$2 אינו מבחין תקין עבור $1 – {{PLURAL:$3|1=המבחין התקין היחיד. הוא $5|2=המבחינים התקינים היחידים הם $5 או $6|המבחינים התקינים היחידים הם:$4}}", + "wbqc-violation-message-range-parameters-needed": "למאפיינים עם ערכים מסוג \"$1\" עם האילוץ \"$4\" צריכים להיות הפרמטרים \"$2\" וגם \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "שתי נקודות קצה של טווח יחידת־זמן צריכות להיות עם היחידה \"year\" או לא להיות עם היחידה הזאת, כי לא ניתן להמיר שנים לשניות ללא אובדן מידע.", + "wbqc-violation-message-range-parameters-same": "נקודת ההתחלה ($1) ונקודת הסוף ($2) של הטווח צריכות להיות שונות.", + "wbqc-violation-message-range-quantity-closed": "הערך עבור $1 (כעת: $2) אמור להיות בין $3 לבין $4.", + "wbqc-violation-message-range-quantity-leftopen": "הערך עבור $1 (כעת: $2) אמור להיות לא פחות מ־$3.", + "wbqc-violation-message-range-quantity-rightopen": "הערך עבור $1 (כעת: $2) אמור להיות לא יותר מ־$3.", + "wbqc-violation-message-range-time-closed": "הערך עבור $1 (כעת: $2) אמור להיות בין $3 לבין $4.", + "wbqc-violation-message-range-time-closed-leftnow": "הערך של $1 (כעת $2) צריך להיות בעתיד, אבל לא אחרי $3.", + "wbqc-violation-message-range-time-closed-rightnow": "הערך של $1 (כעת $2) צריך להיות בעתיד, אבל לא לפני $3.", + "wbqc-violation-message-range-time-leftopen": "הערך עבור $1 (כעת: $2) אמור להיות לא אחרי $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "הערך של $1 (כעת $2) לא אמור להיות בעתיד.", + "wbqc-violation-message-range-time-rightopen": "הערך עבור $1 (כעת: $2) אמור להיות לא לפני $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "הערך של $1 (כעת $2) לא אמור להיות בעבר.", + "wbqc-violation-message-single-value": "המאפיין הזה אמור להכיל רק ערך אחד.", + "wbqc-violation-message-single-value-separators": "למאפיין הזה צריך להיות ערך אחד בלבד עם {{PLURAL:$2|1=אותו המבחין $4.|אותם המבחינים עבור המאפיינים האלה: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "המאפיין הזה צריך להכיל ערך אחד שמסומן בתור ”הטוב ביותר“. כמו־כן, מתוך כל המאפיינים הנוכחיים, מאפיין אחד צריך להיות מסומן עם הדירוג ”מועדף“.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "המאפיין הזה צריך להכיל ערך אחד שמסומן בתור \"הטוב ביותר\", עם {{PLURAL:$2|1=אותו המבחין $4.|אותם המבחינים עבור המאפיינים האלה: $3.}} מתוך הערכים הנוכחיים, אחד צריך להיות מסומן בדירוג \"מועדף\".", + "wbqc-violation-message-single-best-value-multi-preferred": "המאפיין הזה צריך להכיל ערך אחד שמסומן בתור ”הטוב ביותר“. כמו־כן, צריך להיות רק ערך אחד עם הדירוג ”מועדף“.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "המאפיין הזה צריך להכיל ערך אחד שמסומן בתור \"הטוב ביותר\", עם {{PLURAL:$2|1=אותו המבחין $4.|אותם המבחינים עבור המאפיינים האלה: $3.}} אמור להיות לא יותר מערך אחד שמסומן בדירוג \"מועדף\".", + "wbqc-violation-message-symmetric": "לישות $1 אמורה להיות גם הקביעה הסימטרית $2 $3.", + "wbqc-violation-message-type-instance": "ישויות שמשתמשות במאפיין $1 אמורות להיות מופעים של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת ישות $2 אינה כזאת{{PLURAL:$3|.|: $4}}", + "wbqc-violation-message-type-subclass": "ישויות שמשתמשות במאפיין $1 אמורות להיות תת־מחלקות של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת ישות $2 אינה כזאת{{PLURAL:$3|.|: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "ישויות שמשתמשות במאפיין $1 אמורות להיות מופעים או תת־מחלקות של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה|אחת מהתת־מחלקות שלהם}}), אבל כעת $2 {{PLURAL:$3|1=אינו כזה.|2=אינו כזה.|אינו כזה: $4}}", + "wbqc-violation-message-valueType-instance": "ערכים של קביעות $1 אמורים להיות מופעים של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת ישות $2 אינה כזאת{{PLURAL:$3|.|: $4}}", + "wbqc-violation-message-valueType-subclass": "ערכים של קביעות $1 אמורים להיות תת־מחלקות של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת ישות $2 אינה כזאת{{PLURAL:$3|.|: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "ערכים של קביעות $1 אמורים להיות מופעים או תת־מחלקות של {{PLURAL:$3|1=$5|2=$5 או $6|אחת מהמחלקות הבאות}} (או של {{PLURAL:$3|1=תת־מחלקה שלה|2=תת־מחלקה שלהן|אחת מהתת־מחלקות שלהן}}), אבל כעת ישות $2 אינה כזאת{{PLURAL:$3|.|: $4}}", + "wbqc-violation-message-target-required-claim": "לישות $1 אמורה להיות {{PLURAL:$3|0=קביעה $2.|1=קביעה $2 $5.הקביעה עבור $2 עם אחד מהערכים הבאים: $4}}", + "wbqc-violation-message-unique-value": "ערך המאפיין הזה צריך לא להיות נוכח בשום פריט אחר, אבל הוא נוכח {{PLURAL:$1|1=בפריט $3.|2=בפריט $3 ובפריט $4.|בפריטים הבאים: $2}}", + "wbqc-violation-message-valueOnly": "המאפיין הזה צריך לשמש רק הערך הראשי של הקביעה, ולא עבור מבחינים או מקורות.", + "wbqc-violation-message-reference": "המאפיין אמור לשמש רק במקורות, לא עבור הערך הראשי של הקביעה או עבור מבחין.", + "wbqc-violation-message-noBounds": "לערכים של המאפיין $1 לא אמורות להיות גבולות.", + "wbqc-violation-message-units-none": "לערך של המאפיין $1 לא צריכה להיות יחידה.", + "wbqc-violation-message-units": "הערך של המאפיין $1 צריך להשתמש {{PLURAL:$2|1=ביחידה $4.|2=ביחידה $4 או ביחידה $5.|באחת היחידות הבאות: $3}}", + "wbqc-violation-message-units-or-none": "הערך של המאפיין $1 צריך להשתמש {{PLURAL:$2|1=ביחידה $4|2=ביחידה $4 או ביחידה $5|באחת היחידות הבאות}}, או לא להשתמש {{PLURAL:$2|1=באף יחידה.|2=בשום יחידה.|בשום יחידה: $3}}", + "wbqc-violation-message-entityType": "המאפיין $1 לא יכול להיות בשימוש בסוג הישות הזה, {{PLURAL:$2|1=סוג הישות התקין היחיד הוא $4.|2=סוגי הישות התקינים היחידים הם $4 או $5.|סוגי הישות התקינים היחידים הם: $3}}", + "wbqc-violation-message-none-of": "הערך של המאפיין $1 לא יכול להיות {{PLURAL:$2|1=$4.|2=$4 או $5.|אחד מהבאים: $3}}", + "wbqc-violation-message-integer": "הערכים של המאפיין $1 צריכים להיות מספרים שלמים, אך הערך $2 כולל חלק עשרוני.", + "wbqc-violation-message-integer-bounds": "הערכים של המאפיין $1 צריכים להיות מספרים שלמים, אך הגבולות של הערך $2 כוללות חלק עשרוני.", + "wbqc-violation-message-citationNeeded": "לקביעות של המאפיין $1 אמור להיות לפחות מקור אחד.", + "wbqc-violation-message-language": "קביעות עבור $1 צריכות להיות רק על יחידות מילוניות שהשפה שלהן היא {{PLURAL:$2|1=$4.|2 $4 או $5.|אחת מהבאות: $3}}", + "wbqc-violation-message-label-lacking": "לישויות עם קביעות עבור $1 צריכה להיות גם תוויות לפחות {{PLURAL:$2|בשפה $4.|לפחות באחת מהשפות הבאות: $3}}", + "wbqc-violation-message-property-scope": "המאפיין $1 לא אמור להיות בשימוש במיקום הזה ($2). {{PLURAL:$3|המיקום התקין היחיד|המיקומים התקינים היחידים}} עבור מאפיין זה {{PLURAL:$3|הוא $5.|הם: $4}}", + "wbqc-violation-message-exception": "הישות הזאת היא חריגה ידועה עבור האילוץ הזה והיא סומנה בתור כזאת." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/hi.json b/dist/extensions/WikibaseQualityConstraints/i18n/hi.json new file mode 100644 index 000000000..48a869764 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/hi.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Nitin1485", + "Rajatkatiyar10", + "Sachinkatiyar", + "Sfic", + "Vishwanath" + ] + }, + "wbqc-constraintreport-status-warning": "चेतावनी", + "wbqc-cached-hours": "यह परिणाम गुप्त है और {{PLURAL:$1|1=एक घंटे|$1 घंटे}} तक पुराना हो सकता है।", + "wbqc-cached-days": "यह परिणाम गुप्त है और {{PLURAL:$1|1=एक घंटे|$1 दिन}} तक पुराना हो सकता है।", + "wbqc-violation-message-parameter-string": "\"$1\" पैरामीटर का मान एक स्ट्रिंग होना चाहिए, \"$2\" नहीं होना चाहिए।", + "wbqc-violation-message-parameter-monolingualtext": "पैरामीटर \"$1\" के लिए मान एक एकल टेक्स्ट होना चाहिए, \"$2\" नहीं।", + "wbqc-violation-message-parameter-single-per-language": "पैरामीटर \"$1\" में प्रति भाषा केवल एक मान होना चाहिए, लेकिन $2 ($3) के लिए कई मान हैं।", + "wbqc-violation-message-range-parameters-same": "किसी श्रेणी के प्रारंभ ($1) और समाप्ति बिंदु ($2) समान नहीं होना चाहिए", + "wbqc-violation-message-range-quantity-leftopen": "$1 ($2) का मान $3 से अधिक नहीं होना चाहिए", + "wbqc-violation-message-range-time-closed-leftnow": "$1 ($2) का मान भविष्य में होना चाहिए, लेकिन $3 के बाद नहीं होना चाहिए", + "wbqc-violation-message-range-time-closed-rightnow": "$1 ($2) का मान अतीत में होना चाहिए, लेकिन $3 से पहले नहीं होना चाहिए", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1 ($2) का मान भविष्य में नहीं होना चाहिए।", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1 ($2) का मान अतीत में नहीं होना चाहिए" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/hr.json b/dist/extensions/WikibaseQualityConstraints/i18n/hr.json new file mode 100644 index 000000000..7555d15ee --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/hr.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Bugoslav" + ] + }, + "wbqc-constraintreport": "Izvješće o ograničenjima" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ht.json b/dist/extensions/WikibaseQualityConstraints/i18n/ht.json new file mode 100644 index 000000000..c3110030b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ht.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Bfpage", + "Tisave" + ] + }, + "wbqc-constraintreport-form-submit-label": "Tcheke", + "wbqc-constraintreport-result-headline": "Rezilta pou", + "wbqc-constraintreport-no-parameter": "okenn" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/hu.json b/dist/extensions/WikibaseQualityConstraints/i18n/hu.json new file mode 100644 index 000000000..2686a9786 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/hu.json @@ -0,0 +1,144 @@ +{ + "@metadata": { + "authors": [ + "Csigabi", + "Máté", + "Tacsipacsi", + "Urbalazs", + "Adam78" + ] + }, + "wbqc-constraintreport": "Kikötésjelentés", + "wbqc-desc": "Ellenőrzi a kikötéseket az elemeken és tulajdonságokon, és az eredményeket egy speciális lapon jeleníti meg", + "wbqc-constraintreport-explanation-part-one": "Ez a speciális lap ellenőrzi a kikötéseket az általad kiválasztott entitáson. Az entitások az élő rendszerből lesznek lekérdezve, így ha javítasz egy kikötésmegszegést, az azonnal lekerül erről a listáról.", + "wbqc-constraintreport-explanation-part-two": "A kikötések a tulajdonságok állításaiból lesznek feldolgozva az állítások minden módosításakor, általában pár percen belül.", + "wbqc-constraintreport-form-section": "Kikötések ellenőrzése egy entitásra", + "wbqc-constraintreport-form-submit-label": "Ellenőrzés", + "wbqc-constraintreport-form-entityid-label": "Entitásazonosító:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx vagy Pxx", + "wbqc-constraintreport-result-headline": "Eredmény ehhez:", + "wbqc-constraintreport-invalid-entity-id": "Érvénytelen azonosító.", + "wbqc-constraintreport-not-existent-entity": "Az elem nem létezik.", + "wbqc-constraintreport-empty-result": "Nincsenek kikötések definiálva ehhez az entitáshoz.", + "wbqc-constraintreport-status-violation": "Megszegés", + "wbqc-constraintreport-status-compliance": "Megfelelő", + "wbqc-constraintreport-status-exception": "Kivétel", + "wbqc-constraintreport-status-todo": "Még nem ellenőrizhető", + "wbqc-constraintreport-status-bad-parameters": "Rossz paraméterek", + "wbqc-constraintreport-status-deprecated": "Elavult", + "wbqc-constraintreport-status-warning": "Figyelmeztetés", + "wbqc-constraintreport-status-suggestion": "Javaslat", + "wbqc-constraintreport-result-table-header-status": "Állapot", + "wbqc-constraintreport-result-table-header-property": "Tulajdonság", + "wbqc-constraintreport-result-table-header-message": "Üzenet", + "wbqc-constraintreport-result-table-header-constraint": "Kikötés", + "wbqc-constraintreport-result-link-to-constraint": "ugrás a kikötéshez", + "wbqc-constraintreport-no-parameter": "semmi", + "wbqc-issues-short": "Problémák", + "wbqc-issues-long": "Ezzel az állítással problémák vannak.", + "wbqc-potentialissues-short": "Lehetséges problémák", + "wbqc-potentialissues-long": "Ezzel az állítással lehet, hogy problémák vannak.", + "wbqc-suggestions-short": "Javaslatok", + "wbqc-suggestions-long": "Ehhez az állításhoz javaslatok vannak.", + "wbqc-badparameters-short": "Rossz paraméterek", + "wbqc-badparameters-long": "A kikötésállítás érvénytelen paramétereket tartalmaz.", + "wbqc-parameterissues-short": "Haladó problémák", + "wbqc-parameterissues-long": "Ezek a problémák a tulajdonság kikötésdefinícióit érintik, nem ezt az állítást.", + "wbqc-constrainttypehelp-short": "Súgó", + "wbqc-constrainttypehelp-long": "Súgólap ehhez a kikötéstípushoz", + "wbqc-constraintdiscuss-short": "Megbeszélés", + "wbqc-constraintdiscuss-long": "Megbeszéléslap ehhez a kikötéshez", + "wbqc-cached-generic": "Ez az eredmény gyorsítótárazva van, és elavult lehet.", + "wbqc-cached-minutes": "Ez az eredmény gyorsítótárazva van, és legfeljebb $1 perc lemaradásban lehet.", + "wbqc-cached-hours": "Ez az eredmény gyorsítótárazva van, és legfeljebb $1 óra lemaradásban lehet.", + "wbqc-cached-days": "Ez az eredmény gyorsítótárazva van, és legfeljebb $1 nap lemaradásban lehet.", + "wbqc-dataValueType-wikibase-entityid": "Entitásazonosító", + "wbq-subextension-name-wbqc": "Kikötések", + "wbqc-violation-header-parameters": "Paraméterek:", + "wbqc-violations-group": "Kikötések", + "wbqc-violation-message": "Az ellenőrzés kikötésmegszegést talált. Kattints az ikonra további információkért.", + "wbqc-violation-message-not-yet-implemented": "Technikai okokból a(z) „$1” kikötés ellenőrzése még nincs megvalósítva.", + "wbqc-violation-message-security-reason": "Biztonsági okokból jelenleg nem lehetséges a(z) „$1” kikötés ellenőrzése. Dolgozunk a megoldáson.", + "wbqc-violation-message-value-needed-of-type": "A(z) „$1” kikötésű tulajdonságoknak „$2” típusú értékekkel kell rendelkezniük.", + "wbqc-violation-message-value-needed-of-types-2": "A(z) „$1” kikötésű tulajdonságoknak „$2” vagy „$3” típusú értékekkel kell rendelkezniük.", + "wbqc-violation-message-parameter-needed": "A(z) „$1” kikötésű tulajdonságoknak szükségük van egy „$2” paraméterre.", + "wbqc-violation-message-parameters-needed-3": "A(z) „$1” kikötésű tulajdonságoknak szükségük van a(z) „$2”, „$3” és „$4” paraméterekre.", + "wbqc-violation-message-target-entity-must-exist": "A célentitásnak léteznie kell.", + "wbqc-violation-message-value-entity-must-exist": "Az értékentitásnak léteznie kell.", + "wbqc-violation-message-parameter-value": "A(z) „$1” paraméternek egyedi értékkel kell rendelkeznie, nem „ismeretlen érték”-kel vagy „nincs érték”-kel.", + "wbqc-violation-message-parameter-value-or-novalue": "A(z) „$1” paraméternek egyedi értékkel vagy „nincs érték”-kel kell rendelkeznie, de soha nem „ismeretlen érték”-kel.", + "wbqc-violation-message-parameter-entity": "A(z) „$1” paraméter értékének entitásnak kellene lennie, de az „$2”.", + "wbqc-violation-message-parameter-item": "A(z) „$1” paraméter értékének elemnek kell lennie, nem „$2” típusúnak.", + "wbqc-violation-message-parameter-property": "A(z) „$1” paraméter értékének tulajdonságnak kell lennie, nem „$2” típusúnak.", + "wbqc-violation-message-parameter-string": "A(z) „$1” paraméter értékének karakterláncnak kell lennie, nem „$2” típusúnak.", + "wbqc-violation-message-parameter-monolingualtext": "A(z) „$1” paraméter értékének egynyelvű szövegnek kell lennie, nem „$2” típusúnak.", + "wbqc-violation-message-parameter-single": "A(z) „$1” paraméternek egyetlen értéke lehet.", + "wbqc-violation-message-parameter-single-per-language": "A(z) „$1” paraméternek nyelvenként egyetlen értéke lehet, de több értéke van $2 ($3) nyelvhez.", + "wbqc-violation-message-parameter-oneof": "A(z) „$1” paraméternek {{PLURAL:$2|a(z) „$4” értéket|a következő értékek egyikét}} kell felvennie{{PLURAL:$2|1=.|2=: „$4” vagy „$5”.|:$3}}", + "wbqc-violation-message-parameter-regex": "„$1” nem érvényes reguláris kifejezés.", + "wbqc-violation-message-sparql-error": "A SPARQL-lekérdezés hibát adott vissza.", + "wbqc-violation-message-parameters-error-unknown": "A kikötés paramétereinek importálása sikertelen.", + "wbqc-violation-message-parameters-error-toolong": "A kikötés paramétereinek importálása sikertelen, mert túl hosszúak.", + "wbqc-violation-message-commons-link-no-existent": "A Commons-hivatkozásnak léteznie kell.", + "wbqc-violation-message-commons-link-not-well-formed": "A Commons-hivatkozásnak jól formázottnak kell lennie.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Az ellenőrzés a(z) „$1” névtérre még nincs megvalósítva.", + "wbqc-violation-message-conflicts-with-property": "Egy entitásnak nem szabad $1 és $2 állításokkal is rendelkeznie.", + "wbqc-violation-message-conflicts-with-claim": "Egy entitásnak nem szabad $1 állítással rendelkeznie, ha van egy $2 állítása is $3 értékkel.", + "wbqc-violation-message-contemporary-subject-earlier": "A(z) $1 és $3 entitásoknak kortársaknak kell lenniük a(z) $2 állításon keresztüli összekapcsoláshoz, de a(z) $1 legkésőbbi befejezésértéke $4, a(z) $3 legkorábbi kezdetértéke pedig $5.", + "wbqc-violation-message-contemporary-value-earlier": "A(z) $1 és $3 entitásoknak kortársaknak kell lenniük a(z) $2 állításon keresztüli összekapcsoláshoz, de a(z) $3 legkésőbbi befejezésértéke $4, a(z) $1 legkorábbi kezdetértéke pedig $5.", + "wbqc-violation-message-diff-within-range": "$3 ($4) és $1 ($2) közötti különbségnek $5 és $6 között kell lennie.", + "wbqc-violation-message-diff-within-range-leftopen": "$3 ($4) és $1 ($2) közötti különbség nem lehet nagyobb mint $5.", + "wbqc-violation-message-diff-within-range-rightopen": "$3 ($4) és $1 ($2) közötti különbség nem lehet kisebb mint $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "A paraméterekben megadott tulajdonságnak ugyanolyan értéktípusúnak kell lennie, mint ez a tulajdonság.", + "wbqc-violation-message-format": "A(z) $1 értékének ($2) illeszkednie kell a következő reguláris kifejezésre: $3.", + "wbqc-violation-message-format-clarification": "A(z) $1 értékének ($2) illeszkednie kell a következő formátumra: „$4” (reguláris kifejezés: $3).", + "wbqc-violation-message-inverse": "A(z) $1 kell, hogy rendelkezzen egy inverz $2 $3 állítással.", + "wbqc-violation-message-item": "A(z) $1 tulajdonság használóinak rendelkezniük kell {{PLURAL:$3|0=egy $2 állítással is.|1=egy $2 $5 állítással is.|egy állítással a(z) $2 tulajdonsághoz is a következő értékek egyikével:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Ehhez a(z) $1 állításhoz hiányzik egy $2 minősítő.", + "wbqc-violation-message-multi-value": "Ennek a tulajdonságnak többféle értékkel kell rendelkeznie.", + "wbqc-violation-message-multi-value-separators": "Ennek a tulajdonságnak többféle {{PLURAL:$2|1=azonos $4 minősítőjű értékkel rendelkeznie.|a következő minősítőkben azonos értékkel kell rendelkeznie: $3}}", + "wbqc-violation-message-one-of": "A(z) $1 tulajdonság értékének a {{PLURAL:$2|következőnek|következők egyikének}} kell lennie: {{PLURAL:$2|1=$4.|2=$4 vagy $5.|$3}}", + "wbqc-violation-message-qualifier": "A tulajdonság csak minősítőként használható.", + "wbqc-violation-message-no-qualifiers": "A(z) $1 állításoknak nem lehet minősítőjük.", + "wbqc-violation-message-qualifiers": "$2 nem érvényes minősítő ehhez: $1 – csak a következő {{PLURAL:$3|1=minősítő engedélyezett: $5.|2=minősítők engedélyezettek: $5 és $6.|minősítők engedélyezettek: $4}}", + "wbqc-violation-message-range-parameters-needed": "A(z) „$1” adattípusú, „$4” kikötéssel rendelkező tulajdonságoknak meg kell adni a(z) „$2” és „$3” paramétereket.", + "wbqc-violation-message-range-parameters-one-year": "Egy időtartam végpontjai közül vagy mindkettő, vagy egyik sem lehet „év” egységben, mert az éveket nem lehet veszteségmentesen másodpercekké konvertálni.", + "wbqc-violation-message-range-parameters-same": "Egy intervallum kezdő- ($1) és végpontja ($2) nem lehet azonos.", + "wbqc-violation-message-range-quantity-closed": "A(z) $1 értékének ($2) $3 és $4 közé kell esnie.", + "wbqc-violation-message-range-quantity-leftopen": "A(z) $1 értéke ($2) nem lehet több mint $3.", + "wbqc-violation-message-range-quantity-rightopen": "A(z) $1 értéke ($2) nem lehet kevesebb mint $3.", + "wbqc-violation-message-range-time-closed": "A(z) $1 értékének ($2) $3 és $4 közé kell esnie.", + "wbqc-violation-message-range-time-closed-leftnow": "A(z) $1 értékének ($2) a jövőben kell lennie, de nem később mint $3.", + "wbqc-violation-message-range-time-closed-rightnow": "A(z) $1 értékének ($2) a múltban kell lennie, de nem korábban mint $3.", + "wbqc-violation-message-range-time-leftopen": "A(z) $1 értéke ($2) nem lehet később mint $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "A(z) $1 értéke ($2) nem lehet a jövőben.", + "wbqc-violation-message-range-time-rightopen": "A(z) $1 értéke ($2) nem lehet korábban mint $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "A(z) $1 értéke ($2) nem lehet a múltban.", + "wbqc-violation-message-single-value": "Ennek a tulajdonságnak egyféle értékkel kell rendelkeznie.", + "wbqc-violation-message-single-value-separators": "Ennek a tulajdonságnak egyféle {{PLURAL:$2|1=azonos $4 minősítőjű értékkel kell rendelkeznie.|az alábbi minősítőkben azonos értékkel kell rendelkeznie: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Ennek a tulajdonságnak egyféle „legjobb” értékkel kell rendelkeznie. A jelenlegi több érték közül egyet meg kell jelölni „preferált” ranggal.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ennek a tulajdonságnak többféle {{PLURAL:$2|1=azonos $4 minősítőjű „legjobb” értékkel rendelkeznie.|a következő minősítőkben azonos „legjobb” értékkel kell rendelkeznie: $3}} A jelenlegi több érték közül egyet meg kell jelölni „preferált” ranggal.", + "wbqc-violation-message-single-best-value-multi-preferred": "Ennek a tulajdonságnak egyféle „legjobb” értékkel kell rendelkeznie. Nem lehetne egynél több „preferált” rangú érték.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ennek a tulajdonságnak többféle {{PLURAL:$2|1=azonos $4 minősítőjű „legjobb” értékkel rendelkeznie.|a következő minősítőkben azonos „legjobb” értékkel kell rendelkeznie: $3}} Nem lehetne egynél több „preferált” rangú érték.", + "wbqc-violation-message-symmetric": "A(z) $1 kell, hogy rendelkezzen egy szimmetrikus $2 $3 állítással.", + "wbqc-violation-message-type-instance": "A(z) „$1” tulajdonságot használó entitásoknak {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) példányainak kell lenniük, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-type-subclass": "A(z) „$1” tulajdonságot használó entitásoknak {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) alosztályainak kell lenniük, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "A(z) „$1” tulajdonságot használó entitásoknak {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) példányainak vagy alosztályainak kell lenniük, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-valueType-instance": "A(z) „$1” állítások értékének {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) példányának kell lennie, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-valueType-subclass": "A(z) „$1” állítások értékének {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) alosztályának kell lennie, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "A(z) „$1” állítások értékének {{PLURAL:$3|1=a(z) $5 osztály|2=a(z) $5 vagy $6 osztály|a következő osztályok egyike}} (vagy {{PLURAL:$3|egy|valamelyikük}} alosztálya) példányának vagy alosztályának kell lennie, de a(z) $2 nem {{PLURAL:$3|1=az.|2=az.|az: $4}}", + "wbqc-violation-message-target-required-claim": "A(z) $1 egy {{PLURAL:$3|0=$2|1=$2 $5|$2}} állítással kell rendelkezzen{{PLURAL:$3|0=.|1=.| a következő értékek egyikével: $4}}", + "wbqc-violation-message-unique-value": "A tulajdonság értéke nem szerepelhet másik elemen, de {{PLURAL:$1|1=a(z) $3 elemen|2=a(z) $3 és $4 elemen|a következő elemeken}} is szerepel{{PLURAL:$1|1=.|2=.|: $2}}", + "wbqc-violation-message-valueOnly": "A tulajdonság csak egy állítás fő értékeként használható, minősítőként és forráshivatkozásként nem.", + "wbqc-violation-message-reference": "A tulajdonság csak a forráshivatkozásokban használható, egy állítás fő értékeként és minősítőként nem.", + "wbqc-violation-message-units-none": "A(z) „$1” értéke nem rendelkezhet mértékegységgel.", + "wbqc-violation-message-units": "A(z) „$1” értékének {{PLURAL:$2|1=$4 mértékegységgel kell rendelkeznie.|2=$4 vagy $5 mértékegységgel kell rendelkeznie.|a következő mértékegységek egyikével kell rendelkeznie: $3}}", + "wbqc-violation-message-units-or-none": "A(z) „$1” értékének {{PLURAL:$2|1=$4 mértékegységgel|2=$4 vagy $5 mértékegységgel|a következő mértékegységek egyikével}} kell rendelkeznie, vagy mértékegység nélkülinek kell {{PLURAL:$2|1=lennie.|2=lennie.|lennie: $3}}", + "wbqc-violation-message-entityType": "A(z) „$1” tulajdonság nem használható ezen az entitástípuson, csak {{PLURAL:$2|1=$4 entitástípuson.|2=$4 vagy $5 entitástípuson.|a következő entitástípusok egyikén: $3}}", + "wbqc-violation-message-none-of": "A(z) „$1” tulajdonság értéke nem lehet {{PLURAL:$2|1=„$4”.|2=„$4” vagy „$5”.|az alábbiak egyike sem: $3}}", + "wbqc-violation-message-integer": "A(z) „$1” tulajdonság értékének egész számnak kell lennie, de a(z) „$2” nem az.", + "wbqc-violation-message-citationNeeded": "A(z) „$1” tulajdonság állításainak legalább egy forráshivatkozással kell rendelkezniük.", + "wbqc-violation-message-label-lacking": "A(z) $1 tulajdonsággal rendelkező entitásoknak {{PLURAL:$2|$4 nyelvű címkével is kell rendelkezniük.|rendelkezniük kell címkével a következő nyelveken: $3}}", + "wbqc-violation-message-property-scope": "A(z) „$1” tulajdonság nem használható ezen a helyen ($2). Az {{PLURAL:$3|egyetlen érvényes hely|egyedüli érvényes helyek}} ennek a tulajdonságnak {{PLURAL:$3|a következő: $5.|a következők: $4}}", + "wbqc-violation-message-exception": "Ez az entitás egy ismert kivétel ez alól a kikötés alól, és meg lett jelölve ekként." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/hy.json b/dist/extensions/WikibaseQualityConstraints/i18n/hy.json new file mode 100644 index 000000000..4b9b9b098 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/hy.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Kareyac" + ] + }, + "wbqc-constraintreport-status-suggestion": "Առաջարկություն", + "wbqc-suggestions-short": "Առաջարկություններ", + "wbqc-constrainttypehelp-short": "Օգնություն" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/hyw.json b/dist/extensions/WikibaseQualityConstraints/i18n/hyw.json new file mode 100644 index 000000000..4550f0850 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/hyw.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Kareyac" + ] + }, + "wbqc-constrainttypehelp-short": "Օգնութիւն" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ia.json b/dist/extensions/WikibaseQualityConstraints/i18n/ia.json new file mode 100644 index 000000000..9bbfa28be --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ia.json @@ -0,0 +1,146 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "wbqc-constraintreport": "Reporto de restrictiones", + "wbqc-desc": "Verifica restrictiones sur elementos e proprietates e monstra le resultatos in un pagina special", + "wbqc-constraintreport-explanation-part-one": "Iste pagina special effectua controlos de restriction sur qualcunque entitate que tu vole. Le entitates es recuperate del systema active, de sorta que cata violation del restriction que tu repara ibi essera instantaneemente eliminate de iste lista.", + "wbqc-constraintreport-explanation-part-two": "Le restrictiones es analysate ab declarationes sur proprietates cata vice que iste declarationes es modificate, generalmente in poc minutas.", + "wbqc-constraintreport-form-section": "Verificar restrictiones pro entitate", + "wbqc-constraintreport-form-submit-label": "Verificar", + "wbqc-constraintreport-form-entityid-label": "ID de entitate:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx o Pxx", + "wbqc-constraintreport-result-headline": "Resultato pro", + "wbqc-constraintreport-invalid-entity-id": "ID de entitate non valide.", + "wbqc-constraintreport-not-existent-entity": "Entitate non existe.", + "wbqc-constraintreport-empty-result": "Il non ha restrictiones definite sur iste entitate.", + "wbqc-constraintreport-status-violation": "Violation", + "wbqc-constraintreport-status-compliance": "Conformitate", + "wbqc-constraintreport-status-exception": "Exception", + "wbqc-constraintreport-status-todo": "A facer", + "wbqc-constraintreport-status-bad-parameters": "Mal parametros", + "wbqc-constraintreport-status-deprecated": "Obsolescente", + "wbqc-constraintreport-status-warning": "Advertimento", + "wbqc-constraintreport-status-suggestion": "Suggestion", + "wbqc-constraintreport-status-not-in-scope": "Foras del ambito", + "wbqc-constraintreport-result-table-header-status": "Stato", + "wbqc-constraintreport-result-table-header-property": "Proprietate", + "wbqc-constraintreport-result-table-header-message": "Message", + "wbqc-constraintreport-result-table-header-constraint": "Restriction", + "wbqc-constraintreport-result-link-to-claim": "ir al assertion", + "wbqc-constraintreport-result-link-to-constraint": "ir al restriction", + "wbqc-constraintreport-no-parameter": "necun", + "wbqc-issues-short": "Problemas", + "wbqc-issues-long": "Iste declaration ha alcun problemas.", + "wbqc-potentialissues-short": "Possibile problemas", + "wbqc-potentialissues-long": "Iste declaration ha alcun problemas potential.", + "wbqc-suggestions-short": "Suggestiones", + "wbqc-suggestions-long": "Il ha alcun suggestiones pro meliorar iste declaration.", + "wbqc-badparameters-short": "Mal parametros", + "wbqc-badparameters-long": "Iste declaration de restriction ha alcun parametros non valide.", + "wbqc-parameterissues-short": "Problemas complexe", + "wbqc-parameterissues-long": "Iste problemas es problemas con le definition del restriction sur le proprietate, non con iste declaration.", + "wbqc-constrainttypehelp-short": "Adjuta", + "wbqc-constrainttypehelp-long": "Pagina de adjuta pro iste typo de restriction", + "wbqc-constraintdiscuss-short": "Discuter", + "wbqc-constraintdiscuss-long": "Pagina de discussion sur iste restriction", + "wbqc-cached-generic": "Iste resultato proveni del cache e pote esser obsolete.", + "wbqc-cached-minutes": "Iste resultato proveni del cache e pote esser obsolete per usque a {{PLURAL:$1|1=un minuta|$1 minutas}}.", + "wbqc-cached-hours": "Iste resultato proveni del cache e pote esser obsolete per usque a {{PLURAL:$1|1=un hora|$1 horas}}.", + "wbqc-cached-days": "Iste resultato proveni del cache e pote esser obsolete per usque a {{PLURAL:$1|1=un die|$1 dies}}.", + "wbqc-dataValueType-wikibase-entityid": "ID de entitate", + "wbq-subextension-name-wbqc": "Restrictiones", + "wbqc-violation-header-parameters": "Parametros:", + "wbqc-violations-group": "Restrictiones", + "wbqc-violation-message": "Controlo de restriction ha identificate un violation. Per favor clicca sur le icone pro ulterior information.", + "wbqc-violation-message-not-yet-implemented": "Pro rationes technic, le controlo pro le restriction \"$1\" non ha ancora essite implementate.", + "wbqc-violation-message-security-reason": "Pro rationes de securitate, non es possibile verificar le restriction \"$1\" in iste momento. Nos labora a un solution.", + "wbqc-violation-message-value-needed-of-type": "Proprietates con restriction \"$1\" debe haber valores de typo \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Proprietates con restriction \"$1\" debe haber valores de typo \"$2\" o \"$3\".", + "wbqc-violation-message-parameter-needed": "Proprietates con restriction \"$1\" require un parametro \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Proprietates con restriction \"$1\" require le parametros \"$2\", \"$3\" e \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "Le entitate de destination debe exister.", + "wbqc-violation-message-value-entity-must-exist": "Le entitate de valor debe exister.", + "wbqc-violation-message-parameter-value": "Le parametro \"$1\" debe haber un valor personalisate, non \"necun valor\" o \"valor incognite\".", + "wbqc-violation-message-parameter-value-or-novalue": "Le parametro \"$1\" debe haber un valor personalisate o \"necun valor\", ma nunquam \"valor incognite\".", + "wbqc-violation-message-parameter-entity": "Le valor del parametro \"$1\" debe esser un entitate, non \"$2\".", + "wbqc-violation-message-parameter-item": "Le valor del parametro \"$1\" debe esser un elemento, non \"$2\".", + "wbqc-violation-message-parameter-property": "Le valor del parametro \"$1\" debe esser un proprietate, non \"$2\".", + "wbqc-violation-message-parameter-string": "Le valor del parametro \"$1\" debe esser un catena, non \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Le valor del parametro \"$1\" debe esser un texto monolingue, non \"$2\".", + "wbqc-violation-message-parameter-single": "Le parametro \"$1\" debe haber solo un valor singule.", + "wbqc-violation-message-parameter-single-per-language": "Le parametro \"$1\" debe haber solo un valor singule per lingua, ma ha plure valores pro $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Le parametro \"$1\" debe esser {{PLURAL:$2|1=$4.|2=o $4 o $5.|un del sequentes:$3}}", + "wbqc-violation-message-parameter-regex": "$1 non es un expression regular valide.", + "wbqc-violation-message-sparql-error": "Le consulta SPARQL ha resultate in un error.", + "wbqc-violation-message-parameters-error-unknown": "Le parametros de iste restriction non poteva esser importate.", + "wbqc-violation-message-parameters-error-toolong": "Le parametros de iste restriction non poteva esser importate perque illos es troppo longe.", + "wbqc-violation-message-invalid-scope": "$1 non es un ambito valide pro le typo de restriction $2; le unic ambito{{PLURAL:$3||s}} valide pro iste typo de restriction {{PLURAL:$3|es $5.|2=es $5 e $6.|es: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Le ligamine a Commons deberea exister.", + "wbqc-violation-message-commons-link-not-well-formed": "Le ligamine a Commons deberea esser ben formate.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Controlo pro spatio de nomines \"$1\" non es ancora implementate.", + "wbqc-violation-message-conflicts-with-property": "Un entitate non debe haber declarationes pro le duo de $1 e $2.", + "wbqc-violation-message-conflicts-with-claim": "Un entitate non debe haber un declaration pro $1 si illo ha equalmente un declaration pro $2 con valor $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Le entitates $1 e $3 debe esser contemporanee pro esser ligate per $2, ma le ultime valor de fin de $1 es $4 e le prime valor de initio de $3 es $5.", + "wbqc-violation-message-contemporary-value-earlier": "Le entitates $1 e $3 debe esser contemporanee pro esser ligate per $2, ma le ultime valor de fin de $3 es $4 e le prime valor de initio de $1 es $5.", + "wbqc-violation-message-diff-within-range": "Le differentia inter $3 ($4) e $1 ($2) debe esser inter $5 e $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Le differentia inter $3 ($4) e $1 ($2) non debe esser plus de $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Le differentia inter $3 ($4) e $1 ($2) non debe esser minus de $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Le proprietate definite in le parametros debe haber un valor del mesme typo que iste proprietate.", + "wbqc-violation-message-format": "Le valor pro $1 ($2) debe concordar con le regex $3.", + "wbqc-violation-message-format-clarification": "Le valor pro $1 ($2) debe concordar con “$4” (regex: $3).", + "wbqc-violation-message-inverse": "$1 debe equalmente haber le declaration inverse $2 $3.", + "wbqc-violation-message-item": "Un entitate con $1 debe equalmente haber {{PLURAL:$3|0=un declaration $2.|1=un declaration $2 $5.|un declaration pro $2 con un del sequente valores:$4}}", + "wbqc-violation-message-mandatory-qualifier": "A iste declaration $1 manca un qualificator $2.", + "wbqc-violation-message-multi-value": "Iste proprietate debe continer plure valores.", + "wbqc-violation-message-multi-value-separators": "Iste proprietate debe continer plure valores con le mesme {{PLURAL:$2|1=qualificator $4.|insimul de qualificatores pro iste proprietates: $3}}", + "wbqc-violation-message-one-of": "Le valor pro $1 debe esser {{PLURAL:$2|1=$4.|2=$4 o $5.|un del sequentes:$3}}", + "wbqc-violation-message-qualifier": "Le proprietate debe solmente esser usate como qualificator.", + "wbqc-violation-message-no-qualifiers": "Declarationes de $1 non debe haber alcun qualificatores.", + "wbqc-violation-message-qualifiers": "$2 non es un qualificator valide pro $1 - le sol {{PLURAL:$3|1=qualificator valide es $5.|2=qualificatores valide es $5 e $6.|qualificatores valide es:$4}}", + "wbqc-violation-message-range-parameters-needed": "Proprietates con valores de typo \"$1\" con restriction \"$4\" require le parametros \"$2\" e \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "O ambes o nulle del punctos final de un intervallo de unitate de tempore debe haber le unitate \"anno\", perque annos non pote esser convertite in secundas sin perdita.", + "wbqc-violation-message-range-parameters-same": "Le puncto de initio ($1) e puncto de fin ($2) de un intervallo non debe esser le mesme.", + "wbqc-violation-message-range-quantity-closed": "Le valor pro $1 ($2) debe esser inter $3 e $4.", + "wbqc-violation-message-range-quantity-leftopen": "Le valor pro $1 ($2) non debe esser plus de $3.", + "wbqc-violation-message-range-quantity-rightopen": "Le valor pro $1 ($2) non debe esser minus de $3.", + "wbqc-violation-message-range-time-closed": "Le valor pro $1 ($2) debe esser inter $3 e $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Le valor pro $1 ($2) debe esser in le futuro, ma non post $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Le valor pro $1 ($2) debe esser in le futuro, ma non ante $3.", + "wbqc-violation-message-range-time-leftopen": "Le valor pro $1 ($2) non debe esser post $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Le valor pro $1 ($2) non debe esser in le futuro.", + "wbqc-violation-message-range-time-rightopen": "Le valor pro $1 ($2) non debe esser ante $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Le valor pro $1 ($2) non debe esser in le passato.", + "wbqc-violation-message-single-value": "Iste proprietate debe continer un valor singule.", + "wbqc-violation-message-single-value-separators": "Iste proprietate debe solmente haber un valor singule con le mesme {{PLURAL:$2|1=qualificator $4.|insimul de qualificatores pro iste proprietates: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Iste proprietate debe continer un singule valor “optime”. Inter le plure valores actual, un debe esser marcate con le rango “preferite”.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Iste proprietate debe continer un singule valor “optime” con le mesme {{PLURAL:$2|1=qualificator $4.|insimul de qualificatores pro iste proprietates: $3}}. Inter le plure valores actual, un debe esser marcate con le rango “preferite”.", + "wbqc-violation-message-single-best-value-multi-preferred": "Iste proprietate debe continer un singule valor “optime”. Non debe exister plus de un valor con rango “preferite”.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Iste proprietate debe continer un singule valor “optime” con le mesme {{PLURAL:$2|1=qualificator $4.|insimul de qualificatores pro iste proprietates: $3}}. Non debe exister plus de un valor con rango “preferite”.", + "wbqc-violation-message-symmetric": "$1 debe equalmente haber le declaration symmetric $2 $3.", + "wbqc-violation-message-type-instance": "Entitates usante le proprietate $1 debe esser instantias de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-type-subclass": "Entitates usante le proprietate $1 debe esser subclasses de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entitates usante le proprietate $1 debe esser instantias o subclasses de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-valueType-instance": "Le valores de declarationes $1 debe esser instantias de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-valueType-subclass": "Le valores de declarationes $1 debe esser subclasses de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Le valores de declarationes $1 debe esser instantias o subclasses de {{PLURAL:$3|1=$5|2=$5 o $6|un del sequente classes}} (o de {{PLURAL:$3|1=un subclasse de illo|2=un subclasse de illos|un de lor subclasses}}), ma $2 actualmente {{PLURAL:$3|1=non lo es.|2=non lo es.|non lo es: $4}}", + "wbqc-violation-message-target-required-claim": "$1 debe haber {{PLURAL:$3|0=un declaration $2.|1=un declaration $2 $5.|un declaration pro $2 con un del sequentes valores:$4}}", + "wbqc-violation-message-unique-value": "Le valor de iste proprietate non deberea esser presente sur alcun altere elemento, sed es etiam presente sur {{PLURAL:$1|1=$3.|2=$3 e $4.|le sequente elementos: $2}}", + "wbqc-violation-message-valueOnly": "Iste proprietate debe solmente esser usate pro le valor principal de un declaration, non pro qualificatores o referentias.", + "wbqc-violation-message-reference": "Le proprietate debe solmente esser usate in referentias, non pro le valor principal de un declaration o pro un qualificator.", + "wbqc-violation-message-noBounds": "Valores pro $1 non debe haber alcun limites.", + "wbqc-violation-message-units-none": "Le valor pro $1 non debe haber un unitate.", + "wbqc-violation-message-units": "Le valor pro $1 debe haber {{PLURAL:$2|1=le unitate $4.|2=le unitate $4 o $5.|un del sequente unitates: $3}}", + "wbqc-violation-message-units-or-none": "Le valor pro $1 debe haber {{PLURAL:$2|1=le unitate $4|2=le unitate $4 o $5|un del sequente unitates}} o esser {{PLURAL:$2|1=sin unitate.|2=sin unitate.|sin unitate: $3}}", + "wbqc-violation-message-entityType": "Le proprietate $1 non debe esser usate in iste typo de entitate, le unic {{PLURAL:$2|1=typo de entitate valide es $4.|2=typos de entitate valide es $4 e $5.|typos de entitate valide es: $3}}", + "wbqc-violation-message-none-of": "Le valor pro $1 non debe esser {{PLURAL:$2|1=$4.|2=$4 o $5.|un del sequentes:$3}}", + "wbqc-violation-message-integer": "Le valores pro $1 debe esser numeros integre, ma $2 ha un parte fractional.", + "wbqc-violation-message-integer-bounds": "Le valores pro $1 debe esser numeros integre, ma le limites de $2 ha un parte fractional.", + "wbqc-violation-message-citationNeeded": "Declarationes pro $1 debe haber al minus un referentia.", + "wbqc-violation-message-language": "Declarationes pro $1 debe esser solmente sur lexemas con le lingua fixate a {{PLURAL:$2|1=$4.|2=o $4 o $5.|un del sequentes: $3}}", + "wbqc-violation-message-label-lacking": "Entitates con declarationes pro $1 debe tamben haber un etiquetta al minus in {{PLURAL:$2|1=le lingua $4.|un del sequente linguas: $3}}", + "wbqc-violation-message-property-scope": "Le proprietate $1 non debe esser usate in iste loco ($2). Le sol {{PLURAL:$3|loco|locos}} valide pro iste proprietate {{PLURAL:$3|es $5.|es: $4}}", + "wbqc-violation-message-exception": "Iste entitate es un exception cognoscite pro iste restriction e ha essite marcate como tal." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/id.json b/dist/extensions/WikibaseQualityConstraints/i18n/id.json new file mode 100644 index 000000000..908eeadc1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/id.json @@ -0,0 +1,150 @@ +{ + "@metadata": { + "authors": [ + "Daud I.F. Argana", + "Pebaryan", + "RXerself", + "Zakiy", + "Amire80" + ] + }, + "wbqc-constraintreport": "Laporan pewatas", + "wbqc-desc": "Memeriksa pewatas baik pada butir dan atribut serta memperlihatkan hasilnya pada sebuah halaman istimewa", + "wbqc-constraintreport-explanation-part-one": "Halaman istimewa ini melakukan pemeriksaan pewatas pada entitas apapun yang dapat disesuaikan. Entitas yang diperiksa berasal dari sistem aktif sehingga setiap pelanggaran pewatas yang diperbaiki akan terhapus otomatis dari daftar ini.", + "wbqc-constraintreport-explanation-part-two": "Pewatas yang diperiksa berasal dari pernyataan-pernyataan pada atribut setiap kali pernyataan tersebut disunting. Pemeriksaan biasanya akan berjalan dalam beberapa menit setelah suntingan disimpan.", + "wbqc-constraintreport-form-section": "Periksa pewatas untuk entitas", + "wbqc-constraintreport-form-submit-label": "Periksa", + "wbqc-constraintreport-form-entityid-label": "ID Entitas:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx atau Pxx", + "wbqc-constraintreport-result-headline": "Hasil untuk", + "wbqc-constraintreport-invalid-entity-id": "ID entitas tidak sah.", + "wbqc-constraintreport-not-existent-entity": "Entitas tidak ditemukan.", + "wbqc-constraintreport-empty-result": "Tidak ada pewatas pada entitas ini.", + "wbqc-constraintreport-status-violation": "Pelanggaran", + "wbqc-constraintreport-status-compliance": "Ketaatan", + "wbqc-constraintreport-status-exception": "Pengecualian", + "wbqc-constraintreport-status-todo": "Untuk dikerjakan", + "wbqc-constraintreport-status-bad-parameters": "Parameter buruk", + "wbqc-constraintreport-status-deprecated": "Usang", + "wbqc-constraintreport-status-warning": "Peringatan", + "wbqc-constraintreport-status-suggestion": "Saran", + "wbqc-constraintreport-status-not-in-scope": "Tidak termasuk cakupan", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Atribut", + "wbqc-constraintreport-result-table-header-message": "Pesan", + "wbqc-constraintreport-result-table-header-constraint": "Pewatas", + "wbqc-constraintreport-result-link-to-claim": "ke klaim", + "wbqc-constraintreport-result-link-to-constraint": "ke pewatas", + "wbqc-constraintreport-no-parameter": "tidak ada", + "wbqc-issues-short": "Masalah", + "wbqc-issues-long": "Pernyataan ini memiliki beberapa masalah.", + "wbqc-potentialissues-short": "Kemungkinan masalah", + "wbqc-potentialissues-long": "Pernyataan ini dapat memiliki masalah.", + "wbqc-suggestions-short": "Saran", + "wbqc-suggestions-long": "Ada beberapa saran untuk memperbaiki pernyataan ini.", + "wbqc-badparameters-short": "Parameter buruk", + "wbqc-badparameters-long": "Pernyataan pewatas ini memiliki beberapa parameter buruk yang tidak sah.", + "wbqc-parameterissues-short": "Masalah lanjutan", + "wbqc-parameterissues-long": "Masalah-masalah berikut memiliki kaitan dengan definisi pewatas pada atribut, bukan dengan pernyataan.", + "wbqc-constrainttypehelp-short": "Bantuan", + "wbqc-constrainttypehelp-long": "Halaman bantuan mengenai pewatas jenis ini", + "wbqc-constraintdiscuss-short": "Pembicaraan", + "wbqc-constraintdiscuss-long": "Halaman pembicaraan mengenai pewatas ini", + "wbqc-cached-generic": "Hasil ini berasal dari memori tembolok sehingga bisa jadi kurang aktual.", + "wbqc-cached-minutes": "Hasil ini berasal dari memori tembolok sehingga bisa jadi kurang aktual paling tidak selama {{PLURAL:$1|1=satu menit|$1 menit}}.", + "wbqc-cached-hours": "Hasil ini berasal dari memori tembolok sehingga bisa jadi kurang aktual paling tidak selama {{PLURAL:$1|1=satu jam|$1 jam}}.", + "wbqc-cached-days": "Hasil ini berasal dari memori tembolok sehingga bisa jadi kurang aktual paling tidak selama {{PLURAL:$1|1=satu hari|$1 hari}}.", + "wbqc-dataValueType-wikibase-entityid": "ID Entitas", + "wbq-subextension-name-wbqc": "Pewatas", + "wbqc-violation-header-parameters": "Parameter:", + "wbqc-violations-group": "Pewatas", + "wbqc-violation-message": "Pemeriksaan pewatas telah menemukan sebuah pelanggaran. Silakan klik pada ikon untuk informasi lebih lanjut.", + "wbqc-violation-message-not-yet-implemented": "Karena alasan teknis, pemeriksaan terhadap pewatas \"$1\" belum bisa dilakukan.", + "wbqc-violation-message-security-reason": "Karena alasan keamanan, pemeriksaan pewatas \"$1\" tidak dapat dilakukan saat ini. Kami sedang berupaya untuk memperbaiki galat ini.", + "wbqc-violation-message-value-needed-of-type": "Atribut dengan pewatas \"$1\" seharusnya memiliki nilai dengan jenis \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Atribut dengan pewatas \"$1\" seharusnya memiliki nilai dengan jenis \"$2\" atau \"$3\".", + "wbqc-violation-message-parameter-needed": "Atribut dengan pewatas \"$1\" seharusnya memiliki parameter \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Atribut dengan pewatas \"$1\" seharusnya memiliki parameter \"$2\", \n\"$3\", dan \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "Entitas yang dituju tidak ditemukan.", + "wbqc-violation-message-value-entity-must-exist": "Entitas nilai tidak ditemukan.", + "wbqc-violation-message-parameter-value": "Parameter \"$1\" seharusnya memiliki nilai tertentu selain \"tanpa nilai\" atau \"nilai tidak diketahui\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parameter \"$1\" seharusnya memiliki nilai tertentu atau \"tidak bernilai\" namun tidak boleh \"nilai tidak diketahui\".", + "wbqc-violation-message-parameter-entity": "Nilai untuk parameter \"$1\" seharusnya berupa entitas dan bukan \"$2\".", + "wbqc-violation-message-parameter-item": "Nilai untuk parameter \"$1\" seharusnya berupa butir dan bukan \"$2\".", + "wbqc-violation-message-parameter-property": "Nilai untuk parameter \"$1\" seharusnya berupa atribut dan bukan \"$2\".", + "wbqc-violation-message-parameter-string": "Nilai untuk parameter \"$1\" seharusnya berupa string dan bukan \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Nilai untuk parameter \"$1\" seharusnya berupa teks dalam satu bahasa dan bukan \"$2\".", + "wbqc-violation-message-parameter-single": "Parameter \"$1\" hanya boleh memiliki satu nilai.", + "wbqc-violation-message-parameter-single-per-language": "Parameter \"$1\" hanya boleh memiilki satu nilai per satu bahasa namun bisa memiliki nilai lebih dari satu untuk $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Parameter \"$1\" seharusnya {{PLURAL:$2|1=merupakan $4.|2=merupakan $4 atau $5.|merupakan salah satu yang di bawah ini:$3}}", + "wbqc-violation-message-parameter-regex": "$1 bukan regular expression yang sah.", + "wbqc-violation-message-sparql-error": "Kueri SPARQL yang dihasilkan memiliki kesalahan.", + "wbqc-violation-message-parameters-error-unknown": "Parameter pewatas ini tidak dapat diimpor.", + "wbqc-violation-message-parameters-error-toolong": "Parameter pewatas ini tidak dapat diimpor karena terlalu panjang.", + "wbqc-violation-message-invalid-scope": "$1 bukan merupakan cakupan jenis pewatas $2 yang sah. Cakupan $3 yang sah untuk jenis pewatas ini adalah {{PLURAL:$3|$5.|2=$5 dan $6.|: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Pranala Commons tidak ditemukan.", + "wbqc-violation-message-commons-link-not-well-formed": "Pranala Commons mengandung karakter yang tidak sah.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Pemeriksaan belum diterapkan untuk ruangnama \"$1\".", + "wbqc-violation-message-conflicts-with-property": "Sebuah entitas seharusnya tidak memiliki pernyataan $1 dan $2 bersama-sama.", + "wbqc-violation-message-conflicts-with-claim": "Sebuah entitas tidak diperbolehkan memiliki pernyataan untuk $1 bersamaan dengan pernyataan $2 bernilai $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entitas $1 dan $3 ditautkan melalui $2 sebagai entitas dari periode yang sama namun nilai terakhir untuk $1 adalah $4 dan nilai paling awal untuk $3 adalah $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entitas $1 dan $3 ditautkan melalui $2 sebagai entitas dari periode yang sama namun nilai terakhir untuk $3 adalah $4 dan nilai paling awal untuk $1 adalah $5.", + "wbqc-violation-message-diff-within-range": "Perbedaan antara $3 ($4) dan $1 ($2) seharusnya bernilai antara $5 dan $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Perbedaan antara $3 ($4) dan $1 ($2) seharusnya bernilai kurang dari $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Perbedaan antara $3 ($4) dan $1 ($2) seharusnya bernilai lebih dari $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Atribut yang digunakan di parameter seharusnya memiliki nilai dengan jenis sama dengan jenis nilai di atribut ini.", + "wbqc-violation-message-format": "Nilai untuk $1 ($2) seharusnya sesuai dengan ekspresi reguler $3.", + "wbqc-violation-message-format-clarification": "Nilai untuk $1 ($2) seharusnya sesuai dengan \"$4\"(ekspresi reguler: $3).", + "wbqc-violation-message-inverse": "$1 juga seharusnya memiliki pernyataan yang sebaliknya yaitu $2 dengan nilai $3.", + "wbqc-violation-message-item": "Sebuah entitas dengan $1 seharusnya memiliki {{PLURAL:$3|0=pernyataan $2.|1=pernyataan $2 $5.|pernyataan $2 dengan salah satu nilai:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Pernyataan $1 ini seharusnya disertai penjelas $2.", + "wbqc-violation-message-multi-value": "Atribut ini seharusnya memiliki lebih dari satu nilai.", + "wbqc-violation-message-multi-value-separators": "Atribut ini seharusnya memiliki lebih dari satu nilai dengan {{PLURAL:$2|1=penjelas $4 yang sama.|beberapa penjelas yang sama untuk atribut ini: $3}}", + "wbqc-violation-message-one-of": "$1 seharusnya memiliki nilai {{PLURAL:$2|1=$4.|2=$4 atau $5.|salah satu yang di bawah ini:$3}}", + "wbqc-violation-message-qualifier": "Atribut ini sebaiknya hanya digunakan sebagai penjelas.", + "wbqc-violation-message-no-qualifiers": "Pernyataan $1 sebaiknya tidak memiliki pewatas.", + "wbqc-violation-message-qualifiers": "$2 bukan penjelas yang sah untuk $1. Penjelas yang sah untuk $1 adalah {{PLURAL:$3|1=$5.|2=$5 dan $6.|sebagai berikut:$4}}", + "wbqc-violation-message-range-parameters-needed": "Atribut dengan jenis nilai \"$1\" dengan pewatas \"$4\" seharusnya disertai parameter \"$2\" dan \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Nilai untuk titik waktu paling awal dan paling akhir harus sama-sama memiliki satuan \"tahun\" atau sama-sama tidak memiliki satuan \"tahun\" tidak bisa salah satu saja. Perhitungan satuan tahun terhadap bulan, hari, jam, dst. tidak bisa menghasilkan nilai yang rapi dengan adanya tahun kabisat.", + "wbqc-violation-message-range-parameters-same": "Nilai awal ($1) dan akhir ($2) tidak boleh sama.", + "wbqc-violation-message-range-quantity-closed": "Nilai untuk $1 ($2) harus bernilai antara $3 dan $4.", + "wbqc-violation-message-range-quantity-leftopen": "Nilai untuk $1 ($2) harus kurang dari $3.", + "wbqc-violation-message-range-quantity-rightopen": "Nilai untuk $1 ($2) harus lebih dari $3.", + "wbqc-violation-message-range-time-closed": "Nilai untuk $1 ($2) harus bernilai antara $3 dan $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Nilai untuk $1 ($2) harus berada di masa depan namun sebelum $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Nilai untuk $1 ($2) harus berada di masa lalu namun setelah $3.", + "wbqc-violation-message-range-time-leftopen": "Nilai untuk $1 ($2) harus berada sebelum $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Nilai untuk $1 ($2) tidak bisa berada di masa depan.", + "wbqc-violation-message-range-time-rightopen": "Nilai untuk $1 ($2) harus berada setelah $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Nilai untuk $1 ($2) tidak bisa berada di masa lalu.", + "wbqc-violation-message-single-value": "Atribut ini sebaiknya hanya memiliki satu nilai.", + "wbqc-violation-message-single-value-separators": "Atribut ini sebaiknya hanya memiliki satu nilai dengan penjelas {{PLURAL:$2|1=$4.|berikut: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Atribut ini seharusnya memiliki satu nilai dengan \"peringkat utama\". Mohon pilih salah satu.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Atribut ini seharusnya memiliki satu nilai dengan \"peringkat utama\" dan {{PLURAL:$2|1=penjelas $4.|penjelas: $3}}.", + "wbqc-violation-message-single-best-value-multi-preferred": "Atribut ini seharusnya memiliki hanya satu nilai dengan \"peringkat utama\".", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Atribut ini seharusnya memiliki hanya satu nilai dengan {{PLURAL:$2|1=penjelas $4.|penjelas: $3}}", + "wbqc-violation-message-symmetric": "$1 juga harus memiliki pernyataan $2 $3 yang serupa.", + "wbqc-violation-message-type-instance": "$2 jika memakai atribut $1 harus memiliki {{PLURAL:$3|1=nilai $5|2=nilai $5 atau $6|\"adalah\" bernilai salah satu}} atau paling tidak {{PLURAL:$3|1=subkelas di bawahnya sebagai nilai \"adalah\".|2=subkelas di bawahnya sebagai nilai \"adalah\".|subkelas dari yang berikut ini: $4}}", + "wbqc-violation-message-type-subclass": "$2 jika memakai atribut $1 harus merupakan subkelas {{PLURAL:$3|1=dari $5.|2=dari $5 atau $6.|dari salah satu di bawah ini: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "$2 jika memakai atribut $1 harus memiliki {{PLURAL:$3|1=nilai $5|2=nilai $5 atau $6|\"adalah\" atau \"subkelas dari\" bernilai salah satu}} atau paling tidak {{PLURAL:$3|1=subkelas di bawahnya sebagai nilai \"adalah\" atau \"subkelas dari\".|2=subkelas di bawah keduanya sebagai nilai \"adalah\" atau \"subkelas dari\".|di bawah dari yang berikut ini: $4}}", + "wbqc-violation-message-valueType-instance": "Nilai $2 tidak cocok dengan $1. Nilai dari pernyataan $1 hanya boleh entitas yang memiliki nilai \"adalah\" {{PLURAL:$3|1=$5|2=$5 atau $6|salah satu}} atau {{PLURAL:$3|1=subkelasnya.|2=subkelas salah satunya.|subkelas salah satu dari yang berikut: $4}}", + "wbqc-violation-message-valueType-subclass": "Nilai $2 tidak cocok dengan $1. Nilai dari pernyataan $1 hanya boleh entitas subkelas dari {{PLURAL:$3|1=$5|2=$5 atau $6|salah satu}} atau {{PLURAL:$3|1=subkelasnya.|2=subkelas salah satunya.|subkelas salah satu dari yang berikut: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Nilai $2 tidak cocok dengan $1. Nilai dari pernyataan $1 hanya boleh entitas subkelas dari atau yang memiliki nilai \"adalah\" {{PLURAL:$3|1=$5|2=$5 atau $6|salah satu}} atau {{PLURAL:$3|1=subkelasnya.|2=subkelas salah satunya.|subkelas salah satu dari yang berikut: $4}}", + "wbqc-violation-message-target-required-claim": "$1 juga membutuhkan {{PLURAL:$3|0=atribut $2.|1=atribut $2 dengan nilai $5.|atribut $2 dengan nilai: $4}}", + "wbqc-violation-message-unique-value": "Nilai atribut ini seharusnya tidak ada di butir lain. Nilai atribut ini saat ini ada di butir berikut: {{PLURAL:$1|1=$3.|2=$3; $4.|$2}}", + "wbqc-violation-message-valueOnly": "Atribut ini seharusnya hanya digunakan pada nilai utama suatu pernyataan, tidak pada penjelas atau referensi.", + "wbqc-violation-message-reference": "Atribut ini seharusnya hanya digunakan pada rujukan dan tidak pada nilai utama atau penjelas suatu pernyataan.", + "wbqc-violation-message-noBounds": "Nilai untuk $1 seharusnya tidak memiliki batas atas atau bawah.", + "wbqc-violation-message-units-none": "Nilai untuk $1 tidak diperbolehkan memiliki satuan.", + "wbqc-violation-message-units": "Nilai untuk $1 seharusnya memiliki satuan {{PLURAL:$2|1=$4.|2=$4 atau $5.|salah satu dari yang berikut: $3}}", + "wbqc-violation-message-units-or-none": "Nilai untuk $1 seharusnya memiliki satuan {{PLURAL:$2|1=$4|2=$4 atau $5|yang berikut ini}} atau {{PLURAL:$2|1=tidak sama sekali.|2=tidak sama sekali.|tidak sama sekali: $3}}", + "wbqc-violation-message-entityType": "Atribut $1 seharusnya tidak digunakan pada entitas jenis ini. Atribut $1 hanya bisa digunakan pada jenis entitas {{PLURAL:$2|1=$4.|2=$4 dan $5.|: $3}}", + "wbqc-violation-message-none-of": "Nilai untuk atribut $1 seharusnya bukan {{PLURAL:$2|1=$4.|2=$4 atau $5.|termasuk:$3}}", + "wbqc-violation-message-integer": "Nilai untuk $1 seharusnya berupa bilangan bulat (integer) sedangkan $2 sebagian adalah pecahan atau bilangan desimal.", + "wbqc-violation-message-integer-bounds": "Nilai untuk $1 seharusnya berupa bilangan bulat sedangkan batas atas atau bawah $2 sebagian adalah pecahan atau bilangan desimal.", + "wbqc-violation-message-citationNeeded": "Pernyataan $1 sebaiknya memiliki paling tidak satu rujukan.", + "wbqc-violation-message-language": "Pernyataan untuk $1 seharusnya hanya terdapat pada Leksem dengan {{PLURAL:$2|1=bahasa $4.|2=bahasa $4 atau $5.|salah satu di antara bahasa berikut: $3}}", + "wbqc-violation-message-label-lacking": "Entitas dengan pernyataan untuk $1 seharusnya juga punya label paling tidak dalam {{PLURAL:$2|1=bahasa $4.|salah satu di antara bahasa-bahasa berikut: $3}}", + "wbqc-violation-message-property-scope": "Atribut $1 seharusnya tidak digunakan di sini ($2) dan hanya digunakan di {{PLURAL:$3|$5.|: $4}}", + "wbqc-violation-message-exception": "Entitas ini mendapat pengecualian khusus terhadap pewatas. Pengecualian tersebut telah ditandai." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ilo.json b/dist/extensions/WikibaseQualityConstraints/i18n/ilo.json new file mode 100644 index 000000000..4617483a3 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ilo.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Lam-ang" + ] + }, + "wbqc-violation-message-units-none": "Ti pateg para iti $1 ket nasken nga awanan iti yunit." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/io.json b/dist/extensions/WikibaseQualityConstraints/i18n/io.json new file mode 100644 index 000000000..e10eac4df --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/io.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Joao Xavier" + ] + }, + "wbqc-constraintreport-result-table-header-status": "Stando", + "wbqc-constraintreport-no-parameter": "nulo", + "wbqc-violation-header-parameters": "Parametri:", + "wbqc-violations-group": "Restrikti" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/is.json b/dist/extensions/WikibaseQualityConstraints/i18n/is.json new file mode 100644 index 000000000..739c07ffc --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/is.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "Sveinn í Felli" + ] + }, + "wbqc-constraintreport-form-submit-label": "Athuga", + "wbqc-constraintreport-result-headline": "Niðurstaða fyrir", + "wbqc-constraintreport-status-exception": "Frávik", + "wbqc-constraintreport-status-todo": "Geralistinn", + "wbqc-constraintreport-status-deprecated": "Úrelt", + "wbqc-constraintreport-status-warning": "Aðvörun", + "wbqc-constraintreport-result-table-header-status": "Staða", + "wbqc-constraintreport-result-table-header-constraint": "Hömlur", + "wbqc-constraintreport-no-parameter": "ekkert", + "wbqc-issues-short": "Vandamál", + "wbqc-constrainttypehelp-short": "Hjálp", + "wbq-subextension-name-wbqc": "Hömlur", + "wbqc-violation-header-parameters": "Viðföng:", + "wbqc-violations-group": "Hömlur" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/it.json b/dist/extensions/WikibaseQualityConstraints/i18n/it.json new file mode 100644 index 000000000..156395dd9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/it.json @@ -0,0 +1,123 @@ +{ + "@metadata": { + "authors": [ + "Alexmar983", + "Beta16", + "Dansita", + "Lucas2", + "Macofe", + "Ontsed", + "Sakretsu", + "Sarah Bernabei", + "Segaz3", + "ValterVB", + "Horcrux92" + ] + }, + "wbqc-constraintreport": "Controllo vincoli", + "wbqc-desc": "Controlla i vincoli sia sugli elementi che sulle proprietà e visualizza i risultati in una pagina speciale", + "wbqc-constraintreport-explanation-part-one": "Questa pagina speciale esegue la verifica dei vincoli per qualsiasi entità desiderata. Le entità sono recuperate dal sistema in tempo reale, perciò ogni violazione del vincolo che risolvi sarà immediatamente rimossa da questa lista.", + "wbqc-constraintreport-explanation-part-two": "I vincoli sono analizzati dalle dichiarazioni nelle proprietà ogni volta che queste sono modificate, solitamente nel giro di pochi minuti.", + "wbqc-constraintreport-form-section": "Controlla i vincoli per l'entità", + "wbqc-constraintreport-form-submit-label": "Controlla", + "wbqc-constraintreport-form-entityid-label": "ID entità:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx o Pxx", + "wbqc-constraintreport-result-headline": "Risultato per", + "wbqc-constraintreport-invalid-entity-id": "Entità ID non valida.", + "wbqc-constraintreport-not-existent-entity": "L'entità non esiste!", + "wbqc-constraintreport-empty-result": "Non ci sono vincoli definiti su questa entità.", + "wbqc-constraintreport-status-violation": "Violazione", + "wbqc-constraintreport-status-compliance": "Conforme", + "wbqc-constraintreport-status-exception": "Eccezione", + "wbqc-constraintreport-status-todo": "Da fare", + "wbqc-constraintreport-status-bad-parameters": "Parametri incorretti", + "wbqc-constraintreport-status-suggestion": "Suggerimento", + "wbqc-constraintreport-result-table-header-status": "Stato", + "wbqc-constraintreport-result-table-header-property": "Proprietà", + "wbqc-constraintreport-result-table-header-message": "Messaggio", + "wbqc-constraintreport-result-table-header-constraint": "Vincolo", + "wbqc-constraintreport-result-link-to-claim": "vai all'asserzione", + "wbqc-constraintreport-result-link-to-constraint": "vai al vincolo", + "wbqc-constraintreport-no-parameter": "nessuno", + "wbqc-potentialissues-short": "Problemi potenziali", + "wbqc-potentialissues-long": "Questa dichiarazione ha alcuni potenziali problemi.", + "wbqc-suggestions-short": "Suggerimenti", + "wbqc-badparameters-short": "Parametri incorretti", + "wbqc-constrainttypehelp-short": "Aiuto", + "wbqc-constrainttypehelp-long": "Pagina di aiuto per questo tipo di vincolo", + "wbqc-constraintdiscuss-short": "Discuti", + "wbqc-constraintdiscuss-long": "Pagina di discussione su questo vincolo", + "wbqc-cached-minutes": "Questo risultato è memorizzato nella cache e potrebbe non essere aggiornato da {{PLURAL:$1|1=un minuto|$1 minuti}}.", + "wbqc-cached-hours": "Questo risultato è memorizzato nella cache e potrebbe non essere aggiornato da {{PLURAL:$1|1=un'ora|$1 ore}}.", + "wbqc-cached-days": "Questo risultato è memorizzato nella cache e potrebbe non essere aggiornato da {{PLURAL:$1|1=un giorno|$1 giorni}}.", + "wbqc-dataValueType-wikibase-entityid": "ID entità", + "wbq-subextension-name-wbqc": "Vincoli", + "wbqc-violation-header-parameters": "Parametri:", + "wbqc-violations-group": "Vincoli", + "wbqc-violation-message": "Il controllo del vincolo ha rilevato una violazione. Si prega di fare clic sull'icona per ulteriori informazioni.", + "wbqc-violation-message-not-yet-implemented": "Per motivi tecnici, il controllo per il vincolo di \"$1\" non è ancora stato implementato.", + "wbqc-violation-message-security-reason": "Per motivi di sicurezza, il controllo per il vincolo di \"$1\" non è possibile al momento. Stiamo lavorando a una soluzione.", + "wbqc-violation-message-value-needed-of-type": "Proprietà con vincolo \"$1\" devono avere valori di tipo \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Proprietà con vincolo \"$1\" devono avere valori di tipo \"$2\" o \"$3\".", + "wbqc-violation-message-parameter-needed": "Proprietà con il vincolo \"$1\" necessitano di un parametro \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Proprietà con vincolo \"$1\" necessitano di parametri \"$2\", \"$3\" e \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "L'entità di destinazione deve esistere.", + "wbqc-violation-message-value-entity-must-exist": "Il valore dell'entità deve esistere.", + "wbqc-violation-message-parameter-value": "Il parametro \"$1\" deve avere un valore personalizzato, no \"nessun valore\" o \"valore sconosciuto\".", + "wbqc-violation-message-parameter-entity": "Il valore per il parametro \"$1\" deve essere un'entità, no \"$2\".", + "wbqc-violation-message-parameter-item": "Il valore per il parametro \"$1\" deve essere un'elemento, no \"$2\".", + "wbqc-violation-message-parameter-string": "Il valore per il parametro \"$1\" deve essere una stringa, no \"$2\".", + "wbqc-violation-message-parameter-single": "Il parametro \"$1\" deve avere solo un singolo valore.", + "wbqc-violation-message-parameter-oneof": "Il parametro \"$1\" deve essere {{PLURAL:$2|1=$4.|2=$4 o $5.|uno dei seguenti:$3}}", + "wbqc-violation-message-parameter-regex": "$1 non è un'espressione regolare valida.", + "wbqc-violation-message-commons-link-no-existent": "Il collegamento a Commons dovrebbe esistere.", + "wbqc-violation-message-commons-link-not-well-formed": "Il collegamento a Commons dovrebbe essere ben formato.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Il controllo per il namespace \"$1\" non è stato ancora implementato.", + "wbqc-violation-message-conflicts-with-property": "Un'entità non dovrebbe avere dichiarazioni sia per $1 che per $2.", + "wbqc-violation-message-conflicts-with-claim": "Un'entità non dovrebbe avere una dichiarazione per $1 se c'è una dichiarazione $2 con valore $3.", + "wbqc-violation-message-diff-within-range": "La differenza tra $3 ($4) e $1 ($2) dovrebbe essere compresa tra $5 e $6.", + "wbqc-violation-message-diff-within-range-leftopen": "La differenza tra $3 ($4) e $1 ($2) non dovrebbe essere superiore a $5.", + "wbqc-violation-message-diff-within-range-rightopen": "La differenza tra $3 ($4) e $1 ($2) non dovrebbe essere inferiore a $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "La proprietà definita nei parametri deve avere un valore dello stesso tipo di questa proprietà.", + "wbqc-violation-message-format": "Il valore per $1 ($2) dovrebbe corrispondere all'espressione regolare $3.", + "wbqc-violation-message-format-clarification": "Il valore per $1 ($2) dovrebbe corrispondere a \"$4\" (espressione regolare: $3).", + "wbqc-violation-message-inverse": "$1 dovrebbe avere anche la dichiarazione inversa $2 $3.", + "wbqc-violation-message-item": "Un'entità con $1 dovrebbe avere anche {{PLURAL:$3|0=una dichiarazione $2.|1=una dichiarazione $2 $5.|una dichiarazione per $2 con uno dei seguenti valori:$4}}", + "wbqc-violation-message-mandatory-qualifier": "A questa dichiarazione $1 manca il qualificatore $2.", + "wbqc-violation-message-multi-value": "Questa proprietà dovrebbe contenere valori multipli.", + "wbqc-violation-message-one-of": "Il valore per $1 deve essere {{PLURAL:$2|1=$4.|2=$4 o $5.|uno dei seguenti:$3}}", + "wbqc-violation-message-qualifier": "La proprietà dovrebbe essere usata solo come qualificatore.", + "wbqc-violation-message-no-qualifiers": "Le dichiarazioni $1 non dovrebbero avere alcun qualificatore.", + "wbqc-violation-message-qualifiers": "$2 non è un qualificatore valido per $1 – {{PLURAL:$3|1=l'unico qualificatore valido è $5.|2=gli unici qualificatori validi sono $5 e $6.|gli unici qualificatori validi sono:$4}}", + "wbqc-violation-message-range-parameters-needed": "Proprietà con valori di tipo \"$1\" con vincolo \"$4\" necessitano di parametri \"$2\" e \"$3\".", + "wbqc-violation-message-range-parameters-same": "L'inizio ($1) e la fine ($2) di un intervallo non dovrebbe essere lo stesso.", + "wbqc-violation-message-range-quantity-closed": "Il valore per $1 ($2) dovrebbe essere compreso tra $3 e $4.", + "wbqc-violation-message-range-quantity-leftopen": "Il valore per $1 ($2) non dovrebbe essere superiore a $3.", + "wbqc-violation-message-range-quantity-rightopen": "Il valore per $1 ($2) non dovrebbe essere inferiore a $3.", + "wbqc-violation-message-range-time-closed": "Il valore per $1 ($2) dovrebbe essere compreso tra $3 e $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Il valore per $1 ($2) dovrebbe essere nel futuro, ma non successivo al $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Il valore per $1 ($2) dovrebbe essere nel passato, ma non precedente al $3.", + "wbqc-violation-message-range-time-leftopen": "Il valore per $1 ($2) non dovrebbe essere successivo a $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Il valore per $1 ($2) non dovrebbe essere nel futuro.", + "wbqc-violation-message-range-time-rightopen": "Il valore per $1 ($2) non dovrebbe essere precedente a $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Il valore per $1 ($2) non dovrebbe essere nel passato.", + "wbqc-violation-message-single-value": "Questa proprietà dovrebbe contenere solo un singolo valore.", + "wbqc-violation-message-single-best-value-no-preferred": "Questa proprietà dovrebbe contenere un unico valore \"migliore\". Degli attuali valori multipli, uno dovrebbe essere classificato come \"preferito\".", + "wbqc-violation-message-single-best-value-multi-preferred": "Questa proprietà dovrebbe contenere un unico valore \"migliore\". Non ci dovrebbe essere più di un valore classificato \"preferito\".", + "wbqc-violation-message-symmetric": "$1 dovrebbe avere anche la dichiarazione simmetrica $2 $3.", + "wbqc-violation-message-type-instance": "Entità che usano la proprietà $1 dovrebbero essere istanza di {{PLURAL:$3|1=$5|2=$5 o $6|una delle seguenti classi}} (o di {{PLURAL:$3|1=una delle sue sottoclassi|2=una loro sottoclasse|una delle loro sottoclassi}}), ma $2 attualmente {{PLURAL:$3|1=non lo è.|2=non lo è.|non lo è: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entità che usano la proprietà $1 dovrebbero essere istanza o sottoclasse di {{PLURAL:$3|1=$5|2=$5 o $6|una delle seguenti classi}} (o di {{PLURAL:$3|1=una delle sue sottoclassi|2=una loro sottoclasse|una delle loro sottoclassi}}), ma $2 attualmente {{PLURAL:$3|1=non lo è.|2=non lo è.|non lo è: $4}}", + "wbqc-violation-message-valueType-instance": "I valori della dichiarazione $1 dovrebbero essere istanza di {{PLURAL:$3|1=$5|2=$5 o $6|una delle seguenti classi}} (o di {{PLURAL:$3|1=una sua sottoclasse|2=una loro sottoclasse|una delle loro sottoclassi}}), ma $2 attualmente {{PLURAL:$3|1=non lo è.|2=non lo è.|non lo è: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "I valori della dichiarazione $1 dovrebbero essere istanza o sottoclasse di {{PLURAL:$3|1=$5|2=$5 o $6|una delle seguenti classi}} (o di {{PLURAL:$3|1=una sua sottoclasse|2=una loro sottoclasse|una delle loro sottoclassi}}), ma $2 attualmente {{PLURAL:$3|1=non lo è.|2=non lo è.|non lo è: $4}}", + "wbqc-violation-message-unique-value": "Il valore di questa proprietà non dovrebbe essere presente in nessun altro elemento, ma è presente anche {{PLURAL:$1|1=in $3.|2=in $3 e $4.|nei seguenti elementi: $2}}", + "wbqc-violation-message-reference": "La proprietà deve essere utilizzata solo nei riferimenti, non per il valore principale di una dichiarazione o per un qualificatore.", + "wbqc-violation-message-noBounds": "Valori per $1 non dovrebbero avere alcun limite", + "wbqc-violation-message-units-none": "Il valore di $1 non dovrebbe avere un'unità.", + "wbqc-violation-message-units": "Il valore per $1 deve avere {{PLURAL:$2|1=l'unità $4.|2=l'unità $4 o $5.|una delle seguenti unità:$3}}", + "wbqc-violation-message-units-or-none": "Il valore per $1 deve avere {{PLURAL:$2|1=l'unità $4.|2=l'unità $4 o $5.|una delle seguenti unità:$3}} o essere {{PLURAL:$2|1=adimensionale.|2=adimensionale.|adimensionale: $3}}", + "wbqc-violation-message-none-of": "Il valore per $1 non dovrebbe essere {{PLURAL:$2|1=$4.|2=$4 o $5.|uno dei seguenti:$3}}", + "wbqc-violation-message-integer": "I valori per $1 dovrebbero essere interi, ma $2 ha una parte frazionaria.", + "wbqc-violation-message-integer-bounds": "I valori per $1 dovrebbero essere interi, ma i limiti di $2 hanno una parte frazionaria.", + "wbqc-violation-message-citationNeeded": "Le dichiarazioni per $1 dovrebbero avere almeno un riferimento.", + "wbqc-violation-message-label-lacking": "Entità con dichiarazioni per $1 dovrebbero avere un'etichetta almeno in {{PLURAL:$2|1=$4.|una delle seguenti lingue: $3}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ja.json b/dist/extensions/WikibaseQualityConstraints/i18n/ja.json new file mode 100644 index 000000000..37f65256f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ja.json @@ -0,0 +1,144 @@ +{ + "@metadata": { + "authors": [ + "Afaz", + "Kkairri", + "Otokoume", + "Shirayuki", + "Sujiniku" + ] + }, + "wbqc-constraintreport": "制約チェック", + "wbqc-desc": "項目およびプロパティの制約をチェックし、結果を特別ページに表示", + "wbqc-constraintreport-explanation-part-one": "この特別ページでは、任意のエンティティに制約チェックを行えます。エンティティは稼働中のシステムから取得されているため、制約違反を修正した場合はこの一覧から即座に除去されます。", + "wbqc-constraintreport-explanation-part-two": "文が編集されるたびにプロパティ制約はチェックされます。これは通常、数分以内に実行されます。", + "wbqc-constraintreport-form-section": "制約チェックの実行", + "wbqc-constraintreport-form-submit-label": "実行", + "wbqc-constraintreport-form-entityid-label": "エンティティIDを入力", + "wbqc-constraintreport-form-entityid-placeholder": "QxxまたはPxx", + "wbqc-constraintreport-result-headline": "結果表示:", + "wbqc-constraintreport-invalid-entity-id": "無効なエンティティIDです。", + "wbqc-constraintreport-not-existent-entity": "エンティティが存在しません。", + "wbqc-constraintreport-empty-result": "このエンティティには制約が定義されていません。", + "wbqc-constraintreport-status-violation": "違反", + "wbqc-constraintreport-status-compliance": "適合", + "wbqc-constraintreport-status-exception": "例外", + "wbqc-constraintreport-status-todo": "チェック予定", + "wbqc-constraintreport-status-bad-parameters": "無効なパラメーター", + "wbqc-constraintreport-status-deprecated": "非推奨ランク", + "wbqc-constraintreport-status-warning": "警告", + "wbqc-constraintreport-status-suggestion": "提案", + "wbqc-constraintreport-status-not-in-scope": "チェックせず", + "wbqc-constraintreport-result-table-header-status": "状態", + "wbqc-constraintreport-result-table-header-property": "プロパティ", + "wbqc-constraintreport-result-table-header-message": "メッセージ", + "wbqc-constraintreport-result-table-header-constraint": "制約", + "wbqc-constraintreport-result-link-to-claim": "この主張に移動", + "wbqc-constraintreport-result-link-to-constraint": "この制約に移動", + "wbqc-constraintreport-no-parameter": "なし", + "wbqc-issues-short": "問題点", + "wbqc-issues-long": "この文には問題点が含まれています", + "wbqc-potentialissues-short": "問題の可能性", + "wbqc-potentialissues-long": "この文には問題が含まれている可能性があります", + "wbqc-suggestions-short": "提案", + "wbqc-suggestions-long": "この文を改善できる提案があります", + "wbqc-badparameters-short": "無効なパラメーター", + "wbqc-badparameters-long": "この制約の文には、有効でないパラメーターが設定されています。", + "wbqc-parameterissues-short": "高次の問題点", + "wbqc-parameterissues-long": "プロパティ制約の定義での問題点です。この文自体に対してではありません。", + "wbqc-constrainttypehelp-short": "ヘルプ", + "wbqc-constrainttypehelp-long": "この制約のヘルプページ", + "wbqc-constraintdiscuss-short": "議論", + "wbqc-constraintdiscuss-long": "この制約についての議論ページ", + "wbqc-cached-generic": "この結果はキャッシュされたもので、最新の状態ではありません。", + "wbqc-cached-minutes": "この結果はキャッシュされたもので、最新の状態ではありません(最大{{PLURAL:$1|$1分}})。", + "wbqc-cached-hours": "この結果はキャッシュされたもので、最新の状態ではありません(最大{{PLURAL:$1|$1時間}})。", + "wbqc-cached-days": "この結果はキャッシュされたもので、最新の状態ではありません(最大{{PLURAL:$1|$1日}})。", + "wbqc-dataValueType-wikibase-entityid": "エンティティID", + "wbq-subextension-name-wbqc": "制約", + "wbqc-violation-header-parameters": "パラメーター:", + "wbqc-violations-group": "制約", + "wbqc-violation-message": "プロパティ制約に違反しています。詳細はアイコンをクリックしてください。", + "wbqc-violation-message-not-yet-implemented": "技術的な理由から、制約「$1」のチェックはまだ実装されていません。", + "wbqc-violation-message-security-reason": "セキュリティ上の理由から、現時点では制約「$1」をチェックできません。解決に向けて取り組んでいるところです。", + "wbqc-violation-message-value-needed-of-type": "プロパティ制約「$1」をもつプロパティの値にはデータ型「$2」が必要です。", + "wbqc-violation-message-value-needed-of-types-2": "プロパティ制約「$1」をもつプロパティの値にはデータ型「$2」か「$3」が必要です。", + "wbqc-violation-message-parameter-needed": "プロパティ制約「$1」をもつプロパティにはパラメーター「$2」が必要です。", + "wbqc-violation-message-parameters-needed-3": "プロパティ制約「$1」をもつプロパティにはパラメーター「$2」、「$3」、「$4」が必要です。", + "wbqc-violation-message-target-entity-must-exist": "対象のエンティティが存在する必要があります。", + "wbqc-violation-message-value-entity-must-exist": "値のエンティティが存在する必要があります。", + "wbqc-violation-message-parameter-value": "パラメーター「$1」はカスタム値でなければなりません。「値なし」、「不明な値」は無効です。", + "wbqc-violation-message-parameter-value-or-novalue": "パラメーター「$1」はカスタム値か「値なし」でなくてはなりません。「不明な値」は無効です。", + "wbqc-violation-message-parameter-entity": "パラメーター「$1」の値は、「$2」ではなく、エンティティでなければなりません。", + "wbqc-violation-message-parameter-item": "パラメーター「$1」の値は、「$2」ではなく、項目でなければなりません。", + "wbqc-violation-message-parameter-property": "パラメーター「$1」の値は、「$2」ではなく、プロパティでなければなりません。", + "wbqc-violation-message-parameter-string": "パラメーター「$1」の値は、「$2」ではなく、文字列でなければなりません。", + "wbqc-violation-message-parameter-monolingualtext": "パラメーター「$1」の値は、「$2」ではなく、単一言語テキストでなければなりません。", + "wbqc-violation-message-parameter-single": "パラメーター「$1」は単一値でなければなりません。", + "wbqc-violation-message-parameter-single-per-language": "パラメーター「$1」には言語ごとに単一の値でなければなりませんが、$2 ($3)には複数の値が存在します。", + "wbqc-violation-message-parameter-oneof": "パラメーター「$1」は{{PLURAL:$2|1=$4でなければなりません。|2=$4か$5でなければなりません|以下のいずれかでなければなりません。$3}}", + "wbqc-violation-message-parameter-regex": "$1は無効な正規表現です。", + "wbqc-violation-message-sparql-error": "SPARQLクエリでエラーが発生しました。", + "wbqc-violation-message-parameters-error-unknown": "この制約のパラメーターをインポートできませんでした。", + "wbqc-violation-message-parameters-error-toolong": "この制約のパラメーターは、長すぎるためインポートできませんでした。", + "wbqc-violation-message-invalid-scope": "$1は制約「$2」が扱う範囲内にありません。有効な{{PLURAL:$3|範囲}}は{{PLURAL:$3|1=$5です。|2=$5と$6です。|以下のとおりです。$4}}", + "wbqc-violation-message-commons-link-no-existent": "コモンズへのリンクは実在しなければなりません。", + "wbqc-violation-message-commons-link-not-well-formed": "コモンズへのリンクは整形式でなければなりません。", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "名前空間「$1」は実装されていません。間違っていないか確認してください。", + "wbqc-violation-message-conflicts-with-property": "エンティティは$1と$2の文を両方もつことはできません。", + "wbqc-violation-message-conflicts-with-claim": "エンティティが「$2:$3」の文をもつ場合、$1の文を使用してはなりません。", + "wbqc-violation-message-contemporary-subject-earlier": "2つのエンティティ「$1」と「$3」は、プロパティ「$2」によって紐づけされているため同時代のものである必要がありますが、「$1」の最も早い終了日が「$4」、「$3」の最も遅い開始日は「$5」となっています。", + "wbqc-violation-message-contemporary-value-earlier": "2つのエンティティ「$1」と「$3」は、プロパティ「$2」によって紐づけされているため同時代のものである必要がありますが、「$3」の最も早い終了日が「$4」、「$1」の最も遅い開始日は「$5」となっています。", + "wbqc-violation-message-diff-within-range": "$3($4)と$1($2)の間は、$5から$6の範囲でなければなりません。", + "wbqc-violation-message-diff-within-range-leftopen": "$3($4)と$1($2)の間は、$5よりも大きくなければなりません。", + "wbqc-violation-message-diff-within-range-rightopen": "$3($4)と$1($2)の間は、$5よりも小さくなければなりません。", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "パラメーター内に定義されているプロパティは、このプロパティと同じ型の値を持たなければなりません。", + "wbqc-violation-message-format": "$1の値($2)は次の正規表現に一致しなければなりません。$3", + "wbqc-violation-message-format-clarification": "$1の値($2)は「$4」に一致しなければなりません(正規表現:$3)。", + "wbqc-violation-message-inverse": "$1は逆関係の文「$2:$3」をもつ必要があります。", + "wbqc-violation-message-item": "$1を持つエンティティは{{PLURAL:$3|0=$2の文も必要です。|1=「$2:$5」である文も必要です。|$2の値が以下のいずれかである文も必要です。$4}}", + "wbqc-violation-message-mandatory-qualifier": "$1は修飾子として$2が必須です。", + "wbqc-violation-message-multi-value": "このプロパティには複数の値を設定する必要があります。", + "wbqc-violation-message-one-of": "$1の値は{{PLURAL:$2|1=$4でなければなりません。|2=$4か$5でなければなりません。|以下のいずれかでなければなりません。$3}}", + "wbqc-violation-message-qualifier": "このプロパティは修飾子にのみ使用できます。", + "wbqc-violation-message-no-qualifiers": "$1は修飾子を使用しません。", + "wbqc-violation-message-qualifiers": "$2は$1には無効な修飾子です。 – 有効な{{PLURAL:$3|1=修飾子は$5です。|2=修飾子は$5か$6です。|修飾子は以下のとおり。$4}}", + "wbqc-violation-message-range-parameters-needed": "値のデータ型が「$1」でプロパティ制約「$4」をもつプロパティはパラメーター「$2」と「$3」が必要です。", + "wbqc-violation-message-range-parameters-one-year": "時間の単位はどちらも「年」にそろえるか、あるいはどちらも「年」を使用しないようにする必要があります。(うるう年があるので他の時間単位に正確に変換することができないため)", + "wbqc-violation-message-range-parameters-same": "範囲の開始点($1)と終了点($2)が同じであってはなりません。", + "wbqc-violation-message-range-quantity-closed": "$1の値($2)は、$3から$4の範囲でなければなりません。", + "wbqc-violation-message-range-quantity-leftopen": "$1の値($2)は、$3を超えてはなりません。", + "wbqc-violation-message-range-quantity-rightopen": "$1の値($2)は、$3を下回ってはなりません。", + "wbqc-violation-message-range-time-closed": "$1の値($2)は、$3から$4の範囲でなければなりません。", + "wbqc-violation-message-range-time-closed-leftnow": "$1の値($2)は、$3より未来になってはなりません。", + "wbqc-violation-message-range-time-closed-rightnow": "$1の値($2)は、$3より過去になってはなりません。", + "wbqc-violation-message-range-time-leftopen": "$1の値($2)は、$3を超えてはなりません。", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1の値($2)は未来の値であってはなりません。", + "wbqc-violation-message-range-time-rightopen": "$1の値($2)は、$3より前になってはなりません。", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1の値($2)は過去の値であってはなりません。", + "wbqc-violation-message-single-value": "このプロパティには複数の値を設定してはなりません。", + "wbqc-violation-message-single-best-value-no-preferred": "このプロパティには「最良値」が含まれている必要があります。現在の複数の値の中で、いずれか1つを「推奨」ランクに設定する必要があります。", + "wbqc-violation-message-single-best-value-multi-preferred": "このプロパティには「最良値」が含まれている必要があります。「推奨」ランクをただ1つの値にだけ設定する必要があります。", + "wbqc-violation-message-symmetric": "$1は対称関係の文「$2:$3」をもつ必要があります。", + "wbqc-violation-message-type-instance": "$1を使うエンティティは{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})のインスタンスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-type-subclass": "$1を使うエンティティは{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})の下位クラスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-type-instanceOrSubclass": "$1を使うエンティティは{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})のインスタンスまたは下位クラスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-valueType-instance": "$1の値は{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})のインスタンスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-valueType-subclass": "$1の値は{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})の下位クラスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "$1の値は{{PLURAL:$3|1=$5|2=$5または$6|以下のクラスのいずれか}}(または{{PLURAL:$3|その下位クラス}})のインスタンスまたは下位クラスでなければなりませんが、$2は現在{{PLURAL:$3|1=そうなっていません。|2=そうなっていません。|そうなっていません。$4}}", + "wbqc-violation-message-target-required-claim": "$1には{{PLURAL:$3|0=$2の文が必要です。|1=「$2:$5」である文が必要です。|$2の値が以下のいずれかである文が必要です。$4}}", + "wbqc-violation-message-unique-value": "このプロパティの値は他の項目の値と重複してはなりませんが、{{PLURAL:$1|1=$3に同じ値があります。|2=$3と$4に同じ値があります。|以下の項目にに同じ値があります。$2}}", + "wbqc-violation-message-valueOnly": "このプロパティは文の値にのみ使用できます。修飾子や情報源には使用できません。", + "wbqc-violation-message-reference": "このプロパティは情報源にのみ使用できます。文の値や修飾子には使用できません。", + "wbqc-violation-message-noBounds": "$1の値は増減の幅をもちません。", + "wbqc-violation-message-units-none": "$1の値は単位を使用しません。", + "wbqc-violation-message-units": "$1の値は{{PLURAL:$2|1=$4を単位として使用します。|2=$4または$5を単位として使用します。|以下のいずれかの単位を使用します。 $3}}", + "wbqc-violation-message-units-or-none": "$1の値は単位をしないか、または{{PLURAL:$2|1=$4を単位として使用します。|2=$4または$5を単位として使用します。|以下のいずれかの単位を使用します。$3}}", + "wbqc-violation-message-entityType": "$1はこの種類のエンティティに使用してはなりません。有効な{{PLURAL:$2|1=エンティティの種類は$4です。|2=エンティティの種類は$4または$5です。|エンティティの種類は以下になります。$3}}", + "wbqc-violation-message-none-of": "$1の値は{{PLURAL:$2|1=$4であってはなりません。|2=$4または$5であってはなりません。|以下のいずれかであってはなりません。$3}}", + "wbqc-violation-message-integer": "$1の値は整数でなければいけませんが、$2は小数です。", + "wbqc-violation-message-integer-bounds": "$1の値は整数でなければいけませんが、$2の範囲指定が小数です。", + "wbqc-violation-message-citationNeeded": "$1の文には少なくとも1つの出典が必要です。", + "wbqc-violation-message-property-scope": "このプロパティ「$1」は、この場所($2)では使えません。このプロパティが使えるのは、{{PLURAL:$3|$5だけです。|次の場所だけです: $4}}", + "wbqc-violation-message-exception": "このエンティティは、この制約の既知の例外です。" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ka.json b/dist/extensions/WikibaseQualityConstraints/i18n/ka.json new file mode 100644 index 000000000..ab1ade64e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ka.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "MIKHEIL" + ] + }, + "wbqc-constraintreport-status-warning": "გაფრთხილება" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/kab.json b/dist/extensions/WikibaseQualityConstraints/i18n/kab.json new file mode 100644 index 000000000..7904f59e8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/kab.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Belkacem77" + ] + }, + "wbqc-constraintreport-no-parameter": "ulac" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/kea.json b/dist/extensions/WikibaseQualityConstraints/i18n/kea.json new file mode 100644 index 000000000..6eb38e35c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/kea.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Quintino Lopes Castro Tavares", + "Waldyrious" + ] + }, + "wbqc-constraintreport-result-table-header-property": "Propredadi", + "wbqc-constraintreport-result-table-header-message": "Mensajen" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/kn.json b/dist/extensions/WikibaseQualityConstraints/i18n/kn.json new file mode 100644 index 000000000..19ad8e559 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/kn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Anoop rao", + "~aanzx", + "Anzx" + ] + }, + "wbqc-potentialissues-short": "ಸಂಭಾವ್ಯ ಸಮಸ್ಯೆಗಳು", + "wbqc-potentialissues-long": "ಈ ಹೇಳಿಕೆಯು ಕೆಲವು ಸಂಭಾವ್ಯ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ko.json b/dist/extensions/WikibaseQualityConstraints/i18n/ko.json new file mode 100644 index 000000000..042dbef47 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ko.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "Alex00728", + "Doyoon1995", + "Kwj2772", + "LiteHell", + "Ykhwong", + "아라", + "Dr1t jg" + ] + }, + "wbqc-constraintreport": "제약 보고서", + "wbqc-constraintreport-explanation-part-one": "이 특수 문서는 당신이 원하는 모든 개체에 대한 제약을 검사합니다. 개체는 라이브 시스템으로부터 불러오므로, 제약 위반사항을 고치는 대로 이 목록에서 제거됩니다.", + "wbqc-constraintreport-explanation-part-two": "제약 조건은 일반적으로 몇 분 내에 편집할 때마다 해당 명제에서 속성이 분석됨.", + "wbqc-constraintreport-form-section": "개체의 제약 사항을 검사", + "wbqc-constraintreport-form-submit-label": "검사", + "wbqc-constraintreport-form-entityid-label": "개체 ID:", + "wbqc-constraintreport-result-headline": "다음 개체에 대한 결과:", + "wbqc-constraintreport-invalid-entity-id": "개체 ID가 올바르지 않습니다.", + "wbqc-constraintreport-not-existent-entity": "개체가 존재하지 않습니다.", + "wbqc-constraintreport-empty-result": "이 개체에 정의된 제약이 없습니다.", + "wbqc-constraintreport-status-violation": "위반", + "wbqc-constraintreport-status-exception": "예외", + "wbqc-constraintreport-status-todo": "검사 불가", + "wbqc-constraintreport-status-bad-parameters": "잘못된 변수", + "wbqc-constraintreport-status-deprecated": "사용되지 않음", + "wbqc-constraintreport-status-warning": "경고", + "wbqc-constraintreport-status-suggestion": "제안", + "wbqc-constraintreport-result-table-header-status": "상태", + "wbqc-constraintreport-result-table-header-property": "속성", + "wbqc-constraintreport-result-table-header-message": "메시지", + "wbqc-constraintreport-result-table-header-constraint": "제약 조건", + "wbqc-constraintreport-no-parameter": "없음", + "wbqc-issues-short": "이슈", + "wbqc-issues-long": "이 문에 일부 문제가 있습니다.", + "wbqc-potentialissues-short": "잠재적인 문제", + "wbqc-potentialissues-long": "이 문에는 잠재적인 문제가 있습니다.", + "wbqc-suggestions-short": "제안", + "wbqc-badparameters-short": "잘못된 변수", + "wbqc-constrainttypehelp-short": "도움말", + "wbqc-constraintdiscuss-short": "토론", + "wbqc-cached-generic": "이 결과는 캐시되어 있으므로 최신화되어 있지 않을 수 있습니다.", + "wbqc-cached-minutes": "이 결과는 캐시되어 있으므로 최대 {{PLURAL:$1|1=1분|$1분}} 전까지 최신화되어 있지 않을 수 있습니다.", + "wbqc-cached-hours": "이 결과는 캐시 처리되며 최대 {{PLURAL:$1|1=한 시간|$1시간}} 동안은 최신화되어 있지 않을 수 있습니다.", + "wbqc-cached-days": "이 결과는 캐시 처리되며 최대 {{PLURAL:$1|1=하루|$1일}} 동안은 최신화되어 있지 않을 수 있습니다.", + "wbqc-dataValueType-wikibase-entityid": "개체 ID", + "wbq-subextension-name-wbqc": "제약 조건", + "wbqc-violation-header-parameters": "변수:", + "wbqc-violations-group": "제약 조건", + "wbqc-violation-message-not-yet-implemented": "기술적 이유로, \"$1\" 제약에 대한 검사는 도입되지 않았습니다.", + "wbqc-violation-message-security-reason": "보안상의 이유로, \"$1\" 제약에 대한 검사는 현재 불가능합니다. 개발자들이 해결책을 찾기 위해 작업 중입니다.", + "wbqc-violation-message-parameter-value": "\"$1\" 변수는 \"없는 값\"이나 \"알 수 없는 값\"이 아닌 사용자 지정 값이 있어야 합니다.", + "wbqc-violation-message-parameter-value-or-novalue": "\"$1\" 변수는 \"알 수 없는 값\"이 아닌 사용자 지정 값이 있어야 합니다.", + "wbqc-violation-message-parameter-entity": "\"$1\" 변수의 값은 \"$2\"이(가) 아닌 엔티티여야 합니다.", + "wbqc-violation-message-parameter-item": "\"$1\" 변수의 값은 \"$2\"이(가) 아닌 항목이어야 합니다.", + "wbqc-violation-message-parameter-property": "\"$1\" 변수의 값은 \"$2\"이(가) 아닌 속성이어야 합니다.", + "wbqc-violation-message-parameter-string": "변수 \"$1\"의 값은 \"$2\"이(가) 아닌 문자열이어야 합니다.", + "wbqc-violation-message-parameter-single": "\"$1\" 변수는 하나의 값만 있어야 합니다.", + "wbqc-violation-message-parameter-single-per-language": "\"$1\" 변수는 언어마다 오직 하나의 값만 있어야 하지만 $2($3)에 여러 개의 값이 있습니다.", + "wbqc-violation-message-parameter-oneof": "\"$1\" 변수는 {{PLURAL:$2|1=$4여야 합니다.|2=$4 또는 $5여야 합니다.|다음 중 하나여야 합니다:$3}}", + "wbqc-violation-message-parameter-regex": "$1은(는) 유효한 정규 표현식이 아닙니다.", + "wbqc-violation-message-sparql-error": "SPARQL 쿼리에서 오류가 발생했습니다.", + "wbqc-violation-message-commons-link-no-existent": "공용 링크가 존재해야 합니다.", + "wbqc-violation-message-commons-link-not-well-formed": "공용 링크가 올바르게 구성되어야 합니다.", + "wbqc-violation-message-diff-within-range": "$3 ($4)와 $1 ($2) 사이의 차이는 $5와 $6 사이여야 합니다.", + "wbqc-violation-message-diff-within-range-leftopen": "$3 ($4)와 $1 ($2) 사이의 차이는 $5 ((−∞; $5])을(를) 넘을 수 없습니다.", + "wbqc-violation-message-diff-within-range-rightopen": "$3 ($4)와 $1 ($2) 사이의 차이는 $5 ([$5; ∞)) 만큼이어야 합니다.", + "wbqc-violation-message-format": "$1 ($2)의 값은 $3 정규식과 일치해야 합니다.", + "wbqc-violation-message-format-clarification": "$1 ($2)의 값은 \"$4\"와(과) 일치해야 합니다. (정규식: $3)", + "wbqc-violation-message-inverse": "$1 항목 또한 $2 $3 반대 속성을 포함하는 것이 좋습니다.", + "wbqc-violation-message-item": "$1의 항목은 {{PLURAL:$3|0=$2 문을 포함하는 것이 좋습니다.|1=$2 $5 문을 포함하는 것이 좋습니다.|$2의 문에 다음의 값 중 하나를 포함하는 것이 좋습니다:$4}}", + "wbqc-violation-message-multi-value": "이 속성은 여러 개의 값을 포함해야 합니다.", + "wbqc-violation-message-one-of": "$1의 값은 {{PLURAL:$2|1=$4여야 합니다.|2=$4 또는 $5여야 합니다.|다음 중 하나여야 합니다:$3}}", + "wbqc-violation-message-range-quantity-closed": "$1 ($2)의 값은 $3와 $4 사이여야 합니다.", + "wbqc-violation-message-range-quantity-leftopen": "$1 ($2)의 값은 $3 ((−∞; $3])을(를) 넘을 수 없습니다.", + "wbqc-violation-message-range-quantity-rightopen": "$1 ($2)의 값은 $3 ([$3; ∞)) 만큼은 있어야 합니다.", + "wbqc-violation-message-range-time-closed": "$1 ($2)의 값은 $3와 $4 사이여야 합니다.", + "wbqc-violation-message-range-time-leftopen": "$1 ($2)의 값은 $3 이후가 될 수 없습니다.", + "wbqc-violation-message-range-time-rightopen": "$1 ($2)의 값은 $3 이전이 될 수 없습니다.", + "wbqc-violation-message-single-value": "이 속성은 하나의 값만 포함해야 합니다.", + "wbqc-violation-message-symmetric": "$1 항목은 대칭이 되는 문 $2 $3도 포함하는 것이 좋습니다.", + "wbqc-violation-message-target-required-claim": "$1 항목은 {{PLURAL:$3|0=$2 문을 포함하는 것이 좋습니다.|1=$2 $5 문을 포함하는 것이 좋습니다.|$2의 문에 다음의 값 중 하나를 포함하는 것이 좋습니다:$4}}", + "wbqc-violation-message-unique-value": "이 속성의 값은 어떠한 항목에도 존재해서는 안 됩니다. {{PLURAL:$1|1=$3|2=$3와 $4|$2 항목들}}에도 존재합니다.", + "wbqc-violation-message-units-none": "$1의 값은 단위를 포함하지 않아야 합니다.", + "wbqc-violation-message-units": "$1의 값은 {{PLURAL:$2|1=$4여야 합니다.|2=$4 또는 $5여야 합니다.|다음 중 하나여야 합니다: $3}}", + "wbqc-violation-message-units-or-none": "$1의 값은 {{PLURAL:$2|1=$4를 단위|2=$4 또는 $5를 단위|다음 중 하나를 단위}}로 하거나 {{PLURAL:$2|1=단위가 없어야 합니다.|2=단위가 없어야 합니다.|단위가 없어야 합니다: $3}}", + "wbqc-violation-message-none-of": "$1의 값은 {{PLURAL:$2|1=$4이(가) 될 수 없습니다.|2=$4 또는 $5이(가) 될 수 없습니다.|다음 중 하나가 될 수 없습니다:$3}}", + "wbqc-violation-message-integer": "$1의 값은 정수여야 하지만 $2에 소수부가 있습니다.", + "wbqc-violation-message-integer-bounds": "$1의 값은 정수여야 하지만 $2의 경계에 소수부가 있습니다.", + "wbqc-violation-message-citationNeeded": "$1의 문은 적어도 하나의 참조를 갖는 것이 좋습니다." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ksh.json b/dist/extensions/WikibaseQualityConstraints/i18n/ksh.json new file mode 100644 index 000000000..5e37a0447 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ksh.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "wbqc-constraintreport": "Bereesch övver Beschrängkonge", + "wbqc-constraintreport-explanation-part-one": "Heh di {{int:specialpage}} pröhv de Beschrängkonge vun jehde Saach, di de wells. De Saache wähde vum lebänndeje Süßtehm met de Dahtebangk jehollt, esu weed och jehde Verläzong vun ene Beschrängkung, wam_mer se doh reparehrt hät, tiräk heh uß de Leß jeschmeße.", + "wbqc-constraintreport-explanation-part-two": "De Beschrängkonge wähde jehde Woch vun de Klaafsigge övver de Eijeschaffte enjelässe. Dröm, wann De doh en Beschrängkong derbei deiht, fott nemmps, udder veränders, kann et en Woch duehre, bes dat heh em Bereesch ens opdouch. Mer ärbeide draan, dat mer di Beschrängkonge en de Behouptonge övver de Eijeschaffte medd enboue, su dat mer aam ldänndeje Süßtehm den de Dahtebangk pröhve künne.", + "wbqc-constraintreport-form-submit-label": "Lohß jonn!", + "wbqc-constraintreport-form-entityid-placeholder": "Qxy/Pxy", + "wbqc-constraintreport-result-headline": "Wat eruß kohm för", + "wbqc-constraintreport-not-existent-entity": "Di Saach jidd_et nit!", + "wbqc-constraintreport-empty-result": "Mer han kein Beschrängkonge för di Saach heh ennjereschdt.", + "wbqc-constraintreport-status-violation": "Verläzong", + "wbqc-constraintreport-status-compliance": "Kütt zepaß", + "wbqc-constraintreport-status-exception": "Ußnahm", + "wbqc-constraintreport-status-todo": "Noch ze donn", + "wbqc-constraintreport-result-table-header-status": "Zohschtand", + "wbqc-constraintreport-result-table-header-constraint": "Beschrängkong", + "wbqc-constraintreport-result-link-to-claim": "jangk op di Behouptong", + "wbqc-constraintreport-result-link-to-constraint": "jangk op di Beschrängkong", + "wbqc-constraintreport-no-parameter": "keine", + "wbq-subextension-name-wbqc": "Beschrängkonge", + "wbqc-violation-header-parameters": "Parramehtere:", + "wbqc-violations-group": "Beschrängkonge", + "wbqc-violation-message": "De Pröhfong hädd_en Verläzong vum Berett för de müjjelesche Wääte jefonge. Op dat Minnibelldsche Kleke brängk Der mih Aanjahbe derzoh.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "För dat Appachtemang „$1“ jidd_et noch keine Pröhvong.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Di Eijeschaff, di en dä Parramehtere faßjelaht es, moß ene Wäät vun dersällve Zoot han, wi heh di Eijeschaff.", + "wbqc-violation-message-multi-value": "Heh di Eijeschaff moß mih wi eijne Wäät han. Et möße alsu zwai udder mih Behoutonge doh sin, di se bruche." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ksw.json b/dist/extensions/WikibaseQualityConstraints/i18n/ksw.json new file mode 100644 index 000000000..4ac1a7979 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ksw.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "SawJaemin" + ] + }, + "wbqc-constrainttypehelp-short": "တၢ်မၤစၢၤ" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ku-latn.json b/dist/extensions/WikibaseQualityConstraints/i18n/ku-latn.json new file mode 100644 index 000000000..8efd906c0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ku-latn.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Bikarhêner", + "Cûndûllah el-Kurdî", + "George Animal", + "Ghybu" + ] + }, + "wbqc-constraintreport-result-headline": "Encama bo", + "wbqc-constraintreport-result-table-header-status": "Rewş", + "wbqc-constrainttypehelp-short": "Alîkarî", + "wbqc-violation-header-parameters": "Parametre:" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ky.json b/dist/extensions/WikibaseQualityConstraints/i18n/ky.json new file mode 100644 index 000000000..4f749afcc --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ky.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Bosogo" + ] + }, + "wbqc-constrainttypehelp-short": "Жардам" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lag.json b/dist/extensions/WikibaseQualityConstraints/i18n/lag.json new file mode 100644 index 000000000..3779872ed --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lag.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Baba Tabita" + ] + }, + "wbqc-constraintreport-no-parameter": "kʉsiina tʉkʉ", + "wbqc-constrainttypehelp-short": "Ʉyaambɨri" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lb.json b/dist/extensions/WikibaseQualityConstraints/i18n/lb.json new file mode 100644 index 000000000..c230117a1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lb.json @@ -0,0 +1,88 @@ +{ + "@metadata": { + "authors": [ + "Les Meloures", + "Robby", + "Soued031", + "Volvox" + ] + }, + "wbqc-constraintreport": "Rapport vun de Limitatiounen", + "wbqc-constraintreport-form-submit-label": "Nokucken", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx oder Pxx", + "wbqc-constraintreport-result-headline": "Resultat fir", + "wbqc-constraintreport-not-existent-entity": "Objet gëtt et net.", + "wbqc-constraintreport-empty-result": "Et gëtt keng Limitatiounen déi fir dësen Objet definéiert sinn.", + "wbqc-constraintreport-status-violation": "Violatioun", + "wbqc-constraintreport-status-compliance": "Konform", + "wbqc-constraintreport-status-exception": "Ausnam", + "wbqc-constraintreport-status-todo": "Nach ze maachen", + "wbqc-constraintreport-status-bad-parameters": "Falsch Parameteren", + "wbqc-constraintreport-status-deprecated": "Net méi aktuell", + "wbqc-constraintreport-status-warning": "Warnung", + "wbqc-constraintreport-status-suggestion": "Virschlag", + "wbqc-constraintreport-status-not-in-scope": "Net am Perimeter", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Eegenschaft", + "wbqc-constraintreport-result-table-header-message": "Message", + "wbqc-constraintreport-result-table-header-constraint": "Limitatioun", + "wbqc-constraintreport-result-link-to-claim": "op d'Behaaptung goen", + "wbqc-constraintreport-result-link-to-constraint": "op d'Limitatioun goen", + "wbqc-constraintreport-no-parameter": "keng", + "wbqc-issues-short": "Problemer", + "wbqc-issues-long": "Dës Deklaratioun huet e puer Problemer.", + "wbqc-potentialissues-short": "Potenziell Problemer", + "wbqc-potentialissues-long": "Dës Deklaratioun huet e puer potentiell Problemer.", + "wbqc-suggestions-short": "Virschléi", + "wbqc-badparameters-short": "Falsch Parameteren", + "wbqc-parameterissues-short": "Komplex Problemer", + "wbqc-constrainttypehelp-short": "Hëllef", + "wbqc-constrainttypehelp-long": "Hëllefssäit fir dësen Typ vu Limitatioun", + "wbqc-constraintdiscuss-short": "Diskutéieren", + "wbqc-constraintdiscuss-long": "Diskussiounssäit iwwer dës Limitatioun", + "wbqc-cached-generic": "Dëst Resultat kënnt aus dem Tëschespäicher a kéint vereelzt sinn.", + "wbqc-cached-minutes": "Dëst Resultat kënnt aus dem Tëschespäicher a ka bis zu {{PLURAL:$1|1=enger MInutt|$1 MInutten}} al sinn.", + "wbqc-cached-hours": "Dëst Resultat kënnt aus dem Tëschespäicher a ka bis zu {{PLURAL:$1|1=enger Stonn|$1 Stonnen}} al sinn.", + "wbqc-cached-days": "Dëst Resultat kënnt aus dem Tëschespäicher a ka bis zu {{PLURAL:$1|1=engem Dag|$1 Deeg}} al sinn.", + "wbqc-dataValueType-wikibase-entityid": "Objets-ID", + "wbq-subextension-name-wbqc": "Limitatiounen", + "wbqc-violation-header-parameters": "Parameteren:", + "wbqc-violations-group": "Limitatiounen", + "wbqc-violation-message-not-yet-implemented": "Aus technesche Grënn gouf d'Nokucke vun der Limitatioun \"$1\" nach net implementéiert.", + "wbqc-violation-message-security-reason": "Aus technesche Grënn ass et net méiglech d'Limitatioun \"$1\" nozekucken. Mir schaffen un enger Léisung.", + "wbqc-violation-message-target-entity-must-exist": "D'Zil-Entitéit muss existéieren.", + "wbqc-violation-message-value-entity-must-exist": "De Wäert vun der Entitéit muss existéieren.", + "wbqc-violation-message-parameter-value": "De Parameter \"$1\" muss e personaliséierte Wäert hunn an net \"kee Wäert\" oder \"onbekannte Wäert\".", + "wbqc-violation-message-parameter-item": "De Wäert fir de Parameter \"$1\" muss en Element sinn, net \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "De Wäert fir de Parameter \"$1\" muss en Text an enger Sprooch sinn, net \"$2\".", + "wbqc-violation-message-parameter-single": "De Parameter \"$1\" muss een eenzege Wäert hunn.", + "wbqc-violation-message-sparql-error": "D'SPARQL Ufro huet zu engem Feeler gefouert.", + "wbqc-violation-message-parameters-error-unknown": "D'Parametere vun dëser Limitatioun konnten net importéiert ginn.", + "wbqc-violation-message-parameters-error-toolong": "D'Parameter vun dëser Limitatioun konnten net importéiert gi wëll se ze laang waren.", + "wbqc-violation-message-commons-link-no-existent": "De Commons Link sollt et ginn.", + "wbqc-violation-message-commons-link-not-well-formed": "De Commons Link soll gutt forméiert sinn.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "D'Nokucke fir den Nummraum \"$1\" ass nach net implementéiert.", + "wbqc-violation-message-conflicts-with-property": "En Objet soll keng Aussoen hu fir esouwuel $1 wéi $2.", + "wbqc-violation-message-diff-within-range-leftopen": "Den Ënnerscheed tëscht $3 ($4) an $1 ($2) soll net méi wéi $5 sinn.", + "wbqc-violation-message-diff-within-range-rightopen": "Den Ënnerscheed tëscht $3 ($4) an $1 ($2) soll net méi kleng wéi $5 sinn.", + "wbqc-violation-message-inverse": "$1 misst och déi ëmgekéiert Ausso $2 $3 hunn.", + "wbqc-violation-message-mandatory-qualifier": "Dëser Ausso iwwer d'Funktioun $1 feelt d'Bestëmmung $2.", + "wbqc-violation-message-multi-value": "Dës Eegenschaft soll méi Wäerter hunn.", + "wbqc-violation-message-qualifier": "D'Eegenschaft däerf nëmmen als Qualificateur benotzt ginn.", + "wbqc-violation-message-range-quantity-closed": "De Wäert fir $1 ($2) soll tëscht $3 an $4 sinn.", + "wbqc-violation-message-range-quantity-leftopen": "De Wäert fir $1 ($2) soll net méi wéi $3 sinn.", + "wbqc-violation-message-range-quantity-rightopen": "De Wäert fir $1 ($2) soll net manner wéi $3 sinn.", + "wbqc-violation-message-range-time-closed": "De Wäert fir $1 ($2) soll tëscht $3 an $4 sinn.", + "wbqc-violation-message-range-time-closed-rightnow": "De Wäert fir $1 ($2) soll an der Vergaangenheet sinn, awer net virum $3.", + "wbqc-violation-message-range-time-leftopen": "De Wäert fir $1 ($2) soll net no $3 sinn.", + "wbqc-violation-message-range-time-leftopen-rightnow": "De Wäert fir $1 ($2) soll net an der Zukunft sinn.", + "wbqc-violation-message-range-time-rightopen": "De Wäert fir $1 ($2) soll net viru(n) $3 sinn.", + "wbqc-violation-message-range-time-rightopen-leftnow": "De Wäert fir $1 ($2) däerf net an der Vergaangenheet sinn.", + "wbqc-violation-message-single-value": "Dës Eegenschaft soll nëmmen een eenzege Wäert hunn.", + "wbqc-violation-message-single-best-value-no-preferred": "Dës Eegenschaft soll nëmmen ee beschte Wäert mat hunn. Vun den aktuelle verschiddene Wäerter soll ee mat 'prioritär Bewäertung' markéiert ginn.", + "wbqc-violation-message-reference": "D'Eegenschaft soll nëmmen a Referenze benotzt ginn an net als Haaptwäert vun enger Ausso oder als Qualificateur.", + "wbqc-violation-message-noBounds": "Wäerter fir $1 solle keng Limitten hunn.", + "wbqc-violation-message-units-none": "De Wäert fir $1 däerf keng Eenheet hunn.", + "wbqc-violation-message-citationNeeded": "Aussoe fir $1 solle mindestens eng Referenz hunn.", + "wbqc-violation-message-property-scope": "D'Eegenschaft $1 soll op dëser Plaz ($2) net benotzt ginn. Déi eenzeg valabel {{PLURAL:$3|Plaz|Plaze}} fir dës Eegenschaft {{PLURAL:$3|ass $5.|sinn: $4.}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lfn.json b/dist/extensions/WikibaseQualityConstraints/i18n/lfn.json new file mode 100644 index 000000000..e0e338f5e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lfn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Mafcadio" + ] + }, + "wbqc-constrainttypehelp-short": "Aida" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lrc.json b/dist/extensions/WikibaseQualityConstraints/i18n/lrc.json new file mode 100644 index 000000000..79e3e3553 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lrc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Mogoeilor" + ] + }, + "wbqc-constraintreport-result-table-header-status": "حال وبال" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lt.json b/dist/extensions/WikibaseQualityConstraints/i18n/lt.json new file mode 100644 index 000000000..1c77031e7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lt.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Eitvys200", + "Nokeoo" + ] + }, + "wbqc-dataValueType-wikibase-entityid": "Objekto ID" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/lv.json b/dist/extensions/WikibaseQualityConstraints/i18n/lv.json new file mode 100644 index 000000000..fb206eccb --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/lv.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Papuass" + ] + }, + "wbqc-constraintreport": "Ierobežotāju ziņojums", + "wbqc-constraintreport-form-entityid-label": "Vienuma ID:", + "wbqc-constraintreport-status-violation": "Pārkāpums", + "wbqc-constraintreport-status-exception": "Izņēmums", + "wbqc-constraintreport-status-bad-parameters": "Nederīgi parametri", + "wbqc-constraintreport-status-deprecated": "Novecojis", + "wbqc-constraintreport-status-warning": "Brīdinājums", + "wbqc-constraintreport-status-suggestion": "Ieteikums", + "wbqc-constraintreport-result-table-header-status": "Statuss", + "wbqc-constraintreport-result-table-header-property": "Īpašība", + "wbqc-constraintreport-result-table-header-message": "Paziņojums", + "wbqc-suggestions-short": "Ieteikumi", + "wbqc-badparameters-short": "Nederīgi parametri", + "wbq-subextension-name-wbqc": "Ierobežojumi", + "wbqc-violation-header-parameters": "Parametri:", + "wbqc-violations-group": "Ierobežojumi", + "wbqc-violation-message-parameter-regex": "$1 nav derīga regulārā izteiksme." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/mk.json b/dist/extensions/WikibaseQualityConstraints/i18n/mk.json new file mode 100644 index 000000000..bfcf1284d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/mk.json @@ -0,0 +1,148 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06", + "Vlad5250", + "Amire80" + ] + }, + "wbqc-constraintreport": "Извештај за услови", + "wbqc-desc": "Ги проверува условите и за предметите и за својствата, па го прикажува исходот на посебна страница", + "wbqc-constraintreport-explanation-part-one": "Оваа службена страница врши проверки на условите врз било која единица што ќе ја укажете. Единиците се преземаат од системот во живо, така што секое несогласување со услов што ќе го поправите ќе биде веднаш отстрането од списокот.", + "wbqc-constraintreport-explanation-part-two": "Условите се расчленуваат од искази на својствата секојпат кога ќе се изменат тие искази, обично во текот на неколку минути.", + "wbqc-constraintreport-form-section": "Провери ги условите на единицата", + "wbqc-constraintreport-form-submit-label": "Провери", + "wbqc-constraintreport-form-entityid-label": "Назнака на единицата:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx или Pxx", + "wbqc-constraintreport-result-headline": "Исход за", + "wbqc-constraintreport-invalid-entity-id": "Неважечка назнака на единица:", + "wbqc-constraintreport-not-existent-entity": "Единицата не постои!", + "wbqc-constraintreport-empty-result": "Нема зададено услови за единицава.", + "wbqc-constraintreport-status-violation": "Нескладност", + "wbqc-constraintreport-status-compliance": "Усогласеност", + "wbqc-constraintreport-status-exception": "Исклучок", + "wbqc-constraintreport-status-todo": "За проверување", + "wbqc-constraintreport-status-bad-parameters": "Неисправни параметри", + "wbqc-constraintreport-status-deprecated": "Застарен", + "wbqc-constraintreport-status-warning": "Предупредување", + "wbqc-constraintreport-status-suggestion": "Предлог", + "wbqc-constraintreport-status-not-in-scope": "Не е во делокруг", + "wbqc-constraintreport-result-table-header-status": "Статус", + "wbqc-constraintreport-result-table-header-property": "Својство", + "wbqc-constraintreport-result-table-header-message": "Порака", + "wbqc-constraintreport-result-table-header-constraint": "Услов", + "wbqc-constraintreport-result-link-to-claim": "оди на тврдењето", + "wbqc-constraintreport-result-link-to-constraint": "оди на условот", + "wbqc-constraintreport-no-parameter": "нема", + "wbqc-issues-short": "Проблеми", + "wbqc-issues-long": "Исказов има извесни проблеми.", + "wbqc-potentialissues-short": "Потенцијални проблеми", + "wbqc-potentialissues-long": "Исказов има извесни потенцијални проблеми.", + "wbqc-suggestions-short": "Предлози", + "wbqc-suggestions-long": "Има некои предлози како да се подобри исказов.", + "wbqc-badparameters-short": "Неисправни параметри", + "wbqc-badparameters-long": "Овој условувачки исказ има извесни неважечки параметри.", + "wbqc-parameterissues-short": "Напредни проблеми", + "wbqc-parameterissues-long": "Овие прашања се проблеми со условни определби на својството, а не со овој исказ.", + "wbqc-constrainttypehelp-short": "Помош", + "wbqc-constrainttypehelp-long": "Помошна страница за овој вид на услов", + "wbqc-constraintdiscuss-short": "Разговор", + "wbqc-constraintdiscuss-long": "Разговорна страница за овој услов", + "wbqc-cached-generic": "Исходот е меѓускладиран и затоа може да е застарен.", + "wbqc-cached-minutes": "Исходот е меѓускладиран и затоа може да е застарен веќе {{PLURAL:$1|1=една минута|$1 минути}}.", + "wbqc-cached-hours": "Исходот е меѓускладиран и затоа може да е застарен веќе {{PLURAL:$1|1=еден час|$1 часа}}.", + "wbqc-cached-days": "Исходот е меѓускладиран и затоа може да е застарен веќе {{PLURAL:$1|1=еден ден|$1 дена}}.", + "wbqc-dataValueType-wikibase-entityid": "Назнака на единицата", + "wbq-subextension-name-wbqc": "Услови", + "wbqc-violation-header-parameters": "Параметри:", + "wbqc-violations-group": "Услови", + "wbqc-violation-message": "Проверката на условите укажува на нескладност. Стиснете на иконата за повеќе информации.", + "wbqc-violation-message-not-yet-implemented": "Од технички причини, проверката на условот „$1“ сè уште не е воведена.", + "wbqc-violation-message-security-reason": "Од безбедносни причини, во моментов не може да се провери условот „$1“. Работиме на решение на проблемот.", + "wbqc-violation-message-value-needed-of-type": "Својствата со условот „$1“ треба да имаат вредност од типот „$2“.", + "wbqc-violation-message-value-needed-of-types-2": "Својствата со условот „$1“ треба да имаат вредност од типот „$2“ или „$3“.", + "wbqc-violation-message-parameter-needed": "Својствата со условот „$1“ имаат потреба од параметар „$2“.", + "wbqc-violation-message-parameters-needed-3": "На својствата со условот „$1“ има требаатпараметрите „$2“, „$3“ и „$4“.", + "wbqc-violation-message-target-entity-must-exist": "Целната единица мора да постои.", + "wbqc-violation-message-value-entity-must-exist": "Единица со вредност мора да постои.", + "wbqc-violation-message-parameter-value": "Параметарот „$1“ мора да има прилагодена вредност, а не „без вредност“ или „непозната вредност“.", + "wbqc-violation-message-parameter-value-or-novalue": "Параметарот „$1“ мора да има прилагодена вредност или „без вредност“, но никогаш „непозната вредност“.", + "wbqc-violation-message-parameter-entity": "Вредноста за параметарот „$1“ мора да биде единица, а не „$2“.", + "wbqc-violation-message-parameter-item": "Вредноста за параметарот „$1“ мора да биде предмет, а не „$2“.", + "wbqc-violation-message-parameter-property": "Вредноста за параметарот „$1“ мора да биде својство, а не „$2“.", + "wbqc-violation-message-parameter-string": "Вредноста за параметарот „$1“ мора да биде низа, а не „$2“.", + "wbqc-violation-message-parameter-monolingualtext": "Вредноста за параметарот „$1“ мора да биде еднојазичен текст, а не „$2“.", + "wbqc-violation-message-parameter-single": "Параметарот „$1“ мора да има само една вредност.", + "wbqc-violation-message-parameter-single-per-language": "Параметарот „$1“ мора да има само една вредност по јазик, туку повеќекратни вредности за $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Параметарот „$1“ мора да биде {{PLURAL:$2|1=$4.|2=или $4 или $5.|еден од следниве: $3}}", + "wbqc-violation-message-parameter-regex": "$1 не претставува важечки регуларен израз.", + "wbqc-violation-message-sparql-error": "Барањето со SPARQL даде грешка.", + "wbqc-violation-message-parameters-error-unknown": "Не можев да ги увезам параметрите на овој услов.", + "wbqc-violation-message-parameters-error-toolong": "Не можев да ги увезам параметрите на овој услов бидејќи се предолги.", + "wbqc-violation-message-invalid-scope": "$1 не претставува важечки делокруг за условниот тип $2; {{PLURAL:$3|единствениот важечки делокруг|единствените важечки делокрузи}} за условниот тип {{PLURAL:$3|е $5.|2=се $5 и $6.|се: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Врската кон Ризницата треба да постои.", + "wbqc-violation-message-commons-link-not-well-formed": "Врската кон Ризницата треба да биде добро срочена.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Проверката на именскиот простор „$1“ сè уште не е воведена.", + "wbqc-violation-message-conflicts-with-property": "Единицата не треба да има искази за $1 и $2.", + "wbqc-violation-message-conflicts-with-claim": "Својството не треба да има исказ за $1 ако воедно има исказ за $2 со вредноста $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Единиците $1 и $3 треба истовремено да се поврзани преку $2, но најновата конечна вредност на $1 е $4, а најраната почетна вредност на $3 е $5.", + "wbqc-violation-message-contemporary-value-earlier": "Единиците $1 и $3 треба истовремено да се поврзани преку $2, но најновата конечна вредност на $3 е $4, а најраната почетна вредност на $1 е $5.", + "wbqc-violation-message-diff-within-range": "Разликата помеѓу $3 ($4) и $1 ($2) треба да изнесува помеѓу $5 и $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Разликата помеѓу $3 ($4) и $1 ($2) не треба да е поголема од $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Разликата помеѓу $3 ($4) и $1 ($2) не треба да е помала од $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Својството определено во параметрите мора да има вредност од ист тип како својството.", + "wbqc-violation-message-format": "Вредноста на својството $1 ($2) треба да одговараат на регуларниот израз $3.", + "wbqc-violation-message-format-clarification": "Вредноста за $1 ($2) треба да одговараат на „$4“ (рег. изр.: $3).", + "wbqc-violation-message-inverse": "$1 треба да го има и обратниот исказ $2 $3.", + "wbqc-violation-message-item": "Единицата со $1 треба да има и {{PLURAL:$3|0=исказ $2.|1=исказ $2 $5.|исказот за $2 со една од следниве вредности: $4}}", + "wbqc-violation-message-mandatory-qualifier": "На овој исказ $1 му недостасува определницата $2.", + "wbqc-violation-message-multi-value": "Ова својство треба да содржи повеќе вредности.", + "wbqc-violation-message-multi-value-separators": "Ова својство треба истовремено да содржи повеќе вредности {{PLURAL:$2|1=$4 определница.|збир определници за својствата: $3}}", + "wbqc-violation-message-one-of": "Вредноста за $1 треба да биде {{PLURAL:$2|1=$4.|2=или $4 или $5.|една од следниве: $3}}", + "wbqc-violation-message-qualifier": "Својството треба да се користи само како определница.", + "wbqc-violation-message-no-qualifiers": "Исказите $1 не треба да имаат определници.", + "wbqc-violation-message-qualifiers": "$2 не претставува важечка определница за $1 — {{PLURAL:$3|1=единствената важечка определница е $5.|2=единствените важечки определници се $5 и $6.|определниците се: $4}}", + "wbqc-violation-message-range-parameters-needed": "Својствата со вредности од типот „$1“ со условот „$4“ треба да ги имаат параметрите „$2“ и „$3“.", + "wbqc-violation-message-range-parameters-one-year": "Обете завршници на временскоединичниот опсег мора да имаат (или обете да немаат) единица „година“ бидејќи годините не можат беззагубно да се претворат во секунди.", + "wbqc-violation-message-range-parameters-same": "Почетокот ($1) и завршницата ($2) на опсегот не смеат да бидат исти.", + "wbqc-violation-message-range-quantity-closed": "Вредноста за $1 ($2) треба да изнесува помеѓу $3 и $4.", + "wbqc-violation-message-range-quantity-leftopen": "Вредноста за $1 ($2) треба да изнесува не повеќе од $3.", + "wbqc-violation-message-range-quantity-rightopen": "Вредноста за $1 ($2) треба да изнесува не помалку од $3.", + "wbqc-violation-message-range-time-closed": "Вредноста за $1 ($2) треба да изнесува помеѓу $3 и $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Вредноста за $1 ($2) треба да биде во иднината, но не по $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Вредноста за $1 ($2) треба дда биде во минатото, но не пред $3.", + "wbqc-violation-message-range-time-leftopen": "Вредноста за $1 ($2) не треба да биде по $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Вредноста за $1 ($2) не треба да биде во иднината.", + "wbqc-violation-message-range-time-rightopen": "Вредноста за $1 ($2) не треба да биде пред $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Вредноста за $1 ($2) не треба да биде во минатото.", + "wbqc-violation-message-single-value": "Ова својство треба да има содржи една вредност.", + "wbqc-violation-message-single-value-separators": "Ова својство треба да содржи само една вредност со {{PLURAL:$2|1=истата $4 определница.|истиот збир определници за својствата: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Ова својство треба да содржи една вредност за „најдобро“. Од повеќето тековни слоеви, еден треба да се означи како „претпочитано“.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ова својство треба да содржи една „најдобра“ вредност со {{PLURAL:$2|1=истата $4 определница.|истиот збир определници: $3}} Од тековните вредности, една треба да е означена како „претпочитана“.", + "wbqc-violation-message-single-best-value-multi-preferred": "Ова својство треба да содржи една вредност за „најдобро“. Не треба да има повеќе од една вредност означена како „претпочитано“.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ова својство треба да содржи една „најдобра“ вредност со {{PLURAL:$2|1=истата $4 определница.|истиот збир определници: $3}} Треба да нема повеќе од една вредност означена како „претопочитана“.", + "wbqc-violation-message-symmetric": "$1 треба да го има и симетричниот исказ $2 $3.", + "wbqc-violation-message-type-instance": "Единиците што го користат својството $1 треба бидат примероци на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-type-subclass": "Единиците што го користат својството $1 треба да бидат поткласи на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Единиците што го користат својството $1 треба да бидат примероци на поткласи на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-valueType-instance": "Вредностите со искази $1 треба да бидат примероци на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-valueType-subclass": "Вредностите со искази $1 треба да се примероци на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Вредностите со искази $1 треба да се примероци на поткласите на {{PLURAL:$3|1=$5|2=$5 или $6|една од следниве класи}} (или {{PLURAL:$3|1=нејзина поткласа|2=нивна поткласа|една од нивните поткласи}}), но $2 тековно {{PLURAL:$3|1=не е.|2=не е.|не е: $4}}", + "wbqc-violation-message-target-required-claim": "$1 треба да има има {{PLURAL:$3|0=исказ $2.|1=исказ $2 $5.|исказ за $2 со една од следниве вредности: $4}}", + "wbqc-violation-message-unique-value": "Вредноста на ова својство не треба да се наоѓа во друго својство, но присутна е во {{PLURAL:$1|1=$3.|2=$3 и $4.|следниве предмети: $2}}", + "wbqc-violation-message-valueOnly": "Ова својство треба да се користи за главната вредност на исказот, а не за определниците и наводите", + "wbqc-violation-message-reference": "Својството треба да се користи само во наводите, а не за главната вредност на исказот или за определница.", + "wbqc-violation-message-noBounds": "Вредностите за $1 не треба да има никакви граници.", + "wbqc-violation-message-units-none": "Вредноста за $1 не треба да има единица.", + "wbqc-violation-message-units": "Вредноста за $1 треба да {{PLURAL:$2|1=ја има единицата $4.|2=ја има единицата $4 или $5.|една од следниве единици: $3}}", + "wbqc-violation-message-units-or-none": "Вредноста за $1 треба да {{PLURAL:$2|1=ја има единицата $4.|2=ја има единицата $4 или $5.|една од следниве единици}} или да {{PLURAL:$2|1=нема единица.|2=нема единица.|нема единица: $3}}", + "wbqc-violation-message-entityType": "Својството $1 не треба да се користи во единица од овој вид. {{PLURAL:$2|1=Единствениот важечки вид е $4.|2=Единствените важечки видови се $4 и $5.|Единствените важечки видови се: $3}}", + "wbqc-violation-message-none-of": "Вредноста за $1 не треба да биде {{PLURAL:$2|1=$4.|2=$4 или $5.|една од следниве: $3}}", + "wbqc-violation-message-integer": "Вредностите за $1 треба да бидат целобројни, но $2 е дробна.", + "wbqc-violation-message-integer-bounds": "Вредностите за $1 треба да бидат целобројни, но границите на $2 имаат дробен дел.", + "wbqc-violation-message-citationNeeded": "Исказите за $1 треба да имаат барем еден навод.", + "wbqc-violation-message-language": "Исказите за $1 треба да бидат само на оние лексеми чиј зададен јазик е {{PLURAL:$2|1=$4.|2=или $4 или $5.|еден од следниве: $3}}", + "wbqc-violation-message-label-lacking": "Единиците со искази за $1 треба да имаат и натписи {{PLURAL:$2|1=на барем $4 јазик.|барем на некој од следниве јазици: $3}}", + "wbqc-violation-message-property-scope": "Својството $1 не треба да се користи на ова место ($2). {{PLURAL:$3|Единственото соодветно место|Единствените соодветни места}} за него {{PLURAL:$3|е $5.|се: $4}}", + "wbqc-violation-message-exception": "Оваа единица е познат исклучок од условов и е означена како таква." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/mr.json b/dist/extensions/WikibaseQualityConstraints/i18n/mr.json new file mode 100644 index 000000000..589c4612e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/mr.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Rupalichinchure" + ] + }, + "wbqc-constraintreport-status-bad-parameters": "खराब पॅरामिटर्स" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ms-arab.json b/dist/extensions/WikibaseQualityConstraints/i18n/ms-arab.json new file mode 100644 index 000000000..fd80ae29e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ms-arab.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Tofeiku" + ] + }, + "wbqc-constraintreport": "لاڤورن ککڠن", + "wbqc-constraintreport-form-section": "ڤريقسا ککڠن اونتوق اينتيتي", + "wbqc-constraintreport-result-table-header-constraint": "ککڠن", + "wbqc-badparameters-long": "کڽاتاءن ککڠن اين ممڤوڽاءي ببراڤ ڤاراميتر يڠ تيدق صح.", + "wbqc-constrainttypehelp-long": "لامن بنتوان باݢي جنيس ککڠن اين", + "wbqc-constraintdiscuss-long": "لامن ڤربينچڠن تنتڠ ککڠن اين", + "wbq-subextension-name-wbqc": "ککڠن", + "wbqc-violations-group": "ککڠن", + "wbqc-violation-message-parameters-error-unknown": "ڤاراميتر ککڠن اين تيدق داڤت دأيمڤورت." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/my.json b/dist/extensions/WikibaseQualityConstraints/i18n/my.json new file mode 100644 index 000000000..afabfa46d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/my.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Dr Lotus Black" + ] + }, + "wbqc-constraintreport-status-warning": "သတိပေးချက်", + "wbqc-constraintreport-status-suggestion": "အကြံပေးမှု", + "wbqc-constraintreport-result-table-header-status": "အခြေအနေ", + "wbqc-suggestions-short": "အကြံပေးမှုများ", + "wbqc-constrainttypehelp-short": "အကူအညီ" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/nb.json b/dist/extensions/WikibaseQualityConstraints/i18n/nb.json new file mode 100644 index 000000000..b05b2ab79 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/nb.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "Danmichaelo", + "Imre Eilertsen", + "Jeblad", + "Jon Harald Søby", + "Kingu", + "Amire80" + ] + }, + "wbqc-constraintreport": "Begrensningsrapporter", + "wbqc-desc": "Sjekker begrensningene på både elementene og egenskapene og viser resultatene på en spesialside", + "wbqc-constraintreport-explanation-part-one": "Denne spesialsiden utfører begrensningssjekk på den entitetstypen du ønsker. Entitetene hentes fra det aktive systemet, så hvert begrensningsbrudd du fikser blir umiddelbart fjernet fra denne listen.", + "wbqc-constraintreport-explanation-part-two": "Begrensningene tolkes fra påstander i egenskapene hver gang de påstandene redigeres, vanligvis i løpet av noen minutter.", + "wbqc-constraintreport-form-section": "Sjekk begrensinger for entitet", + "wbqc-constraintreport-form-submit-label": "Sjekk", + "wbqc-constraintreport-form-entityid-label": "Entitetens ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx eller Pxx", + "wbqc-constraintreport-result-headline": "Resultat for", + "wbqc-constraintreport-invalid-entity-id": "Ugyldig ID for entiteten.", + "wbqc-constraintreport-not-existent-entity": "Entiteten finnes ikke.", + "wbqc-constraintreport-empty-result": "Ingen begrensninger er definert for denne entiteten.", + "wbqc-constraintreport-status-violation": "Brudd", + "wbqc-constraintreport-status-compliance": "Samsvar", + "wbqc-constraintreport-status-exception": "Unntak", + "wbqc-constraintreport-status-todo": "Å gjøre", + "wbqc-constraintreport-status-bad-parameters": "Ugyldige parametre", + "wbqc-constraintreport-status-deprecated": "Foreldet", + "wbqc-constraintreport-status-warning": "Advarsel", + "wbqc-constraintreport-status-suggestion": "Forslag", + "wbqc-constraintreport-status-not-in-scope": "Ikke omfattet", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Egenskap", + "wbqc-constraintreport-result-table-header-message": "Melding", + "wbqc-constraintreport-result-table-header-constraint": "Begrensing", + "wbqc-constraintreport-result-link-to-claim": "gå til påstand", + "wbqc-constraintreport-result-link-to-constraint": "gå til begrensing", + "wbqc-constraintreport-no-parameter": "ingen", + "wbqc-issues-short": "Problemer", + "wbqc-issues-long": "Denne påstanden har noen problemer.", + "wbqc-potentialissues-short": "Mulige problemer", + "wbqc-potentialissues-long": "Dette utsagnet har mulige problemer.", + "wbqc-suggestions-short": "Forslag", + "wbqc-suggestions-long": "Det er noen forslag for forbedring av denne påstanden.", + "wbqc-badparameters-short": "Ugyldige parametre", + "wbqc-badparameters-long": "Denne begrensningspåstanden har noen ugyldige parametre.", + "wbqc-parameterissues-short": "Avanserte problemer", + "wbqc-parameterissues-long": "Disse problemene gjelder begrensningsdefinisjonen på egenskapen, ikke denne påstanden.", + "wbqc-constrainttypehelp-short": "Hjelp", + "wbqc-constrainttypehelp-long": "Hjelpeside for denne begrensningstypen", + "wbqc-constraintdiscuss-short": "Diskuter", + "wbqc-constraintdiscuss-long": "Diskusjonsside for denne begrensningen", + "wbqc-cached-generic": "Dette resultatet er mellomlagret og kan være utdatert.", + "wbqc-cached-minutes": "Dette resultatet er mellomlagret og kan være utdatert med opptil {{PLURAL:$1|ett minutt|$1 minutter}}.", + "wbqc-cached-hours": "Dette resultatet er mellomlagret og kan være utdatert med opptil {{PLURAL:$1|én time|$1 timer}}.", + "wbqc-cached-days": "Dette resultatet er mellomlagret og kan være utdatert med opptil {{PLURAL:$1|én dag|$1 dager}}.", + "wbqc-dataValueType-wikibase-entityid": "Entitets-ID", + "wbq-subextension-name-wbqc": "Begrensing", + "wbqc-violation-header-parameters": "Parametre:", + "wbqc-violations-group": "Begrensing", + "wbqc-violation-message": "Begrensningssjekken har pekt ut et brudd. Klikk på ikonet for mer informasjon.", + "wbqc-violation-message-not-yet-implemented": "Av tekniske grunner har ikke sjekken for begrensningen «$1» blitt implementert ennå.", + "wbqc-violation-message-security-reason": "Av sikkerehtsårsaker er det ikke mulig å sjekke begrensningen «$1» for øyeblikket. Vi jobber med å fikse det.", + "wbqc-violation-message-value-needed-of-type": "Egenskapen med begrensningen «$1» må ha en verdier av type «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Egenskaper med begrensningen «$1» må ha en verdier av type «$2» eller «$3».", + "wbqc-violation-message-parameter-needed": "Egenskaper med begrensningen «$1» trenger en parameter «$2».", + "wbqc-violation-message-parameters-needed-3": "Egenskaper med begrensningen «$1» trenger parametre «$2», «$3» og «$4».", + "wbqc-violation-message-target-entity-must-exist": "Målentiteten må eksistere.", + "wbqc-violation-message-value-entity-must-exist": "Verdien må være en eksisterende entitet.", + "wbqc-violation-message-parameter-value": "Parameteren «$1» må ha en bestemt verdi, ikke \"ingen verdi\" eller \"ukjent verdi\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parameteren «$1» kan ha en bestemt verdi eller \"ingen verdi\", men ikke \"ukjent verdi\".", + "wbqc-violation-message-parameter-entity": "Verdien til parameteren «$1» må være en entitet, ikke «$2».", + "wbqc-violation-message-parameter-item": "Verdien til parameteren «$1» må være et element, ikke «$2».", + "wbqc-violation-message-parameter-property": "Verdien til parameteren «$1» må være en egenskap, ikke «$2».", + "wbqc-violation-message-parameter-string": "Verdien til parameteren «$1» må være en streng, ikke «$2».", + "wbqc-violation-message-parameter-monolingualtext": "Verdien for parameteren «$1» må være en enspråklig tekst, ikke «$2».", + "wbqc-violation-message-parameter-single": "Verdien til parameteren «$1» skal kun bestå av én enkelt verdi.", + "wbqc-violation-message-parameter-single-per-language": "Parameteren «$1» må bare ha én verdi per språk, men har flere verdier for $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Parameteren «$1» må være {{PLURAL:$2|1=$4.|2=enten $4 eller $5.|én av følgende:$3}}", + "wbqc-violation-message-parameter-regex": "$1 er ikke et gyldig regulært uttrykk.", + "wbqc-violation-message-sparql-error": "SPARQL-spørringen feilet.", + "wbqc-violation-message-parameters-error-unknown": "Parameterne i denne begrensningen kunne ikke importeres.", + "wbqc-violation-message-parameters-error-toolong": "Parameterne til denne begrensningen kunne ikke importeres fordi de er for lange.", + "wbqc-violation-message-invalid-scope": "$1 omfattes ikke av begrensningstypen $2; {{PLURAL:$3|det}} eneste som omfattes av denne begrensningstypen er {{PLURAL:$3|$5|2=$5 og $6|$4}}", + "wbqc-violation-message-commons-link-no-existent": "Lenka til Commons bør eksistere.", + "wbqc-violation-message-commons-link-not-well-formed": "Lenka til Commons bør være en gyldig URL.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Sjekken for navnerommet «$1» er ikke implementert ennå.", + "wbqc-violation-message-conflicts-with-property": "En entitet skal aldri ha utsagn for både $1 og $2.", + "wbqc-violation-message-conflicts-with-claim": "En entitet skal ikke ha et utsagn for $1 hvis den også har et utsagn for $2 med verdi $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entitetene $1 og $3 bør være samtidige for å lenkes via $2, men den siste sluttdatoen for $1 er $4 og den tidligste startverdien for $3 er $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entitetene $1 og $3 bør være samtidige for å lenkes via $2, men den siste sluttverdien for $3 er $4 og den tidligste startverdien for $1 er $5.", + "wbqc-violation-message-diff-within-range": "Forskjellen mellom $3 ($4) og $1 ($2) bør være mellom $5 og $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Forskjellen mellom $3 ($4) og $1 ($2) bør ikke overstige $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Forskjellen mellom $3 ($4) og $1 ($2) bør ikke være mindre enn $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Egenskapen som defineres i parameterne må ha en verdi av samme type som denne egenskapen.", + "wbqc-violation-message-format": "Verdien for $1 ($2) bør matche det regulære uttrykket $3.", + "wbqc-violation-message-format-clarification": "Verdien for $1 ($2) bør matche «$4» (regulært uttrykk: $3).", + "wbqc-violation-message-inverse": "$1 bør også ha det inverse utsagnet $2 $3.", + "wbqc-violation-message-item": "En entitet med $1 bør også ha {{PLURAL:$3|0=et $2-utsagn.|1=utsagnet $2 $5.|et $2-utsagn med en av følgende verdier: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Dette $1-utsagnet mangler en $2-kvalifikator.", + "wbqc-violation-message-multi-value": "Denne egenskapen bør inneholde flere verdier.", + "wbqc-violation-message-multi-value-separators": "Denne egenskaper bør inneholde flere verdier med samme {{PLURAL:$2|kvalifikator $4|sett av kvalifikatorer for disse egenskapene: $3}}", + "wbqc-violation-message-one-of": "Verdien for $1 skal være {{PLURAL:$2|1=$4.|2=enten $4 eller $5.|en av følgende:$3}}", + "wbqc-violation-message-qualifier": "Egenskapen skal kun brukes som kvalifikator.", + "wbqc-violation-message-no-qualifiers": "$1-utsagn skal ikke ha kvalifikatorer.", + "wbqc-violation-message-qualifiers": "$2 er ikke en gyldig kvalifikator for $1 – {{PLURAL:$3|1=den eneste gyldige kvalifikatoren er $5.|2=de eneste gyldige kvalifikatorene er $5 og $6.|de eneste gyldige kvalifikatorene er:$4}}", + "wbqc-violation-message-range-parameters-needed": "Egenskaper med verdier av typen «$1» med begresningen «$4» trenger parametrene «$2» og «$3».", + "wbqc-violation-message-range-parameters-one-year": "Endepunkter for et tidsenhetsintervall må enten ha enheten «year» begge steder eller ingen steder, fordi år ikke kan konverteres til sekunder uten datatap.", + "wbqc-violation-message-range-parameters-same": "Start- ($1) og sluttpunktet ($2) til et intervall kan ikke være det samme.", + "wbqc-violation-message-range-quantity-closed": "Verdien for $1 ($2) bør være mellom $3 og $4.", + "wbqc-violation-message-range-quantity-leftopen": "Verdien for $1 ($2) bør ikke overstige $3.", + "wbqc-violation-message-range-quantity-rightopen": "Verdien for $1 ($2) bør ikke være mindre enn $3.", + "wbqc-violation-message-range-time-closed": "Verdien for $1 ($2) bør ligge mellom $3 og $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Verdien for $1 ($2) bør være i framtida, men ikke etter $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Verdien for $1 ($2) bør være i fortida, men ikke før $3.", + "wbqc-violation-message-range-time-leftopen": "Verdien for $1 ($2) bør ikke være etter $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Verdien for $1 ($2) bør ikke være i framtida.", + "wbqc-violation-message-range-time-rightopen": "Verdien for $1 ($2) bør ikke være før $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Verdien for $1 ($2) bør ikke være i fortida.", + "wbqc-violation-message-single-value": "Denne egenskapen bør bare ha én enkel verdi.", + "wbqc-violation-message-single-value-separators": "Denne genskapen bør kun ha én enkel verdi med samme {{PLURAL:$2|kvalifikator $4|sett av kvalifikatorer for disse egenskapene: $3}}.", + "wbqc-violation-message-single-best-value-no-preferred": "Denne egenskapen bør inneholde én enkelt verdi som er «best». Av de nåværende verdiene bør kun én ha rangering som «foretrukket».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Denne egenskapen bør inneholde én enkel verdi som er «best» med samme {{PLURAL:$2|kvalifikator $4|sett av kvalifikatorer for disse egenskapene: $3}}. Av de nåværende verdiene bør bare én være merket som «foretrukket».", + "wbqc-violation-message-single-best-value-multi-preferred": "Denne egenskapen bør inneholde én enkel verdi som er «best». Det bør ikke være mer enn én verdi med rangeringen «foretrukket».", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Denne egenskapen bør inneholde én enkel verdi som er «best» med samme {{PLURAL:$2|kvalifikator $4|sett av kvalifikatorer for disse egenskapene: $3}}. Det bør ikke være mer enn én verdi med rangering «foretrukket».", + "wbqc-violation-message-symmetric": "$1 bør også ha det symmetriske utsagnet $2 $3.", + "wbqc-violation-message-type-instance": "Entiteter som bruker egenskapen $1 bør være forekomster av {{PLURAL:$3|1=$5|2=$5 eller $6|en av følgende klasser: $4}} (eller {{PLURAL:$3|en underklasse}}), men $2 er ikke det.", + "wbqc-violation-message-type-subclass": "Elementer som bruker egenskapen $1 bør være underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av følgende klasser: $4}} (eller {{PLURAL:$3|en underklasse}}), but $2 er ikke det", + "wbqc-violation-message-type-instanceOrSubclass": "Entiteter som bruker egenskapen $1 bør være underklasser av {{PLURAL:$3|$5|2=$5 eller $6|én av følgende klasser}} (eller {{PLURAL:$3|en underklasse av den|2=en underklasse av dem|én av deres underklasser}}), men $2 er for tiden {{PLURAL:$3|ikke det|ikke det: $4}}.", + "wbqc-violation-message-valueType-instance": "Verdier i $1-utsagn bør være forekomster av {{PLURAL:$3|1=$5|2=$5 eller $6|en av følgende klasser: $4}} (eller {{PLURAL:$3|en underklasse}}), men $2 er ikke det", + "wbqc-violation-message-valueType-subclass": "Verdier i $1-utsagn bør være underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av følgende klasser: $4}} (eller {{PLURAL:$3|en underklasse}}), men $2 er ikke det", + "wbqc-violation-message-valueType-instanceOrSubclass": "Verdier i $1-utsagn bør være forekomst eller underklasse av {{PLURAL:$3|1=$5|2=$5 eller $6|en av følgende klasser: $4}} (eller {{PLURAL:$3|en underklasse}}), men $2 er ikke det", + "wbqc-violation-message-target-required-claim": "$1 bør ha {{PLURAL:$3|0=et $2-utsagn.|1=$2 $5.|et $2-utsagn med en av følgende verdier:$4}}", + "wbqc-violation-message-unique-value": "Denne verdien skal ikke finnes for andre elementer, men finnes på {{PLURAL:$1|1=$3.|2=$3 og $4.|følgende elementer: $2}}", + "wbqc-violation-message-valueOnly": "Denne egenskapen bør kun brukes for hovedverdien til en påstand, ikke for kvalifikatorer eller referanser.", + "wbqc-violation-message-reference": "Egenskapen bør kun brukes i referanser, ikke for hovedverdien til en påstand eller for en kvalifikator.", + "wbqc-violation-message-noBounds": "Verdier for $1 bør ikke ha noen grenser.", + "wbqc-violation-message-units-none": "Verdien for $1 bør ikke ha noen enhet.", + "wbqc-violation-message-units": "Verdien for $1 bør ha {{PLURAL:$2|enheten $4|2=enheten $4 eller $5|én av følgende enheter: $3}}.", + "wbqc-violation-message-units-or-none": "Verdien for $1 bør ha {{PLURAL:$2|enheten $4|2=enheten $4 eller $5|én av følgende enheter}} eller være {{PLURAL:$2|enhetsløs|enhetsløs: $3}}", + "wbqc-violation-message-entityType": "Egenskapen $1 bør ikke brukes for denne entitetstypen, {{PLURAL:$2|den eneste gyldige entitetstypen er $4|2=de eneste gyldige entitetstypene er $4 og $5|de eneste gyldige entitetstypene er: $3}}.", + "wbqc-violation-message-none-of": "Verdien for $1 bør ikke være {{PLURAL:$2|$4|2=enten $4 eller $5|én av følgende: $3}}.", + "wbqc-violation-message-integer": "Verdier for $1 bør være heltall, men $2 har en desimaldel.", + "wbqc-violation-message-integer-bounds": "Verdier for $1 bør være heltall, men grensene til $2 har en desimaldel.", + "wbqc-violation-message-citationNeeded": "Påstander for $1 bør ha minst én referanse.", + "wbqc-violation-message-language": "Utsagn for $1 bør kun være på leksemer på {{PLURAL:$2|1=$4|2=$4 eller $5|ett av følgende språk: $3}}.", + "wbqc-violation-message-label-lacking": "Entiteter med utsagn for $1 bør også ha {{PLURAL:$2|en etikett på $4|etiketter på følgende språk: $3}}.", + "wbqc-violation-message-property-scope": "Egenskapen $1 bør ikke brukes for dette stedet ($2). {{PLURAL:$3|Det eneste gyldige stedet|De eneste gyldige stedene}} for denne egenskapen er {{PLURAL:$3|$5|$4}}.", + "wbqc-violation-message-exception": "Denne entiteten er et kjent unntak fra denne begrensningen og har blitt merket som det." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/nds.json b/dist/extensions/WikibaseQualityConstraints/i18n/nds.json new file mode 100644 index 000000000..b8ec25f58 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/nds.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Slomox" + ] + }, + "wbqc-constrainttypehelp-short": "Hülp" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ne.json b/dist/extensions/WikibaseQualityConstraints/i18n/ne.json new file mode 100644 index 000000000..09bf9e785 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ne.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Nirajan pant", + "Nirjal stha", + "पर्वत सुबेदी", + "बिप्लब आनन्द", + "सरोज कुमार ढकाल", + "हिमाल सुबेदी", + "बडा काजी" + ] + }, + "wbqc-constraintreport": "प्रतिबन्ध प्रतिवेदन", + "wbqc-constraintreport-form-submit-label": "जाँच", + "wbqc-constraintreport-form-entityid-placeholder": "क्युएक्सएकस/पिएक्सएक्स", + "wbqc-constraintreport-result-headline": "$1 को परिणाम", + "wbqc-constraintreport-status-violation": "प्रतिपालना", + "wbqc-constraintreport-status-compliance": "अनुपालना", + "wbqc-constraintreport-status-todo": "टोडो", + "wbqc-constraintreport-result-table-header-status": "स्थिति", + "wbqc-constraintreport-result-table-header-constraint": "श्रोत अभाव", + "wbqc-constraintreport-result-link-to-claim": "दाबीमा जानुहोस्", + "wbqc-issues-short": "मुद्दाहरू", + "wbqc-suggestions-short": "सुझावहरू", + "wbqc-constrainttypehelp-short": "सहायता" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/nl.json b/dist/extensions/WikibaseQualityConstraints/i18n/nl.json new file mode 100644 index 000000000..11ec16fa2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/nl.json @@ -0,0 +1,156 @@ +{ + "@metadata": { + "authors": [ + "Bdijkstra", + "Festina90", + "Macofe", + "Mainframe98", + "Mar(c)", + "McDutchie", + "RadioAzureus", + "Romaine", + "Siebrand", + "Sjoerddebruin", + "Amire80" + ] + }, + "wbqc-constraintreport": "Beperkingenrapportage", + "wbqc-desc": "Controleert beperkingen op zowel items als eigenschappen en toont de resultaten op een speciale pagina.", + "wbqc-constraintreport-explanation-part-one": "Via deze pagina kunt u een beperkingencontrole uitvoeren op de gewenste entiteit. De entiteiten worden uit het productiesysteem opgehaald, dus iedere overtreding op de beperkingen die u hier oplost, wordt direct uit deze lijst verwijderd.", + "wbqc-constraintreport-explanation-part-two": "De beperkingen worden ontleend aan verklaringen op eigenschappen elke keer dat deze uitspraken worden bewerkt, meestal binnen een paar minuten.", + "wbqc-constraintreport-form-section": "Beperkingen voor entiteit controleren", + "wbqc-constraintreport-form-submit-label": "Controleren", + "wbqc-constraintreport-form-entityid-label": "Entiteits-ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx of Pxx", + "wbqc-constraintreport-result-headline": "Resultaat voor", + "wbqc-constraintreport-invalid-entity-id": "Ongeldige entiteits-ID.", + "wbqc-constraintreport-not-existent-entity": "Entiteit bestaat niet.", + "wbqc-constraintreport-empty-result": "Er zijn geen beperkingen opgegeven voor deze entiteit.", + "wbqc-constraintreport-status-violation": "Overtreding", + "wbqc-constraintreport-status-compliance": "Nakoming", + "wbqc-constraintreport-status-exception": "Uitzondering", + "wbqc-constraintreport-status-todo": "Te doen", + "wbqc-constraintreport-status-bad-parameters": "Foute parameters", + "wbqc-constraintreport-status-deprecated": "Verouderd", + "wbqc-constraintreport-status-warning": "Waarschuwing", + "wbqc-constraintreport-status-suggestion": "Suggestie", + "wbqc-constraintreport-status-not-in-scope": "Niet in bereik", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Eigenschap", + "wbqc-constraintreport-result-table-header-message": "Bericht", + "wbqc-constraintreport-result-table-header-constraint": "Beperking", + "wbqc-constraintreport-result-link-to-claim": "naar verklaring gaan", + "wbqc-constraintreport-result-link-to-constraint": "naar beperking gaan", + "wbqc-constraintreport-no-parameter": "geen", + "wbqc-issues-short": "Problemen", + "wbqc-issues-long": "Deze verklaring kent enkele problemen.", + "wbqc-potentialissues-short": "Mogelijke problemen", + "wbqc-potentialissues-long": "Deze verklaring heeft mogelijke problemen.", + "wbqc-suggestions-short": "Suggesties", + "wbqc-suggestions-long": "Er zijn enkele suggesties ter verbetering van deze verklaring.", + "wbqc-badparameters-short": "Foute parameters", + "wbqc-badparameters-long": "Deze beperkingsverklaring heeft enkele ongeldige parameters.", + "wbqc-parameterissues-short": "Geavanceerde problemen", + "wbqc-parameterissues-long": "Deze problemen hebben te maken met de beperkingsdefinitie van de eigenschap, niet met deze verklaring.", + "wbqc-constrainttypehelp-short": "Help", + "wbqc-constrainttypehelp-long": "Hulppagina voor dit type beperking", + "wbqc-constraintdiscuss-short": "Overleggen", + "wbqc-constraintdiscuss-long": "Overlegpagina van deze beperking", + "wbqc-cached-generic": "Dit resultaat komt uit de cache en is mogelijk verouderd.", + "wbqc-cached-minutes": "Dit resultaat komt uit de cache en kan tot {{PLURAL:$1|1=één minuut|$1 minuten}} verouderd zijn.", + "wbqc-cached-hours": "Dit resultaat komt uit de cache en kan tot {{PLURAL:$1|1=één uur|$1 uur}} verouderd zijn.", + "wbqc-cached-days": "Dit resultaat komt uit de cache en kan tot {{PLURAL:$1|1=één dag|$1 dagen}} verouderd zijn.", + "wbqc-dataValueType-wikibase-entityid": "Entiteits-ID", + "wbq-subextension-name-wbqc": "Beperkingen", + "wbqc-violation-header-parameters": "Parameters:", + "wbqc-violations-group": "Beperkingen", + "wbqc-violation-message": "Bij de beperkingencontrole is een overtreding ontdekt. Klik op het pictogram voor meer informatie.", + "wbqc-violation-message-not-yet-implemented": "Om technische redenen is de controle op de beperking “$1” nog niet geïmplementeerd.", + "wbqc-violation-message-security-reason": "Om veiligheidsredenen kan de controle op de beperking \"$1\" nog niet worden uitgevoerd. We werken aan een oplossing.", + "wbqc-violation-message-value-needed-of-type": "Eigenschappen met de beperking “$1” moeten waarden hebben van het type “$2”.", + "wbqc-violation-message-value-needed-of-types-2": "Eigenschappen met de beperking “$1” moeten waarden hebben van de typen “$2” en “$3”.", + "wbqc-violation-message-parameter-needed": "Eigenschappen met de beperking “$1” hebben een parameter “$2” nodig.", + "wbqc-violation-message-parameters-needed-3": "Eigenschappen met de beperking “$1” hebben de parameters “$2”, “$3” en “$4” nodig.", + "wbqc-violation-message-target-entity-must-exist": "De doelentiteit moet bestaan.", + "wbqc-violation-message-value-entity-must-exist": "De entiteit die opgegeven is als waarde moet bestaan.", + "wbqc-violation-message-parameter-value": "De parameter “$1” moet een aangepaste waarde bevatten, niet “geen waarde” of “onbekende waarde”.", + "wbqc-violation-message-parameter-value-or-novalue": "De parameter “$1” moet een aangepaste waarde of “geen waarde” bevatten, maar nooit “onbekende waarde”.", + "wbqc-violation-message-parameter-entity": "De waarde voor de parameter “$1” moet een entiteit zijn, niet “$2”.", + "wbqc-violation-message-parameter-item": "De waarde voor de parameter “$1” moet een item zijn, niet “$2”.", + "wbqc-violation-message-parameter-property": "De waarde voor de parameter “$1” moet een eigenschap zijn, niet “$2”.", + "wbqc-violation-message-parameter-string": "De waarde voor de parameter “$1” moet een tekenreeks zijn, niet “$2”.", + "wbqc-violation-message-parameter-monolingualtext": "De waarde voor de parameter “$1” moet een ééntalige tekst zijn, niet “$2”.", + "wbqc-violation-message-parameter-single": "De parameter “$1” moet slechts één waarde hebben.", + "wbqc-violation-message-parameter-single-per-language": "De parameter “$1” mag maar één waarde per taal hebben, maar heeft meerdere waarden voor $2 ($3).", + "wbqc-violation-message-parameter-oneof": "De parameter “$1” moet {{PLURAL:$2|1=$4 zijn.|2=$4 of $5 zijn.|één van de volgende zijn: $3}}", + "wbqc-violation-message-parameter-regex": "$1 is geen geldige reguliere expressie.", + "wbqc-violation-message-sparql-error": "De SPARQL-zoekopdracht heeft geleid tot een foutmelding.", + "wbqc-violation-message-parameters-error-unknown": "De parameters voor deze beperking konden niet worden geïmporteerd.", + "wbqc-violation-message-parameters-error-toolong": "De parameters voor deze beperking konden niet worden geïmporteerd omdat deze te lang waren.", + "wbqc-violation-message-invalid-scope": "$1 is geen geldig bereik voor beperkingstype $2; {{PLURAL:$3|het enige geldige bereik|de enige geldige bereiken}} voor dit type beperking {{PLURAL:$3|is $5.|2=zijn $5 en $6.|zijn: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Er moet een koppeling naar Commons zijn.", + "wbqc-violation-message-commons-link-not-well-formed": "De koppeling naar Commons mag geen ongeldige tekens bevatten.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "De controle voor de naamruimte “$1” is nog niet geïmplementeerd.", + "wbqc-violation-message-conflicts-with-property": "Een entiteit hoort geen verklaringen te hebben voor $1 en $2 tegelijkertijd.", + "wbqc-violation-message-conflicts-with-claim": "Een entiteit hoort geen verklaring te hebben voor $1, wanneer deze ook een verklaring heeft voor $2 met als waarde $3.", + "wbqc-violation-message-contemporary-subject-earlier": "De entiteiten $1 en $3 moeten gelijktijdig zijn om via $2 met elkaar verbonden te zijn, maar de laatste eindwaarde van $1 is $4 en de vroegste beginwaarde van $3 is $5.", + "wbqc-violation-message-contemporary-value-earlier": "De entiteiten $1 en $3 moeten gelijktijdig zijn om via $2 met elkaar verbonden te zijn, maar de laatste eindwaarde van $3 is $4 en de vroegste beginwaarde van $1 is $5.", + "wbqc-violation-message-diff-within-range": "Het verschil tussen $3 ($4) en $1 ($2) moet tussen $5 en $6 liggen.", + "wbqc-violation-message-diff-within-range-leftopen": "Het verschil tussen $3 ($4) en $1 ($2) mag niet groter zijn dan $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Het verschil tussen $3 ($4) en $1 ($2) mag niet kleiner zijn dan $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "De in de parameters opgegeven eigenschap moet een waarde van hetzelfde type als dat van deze eigenschap hebben.", + "wbqc-violation-message-format": "De waarde voor $1 ($2) moet de reguliere expressie $3 volgen.", + "wbqc-violation-message-format-clarification": "De waarde voor $1 ($2) moet overeenkomen met “$4” (reguliere expressie: $3).", + "wbqc-violation-message-inverse": "$1 moet ook de omgekeerde verklaring $2 $3 hebben.", + "wbqc-violation-message-item": "Een entiteit met $1 moet ook {{PLURAL:$3|0=een verklaring $2 bevatten.|1=een verklaring $2 $5 bevatten.|een verklaring voor $2 met een van de volgende waarden bevatten: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Bij deze verklaring “$1” ontbreekt een kwalificatie “$2”.", + "wbqc-violation-message-multi-value": "Deze eigenschap moet meerdere waarden bevatten.", + "wbqc-violation-message-multi-value-separators": "Deze eigenschap moet meerdere waarden bevatten met dezelfde {{PLURAL:$2|1=kwalificatie: $4.|verzameling kwalificaties voor deze eigenschappen: $3}}", + "wbqc-violation-message-one-of": "De waarde voor $1 moet {{PLURAL:$2|1=$4 zijn.|2=$4 of $5 zijn.|een van de volgende waarden zijn: $3}}", + "wbqc-violation-message-qualifier": "De eigenschap mag alleen als kwalificatie worden gebruikt.", + "wbqc-violation-message-no-qualifiers": "$1-verklaringen mogen geen kwalificaties hebben.", + "wbqc-violation-message-qualifiers": "$2 is geen geldige kwalificatie voor $1 – de enige geldige {{PLURAL:$3|1=kwalificatie is $5.|2=kwalificaties zijn $5 en $6.|kwalificaties zijn: $4}}", + "wbqc-violation-message-range-parameters-needed": "Eigenschappen met waarden van het type “$1” met beperking “$4” hebben de parameters “$2” en “$3” nodig.", + "wbqc-violation-message-range-parameters-one-year": "Eindpunten van een tijdseenheidbereik moeten beide of geen van beide de eenheid “jaar” hebben, want jaren kunnen zonder verlies in seconden worden omgezet.", + "wbqc-violation-message-range-parameters-same": "Het begin ($1) en het eind ($2) van een bereik mogen niet hetzelfde zijn.", + "wbqc-violation-message-range-quantity-closed": "De waarde voor $1 ($2) moet tussen $3 en $4 liggen.", + "wbqc-violation-message-range-quantity-leftopen": "De waarde voor $1 ($2) mag niet meer dan $3 zijn.", + "wbqc-violation-message-range-quantity-rightopen": "De waarde voor $1 ($2) mag niet lager dan $3 zijn.", + "wbqc-violation-message-range-time-closed": "De waarde voor $1 ($2) moet tussen $3 en $4 liggen.", + "wbqc-violation-message-range-time-closed-leftnow": "De waarde voor $1 ($2) moet in de toekomst liggen, maar niet na $3.", + "wbqc-violation-message-range-time-closed-rightnow": "De waarde voor $1 ($2) moet in het verleden liggen, maar niet vóór $3.", + "wbqc-violation-message-range-time-leftopen": "De waarde voor $1 ($2) mag niet na $3 zijn.", + "wbqc-violation-message-range-time-leftopen-rightnow": "De waarde voor $1 ($2) mag niet in de toekomst liggen.", + "wbqc-violation-message-range-time-rightopen": "De waarde voor $1 ($2) mag niet vóór $3 zijn.", + "wbqc-violation-message-range-time-rightopen-leftnow": "De waarde voor $1 ($2) mag niet in het verleden liggen.", + "wbqc-violation-message-single-value": "Deze eigenschap hoort maar één waarde te bevatten.", + "wbqc-violation-message-single-value-separators": "Deze eigenschap moet slechts één waarde hebben met dezelfde {{PLURAL:$2|1=kwalificatie: $4.|verzameling kwalificaties voor deze eigenschappen: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Deze eigenschap moet één “beste” waarde bevatten. Van de meerdere bestaande waarden moet er één de rang “voorkeur” hebben.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Deze eigenschap moet één “beste” waarde bevatten met dezelfde {{PLURAL:$2|1=kwalificatie: $4.|verzameling kwalificaties voor deze eigenschappen: $3}} Van de huidige meerdere waarden moet er één worden gemarkeerd met de rang “voorkeur”.", + "wbqc-violation-message-single-best-value-multi-preferred": "Deze eigenschap moet één “beste” waarde bevatten. Er mag niet meer dan één waarde met de rang “voorkeur” zijn.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Deze eigenschap moet één “beste” waarde bevatten met dezelfde {{PLURAL:$2|1=kwalificatie: $4.|verzameling kwalificaties voor deze eigenschappen: $3}} Er mag niet meer dan één waarde zijn met de rang “voorkeur”.", + "wbqc-violation-message-symmetric": "$1 moet ook de symmetrische verklaring $2 $3 hebben.", + "wbqc-violation-message-type-instance": "Entiteiten die de eigenschap $1 gebruiken moeten instanties zijn van {{PLURAL:$3|1=$5|2=$5 of $6|één van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-type-subclass": "Entiteiten die de eigenschap $1 gebruiken moeten subklassen zijn van {{PLURAL:$3|1=$5|2=$5 of $6|één van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entiteiten die de eigenschap $1 gebruiken moeten instanties of subklassen zijn van {{PLURAL:$3|1=$5|2=$5 of $6|één van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-valueType-instance": "Waarden van $1-verklaringen moeten instanties zijn van {{PLURAL:$3|1=$5|2=$5 of $6|één van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-valueType-subclass": "Waarden van $1-verklaringen moeten subklassen zijn van {{PLURAL:$3|1=$5|2=$5 of $6|een van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Waarden van $1-verklaringen moeten instanties of subklassen zijn van {{PLURAL:$3|1=$5|2=$5 of $6|een van de volgende klassen}} (of een subklasse ervan), maar $2 is dat op dit moment {{PLURAL:$3|1=niet.|2=niet.|niet: $4}}", + "wbqc-violation-message-target-required-claim": "$1 moet {{PLURAL:$3|0=een verklaring $2 hebben.|1=een verklaring $2 $5 hebben.|een verklaring voor $2 met één van de volgende waarden hebben: $4}}", + "wbqc-violation-message-unique-value": "De waarde van deze eigenschap mag niet voorkomen op andere items, maar komt wel voor op {{PLURAL:$1|1=$3.|2=$3 en $4.|de volgende items: $2}}", + "wbqc-violation-message-valueOnly": "Deze eigenschap mag alleen worden gebruikt voor de hoofdwaarde van een verklaring, niet voor kwalificaties of referenties.", + "wbqc-violation-message-reference": "De eigenschap mag alleen worden gebruikt in referenties, en niet voor de hoofdwaarde van een verklaring of voor een kwalificatie.", + "wbqc-violation-message-noBounds": "Waarden voor $1 mogen geen grenzen hebben.", + "wbqc-violation-message-units-none": "De waarde voor $1 mag geen eenheid bevatten.", + "wbqc-violation-message-units": "De waarde voor $1 moet {{PLURAL:$2|1=de eenheid $4 hebben.|2=de eenheid $4 of $5 hebben.|één van de volgende eenheden hebben: $3}}", + "wbqc-violation-message-units-or-none": "De waarde voor $1 moet {{PLURAL:$2|1=de eenheid $4|2=de eenheid $4 of $5|één van de volgende eenheden}} of geen enkele eenheid {{PLURAL:$2|1=hebben.|2=hebben.|hebben: $3}}", + "wbqc-violation-message-entityType": "De eigenschap $1 mag niet worden gebruikt voor dit type entiteit. {{PLURAL:$2|1=Het enige geldige entiteitstype is $4.|2=De enige geldige entiteitstypes zijn $4 en $5.|De geldige entiteitstypes zijn: $3}}", + "wbqc-violation-message-none-of": "De waarde voor $1 mag {{PLURAL:$2|1=niet $4 zijn.|2=niet $4 of $5 zijn.|geen van de volgende zijn: $3}}", + "wbqc-violation-message-integer": "De waarden voor $1 moeten gehele getallen zijn, maar $2 heeft cijfers na de komma.", + "wbqc-violation-message-integer-bounds": "De waarden voor $1 moeten gehele getallen zijn, maar de grenzen van $2 hebben cijfers na de komma.", + "wbqc-violation-message-citationNeeded": "Verklaringen voor $1 moeten ten minste één referentie bevatten.", + "wbqc-violation-message-language": "Verklaringen voor $1 moeten alleen op lexemen staan waarbij de taal is ingesteld op {{PLURAL:$2|1=$4.|2=$4 of $5.|één van de volgende: $3}}", + "wbqc-violation-message-label-lacking": "Entiteiten met statements voor $1 moeten ook een label hebben in ten minste {{PLURAL:$2|1=de taal $4.|één van de volgende talen: $3}}", + "wbqc-violation-message-property-scope": "De eigenschap $1 mag niet op deze plek ($2) worden gebruikt. De enige geldige {{PLURAL:$3|locatie|locaties}} voor deze eigenschap {{PLURAL:$3|is $5.|zijn: $4}}", + "wbqc-violation-message-exception": "Deze entiteit is een bekende uitzondering op deze beperking en is ook als zodanig gemarkeerd." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/nn.json b/dist/extensions/WikibaseQualityConstraints/i18n/nn.json new file mode 100644 index 000000000..2533c7f1f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/nn.json @@ -0,0 +1,52 @@ +{ + "@metadata": { + "authors": [ + "Njardarlogar" + ] + }, + "wbqc-constraintreport": "Avgrensingsrapport", + "wbqc-constraintreport-form-section": "Gå gjennom avgrensingar for ei eining", + "wbqc-constraintreport-form-entityid-label": "Einings-ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx eller Pxx", + "wbqc-constraintreport-status-todo": "Uferdig", + "wbqc-constraintreport-status-warning": "Åtvaring", + "wbqc-constraintreport-result-table-header-property": "Eigenskap", + "wbqc-constraintreport-result-table-header-constraint": "Avgrensing", + "wbqc-issues-short": "Vanskar", + "wbqc-issues-long": "Denne utsegna har nokre vanskar.", + "wbqc-potentialissues-short": "Moglege vanskar", + "wbqc-potentialissues-long": "Denne utsegna har nokre mogelege vanskar.", + "wbqc-suggestions-short": "Framlegg", + "wbqc-suggestions-long": "Det finst framlegg til betring av denne utsegna.", + "wbqc-parameterissues-short": "Avanserte vanskar", + "wbqc-parameterissues-long": "Desse vanskane gjeld definisjonen av avgrensinga på sjølve eigenskapen og ikkje denne utsegna.", + "wbqc-constrainttypehelp-short": "Hjelp", + "wbqc-constrainttypehelp-long": "Hjelpeside for denne avgrensingstypen", + "wbqc-constraintdiscuss-short": "Diskuter", + "wbqc-constraintdiscuss-long": "Diskusjonsside for denne avgrensinga", + "wbqc-cached-generic": "Dette resultatet er mellomlagra og kan vera utdatert.", + "wbqc-cached-minutes": "Dette resultatet er mellomlagra og kan vera utdatert med opp til {{PLURAL:$1|1=eitt minutt|$1 minutt}}.", + "wbqc-cached-hours": "Dette resultatet er mellomlagra og kan vera utdatert med opp til {{PLURAL:$1|1=éin time|$1 timar}}.", + "wbqc-cached-days": "Dette resultatet er mellomlagra og kan vera utdatert med opp til {{PLURAL:$1|1=éin dag|$1 dagar}}.", + "wbqc-dataValueType-wikibase-entityid": "Einings-ID", + "wbqc-violation-message-parameter-single": "Parameteren «$1» kan berre ha éin einskild verdi.", + "wbqc-violation-message-parameter-regex": "$1 er ikkje eit gyldig regulært uttrykk.", + "wbqc-violation-message-conflicts-with-property": "Ei eining skal aldri ha utsegner for både $1 og $2.", + "wbqc-violation-message-conflicts-with-claim": "Ei eining skal ikkje ha ei utsegn for $1 om ho dessutan har ei utsegn for $2 med verdi $3.", + "wbqc-violation-message-format": "Verdien for $1 ($2) skal svara til det regulære uttrykket $3.", + "wbqc-violation-message-item": "Ei eining med $1 bør dessutan ha {{PLURAL:$3|0=ei $2-utsegn.|1=ei $2-utsegn $5.|ei $2-utsegn med ein av desse verdiane: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Denne $1-utsegna manglar kvalifikatoren $2.", + "wbqc-violation-message-multi-value": "Denne eigenskapen skal ha meir enn éin verdi.", + "wbqc-violation-message-single-value": "Denne eigenskapen skal berre ha éin verdi.", + "wbqc-violation-message-type-instance": "Einingar som nyttar eigenskapen $1 bør vera førekomstar av {{PLURAL:$3|1=$5|2=$5 eller $6|ein av klassane under}} (eller av {{PLURAL:$3|1=ein av underklassane hans|2=ein av underklassane deira|ein av underklassane deira}}), men $2 {{PLURAL:$3|1=er ikkje det.|2=er ikkje det.|er ikkje det: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Einingar som nyttar eigenskapen $1 bør vera førekomstar eller underklassar av {{PLURAL:$3|1=$5|2=$5 eller $6|ein av klassane under}} (eller av {{PLURAL:$3|1=ein av underklassane hans|2=ein av underklassane deira|ein av underklassane deira}}), men $2 {{PLURAL:$3|1=er ikkje det.|2=er ikkje det.|er ikkje det: $4}}", + "wbqc-violation-message-valueType-instance": "Verdiar i $1-utsegner bør vera førekomstar av {{PLURAL:$3|1=$5|2=$5 eller $6|ein av desse klassane: $4}} (eller {{PLURAL:$3|1=ein underklasse av han|2=ein underklasse av dei|ein av underklassane deira}}), men $2 er ikkje det", + "wbqc-violation-message-target-required-claim": "$1 bør ha {{PLURAL:$3|0=ei $2-utsegn.|1=ei $2-utsegn med verdien $5.|ei $2-utsegn med ein av desse verdiane: $4}}", + "wbqc-violation-message-units-none": "Verdien til $1 bør ikkje ha ei eining.", + "wbqc-violation-message-units": "Verdien til $1 bør ha {{PLURAL:$2|1=eininga $4.|2=eininga $4 eller $5.|ein av desse einingane: $3}}", + "wbqc-violation-message-units-or-none": "Verdien til $1 bør ha {{PLURAL:$2|1=eininga $4.|2=eininga $4 eller $5.|ein av desse einingane}} eller vera utan {{PLURAL:$2|1=eining.|2=eining.|eining: $3}}", + "wbqc-violation-message-entityType": "Eigenskapen $1 bør ikkje nyttast for denne einingstypen, {{PLURAL:$2|den|dei}} einaste gyldige {{PLURAL:$2|1=einingstypen er $4.|2=einingstypane er $4 og $5.|einingstypane er desse: $3}}", + "wbqc-violation-message-none-of": "Verdien for $1 skal ikkje vera {{PLURAL:$2|1=$4|2=anten $4 eller $5|éin av desse: $3}}.", + "wbqc-violation-message-citationNeeded": "Utsegner for $1 bør ha minst éin referanse.", + "wbqc-violation-message-label-lacking": "Einingar med utsegner for $1 skal òg ha {{PLURAL:$2|1=ein merkelapp på $4|merkelappar på desse språka: $3}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/pl.json b/dist/extensions/WikibaseQualityConstraints/i18n/pl.json new file mode 100644 index 000000000..485b81ff7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/pl.json @@ -0,0 +1,41 @@ +{ + "@metadata": { + "authors": [ + "Chrumps", + "CiaPan", + "InternerowyGołąb", + "Woytecr" + ] + }, + "wbqc-constraintreport-form-submit-label": "Sprawdź", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx lub Pxx", + "wbqc-constraintreport-result-headline": "Wynik dla", + "wbqc-constraintreport-invalid-entity-id": "Nieprawidłowy identyfikator elementu", + "wbqc-constraintreport-not-existent-entity": "Element nie istnieje.", + "wbqc-constraintreport-status-violation": "Naruszenie", + "wbqc-constraintreport-status-compliance": "Zgodność", + "wbqc-constraintreport-status-exception": "Wyjątek", + "wbqc-constraintreport-status-todo": "Do zrobienia", + "wbqc-constraintreport-status-bad-parameters": "Złe parametry", + "wbqc-constraintreport-status-warning": "Ostrzeżenie", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Właściwość", + "wbqc-constraintreport-result-table-header-message": "Wiadomość", + "wbqc-constraintreport-no-parameter": "brak", + "wbqc-badparameters-short": "Złe parametry", + "wbqc-constrainttypehelp-short": "Pomoc", + "wbqc-violation-header-parameters": "Parametry:", + "wbqc-violation-message-parameter-regex": "$1 nie jest prawidłowym wyrażeniem regularnym.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Właściwość określona w parametrach musi mieć wartość tego samego typu jak ta właściwość.", + "wbqc-violation-message-format": "Wartość dla $1 ($2) powinna pasować do wzorca $3.", + "wbqc-violation-message-multi-value": "Ta właściwość powinna zawierać wiele wartości.", + "wbqc-violation-message-one-of": "Właściwość $1 powinna mieć wartość {{PLURAL:$2|1=$4.|2=$4 albo $5.|jedną z następujących:$3}}", + "wbqc-violation-message-qualifier": "Ta właściwość powinna być stosowana tylko jako kwalifikator.", + "wbqc-violation-message-range-quantity-leftopen": "Wartość $1 ($2) nie powinna być większa od $3.", + "wbqc-violation-message-range-time-closed": "Wartość $1 ($2) powinna być powinna $3 oraz $4.", + "wbqc-violation-message-single-value": "Ta właściwość powinna zawierać tylko jedną wartość.", + "wbqc-violation-message-target-required-claim": "$1 powinno mieć {{PLURAL:$3|0=deklarację $2.|1=deklarację $2 $5.|deklarację dla $2 z jedną z następujących wartości: $4}}", + "wbqc-violation-message-units-none": "Wartość $1 nie powinna mieć jednostki.", + "wbqc-violation-message-integer": "Wartości dla $1 powinny być liczbami całkowitymi, ale $2 ma część ułamkową.", + "wbqc-violation-message-property-scope": "Właściwość $1 nie powinna być używana w tej lokalizacji ($2). {{PLURAL:$3| Jedyna prawidłowa|Jedyne prawidłowe}} dla tej właściwości {{PLURAL:$3|to $5|to: $4}}" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/pnb.json b/dist/extensions/WikibaseQualityConstraints/i18n/pnb.json new file mode 100644 index 000000000..f5c087ef8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/pnb.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Abbas dhothar", + "Bgo eiu" + ] + }, + "wbqc-constraintreport-form-submit-label": "نرودھ کھوج شروع کرو", + "wbqc-constraintreport-form-entityid-label": "چیز دا شناختی:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx یا Pxx", + "wbqc-constraintreport-result-headline": "نتیجہ:", + "wbqc-constraintreport-invalid-entity-id": "چیز دا شناختی نہیں درست اے۔", + "wbqc-constraintreport-not-existent-entity": "چیز نہیں ہندی۔", + "wbqc-constraintreport-status-todo": "ہݨے نرودھ کم نہیں سکدا", + "wbqc-constraintreport-status-warning": "خبردار", + "wbqc-constraintreport-result-table-header-status": "حالت", + "wbqc-constraintreport-result-table-header-property": "وشیشتا", + "wbqc-constraintreport-result-table-header-message": "سنیہا", + "wbqc-constraintreport-result-table-header-constraint": "نرودھ", + "wbqc-constraintreport-no-parameter": "کوئی نئیں", + "wbqc-issues-short": "مسئلے", + "wbqc-parameterissues-short": "اضافی مسئلے", + "wbqc-constrainttypehelp-short": "مدد", + "wbqc-constraintdiscuss-short": "گل بات", + "wbqc-dataValueType-wikibase-entityid": "چیز دا شناختی", + "wbq-subextension-name-wbqc": "نرودھ", + "wbqc-violation-header-parameters": "ماپ دنڈ:", + "wbqc-violations-group": "نرودھ", + "wbqc-violation-message-qualifiers": "$1 لئی $2 وشیشگتا نہیں درست اے۔ {{PLURAL:$3|1=صرف $5 ورت ہی سکدے۔|2=صرف $5 یا $6 ورت ہی سکدے۔|صرف ایہہ وشیشگتاواں ورت ہی سکدے: $4}}", + "wbqc-violation-message-citationNeeded": "$1 بیاناں لئی حوالے ضروری اے۔" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ps.json b/dist/extensions/WikibaseQualityConstraints/i18n/ps.json new file mode 100644 index 000000000..d6657627a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ps.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "wbqc-constraintreport-result-table-header-status": "دريځ", + "wbqc-constraintreport-no-parameter": "هېڅ" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/pt-br.json b/dist/extensions/WikibaseQualityConstraints/i18n/pt-br.json new file mode 100644 index 000000000..211a20050 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/pt-br.json @@ -0,0 +1,148 @@ +{ + "@metadata": { + "authors": [ + "Eduardo Addad de Oliveira", + "Eduardoaddad", + "Felipe L. Ewald", + "Hamilton Abreu", + "Vagnerrondon" + ] + }, + "wbqc-constraintreport": "Relatório de restrição", + "wbqc-desc": "Verifica restrições em itens e propriedades e exibe os resultados em uma página especial", + "wbqc-constraintreport-explanation-part-one": "Esta página especial realiza verificações de restrições em qualquer entidade que você deseja. As entidades são obtidas do sistema ao vivo, então cada violação de restrição que você conserta será removida instantaneamente dessa lista.", + "wbqc-constraintreport-explanation-part-two": "As restrições são analisadas a partir de declarações sobre propriedades cada vez que essas instruções são editadas, geralmente dentro de alguns minutos.", + "wbqc-constraintreport-form-section": "Verifica restrições para entidade", + "wbqc-constraintreport-form-submit-label": "Verificar", + "wbqc-constraintreport-form-entityid-label": "ID da entidade:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx ou Pxx", + "wbqc-constraintreport-result-headline": "Resultado para", + "wbqc-constraintreport-invalid-entity-id": "ID da entidade inválido.", + "wbqc-constraintreport-not-existent-entity": "Entidade não existe.", + "wbqc-constraintreport-empty-result": "Não há restrições definidas nesta entidade.", + "wbqc-constraintreport-status-violation": "Violação", + "wbqc-constraintreport-status-compliance": "Conformidade", + "wbqc-constraintreport-status-exception": "Exceção", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Parâmetros incorretos", + "wbqc-constraintreport-status-deprecated": "Obsoleto", + "wbqc-constraintreport-status-warning": "Aviso", + "wbqc-constraintreport-status-suggestion": "Sugestão", + "wbqc-constraintreport-status-not-in-scope": "Fora do âmbito", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Propriedade", + "wbqc-constraintreport-result-table-header-message": "Mensagem", + "wbqc-constraintreport-result-table-header-constraint": "Limitação", + "wbqc-constraintreport-result-link-to-claim": "ir para a reinvindicação", + "wbqc-constraintreport-result-link-to-constraint": "ir para a restrição", + "wbqc-constraintreport-no-parameter": "nenhum", + "wbqc-issues-short": "Problemas", + "wbqc-issues-long": "Esta declaração tem alguns problemas.", + "wbqc-potentialissues-short": "Problemas potenciais", + "wbqc-potentialissues-long": "Esta declaração tem alguns problemas potenciais.", + "wbqc-suggestions-short": "Sugestões", + "wbqc-suggestions-long": "Existem algumas sugestões para melhorar essa declaração.", + "wbqc-badparameters-short": "Parâmetros incorretos", + "wbqc-badparameters-long": "Esta declaração de restrição possui alguns parâmetros inválidos.", + "wbqc-parameterissues-short": "Problemas avançados", + "wbqc-parameterissues-long": "Esses problemas são problemas com a definição de restrição na propriedade, não com esta declaração.", + "wbqc-constrainttypehelp-short": "Ajuda", + "wbqc-constrainttypehelp-long": "Página de ajuda para este tipo de restrição", + "wbqc-constraintdiscuss-short": "Discussão", + "wbqc-constraintdiscuss-long": "Página de discussão sobre esta restrição", + "wbqc-cached-generic": "Esse resultado é armazenado em cache e pode estar desatualizado.", + "wbqc-cached-minutes": "Esse resultado está em cache e pode estar desatualizado até {{PLURAL:$1|1=um minuto|$1 minutos}}.", + "wbqc-cached-hours": "Este resultado foi armazenado na cache e pode estar desatualizado em até {{PLURAL:$1|1=uma hora|$1 horas}}.", + "wbqc-cached-days": "Este resultado foi armazenado na cache e pode estar desatualizado em até {{PLURAL:$1|1=um dia|$1 dias}}.", + "wbqc-dataValueType-wikibase-entityid": "Identificador da entidade", + "wbq-subextension-name-wbqc": "Restrições", + "wbqc-violation-header-parameters": "Parâmetros:", + "wbqc-violations-group": "Restrições", + "wbqc-violation-message": "A verificação de restrição apontou uma violação. Clique no ícone para obter mais informações.", + "wbqc-violation-message-not-yet-implemented": "Por razões técnicas, a verificação da restrição \"$1\" ainda não foi implementada.", + "wbqc-violation-message-security-reason": "Por razões de segurança, não é possível verificar a restrição \"$1\" no momento. Estamos trabalhando em uma solução.", + "wbqc-violation-message-value-needed-of-type": "Propriedades com restrição \"$1\" precisam ter valores do tipo \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Propriedades com restrição \"$1\" precisam ter valores do tipo \"$2\" ou \"$3\".", + "wbqc-violation-message-parameter-needed": "As propriedades com restrição \"$1\" precisam de um parâmetro \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Propriedades com restrição \"$1\" precisam de parâmetros \"$2\", \"$3\" ​​e \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "A entidade alvo deve existir.", + "wbqc-violation-message-value-entity-must-exist": "A valor entidade deve existir.", + "wbqc-violation-message-parameter-value": "O parâmetro \"$1\" deve ter um valor personalizado, não \"sem valor\" ou \"valor desconhecido\".", + "wbqc-violation-message-parameter-value-or-novalue": "O parâmetro \"$1\" deve ter um valor personalizado ou \"sem valor\", mas nunca \"valor desconhecido\".", + "wbqc-violation-message-parameter-entity": "O valor para o parâmetro \"$1\" deve ser uma entidade, não \"$2\".", + "wbqc-violation-message-parameter-item": "O valor para o parâmetro \"$1\" deve ser um item, não \"$2\".", + "wbqc-violation-message-parameter-property": "O valor para o parâmetro \"$1\" deve ser uma propriedade, não \"$2\".", + "wbqc-violation-message-parameter-string": "O valor para o parâmetro \"$1\" deve ser uma string, não \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "O valor para o parâmetro \"$1\" tem de ser um texto numa única língua, não \"$2\".", + "wbqc-violation-message-parameter-single": "O parâmetro \"$1\" deve ter apenas um valor único.", + "wbqc-violation-message-parameter-single-per-language": "O parâmetro \"$1\" tem de ter um único valor por língua, mas tem mais do que um valor para $2 ($3).", + "wbqc-violation-message-parameter-oneof": "O parâmetro \"$1\" deve ser {{PLURAL:$2|1=$4.|2=$4 ou $5.|um dos seguintes:$3}}", + "wbqc-violation-message-parameter-regex": "$1 não é uma expressão regular válida.", + "wbqc-violation-message-sparql-error": "A consulta SPARQL resultou em um erro.", + "wbqc-violation-message-parameters-error-unknown": "Os parâmetros dessa restrição não podem ser importados.", + "wbqc-violation-message-parameters-error-toolong": "Os parâmetros dessa restrição não podiam ser importados porque eram muito longos.", + "wbqc-violation-message-invalid-scope": "$1 não é um âmbito válido para o tipo de restrição $2; {{PLURAL:$3|o único âmbito válido|os únicos âmbitos válidos}} para este tipo de restrição {{PLURAL:$3|é $5.|2=são $5 e $6.|são: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Link Commons deve existir.", + "wbqc-violation-message-commons-link-not-well-formed": "O link do Commons deve estar bem formado.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "A verificação para o espaço nominal \"$1\" ainda não foi implementada.", + "wbqc-violation-message-conflicts-with-property": "Uma entidade não deve ter declarações para $1 e $2.", + "wbqc-violation-message-conflicts-with-claim": "Uma entidade não deve ter uma declaração para $1 se ela também tiver uma declaração de $2 com valor de $3.", + "wbqc-violation-message-contemporary-subject-earlier": "As entidades $1 e $3 devem ser contemporâneas para serem ligadas através de $2, mas o valor final mais recente de $1 é $4 e o valor inicial mais antigo de $3 é $5.", + "wbqc-violation-message-contemporary-value-earlier": "As entidades $1 e $3 devem ser contemporâneas para serem ligadas através de $2, mas o valor final mais recente de $3 é $4 e o valor inicial mais antigo de $1 é $5.", + "wbqc-violation-message-diff-within-range": "A diferença entre $3 ($4) e $1 ($2) deveria estar compreendida entre $5 e $6.", + "wbqc-violation-message-diff-within-range-leftopen": "A diferença entre $3 ($4) e $1 ($2) deveria ser igual ou inferior a $5.", + "wbqc-violation-message-diff-within-range-rightopen": "A diferença entre $3 ($4) e $1 ($2) deveria ser igual ou superior a $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "A propriedade definida nos parâmetros deve ter um valor do mesmo tipo que essa propriedade.", + "wbqc-violation-message-format": "O valor de $1 ($2) deveria coincidir com a expressão regular $3.", + "wbqc-violation-message-format-clarification": "O valor de $1 ($2) deveria coincidir com \"$4\" (expressão regular: $3).", + "wbqc-violation-message-inverse": "$1 também deve ter a declaração inversa $2 $3.", + "wbqc-violation-message-item": "Uma entidade com $1 também deve ter {{PLURAL:$3|0=uma declaração $2.|1=uma declaração $2 $5.|uma declaração para $2 com um dos seguintes valores: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Está faltando um qualificador $2 nesta declaração $1.", + "wbqc-violation-message-multi-value": "Esta propriedade devia conter mais do que um valor.", + "wbqc-violation-message-multi-value-separators": "Esta propriedade devia conter mais do que um valor com o mesmo {{PLURAL:$2|1=$4 qualitativo.|conjunto de qualitativos para essas propriedades: $3}}", + "wbqc-violation-message-one-of": "O valor de \"$1\" deveria ser {{PLURAL:$2|1=$4.|2=$4 ou $5.|um dos seguintes:$3}}", + "wbqc-violation-message-qualifier": "A propriedade só deve ser usada como um qualificador.", + "wbqc-violation-message-no-qualifiers": "As declarações de $1 não devem ter qualificadores.", + "wbqc-violation-message-qualifiers": "$2 não é um qualificador válido para $1 – {{PLURAL:$3|1=o único qualificador válido é $5.|2=os únicos qualificadores válidos são $5 e $6.|Qualificadores válidos são: $4}}", + "wbqc-violation-message-range-parameters-needed": "Propriedades com valores do tipo \"$1\" com restrição \"$4\" precisam dos parâmetros \"$2\" e \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Os extremos de um intervalo de unidades de tempo têm de ter ambos ou nenhum a unidade \"ano\", porque os anos não podem ser convertidos em segundos sem perdas.", + "wbqc-violation-message-range-parameters-same": "Os pontos iniciais ($1) e finais ($2) de uma gama não devem ser os mesmos.", + "wbqc-violation-message-range-quantity-closed": "O valor de $1 ($2) deve estar entre $3 e $4.", + "wbqc-violation-message-range-quantity-leftopen": "O valor de $1 ($2) deve ser igual ou inferior a $3.", + "wbqc-violation-message-range-quantity-rightopen": "O valor de $1 ($2) deve ser igual ou superior a $3.", + "wbqc-violation-message-range-time-closed": "O valor de $1 ($2) deve estar entre $3 e $4.", + "wbqc-violation-message-range-time-closed-leftnow": "O valor de $1 ($2) deve estar no futuro, mas não deve ser posterior a $3.", + "wbqc-violation-message-range-time-closed-rightnow": "O valor de $1 ($2) deve estar no passado, mas não antes de $3.", + "wbqc-violation-message-range-time-leftopen": "O valor de $1 ($2) não deve ser posterior a $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "O valor de $1 ($2) não deve estar no futuro.", + "wbqc-violation-message-range-time-rightopen": "O valor de $1 ($2) não deve ser anterior a $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "O valor de $1 ($2) não deve estar no passado.", + "wbqc-violation-message-single-value": "Esta propriedade só deve conter um único valor.", + "wbqc-violation-message-single-value-separators": "Esta propriedade devia conter apenas um valor único com o mesmo {{PLURAL:$2|1=$4 qualitativo.|conjunto de qualitativos para essas propriedades: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Esta propriedade só deve conter um único valor, o \"melhor\". Dos vários valores atuais, só um pode ser marcado com a classificação \"preferido\".", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Esta propriedade só deve conter um único valor, o \"melhor\", com o mesmo {{PLURAL:$2|1=qualificador $4.|conjunto de qualificadores para estas propriedades: $3}} Dos vários valores atuais, um deve ser marcado com a classificação “preferido”.", + "wbqc-violation-message-single-best-value-multi-preferred": "Esta propriedade só deve conter um único valor, o \"melhor\". Não deve haver mais do que um valor com a classificação \"preferido\".", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Esta propriedade só deve conter um único valor, o \"melhor\", com o mesmo {{PLURAL:$2|1=qualificador $4.|conjunto de qualificadores para estas propriedades: $3}} Não deve haver mais do que um valor marcado com a classificação “preferido”.", + "wbqc-violation-message-symmetric": "$1 também deve ter a declaração simétrica $2 $3.", + "wbqc-violation-message-type-instance": "Entidades que usam a propriedade $1 devem ser instâncias de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse de|2=uma subclasse deles|uma de suas subclasses}}), mas $2 atualmente {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-type-subclass": "Entidades que usam a propriedade $1 devem ser subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse de|2=uma subclasse deles|uma de suas subclasses}}), mas $2 atualmente {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "As entidades que usam a propriedade $1 deveriam ser instâncias ou subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-instance": "Os valores das declarações de $1 devem ser instâncias de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse deles|uma das suas subclasses}}), mas $2 atualmente {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-subclass": "Os valores das declarações de $1 devem ser subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse deles|uma das suas subclasses}}), mas $2 atualmente {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Os valores de declarações $1 deveriam ser instâncias ou subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-target-required-claim": "$1 deve ter {{PLURAL:$3|0=uma declaração $2.|1=uma declaração $2 $5.|Uma declaração para $2 com um dos seguintes valores: $4}}", + "wbqc-violation-message-unique-value": "O valor dessa propriedade não deve estar presente em nenhum outro item, mas também está presente em {{PLURAL:$1|1=$3.|2=$3 e $4.|nos seguintes itens: $2}}", + "wbqc-violation-message-valueOnly": "Esta propriedade só deve ser usada para o valor principal de uma declaração, não para qualificadores ou referências.", + "wbqc-violation-message-reference": "A propriedade só deve ser usada em referências e não para o valor principal de uma declaração nem para um qualificador.", + "wbqc-violation-message-noBounds": "Os valores para $1 não devem ter limites.", + "wbqc-violation-message-units-none": "O valor de $1 não deve ter uma unidade.", + "wbqc-violation-message-units": "O valor de $1 deve ter {{PLURAL:$2|1=a unidade $4.|2=a unidade $4 ou $5.|uma das seguintes unidades: $3}}", + "wbqc-violation-message-units-or-none": "O valor de $1 deve ter {{PLURAL:$2|1=a unidade $4|2=a unidade $4 ou $5|uma das seguintes unidades}} ou {{PLURAL:$2|1=não ter unidade nenhuma.|2=não ter unidade nenhuma.|não ter unidade nenhuma: $3}}", + "wbqc-violation-message-entityType": "A propriedade $1 não deve ser usada neste tipo de entidade; {{PLURAL:$2|1=o único tipo de entidade válido é $4.|2=os únicos tipos de entidade válidos são $4 e $5.|os únicos tipos de entidade válidos são: $3}}", + "wbqc-violation-message-none-of": "O valor de $1 não deveria ser {{PLURAL:$2|1=$4.|2=$4 ou $5.|um dos seguintes:$3}}", + "wbqc-violation-message-integer": "Os valores de $1 devem ser inteiros, mas $2 tem uma parte fracionária.", + "wbqc-violation-message-integer-bounds": "Os valores para $1 devem ser inteiros, mas os valores de $2 têm uma parte fracionária.", + "wbqc-violation-message-citationNeeded": "Declarações para $1 devem ter pelo menos uma referência.", + "wbqc-violation-message-property-scope": "A propriedade $1 não deve ser usada neste local ($2). {{PLURAL:$3|O único local válido|Os únicos locais válidos}} para esta propriedade {{PLURAL:$3|é $5.|são: $4}}", + "wbqc-violation-message-exception": "Esta entidade é uma exceção conhecida para esta restrição e foi marcada como tal." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/pt.json b/dist/extensions/WikibaseQualityConstraints/i18n/pt.json new file mode 100644 index 000000000..afe304bf2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/pt.json @@ -0,0 +1,151 @@ +{ + "@metadata": { + "authors": [ + "Athena in Wonderland", + "Hamilton Abreu", + "Macofe", + "Mansil alfalb", + "Vitorvicentevalente", + "Amire80" + ] + }, + "wbqc-constraintreport": "Relatório de restrições", + "wbqc-desc": "Verifica as restrições dos objetos e das propriedades e apresenta os resultados numa página especial", + "wbqc-constraintreport-explanation-part-one": "Esta página especial realiza a verificação das restrições de qualquer entidade que queira. As entidades são extraídas do sistema real, pelo que cada violação de restrição que resolva lá será eliminada instantaneamente desta lista.", + "wbqc-constraintreport-explanation-part-two": "A análise sintática das restrições é feita a partir das declarações sobre propriedades, sempre que essas declarações são editadas e normalmente após poucos minutos.", + "wbqc-constraintreport-form-section": "Verificar as restrições da entidade", + "wbqc-constraintreport-form-submit-label": "Verificar", + "wbqc-constraintreport-form-entityid-label": "Identificador da entidade:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx ou Pxx", + "wbqc-constraintreport-result-headline": "Resultados para", + "wbqc-constraintreport-invalid-entity-id": "Identificador de entidade inválido.", + "wbqc-constraintreport-not-existent-entity": "A entidade não existe.", + "wbqc-constraintreport-empty-result": "Não há restrições definidas sobre esta entidade.", + "wbqc-constraintreport-status-violation": "Violação", + "wbqc-constraintreport-status-compliance": "Conformidade", + "wbqc-constraintreport-status-exception": "Exceção", + "wbqc-constraintreport-status-todo": "Pendente", + "wbqc-constraintreport-status-bad-parameters": "Parâmetros incorretos", + "wbqc-constraintreport-status-deprecated": "Descontinuada", + "wbqc-constraintreport-status-warning": "Aviso", + "wbqc-constraintreport-status-suggestion": "Sugestão", + "wbqc-constraintreport-status-not-in-scope": "Fora do âmbito", + "wbqc-constraintreport-result-table-header-status": "Estado", + "wbqc-constraintreport-result-table-header-property": "Propriedade", + "wbqc-constraintreport-result-table-header-message": "Mensagem", + "wbqc-constraintreport-result-table-header-constraint": "Restrição", + "wbqc-constraintreport-result-link-to-claim": "ir para a alegação", + "wbqc-constraintreport-result-link-to-constraint": "ir para a restrição", + "wbqc-constraintreport-no-parameter": "nenhum", + "wbqc-issues-short": "Problemas", + "wbqc-issues-long": "Esta declaração tem alguns problemas.", + "wbqc-potentialissues-short": "Possíveis problemas", + "wbqc-potentialissues-long": "Esta declaração tem alguns possíveis problemas.", + "wbqc-suggestions-short": "Sugestões", + "wbqc-suggestions-long": "Há algumas sugestões para melhorar esta declaração.", + "wbqc-badparameters-short": "Parâmetros incorretos", + "wbqc-badparameters-long": "Esta declaração de restrição tem alguns parâmetros inválidos.", + "wbqc-parameterissues-short": "Problemas avançados", + "wbqc-parameterissues-long": "Estes problemas estão relacionados com a definição da restrição sobre a propriedade, não com esta declaração.", + "wbqc-constrainttypehelp-short": "Ajuda", + "wbqc-constrainttypehelp-long": "Página de ajuda para este tipo de restrição", + "wbqc-constraintdiscuss-short": "Discutir", + "wbqc-constraintdiscuss-long": "Página de discussão sobre esta restrição", + "wbqc-cached-generic": "Este resultado vem da cache e pode estar desatualizado.", + "wbqc-cached-minutes": "Este resultado vem da cache e pode estar desatualizado em até {{PLURAL:$1|1=um minuto|$1 minutos}}.", + "wbqc-cached-hours": "Este resultado foi armazenado na cache e pode estar desatualizado em até {{PLURAL:$1|1=uma hora|$1 horas}}.", + "wbqc-cached-days": "Este resultado foi armazenado na cache e pode estar desatualizado em até {{PLURAL:$1|1=um dia|$1 dias}}.", + "wbqc-dataValueType-wikibase-entityid": "Identificador da entidade", + "wbq-subextension-name-wbqc": "Restrições", + "wbqc-violation-header-parameters": "Parâmetros:", + "wbqc-violations-group": "Restrições", + "wbqc-violation-message": "A verificação da restrição assinalou uma violação. Clique o ícone para obter mais informações, por favor.", + "wbqc-violation-message-not-yet-implemented": "Por razões técnicas, a verificação da restrição \"$1\" ainda não foi implementada.", + "wbqc-violation-message-security-reason": "Por motivos de segurança, não é possível verificar a restrição \"$1\" neste momento. Estamos a trabalhar numa solução.", + "wbqc-violation-message-value-needed-of-type": "As propriedades com a restrição \"$1\" têm de ter valores do tipo \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "As propriedades com a restrição \"$1\" têm de ter valores do tipo \"$2\" ou \"$3\".", + "wbqc-violation-message-parameter-needed": "As propriedades com a restrição \"$1\" necessitam de um parâmetro \"$2\".", + "wbqc-violation-message-parameters-needed-3": "As propriedades com a restrição \"$1\" necessitam dos parâmetros \"$2\", \"$3\" e \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "A entidade de destino tem de existir.", + "wbqc-violation-message-value-entity-must-exist": "A entidade de valor tem de existir.", + "wbqc-violation-message-parameter-value": "O parâmetro \"$1\" tem de ter um valor próprio, não pode conter \"no value\" (sem valor) nem \"unknown value\" (valor desconhecido).", + "wbqc-violation-message-parameter-value-or-novalue": "O parâmetro \"$1\" tem de ter um valor próprio ou \"no value\" (sem valor), mas nunca \"unknown value\" (valor desconhecido).", + "wbqc-violation-message-parameter-entity": "O valor do parâmetro \"$1\" tem de ser uma entidade, e não \"$2\".", + "wbqc-violation-message-parameter-item": "O valor do parâmetro \"$1\" tem de ser um objeto, e não \"$2\".", + "wbqc-violation-message-parameter-property": "O valor do parâmetro \"$1\" tem de ser uma propriedade, e não \"$2\".", + "wbqc-violation-message-parameter-string": "O valor do parâmetro \"$1\" tem de ser um texto, e não \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "O valor para o parâmetro \"$1\" tem de ser um texto numa única língua, não \"$2\".", + "wbqc-violation-message-parameter-single": "O parâmetro \"$1\" tem de ter um só valor.", + "wbqc-violation-message-parameter-single-per-language": "O parâmetro \"$1\" tem de ter um único valor por língua, mas tem mais do que um valor para $2 ($3).", + "wbqc-violation-message-parameter-oneof": "O parâmetro \"$1\" tem de ser {{PLURAL:$2|1=$4.|2=ou $4 ou $5.|um dos seguintes:$3}}", + "wbqc-violation-message-parameter-regex": "$1 não é uma expressão regular válida.", + "wbqc-violation-message-sparql-error": "A consulta SPARQL produziu um erro.", + "wbqc-violation-message-parameters-error-unknown": "Não foi possível importar os parâmetros desta restrição.", + "wbqc-violation-message-parameters-error-toolong": "Não foi possível importar os parâmetros desta restrição porque eram demasiado longos.", + "wbqc-violation-message-invalid-scope": "$1 não é um âmbito válido para o tipo de restrição $2; {{PLURAL:$3|o único âmbito válido|os únicos âmbitos válidos}} para este tipo de restrição {{PLURAL:$3|é $5.|2=são $5 e $6.|são: $4}}", + "wbqc-violation-message-commons-link-no-existent": "O destino da hiperligação para a wiki Commons devia existir.", + "wbqc-violation-message-commons-link-not-well-formed": "A hiperligação para a wiki Commons não pode conter caracteres inválidos.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "A verificação do espaço nominal \"$1\" ainda não está implementada.", + "wbqc-violation-message-conflicts-with-property": "Uma entidade não devia ter declarações para $1 e $2 ao mesmo tempo.", + "wbqc-violation-message-conflicts-with-claim": "Uma entidade não devia ter uma declaração para $1 se também tem uma declaração para $2 com o valor $3.", + "wbqc-violation-message-contemporary-subject-earlier": "As entidades $1 e $3 devem ser contemporâneas para serem ligadas através de $2, mas o valor final mais recente de $1 é $4 e o valor inicial mais antigo de $3 é $5.", + "wbqc-violation-message-contemporary-value-earlier": "As entidades $1 e $3 devem ser contemporâneas para serem ligadas através de $2, mas o valor final mais recente de $3 é $4 e o valor inicial mais antigo de $1 é $5.", + "wbqc-violation-message-diff-within-range": "A diferença entre $3 ($4) e $1 ($2) deveria estar compreendida entre $5 e $6.", + "wbqc-violation-message-diff-within-range-leftopen": "A diferença entre $3 ($4) e $1 ($2) deveria ser igual ou inferior a $5.", + "wbqc-violation-message-diff-within-range-rightopen": "A diferença entre $3 ($4) e $1 ($2) deveria ser igual ou superior a $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "A propriedade definida nos parâmetros tem de ter um valor do mesmo tipo que esta propriedade.", + "wbqc-violation-message-format": "O valor de $1 ($2) deveria coincidir com a expressão regular $3.", + "wbqc-violation-message-format-clarification": "O valor de $1 ($2) deveria coincidir com \"$4\" (expressão regular: $3).", + "wbqc-violation-message-inverse": "$1 também deveria ter a declaração inversa $2 $3.", + "wbqc-violation-message-item": "Uma entidade com $1 também deveria ter {{PLURAL:$3|0=uma declaração $2.|1=uma declaração $2 $5.|uma declaração para $2 com um dos seguintes valores:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Falta um qualificador $2 a esta declaração $1.", + "wbqc-violation-message-multi-value": "Esta propriedade devia conter mais do que um valor.", + "wbqc-violation-message-multi-value-separators": "Esta propriedade devia conter mais do que um valor com o mesmo {{PLURAL:$2|1=$4 qualitativo.|conjunto de qualitativos para essas propriedades: $3}}", + "wbqc-violation-message-one-of": "O valor de $1 deveria ser {{PLURAL:$2|1=$4.|2=ou $4 ou $5.|um dos seguintes:$3}}", + "wbqc-violation-message-qualifier": "A propriedade só devia ser usada como qualificador.", + "wbqc-violation-message-no-qualifiers": "As declarações $1 não deviam ter nenhum qualificador.", + "wbqc-violation-message-qualifiers": "$2 não é um qualificador válido para $1 – {{PLURAL:$3|1=o único qualificador válido é $5.|2=os únicos qualificadores válidos são $5 e $6.|os únicos qualificadores válidos são:$4}}", + "wbqc-violation-message-range-parameters-needed": "As propriedades com valores do tipo \"$1\" com a restrição \"$4\" necessitam dos parâmetros \"$2\" e \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Os extremos de um intervalo de unidades de tempo têm de ter ambos ou nenhum a unidade \"ano\", porque os anos não podem ser convertidos em segundos sem perdas.", + "wbqc-violation-message-range-parameters-same": "Os pontos iniciais ($1) e finais ($2) de uma gama não devem ser os mesmos.", + "wbqc-violation-message-range-quantity-closed": "O valor de $1 ($2) deve estar compreendido entre $3 e $4.", + "wbqc-violation-message-range-quantity-leftopen": "O valor de $1 ($2) deve ser igual ou inferior a $3.", + "wbqc-violation-message-range-quantity-rightopen": "O valor de $1 ($2) deve ser igual ou superior a $3.", + "wbqc-violation-message-range-time-closed": "O valor de $1 ($2) deve estar compreendido entre $3 e $4.", + "wbqc-violation-message-range-time-closed-leftnow": "O valor de $1 ($2) deve estar no futuro, mas não deve ser posterior a $3.", + "wbqc-violation-message-range-time-closed-rightnow": "O valor de $1 ($2) deve estar no passado, mas não antes de $3.", + "wbqc-violation-message-range-time-leftopen": "O valor de $1 ($2) não deve ser depois de $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "O valor de $1 ($2) não deve estar no futuro.", + "wbqc-violation-message-range-time-rightopen": "O valor de $1 ($2) não deve ser antes de $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "O valor de $1 ($2) não deve estar no passado.", + "wbqc-violation-message-single-value": "Esta propriedade só deve conter um único valor.", + "wbqc-violation-message-single-value-separators": "Esta propriedade devia conter apenas um valor único com o mesmo {{PLURAL:$2|1=$4 qualitativo.|conjunto de qualitativos para essas propriedades: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Esta propriedade só deve conter um único valor, o “melhor”. Dos vários valores atuais, só um pode ser marcado com a classificação “preferido”.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Esta propriedade só deve conter um único valor, o \"melhor\", com o mesmo {{PLURAL:$2|1=qualificador $4.|conjunto de qualificadores para estas propriedades: $3}} Dos vários valores atuais, um deve ser marcado com a classificação “preferido”.", + "wbqc-violation-message-single-best-value-multi-preferred": "Esta propriedade só deve conter um único valor, o “melhor”. Não deve haver mais do que um valor com a classificação “preferido”.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Esta propriedade só deve conter um único valor, o \"melhor\", com o mesmo {{PLURAL:$2|1=qualificador $4.|conjunto de qualificadores para estas propriedades: $3}} Não deve haver mais do que um valor marcado com a classificação “preferido”.", + "wbqc-violation-message-symmetric": "$1 também deveria ter a declaração simétrica $2 $3.", + "wbqc-violation-message-type-instance": "As entidades que usam a propriedade $1 deveriam ser instâncias de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-type-subclass": "As entidades que usam a propriedade $1 deveriam ser subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "As entidades que usam a propriedade $1 deveriam ser instâncias ou subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-instance": "Os valores de declarações $1 deveriam ser instâncias de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-subclass": "Os valores de declarações $1 deveriam ser subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Os valores de declarações $1 deveriam ser instâncias ou subclasses de {{PLURAL:$3|1=$5|2=$5 ou $6|uma das seguintes classes}} (ou de {{PLURAL:$3|1=uma subclasse dela|2=uma subclasse delas|uma das subclasses delas}}), mas neste momento $2 {{PLURAL:$3|1=não é.|2=não é.|não é: $4}}", + "wbqc-violation-message-target-required-claim": "$1 deveria ter {{PLURAL:$3|0=uma declaração $2.|1=uma declaração $2 $5.|uma declaração para $2 com um dos seguintes valores:$4}}", + "wbqc-violation-message-unique-value": "O valor da propriedade não pode estar presente em nenhum outro objeto, mas também está presente {{PLURAL:$1|1=em $3.|2=em $3 e $4.|nos seguintes objetos: $2}}", + "wbqc-violation-message-valueOnly": "Esta propriedade só deve ser usada para o valor principal de uma declaração, não para qualificadores nem referências.", + "wbqc-violation-message-reference": "A propriedade só deve ser usada em referências e não para o valor principal de uma declaração nem para um qualificador.", + "wbqc-violation-message-noBounds": "Os valores para $1 não devem ter limites.", + "wbqc-violation-message-units-none": "O valor de $1 não deve ter uma unidade.", + "wbqc-violation-message-units": "O valor de $1 deve ter {{PLURAL:$2|1=a unidade $4.|2=a unidade $4 ou $5.|uma das seguintes unidades: $3}}", + "wbqc-violation-message-units-or-none": "O valor de $1 deve ter {{PLURAL:$2|1=a unidade $4|2=a unidade $4 ou $5|uma das seguintes unidades}} ou {{PLURAL:$2|1=não ter unidade nenhuma.|2=não ter unidade nenhuma.|não ter unidade nenhuma: $3}}", + "wbqc-violation-message-entityType": "A propriedade $1 não deve ser usada neste tipo de entidade; {{PLURAL:$2|1=o único tipo de entidade válido é $4.|2=os únicos tipos de entidade válidos são $4 e $5.|os únicos tipos de entidade válidos são: $3}}", + "wbqc-violation-message-none-of": "O valor para $1 não deve ser {{PLURAL:$2|1=$4.|2=nem $4 nem $5.|nenhum dos seguintes: $3}}", + "wbqc-violation-message-integer": "Os valores de $1 devem ser inteiros, mas $2 tem uma parte fracionária.", + "wbqc-violation-message-integer-bounds": "Os valores de $1 devem ser inteiros, mas os limites de $2 têm uma parte fracionária.", + "wbqc-violation-message-citationNeeded": "As declarações de $1 devem ter pelo menos uma referência.", + "wbqc-violation-message-language": "As declarações da propriedade $1 só devem estar em lexemas com a língua definida como {{PLURAL:$2|1=$4.|2=$4 ou $5.|uma das seguintes: $3}}", + "wbqc-violation-message-label-lacking": "As entidades com declarações da propriedade $1 também devem ter uma etiqueta pelo menos {{PLURAL:$2|1=na língua $4.|em qualquer uma das seguintes línguas: $3}}", + "wbqc-violation-message-property-scope": "A propriedade $1 não deve ser usada neste local ($2). {{PLURAL:$3|O único local válido|Os únicos locais válidos}} para esta propriedade {{PLURAL:$3|é $5.|são: $4}}", + "wbqc-violation-message-exception": "Esta entidade é uma exceção conhecida para esta restrição e foi marcada como tal." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/qqq.json b/dist/extensions/WikibaseQualityConstraints/i18n/qqq.json new file mode 100644 index 000000000..edd754559 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/qqq.json @@ -0,0 +1,156 @@ +{ + "@metadata": { + "authors": [ + "Abián", + "Alifakoor", + "Amire80", + "BaRaN6161 TURK", + "Liuxinyu970226", + "Lucas Werkmeister (WMDE)", + "Metalhead64", + "MuratTheTurkish", + "Raymond", + "Robby", + "Verdy p" + ] + }, + "wbqc-constraintreport": "{{doc-special|ConstraintReport}}", + "wbqc-desc": "{{desc|name=Wikibase Quality Constraints|url=https://www.mediawiki.org/wiki/Extension:WikibaseQualityConstraints}}", + "wbqc-constraintreport-explanation-part-one": "Explanation (part one), what this special page does and how it gets its data.", + "wbqc-constraintreport-explanation-part-two": "Explanation (part two), what this special page does and how it gets its data.", + "wbqc-constraintreport-form-section": "Header of the section of the entity id form.", + "wbqc-constraintreport-form-submit-label": "Label of the button, that starts the check.\n{{Identical|Check}}", + "wbqc-constraintreport-form-entityid-label": "Label for the entity id input field.", + "wbqc-constraintreport-form-entityid-placeholder": "Entity id placeholder for the input field.", + "wbqc-constraintreport-result-headline": "Result headline. Label of checked entity is appended to this.", + "wbqc-constraintreport-invalid-entity-id": "Text to display when the entered entity id is invalid.", + "wbqc-constraintreport-not-existent-entity": "Text to display when the requested entity does not exist.", + "wbqc-constraintreport-empty-result": "Message that appears, when there are no constraints defined for the given entity.", + "wbqc-constraintreport-status-violation": "Status for claims that are violated against a constraint.", + "wbqc-constraintreport-status-compliance": "Status for claims that comply with a constraint", + "wbqc-constraintreport-status-exception": "Status for claims that were marked as a exception", + "wbqc-constraintreport-status-todo": "Status for constraints which cannot be checked yet.\n{{Identical|Todo}}", + "wbqc-constraintreport-status-bad-parameters": "Status for constraints that have missing or invalid constraint parameters.", + "wbqc-constraintreport-status-deprecated": "Status for constraint checks that have been skipped because the statement is deprecated.", + "wbqc-constraintreport-status-warning": "Status for statements that violate a non-mandatory constraint.\n{{Identical|Warning}}", + "wbqc-constraintreport-status-suggestion": "Status for statements that violate a suggestion constraint.", + "wbqc-constraintreport-status-not-in-scope": "Status for constraint checks that have been skipped because the kind of the snak to be checked (main snak, qualifier, or reference) is not within the scope of the constraint. This should follow the label of the “constraint scope” property ([[wikidata:Property:P4680|P4680 on Wikidata]]).", + "wbqc-constraintreport-result-table-header-status": "Header of the column that tells whether the check found a violation or something else.\n{{Identical|Status}}", + "wbqc-constraintreport-result-table-header-property": "Header of the column that shows the property of the constraint check. The constraint being checked is defined on this property.\n{{Identical|Property}}", + "wbqc-constraintreport-result-table-header-message": "Header of the column that displays the message of a constraint check result.\n{{Identical|Message}}", + "wbqc-constraintreport-result-table-header-constraint": "Header of the column that gives information about which constraint was checked.\n{{Identical|Constraint}}", + "wbqc-constraintreport-result-link-to-claim": "Text for the link to a claim group on the entity page.", + "wbqc-constraintreport-result-link-to-constraint": "Text for the link to a constraint on the property page.", + "wbqc-constraintreport-no-parameter": "Text that is displayed when there was no value for a parameter given.\n{{Identical|None}}", + "wbqc-issues-short": "Headline of the constraint report popup section for violations of mandatory constraints. These issues/problems are more severe than violations of non-mandatory constraints, which have the heading {{msg-mw|wbqc-potentialissues-short}}.\n{{Identical|Issue}}", + "wbqc-issues-long": "Title for the icon shown on statements with mandatory constraint violations, usually displayed by the browser when the user hovers over the icon with the mouse cursor.", + "wbqc-potentialissues-short": "Headline of the constraint report popup section for violations of non-mandatory constraints. Should be easy to understand for users, and convey that the reported violations are not always errors, but should be thought of as hints to the user that something might be wrong.", + "wbqc-potentialissues-long": "Title for the icon shown on statements with non-mandatory constraint violations, usually displayed by the browser when the user hovers over the icon with the mouse cursor.\n{{Related|wbqc-potentialissues-short}}\n{{Related|wbqc-issues-long}}", + "wbqc-suggestions-short": "Headline of the constraint report popup section for violations of suggestion constraints. Should be easy to understand for users, and convey that the reported violations are just suggestions for improvements to the statement, not indications of problems.", + "wbqc-suggestions-long": "Title for the icon shown on statements with suggestion constraint violations, usually displayed by the browser when the user hovers over the icon with the mouse cursor.\n{{Related|wbqc-suggestions-short}}\n{{Related|wbqc-issues-long}}", + "wbqc-badparameters-short": "Headline of the constraint parameter report popup shown on constraint statements with invalid constraint parameters.", + "wbqc-badparameters-long": "Title for the icon shown on constraint statements with invalid constraint parameters, usually displayed by the browser when the user hovers over the icon with the mouse cursor.\n{{Related|wbqc-badparameters-short}}", + "wbqc-parameterissues-short": "Headline of the section of the constraint parameter report popup that contains problems about the constraint parameters. The section is collapsed by default, since these problems are harder to understand and fix than normal constraint violations. The headline should convey that normal users are not expected to deal with these problems.\n\nThese problems are also displayed on property pages in a separate popup: see {{msg-mw|wbqc-badparameters-short}} / {{msg-mw|wbqc-badparameters-long}}.", + "wbqc-parameterissues-long": "Longer explanation of the section of the constraint parameter report popup that contains problems about the constraint parameters.\n{{Related|wbqc-parameterissues-short}}", + "wbqc-constrainttypehelp-short": "Text for the help link shown next to the constraint type in a constraint violation report. The link leads to a help page on Wikidata about the constraint type.\n{{Identical|Help}}", + "wbqc-constrainttypehelp-long": "Title for the help link shown next to the constraint type in a constraint violation report. The link leads to a help page on Wikidata about the constraint type.\n{{Related|wbqc-constrainttypehelp-short}}", + "wbqc-constraintdiscuss-short": "Text for the discussion link shown next to the constraint type in a constraint violation report. The link leads to the talk page of the property on which the constraint is defined.\n{{Identical|Discuss}}", + "wbqc-constraintdiscuss-long": "Title for the discussion link shown next to the constraint type in a constraint violation report. The link leads to the talk page of the property on which the constraint is defined.\n{{Related|wbqc-constraintdiscuss-short}}", + "wbqc-cached-generic": "Generic message informing the user that a constraint check result might be outdated. There is no information on how old the cached result is; if more information is available, a more specific message is used.", + "wbqc-cached-minutes": "Message informing the user that a constraint check result might be outdated by up to ''n'' minutes.\n{{Related|wbqc-cached-generic}}", + "wbqc-cached-hours": "Message informing the user that a constraint check result might be outdated by up to ''n'' hours.\n{{Related|Wbqc-cached}}", + "wbqc-cached-days": "Message informing the user that a constraint check result might be outdated by up to ''n'' days.\n{{Related|wbqc-cached-minutes}}\n{{Related|wbqc-cached-generic}}", + "wbqc-dataValueType-wikibase-entityid": "The name of a data value type.\n{{related|Wbqc-dataValueType-wikibase}}", + "wbq-subextension-name-wbqc": "Name of this subextension. Is shown in special page that lists all the violations.\n{{Identical|Constraint}}", + "wbqc-violation-header-parameters": "Header for section in violations special page that displays the parameters of the constraint.\n{{Identical|Parameter}}", + "wbqc-violations-group": "Type of violations this extension finds.\n{{Identical|Constraint}}", + "wbqc-violation-message": "Generic message to tell that there was a violation.", + "wbqc-violation-message-not-yet-implemented": "Message for when a check is yet to be implemented. Not actually a violation, more of a todo.", + "wbqc-violation-message-security-reason": "Message for when a check is not possible due to security reasons. Not actually a violation, more of a todo.", + "wbqc-violation-message-value-needed-of-type": "Message for when a property needs a value of a specific type (like string or wikibase-entityid), but it doesn't.", + "wbqc-violation-message-value-needed-of-types-2": "Message for when a property needs a value of one of two specific types (like string or wikibase-entityid), but it doesn't.", + "wbqc-violation-message-parameter-needed": "Message for when a constraint needs a specific parameter, but it's missing.", + "wbqc-violation-message-parameters-needed-3": "Message for when a constraint needs three specific parameters, but some of them are missing.", + "wbqc-violation-message-target-entity-must-exist": "Message for when an entity is referenced, but it doesn't exist (any more).", + "wbqc-violation-message-value-entity-must-exist": "Message for when the property has an entity as its value, but it doesn't exist (any more).", + "wbqc-violation-message-parameter-value": "Message for when \"no value\" or \"unknown value\" has been entered as the value of a constraint parameter that must be an actual value. $1 contains the parameter.", + "wbqc-violation-message-parameter-value-or-novalue": "Message for when \"unknown value\" has been entered as the value of a constraint parameter that must be an actual value or \"no value\". $1 contains the parameter.\n{{Related|wbqc-violation-message-parameter-value}}", + "wbqc-violation-message-parameter-entity": "Message for when the value of a constraint parameter must be an entity, but is some other kind of data value. $1 contains the parameter, $2 the value.", + "wbqc-violation-message-parameter-item": "Message for when the value of a constraint parameter must be an item, but is some other kind of entity. $1 contains the parameter, $2 the value.\n{{Related|wbqc-violation-message-parameter-entity}}", + "wbqc-violation-message-parameter-property": "Message for when the value of a constraint parameter must be a property, but is some other kind of entity. $1 contains the parameter, $2 the value.\n{{Related|wbqc-violation-message-parameter-entity}}", + "wbqc-violation-message-parameter-string": "Message for when the value of a constraint parameter must be a string, but is some other value type. $1 contains the parameter, $2 the value.", + "wbqc-violation-message-parameter-monolingualtext": "Message for when the value of a constraint parameter must be a monolingual text, but is some other value type. Parameters:\n* $1 contains the parameter.\n* $2 contains the value.", + "wbqc-violation-message-parameter-single": "Message for when a constraint parameter has multiple values but only supports one. $1 contains the parameter.", + "wbqc-violation-message-parameter-single-per-language": "Message for when a constraint parameter has multiple values with the same language but only supports one value per language. (This is, in effect, used to construct a multilingual text from several monolingual texts.) Parameters:\n* $1 is the parameter.\n* $2 is the language name in the language itself (autonym), e. g. “English” or “français cadien” (without any quotation marks).\n* $3 is the language code, e. g. en or frc.\n{{Related|wbqc-violation-message-parameter-single}}", + "wbqc-violation-message-parameter-oneof": "Message for when a constraint parameter must be one of several values, but is something different. $1 contains the parameter, $2 the number of allowed values (possibly 1), $3 an HTML list of all allowed values, and $4, $5 etc. are the individual allowed values.\n{{Related|wbqc-violation-message-one-of}}", + "wbqc-violation-message-parameter-regex": "Message for when a constraint parameter must be a valid regular expression, but has an error. $1 contains the parameter value.", + "wbqc-violation-message-sparql-error": "Message for when a constraint checker runs a SPARQL query but the SPARQL endpoint returns an error instead of query results.", + "wbqc-violation-message-parameters-error-unknown": "Message for when the constraint parameters of a constraint could not be imported, but the reason is unknown.n", + "wbqc-violation-message-parameters-error-toolong": "Message for when the constraint parameters of a constraint could not be imported because they were too long to be stored in the database.", + "wbqc-violation-message-invalid-scope": "Message for when a constraint specifies a scope that is not valid for this constraint type, such as a “constraint checked on qualifiers” scope on a “used as reference” constraint. Parameters:\n* $1 is the invalid scope.\n* $2 is the constraint type.\n* $3 is the number of valid scopes.\n* $4 is an HTML list of all valid scopes for this constraint type.\n* $5, $6 etc. are the individual valid scopes for this constraint type.\nThis should follow the label of the “constraint scope” property ([[wikidata:Property:P4680|P4680 on Wikidata]]), similar to {{msg-mw|wbqc-constraintreport-status-not-in-scope}}.", + "wbqc-violation-message-commons-link-no-existent": "Message for violation of Commons link constraint. When linked commons page does not exist.", + "wbqc-violation-message-commons-link-not-well-formed": "Message for violation of Commons link constraint. When link contains invalid characters.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Message for when the check for the Commons link constraint has not yet been implemented for a specific namespace.", + "wbqc-violation-message-conflicts-with-property": "Message for a violation of the “Conflicts with” constraint, when there is a statement with a conflicting property. $1 contains the property of the current statement (which has the constraint), and $2 contains the conflicting property.", + "wbqc-violation-message-conflicts-with-claim": "Message for a violation of the “Conflicts with” constraint, when there is a conflicting statement. $1 contains the property of the current statement (which has the constriant), $2 contains the property of the conflicting statement, and $3 contains the value of the conflicting statement.\n{{Related|Wbqc-violation-message-conflicts-with-property}}", + "wbqc-violation-message-contemporary-subject-earlier": "Message for a violation of the “Contemporary” constraint, when the linked entities are not contemporary. Parameters:\n* $1 is the subject entity.\n* $2 is the property of the statement with the constraint.\n* $3 is the value entity.\n* $4 is the end time value of the subject entity.\n* $5 is the start time value of the value entity.\n{{Related|Wbqc-violation-message-contemporary-subject-earlier}}", + "wbqc-violation-message-contemporary-value-earlier": "Message for a violation of the “Contemporary” constraint, when the linked entities are not contemporary. Parameters:\n* $1 is the subject entity.\n* $2 is the property of the statement with the constraint.\n* $3 is the value entity.\n* $4 is the end time value of the value entity.\n* $5 is the start time value of the subject entity.\n{{Related|Wbqc-violation-message-contemporary-subject-earlier}}", + "wbqc-violation-message-diff-within-range": "Message for a violation of the “Diff within range” constraint, when the difference between two values is smaller or larger than allowed (for a range with both limits). Parameters:\n* $1 is the first property.\n* $2 is the value of the first property.\n* $3 is the second property.\n* $4 is the value of the second property.\n* $5 is the lower bound of the range (inclusive).\n* $6 is the upper bound of the range (inclusive).\nThe “first property” is the one referenced in the constraint, and the “second property” is the one that the constraint is placed on. The difference is calculated as “second property” − “first property” ($4 − $2).", + "wbqc-violation-message-diff-within-range-leftopen": "Message for a violation of the “Diff within range” constraint, when the difference between two values is larger than allowed (for a range with an upper but no lower limit). Parameters:\n* $1 is the first property.\n* $2 is the value of the first property.\n* $3 is the second property.\n* $4 is the value of the second property.\n* $5 is the upper bound of the range (inclusive).\nThe “first property” is the one referenced in the constraint, and the “second property” is the one that the constraint is placed on. The difference is calculated as “second property” − “first property” ($4 − $2).\n{{Related|wbqc-violation-message-diff-within-range}}", + "wbqc-violation-message-diff-within-range-rightopen": "Message for a violation of the “Diff within range” constraint, when the difference between two values is larger than allowed (for a range with a lower but no upper limit). Parameters:\n* $1 is the first property.\n* $2 is the value of the first property.\n* $3 is the second property.\n* $4 is the value of the second property.\n* $5 is the lower bound of the range (inclusive).\nThe “first property” is the one referenced in the constraint, and the “second property” is the one that the constraint is placed on. The difference is calculated as “second property” − “first property” ($4 − $2).\n{{Related|wbqc-violation-message-diff-within-range}}", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Message for violation of Diff within range constraint. When this and the given property differ in value type.", + "wbqc-violation-message-format": "Message for a violation of the “Format” constraint, when the value of a statement does not match a certain pattern (“regex” is short for “regular expression”). Parameters:\n* $1 is the property of the statement that has the constraint.\n* $2 is the text value of the statement.\n* $3 is the regex.\nThis message is only used if no syntax clarification for the regex has been provided; if a syntax clarification is available, {{msg-mw|wbqc-violation-message-format-clarification}} is used instead.", + "wbqc-violation-message-format-clarification": "Message for a violation of the “Format” constraint, when the value of a statement does not match a certain pattern (“regex” is short for “regular expression”). Parameters:\n* $1 is the property of the statement that has the constraint.\n* $2 is the text value of the statement.\n* $3 is the regex.\n* $4 is a human-readable explanation of the regex in the user’s language or a fallback language (possibly English).\n{{Related|wbqc-violation-message-format}}", + "wbqc-violation-message-inverse": "Message for a violation of the “Inverse” constraint, when the inverse statement of a statement does not exist. $1, $2 and $3 contain the expected subject entity, property, and target entity of the missing inverse statement.", + "wbqc-violation-message-item": "Message for a violation of the “Item” constraint, when the subject entity of a statement is missing another statement. Parameters:\n* $1 is the property of the statement that has the constraint.\n* $2 is the property of the missing statement.\n* $3 is the number of values permitted for the missing statement (or 0, in which case the constraint only specifies that there should be a statement but not the values it should have).\n* $4 is an HTML list of all values permitted for the missing statement.\n* $5, $6 etc. are the individual values permitted for the missing statement.\n{{Related|wbqc-violation-message-target-required-claim}}", + "wbqc-violation-message-mandatory-qualifier": "Message for a violation of the “Mandatory qualifier” constraint, when a mandatory qualifier is missing on a statement. Parameters:\n* $1 is the property of the statement.\n* $2 is the missing qualifier.", + "wbqc-violation-message-multi-value": "Message for a violation of the “multi value” constraint, when only one value exists. Parameters:\n* $1 is the property of the statement.", + "wbqc-violation-message-multi-value-separators": "Message for a violation of the “multi value” constraint, when only one value with the same set of qualifiers exists. Parameters:\n* $1 is the property of the statement.\n* $2 is the number of separator properties.\n* $3 is an HTML list of all separator properties.\n* $4, $5 etc. are the individual separator properties.", + "wbqc-violation-message-one-of": "Message for a violation of the “One of” constraint, when the value is not one of the allowed values. Parameters:\n* $1 is the property that has the constraint.\n* $2 is the number of allowed values (note that certain constraints have only a single allowed value).\n* $3 is an HTML list of all allowed values.\n* $4, $5 etc. are the individual allowed values.", + "wbqc-violation-message-qualifier": "Message for violation of Qualifier constraint. When the property is used in a claim.", + "wbqc-violation-message-no-qualifiers": "Message for a violation of the “Qualifiers” constraint, when a statement has a qualifier but the property has no permitted qualifiers. This is a special case of {{msg-mw|wbqc-violation-message-qualifiers}}. Parameters:\n* $1 is the qualifier property that is not permitted.\n{{Related|wbqc-violation-message-qualifiers}}", + "wbqc-violation-message-qualifiers": "Message for a violation of the “Qualifiers” constraint, when a statement has a qualifier that is not permitted. Parameters:\n* $1 is the property of the statement.\n* $2 is the qualifier property that is not permitted.\n* $3 is the number of permitted qualifiers. (This number is always greater than zero, since the special case of no permitted qualifiers is handled by the separate message {{msg-mw|wbqc-violation-message-no-qualifiers}}.)\n* $4 is an HTML list of all permitted qualifiers.\n* $5, $6 etc. are the individual permitted qualifiers.\n{{Related|wbqc-violation-message-no-qualifiers}}", + "wbqc-violation-message-range-parameters-needed": "Message for when a constraint needs two specific parameters to form a range, but one or both of them are missing. Parameters:\n* $1 is the data type (\"quantity\" or \"time\").\n* $2 is the parameter needed for the lower boundary.\n* $3 is the parameter needed for the upper boundary.\n* $4 is the constraint type name (\"Range\" or \"Diff within range\").", + "wbqc-violation-message-range-parameters-one-year": "Message for when a constraint has two parameters to form a range, and one of the parameters has the unit “year” and the other one has a different unit (e. g. “seconds”). Because years cannot be losslessly converted to other time units (due to leap years), this is not allowed: either both range endpoints should have the unit “year”, or both should have a different unit.", + "wbqc-violation-message-range-parameters-same": "Message for when the valid range defined by two constraint parameters is empty because the two parameters contain the same value. Special cases of this message are ranges open on both sides (no lower and no upper boundary), or ranges where both endpoints are the special value “now”. Parameters: \n* $1 is the parameter for the lower boundary of the range.\n* $2 is the parameter for the upper boundary of the range.", + "wbqc-violation-message-range-quantity-closed": "Message for a violation of the “Range” constraint, when the value of a statement is smaller or larger than allowed (for a quantity range with both limits). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the lower bound of the range (inclusive).\n* $4 is the upper bound of the range (inclusive).", + "wbqc-violation-message-range-quantity-leftopen": "Message for a violation of the “Range” constraint, when the value of a statement is larger than allowed (for a quantity range with an upper but no lower limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the upper bound of the range (inclusive).", + "wbqc-violation-message-range-quantity-rightopen": "Message for a violation of the “Range” constraint, when the value of a statement is smaller than allowed (for a quantity range with a lower but no upper limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the lower bound of the range (inclusive).", + "wbqc-violation-message-range-time-closed": "Message for a violation of the “Range” constraint, when the value of a statement is earlier or later than allowed (for a time range with both limits). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the lower bound of the range (inclusive).\n* $4 is the upper bound of the range (inclusive).", + "wbqc-violation-message-range-time-closed-leftnow": "Message for a violation of the “Range” constraint, when the value of a statement is earlier or later than allowed (for a time range with both limits, where the lower (left) limit is the current day). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the upper bound of the range (inclusive).", + "wbqc-violation-message-range-time-closed-rightnow": "Message for a violation of the “Range” constraint, when the value of a statement is earlier or later than allowed (for a time range with both limits, where the upper (right) limit is the current day). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the lower bound of the range (inclusive).", + "wbqc-violation-message-range-time-leftopen": "Message for a violation of the “Range” constraint, when the value of a statement is later than allowed (for a time range with an upper but no lower limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the upper bound of the range (inclusive).", + "wbqc-violation-message-range-time-leftopen-rightnow": "Message for a violation of the “Range” constraint, when the value of a statement is later than allowed (for a time range with no lower limit and the current day as the upper limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n{{Related|wbqc-violation-message-range-time-leftopen}}\n{{Related|wbqc-violation-message-range-time-rightopen-leftnow}}", + "wbqc-violation-message-range-time-rightopen": "Message for a violation of the “Range” constraint, when the value of a statement is earlier than allowed (for a time range with a lower but no upper limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n* $3 is the lower bound of the range (inclusive).", + "wbqc-violation-message-range-time-rightopen-leftnow": "Message for a violation of the “Range” constraint, when the value of a statement is earlier than allowed (for a time range with no upper limit and the current day as the lower limit). Parameters:\n* $1 is the property of the statement.\n* $2 is the value of the statement.\n{{Related|wbqc-violation-message-range-time-rightopen}}\n{{Related|wbqc-violation-message-range-time-leftopen-rightnow}}", + "wbqc-violation-message-single-value": "Message for a violation of the “single value” constraint, when more than one value exists. Parameters:\n* $1 is the property of the statement.", + "wbqc-violation-message-single-value-separators": "Message for a violation of the “single value” constraint, when more than one value with the same set of qualifiers exists. Parameters:\n* $1 is the property of the statement.\n* $2 is the number of separator properties.\n* $3 is an HTML list of all separator properties.\n* $4, $5 etc. are the individual separator properties.", + "wbqc-violation-message-single-best-value-no-preferred": "Message for a violation of the “Single best value” constraint, when there are multiple statements and none of them have preferred rank.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Message for a violation of the “Single best value” constraint, when there are multiple statements with the same set of qualifiers and none of them have preferred rank. Parameters:\n* $1 is the property of the statement.\n* $2 is the number of separator properties.\n* $3 is an HTML list of all separator properties.\n* $4, $5 etc. are the individual separator properties.", + "wbqc-violation-message-single-best-value-multi-preferred": "Message for a violation of the “Single best value” constraint, when there are multiple statements with preferred rank.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Message for a violation of the “Single best value” constraint, when there are multiple statements with the same set of qualifiers and with preferred rank. Parameters:\n* $1 is the property of the statement.\n* $2 is the number of separator properties.\n* $3 is an HTML list of all separator properties.\n* $4, $5 etc. are the individual separator properties.", + "wbqc-violation-message-symmetric": "Message for a violation of the “Symmetric” constraint, when the symmetric statement of a statement does not exist. $1, $2 and $3 contain the expected subject entity, property, and target entity of the missing symmetric statement.", + "wbqc-violation-message-type-instance": "Message for a violation of the “Type” constraint, when the subject of a statement should be an instance of a certain type but isn't. $1 is the property of the statement, $2 is the subject of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-type-instance}}", + "wbqc-violation-message-type-subclass": "Message for a violation of the “Type” constraint, when the subject of a statement should be a subclass of a certain type but isn't. $1 is the property of the statement, $2 is the subject of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-type-instance}}", + "wbqc-violation-message-type-instanceOrSubclass": "Message for a violation of the “Type” constraint, when the subject of a statement should be an instance or a subclass of a certain type but isn't. $1 is the property of the statement, $2 is the subject of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-type-instance}}", + "wbqc-violation-message-valueType-instance": "Message for a violation of the “Value type” constraint, when the value of a statement should be an instance of a certain type but isn't. $1 is the property of the statement, $2 is the value of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-valueType-instance}}", + "wbqc-violation-message-valueType-subclass": "Message for a violation of the “Value type” constraint, when the value of a statement should be a subclass of a certain type but isn't. $1 is the property of the statement, $2 is the value of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-valueType-instance}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Message for a violation of the “Value type” constraint, when the value of a statement should be an instance or a subclass of a certain type but isn't. $1 is the property of the statement, $2 is the value of the statement, $3 is the number of classes, $4 is an HTML list of all classes, and $5, $6 etc. are the individual classes.\n{{Related|wbqc-violation-message-valueType-instance}}", + "wbqc-violation-message-target-required-claim": "Message for a violation of the “Target required claim” constraint, when the target entity of a statement is missing an expected statement. Parameters:\n* $1 is the subject entity of the missing statement, i. e. the target entity of the statement that has the constraint.\n* $2 is the property of the missing statement.\n* $3 is the number of values permitted for the missing statement (or 0, in which case the constraint only specifies that there should be a statement but not the values it should have).\n* $4 is an HTML list of all values permitted for the missing statement.\n* $5, $6 etc. are the individual values permitted for the missing statement.\n{{Related|wbqc-violation-message-item}}", + "wbqc-violation-message-unique-value": "Message for violation of the Unique Value constraint, when other items are found. Parameters:\n* $1 is the number of other items with the same value.\n* $2 is an HTML list of all other items found with the same value.\n* $3, $4 etc. are the individual other items with the same value.", + "wbqc-violation-message-valueOnly": "Message for a violation of the “used for values only” constraint, when a property intended for the main value only was used in a qualifier or reference.\n{{Related|Wbqc-violation-message-valueOnly}}", + "wbqc-violation-message-reference": "Message for a violation of the “used as reference” constraint, when a property intended for references only was used for the main value or in a qualifier.\n{{Related|Wbqc-violation-message-valueOnly}}", + "wbqc-violation-message-noBounds": "Message for a violation of the “no bounds” constraint, when a property intended to have unbounded quantities as its value. Parameters:\n* $1 is the property which has the constraint.", + "wbqc-violation-message-units-none": "Message for a violation of the “allowed units” constraint, when a property should not be used with any units but the value has a unit. Parameters:\n* $1 is the property ID of the property to which the constraint applies.\n{{Related|Wbqc-violation-message-units-none}}", + "wbqc-violation-message-units": "Message for a violation of the “allowed units” constraint, when a property should be used with a certain set of units but the value has a different unit or is unitless. Parameters:\n* $1 is the property ID of the property to which the constraint applies.\n* $2 is the number of allowed units.\n* $3 is an HTML list of all allowed units.\n* $4, $5 etc. are the individual allowed units.\n{{Related|Wbqc-violation-message-units-none}}", + "wbqc-violation-message-units-or-none": "Message for a violation of the “allowed units” constraint, when a property should be used with a certain set of units (including “no value”, permitting unitless values) but the value has a different unit. Parameters:\n* $1 is the property ID of the property to which the constraint applies.\n* $2 is the number of allowed units.\n* $3 is an HTML list of all allowed units.\n* $4, $5 etc. are the individual allowed units.", + "wbqc-violation-message-entityType": "Message for a violation of the “entity type” constraint, when a property should only be used in limited number entity types and not all. Parameters:\n* $1 is the property which has the constraint.\n* $2 is the number of acceptable entity types.\n* $3 is an HTML list of all acceptable entity types.\n* $4, $5 etc. are the individual acceptable entity types.", + "wbqc-violation-message-none-of": "Message for a violation of the “none of” constraint, when the value is one of the disallowed values. Parameters:\n* $1 is the property of the statement.\n* $2 the number of disallowed values (note that certain constraints might have only a single disallowed value).\n* $3 is an HTML list of all disallowed values.\n* $4, $5 etc. are the individual disallowed values.", + "wbqc-violation-message-integer": "Message for a violation of the “integer” constraint, when a property should have integer quantities as its value but the value is not integer. Parameters:\n* $1 is the property which has the constraint.\n* $2 is the value of the statement.", + "wbqc-violation-message-integer-bounds": "Message for a violation of the “integer” constraint, when a property should have integer quantities as its value and the value is integer but its bounds are not (for example: 10±0.5). Parameters:\n* $1 is the property which has the constraint.\n* $2 is the value of the statement.", + "wbqc-violation-message-citationNeeded": "Message for a violation of the “citation needed” constraint, when a property intended to have at least one reference for its values. Parameters:\n* $1 is the property which has the constraint.", + "wbqc-violation-message-language": "Message for a violation of the “lexeme language” constraint, when property can be used only on lexemes with language set to a limited number of values. Parameters:\n* $1 is the property of the statement.\n* $2 the number of languages allowed.\n* $3 is an HTML list of all languages.\n* $4, $5 etc. are the individual languages.", + "wbqc-violation-message-label-lacking": "Message for a violation of the “label in language” constraint, when property can be used only on entities having label at least in those languages. Parameters:\n* $1 is the property of the statement.\n* $2 the number of languages required.\n* $3 is an HTML list of all languages.\n* $4, $5 etc. are the individual languages.", + "wbqc-violation-message-property-scope": "Message for a violation of the “property scope” constraint, when a property has been used in a location where it is not intended to be used.\n\nThere are three types of locations, each represented by an item:\n* the main value of a statement\n* the qualifiers of a statement\n* the references of a statement\nPlease avoid phrasing the message in a way that depends on the labels of those items, since they may change in the future (i. e., don’t try to use them to build full sentences, even though the current labels might allow it).\n\nParameters:\n* $1 is the property that has been used in an unexpected location.\n* $2 is the location where the property was found.\n* $3 is the number of allowed locations for the property.\n* $4 is an HTML list of all allowed locations for the property.\n* $5, $6 etc. are the individual allowed locations for the property.", + "wbqc-violation-message-exception": "Message for a constraint check result on an entity that has been marked as an exception to the constraint. This message only appears on [[Special:ConstraintReport]]; the gadget does not show exception reports." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ro.json b/dist/extensions/WikibaseQualityConstraints/i18n/ro.json new file mode 100644 index 000000000..5680136b9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ro.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Matrafox" + ] + }, + "wbqc-potentialissues-short": "Posibile erori", + "wbqc-potentialissues-long": "Aceasta afirmație poate conține erori.", + "wbqc-violation-message-no-qualifiers": "Declarațiile $1 nu trebuie să conțină calificative." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/roa-tara.json b/dist/extensions/WikibaseQualityConstraints/i18n/roa-tara.json new file mode 100644 index 000000000..3aaea917b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/roa-tara.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "wbqc-constraintreport": "Elenghe de le vingole", + "wbqc-desc": "Condrolle le vingole sus a le eleminde e sus a le probbietà e face 'ndrucà le resultate jndr'à 'na pàgena speciale", + "wbqc-constraintreport-form-section": "Condrolle le vingole pe entità", + "wbqc-constraintreport-form-submit-label": "Verifiche", + "wbqc-constraintreport-form-entityid-label": "ID de l'entità:", + "wbqc-constraintreport-result-headline": "Resultate pe", + "wbqc-constraintreport-invalid-entity-id": "ID de l'entità non valide.", + "wbqc-constraintreport-not-existent-entity": "L'entità non g'esiste.", + "wbqc-constraintreport-empty-result": "Non ge stonne vingole definite sus a st'entità.", + "wbqc-constraintreport-status-violation": "Violazione", + "wbqc-constraintreport-status-compliance": "Conforme", + "wbqc-constraintreport-status-exception": "Eccezzione", + "wbqc-constraintreport-status-todo": "Da fà", + "wbqc-constraintreport-status-bad-parameters": "Parametre sbagghiate", + "wbqc-constraintreport-status-deprecated": "Sconzigliate", + "wbqc-constraintreport-status-warning": "Avvertimende", + "wbqc-constraintreport-result-table-header-status": "State", + "wbqc-constraintreport-result-table-header-constraint": "Vingole", + "wbqc-constraintreport-result-link-to-claim": "vèje a l'asserzione", + "wbqc-constraintreport-result-link-to-constraint": "vèje a 'u vingole", + "wbqc-constraintreport-no-parameter": "ninde", + "wbqc-constrainttypehelp-short": "Aijute" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ru.json b/dist/extensions/WikibaseQualityConstraints/i18n/ru.json new file mode 100644 index 000000000..29b8f92e3 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ru.json @@ -0,0 +1,158 @@ +{ + "@metadata": { + "authors": [ + "Fenixs-ru", + "Happy13241", + "Kaganer", + "Kareyac", + "Michgrig", + "Movses", + "Okras", + "Ole Yves", + "Redredsonia", + "Stjn", + "Александр Сигачёв", + "Дмитрий", + "Facenapalm" + ] + }, + "wbqc-constraintreport": "Отчёт об ограничениях", + "wbqc-desc": "Проверяет элементы и свойства на ограничения и отображает результат на служебной странице.", + "wbqc-constraintreport-explanation-part-one": "Эта служебная страница выполняет проверку ограничений для любой заданной сущности. Сущности подгружаются наживую, поэтому исправленные нарушения тут же пропадут из этого списка.", + "wbqc-constraintreport-explanation-part-two": "Ограничения подгружаются из утверждений на страницах свойств каждый раз, когда они меняются — как правило, это занимает несколько минут.", + "wbqc-constraintreport-form-section": "Проверить ограничения для сущности", + "wbqc-constraintreport-form-submit-label": "Проверить", + "wbqc-constraintreport-form-entityid-label": "Идентификатор сущности:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx или Pxx", + "wbqc-constraintreport-result-headline": "Результат для", + "wbqc-constraintreport-invalid-entity-id": "Недопустимый идентификатор сущности.", + "wbqc-constraintreport-not-existent-entity": "Сущность не существует.", + "wbqc-constraintreport-empty-result": "Ограничения для этой сущности не определены.", + "wbqc-constraintreport-status-violation": "Нарушение", + "wbqc-constraintreport-status-compliance": "Соответствие", + "wbqc-constraintreport-status-exception": "Исключение", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Неверные параметры", + "wbqc-constraintreport-status-deprecated": "Устаревший", + "wbqc-constraintreport-status-warning": "Предупреждение", + "wbqc-constraintreport-status-suggestion": "Совет", + "wbqc-constraintreport-status-not-in-scope": "Вне области действия", + "wbqc-constraintreport-result-table-header-status": "Состояние", + "wbqc-constraintreport-result-table-header-property": "Свойство", + "wbqc-constraintreport-result-table-header-message": "Сообщение", + "wbqc-constraintreport-result-table-header-constraint": "Ограничение", + "wbqc-constraintreport-result-link-to-claim": "перейти к утверждению", + "wbqc-constraintreport-result-link-to-constraint": "перейти к ограничению", + "wbqc-constraintreport-no-parameter": "нет", + "wbqc-issues-short": "Проблемы", + "wbqc-issues-long": "У этого утверждения обнаружен ряд проблем.", + "wbqc-potentialissues-short": "Возможные проблемы", + "wbqc-potentialissues-long": "У этого утверждения обнаружен ряд возможных проблем.", + "wbqc-suggestions-short": "Предложения", + "wbqc-suggestions-long": "Советы по улучшению этого утверждения.", + "wbqc-badparameters-short": "Неверные параметры", + "wbqc-badparameters-long": "Некоторые параметры этого ограничения заданы некорректно.", + "wbqc-parameterissues-short": "Дополнительные проблемы", + "wbqc-parameterissues-long": "Эти проблемы связаны с определением ограничения на странице свойства, а не с данным утверждением.", + "wbqc-constrainttypehelp-short": "Справка", + "wbqc-constrainttypehelp-long": "Страница справки этого типа ограничений", + "wbqc-constraintdiscuss-short": "Обсудить", + "wbqc-constraintdiscuss-long": "Страница обсуждения этого ограничения", + "wbqc-cached-generic": "Результат прокэширован и может отставать.", + "wbqc-cached-minutes": "Результат прокэширован и может отставать на {{PLURAL:$1|1=одну минуту|$1 минуты|$1 минут}}.", + "wbqc-cached-hours": "Результат прокэширован и может отставать на {{PLURAL:$1|1=один час|$1 часа|$1 часов}}.", + "wbqc-cached-days": "Результат прокэширован и может отставать на {{PLURAL:$1|1=один день|$1 дня|$1 дней}}.", + "wbqc-dataValueType-wikibase-entityid": "Идентификатор сущности", + "wbq-subextension-name-wbqc": "Ограничения", + "wbqc-violation-header-parameters": "Параметры:", + "wbqc-violations-group": "Ограничения", + "wbqc-violation-message": "Проверка на ограничения обнаружила нарушение. Пожалуйста, кликните на иконку для получения дополнительной информации.", + "wbqc-violation-message-not-yet-implemented": "По техническим причинам проверка ограничения «$1» ещё не была реализована.", + "wbqc-violation-message-security-reason": "Из соображений безопасности проверка ограничения «$1» в данный момент недоступна. Мы работаем над решением этой проблемы.", + "wbqc-violation-message-value-needed-of-type": "Свойства с ограничением «$1» должны иметь значения типа «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Свойства с ограничением «$1» должны иметь значения типа «$2» или «$3».", + "wbqc-violation-message-parameter-needed": "Свойствам с ограничением «$1» требуется параметр «$2».", + "wbqc-violation-message-parameters-needed-3": "Свойствам с ограничением «$1» требуются параметры «$2», «$3» и «$4».", + "wbqc-violation-message-target-entity-must-exist": "Целевая сущность должна существовать.", + "wbqc-violation-message-value-entity-must-exist": "Сущность значения должна существовать.", + "wbqc-violation-message-parameter-value": "Значение параметра «$1» должно быть задано, а не установлено в «нет значения» или «значение неизвестно».", + "wbqc-violation-message-parameter-value-or-novalue": "Значение параметра «$1» должно быть задано или установлено в «нет значения», но не в «значение неизвестно».", + "wbqc-violation-message-parameter-entity": "Значение параметра «$1» должно быть сущностью, а не «$2».", + "wbqc-violation-message-parameter-item": "Значение параметра «$1» должно быть элементом, а не «$2».", + "wbqc-violation-message-parameter-property": "Значение параметра «$1» должно быть свойством, а не «$2».", + "wbqc-violation-message-parameter-string": "Значение параметра «$1» должно быть строковым, а не «$2».", + "wbqc-violation-message-parameter-monolingualtext": "Значение параметра «$1» должно быть одноязычным текстом, а не «$2».", + "wbqc-violation-message-parameter-single": "Параметр «$1» должен содержать одно значение.", + "wbqc-violation-message-parameter-single-per-language": "Параметр «$1» должен содержать по одному значению на язык, но для языка $2 ($3) задано несколько значений.", + "wbqc-violation-message-parameter-oneof": "Параметр «$1» должен {{PLURAL:$2|1=иметь значение $4.|2=иметь значение $4 или $5.|иметь одно из следующих значений:$3}}", + "wbqc-violation-message-parameter-regex": "$1 не является корректным регулярным выражением.", + "wbqc-violation-message-sparql-error": "Запрос SPARQL выдал ошибку.", + "wbqc-violation-message-parameters-error-unknown": "Не удалось импортировать параметры данного ограничения.", + "wbqc-violation-message-parameters-error-toolong": "Не удалось импортировать параметры данного ограничения, поскольку они были слишком длинными.", + "wbqc-violation-message-invalid-scope": "$1 не является корректной областью действия для ограничения типа $2; для этого типа {{PLURAL:$3|допустима|допустимы}} только {{PLURAL:$3|область действия $5.|2=области действия $5 и $6.|следующие области действия: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Ссылка на Викисклад должна существовать.", + "wbqc-violation-message-commons-link-not-well-formed": "Ссылка на Викисклад должна быть правильно оформлена.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Проверка для пространства имён «$1» ещё не реализована.", + "wbqc-violation-message-conflicts-with-property": "Сущность не должна одновременно содержать утверждения $1 и $2.", + "wbqc-violation-message-conflicts-with-claim": "Сущность не должна содержать утверждение $1, если задано утверждение $2 со значением $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Сущности $1 и $3 должны быть современниками для связи через $2, однако $1 заканчивается $4, а $3 начинается $5.", + "wbqc-violation-message-contemporary-value-earlier": "Сущности $1 и $3 должны быть современниками для связи через $2, однако $3 заканчивается $4, а $1 начинается $5.", + "wbqc-violation-message-diff-within-range": "Разница между $3 ($4) и $1 ($2) должна быть в диапазоне от $5 до $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Разница между $3 ($4) и $1 ($2) не должна превышать $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Разница между $3 ($4) и $1 ($2) не должна быть меньше $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Свойства, указанные в параметрах, должны быть того же типа, что и данное свойство.", + "wbqc-violation-message-format": "Значение для $1 ($2) должно соответствовать регулярному выражению $3.", + "wbqc-violation-message-format-clarification": "Значение для $1 ($2) должно соответствовать “$4” (регулярное выражение: $3).", + "wbqc-violation-message-inverse": "$1 также должно иметь обратное утверждение $2 со значением $3.", + "wbqc-violation-message-item": "Сущность со свойством $1 должно также иметь {{PLURAL:$3|0=утверждение $2.|1=утверждение $2 со значением $5.|утверждение $2 с одним из следующих значений:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Этому утверждению $1 не хватает квалификатора $2.", + "wbqc-violation-message-multi-value": "Это свойство должно содержать несколько значений.", + "wbqc-violation-message-multi-value-separators": "Это свойство должно содержать несколько значений с одинаковым {{PLURAL:$2|1=квалификатором $4.|набором квалификаторов: $3}}", + "wbqc-violation-message-one-of": "Свойство $1 должно иметь {{PLURAL:$2|1=значение $4.|2=значение $4 или $5.|одно из следующих значений:$3}}", + "wbqc-violation-message-qualifier": "Данное свойство следует использовать только в качестве квалификатора.", + "wbqc-violation-message-no-qualifiers": "Для утверждения «$1» квалификаторы не предусмотрены.", + "wbqc-violation-message-qualifiers": "«$2» — некорректный квалификатор для «$1»; {{PLURAL:$3|1=корректным будет только «$5».|2=корректными будут только «$5» и «$6».|корректные квалификаторы:$4}}", + "wbqc-violation-message-range-parameters-needed": "Свойства со значениями типа «$1» и ограничением «$4» должны иметь параметры «$2» и «$3».", + "wbqc-violation-message-range-parameters-one-year": "Границы диапазона времени должны либо обе содержать единицу измерения «год», либо обе её не содержать, поскольку года невозможно преобразовать в секунды без потери точности.", + "wbqc-violation-message-range-parameters-same": "Начало ($1) и конец ($2) диапазона не должны совпадать.", + "wbqc-violation-message-range-quantity-closed": "Значение $1 ($2) должно быть в диапазоне от $3 до $4.", + "wbqc-violation-message-range-quantity-leftopen": "Значение $1 ($2) не должно превышать $3.", + "wbqc-violation-message-range-quantity-rightopen": "Значение $1 ($2) не должно быть меньше $3.", + "wbqc-violation-message-range-time-closed": "Значение $1 ($2) должно быть в диапазоне от $3 до $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Значение $1 ($2) должно быть в будущем, но не позднее $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Значение $1 ($2) должно быть в прошлом, но не раньше $3.", + "wbqc-violation-message-range-time-leftopen": "Значение $1 ($2) должно быть не позднее $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Значение $1 ($2) должно не быть в будущем.", + "wbqc-violation-message-range-time-rightopen": "Значение $1 ($2) должно быть не ранее $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Значение $1 ($2) должно не быть в прошлом.", + "wbqc-violation-message-single-value": "Это свойство должно содержать только одно значение.", + "wbqc-violation-message-single-value-separators": "У этого свойства не может быть нескольких значений с одинаковым {{PLURAL:$2|1=квалификатором $4.|набором квалификаторов: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "У этого свойства должно быть одно «лучшее» значение. Следует присвоить «предпочтительный ранг» одному из текущих значений.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "У этого свойства должно быть одно «лучшее» значение для каждого {{PLURAL:$2|1=квалификатора $4.|набора квалификаторов: $3}} Следует присвоить «предпочтительный ранг» одному из текущих значений.", + "wbqc-violation-message-single-best-value-multi-preferred": "У этого свойства должно быть одно «лучшее» значение. Несколько значений с «предпочтительным рангом» недопустимы.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "У этого свойства должно быть одно «лучшее» значение для каждого {{PLURAL:$2|1=квалификатора $4.|набора квалификаторов: $3}} Несколько значений с «предпочтительным рангом» недопустимы.", + "wbqc-violation-message-symmetric": "$1 также должно иметь аналогичное утверждение $2 со значением $3.", + "wbqc-violation-message-type-instance": "Сущности с утверждением $1 должны быть разновидностью {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), однако $2 сейчас {{PLURAL:$3|1=таковой не является.|2=таковой не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-type-subclass": "Сущности с утверждением $1 должны быть подклассом {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), однако $2 сейчас {{PLURAL:$3|1=таковой не является.|2=таковой не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Сущности с утверждением $1 должны быть разновидностью или подклассом {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), однако $2 сейчас {{PLURAL:$3|1=таковой не является.|2=таковой не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-valueType-instance": "Значение утверждения $1 должно быть разновидностью {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), однако $2 сейчас {{PLURAL:$3|1=таковым не является.|2=таковым не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-valueType-subclass": "Значение утверждения $1 должно быть подклассом {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), однако $2 сейчас {{PLURAL:$3|1=таковым не является.|2=таковым не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Значения утверждения $1 должны быть элементами или подклассами {{PLURAL:$3|1=$5|2=$5 или $6|одного из следующих классов}} (или {{PLURAL:$3|1=его подклассов|2=их подклассов|одного из их подклассов}}), но $2 сейчас {{PLURAL:$3|1=таковым не является.|2=таковым не является.|не относится ни к одному из них: $4}}", + "wbqc-violation-message-target-required-claim": "Элемент «$1» должен содержать {{PLURAL:$3|0=утверждение со свойством «$2».|1=утверждение со свойством «$2» и значением «$5».|утверждение со свойством «$2» и одним из значений:$4}}", + "wbqc-violation-message-unique-value": "Значение этого свойства не должно совпадать с другими элементами, однако оно также задано в {{PLURAL:$1|1=$3.|2=$3 и $4.|следующих элементах: $2}}", + "wbqc-violation-message-valueOnly": "Данное свойство следует использовать только в качестве основного утверждения, а не квалификатора или источника.", + "wbqc-violation-message-reference": "Данное свойство следует использовать только в качестве источника, а не основного утверждения или квалификатора.", + "wbqc-violation-message-noBounds": "У значений $1 не должно быть заданных границ.", + "wbqc-violation-message-units-none": "У значения $1 не следует указывать единицу измерения.", + "wbqc-violation-message-units": "Значение $1 должно иметь {{PLURAL:$2|1=единицу измерения $4.|2=единицу измерения $4 или $5.|одну из следующих единиц изменения: $3}}", + "wbqc-violation-message-units-or-none": "Значение $1 должно быть безразмерным или иметь {{PLURAL:$2|1=единицу измерения $4.|2=единицу измерения $4 или $5.|одну из следующих единиц изменения: $3}}", + "wbqc-violation-message-entityType": "Свойство $1 не должно быть использовано в сущностях этого типа, {{PLURAL:$2|1=единственный разрешённый тип — $4.|2=разрешёны только типы $4 и $5.|разрешены следующие типы: $3}}", + "wbqc-violation-message-none-of": "Свойство $1 не должно иметь {{PLURAL:$2|1=значение $4.|2=значение $4 или $5.|ни одного из следующих значений:$3}}", + "wbqc-violation-message-integer": "Значение $1 должно быть целочисленным, однако у $2 есть дробная часть.", + "wbqc-violation-message-integer-bounds": "Значения $1 должны быть целочисленными, однако у границ $2 есть дробная часть.", + "wbqc-violation-message-citationNeeded": "Утверждения $1 должны опираться хотя бы на один источник.", + "wbqc-violation-message-language": "Утверждения $1 допустимы только в лексемах {{PLURAL:$2|1=языка $4.|2=языков $4 или $5.|одного из следующих языков: $3}}", + "wbqc-violation-message-label-lacking": "Сущности с утверждением $1 должны также содержать название {{PLURAL:$2|1=на языке: $4.|хотя бы на одном из следующих языков: $3}}", + "wbqc-violation-message-property-scope": "Свойство $1 не должно использоваться в этом месте ($2). Допустимые {{PLURAL:$3|место|места}} для этого свойства {{PLURAL:$3|это $5.|являются: $4}}", + "wbqc-violation-message-exception": "Эта сущность — известное исключение из данного ограничения и помечена как таковая." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sa.json b/dist/extensions/WikibaseQualityConstraints/i18n/sa.json new file mode 100644 index 000000000..532f3e47c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sa.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Charunandan16" + ] + }, + "wbqc-violation-message-citationNeeded": "$1इति एतदर्थं कृतानि वचनानि एकं तु सन्दर्भम् अपेक्षन्ते।" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/scn.json b/dist/extensions/WikibaseQualityConstraints/i18n/scn.json new file mode 100644 index 000000000..223df47a4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/scn.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Ajeje Brazorf" + ] + }, + "wbqc-constraintreport-form-entityid-placeholder": "Qxx o Pxx", + "wbqc-constraintreport-status-warning": "Accura", + "wbqc-constraintreport-result-table-header-status": "Statu", + "wbqc-constraintreport-result-table-header-message": "Missaggiu", + "wbqc-constraintreport-no-parameter": "nuḍḍu", + "wbqc-constrainttypehelp-short": "Aiutu" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sd.json b/dist/extensions/WikibaseQualityConstraints/i18n/sd.json new file mode 100644 index 000000000..f29272fcd --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sd.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "Aursani", + "Mehtab ahmed", + "Sindhu" + ] + }, + "wbqc-constraintreport-not-existent-entity": "اها شَي وجود نہ ٿي رکي.", + "wbqc-constraintreport-status-suggestion": "مشورو", + "wbqc-constraintreport-result-table-header-status": "صو‌‌رتحال", + "wbqc-constraintreport-no-parameter": "ڪوبہ نہ", + "wbqc-suggestions-short": "مشورا", + "wbqc-violation-header-parameters": "نيم پيما", + "wbqc-violations-group": "حدبندي", + "wbqc-violation-message": "حدبندي چڪاس هڪ خلاف ورزيءَ جي نشاندهي ڪئي آهي. مهرباني ڪري وڌيڪ معلومات لاءِآئيڪن تي ڪلڪ ڪندا." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/si.json b/dist/extensions/WikibaseQualityConstraints/i18n/si.json new file mode 100644 index 000000000..1e5047e91 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/si.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Pradeepmaduranga", + "Susith Chandira Gts", + 1100100 + ] + }, + "wbqc-constraintreport": "අවහිරතා වාර්තාව", + "wbqc-constraintreport-form-submit-label": "පරික්ෂා කරන්න", + "wbqc-constraintreport-result-headline": "සදහා ප්‍රතිඵල" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/skr-arab.json b/dist/extensions/WikibaseQualityConstraints/i18n/skr-arab.json new file mode 100644 index 000000000..4f3a151a0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/skr-arab.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Saraiki" + ] + }, + "wbqc-constraintreport-status-warning": "خبردار", + "wbqc-constraintreport-result-table-header-message": "سنیہا", + "wbqc-constraintdiscuss-short": "بحث کرو" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sl.json b/dist/extensions/WikibaseQualityConstraints/i18n/sl.json new file mode 100644 index 000000000..819e0bea7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sl.json @@ -0,0 +1,149 @@ +{ + "@metadata": { + "authors": [ + "Eleassar", + "HairyFotr", + "Janezdrilc", + "Amire80" + ] + }, + "wbqc-constraintreport": "Poročilo o omejitvi", + "wbqc-desc": "Preveri omejitve za objekte in lastnosti in prikaži zadetke na posebni strani", + "wbqc-constraintreport-explanation-part-one": "Ta posebna stran izvaja preverjanje omejitev za katero koli entiteto, ki jo izberete. Entitete se pridobivajo iz aktivnega sistema, tako da bo vsaka kršitev omejitve, ki jo tam popravite, takoj odstranjena s tega seznama.", + "wbqc-constraintreport-explanation-part-two": "Omejitve se razčlenijo iz izjav o lastnostih vsakič, ko so te izjave urejene, običajno v nekaj minutah.", + "wbqc-constraintreport-form-section": "Preveri omejitve za entiteto", + "wbqc-constraintreport-form-submit-label": "Preveri", + "wbqc-constraintreport-form-entityid-label": "ID entitete:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx ali Pxx", + "wbqc-constraintreport-result-headline": "Zadetek za", + "wbqc-constraintreport-invalid-entity-id": "Neveljaven ID entitete:", + "wbqc-constraintreport-not-existent-entity": "Entiteta ne obstaja.", + "wbqc-constraintreport-empty-result": "Za to entiteto niso določene nobene omejitve.", + "wbqc-constraintreport-status-violation": "Kršitev", + "wbqc-constraintreport-status-compliance": "Skladnost", + "wbqc-constraintreport-status-exception": "Izjema", + "wbqc-constraintreport-status-todo": "V načrtu", + "wbqc-constraintreport-status-bad-parameters": "Nepravilni parametri", + "wbqc-constraintreport-status-deprecated": "Nasprotujoče", + "wbqc-constraintreport-status-warning": "Opozorilo", + "wbqc-constraintreport-status-suggestion": "Predlog", + "wbqc-constraintreport-status-not-in-scope": "Izven obsega", + "wbqc-constraintreport-result-table-header-status": "Stanje", + "wbqc-constraintreport-result-table-header-property": "Lastnost", + "wbqc-constraintreport-result-table-header-message": "Sporočilo", + "wbqc-constraintreport-result-table-header-constraint": "Omejitev", + "wbqc-constraintreport-result-link-to-claim": "pojdi na izjavo", + "wbqc-constraintreport-result-link-to-constraint": "pojdi na omejitev", + "wbqc-constraintreport-no-parameter": "nobeno", + "wbqc-issues-short": "Težave", + "wbqc-issues-long": "Ta izjava ima nekaj težav.", + "wbqc-potentialissues-short": "Možne težave", + "wbqc-potentialissues-long": "Ta izjava ima nekaj možnih težav.", + "wbqc-suggestions-short": "Predlogi", + "wbqc-suggestions-long": "Na voljo je nekaj predlogov za izboljšanje izjave.", + "wbqc-badparameters-short": "Nepravilni parametri", + "wbqc-badparameters-long": "Ta izjava omejitve vsebuje nekatere neveljavne parametre.", + "wbqc-parameterissues-short": "Dodatne težave", + "wbqc-parameterissues-long": "Te težave se nanašajo ne določilo omejitve lastnosti, ne na to izjavo.", + "wbqc-constrainttypehelp-short": "Pomoč", + "wbqc-constrainttypehelp-long": "Stran pomoči za to vrsto omejitve", + "wbqc-constraintdiscuss-short": "Pogovor", + "wbqc-constraintdiscuss-long": "Pogovorna stran te omejitve", + "wbqc-cached-generic": "Ta rezultat je predpomnjen, zaradi česar je morda zastarel.", + "wbqc-cached-minutes": "Ta rezultat je predpomnjen, zaradi česar je morda zastarel do {{PLURAL:$1|1=ene minute|$1 minut}}.", + "wbqc-cached-hours": "Ta rezultat je predpomnjen, zaradi česar je morda zastarel do {{PLURAL:$1|1=ene ure|$1 ur}}.", + "wbqc-cached-days": "Ta rezultat je predpomnjen, zaradi česar je morda zastarel do {{PLURAL:$1|1=enega dne|$1 dni}}.", + "wbqc-dataValueType-wikibase-entityid": "ID entitete", + "wbq-subextension-name-wbqc": "Omejitve", + "wbqc-violation-header-parameters": "Parametri:", + "wbqc-violations-group": "Omejitve", + "wbqc-violation-message": "Preverjanje omejitev je zaznalo kršitev. Za dodatne informacije kliknite ikono.", + "wbqc-violation-message-not-yet-implemented": "Zaradi tehničnih razlogov preverjanje za omejitev \"$1\" ni bilo sprogramirano.", + "wbqc-violation-message-security-reason": "Zaradi varnostnih razlogov trenutno ni mogoče preveriti omejitve \"$1\". Iskanje rešitve še poteka.", + "wbqc-violation-message-value-needed-of-type": "Lastnosti z omejitvijo \"$1\" morajo imeti vrednosti vrste \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Lastnosti z omejitvijo \"$1\" morajo imeti vrednosti vrst \"$2\" ali \"$3\".", + "wbqc-violation-message-parameter-needed": "Lastnosti z omejitvijo \"$1\" morajo imeti parameter \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Lastnosti z omejitvijo \"$1\" morajo imeti parametre \"$2\", \"$3\" in \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "Obstajati mora ciljna entiteta.", + "wbqc-violation-message-value-entity-must-exist": "Obstajati mora vrednostna entiteta.", + "wbqc-violation-message-parameter-value": "Parameter \"$1\" mora imeti neko vrednost, ne \"brez vrednosti\" ali \"neznana vrednost\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parameter \"$1\" mora imeti neko vrednost ali \"brez vrednost\", nikoli pa \"neznana vrednost\".", + "wbqc-violation-message-parameter-entity": "Vrednost za parameter »$1« mora biti entiteta, ne »$2«.", + "wbqc-violation-message-parameter-item": "Vrednost za parameter \"$1\" mora biti objekt, ne \"$2\".", + "wbqc-violation-message-parameter-property": "Vrednost za parameter \"$1\" mora biti lastnost, ne \"$2\".", + "wbqc-violation-message-parameter-string": "Vrednost za parameter \"$1\" mora biti niz, ne \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Vrednost za parameter \"$1\" mora biti besedilo v enem jeziku, ne \"$2\".", + "wbqc-violation-message-parameter-single": "Parameter \"$1\" mora imeti eno vrednost.", + "wbqc-violation-message-parameter-single-per-language": "Parameter \"$1\" sme imeti samo eno vrednost na jezik, vendar ima lahko več vrednosti za $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Parameter \"$1\" mora biti {{PLURAL:$2|1=$4.|2=$4 ali $5.|en izmed naslednjih:$3}}", + "wbqc-violation-message-parameter-regex": "$1 ni veljaven regularni izraz.", + "wbqc-violation-message-sparql-error": "SPARQL iskanje se je končalo neuspešno.", + "wbqc-violation-message-parameters-error-unknown": "Parametrov te omejitve ni mogoče uvoziti.", + "wbqc-violation-message-parameters-error-toolong": "Parametrov te omejitve zaradi njihove preobsežnosti ni bilo mogoče uvoziti.", + "wbqc-violation-message-invalid-scope": "$1 ni veljaven obseg za omejitev vrste $2; edini {{PLURAL:$3|veljavni obseg|veljavna obsega|veljavni obsegi|veljavnih obsegov}} za to vrsto {{PLURAL:$3|je $5.|2=sta $5 in $6.|so: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Obstajati mora povezava na Zbirko.", + "wbqc-violation-message-commons-link-not-well-formed": "Povezava na Zbirko mora biti ustrezna.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Preverjanje za imenski prostor \"$1\" še ni sprogramirano.", + "wbqc-violation-message-conflicts-with-property": "Entiteta ne sme hkrati imeti izjav za $1 in $2.", + "wbqc-violation-message-conflicts-with-claim": "Entiteta ne sme imeti izjave $1, če ima izjavo $2 z vrednostjo $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entiteti $1 in $3 bi morali biti za povezavo prek $2 aktualni, vendar je zadnja končna vrednost $1 enaka $4, najzgodnejša začetna vrednost $3 pa je enaka $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entiteti $1 in $3 bi morali biti za povezavo prek $2 aktualni, vendar je zadnja končna vrednost $3 enaka $4, najzgodnejša začetna vrednost $1 pa je enaka $5.", + "wbqc-violation-message-diff-within-range": "Razlika med $3 ($4) in $1 ($2) mora biti med $5 in $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Razlika med $3 ($4) in $1 ($2) ne sme biti več kot $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Razlika med $3 ($4) in $1 ($2) ne sme biti manj kot $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Lastnost, ki je opredeljena v parametrih, mora imeti vrednost iste vrste kot ta lastnost.", + "wbqc-violation-message-format": "Vrednost za $1 ($2) se mora ujemati z regularnim izrazom $3.", + "wbqc-violation-message-format-clarification": "Vrednost za $1 ($2) se mora ujemati z “$4” (regularni izraz: $3).", + "wbqc-violation-message-inverse": "$1 mora imeti tudi obratno izjavo $2 $3.", + "wbqc-violation-message-item": "Entiteta z $1 mora imeti tudi {{PLURAL:$3|0=izjavo $2.|1=izjavo $2 $5.|izjavo za $2 z eno od naslednjih vrednosti:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Tej izjavi $1 manjka kvalifikator $2.", + "wbqc-violation-message-multi-value": "Ta lastnost mora vsebovati več vrednosti.", + "wbqc-violation-message-multi-value-separators": "Ta lastnost mora imeti več vrednosti z enakim {{PLURAL:$2|1=$4 kvalifikatorjem.|naborom kvalifikatorjev za te lastnosti: $3}}", + "wbqc-violation-message-one-of": "Vrednost za $1 mora biti {{PLURAL:$2|1=$4.|2=$4 ali $5.|ena izmed naslednjih:$3}}", + "wbqc-violation-message-qualifier": "Lastnost mora biti uporabljena le kot kvalifikator.", + "wbqc-violation-message-no-qualifiers": "Izjave $1 ne smejo imeti nobenih kvalifikatorjev.", + "wbqc-violation-message-qualifiers": "$2 ni veljaven kvalifikator za $1 – {{PLURAL:$3|1=edini veljavni je $5.|2=edina veljavna sta $5 in $6.|edini veljavni so:$4}}", + "wbqc-violation-message-range-parameters-needed": "Lastnosti z vrednostmi vrste \"$1\" z omejitvijo \"$4\" morajo imeti parametra \"$2\" in \"$3\".", + "wbqc-violation-message-range-parameters-one-year": "Končni točki razpona časovne enote morata obe ali nobena imeti enoto »leto«, ker let ni mogoče pretvoriti v sekunde brez izgub.", + "wbqc-violation-message-range-parameters-same": "Začetna ($1) in končna točka ($2) v razponu ne smeta biti enaki.", + "wbqc-violation-message-range-quantity-closed": "Vrednost za $1 ($2) mora biti med $3 in $4.", + "wbqc-violation-message-range-quantity-leftopen": "Vrednost za $1 ($2) ne sme biti več kot $3.", + "wbqc-violation-message-range-quantity-rightopen": "Vrednost za $1 ($2) ne sme biti manjša kot $3.", + "wbqc-violation-message-range-time-closed": "Vrednost za $1 ($2) mora biti med $3 in $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Vrednost za $1 ($2) mora biti v prihodnosti, vendar ne pozneje od $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Vrednost za $1 ($2) ne mora biti v preteklosti, vendar ne pred $3.", + "wbqc-violation-message-range-time-leftopen": "Vrednost za $1 ($2) ne sme biti poznejša od $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Vrednost za $1 ($2) ne sme biti v prihodnosti.", + "wbqc-violation-message-range-time-rightopen": "Vrednost za $1 ($2) ne sme biti zgodnejša od $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Vrednost za $1 ($2) ne sme biti v preteklosti.", + "wbqc-violation-message-single-value": "Ta lastnost mora vsebovati eno vrednost.", + "wbqc-violation-message-single-value-separators": "Ta lastnost mora imeti eno vrednost z enakim {{PLURAL:$2|1=$4 kvalifikatorjem.|naborom kvalifikatorjev za te lastnosti: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Ta lastnost mora vsebovati eno \"najboljšo\" vrednost. Ena izmed trenutnih vrednosti mora biti označena z \"želenim mestom\".", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ta lastnost mora vsebovati eno \"najboljšo\" vrednost z enakim {{PLURAL:$2|1=$4 kvalifikatorjem.|naborom kvalifikatorjev za te lastnosti: $3}} Ena izmed trenutnih vrednosti mora biti označena z \"želenim mestom\".", + "wbqc-violation-message-single-best-value-multi-preferred": "Ta lastnost mora vsebovati eno \"najboljšo\" vrednost. Ne sme obstajati več vrednosti, označenih z \"želenim mestom\".", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ta lastnost mora vsebovati eno \"najboljšo\" vrednost z enakim {{PLURAL:$2|1=$4 kvalifikatorjem.|naborom kvalifikatorjev za te lastnosti: $3}} Ne sme obstajati več vrednosti, označena z \"želenim mestom\".", + "wbqc-violation-message-symmetric": "$1 mora imeti tudi simetrično izjavo $2 $3.", + "wbqc-violation-message-type-instance": "Entitete, ki uporabljajo $1, morajo biti primerki {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegovega podrazreda|2=njunega podrazreda|enega od njihovih podrazredov}}), vendar $2 trenutno to {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-type-subclass": "Entitete, ki uporabljajo $1, morajo biti podrazredi {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegovega podrazreda|2=njunega podrazreda|enega od njunih podrazredov}}), vendar $2 trenutno to {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entitete, ki uporabljajo $1, morajo biti primerki ali podrazredi {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegovega podrazred|2=njunega podrazreda|enega od njihovih podrazredov}}), vendar $2 trenutno to {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-valueType-instance": "Vrednosti izjav $1 morajo biti primerki {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegov podrazred|2=njihov podrazred|eden od njihovih podrazredov}}), vendar $2 trenutno {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-valueType-subclass": "Vrednosti izjav $1 morajo biti podrazredi {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegov podrazred|2=njihov podrazred|eden od njihovih podrazredov}}), vendar $2 trenutno {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Vrednosti izjav $1 morajo biti primerki ali podrazredi {{PLURAL:$3|1=$5|2=$5 ali $6|enega od naslednjih razredov}} (ali {{PLURAL:$3|1=njegov podrazred|2=njihov podrazred|eden od njihovih podrazredov}}), vendar $2 trenutno {{PLURAL:$3|1=ni.|2=ni.|ni: $4}}", + "wbqc-violation-message-target-required-claim": "$1 mora imeti {{PLURAL:$3|0=izjavo $2.|1=izjavo $2 $5.|izjavo za $2 z eno do naslednjih vrednosti:$4}}", + "wbqc-violation-message-unique-value": "Te vrednosti lastnosti ne sme vsebovati noben drug predmet, vendar je navedena tudi pri {{PLURAL:$1|1=$3.|2=$3 in $4.|naslednjih predmetih: $2}}", + "wbqc-violation-message-valueOnly": "Ta lastnost mora biti uporabljena samo koz glavna vrednost izjave, ne kot kvalifikator ali vir.", + "wbqc-violation-message-reference": "Lastnost je lahko uporabljena samo kot vir, ne kot glavna vrednost izjave ali kot kvalifikator.", + "wbqc-violation-message-noBounds": "Vrednost za $1 ne sme imeti odstopanj.", + "wbqc-violation-message-units-none": "Vrednost za $1 ne sme imeti enote.", + "wbqc-violation-message-units": "Vrednost za $1 mora imeti {{PLURAL:$2|1=enoto $4.|2=enoti $4 ali $5.|eno od naslednjih enot: $3}}", + "wbqc-violation-message-units-or-none": "Vrednost za $1 mora imeti {{PLURAL:$2|1=enoto $4|2=enoti $4 ali $5|eno od naslednjih enot}} ali biti {{PLURAL:$2|1=brez enote.|2=brez enot.|brez enot: $3}}", + "wbqc-violation-message-entityType": "Lastnost $1 se za to vrsto entitete ne sme uporabljati; {{PLURAL:$2|1=Edina veljavna entitetna vrsta je $4.|2=Edini veljavni entitetni vrsti sta $4 in $5.|Edine veljavne entitetne vrste so: $3}}", + "wbqc-violation-message-none-of": "Vrednost za $1 ne sme biti {{PLURAL:$2|1=$4.|2=$4 ali $5.|ena od naslednjih:$3}}", + "wbqc-violation-message-integer": "Vrednosti za $1 morajo biti cela števila, $2 pa vsebuje decimalke.", + "wbqc-violation-message-integer-bounds": "Vrednosti za $1 morajo biti cela števila, odstopanja pri $2 pa vsebujejo decimalke.", + "wbqc-violation-message-citationNeeded": "Izjave za $1 morajo imeti vsaj en vir.", + "wbqc-violation-message-language": "Izjave za $1 naj bodo samo za lekseme z jezikom, nastavljenim {{PLURAL:$2|1=na $4.|2=bodisi na $4 bodisi na $5.|eno od naslednjega: $3}}.", + "wbqc-violation-message-label-lacking": "Entitete z izjavami za $1 morajo imeti tudi oznako v vsaj {{PLURAL:$2|1=$4 jeziku|katerem koli od naslednjih jezikov: $3}}", + "wbqc-violation-message-property-scope": "Lastnost $1 ne sme biti uporabljena na tem mestu ($2). {{PLURAL:$3|Ustrezno mesto|Ustrezni mesti|Ustrezna mesta}} za to lastnost {{PLURAL:$3|je $5.|so: $4}}", + "wbqc-violation-message-exception": "Ta entiteta je znana izjema za to omejitev in je bila tako tudi označena." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/smn.json b/dist/extensions/WikibaseQualityConstraints/i18n/smn.json new file mode 100644 index 000000000..ccc7b2bd1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/smn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Seipinne", + "Yupik" + ] + }, + "wbqc-constraintreport-status-warning": "Váruttâs", + "wbqc-issues-short": "Čuolmah", + "wbqc-constrainttypehelp-short": "Iše" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sms.json b/dist/extensions/WikibaseQualityConstraints/i18n/sms.json new file mode 100644 index 000000000..84cdb7a47 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sms.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Yupik" + ] + }, + "wbqc-constraintreport-status-bad-parameters": "Vââǥǥlaž paramettar", + "wbqc-constraintreport-status-warning": "Vaartõs", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-issues-short": "Čuõlm", + "wbqc-suggestions-short": "Eʹtǩǩõõzz", + "wbqc-badparameters-short": "Vââǥǥlaž paramettar", + "wbqc-constraintdiscuss-short": "Saǥstõõl", + "wbqc-violation-header-parameters": "Paramettar:" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sq.json b/dist/extensions/WikibaseQualityConstraints/i18n/sq.json new file mode 100644 index 000000000..f9d321410 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sq.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Bjakupi" + ] + }, + "wbqc-violation-message-citationNeeded": "Deklaratat per $1 duhet te kene se paku nje reference." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sr-ec.json b/dist/extensions/WikibaseQualityConstraints/i18n/sr-ec.json new file mode 100644 index 000000000..bfdb64a06 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sr-ec.json @@ -0,0 +1,103 @@ +{ + "@metadata": { + "authors": [ + "Acamicamacaraca", + "BadDog", + "Kizule", + "Obsuser", + "Prevodim", + "Zoranzoki21", + "Милан Јелисавчић", + "Сербијана", + "Milicevic01", + "Zenfiric" + ] + }, + "wbqc-constraintreport": "Извештај о ограничењу", + "wbqc-desc": "Проверава ограничења на ставкама и својствима и приказује резултате на посебној страници", + "wbqc-constraintreport-explanation-part-two": "Ограничења се проверавају са тврдњи на страницама својства сваки пут када се те тврдње измене, обично у року од неколико минута.", + "wbqc-constraintreport-form-submit-label": "Провера", + "wbqc-constraintreport-form-entityid-label": "ID ентитета:", + "wbqc-constraintreport-result-headline": "Резултат за", + "wbqc-constraintreport-not-existent-entity": "Ентитет не постоји.", + "wbqc-constraintreport-empty-result": "Не постоје ограничења дефинисана за овај ентитет.", + "wbqc-constraintreport-status-violation": "Кршење", + "wbqc-constraintreport-status-compliance": "Усаглашеност", + "wbqc-constraintreport-status-exception": "Изузетак", + "wbqc-constraintreport-status-todo": "Задужења", + "wbqc-constraintreport-status-bad-parameters": "Лоши параметри", + "wbqc-constraintreport-status-deprecated": "Застарело", + "wbqc-constraintreport-status-warning": "Упозорење", + "wbqc-constraintreport-status-not-in-scope": "Није у опсегу", + "wbqc-constraintreport-result-table-header-status": "Статус", + "wbqc-constraintreport-result-table-header-property": "Својство", + "wbqc-constraintreport-result-table-header-message": "Порука", + "wbqc-constraintreport-result-table-header-constraint": "Ограничење", + "wbqc-constraintreport-result-link-to-claim": "иди на тврдњу", + "wbqc-constraintreport-result-link-to-constraint": "иди на ограничење", + "wbqc-constraintreport-no-parameter": "ништа", + "wbqc-issues-short": "Проблеми", + "wbqc-issues-long": "Ова изјава има неке проблеме.", + "wbqc-potentialissues-short": "Могући проблеми", + "wbqc-potentialissues-long": "Ова изјава име неке могуће проблеме.", + "wbqc-suggestions-short": "Предлози", + "wbqc-suggestions-long": "Постоји неколико сугестија за побољшавање ове изјаве.", + "wbqc-badparameters-short": "Лоши параметри", + "wbqc-constrainttypehelp-short": "Помоћ", + "wbqc-constraintdiscuss-short": "Расправа", + "wbqc-cached-generic": "Овај резултат је кеширан и можда је застарео.", + "wbqc-cached-minutes": "Овај резултат је кеширан и можда је застарео до {{PLURAL:$1|1=један минут|$1 минут|$1 минута}}.", + "wbqc-cached-hours": "Овај резултат је кеширан и можда је застарео до {{PLURAL:$1|1=један сат|$1 сат|$1 сата|$1 сати}}.", + "wbqc-cached-days": "Овај резултат је кеширан и можда је застарео до {{PLURAL:$1|1=један дан|$1 дан|$1 дана}}.", + "wbqc-dataValueType-wikibase-entityid": "ID ентитета", + "wbq-subextension-name-wbqc": "Ограничења", + "wbqc-violation-header-parameters": "Параметри:", + "wbqc-violations-group": "Ограничења", + "wbqc-violation-message-value-needed-of-types-2": "Својства са ограничењем „$1” морају имати вредности типа „$2” или „$3”.", + "wbqc-violation-message-parameters-needed-3": "Својства са ограничењем „$1” требају параметре „$2”, „$3” и „$4”.", + "wbqc-violation-message-commons-link-no-existent": "Веза до Оставе би требало да постоји.", + "wbqc-violation-message-commons-link-not-well-formed": "Веза до Оставе би требало да буде добро форматирана.", + "wbqc-violation-message-conflicts-with-property": "Ентитет не би требало да има изјаве и за $1 и за $2.", + "wbqc-violation-message-conflicts-with-claim": "Ентитет не би требало да има изјаву за $1 ако такође има изјаву за $2 са вредношћу $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Ентитети $1 и $3 треба да су савремени да би били повезани преко $2, али најкаснија крајња вредност за $1 је $4 а најранија почетна вредност за $3 је $5.", + "wbqc-violation-message-contemporary-value-earlier": "Ентитети $1 и $3 треба да су савремени да би били повезани преко $2, али најкаснија крајња вредност за $3 је $4 а најранија почетна вредност за $1 је $5.", + "wbqc-violation-message-diff-within-range": "Разлика између $3 ($4) и $1 ($2) мора да буде између $5 и $6.", + "wbqc-violation-message-format": "$1 ($2) мора да се поклапа са регуларним изразом $3.", + "wbqc-violation-message-format-clarification": "$1 ($2) мора да се поклапа са \"$4\" (регуларни израз: $3).", + "wbqc-violation-message-inverse": "$1 би такође требало да има инверзну изјаву $2 $3.", + "wbqc-violation-message-item": "Било који ентитет са $1 такође би требало да има {{PLURAL:$3|0=изјаву $2.|1=изјаву $2 $5.|изјаву за $2 са једном од следећих вредности:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Овој $1 изјави недостаје квалификатор $2.", + "wbqc-violation-message-multi-value": "Ово својство треба да садржи више вредности.", + "wbqc-violation-message-one-of": "Вредност за $1 би требало да буде {{PLURAL:$2|1=$4.|2=или $4 или $5.|једна од следећих:$3}}", + "wbqc-violation-message-qualifier": "Својство би требало да се користи само као квалификатор.", + "wbqc-violation-message-no-qualifiers": "Изјаве $1 не би требало да имају квалификаторе.", + "wbqc-violation-message-qualifiers": "$2 није валидан квалификатор за $1 — једини {{PLURAL:$3|1=валидан квалификатор је $5.|2=валидни квалификатори су $5 и $6.|валидни квалификатори су:$4}}", + "wbqc-violation-message-range-parameters-needed": "Својствима са вредностима типа „$1” са „$4” потребни су параметри „$2” и „$3”.", + "wbqc-violation-message-range-parameters-same": "Почетна ($1) и крајња тачка ($2) опсега не смеју бити исте.", + "wbqc-violation-message-range-quantity-closed": "Вредност за $1 ($2) требало би да буде између $3 и $4.", + "wbqc-violation-message-range-quantity-leftopen": "Вредност за $1 ($2) требало би да буде не више од $3.", + "wbqc-violation-message-range-quantity-rightopen": "Вредност за $1 ($2) требало би да буде не више од $3.", + "wbqc-violation-message-range-time-closed": "Вредност за $1 ($2) требало би да буде између $3 и $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Вредност за $1 ($2) би требало да буде у будућности, али не после $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Вредност за $1 ($2) би требало да буде у прошлости, али не пре $3.", + "wbqc-violation-message-range-time-leftopen": "Вредност за $1 ($2) не би требало да буде после $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Вредност за $1 ($2) не би требало да буде у будућности.", + "wbqc-violation-message-range-time-rightopen": "Вредност за $1 ($2) не би требало да буде пре $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Вредност за $1 ($2) не би требало да буде у прошлости.", + "wbqc-violation-message-single-value": "Ово својство треба да садржи само једну вредност.", + "wbqc-violation-message-single-value-separators": "Ово својство треба да има само једну вредност са истим {{PLURAL:$2|1=квалификатором $4.|сетом квалификатора за ова својства: $3}}", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ово својство треба да садржи једну „најбољу” вредност са истим {{PLURAL:$2|1=квалификатором $4.|сетом квалификатора за ова својства: $3}} Од тренутних вишеструких вредности, једна треба да буде означена рангом „Пожељни ранг”.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ово својство треба да садржи једну „најбољу” вредност са истим {{PLURAL:$2|1=квалификатором $4.|сетом квалификатора за ова својства: $3}} Не треба да буде више од једне вредности са рангом „Пожељни ранг”.", + "wbqc-violation-message-symmetric": "$1 би такође требало да има симетричну изјаву $2 $3.", + "wbqc-violation-message-type-instance": "Ентитети који користе својство $1 би требало да буду {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-type-subclass": "Ентитети који користе својство $1 би требало да буду поткласе {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Ентитети који користе својство $1 треба да буду случајеви или поткласе {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-valueType-instance": "Вредности изјава $1 би требало да буду {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-valueType-subclass": "Вредности изјава $1 би требало да буду поткласе {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Вредности изјава $1 требало би да буду случајеви или поткласе {{PLURAL:$3|1=$5|2=$5 или $6|једне од следећих класа}} (или {{PLURAL:$3|1=припадајуће класе|2=припадајућих класа|једне од припадајућих класа}}), али $2 тренутно {{PLURAL:$3|1=није.|2=није.|није: $4}}", + "wbqc-violation-message-target-required-claim": "$1 треба да има {{PLURAL:$3|0=изјаву $2.|1=изјаву $2 $5.|изјаву за $2 са једном од следећих вредности:$4}}", + "wbqc-violation-message-unique-value": "Вредност овог својства не би требало да је присутна ни на једној другој ставци али је такође присутна на {{PLURAL:$1|1=$3.|2=$3 и $4.|следећим: $2}}", + "wbqc-violation-message-noBounds": "Вредност за $1 не би требало да има ограничења.", + "wbqc-violation-message-units-none": "Вредност за $1 не би требало да има јединицу.", + "wbqc-violation-message-citationNeeded": "Изјаве за $1 требало би да имају барем једну референцу." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sr-el.json b/dist/extensions/WikibaseQualityConstraints/i18n/sr-el.json new file mode 100644 index 000000000..e9c4d7182 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sr-el.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "Obsuser" + ] + }, + "wbqc-constraintreport": "Izveštaj o ograničenju", + "wbqc-desc": "Proverava ograničenja na stavkama i svojstvima i prikazuje rezultate na posebnoj stranici", + "wbqc-constraintreport-explanation-part-two": "Ograničenja se proveravaju sa tvrdnji na stranicama svojstva svaki put kada se te tvrdnje izmene, obično u roku od nekoliko minuta.", + "wbqc-constraintreport-form-submit-label": "Provera", + "wbqc-constraintreport-form-entityid-label": "ID entiteta:", + "wbqc-constraintreport-result-headline": "Rezultat za", + "wbqc-constraintreport-empty-result": "Ne postoje ograničenja definisana za ovaj entitet.", + "wbqc-constraintreport-status-violation": "Kršenje", + "wbqc-constraintreport-status-compliance": "Usaglašenost", + "wbqc-constraintreport-status-exception": "Izuzetak", + "wbqc-constraintreport-status-todo": "Zaduženja", + "wbqc-constraintreport-status-bad-parameters": "Loši parametri", + "wbqc-constraintreport-status-deprecated": "Zastarelo", + "wbqc-constraintreport-status-warning": "Upozorenje", + "wbqc-constraintreport-status-not-in-scope": "Nije u opsegu", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Svojstvo", + "wbqc-constraintreport-result-table-header-message": "Poruka", + "wbqc-constraintreport-result-table-header-constraint": "Ograničenje", + "wbqc-constraintreport-result-link-to-claim": "idi na tvrdnju", + "wbqc-constraintreport-result-link-to-constraint": "idi na ograničenje", + "wbqc-constraintreport-no-parameter": "ništa", + "wbqc-issues-short": "Problemi", + "wbqc-issues-long": "Ova izjava ima neke probleme.", + "wbqc-potentialissues-short": "Mogući problemi", + "wbqc-potentialissues-long": "Ova izjava ime neke moguće probleme.", + "wbqc-suggestions-short": "Predlozi", + "wbqc-suggestions-long": "Postoji nekoliko sugestija za poboljšavanje ove izjave.", + "wbqc-badparameters-short": "Loši parametri", + "wbqc-constrainttypehelp-short": "Pomoć", + "wbqc-cached-generic": "Ovaj rezultat je keširan i možda je zastareo.", + "wbqc-cached-minutes": "Ovaj rezultat je keširan i možda je zastareo do {{PLURAL:$1|1=jedan minut|$1 minut|$1 minuta}}.", + "wbqc-cached-hours": "Ovaj rezultat je keširan i možda je zastareo do {{PLURAL:$1|1=jedan sat|$1 sat|$1 sata|$1 sati}}.", + "wbqc-cached-days": "Ovaj rezultat je keširan i možda je zastareo do {{PLURAL:$1|1=jedan dan|$1 dan|$1 dana}}.", + "wbqc-dataValueType-wikibase-entityid": "ID entiteta", + "wbq-subextension-name-wbqc": "Ograničenja", + "wbqc-violation-header-parameters": "Parametri:", + "wbqc-violations-group": "Ograničenja", + "wbqc-violation-message-value-needed-of-types-2": "Svojstva sa ograničenjem „$1” moraju imati vrednosti tipa „$2” ili „$3”.", + "wbqc-violation-message-parameters-needed-3": "Svojstva sa ograničenjem „$1” trebaju parametre „$2”, „$3” i „$4”.", + "wbqc-violation-message-commons-link-no-existent": "Veza do Ostave bi trebalo da postoji.", + "wbqc-violation-message-commons-link-not-well-formed": "Veza do Ostave bi trebalo da bude dobro formatirana.", + "wbqc-violation-message-conflicts-with-property": "Entitet ne bi trebalo da ima izjave i za $1 i za $2.", + "wbqc-violation-message-conflicts-with-claim": "Entitet ne bi trebalo da ima izjavu za $1 ako takođe ima izjavu za $2 sa vrednošću $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entiteti $1 i $3 treba da su savremeni da bi bili povezani preko $2, ali najkasnija krajnja vrednost za $1 je $4 a najranija početna vrednost za $3 je $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entiteti $1 i $3 treba da su savremeni da bi bili povezani preko $2, ali najkasnija krajnja vrednost za $3 je $4 a najranija početna vrednost za $1 je $5.", + "wbqc-violation-message-diff-within-range": "Razlika između $3 ($4) i $1 ($2) mora da bude između $5 i $6.", + "wbqc-violation-message-format": "$1 ($2) mora da se poklapa sa regularnim izrazom $3.", + "wbqc-violation-message-format-clarification": "$1 ($2) mora da se poklapa sa \"$4\" (regularni izraz: $3).", + "wbqc-violation-message-inverse": "$1 bi takođe trebalo da ima inverznu izjavu $2 $3.", + "wbqc-violation-message-item": "Bilo koji entitet sa $1 takođe bi trebalo da ima {{PLURAL:$3|0=izjavu $2.|1=izjavu $2 $5.|izjavu za $2 sa jednom od sledećih vrednosti:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Ovoj $1 izjavi nedostaje kvalifikator $2.", + "wbqc-violation-message-multi-value": "Ovo svojstvo treba da sadrži više vrednosti.", + "wbqc-violation-message-one-of": "Vrednost za $1 bi trebalo da bude {{PLURAL:$2|1=$4.|2=ili $4 ili $5.|jedna od sledećih:$3}}", + "wbqc-violation-message-qualifier": "Svojstvo bi trebalo da se koristi samo kao kvalifikator.", + "wbqc-violation-message-no-qualifiers": "Izjave $1 ne bi trebalo da imaju kvalifikatore.", + "wbqc-violation-message-qualifiers": "$2 nije validan kvalifikator za $1 — jedini {{PLURAL:$3|1=validan kvalifikator je $5.|2=validni kvalifikatori su $5 i $6.|validni kvalifikatori su:$4}}", + "wbqc-violation-message-range-parameters-needed": "Svojstvima sa vrednostima tipa „$1” sa „$4” potrebni su parametri „$2” i „$3”.", + "wbqc-violation-message-range-parameters-same": "Početna ($1) i krajnja tačka ($2) opsega ne smeju biti iste.", + "wbqc-violation-message-range-quantity-closed": "Vrednost za $1 ($2) trebalo bi da bude između $3 i $4.", + "wbqc-violation-message-range-quantity-leftopen": "Vrednost za $1 ($2) trebalo bi da bude ne više od $3.", + "wbqc-violation-message-range-quantity-rightopen": "Vrednost za $1 ($2) trebalo bi da bude ne više od $3.", + "wbqc-violation-message-range-time-closed": "Vrednost za $1 ($2) trebalo bi da bude između $3 i $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Vrednost za $1 ($2) bi trebalo da bude u budućnosti, ali ne posle $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Vrednost za $1 ($2) bi trebalo da bude u prošlosti, ali ne pre $3.", + "wbqc-violation-message-range-time-leftopen": "Vrednost za $1 ($2) ne bi trebalo da bude posle $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Vrednost za $1 ($2) ne bi trebalo da bude u budućnosti.", + "wbqc-violation-message-range-time-rightopen": "Vrednost za $1 ($2) ne bi trebalo da bude pre $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Vrednost za $1 ($2) ne bi trebalo da bude u prošlosti.", + "wbqc-violation-message-single-value": "Ovo svojstvo treba da sadrži samo jednu vrednost.", + "wbqc-violation-message-single-value-separators": "Ovo svojstvo treba da ima samo jednu vrednost sa istim {{PLURAL:$2|1=kvalifikatorom $4.|setom kvalifikatora za ova svojstva: $3}}", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ovo svojstvo treba da sadrži jednu „najbolju” vrednost sa istim {{PLURAL:$2|1=kvalifikatorom $4.|setom kvalifikatora za ova svojstva: $3}} Od trenutnih višestrukih vrednosti, jedna treba da bude označena rangom „Poželjni rang”.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ovo svojstvo treba da sadrži jednu „najbolju” vrednost sa istim {{PLURAL:$2|1=kvalifikatorom $4.|setom kvalifikatora za ova svojstva: $3}} Ne treba da bude više od jedne vrednosti sa rangom „Poželjni rang”.", + "wbqc-violation-message-symmetric": "$1 bi takođe trebalo da ima simetričnu izjavu $2 $3.", + "wbqc-violation-message-type-instance": "Entiteti koji koriste svojstvo $1 bi trebalo da budu {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-type-subclass": "Entiteti koji koriste svojstvo $1 bi trebalo da budu potklase {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entiteti koji koriste svojstvo $1 treba da budu slučajevi ili potklase {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-valueType-instance": "Vrednosti izjava $1 bi trebalo da budu {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-valueType-subclass": "Vrednosti izjava $1 bi trebalo da budu potklase {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Vrednosti izjava $1 trebalo bi da budu slučajevi ili potklase {{PLURAL:$3|1=$5|2=$5 ili $6|jedne od sledećih klasa}} (ili {{PLURAL:$3|1=pripadajuće klase|2=pripadajućih klasa|jedne od pripadajućih klasa}}), ali $2 trenutno {{PLURAL:$3|1=nije.|2=nije.|nije: $4}}", + "wbqc-violation-message-target-required-claim": "$1 treba da ima {{PLURAL:$3|0=izjavu $2.|1=izjavu $2 $5.|izjavu za $2 sa jednom od sledećih vrednosti:$4}}", + "wbqc-violation-message-unique-value": "Vrednost ovog svojstva ne bi trebalo da je prisutna ni na jednoj drugoj stavci ali je takođe prisutna na {{PLURAL:$1|1=$3.|2=$3 i $4.|sledećim: $2}}", + "wbqc-violation-message-noBounds": "Vrednost za $1 ne bi trebalo da ima ograničenja.", + "wbqc-violation-message-units-none": "Vrednost za $1 ne bi trebalo da ima jedinicu.", + "wbqc-violation-message-citationNeeded": "Izjave za $1 trebalo bi da imaju barem jednu referencu." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/sv.json b/dist/extensions/WikibaseQualityConstraints/i18n/sv.json new file mode 100644 index 000000000..d650eb280 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/sv.json @@ -0,0 +1,148 @@ +{ + "@metadata": { + "authors": [ + "Jon Harald Søby", + "Sabelöga", + "WikiPhoenix", + "Larske" + ] + }, + "wbqc-constraintreport": "Begränsningrapporter", + "wbqc-desc": "Kontrollerar begränsningar på både objekt och egenskaper samt visar resultaten på en specialsida", + "wbqc-constraintreport-explanation-part-one": "Denna specialsida utför begränsningskontroller på alla entiteter du vill. Entiteterna hämtas från det realtidsuppdaterande systemet, så varje begränsningsbrott du åtgärdar där kommer direkt att tas bort från denna lista.", + "wbqc-constraintreport-explanation-part-two": "Begränsningarna tolkas från uttalanden på egenskaper varje gång dessa uttalanden redigeras, vanligtvis inom några minuter.", + "wbqc-constraintreport-form-section": "Kolla begränsningar för entitet", + "wbqc-constraintreport-form-submit-label": "Kontrollera", + "wbqc-constraintreport-form-entityid-label": "Enhets-ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx eller Pxx", + "wbqc-constraintreport-result-headline": "Resultat för", + "wbqc-constraintreport-invalid-entity-id": "Ogiltigt entitets-ID.", + "wbqc-constraintreport-not-existent-entity": "Entitet finns inte.", + "wbqc-constraintreport-empty-result": "Inga begränsningar har definierats på denna entitet.", + "wbqc-constraintreport-status-violation": "Brott", + "wbqc-constraintreport-status-compliance": "Motsvarighet", + "wbqc-constraintreport-status-exception": "Undantag", + "wbqc-constraintreport-status-todo": "Att göra", + "wbqc-constraintreport-status-bad-parameters": "Trasiga parametrar", + "wbqc-constraintreport-status-deprecated": "Föråldrad", + "wbqc-constraintreport-status-warning": "Varning", + "wbqc-constraintreport-status-suggestion": "Förslag", + "wbqc-constraintreport-status-not-in-scope": "Inte inom omfång", + "wbqc-constraintreport-result-table-header-status": "Status", + "wbqc-constraintreport-result-table-header-property": "Egenskap", + "wbqc-constraintreport-result-table-header-message": "Meddelande", + "wbqc-constraintreport-result-table-header-constraint": "Begränsning", + "wbqc-constraintreport-result-link-to-claim": "gå till påstående", + "wbqc-constraintreport-result-link-to-constraint": "gå till begränsning", + "wbqc-constraintreport-no-parameter": "ingen", + "wbqc-issues-short": "Problem", + "wbqc-issues-long": "Detta uttalande har några problem.", + "wbqc-potentialissues-short": "Möjliga problem", + "wbqc-potentialissues-long": "Detta uttalande har några möjliga problem.", + "wbqc-suggestions-short": "Förslag", + "wbqc-suggestions-long": "Det finns några förslag på att förbättra detta uttalande.", + "wbqc-badparameters-short": "Trasiga parametrar", + "wbqc-badparameters-long": "Denna begränsningsuttalande har några ogiltiga parametrar.", + "wbqc-parameterissues-short": "Avancerade ärenden", + "wbqc-parameterissues-long": "Dessa ärenden är problem med begränsningsdefinitionen på egenskapen, inte med detta uttalande.", + "wbqc-constrainttypehelp-short": "Hjälp", + "wbqc-constrainttypehelp-long": "Hjälpsida för denna begränsningstyp", + "wbqc-constraintdiscuss-short": "Diskutera", + "wbqc-constraintdiscuss-long": "Diskussionssida om denna begränsning", + "wbqc-cached-generic": "Detta resultat cachelagras och kanske är utdaterat.", + "wbqc-cached-minutes": "Detta resultat cachelagras och kanske kan vara utdaterat upp till {{PLURAL:$1|1=en minut|$1 minuter}}.", + "wbqc-cached-hours": "Detta resultat cachelagras och kanske kan vara utdaterat upp {{PLURAL:$1|1=e timme|$1 timmar}}.", + "wbqc-cached-days": "Detta resultat cachelagras och kanske kan vara utdaterat upp {{PLURAL:$1|1=en dag|$1 dagar}}.", + "wbqc-dataValueType-wikibase-entityid": "Enhets-ID", + "wbq-subextension-name-wbqc": "Begränsningar", + "wbqc-violation-header-parameters": "Parametrar:", + "wbqc-violations-group": "Begränsningar", + "wbqc-violation-message": "Begränsningskontrollen har upptäckt en överträdelse. Klicka på ikonen för mer information.", + "wbqc-violation-message-not-yet-implemented": "Av tekniska skäl har kontrollen för begränsningen \"$1\" ännu inte implementerats.", + "wbqc-violation-message-security-reason": "Av säkerhetsskäl går det för tillfället inte att kontrollera begränsningen \"$1\". Vi arbetar på en lösning.", + "wbqc-violation-message-value-needed-of-type": "Egenskaper med begränsningen \"$1\" måste ha värden av typen \"$2\".", + "wbqc-violation-message-value-needed-of-types-2": "Egenskaper med begränsningen \"$1\" måste ha värden av typen \"$2\" eller \"$3\".", + "wbqc-violation-message-parameter-needed": "Egenskaper med begränsningen \"$1\" behöver parametern \"$2\".", + "wbqc-violation-message-parameters-needed-3": "Egenskaper med begränsningen \"$1\" behöver en parametrarna \"$2\", \"$3\" och \"$4\".", + "wbqc-violation-message-target-entity-must-exist": "Målentiteten måste finnas.", + "wbqc-violation-message-value-entity-must-exist": "Värdesentiteten måste finnas.", + "wbqc-violation-message-parameter-value": "Parametern \"$1\" måste ha ett anpassat värde, inte \"inget värde\" eller \"okänt värde\".", + "wbqc-violation-message-parameter-value-or-novalue": "Parametern \"$1\" måste ha ett anpassat värde eller \"inget värde\", men aldrig \"okänt värde\".", + "wbqc-violation-message-parameter-entity": "Värdet för parametern \"$1\" måste vara en entitet, inte \"$2\".", + "wbqc-violation-message-parameter-item": "Värdet för parametern \"$1\" måste vara ett objekt, inte \"$2\".", + "wbqc-violation-message-parameter-property": "Värdet för parametern \"$1\" måste vara en egenskap, inte \"$2\".", + "wbqc-violation-message-parameter-string": "Värdet för parametern \"$1\" måste vara en sträng, inte \"$2\".", + "wbqc-violation-message-parameter-monolingualtext": "Värdet för parametern \"$1\" måste vara en enspråkig text, inte \"$2\".", + "wbqc-violation-message-parameter-single": "Parametern \"$1\" måste endast ha ett enda värde.", + "wbqc-violation-message-parameter-single-per-language": "Parametern \"$1\" måste endast en ett enda värde per språk, men har flera språkvärden för $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Parametern \"$1\" måste vara {{PLURAL:$2|1=$4.|2=antingen $4 eller $5.|ett av följande:$3}}", + "wbqc-violation-message-parameter-regex": "$1 är inte ett giltigt reguljärt uttryck.", + "wbqc-violation-message-sparql-error": "SPARQL-frågan resulterade i ett fel.", + "wbqc-violation-message-parameters-error-unknown": "Parametrarna för denna begränsning kunde inte importeras.", + "wbqc-violation-message-parameters-error-toolong": "Parametrarna för denna begränsning kunde inte importeras eftersom de var för långa.", + "wbqc-violation-message-invalid-scope": "$1 är inget giltigt omfång för begränsningstyp $2; {{PLURAL:$3|det enda giltiga omfånget|de enda giltiga omfången}} för denna begränsningstyp {{PLURAL:$3|är $5.|2=är $5 och $6.|är: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Commons-länk bör finnas.", + "wbqc-violation-message-commons-link-not-well-formed": "Länkar till Commons bör vara välformaterade.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Kontroll för namnrymden \"$1\" är ännu inte implementerad.", + "wbqc-violation-message-conflicts-with-property": "En entitet bör inte har uttalet för både $1 och $2.", + "wbqc-violation-message-conflicts-with-claim": "En entitet bör inte ha ett uttalande för $1 om det också har ett uttalande för $2 med värdet $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Entiteterna $1 och $3 bör vara samtida för att kunna länkas genom $2, men det senaste slutvärdet för $1 är $4 och det tidigaste startvärdet för $3 är $5.", + "wbqc-violation-message-contemporary-value-earlier": "Entiteterna $1 och $3 bör vara samtida för att kunna länkas genom $2, men det senaste slutvärdet för $3 är $4 och det tidigaste startvärdet för $1 är $5.", + "wbqc-violation-message-diff-within-range": "Skillnaden mellan $3 ($4) och $1 ($2) bör vara mellan $5 och $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Skillnaden mellan $3 ($4) och $1 ($2) bör inte vara mer än $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Skillnaden mellan $3 ($4) och $1 ($2) bör inte vara mindre än $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Egenskapen som definieras i parametrarna måste ha ett värde av samma typ som denna egenskap.", + "wbqc-violation-message-format": "Värdet för $1 ($2) bör matcha det reguljära uttrycket $3.", + "wbqc-violation-message-format-clarification": "Värdet för $1 ($2) bör stämma överens med \"$4\" (regex: $3).", + "wbqc-violation-message-inverse": "$1 bör också har det motsatta uttalandet $2 $3.", + "wbqc-violation-message-item": "En entitet med $1 bör också ha {{PLURAL:$3|0=ett $2-uttal.|1=ett $2-uttal $5.|ett uttal för $2 med ett av följande värden:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Detta uttalande av typen $1 saknar bestämningsordet $2.", + "wbqc-violation-message-multi-value": "Denna egenskap bör innehålla flera värden.", + "wbqc-violation-message-multi-value-separators": "Denna egenskap bör innehålla flera värden med likadana {{PLURAL:$2|1=$4-bestämning.|uppsättningar med bestämningar för dessa egenskaper: $3}}", + "wbqc-violation-message-one-of": "Värdet för $1 bör {{PLURAL:$2|1=vara $4.|2=antingen vara $4 eller $5.|vara en av följande: $3}}", + "wbqc-violation-message-qualifier": "Egenskapen bör endast användas som en bestämning.", + "wbqc-violation-message-no-qualifiers": "$1-uttalanden bör inte har några bestämningar.", + "wbqc-violation-message-qualifiers": "$2 är inte en giltig bestämning för $1 – {{PLURAL:$3|1=den enda giltiga bestämningen är $5.|2=de enda giltiga bestämningarna är $5 och $6.|de enda giltiga bestämningarna är:$4}}", + "wbqc-violation-message-range-parameters-needed": "Egenskapen med värden av typen \"$1\" med begränsningen \"$4\" behöver parametrarna \"$2\" och \"$3\".", + "wbqc-violation-message-range-parameters-same": "Start- ($1) och slutpunkten ($2) för ett intervall måste inte vara densamma.", + "wbqc-violation-message-range-quantity-closed": "Värdet för $1 ($2) bör vara mellan $3 och $4.", + "wbqc-violation-message-range-quantity-leftopen": "Värdet för $1 ($2) bör inte vara mer än $3.", + "wbqc-violation-message-range-quantity-rightopen": "Värdet för $1 ($2) bör inte vara mer än $3.", + "wbqc-violation-message-range-time-closed": "Värdet för $1 ($2) bör vara mellan $3 och $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Värdet för $1 ($2) bör vara i framtiden, men inte efter $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Värdet för $1 ($2) bör vara i det förflutna, men inte före $3.", + "wbqc-violation-message-range-time-leftopen": "Värdet för $1 ($2) bör inte vara efter $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Värdet för $1 ($2) bör vara i framtiden.", + "wbqc-violation-message-range-time-rightopen": "Värdet för $1 ($2) bör inte vara innan $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Värdet för $1 ($2) bör vara i det förflutna.", + "wbqc-violation-message-single-value": "Denna egenskap bör endast innehåll ett enda värde.", + "wbqc-violation-message-single-value-separators": "Denna egenskap bör endast ha ett enda värde med samma {{PLURAL:$2|1=$4 bestämning.|grupp av bestämningar för dessa egenskaper: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Denna egenskap borde bara innehålla ett enda \"bästa\" värde. Ett av de nu flera värdena borde markeras med \"föredragen\" rank.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Den här egenskapen borde bara innehålla ett enda \"bästa\" värde med samma {{PLURAL:$2|1=$4-bestämning.|bestämningar för dessa egenskaper: $3}} En av de nu flera värdena borde markeras med \"föredragen\" rank.", + "wbqc-violation-message-single-best-value-multi-preferred": "Den här egenskapen borde bara innehålla ett enda \"bästa\" värde. En av de nu flera värdena borde markeras med \"föredragen\" rank.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Den här egenskapen borde bara innehålla ett enda \"bästa\" värde med samma {{PLURAL:$2|1=$4-bestämning.|bestämningar för dessa egenskaper: $3}} Det ska inte finnas fler än ett värde med \"föredragen\" rank.", + "wbqc-violation-message-symmetric": "$1 bör även ha det symmetriska uttalet $2 $3.", + "wbqc-violation-message-type-instance": "Entiteter som använder egenskapen $1 bör vara instanser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-type-subclass": "Entiteter som använder egenskapen $1 bör vara underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Entiteter som använder egenskapen $1 bör vara instanser eller underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-valueType-instance": "Värden av $1-uttalanden bör vara instanser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-valueType-subclass": "Värden av $1-uttalanden bör vara underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Värden av $1-uttalanden bör vara instanser eller underklasser av {{PLURAL:$3|1=$5|2=$5 eller $6|en av följande klasser}} (eller av {{PLURAL:$3|1=en underklass av den|2=en underklass av dem|en av deras underklasser}}), men $2 är för tillfället {{PLURAL:$3|1=inte det.|2=inte det.|inte det: $4}}", + "wbqc-violation-message-target-required-claim": "$1 bör ha {{PLURAL:$3|0=uttalandet $2.|1=uttalandet $2 $5.|ett uttalande för $2 med en av följande värden:$4}}", + "wbqc-violation-message-unique-value": "Den här egenskapens värde borde inte finnas på andra objekt, men finns också på {{PLURAL:$1|1=$3.|2=$3 och $4.|följande objekt: $2}}", + "wbqc-violation-message-valueOnly": "Den här egenskapen ska endast användas som huvudvärde i ett uttalande, inte i bestämningar och referenser.", + "wbqc-violation-message-reference": "Den här egenskapen ska endast användas i referenser, inte som huvudvärde i ett uttalande eller som bestämning.", + "wbqc-violation-message-noBounds": "Värden för $1 bör inte har några gränser.", + "wbqc-violation-message-units-none": "Värdet för $1 bör inte ha en enhet.", + "wbqc-violation-message-units": "Värdet för $1 bör ha {{PLURAL:$2|1=enheten $4.|2=enheten $4 eller $5.|en av följande enheter: $3}}", + "wbqc-violation-message-units-or-none": "Värde för $1 bör ha {{PLURAL:$2|1=enheten $4|2=enheten $4 eller $5|en av följande enheter}} eller vara {{PLURAL:$2|1=enhetslös.|2=enhetslösa.|enhetslösa: $3}}", + "wbqc-violation-message-entityType": "Egenskapen $1 bör inte användas på denna typ av entitet, {{PLURAL:$2|1=den enda giltiga entitetstypen är $4.|2=de enda giltiga entitetstyperna är $4 och $5.|de enda giltiga entitetstyperna är: $3}}", + "wbqc-violation-message-none-of": "Värdet för $1 bör {{PLURAL:$2|1=inte vara $4.|2=antingen inte vara $4 eller $5.|inte vara en av följande:$3}}", + "wbqc-violation-message-integer": "Värden för $1 borde vara heltal, men $2 har en bråkdel.", + "wbqc-violation-message-integer-bounds": "Värden för $1 bör vara heltal, men gränserna för $2 har en en bråkdel.", + "wbqc-violation-message-citationNeeded": "Uttalanden för $1 bör ha minst en referens.", + "wbqc-violation-message-language": "Uttalanden för $1 borde bara finnas på lexem som har ställt in {{PLURAL:$2|1=$4|2=antingen $4 eller $5|en av följande: $3,}} som språk.", + "wbqc-violation-message-label-lacking": "Entiteter med uttalanden för $1 borde också minst ha en etikett på {{PLURAL:$2|1=$4.|något av följande språk: $3}}", + "wbqc-violation-message-property-scope": "Egenskapen $1 borde inte användas på den här platsen ($2). {{PLURAL:$3|Den enda giltiga platsen|De enda giltiga platserna}} för denna egenskap {{PLURAL:$3|är $5.|är: $4}}", + "wbqc-violation-message-exception": "Denna entitet är ett känt undantag för denna begränsning och har märkts som sådan." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/tg-cyrl.json b/dist/extensions/WikibaseQualityConstraints/i18n/tg-cyrl.json new file mode 100644 index 000000000..aac264e8c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/tg-cyrl.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "AryanSogd" + ] + }, + "wbq-subextension-name-wbqc": "Маҳдудият", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Хусусияти муайян дар параметрҳо бояд арзиши навъи ба худ монандро дошта бошад.", + "wbqc-violation-message-inverse": "Ин хусусиятро танҳо дар ҳолате истифода бурдан мумкин аст, ки дархости арзиши иншооти худ ва истифода аз бузургиҳои худ карда ҳамин нуқтаро ҳамчун маъно ишора мекунад.", + "wbqc-violation-message-one-of": "Арзиши мол бояд яке аз қисмҳои муайяншуда дар бузургиҳо бошад." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/th.json b/dist/extensions/WikibaseQualityConstraints/i18n/th.json new file mode 100644 index 000000000..8df4a8393 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/th.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "Ans", + "Patsagorn Y." + ] + }, + "wbqc-constraintreport": "รายงานข้อจำกัดการใช้", + "wbqc-desc": "ตรวจสอบข้อจำกัดการใช้ทั้งในไอเทมและประพจน์ แล้วแสดงผลลัพธ์ในหน้าพิเศษ", + "wbqc-constraintreport-form-submit-label": "ตรวจสอบ", + "wbqc-constraintreport-status-violation": "การละเมิดกฎ", + "wbqc-constraintreport-status-compliance": "อนุโลมให้ใช้ได้", + "wbqc-constraintreport-status-exception": "ข้อยกเว้น", + "wbqc-constraintreport-status-todo": "ต้องการการจัดการ", + "wbqc-constraintreport-status-bad-parameters": "พารามิเตอร์ไม่ถูกต้อง", + "wbqc-constraintreport-status-deprecated": "เลิกใช้งานแล้ว", + "wbqc-constraintreport-status-warning": "คำเตือน", + "wbqc-constraintreport-status-suggestion": "ข้อแนะนำ", + "wbqc-constraintreport-status-not-in-scope": "ไม่อยู่ในขอบเขต", + "wbqc-constraintreport-result-table-header-status": "สถานะ", + "wbqc-constraintreport-result-table-header-message": "ข้อความ", + "wbqc-constraintreport-result-table-header-constraint": "เงื่อนไขบังคับ", + "wbqc-constraintreport-result-link-to-constraint": "ไปยังข้อจำกัด", + "wbqc-constraintreport-no-parameter": "ไม่มีค่า", + "wbqc-issues-short": "ปัญหา", + "wbqc-issues-long": "ประพจน์นี้มีปัญหาบางประการ", + "wbqc-potentialissues-short": "อาจเป็นข้อผิดพลาด", + "wbqc-potentialissues-long": "ประพจน์อาจมีปัญหาบางประการ", + "wbqc-suggestions-short": "ข้อแนะนำ", + "wbqc-suggestions-long": "มีข้อแนะนำบางประการสำหรับการปรับปรุงประพจน์นี้", + "wbqc-badparameters-short": "พารามิเตอร์ไม่ถูกต้อง", + "wbq-subextension-name-wbqc": "เงื่อนไขบังคับ", + "wbqc-violations-group": "เงื่อนไขบังคับ" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ti.json b/dist/extensions/WikibaseQualityConstraints/i18n/ti.json new file mode 100644 index 000000000..db4e8c134 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ti.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Joanmp17" + ] + }, + "wbqc-constraintreport-status-suggestion": "ርእይቶ", + "wbqc-suggestions-short": "ምኽርታት" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/tl.json b/dist/extensions/WikibaseQualityConstraints/i18n/tl.json new file mode 100644 index 000000000..d2a1a9e44 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/tl.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Emem.calist", + "Leeheonjin" + ] + }, + "wbqc-constraintreport-no-parameter": "wala", + "wbqc-badparameters-short": "Maling paggamit ng mga 'parameter'", + "wbqc-violation-message-diff-within-range": "Ang pinagkaiba sa pagitan ng $3 ($4) at $1 ($2) ay dapat nasa pagitan ng $5 at $6 ([$5; $6])." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/tr.json b/dist/extensions/WikibaseQualityConstraints/i18n/tr.json new file mode 100644 index 000000000..1cfedb4d0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/tr.json @@ -0,0 +1,152 @@ +{ + "@metadata": { + "authors": [ + "BaRaN6161 TURK", + "Demircimehmed", + "Hedda", + "Incelemeelemani", + "Joseph", + "Sadrettin", + "Sayginer", + "Sezgin İbiş" + ] + }, + "wbqc-constraintreport": "Kısıtlama raporu", + "wbqc-desc": "Hem ögeler hem de özellikler üzerindeki kısıtlamaları kontrol eder ve sonuçları özel bir sayfada görüntüler", + "wbqc-constraintreport-explanation-part-one": "Bu özel sayfa, istediğiniz herhangi bir varlık üzerinde kısıtlama kontrollerini yapar. Varlıklardaki değişiklikler sistem üzerinde anında görülür. Bu nedenle düzenlediğiniz her kısıtlama ihlali anında listeden kaldırılır.", + "wbqc-constraintreport-explanation-part-two": "Kısıtlamalar, bu ifadelerin her düzenlenişinde, genellikle birkaç dakika içinde, özelliklerle ilgili ifadelerden ayrıştırılır.", + "wbqc-constraintreport-form-section": "Varlığın kısıtlarını kontrol edin", + "wbqc-constraintreport-form-submit-label": "Kontrol", + "wbqc-constraintreport-form-entityid-label": "Varlık kimliği:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx veya Pxx", + "wbqc-constraintreport-result-headline": "Sonuçlar", + "wbqc-constraintreport-invalid-entity-id": "Geçersiz varlık kimliği.", + "wbqc-constraintreport-not-existent-entity": "Varlık bulunmuyor.", + "wbqc-constraintreport-empty-result": "Bu varlık üzerinde tanımlanmış hiçbir kısıtlama yoktur.", + "wbqc-constraintreport-status-violation": "İhlal", + "wbqc-constraintreport-status-compliance": "Uyumluluk", + "wbqc-constraintreport-status-exception": "İstisna", + "wbqc-constraintreport-status-todo": "Yapılacaklar", + "wbqc-constraintreport-status-bad-parameters": "Kötü parametreler", + "wbqc-constraintreport-status-deprecated": "Onaylanmayan", + "wbqc-constraintreport-status-warning": "Uyarı", + "wbqc-constraintreport-status-suggestion": "Öneri", + "wbqc-constraintreport-status-not-in-scope": "Kapsamda değil", + "wbqc-constraintreport-result-table-header-status": "Durum", + "wbqc-constraintreport-result-table-header-property": "Özellik", + "wbqc-constraintreport-result-table-header-message": "Mesaj", + "wbqc-constraintreport-result-table-header-constraint": "Kısıtlama", + "wbqc-constraintreport-result-link-to-claim": "iddiaya git", + "wbqc-constraintreport-result-link-to-constraint": "kısıtlamaya git", + "wbqc-constraintreport-no-parameter": "hiçbiri", + "wbqc-issues-short": "Sorunlar", + "wbqc-issues-long": "Bu ifadenin bazı sorunları var.", + "wbqc-potentialissues-short": "Olası sorunlar", + "wbqc-potentialissues-long": "Bu ifadenin bazı olası sorunları var.", + "wbqc-suggestions-short": "Öneriler", + "wbqc-suggestions-long": "Bu ifadeyi geliştirmek için bazı öneriler var.", + "wbqc-badparameters-short": "Kötü parametreler", + "wbqc-badparameters-long": "Bu kısıtlama ifadesinin bazı geçersiz parametreleri var.", + "wbqc-parameterissues-short": "Gelişmiş sorunlar", + "wbqc-parameterissues-long": "Bu özellikteki kısıtlama tanımı ile ilgili sorunlara ait problemler ifade ile ilgili olmayıp özelliğe aittir.", + "wbqc-constrainttypehelp-short": "Yardım", + "wbqc-constrainttypehelp-long": "Bu kısıtlama türü için yardım sayfası", + "wbqc-constraintdiscuss-short": "Tartış", + "wbqc-constraintdiscuss-long": "Bu kısıtlama hakkında tartışma sayfası", + "wbqc-cached-generic": "Bu sonuç önbelleğe alınmış olup, güncel olmayabilir.", + "wbqc-cached-minutes": "Bu sonuç önbelleğe alınmış bir sonuç olup, {{PLURAL:$1|1=bir dakika|$1 dakika}} öncesine aittir.", + "wbqc-cached-hours": "Bu sonuç önbelleğe alınmış bir sonuç olup, {{PLURAL:$1|1=bir saat|$1 saat}} öncesine aittir.", + "wbqc-cached-days": "Bu sonuç önbelleğe alınmış bir sonuç olup, {{PLURAL:$1|1=bir gün|$1 gün}} öncesine aittir.", + "wbqc-dataValueType-wikibase-entityid": "Varlık kimliği", + "wbq-subextension-name-wbqc": "Kısıtlamalar", + "wbqc-violation-header-parameters": "Parametreler:", + "wbqc-violations-group": "Kısıtlamalar", + "wbqc-violation-message": "Kısıtlama kontrolü bir ihlale işaret etti. Daha fazla bilgi için lütfen simgeye tıklayınız.", + "wbqc-violation-message-not-yet-implemented": "Teknik nedenlerden dolayı, \"$1\" sınırlaması kontrolü henüz yapılmamıştır.", + "wbqc-violation-message-security-reason": "Güvenlik nedeniyle, şu anda \"$1\" sınırlamasını kontrol etmek mümkün değildir. Bir çözüm üzerinde çalışıyoruz.", + "wbqc-violation-message-value-needed-of-type": "\"$1\" sınırlamalı özelliklerin \"$2\" türündeki değerlere sahip olması gerekir.", + "wbqc-violation-message-value-needed-of-types-2": "\"$1\" sınırlamalı özelliklerin \"$2\" veya \"$3\" tipinde değerleri olması gerekir.", + "wbqc-violation-message-parameter-needed": "\"$1\" sınırlaması olan özellikler \"$2\" parametresine ihtiyaç duyar.", + "wbqc-violation-message-parameters-needed-3": "\"$1\" kısıtlamalı mülklerin \"$2\", \"$3\" ve \"$4\" parametrelerine ihtiyacı vardır.", + "wbqc-violation-message-target-entity-must-exist": "Hedef varlık var olmalı.", + "wbqc-violation-message-value-entity-must-exist": "Varlık değeri bulunmalı.", + "wbqc-violation-message-parameter-value": "\"$1\" parametresi \"değer yok\" veya \"bilinmeyen değer\" değil özel bir değere sahip olmalıdır.", + "wbqc-violation-message-parameter-value-or-novalue": "\"$1\" parametresinin özel bir değeri veya \"değeri yok\" olmalı, ancak \"bilinmeyen değeri\" olmamalıdır.", + "wbqc-violation-message-parameter-entity": "\"$1\" parametresinin değeri \"$2\" değil bir varlık olmalıdır.", + "wbqc-violation-message-parameter-item": "\"$1\" parametresinin değeri \"$2\" değil bir öğe olmalıdır.", + "wbqc-violation-message-parameter-property": "\"$1\" parametresinin değeri \"$2\" değil bir özellik olmalıdır.", + "wbqc-violation-message-parameter-string": "\"$1\" parametresinin değeri \"$2\" değil bir dize olmalı.", + "wbqc-violation-message-parameter-monolingualtext": "\"$1\" parametresinin değeri, \"$2\" değil tek dilli bir metin olmalıdır.", + "wbqc-violation-message-parameter-single": "\"$1\" parametresi sadece tek bir değere sahip olmalıdır.", + "wbqc-violation-message-parameter-single-per-language": "\"$1\" parametresi, dil başına yalnızca tek bir değere sahip olmalı, ancak $2 ($3) için birden fazla değere sahip olmalıdır.", + "wbqc-violation-message-parameter-oneof": "\"$1\" Parametresi {{PLURAL:$2|1=$4.|2=ya $4 veya $5.|aşağıdakilerden biri:$3}} olmalıdır", + "wbqc-violation-message-parameter-regex": "$1 geçerli bir normal ifade değil.", + "wbqc-violation-message-sparql-error": "SPARQL sorgusu bir hatayla sonuçlandı.", + "wbqc-violation-message-parameters-error-unknown": "Bu kısıtlamanın parametreleri alınamadı.", + "wbqc-violation-message-parameters-error-toolong": "Bu kısıtlamanın parametreleri alınamadı çünkü çok uzunlardı.", + "wbqc-violation-message-invalid-scope": "$1, $2 sınırlama tipi için geçerli bir kapsam değildir; bu kısıtlama türü için yalnızca {{PLURAL:$3|kapsam|kapsam}} geçerli {{PLURAL:$3|$5.|2=$5 ve $6.|: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Commons bağlantısı var olmalı.", + "wbqc-violation-message-commons-link-not-well-formed": "Commons bağlantısı iyi oluşturulmalı.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "\"$1\" ad alanını kontrol et henüz uygulanmadı.", + "wbqc-violation-message-conflicts-with-property": "Bir işletme hem $1 hem de $2 için ifadeler içermemelidir.", + "wbqc-violation-message-conflicts-with-claim": "Bir de $2 $3 değerinde bir deyime sahipse, işletmenin $1 için bir ifadesi olmamalıdır.", + "wbqc-violation-message-contemporary-subject-earlier": "$1 ve $3 varlıklar $2 üzerinden bağlanmak için çağdaş olmalıdır, ancak $1 son bitiş değeri $4 ve en erken başlangıç değeri $3 ve $5.", + "wbqc-violation-message-contemporary-value-earlier": "$1 ve $3 varlıklar $2 üzerinden bağlanmak için çağdaş olmalıdır, ancak $3 son bitiş değeri $4 ve en erken başlangıç değeri $5.", + "wbqc-violation-message-diff-within-range": "$3 ($4) ve $1 ($2) arasındaki fark $5 ile $6 arasında olmalıdır.", + "wbqc-violation-message-diff-within-range-leftopen": "$3 ($4) ve $1 ($2) arasındaki fark $5 fazla olmamalıdır.", + "wbqc-violation-message-diff-within-range-rightopen": "$3 ($4) ve $1 ($2) arasındaki fark $5 az olmamalıdır.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Parametrelerde tanımlanan özellik, bu özellik ile aynı türde bir değere sahip olmalıdır.", + "wbqc-violation-message-format": "$1 ($2) değeri, $3 normal ifadesiyle eşleşmelidir.", + "wbqc-violation-message-format-clarification": "$1 ($2) değeri \"$4\" (normal ifade: $3) ile eşleşmelidir.", + "wbqc-violation-message-inverse": "$1 ters ifadesi $2 $3 olmalıdır.", + "wbqc-violation-message-item": "$1 bir varlığın {{PLURAL:$3|0=$2 ifadesi|1=$2 ifadesi $5|İfadesi şu değerlerden birine sahip $2 ifadesine sahip olmalıdır: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Bu $1 ifadesinde $2 niteleyici eksik.", + "wbqc-violation-message-multi-value": "Bu özellik birden fazla değer içermelidir.", + "wbqc-violation-message-multi-value-separators": "Bu özellik, aynı {{PLURAL:$2|1=$4 niteleyici.|Bu özellikler için niteleyici kümesine sahip birden fazla değer içermelidir: $3}}", + "wbqc-violation-message-one-of": "$1 değeri {{PLURAL:$2|1=$4.|2=$4 veya $5.|aşağıdakilerden biri olmalıdır: $3}}", + "wbqc-violation-message-qualifier": "Özellik yalnızca niteleyici olarak kullanılmalıdır.", + "wbqc-violation-message-no-qualifiers": "$1 ifadelerinde niteleyici olmamalıdır.", + "wbqc-violation-message-qualifiers": "$2, $1 için geçerli bir niteleyici değil - tek geçerli {{PLURAL:$3|1= niteleyici $5.|2= niteleyiciler $5 ve $6.|niteleyiciler: $4}}", + "wbqc-violation-message-range-parameters-needed": "\"$1\" türündeki değerlerle \"$4\" kısıtlamalı özellikler \"$2\" ve \"$3\" parametrelerine ihtiyaç duyar.", + "wbqc-violation-message-range-parameters-one-year": "Bir zaman birimi aralığının uç noktaları, yıl olarak kayıpsız saniyeye dönüştürülemediğinden, hem \"yıl\" birimine sahip olmalıdır ya da hiçbirinde \"yıl\" bulunmamalıdır.", + "wbqc-violation-message-range-parameters-same": "Bir aralığın başlangıç ($1) ve bitiş noktası ($2) aynı olmamalıdır.", + "wbqc-violation-message-range-quantity-closed": "$1 ($2) değeri $3 ile $4 arasında olmalıdır.", + "wbqc-violation-message-range-quantity-leftopen": "$1 ($2) değeri $3'den fazla olmamalıdır.", + "wbqc-violation-message-range-quantity-rightopen": "$1 ($2) değeri $3'den az olmamalıdır.", + "wbqc-violation-message-range-time-closed": "$1 ($2) değeri $3 ile $4 arasında olmalıdır.", + "wbqc-violation-message-range-time-closed-leftnow": "$1 ($2) değeri gelecekte olmalıdır, ancak $3'den sonra olmamalıdır.", + "wbqc-violation-message-range-time-closed-rightnow": "$1 ($2) değeri geçmişte olmalı, ancak $3'den önce olmamalıdır.", + "wbqc-violation-message-range-time-leftopen": "$1 ($2) değeri $3'den sonra olmamalıdır.", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1 ($2) değeri gelecekte olmamalıdır.", + "wbqc-violation-message-range-time-rightopen": "$1 ($2) değeri $3'den önce olmamalıdır.", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1 ($2) değeri geçmişte olmamalıdır.", + "wbqc-violation-message-single-value": "Bu özellik yalnızca tek bir değer içermelidir.", + "wbqc-violation-message-single-value-separators": "Bu mülk yalnızca aynı {{PLURAL:$2|1=$4 niteleyici.|bu mülkler için niteleyici kümesine sahip tek bir değere sahip olmalıdır: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Bu özellik tek bir “en iyi” değer içermelidir. Mevcut çoklu değerlerden biri “tercih edilen” sıralama ile işaretlenmelidir.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Bu özellik, aynı {{PLURAL:$2|1=$4 niteleyici.|bu mülkler için niteleyici seti: $3}} Kümesine sahip tek bir \"en iyi\" değer içermelidir: Mevcut birden çok değerden biri, \"tercih edilen\" sıralama ile işaretlenmelidir .", + "wbqc-violation-message-single-best-value-multi-preferred": "Bu özellik tek bir “en iyi” değer içermelidir. “Tercih edilen” rütbe ile birden fazla değer olmamalıdır.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Bu mülk, aynı {{PLURAL:$2|1=$4 niteleyici.|bu özellikler için niteleyiciler kümesine sahip tek bir \"en iyi\" değer içermelidir: $3}} \"Tercih edilen\" sıralamaya sahip birden fazla değer olmamalıdır.", + "wbqc-violation-message-symmetric": "$1 ayrıca $2 $3 simetrik ifadesine sahip olmalıdır.", + "wbqc-violation-message-type-instance": "$1 özelliğini kullanan varlıklar {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} (veya {{PLURAL:$3|1=bir alt sınıfı|2=bunlardan bir alt sınıf|alt sınıflarından biri}}), ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-type-subclass": "$1 özelliğini kullanan varlıklar, {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} (veya {{PLURAL:$3|1=bir alt sınıfı|2=bunlardan bir alt sınıf|alt sınıflarından biri}}), ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "$1 özelliğini kullanan varlıklar, {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} (veya {{PLURAL:$3|1=bunun bir alt sınıfı|2=bunlardan bir alt sınıf|alt sınıflarından biri}}), ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-valueType-instance": "$1 ifadelerinin değerleri {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} (veya {{PLURAL:$3|1=bunun bir alt sınıfı|2=alt sınıfları|alt sınıflarından biri}}), ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-valueType-subclass": "$1 ifadelerinin değerleri {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} alt sınıfları olmalıdır (veya {{PLURAL:$3|1=bir alt sınıfı|2=alt sınıfları|alt sınıflarından biri}}), ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "$1 ifadelerinin değerleri {{PLURAL:$3|1=$5|2=$5 veya $6|aşağıdaki sınıflardan biri}} (veya {{PLURAL:$3|1=bunun bir alt sınıfı|2=bir alt sınıf|alt sınıflarından biri}}) örnekleri veya alt sınıfları olmalıdır, ancak şu anda $2 {{PLURAL:$3|1=değil.|2=değil.|değil: $4}}", + "wbqc-violation-message-target-required-claim": "$1, {{PLURAL:$3|0 = ifade $2.|1=ifade $2 $5 olmalıdır.|$2 için aşağıdaki değerlerden birini içeren bir ifade:$4}}", + "wbqc-violation-message-unique-value": "Bu mülkün değeri başka hiçbir öğede bulunmamalı, ancak {{PLURAL:$1|1=$3.|2=$3 ve $4.|aşağıdaki öğeler için de mevcut: $2}}", + "wbqc-violation-message-valueOnly": "Bu özellik, niteleyiciler veya referanslar için değil, yalnızca bir ifadenin ana değeri için kullanılmalıdır.", + "wbqc-violation-message-reference": "Özellik yalnızca ifadelerde kullanılmalıdır, ifadenin ana değeri veya niteleyici için kullanılmamalıdır.", + "wbqc-violation-message-noBounds": "$1 değerinde sınır bulunmamalıdır.", + "wbqc-violation-message-units-none": "$1 değerinin bir birimi olmamalıdır.", + "wbqc-violation-message-units": "$1 değerinde {{PLURAL:$2|1=birim $4.|2=birim $4 veya $5.|şu birimlerden biri olmalıdır: $3}}", + "wbqc-violation-message-units-or-none": "$1 değerinin değeri {{PLURAL:$2|1=birim $4|2=birim $4 veya $5|aşağıdaki birimlerden biri}} veya {{PLURAL:$2|1=birimsiz.|2=birimsiz olmalıdır.|birimsiz: $3}}", + "wbqc-violation-message-entityType": "$1 özelliği bu tür varlıklarda kullanılmamalıdır; tek geçerli {{PLURAL:$2|1=varlık türü $4.|2=varlık türleri $4 ve $5.|varlık türleri: $3}}", + "wbqc-violation-message-none-of": "$1 değeri {{PLURAL:$2|1=$4.|2=$4 veya $5.|aşağıdakilerden biri olmamalıdır: $3}}", + "wbqc-violation-message-integer": "$1 için değerler tamsayı olmalıdır, ancak $2 kesirli bir kısmı vardır.", + "wbqc-violation-message-integer-bounds": "$1 için değerler tamsayı olmalıdır, ancak $2 sınırları kesirli bir kısma sahiptir.", + "wbqc-violation-message-citationNeeded": "$1 ifadelerinin en az bir referansı olmalıdır.", + "wbqc-violation-message-language": "$1 için ifadeler yalnızca {{PLURAL:$2|1=$4|2=ya $4 ya da $5 dilleri|$3 dillerinden biri}} için ayarlanmış Sözcük Birimlerde olmalıdır.", + "wbqc-violation-message-property-scope": "$1 özelliği bu konumda kullanılmamalıdır ($2). Bu mülk için tek geçerli {{PLURAL:$3|bölge|bölge}} {{PLURAL:$3|$5.|$4}}", + "wbqc-violation-message-exception": "Bu varlık, bu kısıtlama için bilinen bir istisnadır ve böyle işaretlenmiştir." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ug-arab.json b/dist/extensions/WikibaseQualityConstraints/i18n/ug-arab.json new file mode 100644 index 000000000..8983127b6 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ug-arab.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "چۈشكۈن" + ] + }, + "wbqc-dataValueType-wikibase-entityid": "مەۋجۇت ID" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/uk.json b/dist/extensions/WikibaseQualityConstraints/i18n/uk.json new file mode 100644 index 000000000..a52a8acb4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/uk.json @@ -0,0 +1,155 @@ +{ + "@metadata": { + "authors": [ + "Ahonc", + "Avatar6", + "DDPAT", + "Dars", + "Ice bulldog", + "Movses", + "Piramidion", + "SimondR", + "Vlad5250", + "Максим Підліснюк" + ] + }, + "wbqc-constraintreport": "Звіт про обмеження", + "wbqc-desc": "Перевіряє обмеження як для елементів так і для властивостей, і виводить результати на спеціальній сторінці", + "wbqc-constraintreport-explanation-part-one": "Ця спеціальна сторінка виконує перевірку обмежень на будь-який об'єкт, який ви забажаєте. Об'єкти обираються із робочої системи, тому кожне виправлення хибного обмеження буде миттєво видалене з цього списку.", + "wbqc-constraintreport-explanation-part-two": "Обмеження розбираються із тверджень у властивостях кожного разу, коли ці твердження редагуються, зазвичай у межах кількох хвилин.", + "wbqc-constraintreport-form-section": "Перевірити обмеження для сутності", + "wbqc-constraintreport-form-submit-label": "Перевірити", + "wbqc-constraintreport-form-entityid-label": "Ідентифікатор сутності:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx або Pxx", + "wbqc-constraintreport-result-headline": "Результат для", + "wbqc-constraintreport-invalid-entity-id": "Недійсний ідентифікатор сутності.", + "wbqc-constraintreport-not-existent-entity": "Сутність не існує.", + "wbqc-constraintreport-empty-result": "Немає жодних обмежень, визначених для цієї сутності.", + "wbqc-constraintreport-status-violation": "Порушення", + "wbqc-constraintreport-status-compliance": "Відповідність", + "wbqc-constraintreport-status-exception": "Виняток", + "wbqc-constraintreport-status-todo": "Todo", + "wbqc-constraintreport-status-bad-parameters": "Хибні параметри", + "wbqc-constraintreport-status-deprecated": "Застаріло", + "wbqc-constraintreport-status-warning": "Попередження", + "wbqc-constraintreport-status-suggestion": "Пропозиція", + "wbqc-constraintreport-status-not-in-scope": "Поза сферою дії", + "wbqc-constraintreport-result-table-header-status": "Статус", + "wbqc-constraintreport-result-table-header-property": "Властивість", + "wbqc-constraintreport-result-table-header-message": "Повідомлення", + "wbqc-constraintreport-result-table-header-constraint": "Обмеження", + "wbqc-constraintreport-result-link-to-claim": "перейти до запису", + "wbqc-constraintreport-result-link-to-constraint": "перейти до обмеження", + "wbqc-constraintreport-no-parameter": "немає", + "wbqc-issues-short": "Проблеми", + "wbqc-issues-long": "Це твердження має певні проблеми.", + "wbqc-potentialissues-short": "Потенційні проблеми", + "wbqc-potentialissues-long": "Це твердження має певні потенційні проблеми.", + "wbqc-suggestions-short": "Пропозиції", + "wbqc-suggestions-long": "Є деякі пропозиції, як поліпшити це твердження.", + "wbqc-badparameters-short": "Хибні параметри", + "wbqc-badparameters-long": "Це твердження обмеження має певні недійсні параметри", + "wbqc-parameterissues-short": "Складні проблеми", + "wbqc-parameterissues-long": "Ці питання є проблемами, які стосуються визначення обмеження властивості, а не цього твердження.", + "wbqc-constrainttypehelp-short": "Довідка", + "wbqc-constrainttypehelp-long": "Сторінка довідки для цього типу обмеження", + "wbqc-constraintdiscuss-short": "Обговорити", + "wbqc-constraintdiscuss-long": "Сторінка обговорення цього обмеження", + "wbqc-cached-generic": "Цей результат є кешованим і може бути застарілим.", + "wbqc-cached-minutes": "Цей результати є кешованим і, можливо, застарів на {{PLURAL:$1|$1 хвилину|$1 хвилини|$1 хвилин}}.", + "wbqc-cached-hours": "Цей результат є кешованим і, можливо, застарів на {{PLURAL:$1|$1 годину|$1 години|$1 годин}}.", + "wbqc-cached-days": "Цей результат є кешованим і, можливо, застарів на {{PLURAL:$1|$1 день|$1 дні|$1 днів}}.", + "wbqc-dataValueType-wikibase-entityid": "Ідентифікатор сутності", + "wbq-subextension-name-wbqc": "Обмеження", + "wbqc-violation-header-parameters": "Параметри:", + "wbqc-violations-group": "Обмеження", + "wbqc-violation-message": "Перевірка обмежень виявила порушення. Будь ласка, клацніть на іконці, щоб дізнатися більше.", + "wbqc-violation-message-not-yet-implemented": "З технічних причин перевірку щодо обмеження «$1» ще не було впроваджено.", + "wbqc-violation-message-security-reason": "З міркувань безпеки, перевірку обмеження «$1» на цей момент провести не можна. Ми працюємо над рішенням.", + "wbqc-violation-message-value-needed-of-type": "Властивості «$1» повинні мати значення типу «$2».", + "wbqc-violation-message-value-needed-of-types-2": "Властивості з обмеженням «$1» повинні мати значення типу «$2» або «$3».", + "wbqc-violation-message-parameter-needed": "Властивості з обмеженням «$1» потребують параметра «$2».", + "wbqc-violation-message-parameters-needed-3": "Властивостям з обмеженням «$1» необхідні параметри «$2», «$3» та «$4».", + "wbqc-violation-message-target-entity-must-exist": "Цільова сутність повинна існувати.", + "wbqc-violation-message-value-entity-must-exist": "Сутність для цього значення повинна існувати.", + "wbqc-violation-message-parameter-value": "Параметр «$1» повинен мати нестандартне значення, не «без значення» чи «невідоме значення».", + "wbqc-violation-message-parameter-value-or-novalue": "Параметр «$1» повинен мати нестандартне значення або «без значення», але в жодному разі не «невідоме значення».", + "wbqc-violation-message-parameter-entity": "Значення для параметра «$1» має бути сутністю, не «$2».", + "wbqc-violation-message-parameter-item": "Значення для параметра «$1» має бути елементом, не «$2».", + "wbqc-violation-message-parameter-property": "Значення для параметра «$1» має бути властивістю, не «$2».", + "wbqc-violation-message-parameter-string": "Значення для параметра «$1» має бути рядком, не «$2».", + "wbqc-violation-message-parameter-monolingualtext": "Значення для параметра «$1» має бути мономовним текстом, не «$2».", + "wbqc-violation-message-parameter-single": "Параметр «$1» повинен мати лише одне значення.", + "wbqc-violation-message-parameter-single-per-language": "Параметр «$1» повинен мати лише одне значення на мову, натомість він має кілька значень для $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Параметр «$1» повинен бути {{PLURAL:$2|1=$4.|2=або $4, або $5.|одним з такого: $3}}", + "wbqc-violation-message-parameter-regex": "$1 не є валідним регулярним виразом.", + "wbqc-violation-message-sparql-error": "Запит SPARQL видав помилку.", + "wbqc-violation-message-parameters-error-unknown": "Параметри цього обмеження не вдалося імпортувати.", + "wbqc-violation-message-parameters-error-toolong": "Параметри цього обмеження не вдалося імпортувати, оскільки вони були надто довгими.", + "wbqc-violation-message-invalid-scope": "$1 не є дійсною сферою дії для обмеження типу $2; {{PLURAL:$3|єдиною дійсною сферою дії|єдиними дійсними сферами дії}} для цього типу обмеження {{PLURAL:$3|є $5.|2=є $5 і $6.|є: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Посилання на Вікісховище повинно існувати.", + "wbqc-violation-message-commons-link-not-well-formed": "Посилання на Вікісховище повинно бути правильно вказане.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Перевірка за простором назв «$1» ще не впроваджена.", + "wbqc-violation-message-conflicts-with-property": "Сутність не повинна мати тверджень для $1 та $2 водночас.", + "wbqc-violation-message-conflicts-with-claim": "Сутність не повинна мати твердження для $1, якщо вона також має твердження для $2 зі значенням $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Сутності $1 і $3 мають бути одночасними, щоб на них можна було послатися через $2, однак останнє кінцеве значення $1 — $4, а найраніше початкове значення $3 — $5.", + "wbqc-violation-message-contemporary-value-earlier": "Сутності $1 і $3 мають бути одночасними, щоб на них можна було послатись через $2, однак останнє кінцеве значення $3 — $4, а найраніше початкове значення $1 — $5.", + "wbqc-violation-message-diff-within-range": "Різниця між $3 ($4) та $1 ($2) повинна бути в діапазоні між $5 та $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Різниця між $3 ($4) та $1 ($2) не повинна перевищувати $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Різниця між $3 ($4) та $1 ($2) не повинна бути нижчою $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Властивість, визначена в параметрах, повинна мати значення того ж типу, що й ця властивість.", + "wbqc-violation-message-format": "Значення для $1 ($2) повинно відповідати регулярному виразу $3.", + "wbqc-violation-message-format-clarification": "Значення для $1 ($2) повинно відповідати «$4» (регулярний вираз: $3).", + "wbqc-violation-message-inverse": "$1 має також містити зворотне твердження $2 $3.", + "wbqc-violation-message-item": "Сутність із $1 повинна також мати {{PLURAL:$3|0=твердження $2.|1=твердження $2 $5.|твердження для $2 з одним з таких значень: $4}}", + "wbqc-violation-message-mandatory-qualifier": "Цьому $1 твердженню бракує уточнення $2.", + "wbqc-violation-message-multi-value": "Це властивість повинна містити кілька значень.", + "wbqc-violation-message-multi-value-separators": "Ця властивість повинна містити кілька значень із тим же {{PLURAL:$2|1=уточненням $4.|набором уточнень для цих властивостей: $3}}", + "wbqc-violation-message-one-of": "Значення для $1 має бути {{PLURAL:$2|1=$4.|2=або $4, або $5.|одним з такого: $3}}", + "wbqc-violation-message-qualifier": "Ця властивість повинна використовуватись лише як уточнення.", + "wbqc-violation-message-no-qualifiers": "Твердження $1 не повинні мати жодних уточнень.", + "wbqc-violation-message-qualifiers": "$2 не є валідним уточненням для $1 — єдино {{PLURAL:$3|1=можливим уточненням є $5.|2=можливими уточненнями є $5 і $6.|можливими уточненням є: $4}}", + "wbqc-violation-message-range-parameters-needed": "Властивості зі значеннями типу «$1» із обмеженням «$4» потребують параметрів «$2» та «$3».", + "wbqc-violation-message-range-parameters-one-year": "Кінцеві точки діапазону одиниць часу мають або жодна, або обидві мати одиницю «рік», оскільки роки неможливо безпомилково конвертувати в секунди.", + "wbqc-violation-message-range-parameters-same": "Початкова ($1) й кінцева ($2) точки діапазону не повинні бути однаковими.", + "wbqc-violation-message-range-quantity-closed": "Значення для $1 ($2) має бути між $3 і $4.", + "wbqc-violation-message-range-quantity-leftopen": "Значення для $1 ($2) має бути не більшим ніж $3.", + "wbqc-violation-message-range-quantity-rightopen": "Значення для $1 ($2) має бути не меншим ніж $3.", + "wbqc-violation-message-range-time-closed": "Значення для $1 ($2) має бути між $3 і $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Значення для $1 ($2) має бути в майбутньому, але не після $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Значення для $1 ($2) має бути в минулому, але не до $3.", + "wbqc-violation-message-range-time-leftopen": "Значення для $1 ($2) не повинно бути після $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Значення для $1 ($2) не повинно бути в майбутньому.", + "wbqc-violation-message-range-time-rightopen": "Значення для $1 ($2) не повинно бути до $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Значення для $1 ($2) не повинно бути в минулому.", + "wbqc-violation-message-single-value": "Властивість повинна містити лише одне значення.", + "wbqc-violation-message-single-value-separators": "Ця властивість повинна мати лише одне значення з тим же {{PLURAL:$2|1=уточненням $4.|набором уточнень для цих властивостей: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Ця властивість повинна містити єдине «найкраще» значення. Із поточних декількох значень одне має бути позначене рангом «бажано».", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Ця властивість повинна містити єдине «найкраще» значення з тим же {{PLURAL:$2|1=уточненням $4.|набором уточнень для цих властивостей: $3}} Із поточних декількох значень одне має бути позначене рангом «бажано».", + "wbqc-violation-message-single-best-value-multi-preferred": "Ця властивість повинна містити єдине «найкраще» значення. Має бути не більше одного значення з рангом «бажано».", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Ця властивість повинна містити єдине «найкраще» значення з тим же {{PLURAL:$2|1=уточненням $4.|набором уточнень для цих властивостей: $3}} Має бути не більше одного значення з рангом «бажано».", + "wbqc-violation-message-symmetric": "$1 також має мати симетричне твердження $2 $3.", + "wbqc-violation-message-type-instance": "Сутності, які використовують властивість $1, мають бути примірниками {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|одного з їхніх підкласів}}), але $2 наразі {{PLURAL:$3|1=такими не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-type-subclass": "Сутності, які використовують властивість $1, мають бути підкласами {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|одного з їхніх підкласів}}), однак наразі $2 {{PLURAL:$3|1=такими не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Сутності, які використовують властивість $1, мають бути примірниками чи підкласами {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|2=їхніх підкласів|одного з їхніх підкласів}}), однак наразі $2 {{PLURAL:$3|1=такою не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-valueType-instance": "Значення тверджень $1 мають бути примірниками {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|одного з їхніх підкласів}}), але наразі $2 {{PLURAL:$3|1=такими не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-valueType-subclass": "Значення тверджень $1 мають бути підкласами {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|одного з їхніх підкласів}}), але наразі $2 {{PLURAL:$3|1=такими не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Значення тверджень $1 мають бути примірниками або підкласами {{PLURAL:$3|1=$5|2=$5 або $6|одного з поданих класів}} (або {{PLURAL:$3|1=його підкласу|2=їхніх підкласів|одного з їхніх підкласів}}), однак наразі $2 {{PLURAL:$3|1=такою не є.|2=такими не є.|такими не є: $4}}", + "wbqc-violation-message-target-required-claim": "$1 має містити {{PLURAL:$3|0=твердження $2.|1=твердження $2 $5.|твердження для $2 з одним із таких значень: $4}}", + "wbqc-violation-message-unique-value": "Значення цієї властивості не повинно бути присутнім у будь-якому іншому елементі, але є присутнім також у {{PLURAL:$1|1=$3.|2=$3 і $4.|таких елементах: $2}}", + "wbqc-violation-message-valueOnly": "Цю властивість слід використовувати лише для основного значення твердження, а не для уточнень чи посилань на джерела.", + "wbqc-violation-message-reference": "Властивість слід використовувати лише в посиланнях на джерела, а не для основного значення твердження чи для уточнення.", + "wbqc-violation-message-noBounds": "Значення для $1 не повинні мати будь-яких меж.", + "wbqc-violation-message-units-none": "Значення для $1 не повинно містити жодної одиниці (unit).", + "wbqc-violation-message-units": "Значення для $1 повинно мати {{PLURAL:$2|1=одиницю $4.|2=одиницю $4 або $5.|одну з таких одиниць: $3}}", + "wbqc-violation-message-units-or-none": "Значення для $1 повинно містити {{PLURAL:$2|1=одиницю $4|2=одиницю $4 або $5|одну з таких одиниць}} або {{PLURAL:$2|1=не містити жодної.|2=не містити жодної.|не містити жодної: $3}}", + "wbqc-violation-message-entityType": "Властивість $1 не повинна використовуватись у цьому типі сутностей; {{PLURAL:$2|1=єдиним дійсним типом сутностей є $4.|2=єдиними дійсними типами сутностей є $4 і $5.|єдиними дійсними типами сутностей є: $3}}", + "wbqc-violation-message-none-of": "Значення для $1 не повинно бути {{PLURAL:$2|1=$4.|2=$4 або $5.|одним з такого: $3}}", + "wbqc-violation-message-integer": "Значення для $1 мають бути цілими числами, однак $2 має дробову частину.", + "wbqc-violation-message-integer-bounds": "Значення для $1 мають бути цілими числами, однак межі $2 мають дробову частину.", + "wbqc-violation-message-citationNeeded": "Твердження для $1 повинні мати принаймні одне посилання на джерело.", + "wbqc-violation-message-language": "Висловлювання для $1 мають бути тільки в Лексемах з мовою, встановленою {{PLURAL:$2|1=$4.|2=на $4 або $5.|одним з наступного: $3}}", + "wbqc-violation-message-label-lacking": "Сутності з твердженнями для $1 також повинні мати мітку принаймні {{PLURAL:$2|1=$4 мовами.|будь-якою з таких мов: $3}}", + "wbqc-violation-message-property-scope": "Властивість $1 не слід використовувати у цій локації ($2). {{PLURAL:$3|Єдиною дійсною локацією|Єдиними дійсними локаціями}} для цієї властивості {{PLURAL:$3|є $5.|є: $4}}", + "wbqc-violation-message-exception": "Ця сутність є відомим винятком для цього обмеження, і її позначено як таку." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/ur.json b/dist/extensions/WikibaseQualityConstraints/i18n/ur.json new file mode 100644 index 000000000..34d85155f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/ur.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Hindustanilanguage", + "Zainab Meher" + ] + }, + "wbqc-issues-short": "مسائل", + "wbqc-issues-long": "اس بیان میں کچھ مسائل ہیں۔", + "wbqc-cached-generic": "یہ نتیجہ کیشڈ ہے اور گزرے وقت کا ہو سکتا ہے۔", + "wbqc-cached-minutes": "یہ نتیجہ کیشڈ ہے اور {{PLURAL:$1|1=one minute|$1 minutes}}تک پرانہ ہو جاۓ گا۔" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/vec.json b/dist/extensions/WikibaseQualityConstraints/i18n/vec.json new file mode 100644 index 000000000..c1edc8da8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/vec.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Cusolotto", + "Fierodelveneto" + ] + }, + "wbqc-constraintreport-result-table-header-property": "Proprietà", + "wbqc-constraintreport-result-table-header-message": "Mesagio", + "wbqc-potentialissues-long": "Sta declarasion ła ga calche potensiałe problema", + "wbqc-violation-message-mandatory-qualifier": "A sta declarasion $1 a ła ghe manca el cuałifegador $2" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/vi.json b/dist/extensions/WikibaseQualityConstraints/i18n/vi.json new file mode 100644 index 000000000..cc18dd579 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/vi.json @@ -0,0 +1,150 @@ +{ + "@metadata": { + "authors": [ + "Darcy Le", + "Ioe2015", + "KhangND", + "Minh Nguyen", + "NguoiDungKhongDinhDanh", + "Vinhtantran" + ] + }, + "wbqc-constraintreport": "Báo cáo về ràng buộc", + "wbqc-desc": "Kiểm tra các ràng buộc đối với các khoản mục và thuộc tính và hiển thị các kết quả trên một trang đặc biệt", + "wbqc-constraintreport-explanation-part-one": "Trang đặc biệt này kiểm tra các ràng buộc đối với thực thể nào đó. Các thực thể được lấy từ hệ thống một cách trực tiếp, nên mỗi vi phạm ràng buộc sẽ được xóa khỏi danh sách này ngay khi bạn sửa nó.", + "wbqc-constraintreport-explanation-part-two": "Các ràng buộc được phân tích từ lời phát biểu trên các thuộc tính mỗi lần các lời phát biểu được sửa đổi, thường trong vòng vài phút.", + "wbqc-constraintreport-form-section": "Kiểm tra ràng buộc cho thực thể", + "wbqc-constraintreport-form-submit-label": "Kiểm tra", + "wbqc-constraintreport-form-entityid-label": "ID thực thể:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx hoặc Pxx", + "wbqc-constraintreport-result-headline": "Kết quả cho", + "wbqc-constraintreport-invalid-entity-id": "ID thực thể không hợp lệ.", + "wbqc-constraintreport-not-existent-entity": "Thực thể không tồn tại.", + "wbqc-constraintreport-empty-result": "Thực thể này không có ràng buộc nào được định rõ.", + "wbqc-constraintreport-status-violation": "Vi phạm", + "wbqc-constraintreport-status-compliance": "Sự tuân theo", + "wbqc-constraintreport-status-exception": "Ngoại lệ", + "wbqc-constraintreport-status-todo": "Chờ kiểm tra", + "wbqc-constraintreport-status-bad-parameters": "Tham số hỏng", + "wbqc-constraintreport-status-deprecated": "Lỗi thời", + "wbqc-constraintreport-status-warning": "Cảnh báo", + "wbqc-constraintreport-status-suggestion": "Gợi ý", + "wbqc-constraintreport-status-not-in-scope": "Ngoài phạm vi", + "wbqc-constraintreport-result-table-header-status": "Trạng thái", + "wbqc-constraintreport-result-table-header-property": "Thuộc tính", + "wbqc-constraintreport-result-table-header-message": "Thông điệp", + "wbqc-constraintreport-result-table-header-constraint": "Ràng buộc", + "wbqc-constraintreport-result-link-to-claim": "bước tới khẳng định", + "wbqc-constraintreport-result-link-to-constraint": "bước tới ràng buộc", + "wbqc-constraintreport-no-parameter": "không có", + "wbqc-issues-short": "Các vấn đề", + "wbqc-issues-long": "Lời phát biểu này có vấn đề.", + "wbqc-potentialissues-short": "Vấn đề có thể xảy ra", + "wbqc-potentialissues-long": "Lời phát biểu này có thể có một số vấn đề.", + "wbqc-suggestions-short": "Gợi ý", + "wbqc-suggestions-long": "Có một vài gợi ý để cải tiến lời phát biểu này.", + "wbqc-badparameters-short": "Tham số hỏng", + "wbqc-badparameters-long": "Lời phát biểu ràng buộc này có một số tham số không hợp lệ.", + "wbqc-parameterissues-short": "Vấn đề nâng cao", + "wbqc-parameterissues-long": "Đây là vấn đề liên quan đến định nghĩa ràng buộc đối với thuộc tính, không phải là vấn đề với lời phát biểu này.", + "wbqc-constrainttypehelp-short": "Trợ giúp", + "wbqc-constrainttypehelp-long": "Trang trợ giúp về kiểu ràng buộc này", + "wbqc-constraintdiscuss-short": "Thảo luận", + "wbqc-constraintdiscuss-long": "Trang thảo luận về ràng buộc này", + "wbqc-cached-generic": "Kết quả này được lưu vào bộ đệm và có thể không được cập nhật.", + "wbqc-cached-minutes": "Kết quả này được lưu vào bộ đệm và có thể đã không được cập nhật được {{PLURAL:$1|1=một phút|$1 phút}} rồi.", + "wbqc-cached-hours": "Kết quả này được lưu vào bộ đệm và có thể đã không được cập nhật được {{PLURAL:$1|1=một giờ|$1 giờ}} rồi.", + "wbqc-cached-days": "Kết quả này được lưu vào bộ nhớ đệm và có thể đã không được cập nhật được {{PLURAL:$1|1=một ngày|$1 ngày}} rồi.", + "wbqc-dataValueType-wikibase-entityid": "Mã thực thể", + "wbq-subextension-name-wbqc": "Ràng buộc", + "wbqc-violation-header-parameters": "Tham số:", + "wbqc-violations-group": "Ràng buộc", + "wbqc-violation-message": "Việc kiểm tra ràng buộc đã chỉ ra một vi phạm. Xin hãy nhấn chuột vào hình tượng để biết thêm thông tin.", + "wbqc-violation-message-not-yet-implemented": "Vì lý do kỹ thuật, phần kiểm tra ràng buộc “$1” chưa được thực hiện.", + "wbqc-violation-message-security-reason": "Không thể kiểm tra ràng buộc “$1” vào lúc bây giờ vì lý do an toàn. Chúng tôi đang cố gắng khắc phục vấn đề này.", + "wbqc-violation-message-value-needed-of-type": "Thuộc tính có ràng buộc “$1” phải có giá trị kiểu “$2”.", + "wbqc-violation-message-value-needed-of-types-2": "Thuộc tính với ràng buộc “$1” cần phải có giá trị thuộc kiểu “$2” hoặc “$3”.", + "wbqc-violation-message-parameter-needed": "Thuộc tính có ràng buộc “$1” phải có tham số “$2”.", + "wbqc-violation-message-parameters-needed-3": "Thuộc tính với ràng buộc “$1” cần các tham số “$2”, “$3”, và “$4”.", + "wbqc-violation-message-target-entity-must-exist": "Thực thể đích phải tồn tại.", + "wbqc-violation-message-value-entity-must-exist": "Thực thể giá trị phải tồn tại.", + "wbqc-violation-message-parameter-value": "Tham số “$1” phải có một giá trị tùy chỉnh, không được là “không giá trị” hoặc “không rõ giá trị”.", + "wbqc-violation-message-parameter-value-or-novalue": "Tham số “$1” phải có một giá trị tùy chỉnh hoặc “không giá trị”, nhưng không được là “không rõ giá trị”.", + "wbqc-violation-message-parameter-entity": "Giá trị của tham số “$1” phải là một thực thể, không phải là “$2”.", + "wbqc-violation-message-parameter-item": "Giá trị của tham số “$1” phải là một khoản mục, không phải là “$2”.", + "wbqc-violation-message-parameter-property": "Giá trị của tham số “$1” phải là một thuộc tính, không phải là “$2”.", + "wbqc-violation-message-parameter-string": "Giá trị của tham số “$1” phải là một chuỗi ký tự, không phải là “$2”.", + "wbqc-violation-message-parameter-monolingualtext": "Giá trị của tham số “$1” phải là một văn bản đơn ngữ, không phải là “$2”.", + "wbqc-violation-message-parameter-single": "Tham số “$1” chỉ được có một giá trị.", + "wbqc-violation-message-parameter-single-per-language": "Tham số “$1” chỉ được có một giá trị cho mỗi ngôn ngữ, nhưng lại có nhiều giá trị cho $2 ($3).", + "wbqc-violation-message-parameter-oneof": "Tham số “$1” phải là {{PLURAL:$2|1=$4.|2=$4 hoặc $5.|một trong các giá trị sau:$3}}", + "wbqc-violation-message-parameter-regex": "$1 không phải là một biểu thức chính quy hợp lệ.", + "wbqc-violation-message-sparql-error": "Truy vấn SPARQL trả về lỗi.", + "wbqc-violation-message-parameters-error-unknown": "Không nhập được các tham số của ràng buộc này.", + "wbqc-violation-message-parameters-error-toolong": "Không nhập được các tham số của ràng buộc này vì chúng quá dài.", + "wbqc-violation-message-invalid-scope": "$1 không phải là phạm vi hợp lệ cho kiểu ràng buộc $2; {{PLURAL:$3||các}} ràng buộc hợp lệ của kiểu ràng buộc này {{PLURAL:$3|là $5.|2=là $5 và $6.|là: $4}}", + "wbqc-violation-message-commons-link-no-existent": "Liên kết đến Commons nên tồn tại.", + "wbqc-violation-message-commons-link-not-well-formed": "Liên kết đến Commons nên hợp lệ.", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "Chưa hỗ trợ kiểm tra không gian tên “$1”.", + "wbqc-violation-message-conflicts-with-property": "Thục thể không nên có lời phát biểu cho cả $1 và $2.", + "wbqc-violation-message-conflicts-with-claim": "Thực thể không nên có lời phát biểu $1 nếu nó cũng có lời phát biểu $2 với giá trị $3.", + "wbqc-violation-message-contemporary-subject-earlier": "Các thực thể $1 và $3 phải cùng thời để có thể được liên kết thông qua $2, nhưng giá trị kết thúc trễ nhất của $1 là $4 còn giá trị bắt đầu sớm nhất của $3 là $5.", + "wbqc-violation-message-contemporary-value-earlier": "Các thực thể $1 và $3 phải cùng thời để có thể được liên kết thông qua $2, nhưng giá trị kết thúc trễ nhất của $3 là $4 còn giá trị bắt đầu sớm nhất của $1 là $5.", + "wbqc-violation-message-diff-within-range": "Hiệu số của $3 ($4) và $1 ($2) nên nằm trong khoảng từ $5 đến $6 kể cả $6.", + "wbqc-violation-message-diff-within-range-leftopen": "Hiệu số của $3 ($4) và $1 ($2) không nên lớn hơn $5.", + "wbqc-violation-message-diff-within-range-rightopen": "Hiệu số giữa $3 ($4) và $1 ($2) không nên nhỏ hơn $5.", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "Thuộc tính được định rõ trong thông số phải có giá trị cùng kiểu với thuộc tính này.", + "wbqc-violation-message-format": "Giá trị của $1 ($2) nên trùng với biểu thức chính quy $3.", + "wbqc-violation-message-format-clarification": "Giá trị của $1 ($2) nên trùng với “$4” (biểu thức chính quy: $3).", + "wbqc-violation-message-inverse": "$1 nên cũng có lời phát biểu ngược $2 $3.", + "wbqc-violation-message-item": "Một thực thể có $1 cũng nên có {{PLURAL:$3|0=lời phát biểu $2.|1=lời phát biểu $2 $5.|lời phát biểu dành cho $2 với một trong các giá trị sau:$4}}", + "wbqc-violation-message-mandatory-qualifier": "Lời phát biểu $1 này đang thiếu từ hạn định $2.", + "wbqc-violation-message-multi-value": "Thuộc tính này nên có nhiều giá trị.", + "wbqc-violation-message-multi-value-separators": "Thuộc tính này nên có nhiều giá trị với cùng {{PLURAL:$2|1=từ hạn định $4.|tập từ hạn định dành cho các thuộc tính như thế này: $3}}", + "wbqc-violation-message-one-of": "Giá trị của $1 nên là {{PLURAL:$2|1=$4.|2=$4 hoặc $5.|một trong các giá trị sau: $3}}", + "wbqc-violation-message-qualifier": "Chỉ nên sử dụng thuộc tính này làm từ hạn định.", + "wbqc-violation-message-no-qualifiers": "Lời phát biểu $1 không nên có từ hạn định.", + "wbqc-violation-message-qualifiers": "$2 không phải là từ hạn định hợp lệ cho $1 – chỉ có {{PLURAL:$3|1=$5 là từ hạn định hợp lệ.|2=$5 và $6 là từ hạn định hợp lệ.|các từ hạn định sau là hợp lệ: $4}}", + "wbqc-violation-message-range-parameters-needed": "Thuộc tính với giá thuộc kiểu “$1” với ràng buộc “$4” cần có các tham số “$2” và “$3”.", + "wbqc-violation-message-range-parameters-one-year": "Hai điểm đầu và cuối của một khoảng đơn vị thời gian phải cùng có hoặc cùng không có đơn vị “năm” vì số năm không thể được chuyển đổi sang giây mà không làm mất độ chính xác.", + "wbqc-violation-message-range-parameters-same": "Điểm đầu ($1) và điểm cuối ($2) của một khoảng không được trùng nhau.", + "wbqc-violation-message-range-quantity-closed": "Giá trị của $1 ($2) nên nằm từ $3 đến $4.", + "wbqc-violation-message-range-quantity-leftopen": "Giá trị của $1 ($2) không nên lớn hơn $3.", + "wbqc-violation-message-range-quantity-rightopen": "Giá trị của $1 ($2) không nên nhỏ hơn $3.", + "wbqc-violation-message-range-time-closed": "Giá trị của $1 ($2) nên nằm từ $3 đến $4.", + "wbqc-violation-message-range-time-closed-leftnow": "Giá trị của $1 ($2) nên là thời điểm trong tương lai, nhưng không sau $3.", + "wbqc-violation-message-range-time-closed-rightnow": "Giá trị của $1 ($2) nên là thời điểm trong quá khứ, nhưng không trước $3.", + "wbqc-violation-message-range-time-leftopen": "Giá trị của $1 ($2) không nên sau $3.", + "wbqc-violation-message-range-time-leftopen-rightnow": "Giá trị của $1 ($2) không nên là thời điểm trong tương lai.", + "wbqc-violation-message-range-time-rightopen": "Giá trị của $1 ($2) không nên trước $3.", + "wbqc-violation-message-range-time-rightopen-leftnow": "Giá trị của $1 ($2) không nên là thời điểm trong quá khứ.", + "wbqc-violation-message-single-value": "Thuộc tính này chỉ nên sử dụng một giá trị.", + "wbqc-violation-message-single-value-separators": "Thuộc tính này chỉ nên có một giá trị duy nhất với cùng {{PLURAL:$2|1=từ hạn định $4.|tập từ hạn định dành cho các thuộc tính như thế này: $3}}", + "wbqc-violation-message-single-best-value-no-preferred": "Thuộc tính này chỉ nên có một giá trị “tốt nhất”. Trong các giá trị hiện tại, một giá trị nên được đánh dấu là hạng “ưu tiên”.", + "wbqc-violation-message-single-best-value-no-preferred-separators": "Thuộc tính này chỉ nên có một giá trị “tốt nhất” với cùng {{PLURAL:$2|1=từ hạn định $4.|tập từ hạn định dành cho các thuộc tính như thế này: $3}} Trong các giá trị hiện tại, một giá trị nên được đánh dấu là hạng “ưu tiên”.", + "wbqc-violation-message-single-best-value-multi-preferred": "Thuộc tính này chỉ nên có một giá trị “tốt nhất”. Không nên có hơn một giá trị có hạng “ưu tiên”.", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "Thuộc tính này chỉ nên có một giá trị “tốt nhất” với cùng {{PLURAL:$2|1=từ hạn định $4.|tập từ hạn định dành cho các thuộc tính như thế này: $3}} Không nên có hơn một giá trị có hạng “ưu tiên”.", + "wbqc-violation-message-symmetric": "$1 nên cũng có lời phát biểu đối xứng $2 $3.", + "wbqc-violation-message-type-instance": "Các thực thể dùng thuộc tính $1 nên là thực thể của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-type-subclass": "Các thực thể dùng thuộc tính $1 nên là lớp con của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-type-instanceOrSubclass": "Các thực thể dùng thuộc tính $1 nên là thực thể hoặc lớp con của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-valueType-instance": "Giá trị của lời phát biểu $1 nên là thực thể của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-valueType-subclass": "Giá trị của lời phát biểu $1 nên là lớp con của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "Giá trị của lời phát biểu $1 nên là thực thể hoặc lớp con của {{PLURAL:$3|1=$5|2=$5 hoặc $6|một trong các lớp sau}} (hoặc của {{PLURAL:$3|1=một lớp con của nó|2=một lớp con của chúng|một trong các lớp con của chúng}}), nhưng $2 hiện {{PLURAL:$3|1=không phải.|2=không phải.|không phải: $4}}", + "wbqc-violation-message-target-required-claim": "$1 nên có {{PLURAL:$3|0=một lời phát biểu $2.|1=một lời phát biểu $2 $5.|một lời phát biểu dành cho $2 với một trong các giá trị sau:$4}}", + "wbqc-violation-message-unique-value": "Giá trị của thuộc tính này không nên có mặt trong một khoản mục nào khác, nhưng lại có mặt trong {{PLURAL:$1|1=$3.|2=$3 và $4.|các khoản mục sau: $2}}", + "wbqc-violation-message-valueOnly": "Thuộc tính này chỉ nên dùng làm giá trị chính của một lời phát biểu, không nên dùng làm từ hạn định hoặc nguồn tham khảo.", + "wbqc-violation-message-reference": "Thuộc tính chỉ nên được dùng trong nguồn tham khảo, không nên dùng làm giá trị chính của một lời phát biểu hoặc từ hạn định.", + "wbqc-violation-message-noBounds": "Giá trị của $1 không nên có khoảng giới hạn.", + "wbqc-violation-message-units-none": "Giá trị của $1 không nên có đơn vị.", + "wbqc-violation-message-units": "Giá trị của $1 nên có {{PLURAL:$2|1=đơn vị $4.|2=đơn vị $4 hoặc $5.|một trong các đơn vị sau: $3}}", + "wbqc-violation-message-units-or-none": "Giá trị của $1 nên có {{PLURAL:$2|1=đơn vị $4.|2=đơn vị $4 hoặc $5.|một trong các đơn vị sau}} hoặc {{PLURAL:$2|1=không có đơn vị nào.|2=không có đơn vị nào.|không có đơn vị nào: $3}}", + "wbqc-violation-message-entityType": "Thuộc tính $1 không nên dùng trong kiểu thực thể này, {{PLURAL:$2|1=kiểu thực thể hợp lệ duy nhất là $4.|2=các kiểu thực thể hợp lệ duy nhất là $4 và $5.|các kiểu thực thể hợp lệ duy nhất là: $3}}", + "wbqc-violation-message-none-of": "Giá trị của $1 không được là {{PLURAL:$2|1=$4.|2=$4 hoặc $5.|một trong các giá trị sau:$3}}", + "wbqc-violation-message-integer": "Giá trị của $1 không được là số nguyên, nhưng $2 lại có phần thập phân.", + "wbqc-violation-message-integer-bounds": "Giá trị của $1 phải là số nguyên, nhưng khoảng giá trị của $2 lại có phần thập phân.", + "wbqc-violation-message-citationNeeded": "Lời phát biểu của $1 nên có ít nhất một nguồn tham khảo.", + "wbqc-violation-message-language": "Lời phát biểu của $1 chỉ nên có trong Từ vị với ngôn ngữ đặt là {{PLURAL:$2|1=$4.|2=$4 hoặc $5.|một trong các ngôn ngữ sau: $3}}", + "wbqc-violation-message-property-scope": "Thuộc tính $1 không nên dùng tại vị trí này ($2). {{PLURAL:$3|Vị trí|Các vị trí}} hợp lệ duy nhất của thuộc tính này {{PLURAL:$3|là $5.|là: $4}}", + "wbqc-violation-message-exception": "Thực thể này là một ngoại lệ biết trước của ràng buộc này và đã được đánh dấu." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/xmf.json b/dist/extensions/WikibaseQualityConstraints/i18n/xmf.json new file mode 100644 index 000000000..7e2775d20 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/xmf.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Silovan" + ] + }, + "wbqc-violation-header-parameters": "პარამეტრეფი:" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/yi.json b/dist/extensions/WikibaseQualityConstraints/i18n/yi.json new file mode 100644 index 000000000..5c3f4eaac --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/yi.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "פוילישער", + "Pacha Tchernof" + ] + }, + "wbqc-constraintreport-form-submit-label": "קאנטראלירן", + "wbqc-constraintreport-status-exception": "אויסנאַם", + "wbqc-constraintreport-status-todo": "צו טון", + "wbqc-constraintreport-status-bad-parameters": "אומגילטיגע פאַראַמעטערס", + "wbqc-constraintreport-status-deprecated": "פארעלטערט", + "wbqc-constraintreport-status-warning": "ווארענונג", + "wbqc-constraintreport-status-suggestion": "פֿאָרשלאָג", + "wbqc-constraintreport-result-table-header-status": "סטאַטוס", + "wbqc-constraintreport-result-table-header-message": "מעלדונג", + "wbqc-constraintreport-result-table-header-constraint": "באַשרענקונג", + "wbqc-constraintreport-no-parameter": "קיין", + "wbqc-issues-short": "פראבלעמען", + "wbqc-issues-long": "דער אויסזאג האט עטלעכע פראבלעמען.", + "wbqc-potentialissues-short": "פאטענציאלע פראבלעמען", + "wbqc-suggestions-short": "פֿאָרשלאָגן", + "wbqc-badparameters-short": "אומגילטיגע פאַראַמעטערס", + "wbqc-parameterissues-short": "פארגעשריטענע פראגעס", + "wbqc-constrainttypehelp-short": "הילף", + "wbqc-constraintdiscuss-short": "דיסקוסיע", + "wbq-subextension-name-wbqc": "באַשרענקונגען", + "wbqc-violation-header-parameters": "פאראמעטערס:", + "wbqc-violations-group": "באַשרענקונגען", + "wbqc-violation-message-parameter-single": "דער פאַראַמעטער \"$1\" דאַרף האָבן נאר איין איינציגן ווערט.", + "wbqc-violation-message-mandatory-qualifier": "דער דאזיקער $1 אויסזאג פֿעלט א קוואליפֿיקאטאר $2.", + "wbqc-violation-message-units-none": "די ווערט פון $1 ברויכט נישט קיין איינס." +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/za.json b/dist/extensions/WikibaseQualityConstraints/i18n/za.json new file mode 100644 index 000000000..aa5a12959 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/za.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Midleading" + ] + }, + "wbqc-constraintreport-result-table-header-message": "Siuhsik", + "wbqc-constrainttypehelp-short": "Bangcoh", + "wbqc-constraintdiscuss-short": "Daujlun" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/zh-hans.json b/dist/extensions/WikibaseQualityConstraints/i18n/zh-hans.json new file mode 100644 index 000000000..616d0d02e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/zh-hans.json @@ -0,0 +1,158 @@ +{ + "@metadata": { + "authors": [ + "A Chinese Wikipedian", + "A Retired User", + "Deathkon", + "Hudafu", + "Liuxinyu970226", + "NeverBehave", + "Shizhao", + "Xiplus", + "Xzonn", + "予弦", + "列维劳德", + "神樂坂秀吉", + "铁桶" + ] + }, + "wbqc-constraintreport": "约束报告", + "wbqc-desc": "检查项目和属性的约束,并在特殊页面上显示结果", + "wbqc-constraintreport-explanation-part-one": "此特殊页面可对您希望的任何实体执行约束检查。实体取自实时系统,因此您在那里修复的每个约束违规都会立即从此列表中删除。", + "wbqc-constraintreport-explanation-part-two": "每当编辑属性陈述时,约束都会从这些陈述中解析,通常在几分钟内。", + "wbqc-constraintreport-form-section": "检查实体的约束", + "wbqc-constraintreport-form-submit-label": "检查", + "wbqc-constraintreport-form-entityid-label": "实体ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx或Pxx", + "wbqc-constraintreport-result-headline": "结果为", + "wbqc-constraintreport-invalid-entity-id": "无效的实体ID。", + "wbqc-constraintreport-not-existent-entity": "实体不存在。", + "wbqc-constraintreport-empty-result": "没有对此实体定义约束。", + "wbqc-constraintreport-status-violation": "违反", + "wbqc-constraintreport-status-compliance": "符合", + "wbqc-constraintreport-status-exception": "例外", + "wbqc-constraintreport-status-todo": "待办", + "wbqc-constraintreport-status-bad-parameters": "错误参数", + "wbqc-constraintreport-status-deprecated": "弃用", + "wbqc-constraintreport-status-warning": "警告", + "wbqc-constraintreport-status-suggestion": "建议", + "wbqc-constraintreport-status-not-in-scope": "不在范围", + "wbqc-constraintreport-result-table-header-status": "状态", + "wbqc-constraintreport-result-table-header-property": "属性", + "wbqc-constraintreport-result-table-header-message": "消息", + "wbqc-constraintreport-result-table-header-constraint": "约束", + "wbqc-constraintreport-result-link-to-claim": "转到声称", + "wbqc-constraintreport-result-link-to-constraint": "转到约束", + "wbqc-constraintreport-no-parameter": "无", + "wbqc-issues-short": "问题", + "wbqc-issues-long": "此陈述有一些问题。", + "wbqc-potentialissues-short": "潜在问题", + "wbqc-potentialissues-long": "此陈述有一些潜在问题。", + "wbqc-suggestions-short": "建议", + "wbqc-suggestions-long": "有一些建议可以改进此陈述。", + "wbqc-badparameters-short": "错误参数", + "wbqc-badparameters-long": "此约束陈述存在一些无效参数。", + "wbqc-parameterissues-short": "高级问题", + "wbqc-parameterissues-long": "这些问题是属性上的约束定义的问题,而不是此陈述的问题。", + "wbqc-constrainttypehelp-short": "帮助", + "wbqc-constrainttypehelp-long": "此约束类型的帮助页面", + "wbqc-constraintdiscuss-short": "讨论", + "wbqc-constraintdiscuss-long": "有关此约束的讨论页", + "wbqc-cached-generic": "此结果已缓存,并可能过时。", + "wbqc-cached-minutes": "此结果已缓存,并可能在{{PLURAL:$1|$1分钟}}后过时。", + "wbqc-cached-hours": "此结果已缓存,并可能在最多{{PLURAL:$1|$1小时}}后过期。", + "wbqc-cached-days": "此结果已缓存,并可能在{{PLURAL:$1|$1天}}后过期。", + "wbqc-dataValueType-wikibase-entityid": "实体ID", + "wbq-subextension-name-wbqc": "约束", + "wbqc-violation-header-parameters": "参数:", + "wbqc-violations-group": "约束", + "wbqc-violation-message": "约束检查指出了违例。请点击图标以获取进一步信息。", + "wbqc-violation-message-not-yet-implemented": "由于技术原因,对约束“$1”的检查未能执行。", + "wbqc-violation-message-security-reason": "基于安全原因,目前无法检查“$1”约束。我们正在提供解决方案。", + "wbqc-violation-message-value-needed-of-type": "带约束“$1”的属性需要有类型“$2”的值。", + "wbqc-violation-message-value-needed-of-types-2": "带约束“$1”的属性需要有类型“$2”或“$3”的值。", + "wbqc-violation-message-parameter-needed": "带约束“$1”的属性需要参数“$2”。", + "wbqc-violation-message-parameters-needed-3": "带约束“$1”的属性需要参数“$2”、“$3”和“$4”。", + "wbqc-violation-message-target-entity-must-exist": "目标实体必须存在。", + "wbqc-violation-message-value-entity-must-exist": "值实体必须存在。", + "wbqc-violation-message-parameter-value": "参数“$1”必须包含自定义值,而不是“无值”或“未知值”。", + "wbqc-violation-message-parameter-value-or-novalue": "参数“$1”必须包含自定义值或“无值”,但不可为“未知值”。", + "wbqc-violation-message-parameter-entity": "参数“$1”的值必须是实体,而不是“$2”。", + "wbqc-violation-message-parameter-item": "参数“$1”的值必须是项目,而不是“$2”。", + "wbqc-violation-message-parameter-property": "参数“$1”的值必须是属性,而不是“$2”。", + "wbqc-violation-message-parameter-string": "参数“$1”的值必须是字符串,而不是“$2”。", + "wbqc-violation-message-parameter-monolingualtext": "参数“$1”的值必须是单语文本,而不是“$2”。", + "wbqc-violation-message-parameter-single": "参数“$1”必须只有一个值。", + "wbqc-violation-message-parameter-single-per-language": "参数“$1”必须每种语言只包含一个值,但却有$2($3)的多个值。", + "wbqc-violation-message-parameter-oneof": "参数“$1”必须为{{PLURAL:$2|1=$4。|2=$4或$5。|以下值之一:$3}}", + "wbqc-violation-message-parameter-regex": "$1不是有效的正则表达式。", + "wbqc-violation-message-sparql-error": "SPARQL查询导致错误。", + "wbqc-violation-message-parameters-error-unknown": "无法导入此约束的参数。", + "wbqc-violation-message-parameters-error-toolong": "无法导入此约束的参数,因为太长。", + "wbqc-violation-message-invalid-scope": "$1不是用于约束类型$2的有效范围;用于此约束类型的有效{{PLURAL:$3|范围}}{{PLURAL:$3|只有$5。|2=只有$5和$6。|有:$4}}", + "wbqc-violation-message-commons-link-no-existent": "共享资源链接应存在。", + "wbqc-violation-message-commons-link-not-well-formed": "共享资源链接应符合语法规则。", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "对命名空间“$1”的检查尚未执行。", + "wbqc-violation-message-conflicts-with-property": "一个实体不应同时有$1和$2的陈述。", + "wbqc-violation-message-conflicts-with-claim": "如果实体带有值$3的陈述$2,则该实体不应有$1的陈述。", + "wbqc-violation-message-contemporary-subject-earlier": "实体$1和$3应该是同时通过$2链接,但$1的最新结束值为$4,而$3的最早起始值为$5。", + "wbqc-violation-message-contemporary-value-earlier": "实体$1和$3应该同时通过$2链接,但$3的最新结束值为$4,$1的最早起始值为$5。", + "wbqc-violation-message-diff-within-range": "$3($4)和$1($2)之间的差异应界定在$5和$6之间。", + "wbqc-violation-message-diff-within-range-leftopen": "$3($4)和$1($2)之间的差异不应大于$5。", + "wbqc-violation-message-diff-within-range-rightopen": "$3($4)和$1($2)之间的差异不应小于$5。", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "参数中定义的属性必须具有与此属性相同类型的值。", + "wbqc-violation-message-format": "$1的值($2)应匹配正则表达式$3。", + "wbqc-violation-message-format-clarification": "$1的值($2)应匹配“$4”(正则表达式:$3)。", + "wbqc-violation-message-inverse": "$1也应当拥有相反陈述$2 $3。", + "wbqc-violation-message-item": "具有$1的实体也应拥有{{PLURAL:$3|0=陈述$2。|1=陈述$2 $5。|陈述$2,并使用以下值之一:$4}}", + "wbqc-violation-message-mandatory-qualifier": "此$1陈述缺少修饰符$2。", + "wbqc-violation-message-multi-value": "此属性应包含多个值。", + "wbqc-violation-message-multi-value-separators": "此属性应包含多个值,这些值具有相同的{{PLURAL:$2|1=$4限定符。|用于这些属性的限定符集:$3}}", + "wbqc-violation-message-one-of": "$1的值应为{{PLURAL:$2|1=$4。|2=$4或$5之一。|以下值之一:$3}}", + "wbqc-violation-message-qualifier": "属性应只用作限定符。", + "wbqc-violation-message-no-qualifiers": "$1声明不应包含任何限定符。", + "wbqc-violation-message-qualifiers": "$2不是用于$1的有效限定符——{{PLURAL:$3|1=唯一有效的限定符是$5。|2=只有$5和$6限定符有效。|只有以下限定符有效:$4}}", + "wbqc-violation-message-range-parameters-needed": "带类型“$1”值与约束“$4”的属性需要参数“$2”和“$3”。", + "wbqc-violation-message-range-parameters-one-year": "时间单位范围的两个端点必须都有(或都没有)单位“年”,因为年不能被无损地转换为秒。", + "wbqc-violation-message-range-parameters-same": "范围的起点($1)和终点($2)不能相同。", + "wbqc-violation-message-range-quantity-closed": "$1($2)的值应界定在$3和$4之间。", + "wbqc-violation-message-range-quantity-leftopen": "$1($2)的值不应大于$3。", + "wbqc-violation-message-range-quantity-rightopen": "$1($2)的值不应小于$3。", + "wbqc-violation-message-range-time-closed": "$1($2)的值应界定在$3和$4之间。", + "wbqc-violation-message-range-time-closed-leftnow": "$1($2)的值应在未来,但不应在$3之后。", + "wbqc-violation-message-range-time-closed-rightnow": "$1($2)的值应在过去,但不应在$3之前。", + "wbqc-violation-message-range-time-leftopen": "$1($2)的值不应超过$3。", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1($2)的值不应在未来。", + "wbqc-violation-message-range-time-rightopen": "$1($2)的值不应在$3之前。", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1($2)的值不应在过去。", + "wbqc-violation-message-single-value": "此属性应只包含一个值。", + "wbqc-violation-message-single-value-separators": "此属性只应有一个值,它具有相同的{{PLURAL:$2|1=$4限定符。|用于这些属性的一组修饰符:$3}}", + "wbqc-violation-message-single-best-value-no-preferred": "此属性应包含一个“最佳”的值。在当前多个值中,其中一个应当标记为“首选”级。", + "wbqc-violation-message-single-best-value-no-preferred-separators": "此属性应包含一个“最佳”的值,它具有相同的{{PLURAL:$2|1=$4修饰符。|用于这些属性一组修饰符:$3}}在当前多个值中,其中一个应当标记为“首选”级。", + "wbqc-violation-message-single-best-value-multi-preferred": "此属性应包含一个“最佳”值。这里不应有超过一个“首选”级的值。", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "此属性应包含一个“最佳”的值,它具有相同的{{PLURAL:$2|1=$4修饰符。|用于这些属性的一组修饰符:$3}}这里不应有超过一个“首选”级的值。", + "wbqc-violation-message-symmetric": "$1也应当拥有对称陈述$2 $3。", + "wbqc-violation-message-type-instance": "使用$1属性的实体性质应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-type-subclass": "使用$1属性的实体的子类应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-type-instanceOrSubclass": "使用$1属性的实体的性质或子类应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-valueType-instance": "$1陈述的值性质应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-valueType-subclass": "$1陈述的值的子类应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "$1陈述的值的性质或子类应为{{PLURAL:$3|1=$5|2=$5或$6|以下类之一}}(或为{{PLURAL:$3|其子类之一}}),但$2当前{{PLURAL:$3|1=并非如此。|2=并非如此。|并非如此:$4}}", + "wbqc-violation-message-target-required-claim": "$1应拥有{{PLURAL:$3|0=陈述$2。|1=陈述$2 $5。|陈述$2,并使用以下值之一:$4}}", + "wbqc-violation-message-unique-value": "此属性的值不应出现在其他任何项目中,但却出现在了{{PLURAL:$1|1=$3上。|2=$3和$4上。|以下项中:$2}}", + "wbqc-violation-message-valueOnly": "此属性应仅用于陈述的主值,而不应用于修饰符或参考文献。", + "wbqc-violation-message-reference": "属性只应该被应用于参考文献中,而不是用于陈述或修饰符的主值。", + "wbqc-violation-message-noBounds": "$1的值不应有任何界限。", + "wbqc-violation-message-units-none": "$1的值不应拥有单位。", + "wbqc-violation-message-units": "$1的值应拥有{{PLURAL:$2|1=单位$4。|2=单位$4或$5之一。|以下单位之一:$3}}", + "wbqc-violation-message-units-or-none": "$1的值应拥有{{PLURAL:$2|1=单位$4|2=单位$4或$5之一|以下单位之一}},或者{{PLURAL:$2|1=没有单位。|2=没有单位。|没有单位:$3}}", + "wbqc-violation-message-entityType": "属性$1不应用于此种类型的实体,有效的实体{{PLURAL:$2|1=仅为$4。|2=仅为$4和$5。|只有:$3}}", + "wbqc-violation-message-none-of": "$1的值不应为{{PLURAL:$2|1=$4。|2=$4或$5之一。|以下值之一:$3}}", + "wbqc-violation-message-integer": "用于$1的值应为整数,但$2有小数部分。", + "wbqc-violation-message-integer-bounds": "$1的值应为整数,但$2的界限有小数部分。", + "wbqc-violation-message-citationNeeded": "$1的陈述应有至少一个参考文献。", + "wbqc-violation-message-language": "$1的陈述应该只在语言设置为{{PLURAL:$2|1=$4的词形上。|2=$4或$5的词形上。|以下之一的词形上:$3}}", + "wbqc-violation-message-label-lacking": "$1 的实体声明{{PLURAL:$2|1=还需要$4版的标签。|至少还需要以下任意语言版本的标签:$3}}", + "wbqc-violation-message-property-scope": "属性$1不应在此位置($2)使用。可用于此属性的{{PLURAL:$3|位置}}{{PLURAL:$3|只有$5。|只有:$4}}", + "wbqc-violation-message-exception": "此实体是此约束的已知例外,并已标记为例外。" +} diff --git a/dist/extensions/WikibaseQualityConstraints/i18n/zh-hant.json b/dist/extensions/WikibaseQualityConstraints/i18n/zh-hant.json new file mode 100644 index 000000000..7c0382dfa --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/i18n/zh-hant.json @@ -0,0 +1,152 @@ +{ + "@metadata": { + "authors": [ + "A Chinese Wikipedian", + "Assoc", + "Kly", + "LNDDYL", + "Laundry Machine", + "Liuxinyu970226", + "Cookai1205" + ] + }, + "wbqc-constraintreport": "限制報告", + "wbqc-desc": "檢查項目和屬性的限制,並在特殊頁面上顯示結果", + "wbqc-constraintreport-explanation-part-one": "此特殊頁面可在任何您所想要的實體上執行限制檢查。實體會從運作中系統索取,因此您在此所修正的每一限制違例會立即從清單裡移除。", + "wbqc-constraintreport-explanation-part-two": "每當這些陳述被編輯時,限制從屬性上的陳述做解析時會需要數分鐘。", + "wbqc-constraintreport-form-section": "檢查實體的限制", + "wbqc-constraintreport-form-submit-label": "檢查", + "wbqc-constraintreport-form-entityid-label": "實體ID:", + "wbqc-constraintreport-form-entityid-placeholder": "Qxx 或 Pxx", + "wbqc-constraintreport-result-headline": "結果用於", + "wbqc-constraintreport-invalid-entity-id": "無效實體ID。", + "wbqc-constraintreport-not-existent-entity": "實體不存在。", + "wbqc-constraintreport-empty-result": "此實體上沒有定義限制。", + "wbqc-constraintreport-status-violation": "違例", + "wbqc-constraintreport-status-compliance": "接受", + "wbqc-constraintreport-status-exception": "例外", + "wbqc-constraintreport-status-todo": "待辦事項", + "wbqc-constraintreport-status-bad-parameters": "錯誤參數", + "wbqc-constraintreport-status-deprecated": "已棄用。", + "wbqc-constraintreport-status-warning": "警告", + "wbqc-constraintreport-status-suggestion": "建議", + "wbqc-constraintreport-status-not-in-scope": "不在範圍內", + "wbqc-constraintreport-result-table-header-status": "狀態", + "wbqc-constraintreport-result-table-header-property": "屬性", + "wbqc-constraintreport-result-table-header-message": "訊息", + "wbqc-constraintreport-result-table-header-constraint": "限制", + "wbqc-constraintreport-result-link-to-claim": "前往聲稱", + "wbqc-constraintreport-result-link-to-constraint": "轉到限制", + "wbqc-constraintreport-no-parameter": "無", + "wbqc-issues-short": "問題", + "wbqc-issues-long": "此陳述存在問題。", + "wbqc-potentialissues-short": "潛在問題", + "wbqc-potentialissues-long": "此陳述存在一些潛在問題。", + "wbqc-suggestions-short": "建議", + "wbqc-suggestions-long": "這裡有幾個用來改善此陳述的建議。", + "wbqc-badparameters-short": "錯誤參數", + "wbqc-badparameters-long": "此限制陳述含有一些無效參數。", + "wbqc-parameterissues-short": "進階問題", + "wbqc-parameterissues-long": "這些狀況是在屬性上約束限制問題,與此陳述無關。", + "wbqc-constrainttypehelp-short": "說明", + "wbqc-constrainttypehelp-long": "此限制類型的說明頁面", + "wbqc-constraintdiscuss-short": "討論", + "wbqc-constraintdiscuss-long": "有關此限制的討論頁面", + "wbqc-cached-generic": "此結果已被快取,並且可能過時。", + "wbqc-cached-minutes": "此結果已被快取,並可能在 {{PLURAL:$1|1=1 分鐘|$1 分鐘}}後過時。", + "wbqc-cached-hours": "此結果已被快取,並可能在 {{PLURAL:$1|1=1 小時|$1 小時}}後過時。", + "wbqc-cached-days": "此結果已被快取,並可能在 {{PLURAL:$1|1=1 天|$1 天}}後過時。", + "wbqc-dataValueType-wikibase-entityid": "實體ID", + "wbq-subextension-name-wbqc": "限制", + "wbqc-violation-header-parameters": "參數:", + "wbqc-violations-group": "限制", + "wbqc-violation-message": "限制檢查指出了一次違例,請點選圖標來獲得進一步資訊。", + "wbqc-violation-message-not-yet-implemented": "出於技術問題,對於限制「$1」的檢查無法實行。", + "wbqc-violation-message-security-reason": "出於安全因素,目前無法檢查「$1」限制。我們現在正嘗試弄出解決方案。", + "wbqc-violation-message-value-needed-of-type": "帶有限制「$1」的屬性需要有類型為「$2」的值。", + "wbqc-violation-message-value-needed-of-types-2": "帶有限制「$1」的屬性需要有類型為「$2」或「$3」的值。", + "wbqc-violation-message-parameter-needed": "帶有限制「$1」的屬性需要參數「$2」。", + "wbqc-violation-message-parameters-needed-3": "帶有限制「$1」的屬性需要參數「$2」、「$3」、與「$4」。", + "wbqc-violation-message-target-entity-must-exist": "目標實體必須存在。", + "wbqc-violation-message-value-entity-must-exist": "值項目必須存在。", + "wbqc-violation-message-parameter-value": "參數「$1」的值必須是自定義值,而不是「無值」或「未知值」。", + "wbqc-violation-message-parameter-value-or-novalue": "參數「$1」的值必須是自定義值,而不是「無值」或「未知值」。", + "wbqc-violation-message-parameter-entity": "參數「$1」的值必須是實體,而不是「$2」。", + "wbqc-violation-message-parameter-item": "參數「$1」的值必須是項目,而不是「$2」。", + "wbqc-violation-message-parameter-property": "參數「$1」的值必須是屬性,而不是「$2」。", + "wbqc-violation-message-parameter-string": "參數「$1」的值必須是字串,而不是「$2」。", + "wbqc-violation-message-parameter-monolingualtext": "參數「$1」的值必須是單語言文字,而不是「$2」。", + "wbqc-violation-message-parameter-single": "參數「$1」僅能有一個值。", + "wbqc-violation-message-parameter-single-per-language": "參數「$1」必須在各語言僅有一個值,但$2($3)擁有多個值。", + "wbqc-violation-message-parameter-oneof": "參數「$1」應為{{PLURAL:$2|1=$4。|2=$4 或 $5 之一。|以下之一:$3}}", + "wbqc-violation-message-parameter-regex": "$1 不是有效的正規表達式。", + "wbqc-violation-message-sparql-error": "SPARQL 查詢結果發生了錯誤。", + "wbqc-violation-message-parameters-error-unknown": "此限制的參數不能匯入。", + "wbqc-violation-message-parameters-error-toolong": "因過長緣故,此限制的參數不能匯入。", + "wbqc-violation-message-invalid-scope": "$1不是限制類型$2的有效範圍,適用於此限制類型的有效{{PLURAL:$3|範圍|範圍}}僅為{{PLURAL:$3|$5。|2=$5和$6。|:$4}}", + "wbqc-violation-message-commons-link-no-existent": "共享資源連結應存在。", + "wbqc-violation-message-commons-link-not-well-formed": "共亯資源連結應符合語法規則。", + "wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented": "尚未實行對命名空間「$1」的檢查。", + "wbqc-violation-message-conflicts-with-property": "實體不應擁有用於$1和$2的陳述。", + "wbqc-violation-message-conflicts-with-claim": "如果實體擁有陳述$2帶$3,那麼這個實體不應該擁有用於$1的陳述。", + "wbqc-violation-message-contemporary-subject-earlier": "實體$1與$3應透過$2連結為同時期,但$1最後的結束值是 $4;且$3最早的起始值是 $5。", + "wbqc-violation-message-contemporary-value-earlier": "實體$1與$3應透過$2連結為同時期,但$3最後的結束值是 $4;且$1最早的起始值是 $5。", + "wbqc-violation-message-diff-within-range": "$3($4)與 $1($2)之間的差異應介於 $5 和 $6 之間。", + "wbqc-violation-message-diff-within-range-leftopen": "$3($4)與 $1($2)之間的差異不應大於 $5。", + "wbqc-violation-message-diff-within-range-rightopen": "$3($4)與 $1($2)之間的差異不應小於 $5。", + "wbqc-violation-message-diff-within-range-must-have-equal-types": "定義在參數的屬性必須要有與此屬性相同類型的值。", + "wbqc-violation-message-format": "$1 的值($2)應符合正規表達式 $3。", + "wbqc-violation-message-format-clarification": "$1 的值($2)應符合「$4」(正規表達式:$3)。", + "wbqc-violation-message-inverse": "$1應要有相對陳述$2 $3。", + "wbqc-violation-message-item": "具有$1的實體也應該要有{{PLURAL:$3|0=陳述$2。|1=陳述$2 $5。|陳述$2,且包含下列值之一:$4}}", + "wbqc-violation-message-mandatory-qualifier": "此 $1 陳述缺少限定詞$2。", + "wbqc-violation-message-multi-value": "此屬性應包含多個值。", + "wbqc-violation-message-multi-value-separators": "此屬性應包含帶有相同{{PLURAL:$2|1=$4限定詞|這些屬性限定詞集合:$3}}之多個值", + "wbqc-violation-message-one-of": "$1 的值應為{{PLURAL:$2|1=$4。|2=$4 或 $5 之一。|以下之一:$3}}", + "wbqc-violation-message-qualifier": "屬性應僅用作為限定詞。", + "wbqc-violation-message-no-qualifiers": "$1 陳述不應包含任何限定詞。", + "wbqc-violation-message-qualifiers": "$2不是用於$1的有效限定詞 – 有效限定詞僅為{{PLURAL:$3|1=$5。|2=$5與$6。|:$4}}", + "wbqc-violation-message-range-parameters-needed": "帶有類型是「$1」的值、限制為「$4」的屬性需要參數「$2」和「$3」。", + "wbqc-violation-message-range-parameters-one-year": "時間單位範圍的端點必須皆包含/不包含單位「年」,因為年不能無損地來轉換成秒。", + "wbqc-violation-message-range-parameters-same": "範圍的起始($1)與終點($2)不能相同。", + "wbqc-violation-message-range-quantity-closed": "$1 的值($2)應界於 $3 與 $4 之間。", + "wbqc-violation-message-range-quantity-leftopen": "$1 的值($2)不應大於 $3。", + "wbqc-violation-message-range-quantity-rightopen": "$1 的值($2)不應小於 $3。", + "wbqc-violation-message-range-time-closed": "$1 的值($2)應界於 $3 與 $4 之間。", + "wbqc-violation-message-range-time-closed-leftnow": "$1 的值($2)應在今後,但不應在 $3 之後。", + "wbqc-violation-message-range-time-closed-rightnow": "$1 的值($2)應在先前,但不應在 $3 之前。", + "wbqc-violation-message-range-time-leftopen": "$1 的值($2)不應在 $3 之後。", + "wbqc-violation-message-range-time-leftopen-rightnow": "$1 的值($2)不應在今後。", + "wbqc-violation-message-range-time-rightopen": "$1 的值($2)不應在 $3 之前。", + "wbqc-violation-message-range-time-rightopen-leftnow": "$1 的值($2)不應在先前。", + "wbqc-violation-message-single-value": "此屬性應僅包含一個值。", + "wbqc-violation-message-single-value-separators": "此屬性應只有一個帶有相同的{{PLURAL:$2|1=$4限定詞|這些屬性限定詞集合:$3}}之值", + "wbqc-violation-message-single-best-value-no-preferred": "此屬性應包含一個「最佳」值。在目前多個值裡,應要有一個標記為「首選」級別的值。", + "wbqc-violation-message-single-best-value-no-preferred-separators": "此屬性應包含一個帶有目前多個值裡{{PLURAL:$2|1=$4限定詞|這些屬性的限定詞集合:$3}}的「最佳」值,其中要有一個標記為「首選」級別的值。", + "wbqc-violation-message-single-best-value-multi-preferred": "此屬性應包含一個「最佳」值。在此不應有一個以上「首選」級別的值。", + "wbqc-violation-message-single-best-value-multi-preferred-separators": "此屬性應包含一個帶有與{{PLURAL:$2|1=$4限定詞|這些屬性的限定詞集合:$3}}相同的「最佳」值。在此不應有一個以上「首選」級別的值。", + "wbqc-violation-message-symmetric": "$1應要有一致陳述$2 $3。", + "wbqc-violation-message-type-instance": "使用$1屬性的實體應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之實例,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-type-subclass": "使用$1屬性的實體應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之子類別,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-type-instanceOrSubclass": "使用$1屬性的實體應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之實例或子類別,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-valueType-instance": "$1陳述的值應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之實例,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-valueType-subclass": "$1陳述的值應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之子類別,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-valueType-instanceOrSubclass": "$1陳述的值應是{{PLURAL:$3|1=$5|2=$5或$6|以下類別其一}}(或是{{PLURAL:$3|1=此的子類別|2=它們的子類別|它們其一的子類別}})之實例或子類別,但$2目前{{PLURAL:$3|1=並非如此。|2=並非如此。|並非如此:$4}}", + "wbqc-violation-message-target-required-claim": "$1應該要有{{PLURAL:$3|0=陳述$2。|1=陳述$2 $5。|陳述$2,且包含下列值之一:$4}}", + "wbqc-violation-message-unique-value": "此屬性的值不應出現在任何其它項目,但有出現在{{PLURAL:$1|1=$3。|2=$3和$4。|以下項目:$2}}", + "wbqc-violation-message-valueOnly": "屬性應僅用於陳述的主要值,而非限定詞或參考文獻。", + "wbqc-violation-message-reference": "屬性應僅用於參考文獻,而非陳述或限定詞的主要值。", + "wbqc-violation-message-noBounds": "$1 的值不應有界限。", + "wbqc-violation-message-units-none": "$1 的值不應有單位。", + "wbqc-violation-message-units": "$1的值應要有{{PLURAL:$2|1=單位$4。|2=單位$4或$5之一。|以下單位之一:$3}}", + "wbqc-violation-message-units-or-none": "$1的值應要有{{PLURAL:$2|1=單位$4。|2=單位$4或$5之一。|以下單位之一}},或著是{{PLURAL:$2|1=沒有單位。|2=沒有單位。|沒有單位:$3}}", + "wbqc-violation-message-entityType": "屬性$1不應在此實體類型上使用,有效的實體類型僅為{{PLURAL:$2|1=$4。|2=$4和$5。|:$3}}", + "wbqc-violation-message-none-of": "$1 的值不該為{{PLURAL:$2|1=$4。|2=$4 或 $5 之一。|以下之一:$3}}", + "wbqc-violation-message-integer": "用於 $1 的值應為整數,但 $2 含有小數部份。", + "wbqc-violation-message-integer-bounds": "用於 $1 的值應為整數,但 $2 的範圍含有小數部份。", + "wbqc-violation-message-citationNeeded": "$1的陳述至少需要有一個參考來源。", + "wbqc-violation-message-language": "$1的陳述只能出現在詞彙的語言設定為{{PLURAL:$2|1=$4。|2=$4或$5。|以下之一:$3}}", + "wbqc-violation-message-label-lacking": "陳述 $1 的實體{{PLURAL:$2|1=還需要$4標籤。 |還需要以下任意語言的標籤:$3}}", + "wbqc-violation-message-property-scope": "屬性$1不應在此位置($2)上使用,有效的位置僅為{{PLURAL:$3|$5。|:$4}}", + "wbqc-violation-message-exception": "此實體是該限制的已知例外,並已被如此標記。" +} diff --git a/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintEntities.php b/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintEntities.php new file mode 100644 index 000000000..8ee6320fb --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintEntities.php @@ -0,0 +1,258 @@ +addDescription( + 'Import entities needed for constraint checks ' . + 'from Wikidata into the local repository.' + ); + $this->addOption( + 'config-format', + 'The format in which the resulting configuration will be omitted: ' . + '"globals" for directly settings global variables, suitable for inclusion in LocalSettings.php (default), ' . + 'or "wgConf" for printing parts of arrays suitable for inclusion in $wgConf->settings.' + ); + $this->addOption( + 'dry-run', + 'Don’t actually import entities, just print which ones would be imported.' + ); + $this->requireExtension( 'WikibaseQualityConstraints' ); + } + + /** + * (This cannot happen in the constructor because the autoloader is not yet initialized there.) + */ + private function setupServices() { + $services = MediaWikiServices::getInstance(); + $this->entitySerializer = WikibaseRepo::getAllTypesEntitySerializer( $services ); + $this->entityDeserializer = WikibaseRepo::getInternalFormatEntityDeserializer( $services ); + $this->entityStore = WikibaseRepo::getEntityStore( $services ); + $this->httpRequestFactory = $services->getHttpRequestFactory(); + if ( !$this->getOption( 'dry-run', false ) ) { + $this->user = User::newSystemUser( 'WikibaseQualityConstraints importer' ); + } + } + + public function execute() { + $this->setupServices(); + + $configUpdates = []; + + $extensionJsonFile = __DIR__ . '/../extension.json'; + $extensionJsonText = file_get_contents( $extensionJsonFile ); + $extensionJson = json_decode( $extensionJsonText, /* assoc = */ true ); + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable + $wikidataEntityIds = $this->getEntitiesToImport( $extensionJson['config'], $this->getConfig() ); + + foreach ( $wikidataEntityIds as $key => $wikidataEntityId ) { + $localEntityId = $this->importEntityFromWikidata( $wikidataEntityId ); + $configUpdates[$key] = [ + 'wikidata' => $wikidataEntityId, + 'local' => $localEntityId, + ]; + } + + $this->outputConfigUpdates( $configUpdates ); + } + + /** + * @param array[] $extensionJsonConfig + * @param Config $wikiConfig + * @return string[] + */ + private function getEntitiesToImport( array $extensionJsonConfig, Config $wikiConfig ) { + $wikidataEntityIds = []; + + foreach ( $extensionJsonConfig as $key => $value ) { + if ( !preg_match( '/Id$/', $key ) ) { + continue; + } + + $wikidataEntityId = $value['value']; + $localEntityId = $wikiConfig->get( $key ); + + if ( $localEntityId === $wikidataEntityId ) { + $wikidataEntityIds[$key] = $wikidataEntityId; + } + } + + return $wikidataEntityIds; + } + + /** + * @param string $wikidataEntityId + * @return string local entity ID + */ + private function importEntityFromWikidata( $wikidataEntityId ) { + $wikidataEntityUrl = "https://www.wikidata.org/wiki/Special:EntityData/$wikidataEntityId.json"; + $wikidataEntitiesJson = $this->httpRequestFactory->get( $wikidataEntityUrl, [], __METHOD__ ); + return $this->importEntityFromJson( $wikidataEntityId, $wikidataEntitiesJson ); + } + + /** + * @param string $wikidataEntityId + * @param string $wikidataEntitiesJson + * @return string local entity ID + */ + private function importEntityFromJson( $wikidataEntityId, $wikidataEntitiesJson ) { + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable + $wikidataEntityArray = json_decode( $wikidataEntitiesJson, true )['entities'][$wikidataEntityId]; + $wikidataEntity = $this->entityDeserializer->deserialize( $wikidataEntityArray ); + + $wikidataEntity->setId( null ); + + if ( $wikidataEntity instanceof StatementListProvider ) { + $wikidataEntity->getStatements()->clear(); + } + + if ( $wikidataEntity instanceof Item ) { + $wikidataEntity->setSiteLinkList( new SiteLinkList() ); + } + + if ( $this->getOption( 'dry-run', false ) ) { + $wikidataEntityJson = json_encode( $this->entitySerializer->serialize( $wikidataEntity ) ); + $this->output( $wikidataEntityJson . "\n" ); + return "-$wikidataEntityId"; + } + + try { + $localEntity = $this->entityStore->saveEntity( + $wikidataEntity, + "imported from [[wikidata:$wikidataEntityId]]", + $this->user, + EDIT_NEW | EDIT_FORCE_BOT + )->getEntity(); + + return $localEntity->getId()->getSerialization(); + } catch ( StorageException $storageException ) { + return $this->storageExceptionToEntityId( $storageException ); + } + } + + private function storageExceptionToEntityId( StorageException $storageException ) { + $message = $storageException->getMessage(); + // example messages: + // * Item [[Item:Q475|Q475]] already has label "as references" + // associated with language code en, using the same description text. + // * Item [[Q475]] already has label "as references" + // associated with language code en, using the same description text. + // * Property [[Property:P694|P694]] already has label "instance of" + // associated with language code en. + $pattern = '/[[|]([^][|]*)]] already has label .* associated with language code/'; + if ( preg_match( $pattern, $message, $matches ) ) { + return $matches[1]; + } else { + throw $storageException; + } + } + + private function outputConfigUpdates( array $configUpdates ) { + $configFormat = $this->getOption( 'config-format', 'globals' ); + switch ( $configFormat ) { + case 'globals': + $this->outputConfigUpdatesGlobals( $configUpdates ); + break; + case 'wgConf': + $this->outputConfigUpdatesWgConf( $configUpdates ); + break; + default: + $this->error( "Invalid config format \"$configFormat\", using \"globals\"" ); + $this->outputConfigUpdatesGlobals( $configUpdates ); + break; + } + } + + /** + * @param array[] $configUpdates + */ + private function outputConfigUpdatesGlobals( array $configUpdates ) { + foreach ( $configUpdates as $key => $value ) { + $localValueCode = var_export( $value['local'], true ); + $this->output( "\$wg$key = $localValueCode;\n" ); + } + } + + /** + * @param array[] $configUpdates + */ + private function outputConfigUpdatesWgConf( array $configUpdates ) { + $wikiIdCode = var_export( WikiMap::getCurrentWikiId(), true ); + foreach ( $configUpdates as $key => $value ) { + $keyCode = var_export( "wg$key", true ); + $wikidataValueCode = var_export( $value['wikidata'], true ); + $localValueCode = var_export( $value['local'], true ); + $block = <<< EOF +$keyCode => [ + 'default' => $wikidataValueCode, + $wikiIdCode => $localValueCode, +], + + +EOF; + $this->output( $block ); + } + } + +} + +// @codeCoverageIgnoreStart +$maintClass = ImportConstraintEntities::class; +require_once RUN_MAINTENANCE_IF_MAIN; +// @codeCoverageIgnoreEnd diff --git a/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintStatements.php b/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintStatements.php new file mode 100644 index 000000000..9e98df918 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/maintenance/ImportConstraintStatements.php @@ -0,0 +1,108 @@ +newUpdateConstraintsTableJob = static function ( $propertyIdSerialization ) { + return UpdateConstraintsTableJob::newFromGlobalState( + Title::newMainPage(), + [ 'propertyId' => $propertyIdSerialization ] + ); + }; + + $this->addDescription( 'Imports property constraints from statements on properties' ); + $this->requireExtension( 'WikibaseQualityConstraints' ); + $this->setBatchSize( 10 ); + + // Wikibase classes are not yet loaded, so setup services in a callback run in execute + // that can be overridden in tests. + $this->setupServices = function () { + $services = MediaWikiServices::getInstance(); + $this->propertyInfoLookup = WikibaseRepo::getStore( $services )->getPropertyInfoLookup(); + $this->lbFactory = $services->getDBLoadBalancerFactory(); + }; + } + + public function execute() { + ( $this->setupServices )(); + if ( !$this->getConfig()->get( 'WBQualityConstraintsEnableConstraintsImportFromStatements' ) ) { + $this->error( 'Constraint statements are not enabled. Aborting.' ); + return; + } + + $propertyInfos = $this->propertyInfoLookup->getAllPropertyInfo(); + $propertyIds = array_keys( $propertyInfos ); + + foreach ( array_chunk( $propertyIds, $this->getBatchSize() ) as $propertyIdsChunk ) { + foreach ( $propertyIdsChunk as $propertyIdSerialization ) { + $this->output( sprintf( + 'Importing constraint statements for % 6s... ', + $propertyIdSerialization ), + $propertyIdSerialization + ); + $startTime = microtime( true ); + $job = call_user_func( $this->newUpdateConstraintsTableJob, $propertyIdSerialization ); + $job->run(); + $endTime = microtime( true ); + $millis = ( $endTime - $startTime ) * 1000; + $this->output( sprintf( 'done in % 6.2f ms.', $millis ), $propertyIdSerialization ); + } + + $this->output( 'Waiting for replication... ', 'waitForReplication' ); + $startTime = microtime( true ); + $this->lbFactory->waitForReplication(); + $endTime = microtime( true ); + $millis = ( $endTime - $startTime ) * 1000; + $this->output( sprintf( 'done in % 6.2f ms.', $millis ), 'waitForReplication' ); + } + } + +} + +// @codeCoverageIgnoreStart +$maintClass = ImportConstraintStatements::class; +require_once RUN_MAINTENANCE_IF_MAIN; +// @codeCoverageIgnoreEnd diff --git a/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.js b/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.js new file mode 100644 index 000000000..c3c057fac --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.js @@ -0,0 +1,9 @@ +( function ( $ ) { + 'use strict'; + + $( function () { + $( '.wbqc-expandable-content-indicator' ).on( 'click', function () { + $( this ).closest( 'td' ).find( '.wbqc-expandable-content' ).slideToggle( 'fast' ); + } ); + } ); +}( jQuery ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.less b/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.less new file mode 100644 index 000000000..10cd36fa3 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/SpecialConstraintReportPage.less @@ -0,0 +1,95 @@ +@import 'mediawiki.ui/variables'; +@import '../../lib/ooui/wikimedia-ui-base'; + +/* Entity id form */ +form { + margin-bottom: 20px; +} + +/* Notices */ +.wbqc-constraintreport-notice { + font-style: italic; + + &-error { + font-weight: bold; + color: @colorError; + } +} + +/* Statuses */ +.wbqc-status { + font-weight: bold; + white-space: nowrap; + + &-compliance { + color: @wmui-color-green50; + } + + &-exception { + color: @wmui-color-green30; + } + + &-violation { + color: @colorError; + } + + &-todo { + color: @colorTextLight; + } + + &-bad-parameters { + color: @colorDestructiveActive; + } + + &-deprecated, + &-not-in-scope { + color: @colorNeutral; + } + + &-warning { + color: @wmui-color-yellow30; + } + + &-suggestion { + color: @wmui-color-accent50; + } +} + +/* Tooltip */ +.wbqc-indicator { + color: @colorNeutral; + font-weight: 600; +} + +.wbqc-tooltip { + margin-top: -40px; + margin-left: -5px; + background-color: @background-color-framed; + border: @border-base; + border-radius: 5px; + box-shadow: 2px 2px 1px rgba( 0, 0, 0, 0.2 ); + padding: 2px 5px 2px 5px; + position: absolute; + float: left; + + display: none; /* stylelint-disable-line declaration-empty-line-before */ +} + +.wbqc-indicator .wbqc-tooltip { + /* unset .wbqc-indicator styles */ + color: initial; + font-weight: initial; +} + +.wbqc-indicator:hover .wbqc-tooltip { + display: block; +} + +.wbqc-expandable-content-indicator { + cursor: pointer; +} + +.wbqc-expandable-content { + color: @colorText; + display: none; +} diff --git a/dist/extensions/WikibaseQualityConstraints/modules/gadget-skip.js b/dist/extensions/WikibaseQualityConstraints/modules/gadget-skip.js new file mode 100644 index 000000000..cdc2b58c5 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/gadget-skip.js @@ -0,0 +1 @@ +return !mw.config.exists( 'wbEntityId' ) || mw.config.get( 'wgMFMode' ) || !mw.config.get( 'wbIsEditView' ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/gadget.js b/dist/extensions/WikibaseQualityConstraints/modules/gadget.js new file mode 100644 index 000000000..8787cc6c0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/gadget.js @@ -0,0 +1,591 @@ +module.exports = ( function ( mw, wb, $, OO ) { + 'use strict'; + + var defaultConfig = { + CACHED_STATUSES: 'violation|warning|suggestion|bad-parameters', + WBCHECKCONSTRAINTS_MAX_ID_COUNT: 50 + }; + + function SELF( config ) { + this.config = $.extend( {}, defaultConfig, config ); + } + + SELF.prototype.setEntity = function ( entity ) { + this._entity = entity; + }; + + SELF.prototype.getEntity = function () { + return this._entity; + }; + + SELF.prototype.defaultBehavior = function () { + var entityId = mw.config.get( 'wbEntityId' ); + + if ( entityId === null || mw.config.get( 'wgMFMode' ) || !mw.config.get( 'wbIsEditView' ) ) { + // no entity, mobile frontend, or not editing (diff, oldid, …) – skip + return; + } + + mw.loader.using( [ + 'mediawiki.api', + 'oojs-ui-core', + 'oojs-ui-widgets', + 'oojs-ui.styles.icons-alerts', + 'wikibase.quality.constraints.icon', + 'wikibase.quality.constraints.ui', + 'wikibase.EntityInitializer' + ] ).done( function () { + var api = new mw.Api(), + lang = mw.config.get( 'wgUserLanguage' ); + + wb.EntityInitializer.newFromEntityLoadedHook().getEntity().done( function ( entity ) { + this.setEntity( entity ); + mw.hook( 'wikibase.entityPage.entityView.rendered' ).add( function () { + this.fullCheck( api, lang ); + if ( mw.config.get( 'wgPageContentModel' ) === 'wikibase-property' ) { + this.propertyParameterCheck( api, lang, entityId ); + } + }.bind( this ) ); + }.bind( this ) ); + + mw.hook( 'wikibase.statement.saved' ).add( function ( savedEntityId, statementId ) { + mw.track( 'counter.MediaWiki.wikibase.quality.constraints.gadget.saveStatement' ); + this.snakCheck( api, lang, statementId ); + }.bind( this ) ); + }.bind( this ) ); + }; + + SELF.prototype.fullCheck = function ( api, lang ) { + var entity = this.getEntity(), + entityIds = [ entity.getId() ]; + + if ( typeof entity.getSubEntityIds === 'function' ) { + entityIds = entityIds.concat( entity.getSubEntityIds() ); + } + + mw.track( 'counter.MediaWiki.wikibase.quality.constraints.gadget.loadEntity' ); + return this._fullCheckAllIds( api, lang, entityIds ); + }; + + SELF.prototype._wbcheckconstraints = function ( api, lang, ids ) { + return api.get( { + action: 'wbcheckconstraints', + format: 'json', + formatversion: 2, + uselang: lang, + id: ids, + status: this.config.CACHED_STATUSES + } ); + }; + + SELF.prototype._fullCheckAllIds = function ( api, lang, ids ) { + var i, + j = ids.length, + chunk = this.config.WBCHECKCONSTRAINTS_MAX_ID_COUNT, + promises = []; + + for ( i = 0; i < j; i += chunk ) { + promises.push( + this._wbcheckconstraints( api, lang, ids.slice( i, i + chunk ) ) + ); + } + + return $.when.apply( $, promises ) + .then( this._aggregateMultipleWbcheckconstraintsResponses.bind( this ) ) + .then( this._renderWbcheckconstraintsResult.bind( this ) ) + .promise(); + }; + + /** + * Because of the way this is implemented it can not be done repeatedly for partial results + * (e.g. a wbcheckconstraints result for only some of the entities on a page) + * + * @param {Object} data Map of entity ids and constraint check information + */ + SELF.prototype._renderWbcheckconstraintsResult = function ( data ) { + var self = this; + + $( '.wbqc-constraint-warning' ).remove(); + $( '.wikibase-statementgroupview .wikibase-statementview' ) + .each( function () { + var entityId; + for ( entityId in data ) { + if ( !Object.prototype.hasOwnProperty.call( data, entityId ) ) { + continue; + } + self._addReportsToStatement( data[ entityId ], $( this ) ); + } + } ); + }; + + SELF.prototype._aggregateMultipleWbcheckconstraintsResponses = function ( /* multiple responses */ ) { + var responses = [].slice.call( arguments ), + i = 0, + responseCount = responses.length, + entityConstraints = {}; + + for ( i; i < responseCount; i++ ) { + $.extend( entityConstraints, responses[ i ].wbcheckconstraints ); + } + + return entityConstraints; + }; + + SELF.prototype._getEntityDataByStatementId = function ( response, statementId ) { + var entities = response.wbcheckconstraints, + entity, + property, + properties, + index; + + for ( entity in entities ) { + + if ( Object.prototype.hasOwnProperty.call( entities, entity ) ) { + properties = entities[ entity ].claims; + for ( property in properties ) { + + if ( Object.prototype.hasOwnProperty.call( properties, property ) ) { + for ( index = 0; index < entities[ entity ].claims[ property ].length; index++ ) { + + if ( entities[ entity ].claims[ property ][ index ].id === statementId ) { + return entities[ entity ]; + } + + } + } + + } + } + + } + + return null; + }; + + SELF.prototype.snakCheck = function ( api, lang, statementId ) { + var isUpdated = false, + statementClass = 'wikibase-statement-' + statementId.replace( /\$/, '\\$$' ), + self = this; + + api.get( { + action: 'wbcheckconstraints', + format: 'json', + formatversion: 2, + uselang: lang, + claimid: statementId, + status: this.config.CACHED_STATUSES + } ).then( function ( data ) { + var entityData; + if ( isUpdated ) { + return; + } + entityData = self._getEntityDataByStatementId( data, statementId ); + if ( entityData !== null ) { + self._addReportsToStatement( entityData, + $( '.wikibase-statementgroupview .wikibase-statementview.' + statementClass ) + ); + } + } ); + this.fullCheck( api, lang ).then( function () { + isUpdated = true; + } ); + }; + + SELF.prototype.propertyParameterCheck = function ( api, lang, entityId ) { + mw.track( 'counter.MediaWiki.wikibase.quality.constraints.gadget.loadProperty' ); + return api.get( { + action: 'wbcheckconstraintparameters', + format: 'json', + formatversion: 2, + uselang: lang, + propertyid: entityId + } ).then( function ( data ) { + this._addParameterReports( data.wbcheckconstraintparameters[ entityId ] ); + }.bind( this ) ); + }; + + /** + * Create a popup button according to the parameters and append it to the container. + * + * @param {jQuery} $content Content to be shown in the popup. + * @param {jQuery} $container The container to which the button is appended. + * @param {string} icon Identifier for an icon as provided by OOUI. + * @param {string} titleMessageKey The message key of the title attribute of the button. + * @param {string[]} [classes] Optional list of classes added to the button element + * @param {string} [flags] Optional custom flags the {@link OO.ui.PopupButtonWidget} can understand. + */ + SELF.prototype._buildPopup = function ( $content, $container, icon, titleMessageKey, classes, flags /* = '' */ ) { + // eslint-disable-next-line mediawiki/class-doc + var widget = new OO.ui.PopupButtonWidget( { + icon: icon, + // eslint-disable-next-line mediawiki/msg-doc + title: mw.message( titleMessageKey ).text(), + flags: flags || '', + framed: false, + classes: [ 'wbqc-reports-button', 'wikibase-snakview-indicator' ].concat( classes || [] ), + $overlay: $container.parents( '.wikibase-statementview' ).first(), + popup: { + $content: $content, + width: 400, + padded: true, + head: true, + label: $content.find( '.wbqc-reports:first-child > .oo-ui-labelElement-label *' ).detach() + } + } ); + widget.popup.$element.css( 'z-index', 2 ); // prevent collision with rank selector and property grey field + + $container.append( widget.$element ); + }; + + /** + * Get a message indicating the given cached status. + * + * @param {*} cached A value indicating the cached status. + * Typically an object with a `maximumAgeInSeconds` member. + * @return {string} HTML + */ + SELF.prototype._getCachedMessage = function ( cached ) { + var maximumAgeInMinutes, + maximumAgeInHours, + maximumAgeInDays; + if ( typeof cached === 'object' && cached.maximumAgeInSeconds ) { + if ( cached.maximumAgeInSeconds < 60 * 90 ) { + maximumAgeInMinutes = Math.ceil( cached.maximumAgeInSeconds / 60 ); + return mw.message( 'wbqc-cached-minutes' ) + .params( [ maximumAgeInMinutes ] ) + .escaped(); + } + if ( cached.maximumAgeInSeconds < 60 * 60 * 36 ) { + maximumAgeInHours = Math.ceil( cached.maximumAgeInSeconds / ( 60 * 60 ) ); + return mw.message( 'wbqc-cached-hours' ) + .params( [ maximumAgeInHours ] ) + .escaped(); + } + maximumAgeInDays = Math.ceil( cached.maximumAgeInSeconds / ( 60 * 60 * 24 ) ); + return mw.message( 'wbqc-cached-days' ) + .params( [ maximumAgeInDays ] ) + .escaped(); + } else { + return mw.message( 'wbqc-cached-generic' ) + .escaped(); + } + }; + + /** + * Build a panel for a single constraint check result. + * + * @param {Object} result The constraint check result. + * @return {wikibase.quality.constraints.ui.ConstraintReportPanel} + */ + SELF.prototype._buildReport = function ( result ) { + var config = { + status: result.status, + constraint: result.constraint, + message: result[ 'message-html' ] + }; + if ( result.cached ) { + config.ancillaryMessages = [ this._getCachedMessage( result.cached ) ]; + } + return new wb.quality.constraints.ui.ConstraintReportPanel( config ); + }; + + /** + * Build a panel for a single constraint parameter check result. + * This is to `wbcheckconstraintparameters` what {@link this._buildReport} is to `wbcheckconstraints`. + * + * @param {Object} problem The constraint parameter check result. + * @return {OO.ui.PanelLayout} + */ + SELF.prototype._buildParameterReport = function ( problem ) { + var $report, $heading, $body; + + $report = $( '
' ) + .addClass( 'wbqc-parameter-report' ); + $heading = $( '

' ); // empty for now + $report.append( $heading ); + $body = $( '

' ) + .html( problem[ 'message-html' ] ); + $report.append( $body ); + + return new OO.ui.PanelLayout( { + expanded: false, + $content: $report + } ); + }; + + /** + * Build a list of constraint reports from a list of panels, + * but return it only if the list is nonempty and contains uncollapsed items. + * + * @param {wikibase.quality.constraints.ui.ConstraintReportPanel[]} reports + * A list of individual report panels as returned by {@link this._buildReport}. + * @return {wikibase.quality.constraints.ui.ConstraintReportList|null} + * The list if it contains at least one uncollapsed panel, + * otherwise null. + */ + SELF.prototype._buildReportList = function ( reports ) { + var list = wikibase.quality.constraints.ui.ConstraintReportList.static.fromPanels( + reports, + { + statuses: [ + { + status: 'violation', + label: mw.message( 'wbqc-issues-short' ).text() + }, + { + status: 'warning', + label: mw.message( 'wbqc-potentialissues-short' ).text() + }, + { + status: 'suggestion', + label: mw.message( 'wbqc-suggestions-short' ).text() + }, + { + status: 'bad-parameters', + label: mw.message( 'wbqc-parameterissues-short' ).text(), + subheading: mw.message( 'wbqc-parameterissues-long' ).text(), + collapsed: true + } + ], + expanded: false // expanded: true does not work within a popup + } + ); + if ( + // list isn't empty... + list.items.length > 0 && + // ...and doesn't only contain collapsed items either + list.items[ 0 ].status !== 'bad-parameters' + ) { + return list; + } else { + return null; + } + }; + + /** + * Extract the constraint check results for a certain statement from the full API response. + * + * @param {Object} entityData The constraint check results for a single entity. + * @param {string} propertyId The serialization of the property ID of the statement. + * @param {string} statementId The ID of the statement. + * @return {Object|null} An object containing lists of constraint check results, + * or null if the results could not be extracted. + */ + SELF.prototype._extractResultsForStatement = function ( entityData, propertyId, statementId ) { + var statements, index, statement, results = {}, qualifierPID, referenceIndex, referenceHash, referencePID; + if ( 'claims' in entityData ) { + // API v2 format + statements = entityData.claims[ propertyId ]; + if ( statements === undefined ) { + return null; + } + for ( index in statements ) { + if ( statements[ index ].id === statementId ) { + statement = statements[ index ]; + break; + } + } + if ( statement === undefined ) { + return null; + } + + results.mainsnak = statement.mainsnak.results; + + results.qualifiers = []; + for ( qualifierPID in statement.qualifiers ) { + for ( index in statement.qualifiers[ qualifierPID ] ) { + results.qualifiers.push( + statement.qualifiers[ qualifierPID ][ index ] + ); + } + } + + results.references = []; + for ( referenceIndex in statement.references ) { + referenceHash = statement.references[ referenceIndex ].hash; + if ( !( referenceHash in results.references ) ) { + results.references[ referenceHash ] = []; + } + for ( referencePID in statement.references[ referenceIndex ].snaks ) { + for ( index in statement.references[ referenceIndex ].snaks[ referencePID ] ) { + results.references[ referenceHash ].push( + statement.references[ referenceIndex ].snaks[ referencePID ][ index ] + ); + } + } + } + + return results; + } else { + // API v1 format + if ( propertyId in entityData && statementId in entityData[ propertyId ] ) { + return { + mainsnak: entityData[ propertyId ][ statementId ] + }; + } else { + return null; + } + } + }; + + /** + * Add a popup for the given results to the given snak, + * if there are any results to display. + * + * @param {Array} results A list of constraint check results. + * @param {jQuery} $snak The snak to which the results apply. + * @return {boolean} Whether any results were added to the snak or not. + */ + SELF.prototype._addResultsToSnak = function ( results, $snak ) { + var reports = results.map( this._buildReport.bind( this ) ), + list = this._buildReportList( reports ), + icon, + titleMessageKey; + + if ( list !== null ) { + switch ( list.items[ 0 ].status ) { + case 'violation': + icon = 'mandatory-constraint-violation'; + titleMessageKey = 'wbqc-issues-long'; + break; + case 'warning': + icon = 'non-mandatory-constraint-violation'; + titleMessageKey = 'wbqc-potentialissues-long'; + break; + case 'suggestion': + icon = 'suggestion-constraint-violation'; + titleMessageKey = 'wbqc-suggestions-long'; + break; + default: + throw new Error( 'unexpected status ' + list.items[ 0 ].status ); + } + + this._buildPopup( + list.$element, + $snak.find( '.wikibase-snakview-indicators' ), + icon, + titleMessageKey, + [ 'wbqc-constraint-warning' ] + ); + return true; + } else { + return false; + } + }; + + /** + * Add constraint check results to a certain statement. + * + * @param {Object} entityData The constraint check results for a single entity. + * @param {jQuery} $statement The statement. + */ + SELF.prototype._addReportsToStatement = function ( entityData, $statement ) { + var match = $statement[ 0 ].className.match( + /\bwikibase-statement-([^\s$]+\$[\dA-F-]+)\b/i + ), + statementId = match && match[ 1 ], + propertyId = $statement.parents( '.wikibase-statementgroupview' ).data( 'property-id' ), + results = this._extractResultsForStatement( entityData, propertyId, statementId ), + index, + qualifier, + hash, + reference, + hasResults; + + if ( results === null ) { + return; + } + + this._addResultsToSnak( + results.mainsnak, + $statement.find( '.wikibase-statementview-mainsnak' ) + ); + + for ( index in results.qualifiers ) { + qualifier = results.qualifiers[ index ]; + this._addResultsToSnak( + qualifier.results, + $statement.find( + '.wikibase-statementview-qualifiers ' + + '.wikibase-snakview-' + qualifier.hash + ) + ); + } + + for ( hash in results.references ) { + for ( index in results.references[ hash ] ) { + reference = results.references[ hash ][ index ]; + hasResults = this._addResultsToSnak( + reference.results, + $statement.find( + '.wikibase-statementview-references ' + + '.wikibase-referenceview-' + hash + ' ' + + '.wikibase-snakview-' + reference.hash + ) + ); + if ( hasResults ) { + mw.hook( 'wikibase.entityPage.entityView.rendered' ).add( function () { + var $referenceToggler = $statement + .find( '.wikibase-statementview-references-heading .ui-toggler-toggle-collapsed' ); + if ( $referenceToggler.length > 0 ) { + $referenceToggler.data( 'toggler' ).toggle(); + } + } ); + } + } + } + }; + + /** + * Add constraint parameter check results for all constraint statements listed in the reports. + * + * @param {Object} parameterReports A map from constraint ID (i.e., constraint statement ID) + * to results for that parameter (overall status and list of problems). + */ + SELF.prototype._addParameterReports = function ( parameterReports ) { + var constraintId, + status, + problems, + reports, + list, + $snak; + + for ( constraintId in parameterReports ) { + status = parameterReports[ constraintId ].status; + if ( status === 'okay' ) { + continue; + } + + problems = parameterReports[ constraintId ].problems; + reports = problems.map( this._buildParameterReport.bind( this ) ); + + list = new wikibase.quality.constraints.ui.ConstraintReportList( { + items: [ + new wikibase.quality.constraints.ui.ConstraintReportGroup( { + items: reports, + label: mw.message( 'wbqc-badparameters-short' ).text() + } ) + ], + expanded: false // expanded: true does not work within a popup + } ); + + $snak = $( '.wikibase-statement-' + constraintId.replace( /\$/g, '\\$' ) + + ' .wikibase-statementview-mainsnak .wikibase-snakview' ); + this._buildPopup( + list.$element, + $snak.find( '.wikibase-snakview-indicators' ), + 'alert', + 'wbqc-badparameters-long', + [ 'wbqc-parameter-warning' ], + 'warning' + ); + } + }; + + if ( typeof exports === 'undefined' ) { + ( new SELF() ).defaultBehavior(); + } + + return SELF; + +}( mediaWiki, wikibase, jQuery, OO ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/gadget.less b/dist/extensions/WikibaseQualityConstraints/modules/gadget.less new file mode 100644 index 000000000..e3e3feb30 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/gadget.less @@ -0,0 +1,9 @@ +.wbqc-reports-button, +.oo-ui-buttonElement.oo-ui-iconElement.wbqc-reports-button { + margin-left: 0.5em; +} + +.wbqc-report, +.wbqc-parameter-report { + border-top: 1px solid #eaecf0; +} diff --git a/dist/extensions/WikibaseQualityConstraints/modules/icon/mandatory-constraint-violation.svg b/dist/extensions/WikibaseQualityConstraints/modules/icon/mandatory-constraint-violation.svg new file mode 100644 index 000000000..138162ca9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/icon/mandatory-constraint-violation.svg @@ -0,0 +1,4 @@ + + + + diff --git a/dist/extensions/WikibaseQualityConstraints/modules/icon/non-mandatory-constraint-violation.svg b/dist/extensions/WikibaseQualityConstraints/modules/icon/non-mandatory-constraint-violation.svg new file mode 100644 index 000000000..6c7fe507e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/icon/non-mandatory-constraint-violation.svg @@ -0,0 +1,4 @@ + + + + diff --git a/dist/extensions/WikibaseQualityConstraints/modules/icon/suggestion-constraint-violation.svg b/dist/extensions/WikibaseQualityConstraints/modules/icon/suggestion-constraint-violation.svg new file mode 100644 index 000000000..456419c9d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/icon/suggestion-constraint-violation.svg @@ -0,0 +1,3 @@ + + + diff --git a/dist/extensions/WikibaseQualityConstraints/modules/suggestions.js b/dist/extensions/WikibaseQualityConstraints/modules/suggestions.js new file mode 100644 index 000000000..d80d69d9a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/suggestions.js @@ -0,0 +1,40 @@ +( function ( mw, wb, $ ) { + 'use strict'; + var config = require( './config.json' ), + makeHandler = require( './suggestions/EntitySelectorHookHandlerFactory.js' ); + + function isQualifierContext( element ) { + var $statementview, statementview; + + try { + $statementview = element.closest( ':wikibase-statementview' ); + statementview = $statementview.data( 'statementview' ); + + if ( !statementview ) { + return false; + } + + return element.closest( statementview.$qualifiers ).length > 0; + + } catch ( e ) { + return false; + } + } + + function getMainSnakPropertyId( element ) { + var snakview, snakPropertyId; + + try { + snakview = element.closest( '.wikibase-statementlistview' ) + .find( '.wikibase-snakview.wb-edit' ).data( 'snakview' ); + snakPropertyId = snakview ? snakview.propertyId() : null; + } catch ( e ) { + return null; + } + + return snakPropertyId; + } + + mw.hook( 'wikibase.entityselector.search' ).add( makeHandler( $, mw, config, isQualifierContext, getMainSnakPropertyId ) ); + +}( mediaWiki, wikibase, jQuery ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/suggestions/EntitySelectorHookHandlerFactory.js b/dist/extensions/WikibaseQualityConstraints/modules/suggestions/EntitySelectorHookHandlerFactory.js new file mode 100644 index 000000000..10d798ff4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/suggestions/EntitySelectorHookHandlerFactory.js @@ -0,0 +1,146 @@ +module.exports = function ( $, mw, config, isQualifierContext, getMainSnakPropertyId ) { + 'use strict'; + + var MAX_LABELS_API_LIMIT = 50, + jsonCache = {}; + + function getJsonCached( url ) { + var promise = null; + + if ( jsonCache[ url ] ) { + return jsonCache[ url ]; + } + + promise = $.getJSON( url ); + jsonCache[ url ] = promise; + return promise; + } + + function getConstraintDefinition( repoApiUrl, propertyId, constraintsPropertyId, constraintId, constraintQualifierOfPropertyId ) { + return getJsonCached( repoApiUrl + '?action=wbgetclaims&format=json&entity=' + propertyId + '&property=' + constraintsPropertyId ).then( + function ( d ) { + var oneOfIds = []; + if ( !d.claims || !d.claims[ constraintsPropertyId ] ) { + return oneOfIds; + } + + d.claims[ constraintsPropertyId ].forEach( function ( c ) { + if ( c.mainsnak.datavalue.value.id === constraintId && c.qualifiers && c.qualifiers[ constraintQualifierOfPropertyId ] ) { + oneOfIds = oneOfIds.concat( c.qualifiers[ constraintQualifierOfPropertyId ] + .filter( function ( filterD ) { return filterD.datavalue; } ) + .map( function ( mapD ) { return mapD.datavalue.value.id; } ) ); + } + } ); + + return oneOfIds; + } ); + } + + function createItemsFromIdsFetchLabels( repoApiUrl, language, ids, filter, articlePathPattern ) { + return getJsonCached( repoApiUrl + '?action=wbgetentities&props=labels|descriptions&format=json&languages=' + language + '&ids=' + ids.join( '|' ) ).then( function ( ld ) { + var data = [], + item = null; + ids.forEach( function ( id ) { + var filterTerm = ''; + item = { + id: id, + display: {}, + rating: 1, + url: articlePathPattern.replace( '$1', 'Special:EntityPage/' + id ) + }; + + try { + item.display.label = ld.entities[ id ].labels[ language ]; + filterTerm += item.display.label.value; + } catch ( _ ) { + // no label, ignore + } + + try { + item.display.description = ld.entities[ id ].descriptions[ language ]; + filterTerm += item.display.description.value; + } catch ( _ ) { + // no description, ignore + } + + if ( !filter( filterTerm ) && ( item.display.label || item.display.description ) ) { + data.push( item ); + } + + } ); + return data; + } ); + } + + function createItemsFromIds( repoApiUrl, language, ids, filter, articlePathPattern ) { + var $deferred = $.Deferred(), + promises = [], + itemList = [], + addItems = function ( items ) { + itemList = itemList.concat( items ); + }; + + while ( ids.length > 0 ) { + promises.push( createItemsFromIdsFetchLabels( + repoApiUrl, + language, + ids.splice( 0, MAX_LABELS_API_LIMIT ), + filter, + articlePathPattern + ).then( addItems ) ); + } + + $.when.apply( $, promises ).then( function () { + $deferred.resolve( itemList ); + } ); + + return $deferred.promise(); + } + + return function ( data, addPromise ) { + var propertyConstraintId = config.WBQualityConstraintsPropertyConstraintId, + oneOfConstraintId = config.WBQualityConstraintsOneOfConstraintId, + allowedQualifiersConstraintId = config.WBQualityConstraintsAllowedQualifiersConstraintId, + constraintsPropertyId = config.WBQualityConstraintsPropertyId, + constraintQualifierOfPropertyId = config.WBQualityConstraintsQualifierOfPropertyConstraintId, + mainSnakPropertyId = getMainSnakPropertyId( data.element ), + wbRepo = mw.config.get( 'wbRepo' ), + articlePathPattern = wbRepo.url + wbRepo.articlePath, + constraintId = null, + qualifierId = null, + filterFunction = function ( term ) { + var filter = false; + data.term.split( ' ' ).forEach( function ( t ) { + if ( term.toLowerCase().indexOf( t.toLowerCase() ) === -1 ) { + filter = true; + } + } ); + return filter; + }; + + if ( isQualifierContext( data.element ) && data.options.type === 'property' ) { + constraintId = allowedQualifiersConstraintId; + qualifierId = constraintsPropertyId; + } + + if ( !isQualifierContext( data.element ) && data.options.type === 'item' ) { + constraintId = oneOfConstraintId; + qualifierId = constraintQualifierOfPropertyId; + } + + if ( !constraintId || !qualifierId ) { + return; + } + + addPromise( getConstraintDefinition( + data.options.url, + mainSnakPropertyId, + propertyConstraintId, + constraintId, + qualifierId + ).then( function ( oneOfIds ) { + return createItemsFromIds( data.options.url, data.options.language, oneOfIds, filterFunction, articlePathPattern ); + } ) ); + + }; +}; diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.js b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.js new file mode 100644 index 000000000..d8ce9d9e9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.js @@ -0,0 +1,97 @@ +( function ( OO, wb ) { + 'use strict'; + + /** + * A panel for a group of constraint report results. + * + * @example + * var group = new wikibase.quality.constraints.ui.ConstraintReportGroup( { + * items: [ + * new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'compliance', + * constraint: { + * type: 'Q1', + * typeLabel: 'my constraint', + * link: 'http://example.com/my-constraint' + * }, + * message: 'everything okay' + * } ) + * ], + * label: 'reports that are fine', + * collapsed: true, + * expanded: false, + * framed: true + * } ); + * $( 'body' ).append( group.$element ); + * + * @class + * @extends OO.ui.StackLayout + * eslint-disable-next-line jsdoc/check-tag-names T268378 + * @mixins OO.ui.mixin.LabelElement + * + * @constructor + * @param {Object} config Configuration options + * @cfg {wikibase.quality.constraints.ui.ConstraintReportPanel[]} items The individual constraint report results. + * @cfg {string} [subheading] The subheading of the group. Unlike the label, it is part of the collapsed content if `collapsible` is `true`. + * @cfg {boolean} [collapsible=false] Whether the group can be collapsed or not. If `true`, a `label` is recommended. + * @cfg {boolean} [collapsed=false] Whether the group is collapsed by default or not. (If `true`, implies `collapsible=true` as well.) + * @cfg {string} [status] The status of all reports in this group. Unused by this class, but assigned by `ConstraintReportList.fromPanels`. + */ + wb.quality.constraints.ui.ConstraintReportGroup = function WBQCConstraintReportGroup( config ) { + + var collapsible = config.collapsible || config.collapsed || false, + collapsed = config.collapsed || false, + subheading = config.subheading || null, + status = config.status || null, + $subheadingContainer; + + // Configuration initialization + config.continuous = true; + config.classes = OO.simpleArrayUnion( + config.classes || [], + [ 'wbqc-reports' ] + ); + if ( typeof config.label === 'string' ) { + config.label = $( '' ).text( config.label ); + } + if ( collapsible && config.label === undefined ) { + // blank, but nonempty label so the collapse toggler isn't hidden behind the items + config.label = ' '; + } + + // Parent constructor + wb.quality.constraints.ui.ConstraintReportGroup.parent.call( this, config ); + + // Mixin constructors + OO.ui.mixin.LabelElement.call( this, config ); + + // Properties + this.collapsible = collapsible; + this.collapsed = collapsed; + this.status = status; + + // Initialization + if ( collapsible ) { + this.$element.makeCollapsible( { collapsed: collapsed } ); + } + this.$element.prepend( this.$label ); + if ( subheading !== null ) { + $subheadingContainer = collapsible ? + this.$element.find( '.mw-collapsible-content' ) : + this.$element; + $subheadingContainer.prepend( + $( '

' ).append( $( '' ).text( subheading ) ) + ); + } + }; + + /* Setup */ + + OO.inheritClass( wb.quality.constraints.ui.ConstraintReportGroup, OO.ui.StackLayout ); + OO.mixinClass( wb.quality.constraints.ui.ConstraintReportGroup, OO.ui.mixin.LabelElement ); + + /* Methods */ + + // (none) + +}( OO, wikibase ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.less b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.less new file mode 100644 index 000000000..1e3fec0cd --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportGroup.less @@ -0,0 +1,4 @@ +.wbqc-reports-all .wbqc-reports:not( :first-child ) { + /* add some space between groups in a list */ + margin-top: 1em; +} diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportList.js b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportList.js new file mode 100644 index 000000000..6d49ec5cb --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportList.js @@ -0,0 +1,167 @@ +( function ( OO, wb ) { + 'use strict'; + + /** + * A panel for a list of constraint report results grouped by status. + * + * Usually, you want to initialize the list directly from a list of constraint reports. + * Use the static method {@link wikibase.quality.constraints.ui.ConstraintReportList.fromPanels} for that: + * + * @example + * var report = new wikibase.quality.constraints.ui.ConstraintReportList.static.fromPanels( + * [ + * new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'compliance', + * constraint: { + * type: 'Q1', + * typeLabel: 'my constraint', + * link: 'http://example.com/my-constraint', + * discussLink: 'https://wikidata.org/Property_talk:P2' + * }, + * message: 'everything okay' + * } ), + * new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'violation', + * constraint: { + * type: 'Q2', + * typeLabel: 'my other constraint', + * link: 'http://example.com/my-other-constraint', + * discussLink: 'http://example.com/Property_talk:P2' + * }, + * message: 'doing it wrong' + * } ) + * ], + * { + * statuses: [ + * { + * status: 'violation', + * label: 'Violations' + * }, + * { + * status: 'bad-parameters', + * label: 'Bad parameters', + * collapsed: true + * } + * ], + * expanded: false, + * framed: true + * } + * ); + * $( 'body' ).append( report.$element ); + * + * You can also explicitly provide the groups to the constructor: + * + * @example + * var report = new wikibase.quality.constraints.ui.ConstraintReportList( { + * items: [ + * new wikibase.quality.constraints.ui.ConstraintReportGroup( { + * items: [ + * new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'compliance', + * constraint: { + * type: 'Q1', + * typeLabel: 'my constraint', + * link: 'http://example.com/my-constraint', + * discussLink: 'http://example.com/Property_talk:P2' + * }, + * message: 'everything okay' + * } ) + * ], + * label: 'Violations' + * } ), + * new wikibase.quality.constraints.ui.ConstraintReportGroup( { + * items: [ + * new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'violation', + * constraint: { + * type: 'Q2', + * typeLabel: 'my other constraint', + * link: 'http://example.com/my-other-constraint', + * discussLink: 'http://example.com/Property_talk:P2' + * }, + * message: 'doing it wrong' + * } ) + * ], + * label: 'Bad parameters', + * collapsed: true + * } ) + * ], + * expanded: false, + * framed: true + * } ); + * $( 'body' ).append( report.$element ); + * + * @class + * @extends OO.ui.StackLayout + * + * @constructor + * @param {Object} config Configuration options + * @cfg {wikibase.quality.constraints.ui.ConstraintReportGroup[]} items The constraint report groups. + */ + wb.quality.constraints.ui.ConstraintReportList = function WBQCConstraintReportList( config ) { + + // Configuration initialization + config.continuous = true; + config.classes = OO.simpleArrayUnion( + config.classes || [], + [ 'wbqc-reports-all' ] + ); + + // Parent constructor + wb.quality.constraints.ui.ConstraintReportList.parent.call( this, config ); + + // Mixin constructors + // (none) + }; + + /* Setup */ + + OO.inheritClass( wb.quality.constraints.ui.ConstraintReportList, OO.ui.StackLayout ); + + /* Methods */ + + /** + * Sort a flat list of constraint reports into groups by status. + * + * @param {wikibase.quality.constraints.ui.ConstraintReportPanel[]} panels The individual constraint report panels. + * @param {Object} config Configuration options (all options except `statuses` are passed to the `ConstraintReportList` constructor). + * @param {Object[]} config.statuses The configuration for each group. + * The `status` member selects constraint report panels from `panels` with this status; + * all other options are passed to the `ConstraintReportGroup` constructor. + * The order of status objects in the array determines the order of groups in the list. + * @return {wikibase.quality.constraints.ui.ConstraintReportList} + * @static + */ + wb.quality.constraints.ui.ConstraintReportList.static.fromPanels = function ( panels, config ) { + var panelsByStatus = {}, + items = []; + + panels.forEach( function ( panel ) { + panelsByStatus[ panel.status ] = panelsByStatus[ panel.status ] || []; + panelsByStatus[ panel.status ].push( panel ); + } ); + + config.statuses.forEach( function ( statusConfig ) { + var status = statusConfig.status, + statusPanels = panelsByStatus[ status ]; + + if ( statusPanels === undefined ) { + return; + } + + delete statusConfig.status; // remainder of config is for ConstraintReportGroup + statusConfig.items = statusPanels; + statusConfig.classes = OO.simpleArrayUnion( + statusConfig.classes || [], + [ 'wbqc-reports-status-' + status ] + ); + statusConfig.status = status; + items.push( new wb.quality.constraints.ui.ConstraintReportGroup( statusConfig ) ); + } ); + + delete config.statuses; // remainder of config is for ConstraintReportList + config.items = items; + return new wb.quality.constraints.ui.ConstraintReportList( config ); + }; + +}( OO, wikibase ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.js b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.js new file mode 100644 index 000000000..d7a94f0ea --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.js @@ -0,0 +1,113 @@ +( function ( mw, wb ) { + 'use strict'; + + /** + * A panel for a single constraint report result. + * + * @example + * var report = new wikibase.quality.constraints.ui.ConstraintReportPanel( { + * status: 'compliance', + * constraint: { + * type: 'Q1', + * typeLabel: 'my constraint', + * link: 'http://example.com/my-constraint', + * discussLink: 'http://example.com/Property_talk:P2', + * }, + * message: 'everything okay', + * expanded: false, + * framed: true + * } ); + * $( 'body' ).append( report.$element ); + * + * @class + * @extends OO.ui.PanelLayout + * + * @constructor + * @param {Object} config Configuration options + * @cfg {string} status The status of the report, e.g. 'violation' or 'compliance'. + * @cfg {Object} constraint The constraint of the report, as returned by the wbcheckconstraints API. + * @cfg {string} [message=''] The message (HTML) of the report, if present. + * @cfg {string[]} [ancillaryMessages=[]] Additional messages (HTML) attached to the report, if any. + * @cfg {jQuery} [$heading] The heading element of the panel. Should not yet contain the heading links. + * @cfg {jQuery} [$headingLinks] The container for the links in the heading of the panel. Should not yet contain the help link or the discussion link. + * @cfg {jQuery} [$helpLink] The help link for the heading. + * @cfg {jQuery} [$discussLink] The link to the discussion page. + * @cfg {jQuery} [$message] The message paragraph of the panel. + * @cfg {jQuery} [$ancillaryMessages] The container of the additional messages. + */ + wb.quality.constraints.ui.ConstraintReportPanel = function WBQCConstraintReportPanel( config ) { + // Configuration initialization + config = $.extend( { + message: '', + ancillaryMessages: [] + }, config ); + config.expanded = false; + + // Parent constructor + wb.quality.constraints.ui.ConstraintReportPanel.parent.call( this, config ); + + // Mixin constructors + // (none) + + // Properties + this.status = config.status; + this.constraint = config.constraint; + this.$heading = config.$heading || $( '

' ).append( + $( '' ) + .text( this.constraint.typeLabel ) + .attr( 'href', this.constraint.link ) + .attr( 'target', '_blank' ) + ); + this.$headingLinks = config.$headingLinks || $( '' ); + this.$helpLink = config.$helpLink || $( '' ) + .text( mw.message( 'wbqc-constrainttypehelp-short' ).text() ) + .attr( 'title', mw.message( 'wbqc-constrainttypehelp-long' ).text() ) + .attr( + 'href', + 'https://www.wikidata.org/wiki/Special:MyLanguage/Help:Property_constraints_portal/' + this.constraint.type + ) + .attr( 'target', '_blank' ); + this.$discussLink = config.$discussLink || $( '' ) + .text( mw.message( 'wbqc-constraintdiscuss-short' ).text() ) + .attr( 'title', mw.message( 'wbqc-constraintdiscuss-long' ).text() ) + .attr( 'href', this.constraint.discussLink ) + .attr( 'target', '_blank' ); + this.message = config.message; + this.$message = config.$message || $( '

' ).html( this.message ); + this.ancillaryMessages = config.ancillaryMessages; + this.$ancillaryMessages = config.$ancillaryMessages || $( '

' ).append( + this.ancillaryMessages.map( function ( ancillaryMessage ) { + return $( '

' ).html( ancillaryMessage ); + } ) + ); + + // Events + // (none) + + // Initialization + // The following classes are used here: + // * wbqc-report-status-violation + // * wbqc-report-status-warning + // * wbqc-report-status-suggestion + this.$element + .addClass( 'wbqc-report' ) + .addClass( 'wbqc-report-status-' + this.status ); + this.$headingLinks + .append( this.$helpLink ) + .append( ' ' ) + .append( this.$discussLink ); + this.$heading.append( this.$headingLinks ); + this.$element.append( this.$heading ); + this.$element.append( this.$message ); + this.$element.append( this.$ancillaryMessages ); + }; + + /* Setup */ + + OO.inheritClass( wb.quality.constraints.ui.ConstraintReportPanel, OO.ui.PanelLayout ); + + /* Methods */ + + // (none) + +}( mediaWiki, wikibase ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.less b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.less new file mode 100644 index 000000000..b9b936d42 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/ConstraintReportPanel.less @@ -0,0 +1,23 @@ +@import 'mediawiki.ui/variables'; + +.wbqc-report { + margin-right: 0.5em; + + .wbqc-report-heading { + .wbqc-report-heading-links { + font-weight: normal; + float: right; + margin-left: 1.5em; + } + + + p { + margin-top: 0; + } + } + + .wbqc-ancillary-messages { + font-style: italic; + font-size: 90%; + color: @colorTextLight; + } +} diff --git a/dist/extensions/WikibaseQualityConstraints/modules/ui/module.js b/dist/extensions/WikibaseQualityConstraints/modules/ui/module.js new file mode 100644 index 000000000..8168b1a9a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/modules/ui/module.js @@ -0,0 +1,8 @@ +( function ( wb ) { + 'use strict'; + + wb.quality = wb.quality || {}; + wb.quality.constraints = wb.quality.constraints || {}; + wb.quality.constraints.ui = wb.quality.constraints.ui || {}; + +}( wikibase ) ); diff --git a/dist/extensions/WikibaseQualityConstraints/package-lock.json b/dist/extensions/WikibaseQualityConstraints/package-lock.json new file mode 100644 index 000000000..2869758b8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/package-lock.json @@ -0,0 +1,9481 @@ +{ + "name": "WikibaseQualityConstraints", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "WikibaseQualityConstraints", + "devDependencies": { + "eslint-config-wikimedia": "0.22.1", + "eslint-plugin-jasmine": "^4.1.3", + "grunt": "1.5.3", + "grunt-banana-checker": "0.10.0", + "grunt-eslint": "24.0.0", + "grunt-jasmine-nodejs": "^1.6.1", + "grunt-stylelint": "0.18.0", + "jasmine": "^4.3.0", + "module-alias": "^2.1.0", + "sinon": "^14.0.0", + "stylelint-config-wikimedia": "0.13.1", + "unexpected": "^13.0.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.18.0.tgz", + "integrity": "sha512-TjT8KJULV4I6ZiwIoKr6eMs+XpRejqwJ/VA+QPDeFGe9j6bZFKmMJ81EeFsGm6JNZhnzm37aoxVROmTh2PZoyA==", + "dev": true, + "dependencies": { + "comment-parser": "1.3.0", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~2.2.2" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", + "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@mdn/browser-compat-data": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.7.tgz", + "integrity": "sha512-rOxg9jU9L3PrwhHI5DEqKOARt/gCXku/j3RvaEfP8hxeMI6bh0Ov1TqcgoajA/D01PXKTuLfEYvF3kWuheRB7w==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz", + "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-changes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-changes/-/array-changes-3.0.1.tgz", + "integrity": "sha512-UYXV+qUaTKJO3GUBVfD6b9Mu7wUzDvpfovZKtbxNJApwRUifgrJMidvE+/rbqV3wCffly5HXcbOW3/7shmmEag==", + "dev": true, + "dependencies": { + "arraydiff-papandreou": "0.1.1-patch1" + } + }, + "node_modules/array-changes-async": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-changes-async/-/array-changes-async-3.0.1.tgz", + "integrity": "sha512-WNHLhMOTzntixkBxNm/MiWCNKuC4FMYXk6DKuzZUbkWXAe0Xomwv40SEUicfOuHHtW7Ue661Mc5AJA0AOfqApg==", + "dev": true, + "dependencies": { + "arraydiff-async": "0.2.0" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arraydiff-async": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/arraydiff-async/-/arraydiff-async-0.2.0.tgz", + "integrity": "sha1-uwUouY6BS3AvAfSWvHO+w+V/QIY=", + "dev": true + }, + "node_modules/arraydiff-papandreou": { + "version": "0.1.1-patch1", + "resolved": "https://registry.npmjs.org/arraydiff-papandreou/-/arraydiff-papandreou-0.1.1-patch1.tgz", + "integrity": "sha1-ApAnC/27Sy762LdIJjitWnIQkhA=", + "dev": true + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^3.3.14" + } + }, + "node_modules/ast-metadata-inferer/node_modules/@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/browserslist-config-wikimedia": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.4.0.tgz", + "integrity": "sha512-U/fmsaGlCKOqRIjKqXwQ44qFqiStngRTphj1Cf6IHV6J8OK8T0gu9dKc7Ljq4v7bwhnhN+YCCa4fA3nZlPNivQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001341", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", + "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-diff": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz", + "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=", + "dev": true + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "dev": true + }, + "node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/comment-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz", + "integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/core-js": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz", + "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", + "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "dependencies": { + "css-tokenize": "^1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "through2": "^0.6.3" + }, + "bin": { + "css-rule-stream": "index.js" + } + }, + "node_modules/css-rule-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/css-rule-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^1.0.33" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", + "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1", + "minimist": "^1.1.0", + "repeating": "^1.1.0" + }, + "bin": { + "detect-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent/node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/doiuse": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-4.4.1.tgz", + "integrity": "sha512-TUpr1/YNg20IB09tZmwGCTsTQoxj8jUld/hUZprZMj8vj0VpAJySXEWCr8WMvqvgzk0/kG/FxeSMGKode4UjPg==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001179", + "css-rule-stream": "^1.1.0", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "multimatch": "^5.0.0", + "postcss": "^8.2.4", + "source-map": "^0.7.3", + "through2": "^4.0.2", + "yargs": "^16.2.0" + }, + "bin": { + "doiuse": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "dependencies": { + "readable-stream": "~1.1.9" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", + "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.1.tgz", + "integrity": "sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.3", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^6.0.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-config-wikimedia": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.22.1.tgz", + "integrity": "sha512-TtN+gWJrcW0i1sEu7vPE1tHpEilrMUuTxP6UK97Amvva/KDV9/tvRUifGhw0q5uBswp+HWgF12p8rq68hZqMbA==", + "dev": true, + "dependencies": { + "eslint": "^8.6.0", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-es": "^4.1.0", + "eslint-plugin-jsdoc": "^37.7.1", + "eslint-plugin-json-es": "^1.5.4", + "eslint-plugin-mediawiki": "^0.3.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-jquery": "^2.7.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-qunit": "^7.2.0", + "eslint-plugin-unicorn": "^40.1.0", + "eslint-plugin-vue": "^8.4.1", + "eslint-plugin-wdio": "^7.4.2", + "eslint-plugin-yml": "^0.13.0" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/@humanwhocodes/config-array": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/eslint-config-wikimedia/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint-config-wikimedia/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/eslint": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", + "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/glob-parent/node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-config-wikimedia/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "engines": { + "node": ">=9.x" + } + }, + "node_modules/eslint-plugin-compat/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-compat/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-compat/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-compat/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-compat/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-jasmine": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.3.tgz", + "integrity": "sha512-q8j8KnLH/4uwmPELFZvEyfEcuCuGxXScJaRdqHjOjz064GcfX6aoFbzy5VohZ5QYk2+WvoqMoqDSb9nRLf89GQ==", + "dev": true, + "engines": { + "node": ">=8", + "npm": ">=6" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "37.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.8.0.tgz", + "integrity": "sha512-0HvNH9nyKhp06u5vi8lPB97j/luBrkk+6JrcKVBjLQZuVkyzLYfKOYoc9cFHxMKvJMgYVa2F3g+msV2T8IM3jQ==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.18.0", + "comment-parser": "1.3.0", + "debug": "^4.3.3", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "regextras": "^0.8.0", + "semver": "^7.3.5", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": "^12 || ^14 || ^16 || ^17" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-json-es": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.4.tgz", + "integrity": "sha512-DdjnNMUZ1iMrUXfxUQrTU7IyoEOsa4Kg0Zd6nOyOq1mUb75deK7NrcbI1FlWGdGVgqX99bUOD27i81EYiG794Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0" + } + }, + "node_modules/eslint-plugin-mediawiki": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.3.0.tgz", + "integrity": "sha512-Lhyj2PSkhDzYSc1PNbURysY/WoqvY0brw558ZInT3erzf5KUlro18MTKFdV+nlht475ZgnsfHsgfg6Ut2w1SVg==", + "dev": true, + "dependencies": { + "eslint-plugin-vue": "^7.20.0", + "upath": "^2.0.1" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/eslint-plugin-vue": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz", + "integrity": "sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.1.0", + "natural-compare": "^1.4.0", + "semver": "^6.3.0", + "vue-eslint-parser": "^7.10.0" + }, + "engines": { + "node": ">=8.10" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-mediawiki/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/eslint-plugin-no-jquery": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", + "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", + "dev": true + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-qunit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.2.0.tgz", + "integrity": "sha512-ebT6aOpmMj4vchG0hVw9Ukbutk/lgywrc8gc9w9hH2/4WjKqwMlyM7iVwqB7OAXv6gtQMJZuziT0wNjjymAuWA==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "requireindex": "^1.2.0" + }, + "engines": { + "node": "12.x || 14.x || >=16.0.0" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.5", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-vue": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.4.1.tgz", + "integrity": "sha512-nmWOhNmDx9TZ+yP9ZhezTkZUupSHsYA2TocRm+efPSXMOyFrVczVlaIuQcLBjCtI8CbkBiUQ3VcyQsjlIhDrhA==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "natural-compare": "^1.4.0", + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-vue/node_modules/vue-eslint-parser": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.2.0.tgz", + "integrity": "sha512-hvl8OVT8imlKk/lQyhkshqwQQChzHETcBd5abiO4ePw7ib7QUZLfW+2TUrJHKUvFOCFRJrDin5KJO9OHzB5bRQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-wdio": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.4.2.tgz", + "integrity": "sha512-tkISFycJmRFMKsEjetRcAmWSHKJKnw5rKHDxfE7Ob3tF5lbmYlCLfNKH0UwanOpSdulpe52s3K+CBHSd6qUUNQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/eslint-plugin-yml": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.13.0.tgz", + "integrity": "sha512-rZvdnhe28jIbgSIZo3qYqkl9hKslyTDfMwqIGDzz873gxghzBw0yeFG+P7sMfOkFfpqwJzZy3IKe2cIiCp4FrA==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^0.5.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", + "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/glob-parent/node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "dependencies": { + "glob": "~5.0.0" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/findup-sync/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getobject": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz", + "integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "node_modules/greedy-interval-packer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/greedy-interval-packer/-/greedy-interval-packer-1.2.0.tgz", + "integrity": "sha1-1toR82Ybt5eBLaeKHqUQZ4oqhzk=", + "dev": true + }, + "node_modules/grunt": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", + "dev": true, + "dependencies": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.3", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-banana-checker": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/grunt-banana-checker/-/grunt-banana-checker-0.10.0.tgz", + "integrity": "sha512-Sx+P3zWjn4YmBCqzidnCEkYrACe1SLTIT8kKC6C3f21Hu6sm17U/V+re343cuK3U+iGZv15ux6bY+69buIbYrA==", + "dev": true, + "bin": { + "banana-checker": "src/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-eslint": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-24.0.0.tgz", + "integrity": "sha512-WpTeBBFweyhMuPjGwRSQV9JFJ+EczIdlsc7Dd/1g78QVI1aZsk4g/H3e+3S5HEwsS1RKL2YZIrGj8hMLlBfN8w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "eslint": "^8.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/grunt-eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/grunt-eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/grunt-eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-jasmine-nodejs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/grunt-jasmine-nodejs/-/grunt-jasmine-nodejs-1.6.1.tgz", + "integrity": "sha512-TalyBXfM2Gd+r8iCbtWkDUE+DJaPbrR0yRNXT7CiiYwWiEhutWDZVCUA7d5s5wCZsYW+KSFKjb1AkVqvqFBMmA==", + "dev": true, + "dependencies": { + "glob": "^7.1.1", + "grunt": "^1.0.1", + "jasmine-console-reporter": "^1.2.7", + "jasmine-core": "^2.5.2", + "jasmine-reporters": "^2.2.0", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "dependencies": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "dependencies": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "dependencies": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-stylelint": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.18.0.tgz", + "integrity": "sha512-Ks5OfRUCA6E1v5PkCQKYaMErHtoec/Ub0Vb1xvZ0CKm/1zzWKuqEu2ZVtFcQVDqrC5UM6AXaLHpsLiocVKAgbg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/grunt-stylelint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-stylelint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-stylelint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/grunt-stylelint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/grunt-stylelint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-stylelint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt/node_modules/grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "dependencies": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt/node_modules/grunt-cli/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jasmine": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.3.0.tgz", + "integrity": "sha512-ieBmwkd8L1DXnvSnxx7tecXgA0JDgMXPAwBcqM4lLPedJeI9hTHuWifPynTC+dLe4Y+GkSPSlbqqrmYIgGzYUw==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "jasmine-core": "^4.3.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-console-reporter": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-1.2.8.tgz", + "integrity": "sha1-2JPJwMElcn7Xd3Cc9Hh2gNBRU5Y=", + "dev": true, + "dependencies": { + "chalk": "^2.1.0" + } + }, + "node_modules/jasmine-console-reporter/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jasmine-core": { + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", + "dev": true + }, + "node_modules/jasmine-reporters": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-2.5.0.tgz", + "integrity": "sha512-J69peyTR8j6SzvIPP6aO1Y00wwCqXuIvhwTYvE/di14roCf6X3wDZ4/cKGZ2fGgufjhP2FKjpgrUIKjwau4e/Q==", + "dev": true, + "dependencies": { + "@xmldom/xmldom": "^0.7.3", + "mkdirp": "^1.0.4" + } + }, + "node_modules/jasmine/node_modules/jasmine-core": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.3.0.tgz", + "integrity": "sha512-qybtBUesniQdW6n+QIHMng2vDOHscIC/dEXjW+JzO9+LoAZMb03RCUC5xFOv/btSKPm1xL42fn+RjlU4oB42Lg==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.2.tgz", + "integrity": "sha512-zRokSWcPLSWkoNzsWn9pq7YYSwDhKyEe+cJYT2qaPqLOOJb5sFSi46BPj81vP+e8chvCNdQL9RG86Bi9EI6MDw==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.24.0.tgz", + "integrity": "sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==", + "dev": true + }, + "node_modules/ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "dependencies": { + "split2": "^0.2.1", + "through2": "^0.6.1" + } + }, + "node_modules/ldjson-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ldjson-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/liftup/node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/magicpen": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/magicpen/-/magicpen-6.2.4.tgz", + "integrity": "sha512-rT4JcgakSrmR9/qPY/EsDSvKH4+nQuFfSQ34Djnj0Zx9jJ+c3REOz+K3CITvRZcmAcCFM6jJO7wSiHlMEXYy3A==", + "dev": true, + "dependencies": { + "ansi-styles": "2.0.0", + "color-diff": "0.1.7" + } + }, + "node_modules/magicpen/node_modules/ansi-styles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.0.0.tgz", + "integrity": "sha1-QysmFi/qG2PIeIlqvIzFVI8lBj4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nise": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.5.0.tgz", + "integrity": "sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==", + "dev": true, + "dependencies": { + "htmlparser2": "^8.0.0", + "js-tokens": "^8.0.0", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + }, + "engines": { + "node": "^12 || >=14" + } + }, + "node_modules/postcss-html/node_modules/js-tokens": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.0.tgz", + "integrity": "sha512-PC7MzqInq9OqKyTXfIvQNcjMkODJYC8A17kAaQgeW79yfhqTWSOfjHYQ2mDDcwJ96Iibtwkfh0C7R/OvqPlgVA==", + "dev": true + }, + "node_modules/postcss-less": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", + "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/regextras": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", + "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", + "dev": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "bin": { + "repeating": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sinon": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", + "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^6.1.1", + "diff": "^5.0.0", + "nise": "^5.1.1", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "dependencies": { + "through2": "~0.6.1" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/split2/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/stylelint": { + "version": "14.8.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.1.tgz", + "integrity": "sha512-0YxTop3wTeEVmQWhS7jjLFaBkvfPmffRiJ6eFIDlK++f3OklaobTYFJu32E5u/cIrFLbcW52pLqrYpihA/y0/w==", + "dev": true, + "dependencies": { + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.0.1", + "debug": "^4.3.4", + "execall": "^2.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.0", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.24.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "normalize-selector": "^0.2.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.12", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^2.2.0", + "svg-tags": "^1.0.0", + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-wikimedia": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.13.1.tgz", + "integrity": "sha512-Wpm+cVJ2eZmlPO8HCv223OZZwyVZh5Ha11dRkzlccZwscxVkoKj/lo6xo10GNWBV9kpEA0+ksYJTIXXmRw1AoA==", + "dev": true, + "dependencies": { + "browserslist-config-wikimedia": "0.4.0", + "postcss-html": "1.5.0", + "postcss-less": "6.0.0", + "stylelint": "14.8.1", + "stylelint-config-recommended": "7.0.0", + "stylelint-no-unsupported-browser-features": "5.0.3" + }, + "peerDependencies": { + "postcss-less": "^6.0.0" + } + }, + "node_modules/stylelint-no-unsupported-browser-features": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-5.0.3.tgz", + "integrity": "sha512-FqfbOTk5UEkHsAKOkPH6SvajsfO9YuoWvKxd34tCRBZug9ZNeaPn141nyWkd+ncc8S1gVmO2+O6qVAMj9bvWww==", + "dev": true, + "dependencies": { + "doiuse": "^4.4.1", + "lodash": "^4.17.15", + "postcss": "^8.3.6" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "stylelint": ">=13.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ukkonen": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ukkonen/-/ukkonen-1.4.0.tgz", + "integrity": "sha512-g8SLGxflI0/VNH2C8j66KcfJXrU5StJglRQBYPNiChXFlOrqqYM1icOykOAAUgTeBpktaEuCm9hjpPinQ080PA==", + "dev": true + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore.string/node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/unexpected": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/unexpected/-/unexpected-13.0.1.tgz", + "integrity": "sha512-zONsPi275j2rSvsJ9lPoVFNKJ50eJMaX08XMmnC0IXJasFnOXnqD1fZAWGlnK7hG6PeoYDLOiOsBSzbVYaWr9Q==", + "dev": true, + "dependencies": { + "array-changes": "3.0.1", + "array-changes-async": "3.0.1", + "detect-indent": "3.0.1", + "diff": "^5.0.0", + "greedy-interval-packer": "1.2.0", + "magicpen": "^6.2.4", + "ukkonen": "^1.4.0", + "unexpected-bluebird": "2.9.34-longstack2" + } + }, + "node_modules/unexpected-bluebird": { + "version": "2.9.34-longstack2", + "resolved": "https://registry.npmjs.org/unexpected-bluebird/-/unexpected-bluebird-2.9.34-longstack2.tgz", + "integrity": "sha1-SaysdTsFVt7WAlIQ7pYYIwfSssk=", + "dev": true + }, + "node_modules/upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vue-eslint-parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz", + "integrity": "sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8.10" + } + }, + "node_modules/vue-eslint-parser/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/vue-eslint-parser/node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-eslint-parser": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz", + "integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@es-joy/jsdoccomment": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.18.0.tgz", + "integrity": "sha512-TjT8KJULV4I6ZiwIoKr6eMs+XpRejqwJ/VA+QPDeFGe9j6bZFKmMJ81EeFsGm6JNZhnzm37aoxVROmTh2PZoyA==", + "dev": true, + "requires": { + "comment-parser": "1.3.0", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~2.2.2" + } + }, + "@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", + "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "@mdn/browser-compat-data": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.7.tgz", + "integrity": "sha512-rOxg9jU9L3PrwhHI5DEqKOARt/gCXku/j3RvaEfP8hxeMI6bh0Ov1TqcgoajA/D01PXKTuLfEYvF3kWuheRB7w==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", + "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@xmldom/xmldom": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz", + "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-changes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-changes/-/array-changes-3.0.1.tgz", + "integrity": "sha512-UYXV+qUaTKJO3GUBVfD6b9Mu7wUzDvpfovZKtbxNJApwRUifgrJMidvE+/rbqV3wCffly5HXcbOW3/7shmmEag==", + "dev": true, + "requires": { + "arraydiff-papandreou": "0.1.1-patch1" + } + }, + "array-changes-async": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-changes-async/-/array-changes-async-3.0.1.tgz", + "integrity": "sha512-WNHLhMOTzntixkBxNm/MiWCNKuC4FMYXk6DKuzZUbkWXAe0Xomwv40SEUicfOuHHtW7Ue661Mc5AJA0AOfqApg==", + "dev": true, + "requires": { + "arraydiff-async": "0.2.0" + } + }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arraydiff-async": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/arraydiff-async/-/arraydiff-async-0.2.0.tgz", + "integrity": "sha1-uwUouY6BS3AvAfSWvHO+w+V/QIY=", + "dev": true + }, + "arraydiff-papandreou": { + "version": "0.1.1-patch1", + "resolved": "https://registry.npmjs.org/arraydiff-papandreou/-/arraydiff-papandreou-0.1.1-patch1.tgz", + "integrity": "sha1-ApAnC/27Sy762LdIJjitWnIQkhA=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^3.3.14" + }, + "dependencies": { + "@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + } + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + } + }, + "browserslist-config-wikimedia": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.4.0.tgz", + "integrity": "sha512-U/fmsaGlCKOqRIjKqXwQ44qFqiStngRTphj1Cf6IHV6J8OK8T0gu9dKc7Ljq4v7bwhnhN+YCCa4fA3nZlPNivQ==", + "dev": true + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "caniuse-lite": { + "version": "1.0.30001341", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", + "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "requires": { + "is-regexp": "^2.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-diff": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz", + "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=", + "dev": true + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "comment-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz", + "integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-js": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz", + "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-functions-list": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz", + "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==", + "dev": true + }, + "css-rule-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz", + "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=", + "dev": true, + "requires": { + "css-tokenize": "^1.0.1", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "through2": "^0.6.3" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "css-tokenize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz", + "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^1.0.33" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-indent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", + "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "minimist": "^1.1.0", + "repeating": "^1.1.0" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "doiuse": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-4.4.1.tgz", + "integrity": "sha512-TUpr1/YNg20IB09tZmwGCTsTQoxj8jUld/hUZprZMj8vj0VpAJySXEWCr8WMvqvgzk0/kG/FxeSMGKode4UjPg==", + "dev": true, + "requires": { + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001179", + "css-rule-stream": "^1.1.0", + "duplexer2": "0.0.2", + "ldjson-stream": "^1.2.1", + "multimatch": "^5.0.0", + "postcss": "^8.2.4", + "source-map": "^0.7.3", + "through2": "^4.0.2", + "yargs": "^16.2.0" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "~1.1.9" + } + }, + "electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz", + "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.1.tgz", + "integrity": "sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.3", + "@humanwhocodes/config-array": "^0.6.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^6.0.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-scope": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", + "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + }, + "dependencies": { + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + } + } + } + } + }, + "eslint-config-wikimedia": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.22.1.tgz", + "integrity": "sha512-TtN+gWJrcW0i1sEu7vPE1tHpEilrMUuTxP6UK97Amvva/KDV9/tvRUifGhw0q5uBswp+HWgF12p8rq68hZqMbA==", + "dev": true, + "requires": { + "eslint": "^8.6.0", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-es": "^4.1.0", + "eslint-plugin-jsdoc": "^37.7.1", + "eslint-plugin-json-es": "^1.5.4", + "eslint-plugin-mediawiki": "^0.3.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-jquery": "^2.7.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-qunit": "^7.2.0", + "eslint-plugin-unicorn": "^40.1.0", + "eslint-plugin-vue": "^8.4.1", + "eslint-plugin-wdio": "^7.4.2", + "eslint-plugin-yml": "^0.13.0" + }, + "dependencies": { + "@humanwhocodes/config-array": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", + "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + }, + "dependencies": { + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-plugin-jasmine": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.3.tgz", + "integrity": "sha512-q8j8KnLH/4uwmPELFZvEyfEcuCuGxXScJaRdqHjOjz064GcfX6aoFbzy5VohZ5QYk2+WvoqMoqDSb9nRLf89GQ==", + "dev": true + }, + "eslint-plugin-jsdoc": { + "version": "37.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.8.0.tgz", + "integrity": "sha512-0HvNH9nyKhp06u5vi8lPB97j/luBrkk+6JrcKVBjLQZuVkyzLYfKOYoc9cFHxMKvJMgYVa2F3g+msV2T8IM3jQ==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.18.0", + "comment-parser": "1.3.0", + "debug": "^4.3.3", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.4.0", + "regextras": "^0.8.0", + "semver": "^7.3.5", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-json-es": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-json-es/-/eslint-plugin-json-es-1.5.4.tgz", + "integrity": "sha512-DdjnNMUZ1iMrUXfxUQrTU7IyoEOsa4Kg0Zd6nOyOq1mUb75deK7NrcbI1FlWGdGVgqX99bUOD27i81EYiG794Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0" + } + }, + "eslint-plugin-mediawiki": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.3.0.tgz", + "integrity": "sha512-Lhyj2PSkhDzYSc1PNbURysY/WoqvY0brw558ZInT3erzf5KUlro18MTKFdV+nlht475ZgnsfHsgfg6Ut2w1SVg==", + "dev": true, + "requires": { + "eslint-plugin-vue": "^7.20.0", + "upath": "^2.0.1" + }, + "dependencies": { + "eslint-plugin-vue": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.20.0.tgz", + "integrity": "sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==", + "dev": true, + "requires": { + "eslint-utils": "^2.1.0", + "natural-compare": "^1.4.0", + "semver": "^6.3.0", + "vue-eslint-parser": "^7.10.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + } + }, + "eslint-plugin-no-jquery": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz", + "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==", + "dev": true + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-qunit": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.2.0.tgz", + "integrity": "sha512-ebT6aOpmMj4vchG0hVw9Ukbutk/lgywrc8gc9w9hH2/4WjKqwMlyM7iVwqB7OAXv6gtQMJZuziT0wNjjymAuWA==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "requireindex": "^1.2.0" + } + }, + "eslint-plugin-unicorn": { + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", + "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.15.7", + "ci-info": "^3.3.0", + "clean-regexp": "^1.0.0", + "eslint-utils": "^3.0.0", + "esquery": "^1.4.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.24", + "safe-regex": "^2.1.1", + "semver": "^7.3.5", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-vue": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.4.1.tgz", + "integrity": "sha512-nmWOhNmDx9TZ+yP9ZhezTkZUupSHsYA2TocRm+efPSXMOyFrVczVlaIuQcLBjCtI8CbkBiUQ3VcyQsjlIhDrhA==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "natural-compare": "^1.4.0", + "semver": "^7.3.5", + "vue-eslint-parser": "^8.0.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "vue-eslint-parser": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.2.0.tgz", + "integrity": "sha512-hvl8OVT8imlKk/lQyhkshqwQQChzHETcBd5abiO4ePw7ib7QUZLfW+2TUrJHKUvFOCFRJrDin5KJO9OHzB5bRQ==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + } + } + } + }, + "eslint-plugin-wdio": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.4.2.tgz", + "integrity": "sha512-tkISFycJmRFMKsEjetRcAmWSHKJKnw5rKHDxfE7Ob3tF5lbmYlCLfNKH0UwanOpSdulpe52s3K+CBHSd6qUUNQ==", + "dev": true + }, + "eslint-plugin-yml": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.13.0.tgz", + "integrity": "sha512-rZvdnhe28jIbgSIZo3qYqkl9hKslyTDfMwqIGDzz873gxghzBw0yeFG+P7sMfOkFfpqwJzZy3IKe2cIiCp4FrA==", + "dev": true, + "requires": { + "debug": "^4.3.2", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^0.5.0" + } + }, + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "dev": true + }, + "espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "requires": { + "clone-regexp": "^2.1.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, + "getobject": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz", + "integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "greedy-interval-packer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/greedy-interval-packer/-/greedy-interval-packer-1.2.0.tgz", + "integrity": "sha1-1toR82Ybt5eBLaeKHqUQZ4oqhzk=", + "dev": true + }, + "grunt": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz", + "integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==", + "dev": true, + "requires": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.3", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "dependencies": { + "grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "requires": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + } + } + }, + "grunt-banana-checker": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/grunt-banana-checker/-/grunt-banana-checker-0.10.0.tgz", + "integrity": "sha512-Sx+P3zWjn4YmBCqzidnCEkYrACe1SLTIT8kKC6C3f21Hu6sm17U/V+re343cuK3U+iGZv15ux6bY+69buIbYrA==", + "dev": true + }, + "grunt-eslint": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-24.0.0.tgz", + "integrity": "sha512-WpTeBBFweyhMuPjGwRSQV9JFJ+EczIdlsc7Dd/1g78QVI1aZsk4g/H3e+3S5HEwsS1RKL2YZIrGj8hMLlBfN8w==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "eslint": "^8.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "grunt-jasmine-nodejs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/grunt-jasmine-nodejs/-/grunt-jasmine-nodejs-1.6.1.tgz", + "integrity": "sha512-TalyBXfM2Gd+r8iCbtWkDUE+DJaPbrR0yRNXT7CiiYwWiEhutWDZVCUA7d5s5wCZsYW+KSFKjb1AkVqvqFBMmA==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "grunt": "^1.0.1", + "jasmine-console-reporter": "^1.2.7", + "jasmine-core": "^2.5.2", + "jasmine-reporters": "^2.2.0", + "lodash": "^4.17.4" + } + }, + "grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true + }, + "grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "requires": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "requires": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + } + }, + "grunt-stylelint": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.18.0.tgz", + "integrity": "sha512-Ks5OfRUCA6E1v5PkCQKYaMErHtoec/Ub0Vb1xvZ0CKm/1zzWKuqEu2ZVtFcQVDqrC5UM6AXaLHpsLiocVKAgbg==", + "dev": true, + "requires": { + "chalk": "^4.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "html-tags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", + "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "dev": true + }, + "htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jasmine": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.3.0.tgz", + "integrity": "sha512-ieBmwkd8L1DXnvSnxx7tecXgA0JDgMXPAwBcqM4lLPedJeI9hTHuWifPynTC+dLe4Y+GkSPSlbqqrmYIgGzYUw==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "jasmine-core": "^4.3.0" + }, + "dependencies": { + "jasmine-core": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.3.0.tgz", + "integrity": "sha512-qybtBUesniQdW6n+QIHMng2vDOHscIC/dEXjW+JzO9+LoAZMb03RCUC5xFOv/btSKPm1xL42fn+RjlU4oB42Lg==", + "dev": true + } + } + }, + "jasmine-console-reporter": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-1.2.8.tgz", + "integrity": "sha1-2JPJwMElcn7Xd3Cc9Hh2gNBRU5Y=", + "dev": true, + "requires": { + "chalk": "^2.1.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "jasmine-core": { + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", + "dev": true + }, + "jasmine-reporters": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-2.5.0.tgz", + "integrity": "sha512-J69peyTR8j6SzvIPP6aO1Y00wwCqXuIvhwTYvE/di14roCf6X3wDZ4/cKGZ2fGgufjhP2FKjpgrUIKjwau4e/Q==", + "dev": true, + "requires": { + "@xmldom/xmldom": "^0.7.3", + "mkdirp": "^1.0.4" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsdoc-type-pratt-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.2.tgz", + "integrity": "sha512-zRokSWcPLSWkoNzsWn9pq7YYSwDhKyEe+cJYT2qaPqLOOJb5sFSi46BPj81vP+e8chvCNdQL9RG86Bi9EI6MDw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "known-css-properties": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.24.0.tgz", + "integrity": "sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==", + "dev": true + }, + "ldjson-stream": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz", + "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=", + "dev": true, + "requires": { + "split2": "^0.2.1", + "through2": "^0.6.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + } + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "magicpen": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/magicpen/-/magicpen-6.2.4.tgz", + "integrity": "sha512-rT4JcgakSrmR9/qPY/EsDSvKH4+nQuFfSQ34Djnj0Zx9jJ+c3REOz+K3CITvRZcmAcCFM6jJO7wSiHlMEXYy3A==", + "dev": true, + "requires": { + "ansi-styles": "2.0.0", + "color-diff": "0.1.7" + }, + "dependencies": { + "ansi-styles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.0.0.tgz", + "integrity": "sha1-QysmFi/qG2PIeIlqvIzFVI8lBj4=", + "dev": true + } + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true + }, + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + } + } + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nise": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", + "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": ">=5", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-html": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.5.0.tgz", + "integrity": "sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==", + "dev": true, + "requires": { + "htmlparser2": "^8.0.0", + "js-tokens": "^8.0.0", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.0.tgz", + "integrity": "sha512-PC7MzqInq9OqKyTXfIvQNcjMkODJYC8A17kAaQgeW79yfhqTWSOfjHYQ2mDDcwJ96Iibtwkfh0C7R/OvqPlgVA==", + "dev": true + } + } + }, + "postcss-less": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz", + "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==", + "dev": true + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "regextras": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", + "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", + "dev": true + }, + "repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sinon": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", + "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^9.1.2", + "@sinonjs/samsam": "^6.1.1", + "diff": "^5.0.0", + "nise": "^5.1.1", + "supports-color": "^7.2.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true + }, + "split2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz", + "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=", + "dev": true, + "requires": { + "through2": "~0.6.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "stylelint": { + "version": "14.8.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.8.1.tgz", + "integrity": "sha512-0YxTop3wTeEVmQWhS7jjLFaBkvfPmffRiJ6eFIDlK++f3OklaobTYFJu32E5u/cIrFLbcW52pLqrYpihA/y0/w==", + "dev": true, + "requires": { + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.0.1", + "debug": "^4.3.4", + "execall": "^2.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.2.0", + "ignore": "^5.2.0", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.24.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "normalize-selector": "^0.2.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.12", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^2.2.0", + "svg-tags": "^1.0.0", + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true + }, + "stylelint-config-wikimedia": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/stylelint-config-wikimedia/-/stylelint-config-wikimedia-0.13.1.tgz", + "integrity": "sha512-Wpm+cVJ2eZmlPO8HCv223OZZwyVZh5Ha11dRkzlccZwscxVkoKj/lo6xo10GNWBV9kpEA0+ksYJTIXXmRw1AoA==", + "dev": true, + "requires": { + "browserslist-config-wikimedia": "0.4.0", + "postcss-html": "1.5.0", + "postcss-less": "6.0.0", + "stylelint": "14.8.1", + "stylelint-config-recommended": "7.0.0", + "stylelint-no-unsupported-browser-features": "5.0.3" + } + }, + "stylelint-no-unsupported-browser-features": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/stylelint-no-unsupported-browser-features/-/stylelint-no-unsupported-browser-features-5.0.3.tgz", + "integrity": "sha512-FqfbOTk5UEkHsAKOkPH6SvajsfO9YuoWvKxd34tCRBZug9ZNeaPn141nyWkd+ncc8S1gVmO2+O6qVAMj9bvWww==", + "dev": true, + "requires": { + "doiuse": "^4.4.1", + "lodash": "^4.17.15", + "postcss": "^8.3.6" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "ukkonen": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ukkonen/-/ukkonen-1.4.0.tgz", + "integrity": "sha512-g8SLGxflI0/VNH2C8j66KcfJXrU5StJglRQBYPNiChXFlOrqqYM1icOykOAAUgTeBpktaEuCm9hjpPinQ080PA==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "requires": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + } + } + }, + "unexpected": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/unexpected/-/unexpected-13.0.1.tgz", + "integrity": "sha512-zONsPi275j2rSvsJ9lPoVFNKJ50eJMaX08XMmnC0IXJasFnOXnqD1fZAWGlnK7hG6PeoYDLOiOsBSzbVYaWr9Q==", + "dev": true, + "requires": { + "array-changes": "3.0.1", + "array-changes-async": "3.0.1", + "detect-indent": "3.0.1", + "diff": "^5.0.0", + "greedy-interval-packer": "1.2.0", + "magicpen": "^6.2.4", + "ukkonen": "^1.4.0", + "unexpected-bluebird": "2.9.34-longstack2" + } + }, + "unexpected-bluebird": { + "version": "2.9.34-longstack2", + "resolved": "https://registry.npmjs.org/unexpected-bluebird/-/unexpected-bluebird-2.9.34-longstack2.tgz", + "integrity": "sha1-SaysdTsFVt7WAlIQ7pYYIwfSssk=", + "dev": true + }, + "upath": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", + "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vue-eslint-parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz", + "integrity": "sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^6.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yaml-eslint-parser": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz", + "integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^1.10.2" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/dist/extensions/WikibaseQualityConstraints/package.json b/dist/extensions/WikibaseQualityConstraints/package.json new file mode 100644 index 000000000..467d654da --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/package.json @@ -0,0 +1,28 @@ +{ + "name": "WikibaseQualityConstraints", + "private": true, + "scripts": { + "test": "grunt test" + }, + "devDependencies": { + "eslint-config-wikimedia": "0.22.1", + "eslint-plugin-jasmine": "^4.1.3", + "grunt": "1.5.3", + "grunt-banana-checker": "0.10.0", + "grunt-eslint": "24.0.0", + "grunt-jasmine-nodejs": "^1.6.1", + "grunt-stylelint": "0.18.0", + "jasmine": "^4.3.0", + "module-alias": "^2.1.0", + "sinon": "^14.0.0", + "stylelint-config-wikimedia": "0.13.1", + "unexpected": "^13.0.1" + }, + "_moduleAliases": { + "wikibase.quality.constraints.gadget": "./modules/gadget.js", + "wikibase.quality.constraints.suggestions.EntitySelectorHookHandlerFactory": "./modules/suggestions/EntitySelectorHookHandlerFactory.js" + }, + "browserslist": [ + "ie 11" + ] +} diff --git a/dist/extensions/WikibaseQualityConstraints/phpunit.xml.dist b/dist/extensions/WikibaseQualityConstraints/phpunit.xml.dist new file mode 100644 index 000000000..f67ee0723 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + tests/phpunit + + + + + src + maintenance + + + + + + + diff --git a/dist/extensions/WikibaseQualityConstraints/sql/mysql/tables-generated.sql b/dist/extensions/WikibaseQualityConstraints/sql/mysql/tables-generated.sql new file mode 100644 index 000000000..20134d891 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/mysql/tables-generated.sql @@ -0,0 +1,14 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: extensions/WikibaseQualityConstraints/sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/wbqc_constraints ( + constraint_id INT UNSIGNED AUTO_INCREMENT NOT NULL, + constraint_guid VARBINARY(63) NOT NULL, + pid INT NOT NULL, + constraint_type_qid VARBINARY(25) NOT NULL, + constraint_parameters TEXT DEFAULT NULL, + INDEX wbqc_constraints_pid_index (pid), + UNIQUE INDEX wbqc_constraints_guid_uniq (constraint_guid), + PRIMARY KEY(constraint_id) +) /*$wgDBTableOptions*/; diff --git a/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-constraint_id.sql b/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-constraint_id.sql new file mode 100644 index 000000000..4f701f5af --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-constraint_id.sql @@ -0,0 +1,10 @@ +-- +-- T180834: Add numeric primary key to wbqc_constraints +-- (replacing constraint_guid as primary key) + +ALTER TABLE /*_*/wbqc_constraints + ADD COLUMN constraint_id int unsigned NOT NULL AUTO_INCREMENT FIRST, + DROP PRIMARY KEY, + ADD PRIMARY KEY (constraint_id); + +CREATE INDEX /*i*/wbqc_constraints_guid_index ON /*_*/wbqc_constraints (constraint_guid); diff --git a/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-wbqc_constraints_guid_uniq.sql b/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-wbqc_constraints_guid_uniq.sql new file mode 100644 index 000000000..27825b4f9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/patch-wbqc_constraints-wbqc_constraints_guid_uniq.sql @@ -0,0 +1,9 @@ +-- +-- T180834: Add numeric primary key to wbqc_constraints +-- (replacing constraint_guid as primary key) +-- patch-wbqc_constraints-constraint_id.sql failed to make constraint_guid unique, +-- so this patch replaces the index added there with a unique one. +-- The _uniq suffix is necessary for the updater to distinguish between the two versions of the index. + +DROP INDEX /*i*/wbqc_constraints_guid_index ON /*_*/wbqc_constraints; +CREATE UNIQUE INDEX /*i*/wbqc_constraints_guid_uniq ON /*_*/wbqc_constraints (constraint_guid); diff --git a/dist/extensions/WikibaseQualityConstraints/sql/postgres/tables-generated.sql b/dist/extensions/WikibaseQualityConstraints/sql/postgres/tables-generated.sql new file mode 100644 index 000000000..cbb5eede7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/postgres/tables-generated.sql @@ -0,0 +1,16 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: extensions/WikibaseQualityConstraints/sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE wbqc_constraints ( + constraint_id SERIAL NOT NULL, + constraint_guid TEXT NOT NULL, + pid INT NOT NULL, + constraint_type_qid TEXT NOT NULL, + constraint_parameters TEXT DEFAULT NULL, + PRIMARY KEY(constraint_id) +); + +CREATE INDEX wbqc_constraints_pid_index ON wbqc_constraints (pid); + +CREATE UNIQUE INDEX wbqc_constraints_guid_uniq ON wbqc_constraints (constraint_guid); diff --git a/dist/extensions/WikibaseQualityConstraints/sql/sqlite/tables-generated.sql b/dist/extensions/WikibaseQualityConstraints/sql/sqlite/tables-generated.sql new file mode 100644 index 000000000..e66736869 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/sqlite/tables-generated.sql @@ -0,0 +1,14 @@ +-- This file is automatically generated using maintenance/generateSchemaSql.php. +-- Source: extensions/WikibaseQualityConstraints/sql/tables.json +-- Do not modify this file directly. +-- See https://www.mediawiki.org/wiki/Manual:Schema_changes +CREATE TABLE /*_*/wbqc_constraints ( + constraint_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + constraint_guid BLOB NOT NULL, pid INTEGER NOT NULL, + constraint_type_qid BLOB NOT NULL, + constraint_parameters CLOB DEFAULT NULL +); + +CREATE INDEX wbqc_constraints_pid_index ON /*_*/wbqc_constraints (pid); + +CREATE UNIQUE INDEX wbqc_constraints_guid_uniq ON /*_*/wbqc_constraints (constraint_guid); diff --git a/dist/extensions/WikibaseQualityConstraints/sql/tables.json b/dist/extensions/WikibaseQualityConstraints/sql/tables.json new file mode 100644 index 000000000..9d1c2f018 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/sql/tables.json @@ -0,0 +1,45 @@ +[ + { + "name": "wbqc_constraints", + "columns": [ + { + "name": "constraint_id", + "type": "integer", + "options": { "autoincrement": true, "notnull": true, "unsigned": true } + }, + { + "name": "constraint_guid", + "type": "binary", + "options": { "length": 63, "notnull": true } + }, + { + "name": "pid", + "type": "integer", + "options": { "notnull": true } + }, + { + "name": "constraint_type_qid", + "type": "binary", + "options": { "length": 25, "notnull": true } + }, + { + "name": "constraint_parameters", + "type": "text", + "options": { "default": null, "length": 65535, "notnull": false } + } + ], + "indexes": [ + { + "name": "wbqc_constraints_pid_index", + "columns": [ "pid" ], + "unique": false + }, + { + "name": "wbqc_constraints_guid_uniq", + "columns": [ "constraint_guid" ], + "unique": true + } + ], + "pk": [ "constraint_id" ] + } +] diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CachingResultsSource.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CachingResultsSource.php new file mode 100644 index 000000000..a30c7e76a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CachingResultsSource.php @@ -0,0 +1,493 @@ +resultsSource = $resultsSource; + $this->cache = $cache; + $this->checkResultSerializer = $checkResultSerializer; + $this->checkResultDeserializer = $checkResultDeserializer; + $this->wikiPageEntityMetaDataAccessor = $wikiPageEntityMetaDataAccessor; + $this->entityIdParser = $entityIdParser; + $this->ttlInSeconds = $ttlInSeconds; + $this->possiblyStaleConstraintTypes = $possiblyStaleConstraintTypes; + $this->maxRevisionIds = $maxRevisionIds; + $this->loggingHelper = $loggingHelper; + $this->timeValueComparer = new TimeValueComparer(); + } + + public function getResults( + array $entityIds, + array $claimIds, + ?array $constraintIds, + array $statuses + ) { + $results = []; + $metadatas = []; + if ( $this->canUseStoredResults( $entityIds, $claimIds, $constraintIds, $statuses ) ) { + $storedEntityIds = []; + foreach ( $entityIds as $entityId ) { + $storedResults = $this->getStoredResults( $entityId ); + if ( $storedResults !== null ) { + $this->loggingHelper->logCheckConstraintsCacheHit( $entityId ); + foreach ( $storedResults->getArray() as $checkResult ) { + if ( $this->statusSelected( $statuses, $checkResult ) ) { + $results[] = $checkResult; + } + } + $metadatas[] = $storedResults->getMetadata(); + $storedEntityIds[] = $entityId; + } + } + $entityIds = array_values( array_diff( $entityIds, $storedEntityIds ) ); + } + if ( $entityIds !== [] || $claimIds !== [] ) { + if ( $entityIds !== [] ) { + $this->loggingHelper->logCheckConstraintsCacheMisses( $entityIds ); + } + $response = $this->getAndStoreResults( $entityIds, $claimIds, $constraintIds, $statuses ); + $results = array_merge( $results, $response->getArray() ); + $metadatas[] = $response->getMetadata(); + } + return new CachedCheckResults( + $results, + Metadata::merge( $metadatas ) + ); + } + + /** + * We can only use cached constraint results + * if nothing more than the problematic results of a full constraint check were requested: + * constraint checks for the full entity (not just individual statements), + * without restricting the set of constraints to check, + * and with no statuses other than 'violation', 'warning' and 'bad-parameters'. + * + * @param EntityId[] $entityIds + * @param string[] $claimIds + * @param string[]|null $constraintIds + * @param string[] $statuses + * @return bool + */ + private function canUseStoredResults( + array $entityIds, + array $claimIds, + ?array $constraintIds, + array $statuses + ) { + if ( $claimIds !== [] ) { + return false; + } + if ( $constraintIds !== null ) { + return false; + } + if ( array_diff( $statuses, self::CACHED_STATUSES ) !== [] ) { + return false; + } + return true; + } + + /** + * Check whether a check result should be used, + * either because it has the right status + * or because it is a NullResult whose metadata should be preserved. + * + * @param string[] $statuses + * @param CheckResult $result + * @return bool + */ + private function statusSelected( array $statuses, CheckResult $result ) { + return in_array( $result->getStatus(), $statuses, true ) || + $result instanceof NullResult; + } + + /** + * @param EntityId[] $entityIds + * @param string[] $claimIds + * @param string[]|null $constraintIds + * @param string[] $statuses + * @return CachedCheckResults + */ + public function getAndStoreResults( + array $entityIds, + array $claimIds, + ?array $constraintIds, + array $statuses + ) { + $results = $this->resultsSource->getResults( $entityIds, $claimIds, $constraintIds, $statuses ); + + if ( $this->canStoreResults( $entityIds, $claimIds, $constraintIds, $statuses ) ) { + foreach ( $entityIds as $entityId ) { + $this->storeResults( $entityId, $results ); + } + } + + return $results; + } + + /** + * We can only store constraint results + * if the set of constraints to check was not restricted + * and all the problematic results were requested. + * However, it doesn’t matter whether constraint checks on individual statements were requested: + * we only store results for the mentioned entity IDs, + * and those will be complete regardless of what’s in the statement IDs. + * And it also doesn’t matter whether the set of statuses requested + * was exactly the statuses we cache or a superset of it: + * as long as all the results we want to cache are there, + * we can filter out the extraneous ones before we serialize them. + * + * @param EntityId[] $entityIds + * @param string[] $claimIds + * @param ?string[] $constraintIds + * @param string[] $statuses + * @return bool + */ + private function canStoreResults( + array $entityIds, + array $claimIds, + ?array $constraintIds, + array $statuses + ) { + if ( $constraintIds !== null ) { + return false; + } + if ( array_diff( self::CACHED_STATUSES, $statuses ) !== [] ) { + return false; + } + return true; + } + + /** + * Store check results for the given entity ID in the cache, if possible. + * + * @param EntityId $entityId The entity ID. + * @param CachedCheckResults $results A collection of check results with metadata. + * May include check results for other entity IDs as well, + * or check results with statuses that we’re not interested in caching. + */ + private function storeResults( EntityId $entityId, CachedCheckResults $results ) { + $latestRevisionIds = $this->getLatestRevisionIds( + $results->getMetadata()->getDependencyMetadata()->getEntityIds() + ); + if ( $latestRevisionIds === null ) { + return; + } + + $resultSerializations = []; + foreach ( $results->getArray() as $checkResult ) { + if ( $checkResult->getContextCursor()->getEntityId() !== $entityId->getSerialization() ) { + continue; + } + if ( $this->statusSelected( self::CACHED_STATUSES, $checkResult ) ) { + $resultSerializations[] = $this->checkResultSerializer->serialize( $checkResult ); + } + } + + $value = [ + 'results' => $resultSerializations, + 'latestRevisionIds' => $latestRevisionIds, + ]; + $futureTime = $results->getMetadata()->getDependencyMetadata()->getFutureTime(); + if ( $futureTime !== null ) { + $value['futureTime'] = $futureTime->getArrayValue(); + } + + $this->cache->set( $entityId, $value, $this->ttlInSeconds ); + } + + /** + * @param EntityId $entityId + * @param int $forRevision Requested revision of $entityId + * If this parameter is not zero, the results are returned if this is the latest revision, + * otherwise null is returned, since we can't get constraints for past revisions. + * @return CachedCheckResults|null + */ + public function getStoredResults( + EntityId $entityId, + $forRevision = 0 + ) { + $value = $this->cache->get( $entityId, $curTTL, [], $asOf ); + $now = call_user_func( $this->microtime, true ); + + $dependencyMetadata = $this->checkDependencyMetadata( $value, + [ $entityId->getSerialization() => $forRevision ] ); + if ( $dependencyMetadata === null ) { + return null; + } + + $ageInSeconds = (int)ceil( $now - $asOf ); + $cachingMetadata = $ageInSeconds > 0 ? + CachingMetadata::ofMaximumAgeInSeconds( $ageInSeconds ) : + CachingMetadata::fresh(); + + $results = []; + foreach ( $value['results'] as $resultSerialization ) { + $results[] = $this->deserializeCheckResult( $resultSerialization, $cachingMetadata ); + } + + return new CachedCheckResults( + $results, + Metadata::merge( [ + Metadata::ofCachingMetadata( $cachingMetadata ), + Metadata::ofDependencyMetadata( $dependencyMetadata ), + ] ) + ); + } + + /** + * Extract the dependency metadata of $value + * and check that the dependency metadata does not indicate staleness. + * + * @param array|false $value + * @param int[] $paramRevs Revisions from parameters, id => revision + * These revisions are used instead of ones recorded in the metadata, + * so we can serve requests specifying concrete revisions, and if they are not latest, + * we will reject then. + * @return DependencyMetadata|null the dependency metadata, + * or null if $value should no longer be used + */ + private function checkDependencyMetadata( $value, $paramRevs ) { + if ( $value === false ) { + return null; + } + + if ( array_key_exists( 'futureTime', $value ) ) { + $futureTime = TimeValue::newFromArray( $value['futureTime'] ); + if ( !$this->timeValueComparer->isFutureTime( $futureTime ) ) { + return null; + } + $futureTimeDependencyMetadata = DependencyMetadata::ofFutureTime( $futureTime ); + } else { + $futureTimeDependencyMetadata = DependencyMetadata::blank(); + } + + foreach ( $paramRevs as $id => $revision ) { + if ( $revision > 0 ) { + $value['latestRevisionIds'][$id] = min( $revision, $value['latestRevisionIds'][$id] ?? PHP_INT_MAX ); + } + } + + $dependedEntityIds = array_map( + [ $this->entityIdParser, "parse" ], + array_keys( $value['latestRevisionIds'] ) + ); + + if ( $value['latestRevisionIds'] !== $this->getLatestRevisionIds( $dependedEntityIds ) ) { + return null; + } + + return array_reduce( + $dependedEntityIds, + static function ( DependencyMetadata $metadata, EntityId $entityId ) { + return DependencyMetadata::merge( [ + $metadata, + DependencyMetadata::ofEntityId( $entityId ) + ] ); + }, + $futureTimeDependencyMetadata + ); + } + + /** + * Deserialize a check result. + * If the result might be stale after caching + * (because its dependencies cannot be fully tracked in its dependency metadata), + * also add $cachingMetadata to it. + * + * @param array $resultSerialization + * @param CachingMetadata $cachingMetadata + * @return CheckResult + */ + private function deserializeCheckResult( + array $resultSerialization, + CachingMetadata $cachingMetadata + ) { + $result = $this->checkResultDeserializer->deserialize( $resultSerialization ); + if ( $this->isPossiblyStaleResult( $result ) ) { + $result->withMetadata( + Metadata::merge( [ + $result->getMetadata(), + Metadata::ofCachingMetadata( $cachingMetadata ), + ] ) + ); + } + return $result; + } + + /** + * @param CheckResult $result + * @return bool + */ + private function isPossiblyStaleResult( CheckResult $result ) { + if ( $result instanceof NullResult ) { + return false; + } + + return in_array( + $result->getConstraint()->getConstraintTypeItemId(), + $this->possiblyStaleConstraintTypes + ); + } + + /** + * @param EntityId[] $entityIds + * @return int[]|null array from entity ID serializations to revision ID, + * or null to indicate that not all revision IDs could be loaded + */ + private function getLatestRevisionIds( array $entityIds ) { + if ( $entityIds === [] ) { + $this->loggingHelper->logEmptyDependencyMetadata(); + return []; + } + if ( count( $entityIds ) > $this->maxRevisionIds ) { + // one of those entities will probably be edited soon, so might as well skip caching + $this->loggingHelper->logHugeDependencyMetadata( $entityIds, $this->maxRevisionIds ); + return null; + } + + $latestRevisionIds = $this->wikiPageEntityMetaDataAccessor->loadLatestRevisionIds( + $entityIds, + LookupConstants::LATEST_FROM_REPLICA + ); + if ( $this->hasFalseElements( $latestRevisionIds ) ) { + return null; + } + return $latestRevisionIds; + } + + /** + * @param array $array + * @return bool + */ + private function hasFalseElements( array $array ) { + return in_array( false, $array, true ); + } + + /** + * Set a custom function to get the current time, instead of microtime(). + * + * @param callable $microtime + */ + public function setMicrotimeFunction( callable $microtime ) { + $this->microtime = $microtime; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintParameters.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintParameters.php new file mode 100644 index 000000000..55802f7d8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintParameters.php @@ -0,0 +1,331 @@ +apiErrorReporter = $apiHelperFactory->getErrorReporter( $this ); + $this->delegatingConstraintChecker = $delegatingConstraintChecker; + $this->violationMessageRendererFactory = $violationMessageRendererFactory; + $this->statementGuidParser = $statementGuidParser; + $this->dataFactory = $dataFactory; + } + + public function execute() { + $this->dataFactory->increment( + 'wikibase.quality.constraints.api.checkConstraintParameters.execute' + ); + + $params = $this->extractRequestParams(); + $result = $this->getResult(); + + $propertyIds = $this->parsePropertyIds( $params[self::PARAM_PROPERTY_ID] ); + $constraintIds = $this->parseConstraintIds( $params[self::PARAM_CONSTRAINT_ID] ); + + $this->checkPropertyIds( $propertyIds, $result ); + $this->checkConstraintIds( $constraintIds, $result ); + + $result->addValue( null, 'success', 1 ); + } + + /** + * @param array|null $propertyIdSerializations + * @return NumericPropertyId[] + */ + private function parsePropertyIds( $propertyIdSerializations ) { + if ( $propertyIdSerializations === null ) { + return []; + } elseif ( empty( $propertyIdSerializations ) ) { + $this->apiErrorReporter->dieError( + 'If ' . self::PARAM_PROPERTY_ID . ' is specified, it must be nonempty.', + 'no-data' + ); + } + + return array_map( + function ( $propertyIdSerialization ) { + try { + return new NumericPropertyId( $propertyIdSerialization ); + } catch ( InvalidArgumentException $e ) { + $this->apiErrorReporter->dieError( + "Invalid id: $propertyIdSerialization", + 'invalid-property-id', + 0, // default argument + [ self::PARAM_PROPERTY_ID => $propertyIdSerialization ] + ); + } + }, + $propertyIdSerializations + ); + } + + /** + * @param array|null $constraintIds + * @return string[] + */ + private function parseConstraintIds( $constraintIds ) { + if ( $constraintIds === null ) { + return []; + } elseif ( empty( $constraintIds ) ) { + $this->apiErrorReporter->dieError( + 'If ' . self::PARAM_CONSTRAINT_ID . ' is specified, it must be nonempty.', + 'no-data' + ); + } + + return array_map( + function ( $constraintId ) { + try { + $propertyId = $this->statementGuidParser->parse( $constraintId )->getEntityId(); + if ( !$propertyId instanceof NumericPropertyId ) { + $this->apiErrorReporter->dieError( + "Invalid property ID: {$propertyId->getSerialization()}", + 'invalid-property-id', + 0, // default argument + [ self::PARAM_CONSTRAINT_ID => $constraintId ] + ); + } + return $constraintId; + } catch ( StatementGuidParsingException $e ) { + $this->apiErrorReporter->dieError( + "Invalid statement GUID: $constraintId", + 'invalid-guid', + 0, // default argument + [ self::PARAM_CONSTRAINT_ID => $constraintId ] + ); + } + }, + $constraintIds + ); + } + + /** + * @param NumericPropertyId[] $propertyIds + * @param ApiResult $result + */ + private function checkPropertyIds( array $propertyIds, ApiResult $result ) { + foreach ( $propertyIds as $propertyId ) { + $result->addArrayType( $this->getResultPathForPropertyId( $propertyId ), 'assoc' ); + $allConstraintExceptions = $this->delegatingConstraintChecker + ->checkConstraintParametersOnPropertyId( $propertyId ); + foreach ( $allConstraintExceptions as $constraintId => $constraintParameterExceptions ) { + $this->addConstraintParameterExceptionsToResult( + $constraintId, + $constraintParameterExceptions, + $result + ); + } + } + } + + /** + * @param string[] $constraintIds + * @param ApiResult $result + */ + private function checkConstraintIds( array $constraintIds, ApiResult $result ) { + foreach ( $constraintIds as $constraintId ) { + if ( $result->getResultData( $this->getResultPathForConstraintId( $constraintId ) ) ) { + // already checked as part of checkPropertyIds() + continue; + } + $constraintParameterExceptions = $this->delegatingConstraintChecker + ->checkConstraintParametersOnConstraintId( $constraintId ); + $this->addConstraintParameterExceptionsToResult( $constraintId, $constraintParameterExceptions, $result ); + } + } + + /** + * @param NumericPropertyId $propertyId + * @return string[] + */ + private function getResultPathForPropertyId( NumericPropertyId $propertyId ) { + return [ $this->getModuleName(), $propertyId->getSerialization() ]; + } + + /** + * @param string $constraintId + * @return string[] + */ + private function getResultPathForConstraintId( $constraintId ) { + $propertyId = $this->statementGuidParser->parse( $constraintId )->getEntityId(); + '@phan-var NumericPropertyId $propertyId'; + return array_merge( $this->getResultPathForPropertyId( $propertyId ), [ $constraintId ] ); + } + + /** + * Add the ConstraintParameterExceptions for $constraintId to the API result. + * + * @param string $constraintId + * @param ConstraintParameterException[]|null $constraintParameterExceptions + * @param ApiResult $result + */ + private function addConstraintParameterExceptionsToResult( + $constraintId, + $constraintParameterExceptions, + ApiResult $result + ) { + $path = $this->getResultPathForConstraintId( $constraintId ); + if ( $constraintParameterExceptions === null ) { + $result->addValue( + $path, + self::KEY_STATUS, + self::STATUS_NOT_FOUND + ); + } else { + $result->addValue( + $path, + self::KEY_STATUS, + empty( $constraintParameterExceptions ) ? self::STATUS_OKAY : self::STATUS_NOT_OKAY + ); + + $violationMessageRenderer = $this->violationMessageRendererFactory + ->getViolationMessageRenderer( $this->getLanguage() ); + $problems = []; + foreach ( $constraintParameterExceptions as $constraintParameterException ) { + $problems[] = [ + self::KEY_MESSAGE_HTML => $violationMessageRenderer->render( + $constraintParameterException->getViolationMessage() ), + ]; + } + $result->addValue( + $path, + self::KEY_PROBLEMS, + $problems + ); + } + } + + /** + * @return array[] + * @codeCoverageIgnore + */ + public function getAllowedParams() { + return [ + self::PARAM_PROPERTY_ID => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_ISMULTI => true + ], + self::PARAM_CONSTRAINT_ID => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_ISMULTI => true + ] + ]; + } + + /** + * @return string[] + * @codeCoverageIgnore + */ + public function getExamplesMessages() { + return [ + 'action=wbcheckconstraintparameters&propertyid=P247' + => 'apihelp-wbcheckconstraintparameters-example-propertyid-1', + 'action=wbcheckconstraintparameters&' . + 'constraintid=P247$0fe1711e-4c0f-82ce-3af0-830b721d0fba|' . + 'P225$cdc71e4a-47a0-12c5-dfb3-3f6fc0b6613f' + => 'apihelp-wbcheckconstraintparameters-example-constraintid-2', + ]; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraints.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraints.php new file mode 100644 index 000000000..696091d6b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraints.php @@ -0,0 +1,286 @@ +entityIdParser = $entityIdParser; + $this->statementGuidValidator = $statementGuidValidator; + $this->resultBuilder = $apiHelperFactory->getResultBuilder( $this ); + $this->errorReporter = $apiHelperFactory->getErrorReporter( $this ); + $this->resultsSource = $resultsSource; + $this->checkResultsRendererFactory = $checkResultsRendererFactory; + $this->dataFactory = $dataFactory; + } + + /** + * Evaluates the parameters, runs the requested constraint check, and sets up the result + */ + public function execute() { + $this->dataFactory->increment( + 'wikibase.quality.constraints.api.checkConstraints.execute' + ); + + $params = $this->extractRequestParams(); + + $this->validateParameters( $params ); + $entityIds = $this->parseEntityIds( $params ); + $claimIds = $this->parseClaimIds( $params ); + $constraintIDs = $params[self::PARAM_CONSTRAINT_ID]; + $statuses = $params[self::PARAM_STATUS]; + + $checkResultsRenderer = $this->checkResultsRendererFactory + ->getCheckResultsRenderer( $this->getLanguage() ); + + $this->getResult()->addValue( + null, + $this->getModuleName(), + $checkResultsRenderer->render( + $this->resultsSource->getResults( + $entityIds, + $claimIds, + $constraintIDs, + $statuses + ) + )->getArray() + ); + $this->resultBuilder->markSuccess( 1 ); + } + + /** + * @param array $params + * + * @return EntityId[] + */ + private function parseEntityIds( array $params ) { + $ids = $params[self::PARAM_ID]; + + if ( $ids === null ) { + return []; + } elseif ( $ids === [] ) { + $this->errorReporter->dieError( + 'If ' . self::PARAM_ID . ' is specified, it must be nonempty.', 'no-data' ); + } + + return array_map( function ( $id ) { + try { + return $this->entityIdParser->parse( $id ); + } catch ( EntityIdParsingException $e ) { + $this->errorReporter->dieError( + "Invalid id: $id", 'invalid-entity-id', 0, [ self::PARAM_ID => $id ] ); + } + }, $ids ); + } + + /** + * @param array $params + * + * @return string[] + */ + private function parseClaimIds( array $params ) { + $ids = $params[self::PARAM_CLAIM_ID]; + + if ( $ids === null ) { + return []; + } elseif ( $ids === [] ) { + $this->errorReporter->dieError( + 'If ' . self::PARAM_CLAIM_ID . ' is specified, it must be nonempty.', 'no-data' ); + } + + foreach ( $ids as $id ) { + if ( !$this->statementGuidValidator->validate( $id ) ) { + $this->errorReporter->dieError( + "Invalid claim id: $id", 'invalid-guid', 0, [ self::PARAM_CLAIM_ID => $id ] ); + } + } + + return $ids; + } + + private function validateParameters( array $params ) { + if ( $params[self::PARAM_CONSTRAINT_ID] !== null + && empty( $params[self::PARAM_CONSTRAINT_ID] ) + ) { + $paramConstraintId = self::PARAM_CONSTRAINT_ID; + $this->errorReporter->dieError( + "If $paramConstraintId is specified, it must be nonempty.", 'no-data' ); + } + if ( $params[self::PARAM_ID] === null && $params[self::PARAM_CLAIM_ID] === null ) { + $paramId = self::PARAM_ID; + $paramClaimId = self::PARAM_CLAIM_ID; + $this->errorReporter->dieError( + "At least one of $paramId, $paramClaimId must be specified.", 'no-data' ); + } + // contents of PARAM_ID and PARAM_CLAIM_ID are validated by parse{Entity,Claim}Ids() + } + + /** + * @return array[] + * @codeCoverageIgnore + */ + public function getAllowedParams() { + return [ + self::PARAM_ID => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_ISMULTI => true, + ], + self::PARAM_CLAIM_ID => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_ISMULTI => true, + ], + self::PARAM_CONSTRAINT_ID => [ + ParamValidator::PARAM_TYPE => 'string', + ParamValidator::PARAM_ISMULTI => true, + ], + self::PARAM_STATUS => [ + ParamValidator::PARAM_TYPE => [ + CheckResult::STATUS_COMPLIANCE, + CheckResult::STATUS_VIOLATION, + CheckResult::STATUS_WARNING, + CheckResult::STATUS_SUGGESTION, + CheckResult::STATUS_EXCEPTION, + CheckResult::STATUS_NOT_IN_SCOPE, + CheckResult::STATUS_DEPRECATED, + CheckResult::STATUS_BAD_PARAMETERS, + CheckResult::STATUS_TODO, + ], + ParamValidator::PARAM_ISMULTI => true, + ParamValidator::PARAM_ALL => true, + ParamValidator::PARAM_DEFAULT => implode( '|', CachingResultsSource::CACHED_STATUSES ), + ApiBase::PARAM_HELP_MSG_PER_VALUE => [], + ], + ]; + } + + /** + * Returns usage examples for this module + * + * @return string[] + * @codeCoverageIgnore + */ + public function getExamplesMessages() { + return [ + 'action=wbcheckconstraints&id=Q5|Q42' + => 'apihelp-wbcheckconstraints-example-1', + 'action=wbcheckconstraints&claimid=q42%248419C20C-8EF8-4EC0-80D6-AF1CA55E7557' + => 'apihelp-wbcheckconstraints-example-2', + 'action=wbcheckconstraints&format=json&id=Q2&constraintid=P1082%24DA39C2DA-47DA-48FB-8A9A-DA80200FB2DB' + => 'apihelp-wbcheckconstraints-example-3', + ]; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintsRdf.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintsRdf.php new file mode 100644 index 000000000..a4307df78 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckConstraintsRdf.php @@ -0,0 +1,181 @@ +resultsSource = $resultsSource; + $this->entityIdLookup = $entityIdLookup; + $this->rdfVocabulary = $rdfVocabulary; + } + + /** + * @param Article $page + * @param IContextSource $context + * @return CheckConstraintsRdf + */ + public static function newFromGlobalState( + object $page, + IContextSource $context + ) { + return new static( + $page, + $context, + ConstraintsServices::getResultsSource(), + WikibaseRepo::getEntityIdLookup(), + WikibaseRepo::getRdfVocabulary() + ); + } + + /** + * Return the name of the action this object responds to + * @since 1.17 + * + * @return string Lowercase name + */ + public function getName() { + return 'constraintsrdf'; + } + + /** + * Whether this action requires the wiki not to be locked + * @since 1.17 + * + * @return bool + */ + public function requiresWrite() { + return false; + } + + /** + * @see Action::requiresUnblock + * + * @return bool Always false. + */ + public function requiresUnblock() { + return false; + } + + /** + * Cleanup GUID string so it's OK for RDF. + * Should match what we're doing on RDF generation. + * @param string $guid + * @return string + */ + private function cleanupGuid( $guid ) { + return preg_replace( '/[^\w-]/', '-', $guid ); + } + + /** + * Show something on GET request. + * @return string|null Will be added to the HTMLForm if present, or just added to the + * output if not. Return null to not add anything + */ + public function onView() { + $response = $this->getRequest()->response(); + $this->getOutput()->disable(); + + if ( !$this->resultsSource instanceof CachingResultsSource ) { + // TODO: make configurable whether only cached results are returned + $response->statusHeader( 501 ); // Not Implemented + return null; + } + + $entityId = $this->entityIdLookup->getEntityIdForTitle( $this->getTitle() ); + if ( $entityId === null ) { + $response->statusHeader( 404 ); // Not Found + return null; + } + $revId = $this->getRequest()->getInt( 'revision' ); + + $results = $this->resultsSource->getStoredResults( $entityId, $revId ); + if ( $results === null ) { + $response->statusHeader( 204 ); // No Content + return null; + } + + $format = 'ttl'; // TODO: make format an option + + $writerFactory = new RdfWriterFactory(); + $formatName = $writerFactory->getFormatName( $format ); + $contentType = $writerFactory->getMimeTypes( $formatName )[0]; + + $writer = $writerFactory->getWriter( $formatName ); + foreach ( [ RdfVocabulary::NS_STATEMENT, RdfVocabulary::NS_ONTOLOGY ] as $ns ) { + $writer->prefix( $ns, $this->rdfVocabulary->getNamespaceURI( $ns ) ); + } + $writer->start(); + $writtenAny = false; + + foreach ( $results->getArray() as $checkResult ) { + if ( $checkResult instanceof NullResult ) { + continue; + } + if ( $checkResult->getStatus() === CheckResult::STATUS_BAD_PARAMETERS ) { + continue; + } + $writtenAny = true; + $writer->about( RdfVocabulary::NS_STATEMENT, + $this->cleanupGuid( $checkResult->getContextCursor()->getStatementGuid() ) ) + ->say( RdfVocabulary::NS_ONTOLOGY, 'hasViolationForConstraint' ) + ->is( RdfVocabulary::NS_STATEMENT, + $this->cleanupGuid( $checkResult->getConstraint()->getConstraintId() ) ); + } + $writer->finish(); + if ( $writtenAny ) { + $response->header( "Content-Type: $contentType; charset=UTF-8" ); + echo $writer->drain(); + } else { + // Do not output RDF if we haven't written any actual statements. Output 204 instead + $writer->drain(); + $response->statusHeader( 204 ); // No Content + } + return null; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRenderer.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRenderer.php new file mode 100644 index 000000000..6428075ea --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRenderer.php @@ -0,0 +1,107 @@ +entityTitleLookup = $entityTitleLookup; + $this->entityIdLabelFormatter = $entityIdLabelFormatter; + $this->violationMessageRenderer = $violationMessageRenderer; + } + + /** + * @param CachedCheckResults $checkResults + * @return CachedCheckConstraintsResponse + */ + public function render( CachedCheckResults $checkResults ) { + $response = []; + foreach ( $checkResults->getArray() as $checkResult ) { + $resultArray = $this->checkResultToArray( $checkResult ); + $checkResult->getContextCursor()->storeCheckResultInArray( $resultArray, $response ); + } + return new CachedCheckConstraintsResponse( + $response, + $checkResults->getMetadata() + ); + } + + public function checkResultToArray( CheckResult $checkResult ) { + if ( $checkResult instanceof NullResult ) { + return null; + } + + $constraintId = $checkResult->getConstraint()->getConstraintId(); + $typeItemId = $checkResult->getConstraint()->getConstraintTypeItemId(); + $constraintPropertyId = new NumericPropertyId( $checkResult->getContextCursor()->getSnakPropertyId() ); + + $title = $this->entityTitleLookup->getTitleForId( $constraintPropertyId ); + $talkTitle = $title->getTalkPageIfDefined(); + $typeLabel = $this->entityIdLabelFormatter->formatEntityId( new ItemId( $typeItemId ) ); + $link = $title->getFullURL() . '#' . $constraintId; + + $constraint = [ + 'id' => $constraintId, + 'type' => $typeItemId, + 'typeLabel' => $typeLabel, + 'link' => $link, + 'discussLink' => $talkTitle ? $talkTitle->getFullURL() : $title->getFullURL(), + ]; + + $result = [ + 'status' => $checkResult->getStatus(), + 'property' => $constraintPropertyId->getSerialization(), + 'constraint' => $constraint + ]; + $message = $checkResult->getMessage(); + if ( $message ) { + $result['message-html'] = $this->violationMessageRenderer->render( $message ); + } + if ( $checkResult->getContextCursor()->getType() === Context::TYPE_STATEMENT ) { + $result['claim'] = $checkResult->getContextCursor()->getStatementGuid(); + } + $cachingMetadataArray = $checkResult->getMetadata()->getCachingMetadata()->toArray(); + if ( $cachingMetadataArray !== null ) { + $result['cached'] = $cachingMetadataArray; + } + + return $result; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRendererFactory.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRendererFactory.php new file mode 100644 index 000000000..7bc6e8a44 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckResultsRendererFactory.php @@ -0,0 +1,46 @@ +entityTitleLookup = $entityTitleLookup; + $this->entityIdLabelFormatterFactory = $entityIdLabelFormatterFactory; + $this->violationMessageRendererFactory = $violationMessageRendererFactory; + } + + public function getCheckResultsRenderer( Language $language ): CheckResultsRenderer { + return new CheckResultsRenderer( + $this->entityTitleLookup, + $this->entityIdLabelFormatterFactory + ->getEntityIdFormatter( $language ), + $this->violationMessageRendererFactory + ->getViolationMessageRenderer( $language ) + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/CheckingResultsSource.php b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckingResultsSource.php new file mode 100644 index 000000000..211a4bf55 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/CheckingResultsSource.php @@ -0,0 +1,101 @@ +delegatingConstraintChecker = $delegatingConstraintChecker; + } + + /** + * @param EntityId[] $entityIds + * @param string[] $claimIds + * @param ?string[] $constraintIds + * @param string[] $statuses + * @return CachedCheckResults + */ + public function getResults( + array $entityIds, + array $claimIds, + ?array $constraintIds, + array $statuses + ) { + $results = []; + $metadatas = []; + $statusesFlipped = array_flip( $statuses ); + foreach ( $entityIds as $entityId ) { + $entityResults = $this->delegatingConstraintChecker->checkAgainstConstraintsOnEntityId( + $entityId, + $constraintIds, + [ $this, 'defaultResultsPerContext' ], + [ $this, 'defaultResultsPerEntity' ] + ); + foreach ( $entityResults as $result ) { + $metadatas[] = $result->getMetadata(); + if ( $this->statusSelected( $statusesFlipped, $result ) ) { + $results[] = $result; + } + } + } + foreach ( $claimIds as $claimId ) { + $claimResults = $this->delegatingConstraintChecker->checkAgainstConstraintsOnClaimId( + $claimId, + $constraintIds, + [ $this, 'defaultResultsPerContext' ] + ); + foreach ( $claimResults as $result ) { + $metadatas[] = $result->getMetadata(); + if ( $this->statusSelected( $statusesFlipped, $result ) ) { + $results[] = $result; + } + } + } + return new CachedCheckResults( + $results, + Metadata::merge( $metadatas ) + ); + } + + public function defaultResultsPerContext( Context $context ) { + return $context->getType() === Context::TYPE_STATEMENT ? + [ new NullResult( $context->getCursor() ) ] : + []; + } + + public function defaultResultsPerEntity( EntityId $entityId ) { + return [ + ( new NullResult( new EntityContextCursor( $entityId->getSerialization() ) ) ) + ->withMetadata( Metadata::ofDependencyMetadata( + DependencyMetadata::ofEntityId( $entityId ) + ) ) + ]; + } + + public function statusSelected( array $statusesFlipped, CheckResult $result ) { + return array_key_exists( $result->getStatus(), $statusesFlipped ) || + $result instanceof NullResult; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/ExpiryLock.php b/dist/extensions/WikibaseQualityConstraints/src/Api/ExpiryLock.php new file mode 100644 index 000000000..f98d7a094 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/ExpiryLock.php @@ -0,0 +1,115 @@ +cache = $cache; + } + + /** + * @param string $id of the lock + * + * @return string cache key + * + * @throws \Wikimedia\Assert\ParameterTypeException + */ + private function makeKey( $id ) { + if ( empty( trim( $id ) ) ) { + throw new ParameterTypeException( '$id', 'non-empty string' ); + } + + Assert::parameterType( 'string', $id, '$id' ); + + return $this->cache->makeKey( + 'WikibaseQualityConstraints', + 'ExpiryLock', + (string)$id + ); + } + + /** + * @param string $id of the lock + * @param ConvertibleTimestamp $expiryTimestamp + * + * @return boolean success + * + * @throws \Wikimedia\Assert\ParameterTypeException + */ + public function lock( $id, ConvertibleTimestamp $expiryTimestamp ) { + + $cacheId = $this->makeKey( $id ); + + if ( !$this->isLockedInternal( $cacheId ) ) { + return $this->cache->set( + $cacheId, + $expiryTimestamp->getTimestamp( TS_UNIX ), + (int)$expiryTimestamp->getTimestamp( TS_UNIX ) + ); + } else { + return false; + } + } + + /** + * @param string $cacheId the converted cache id + * + * @return boolean representing if the Lock is Locked + * + * @throws \Wikimedia\Assert\ParameterTypeException + */ + private function isLockedInternal( $cacheId ) { + $expiryTime = $this->cache->get( $cacheId ); + if ( !$expiryTime ) { + return false; + } + + try { + $lockExpiryTimeStamp = new ConvertibleTimestamp( $expiryTime ); + } catch ( TimestampException $exception ) { + return false; + } + + $now = new ConvertibleTimestamp(); + if ( $now->timestamp < $lockExpiryTimeStamp->timestamp ) { + return true; + } else { + return false; + } + } + + /** + * @param string $id of the lock + * + * @return boolean representing if the Lock is Locked + * + * @throws \Wikimedia\Assert\ParameterTypeException + */ + public function isLocked( $id ) { + return $this->isLockedInternal( $this->makeKey( $id ) ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsCache.php b/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsCache.php new file mode 100644 index 000000000..6c88ce8bc --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsCache.php @@ -0,0 +1,87 @@ +getMainWANObjectCache(), + 'v2.2' // .1: T188384; .2: T189593 + ); + } + + /** + * @param WANObjectCache $cache + * @param string $formatVersion The version of the API response format. + */ + public function __construct( WANObjectCache $cache, $formatVersion ) { + $this->cache = $cache; + $this->formatVersion = $formatVersion; + } + + /** + * @param EntityId $entityId + * @return string cache key + */ + public function makeKey( EntityId $entityId ) { + return $this->cache->makeKey( + 'WikibaseQualityConstraints', // extension + 'checkConstraints', // action + $this->formatVersion, // API response format version + $entityId->getSerialization() + ); + } + + /** + * @param EntityId $key + * @param mixed &$curTTL + * @param string[] $checkKeys + * @param mixed|null &$info + * @return mixed + */ + public function get( EntityId $key, &$curTTL = null, array $checkKeys = [], &$info = null ) { + return $this->cache->get( $this->makeKey( $key ), $curTTL, $checkKeys, $info ); + } + + /** + * @param EntityId $key + * @param mixed $value + * @param int $ttl + * @param array $opts + * @return bool + */ + public function set( EntityId $key, $value, $ttl = 0, array $opts = [] ) { + return $this->cache->set( $this->makeKey( $key ), $value, $ttl, $opts ); + } + + /** + * @param EntityId $key + * @return bool + */ + public function delete( EntityId $key ) { + return $this->cache->delete( $this->makeKey( $key ) ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsSource.php b/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsSource.php new file mode 100644 index 000000000..182d4e21a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Api/ResultsSource.php @@ -0,0 +1,30 @@ +lookup = $lookup; + } + + /** + * @param NumericPropertyId $propertyId + * + * @return Constraint[] + */ + public function queryConstraintsForProperty( NumericPropertyId $propertyId ) { + $id = $propertyId->getSerialization(); + if ( !array_key_exists( $id, $this->cache ) ) { + $this->cache[$id] = $this->lookup->queryConstraintsForProperty( $propertyId ); + } + return $this->cache[$id]; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Constraint.php b/dist/extensions/WikibaseQualityConstraints/src/Constraint.php new file mode 100644 index 000000000..e5e809b71 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Constraint.php @@ -0,0 +1,86 @@ +constraintId = $constraintId; + $this->propertyId = $propertyId; + $this->constraintTypeItemId = $constraintTypeItemId; + $this->constraintParameters = $constraintParameters; + } + + /** + * @return string + */ + public function getConstraintId() { + return $this->constraintId; + } + + /** + * @return string + * + * Item ID serialization of the constraint type item. + */ + public function getConstraintTypeItemId() { + return $this->constraintTypeItemId; + } + + /** + * @return NumericPropertyId + */ + public function getPropertyId() { + return $this->propertyId; + } + + /** + * The constraint parameters, imported from the qualifiers of the constraint statement. + * Contains lists of snak array serializations, indexed by property ID serialization. + * (The import is done by {@link UpdateConstraintsTableJob}.) + * + * @return array + */ + public function getConstraintParameters() { + return $this->constraintParameters; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedArray.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedArray.php new file mode 100644 index 000000000..80880cad4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedArray.php @@ -0,0 +1,42 @@ +array = $array; + $this->metadata = $metadata; + } + + /** + * @return array + */ + public function getArray() { + return $this->array; + } + + /** + * @return Metadata + */ + public function getMetadata() { + return $this->metadata; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedBool.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedBool.php new file mode 100644 index 000000000..4b22cffd4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedBool.php @@ -0,0 +1,46 @@ +bool = $bool; + $this->metadata = $metadata; + } + + /** + * @return bool + */ + public function getBool() { + return $this->bool; + } + + /** + * @return Metadata + */ + public function getMetadata() { + return $this->metadata; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedCheckConstraintsResponse.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedCheckConstraintsResponse.php new file mode 100644 index 000000000..cfdd7aa68 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/CachedCheckConstraintsResponse.php @@ -0,0 +1,22 @@ + 0, '$maxAge', '$maxage > 0' ); + $ret = new self; + $ret->maxAge = $maxAge; + return $ret; + } + + /** + * Deserializes the metadata from an array (or null if the value is fresh). + * @param array|null $array As returned by toArray. + * @return self + */ + public static function ofArray( array $array = null ) { + $ret = new self; + if ( $array !== null ) { + $ret->maxAge = $array['maximumAgeInSeconds']; + } + return $ret; + } + + /** + * @param self[] $metadatas + * @return self + */ + public static function merge( array $metadatas ) { + Assert::parameterElementType( self::class, $metadatas, '$metadatas' ); + $ret = new self; + foreach ( $metadatas as $metadata ) { + $ret->maxAge = max( $ret->maxAge, $metadata->maxAge ); + } + return $ret; + } + + /** + * @return bool Whether the value is cached or not (fresh). + */ + public function isCached() { + return $this->maxAge !== false; + } + + /** + * @return int The maximum age of the cached value (in seconds), in other words: + * the value might be outdated by up to this many seconds. + * For a fresh value, returns 0. + */ + public function getMaximumAgeInSeconds() { + if ( is_int( $this->maxAge ) ) { + return $this->maxAge; + } else { + return 0; + } + } + + /** + * Serializes the metadata into an array (or null if the value is fresh). + * @return array|null + */ + public function toArray() { + return $this->isCached() ? + [ + 'maximumAgeInSeconds' => $this->maxAge, + ] : + null; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/DependencyMetadata.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/DependencyMetadata.php new file mode 100644 index 000000000..670d8bec1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/DependencyMetadata.php @@ -0,0 +1,107 @@ +entityIds[] = $entityId; + return $ret; + } + + /** + * Track that a value depends on a certain time value being a future date, not a past one. + * @param TimeValue $timeValue A point in time on which the value might start to become invalid. + * @return self Indication that a value will only remain valid + * as long as the given time value is in the future, not in the past. + */ + public static function ofFutureTime( TimeValue $timeValue ) { + $ret = new self; + $ret->timeValue = $timeValue; + return $ret; + } + + /** + * @param self[] $metadatas + * @return self + */ + public static function merge( array $metadatas ) { + Assert::parameterElementType( self::class, $metadatas, '$metadatas' ); + $ret = new self; + $entityIds = []; + foreach ( $metadatas as $metadata ) { + foreach ( $metadata->entityIds as $entityId ) { + $entityIds[$entityId->getSerialization()] = $entityId; + } + $ret->timeValue = self::minTimeValue( $ret->timeValue, $metadata->timeValue ); + } + $ret->entityIds = array_values( $entityIds ); + return $ret; + } + + /** + * @param TimeValue|null $t1 + * @param TimeValue|null $t2 + * @return TimeValue|null + */ + private static function minTimeValue( TimeValue $t1 = null, TimeValue $t2 = null ) { + if ( $t1 === null ) { + return $t2; + } + if ( $t2 === null ) { + return $t1; + } + return ( new TimeValueComparer() )->getMinimum( $t1, $t2 ); + } + + /** + * @return EntityId[] Entity IDs from whose entities the value was derived. + * Changes to those entity IDs should invalidate the value. + */ + public function getEntityIds() { + return $this->entityIds; + } + + /** + * @return TimeValue|null A point in time which was in the future when the value was first determined. + * The value should be invalidated once this point in time is no longer in the future. + */ + public function getFutureTime() { + return $this->timeValue; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/Metadata.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/Metadata.php new file mode 100644 index 000000000..d0d4b3de7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Cache/Metadata.php @@ -0,0 +1,81 @@ +cachingMetadata = CachingMetadata::fresh(); + $ret->dependencyMetadata = DependencyMetadata::blank(); + return $ret; + } + + public static function ofCachingMetadata( CachingMetadata $cachingMetadata ) { + $ret = new self; + $ret->cachingMetadata = $cachingMetadata; + $ret->dependencyMetadata = DependencyMetadata::blank(); + return $ret; + } + + public static function ofDependencyMetadata( DependencyMetadata $dependencyMetadata ) { + $ret = new self; + $ret->cachingMetadata = CachingMetadata::fresh(); + $ret->dependencyMetadata = $dependencyMetadata; + return $ret; + } + + /** + * @param self[] $metadatas + * @return self + */ + public static function merge( array $metadatas ) { + Assert::parameterElementType( self::class, $metadatas, '$metadatas' ); + $cachingMetadatas = []; + $dependencyMetadatas = []; + foreach ( $metadatas as $metadata ) { + $cachingMetadatas[] = $metadata->cachingMetadata; + $dependencyMetadatas[] = $metadata->dependencyMetadata; + } + $ret = new self; + $ret->cachingMetadata = CachingMetadata::merge( $cachingMetadatas ); + $ret->dependencyMetadata = DependencyMetadata::merge( $dependencyMetadatas ); + return $ret; + } + + /** + * @return CachingMetadata + */ + public function getCachingMetadata() { + return $this->cachingMetadata; + } + + /** + * @return DependencyMetadata + */ + public function getDependencyMetadata() { + return $this->dependencyMetadata; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/AllowedUnitsChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/AllowedUnitsChecker.php new file mode 100644 index 000000000..2eeb8e57f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/AllowedUnitsChecker.php @@ -0,0 +1,191 @@ +constraintParameterParser = $constraintParameterParser; + $this->unitConverter = $unitConverter; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks an “allowed units” constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $unitsParameter = $this->constraintParameterParser + ->parseUnitsParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId() + ); + + $snak = $context->getSnak(); + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + if ( !$dataValue instanceof UnboundedQuantityValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraint->getConstraintTypeItemId() ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'quantity' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + if ( $dataValue->getUnit() === '1' ) { + return $this->checkUnitless( $context, $constraint, $unitsParameter, $snak ); + } + + $status = CheckResult::STATUS_VIOLATION; + $actualUnit = $this->standardize( $dataValue )->getUnit(); + foreach ( $unitsParameter->getUnitQuantities() as $unitQuantity ) { + $allowedUnit = $this->standardize( $unitQuantity )->getUnit(); + if ( $actualUnit === $allowedUnit ) { + $status = CheckResult::STATUS_COMPLIANCE; + break; + } + } + + if ( $status === CheckResult::STATUS_VIOLATION ) { + if ( $unitsParameter->getUnitItemIds() === [] ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-units-none' ) ) + ->withEntityId( $snak->getPropertyId(), Role::CONSTRAINT_PROPERTY ); + } else { + $messageKey = $unitsParameter->getUnitlessAllowed() ? + 'wbqc-violation-message-units-or-none' : + 'wbqc-violation-message-units'; + $message = ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $snak->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityIdList( $unitsParameter->getUnitItemIds(), Role::CONSTRAINT_PARAMETER_VALUE ); + } + } else { + $message = null; + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + /** + * @param Context $context + * @param Constraint $constraint + * @param UnitsParameter $unitsParameter + * @param PropertyValueSnak $snak + * @return CheckResult + */ + private function checkUnitless( + Context $context, + Constraint $constraint, + UnitsParameter $unitsParameter, + PropertyValueSnak $snak + ) { + if ( $unitsParameter->getUnitlessAllowed() ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } else { + $message = ( new ViolationMessage( 'wbqc-violation-message-units' ) ) + ->withEntityId( $snak->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityIdList( $unitsParameter->getUnitItemIds(), Role::CONSTRAINT_PARAMETER_VALUE ); + $status = CheckResult::STATUS_VIOLATION; + } + + return new CheckResult( $context, $constraint, [], $status, $message ); + } + + /** + * Convert $value to standard units. + * + * @param UnboundedQuantityValue $value + * @return UnboundedQuantityValue + */ + private function standardize( UnboundedQuantityValue $value ) { + if ( $this->unitConverter === null ) { + return $value; + } + + $standard = $this->unitConverter->toStandardUnits( $value ); + if ( $standard !== null ) { + return $standard; + } else { + return $value; + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId(), + true + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CitationNeededChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CitationNeededChecker.php new file mode 100644 index 000000000..221e2a83f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CitationNeededChecker.php @@ -0,0 +1,64 @@ + CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_NOT_IN_SCOPE, + Context::TYPE_REFERENCE => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ Context::TYPE_STATEMENT ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + public function checkConstraint( Context $context, Constraint $constraint ) { + $referenceList = $context->getSnakStatement()->getReferences(); + + if ( $referenceList->isEmpty() ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-citationNeeded' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ); + return new CheckResult( + $context, + $constraint, + [], + CheckResult::STATUS_VIOLATION, + $message + ); + } + + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CommonsLinkChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CommonsLinkChecker.php new file mode 100644 index 000000000..6b3610284 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/CommonsLinkChecker.php @@ -0,0 +1,206 @@ +constraintParameterParser = $constraintParameterParser; + $this->pageNameNormalizer = $pageNameNormalizer; + $this->propertyDatatypeLookup = $propertyDatatypeLookup; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes(): array { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes(): array { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Get the number of a namespace on Wikimedia Commons (commonswiki). + * All namespaces not known to this function will be looked up by the TitleParser. + * + * @return array first element is the namespace number (default namespace for TitleParser), + * second element is a string to prepend to the title before giving it to the TitleParser + */ + private function getCommonsNamespace( string $namespace ): array { + switch ( $namespace ) { + case '': + return [ NS_MAIN, '' ]; + // extra namespaces, see operations/mediawiki-config.git, + // wmf-config/InitialiseSettings.php, 'wgExtraNamespaces' key, 'commonswiki' subkey + case 'Creator': + return [ 100, '' ]; + case 'TimedText': + return [ 102, '' ]; + case 'Sequence': + return [ 104, '' ]; + case 'Institution': + return [ 106, '' ]; + // extension namespace, see mediawiki/extensions/JsonConfig.git, + // extension.json, 'namespaces' key, third element + case 'Data': + return [ 486, '' ]; + default: + return [ NS_MAIN, $namespace . ':' ]; + } + } + + /** + * Checks 'Commons link' constraint. + * + * @throws ConstraintParameterException + */ + public function checkConstraint( Context $context, Constraint $constraint ): CheckResult { + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $namespace = $this->constraintParameterParser->parseNamespaceParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['namespace'] = [ $namespace ]; + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Commons link' constraint has to be 'string' + * parameter $namespace can be null, works for commons galleries + */ + if ( $dataValue->getType() !== 'string' ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'string' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $commonsLink = $dataValue->getValue(); + if ( !$this->commonsLinkIsWellFormed( $commonsLink ) ) { + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, + new ViolationMessage( 'wbqc-violation-message-commons-link-not-well-formed' ) ); + } + + $dataType = $this->propertyDatatypeLookup->getDataTypeIdForProperty( $snak->getPropertyId() ); + switch ( $dataType ) { + case 'geo-shape': + case 'tabular-data': + if ( strpos( $commonsLink, $namespace . ':' ) !== 0 ) { + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, + new ViolationMessage( 'wbqc-violation-message-commons-link-not-well-formed' ) ); + } + $pageName = $commonsLink; + break; + default: + $pageName = $namespace ? $namespace . ':' . $commonsLink : $commonsLink; + break; + } + + $prefix = $this->getCommonsNamespace( $namespace )[1]; + $normalizedTitle = $this->pageNameNormalizer->normalizePageName( + $pageName, + 'https://commons.wikimedia.org/w/api.php' + ); + if ( $normalizedTitle === false ) { + if ( $this->valueIncludesNamespace( $commonsLink, $namespace ) ) { + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, + new ViolationMessage( 'wbqc-violation-message-commons-link-not-well-formed' ) ); + } + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, + new ViolationMessage( 'wbqc-violation-message-commons-link-no-existent' ) ); + } + + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE, null ); + } + + public function checkConstraintParameters( Constraint $constraint ): array { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseNamespaceParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + + private function commonsLinkIsWellFormed( string $commonsLink ): bool { + $toReplace = [ "_", "%20" ]; + $compareString = trim( str_replace( $toReplace, '', $commonsLink ) ); + + return $commonsLink === $compareString; + } + + /** + * Checks whether the value of the statement already includes the namespace. + * This special case should be reported as “malformed title” instead of “title does not exist”. + */ + private function valueIncludesNamespace( string $value, string $namespace ): bool { + return $namespace !== '' && + strncasecmp( $value, $namespace . ':', strlen( $namespace ) + 1 ) === 0; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ConflictsWithChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ConflictsWithChecker.php new file mode 100644 index 000000000..3055bfb73 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ConflictsWithChecker.php @@ -0,0 +1,170 @@ +constraintParameterParser = $constraintParameterParser; + $this->connectionCheckerHelper = $connectionCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + // TODO T175562 + Context::TYPE_QUALIFIER => CheckResult::STATUS_TODO, + Context::TYPE_REFERENCE => CheckResult::STATUS_TODO, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + // TODO T175562 + // Context::TYPE_QUALIFIER, + // Context::TYPE_REFERENCE, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Conflicts with' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $propertyId = $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = [ $propertyId ]; + + $items = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + $parameters['items'] = $items; + + $statementList = $context->getEntity() + ->getStatements() + ->getByRank( [ Statement::RANK_PREFERRED, Statement::RANK_NORMAL ] ); + + /* + * 'Conflicts with' can be defined with + * a) a property only + * b) a property and a number of items (each combination of property and item forming an individual claim) + */ + if ( $items === [] ) { + $offendingStatement = $this->connectionCheckerHelper->findStatementWithProperty( + $statementList, + $propertyId + ); + if ( $offendingStatement !== null ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-conflicts-with-property' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $propertyId, Role::PREDICATE ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + } else { + $offendingStatement = $this->connectionCheckerHelper->findStatementWithPropertyAndItemIdSnakValues( + $statementList, + $propertyId, + $items + ); + if ( $offendingStatement !== null ) { + $offendingValue = ItemIdSnakValue::fromSnak( $offendingStatement->getMainSnak() ); + $message = ( new ViolationMessage( 'wbqc-violation-message-conflicts-with-claim' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withItemIdSnakValue( $offendingValue, Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ContemporaryChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ContemporaryChecker.php new file mode 100644 index 000000000..a532020bf --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ContemporaryChecker.php @@ -0,0 +1,265 @@ +entityLookup = $entityLookup; + $this->rangeCheckerHelper = $rangeCheckerHelper; + $this->config = $config; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_NOT_IN_SCOPE, + Context::TYPE_REFERENCE => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ Context::TYPE_STATEMENT ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Contemporary' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @return CheckResult + * @throws \ConfigException + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + $snak = $context->getSnak(); + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + if ( !$dataValue instanceof EntityIdValue ) { + // wrong data type + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraint->getConstraintTypeItemId() ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'wikibase-entityid' ); + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_VIOLATION, $message ); + } + + $objectId = $dataValue->getEntityId(); + $objectItem = $this->entityLookup->getEntity( $objectId ); + if ( !( $objectItem instanceof StatementListProvider ) ) { + // object was deleted/doesn't exist + $message = new ViolationMessage( 'wbqc-violation-message-value-entity-must-exist' ); + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_VIOLATION, $message ); + } + /** @var Statement[] $objectStatements */ + $objectStatements = $objectItem->getStatements()->toArray(); + + $subjectId = $context->getEntity()->getId(); + $subjectStatements = $context->getEntity()->getStatements()->toArray(); + /** @var String[] $startPropertyIds */ + $startPropertyIds = $this->config->get( self::CONFIG_VARIABLE_START_PROPERTY_IDS ); + /** @var String[] $endPropertyIds */ + $endPropertyIds = $this->config->get( self::CONFIG_VARIABLE_END_PROPERTY_IDS ); + $subjectStartValue = $this->getExtremeValue( + $startPropertyIds, + $subjectStatements, + 'start' + ); + $objectStartValue = $this->getExtremeValue( + $startPropertyIds, + $objectStatements, + 'start' + ); + $subjectEndValue = $this->getExtremeValue( + $endPropertyIds, + $subjectStatements, + 'end' + ); + $objectEndValue = $this->getExtremeValue( + $endPropertyIds, + $objectStatements, + 'end' + ); + if ( + $this->rangeCheckerHelper->getComparison( $subjectStartValue, $subjectEndValue ) <= 0 && + $this->rangeCheckerHelper->getComparison( $objectStartValue, $objectEndValue ) <= 0 && ( + $this->rangeCheckerHelper->getComparison( $subjectEndValue, $objectStartValue ) < 0 || + $this->rangeCheckerHelper->getComparison( $objectEndValue, $subjectStartValue ) < 0 + ) + ) { + if ( + $subjectEndValue == null || + $this->rangeCheckerHelper->getComparison( $objectEndValue, $subjectEndValue ) < 0 + ) { + $earlierEntityId = $objectId; + $minEndValue = $objectEndValue; + $maxStartValue = $subjectStartValue; + } else { + $earlierEntityId = $subjectId; + $minEndValue = $subjectEndValue; + $maxStartValue = $objectStartValue; + } + $message = $this->getViolationMessage( + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable + $earlierEntityId, + $subjectId, + $context->getSnak()->getPropertyId(), + $objectId, + // @phan-suppress-next-line PhanTypeMismatchArgumentNullable + $minEndValue, + $maxStartValue + ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + return new CheckResult( $context, $constraint, [], $status, $message ); + } + + /** + * @param string[] $extremePropertyIds + * @param Statement[] $statements + * @param string $startOrEnd 'start' or 'end' + * + * @return DataValue|null + */ + private function getExtremeValue( $extremePropertyIds, $statements, $startOrEnd ) { + if ( $startOrEnd !== 'start' && $startOrEnd !== 'end' ) { + throw new \InvalidArgumentException( '$startOrEnd must be \'start\' or \'end\'.' ); + } + $extremeValue = null; + foreach ( $extremePropertyIds as $extremePropertyId ) { + $statementList = new StatementList( ...$statements ); + $extremeStatements = $statementList->getByPropertyId( new NumericPropertyId( $extremePropertyId ) ); + /** @var Statement $extremeStatement */ + foreach ( $extremeStatements as $extremeStatement ) { + if ( $extremeStatement->getRank() !== Statement::RANK_DEPRECATED ) { + $snak = $extremeStatement->getMainSnak(); + if ( !$snak instanceof PropertyValueSnak ) { + return null; + } else { + $comparison = $this->rangeCheckerHelper->getComparison( + $snak->getDataValue(), + $extremeValue + ); + if ( + $extremeValue === null || + ( $startOrEnd === 'start' && $comparison < 0 ) || + ( $startOrEnd === 'end' && $comparison > 0 ) + ) { + $extremeValue = $snak->getDataValue(); + } + } + } + } + } + return $extremeValue; + } + + /** + * @param EntityId $earlierEntityId + * @param EntityId $subjectId + * @param EntityId $propertyId + * @param EntityId $objectId + * @param DataValue $minEndValue + * @param DataValue $maxStartValue + * + * @return ViolationMessage + */ + private function getViolationMessage( + EntityId $earlierEntityId, + EntityId $subjectId, + EntityId $propertyId, + EntityId $objectId, + DataValue $minEndValue, + DataValue $maxStartValue + ) { + $messageKey = $earlierEntityId === $subjectId ? + 'wbqc-violation-message-contemporary-subject-earlier' : + 'wbqc-violation-message-contemporary-value-earlier'; + return ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $subjectId, Role::SUBJECT ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withEntityId( $objectId, Role::OBJECT ) + ->withDataValue( $minEndValue, Role::OBJECT ) + ->withDataValue( $maxStartValue, Role::OBJECT ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/DiffWithinRangeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/DiffWithinRangeChecker.php new file mode 100644 index 000000000..eabc4ddd6 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/DiffWithinRangeChecker.php @@ -0,0 +1,222 @@ +constraintParameterParser = $constraintParameterParser; + $this->rangeCheckerHelper = $rangeCheckerHelper; + $this->config = $config; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return array [ DataValue|null $min, DataValue|null $max, NumericPropertyId $property, array $parameters ] + */ + private function parseConstraintParameters( Constraint $constraint ) { + list( $min, $max ) = $this->constraintParameterParser->parseQuantityRangeParameter( + $constraint->getConstraintParameters(), + $constraint->getConstraintTypeItemId() + ); + $property = $this->constraintParameterParser->parsePropertyParameter( + $constraint->getConstraintParameters(), + $constraint->getConstraintTypeItemId() + ); + + $parameters = []; + if ( $min !== null ) { + $parameters['minimum_quantity'] = [ $min ]; + } + if ( $max !== null ) { + $parameters['maximum_quantity'] = [ $max ]; + } + $parameters['property'] = [ $property ]; + + return [ $min, $max, $property, $parameters ]; + } + + /** + * Check whether the endpoints of a range are in years or not. + * @param QuantityValue|null $min + * @param QuantityValue|null $max + * + * @return bool + */ + private function rangeInYears( $min, $max ) { + $yearUnit = $this->config->get( 'WBQualityConstraintsYearUnit' ); + + if ( $min !== null && $min->getUnit() === $yearUnit ) { + return true; + } + if ( $max !== null && $max->getUnit() === $yearUnit ) { + return true; + } + + return false; + } + + /** + * Checks 'Diff within range' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $minuend = $snak->getDataValue(); + '@phan-var \DataValues\TimeValue|\DataValues\QuantityValue|\DataValues\UnboundedQuantityValue $minuend'; + + /** @var NumericPropertyId $property */ + list( $min, $max, $property, $parameters ) = $this->parseConstraintParameters( $constraint ); + + // checks only the first occurrence of the referenced property + foreach ( $context->getSnakGroup( Context::GROUP_NON_DEPRECATED ) as $otherSnak ) { + if ( + !$property->equals( $otherSnak->getPropertyId() ) || + !$otherSnak instanceof PropertyValueSnak + ) { + continue; + } + + $subtrahend = $otherSnak->getDataValue(); + '@phan-var \DataValues\TimeValue|\DataValues\QuantityValue|\DataValues\UnboundedQuantityValue $subtrahend'; + if ( $subtrahend->getType() === $minuend->getType() ) { + $diff = $this->rangeInYears( $min, $max ) && $minuend->getType() === 'time' ? + $this->rangeCheckerHelper->getDifferenceInYears( $minuend, $subtrahend ) : + $this->rangeCheckerHelper->getDifference( $minuend, $subtrahend ); + + if ( $this->rangeCheckerHelper->getComparison( $min, $diff ) > 0 || + $this->rangeCheckerHelper->getComparison( $diff, $max ) > 0 + ) { + // at least one of $min, $max is set at this point, otherwise there could be no violation + $openness = $min !== null ? ( $max !== null ? '' : '-rightopen' ) : '-leftopen'; + // possible message keys: + // wbqc-violation-message-diff-within-range + // wbqc-violation-message-diff-within-range-leftopen + // wbqc-violation-message-diff-within-range-rightopen + $message = ( new ViolationMessage( "wbqc-violation-message-diff-within-range$openness" ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE ) + ->withDataValue( $minuend, Role::OBJECT ) + ->withEntityId( $otherSnak->getPropertyId(), Role::PREDICATE ) + ->withDataValue( $subtrahend, Role::OBJECT ); + if ( $min !== null ) { + $message = $message->withDataValue( $min, Role::OBJECT ); + } + if ( $max !== null ) { + $message = $message->withDataValue( $max, Role::OBJECT ); + } + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + } else { + $message = new ViolationMessage( 'wbqc-violation-message-diff-within-range-must-have-equal-types' ); + $status = CheckResult::STATUS_VIOLATION; + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseQuantityRangeParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/EntityTypeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/EntityTypeChecker.php new file mode 100644 index 000000000..d8590560e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/EntityTypeChecker.php @@ -0,0 +1,96 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $constraintParameters = $constraint->getConstraintParameters(); + $entityTypes = $this->constraintParameterParser->parseEntityTypesParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId() + ); + $parameters = [ + 'item' => $entityTypes->getEntityTypes(), + ]; + + if ( !in_array( $context->getEntity()->getType(), $entityTypes->getEntityTypes() ) ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-entityType' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityIdList( $entityTypes->getEntityTypeItemIds(), Role::CONSTRAINT_PARAMETER_VALUE ); + + return new CheckResult( + $context, + $constraint, + [], + CheckResult::STATUS_VIOLATION, + $message + ); + } + + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseEntityTypesParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId() + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/FormatChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/FormatChecker.php new file mode 100644 index 000000000..bf70c939a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/FormatChecker.php @@ -0,0 +1,251 @@ +constraintParameterParser = $constraintParameterParser; + $this->config = $config; + $this->sparqlHelper = $sparqlHelper; + $this->shellboxClientFactory = $shellboxClientFactory; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Format' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $format = $this->constraintParameterParser->parseFormatParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['pattern'] = [ $format ]; + + $syntaxClarifications = $this->constraintParameterParser->parseSyntaxClarificationParameter( + $constraintParameters + ); + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Format' constraint has to be 'string' or 'monolingualtext' + */ + switch ( $dataValue->getType() ) { + case 'string': + $text = $dataValue->getValue(); + break; + case 'monolingualtext': + /** @var MonolingualTextValue $dataValue */ + '@phan-var MonolingualTextValue $dataValue'; + $text = $dataValue->getText(); + break; + default: + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-types-2' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'string' ) + ->withDataValueType( 'monolingualtext' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + $status = $this->runRegexCheck( $text, $format ); + $message = $this->formatMessage( + $status, + $text, + $format, + $context->getSnak()->getPropertyId(), + $syntaxClarifications, + $constraintTypeItemId + ); + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + private function formatMessage( + string $status, + string $text, + string $format, + PropertyId $propertyId, + MultilingualTextValue $syntaxClarifications, + string $constraintTypeItemId + ): ?ViolationMessage { + $message = null; + if ( $status === CheckResult::STATUS_VIOLATION ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-format-clarification' ) ) + ->withEntityId( $propertyId, Role::CONSTRAINT_PROPERTY ) + ->withDataValue( new StringValue( $text ), Role::OBJECT ) + ->withInlineCode( $format, Role::CONSTRAINT_PARAMETER_VALUE ) + ->withMultilingualText( $syntaxClarifications, Role::CONSTRAINT_PARAMETER_VALUE ); + } elseif ( $status === CheckResult::STATUS_TODO ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-security-reason' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ); + } + + return $message; + } + + private function runRegexCheck( string $text, string $format ): string { + if ( !$this->config->get( 'WBQualityConstraintsCheckFormatConstraint' ) ) { + return CheckResult::STATUS_TODO; + } + if ( + $this->config->get( 'WBQualityConstraintsFormatCheckerShellboxRatio' ) > (float)wfRandom() + ) { + return $this->runRegexCheckUsingShellbox( $text, $format ); + } + + return $this->runRegexCheckUsingSparql( $text, $format ); + } + + private function runRegexCheckUsingShellbox( string $text, string $format ): string { + if ( !$this->shellboxClientFactory->isEnabled( 'constraint-regex-checker' ) ) { + return CheckResult::STATUS_TODO; + } + try { + $pattern = '/^(?:' . str_replace( '/', '\/', $format ) . ')$/u'; + $shellboxResponse = $this->shellboxClientFactory->getClient( [ + 'timeout' => $this->config->get( 'WBQualityConstraintsSparqlMaxMillis' ) / 1000, + 'service' => 'constraint-regex-checker', + ] )->call( + 'constraint-regex-checker', + 'preg_match', + [ $pattern, $text ] + ); + } catch ( ShellboxError $exception ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-regex' ) ) + ->withInlineCode( $pattern, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + + if ( $shellboxResponse ) { + return CheckResult::STATUS_COMPLIANCE; + } else { + return CheckResult::STATUS_VIOLATION; + } + } + + private function runRegexCheckUsingSparql( string $text, string $format ): string { + if ( $this->sparqlHelper instanceof DummySparqlHelper ) { + return CheckResult::STATUS_TODO; + } + + if ( $this->sparqlHelper->matchesRegularExpression( $text, $format ) ) { + return CheckResult::STATUS_COMPLIANCE; + } else { + return CheckResult::STATUS_VIOLATION; + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseFormatParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseSyntaxClarificationParameter( + $constraintParameters + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/IntegerChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/IntegerChecker.php new file mode 100644 index 000000000..aacbecd14 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/IntegerChecker.php @@ -0,0 +1,113 @@ +getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + + $violationMessage = $this->checkSnak( $snak ); + + return new CheckResult( + $context, + $constraint, + [], + $violationMessage === null ? + CheckResult::STATUS_COMPLIANCE : + CheckResult::STATUS_VIOLATION, + $violationMessage + ); + } + + /** + * @param PropertyValueSnak $snak + * @return ViolationMessage|null + */ + public function checkSnak( PropertyValueSnak $snak ) { + $dataValue = $snak->getDataValue(); + + if ( $dataValue instanceof DecimalValue ) { + if ( !$this->isInteger( $dataValue ) ) { + return $this->getViolationMessage( 'wbqc-violation-message-integer', $snak ); + } + } elseif ( $dataValue instanceof UnboundedQuantityValue ) { + if ( !$this->isInteger( $dataValue->getAmount() ) ) { + return $this->getViolationMessage( 'wbqc-violation-message-integer', $snak ); + } elseif ( + $dataValue instanceof QuantityValue && ( + !$this->isInteger( $dataValue->getLowerBound() ) || + !$this->isInteger( $dataValue->getUpperBound() ) + ) + ) { + return $this->getViolationMessage( 'wbqc-violation-message-integer-bounds', $snak ); + } + } + + return null; + } + + /** + * @param DecimalValue $decimalValue + * @return bool + */ + private function isInteger( DecimalValue $decimalValue ) { + return $decimalValue->getTrimmed()->getFractionalPart() === ''; + } + + /** + * @param string $messageKey + * @param PropertyValueSnak $snak + * @return ViolationMessage + */ + private function getViolationMessage( $messageKey, PropertyValueSnak $snak ) { + return ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $snak->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withDataValue( $snak->getDataValue() ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/InverseChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/InverseChecker.php new file mode 100644 index 000000000..a5fcb64b8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/InverseChecker.php @@ -0,0 +1,170 @@ +entityLookup = $lookup; + $this->constraintParameterParser = $constraintParameterParser; + $this->connectionCheckerHelper = $connectionCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + // TODO T175594 + Context::TYPE_QUALIFIER => CheckResult::STATUS_TODO, + Context::TYPE_REFERENCE => CheckResult::STATUS_TODO, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + // TODO T175594 + // Context::TYPE_QUALIFIER, + // Context::TYPE_REFERENCE, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Inverse' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $propertyId = $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = [ $propertyId ]; + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Inverse' constraint has to be 'wikibase-entityid' + */ + if ( !$dataValue instanceof EntityIdValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'wikibase-entityid' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $targetEntityId = $dataValue->getEntityId(); + $targetEntity = $this->entityLookup->getEntity( $targetEntityId ); + if ( !$targetEntity instanceof StatementListProvider ) { + $message = new ViolationMessage( 'wbqc-violation-message-target-entity-must-exist' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $inverseStatement = $this->connectionCheckerHelper->findStatementWithPropertyAndEntityIdValue( + $targetEntity->getStatements(), + $propertyId, + $context->getEntity()->getId() + ); + if ( $inverseStatement !== null ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } else { + $message = ( new ViolationMessage( 'wbqc-violation-message-inverse' ) ) + ->withEntityId( $targetEntityId, Role::SUBJECT ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withEntityId( $context->getEntity()->getId(), Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( Metadata::ofDependencyMetadata( + DependencyMetadata::ofEntityId( $targetEntityId ) ) ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ItemChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ItemChecker.php new file mode 100644 index 000000000..d109751fd --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ItemChecker.php @@ -0,0 +1,156 @@ +constraintParameterParser = $constraintParameterParser; + $this->connectionCheckerHelper = $connectionCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + // TODO T175562 + Context::TYPE_QUALIFIER => CheckResult::STATUS_TODO, + Context::TYPE_REFERENCE => CheckResult::STATUS_TODO, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + // TODO T175562 + // Context::TYPE_QUALIFIER, + // Context::TYPE_REFERENCE, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Item' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $propertyId = $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = [ $propertyId ]; + + $items = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + $parameters['items'] = $items; + + /* + * 'Item' can be defined with + * a) a property only + * b) a property and a number of items (each combination of property and item forming an individual claim) + */ + if ( $items === [] ) { + $requiredStatement = $this->connectionCheckerHelper->findStatementWithProperty( + $context->getEntity()->getStatements(), + $propertyId + ); + } else { + $requiredStatement = $this->connectionCheckerHelper->findStatementWithPropertyAndItemIdSnakValues( + $context->getEntity()->getStatements(), + $propertyId, + $items + ); + } + + if ( $requiredStatement !== null ) { + $status = CheckResult::STATUS_COMPLIANCE; + $message = null; + } else { + $status = CheckResult::STATUS_VIOLATION; + $message = ( new ViolationMessage( 'wbqc-violation-message-item' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withItemIdSnakValueList( $items, Role::OBJECT ); + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/LabelInLanguageChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/LabelInLanguageChecker.php new file mode 100644 index 000000000..ab37de6ed --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/LabelInLanguageChecker.php @@ -0,0 +1,119 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_REFERENCE => CheckResult::STATUS_COMPLIANCE, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + Context::TYPE_QUALIFIER, + Context::TYPE_REFERENCE, + ]; + } + + public function getSupportedEntityTypes() { + return [ + 'item' => CheckResult::STATUS_COMPLIANCE, + 'property' => CheckResult::STATUS_COMPLIANCE, + 'lexeme' => CheckResult::STATUS_NOT_IN_SCOPE, + 'form' => CheckResult::STATUS_NOT_IN_SCOPE, + 'sense' => CheckResult::STATUS_NOT_IN_SCOPE, + 'mediainfo' => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * Checks 'Language' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ): CheckResult { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + + $languages = $this->constraintParameterParser->parseLanguageParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId() + ); + $parameters['language'] = $languages; + + $status = CheckResult::STATUS_VIOLATION; + $message = ( new ViolationMessage( 'wbqc-violation-message-label-lacking' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE ) + ->withLanguages( $languages ); + + /** @var LabelsProvider $entity */ + $entity = $context->getEntity(); + '@phan-var LabelsProvider $entity'; + + foreach ( $languages as $language ) { + if ( $entity->getLabels()->hasTermForLanguage( $language ) ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ): array { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseLanguageParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId() + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/Lexeme/LanguageChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/Lexeme/LanguageChecker.php new file mode 100644 index 000000000..766cd610c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/Lexeme/LanguageChecker.php @@ -0,0 +1,154 @@ +constraintParameterParser = $constraintParameterParser; + $this->entityLookup = $lookup; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return [ + 'item' => CheckResult::STATUS_NOT_IN_SCOPE, + 'property' => CheckResult::STATUS_NOT_IN_SCOPE, + 'lexeme' => CheckResult::STATUS_COMPLIANCE, + 'form' => CheckResult::STATUS_COMPLIANCE, + 'sense' => CheckResult::STATUS_COMPLIANCE, + 'mediainfo' => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * Checks 'Language' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $languages = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + $parameters['languages'] = $languages; + + $message = ( new ViolationMessage( 'wbqc-violation-message-language' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE ) + ->withItemIdSnakValueList( $languages, Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + + $lexeme = $this->getLexeme( $context ); + if ( !$lexeme ) { + // Lexeme doesn't exist, let's not bother + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE ); + } + + /** @var Lexeme $lexeme */ + '@phan-var Lexeme $lexeme'; + + foreach ( $languages as $language ) { + if ( $language->isNoValue() || $language->isSomeValue() ) { + continue; + } + if ( $lexeme->getLanguage()->equals( $language->getItemId() ) ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + private function getLexeme( Context $context ): ?EntityDocument { + $entityType = $context->getEntity()->getType(); + + if ( $entityType === Lexeme::ENTITY_TYPE ) { + return $context->getEntity(); + } + + if ( in_array( $entityType, [ Form::ENTITY_TYPE, Sense::ENTITY_TYPE ] ) ) { + /** @var LexemeSubEntityId $id */ + $id = $context->getEntity()->getId(); + '@phan-var LexemeSubEntityId $id'; + return $this->entityLookup->getEntity( $id->getLexemeId() ); + } + } + + public function checkConstraintParameters( Constraint $constraint ): array { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MandatoryQualifiersChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MandatoryQualifiersChecker.php new file mode 100644 index 000000000..700637efc --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MandatoryQualifiersChecker.php @@ -0,0 +1,117 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_NOT_IN_SCOPE, + Context::TYPE_REFERENCE => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Mandatory qualifiers' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $propertyId = $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = [ $propertyId ]; + + $message = ( new ViolationMessage( 'wbqc-violation-message-mandatory-qualifier' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $propertyId, Role::QUALIFIER_PREDICATE ); + $status = CheckResult::STATUS_VIOLATION; + + /** @var Snak $qualifier */ + foreach ( $context->getSnakStatement()->getQualifiers() as $qualifier ) { + if ( $propertyId->equals( $qualifier->getPropertyId() ) ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MultiValueChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MultiValueChecker.php new file mode 100644 index 000000000..5a71b227b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/MultiValueChecker.php @@ -0,0 +1,111 @@ +constraintParameterParser = $constraintParameterParser; + $this->valueCountCheckerHelper = new ValueCountCheckerHelper(); + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Multi value' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + + $separators = $this->constraintParameterParser->parseSeparatorsParameter( + $constraint->getConstraintParameters() + ); + $parameters['separator'] = $separators; + + $propertyId = $context->getSnak()->getPropertyId(); + $propertyCount = $this->valueCountCheckerHelper->getPropertyCount( + $context->getSnakGroup( Context::GROUP_NON_DEPRECATED, $separators ), + $propertyId + ); + + if ( $propertyCount <= 1 ) { + $message = ( new ViolationMessage( + $separators === [] ? + 'wbqc-violation-message-multi-value' : + 'wbqc-violation-message-multi-value-separators' + ) ) + ->withEntityId( $propertyId ) + ->withEntityIdList( $separators ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseSeparatorsParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoBoundsChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoBoundsChecker.php new file mode 100644 index 000000000..6761d559d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoBoundsChecker.php @@ -0,0 +1,67 @@ +getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + + if ( $snak->getDataValue() instanceof QuantityValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-noBounds' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ); + return new CheckResult( + $context, + $constraint, + [], + CheckResult::STATUS_VIOLATION, + $message + ); + } + + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoneOfChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoneOfChecker.php new file mode 100644 index 000000000..ed0e53d5c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/NoneOfChecker.php @@ -0,0 +1,110 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'None of' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $items = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + $parameters['item'] = $items; + + $snak = $context->getSnak(); + + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + + foreach ( $items as $item ) { + if ( $item->matchesSnak( $snak ) ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-none-of' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE ) + ->withItemIdSnakValueList( $items, Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/OneOfChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/OneOfChecker.php new file mode 100644 index 000000000..ebb23fbae --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/OneOfChecker.php @@ -0,0 +1,110 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'One of' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $items = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + $parameters['item'] = $items; + + $snak = $context->getSnak(); + + $message = ( new ViolationMessage( 'wbqc-violation-message-one-of' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::PREDICATE ) + ->withItemIdSnakValueList( $items, Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + + foreach ( $items as $item ) { + if ( $item->matchesSnak( $snak ) ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + true + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/PropertyScopeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/PropertyScopeChecker.php new file mode 100644 index 000000000..031a07417 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/PropertyScopeChecker.php @@ -0,0 +1,94 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + public function checkConstraint( Context $context, Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $allowedContextTypes = $this->constraintParameterParser->parsePropertyScopeParameter( + $constraintParameters, + $constraintTypeItemId + ); + + if ( in_array( $context->getType(), $allowedContextTypes ) ) { + return new CheckResult( + $context->getCursor(), + $constraint, + [], + CheckResult::STATUS_COMPLIANCE + ); + } else { + return new CheckResult( + $context->getCursor(), + $constraint, + [], + CheckResult::STATUS_VIOLATION, + ( new ViolationMessage( 'wbqc-violation-message-property-scope' ) ) + ->withEntityId( $context->getSnak()->getPropertyId() ) + ->withPropertyScope( $context->getType() ) + ->withPropertyScopeList( $allowedContextTypes ) + ); + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyScopeParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifierChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifierChecker.php new file mode 100644 index 000000000..2d904972a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifierChecker.php @@ -0,0 +1,61 @@ +getType() === Context::TYPE_QUALIFIER ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } else { + $message = new ViolationMessage( 'wbqc-violation-message-qualifier' ); + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_VIOLATION, $message ); + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifiersChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifiersChecker.php new file mode 100644 index 000000000..2b8ccaed4 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/QualifiersChecker.php @@ -0,0 +1,130 @@ +constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_NOT_IN_SCOPE, + Context::TYPE_REFERENCE => CheckResult::STATUS_NOT_IN_SCOPE, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Qualifiers' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $properties = $this->constraintParameterParser->parsePropertiesParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = $properties; + + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + + /** @var Snak $qualifier */ + foreach ( $context->getSnakStatement()->getQualifiers() as $qualifier ) { + $allowedQualifier = false; + foreach ( $properties as $property ) { + if ( $qualifier->getPropertyId()->equals( $property ) ) { + $allowedQualifier = true; + break; + } + } + if ( !$allowedQualifier ) { + if ( empty( $properties ) || $properties === [ '' ] ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-no-qualifiers' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ); + } else { + $message = ( new ViolationMessage( 'wbqc-violation-message-qualifiers' ) ) + ->withEntityId( $context->getSnak()->getPropertyId(), Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $qualifier->getPropertyId(), Role::QUALIFIER_PREDICATE ) + ->withEntityIdList( $properties, Role::QUALIFIER_PREDICATE ); + } + $status = CheckResult::STATUS_VIOLATION; + break; + } + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertiesParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/RangeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/RangeChecker.php new file mode 100644 index 000000000..111a1dbc7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/RangeChecker.php @@ -0,0 +1,232 @@ +propertyDataTypeLookup = $propertyDataTypeLookup; + $this->constraintParameterParser = $constraintParameterParser; + $this->rangeCheckerHelper = $rangeCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Range' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + list( $min, $max ) = $this->parseRangeParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId(), + $dataValue->getType() + ); + $parameterKey = $dataValue->getType() === 'quantity' ? 'quantity' : 'date'; + if ( $min !== null ) { + $parameters['minimum_' . $parameterKey] = [ $min ]; + } + if ( $max !== null ) { + $parameters['maximum_' . $parameterKey] = [ $max ]; + } + + if ( $this->rangeCheckerHelper->getComparison( $min, $dataValue ) > 0 || + $this->rangeCheckerHelper->getComparison( $dataValue, $max ) > 0 + ) { + $message = $this->getViolationMessage( + $context->getSnak()->getPropertyId(), + $dataValue, + $min, + $max + ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + + if ( + $dataValue instanceof TimeValue && + ( $min instanceof NowValue || $max instanceof NowValue ) && + $this->rangeCheckerHelper->isFutureTime( $dataValue ) + ) { + $dependencyMetadata = DependencyMetadata::ofFutureTime( $dataValue ); + } else { + $dependencyMetadata = DependencyMetadata::blank(); + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( Metadata::ofDependencyMetadata( $dependencyMetadata ) ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\ConstraintReport\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @param string $type 'quantity' or 'time' (can be data type or data value type) + * + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return DataValue[] a pair of two data values, either of which may be null to signify an open range + */ + private function parseRangeParameter( array $constraintParameters, $constraintTypeItemId, $type ) { + switch ( $type ) { + case 'quantity': + return $this->constraintParameterParser->parseQuantityRangeParameter( + $constraintParameters, + $constraintTypeItemId + ); + case 'time': + return $this->constraintParameterParser->parseTimeRangeParameter( + $constraintParameters, + $constraintTypeItemId + ); + } + + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-types-2' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'quantity' ) + ->withDataValueType( 'time' ) + ); + } + + /** + * @param PropertyId $predicate + * @param DataValue $value + * @param DataValue|null $min + * @param DataValue|null $max + * + * @return ViolationMessage + */ + private function getViolationMessage( PropertyId $predicate, DataValue $value, $min, $max ) { + // possible message keys: + // wbqc-violation-message-range-quantity-closed + // wbqc-violation-message-range-quantity-leftopen + // wbqc-violation-message-range-quantity-rightopen + // wbqc-violation-message-range-time-closed + // wbqc-violation-message-range-time-closed-leftnow + // wbqc-violation-message-range-time-closed-rightnow + // wbqc-violation-message-range-time-leftopen + // wbqc-violation-message-range-time-leftopen-rightnow + // wbqc-violation-message-range-time-rightopen + // wbqc-violation-message-range-time-rightopen-leftnow + $messageKey = 'wbqc-violation-message-range'; + $messageKey .= '-' . $value->getType(); + // at least one of $min, $max is set, otherwise there could be no violation + $messageKey .= '-' . ( $min !== null ? ( $max !== null ? 'closed' : 'rightopen' ) : 'leftopen' ); + if ( $min instanceof NowValue ) { + $messageKey .= '-leftnow'; + } elseif ( $max instanceof NowValue ) { + $messageKey .= '-rightnow'; + } + $message = ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $predicate, Role::PREDICATE ) + ->withDataValue( $value, Role::OBJECT ); + if ( $min !== null && !( $min instanceof NowValue ) ) { + $message = $message->withDataValue( $min, Role::OBJECT ); + } + if ( $max !== null && !( $max instanceof NowValue ) ) { + $message = $message->withDataValue( $max, Role::OBJECT ); + } + return $message; + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + // we don’t have a data value here, so get the type from the property instead + // (the distinction between data type and data value type is irrelevant for 'quantity' and 'time') + $type = $this->propertyDataTypeLookup->getDataTypeIdForProperty( $constraint->getPropertyId() ); + $this->parseRangeParameter( + $constraintParameters, + $constraint->getConstraintTypeItemId(), + $type + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ReferenceChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ReferenceChecker.php new file mode 100644 index 000000000..29e9b99e5 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ReferenceChecker.php @@ -0,0 +1,50 @@ +getType() === Context::TYPE_REFERENCE ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } else { + $message = new ViolationMessage( 'wbqc-violation-message-reference' ); + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_VIOLATION, $message ); + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleBestValueChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleBestValueChecker.php new file mode 100644 index 000000000..7b9be2267 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleBestValueChecker.php @@ -0,0 +1,147 @@ +constraintParameterParser = $constraintParameterParser; + $this->valueCountCheckerHelper = new ValueCountCheckerHelper(); + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Single best value' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + + $separators = $this->constraintParameterParser->parseSeparatorsParameter( + $constraint->getConstraintParameters() + ); + $parameters['separator'] = $separators; + + $propertyId = $context->getSnak()->getPropertyId(); + $bestRankCount = $this->valueCountCheckerHelper->getPropertyCount( + $context->getSnakGroup( Context::GROUP_BEST_RANK, $separators ), + $propertyId + ); + + if ( $bestRankCount > 1 ) { + $nonDeprecatedCount = $this->valueCountCheckerHelper->getPropertyCount( + $context->getSnakGroup( Context::GROUP_NON_DEPRECATED ), + $propertyId + ); + $message = $this->getViolationMessage( + $bestRankCount, + $nonDeprecatedCount, + $separators, + $propertyId + ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseSeparatorsParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + + /** + * @param int $bestRankCount + * @param int $nonDeprecatedCount + * @param PropertyId[] $separators + * @param PropertyId $propertyId + * @return ViolationMessage + */ + private function getViolationMessage( + $bestRankCount, + $nonDeprecatedCount, + $separators, + $propertyId + ) { + if ( $bestRankCount === $nonDeprecatedCount ) { + if ( $separators === [] ) { + $messageKey = 'wbqc-violation-message-single-best-value-no-preferred'; + } else { + $messageKey = 'wbqc-violation-message-single-best-value-no-preferred-separators'; + } + } else { + if ( $separators === [] ) { + $messageKey = 'wbqc-violation-message-single-best-value-multi-preferred'; + } else { + $messageKey = 'wbqc-violation-message-single-best-value-multi-preferred-separators'; + } + } + + return ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $propertyId ) + ->withEntityIdList( $separators ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleValueChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleValueChecker.php new file mode 100644 index 000000000..288a4e15d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SingleValueChecker.php @@ -0,0 +1,122 @@ +constraintParameterParser = $constraintParameterParser; + $this->valueCountCheckerHelper = new ValueCountCheckerHelper(); + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Single value' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + + $separators = $this->constraintParameterParser->parseSeparatorsParameter( + $constraint->getConstraintParameters() + ); + $parameters['separator'] = $separators; + + $propertyId = $context->getSnak()->getPropertyId(); + $propertyCount = $this->valueCountCheckerHelper->getPropertyCount( + $context->getSnakGroup( Context::GROUP_NON_DEPRECATED, $separators ), + $propertyId + ); + + if ( $propertyCount > 1 ) { + $message = $this->getViolationMessage( $separators, $propertyId ); + $status = CheckResult::STATUS_VIOLATION; + } else { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } + + return new CheckResult( $context, $constraint, $parameters, $status, $message ); + } + + /** + * @param PropertyId[] $separators + * @param PropertyId $propertyId + * @return ViolationMessage + */ + private function getViolationMessage( array $separators, PropertyId $propertyId ) { + $messageKey = $separators === [] ? + 'wbqc-violation-message-single-value' : + 'wbqc-violation-message-single-value-separators'; + + return ( new ViolationMessage( $messageKey ) ) + ->withEntityId( $propertyId ) + ->withEntityIdList( $separators ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseSeparatorsParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SymmetricChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SymmetricChecker.php new file mode 100644 index 000000000..26b4ebce0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/SymmetricChecker.php @@ -0,0 +1,143 @@ +entityLookup = $lookup; + $this->connectionCheckerHelper = $connectionCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + // TODO T175594 + Context::TYPE_QUALIFIER => CheckResult::STATUS_TODO, + Context::TYPE_REFERENCE => CheckResult::STATUS_TODO, + ]; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + // TODO T175594 + // Context::TYPE_QUALIFIER, + // Context::TYPE_REFERENCE, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Symmetric' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + + $snak = $context->getSnak(); + $propertyId = $context->getSnak()->getPropertyId(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Symmetric' constraint has to be 'wikibase-entityid' + */ + if ( !$dataValue instanceof EntityIdValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraint->getConstraintTypeItemId() ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'wikibase-entityid' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $targetEntityId = $dataValue->getEntityId(); + $targetEntity = $this->entityLookup->getEntity( $targetEntityId ); + if ( !$targetEntity instanceof StatementListProvider ) { + $message = new ViolationMessage( 'wbqc-violation-message-target-entity-must-exist' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $symmetricStatement = $this->connectionCheckerHelper->findStatementWithPropertyAndEntityIdValue( + $targetEntity->getStatements(), + $propertyId, + $context->getEntity()->getId() + ); + if ( $symmetricStatement !== null ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } else { + $message = ( new ViolationMessage( 'wbqc-violation-message-symmetric' ) ) + ->withEntityId( $targetEntityId, Role::SUBJECT ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withEntityId( $context->getEntity()->getId(), Role::OBJECT ); + $status = CheckResult::STATUS_VIOLATION; + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( Metadata::ofDependencyMetadata( + DependencyMetadata::ofEntityId( $targetEntityId ) ) ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TargetRequiredClaimChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TargetRequiredClaimChecker.php new file mode 100644 index 000000000..3ff639811 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TargetRequiredClaimChecker.php @@ -0,0 +1,189 @@ +entityLookup = $lookup; + $this->constraintParameterParser = $constraintParameterParser; + $this->connectionCheckerHelper = $connectionCheckerHelper; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Target required claim' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $propertyId = $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['property'] = [ $propertyId ]; + + $items = $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + $parameters['items'] = $items; + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Target required claim' constraint has to be 'wikibase-entityid' + */ + if ( !$dataValue instanceof EntityIdValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'wikibase-entityid' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $targetEntityId = $dataValue->getEntityId(); + $targetEntity = $this->entityLookup->getEntity( $targetEntityId ); + if ( !$targetEntity instanceof StatementListProvider ) { + $message = new ViolationMessage( 'wbqc-violation-message-target-entity-must-exist' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + /* + * 'Target required claim' can be defined with + * a) a property only + * b) a property and a number of items (each combination forming an individual claim) + */ + if ( $items === [] ) { + $requiredStatement = $this->connectionCheckerHelper->findStatementWithProperty( + $targetEntity->getStatements(), + $propertyId + ); + } else { + $requiredStatement = $this->connectionCheckerHelper->findStatementWithPropertyAndItemIdSnakValues( + $targetEntity->getStatements(), + $propertyId, + $items + ); + } + + if ( $requiredStatement !== null ) { + $status = CheckResult::STATUS_COMPLIANCE; + $message = null; + } else { + $status = CheckResult::STATUS_VIOLATION; + $message = ( new ViolationMessage( 'wbqc-violation-message-target-required-claim' ) ) + ->withEntityId( $targetEntityId, Role::SUBJECT ) + ->withEntityId( $propertyId, Role::PREDICATE ) + ->withItemIdSnakValueList( $items, Role::OBJECT ); + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( Metadata::ofDependencyMetadata( + DependencyMetadata::ofEntityId( $targetEntityId ) ) ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parsePropertyParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + false + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TypeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TypeChecker.php new file mode 100644 index 000000000..5ed795f55 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/TypeChecker.php @@ -0,0 +1,162 @@ +constraintParameterParser = $constraintParameterParser; + $this->typeCheckerHelper = $typeCheckerHelper; + $this->config = $config; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Type' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @throws SparqlHelperException if the checker uses SPARQL and the query times out or some other error occurs + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + if ( $context->getType() === Context::TYPE_REFERENCE ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $classes = $this->constraintParameterParser->parseClassParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['class'] = array_map( + static function ( $id ) { + return new ItemId( $id ); + }, + $classes + ); + + $relation = $this->constraintParameterParser->parseRelationParameter( + $constraintParameters, + $constraintTypeItemId + ); + $relationIds = []; + if ( $relation === 'instance' || $relation === 'instanceOrSubclass' ) { + $relationIds[] = $this->config->get( 'WBQualityConstraintsInstanceOfId' ); + } + if ( $relation === 'subclass' || $relation === 'instanceOrSubclass' ) { + $relationIds[] = $this->config->get( 'WBQualityConstraintsSubclassOfId' ); + } + $parameters['relation'] = [ $relation ]; + + $result = $this->typeCheckerHelper->hasClassInRelation( + $context->getEntity()->getStatements(), + $relationIds, + $classes + ); + + if ( $result->getBool() ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } else { + $message = $this->typeCheckerHelper->getViolationMessage( + $context->getSnak()->getPropertyId(), + $context->getEntity()->getId(), + $classes, + 'type', + $relation + ); + $status = CheckResult::STATUS_VIOLATION; + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( $result->getMetadata() ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseClassParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseRelationParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/UniqueValueChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/UniqueValueChecker.php new file mode 100644 index 000000000..2f6ae53ad --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/UniqueValueChecker.php @@ -0,0 +1,145 @@ +sparqlHelper = $sparqlHelper; + $this->constraintParameterParser = $constraintParameterParser; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return [ + Context::TYPE_STATEMENT, + ]; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Unique value' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws SparqlHelperException if the checker uses SPARQL and the query times out or some other error occurs + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + $parameters = []; + + if ( !( $this->sparqlHelper instanceof DummySparqlHelper ) ) { + + $separators = $this->constraintParameterParser->parseSeparatorsParameter( + $constraint->getConstraintParameters() + ); + $parameters['separator'] = $separators; + + if ( $context->getType() === 'statement' ) { + $result = $this->sparqlHelper->findEntitiesWithSameStatement( + $context->getSnakStatement(), + $separators + ); + } else { + $snak = $context->getSnak(); + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } + $result = $this->sparqlHelper->findEntitiesWithSameQualifierOrReference( + $context->getEntity()->getId(), + $snak, + $context->getType(), + // ignore qualifiers of deprecated statements but still check their references + $context->getType() === 'qualifier' + ); + } + $otherEntities = $result->getArray(); + $metadata = $result->getMetadata(); + + if ( $otherEntities === [] ) { + $status = CheckResult::STATUS_COMPLIANCE; + $message = null; + } else { + $otherEntities = array_values( array_filter( $otherEntities ) ); // remove nulls + $status = CheckResult::STATUS_VIOLATION; + $message = ( new ViolationMessage( 'wbqc-violation-message-unique-value' ) ) + ->withEntityIdList( $otherEntities, Role::SUBJECT ); + } + } else { + $status = CheckResult::STATUS_TODO; + $message = ( new ViolationMessage( 'wbqc-violation-message-not-yet-implemented' ) ) + ->withEntityId( new ItemId( $constraint->getConstraintTypeItemId() ), Role::CONSTRAINT_TYPE_ITEM ); + $metadata = Metadata::blank(); + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( $metadata ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $exceptions = []; + try { + $this->constraintParameterParser->parseSeparatorsParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueOnlyChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueOnlyChecker.php new file mode 100644 index 000000000..00058db5f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueOnlyChecker.php @@ -0,0 +1,50 @@ +getType() === Context::TYPE_STATEMENT ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_COMPLIANCE ); + } else { + $message = new ViolationMessage( 'wbqc-violation-message-valueOnly' ); + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_VIOLATION, $message ); + } + } + + public function checkConstraintParameters( Constraint $constraint ) { + // no parameters + return []; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueTypeChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueTypeChecker.php new file mode 100644 index 000000000..b2bd77119 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Checker/ValueTypeChecker.php @@ -0,0 +1,205 @@ +entityLookup = $lookup; + $this->constraintParameterParser = $constraintParameterParser; + $this->typeCheckerHelper = $typeCheckerHelper; + $this->config = $config; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getSupportedContextTypes() { + return self::ALL_CONTEXT_TYPES_SUPPORTED; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getDefaultContextTypes() { + return Context::ALL_CONTEXT_TYPES; + } + + /** @codeCoverageIgnore This method is purely declarative. */ + public function getSupportedEntityTypes() { + return self::ALL_ENTITY_TYPES_SUPPORTED; + } + + /** + * Checks 'Value type' constraint. + * + * @param Context $context + * @param Constraint $constraint + * + * @throws ConstraintParameterException + * @throws SparqlHelperException if the checker uses SPARQL and the query times out or some other error occurs + * @return CheckResult + */ + public function checkConstraint( Context $context, Constraint $constraint ) { + if ( $context->getSnakRank() === Statement::RANK_DEPRECATED ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_DEPRECATED ); + } + + $parameters = []; + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $classes = $this->constraintParameterParser->parseClassParameter( + $constraintParameters, + $constraintTypeItemId + ); + $parameters['class'] = array_map( + static function ( $id ) { + return new ItemId( $id ); + }, + $classes + ); + + $relation = $this->constraintParameterParser->parseRelationParameter( + $constraintParameters, + $constraintTypeItemId + ); + $relationIds = []; + if ( $relation === 'instance' || $relation === 'instanceOrSubclass' ) { + $relationIds[] = $this->config->get( 'WBQualityConstraintsInstanceOfId' ); + } + if ( $relation === 'subclass' || $relation === 'instanceOrSubclass' ) { + $relationIds[] = $this->config->get( 'WBQualityConstraintsSubclassOfId' ); + } + $parameters['relation'] = [ $relation ]; + + $snak = $context->getSnak(); + + if ( !$snak instanceof PropertyValueSnak ) { + // nothing to check + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_COMPLIANCE ); + } + + $dataValue = $snak->getDataValue(); + + /* + * error handling: + * type of $dataValue for properties with 'Value type' constraint has to be 'wikibase-entityid' + */ + if ( !$dataValue instanceof EntityIdValue ) { + $message = ( new ViolationMessage( 'wbqc-violation-message-value-needed-of-type' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withDataValueType( 'wikibase-entityid' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + try { + $item = $this->entityLookup->getEntity( $dataValue->getEntityId() ); + } catch ( UnresolvedEntityRedirectException $e ) { + // Edge case (double redirect): Pretend the entity doesn't exist + $item = null; + } + + if ( !( $item instanceof StatementListProvidingEntity ) ) { + $message = new ViolationMessage( 'wbqc-violation-message-value-entity-must-exist' ); + return new CheckResult( $context, $constraint, $parameters, CheckResult::STATUS_VIOLATION, $message ); + } + + $statements = $item->getStatements(); + + $result = $this->typeCheckerHelper->hasClassInRelation( + $statements, + $relationIds, + $classes + ); + + if ( $result->getBool() ) { + $message = null; + $status = CheckResult::STATUS_COMPLIANCE; + } else { + $message = $this->typeCheckerHelper->getViolationMessage( + $context->getSnak()->getPropertyId(), + $item->getId(), + $classes, + 'valueType', + $relation + ); + $status = CheckResult::STATUS_VIOLATION; + } + + return ( new CheckResult( $context, $constraint, $parameters, $status, $message ) ) + ->withMetadata( $result->getMetadata() ); + } + + public function checkConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + $exceptions = []; + try { + $this->constraintParameterParser->parseClassParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + try { + $this->constraintParameterParser->parseRelationParameter( + $constraintParameters, + $constraintTypeItemId + ); + } catch ( ConstraintParameterException $e ) { + $exceptions[] = $e; + } + return $exceptions; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ConstraintChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ConstraintChecker.php new file mode 100644 index 000000000..b83cc091d --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ConstraintChecker.php @@ -0,0 +1,124 @@ + CheckResult::STATUS_COMPLIANCE, + 'property' => CheckResult::STATUS_COMPLIANCE, + 'lexeme' => CheckResult::STATUS_COMPLIANCE, + 'form' => CheckResult::STATUS_COMPLIANCE, + 'sense' => CheckResult::STATUS_COMPLIANCE, + 'mediainfo' => CheckResult::STATUS_COMPLIANCE, + ]; + + /** + * Convenience constant, returned by many {@link getSupportedContextTypes} implementations. + */ + public const ALL_CONTEXT_TYPES_SUPPORTED = [ + Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_QUALIFIER => CheckResult::STATUS_COMPLIANCE, + Context::TYPE_REFERENCE => CheckResult::STATUS_COMPLIANCE, + ]; + + /** + * Determines which context types this constraint type supports. + * checkConstraint() should only be called for contexts with one of the supported types. + * + * Returns an array from context types + * (i. e., Context::TYPE_* constants) + * to result status (i. e., CheckResult::STATUS_* constants). + * STATUS_COMPLIANCE means that the constraint type supports this context type + * (checkConstraint() might of course return a different status, e. g. VIOLATION); + * STATUS_TODO means that the constraint type might support this context type in the future, + * but it is not currently supported; + * and STATUS_NOT_IN_SCOPE means that the constraint type does not support this context type. + * + * For example, the array + * + * [ + * Context::TYPE_STATEMENT => CheckResult::STATUS_COMPLIANCE, + * Context::TYPE_QUALIFIER => CheckResult::STATUS_TODO, + * Context::TYPE_REFERENCE => CheckResult::STATUS_NOT_IN_SCOPE, + * ] + * + * indicates that a constraint type makes sense on statements and qualifiers + * (but not references), but has only been implemented on statements so far. + * + * Many implementations can just return {@link ALL_CONTEXT_TYPES_SUPPORTED}. + * + * @return string[] + */ + public function getSupportedContextTypes(); + + /** + * Determines the context types where this constraint type is checked + * if the constraint scope has not been explicitly specified as a constraint parameter. + * Returns an array of context types (i. e., Context::TYPE_* constants). + * + * For example, the array [ Context::TYPE_STATEMENT ] indicates that, + * by default, a constraint should only be checked on the main snak of a statement. + * Depending on the {@link getSupportedContextTypes supported context types}, + * it might also be checked on other context types + * if the constraint explicitly specifies a different scope + * (which might not even include the “statement” scope). + * + * Many implementations can just return {@link Context::ALL_CONTEXT_TYPES}. + * + * @return string[] + */ + public function getDefaultContextTypes(); + + /** + * Determines which entity types this constraint type supports. + * checkConstraint() should only be called for contexts with one of the supported entity types. + * + * Returns an array from entity types to result status (CheckResult::STATUS_* constants). + * The meaning of STATUS_COMPLIANCE, STATUS_TODO and STATUS_NOT_IN_SCOPE + * is the same as for {@link getSupportedContextTypes}. + * + * Most implementations can just return {@link ALL_ENTITY_TYPES_SUPPORTED}. + * + * @return string[] + */ + public function getSupportedEntityTypes(); + + /** + * @param Context $context + * @param Constraint $constraint + * + * @return CheckResult + * + * @throws ConstraintParameterException if the constraint parameters are invalid + * @throws SparqlHelperException if the checker uses SPARQL and the query times out or some other error occurs + */ + public function checkConstraint( Context $context, Constraint $constraint ); + + /** + * Check if the constraint parameters of $constraint are valid. + * Returns a list of ConstraintParameterExceptions, one for each problematic parameter; + * if the list is empty, all constraint parameters are okay. + * + * @param Constraint $constraint + * + * @return ConstraintParameterException[] + */ + public function checkConstraintParameters( Constraint $constraint ); + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/AbstractContext.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/AbstractContext.php new file mode 100644 index 000000000..9e861b653 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/AbstractContext.php @@ -0,0 +1,51 @@ +entity = $entity; + $this->snak = $snak; + } + + public function getSnak() { + return $this->snak; + } + + public function getEntity() { + return $this->entity; + } + + // unimplemented: getType + + public function getSnakRank() { + return null; + } + + public function getSnakStatement() { + return null; + } + + // unimplemented: getCursor + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ApiV2ContextCursor.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ApiV2ContextCursor.php new file mode 100644 index 000000000..4b054d12b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ApiV2ContextCursor.php @@ -0,0 +1,102 @@ +getEntityId(); + + if ( !array_key_exists( $entityId, $container ) ) { + $container[$entityId] = []; + } + $entityContainer = &$container[$entityId]; + + if ( !array_key_exists( 'claims', $entityContainer ) ) { + $entityContainer['claims'] = []; + } + $claimsArray = &$entityContainer['claims']; + + return $claimsArray; + } + + /** + * Returns the statement subcontainer. + * + * @param array[] &$container + * @return array + */ + protected function &getStatementArray( array &$container ) { + $statementPropertyId = $this->getStatementPropertyId(); + $statementGuid = $this->getStatementGuid(); + + $claimsContainer = &$this->getClaimsArray( $container ); + + if ( !array_key_exists( $statementPropertyId, $claimsContainer ) ) { + $claimsContainer[$statementPropertyId] = []; + } + $propertyContainer = &$claimsContainer[$statementPropertyId]; + + foreach ( $propertyContainer as &$statement ) { + if ( $statement['id'] === $statementGuid ) { + $statementArray = &$statement; + break; + } + } + if ( !isset( $statementArray ) ) { + $statementArray = [ 'id' => $statementGuid ]; + $propertyContainer[] = &$statementArray; + } + + return $statementArray; + } + + /** + * This method returns the array with the 'hash' and 'reports' member. + * It should locate the array in $container or, + * if the array doesn’t exist yet, create it and emplace it there. + * + * @param array[] &$container + * @return array + */ + abstract protected function &getMainArray( array &$container ); + + /** + * @param ?array $result + * @param array[] &$container + */ + public function storeCheckResultInArray( ?array $result, array &$container ) { + $mainArray = &$this->getMainArray( $container ); + if ( !array_key_exists( 'results', $mainArray ) ) { + $mainArray['results'] = []; + } + + if ( $result !== null ) { + $mainArray['results'][] = $result; + } + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/Context.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/Context.php new file mode 100644 index 000000000..43bf43448 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/Context.php @@ -0,0 +1,133 @@ + '\entity', + 'i' => $cursor->getEntityId(), + ]; + } + + $type = $cursor->getType(); + $serialization = [ + 't' => $type, + 'i' => $cursor->getEntityId(), + 'p' => $cursor->getStatementPropertyId(), + 'g' => $cursor->getStatementGuid(), + 'h' => $cursor->getSnakHash(), + ]; + + if ( $type === Context::TYPE_QUALIFIER || $type === Context::TYPE_REFERENCE ) { + $serialization['P'] = $cursor->getSnakPropertyId(); + if ( $type === Context::TYPE_REFERENCE ) { + /** @var ReferenceContextCursor $cursor */ + '@phan-var ReferenceContextCursor $cursor'; + $serialization['r'] = $cursor->getReferenceHash(); + } + } + + return $serialization; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/EntityContextCursor.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/EntityContextCursor.php new file mode 100644 index 000000000..bd5a1b523 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/EntityContextCursor.php @@ -0,0 +1,97 @@ +entityId = $entityId; + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function getType() { + throw new LogicException( 'EntityContextCursor has no full associated context' ); + } + + public function getEntityId() { + return $this->entityId; + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function getStatementPropertyId() { + throw new LogicException( 'EntityContextCursor has no full associated context' ); + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function getStatementGuid() { + throw new LogicException( 'EntityContextCursor has no full associated context' ); + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function getSnakPropertyId() { + throw new LogicException( 'EntityContextCursor has no full associated context' ); + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function getSnakHash() { + throw new LogicException( 'EntityContextCursor has no full associated context' ); + } + + /** + * @codeCoverageIgnore This method is not supported. + */ + public function &getMainArray( array &$container ) { + throw new LogicException( 'EntityContextCursor cannot store check results' ); + } + + /** + * Populate the results container up to the 'claims' level. + * + * @param ?array $result must be null + * @param array[] &$container + */ + public function storeCheckResultInArray( ?array $result, array &$container ) { + if ( $result !== null ) { + throw new LogicException( 'EntityContextCursor cannot store check results' ); + } + + // this ensures that the claims array is present in the $container, + // populating it if necessary, even though we ignore the return value + $this->getClaimsArray( $container ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContext.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContext.php new file mode 100644 index 000000000..9e92cd871 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContext.php @@ -0,0 +1,175 @@ +getMainSnak() ); + + $this->statement = $statement; + } + + public function getType() { + return self::TYPE_STATEMENT; + } + + public function getSnakRank() { + return $this->statement->getRank(); + } + + public function getSnakStatement() { + return $this->statement; + } + + public function getSnakGroup( $groupingMode, array $separators = [] ) { + /** @var StatementList $statements */ + $statements = $this->entity->getStatements(); + switch ( $groupingMode ) { + case Context::GROUP_NON_DEPRECATED: + $statements = $statements->getByRank( [ + Statement::RANK_NORMAL, + Statement::RANK_PREFERRED, + ] ); + break; + case Context::GROUP_BEST_RANK: + $statements = $this->getBestStatementsPerPropertyId( $statements ); + break; + default: + throw new LogicException( 'Unknown $groupingMode ' . $groupingMode ); + } + return $this->getStatementsWithSameQualifiersForProperties( + $this->statement, + $statements, + $separators + )->getMainSnaks(); + } + + private function getBestStatementsPerPropertyId( StatementList $statements ) { + $allBestStatements = new StatementList(); + foreach ( $statements->getPropertyIds() as $propertyId ) { + $bestStatements = $statements->getByPropertyId( $propertyId ) + ->getBestStatements(); + foreach ( $bestStatements as $bestStatement ) { + $allBestStatements->addStatement( $bestStatement ); + } + } + return $allBestStatements; + } + + /** + * Returns the statements of a statement list + * which for a set of propert IDs have the same qualifiers as a certain statement. + * “unknown value” qualifiers are considered different from each other. + * + * @param Statement $currentStatement + * @param StatementList $allStatements + * @param PropertyId[] $qualifierPropertyIds + * @return StatementList + */ + private function getStatementsWithSameQualifiersForProperties( + Statement $currentStatement, + StatementList $allStatements, + array $qualifierPropertyIds + ) { + $similarStatements = new StatementList(); + foreach ( $allStatements as $statement ) { + if ( $statement === $currentStatement ) { + // if the statement has an “unknown value” qualifier, + // it might be considered different from itself, + // so add it explicitly to ensure it’s always included + $similarStatements->addStatement( $statement ); + continue; + } + foreach ( $qualifierPropertyIds as $qualifierPropertyId ) { + if ( !$this->haveSameQualifiers( $currentStatement, $statement, $qualifierPropertyId ) ) { + continue 2; + } + } + $similarStatements->addStatement( $statement ); + } + return $similarStatements; + } + + /** + * Tests whether two statements have the same qualifiers with a certain property ID. + * “unknown value” qualifiers are considered different from each other. + * + * @param Statement $s1 + * @param Statement $s2 + * @param PropertyId $propertyId + * @return bool + */ + private function haveSameQualifiers( Statement $s1, Statement $s2, PropertyId $propertyId ) { + $q1 = $this->getSnaksWithPropertyId( $s1->getQualifiers(), $propertyId ); + $q2 = $this->getSnaksWithPropertyId( $s2->getQualifiers(), $propertyId ); + + if ( $q1->count() !== $q2->count() ) { + return false; + } + + foreach ( $q1 as $qualifier ) { + switch ( $qualifier->getType() ) { + case 'value': + case 'novalue': + if ( !$q2->hasSnak( $qualifier ) ) { + return false; + } + break; + case 'somevalue': + return false; // all “unknown value”s are considered different from each other + } + } + + // a SnakList cannot contain the same snak more than once, + // so if every snak of q1 is also in q2 and their cardinality is identical, + // then they must be entirely identical + return true; + } + + /** + * Returns the snaks of the given snak list with the specified property ID. + * + * @param SnakList $allSnaks + * @param PropertyId $propertyId + * @return SnakList + */ + private function getSnaksWithPropertyId( SnakList $allSnaks, PropertyId $propertyId ) { + $snaks = new SnakList(); + /** @var Snak $snak */ + foreach ( $allSnaks as $snak ) { + if ( $snak->getPropertyId()->equals( $propertyId ) ) { + $snaks->addSnak( $snak ); + } + } + return $snaks; + } + + public function getCursor() { + return new MainSnakContextCursor( + $this->entity->getId()->getSerialization(), + $this->statement->getPropertyId()->getSerialization(), + $this->statement->getGuid(), + $this->statement->getMainSnak()->getHash() + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContextCursor.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContextCursor.php new file mode 100644 index 000000000..f638f0f0a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/MainSnakContextCursor.php @@ -0,0 +1,87 @@ +entityId = $entityId; + $this->statementPropertyId = $statementPropertyId; + $this->statementGuid = $statementGuid; + $this->snakHash = $snakHash; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getType() { + return Context::TYPE_STATEMENT; + } + + public function getEntityId() { + return $this->entityId; + } + + public function getStatementPropertyId() { + return $this->statementPropertyId; + } + + public function getStatementGuid() { + return $this->statementGuid; + } + + public function getSnakPropertyId() { + return $this->statementPropertyId; + } + + public function getSnakHash() { + return $this->snakHash; + } + + protected function &getMainArray( array &$container ) { + $statementArray = &$this->getStatementArray( $container ); + + if ( !array_key_exists( 'mainsnak', $statementArray ) ) { + $snakHash = $this->getSnakHash(); + $statementArray['mainsnak'] = [ 'hash' => $snakHash ]; + } + $mainsnakArray = &$statementArray['mainsnak']; + + return $mainsnakArray; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContext.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContext.php new file mode 100644 index 000000000..0a3ccb7c6 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContext.php @@ -0,0 +1,49 @@ +statement = $statement; + } + + public function getType() { + return self::TYPE_QUALIFIER; + } + + public function getSnakGroup( $groupingMode, array $separators = [] ) { + $snaks = $this->statement->getQualifiers(); + return array_values( $snaks->getArrayCopy() ); + } + + public function getCursor() { + return new QualifierContextCursor( + $this->entity->getId()->getSerialization(), + $this->statement->getPropertyId()->getSerialization(), + $this->statement->getGuid(), + $this->snak->getHash(), + $this->snak->getPropertyId()->getSerialization() + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContextCursor.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContextCursor.php new file mode 100644 index 000000000..650806b22 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/QualifierContextCursor.php @@ -0,0 +1,112 @@ +entityId = $entityId; + $this->statementPropertyId = $statementPropertyId; + $this->statementGuid = $statementGuid; + $this->snakHash = $snakHash; + $this->snakPropertyId = $snakPropertyId; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getType() { + return Context::TYPE_QUALIFIER; + } + + public function getEntityId() { + return $this->entityId; + } + + public function getStatementPropertyId() { + return $this->statementPropertyId; + } + + public function getStatementGuid() { + return $this->statementGuid; + } + + public function getSnakPropertyId() { + return $this->snakPropertyId; + } + + public function getSnakHash() { + return $this->snakHash; + } + + protected function &getMainArray( array &$container ) { + $statementArray = &$this->getStatementArray( $container ); + + if ( !array_key_exists( 'qualifiers', $statementArray ) ) { + $statementArray['qualifiers'] = []; + } + $qualifiersArray = &$statementArray['qualifiers']; + + $snakPropertyId = $this->getSnakPropertyId(); + if ( !array_key_exists( $snakPropertyId, $qualifiersArray ) ) { + $qualifiersArray[$snakPropertyId] = []; + } + $propertyArray = &$qualifiersArray[$snakPropertyId]; + + $snakHash = $this->getSnakHash(); + foreach ( $propertyArray as &$potentialQualifierArray ) { + if ( $potentialQualifierArray['hash'] === $snakHash ) { + $qualifierArray = &$potentialQualifierArray; + break; + } + } + if ( !isset( $qualifierArray ) ) { + $qualifierArray = [ 'hash' => $snakHash ]; + $propertyArray[] = &$qualifierArray; + } + + return $qualifierArray; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContext.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContext.php new file mode 100644 index 000000000..9a809bb73 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContext.php @@ -0,0 +1,58 @@ +statement = $statement; + $this->reference = $reference; + } + + public function getType() { + return self::TYPE_REFERENCE; + } + + public function getSnakGroup( $groupingMode, array $separators = [] ) { + $snaks = $this->reference->getSnaks(); + return array_values( $snaks->getArrayCopy() ); + } + + public function getCursor() { + return new ReferenceContextCursor( + $this->entity->getId()->getSerialization(), + $this->statement->getPropertyId()->getSerialization(), + $this->statement->getGuid(), + $this->snak->getHash(), + $this->snak->getPropertyId()->getSerialization(), + $this->reference->getHash() + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContextCursor.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContextCursor.php new file mode 100644 index 000000000..0e3ace100 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Context/ReferenceContextCursor.php @@ -0,0 +1,138 @@ +entityId = $entityId; + $this->statementPropertyId = $statementPropertyId; + $this->statementGuid = $statementGuid; + $this->snakHash = $snakHash; + $this->snakPropertyId = $snakPropertyId; + $this->referenceHash = $referenceHash; + } + + /** + * @codeCoverageIgnore This method is purely declarative. + */ + public function getType() { + return Context::TYPE_REFERENCE; + } + + public function getEntityId() { + return $this->entityId; + } + + public function getStatementPropertyId() { + return $this->statementPropertyId; + } + + public function getStatementGuid() { + return $this->statementGuid; + } + + public function getSnakPropertyId() { + return $this->snakPropertyId; + } + + public function getSnakHash() { + return $this->snakHash; + } + + public function getReferenceHash() { + return $this->referenceHash; + } + + protected function &getMainArray( array &$container ) { + $statementArray = &$this->getStatementArray( $container ); + + if ( !array_key_exists( 'references', $statementArray ) ) { + $statementArray['references'] = []; + } + $referencesArray = &$statementArray['references']; + + $referenceHash = $this->getReferenceHash(); + foreach ( $referencesArray as &$potentialReferenceArray ) { + if ( $potentialReferenceArray['hash'] === $referenceHash ) { + $referenceArray = &$potentialReferenceArray; + break; + } + } + if ( !isset( $referenceArray ) ) { + $referenceArray = [ 'hash' => $referenceHash, 'snaks' => [] ]; + $referencesArray[] = &$referenceArray; + } + + $snaksArray = &$referenceArray['snaks']; + + $snakPropertyId = $this->getSnakPropertyId(); + if ( !array_key_exists( $snakPropertyId, $snaksArray ) ) { + $snaksArray[$snakPropertyId] = []; + } + $propertyArray = &$snaksArray[$snakPropertyId]; + + $snakHash = $this->getSnakHash(); + foreach ( $propertyArray as &$potentialSnakArray ) { + if ( $potentialSnakArray['hash'] === $snakHash ) { + $snakArray = &$potentialSnakArray; + break; + } + } + if ( !isset( $snakArray ) ) { + $snakArray = [ 'hash' => $snakHash ]; + $propertyArray[] = &$snakArray; + } + + return $snakArray; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/DelegatingConstraintChecker.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/DelegatingConstraintChecker.php new file mode 100644 index 000000000..ae49e0cfe --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/DelegatingConstraintChecker.php @@ -0,0 +1,791 @@ +entityLookup = $lookup; + $this->checkerMap = $checkerMap; + $this->constraintLookup = $constraintRepository; + $this->constraintParameterParser = $constraintParameterParser; + $this->statementGuidParser = $statementGuidParser; + $this->loggingHelper = $loggingHelper; + $this->checkQualifiers = $checkQualifiers; + $this->checkReferences = $checkReferences; + $this->propertiesWithViolatingQualifiers = $propertiesWithViolatingQualifiers; + } + + /** + * Starts the whole constraint-check process for entity or constraint ID on entity. + * Statements of the entity will be checked against every constraint that is defined on the property. + * + * @param EntityId $entityId + * @param string[]|null $constraintIds + * @param callable|null $defaultResultsPerContext + * Optional function to pre-populate the check results per context. + * For each {@link Context} where constraints will be checked, + * this function (if not null) is first called with that context as argument, + * and may return an array of check results to which the regular results are appended. + * @param callable|null $defaultResultsPerEntity + * Optional function to pre-populate the check results per entity. + * This function (if not null) is called once with $entityId as argument, + * and may return an array of check results to which the regular results are appended. + * + * @return CheckResult[] + */ + public function checkAgainstConstraintsOnEntityId( + EntityId $entityId, + array $constraintIds = null, + callable $defaultResultsPerContext = null, + callable $defaultResultsPerEntity = null + ) { + $checkResults = []; + $entity = $this->entityLookup->getEntity( $entityId ); + + if ( $entity instanceof StatementListProvidingEntity ) { + $startTime = microtime( true ); + + $checkResults = $this->checkEveryStatement( + $entity, + $constraintIds, + $defaultResultsPerContext + ); + + $endTime = microtime( true ); + + if ( $constraintIds === null ) { // only log full constraint checks + $this->loggingHelper->logConstraintCheckOnEntity( + $entityId, + $checkResults, + $endTime - $startTime, + __METHOD__ + ); + } + } + + if ( $defaultResultsPerEntity !== null ) { + $checkResults = array_merge( $defaultResultsPerEntity( $entityId ), $checkResults ); + } + + return $this->sortResult( $checkResults ); + } + + /** + * Starts the whole constraint-check process. + * Statements of the entity will be checked against every constraint that is defined on the claim. + * + * @param string $guid + * @param string[]|null $constraintIds + * @param callable|null $defaultResults Optional function to pre-populate the check results. + * For each {@link Context} where constraints will be checked, + * this function (if not null) is first called with that context as argument, + * and may return an array of check results to which the regular results are appended. + * + * @return CheckResult[] + */ + public function checkAgainstConstraintsOnClaimId( + $guid, + array $constraintIds = null, + callable $defaultResults = null + ) { + + $parsedGuid = $this->statementGuidParser->parse( $guid ); + $entityId = $parsedGuid->getEntityId(); + $entity = $this->entityLookup->getEntity( $entityId ); + if ( $entity instanceof StatementListProvidingEntity ) { + $statement = $entity->getStatements()->getFirstStatementWithGuid( $guid ); + if ( $statement ) { + $result = $this->checkStatement( + $entity, + $statement, + $constraintIds, + $defaultResults + ); + $output = $this->sortResult( $result ); + return $output; + } + } + + return []; + } + + private function getValidContextTypes( Constraint $constraint ) { + if ( !array_key_exists( $constraint->getConstraintTypeItemId(), $this->checkerMap ) ) { + return [ + Context::TYPE_STATEMENT, + Context::TYPE_QUALIFIER, + Context::TYPE_REFERENCE, + ]; + } + + return array_keys( array_filter( + $this->checkerMap[$constraint->getConstraintTypeItemId()]->getSupportedContextTypes(), + static function ( $resultStatus ) { + return $resultStatus !== CheckResult::STATUS_NOT_IN_SCOPE; + } + ) ); + } + + private function getValidEntityTypes( Constraint $constraint ) { + if ( !array_key_exists( $constraint->getConstraintTypeItemId(), $this->checkerMap ) ) { + return array_keys( ConstraintChecker::ALL_ENTITY_TYPES_SUPPORTED ); + } + + return array_keys( array_filter( + $this->checkerMap[$constraint->getConstraintTypeItemId()]->getSupportedEntityTypes(), + static function ( $resultStatus ) { + return $resultStatus !== CheckResult::STATUS_NOT_IN_SCOPE; + } + ) ); + } + + /** + * Like ConstraintChecker::checkConstraintParameters, + * but for meta-parameters common to all checkers. + * + * @param Constraint $constraint + * + * @return ConstraintParameterException[] + */ + private function checkCommonConstraintParameters( Constraint $constraint ) { + $constraintParameters = $constraint->getConstraintParameters(); + try { + $this->constraintParameterParser->checkError( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + return [ $e ]; + } + + $problems = []; + try { + $this->constraintParameterParser->parseExceptionParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $problems[] = $e; + } + try { + $this->constraintParameterParser->parseConstraintStatusParameter( $constraintParameters ); + } catch ( ConstraintParameterException $e ) { + $problems[] = $e; + } + try { + $this->constraintParameterParser->parseConstraintScopeParameters( + $constraintParameters, + $constraint->getConstraintTypeItemId(), + $this->getValidContextTypes( $constraint ), + $this->getValidEntityTypes( $constraint ) + ); + } catch ( ConstraintParameterException $e ) { + $problems[] = $e; + } + return $problems; + } + + /** + * Check the constraint parameters of all constraints for the given property ID. + * + * @param NumericPropertyId $propertyId + * @return ConstraintParameterException[][] first level indexed by constraint ID, + * second level like checkConstraintParametersOnConstraintId (but without possibility of null) + */ + public function checkConstraintParametersOnPropertyId( NumericPropertyId $propertyId ) { + $constraints = $this->constraintLookup->queryConstraintsForProperty( $propertyId ); + $result = []; + + foreach ( $constraints as $constraint ) { + $problems = $this->checkCommonConstraintParameters( $constraint ); + + if ( array_key_exists( $constraint->getConstraintTypeItemId(), $this->checkerMap ) ) { + $checker = $this->checkerMap[$constraint->getConstraintTypeItemId()]; + $problems = array_merge( $problems, $checker->checkConstraintParameters( $constraint ) ); + } + + $result[$constraint->getConstraintId()] = $problems; + } + + return $result; + } + + /** + * Check the constraint parameters of the constraint with the given ID. + * + * @param string $constraintId + * + * @return ConstraintParameterException[]|null list of constraint parameter exceptions + * (empty means all parameters okay), or null if constraint is not found + */ + public function checkConstraintParametersOnConstraintId( $constraintId ) { + $propertyId = $this->statementGuidParser->parse( $constraintId )->getEntityId(); + '@phan-var NumericPropertyId $propertyId'; + $constraints = $this->constraintLookup->queryConstraintsForProperty( $propertyId ); + + foreach ( $constraints as $constraint ) { + if ( $constraint->getConstraintId() === $constraintId ) { + $problems = $this->checkCommonConstraintParameters( $constraint ); + + if ( array_key_exists( $constraint->getConstraintTypeItemId(), $this->checkerMap ) ) { + $checker = $this->checkerMap[$constraint->getConstraintTypeItemId()]; + $problems = array_merge( $problems, $checker->checkConstraintParameters( $constraint ) ); + } + + return $problems; + } + } + + return null; + } + + /** + * @param StatementListProvidingEntity $entity + * @param string[]|null $constraintIds list of constraints to check (if null: all constraints) + * @param callable|null $defaultResultsPerContext optional function to pre-populate the check results + * + * @return CheckResult[] + */ + private function checkEveryStatement( + StatementListProvidingEntity $entity, + array $constraintIds = null, + callable $defaultResultsPerContext = null + ) { + $result = []; + + /** @var Statement $statement */ + foreach ( $entity->getStatements() as $statement ) { + $result = array_merge( $result, + $this->checkStatement( + $entity, + $statement, + $constraintIds, + $defaultResultsPerContext + ) ); + } + + return $result; + } + + /** + * @param StatementListProvidingEntity $entity + * @param Statement $statement + * @param string[]|null $constraintIds list of constraints to check (if null: all constraints) + * @param callable|null $defaultResultsPerContext optional function to pre-populate the check results + * + * @return CheckResult[] + */ + private function checkStatement( + StatementListProvidingEntity $entity, + Statement $statement, + array $constraintIds = null, + callable $defaultResultsPerContext = null + ) { + $result = []; + + $result = array_merge( $result, + $this->checkConstraintsForMainSnak( + $entity, + $statement, + $constraintIds, + $defaultResultsPerContext + ) ); + + if ( $this->checkQualifiers ) { + $result = array_merge( $result, + $this->checkConstraintsForQualifiers( + $entity, + $statement, + $constraintIds, + $defaultResultsPerContext + ) ); + } + + if ( $this->checkReferences ) { + $result = array_merge( $result, + $this->checkConstraintsForReferences( + $entity, + $statement, + $constraintIds, + $defaultResultsPerContext + ) ); + } + + return $result; + } + + /** + * Get the constraints to actually check for a given property ID. + * If $constraintIds is not null, only check constraints with those constraint IDs, + * otherwise check all constraints for that property. + * + * @param PropertyId $propertyId + * @param string[]|null $constraintIds + * @return Constraint[] + */ + private function getConstraintsToUse( PropertyId $propertyId, array $constraintIds = null ) { + if ( !( $propertyId instanceof NumericPropertyId ) ) { + throw new InvalidArgumentException( + 'Non-numeric property ID not supported:' . $propertyId->getSerialization() + ); + } + $constraints = $this->constraintLookup->queryConstraintsForProperty( $propertyId ); + if ( $constraintIds !== null ) { + $constraintsToUse = []; + foreach ( $constraints as $constraint ) { + if ( in_array( $constraint->getConstraintId(), $constraintIds ) ) { + $constraintsToUse[] = $constraint; + } + } + return $constraintsToUse; + } else { + return $constraints; + } + } + + /** + * @param StatementListProvidingEntity $entity + * @param Statement $statement + * @param string[]|null $constraintIds list of constraints to check (if null: all constraints) + * @param callable|null $defaultResults optional function to pre-populate the check results + * + * @return CheckResult[] + */ + private function checkConstraintsForMainSnak( + StatementListProvidingEntity $entity, + Statement $statement, + array $constraintIds = null, + callable $defaultResults = null + ) { + $context = new MainSnakContext( $entity, $statement ); + $constraints = $this->getConstraintsToUse( + $statement->getPropertyId(), + $constraintIds + ); + $result = $defaultResults !== null ? $defaultResults( $context ) : []; + + foreach ( $constraints as $constraint ) { + $parameters = $constraint->getConstraintParameters(); + try { + $exceptions = $this->constraintParameterParser->parseExceptionParameter( $parameters ); + } catch ( ConstraintParameterException $e ) { + $result[] = new CheckResult( + $context, + $constraint, + [], + CheckResult::STATUS_BAD_PARAMETERS, $e->getViolationMessage() + ); + continue; + } + + if ( in_array( $entity->getId(), $exceptions ) ) { + $message = new ViolationMessage( 'wbqc-violation-message-exception' ); + $result[] = new CheckResult( $context, $constraint, [], CheckResult::STATUS_EXCEPTION, $message ); + continue; + } + + $result[] = $this->getCheckResultFor( $context, $constraint ); + } + + return $result; + } + + /** + * @param StatementListProvidingEntity $entity + * @param Statement $statement + * @param string[]|null $constraintIds list of constraints to check (if null: all constraints) + * @param callable|null $defaultResultsPerContext optional function to pre-populate the check results + * + * @return CheckResult[] + */ + private function checkConstraintsForQualifiers( + StatementListProvidingEntity $entity, + Statement $statement, + array $constraintIds = null, + callable $defaultResultsPerContext = null + ) { + $result = []; + + if ( in_array( + $statement->getPropertyId()->getSerialization(), + $this->propertiesWithViolatingQualifiers + ) ) { + return $result; + } + + foreach ( $statement->getQualifiers() as $qualifier ) { + $qualifierContext = new QualifierContext( $entity, $statement, $qualifier ); + if ( $defaultResultsPerContext !== null ) { + $result = array_merge( $result, $defaultResultsPerContext( $qualifierContext ) ); + } + $qualifierConstraints = $this->getConstraintsToUse( + $qualifierContext->getSnak()->getPropertyId(), + $constraintIds + ); + foreach ( $qualifierConstraints as $qualifierConstraint ) { + $result[] = $this->getCheckResultFor( $qualifierContext, $qualifierConstraint ); + } + } + + return $result; + } + + /** + * @param StatementListProvidingEntity $entity + * @param Statement $statement + * @param string[]|null $constraintIds list of constraints to check (if null: all constraints) + * @param callable|null $defaultResultsPerContext optional function to pre-populate the check results + * + * @return CheckResult[] + */ + private function checkConstraintsForReferences( + StatementListProvidingEntity $entity, + Statement $statement, + array $constraintIds = null, + callable $defaultResultsPerContext = null + ) { + $result = []; + + /** @var Reference $reference */ + foreach ( $statement->getReferences() as $reference ) { + foreach ( $reference->getSnaks() as $snak ) { + $referenceContext = new ReferenceContext( + $entity, $statement, $reference, $snak + ); + if ( $defaultResultsPerContext !== null ) { + $result = array_merge( $result, $defaultResultsPerContext( $referenceContext ) ); + } + $referenceConstraints = $this->getConstraintsToUse( + $referenceContext->getSnak()->getPropertyId(), + $constraintIds + ); + foreach ( $referenceConstraints as $referenceConstraint ) { + $result[] = $this->getCheckResultFor( + $referenceContext, + $referenceConstraint + ); + } + } + } + + return $result; + } + + /** + * @param Context $context + * @param Constraint $constraint + * + * @throws InvalidArgumentException + * @return CheckResult + */ + private function getCheckResultFor( Context $context, Constraint $constraint ) { + if ( array_key_exists( $constraint->getConstraintTypeItemId(), $this->checkerMap ) ) { + $checker = $this->checkerMap[$constraint->getConstraintTypeItemId()]; + $result = $this->handleScope( $checker, $context, $constraint ); + + if ( $result !== null ) { + $this->addMetadata( $context, $result ); + return $result; + } + + $startTime = microtime( true ); + try { + $result = $checker->checkConstraint( $context, $constraint ); + } catch ( ConstraintParameterException $e ) { + $result = new CheckResult( + $context, + $constraint, + [], + CheckResult::STATUS_BAD_PARAMETERS, + $e->getViolationMessage() + ); + } catch ( SparqlHelperException $e ) { + $message = new ViolationMessage( 'wbqc-violation-message-sparql-error' ); + $result = new CheckResult( $context, $constraint, [], CheckResult::STATUS_TODO, $message ); + } + $endTime = microtime( true ); + + $this->addMetadata( $context, $result ); + + $this->downgradeResultStatus( $context, $result ); + + $this->loggingHelper->logConstraintCheck( + $context, + $constraint, + $result, + get_class( $checker ), + $endTime - $startTime, + __METHOD__ + ); + + return $result; + } else { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_TODO, null ); + } + } + + private function handleScope( + ConstraintChecker $checker, + Context $context, + Constraint $constraint + ): ?CheckResult { + $validContextTypes = $this->getValidContextTypes( $constraint ); + $validEntityTypes = $this->getValidEntityTypes( $constraint ); + try { + [ $checkedContextTypes, $checkedEntityTypes ] = $this->constraintParameterParser->parseConstraintScopeParameters( + $constraint->getConstraintParameters(), + $constraint->getConstraintTypeItemId(), + $validContextTypes, + $validEntityTypes + ); + } catch ( ConstraintParameterException $e ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_BAD_PARAMETERS, $e->getViolationMessage() ); + } + + if ( $checkedContextTypes === null ) { + $checkedContextTypes = $checker->getDefaultContextTypes(); + } + $contextType = $context->getType(); + if ( !in_array( $contextType, $checkedContextTypes ) ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE, null ); + } + if ( $checker->getSupportedContextTypes()[$contextType] === CheckResult::STATUS_TODO ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_TODO, null ); + } + + if ( $checkedEntityTypes === null ) { + $checkedEntityTypes = $validEntityTypes; + } + $entityType = $context->getEntity()->getType(); + if ( !in_array( $entityType, $checkedEntityTypes ) ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_NOT_IN_SCOPE, null ); + } + if ( $checker->getSupportedEntityTypes()[$entityType] === CheckResult::STATUS_TODO ) { + return new CheckResult( $context, $constraint, [], CheckResult::STATUS_TODO, null ); + } + + return null; + } + + private function addMetadata( Context $context, CheckResult $result ) { + $result->withMetadata( Metadata::merge( [ + $result->getMetadata(), + Metadata::ofDependencyMetadata( DependencyMetadata::merge( [ + DependencyMetadata::ofEntityId( $context->getEntity()->getId() ), + DependencyMetadata::ofEntityId( $result->getConstraint()->getPropertyId() ), + ] ) ), + ] ) ); + } + + private function downgradeResultStatus( Context $context, CheckResult &$result ) { + $constraint = $result->getConstraint(); + try { + $constraintStatus = $this->constraintParameterParser + ->parseConstraintStatusParameter( $constraint->getConstraintParameters() ); + } catch ( ConstraintParameterException $e ) { + $result = new CheckResult( $context, $constraint, [], CheckResult::STATUS_BAD_PARAMETERS, $e->getViolationMessage() ); + $constraintStatus = null; + } + if ( $constraintStatus === null ) { + // downgrade violation to warning + if ( $result->getStatus() === CheckResult::STATUS_VIOLATION ) { + $result->setStatus( CheckResult::STATUS_WARNING ); + } + } elseif ( $constraintStatus === 'suggestion' ) { + // downgrade violation to suggestion + if ( $result->getStatus() === CheckResult::STATUS_VIOLATION ) { + $result->setStatus( CheckResult::STATUS_SUGGESTION ); + } + $result->addParameter( 'constraint_status', $constraintStatus ); + } else { + if ( $constraintStatus !== 'mandatory' ) { + // @codeCoverageIgnoreStart + throw new LogicException( + "Unknown constraint status '$constraintStatus', " . + "only known statuses are 'mandatory' and 'suggestion'" + ); + // @codeCoverageIgnoreEnd + } + $result->addParameter( 'constraint_status', $constraintStatus ); + } + } + + /** + * @param CheckResult[] $result + * + * @return CheckResult[] + */ + private function sortResult( array $result ) { + if ( count( $result ) < 2 ) { + return $result; + } + + $sortFunction = static function ( CheckResult $a, CheckResult $b ) { + $orderNum = 0; + $order = [ + CheckResult::STATUS_BAD_PARAMETERS => $orderNum++, + CheckResult::STATUS_VIOLATION => $orderNum++, + CheckResult::STATUS_WARNING => $orderNum++, + CheckResult::STATUS_SUGGESTION => $orderNum++, + CheckResult::STATUS_EXCEPTION => $orderNum++, + CheckResult::STATUS_COMPLIANCE => $orderNum++, + CheckResult::STATUS_DEPRECATED => $orderNum++, + CheckResult::STATUS_NOT_IN_SCOPE => $orderNum++, + 'other' => $orderNum++, + ]; + + $statusA = $a->getStatus(); + $statusB = $b->getStatus(); + + $orderA = array_key_exists( $statusA, $order ) ? $order[ $statusA ] : $order[ 'other' ]; + $orderB = array_key_exists( $statusB, $order ) ? $order[ $statusB ] : $order[ 'other' ]; + + if ( $orderA === $orderB ) { + $cursorA = $a->getContextCursor(); + $cursorB = $b->getContextCursor(); + + if ( $cursorA instanceof EntityContextCursor ) { + return $cursorB instanceof EntityContextCursor ? 0 : -1; + } + if ( $cursorB instanceof EntityContextCursor ) { + return $cursorA instanceof EntityContextCursor ? 0 : 1; + } + + $pidA = $cursorA->getSnakPropertyId(); + $pidB = $cursorB->getSnakPropertyId(); + + if ( $pidA === $pidB ) { + $hashA = $cursorA->getSnakHash(); + $hashB = $cursorB->getSnakHash(); + + if ( $hashA === $hashB ) { + if ( $a instanceof NullResult ) { + return $b instanceof NullResult ? 0 : -1; + } + if ( $b instanceof NullResult ) { + return $a instanceof NullResult ? 0 : 1; + } + + $typeA = $a->getConstraint()->getConstraintTypeItemId(); + $typeB = $b->getConstraint()->getConstraintTypeItemId(); + + if ( $typeA == $typeB ) { + return 0; + } else { + return ( $typeA > $typeB ) ? 1 : -1; + } + } else { + return ( $hashA > $hashB ) ? 1 : -1; + } + } else { + return ( $pidA > $pidB ) ? 1 : -1; + } + } else { + return ( $orderA > $orderB ) ? 1 : -1; + } + }; + + uasort( $result, $sortFunction ); + + return $result; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConnectionCheckerHelper.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConnectionCheckerHelper.php new file mode 100644 index 000000000..624d87aee --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConnectionCheckerHelper.php @@ -0,0 +1,98 @@ +getByPropertyId( $propertyId ); + if ( $statementListByPropertyId->isEmpty() ) { + return null; + } else { + return $statementListByPropertyId->toArray()[0]; + } + } + + /** + * Finds a statement with the given property ID and entity ID value. + * + * @param StatementList $statementList + * @param PropertyId $propertyId + * @param EntityId $value + * + * @return Statement|null + */ + public function findStatementWithPropertyAndEntityIdValue( + StatementList $statementList, + PropertyId $propertyId, + EntityId $value + ) { + $statementListByPropertyId = $statementList->getByPropertyId( $propertyId ); + /** @var Statement $statement */ + foreach ( $statementListByPropertyId as $statement ) { + $snak = $statement->getMainSnak(); + if ( $snak instanceof PropertyValueSnak ) { + $dataValue = $snak->getDataValue(); + if ( $dataValue instanceof EntityIdValue && + $dataValue->getEntityId()->equals( $value ) + ) { + return $statement; + } + } + } + return null; + } + + /** + * Finds a statement with the given property ID and one of the given item ID snak values. + * + * @param StatementList $statementList + * @param PropertyId $propertyId + * @param ItemIdSnakValue[] $values + * + * @return Statement|null + */ + public function findStatementWithPropertyAndItemIdSnakValues( + StatementList $statementList, + PropertyId $propertyId, + array $values + ) { + $statementListByPropertyId = $statementList->getByPropertyId( $propertyId ); + /** @var Statement $statement */ + foreach ( $statementListByPropertyId as $statement ) { + $snak = $statement->getMainSnak(); + foreach ( $values as $value ) { + if ( $value->matchesSnak( $snak ) ) { + return $statement; + } + } + } + return null; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterException.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterException.php new file mode 100644 index 000000000..e3339cc1e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterException.php @@ -0,0 +1,38 @@ +getMessageKey() . '⧽'; + parent::__construct( $message ); + + $this->violationMessage = $violationMessage; + } + + /** + * @return ViolationMessage + */ + public function getViolationMessage() { + return $this->violationMessage; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterParser.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterParser.php new file mode 100644 index 000000000..c6c7f88e9 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ConstraintParameterParser.php @@ -0,0 +1,1026 @@ +config = $config; + $this->snakDeserializer = $factory->newSnakDeserializer(); + $this->unitItemConceptBaseUri = $unitItemConceptBaseUri; + } + + /** + * Check if any errors are recorded in the constraint parameters. + * @param array $parameters + * @throws ConstraintParameterException + */ + public function checkError( array $parameters ) { + if ( array_key_exists( '@error', $parameters ) ) { + $error = $parameters['@error']; + if ( array_key_exists( 'toolong', $error ) && $error['toolong'] ) { + $msg = 'wbqc-violation-message-parameters-error-toolong'; + } else { + $msg = 'wbqc-violation-message-parameters-error-unknown'; + } + throw new ConstraintParameterException( new ViolationMessage( $msg ) ); + } + } + + /** + * Require that $parameters contains exactly one $parameterId parameter. + * @param array $parameters + * @param string $parameterId + * @throws ConstraintParameterException + */ + private function requireSingleParameter( array $parameters, $parameterId ) { + if ( count( $parameters[$parameterId] ) !== 1 ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-single' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + } + + /** + * Require that $snak is a {@link PropertyValueSnak}. + * @param Snak $snak + * @param string $parameterId + * @return void + * @throws ConstraintParameterException + */ + private function requireValueParameter( Snak $snak, $parameterId ) { + if ( !( $snak instanceof PropertyValueSnak ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-value' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + } + + /** + * Parse a single entity ID parameter. + * @param array $snakSerialization + * @param string $parameterId + * @throws ConstraintParameterException + * @return EntityId + */ + private function parseEntityIdParameter( array $snakSerialization, $parameterId ) { + $snak = $this->snakDeserializer->deserialize( $snakSerialization ); + $this->requireValueParameter( $snak, $parameterId ); + $value = $snak->getDataValue(); + if ( $value instanceof EntityIdValue ) { + return $value->getEntityId(); + } else { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-entity' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\ConstraintReport\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return string[] class entity ID serializations + */ + public function parseClassParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $classId = $this->config->get( 'WBQualityConstraintsClassId' ); + if ( !array_key_exists( $classId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $classId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $classes = []; + foreach ( $constraintParameters[$classId] as $class ) { + $classes[] = $this->parseEntityIdParameter( $class, $classId )->getSerialization(); + } + return $classes; + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return string 'instance', 'subclass', or 'instanceOrSubclass' + */ + public function parseRelationParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $relationId = $this->config->get( 'WBQualityConstraintsRelationId' ); + if ( !array_key_exists( $relationId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $relationId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $this->requireSingleParameter( $constraintParameters, $relationId ); + $relationEntityId = $this->parseEntityIdParameter( $constraintParameters[$relationId][0], $relationId ); + if ( !( $relationEntityId instanceof ItemId ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-item' ) ) + ->withEntityId( new NumericPropertyId( $relationId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( new EntityIdValue( $relationEntityId ), Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + return $this->mapItemId( $relationEntityId, [ + $this->config->get( 'WBQualityConstraintsInstanceOfRelationId' ) => 'instance', + $this->config->get( 'WBQualityConstraintsSubclassOfRelationId' ) => 'subclass', + $this->config->get( 'WBQualityConstraintsInstanceOrSubclassOfRelationId' ) => 'instanceOrSubclass', + ], $relationId ); + } + + /** + * Parse a single property ID parameter. + * @param array $snakSerialization + * @param string $parameterId used in error messages + * @throws ConstraintParameterException + * @return PropertyId + */ + private function parsePropertyIdParameter( array $snakSerialization, $parameterId ) { + $snak = $this->snakDeserializer->deserialize( $snakSerialization ); + $this->requireValueParameter( $snak, $parameterId ); + $value = $snak->getDataValue(); + if ( $value instanceof EntityIdValue ) { + $id = $value->getEntityId(); + if ( $id instanceof PropertyId ) { + return $id; + } + } + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-property' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return PropertyId + */ + public function parsePropertyParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $propertyId = $this->config->get( 'WBQualityConstraintsPropertyId' ); + if ( !array_key_exists( $propertyId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $propertyId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $this->requireSingleParameter( $constraintParameters, $propertyId ); + return $this->parsePropertyIdParameter( $constraintParameters[$propertyId][0], $propertyId ); + } + + private function parseItemIdParameter( PropertyValueSnak $snak, $parameterId ) { + $dataValue = $snak->getDataValue(); + if ( $dataValue instanceof EntityIdValue ) { + $entityId = $dataValue->getEntityId(); + if ( $entityId instanceof ItemId ) { + return ItemIdSnakValue::fromItemId( $entityId ); + } + } + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-item' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( $dataValue, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @param bool $required whether the parameter is required (error if absent) or not ([] if absent) + * @param string|null $parameterId the property ID to use, defaults to 'qualifier of property constraint' + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return ItemIdSnakValue[] array of values + */ + public function parseItemsParameter( + array $constraintParameters, + $constraintTypeItemId, + $required, + $parameterId = null + ) { + $this->checkError( $constraintParameters ); + if ( $parameterId === null ) { + $parameterId = $this->config->get( 'WBQualityConstraintsQualifierOfPropertyConstraintId' ); + } + if ( !array_key_exists( $parameterId, $constraintParameters ) ) { + if ( $required ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } else { + return []; + } + } + + $values = []; + foreach ( $constraintParameters[$parameterId] as $parameter ) { + $snak = $this->snakDeserializer->deserialize( $parameter ); + switch ( true ) { + case $snak instanceof PropertyValueSnak: + $values[] = $this->parseItemIdParameter( $snak, $parameterId ); + break; + case $snak instanceof PropertySomeValueSnak: + $values[] = ItemIdSnakValue::someValue(); + break; + case $snak instanceof PropertyNoValueSnak: + $values[] = ItemIdSnakValue::noValue(); + break; + } + } + return $values; + } + + /** + * Parse a parameter that must contain item IDs. + * @param array $constraintParameters see {@link \WikibaseQuality\ConstraintReport\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @param bool $required whether the parameter is required (error if absent) or not ([] if absent) + * @param string $parameterId the property ID to use + * @throws ConstraintParameterException + * @return ItemId[] + */ + private function parseItemIdsParameter( + array $constraintParameters, + string $constraintTypeItemId, + bool $required, + string $parameterId + ): array { + return array_map( static function ( ItemIdSnakValue $value ) use ( $parameterId ): ItemId { + if ( $value->isValue() ) { + return $value->getItemId(); + } else { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-value' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + }, $this->parseItemsParameter( + $constraintParameters, + $constraintTypeItemId, + $required, + $parameterId + ) ); + } + + /** + * Map an item ID parameter to a well-known value or throw an appropriate error. + * @throws ConstraintParameterException + * @return mixed elements of $mapping + */ + private function mapItemId( ItemId $itemId, array $mapping, string $parameterId ) { + $serialization = $itemId->getSerialization(); + if ( array_key_exists( $serialization, $mapping ) ) { + return $mapping[$serialization]; + } else { + $allowed = array_map( static function ( $id ) { + return new ItemId( $id ); + }, array_keys( $mapping ) ); + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-oneof' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withEntityIdList( $allowed, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return PropertyId[] + */ + public function parsePropertiesParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $propertyId = $this->config->get( 'WBQualityConstraintsPropertyId' ); + if ( !array_key_exists( $propertyId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $propertyId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $parameters = $constraintParameters[$propertyId]; + if ( count( $parameters ) === 1 && + $this->snakDeserializer->deserialize( $parameters[0] ) instanceof PropertyNoValueSnak + ) { + return []; + } + + $properties = []; + foreach ( $parameters as $parameter ) { + $properties[] = $this->parsePropertyIdParameter( $parameter, $propertyId ); + } + return $properties; + } + + /** + * @param array $snakSerialization + * @param string $parameterId + * @throws ConstraintParameterException + * @return DataValue|null + */ + private function parseValueOrNoValueParameter( array $snakSerialization, $parameterId ) { + $snak = $this->snakDeserializer->deserialize( $snakSerialization ); + if ( $snak instanceof PropertyValueSnak ) { + return $snak->getDataValue(); + } elseif ( $snak instanceof PropertyNoValueSnak ) { + return null; + } else { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-value-or-novalue' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + } + + /** + * @param array $snakSerialization + * @param string $parameterId + * @return DataValue|null + */ + private function parseValueOrNoValueOrNowParameter( array $snakSerialization, $parameterId ) { + try { + return $this->parseValueOrNoValueParameter( $snakSerialization, $parameterId ); + } catch ( ConstraintParameterException $e ) { + // unknown value means “now” + return new NowValue(); + } + } + + /** + * Checks whether there is exactly one non-null quantity with the given unit. + * @param ?DataValue $min + * @param ?DataValue $max + * @param string $unit + * @return bool + */ + private function exactlyOneQuantityWithUnit( ?DataValue $min, ?DataValue $max, $unit ) { + if ( !( $min instanceof UnboundedQuantityValue ) || + !( $max instanceof UnboundedQuantityValue ) + ) { + return false; + } + + return ( $min->getUnit() === $unit ) !== ( $max->getUnit() === $unit ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $minimumId + * @param string $maximumId + * @param string $constraintTypeItemId used in error messages + * @param string $type 'quantity' or 'time' (can be data type or data value type) + * + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return DataValue[] if the parameter is invalid or missing + */ + private function parseRangeParameter( array $constraintParameters, $minimumId, $maximumId, $constraintTypeItemId, $type ) { + $this->checkError( $constraintParameters ); + if ( !array_key_exists( $minimumId, $constraintParameters ) || + !array_key_exists( $maximumId, $constraintParameters ) + ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-range-parameters-needed' ) ) + ->withDataValueType( $type ) + ->withEntityId( new NumericPropertyId( $minimumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withEntityId( new NumericPropertyId( $maximumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ); + } + + $this->requireSingleParameter( $constraintParameters, $minimumId ); + $this->requireSingleParameter( $constraintParameters, $maximumId ); + $parseFunction = $type === 'time' ? 'parseValueOrNoValueOrNowParameter' : 'parseValueOrNoValueParameter'; + $min = $this->$parseFunction( $constraintParameters[$minimumId][0], $minimumId ); + $max = $this->$parseFunction( $constraintParameters[$maximumId][0], $maximumId ); + + $yearUnit = $this->config->get( 'WBQualityConstraintsYearUnit' ); + if ( $this->exactlyOneQuantityWithUnit( $min, $max, $yearUnit ) ) { + throw new ConstraintParameterException( + new ViolationMessage( 'wbqc-violation-message-range-parameters-one-year' ) + ); + } + if ( $min === null && $max === null || + $min !== null && $max !== null && $min->equals( $max ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-range-parameters-same' ) ) + ->withEntityId( new NumericPropertyId( $minimumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withEntityId( new NumericPropertyId( $maximumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + return [ $min, $max ]; + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return DataValue[] a pair of two data values, either of which may be null to signify an open range + */ + public function parseQuantityRangeParameter( array $constraintParameters, $constraintTypeItemId ) { + return $this->parseRangeParameter( + $constraintParameters, + $this->config->get( 'WBQualityConstraintsMinimumQuantityId' ), + $this->config->get( 'WBQualityConstraintsMaximumQuantityId' ), + $constraintTypeItemId, + 'quantity' + ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return DataValue[] a pair of two data values, either of which may be null to signify an open range + */ + public function parseTimeRangeParameter( array $constraintParameters, $constraintTypeItemId ) { + return $this->parseRangeParameter( + $constraintParameters, + $this->config->get( 'WBQualityConstraintsMinimumDateId' ), + $this->config->get( 'WBQualityConstraintsMaximumDateId' ), + $constraintTypeItemId, + 'time' + ); + } + + /** + * Parse language parameter. + * @param array $constraintParameters + * @throws ConstraintParameterException + * @return string[] + */ + public function parseLanguageParameter( array $constraintParameters, $constraintTypeItemId ): array { + $this->checkError( $constraintParameters ); + $languagePropertyId = $this->config->get( 'WBQualityConstraintsLanguagePropertyId' ); + if ( !array_key_exists( $languagePropertyId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $languagePropertyId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $languages = []; + foreach ( $constraintParameters[$languagePropertyId] as $snak ) { + $languages[] = $this->parseStringParameter( $snak, $languagePropertyId ); + } + return $languages; + } + + /** + * Parse a single string parameter. + * @param array $snakSerialization + * @param string $parameterId + * @throws ConstraintParameterException + * @return string + */ + private function parseStringParameter( array $snakSerialization, $parameterId ) { + $snak = $this->snakDeserializer->deserialize( $snakSerialization ); + $this->requireValueParameter( $snak, $parameterId ); + $value = $snak->getDataValue(); + if ( $value instanceof StringValue ) { + return $value->getValue(); + } else { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-string' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return string + */ + public function parseNamespaceParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $namespaceId = $this->config->get( 'WBQualityConstraintsNamespaceId' ); + if ( !array_key_exists( $namespaceId, $constraintParameters ) ) { + return ''; + } + + $this->requireSingleParameter( $constraintParameters, $namespaceId ); + return $this->parseStringParameter( $constraintParameters[$namespaceId][0], $namespaceId ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return string + */ + public function parseFormatParameter( array $constraintParameters, $constraintTypeItemId ) { + $this->checkError( $constraintParameters ); + $formatId = $this->config->get( 'WBQualityConstraintsFormatAsARegularExpressionId' ); + if ( !array_key_exists( $formatId, $constraintParameters ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withEntityId( new NumericPropertyId( $formatId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + } + + $this->requireSingleParameter( $constraintParameters, $formatId ); + return $this->parseStringParameter( $constraintParameters[$formatId][0], $formatId ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @throws ConstraintParameterException if the parameter is invalid + * @return EntityId[] + */ + public function parseExceptionParameter( array $constraintParameters ) { + $this->checkError( $constraintParameters ); + $exceptionId = $this->config->get( 'WBQualityConstraintsExceptionToConstraintId' ); + if ( !array_key_exists( $exceptionId, $constraintParameters ) ) { + return []; + } + + return array_map( + function ( $snakSerialization ) use ( $exceptionId ) { + return $this->parseEntityIdParameter( $snakSerialization, $exceptionId ); + }, + $constraintParameters[$exceptionId] + ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @throws ConstraintParameterException if the parameter is invalid + * @return string|null 'mandatory', 'suggestion' or null + */ + public function parseConstraintStatusParameter( array $constraintParameters ) { + $this->checkError( $constraintParameters ); + $constraintStatusId = $this->config->get( 'WBQualityConstraintsConstraintStatusId' ); + if ( !array_key_exists( $constraintStatusId, $constraintParameters ) ) { + return null; + } + + $mandatoryId = $this->config->get( 'WBQualityConstraintsMandatoryConstraintId' ); + $supportedStatuses = [ new ItemId( $mandatoryId ) ]; + if ( $this->config->get( 'WBQualityConstraintsEnableSuggestionConstraintStatus' ) ) { + $suggestionId = $this->config->get( 'WBQualityConstraintsSuggestionConstraintId' ); + $supportedStatuses[] = new ItemId( $suggestionId ); + } else { + $suggestionId = null; + } + + $this->requireSingleParameter( $constraintParameters, $constraintStatusId ); + $snak = $this->snakDeserializer->deserialize( $constraintParameters[$constraintStatusId][0] ); + $this->requireValueParameter( $snak, $constraintStatusId ); + '@phan-var \Wikibase\DataModel\Snak\PropertyValueSnak $snak'; + $dataValue = $snak->getDataValue(); + '@phan-var EntityIdValue $dataValue'; + $entityId = $dataValue->getEntityId(); + $statusId = $entityId->getSerialization(); + + if ( $statusId === $mandatoryId ) { + return 'mandatory'; + } elseif ( $statusId === $suggestionId ) { + return 'suggestion'; + } else { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-oneof' ) ) + ->withEntityId( new NumericPropertyId( $constraintStatusId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withEntityIdList( + $supportedStatuses, + Role::CONSTRAINT_PARAMETER_VALUE + ) + ); + } + } + + /** + * Require that $dataValue is a {@link MonolingualTextValue}. + * @param DataValue $dataValue + * @param string $parameterId + * @return void + * @throws ConstraintParameterException + */ + private function requireMonolingualTextParameter( DataValue $dataValue, $parameterId ) { + if ( !( $dataValue instanceof MonolingualTextValue ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-monolingualtext' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withDataValue( $dataValue, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * Parse a series of monolingual text snaks (serialized) into a map from language code to string. + * + * @param array $snakSerializations + * @param string $parameterId + * @throws ConstraintParameterException if invalid snaks are found or a language has multiple texts + * @return MultilingualTextValue + */ + private function parseMultilingualTextParameter( array $snakSerializations, $parameterId ) { + $result = []; + + foreach ( $snakSerializations as $snakSerialization ) { + $snak = $this->snakDeserializer->deserialize( $snakSerialization ); + $this->requireValueParameter( $snak, $parameterId ); + + $value = $snak->getDataValue(); + $this->requireMonolingualTextParameter( $value, $parameterId ); + /** @var MonolingualTextValue $value */ + '@phan-var MonolingualTextValue $value'; + + $code = $value->getLanguageCode(); + if ( array_key_exists( $code, $result ) ) { + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-single-per-language' ) ) + ->withEntityId( new NumericPropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ->withLanguage( $code ) + ); + } + + $result[$code] = $value; + } + + return new MultilingualTextValue( $result ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @throws ConstraintParameterException if the parameter is invalid + * @return MultilingualTextValue + */ + public function parseSyntaxClarificationParameter( array $constraintParameters ) { + $syntaxClarificationId = $this->config->get( 'WBQualityConstraintsSyntaxClarificationId' ); + + if ( !array_key_exists( $syntaxClarificationId, $constraintParameters ) ) { + return new MultilingualTextValue( [] ); + } + + $syntaxClarifications = $this->parseMultilingualTextParameter( + $constraintParameters[$syntaxClarificationId], + $syntaxClarificationId + ); + + return $syntaxClarifications; + } + + /** + * Parse the constraint scope parameters: + * the context types and entity types where the constraint should be checked. + * Depending on configuration, this may be the same property ID or two different ones. + * + * @param array $constraintParameters see {@link \WikibaseQuality\ConstraintReport\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @param string[] $validContextTypes a list of Context::TYPE_* constants which are valid for this constraint type. + * If one of the specified scopes is not in this list, a ConstraintParameterException is thrown. + * @param string[] $validEntityTypes a list of entity types which are valid for this constraint type. + * If one of the specified entity types is not in this list, a ConstraintParameterException is thrown. + * @throws ConstraintParameterException + * @return array [ string[]|null $contextTypes, string[]|null $entityTypes ] + * the context types and entity types in the parameters (each may be null if not specified) + * @suppress PhanTypeArraySuspicious + */ + public function parseConstraintScopeParameters( + array $constraintParameters, + string $constraintTypeItemId, + array $validContextTypes, + array $validEntityTypes + ): array { + $contextTypeParameterId = $this->config->get( 'WBQualityConstraintsConstraintScopeId' ); + $contextTypeItemIds = $this->parseItemIdsParameter( + $constraintParameters, + $constraintTypeItemId, + false, + $contextTypeParameterId + ); + $entityTypeParameterId = $this->config->get( 'WBQualityConstraintsConstraintEntityTypesId' ); + $entityTypeItemIds = $this->parseItemIdsParameter( + $constraintParameters, + $constraintTypeItemId, + false, + $entityTypeParameterId + ); + + $contextTypeMapping = $this->getConstraintScopeContextTypeMapping(); + $entityTypeMapping = $this->getEntityTypeMapping(); + + // these nulls will turn into arrays the first time $contextTypes[] or $entityTypes[] is reached, + // so they’ll be returned as null iff the parameter was not specified + $contextTypes = null; + $entityTypes = null; + + if ( $contextTypeParameterId === $entityTypeParameterId ) { + $itemIds = $contextTypeItemIds; + $mapping = $contextTypeMapping + $entityTypeMapping; + foreach ( $itemIds as $itemId ) { + $mapped = $this->mapItemId( $itemId, $mapping, $contextTypeParameterId ); + if ( in_array( $mapped, $contextTypeMapping, true ) ) { + $contextTypes[] = $mapped; + } else { + $entityTypes[] = $mapped; + } + } + } else { + foreach ( $contextTypeItemIds as $contextTypeItemId ) { + $contextTypes[] = $this->mapItemId( + $contextTypeItemId, + $contextTypeMapping, + $contextTypeParameterId + ); + } + foreach ( $entityTypeItemIds as $entityTypeItemId ) { + $entityTypes[] = $this->mapItemId( + $entityTypeItemId, + $entityTypeMapping, + $entityTypeParameterId + ); + } + } + + $this->checkValidScope( $constraintTypeItemId, $contextTypes, $validContextTypes ); + $this->checkValidScope( $constraintTypeItemId, $entityTypes, $validEntityTypes ); + + return [ $contextTypes, $entityTypes ]; + } + + private function checkValidScope( string $constraintTypeItemId, ?array $types, array $validTypes ): void { + $invalidTypes = array_diff( $types ?: [], $validTypes ); + if ( $invalidTypes !== [] ) { + $invalidType = array_pop( $invalidTypes ); + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-invalid-scope' ) ) + ->withConstraintScope( $invalidType, Role::CONSTRAINT_PARAMETER_VALUE ) + ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) + ->withConstraintScopeList( $validTypes, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * Turn an item ID into a full unit string (using the concept URI). + * + * @param ItemId $unitId + * @return string unit + */ + private function parseUnitParameter( ItemId $unitId ) { + return $this->unitItemConceptBaseUri . $unitId->getSerialization(); + } + + /** + * Turn an ItemIdSnakValue into a single unit parameter. + * + * @param ItemIdSnakValue $item + * @return UnitsParameter + * @throws ConstraintParameterException + */ + private function parseUnitItem( ItemIdSnakValue $item ) { + switch ( true ) { + case $item->isValue(): + $unit = $this->parseUnitParameter( $item->getItemId() ); + return new UnitsParameter( + [ $item->getItemId() ], + [ UnboundedQuantityValue::newFromNumber( 1, $unit ) ], + false + ); + case $item->isSomeValue(): + $qualifierId = $this->config->get( 'WBQualityConstraintsQualifierOfPropertyConstraintId' ); + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-value-or-novalue' ) ) + ->withEntityId( new NumericPropertyId( $qualifierId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) + ); + case $item->isNoValue(): + return new UnitsParameter( [], [], true ); + } + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return UnitsParameter + */ + public function parseUnitsParameter( array $constraintParameters, $constraintTypeItemId ) { + $items = $this->parseItemsParameter( $constraintParameters, $constraintTypeItemId, true ); + $unitItems = []; + $unitQuantities = []; + $unitlessAllowed = false; + + foreach ( $items as $item ) { + $unit = $this->parseUnitItem( $item ); + $unitItems = array_merge( $unitItems, $unit->getUnitItemIds() ); + $unitQuantities = array_merge( $unitQuantities, $unit->getUnitQuantities() ); + $unitlessAllowed = $unitlessAllowed || $unit->getUnitlessAllowed(); + } + + if ( $unitQuantities === [] && !$unitlessAllowed ) { + throw new LogicException( + 'The "units" parameter is required, and yet we seem to be missing any allowed unit' + ); + } + + return new UnitsParameter( $unitItems, $unitQuantities, $unitlessAllowed ); + } + + private function getEntityTypeMapping(): array { + return [ + $this->config->get( 'WBQualityConstraintsWikibaseItemId' ) => 'item', + $this->config->get( 'WBQualityConstraintsWikibasePropertyId' ) => 'property', + $this->config->get( 'WBQualityConstraintsWikibaseLexemeId' ) => 'lexeme', + $this->config->get( 'WBQualityConstraintsWikibaseFormId' ) => 'form', + $this->config->get( 'WBQualityConstraintsWikibaseSenseId' ) => 'sense', + $this->config->get( 'WBQualityConstraintsWikibaseMediaInfoId' ) => 'mediainfo', + ]; + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return EntityTypesParameter + */ + public function parseEntityTypesParameter( array $constraintParameters, $constraintTypeItemId ) { + $entityTypes = []; + $entityTypeItemIds = []; + $parameterId = $this->config->get( 'WBQualityConstraintsQualifierOfPropertyConstraintId' ); + $itemIds = $this->parseItemIdsParameter( + $constraintParameters, + $constraintTypeItemId, + true, + $parameterId + ); + + $mapping = $this->getEntityTypeMapping(); + foreach ( $itemIds as $itemId ) { + $entityType = $this->mapItemId( $itemId, $mapping, $parameterId ); + $entityTypes[] = $entityType; + $entityTypeItemIds[] = $itemId; + } + + if ( empty( $entityTypes ) ) { + // @codeCoverageIgnoreStart + throw new LogicException( + 'The "entity types" parameter is required, ' . + 'and yet we seem to be missing any allowed entity type' + ); + // @codeCoverageIgnoreEnd + } + + return new EntityTypesParameter( $entityTypes, $entityTypeItemIds ); + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @throws ConstraintParameterException if the parameter is invalid + * @return PropertyId[] + */ + public function parseSeparatorsParameter( array $constraintParameters ) { + $separatorId = $this->config->get( 'WBQualityConstraintsSeparatorId' ); + + if ( !array_key_exists( $separatorId, $constraintParameters ) ) { + return []; + } + + $parameters = $constraintParameters[$separatorId]; + $separators = []; + + foreach ( $parameters as $parameter ) { + $separators[] = $this->parsePropertyIdParameter( $parameter, $separatorId ); + } + + return $separators; + } + + private function getConstraintScopeContextTypeMapping(): array { + return [ + $this->config->get( 'WBQualityConstraintsConstraintCheckedOnMainValueId' ) => Context::TYPE_STATEMENT, + $this->config->get( 'WBQualityConstraintsConstraintCheckedOnQualifiersId' ) => Context::TYPE_QUALIFIER, + $this->config->get( 'WBQualityConstraintsConstraintCheckedOnReferencesId' ) => Context::TYPE_REFERENCE, + ]; + } + + private function getPropertyScopeContextTypeMapping(): array { + return [ + $this->config->get( 'WBQualityConstraintsAsMainValueId' ) => Context::TYPE_STATEMENT, + $this->config->get( 'WBQualityConstraintsAsQualifiersId' ) => Context::TYPE_QUALIFIER, + $this->config->get( 'WBQualityConstraintsAsReferencesId' ) => Context::TYPE_REFERENCE, + ]; + } + + /** + * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} + * @param string $constraintTypeItemId used in error messages + * @throws ConstraintParameterException if the parameter is invalid or missing + * @return string[] list of Context::TYPE_* constants + */ + public function parsePropertyScopeParameter( array $constraintParameters, $constraintTypeItemId ) { + $contextTypes = []; + $parameterId = $this->config->get( 'WBQualityConstraintsPropertyScopeId' ); + $itemIds = $this->parseItemIdsParameter( + $constraintParameters, + $constraintTypeItemId, + true, + $parameterId + ); + + $mapping = $this->getPropertyScopeContextTypeMapping(); + foreach ( $itemIds as $itemId ) { + $contextTypes[] = $this->mapItemId( $itemId, $mapping, $parameterId ); + } + + if ( empty( $contextTypes ) ) { + // @codeCoverageIgnoreStart + throw new LogicException( + 'The "property scope" parameter is required, ' . + 'and yet we seem to be missing any allowed scope' + ); + // @codeCoverageIgnoreEnd + } + + return $contextTypes; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/DummySparqlHelper.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/DummySparqlHelper.php new file mode 100644 index 000000000..0f0bcb595 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/DummySparqlHelper.php @@ -0,0 +1,54 @@ +entityTypes = $entityTypes; + $this->entityTypeItemIds = $entityTypeItemIds; + } + + /** + * @return string[] The allowed entity types as strings. + * @see EntityDocument::getType() + */ + public function getEntityTypes() { + return $this->entityTypes; + } + + /** + * @return ItemId[] The item IDs of the allowed entity types. + */ + public function getEntityTypeItemIds() { + return $this->entityTypeItemIds; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/LoggingHelper.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/LoggingHelper.php new file mode 100644 index 000000000..85a5fe871 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/LoggingHelper.php @@ -0,0 +1,307 @@ +dataFactory = $dataFactory; + $this->logger = $logger; + $this->constraintCheckDurationLimits = [ + 'info' => $config->get( 'WBQualityConstraintsCheckDurationInfoSeconds' ), + 'warning' => $config->get( 'WBQualityConstraintsCheckDurationWarningSeconds' ), + ]; + $this->constraintCheckOnEntityDurationLimits = [ + 'info' => $config->get( 'WBQualityConstraintsCheckOnEntityDurationInfoSeconds' ), + 'warning' => $config->get( 'WBQualityConstraintsCheckOnEntityDurationWarningSeconds' ), + ]; + } + + /** + * Find the longest limit in $limits which the $durationSeconds exceeds, + * and return it along with the associated log level. + * + * @param float $durationSeconds + * @return array [ $limitSeconds, $logLevel ] + */ + private function findLimit( $limits, $durationSeconds ) { + $limitSeconds = null; + $logLevel = null; + + foreach ( $limits as $level => $limit ) { + if ( + // duration exceeds this limit + isset( $limit ) && $durationSeconds > $limit && + // this limit is longer than previous longest limit + ( $limitSeconds === null || $limit > $limitSeconds ) + ) { + $limitSeconds = $limit; + $logLevel = $level; + } + } + + return [ $limitSeconds, $logLevel ]; + } + + /** + * Log a single constraint check. + * The constraint check is tracked on the statsd data factory, + * and also logged with the logger interface if it took longer than a certain time. + * Multiple limits corresponding to different log levels can be specified in the configuration; + * checks that exceed a higher limit are logged at a more severe level. + * + * @param Context $context + * @param Constraint $constraint + * @param CheckResult $result + * @param string $constraintCheckerClass + * @param float $durationSeconds + * @param string $method Use __METHOD__. + */ + public function logConstraintCheck( + Context $context, + Constraint $constraint, + CheckResult $result, + $constraintCheckerClass, + $durationSeconds, + $method + ) { + $constraintCheckerClassShortName = substr( strrchr( $constraintCheckerClass, '\\' ), 1 ); + $constraintTypeItemId = $constraint->getConstraintTypeItemId(); + + $this->dataFactory->timing( + 'wikibase.quality.constraints.check.timing.' . + $constraintTypeItemId . '-' . + $constraintCheckerClassShortName, + $durationSeconds * 1000 + ); + + // find the longest limit (and associated log level) that the duration exceeds + list( $limitSeconds, $logLevel ) = $this->findLimit( + $this->constraintCheckDurationLimits, + $durationSeconds + ); + if ( $limitSeconds === null ) { + return; + } + if ( $context->getType() !== Context::TYPE_STATEMENT ) { + // TODO log less details but still log something + return; + } + + $resultMessage = $result->getMessage(); + if ( $resultMessage !== null ) { + $resultMessageKey = $resultMessage->getMessageKey(); + } else { + $resultMessageKey = null; + } + + $this->logger->log( + $logLevel, + 'Constraint check with {constraintCheckerClassShortName} ' . + 'took longer than {limitSeconds} second(s) ' . + '(duration: {durationSeconds} seconds).', + [ + 'method' => $method, + 'loggingMethod' => __METHOD__, + 'durationSeconds' => $durationSeconds, + 'limitSeconds' => $limitSeconds, + 'constraintId' => $constraint->getConstraintId(), + 'constraintPropertyId' => $constraint->getPropertyId()->getSerialization(), + 'constraintTypeItemId' => $constraintTypeItemId, + 'constraintParameters' => json_encode( $constraint->getConstraintParameters() ), + 'constraintCheckerClass' => $constraintCheckerClass, + 'constraintCheckerClassShortName' => $constraintCheckerClassShortName, + 'entityId' => $context->getEntity()->getId()->getSerialization(), + 'statementGuid' => $context->getSnakStatement()->getGuid(), + 'resultStatus' => $result->getStatus(), + 'resultParameters' => json_encode( $result->getParameters() ), + 'resultMessage' => $resultMessageKey, + ] + ); + } + + /** + * Log a full constraint check on an entity. + * The constraint check is tracked on the statsd data factory, + * and also logged with the logger interface if it took longer than a certain time. + * Multiple limits corresponding to different log levels can be specified in the configuration; + * checks that exceed a higher limit are logged at a more severe level. + * + * + * @param EntityId $entityId + * @param CheckResult[] $checkResults + * @param float $durationSeconds + */ + public function logConstraintCheckOnEntity( + EntityId $entityId, + array $checkResults, + $durationSeconds, + $method + ) { + $this->dataFactory->timing( + 'wikibase.quality.constraints.check.entity.timing', + $durationSeconds * 1000 + ); + + // find the longest limit (and associated log level) that the duration exceeds + list( $limitSeconds, $logLevel ) = $this->findLimit( + $this->constraintCheckOnEntityDurationLimits, + $durationSeconds + ); + if ( $limitSeconds === null ) { + return; + } + + $this->logger->log( + $logLevel, + 'Full constraint check on {entityId} ' . + 'took longer than {limitSeconds} second(s) ' . + '(duration: {durationSeconds} seconds).', + [ + 'method' => $method, + 'loggingMethod' => __METHOD__, + 'durationSeconds' => $durationSeconds, + 'limitSeconds' => $limitSeconds, + 'entityId' => $entityId->getSerialization(), + // $checkResults currently not logged + ] + ); + } + + /** + * Log a cache hit for a complete constraint check result for the given entity ID. + * + * @param EntityId $entityId + */ + public function logCheckConstraintsCacheHit( EntityId $entityId ) { + $this->dataFactory->increment( + 'wikibase.quality.constraints.cache.entity.hit' + ); + } + + /** + * Log cache misses for a complete constraint check result for the given entity IDs. + * + * @param EntityId[] $entityIds + */ + public function logCheckConstraintsCacheMisses( array $entityIds ) { + $this->dataFactory->updateCount( + 'wikibase.quality.constraints.cache.entity.miss', + count( $entityIds ) + ); + } + + /** + * Log that the dependency metadata for a check result had an empty set of entity IDs. + * This should never happen – at least the entity being checked should always be contained. + */ + public function logEmptyDependencyMetadata() { + $this->logger->log( + 'warning', + 'Dependency metadata for constraint check result had empty set of entity IDs.', + [ + 'loggingMethod' => __METHOD__, + // callers of this method don’t have much information to pass to us, + // so for now we don’t log any other structured data + // and hope that the request URL provides enough information + ] + ); + } + + /** + * Log that the dependency metadata for a check result has a very large set of entity IDs. + * + * @param EntityId[] $entityIds + * @param int $maxRevisionIds + */ + public function logHugeDependencyMetadata( array $entityIds, $maxRevisionIds ) { + $this->logger->log( + 'warning', + 'Dependency metadata for constraint check result has huge set of entity IDs ' . + '(count ' . count( $entityIds ) . ', limit ' . $maxRevisionIds . '); ' . + 'caching disabled for this check result.', + [ + 'loggingMethod' => __METHOD__, + 'entityIds' => json_encode( + array_map( + static function ( EntityId $entityId ) { + return $entityId->getSerialization(); + }, + $entityIds + ) + ), + 'maxRevisionIds' => $maxRevisionIds, + ] + ); + } + + public function logSparqlHelperTooManyRequestsRetryAfterPresent( + ConvertibleTimestamp $retryAfterTime, + MWHttpRequest $request + ) { + $this->logger->notice( + 'Sparql API replied with status 429 and a retry-after header. Requesting to retry after {retryAfterTime}', + [ + 'retryAfterTime' => $retryAfterTime, + 'responseHeaders' => json_encode( $request->getResponseHeaders() ), + 'responseContent' => $request->getContent(), + ] + ); + } + + public function logSparqlHelperTooManyRequestsRetryAfterInvalid( MWHttpRequest $request ) { + $this->logger->warning( + 'Sparql API replied with status 429 and no valid retry-after header.', + [ + 'responseHeaders' => json_encode( $request->getResponseHeaders() ), + 'responseContent' => $request->getContent(), + ] + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/NowValue.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/NowValue.php new file mode 100644 index 000000000..0394b638e --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/NowValue.php @@ -0,0 +1,50 @@ +config = $config; + $this->timeParser = new IsoTimestampParser(); + $this->timeCalculator = new TimeValueCalculator(); + $this->timeValueComparer = new TimeValueComparer( $this->timeCalculator ); + $this->unitConverter = $unitConverter; + } + + /** + * @param UnboundedQuantityValue $value + * @return UnboundedQuantityValue $value converted to standard units if possible, otherwise unchanged $value. + */ + private function standardize( UnboundedQuantityValue $value ) { + if ( $this->unitConverter !== null ) { + $standard = $this->unitConverter->toStandardUnits( $value ); + if ( $standard !== null ) { + return $standard; + } else { + return $value; + } + } else { + return $value; + } + } + + /** + * Compare two values. + * If one of them is null, return 0 (equal). + * + * @param DataValue|null $lhs left-hand side + * @param DataValue|null $rhs right-hand side + * + * @throws InvalidArgumentException if the values do not both have the same, supported data value type + * @return integer An integer less than, equal to, or greater than zero + * when $lhs is respectively less than, equal to, or greater than $rhs. + * (In other words, just like the “spaceship” operator <=>.) + */ + public function getComparison( DataValue $lhs = null, DataValue $rhs = null ) { + if ( $lhs === null || $rhs === null ) { + return 0; + } + + if ( $lhs->getType() !== $rhs->getType() ) { + throw new InvalidArgumentException( 'Different data value types' ); + } + + switch ( $lhs->getType() ) { + case 'time': + /** @var TimeValue $lhs */ + /** @var TimeValue $rhs */ + '@phan-var TimeValue $lhs'; + '@phan-var TimeValue $rhs'; + return $this->timeValueComparer->getComparison( $lhs, $rhs ); + case 'quantity': + /** @var QuantityValue|UnboundedQuantityValue $lhs */ + /** @var QuantityValue|UnboundedQuantityValue $rhs */ + '@phan-var QuantityValue|UnboundedQuantityValue $lhs'; + '@phan-var QuantityValue|UnboundedQuantityValue $rhs'; + $lhsStandard = $this->standardize( $lhs ); + $rhsStandard = $this->standardize( $rhs ); + return $lhsStandard->getAmount()->compare( $rhsStandard->getAmount() ); + } + + throw new InvalidArgumentException( 'Unsupported data value type' ); + } + + /** + * Computes $minuend - $subtrahend, in a format depending on the data type. + * For time values, the difference is in seconds; + * for quantity values, the difference is the numerical difference between the quantities, + * after attempting normalization of each side. + * + * @param TimeValue|QuantityValue|UnboundedQuantityValue $minuend + * @param TimeValue|QuantityValue|UnboundedQuantityValue $subtrahend + * + * @throws InvalidArgumentException if the values do not both have the same, supported data value type + * @return UnboundedQuantityValue + */ + public function getDifference( DataValue $minuend, DataValue $subtrahend ) { + if ( $minuend->getType() === 'time' && $subtrahend->getType() === 'time' ) { + $minuendSeconds = $this->timeCalculator->getTimestamp( $minuend ); + $subtrahendSeconds = $this->timeCalculator->getTimestamp( $subtrahend ); + return UnboundedQuantityValue::newFromNumber( + $minuendSeconds - $subtrahendSeconds, + $this->config->get( 'WBQualityConstraintsSecondUnit' ) + ); + } + if ( $minuend->getType() === 'quantity' && $subtrahend->getType() === 'quantity' ) { + $minuendStandard = $this->standardize( $minuend ); + $subtrahendStandard = $this->standardize( $subtrahend ); + $minuendValue = $minuendStandard->getAmount()->getValueFloat(); + $subtrahendValue = $subtrahendStandard->getAmount()->getValueFloat(); + $diff = $minuendValue - $subtrahendValue; + // we don’t check whether both quantities have the same standard unit – + // that’s the job of a different constraint type, Units (T164372) + return UnboundedQuantityValue::newFromNumber( $diff, $minuendStandard->getUnit() ); + } + + throw new InvalidArgumentException( 'Unsupported or different data value types' ); + } + + public function getDifferenceInYears( TimeValue $minuend, TimeValue $subtrahend ) { + if ( !preg_match( '/^([-+]\d{1,16})-(.*)$/', $minuend->getTime(), $minuendMatches ) || + !preg_match( '/^([-+]\d{1,16})-(.*)$/', $subtrahend->getTime(), $subtrahendMatches ) + ) { + throw new InvalidArgumentException( 'TimeValue::getTime() did not match expected format' ); + } + $minuendYear = (float)$minuendMatches[1]; + $subtrahendYear = (float)$subtrahendMatches[1]; + $minuendRest = $minuendMatches[2]; + $subtrahendRest = $subtrahendMatches[2]; + + // calculate difference of years + $diff = $minuendYear - $subtrahendYear; + if ( $minuendYear > 0.0 && $subtrahendYear < 0.0 ) { + $diff -= 1.0; // there is no year 0, remove it from difference + } elseif ( $minuendYear < 0.0 && $subtrahendYear > 0.0 ) { + $diff -= -1.0; // there is no year 0, remove it from negative difference + } + + // adjust for date within year by parsing the month-day part within the same year + $minuendDateValue = $this->timeParser->parse( '+0000000000001970-' . $minuendRest ); + $subtrahendDateValue = $this->timeParser->parse( '+0000000000001970-' . $subtrahendRest ); + $minuendDateSeconds = $this->timeCalculator->getTimestamp( $minuendDateValue ); + $subtrahendDateSeconds = $this->timeCalculator->getTimestamp( $subtrahendDateValue ); + if ( $minuendDateSeconds < $subtrahendDateSeconds ) { + // difference in the last year is actually less than one full year + // e. g. 1975-03-01 - 1974-09-01 is just six months + // (we don’t need sub-year precision in the difference, adjusting by 0.5 is enough) + $diff -= 0.5; + } elseif ( $minuendDateSeconds > $subtrahendDateSeconds ) { + // difference in the last year is actually more than one full year + // e. g. 1975-09-01 - 1974-03-01 is 18 months + // (we don’t need sub-year precision in the difference, adjusting by 0.5 is enough) + $diff += 0.5; + } + + $unit = $this->config->get( 'WBQualityConstraintsYearUnit' ); + return UnboundedQuantityValue::newFromNumber( $diff, $unit ); + } + + public function isFutureTime( TimeValue $timeValue ) { + return $this->timeValueComparer->isFutureTime( $timeValue ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelper.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelper.php new file mode 100644 index 000000000..3713d7979 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelper.php @@ -0,0 +1,910 @@ +rdfVocabulary = $rdfVocabulary; + $this->entityIdParser = $entityIdParser; + $this->propertyDataTypeLookup = $propertyDataTypeLookup; + $this->cache = $cache; + $this->violationMessageSerializer = $violationMessageSerializer; + $this->violationMessageDeserializer = $violationMessageDeserializer; + $this->dataFactory = $dataFactory; + $this->throttlingLock = $throttlingLock; + $this->loggingHelper = $loggingHelper; + $this->defaultUserAgent = $defaultUserAgent; + $this->requestFactory = $requestFactory; + $this->entityPrefixes = []; + foreach ( $rdfVocabulary->entityNamespaceNames as $namespaceName ) { + $this->entityPrefixes[] = $rdfVocabulary->getNamespaceURI( $namespaceName ); + } + + $this->endpoint = $config->get( 'WBQualityConstraintsSparqlEndpoint' ); + $this->maxQueryTimeMillis = $config->get( 'WBQualityConstraintsSparqlMaxMillis' ); + $this->instanceOfId = $config->get( 'WBQualityConstraintsInstanceOfId' ); + $this->subclassOfId = $config->get( 'WBQualityConstraintsSubclassOfId' ); + $this->cacheMapSize = $config->get( 'WBQualityConstraintsFormatCacheMapSize' ); + $this->timeoutExceptionClasses = $config->get( + 'WBQualityConstraintsSparqlTimeoutExceptionClasses' + ); + $this->sparqlHasWikibaseSupport = $config->get( + 'WBQualityConstraintsSparqlHasWikibaseSupport' + ); + $this->sparqlThrottlingFallbackDuration = (int)$config->get( + 'WBQualityConstraintsSparqlThrottlingFallbackDuration' + ); + + $this->prefixes = $this->getQueryPrefixes( $rdfVocabulary ); + } + + private function getQueryPrefixes( RdfVocabulary $rdfVocabulary ) { + // TODO: it would probably be smarter that RdfVocubulary exposed these prefixes somehow + $prefixes = ''; + foreach ( $rdfVocabulary->entityNamespaceNames as $sourceName => $namespaceName ) { + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + } + $prefixes .= <<getNamespaceURI( RdfVocabulary::NS_STATEMENT )}> +PREFIX wdv: <{$rdfVocabulary->getNamespaceURI( RdfVocabulary::NS_VALUE )}>\n +END; + + foreach ( $rdfVocabulary->propertyNamespaceNames as $sourceName => $sourceNamespaces ) { + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_DIRECT_CLAIM]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_CLAIM]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_CLAIM_STATEMENT]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_QUALIFIER]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_QUALIFIER_VALUE]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_REFERENCE]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + $namespaceName = $sourceNamespaces[RdfVocabulary::NSP_REFERENCE_VALUE]; + $prefixes .= <<getNamespaceURI( $namespaceName )}>\n +END; + } + $prefixes .= <<getNamespaceURI( RdfVocabulary::NS_ONTOLOGY )}>\n +END; + return $prefixes; + } + + /** + * @param string $id entity ID serialization of the entity to check + * @param string[] $classes entity ID serializations of the expected types + * + * @return CachedBool + * @throws SparqlHelperException if the query times out or some other error occurs + */ + public function hasType( $id, array $classes ) { + // TODO hint:gearing is a workaround for T168973 and can hopefully be removed eventually + $gearingHint = $this->sparqlHasWikibaseSupport ? + ' hint:Prior hint:gearing "forward".' : + ''; + + $metadatas = []; + + foreach ( array_chunk( $classes, 20 ) as $classesChunk ) { + $classesValues = implode( ' ', array_map( + static function ( $class ) { + return 'wd:' . $class; + }, + $classesChunk + ) ); + + $query = <<subclassOfId}* ?class.$gearingHint +} +EOF; + + $result = $this->runQuery( $query ); + $metadatas[] = $result->getMetadata(); + if ( $result->getArray()['boolean'] ) { + return new CachedBool( + true, + Metadata::merge( $metadatas ) + ); + } + } + + return new CachedBool( + false, + Metadata::merge( $metadatas ) + ); + } + + /** + * Helper function used by findEntitiesWithSameStatement to filter + * out entities with different qualifiers or no qualifier value. + * + * @param PropertyId $separator + * @return string + */ + private function nestedSeparatorFilter( PropertyId $separator ) { + $filter = <<getPropertyId()->serialize(); + $guid = str_replace( '$', '-', $statement->getGuid() ); + + $separatorFilters = array_map( [ $this, 'nestedSeparatorFilter' ], $separators ); + $finalSeparatorFilter = implode( "\n", $separatorFilters ); + + $query = <<runQuery( $query ); + + return $this->getOtherEntities( $result ); + } + + /** + * @param EntityId $entityId The entity ID on the containing entity + * @param PropertyValueSnak $snak + * @param string $type Context::TYPE_QUALIFIER or Context::TYPE_REFERENCE + * @param boolean $ignoreDeprecatedStatements Whether to ignore deprecated statements or not. + * + * @return CachedEntityIds + * @throws SparqlHelperException if the query times out or some other error occurs + */ + public function findEntitiesWithSameQualifierOrReference( + EntityId $entityId, + PropertyValueSnak $snak, + $type, + $ignoreDeprecatedStatements + ) { + $eid = $entityId->getSerialization(); + $pid = $snak->getPropertyId()->getSerialization(); + $prefix = $type === Context::TYPE_QUALIFIER ? 'pq' : 'pr'; + $dataValue = $snak->getDataValue(); + $dataType = $this->propertyDataTypeLookup->getDataTypeIdForProperty( + $snak->getPropertyId() + ); + list( $value, $isFullValue ) = $this->getRdfLiteral( $dataType, $dataValue ); + if ( $isFullValue ) { + $prefix .= 'v'; + } + $path = $type === Context::TYPE_QUALIFIER ? + "$prefix:$pid" : + "prov:wasDerivedFrom/$prefix:$pid"; + + $deprecatedFilter = ''; + if ( $ignoreDeprecatedStatements ) { + $deprecatedFilter = <<< EOF + MINUS { ?otherStatement wikibase:rank wikibase:DeprecatedRank. } +EOF; + } + + $query = <<runQuery( $query ); + + return $this->getOtherEntities( $result ); + } + + /** + * Return SPARQL code for a string literal with $text as content. + * + * @param string $text + * + * @return string + */ + private function stringLiteral( $text ) { + return '"' . strtr( $text, [ '"' => '\\"', '\\' => '\\\\' ] ) . '"'; + } + + /** + * Extract and parse entity IDs from the ?otherEntity column of a SPARQL query result. + * + * @param CachedQueryResults $results + * + * @return CachedEntityIds + */ + private function getOtherEntities( CachedQueryResults $results ) { + return new CachedEntityIds( array_map( + function ( $resultBindings ) { + $entityIRI = $resultBindings['otherEntity']['value']; + foreach ( $this->entityPrefixes as $entityPrefix ) { + $entityPrefixLength = strlen( $entityPrefix ); + if ( substr( $entityIRI, 0, $entityPrefixLength ) === $entityPrefix ) { + try { + return $this->entityIdParser->parse( + substr( $entityIRI, $entityPrefixLength ) + ); + } catch ( EntityIdParsingException $e ) { + // fall through + } + } + + return null; + } + + return null; + }, + $results->getArray()['results']['bindings'] + ), $results->getMetadata() ); + } + + // phpcs:disable Generic.Metrics.CyclomaticComplexity,Squiz.WhiteSpace.FunctionSpacing + /** + * Get an RDF literal or IRI with which the given data value can be matched in a query. + * + * @param string $dataType + * @param DataValue $dataValue + * + * @return array the literal or IRI as a string in SPARQL syntax, + * and a boolean indicating whether it refers to a full value node or not + */ + private function getRdfLiteral( $dataType, DataValue $dataValue ) { + switch ( $dataType ) { + case 'string': + case 'external-id': + return [ $this->stringLiteral( $dataValue->getValue() ), false ]; + case 'commonsMedia': + $url = $this->rdfVocabulary->getMediaFileURI( $dataValue->getValue() ); + return [ '<' . $url . '>', false ]; + case 'geo-shape': + $url = $this->rdfVocabulary->getGeoShapeURI( $dataValue->getValue() ); + return [ '<' . $url . '>', false ]; + case 'tabular-data': + $url = $this->rdfVocabulary->getTabularDataURI( $dataValue->getValue() ); + return [ '<' . $url . '>', false ]; + case 'url': + $url = $dataValue->getValue(); + if ( !preg_match( '/^[^<>"{}\\\\|^`\\x00-\\x20]*$/D', $url ) ) { + // not a valid URL for SPARQL (see SPARQL spec, production 139 IRIREF) + // such an URL should never reach us, so just throw + throw new InvalidArgumentException( 'invalid URL: ' . $url ); + } + return [ '<' . $url . '>', false ]; + case 'wikibase-item': + case 'wikibase-property': + /** @var EntityIdValue $dataValue */ + '@phan-var EntityIdValue $dataValue'; + return [ 'wd:' . $dataValue->getEntityId()->getSerialization(), false ]; + case 'monolingualtext': + /** @var MonolingualTextValue $dataValue */ + '@phan-var MonolingualTextValue $dataValue'; + $lang = $dataValue->getLanguageCode(); + if ( !preg_match( '/^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/D', $lang ) ) { + // not a valid language tag for SPARQL (see SPARQL spec, production 145 LANGTAG) + // such a language tag should never reach us, so just throw + throw new InvalidArgumentException( 'invalid language tag: ' . $lang ); + } + return [ $this->stringLiteral( $dataValue->getText() ) . '@' . $lang, false ]; + case 'globe-coordinate': + case 'quantity': + case 'time': + // @phan-suppress-next-line PhanUndeclaredMethod + return [ 'wdv:' . $dataValue->getHash(), true ]; + default: + throw new InvalidArgumentException( 'unknown data type: ' . $dataType ); + } + } + // phpcs:enable + + /** + * @param string $text + * @param string $regex + * + * @return boolean + * @throws SparqlHelperException if the query times out or some other error occurs + * @throws ConstraintParameterException if the $regex is invalid + */ + public function matchesRegularExpression( $text, $regex ) { + // caching wrapper around matchesRegularExpressionWithSparql + + $textHash = hash( 'sha256', $text ); + $cacheKey = $this->cache->makeKey( + 'WikibaseQualityConstraints', // extension + 'regex', // action + 'WDQS-Java', // regex flavor + hash( 'sha256', $regex ) + ); + + $cacheMapArray = $this->cache->getWithSetCallback( + $cacheKey, + WANObjectCache::TTL_DAY, + function ( $cacheMapArray ) use ( $text, $regex, $textHash ) { + // Initialize the cache map if not set + if ( $cacheMapArray === false ) { + $key = 'wikibase.quality.constraints.regex.cache.refresh.init'; + $this->dataFactory->increment( $key ); + return []; + } + + $key = 'wikibase.quality.constraints.regex.cache.refresh'; + $this->dataFactory->increment( $key ); + $cacheMap = MapCacheLRU::newFromArray( $cacheMapArray, $this->cacheMapSize ); + if ( $cacheMap->has( $textHash ) ) { + $key = 'wikibase.quality.constraints.regex.cache.refresh.hit'; + $this->dataFactory->increment( $key ); + $cacheMap->get( $textHash ); // ping cache + } else { + $key = 'wikibase.quality.constraints.regex.cache.refresh.miss'; + $this->dataFactory->increment( $key ); + try { + $matches = $this->matchesRegularExpressionWithSparql( $text, $regex ); + } catch ( ConstraintParameterException $e ) { + $matches = $this->serializeConstraintParameterException( $e ); + } catch ( SparqlHelperException $e ) { + // don’t cache this + return $cacheMap->toArray(); + } + $cacheMap->set( + $textHash, + $matches, + 3 / 8 + ); + } + + return $cacheMap->toArray(); + }, + [ + // Once map is > 1 sec old, consider refreshing + 'ageNew' => 1, + // Update 5 seconds after "ageNew" given a 1 query/sec cache check rate + 'hotTTR' => 5, + // avoid querying cache servers multiple times in a request + // (e. g. when checking format of a reference URL used multiple times on an entity) + 'pcTTL' => WANObjectCache::TTL_PROC_LONG, + ] + ); + + if ( isset( $cacheMapArray[$textHash] ) ) { + $key = 'wikibase.quality.constraints.regex.cache.hit'; + $this->dataFactory->increment( $key ); + $matches = $cacheMapArray[$textHash]; + if ( is_bool( $matches ) ) { + return $matches; + } elseif ( is_array( $matches ) && + $matches['type'] == ConstraintParameterException::class ) { + throw $this->deserializeConstraintParameterException( $matches ); + } else { + throw new MWException( + 'Value of unknown type in object cache (' . + 'cache key: ' . $cacheKey . ', ' . + 'cache map key: ' . $textHash . ', ' . + 'value type: ' . gettype( $matches ) . ')' + ); + } + } else { + $key = 'wikibase.quality.constraints.regex.cache.miss'; + $this->dataFactory->increment( $key ); + return $this->matchesRegularExpressionWithSparql( $text, $regex ); + } + } + + private function serializeConstraintParameterException( ConstraintParameterException $cpe ) { + return [ + 'type' => ConstraintParameterException::class, + 'violationMessage' => $this->violationMessageSerializer->serialize( $cpe->getViolationMessage() ), + ]; + } + + private function deserializeConstraintParameterException( array $serialization ) { + $message = $this->violationMessageDeserializer->deserialize( + $serialization['violationMessage'] + ); + return new ConstraintParameterException( $message ); + } + + /** + * This function is only public for testing purposes; + * use matchesRegularExpression, which is equivalent but caches results. + * + * @param string $text + * @param string $regex + * + * @return boolean + * @throws SparqlHelperException if the query times out or some other error occurs + * @throws ConstraintParameterException if the $regex is invalid + */ + public function matchesRegularExpressionWithSparql( $text, $regex ) { + $textStringLiteral = $this->stringLiteral( $text ); + $regexStringLiteral = $this->stringLiteral( '^(?:' . $regex . ')$' ); + + $query = <<runQuery( $query, false ); + + $vars = $result->getArray()['results']['bindings'][0]; + if ( array_key_exists( 'matches', $vars ) ) { + // true or false ⇒ regex okay, text matches or not + return $vars['matches']['value'] === 'true'; + } else { + // empty result: regex broken + throw new ConstraintParameterException( + ( new ViolationMessage( 'wbqc-violation-message-parameter-regex' ) ) + ->withInlineCode( $regex, Role::CONSTRAINT_PARAMETER_VALUE ) + ); + } + } + + /** + * Check whether the text content of an error response indicates a query timeout. + * + * @param string $responseContent + * + * @return boolean + */ + public function isTimeout( $responseContent ) { + $timeoutRegex = implode( '|', array_map( + static function ( $fqn ) { + return preg_quote( $fqn, '/' ); + }, + $this->timeoutExceptionClasses + ) ); + return (bool)preg_match( '/' . $timeoutRegex . '/', $responseContent ); + } + + /** + * Return the max-age of a cached response, + * or a boolean indicating whether the response was cached or not. + * + * @param array $responseHeaders see MWHttpRequest::getResponseHeaders() + * + * @return int|boolean the max-age (in seconds) + * or a plain boolean if no max-age can be determined + */ + public function getCacheMaxAge( $responseHeaders ) { + if ( + array_key_exists( 'x-cache-status', $responseHeaders ) && + preg_match( '/^hit(?:-.*)?$/', $responseHeaders['x-cache-status'][0] ) + ) { + $maxage = []; + if ( + array_key_exists( 'cache-control', $responseHeaders ) && + preg_match( '/\bmax-age=(\d+)\b/', $responseHeaders['cache-control'][0], $maxage ) + ) { + return intval( $maxage[1] ); + } else { + return true; + } + } else { + return false; + } + } + + /** + * Get the delay date of a 429 headered response, which is caused by + * throttling of to many SPARQL-Requests. The header-format is defined + * in RFC7231 see: https://tools.ietf.org/html/rfc7231#section-7.1.3 + * + * @param MWHttpRequest $request + * + * @return int|ConvertibleTimestamp + * or SparlHelper::NO_RETRY_AFTER if there is no Retry-After header + * or SparlHelper::EMPTY_RETRY_AFTER if there is an empty Retry-After + * or SparlHelper::INVALID_RETRY_AFTER if there is something wrong with the format + */ + public function getThrottling( MWHttpRequest $request ) { + $retryAfterValue = $request->getResponseHeader( 'Retry-After' ); + if ( $retryAfterValue === null ) { + return self::NO_RETRY_AFTER; + } + + $trimmedRetryAfterValue = trim( $retryAfterValue ); + if ( empty( $trimmedRetryAfterValue ) ) { + return self::EMPTY_RETRY_AFTER; + } + + if ( is_numeric( $trimmedRetryAfterValue ) ) { + $delaySeconds = (int)$trimmedRetryAfterValue; + if ( $delaySeconds >= 0 ) { + return $this->getTimestampInFuture( new DateInterval( 'PT' . $delaySeconds . 'S' ) ); + } + } else { + $return = strtotime( $trimmedRetryAfterValue ); + if ( !empty( $return ) ) { + return new ConvertibleTimestamp( $return ); + } + } + return self::INVALID_RETRY_AFTER; + } + + private function getTimestampInFuture( DateInterval $delta ) { + $now = new ConvertibleTimestamp(); + return new ConvertibleTimestamp( $now->timestamp->add( $delta ) ); + } + + /** + * Runs a query against the configured endpoint and returns the results. + * TODO: See if Sparql Client in core can be used instead of rolling our own + * + * @param string $query The query, unencoded (plain string). + * @param bool $needsPrefixes Whether the query requires prefixes or they can be omitted. + * + * @return CachedQueryResults + * + * @throws SparqlHelperException if the query times out or some other error occurs + */ + public function runQuery( $query, $needsPrefixes = true ) { + + if ( $this->throttlingLock->isLocked( self::EXPIRY_LOCK_ID ) ) { + $this->dataFactory->increment( 'wikibase.quality.constraints.sparql.throttling' ); + throw new TooManySparqlRequestsException(); + } + + if ( $this->sparqlHasWikibaseSupport ) { + $needsPrefixes = false; + } + + if ( $needsPrefixes ) { + $query = $this->prefixes . $query; + } + $query = "#wbqc\n" . $query; + + $url = $this->endpoint . '?' . http_build_query( + [ + 'query' => $query, + 'format' => 'json', + 'maxQueryTimeMillis' => $this->maxQueryTimeMillis, + ], + '', ini_get( 'arg_separator.output' ), + // encode spaces with %20, not + + PHP_QUERY_RFC3986 + ); + + $options = [ + 'method' => 'GET', + 'timeout' => (int)round( ( $this->maxQueryTimeMillis + 1000 ) / 1000 ), + 'connectTimeout' => 'default', + 'userAgent' => $this->defaultUserAgent, + ]; + $request = $this->requestFactory->create( $url, $options, __METHOD__ ); + $startTime = microtime( true ); + $requestStatus = $request->execute(); + $endTime = microtime( true ); + $this->dataFactory->timing( + 'wikibase.quality.constraints.sparql.timing', + ( $endTime - $startTime ) * 1000 + ); + + $this->guardAgainstTooManyRequestsError( $request ); + + $maxAge = $this->getCacheMaxAge( $request->getResponseHeaders() ); + if ( $maxAge ) { + $this->dataFactory->increment( 'wikibase.quality.constraints.sparql.cached' ); + } + + if ( $requestStatus->isOK() ) { + $json = $request->getContent(); + $jsonStatus = FormatJson::parse( $json, FormatJson::FORCE_ASSOC ); + if ( $jsonStatus->isOK() ) { + return new CachedQueryResults( + $jsonStatus->getValue(), + Metadata::ofCachingMetadata( + $maxAge ? + CachingMetadata::ofMaximumAgeInSeconds( $maxAge ) : + CachingMetadata::fresh() + ) + ); + } else { + $jsonErrorCode = $jsonStatus->getErrors()[0]['message']; + $this->dataFactory->increment( + "wikibase.quality.constraints.sparql.error.json.$jsonErrorCode" + ); + // fall through to general error handling + } + } else { + $this->dataFactory->increment( + "wikibase.quality.constraints.sparql.error.http.{$request->getStatus()}" + ); + // fall through to general error handling + } + + $this->dataFactory->increment( 'wikibase.quality.constraints.sparql.error' ); + + if ( $this->isTimeout( $request->getContent() ) ) { + $this->dataFactory->increment( + 'wikibase.quality.constraints.sparql.error.timeout' + ); + } + + throw new SparqlHelperException(); + } + + /** + * Handle a potential “too many requests” error. + * + * @param MWHttpRequest $request + * @throws TooManySparqlRequestsException + */ + private function guardAgainstTooManyRequestsError( MWHttpRequest $request ): void { + if ( $request->getStatus() !== self::HTTP_TOO_MANY_REQUESTS ) { + return; + } + + $fallbackBlockDuration = $this->sparqlThrottlingFallbackDuration; + + if ( $fallbackBlockDuration < 0 ) { + throw new InvalidArgumentException( 'Fallback duration must be positive int but is: ' . + $fallbackBlockDuration ); + } + + $this->dataFactory->increment( 'wikibase.quality.constraints.sparql.throttling' ); + $throttlingUntil = $this->getThrottling( $request ); + if ( !( $throttlingUntil instanceof ConvertibleTimestamp ) ) { + $this->loggingHelper->logSparqlHelperTooManyRequestsRetryAfterInvalid( $request ); + $this->throttlingLock->lock( + self::EXPIRY_LOCK_ID, + $this->getTimestampInFuture( new DateInterval( 'PT' . $fallbackBlockDuration . 'S' ) ) + ); + } else { + $this->loggingHelper->logSparqlHelperTooManyRequestsRetryAfterPresent( $throttlingUntil, $request ); + $this->throttlingLock->lock( self::EXPIRY_LOCK_ID, $throttlingUntil ); + } + throw new TooManySparqlRequestsException(); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelperException.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelperException.php new file mode 100644 index 000000000..44b1430ef --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/SparqlHelperException.php @@ -0,0 +1,16 @@ +timeValueCalculator = $timeValueCalculator ?: new TimeValueCalculator(); + } + + public function getComparison( TimeValue $lhs, TimeValue $rhs ) { + $lhsTimestamp = $this->timeValueCalculator->getTimestamp( $lhs ); + $rhsTimestamp = $this->timeValueCalculator->getTimestamp( $rhs ); + + if ( $lhsTimestamp === $rhsTimestamp ) { + return 0; + } + + return $lhsTimestamp < $rhsTimestamp ? -1 : 1; + } + + public function getMinimum( TimeValue $timeValue1, TimeValue $timeValue2 ) { + return $this->getComparison( $timeValue1, $timeValue2 ) <= 0 ? $timeValue1 : $timeValue2; + } + + public function isFutureTime( TimeValue $timeValue ) { + return $this->getComparison( $timeValue, new NowValue() ) >= 0; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/TooManySparqlRequestsException.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/TooManySparqlRequestsException.php new file mode 100644 index 000000000..2f3aeae19 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/TooManySparqlRequestsException.php @@ -0,0 +1,14 @@ +entityLookup = $lookup; + $this->config = $config; + $this->sparqlHelper = $sparqlHelper; + $this->dataFactory = $dataFactory; + } + + /** + * Checks if $comparativeClass is a subclass + * of one of the item ID serializations in $classesToCheck. + * If the class hierarchy is not exhausted before + * the configured limit (WBQualityConstraintsTypeCheckMaxEntities) is reached, + * an OverflowException is thrown. + * + * @param EntityId $comparativeClass + * @param string[] $classesToCheck + * @param int &$entitiesChecked + * + * @return bool + * @throws OverflowException if $entitiesChecked exceeds the configured limit + */ + private function isSubclassOf( EntityId $comparativeClass, array $classesToCheck, &$entitiesChecked = 0 ) { + $maxEntities = $this->config->get( 'WBQualityConstraintsTypeCheckMaxEntities' ); + if ( ++$entitiesChecked > $maxEntities ) { + throw new OverflowException( 'Too many entities to check' ); + } + + $item = $this->entityLookup->getEntity( $comparativeClass ); + if ( !( $item instanceof StatementListProvider ) ) { + return false; // lookup failed, probably because item doesn't exist + } + + $subclassId = $this->config->get( 'WBQualityConstraintsSubclassOfId' ); + $statements = $item->getStatements() + ->getByPropertyId( new NumericPropertyId( $subclassId ) ) + ->getBestStatements(); + /** @var Statement $statement */ + foreach ( $statements as $statement ) { + $mainSnak = $statement->getMainSnak(); + + if ( !$this->hasCorrectType( $mainSnak ) ) { + continue; + } + /** @var PropertyValueSnak $mainSnak */ + /** @var EntityIdValue $dataValue */ + + $dataValue = $mainSnak->getDataValue(); + '@phan-var EntityIdValue $dataValue'; + $comparativeClass = $dataValue->getEntityId(); + + if ( in_array( $comparativeClass->getSerialization(), $classesToCheck ) ) { + return true; + } + + if ( $this->isSubclassOf( $comparativeClass, $classesToCheck, $entitiesChecked ) ) { + return true; + } + } + + return false; + } + + /** + * Checks if $comparativeClass is a subclass + * of one of the item ID serializations in $classesToCheck. + * If isSubclassOf() aborts due to hitting the configured limit, + * the injected {@link SparqlHelper} is consulted if present, + * otherwise the check returns false. + * + * @param EntityId $comparativeClass + * @param string[] $classesToCheck + * + * @return CachedBool + * @throws SparqlHelperException if SPARQL is used and the query times out or some other error occurs + */ + public function isSubclassOfWithSparqlFallback( EntityId $comparativeClass, array $classesToCheck ) { + try { + $entitiesChecked = 0; + $start1 = microtime( true ); + $isSubclass = $this->isSubclassOf( $comparativeClass, $classesToCheck, $entitiesChecked ); + $end1 = microtime( true ); + $this->dataFactory->timing( + 'wikibase.quality.constraints.type.php.success.timing', + ( $end1 - $start1 ) * 1000 + ); + $this->dataFactory->timing( // not really a timing, but works like one (we want percentiles etc.) + 'wikibase.quality.constraints.type.php.success.entities', + $entitiesChecked + ); + + return new CachedBool( $isSubclass, Metadata::blank() ); + } catch ( OverflowException $e ) { + $end1 = microtime( true ); + $this->dataFactory->timing( + 'wikibase.quality.constraints.type.php.overflow.timing', + ( $end1 - $start1 ) * 1000 + ); + + if ( !( $this->sparqlHelper instanceof DummySparqlHelper ) ) { + $this->dataFactory->increment( + 'wikibase.quality.constraints.sparql.typeFallback' + ); + + $start2 = microtime( true ); + $hasType = $this->sparqlHelper->hasType( + $comparativeClass->getSerialization(), + $classesToCheck + ); + $end2 = microtime( true ); + $this->dataFactory->timing( + 'wikibase.quality.constraints.type.sparql.success.timing', + ( $end2 - $start2 ) * 1000 + ); + + return $hasType; + } else { + return new CachedBool( false, Metadata::blank() ); + } + } + } + + /** + * Checks, if one of the itemId serializations in $classesToCheck + * is contained in the list of $statements + * via properties $relationIds or if it is a subclass of + * one of the items referenced in $statements via $relationIds + * + * @param StatementList $statements + * @param string[] $relationIds + * @param string[] $classesToCheck + * + * @return CachedBool + * @throws SparqlHelperException if SPARQL is used and the query times out or some other error occurs + */ + public function hasClassInRelation( StatementList $statements, array $relationIds, array $classesToCheck ) { + $metadatas = []; + + foreach ( $this->getBestStatementsByPropertyIds( $statements, $relationIds ) as $statement ) { + $mainSnak = $statement->getMainSnak(); + + if ( !$this->hasCorrectType( $mainSnak ) ) { + continue; + } + /** @var PropertyValueSnak $mainSnak */ + /** @var EntityIdValue $dataValue */ + + $dataValue = $mainSnak->getDataValue(); + '@phan-var EntityIdValue $dataValue'; + $comparativeClass = $dataValue->getEntityId(); + + if ( in_array( $comparativeClass->getSerialization(), $classesToCheck ) ) { + // discard $metadatas, we know this is fresh + return new CachedBool( true, Metadata::blank() ); + } + + $result = $this->isSubclassOfWithSparqlFallback( $comparativeClass, $classesToCheck ); + $metadatas[] = $result->getMetadata(); + if ( $result->getBool() ) { + return new CachedBool( + true, + Metadata::merge( $metadatas ) + ); + } + } + + return new CachedBool( + false, + Metadata::merge( $metadatas ) + ); + } + + /** + * @param Snak $mainSnak + * @return bool + * @phan-assert PropertyValueSnak $mainSnak + */ + private function hasCorrectType( Snak $mainSnak ) { + return $mainSnak instanceof PropertyValueSnak + && $mainSnak->getDataValue()->getType() === 'wikibase-entityid'; + } + + /** + * @param StatementList $statements + * @param string[] $propertyIdSerializations + * + * @return Statement[] + */ + private function getBestStatementsByPropertyIds( + StatementList $statements, + array $propertyIdSerializations + ) { + $statementArrays = []; + + foreach ( $propertyIdSerializations as $propertyIdSerialization ) { + $propertyId = new NumericPropertyId( $propertyIdSerialization ); + $statementArrays[] = $statements + ->getByPropertyId( $propertyId ) + ->getBestStatements() + ->toArray(); + } + + return call_user_func_array( 'array_merge', $statementArrays ); + } + + /** + * @param PropertyId $propertyId ID of the property that introduced the constraint + * @param EntityId $entityId ID of the entity that does not have the required type + * @param string[] $classes item ID serializations of the classes that $entityId should have + * @param string $checker "type" or "valueType" (for message key) + * @param string $relation "instance", "subclass", or "instanceOrSubclass" (for message key) + * + * @return ViolationMessage + */ + public function getViolationMessage( + PropertyId $propertyId, + EntityId $entityId, + array $classes, + $checker, + $relation + ) { + $classes = array_map( + static function ( $itemIdSerialization ) { + return new ItemId( $itemIdSerialization ); + }, + $classes + ); + + // Possible messages: + // wbqc-violation-message-type-instance + // wbqc-violation-message-type-subclass + // wbqc-violation-message-type-instanceOrSubclass + // wbqc-violation-message-valueType-instance + // wbqc-violation-message-valueType-subclass + // wbqc-violation-message-valueType-instanceOrSubclass + return ( new ViolationMessage( 'wbqc-violation-message-' . $checker . '-' . $relation ) ) + ->withEntityId( $propertyId, Role::CONSTRAINT_PROPERTY ) + ->withEntityId( $entityId, Role::SUBJECT ) + ->withEntityIdList( $classes, Role::OBJECT ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/UnitsParameter.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/UnitsParameter.php new file mode 100644 index 000000000..a7a000807 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/UnitsParameter.php @@ -0,0 +1,67 @@ +unitItemIds = $unitItemIds; + $this->unitQuantities = $unitQuantities; + $this->unitlessAllowed = $unitlessAllowed; + } + + /** + * @return ItemId[] The item IDs of the allowed units. + */ + public function getUnitItemIds() { + return $this->unitItemIds; + } + + /** + * @return UnboundedQuantityValue[] Quantities with the allowed units. + */ + public function getUnitQuantities() { + return $this->unitQuantities; + } + + /** + * @return bool Whether unitless values (unit '1') are allowed or not. + */ + public function getUnitlessAllowed() { + return $this->unitlessAllowed; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ValueCountCheckerHelper.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ValueCountCheckerHelper.php new file mode 100644 index 000000000..942334ac7 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Helper/ValueCountCheckerHelper.php @@ -0,0 +1,32 @@ +getPropertyId()->equals( $propertyId ); + } + ) ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ItemIdSnakValue.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ItemIdSnakValue.php new file mode 100644 index 000000000..4ceb129ba --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/ItemIdSnakValue.php @@ -0,0 +1,165 @@ +itemId = $itemId; + return $ret; + } + + /** + * Get an {@link ItemIdSnakValue} that wraps an unknown value. + * + * @return self + */ + public static function someValue() { + $ret = new self; + $ret->some = true; + return $ret; + } + + /** + * Get an {@link ItemIdSnakValue} that wraps no value. + * + * @return self + */ + public static function noValue() { + $ret = new self; + $ret->no = true; + return $ret; + } + + /** + * Get an {@link ItemIdSnakValue} that matches the given snak. + * + * @param Snak $snak + * + * @throws InvalidArgumentException + * @return self + */ + public static function fromSnak( Snak $snak ) { + switch ( true ) { + case $snak instanceof PropertyValueSnak: + $dataValue = $snak->getDataValue(); + if ( $dataValue instanceof EntityIdValue ) { + $itemId = $dataValue->getEntityId(); + if ( $itemId instanceof ItemId ) { + return self::fromItemId( $itemId ); + } + } + break; + case $snak instanceof PropertySomeValueSnak: + return self::someValue(); + case $snak instanceof PropertyNoValueSnak: + return self::noValue(); + } + + throw new InvalidArgumentException( 'Snak must contain item ID value or be a somevalue / novalue snak' ); + } + + /** + * Check whether this {@link ItemIdSnakValue} contains a known value or not. + * + * @return bool + */ + public function isValue() { + return $this->itemId !== null; + } + + /** + * Check whether this {@link ItemIdSnakValue} contains an unknown value or not. + * + * @return bool + */ + public function isSomeValue() { + return $this->some; + } + + /** + * Check whether this {@link ItemIdSnakValue} contains no value or not. + * + * @return bool + */ + public function isNoValue() { + return $this->no; + } + + /** + * Get the item ID contained in this {@link ItemIdSnakValue}. + * Only valid if {@link isValue} is true. + * + * @throws DomainException if this value does not contain an item ID + * @return ItemId + */ + public function getItemId() { + if ( !$this->isValue() ) { + throw new DomainException( 'This value does not contain an item ID.' ); + } + return $this->itemId; + } + + /** + * Check whether this value matches the given $snak + * (same kind and, if contains known value, same value). + * + * @param Snak $snak + * @return bool + */ + public function matchesSnak( Snak $snak ) { + switch ( true ) { + case $snak instanceof PropertyValueSnak: + $dataValue = $snak->getDataValue(); + return $this->isValue() && + $dataValue instanceof EntityIdValue && + $dataValue->getEntityId() instanceof ItemId && + $dataValue->getEntityId()->equals( $this->getItemId() ); + case $snak instanceof PropertySomeValueSnak: + return $this->isSomeValue(); + case $snak instanceof PropertyNoValueSnak: + return $this->isNoValue(); + } + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/MultilingualTextViolationMessageRenderer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/MultilingualTextViolationMessageRenderer.php new file mode 100644 index 000000000..1a532e4db --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/MultilingualTextViolationMessageRenderer.php @@ -0,0 +1,115 @@ +alternativeMessageKeys = [ + 'wbqc-violation-message-format-clarification' => 'wbqc-violation-message-format', + ]; + } + + /** + * @param ViolationMessage $violationMessage + * @return string + */ + public function render( ViolationMessage $violationMessage ) { + if ( !array_key_exists( $violationMessage->getMessageKey(), $this->alternativeMessageKeys ) ) { + return parent::render( $violationMessage ); + } + + $arguments = $violationMessage->getArguments(); + $multilingualTextArgument = array_pop( $arguments ); + $multilingualTextParams = $this->renderMultilingualText( + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable TODO Ensure this is not an actual issue + $multilingualTextArgument['value'], + // @phan-suppress-next-line PhanTypeArraySuspiciousNullable + $multilingualTextArgument['role'] + ); + + $paramsLists = [ [] ]; + foreach ( $arguments as $argument ) { + $paramsLists[] = $this->renderArgument( $argument ); + } + $regularParams = call_user_func_array( 'array_merge', $paramsLists ); + + if ( $multilingualTextParams === null ) { + return $this->messageLocalizer + ->msg( $this->alternativeMessageKeys[$violationMessage->getMessageKey()] ) + ->params( $regularParams ) + ->escaped(); + } else { + return $this->messageLocalizer + ->msg( $violationMessage->getMessageKey() ) + ->params( $regularParams ) + ->params( $multilingualTextParams ) + ->escaped(); + } + } + + /** + * @param MultilingualTextValue $text + * @param string|null $role one of the Role::* constants + * @return array[]|null list of parameters as accepted by Message::params(), + * or null if the text is not available in the user’s language + */ + protected function renderMultilingualText( MultilingualTextValue $text, $role ) { + global $wgLang; + $languageCodes = $wgLang->getFallbackLanguages(); + array_unshift( $languageCodes, $wgLang->getCode() ); + + $texts = $text->getTexts(); + foreach ( $languageCodes as $languageCode ) { + if ( array_key_exists( $languageCode, $texts ) ) { + return [ Message::rawParam( $this->addRole( + htmlspecialchars( $texts[$languageCode]->getText() ), + $role + ) ) ]; + } + } + + return null; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessage.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessage.php new file mode 100644 index 000000000..8e91d781c --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessage.php @@ -0,0 +1,372 @@ +messageKeySuffix = substr( $messageKey, strlen( self::MESSAGE_KEY_PREFIX ) ); + $this->arguments = []; + } + + /** + * Get the full message key of this message. + * @return string + */ + public function getMessageKey() { + return self::MESSAGE_KEY_PREFIX . $this->messageKeySuffix; + } + + /** + * Get the arguments to this message, + * a list of [ 'type' => self::TYPE_*, 'role' => Role::*, 'value' => $value ] elements. + * @return array[] + */ + public function getArguments() { + return $this->arguments; + } + + /** + * Note: usually you don’t want to use this function directly. + * + * @param string $type one of the self::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @param mixed $value the value, which should match the $type + * @return ViolationMessage + */ + public function withArgument( $type, $role, $value ) { + $ret = clone $this; + $ret->arguments[] = [ 'type' => $type, 'role' => $role, 'value' => $value ]; + return $ret; + } + + /** + * Append a single entity ID to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param EntityId $entityId + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withEntityId( EntityId $entityId, $role = null ) { + return $this->withArgument( self::TYPE_ENTITY_ID, $role, $entityId ); + } + + /** + * Append a list of entity IDs to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * This is not the same as appending the list elements individually with {@link withEntityId}! + * In the final message, this corresponds to + * one parameter for the number of list elements, + * one parameter with an HTML list of the list elements, + * and then one parameter per entity ID. + * + * @param EntityId[] $entityIdList + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withEntityIdList( array $entityIdList, $role = null ) { + return $this->withArgument( self::TYPE_ENTITY_ID_LIST, $role, $entityIdList ); + } + + /** + * Append a single item ID, “unknown value”, or “no value” to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param ItemIdSnakValue $value + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withItemIdSnakValue( ItemIdSnakValue $value, $role = null ) { + return $this->withArgument( self::TYPE_ITEM_ID_SNAK_VALUE, $role, $value ); + } + + /** + * Append a list of item IDs, “unknown value”s, or “no value”s to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * This is not the same as appending the list elements individually with {@link withItemIdSnakValue}! + * In the final message, this corresponds to + * one parameter for the number of list elements, + * one parameter with an HTML list of the list elements, + * and then one parameter per value. + * + * @param ItemIdSnakValue[] $valueList + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withItemIdSnakValueList( array $valueList, $role = null ) { + return $this->withArgument( self::TYPE_ITEM_ID_SNAK_VALUE_LIST, $role, $valueList ); + } + + /** + * Append a single data value to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param DataValue $dataValue + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withDataValue( DataValue $dataValue, $role = null ) { + return $this->withArgument( self::TYPE_DATA_VALUE, $role, $dataValue ); + } + + /** + * Append a single data value type, like "time" or "wikibase-entityid". + * (This operation returns a modified copy, the original object is unchanged.) + * + * Data value types should not be confused with data types, like "time" or "wikibase-item". + * For example, "wikibase-entityid" is the data value type + * used by the data types "wikibase-item" and "wikibase-property". + * + * @param string $dataValueType + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withDataValueType( $dataValueType, $role = null ) { + return $this->withArgument( self::TYPE_DATA_VALUE_TYPE, $role, $dataValueType ); + } + + /** + * Append a single short fragment of inline computer code to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param string $code + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withInlineCode( $code, $role = null ) { + return $this->withArgument( self::TYPE_INLINE_CODE, $role, $code ); + } + + /** + * Append a single constraint scope to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param string $scope one of the Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withConstraintScope( $scope, $role = null ) { + return $this->withArgument( self::TYPE_CONSTRAINT_SCOPE, $role, $scope ); + } + + /** + * Append a list of constraint scopes to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param string[] $scopeList Role::* constants + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withConstraintScopeList( array $scopeList, $role = null ) { + return $this->withArgument( self::TYPE_CONSTRAINT_SCOPE_LIST, $role, $scopeList ); + } + + /** + * Append a single property scope to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param string $scope one of the Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withPropertyScope( $scope, $role = null ) { + return $this->withArgument( self::TYPE_PROPERTY_SCOPE, $role, $scope ); + } + + /** + * Append a list of property scopes to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * @param string[] $scopeList Role::* constants + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withPropertyScopeList( array $scopeList, $role = null ) { + return $this->withArgument( self::TYPE_PROPERTY_SCOPE_LIST, $role, $scopeList ); + } + + /** + * Append a single language to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * One language argument corresponds to two params in the final message, + * one for the language name (autonym) and one for the language code. + * + * (Language arguments do not support roles.) + * + * @param string $languageCode + * @return ViolationMessage + */ + public function withLanguage( $languageCode ) { + return $this->withArgument( self::TYPE_LANGUAGE, null, $languageCode ); + } + + /** + * Append a single language to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * One language argument corresponds to two params in the final message, + * one for the language name (autonym) and one for the language code. + * + * (Language arguments do not support roles.) + * + * @param string[] $languageCodes + * @return ViolationMessage + */ + public function withLanguages( $languageCodes ) { + return $this->withArgument( self::TYPE_LANGUAGE_LIST, null, $languageCodes ); + } + + /** + * Append a multilingual text value to the message arguments. + * (This operation returns a modified copy, the original object is unchanged.) + * + * Note that multilingual text arguments can only be rendered for specific message keys + * (see {@link MultilingualTextViolationMessageRenderer} for details), + * but this method does not verify whether you’re using one of those message keys. + * + * @param MultilingualTextValue $text + * @param string|null $role one of the Role::* constants + * @return ViolationMessage + */ + public function withMultilingualText( MultilingualTextValue $text, $role = null ) { + return $this->withArgument( self::TYPE_MULTILINGUAL_TEXT, $role, $text ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageDeserializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageDeserializer.php new file mode 100644 index 000000000..39e8ab396 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageDeserializer.php @@ -0,0 +1,197 @@ +entityIdParser = $entityIdParser; + $this->dataValueFactory = $dataValueFactory; + } + + public function unabbreviateViolationMessageKey( $messageKeySuffix ) { + return ViolationMessage::MESSAGE_KEY_PREFIX . $messageKeySuffix; + } + + /** + * @param array $serialization + * @return ViolationMessage + */ + public function deserialize( $serialization ) { + Assert::parameterType( 'array', $serialization, '$serialization' ); + + $message = new ViolationMessage( + $this->unabbreviateViolationMessageKey( $serialization['k'] ) + ); + + foreach ( $serialization['a'] as $serializedArgument ) { + $message = $this->deserializeArgument( $message, $serializedArgument ); + } + + return $message; + } + + /** + * @param ViolationMessage $message + * @param array $serializedArgument [ 't' => ViolationMessage::TYPE_*, 'v' => serialized value, 'r' => $role ] + * @return ViolationMessage $message with the deserialized argument appended + */ + private function deserializeArgument( ViolationMessage $message, array $serializedArgument ) { + $methods = [ + ViolationMessage::TYPE_ENTITY_ID => 'deserializeEntityId', + ViolationMessage::TYPE_ENTITY_ID_LIST => 'deserializeEntityIdList', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE => 'deserializeItemIdSnakValue', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE_LIST => 'deserializeItemIdSnakValueList', + ViolationMessage::TYPE_DATA_VALUE => 'deserializeDataValue', + ViolationMessage::TYPE_DATA_VALUE_TYPE => 'deserializeStringByIdentity', + ViolationMessage::TYPE_INLINE_CODE => 'deserializeStringByIdentity', + ViolationMessage::TYPE_CONSTRAINT_SCOPE => 'deserializeContextType', + ViolationMessage::TYPE_CONSTRAINT_SCOPE_LIST => 'deserializeContextTypeList', + ViolationMessage::TYPE_PROPERTY_SCOPE => 'deserializeContextType', + ViolationMessage::TYPE_PROPERTY_SCOPE_LIST => 'deserializeContextTypeList', + ViolationMessage::TYPE_LANGUAGE => 'deserializeStringByIdentity', + ViolationMessage::TYPE_LANGUAGE_LIST => 'deserializeStringByIdentity', + ViolationMessage::TYPE_MULTILINGUAL_TEXT => 'deserializeMultilingualText', + ]; + + $type = $serializedArgument['t']; + $serializedValue = $serializedArgument['v']; + $role = $serializedArgument['r']; + + if ( array_key_exists( $type, $methods ) ) { + $method = $methods[$type]; + $value = $this->$method( $serializedValue ); + } else { + throw new InvalidArgumentException( + 'Unknown ViolationMessage argument type ' . $type . '!' + ); + } + + return $message->withArgument( $type, $role, $value ); + } + + /** + * @param string $string any value that shall simply be deserialized into itself + * @return string that same value, unchanged + */ + private function deserializeStringByIdentity( $string ) { + return $string; + } + + /** + * @param string $entityIdSerialization entity ID serialization + * @return EntityId + */ + private function deserializeEntityId( $entityIdSerialization ) { + return $this->entityIdParser->parse( $entityIdSerialization ); + } + + /** + * @param string[] $entityIdSerializations entity ID serializations + * @return EntityId[] + */ + private function deserializeEntityIdList( array $entityIdSerializations ) { + return array_map( [ $this, 'deserializeEntityId' ], $entityIdSerializations ); + } + + /** + * @param string $valueSerialization entity ID serialization, '::somevalue' or '::novalue' + * @return ItemIdSnakValue + */ + private function deserializeItemIdSnakValue( $valueSerialization ) { + switch ( $valueSerialization ) { + case '::somevalue': + return ItemIdSnakValue::someValue(); + case '::novalue': + return ItemIdSnakValue::noValue(); + default: + $itemId = $this->deserializeEntityId( $valueSerialization ); + '@phan-var \Wikibase\DataModel\Entity\ItemId $itemId'; + return ItemIdSnakValue::fromItemId( $itemId ); + } + } + + /** + * @param string[] $valueSerializations entity ID serializations, '::somevalue's or '::novalue's + * @return ItemIdSnakValue[] + */ + private function deserializeItemIdSnakValueList( $valueSerializations ) { + return array_map( [ $this, 'deserializeItemIdSnakValue' ], $valueSerializations ); + } + + /** + * @param array $dataValueSerialization the data value in array form + * @return DataValue + */ + private function deserializeDataValue( array $dataValueSerialization ) { + return $this->dataValueFactory->newFromArray( $dataValueSerialization ); + } + + /** + * @param string $contextTypeAbbreviation + * @return string one of the Context::TYPE_* constants + */ + private function deserializeContextType( $contextTypeAbbreviation ) { + switch ( $contextTypeAbbreviation ) { + case 's': + return Context::TYPE_STATEMENT; + case 'q': + return Context::TYPE_QUALIFIER; + case 'r': + return Context::TYPE_REFERENCE; + default: + // @codeCoverageIgnoreStart + throw new LogicException( + 'Unknown context type abbreviation ' . $contextTypeAbbreviation + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * @param string[] $contextTypeAbbreviations + * @return string[] Context::TYPE_* constants + */ + private function deserializeContextTypeList( array $contextTypeAbbreviations ) { + return array_map( [ $this, 'deserializeContextType' ], $contextTypeAbbreviations ); + } + + /** + * @param mixed $textSerialization {@see MultilingualTextValue::getArrayValue} + * @return MultilingualTextValue + */ + private function deserializeMultilingualText( $textSerialization ) { + return MultilingualTextValue::newFromArray( $textSerialization ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRenderer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRenderer.php new file mode 100644 index 000000000..c2db83a81 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRenderer.php @@ -0,0 +1,421 @@ +not support multilingual text arguments – + * for that, use {@link MultilingualTextViolationMessageRenderer}. + * + * @license GPL-2.0-or-later + */ +class ViolationMessageRenderer { + + /** + * @var EntityIdFormatter + */ + private $entityIdFormatter; + + /** + * @var ValueFormatter + */ + private $dataValueFormatter; + + /** + * @var MessageLocalizer + */ + protected $messageLocalizer; + + /** + * @var Config + */ + private $config; + + /** + * @var int + */ + private $maxListLength; + + /** + * @param EntityIdFormatter $entityIdFormatter + * @param ValueFormatter $dataValueFormatter + * @param MessageLocalizer $messageLocalizer + * @param Config $config + * @param int $maxListLength The maximum number of elements to be rendered in a list parameter. + * Longer lists are truncated to this length and then rendered with an ellipsis in the HMTL list. + */ + public function __construct( + EntityIdFormatter $entityIdFormatter, + ValueFormatter $dataValueFormatter, + MessageLocalizer $messageLocalizer, + Config $config, + $maxListLength = 10 + ) { + $this->entityIdFormatter = $entityIdFormatter; + $this->dataValueFormatter = $dataValueFormatter; + $this->messageLocalizer = $messageLocalizer; + $this->config = $config; + $this->maxListLength = $maxListLength; + } + + /** + * @param ViolationMessage $violationMessage + * @return string + */ + public function render( ViolationMessage $violationMessage ) { + $messageKey = $violationMessage->getMessageKey(); + $paramsLists = [ [] ]; + foreach ( $violationMessage->getArguments() as $argument ) { + $params = $this->renderArgument( $argument ); + $paramsLists[] = $params; + } + $allParams = call_user_func_array( 'array_merge', $paramsLists ); + return $this->messageLocalizer + ->msg( $messageKey ) + ->params( $allParams ) + ->escaped(); + } + + /** + * @param string $value HTML + * @param string|null $role one of the Role::* constants + * @return string HTML + */ + protected function addRole( $value, $role ) { + if ( $role === null ) { + return $value; + } + + return '' . + $value . + ''; + } + + /** + * @param string $key message key + * @return string HTML + */ + protected function msgEscaped( $key ) { + return $this->messageLocalizer->msg( $key )->escaped(); + } + + /** + * @param array $argument + * @return array[] params (for Message::params) + */ + protected function renderArgument( array $argument ) { + $methods = [ + ViolationMessage::TYPE_ENTITY_ID => 'renderEntityId', + ViolationMessage::TYPE_ENTITY_ID_LIST => 'renderEntityIdList', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE => 'renderItemIdSnakValue', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE_LIST => 'renderItemIdSnakValueList', + ViolationMessage::TYPE_DATA_VALUE => 'renderDataValue', + ViolationMessage::TYPE_DATA_VALUE_TYPE => 'renderDataValueType', + ViolationMessage::TYPE_INLINE_CODE => 'renderInlineCode', + ViolationMessage::TYPE_CONSTRAINT_SCOPE => 'renderConstraintScope', + ViolationMessage::TYPE_CONSTRAINT_SCOPE_LIST => 'renderConstraintScopeList', + ViolationMessage::TYPE_PROPERTY_SCOPE => 'renderPropertyScope', + ViolationMessage::TYPE_PROPERTY_SCOPE_LIST => 'renderPropertyScopeList', + ViolationMessage::TYPE_LANGUAGE => 'renderLanguage', + ViolationMessage::TYPE_LANGUAGE_LIST => 'renderLanguageList', + ]; + + $type = $argument['type']; + $value = $argument['value']; + $role = $argument['role']; + + if ( array_key_exists( $type, $methods ) ) { + $method = $methods[$type]; + $params = $this->$method( $value, $role ); + } else { + throw new InvalidArgumentException( + 'Unknown ViolationMessage argument type ' . $type . '!' + ); + } + + return $params; + } + + /** + * @param array $list + * @param string|null $role one of the Role::* constants + * @param callable $render must accept $list elements and $role as parameters + * and return a single-element array with a raw message param (i. e. [ Message::rawParam( … ) ]) + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderList( array $list, $role, callable $render ) { + if ( $list === [] ) { + return [ + Message::numParam( 0 ), + Message::rawParam( '

    ' ), + ]; + } + + if ( count( $list ) > $this->maxListLength ) { + $list = array_slice( $list, 0, $this->maxListLength ); + $truncated = true; + } + + $renderedParamsLists = array_map( + $render, + $list, + array_fill( 0, count( $list ), $role ) + ); + $renderedParams = array_map( + static function ( $params ) { + return $params[0]; + }, + $renderedParamsLists + ); + $renderedElements = array_map( + static function ( $param ) { + return $param['raw']; + }, + $renderedParams + ); + if ( isset( $truncated ) ) { + $renderedElements[] = $this->msgEscaped( 'ellipsis' ); + } + + return array_merge( + [ + Message::numParam( count( $list ) ), + Message::rawParam( + '
    • ' . + implode( '
    • ', $renderedElements ) . + '
    ' + ), + ], + $renderedParams + ); + } + + /** + * @param EntityId $entityId + * @param string|null $role one of the Role::* constants + * @return array[] list of a single raw message param (i. e. [ Message::rawParam( … ) ]) + */ + private function renderEntityId( EntityId $entityId, $role ) { + return [ Message::rawParam( $this->addRole( + $this->entityIdFormatter->formatEntityId( $entityId ), + $role + ) ) ]; + } + + /** + * @param EntityId[] $entityIdList + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderEntityIdList( array $entityIdList, $role ) { + return $this->renderList( $entityIdList, $role, [ $this, 'renderEntityId' ] ); + } + + /** + * @param ItemIdSnakValue $value + * @param string|null $role one of the Role::* constants + * @return array[] list of a single raw message param (i. e. [ Message::rawParam( … ) ]) + */ + private function renderItemIdSnakValue( ItemIdSnakValue $value, $role ) { + switch ( true ) { + case $value->isValue(): + return $this->renderEntityId( $value->getItemId(), $role ); + case $value->isSomeValue(): + return [ Message::rawParam( $this->addRole( + '' . + $this->msgEscaped( 'wikibase-snakview-snaktypeselector-somevalue' ) . + '', + $role + ) ) ]; + case $value->isNoValue(): + return [ Message::rawParam( $this->addRole( + '' . + $this->msgEscaped( 'wikibase-snakview-snaktypeselector-novalue' ) . + '', + $role + ) ) ]; + default: + // @codeCoverageIgnoreStart + throw new LogicException( + 'ItemIdSnakValue should guarantee that one of is{,Some,No}Value() is true' + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * @param ItemIdSnakValue[] $valueList + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderItemIdSnakValueList( array $valueList, $role ) { + return $this->renderList( $valueList, $role, [ $this, 'renderItemIdSnakValue' ] ); + } + + /** + * @param DataValue $dataValue + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderDataValue( DataValue $dataValue, $role ) { + return [ Message::rawParam( $this->addRole( + $this->dataValueFormatter->format( $dataValue ), + $role + ) ) ]; + } + + /** + * @param string $dataValueType + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderDataValueType( $dataValueType, $role ) { + $messageKeys = [ + 'string' => 'datatypes-type-string', + 'monolingualtext' => 'datatypes-type-monolingualtext', + 'time' => 'datatypes-type-time', + 'quantity' => 'datatypes-type-quantity', + 'wikibase-entityid' => 'wbqc-dataValueType-wikibase-entityid', + ]; + + if ( array_key_exists( $dataValueType, $messageKeys ) ) { + return [ Message::rawParam( $this->addRole( + $this->msgEscaped( $messageKeys[$dataValueType] ), + $role + ) ) ]; + } else { + // @codeCoverageIgnoreStart + throw new LogicException( + 'Unknown data value type ' . $dataValueType + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * @param string $code (not yet HTML-escaped) + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderInlineCode( $code, $role ) { + return [ Message::rawParam( $this->addRole( + '' . htmlspecialchars( $code ) . '', + $role + ) ) ]; + } + + /** + * @param string $scope one of the Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return array[] list of a single raw message param (i. e. [ Message::rawParam( … ) ]) + */ + private function renderConstraintScope( $scope, $role ) { + switch ( $scope ) { + case Context::TYPE_STATEMENT: + $itemId = $this->config->get( + 'WBQualityConstraintsConstraintCheckedOnMainValueId' + ); + break; + case Context::TYPE_QUALIFIER: + $itemId = $this->config->get( + 'WBQualityConstraintsConstraintCheckedOnQualifiersId' + ); + break; + case Context::TYPE_REFERENCE: + $itemId = $this->config->get( + 'WBQualityConstraintsConstraintCheckedOnReferencesId' + ); + break; + default: + // callers should never let this happen, but if it does happen, + // showing “unknown value” seems reasonable + // @codeCoverageIgnoreStart + return $this->renderItemIdSnakValue( ItemIdSnakValue::someValue(), $role ); + // @codeCoverageIgnoreEnd + } + return $this->renderEntityId( new ItemId( $itemId ), $role ); + } + + /** + * @param string[] $scopeList Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderConstraintScopeList( array $scopeList, $role ) { + return $this->renderList( $scopeList, $role, [ $this, 'renderConstraintScope' ] ); + } + + /** + * @param string $scope one of the Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return array[] list of a single raw message param (i. e. [ Message::rawParam( … ) ]) + */ + private function renderPropertyScope( $scope, $role ) { + switch ( $scope ) { + case Context::TYPE_STATEMENT: + $itemId = $this->config->get( 'WBQualityConstraintsAsMainValueId' ); + break; + case Context::TYPE_QUALIFIER: + $itemId = $this->config->get( 'WBQualityConstraintsAsQualifiersId' ); + break; + case Context::TYPE_REFERENCE: + $itemId = $this->config->get( 'WBQualityConstraintsAsReferencesId' ); + break; + default: + // callers should never let this happen, but if it does happen, + // showing “unknown value” seems reasonable + // @codeCoverageIgnoreStart + return $this->renderItemIdSnakValue( ItemIdSnakValue::someValue(), $role ); + // @codeCoverageIgnoreEnd + } + return $this->renderEntityId( new ItemId( $itemId ), $role ); + } + + /** + * @param string[] $scopeList Context::TYPE_* constants + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderPropertyScopeList( array $scopeList, $role ) { + return $this->renderList( $scopeList, $role, [ $this, 'renderPropertyScope' ] ); + } + + /** + * @param string $languageCode MediaWiki language code + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderLanguage( $languageCode, $role ) { + return [ + // ::renderList (through ::renderLanguageList) requires 'raw' parameter + // so we effectively build Message::plaintextParam here + Message::rawParam( htmlspecialchars( Language::fetchLanguageName( $languageCode ) ) ), + Message::plaintextParam( $languageCode ), + ]; + } + + /** + * @param string[] $languageCodes MediaWiki language codes + * @param string|null $role one of the Role::* constants + * @return array[] list of parameters as accepted by Message::params() + */ + private function renderLanguageList( $languageCodes, $role ) { + return $this->renderList( $languageCodes, $role, [ $this, 'renderLanguage' ] ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRendererFactory.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRendererFactory.php new file mode 100644 index 000000000..490f69e5b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageRendererFactory.php @@ -0,0 +1,57 @@ +config = $config; + $this->messageLocalizer = $messageLocalizer; + $this->entityIdHtmlLinkFormatterFactory = $entityIdHtmlLinkFormatterFactory; + $this->valueFormatterFactory = $valueFormatterFactory; + } + + public function getViolationMessageRenderer( Language $language ): ViolationMessageRenderer { + $formatterOptions = new FormatterOptions(); + $formatterOptions->setOption( SnakFormatter::OPT_LANG, $language->getCode() ); + return new MultilingualTextViolationMessageRenderer( + $this->entityIdHtmlLinkFormatterFactory + ->getEntityIdFormatter( $language ), + $this->valueFormatterFactory + ->getValueFormatter( SnakFormatter::FORMAT_HTML, $formatterOptions ), + $this->messageLocalizer, + $this->config + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageSerializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageSerializer.php new file mode 100644 index 000000000..671df7dd2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Message/ViolationMessageSerializer.php @@ -0,0 +1,199 @@ +getArguments(); + $serializedArguments = []; + foreach ( $arguments as $argument ) { + $serializedArguments[] = $this->serializeArgument( $argument ); + } + + return [ + 'k' => $this->abbreviateViolationMessageKey( $object->getMessageKey() ), + 'a' => $serializedArguments, + ]; + } + + /** + * @param array $argument element of ViolationMessage::getArguments() + * @return array [ 't' => ViolationMessage::TYPE_*, 'v' => serialized value, 'r' => $role ] + */ + private function serializeArgument( array $argument ) { + $methods = [ + ViolationMessage::TYPE_ENTITY_ID => 'serializeEntityId', + ViolationMessage::TYPE_ENTITY_ID_LIST => 'serializeEntityIdList', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE => 'serializeItemIdSnakValue', + ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE_LIST => 'serializeItemIdSnakValueList', + ViolationMessage::TYPE_DATA_VALUE => 'serializeDataValue', + ViolationMessage::TYPE_DATA_VALUE_TYPE => 'serializeStringByIdentity', + ViolationMessage::TYPE_INLINE_CODE => 'serializeStringByIdentity', + ViolationMessage::TYPE_CONSTRAINT_SCOPE => 'serializeContextType', + ViolationMessage::TYPE_CONSTRAINT_SCOPE_LIST => 'serializeContextTypeList', + ViolationMessage::TYPE_PROPERTY_SCOPE => 'serializeContextType', + ViolationMessage::TYPE_PROPERTY_SCOPE_LIST => 'serializeContextTypeList', + ViolationMessage::TYPE_LANGUAGE => 'serializeStringByIdentity', + ViolationMessage::TYPE_LANGUAGE_LIST => 'serializeStringListByIdentity', + ViolationMessage::TYPE_MULTILINGUAL_TEXT => 'serializeMultilingualText', + ]; + + $type = $argument['type']; + $value = $argument['value']; + $role = $argument['role']; + + if ( array_key_exists( $type, $methods ) ) { + $method = $methods[$type]; + $serializedValue = $this->$method( $value ); + } else { + throw new InvalidArgumentException( + 'Unknown ViolationMessage argument type ' . $type . '!' + ); + } + + $serialized = [ + 't' => $type, + 'v' => $serializedValue, + 'r' => $role, + ]; + + return $serialized; + } + + /** + * @param string $string any value that shall simply be serialized to itself + * @return string that same value, unchanged + */ + private function serializeStringByIdentity( $string ) { + Assert::parameterType( 'string', $string, '$string' ); + return $string; + } + + /** + * @param string[] $strings + * @return string[] + */ + private function serializeStringListByIdentity( $strings ) { + Assert::parameterElementType( 'string', $strings, '$strings' ); + return $strings; + } + + /** + * @param EntityId $entityId + * @return string entity ID serialization + */ + private function serializeEntityId( EntityId $entityId ) { + return $entityId->getSerialization(); + } + + /** + * @param EntityId[] $entityIdList + * @return string[] entity ID serializations + */ + private function serializeEntityIdList( array $entityIdList ) { + return array_map( [ $this, 'serializeEntityId' ], $entityIdList ); + } + + /** + * @param ItemIdSnakValue $value + * @return string entity ID serialization, '::somevalue', or '::novalue' + * (according to EntityId::PATTERN, entity ID serializations can never begin with two colons) + */ + private function serializeItemIdSnakValue( ItemIdSnakValue $value ) { + switch ( true ) { + case $value->isValue(): + return $this->serializeEntityId( $value->getItemId() ); + case $value->isSomeValue(): + return '::somevalue'; + case $value->isNoValue(): + return '::novalue'; + default: + // @codeCoverageIgnoreStart + throw new LogicException( + 'ItemIdSnakValue should guarantee that one of is{,Some,No}Value() is true' + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * @param ItemIdSnakValue[] $valueList + * @return string[] array of entity ID serializations, '::somevalue's or '::novalue's + */ + private function serializeItemIdSnakValueList( array $valueList ) { + return array_map( [ $this, 'serializeItemIdSnakValue' ], $valueList ); + } + + /** + * @param DataValue $dataValue + * @return array the data value in array form + */ + private function serializeDataValue( DataValue $dataValue ) { + return $dataValue->toArray(); + } + + /** + * @param string $contextType one of the Context::TYPE_* constants + * @return string the abbreviated context type + */ + private function serializeContextType( $contextType ) { + switch ( $contextType ) { + case Context::TYPE_STATEMENT: + return 's'; + case Context::TYPE_QUALIFIER: + return 'q'; + case Context::TYPE_REFERENCE: + return 'r'; + default: + // @codeCoverageIgnoreStart + throw new LogicException( + 'Unknown context type ' . $contextType + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * @param string[] $contextTypeList Context::TYPE_* constants + * @return string[] abbreviated context types + */ + private function serializeContextTypeList( array $contextTypeList ) { + return array_map( [ $this, 'serializeContextType' ], $contextTypeList ); + } + + /** + * @param MultilingualTextValue $text + * @return mixed {@see MultilingualTextValue::getArrayValue} + */ + private function serializeMultilingualText( MultilingualTextValue $text ) { + return $text->getArrayValue(); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResult.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResult.php new file mode 100644 index 000000000..02d3f7b2f --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResult.php @@ -0,0 +1,241 @@ + string[]) parsed constraint parameters + * ($constraint->getParameters() contains the unparsed parameters) + * @param string $status One of the self::STATUS_… constants + * @param ViolationMessage|null $message + */ + public function __construct( + $contextCursor, + Constraint $constraint, + array $parameters = [], + $status = self::STATUS_TODO, + ViolationMessage $message = null + ) { + if ( $contextCursor instanceof Context ) { + $context = $contextCursor; + $this->contextCursor = $context->getCursor(); + $this->snakType = $context->getSnak()->getType(); + $mainSnak = $context->getSnak(); + if ( $mainSnak instanceof PropertyValueSnak ) { + $this->dataValue = $mainSnak->getDataValue(); + } else { + $this->dataValue = null; + } + } else { + $this->contextCursor = $contextCursor; + $this->snakType = null; + $this->dataValue = null; + } + $this->constraint = $constraint; + $this->parameters = $parameters; + $this->status = $status; + $this->message = $message; + $this->metadata = Metadata::blank(); + } + + /** + * @return ContextCursor + */ + public function getContextCursor() { + return $this->contextCursor; + } + + /** + * @return string|null only available if the CheckResult was created from a full Context + */ + public function getSnakType() { + return $this->snakType; + } + + /** + * @return DataValue|null only available if the CheckResult was created from a full Context + */ + public function getDataValue() { + return $this->dataValue; + } + + /** + * @return Constraint + */ + public function getConstraint() { + return $this->constraint; + } + + /** + * @return string + */ + public function getConstraintId() { + return $this->constraint->getConstraintId(); + } + + /** + * @return array[] + */ + public function getParameters() { + return $this->parameters; + } + + /** + * @param string $key + * @param string $value + */ + public function addParameter( $key, $value ) { + $this->parameters[$key][] = $value; + } + + /** + * @return string One of the self::STATUS_… constants + */ + public function getStatus() { + return $this->status; + } + + /** + * @param string $status + */ + public function setStatus( $status ) { + $this->status = $status; + } + + /** + * @return ViolationMessage|null + */ + public function getMessage() { + return $this->message; + } + + /** + * @param Metadata $metadata + * @return self + */ + public function withMetadata( Metadata $metadata ) { + $this->metadata = $metadata; + return $this; + } + + /** + * @return Metadata + */ + public function getMetadata() { + return $this->metadata; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultDeserializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultDeserializer.php new file mode 100644 index 000000000..039dbe1df --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultDeserializer.php @@ -0,0 +1,183 @@ +constraintDeserializer = $constraintDeserializer; + $this->contextCursorDeserializer = $contextCursorDeserializer; + $this->violationMessageDeserializer = $violationMessageDeserializer; + $this->entityIdParser = $entityIdParser; + } + + /** + * @param array $serialization + * @return CheckResult + */ + public function deserialize( array $serialization ) { + $contextCursor = $this->contextCursorDeserializer->deserialize( + $serialization[CheckResultSerializer::KEY_CONTEXT_CURSOR] + ); + + if ( array_key_exists( CheckResultSerializer::KEY_NULL_RESULT, $serialization ) ) { + $result = new NullResult( $contextCursor ); + $cachingMetadata = CachingMetadata::fresh(); + } else { + $constraint = $this->constraintDeserializer->deserialize( + $serialization[CheckResultSerializer::KEY_CONSTRAINT] + ); + + $parameters = []; // serialization of parameters not supported yet + + $status = $serialization[CheckResultSerializer::KEY_CHECK_RESULT_STATUS]; + + $violationMessage = $this->getViolationMessageFromSerialization( $serialization ); + + $result = new CheckResult( + $contextCursor, + $constraint, + $parameters, + $status, + $violationMessage + ); + + $cachingMetadata = $this->deserializeCachingMetadata( + $serialization[CheckResultSerializer::KEY_CACHING_METADATA] + ); + } + + $dependencyMetadata = $this->getDependencyMetadataFromSerialization( $serialization ); + + return $result->withMetadata( + Metadata::merge( [ + Metadata::ofCachingMetadata( $cachingMetadata ), + Metadata::ofDependencyMetadata( $dependencyMetadata ), + ] ) + ); + } + + /** + * @param array $serialization + * @return null|ViolationMessage + */ + private function getViolationMessageFromSerialization( array $serialization ) { + if ( array_key_exists( CheckResultSerializer::KEY_VIOLATION_MESSAGE, $serialization ) ) { + return $this->violationMessageDeserializer->deserialize( + $serialization[CheckResultSerializer::KEY_VIOLATION_MESSAGE] + ); + } else { + return null; + } + } + + /** + * @param array $serialization + * @return DependencyMetadata + */ + private function getDependencyMetadataFromSerialization( array $serialization ) { + if ( array_key_exists( CheckResultSerializer::KEY_DEPENDENCY_METADATA, $serialization ) ) { + return $this->deserializeDependencyMetadata( + $serialization[CheckResultSerializer::KEY_DEPENDENCY_METADATA] + ); + } else { + return DependencyMetadata::blank(); + } + } + + /** + * @param array $serialization + * @return CachingMetadata + */ + private function deserializeCachingMetadata( array $serialization ) { + if ( + array_key_exists( + CheckResultSerializer::KEY_CACHING_METADATA_MAX_AGE, + $serialization + ) + ) { + return CachingMetadata::ofMaximumAgeInSeconds( + $serialization[CheckResultSerializer::KEY_CACHING_METADATA_MAX_AGE] + ); + } else { + return CachingMetadata::fresh(); + } + } + + /** + * @param array $serialization + * @return DependencyMetadata + */ + private function deserializeDependencyMetadata( array $serialization ) { + if ( + array_key_exists( + CheckResultSerializer::KEY_DEPENDENCY_METADATA_FUTURE_TIME, + $serialization + ) + ) { + $futureTime = TimeValue::newFromArray( + $serialization[CheckResultSerializer::KEY_DEPENDENCY_METADATA_FUTURE_TIME] + ); + $futureTimeDependencyMetadata = DependencyMetadata::ofFutureTime( $futureTime ); + } else { + $futureTimeDependencyMetadata = DependencyMetadata::blank(); + } + + $dependencyMetadata = array_reduce( + $serialization[CheckResultSerializer::KEY_DEPENDENCY_METADATA_ENTITY_IDS], + function ( DependencyMetadata $metadata, $entityIdSerialization ) { + $entityId = $this->entityIdParser->parse( $entityIdSerialization ); + + return DependencyMetadata::merge( [ + $metadata, + DependencyMetadata::ofEntityId( $entityId ) + ] ); + }, + $futureTimeDependencyMetadata + ); + + return $dependencyMetadata; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultSerializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultSerializer.php new file mode 100644 index 000000000..6fed9ca97 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/CheckResultSerializer.php @@ -0,0 +1,156 @@ +constraintSerializer = $constraintSerializer; + $this->contextCursorSerializer = $contextCursorSerializer; + $this->violationMessageSerializer = $violationMessageSerializer; + $this->serializeDependencyMetadata = $serializeDependencyMetadata; + } + + /** + * @param CheckResult $checkResult + * @return array + */ + public function serialize( CheckResult $checkResult ) { + $contextCursor = $checkResult->getContextCursor(); + + $serialization = [ + self::KEY_CONTEXT_CURSOR => $this->contextCursorSerializer->serialize( $contextCursor ), + ]; + + if ( $checkResult instanceof NullResult ) { + $serialization[self::KEY_NULL_RESULT] = 1; + } else { + $constraint = $checkResult->getConstraint(); + $cachingMetadata = $checkResult->getMetadata()->getCachingMetadata(); + $violationMessage = $checkResult->getMessage(); + + $serialization[self::KEY_CONSTRAINT] = + $this->constraintSerializer->serialize( $constraint ); + $serialization[self::KEY_CHECK_RESULT_STATUS] = + $checkResult->getStatus(); + $serialization[self::KEY_CACHING_METADATA] = + $this->serializeCachingMetadata( $cachingMetadata ); + + if ( $violationMessage !== null ) { + $serialization[self::KEY_VIOLATION_MESSAGE] = + $this->violationMessageSerializer->serialize( $violationMessage ); + } + } + + if ( $this->serializeDependencyMetadata ) { + $serialization[self::KEY_DEPENDENCY_METADATA] = + $this->serializeDependencyMetadata( $checkResult ); + } + + return $serialization; + } + + /** + * @param CachingMetadata $cachingMetadata + * @return array + */ + private function serializeCachingMetadata( CachingMetadata $cachingMetadata ) { + $maximumAge = $cachingMetadata->getMaximumAgeInSeconds(); + + $serialization = []; + + if ( $maximumAge > 0 ) { + $serialization[self::KEY_CACHING_METADATA_MAX_AGE] = $maximumAge; + } + + return $serialization; + } + + /** + * @param CheckResult $checkResult + * @return array + */ + private function serializeDependencyMetadata( CheckResult $checkResult ) { + $dependencyMetadata = $checkResult->getMetadata()->getDependencyMetadata(); + $entityIds = $dependencyMetadata->getEntityIds(); + $futureTime = $dependencyMetadata->getFutureTime(); + + $serialization = [ + self::KEY_DEPENDENCY_METADATA_ENTITY_IDS => array_map( + static function ( EntityId $entityId ) { + return $entityId->getSerialization(); + }, + $entityIds + ), + ]; + + if ( $futureTime !== null ) { + $serialization[self::KEY_DEPENDENCY_METADATA_FUTURE_TIME] = + $futureTime->getArrayValue(); + } + + return $serialization; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/NullResult.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/NullResult.php new file mode 100644 index 000000000..45a965648 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintCheck/Result/NullResult.php @@ -0,0 +1,46 @@ +getService( $name ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getConflictsWithChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::CONFLICTS_WITH_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getItemChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::ITEM_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getTargetRequiredClaimChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::TARGET_REQUIRED_CLAIM_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getSymmetricChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::SYMMETRIC_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getInverseChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::INVERSE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getQualifierChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::QUALIFIER_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getQualifiersChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::QUALIFIERS_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getMandatoryQualifiersChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::MANDATORY_QUALIFIERS_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getRangeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::RANGE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getDiffWithinRangeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::DIFF_WITHIN_RANGE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getTypeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::TYPE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getValueTypeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::VALUE_TYPE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getSingleValueChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::SINGLE_VALUE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getMultiValueChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::MULTI_VALUE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getUniqueValueChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::UNIQUE_VALUE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getFormatChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::FORMAT_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getCommonsLinkChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::COMMONS_LINK_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getOneOfChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::ONE_OF_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getValueOnlyChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::VALUE_ONLY_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getReferenceChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::REFERENCE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getNoBoundsChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::NO_BOUNDS_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getAllowedUnitsChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::ALLOWED_UNITS_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getSingleBestValueChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::SINGLE_BEST_VALUE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getEntityTypeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::ENTITY_TYPE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getNoneOfChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::NONE_OF_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getIntegerChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::INTEGER_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getCitationNeededChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::CITATION_NEEDED_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getPropertyScopeChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::PROPERTY_SCOPE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return ConstraintChecker + */ + public static function getContemporaryChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::CONTEMPORARY_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return LanguageChecker + */ + public static function getLexemeLanguageChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::LEXEME_LANGUAGE_CHECKER ); + } + + /** + * @param MediaWikiServices|null $services + * @return LabelInLanguageChecker + */ + public static function getLabelInLanguageChecker( MediaWikiServices $services = null ) { + return self::getService( $services, self::LABEL_IN_LANGUAGE_CHECKER ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintDeserializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintDeserializer.php new file mode 100644 index 000000000..2ab0d8024 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintDeserializer.php @@ -0,0 +1,24 @@ +entityIdLabelFormatter = $entityIdFormatter; + $this->dataValueFormatter = $dataValueFormatter; + $this->messageLocalizer = $messageLocalizer; + $this->config = $config; + } + + /** + * Formats parameter values of constraints. + * + * @param string|ItemId|NumericPropertyId|DataValue $value + * + * @return string HTML + */ + public function formatValue( $value ) { + if ( is_string( $value ) ) { + // Cases like 'Format' 'pattern' or 'minimum'/'maximum' values, which we have stored as + // strings + return htmlspecialchars( $value ); + } elseif ( $value instanceof EntityId ) { + // Cases like 'Conflicts with' 'property', to which we can link + return $this->formatEntityId( $value ); + } elseif ( $value instanceof ItemIdSnakValue ) { + // Cases like EntityId but can also be somevalue or novalue + return $this->formatItemIdSnakValue( $value ); + } else { + // Cases where we format a DataValue + return $this->formatDataValue( $value ); + } + } + + /** + * Formats constraint parameters. + * + * @param (string|ItemId|NumericPropertyId|DataValue)[][]|null $parameters + * + * @return string|null HTML + */ + public function formatParameters( $parameters ) { + if ( $parameters === null || $parameters === [] ) { + return null; + } + + $valueFormatter = function ( $value ) { + return $this->formatValue( $value ); + }; + + $formattedParameters = []; + foreach ( $parameters as $parameterName => $parameterValue ) { + $formattedParameterValues = implode( ', ', + $this->limitArrayLength( array_map( $valueFormatter, $parameterValue ) ) ); + $formattedParameters[] = sprintf( '%s: %s', $parameterName, $formattedParameterValues ); + } + + return implode( '; ', $formattedParameters ); + } + + /** + * Cuts an array after n values and appends dots if needed. + * + * @param string[] $array + * + * @return string[] + */ + private function limitArrayLength( array $array ) { + if ( count( $array ) > self::MAX_PARAMETER_ARRAY_LENGTH ) { + $array = array_slice( $array, 0, self::MAX_PARAMETER_ARRAY_LENGTH ); + array_push( $array, '...' ); + } + + return $array; + } + + /** + * @param DataValue $value + * @return string HTML + */ + public function formatDataValue( DataValue $value ) { + return $this->dataValueFormatter->format( $value ); + } + + /** + * @param EntityId $entityId + * @return string HTML + */ + public function formatEntityId( EntityId $entityId ) { + return $this->entityIdLabelFormatter->formatEntityId( $entityId ); + } + + /** + * Format an {@link ItemIdSnakValue} (known value, unknown value, or no value). + * + * @param ItemIdSnakValue $value + * @return string HTML + */ + public function formatItemIdSnakValue( ItemIdSnakValue $value ) { + switch ( true ) { + case $value->isValue(): + return $this->formatEntityId( $value->getItemId() ); + case $value->isSomeValue(): + return $this->messageLocalizer + ->msg( 'wikibase-snakview-snaktypeselector-somevalue' ) + ->escaped(); + case $value->isNoValue(): + return $this->messageLocalizer + ->msg( 'wikibase-snakview-snaktypeselector-novalue' ) + ->escaped(); + } + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryLookup.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryLookup.php new file mode 100644 index 000000000..cb501b3ee --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryLookup.php @@ -0,0 +1,88 @@ +lb = $lb; + $this->dbName = $dbName; + } + + /** + * @param NumericPropertyId $propertyId + * + * @return Constraint[] + */ + public function queryConstraintsForProperty( NumericPropertyId $propertyId ) { + $dbr = $this->lb->getConnection( ILoadBalancer::DB_REPLICA, [], $this->dbName ); + + $results = $dbr->newSelectQueryBuilder() + ->select( [ + 'constraint_type_qid', + 'constraint_parameters', + 'constraint_guid', + 'pid', + ] ) + ->from( 'wbqc_constraints' ) + ->where( [ 'pid' => $propertyId->getNumericId() ] ) + ->caller( __METHOD__ ) + ->fetchResultSet(); + + return $this->convertToConstraints( $results ); + } + + /** + * @param IResultWrapper $results + * + * @return Constraint[] + */ + private function convertToConstraints( IResultWrapper $results ) { + $constraints = []; + $logger = LoggerFactory::getInstance( 'WikibaseQualityConstraints' ); + foreach ( $results as $result ) { + $constraintTypeItemId = $result->constraint_type_qid; + $constraintParameters = json_decode( $result->constraint_parameters, true ); + + if ( $constraintParameters === null ) { + // T171295 + $logger->warning( 'Constraint {constraintId} has invalid constraint parameters.', [ + 'method' => __METHOD__, + 'constraintId' => $result->constraint_guid, + 'constraintParameters' => $result->constraint_parameters, + ] ); + $constraintParameters = [ '@error' => [ /* unknown */ ] ]; + } + + $constraints[] = new Constraint( + $result->constraint_guid, + NumericPropertyId::newFromNumber( $result->pid ), + $constraintTypeItemId, + $constraintParameters + ); + } + return $constraints; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryStore.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryStore.php new file mode 100644 index 000000000..2f89ad4be --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintRepositoryStore.php @@ -0,0 +1,83 @@ +lb = $lb; + $this->dbName = $dbName; + } + + private function encodeConstraintParameters( array $constraintParameters ) { + $json = json_encode( $constraintParameters, JSON_FORCE_OBJECT ); + + if ( strlen( $json ) > 50000 ) { + $json = json_encode( [ '@error' => [ 'toolong' => true ] ] ); + } + + return $json; + } + + /** + * @param Constraint[] $constraints + * + * @throws DBUnexpectedError + * @return bool + */ + public function insertBatch( array $constraints ) { + $accumulator = array_map( + function ( Constraint $constraint ) { + return [ + 'constraint_guid' => $constraint->getConstraintId(), + 'pid' => $constraint->getPropertyId()->getNumericId(), + 'constraint_type_qid' => $constraint->getConstraintTypeItemId(), + 'constraint_parameters' => $this->encodeConstraintParameters( $constraint->getConstraintParameters() ) + ]; + }, + $constraints + ); + + $dbw = $this->lb->getConnection( ILoadBalancer::DB_PRIMARY, [], $this->dbName ); + return $dbw->insert( 'wbqc_constraints', $accumulator, __METHOD__ ); + } + + /** + * Delete all constraints for the property ID. + * + * @param NumericPropertyId $propertyId + * + * @throws DBUnexpectedError + */ + public function deleteForProperty( NumericPropertyId $propertyId ) { + $dbw = $this->lb->getConnection( ILoadBalancer::DB_PRIMARY, [], $this->dbName ); + $dbw->delete( + 'wbqc_constraints', + [ + 'pid' => $propertyId->getNumericId(), + ], + __METHOD__ + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintSerializer.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintSerializer.php new file mode 100644 index 000000000..84de3866b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintSerializer.php @@ -0,0 +1,39 @@ +serializeConstraintParameters = $serializeConstraintParameters; + } + + /** + * @param Constraint $constraint + * @return array + */ + public function serialize( Constraint $constraint ) { + $serialization = [ + 'id' => $constraint->getConstraintId(), + 'pid' => $constraint->getPropertyId()->getSerialization(), + 'qid' => $constraint->getConstraintTypeItemId(), + ]; + if ( $this->serializeConstraintParameters ) { + $serialization['params'] = $constraint->getConstraintParameters(); + } + return $serialization; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/ConstraintStore.php b/dist/extensions/WikibaseQualityConstraints/src/ConstraintStore.php new file mode 100644 index 000000000..a47c679c1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ConstraintStore.php @@ -0,0 +1,30 @@ +getService( $name ); + } + + public static function getLoggingHelper( MediaWikiServices $services = null ): LoggingHelper { + return self::getService( $services, self::LOGGING_HELPER ); + } + + public static function getConstraintStore( + MediaWikiServices $services = null + ): ConstraintStore { + return self::getService( $services, self::CONSTRAINT_STORE ); + } + + public static function getConstraintLookup( MediaWikiServices $services = null ): ConstraintLookup { + return self::getService( $services, self::CONSTRAINT_LOOKUP ); + } + + public static function getCheckResultSerializer( + MediaWikiServices $services = null + ): CheckResultSerializer { + return self::getService( $services, self::CHECK_RESULT_SERIALIZER ); + } + + public static function getCheckResultDeserializer( + MediaWikiServices $services = null + ): CheckResultDeserializer { + return self::getService( $services, self::CHECK_RESULT_DESERIALIZER ); + } + + public static function getViolationMessageSerializer( + MediaWikiServices $services = null + ): ViolationMessageSerializer { + return self::getService( $services, self::VIOLATION_MESSAGE_SERIALIZER ); + } + + public static function getViolationMessageDeserializer( + MediaWikiServices $services = null + ): ViolationMessageDeserializer { + return self::getService( $services, self::VIOLATION_MESSAGE_DESERIALIZER ); + } + + public static function getConstraintParameterParser( + MediaWikiServices $services = null + ): ConstraintParameterParser { + return self::getService( $services, self::CONSTRAINT_PARAMETER_PARSER ); + } + + public static function getConnectionCheckerHelper( + MediaWikiServices $services = null + ): ConnectionCheckerHelper { + return self::getService( $services, self::CONNECTION_CHECKER_HELPER ); + } + + public static function getRangeCheckerHelper( MediaWikiServices $services = null ): RangeCheckerHelper { + return self::getService( $services, self::RANGE_CHECKER_HELPER ); + } + + public static function getSparqlHelper( MediaWikiServices $services = null ): SparqlHelper { + return self::getService( $services, self::SPARQL_HELPER ); + } + + public static function getTypeCheckerHelper( MediaWikiServices $services = null ): TypeCheckerHelper { + return self::getService( $services, self::TYPE_CHECKER_HELPER ); + } + + public static function getDelegatingConstraintChecker( + MediaWikiServices $services = null + ): DelegatingConstraintChecker { + return self::getService( $services, self::DELEGATING_CONSTRAINT_CHECKER ); + } + + public static function getResultsSource( MediaWikiServices $services = null ): ResultsSource { + return self::getService( $services, self::RESULTS_SOURCE ); + } + + public static function getExpiryLock( MediaWikiServices $services = null ): ExpiryLock { + return self::getService( $services, self::EXPIRY_LOCK ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableBuilder.php b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableBuilder.php new file mode 100644 index 000000000..49912f2d5 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableBuilder.php @@ -0,0 +1,161 @@ +addHeader( $header ); + } + } + + /** + * @param string|HtmlTableHeaderBuilder $header + * + * @throws InvalidArgumentException + */ + private function addHeader( $header ) { + Assert::parameterType( 'string|' . HtmlTableHeaderBuilder::class, $header, '$header' ); + + if ( is_string( $header ) ) { + $header = new HtmlTableHeaderBuilder( $header ); + } + + $this->headers[] = $header; + + if ( $header->getIsSortable() ) { + $this->isSortable = true; + } + } + + /** + * @return HtmlTableHeaderBuilder[] + */ + public function getHeaders() { + return $this->headers; + } + + /** + * @return array[] + */ + public function getRows() { + return $this->rows; + } + + /** + * @return bool + */ + public function isSortable() { + return $this->isSortable; + } + + /** + * Adds row with specified cells to table. + * + * @param string[]|HtmlTableCellBuilder[] $cells + * + * @throws InvalidArgumentException + */ + public function appendRow( array $cells ) { + foreach ( $cells as $key => $cell ) { + if ( is_string( $cell ) ) { + $cells[$key] = new HtmlTableCellBuilder( $cell ); + } elseif ( !( $cell instanceof HtmlTableCellBuilder ) ) { + throw new InvalidArgumentException( '$cells must be array of HtmlTableCell objects.' ); + } + } + + $this->rows[] = $cells; + } + + /** + * Adds rows with specified cells to table. + * + * @param array[] $rows + * + * @throws InvalidArgumentException + */ + public function appendRows( array $rows ) { + foreach ( $rows as $cells ) { + if ( !is_array( $cells ) ) { + throw new InvalidArgumentException( '$rows must be array of arrays of HtmlTableCell objects.' ); + } + + $this->appendRow( $cells ); + } + } + + /** + * Returns table as html. + * + * @return string + */ + public function toHtml() { + // Open table + $tableClasses = 'wikitable'; + if ( $this->isSortable ) { + $tableClasses .= ' sortable'; + } + $html = Html::openElement( 'table', [ 'class' => $tableClasses ] ); + + // Write headers + $html .= Html::openElement( 'thead' ); + $html .= Html::openElement( 'tr' ); + foreach ( $this->headers as $header ) { + $html .= $header->toHtml(); + } + $html .= Html::closeElement( 'tr' ); + $html .= Html::closeElement( 'thead' ); + $html .= Html::openElement( 'tbody' ); + + // Write rows + foreach ( $this->rows as $row ) { + $html .= Html::openElement( 'tr' ); + + /** + * @var HtmlTableCellBuilder $cell + */ + foreach ( $row as $cell ) { + $html .= $cell->toHtml(); + } + + $html .= Html::closeElement( 'tr' ); + } + + // Close table + $html .= Html::closeElement( 'tbody' ); + $html .= Html::closeElement( 'table' ); + + return $html; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableCellBuilder.php b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableCellBuilder.php new file mode 100644 index 000000000..db6baac99 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableCellBuilder.php @@ -0,0 +1,76 @@ +content = $content; + $this->attributes = $attributes; + $this->isRawContent = $isRawContent; + } + + /** + * @return string HTML + */ + public function getContent() { + return $this->content; + } + + /** + * @return array + */ + public function getAttributes() { + return $this->attributes; + } + + /** + * @return string HTML + * @suppress SecurityCheck-DoubleEscaped + */ + public function toHtml() { + if ( $this->isRawContent ) { + return Html::rawElement( 'td', $this->getAttributes(), $this->content ); + } else { + return Html::element( 'td', $this->getAttributes(), $this->content ); + } + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableHeaderBuilder.php b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableHeaderBuilder.php new file mode 100644 index 000000000..23eefa4c0 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Html/HtmlTableHeaderBuilder.php @@ -0,0 +1,90 @@ +content = $content; + $this->isSortable = $isSortable; + $this->isRawContent = $isRawContent; + } + + /** + * @return string + */ + public function getContent() { + return $this->content; + } + + /** + * @return bool + */ + public function getIsSortable() { + return $this->isSortable; + } + + /** + * Returns header as html. + * + * @return string HTML + */ + public function toHtml() { + $attributes = [ 'role' => 'columnheader button' ]; + + if ( !$this->isSortable ) { + $attributes['class'] = 'unsortable'; + } + + if ( !$this->isRawContent ) { + // @phan-suppress-next-line SecurityCheck-DoubleEscaped + $content = htmlspecialchars( $this->content ); + } else { + $content = $this->content; + } + + return Html::rawElement( 'th', $attributes, $content ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Job/CheckConstraintsJob.php b/dist/extensions/WikibaseQualityConstraints/src/Job/CheckConstraintsJob.php new file mode 100644 index 000000000..f5556aa9a --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Job/CheckConstraintsJob.php @@ -0,0 +1,88 @@ + 'Q1234' + */ + public function __construct( Title $title, array $params ) { + parent::__construct( self::COMMAND, $title, $params ); + $this->removeDuplicates = true; + + Assert::parameterType( 'string', $params['entityId'], '$params[\'entityId\']' ); + + $resultSource = ConstraintsServices::getResultsSource( MediaWikiServices::getInstance() ); + '@phan-var CachingResultsSource $resultSource'; + // This job should only ever be used when caching result sources are used. + $this->setResultsSource( $resultSource ); + + $this->setEntityIdParser( WikibaseRepo::getEntityIdParser() ); + } + + public function setResultsSource( CachingResultsSource $resultsSource ) { + $this->resultsSource = $resultsSource; + } + + public function setEntityIdParser( EntityIdParser $parser ) { + $this->entityIdParser = $parser; + } + + /** + * @see Job::run + * + * @return bool + */ + public function run() { + try { + $entityId = $this->entityIdParser->parse( $this->params['entityId'] ); + } catch ( EntityIdParsingException $e ) { + return false; + } + + $this->checkConstraints( $entityId ); + + return true; + } + + private function checkConstraints( EntityId $entityId ) { + $this->resultsSource->getResults( + [ $entityId ], + [], + null, + [] + ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Job/UpdateConstraintsTableJob.php b/dist/extensions/WikibaseQualityConstraints/src/Job/UpdateConstraintsTableJob.php new file mode 100644 index 000000000..2551ee0d2 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Job/UpdateConstraintsTableJob.php @@ -0,0 +1,231 @@ +getMainConfig(), + ConstraintsServices::getConstraintStore(), + $services->getDBLoadBalancerFactory(), + WikibaseRepo::getStore()->getEntityRevisionLookup( Store::LOOKUP_CACHING_DISABLED ), + WikibaseRepo::getBaseDataModelSerializerFactory( $services ) + ->newSnakSerializer(), + $services->getJobQueueGroup() + ); + } + + /** + * @var string + */ + private $propertyId; + + /** + * @var int|null + */ + private $revisionId; + + /** + * @var Config + */ + private $config; + + /** + * @var ConstraintStore + */ + private $constraintStore; + + /** @var ILBFactory */ + private $lbFactory; + + /** + * @var EntityRevisionLookup + */ + private $entityRevisionLookup; + + /** + * @var Serializer + */ + private $snakSerializer; + + /** + * @var JobQueueGroup + */ + private $jobQueueGroup; + + /** + * @param Title $title + * @param string[] $params should contain 'propertyId' => 'P...' + * @param string $propertyId property ID of the property for this job (which has the constraint statements) + * @param int|null $revisionId revision ID that triggered this job, if any + * @param Config $config + * @param ConstraintStore $constraintStore + * @param ILBFactory $lbFactory + * @param EntityRevisionLookup $entityRevisionLookup + * @param Serializer $snakSerializer + * @param JobQueueGroup $jobQueueGroup + */ + public function __construct( + Title $title, + array $params, + $propertyId, + $revisionId, + Config $config, + ConstraintStore $constraintStore, + ILBFactory $lbFactory, + EntityRevisionLookup $entityRevisionLookup, + Serializer $snakSerializer, + JobQueueGroup $jobQueueGroup + ) { + parent::__construct( 'constraintsTableUpdate', $title, $params ); + + $this->propertyId = $propertyId; + $this->revisionId = $revisionId; + $this->config = $config; + $this->constraintStore = $constraintStore; + $this->lbFactory = $lbFactory; + $this->entityRevisionLookup = $entityRevisionLookup; + $this->snakSerializer = $snakSerializer; + $this->jobQueueGroup = $jobQueueGroup; + } + + public function extractParametersFromQualifiers( SnakList $qualifiers ) { + $parameters = []; + foreach ( $qualifiers as $qualifier ) { + $qualifierId = $qualifier->getPropertyId()->getSerialization(); + $paramSerialization = $this->snakSerializer->serialize( $qualifier ); + $parameters[$qualifierId][] = $paramSerialization; + } + return $parameters; + } + + public function extractConstraintFromStatement( + NumericPropertyId $propertyId, + Statement $constraintStatement + ) { + $constraintId = $constraintStatement->getGuid(); + $snak = $constraintStatement->getMainSnak(); + '@phan-var \Wikibase\DataModel\Snak\PropertyValueSnak $snak'; + $dataValue = $snak->getDataValue(); + '@phan-var \Wikibase\DataModel\Entity\EntityIdValue $dataValue'; + $entityId = $dataValue->getEntityId(); + $constraintTypeQid = $entityId->getSerialization(); + $parameters = $this->extractParametersFromQualifiers( $constraintStatement->getQualifiers() ); + return new Constraint( + $constraintId, + $propertyId, + $constraintTypeQid, + $parameters + ); + } + + public function importConstraintsForProperty( + Property $property, + ConstraintStore $constraintStore, + NumericPropertyId $propertyConstraintPropertyId + ) { + $constraintsStatements = $property->getStatements() + ->getByPropertyId( $propertyConstraintPropertyId ) + ->getByRank( [ Statement::RANK_PREFERRED, Statement::RANK_NORMAL ] ); + $constraints = []; + foreach ( $constraintsStatements->getIterator() as $constraintStatement ) { + // @phan-suppress-next-line PhanTypeMismatchArgumentSuperType + $constraints[] = $this->extractConstraintFromStatement( $property->getId(), $constraintStatement ); + if ( count( $constraints ) >= self::BATCH_SIZE ) { + $constraintStore->insertBatch( $constraints ); + // interrupt transaction and wait for replication + $connection = $this->lbFactory->getMainLB()->getConnection( DB_PRIMARY ); + $connection->endAtomic( __CLASS__ ); + if ( !$connection->explicitTrxActive() ) { + $this->lbFactory->waitForReplication(); + } + $connection->startAtomic( __CLASS__ ); + $constraints = []; + } + } + $constraintStore->insertBatch( $constraints ); + } + + /** + * @see Job::run + * + * @return bool + */ + public function run() { + // TODO in the future: only touch constraints affected by the edit (requires T163465) + + $propertyId = new NumericPropertyId( $this->propertyId ); + $propertyRevision = $this->entityRevisionLookup->getEntityRevision( + $propertyId, + 0, // latest + LookupConstants::LATEST_FROM_REPLICA + ); + + if ( $this->revisionId !== null && $propertyRevision->getRevisionId() < $this->revisionId ) { + $this->jobQueueGroup->push( $this ); + return true; + } + + $connection = $this->lbFactory->getMainLB()->getConnection( DB_PRIMARY ); + // start transaction (if not started yet) – using __CLASS__, not __METHOD__, + // because importConstraintsForProperty() can interrupt the transaction + $connection->startAtomic( __CLASS__ ); + + $this->constraintStore->deleteForProperty( $propertyId ); + + /** @var Property $property */ + $property = $propertyRevision->getEntity(); + '@phan-var Property $property'; + $this->importConstraintsForProperty( + $property, + $this->constraintStore, + new NumericPropertyId( $this->config->get( 'WBQualityConstraintsPropertyConstraintId' ) ) + ); + + $connection->endAtomic( __CLASS__ ); + + return true; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/Role.php b/dist/extensions/WikibaseQualityConstraints/src/Role.php new file mode 100644 index 000000000..027ea42dd --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Role.php @@ -0,0 +1,78 @@ + static function ( MediaWikiServices $services ) { + return new ConflictsWithChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getConnectionCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::ITEM_CHECKER => static function ( MediaWikiServices $services ) { + return new ItemChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getConnectionCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::TARGET_REQUIRED_CLAIM_CHECKER => static function ( MediaWikiServices $services ) { + return new TargetRequiredClaimChecker( + WikibaseServices::getEntityLookup( $services ), + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getConnectionCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::SYMMETRIC_CHECKER => static function ( MediaWikiServices $services ) { + return new SymmetricChecker( + WikibaseServices::getEntityLookupWithoutCache( $services ), + ConstraintsServices::getConnectionCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::INVERSE_CHECKER => static function ( MediaWikiServices $services ) { + return new InverseChecker( + WikibaseServices::getEntityLookup( $services ), + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getConnectionCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::QUALIFIER_CHECKER => static function ( MediaWikiServices $services ) { + return new QualifierChecker(); + }, + + ConstraintCheckerServices::QUALIFIERS_CHECKER => static function ( MediaWikiServices $services ) { + return new QualifiersChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::MANDATORY_QUALIFIERS_CHECKER => static function ( MediaWikiServices $services ) { + return new MandatoryQualifiersChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::RANGE_CHECKER => static function ( MediaWikiServices $services ) { + return new RangeChecker( + WikibaseServices::getPropertyDataTypeLookup( $services ), + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getRangeCheckerHelper( $services ) + ); + }, + + ConstraintCheckerServices::DIFF_WITHIN_RANGE_CHECKER => static function ( MediaWikiServices $services ) { + return new DiffWithinRangeChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getRangeCheckerHelper( $services ), + $services->getMainConfig() + ); + }, + + ConstraintCheckerServices::TYPE_CHECKER => static function ( MediaWikiServices $services ) { + return new TypeChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getTypeCheckerHelper( $services ), + $services->getMainConfig() + ); + }, + + ConstraintCheckerServices::VALUE_TYPE_CHECKER => static function ( MediaWikiServices $services ) { + return new ValueTypeChecker( + WikibaseServices::getEntityLookup( $services ), + ConstraintsServices::getConstraintParameterParser( $services ), + ConstraintsServices::getTypeCheckerHelper( $services ), + $services->getMainConfig() + ); + }, + + ConstraintCheckerServices::SINGLE_VALUE_CHECKER => static function ( MediaWikiServices $services ) { + return new SingleValueChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::MULTI_VALUE_CHECKER => static function ( MediaWikiServices $services ) { + return new MultiValueChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::UNIQUE_VALUE_CHECKER => static function ( MediaWikiServices $services ) { + // TODO return a different, dummy implementation if SPARQL is not available + return new UniqueValueChecker( + ConstraintsServices::getSparqlHelper( $services ), + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::FORMAT_CHECKER => static function ( MediaWikiServices $services ) { + // TODO return a different, dummy implementation if SPARQL is not available + return new FormatChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + $services->getMainConfig(), + ConstraintsServices::getSparqlHelper( $services ), + $services->getShellboxClientFactory() + ); + }, + + ConstraintCheckerServices::COMMONS_LINK_CHECKER => static function ( MediaWikiServices $services ) { + $pageNameNormalizer = new MediaWikiPageNameNormalizer(); + return new CommonsLinkChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + $pageNameNormalizer, + WikibaseRepo::getPropertyDataTypeLookup( $services ) + ); + }, + + ConstraintCheckerServices::ONE_OF_CHECKER => static function ( MediaWikiServices $services ) { + return new OneOfChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::VALUE_ONLY_CHECKER => static function ( MediaWikiServices $services ) { + return new ValueOnlyChecker(); + }, + + ConstraintCheckerServices::REFERENCE_CHECKER => static function ( MediaWikiServices $services ) { + return new ReferenceChecker(); + }, + + ConstraintCheckerServices::NO_BOUNDS_CHECKER => static function ( MediaWikiServices $services ) { + return new NoBoundsChecker(); + }, + + ConstraintCheckerServices::ALLOWED_UNITS_CHECKER => static function ( MediaWikiServices $services ) { + return new AllowedUnitsChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + WikibaseRepo::getUnitConverter( $services ) + ); + }, + + ConstraintCheckerServices::SINGLE_BEST_VALUE_CHECKER => static function ( MediaWikiServices $services ) { + return new SingleBestValueChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::ENTITY_TYPE_CHECKER => static function ( MediaWikiServices $services ) { + return new EntityTypeChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::NONE_OF_CHECKER => static function ( MediaWikiServices $services ) { + return new NoneOfChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::INTEGER_CHECKER => static function ( MediaWikiServices $services ) { + return new IntegerChecker(); + }, + + ConstraintCheckerServices::CITATION_NEEDED_CHECKER => static function ( MediaWikiServices $services ) { + return new CitationNeededChecker(); + }, + + ConstraintCheckerServices::PROPERTY_SCOPE_CHECKER => static function ( MediaWikiServices $services ) { + return new PropertyScopeChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, + + ConstraintCheckerServices::CONTEMPORARY_CHECKER => static function ( MediaWikiServices $services ) { + return new ContemporaryChecker( + WikibaseServices::getEntityLookup( $services ), + ConstraintsServices::getRangeCheckerHelper( $services ), + $services->getMainConfig() + ); + }, + + ConstraintCheckerServices::LEXEME_LANGUAGE_CHECKER => static function ( MediaWikiServices $services ) { + return new LanguageChecker( + ConstraintsServices::getConstraintParameterParser( $services ), + WikibaseServices::getEntityLookup( $services ) + ); + }, + + ConstraintCheckerServices::LABEL_IN_LANGUAGE_CHECKER => static function ( MediaWikiServices $services ) { + return new LabelInLanguageChecker( + ConstraintsServices::getConstraintParameterParser( $services ) + ); + }, +]; diff --git a/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring-Wikibase.php b/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring-Wikibase.php new file mode 100644 index 000000000..d5716f2c8 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring-Wikibase.php @@ -0,0 +1,27 @@ + static function ( MediaWikiServices $services ) { + return new ExceptionIgnoringEntityLookup( + WikibaseRepo::getEntityLookup( $services ) + ); + }, + + WikibaseServices::ENTITY_LOOKUP_WITHOUT_CACHE => static function ( MediaWikiServices $services ) { + return new ExceptionIgnoringEntityLookup( + WikibaseRepo::getStore( $services ) + ->getEntityLookup( Store::LOOKUP_CACHING_RETRIEVE_ONLY ) + ); + }, + + WikibaseServices::PROPERTY_DATA_TYPE_LOOKUP => static function ( MediaWikiServices $services ) { + return WikibaseRepo::getPropertyDataTypeLookup( $services ); + }, +]; diff --git a/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring.php b/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring.php new file mode 100644 index 000000000..99a4575cc --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/ServiceWiring.php @@ -0,0 +1,311 @@ + static function ( MediaWikiServices $services ) { + return new ExpiryLock( ObjectCache::getInstance( CACHE_ANYTHING ) ); + }, + + ConstraintsServices::LOGGING_HELPER => static function ( MediaWikiServices $services ) { + return new LoggingHelper( + $services->getStatsdDataFactory(), + LoggerFactory::getInstance( 'WikibaseQualityConstraints' ), + $services->getMainConfig() + ); + }, + + ConstraintsServices::CONSTRAINT_STORE => static function ( MediaWikiServices $services ) { + $sourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services ); + $propertySource = $sourceDefinitions->getDatabaseSourceForEntityType( Property::ENTITY_TYPE ); + if ( $propertySource === null ) { + throw new RuntimeException( 'Can\'t get a ConstraintStore for properties not stored in a database.' ); + } + + $localEntitySourceName = WikibaseRepo::getLocalEntitySource( $services )->getSourceName(); + if ( $propertySource->getSourceName() !== $localEntitySourceName ) { + throw new RuntimeException( 'Can\'t get a ConstraintStore for a non local entity source.' ); + } + + $dbName = $propertySource->getDatabaseName(); + return new ConstraintRepositoryStore( + $services->getDBLoadBalancerFactory()->getMainLB( $dbName ), + $dbName + ); + }, + + ConstraintsServices::CONSTRAINT_LOOKUP => static function ( MediaWikiServices $services ) { + $sourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services ); + $propertySource = $sourceDefinitions->getDatabaseSourceForEntityType( Property::ENTITY_TYPE ); + if ( $propertySource === null ) { + throw new RuntimeException( 'Can\'t get a ConstraintStore for properties not stored in a database.' ); + } + + $dbName = $propertySource->getDatabaseName(); + $rawLookup = new ConstraintRepositoryLookup( + $services->getDBLoadBalancerFactory()->getMainLB( $dbName ), + $dbName + ); + return new CachingConstraintLookup( $rawLookup ); + }, + + ConstraintsServices::CHECK_RESULT_SERIALIZER => static function ( MediaWikiServices $services ) { + return new CheckResultSerializer( + new ConstraintSerializer( + false // constraint parameters are not exposed + ), + new ContextCursorSerializer(), + new ViolationMessageSerializer(), + false // unnecessary to serialize individual result dependencies + ); + }, + + ConstraintsServices::CHECK_RESULT_DESERIALIZER => static function ( MediaWikiServices $services ) { + $entityIdParser = WikibaseRepo::getEntityIdParser( $services ); + $dataValueFactory = WikibaseRepo::getDataValueFactory( $services ); + + return new CheckResultDeserializer( + new ConstraintDeserializer(), + new ContextCursorDeserializer(), + new ViolationMessageDeserializer( + $entityIdParser, + $dataValueFactory + ), + $entityIdParser + ); + }, + + ConstraintsServices::VIOLATION_MESSAGE_SERIALIZER => static function ( MediaWikiServices $services ) { + return new ViolationMessageSerializer(); + }, + + ConstraintsServices::VIOLATION_MESSAGE_DESERIALIZER => static function ( MediaWikiServices $services ) { + $entityIdParser = WikibaseRepo::getEntityIdParser( $services ); + $dataValueFactory = WikibaseRepo::getDataValueFactory( $services ); + + return new ViolationMessageDeserializer( + $entityIdParser, + $dataValueFactory + ); + }, + + ConstraintsServices::CONSTRAINT_PARAMETER_PARSER => static function ( MediaWikiServices $services ) { + $deserializerFactory = WikibaseRepo::getBaseDataModelDeserializerFactory( $services ); + $entitySourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services ); + + return new ConstraintParameterParser( + $services->getMainConfig(), + $deserializerFactory, + $entitySourceDefinitions->getDatabaseSourceForEntityType( 'item' )->getConceptBaseUri() + ); + }, + + ConstraintsServices::CONNECTION_CHECKER_HELPER => static function ( MediaWikiServices $services ) { + return new ConnectionCheckerHelper(); + }, + + ConstraintsServices::RANGE_CHECKER_HELPER => static function ( MediaWikiServices $services ) { + return new RangeCheckerHelper( + $services->getMainConfig(), + WikibaseRepo::getUnitConverter( $services ) + ); + }, + + ConstraintsServices::SPARQL_HELPER => static function ( MediaWikiServices $services ) { + $endpoint = $services->getMainConfig()->get( 'WBQualityConstraintsSparqlEndpoint' ); + if ( $endpoint === '' ) { + return new DummySparqlHelper(); + } + + $rdfVocabulary = WikibaseRepo::getRdfVocabulary( $services ); + $entityIdParser = WikibaseRepo::getEntityIdParser( $services ); + $propertyDataTypeLookup = WikibaseRepo::getPropertyDataTypeLookup( $services ); + + return new SparqlHelper( + $services->getMainConfig(), + $rdfVocabulary, + $entityIdParser, + $propertyDataTypeLookup, + $services->getMainWANObjectCache(), + ConstraintsServices::getViolationMessageSerializer( $services ), + ConstraintsServices::getViolationMessageDeserializer( $services ), + $services->getStatsdDataFactory(), + ConstraintsServices::getExpiryLock( $services ), + ConstraintsServices::getLoggingHelper( $services ), + WikiMap::getCurrentWikiId() . ' WikibaseQualityConstraints ' . $services->getHttpRequestFactory()->getUserAgent(), + $services->getHttpRequestFactory() + ); + }, + + ConstraintsServices::TYPE_CHECKER_HELPER => static function ( MediaWikiServices $services ) { + return new TypeCheckerHelper( + WikibaseServices::getEntityLookup( $services ), + $services->getMainConfig(), + ConstraintsServices::getSparqlHelper( $services ), + $services->getStatsdDataFactory() + ); + }, + + ConstraintsServices::DELEGATING_CONSTRAINT_CHECKER => static function ( MediaWikiServices $services ) { + $statementGuidParser = WikibaseRepo::getStatementGuidParser( $services ); + + $config = $services->getMainConfig(); + $checkerMap = [ + $config->get( 'WBQualityConstraintsConflictsWithConstraintId' ) + => ConstraintCheckerServices::getConflictsWithChecker( $services ), + $config->get( 'WBQualityConstraintsItemRequiresClaimConstraintId' ) + => ConstraintCheckerServices::getItemChecker( $services ), + $config->get( 'WBQualityConstraintsValueRequiresClaimConstraintId' ) + => ConstraintCheckerServices::getTargetRequiredClaimChecker( $services ), + $config->get( 'WBQualityConstraintsSymmetricConstraintId' ) + => ConstraintCheckerServices::getSymmetricChecker( $services ), + $config->get( 'WBQualityConstraintsInverseConstraintId' ) + => ConstraintCheckerServices::getInverseChecker( $services ), + $config->get( 'WBQualityConstraintsUsedAsQualifierConstraintId' ) + => ConstraintCheckerServices::getQualifierChecker( $services ), + $config->get( 'WBQualityConstraintsAllowedQualifiersConstraintId' ) + => ConstraintCheckerServices::getQualifiersChecker( $services ), + $config->get( 'WBQualityConstraintsMandatoryQualifierConstraintId' ) + => ConstraintCheckerServices::getMandatoryQualifiersChecker( $services ), + $config->get( 'WBQualityConstraintsRangeConstraintId' ) + => ConstraintCheckerServices::getRangeChecker( $services ), + $config->get( 'WBQualityConstraintsDifferenceWithinRangeConstraintId' ) + => ConstraintCheckerServices::getDiffWithinRangeChecker( $services ), + $config->get( 'WBQualityConstraintsTypeConstraintId' ) + => ConstraintCheckerServices::getTypeChecker( $services ), + $config->get( 'WBQualityConstraintsValueTypeConstraintId' ) + => ConstraintCheckerServices::getValueTypeChecker( $services ), + $config->get( 'WBQualityConstraintsSingleValueConstraintId' ) + => ConstraintCheckerServices::getSingleValueChecker( $services ), + $config->get( 'WBQualityConstraintsMultiValueConstraintId' ) + => ConstraintCheckerServices::getMultiValueChecker( $services ), + $config->get( 'WBQualityConstraintsDistinctValuesConstraintId' ) + => ConstraintCheckerServices::getUniqueValueChecker( $services ), + $config->get( 'WBQualityConstraintsFormatConstraintId' ) + => ConstraintCheckerServices::getFormatChecker( $services ), + $config->get( 'WBQualityConstraintsCommonsLinkConstraintId' ) + => ConstraintCheckerServices::getCommonsLinkChecker( $services ), + $config->get( 'WBQualityConstraintsOneOfConstraintId' ) + => ConstraintCheckerServices::getOneOfChecker( $services ), + $config->get( 'WBQualityConstraintsUsedForValuesOnlyConstraintId' ) + => ConstraintCheckerServices::getValueOnlyChecker( $services ), + $config->get( 'WBQualityConstraintsUsedAsReferenceConstraintId' ) + => ConstraintCheckerServices::getReferenceChecker( $services ), + $config->get( 'WBQualityConstraintsNoBoundsConstraintId' ) + => ConstraintCheckerServices::getNoBoundsChecker( $services ), + $config->get( 'WBQualityConstraintsAllowedUnitsConstraintId' ) + => ConstraintCheckerServices::getAllowedUnitsChecker( $services ), + $config->get( 'WBQualityConstraintsSingleBestValueConstraintId' ) + => ConstraintCheckerServices::getSingleBestValueChecker( $services ), + $config->get( 'WBQualityConstraintsAllowedEntityTypesConstraintId' ) + => ConstraintCheckerServices::getEntityTypeChecker( $services ), + $config->get( 'WBQualityConstraintsNoneOfConstraintId' ) + => ConstraintCheckerServices::getNoneOfChecker( $services ), + $config->get( 'WBQualityConstraintsIntegerConstraintId' ) + => ConstraintCheckerServices::getIntegerChecker( $services ), + $config->get( 'WBQualityConstraintsCitationNeededConstraintId' ) + => ConstraintCheckerServices::getCitationNeededChecker( $services ), + $config->get( 'WBQualityConstraintsPropertyScopeConstraintId' ) + => ConstraintCheckerServices::getPropertyScopeChecker( $services ), + $config->get( 'WBQualityConstraintsContemporaryConstraintId' ) + => ConstraintCheckerServices::getContemporaryChecker( $services ), + $config->get( 'WBQualityConstraintsLexemeLanguageConstraintId' ) + => ConstraintCheckerServices::getLexemeLanguageChecker( $services ), + $config->get( 'WBQualityConstraintsLabelInLanguageConstraintId' ) + => ConstraintCheckerServices::getLabelInLanguageChecker( $services ), + ]; + + return new DelegatingConstraintChecker( + WikibaseServices::getEntityLookup( $services ), + $checkerMap, + ConstraintsServices::getConstraintLookup( $services ), + ConstraintsServices::getConstraintParameterParser( $services ), + $statementGuidParser, + ConstraintsServices::getLoggingHelper( $services ), + $config->get( 'WBQualityConstraintsCheckQualifiers' ), + $config->get( 'WBQualityConstraintsCheckReferences' ), + $config->get( 'WBQualityConstraintsPropertiesWithViolatingQualifiers' ) + ); + }, + + ConstraintsServices::RESULTS_SOURCE => static function ( MediaWikiServices $services ) { + $config = $services->getMainConfig(); + $resultsSource = new CheckingResultsSource( + ConstraintsServices::getDelegatingConstraintChecker( $services ) + ); + + $cacheCheckConstraintsResults = false; + + if ( $config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) ) { + $cacheCheckConstraintsResults = true; + // check that we can use getLocalRepoWikiPageMetaDataAccessor() + // TODO we should always be able to cache constraint check results (T244726) + $entitySources = WikibaseRepo::getEntitySourceDefinitions( $services )->getSources(); + $localEntitySourceName = WikibaseRepo::getLocalEntitySource( $services )->getSourceName(); + + foreach ( $entitySources as $entitySource ) { + if ( $entitySource->getSourceName() !== $localEntitySourceName ) { + LoggerFactory::getInstance( 'WikibaseQualityConstraints' )->warning( + 'Cannot cache constraint check results for non-local source: ' . + $entitySource->getSourceName() + ); + $cacheCheckConstraintsResults = false; + break; + } + } + } + + if ( $cacheCheckConstraintsResults ) { + $possiblyStaleConstraintTypes = [ + $config->get( 'WBQualityConstraintsCommonsLinkConstraintId' ), + $config->get( 'WBQualityConstraintsTypeConstraintId' ), + $config->get( 'WBQualityConstraintsValueTypeConstraintId' ), + $config->get( 'WBQualityConstraintsDistinctValuesConstraintId' ), + ]; + $entityIdParser = WikibaseRepo::getEntityIdParser( $services ); + $wikiPageEntityMetaDataAccessor = WikibaseRepo::getLocalRepoWikiPageMetaDataAccessor( + $services ); + + $resultsSource = new CachingResultsSource( + $resultsSource, + ResultsCache::getDefaultInstance(), + ConstraintsServices::getCheckResultSerializer( $services ), + ConstraintsServices::getCheckResultDeserializer( $services ), + $wikiPageEntityMetaDataAccessor, + $entityIdParser, + $config->get( 'WBQualityConstraintsCacheCheckConstraintsTTLSeconds' ), + $possiblyStaleConstraintTypes, + $config->get( 'WBQualityConstraintsCacheCheckConstraintsMaximumRevisionIds' ), + ConstraintsServices::getLoggingHelper( $services ) + ); + } + + return $resultsSource; + }, +]; diff --git a/dist/extensions/WikibaseQualityConstraints/src/Specials/SpecialConstraintReport.php b/dist/extensions/WikibaseQualityConstraints/src/Specials/SpecialConstraintReport.php new file mode 100644 index 000000000..7cd254ab1 --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/Specials/SpecialConstraintReport.php @@ -0,0 +1,625 @@ +entityLookup = $entityLookup; + $this->entityTitleLookup = $entityTitleLookup; + $this->entityIdParser = $entityIdParser; + + $language = $this->getLanguage(); + + $formatterOptions = new FormatterOptions(); + $formatterOptions->setOption( SnakFormatter::OPT_LANG, $language->getCode() ); + $dataValueFormatter = $valueFormatterFactory->getValueFormatter( + SnakFormatter::FORMAT_HTML, + $formatterOptions + ); + + $this->entityIdLabelFormatter = $entityIdLabelFormatterFactory->getEntityIdFormatter( + $language + ); + + $this->entityIdLinkFormatter = $entityIdHtmlLinkFormatterFactory->getEntityIdFormatter( + $language + ); + + $this->constraintChecker = $constraintChecker; + + $this->constraintParameterRenderer = new ConstraintParameterRenderer( + $this->entityIdLabelFormatter, + $dataValueFormatter, + $this->getContext(), + $config + ); + $this->violationMessageRenderer = new MultilingualTextViolationMessageRenderer( + $this->entityIdLinkFormatter, + $dataValueFormatter, + $this->getContext(), + $config + ); + + $this->config = $config; + $this->dataFactory = $dataFactory; + } + + /** + * Returns array of modules that should be added + * + * @return string[] + */ + private function getModules() { + return [ + 'SpecialConstraintReportPage', + 'wikibase.quality.constraints.icon', + ]; + } + + /** + * @see SpecialPage::getGroupName + * + * @return string + */ + protected function getGroupName() { + return 'wikibase'; + } + + /** + * @see SpecialPage::getDescription + * + * @return string + */ + public function getDescription() { + return $this->msg( 'wbqc-constraintreport' )->text(); + } + + /** + * @see SpecialPage::execute + * + * @param string|null $subPage + * + * @throws InvalidArgumentException + * @throws EntityIdParsingException + * @throws UnexpectedValueException + */ + public function execute( $subPage ) { + $out = $this->getOutput(); + + $postRequest = $this->getContext()->getRequest()->getVal( 'entityid' ); + if ( $postRequest ) { + $out->redirect( $this->getPageTitle( strtoupper( $postRequest ) )->getLocalURL() ); + return; + } + + $out->enableOOUI(); + $out->addModules( $this->getModules() ); + + $this->setHeaders(); + + $out->addHTML( $this->getExplanationText() ); + $this->buildEntityIdForm(); + + if ( !$subPage ) { + return; + } + + if ( !is_string( $subPage ) ) { + throw new InvalidArgumentException( '$subPage must be string.' ); + } + + try { + $entityId = $this->entityIdParser->parse( $subPage ); + } catch ( EntityIdParsingException $e ) { + $out->addHTML( + $this->buildNotice( 'wbqc-constraintreport-invalid-entity-id', true ) + ); + return; + } + + if ( !$this->entityLookup->hasEntity( $entityId ) ) { + $out->addHTML( + $this->buildNotice( 'wbqc-constraintreport-not-existent-entity', true ) + ); + return; + } + + $this->dataFactory->increment( + 'wikibase.quality.constraints.specials.specialConstraintReport.executeCheck' + ); + $results = $this->constraintChecker->checkAgainstConstraintsOnEntityId( $entityId ); + + if ( $results !== [] ) { + $out->addHTML( + $this->buildResultHeader( $entityId ) + . $this->buildSummary( $results ) + . $this->buildResultTable( $entityId, $results ) + ); + } else { + $out->addHTML( + $this->buildResultHeader( $entityId ) + . $this->buildNotice( 'wbqc-constraintreport-empty-result' ) + ); + } + } + + /** + * Builds html form for entity id input + */ + private function buildEntityIdForm() { + $formDescriptor = [ + 'entityid' => [ + 'class' => 'HTMLTextField', + 'section' => 'section', + 'name' => 'entityid', + 'label-message' => 'wbqc-constraintreport-form-entityid-label', + 'cssclass' => 'wbqc-constraintreport-form-entity-id', + 'placeholder' => $this->msg( 'wbqc-constraintreport-form-entityid-placeholder' )->escaped() + ] + ]; + $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext(), 'wbqc-constraintreport-form' ); + $htmlForm->setSubmitText( $this->msg( 'wbqc-constraintreport-form-submit-label' )->escaped() ); + $htmlForm->setSubmitCallback( static function () { + return false; + } ); + $htmlForm->setMethod( 'post' ); + $htmlForm->show(); + } + + /** + * Builds notice with given message. Optionally notice can be handles as error by settings $error to true + * + * @param string $messageKey + * @param bool $error + * + * @throws InvalidArgumentException + * + * @return string HTML + */ + private function buildNotice( $messageKey, $error = false ) { + if ( !is_string( $messageKey ) ) { + throw new InvalidArgumentException( '$message must be string.' ); + } + if ( !is_bool( $error ) ) { + throw new InvalidArgumentException( '$error must be bool.' ); + } + + $cssClasses = 'wbqc-constraintreport-notice'; + if ( $error ) { + $cssClasses .= ' wbqc-constraintreport-notice-error'; + } + + return Html::rawElement( + 'p', + [ + 'class' => $cssClasses + ], + $this->msg( $messageKey )->escaped() + ); + } + + /** + * @return string HTML + */ + private function getExplanationText() { + return Html::rawElement( + 'div', + [ 'class' => 'wbqc-explanation' ], + Html::rawElement( + 'p', + [], + $this->msg( 'wbqc-constraintreport-explanation-part-one' )->escaped() + ) + . Html::rawElement( + 'p', + [], + $this->msg( 'wbqc-constraintreport-explanation-part-two' )->escaped() + ) + ); + } + + /** + * @param EntityId $entityId + * @param CheckResult[] $results + * + * @return string HTML + * @suppress SecurityCheck-DoubleEscaped + */ + private function buildResultTable( EntityId $entityId, array $results ) { + // Set table headers + $table = new HtmlTableBuilder( + [ + new HtmlTableHeaderBuilder( + $this->msg( 'wbqc-constraintreport-result-table-header-status' )->escaped(), + true + ), + new HtmlTableHeaderBuilder( + $this->msg( 'wbqc-constraintreport-result-table-header-property' )->escaped(), + true + ), + new HtmlTableHeaderBuilder( + $this->msg( 'wbqc-constraintreport-result-table-header-message' )->escaped(), + true + ), + new HtmlTableHeaderBuilder( + $this->msg( 'wbqc-constraintreport-result-table-header-constraint' )->escaped(), + true + ) + ] + ); + + foreach ( $results as $result ) { + $table = $this->appendToResultTable( $table, $entityId, $result ); + } + + return $table->toHtml(); + } + + private function appendToResultTable( HtmlTableBuilder $table, EntityId $entityId, CheckResult $result ) { + $message = $result->getMessage(); + if ( $message === null ) { + // no row for this result + return $table; + } + + // Status column + $statusColumn = $this->formatStatus( $result->getStatus() ); + + // Property column + $propertyId = new NumericPropertyId( $result->getContextCursor()->getSnakPropertyId() ); + $propertyColumn = $this->getClaimLink( + $entityId, + $propertyId, + $this->entityIdLabelFormatter->formatEntityId( $propertyId ) + ); + + // Message column + $messageColumn = $this->violationMessageRenderer->render( $message ); + + // Constraint column + $constraintTypeItemId = $result->getConstraint()->getConstraintTypeItemId(); + try { + $constraintTypeLabel = $this->entityIdLabelFormatter->formatEntityId( new ItemId( $constraintTypeItemId ) ); + } catch ( InvalidArgumentException $e ) { + $constraintTypeLabel = htmlspecialchars( $constraintTypeItemId ); + } + $constraintLink = $this->getClaimLink( + $propertyId, + new NumericPropertyId( $this->config->get( 'WBQualityConstraintsPropertyConstraintId' ) ), + $constraintTypeLabel + ); + $constraintColumn = $this->buildExpandableElement( + $constraintLink, + $this->constraintParameterRenderer->formatParameters( $result->getParameters() ), + '[...]' + ); + + // Append cells + $table->appendRow( + [ + new HtmlTableCellBuilder( + $statusColumn, + [], + true + ), + new HtmlTableCellBuilder( + $propertyColumn, + [], + true + ), + new HtmlTableCellBuilder( + $messageColumn, + [], + true + ), + new HtmlTableCellBuilder( + $constraintColumn, + [], + true + ) + ] + ); + + return $table; + } + + /** + * Returns html text of the result header + * + * @param EntityId $entityId + * + * @return string HTML + */ + protected function buildResultHeader( EntityId $entityId ) { + $entityLink = sprintf( '%s (%s)', + $this->entityIdLinkFormatter->formatEntityId( $entityId ), + htmlspecialchars( $entityId->getSerialization() ) ); + + return Html::rawElement( + 'h3', + [], + sprintf( '%s %s', $this->msg( 'wbqc-constraintreport-result-headline' )->escaped(), $entityLink ) + ); + } + + /** + * Builds summary from given results + * + * @param CheckResult[] $results + * + * @return string HTML + */ + protected function buildSummary( array $results ) { + $statuses = []; + foreach ( $results as $result ) { + $status = strtolower( $result->getStatus() ); + $statuses[$status] = isset( $statuses[$status] ) ? $statuses[$status] + 1 : 1; + } + + $statusElements = []; + foreach ( $statuses as $status => $count ) { + if ( $count > 0 ) { + $statusElements[] = + $this->formatStatus( $status ) + . ': ' + . $count; + } + } + + return Html::rawElement( 'p', [], implode( ', ', $statusElements ) ); + } + + /** + * Builds a html div element with given content and a tooltip with given tooltip content + * If $tooltipContent is null, no tooltip will be created + * + * @param string $content + * @param string $expandableContent + * @param string $indicator + * + * @throws InvalidArgumentException + * + * @return string HTML + */ + protected function buildExpandableElement( $content, $expandableContent, $indicator ) { + if ( !is_string( $content ) ) { + throw new InvalidArgumentException( '$content has to be string.' ); + } + if ( $expandableContent && ( !is_string( $expandableContent ) ) ) { + throw new InvalidArgumentException( '$tooltipContent, if provided, has to be string.' ); + } + + if ( empty( $expandableContent ) ) { + return $content; + } + + $tooltipIndicator = Html::element( + 'span', + [ + 'class' => 'wbqc-expandable-content-indicator wbqc-indicator' + ], + $indicator + ); + + $wrappedExpandableContent = Html::element( + 'div', + [ + 'class' => 'wbqc-expandable-content' + ], + $expandableContent + ); + + return sprintf( '%s %s %s', $content, $tooltipIndicator, $wrappedExpandableContent ); + } + + /** + * Formats given status to html + * + * @param string $status + * + * @throws InvalidArgumentException + * + * @return string HTML + */ + private function formatStatus( $status ) { + $messageName = "wbqc-constraintreport-status-" . strtolower( $status ); + $statusIcons = [ + CheckResult::STATUS_SUGGESTION => [ + 'icon' => 'suggestion-constraint-violation', + ], + CheckResult::STATUS_WARNING => [ + 'icon' => 'non-mandatory-constraint-violation', + ], + CheckResult::STATUS_VIOLATION => [ + 'icon' => 'mandatory-constraint-violation', + ], + CheckResult::STATUS_BAD_PARAMETERS => [ + 'icon' => 'alert', + 'flags' => 'warning', + ], + ]; + + if ( array_key_exists( $status, $statusIcons ) ) { + $iconWidget = new IconWidget( $statusIcons[$status] ); + $iconHtml = $iconWidget->toString() . ' '; + } else { + $iconHtml = ''; + } + + $labelWidget = new LabelWidget( [ + 'label' => $this->msg( $messageName )->text(), + ] ); + $labelHtml = $labelWidget->toString(); + + $formattedStatus = + Html::rawElement( + 'span', + [ + 'class' => 'wbqc-status wbqc-status-' . $status + ], + $iconHtml . $labelHtml + ); + + return $formattedStatus; + } + + /** + * Returns html link to given entity with anchor to specified property. + * + * @param EntityId $entityId + * @param NumericPropertyId $propertyId + * @param string $text HTML + * + * @return string HTML + */ + private function getClaimLink( EntityId $entityId, NumericPropertyId $propertyId, $text ) { + return Html::rawElement( + 'a', + [ + 'href' => $this->getClaimUrl( $entityId, $propertyId ), + 'target' => '_blank' + ], + $text + ); + } + + /** + * Returns url of given entity with anchor to specified property. + * + * @param EntityId $entityId + * @param NumericPropertyId $propertyId + * + * @return string + */ + private function getClaimUrl( EntityId $entityId, NumericPropertyId $propertyId ) { + $title = $this->entityTitleLookup->getTitleForId( $entityId ); + $entityUrl = sprintf( '%s#%s', $title->getLocalURL(), $propertyId->getSerialization() ); + + return $entityUrl; + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/WikibaseQualityConstraintsHooks.php b/dist/extensions/WikibaseQualityConstraints/src/WikibaseQualityConstraintsHooks.php new file mode 100644 index 000000000..90b97bc2b --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/WikibaseQualityConstraintsHooks.php @@ -0,0 +1,150 @@ +addExtensionTable( + 'wbqc_constraints', + $dir . "/{$updater->getDB()->getType()}/tables-generated.sql" + ); + $updater->addExtensionField( + 'wbqc_constraints', + 'constraint_id', + $dir . '/patch-wbqc_constraints-constraint_id.sql' + ); + $updater->addExtensionIndex( + 'wbqc_constraints', + 'wbqc_constraints_guid_uniq', + $dir . '/patch-wbqc_constraints-wbqc_constraints_guid_uniq.sql' + ); + } + + public static function onWikibaseChange( Change $change ) { + if ( !( $change instanceof EntityChange ) ) { + return; + } + /** @var EntityChange $change */ + + $services = MediaWikiServices::getInstance(); + $config = $services->getMainConfig(); + $jobQueueGroup = $services->getJobQueueGroup(); + + // If jobs are enabled and the results would be stored in some way run a job. + if ( + $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobs' ) && + $config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) && + self::isSelectedForJobRunBasedOnPercentage() + ) { + $params = [ 'entityId' => $change->getEntityId()->getSerialization() ]; + $jobQueueGroup->lazyPush( + new JobSpecification( CheckConstraintsJob::COMMAND, $params ) + ); + } + + if ( $config->get( 'WBQualityConstraintsEnableConstraintsImportFromStatements' ) && + self::isConstraintStatementsChange( $config, $change ) + ) { + $params = [ 'propertyId' => $change->getEntityId()->getSerialization() ]; + $metadata = $change->getMetadata(); + if ( array_key_exists( 'rev_id', $metadata ) ) { + $params['revisionId'] = $metadata['rev_id']; + } + $jobQueueGroup->push( + new JobSpecification( 'constraintsTableUpdate', $params ) + ); + } + } + + private static function isSelectedForJobRunBasedOnPercentage() { + $config = MediaWikiServices::getInstance()->getMainConfig(); + $percentage = $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobsRatio' ); + + return mt_rand( 1, 100 ) <= $percentage; + } + + public static function isConstraintStatementsChange( Config $config, Change $change ) { + if ( !( $change instanceof EntityChange ) || + $change->getAction() !== EntityChange::UPDATE || + !( $change->getEntityId() instanceof NumericPropertyId ) + ) { + return false; + } + + $info = $change->getInfo(); + + if ( !array_key_exists( 'compactDiff', $info ) ) { + // the non-compact diff ($info['diff']) does not contain statement diffs (T110996), + // so we only know that the change *might* affect the constraint statements + return true; + } + + /** @var EntityDiffChangedAspects $aspects */ + $aspects = $info['compactDiff']; + + $propertyConstraintId = $config->get( 'WBQualityConstraintsPropertyConstraintId' ); + return in_array( $propertyConstraintId, $aspects->getStatementChanges() ); + } + + public static function onArticlePurge( WikiPage $wikiPage ) { + $entityContentFactory = WikibaseRepo::getEntityContentFactory(); + if ( $entityContentFactory->isEntityContentModel( $wikiPage->getContentModel() ) ) { + $entityIdLookup = WikibaseRepo::getEntityIdLookup(); + $entityId = $entityIdLookup->getEntityIdForTitle( $wikiPage->getTitle() ); + if ( $entityId !== null ) { + $resultsCache = ResultsCache::getDefaultInstance(); + $resultsCache->delete( $entityId ); + } + } + } + + public static function onBeforePageDisplay( OutputPage $out, Skin $skin ) { + $lookup = WikibaseRepo::getEntityNamespaceLookup(); + $title = $out->getTitle(); + if ( $title === null ) { + return; + } + + if ( !$lookup->isNamespaceWithEntities( $title->getNamespace() ) ) { + return; + } + if ( empty( $out->getJsConfigVars()['wbIsEditView'] ) ) { + return; + } + + $out->addModules( 'wikibase.quality.constraints.suggestions' ); + + if ( !$out->getUser()->isRegistered() ) { + return; + } + + $out->addModules( 'wikibase.quality.constraints.gadget' ); + } + +} diff --git a/dist/extensions/WikibaseQualityConstraints/src/WikibaseServices.php b/dist/extensions/WikibaseQualityConstraints/src/WikibaseServices.php new file mode 100644 index 000000000..48a5edccf --- /dev/null +++ b/dist/extensions/WikibaseQualityConstraints/src/WikibaseServices.php @@ -0,0 +1,54 @@ +getService( $name ); + } + + /** + * @param MediaWikiServices|null $services + * @return EntityLookup + */ + public static function getEntityLookup( MediaWikiServices $services = null ) { + return self::getService( $services, self::ENTITY_LOOKUP ); + } + + /** + * @param MediaWikiServices|null $services + * @return PropertyDataTypeLookup + */ + public static function getPropertyDataTypeLookup( MediaWikiServices $services = null ) { + return self::getService( $services, self::PROPERTY_DATA_TYPE_LOOKUP ); + } + + /** + * @param MediaWikiServices|null $services + * @return EntityLookup + */ + public static function getEntityLookupWithoutCache( MediaWikiServices $services = null ) { + return self::getService( $services, self::ENTITY_LOOKUP_WITHOUT_CACHE ); + } + +} diff --git a/dist/vendor/autoload.php b/dist/vendor/autoload.php index ff3c2c735..7f784b47a 100644 --- a/dist/vendor/autoload.php +++ b/dist/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit363f9183335017aee6b02c5b8326cd74::getLoader(); +return ComposerAutoloaderInit1db05c5f94c753941a4ad3fad2817c00::getLoader(); diff --git a/dist/vendor/composer/autoload_real.php b/dist/vendor/composer/autoload_real.php index 8edb8b292..22a4f2e9b 100644 --- a/dist/vendor/composer/autoload_real.php +++ b/dist/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit363f9183335017aee6b02c5b8326cd74 +class ComposerAutoloaderInit1db05c5f94c753941a4ad3fad2817c00 { private static $loader; @@ -24,9 +24,9 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit363f9183335017aee6b02c5b8326cd74', 'loadClassLoader'), true, false); + spl_autoload_register(array('ComposerAutoloaderInit1db05c5f94c753941a4ad3fad2817c00', 'loadClassLoader'), true, false); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); - spl_autoload_unregister(array('ComposerAutoloaderInit363f9183335017aee6b02c5b8326cd74', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit1db05c5f94c753941a4ad3fad2817c00', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -36,7 +36,7 @@ public static function getLoader() if ($useStaticLoader) { require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit363f9183335017aee6b02c5b8326cd74::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -57,19 +57,19 @@ public static function getLoader() $loader->register(false); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire363f9183335017aee6b02c5b8326cd74($fileIdentifier, $file); + composerRequire1db05c5f94c753941a4ad3fad2817c00($fileIdentifier, $file); } return $loader; } } -function composerRequire363f9183335017aee6b02c5b8326cd74($fileIdentifier, $file) +function composerRequire1db05c5f94c753941a4ad3fad2817c00($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/dist/vendor/composer/autoload_static.php b/dist/vendor/composer/autoload_static.php index 8256cca5d..5bc14489a 100644 --- a/dist/vendor/composer/autoload_static.php +++ b/dist/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit363f9183335017aee6b02c5b8326cd74 +class ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00 { public static $files = array ( '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', @@ -4249,11 +4249,11 @@ class ComposerStaticInit363f9183335017aee6b02c5b8326cd74 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInit363f9183335017aee6b02c5b8326cd74::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInit1db05c5f94c753941a4ad3fad2817c00::$classMap; }, null, ClassLoader::class); } diff --git a/dist/wbstack/src/Settings/LocalSettings.php b/dist/wbstack/src/Settings/LocalSettings.php index a3ec099be..55f4f3155 100644 --- a/dist/wbstack/src/Settings/LocalSettings.php +++ b/dist/wbstack/src/Settings/LocalSettings.php @@ -360,6 +360,8 @@ wfLoadExtension( 'DeleteBatch' ); wfLoadExtension( 'MultimediaViewer' ); wfLoadExtension( 'WikiHiero' ); +wfLoadExtension( 'WikibaseQualityConstraints' ); + # ConfirmAccount (only loaded when the setting is on) if( $wikiInfo->getSetting('wwExtEnableConfirmAccount') ) { diff --git a/pacman.yaml b/pacman.yaml index 3f03efafe..0aa1e3190 100644 --- a/pacman.yaml +++ b/pacman.yaml @@ -930,6 +930,28 @@ - .rubocop_todo.yml - Gruntfile.js - Doxyfile +- name: WikibaseQualityConstraints + artifactUrl: https://codeload.github.com/wikimedia/mediawiki-extensions-WikibaseQualityConstraints/zip/6a261e0cacd967ebf0515148b0596202e260f2fa + artifactLevel: 1 + destination: ./dist/extensions/WikibaseQualityConstraints + remove: + - tests + - .github + - .stylelintignore + - .nvmrc + - .eslintignore + - .phan + - .storybook + - .vscode + - .gitignore + - .eslintrc.json + - .gitreview + - .phpcs.xml + - .stylelintrc.json + - .rubocop.yml + - .rubocop_todo.yml + - Gruntfile.js + - Doxyfile - name: WikibaseManifest artifactUrl: https://codeload.github.com/wikimedia/mediawiki-extensions-WikibaseManifest/zip/a9acda8d9f3e671e30fdf14c00570d1b06a763ab artifactLevel: 1 diff --git a/wikiman.yaml b/wikiman.yaml index ce9efcc51..c3fd2dd65 100644 --- a/wikiman.yaml +++ b/wikiman.yaml @@ -108,6 +108,8 @@ extensions: repoName: wikimedia/mediawiki-extensions-MultimediaViewer - name: Auth_remoteuser repoName: wikimedia/mediawiki-extensions-Auth_remoteuser + - name: WikibaseQualityConstraints + repoName: wikimedia/mediawiki-extensions-WikibaseQualityConstraints - name: WikibaseManifest repoName: wikimedia/mediawiki-extensions-WikibaseManifest remove: