commit a998ec05eeb75333ca0753228dda0cf6150ba14e Author: Laur Ivan Date: Wed Mar 9 22:38:02 2022 +0100 Initial commit. diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..33414b1 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "no-console": "off", + "linebreak-style": "off", + "quotes": [ + "error", + "double", + { "allowTemplateLiterals": true } + ], + "keyword-spacing": ["error", { "before": true }], + "space-before-blocks": ["error"] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d628b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Visual Studio 2015 cache/options directory +.vs/ +.nyc_output/ +lib/ +dist/ +node_modules/ + +# Testing and coverage reports +coverage/ +mochawesome-report/ + + +#Exclude tsc generated files +js/*.map +js/ts.js \ No newline at end of file diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000..2343515 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,3 @@ +{ + "spec": "./tests" +} diff --git a/.nycrc.json b/.nycrc.json new file mode 100644 index 0000000..44b20ae --- /dev/null +++ b/.nycrc.json @@ -0,0 +1,16 @@ +{ + "extends": "@istanbuljs/nyc-config-typescript", + "check-coverage": true, + "include": [ + "**/src/*.ts" + ], + "reporter": [ + "lcov", + "cobertura", + "text-summary" + ], + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90 +} \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..9576ed0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "singleQuote": true, + "printWidth": 80 +} \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..e72bfdd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d9ce2e0 --- /dev/null +++ b/README.md @@ -0,0 +1,361 @@ +# Introduction + +This folder has the dpt library written in TS. +Original code is in the knx.js library, but it's not exposed. + +From [here](https://www.promotic.eu/en/pmdoc/Subsystems/Comm/PmDrivers/KNXDTypes.htm): + +| Identifier | Name | Size | PROMOTIC data type | Interpretation range | Note | +| ---------- | ---------------------------------------- | ------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| 1.001 | DPT_Switch | 1 bit | Boolean | 0 = off, 1 = on | | +| 1.002 | DPT_Bool | 1 bit | Boolean | 0 = false, 1 = true | | +| 1.003 | DPT_Enable | 1 bit | Boolean | 0 = disable, 1 = enable | | +| 1.004 | DPT_Ramp | 1 bit | Boolean | 0 = no ramp, 1 = ramp | | +| 1.005 | DPT_Alarm | 1 bit | Boolean | 0 = no alarm, 1 = alarm | | +| 1.006 | DPT_BinaryValue | 1 bit | Boolean | 0 = low, 1 = high | | +| 1.007 | DPT_Step | 1 bit | Boolean | 0 = decrease, 1 = increase | | +| 1.008 | DPT_UpDown | 1 bit | Boolean | 0 = up, 1 = down | | +| 1.009 | DPT_OpenClose | 1 bit | Boolean | 0 = open, 1 = close | | +| 1.010 | DPT_Start | 1 bit | Boolean | 0 = stop, 1 = start | | +| 1.011 | DPT_State | 1 bit | Boolean | 0 = inactive, 1 = active | | +| 1.012 | DPT_Invert | 1 bit | Boolean | 0 = not inverted, 1 = inverted | | +| 1.013 | DPT_DimSendStyle | 1 bit | Boolean | 0 = start-stop, 1 = cyclically | | +| 1.014 | DPT_InputSource | 1 bit | Boolean | 0 = fixed, 1 = calculated | | +| 1.015 | DPT_Reset | 1 bit | Boolean | 0 = dummy, 1 = trigger | | +| 1.016 | DPT_Ack | 1 bit | Boolean | 0 = dummy, 1 = trigger | | +| 1.017 | DPT_Trigger | 1 bit | Boolean | 0,1 = trigger | | +| 1.018 | DPT_Occupancy | 1 bit | Boolean | 0 = not occupied, 1 = occupied | | +| 1.019 | DPT\_Window\_Door | 1 bit | Boolean | 0 = closed, 1 = open | | +| 1.021 | DPT_LogicalFunction | 1 bit | Boolean | 0 = OR, 1 = AND | | +| 1.022 | DPT\_Scene\_AB | 1 bit | Boolean | 0 = sceneA, 1 = sceneB | | +| 1.023 | DPT\_ShutterBlinds\_Mode | 1 bit | Boolean | 0 = UpDown only, 1 = UpDown + StepStop | | +| 1.100 | DPT_Heat/Cool | 1 bit | Boolean | 0 = cooling, 1 = heating | | +| 2.001 | DPT\_Switch\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.002 | DPT\_Bool\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.003 | DPT\_Enable\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.004 | DPT\_Ramp\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.005 | DPT\_Alarm\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.006 | DPT\_BinaryValue\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.007 | DPT\_Step\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.008 | DPT\_Direction1\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.009 | DPT\_Direction2\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.010 | DPT\_Start\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.011 | DPT\_State\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 2.012 | DPT\_Invert\_Control | 2 bits | Long | C₁V₁

C = {0 (no control), 1 (control)}; V = {0,1} according to type 1.XXX | | +| 3.007 | DPT\_Control\_Dimming | 4 bits | Long | C₁S₃

C = {0 (decrease), 1 (increase)}; S = \[000..111\] | | +| 3.008 | DPT\_Control\_Blinds | 4 bits | Long | C₁S₃

C = {0 (up), 1 (down)}; S = \[000..111\] | | +| 4.001 | DPT\_Char\_ASCII | 1 byte | Long | ASCII character | | +| 4.002 | DPT\_Char\_8859_1 | 1 byte | Long | ISO_8859 character | | +| 5.001 | DPT_Scaling | 1 byte | Long | \[0 … 100\]% | | +| 5.003 | DPT_Angle | 1 byte | Long | \[0 … 360\]° | | +| 5.004 | DPT\_Percent\_U8 | 1 byte | Long | \[0 … 255\]% | | +| 5.005 | DPT_DecimalFactor | 1 byte | Long | | | +| 5.006 | DPT_Tariff | 1 byte | Long | \[0 … 254\] | | +| 5.010 | DPT\_Value\_1_Ucount | 1 byte | Long | \[0 … 255\] | | +| 6.001 | DPT\_Percent\_V8 | 1 byte | Long | \[-128 … 127\]% | | +| 6.010 | DPT\_Value\_1_Count | 1 byte | Long | \[-128 … 127\] | | +| 6.020 | DPT\_Status\_Mode3 | 1 byte | Long | A₁B₁C₁D₁E₁F₃

A,B,C,D,E = {0 (set), 1 (clear)}; F = {001 (mode 0), 010 (mode 1), 100 (mode 2)} | | +| 7.001 | DPT\_Value\_2_Ucount | 2 bytes | Long | \[0 … 65535\] pulses | | +| 7.002 | DPT_TimePeriodMsec | 2 bytes | Long | \[0 … 65535\] ms | | +| 7.003 | DPT_TimePeriod10Msec | 2 bytes | Long | \[0 … 6553,5\] s | k=0,1 | +| 7.004 | DPT_TimePeriod100Msec | 2 bytes | Long | \[0 … 655,35\] s | k=0,01 | +| 7.005 | DPT_TimePeriodSec | 2 bytes | Long | \[0 … 65535\] s | | +| 7.006 | DPT_TimePeriodMin | 2 bytes | Long | \[0 … 65535\] min | | +| 7.007 | DPT_TimePeriodHrs | 2 bytes | Long | \[0 … 65535\] h | | +| 7.010 | DPT_PropDataType | 2 bytes | Long | \[0 … 65535\] | | +| 7.011 | DPT\_Length\_mm | 2 bytes | Long | \[0 … 65535\] mm | | +| 7.012 | DPT_UElCurrentmA | 2 bytes | Long | \[0 … 65535\] mA | | +| 7.013 | DPT_Brightness | 2 bytes | Long | \[0..65535\] lux | | +| 8.001 | DPT\_Value\_2_Count | 2 bytes | Long | \[-32 768 … 32 767\] | | +| 8.002 | DPT_DeltaTimeMsec | 2 bytes | Long | \[-32 768 … 32 767\] ms | | +| 8.003 | DPT_DeltaTime10Msec | 2 bytes | Long | \[-3276,8 … 3276,7\] s | k=0,1 | +| 8.004 | DPT_DeltaTime100Msec | 2 bytes | Long | \[-327,68 … 327,67\] s | k=0,01 | +| 8.005 | DPT_DeltaTimeSec | 2 bytes | Long | \[-32 768 … 32 767\] s | | +| 8.006 | DPT_DeltaTimeMin | 2 bytes | Long | \[-32 768 … 32 767\] min | | +| 8.007 | DPT_DeltaTimeHrs | 2 bytes | Long | \[-32 768 … 32 767\] h | | +| 8.010 | DPT\_Percent\_V16 | 2 bytes | Long | \[-327,68 … 327,67\] % | k=0,01 | +| 8.011 | DPT\_Rotation\_Angle | 2 bytes | Long | \[-32 768 … 32 767\] ° | | +| 9.001 | DPT\_Value\_Temp | 2 bytes | Double | \[-273 … 670760\] °C | | +| 9.002 | DPT\_Value\_Tempd | 2 bytes | Double | \[-670760 … 670760\] K | | +| 9.003 | DPT\_Value\_Tempa | 2 bytes | Double | \[-670760 … 670760\] K/h | | +| 9.004 | DPT\_Value\_Lux | 2 bytes | Double | \[0 … 670760\] Lux | | +| 9.005 | DPT\_Value\_Wsp | 2 bytes | Double | \[0 … 670760\] m/s | | +| 9.006 | DPT\_Value\_Pres | 2 bytes | Double | \[0 … 670760\] Pa | | +| 9.007 | DPT\_Value\_Humidity | 2 bytes | Double | \[0 … 670760\] % | | +| 9.008 | DPT\_Value\_AirQuality | 2 bytes | Double | \[0 … 670760\] ppm | | +| 9.010 | DPT\_Value\_Time1 | 2 bytes | Double | \[-670760 … 670760\] s | | +| 9.011 | DPT\_Value\_Time2 | 2 bytes | Double | \[-670760 … 670760\] ms | | +| 9.020 | DPT\_Value\_Volt | 2 bytes | Double | \[-670760 … 670760\] mV | | +| 9.021 | DPT\_Value\_Curr | 2 bytes | Double | \[-670760 … 670760\] mA | | +| 9.022 | DPT_PowerDensity | 2 bytes | Double | \[-670760 … 670760\] W/m2 | | +| 9.023 | DPT_KelvinPerPercent | 2 bytes | Double | \[-670760 … 670760\] K/% | | +| 9.024 | DPT_Power | 2 bytes | Double | \[-670760 … 670760\] kW | | +| 9.025 | DPT\_Value\_Volume_Flow | 2 bytes | Double | \[-670760 … 670760\] l/h | | +| 9.026 | DPT\_Rain\_Amount | 2 bytes | Double | \[-670760 … 670760\] l/m2 | | +| 9.027 | DPT\_Value\_Temp_F | 2 bytes | Double | \[-459,6 … 670760\] °F | | +| 9.028 | DPT\_Value\_Wsp_kmh | 2 bytes | Double | \[0 … 670760\]km/h | | +| 10.001 | DPT_TimeOfDay | 3 bytes | Long | D₃H₅R₁R₁M₆rrS₆

D = \[0 … 7\]; H = \[0 … 23\]; M = \[0 … 59\]; S = \[0 … 59\]; R = {0} | | +| 11.001 | DPT_Date | 3 bytes | Long | R₁R₁R₁D₅R₁R₁R₁R₁M₄R₁Y₇

D = \[1 … 31\]; M = \[1 … 12\]; Y = \[0 … 99\]; R = {0} | | +| 12.001 | DPT\_Value\_4_Ucount | 4 bytes | Long | \[0 … 4 294 967 295\] | | +| 13.001 | DPT\_Value\_4_Count | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] | | +| 13.002 | DPT\_FlowRate\_m3/h | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] | | +| 13.010 | DPT_ActiveEnergy | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] Wh | | +| 13.012 | DPT_ReactiveEnergy | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] VAh | | +| 13.013 | DPT\_ActiveEnergy\_kWh | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] kWh | | +| 13.014 | DPT\_ApparantEnergy\_kVAh | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] kVAh | | +| 13.015 | DPT\_ReactiveEnergy\_kVARh | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] kVARh | | +| 13.100 | DPT_LongDeltaTimeSec | 4 bytes | Long | \[-2 147 483 648 … 2 147 483 647\] s | | +| 14.000 | DPT\_Value\_Acceleration | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.001 | DPT\_Value\_Acceleration_Angular | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.002 | DPT\_Value\_Activation_Energy | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.003 | DPT\_Value\_Activity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.004 | DPT\_Value\_Mol | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.005 | DPT\_Value\_Amplitude | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.006 | DPT\_Value\_AngleRad | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.007 | DPT\_Value\_AngleDeg | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.008 | DPT\_Value\_Angular_Momentum | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.009 | DPT\_Value\_Angular_Velocity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.010 | DPT\_Value\_Area | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.011 | DPT\_Value\_Capacitance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.012 | DPT\_Value\_Charge_DensitySurface | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.013 | DPT\_Value\_Charge_DensityVolume | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.014 | DPT\_Value\_Compressibility | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.015 | DPT\_Value\_Conductance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.016 | DPT\_Value\_Electrical_Conductivity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.017 | DPT\_Value\_Density | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.018 | DPT\_Value\_Electric_Charge | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.019 | DPT\_Value\_Electric_Current | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.020 | DPT\_Value\_Electric_CurrentDensity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.021 | DPT\_Value\_Electric_DipoleMoment | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.022 | DPT\_Value\_Electric_Displacement | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.023 | DPT\_Value\_Electric_FieldStrength | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.024 | DPT\_Value\_Electric_Flux | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.025 | DPT\_Value\_Electric_FluxDensity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.026 | DPT\_Value\_Electric_Polarization | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.027 | DPT\_Value\_Electric_Potential | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.028 | DPT\_Value\_Electric_PotentialDifference | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.029 | DPT\_Value\_ElectromagneticMoment | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.030 | DPT\_Value\_Electromotive_Force | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.031 | DPT\_Value\_Energy | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.032 | DPT\_Value\_Force | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.033 | DPT\_Value\_Frequency | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.034 | DPT\_Value\_Angular_Frequency | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.035 | DPT\_Value\_Heat_Capacity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.036 | DPT\_Value\_Heat_FlowRate | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.037 | DPT\_Value\_Heat_Quantity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.038 | DPT\_Value\_Impedance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.039 | DPT\_Value\_Length | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.040 | DPT\_Value\_Light_Quantity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.041 | DPT\_Value\_Luminance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.042 | DPT\_Value\_Luminous_Flux | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.043 | DPT\_Value\_Luminous_Intensity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.044 | DPT\_Value\_Magnetic_FieldStrength | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.045 | DPT\_Value\_Magnetic_Flux | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.046 | DPT\_Value\_Magnetic_FluxDensity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.047 | DPT\_Value\_Magnetic_Moment | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.048 | DPT\_Value\_Magnetic_Polarization | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.049 | DPT\_Value\_Magnetization | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.050 | DPT\_Value\_MagnetomotiveForce | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.051 | DPT\_Value\_Mass | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.052 | DPT\_Value\_MassFlux | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.053 | DPT\_Value\_Momentum | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.054 | DPT\_Value\_Phase_AngleRad | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.055 | DPT\_Value\_Phase_AngleDeg | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.056 | DPT\_Value\_Power | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.057 | DPT\_Value\_Power_Factor | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.058 | DPT\_Value\_Pressure | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.059 | DPT\_Value\_Reactance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.060 | DPT\_Value\_Resistance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.061 | DPT\_Value\_Resistivity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.062 | DPT\_Value\_SelfInductance | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.063 | DPT\_Value\_SolidAngle | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.064 | DPT\_Value\_Sound_Intensity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.065 | DPT\_Value\_Speed | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.066 | DPT\_Value\_Stress | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.067 | DPT\_Value\_Surface_Tension | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.068 | DPT\_Value\_Common_Temperature | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.069 | DPT\_Value\_Absolute_Temperature | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.070 | DPT\_Value\_TemperatureDifference | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.071 | DPT\_Value\_Thermal_Capacity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.072 | DPT\_Value\_Thermal_Conductivity | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.073 | DPT\_Value\_ThermoelectricPower | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.074 | DPT\_Value\_Time | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.075 | DPT\_Value\_Torque | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.076 | DPT\_Value\_Volume | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.077 | DPT\_Value\_Volume_Flux | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.078 | DPT\_Value\_Weight | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 14.079 | DPT\_Value\_Work | 4 bytes | Double | Z₁E₈F₂₃

Z = {0,1}; E = \[0 … 255\]; F = \[0 … 8 388 607\] | | +| 15.000 | DPT\_Access\_Data | 4 bytes | Long | U₄V₄W₄X₄Y₄Z₄E₁P₁D₁C₁N₄

U,V,W,X,Y,Z = \[0 … 9\]; E,P,D,C = {0,1}; N = \[0 … 15\] | | +| 17.001 | DPT_SceneNumber | 1 byte | Long | R₁R₁U₆

R = {0}; U = \[0 … 63\] | | +| 18.001 | DPT_SceneControl | 1 byte | Long | C₁R₁U₆

C = {0,1}; R = {0}; U = \[0 … 63\] | | +| 19.001 | DPT_DateTime | 8 bytes | String | U₈R₁R₁R₁R₁M₄R₁R₁R₁D₅W₃H₅R₁R₁S₆R₁R₁S₆E₁F₁G₁I₁J₁K₁L₁N₁O₁R₁R₁R₁R₁R₁R₁R₁

U = \[0 … 255\]; M = \[1 … 12\]; D = \[1 … 31\]; W = \[0 … 7\]; H = \[0 … 24\]; S = \[0 … 59\]; R = {0}; E,F,G,I,J,K,L,N,O = {0,1} | | +| 20.001 | DPT_SCLOMode | 1 byte | Long | \[0 … 3\] | | +| 20.002 | DPT_BuildingMode | 1 byte | Long | \[0 … 2\] | | +| 20.003 | DPT_OccMode | 1 byte | Long | \[0 … 2\] | | +| 20.004 | DPT_Priority | 1 byte | Long | \[0 … 3\] | | +| 20.005 | DPT_LightApplicationMode | 1 byte | Long | \[0 … 2\] | | +| 20.006 | DPT_ApplicationArea | 1 byte | Long | {0,1,10,11,12,13,14} | | +| 20.007 | DPT_AlarmClassType | 1 byte | Long | \[0 … 3\] | | +| 20.008 | DPT_PSUMode | 1 byte | Long | \[0 … 2\] | | +| 20.011 | DPT\_ErrorClass\_System | 1 byte | Long | \[0 … 18\] | | +| 20.012 | DPT\_ErrorClass\_HVAC | 1 byte | Long | \[0 … 4\] | | +| 20.013 | DPT\_Time\_Delay | 1 byte | Long | \[0 … 25\] | | +| 20.014 | DPT\_Beaufort\_Wind\_Force\_Scale | 1 byte | Long | \[0 … 12\] | | +| 20.017 | DPT_SensorSelect | 1 byte | Long | \[0 … 4\] | | +| 20.020 | DPT_ActuatorConnectType | 1 byte | Long | \[1 … 2\] | | +| 20.100 | DPT_FuelType | 1 byte | Long | \[0 … 3\] | | +| 20.101 | DPT_BurnerType | 1 byte | Long | \[0 … 3\] | | +| 20.102 | DPT_HVACMode | 1 byte | Long | \[0 … 4\] | | +| 20.103 | DPT_DHWMode | 1 byte | Long | \[0 … 4\] | | +| 20.104 | DPT_LoadPriority | 1 byte | Long | \[0 … 2\] | | +| 20.105 | DPT_HVACContrMode | 1 byte | Long | {\[0 … 17\],20} | | +| 20.106 | DPT_HVACEmergMode | 1 byte | Long | \[0 … 5\] | | +| 20.107 | DPT_ChangeoverMode | 1 byte | Long | \[0 … 2\] | | +| 20.108 | DPT_ValveMode | 1 byte | Long | \[1 … 5\] | | +| 20.109 | DPT_DamperMode | 1 byte | Long | \[1 … 4\] | | +| 20.110 | DPT_HeaterMode | 1 byte | Long | \[1 … 3\] | | +| 20.111 | DPT_FanMode | 1 byte | Long | \[0 … 2\] | | +| 20.112 | DPT_MasterSlaveMode | 1 byte | Long | \[0 … 2\] | | +| 20.113 | DPT_StatusRoomSetp | 1 byte | Long | \[0 … 2\] | | +| 20.120 | DPT_ADAType | 1 byte | Long | \[1 … 2\] | | +| 20.121 | DPT_BackupMode | 1 byte | Long | \[0 … 1\] | | +| 20.122 | DPT_StartSynchronization | 1 byte | Long | \[0 … 2\] | | +| 20.600 | DPT\_Behaviour\_Lock_Unlock | 1 byte | Long | \[0 … 6\] | | +| 20.601 | DPT\_Behaviour\_Bus\_Power\_Up_Down | 1 byte | Long | \[0 … 4\] | | +| 20.602 | DPT\_DALI\_Fade_Time | 1 byte | Long | \[0 … 15\] | | +| 20.603 | DPT_BlinkingMode | 1 byte | Long | \[0 … 2\] | | +| 20.604 | DPT_LightControlMode | 1 byte | Long | \[0 … 1\] | | +| 20.605 | DPT_SwitchPBModel | 1 byte | Long | \[1 … 2\] | | +| 20.606 | DPT_PBAction | 1 byte | Long | \[0 … 3\] | | +| 20.607 | DPT_DimmPBModel | 1 byte | Long | \[1 … 4\] | | +| 20.608 | DPT_SwitchOnMode | 1 byte | Long | \[0 … 2\] | | +| 20.609 | DPT_LoadTypeSet | 1 byte | Long | \[0 … 2\] | | +| 20.610 | DPT_LoadTypeDetected | 1 byte | Long | \[0 … 3\] | | +| 20.801 | 1 DPT_SABExceptBehaviour | 1 byte | Long | \[0 … 4\] | | +| 20.802 | DPT\_SABBehaviour\_Lock_Unlock | 1 byte | Long | \[0 … 6\] | | +| 20.803 | DPT_SSSBMode | 1 byte | Long | \[1 … 4\] | | +| 20.804 | DPT_BlindsControlMode | 1 byte | Long | \[0 … 1\] | | +| 20.1000 | DPT_CommMode | 1 byte | Long | \[0 … 255\] | | +| 20.1001 | DPT_AddInfoTypes | 1 byte | Long | {00h,01h,02h,03h,04h,05h,06h,07h,FFh} | | +| 20.1002 | DPT\_RF\_ModeSelect | 1 byte | Long | {00h,01h,02h} | | +| 20.1003 | DPT\_RF\_FilterSelect | 1 byte | Long | {00h,01h,02h,03h} | | +| 21.001 | DPT_StatusGen | 1 byte | Long | B₃F₁E₁D₁C₁A₁

A,C,D,E,F = {0,1}; B = {000} | | +| 21.002 | DPT\_Device\_Control | 1 byte | Long | B₃F₁E₁D₁C₁A₁

A,C,D,E,F = {0,1}; B = {000} | | +| 21.100 | DPT_ForceSign | 1 byte | Long | H₁G₁F₁E₁D₁C₁B₁A₁

A,B,C,D,E,F,G,H = {0,1} | | +| 21.101 | DPT_ForceSignCool | 1 byte | Long | B₁A₇

B = {0,1}; A = {0000000} | | +| 21.102 | DPT_StatusRHC | 1 byte | Long | H₁G₁F₁E₁D₁C₁B₁A₁

A,B,C,D,E,F,G,H = {0,1} | | +| 21.103 | DPT_StatusSDHWC | 1 byte | Long | D₅C₁B₁A₁

A,B,C = {0,1}; D = {00000} | | +| 21.104 | DPT_FuelTypeSet | 1 byte | Long | D₅C₁B₁A₁

A,B,C = {0,1}; D = {0} | | +| 21.105 | DPT_StatusRCC | 1 byte | Long | A₇B₁

B = {0,1}; A = {0000000} | | +| 21.106 | DPT_StatusAHU | 1 byte | Long | E₄D₁C₁B₁A₁

A,B,C,D = {0,1}, E = {0000} | | +| 21.601 | DPT_LightActuatorErrorInfo | 1 byte | Long | H₁G₁F₁E₁D₁C₁B₁A₁

A,B,C,D,E,F,G = {0,1}, h = {0} | | +| 21.1000 | DPT\_RF\_ModeInfo | 1 byte | Long | D₅C₁B₁A₁

C,B,A = {0,1}, D = {00000} | | +| 21.1001 | DPT\_RF\_FilterInfo | 1 byte | Long | D₅C₁B₁A₁

C,B,A = {0,1} | | +| 21.1010 | DPT\_Channel\_Activation_8 | 1 byte | Long | H₁G₁F₁E₁D₁C₁B₁A₁

H,G,F,E,D,C,B,A = {0,1} | | +| 22.100 | DPT_StatusDHWC | 2 bytes | Long | J₈HGFEDCBA

J = {00000000}; H,G,F,E,D,C,B,A = {0,1} | | +| 22.101 | DPT_StatusRHCC | 2 bytes | Long | R₁O₁N₁M₁L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

R = {0}; O,N,M,L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | | +| 22.1000 | DPT_Media | 2 bytes | Long | E₁₀D₁C₁F₁B₁A₁F₁

E = {0000000000}; D,C,B,A, = {0,1}; F = {0} | | +| 22.1010 | DPT\_Channel\_Activation_16 | 2 bytes | Long | P₁O₁N₁M₁L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | | +| 23.001 | DPT_OnOffAction | 2 bits | Long | {00(off), 01(on), 10(off/on), 11(on/off)} | | +| 23.002 | DPT\_Alarm\_Reaction | 2 bits | Long | {00 (no alarm is used), 01 (alarm position is UP), 10 (alarm position is DOWN)} | | +| 23.003 | DPT\_UpDown\_Action | 2 bits | Long | {00 (Up), 01 (Down), 01 (UpDown), 11 (DownUp)} | | +| 23.102 | DPT\_HVAC\_PB_Action | 2 bits | Long | {00 (Comfort/Economy), 01 (Comfort/Nothing), 10 (Economy/Nothing), 11 (Building prot/Auto)} | | +| 25.1000 | DPT_DoubleNibble | 1 byte | Long | B₄N₄

B = \[0 … 3\], N = \[0 … 3\] | | +| 26.001 | SceneInfo | 1 byte | Long | B₁A₂U₆

B = {0}; A = {0,1}; U = \[0 … 63\] | | +| 27.001 | CombinedInfoOnOff | 4 bytes | Long | Σ₁Π₁Λ₁Θ₁Δ₁Γ₁Z₁Y₁X₁W₁V₁U₁T₁S₁R₁Q₁P₁O₁N₁M₁L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

Σ,Π,Λ,Θ,Δ,Γ,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | | +| 29.010 | ActiveEnergy_V64 | 8 bytes | String | \[-9 223 372 036 854 775 808 … 9 223 372 036 854 775 807\] | | +| 29.011 | ApparantEnergy_V64 | 8 bytes | String | \[-9 223 372 036 854 775 808 … 9 223 372 036 854 775 807\] | | +| 29.012 | ReactiveEnergy_V64 | 8 bytes | String | \[-9 223 372 036 854 775 808 … 9 223 372 036 854 775 807\] | | +| 30.1010 | Channel\_Activation\_24 | 3 bytes | Long | X₁W₁V₁U₁T₁S₁R₁Q₁P₁O₁N₁M₁L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | | +| 31.101 | PB\_Action\_HVAC_Extended | 3 bits | Long | C₁B₁A₁

C,B,A = {0,1} | | +| 200.100 | Heat/Cool_Z | 2 bytes | Long | M₇G₁F₃E₁D₁C₁B₁A₁

A,B,C,D,E,G = {0,1}; F = {000}; M = {0000000} | | +| 200.101 | BinaryValue_Z | 2 bytes | Long | M₇G₁F₃E₁D₁C₁B₁A₁

A,B,C,D,E,G = {0,1}; F = {000}; M = {0000000} | | +| 201.100 | HVACMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 4\] | | +| 201.102 | DHWMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 4\] | | +| 201.104 | HVACContrMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 20\] | | +| 201.105 | EnableH/Cstage_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 3\] | | +| 201.107 | BuildingMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 2\] | | +| 201.108 | OccMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 2\] | | +| 201.109 | HVACEmergMode_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 5\] | | +| 202.001 | RelValue_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 255\] | | +| 202.002 | UCountValue8_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 255\] | | +| 203.002 | TimePeriodMsec_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]ms | | +| 203.003 | TimePeriod10Msec_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]ms | k = 0,1 | +| 203.004 | TimePeriod100Msec_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]ms | k = 0,01 | +| 203.005 | TimePeriodSec_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]s | | +| 203.006 | TimePeriodMin_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]min | | +| 203.007 | TimePeriodHrs_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]h | | +| 203.011 | UFlowRateLiter/h_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]l/h | k = 0,01 | +| 203.012 | UCountValue16_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\] | | +| 203.013 | UElCurrentμA_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]μA | k = 0,01 | +| 203.014 | PowerKW_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]kW | | +| 203.015 | AtmPressureAbs_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 1200\]kbar | k = 0,05 | +| 203.017 | PercentU16_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]% | k = 0,01 | +| 203.100 | HVACAirQual_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 65 535\]ppm | | +| 203.101 | WindSpeed_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 200\]km/h | k = 0,01 | +| 203.102 | SunIntensity_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 1400\]W/m² | k = 0,05 | +| 203.104 | HVACAirFlowAbs_Z | 3 bytes | Long | N₁₆F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[0 … 1400\]m³/h | | +| 204.001 | RelSignedValue_Z | 2 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-100 … 100\]% | | +| 205.002 | DeltaTimeMsec_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]ms | | +| 205.003 | DeltaTime10Msec_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]ms | k = 0,1 | +| 205.004 | DeltaTime100Msec_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]ms | k = 0,01 | +| 205.005 | DeltaTimeSec_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]s | | +| 205.006 | DeltaTimeMin_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]min | | +| 205.007 | DeltaTimeHrs_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]h | | +| 205.017 | Percent\_V16\_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-32 768 … 32 767\]% | k = 0,01 | +| 205.100 | TempHVACAbs_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000}; N = \[-273 … 655,34\]°C | k = 0,02 | +| 205.101 | TempHVACRel_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000};N = \[-273 … 655,34\]K | k = 0,02 | +| 205.102 | HVACAirFlowRel_Z | 3 bytes | Long | N₈F₃E₁D₁C₁B₁A₁

A,B,C,D,E = {0,1}; F = {000};N = \[-32 768 … 32 767\]K | | +| 206.100 | HVACModeNext | 3 bytes | Long | U₁₆N₈

U = \[0 … 65535\], N=\[0 … 4\] | | +| 206.102 | DHWModeNext | 3 bytes | Long | U₁₆N₈

U = \[0 … 65535\]; N=\[0 … 4\] | | +| 206.104 | OccModeNext | 3 bytes | Long | U₁₆N₈

U = \[0 … 65535\]; N=\[0 … 2\] | | +| 206.105 | BuildingModeNext | 3 bytes | Long | U₁₆N₈

U = \[0 … 65535\]; N=\[0 … 2\] | | +| 207.100 | StatusBUC | 2 bytes | Long | U₈G₂F₁E₁D₁C₁B₁A₁

U = \[0 … 100\]%; G = {00}; F,E,D,C,B,A = {0,1} | | +| 207.101 | LockSign | 2 bytes | Long | U₈C₆B₁A₁

U = \[0 … 100\]%; c = {0}; b,a = {0,1} | | +| 207.102 | ValueDemBOC | 2 bytes | Long | U₈C₆B₁A₁

U = \[0 … 100\]%; C = {000000}; B,A = {0,1} | | +| 207.104 | ActPosDemAbs | 2 bytes | Long | U₈E₄D₁C₁B₁A₁

U = \[0 … 100\]%; E = {0000}; D,C,B,A = {0,1} | | +| 207.105 | StatusAct | 2 bytes | Long | U₈;E₄D₁C₁B₁A₁

U = \[0 … 100\]%; E = {0000}; D,C,B,A = {0,1} | | +| 207.600 | StatusLightingActuator | 2 bytes | Long | U₈H₁G₁F₁E₁D₁C₁B₁A₁

U = \[0 … 100\]%; H,G,F,E,D,C,B,A = {0,1} | | +| 209.100 | StatusHPM | 3 bytes | Long | V₁₆F₃E₁D₁C₁B₁A₁

V=\[-273 … 655,34\]°C; F = {000}; E,D,C,B,A = {0,1} | k = 0,02 | +| 209.101 | TempRoomDemAbs | 3 bytes | Long | V₁₆E₄D₁C₁B₁A₁

V=\[-273 … 655,34\]°C; E = {0000}; D,C,B,A = {0,1} | k = 0,02 | +| 209.102 | StatusCPM | 3 bytes | Long | V₁₆E₄D₁C₁B₁A₁

V=\[-273..655,34\]°C; E = {0000}; D,C,B,A = {0,1} | k = 0,02 | +| 209.103 | StatusWTC | 3 bytes | Long | V₁₆D₅C₁B₁A₁

V=\[-273 … 655,34\]°C; D = {00000}; C,B,A = {0,1} | k = 0,02 | +| 210.100 | TempFlowWaterDemAbs | 4 bytes | Long | V₁₆M₄L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

V=\[-273 … 655,34\]°C; M = {0000}; L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | k = 0,02 | +| 211.100 | EnergyDemWater | 2 bytes | Long | U₈V₈

U = \[0 … 100\]; N = \[0 … 20\] | | +| 212.100 | TempRoomSetpSetShift\[3\] | 6 bytes | String | A₁₆B₁₆C₁₆

A,B,C = \[-655,34 … 655,34\]K | k = 0,02 | +| 212.101 | TempRoomSetpSet\[3\] | 6 bytes | String | A₁₆B₁₆C₁₆

A,B,C = \[-655,34 … 655,34\]°C | k = 0,02 | +| 213.100 | TempRoomSetpSet\[4\] | 8 bytes | String | A₁₆B₁₆C₁₆D₁₆

A,B,C,D = \[-655,34 … 655,34\]°C | k = 0,02 | +| 213.101 | TempDHWSetpSet\[4\] | 8 bytes | String | A₁₆B₁₆C₁₆D₁₆

A,B,C,D = \[-655,34 … 655,34\]°C | k = 0,02 | +| 213.102 | TempRoomSetpSetShift\[4\] | 8 bytes | String | A₁₆B₁₆C₁₆D₁₆

A,B,C,D = \[-655,34 … 655,34\]K | k = 0,02 | +| 214.100 | PowerFlowWaterDemHPM | 4 bytes | Long | V₁₆U₈G₂F₁E₁D₁C₁B₁A₁

V = \[-273 … 655,34\]°C; U = \[0 … 100\]%; H = {00}; F,E,D,C,B,A = {0,1} | k = 0,02 | +| 214.101 | PowerFlowWaterDemCPM | 4 bytes | Long | V₁₆U₈H₅C₁B₁A₁

V = \[-273 … 655,34\]°C; U = \[0 … 100\]%; D = {00000}; C,B,A = {0,1} | k = 0,02 | +| 215.100 | StatusBOC | 5 bytes | String | V₁₆U₈M₄L₁K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

V = \[-273 … 655,34\]°C; U = \[0 … 100\]%; M = {0000}; L,K,J,I,H,G,F,E,D,C,B,A = {0,1} | k = 0,02 | +| 215.101 | StatusCC | 5 bytes | String | V₁₆U₈J₈H₁G₁F₁E₁D₁C₁B₁A₁

V = \[-273 … 655,34\]°C; U = \[0 … 100\]%; J = {00000000}; H,G,F,E,D,C,B,A = {0,1} | | +| 216.100 | SpecHeatProd | 5 bytes | String | V₁₆U₈N₈D₅C₁B₁A₁

V = \[0 … 65 535\]kW; U = \[0 … 100\]%; N = \[0..3\]; D = {00000}; C,B,A = {0,1} | | +| 217.001 | Version | 2 bytes | Long | U₅V₅W₆

U = \[0 … 31\], V = \[0..31\], W = \[0 … 63\] | | +| 218.001 | VolumeLiter_Z | 5 bytes | String | V₃₂F₃E₁D₁C₁B₁A₁

E,D,C,B,A = {0,1}; F = {000}; V = \[-2 147 483 648 l … 2 147 483 647\]l | | +| 218.002 | FlowRate\_m3/h\_Z | 5 bytes | String | V₃₂F₃E₁D₁C₁B₁A₁

E,D,C,B,A = {0,1}; F = {000}; V = \[-2 147 483 648 l … 2 147 483 647\]m³/h | | +| 219.001 | AlarmInfo | 6 bytes | String | U₈N₈V₈W₈P₂N₁M₁L₁K₁J₁I₁D₅C₁B₁A₁

U = \[0 … 255\]; N = \[0 … 3\]; V = \[0 … 50\]; W = \[0 … 6\]; P = {00}; D = {00000}; A,B,C,I,J,K,L,M,N = {0,1} | | +| 220.100 | TempHVACAbsNext | 4 bytes | Long | U₁₆V₁₆

U = \[0 … 65535\]; V = \[-273 … 655,34\] | k = 0,02 | +| 221.001 | SerNum | 6 bytes | String | N₁₆U₃₂

U = \[0 … 65535\]; V = \[0 … 4 294 967 295\] | | +| 222.100 | TempRoomSetpSetF16\[3\] | 6 bytes | String | G₁₆F₁₆E₁₆

G,F,E = \[-273 … 670 760\]°C | | +| 222.101 | TempRoomSetpSetShiftF16\[3\] | 6 bytes | String | G₁₆F₁₆E₁₆

G,F,E = \[-670 760 … 670 760\]K | | +| 223.100 | EnergyDemAir | 3 bytes | Long | G₈F₈E₈

G = \[-100 … 100\]; F = \[0 … 20\]; E = \[0 … 5\] | | +| 224.100 | TempSupplyAirSetpSet | 6 bytes | String | U₁₆V₁₆F₈E₈

U,V = \[-273 … 655,34\]; F = \[0 … 20\]; E = \[0 … 5\] | k = 0,02 | +| 225.001 | ScalingSpeed | 3 bytes | Long | U₁₆V₈

U = \[1 … 65 535\]; V = \[0,4 … 100\] | k = 0,4 | +| 225.002 | Scaling\_Step\_Time | 3 bytes | Long | U₁₆V₈

U = \[1 … 65 535\]; V = \[0,4 … 100\] | k = 0,4 | +| 225.003 | TariffNext | 3 bytes | Long | U₁₆V₈

U = \[0 … 65 535\]; V = \[0 … 254\] | | +| 229.001 | MeteringValue | 6 bytes | String | V₃₂N₈F₃E₁D₁C₁B₁A₁

E,D,C,B,A = {0,1}; f,g,h = {000}; V = \[-2 147 483 648 l … 2 147 483 647\]; N = \[0 … 177\]; | | +| 230.1000 | MBus_Address | 8 bytes | String | U₁₆V₃₂W₈N₈

"MBus address", parameters U,V,W,N are manufacturer specific | | +| 231.001 | Locale_ASCII | 4 bytes | Long | L₁₆R₁₆

L - language; R - region | | +| 232.600 | Colour_RGB | 3 bytes | Long | R₈G₈B₈

R,G,B = \[0..255\] | | +| 234.001 | LanguageCodeAlpha2 | 2 bytes | Long | A₁₆

A - language code | | +| 234.002 | RegionCodeAlpha2 | 2 bytes | Long | A₁₆

A - region code | | +| 235.001 | Tariff_ActiveEnergy | 6 bytes | String | V₃₂U₈C₆B₁A₁

V = \[-2 147 483 648 l … 2 147 483 647\]; U = \[0 … 254\]; C = {000000}; B,A = {0,1} | | +| 236.001 | Prioritised\_Mode\_Control | 1 byte | Long | B₁P₃M₄

B = {0,1}; P = \[0 … 7\]; M = \[0 … 15\] | | +| 237.600 | DALI\_Control\_Gear_Diagnostic | 2 bytes | Long | M₅L₁K₁J₁H₁G₁A₆

M = {00000}; L,K,J,H,G = {0,1}; A = \[0 … 63\] | | +| 238.001 | SceneConfig | 1 byte | Long | A₁B₁N₆

A,B = {0,1}; N = \[0 … 63\] | | +| 238.600 | DALI_Diagnostic | 1 byte | Long | A₁B₁N₆

A,B = {0,1}; N = \[0 … 63\] | | +| 239.001 | FlaggedScaling | 2 bytes | Long | U₈B₇A₁

U = \[0 … 100\]; B = {0000000}; A = {0,1} | k = 0,4 | +| 240.800 | CombinedPosition | 3 bytes | Long | U₁₆C₆B₁A₁

U = \[0 … 100\]; C = {000000}; B,A = {0,1} | k = 0,4 | +| 241.800 | StatusSAB | 4 bytes | Long | U₈V₈N₁M₁L₃K₁J₁I₁H₁G₁F₁E₁D₁C₁B₁A₁

U,V = \[0 … 100\]; L = {000}; N,M,K,J,I,H,G,F,E,D,C,B,A = {0,1} | k = 0,4 | \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d1b1c5b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2981 @@ +{ + "name": "dptlib", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true + }, + "@babel/core": { + "version": "7.17.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.5.tgz", + "integrity": "sha512-/BBMw4EvjmyquN5O+t5eh0+YqB3XXJkYD2cjKpYtWOfFy4lQ4UozNSmxAcWT8r2XtZs0ewG+zrfsqeR15i1ajA==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.17.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz", + "integrity": "sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@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 + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "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 + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "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" + } + } + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "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": { + "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 + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "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 + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "@istanbuljs/nyc-config-typescript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", + "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@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" + } + }, + "@types/chai": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "optional": true + }, + "@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "dev": true + }, + "@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.14.0.tgz", + "integrity": "sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.14.0", + "@typescript-eslint/type-utils": "5.14.0", + "@typescript-eslint/utils": "5.14.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.14.0.tgz", + "integrity": "sha512-aHJN8/FuIy1Zvqk4U/gcO/fxeMKyoSv/rS46UXMXOJKVsLQ+iYPuXNbpbH7cBLcpSbmyyFbwrniLx5+kutu1pw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.14.0", + "@typescript-eslint/types": "5.14.0", + "@typescript-eslint/typescript-estree": "5.14.0", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.14.0.tgz", + "integrity": "sha512-LazdcMlGnv+xUc5R4qIlqH0OWARyl2kaP8pVCS39qSL3Pd1F7mI10DbdXeARcE62sVQE4fHNvEqMWsypWO+yEw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.14.0", + "@typescript-eslint/visitor-keys": "5.14.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.14.0.tgz", + "integrity": "sha512-d4PTJxsqaUpv8iERTDSQBKUCV7Q5yyXjqXUl3XF7Sd9ogNLuKLkxz82qxokqQ4jXdTPZudWpmNtr/JjbbvUixw==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.14.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.14.0.tgz", + "integrity": "sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz", + "integrity": "sha512-QGnxvROrCVtLQ1724GLTHBTR0lZVu13izOp9njRvMkCBgWX26PKvmMP8k82nmXBRD3DQcFFq2oj3cKDwr0FaUA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.14.0", + "@typescript-eslint/visitor-keys": "5.14.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.14.0.tgz", + "integrity": "sha512-EHwlII5mvUA0UsKYnVzySb/5EE/t03duUTweVy8Zqt3UQXBrpEVY144OTceFKaOe4xQXZJrkptCf7PjEBeGK4w==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.14.0", + "@typescript-eslint/types": "5.14.0", + "@typescript-eslint/typescript-estree": "5.14.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz", + "integrity": "sha512-yL0XxfzR94UEkjBqyymMLgCBdojzEuy/eim7N9/RIcTNxpJudAcqsU8eRyfzBbcEzGoPWfdM3AGak3cN08WOIw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.14.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "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.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "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": "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" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "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 + }, + "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 + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "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" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz", + "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001313", + "electron-to-chromium": "^1.4.76", + "escalade": "^3.1.1", + "node-releases": "^2.0.2", + "picocolors": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "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": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001314", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz", + "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==", + "dev": true + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "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" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "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" + } + }, + "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 + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "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 + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "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" + } + }, + "dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "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" + } + }, + "electron-to-chromium": { + "version": "1.4.79", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.79.tgz", + "integrity": "sha512-nWfAxof87mGHkbORCwVRPst4FlSVdprOKS6dBMrcwn3sjwf8iHXEhsu1+FU5Psd7Ps3KKeBufAdfsPK5BmbSUg==", + "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 + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "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.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.2.0", + "@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.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "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" + }, + "dependencies": { + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "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 + }, + "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" + } + } + } + }, + "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-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.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.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" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "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 + }, + "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 + }, + "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-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "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" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "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.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fsu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", + "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", + "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 + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "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-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "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" + } + }, + "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" + } + }, + "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" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "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 + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "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 + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "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 + }, + "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" + } + }, + "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 + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "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-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.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" + } + }, + "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": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "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 + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "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": "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" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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 + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.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" + } + }, + "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" + } + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "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 + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "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" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "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.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.1.tgz", + "integrity": "sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.2.0", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "mochawesome": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.2.tgz", + "integrity": "sha512-kZBHRYoiV+zPrqMO0TU4LOiYDCMR5ciBZEE6fvS6RFMtB2MMndeOQ2LQEpFHtPG8yxFsqg1F6gym5qo3rPs/XA==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "diff": "^5.0.0", + "json-stringify-safe": "^5.0.1", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isobject": "^3.0.2", + "lodash.isstring": "^4.0.1", + "mochawesome-report-generator": "^6.1.1", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2" + } + }, + "mochawesome-report-generator": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.1.1.tgz", + "integrity": "sha512-wTYGAH2KHOSDi7eSvwniq+h4Wvrvt+Bd4mz8774HOHTcxRTECh5zjvG5fP+/VvPbhzsjOlIsylZaOVEdwZlfJg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "dateformat": "^4.5.1", + "escape-html": "^1.0.3", + "fs-extra": "^10.0.0", + "fsu": "^1.1.1", + "lodash.isfunction": "^3.0.9", + "opener": "^1.5.2", + "prop-types": "^15.7.2", + "tcomb": "^3.2.17", + "tcomb-validation": "^3.3.0", + "validator": "^13.6.0", + "yargs": "^17.2.1" + }, + "dependencies": { + "yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "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.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "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 + }, + "nanoid": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "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 + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "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 + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.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 + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "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" + } + }, + "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-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 + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "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 + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "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 + }, + "prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "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 + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "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 + }, + "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" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "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 + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "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-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-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "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 + }, + "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" + } + }, + "tcomb": { + "version": "3.2.29", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", + "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", + "dev": true + }, + "tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "dev": true, + "requires": { + "tcomb": "^3.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "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 + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "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" + } + }, + "ts-mocha": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz", + "integrity": "sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw==", + "dev": true, + "requires": { + "ts-node": "7.0.1", + "tsconfig-paths": "^3.5.0" + } + }, + "ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz", + "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==", + "dev": true, + "optional": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "optional": true + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "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.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 + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "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" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "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 + }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "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" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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 + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "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" + } + }, + "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": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "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 + }, + "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.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "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/package.json b/package.json new file mode 100644 index 0000000..bbbdd7c --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "dptlib", + "version": "0.0.1", + "description": "KNX DPT library", + "main": "lib/index.js", + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.1.0", + "@types/node": "^17.0.14", + "@typescript-eslint/eslint-plugin": "^5.10.2", + "@typescript-eslint/parser": "^5.10.2", + "chai": "^4.3.6", + "eslint": "^8.8.0", + "mocha": "^9.2.0", + "mochawesome": "^7.1.2", + "nyc": "^15.1.0", + "prettier": "^2.5.1", + "ts-mocha": "^9.0.2", + "typescript": "^4.5.5" + }, + "scripts": { + "build": "tsc", + "test": "ts-mocha --reporter mochawesome tests/**/*.test.ts", + "coverage": "nyc npm test", + "lint": "eslint --fix \"**/*.ts\"" + }, + "repository": { + "type": "git", + "url": "http://git.home.lipc.tech/laur/dptlib.git" + }, + "keywords": [ + "knx", + "dpt", + "typescript" + ], + "author": "Laur Ivan", + "license": "GPL-3.0-or-later" +} diff --git a/src/DPT1.ts b/src/DPT1.ts new file mode 100644 index 0000000..40f8648 --- /dev/null +++ b/src/DPT1.ts @@ -0,0 +1,232 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT1 implements DPT { + id = '1'; + name = '1-bit value'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the on/off value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const val = buffer.readUInt8(0); + if (val !== 0 && val !== 1) { + throw new InvalidValueError(`Invalid binary value ${val} for DPT1. Expected 1 or 0`); + } + return val; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (value !== 0 && value !== 1) { + throw new InvalidValueError(`Invalid value ${value} for a DPT1. Should be 0 or 1.`); + } + const buf = Buffer.alloc(this.bufferLength); + buf.writeUInt8(value, 0); + return buf; + } + + subtypes: { + // 1.001 on/off + '001': { + use: 'G', + name: 'DPT_Switch', + desc: 'switch', + enc: { 0: 'Off', 1: 'On' }, + }, + + // 1.002 boolean + '002': { + use: 'G', + name: 'DPT_Bool', + desc: 'bool', + enc: { 0: 'false', 1: 'true' }, + }, + + // 1.003 enable + '003': { + use: 'G', + name: 'DPT_Enable', + desc: 'enable', + enc: { 0: 'disable', 1: 'enable' }, + }, + + // 1.004 ramp + '004': { + use: 'FB', + name: 'DPT_Ramp', + desc: 'ramp', + enc: { 0: 'No ramp', 1: 'Ramp' }, + }, + + // 1.005 alarm + '005': { + use: 'FB', + name: 'DPT_Alarm', + desc: 'alarm', + enc: { 0: 'No alarm', 1: 'Alarm' }, + }, + + // 1.006 binary value + '006': { + use: 'FB', + name: 'DPT_BinaryValue', + desc: 'binary value', + enc: { 0: 'Low', 1: 'High' }, + }, + + // 1.007 step + '007': { + use: 'FB', + name: 'DPT_Step', + desc: 'step', + enc: { 0: 'Decrease', 1: 'Increase' }, + }, + + // 1.008 up/down + '008': { + use: 'G', + name: 'DPT_UpDown', + desc: 'up/down', + enc: { 0: 'Up', 1: 'Down' }, + }, + + // 1.009 open/close + '009': { + use: 'G', + name: 'DPT_OpenClose', + desc: 'open/close', + enc: { 0: 'Open', 1: 'Close' }, + }, + + // 1.010 start/stop + '010': { + use: 'G', + name: 'DPT_Start', + desc: 'start/stop', + enc: { 0: 'Stop', 1: 'Start' }, + }, + + // 1.011 state + '011': { + use: 'FB', + name: 'DPT_State', + desc: 'state', + enc: { 0: 'Inactive', 1: 'Active' }, + }, + + // 1.012 invert + '012': { + use: 'FB', + name: 'DPT_Invert', + desc: 'invert', + enc: { 0: 'Not inverted', 1: 'inverted' }, + }, + + // 1.013 dim send style + '013': { + use: 'FB', + name: 'DPT_DimSendStyle', + desc: 'dim send style', + enc: { 0: 'Start/stop', 1: 'Cyclically' }, + }, + + // 1.014 input source + '014': { + use: 'FB', + name: 'DPT_InputSource', + desc: 'input source', + enc: { 0: 'Fixed', 1: 'Calculated' }, + }, + + // 1.015 reset + '015': { + use: 'G', + name: 'DPT_Reset', + desc: 'reset', + enc: { 0: 'no action(dummy)', 1: 'reset command(trigger)' }, + }, + + // 1.016 acknowledge + '016': { + use: 'G', + name: 'DPT_Ack', + desc: 'ack', + enc: { 0: 'no action(dummy)', 1: 'acknowledge command(trigger)' }, + }, + + // 1.017 trigger + '017': { + use: 'G', + name: 'DPT_Trigger', + desc: 'trigger', + enc: { 0: 'trigger', 1: 'trigger' }, + }, + + // 1.018 occupied + '018': { + use: 'G', + name: 'DPT_Occupancy', + desc: 'occupancy', + enc: { 0: 'not occupied', 1: 'occupied' }, + }, + + // 1.019 open window or door + '019': { + use: 'G', + name: 'DPT_WindowDoor', + desc: 'open window/door', + enc: { 0: 'closed', 1: 'open' }, + }, + + // 1.021 and/or + '021': { + use: 'FB', + name: 'DPT_LogicalFunction', + desc: 'and/or', + enc: { 0: 'logical function OR', 1: 'logical function AND' }, + }, + + // 1.022 scene A/B + '022': { + use: 'FB', + name: 'DPT_Scene_AB', + desc: 'scene A/B', + enc: { 0: 'scene A', 1: 'scene B' }, + }, + + // 1.023 shutter/blinds mode + '023': { + use: 'FB', + name: 'DPT_ShutterBlinds_Mode', + desc: 'shutter/blinds mode', + enc: { + 0: 'only move Up/Down mode (shutter)', + 1: 'move Up/Down + StepStop mode (blind)', + }, + }, + + // 1.100 cooling/heating ---FIXME--- + 100: { + use: '???', + name: 'DPT_Heat/Cool', + desc: 'heat/cool', + enc: { 0: '???', 1: '???' }, + }, + }; + +} diff --git a/src/DPT10.ts b/src/DPT10.ts new file mode 100644 index 0000000..7e97715 --- /dev/null +++ b/src/DPT10.ts @@ -0,0 +1,92 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +const timeRegexp = /(\d{1,2}):(\d{1,2}):(\d{1,2})/; + +export class DPT10 implements DPT { + id = '10'; + name = 'day of week + time of day'; + bufferLength = 3; + + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): Date { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + const [dnh, minutes, seconds] = buffer; + const dow = (dnh & 0b11100000) >> 5; + const hours = dnh & 0b00011111; + + if (hours < 0 || hours > 23) + throw new InvalidValueError(`Hours out of range: Expected [0-23], got ${hours}`) + if (minutes < 0 || minutes > 59) + throw new InvalidValueError(`Minutes out of range: Expected [0-59], got ${minutes}`) + if (seconds < 0 || seconds > 59) + throw new InvalidValueError(`Seconds out of range: Expected [0-59], got ${seconds}`) + + const d = new Date(); + if (d.getDay() !== dow) + // adjust day of month to get the day of week right + d.setDate(d.getDate() + dow - d.getDay()); + // TODO: Shouldn't this be UTCHours? + d.setHours(hours, minutes, seconds); + // reset the milliseconds + d.setMilliseconds(0) + return d; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: Date | number | string): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Must supply a Date, number or String for DPT10 time.`); + + let dow, hour, minute, second; + // day of week. NOTE: JS Sunday = 0 + switch (typeof value) { + case 'string': + // try to parse + let match = timeRegexp.exec(value); + if (match) { + dow = ((new Date().getDay() - 7) % 7) + 7; + hour = parseInt(match[1]); + minute = parseInt(match[2]); + second = parseInt(match[3]); + } else { + throw new InvalidValueError(`DPT10: invalid time format (${value})`); + } + break; + case 'number': + value = new Date(value); + default: + dow = ((value.getDay() - 7) % 7) + 7; + hour = value.getHours(); + minute = value.getMinutes(); + second = value.getSeconds(); + } + + return Buffer.from([(dow << 5) + hour, minute, second]); + } + + + subtypes: { + // 10.001 time of day + '001': { + name: 'DPT_TimeOfDay', + desc: 'time of day', + }, + }; + +} diff --git a/src/DPT11.ts b/src/DPT11.ts new file mode 100644 index 0000000..1aeef43 --- /dev/null +++ b/src/DPT11.ts @@ -0,0 +1,77 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT11 implements DPT { + id = '11'; + name = '3-byte date value'; + bufferLength = 3; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): Date { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + const day = buffer[0] & 31; //0b00011111); + const month = buffer[1] & 15; //0b00001111); + let year = buffer[2] & 127; //0b01111111); + year = year + (year > 89 ? 1900 : 2000); + if ( + day < 1 || + day > 31 || + month < 1 || + month > 12 || + year < 1990 || + year > 2089 + ) { + throw new InvalidValueError(`${buffer} => ${day}/${month}/${year} is not valid date according to DPT11, setting to 1990/01/01`); + } + return new Date(year, month - 1, day); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: Date | string): Buffer { + switch (typeof value) { + case 'string': + case 'number': + value = new Date(value); + break; + case 'object': + // this expects the month property to be zero-based (January = 0, etc.) + if (value instanceof Date) break; + const { year, month, day } = value; + value = new Date(parseInt(year), parseInt(month), parseInt(day)); + } + + if (isNaN(value.getDate())) + throw new InvalidValueError('Must supply a numeric timestamp, Date or String object for DPT11 Date') + + const year = value.getFullYear(); + return Buffer.from([ + value.getDate(), + value.getMonth() + 1, + year - (year >= 2000 ? 2000 : 1900), + ]); + } + + + subtypes: { + // 11.001 date + '001': { + name: 'DPT_Date', + desc: 'Date', + }, + }; + +} diff --git a/src/DPT12.ts b/src/DPT12.ts new file mode 100644 index 0000000..b67a0a5 --- /dev/null +++ b/src/DPT12.ts @@ -0,0 +1,48 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; +import { buffer } from 'stream/consumers'; + +export class DPT12 implements DPT { + id = '12'; + name = '4-byte unsigned value'; + bufferLength = 4 + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + return buffer.readUInt32BE(0); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('Cannot write null value'); + + let result = Buffer.alloc(this.bufferLength) + result.writeUInt32BE(value) + return result; + } + + subtypes: { + // 12.001 counter pulses + "001": { + "name": "DPT_Value_4_Ucount", + "desc": "counter pulses" + } + }; + +} diff --git a/src/DPT13.ts b/src/DPT13.ts new file mode 100644 index 0000000..72c4376 --- /dev/null +++ b/src/DPT13.ts @@ -0,0 +1,102 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT13 implements DPT { + id = '13'; + name = '4-byte signed value'; + bufferLength = 4; + range = [-Math.pow(2, 31), Math.pow(2, 31) - 1] + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + // In 4 bytes, there's no way to exceed the range + return buffer.readInt32BE(0) + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + + if (value === undefined || value === null || Number.isFinite(value)) + throw new InvalidValueError(`Value is not viable`) + if (Number.isInteger(value)) + throw new InvalidValueError(`Value ${value} is not an integer`) + + if (value < this.range[0] || value > this.range[1]) + throw new InvalidValueError(`Value ${value} is out of range`) + + let result = Buffer.alloc(this.bufferLength) + result.writeInt32BE(value) + return result; + } + + subtypes: { + // 13.001 counter pulses (signed) + "001": { + "name": "DPT_Value_4_Count", "desc": "counter pulses (signed)", + "unit": "pulses" + }, + + "002": { + "name": "DPT_Value_Activation_Energy", "desc": "activation energy (J/mol)", + "unit": "J/mol" + }, + + // 13.010 active energy (Wh) + "010": { + "name": "DPT_ActiveEnergy", "desc": "active energy (Wh)", + "unit": "Wh" + }, + + // 13.011 apparent energy (VAh) + "011": { + "name": "DPT_ApparantEnergy", "desc": "apparent energy (VAh)", + "unit": "VAh" + }, + + // 13.012 reactive energy (VARh) + "012": { + "name": "DPT_ReactiveEnergy", "desc": "reactive energy (VARh)", + "unit": "VARh" + }, + + // 13.013 active energy (KWh) + "013": { + "name": "DPT_ActiveEnergy_kWh", "desc": "active energy (kWh)", + "unit": "kWh" + }, + + // 13.014 apparent energy (kVAh) + "014": { + "name": "DPT_ApparantEnergy_kVAh", "desc": "apparent energy (kVAh)", + "unit": "VAh" + }, + + // 13.015 reactive energy (kVARh) + "015": { + "name": "DPT_ReactiveEnergy_kVARh", "desc": "reactive energy (kVARh)", + "unit": "kVARh" + }, + + // 13.100 time lag(s) + "100": { + "name": "DPT_LongDeltaTimeSec", "desc": "time lag(s)", + "unit": "s" + }, + }; + +} diff --git a/src/DPT14.ts b/src/DPT14.ts new file mode 100644 index 0000000..8324c18 --- /dev/null +++ b/src/DPT14.ts @@ -0,0 +1,169 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT14 implements DPT { + id = '14'; + name = '32-bit floating point value'; + bufferLength = 4; + + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + return buffer.readFloatBE(0); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (!value || typeof value != 'number') + throw new InvalidValueError(`Invalid value [${value}]`) + const apdu_data = Buffer.alloc(this.bufferLength); + apdu_data.writeFloatBE(value, 0); + return apdu_data; + } + + + subtypes: { + // TODO + '007': { + name: 'DPT_Value_AngleDeg°', + desc: 'angle, degree', + unit: '°', + }, + + '019': { + name: 'DPT_Value_Electric_Current', + desc: 'electric current', + unit: 'A', + }, + + '027': { + name: 'DPT_Value_Electric_Potential', + desc: 'electric potential', + unit: 'V', + }, + + '028': { + name: 'DPT_Value_Electric_PotentialDifference', + desc: 'electric potential difference', + unit: 'V', + }, + + '031': { + name: 'DPT_Value_Energ', + desc: 'energy', + unit: 'J', + }, + + '032': { + name: 'DPT_Value_Force', + desc: 'force', + unit: 'N', + }, + + '033': { + name: 'DPT_Value_Frequency', + desc: 'frequency', + unit: 'Hz', + }, + + '036': { + name: 'DPT_Value_Heat_FlowRate', + desc: 'heat flow rate', + unit: 'W', + }, + + '037': { + name: 'DPT_Value_Heat_Quantity', + desc: 'heat, quantity of', + unit: 'J', + }, + + '038': { + name: 'DPT_Value_Impedance', + desc: 'impedance', + unit: 'Ω', + }, + + '039': { + name: 'DPT_Value_Length', + desc: 'length', + unit: 'm', + }, + + '051': { + name: 'DPT_Value_Mass', + desc: 'mass', + unit: 'kg', + }, + + '056': { + name: 'DPT_Value_Power', + desc: 'power', + unit: 'W', + }, + + '065': { + name: 'DPT_Value_Speed', + desc: 'speed', + unit: 'm/s', + }, + + '066': { + name: 'DPT_Value_Stress', + desc: 'stress', + unit: 'Pa', + }, + + '067': { + name: 'DPT_Value_Surface_Tension', + desc: 'surface tension', + unit: '1/Nm', + }, + + '068': { + name: 'DPT_Value_Common_Temperature', + desc: 'temperature, common', + unit: '°C', + }, + + '069': { + name: 'DPT_Value_Absolute_Temperature', + desc: 'temperature (absolute)', + unit: 'K', + }, + + '070': { + name: 'DPT_Value_TemperatureDifference', + desc: 'temperature difference', + unit: 'K', + }, + + '078': { + name: 'DPT_Value_Weight', + desc: 'weight', + unit: 'N', + }, + + '079': { + name: 'DPT_Value_Work', + desc: 'work', + unit: 'J', + }, + }; + +} diff --git a/src/DPT15.ts b/src/DPT15.ts new file mode 100644 index 0000000..4c46981 --- /dev/null +++ b/src/DPT15.ts @@ -0,0 +1,100 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +/** + * U 4 bit + * V 4 bit + * W 4 bit + * X 4 bit + * Y 4 bit + * Z 4 bit + * E 1 bit + * P 1 bit + * D 1 bit + * C 1 bit + * N 4 bit + * + * U,V,W,X,Y,Z = [0 … 9]; E,P,D,C = {0,1}; N = [0 … 15] + * + * Source: https://www.promotic.eu/en/pmdoc/Subsystems/Comm/PmDrivers/KNXDTypes.htm + */ +export interface DPT15Result { + U: number + V: number + W: number + X: number + Y: number + Z: number + E: number + P: number + D: number + C: number + N: number +} +export class DPT15 implements DPT { + id = ''; + name = '4-byte access control data'; + bufferLength = 4; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): DPT15Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + const result: DPT15Result = { + U: (buffer[0] & 0xf0) >> 4, + V: (buffer[0] & 0x0f), + W: (buffer[1] & 0xf0) >> 4, + X: (buffer[1] & 0x0f), + Y: (buffer[2] & 0xf0) >> 4, + Z: (buffer[2] & 0x0f), + E: (buffer[3] >> 7) & 0x01, + P: (buffer[3] >> 6) & 0x01, + D: (buffer[3] >> 5) & 0x01, + C: (buffer[3] >> 4) & 0x01, + N: (buffer[3] & 0x0f), + } + + if (Math.max(result.U, result.V, result.W, result.X, result.Y, result.Z) > 9) + throw new InvalidValueError(`Value must be < 9 (U: ${result.U}, V: ${result.V}, W: ${result.W}, X: ${result.X}, y: ${result.Y}, Z: ${result.Z})`) + + return result; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT15Result): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + if (Math.max(value.U, value.V, value.W, value.X, value.Y, value.Z) > 9) + throw new InvalidValueError(`Value must be < 9 (U: ${value.U}, V: ${value.V}, W: ${value.W}, X: ${value.X}, y: ${value.Y}, Z: ${value.Z})`) + + const apdu_data = Buffer.alloc(this.bufferLength); + apdu_data.writeUInt8((value.U << 4) + value.V, 0); + apdu_data.writeUInt8((value.W << 4) + value.X, 1); + apdu_data.writeUInt8((value.Y << 4) + value.Z, 2); + apdu_data.writeUInt8((value.E << 7) + (value.P << 6) + (value.D << 5) + (value.C << 4) + value.N, 3); + return apdu_data; + } + + + subtypes: { + "000": { + name: "DPT_Access_Data", + desc: "default field" + } + }; + +} diff --git a/src/DPT16.ts b/src/DPT16.ts new file mode 100644 index 0000000..cc0c5f8 --- /dev/null +++ b/src/DPT16.ts @@ -0,0 +1,59 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT16 implements DPT { + id = '16'; + name = '14-character string'; + bufferLength = 14; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): string { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + + return buffer.toString('ascii'); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: string): Buffer { + if (typeof value !== 'string') + throw new InvalidValueError('Must supply a string value') + + const buf = Buffer.alloc(14); + buf.write(value, 'ascii'); + return buf; + } + + + subtypes: { + // 16.000 ASCII string + '000': { + use: 'G', + name: 'DPT_String_ASCII', + desc: 'ASCII string', + force_encoding: 'US-ASCII', + }, + + // 16.001 ISO-8859-1 string + '001': { + use: 'G', + name: 'DPT_String_8859_1', + desc: 'ISO-8859-1 string', + force_encoding: 'ISO-8859-1', + }, + }; + +} diff --git a/src/DPT17.ts b/src/DPT17.ts new file mode 100644 index 0000000..d7a891b --- /dev/null +++ b/src/DPT17.ts @@ -0,0 +1,52 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT17 implements DPT { + id = '17'; + name = 'scene number'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + // Scene number between 0 and 63 + return buffer.readUInt8(0) & 0b00111111; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + if (value > 63) + throw new InvalidValueError(`Expected scene number [0, 63]. Got [${value}]`) + + let buf = Buffer.alloc(this.bufferLength) + buf.writeUInt8(value, 0) + return buf; + } + + + subtypes: { + // 17.001 Scene number + "001": { + use: "G", + name: "DPT_SceneNumber", desc: "Scene Number", + }, + }; + +} diff --git a/src/DPT18.ts b/src/DPT18.ts new file mode 100644 index 0000000..201db60 --- /dev/null +++ b/src/DPT18.ts @@ -0,0 +1,62 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export interface DPT18Result { + activateLearn: number + // pad: number // reserved + sceneNumber: number +} +export class DPT18 implements DPT { + id = '18'; + name = '8-bit Scene Activate/Learn + number'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): DPT18Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + + return { + activateLearn: (buffer[0] & 0b10000000) >> 7, + sceneNumber: buffer[0] & 0b00111111 + }; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT18Result): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + if (value.sceneNumber > 63) + throw new InvalidValueError(`Expected scene number [0..63]. Got [${value.sceneNumber}]`) + + if (value.activateLearn > 1) + throw new InvalidValueError(`Expected scene number [0, 1]. Got [${value.activateLearn}]`) + + let buf = Buffer.alloc(this.bufferLength) + buf.writeUInt8((value.activateLearn << 7) + value.sceneNumber) + return buf; + } + + + subtypes: { + // 9.001 temperature (oC) + "001": { + name: "DPT_SceneControl", desc: "scene control" + } + }; + +} diff --git a/src/DPT19.ts b/src/DPT19.ts new file mode 100644 index 0000000..3f02e64 --- /dev/null +++ b/src/DPT19.ts @@ -0,0 +1,226 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +/** + * 19.001 Date & Time + * + *
+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ * Field Names | (Year)                        | 0   0   0   0   (Month)       |
+ * Encoding    | U   U   U   U   U   U   U   U | r   r   r   r   U   U   U   U |
+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ *             | 0   0   0   (Day Of Month)    | (DayOfWeek) (Hour)            |
+ *             | r   r   r   U   U   U   U   U | U   U   U   U   U   U   U   U |
+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ *             | 0   0   (Minutes)             | 0   0   (Seconds)             |
+ *             | r   r   U   U   U   U   U   U | r   r   U   U   U   U   U   U |
+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ *             | F  WD  NWD NY  ND  NDoW NT SST| CLQ SRC 0   0   0   0   0   0 |
+ *             | B   B   B   B   B   B   B   B | B   B   r   r   r   r   r   r |
+ *             +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ * Format:     8 octets (U8 [r4U4] [r3U5] [r3U5] [r2U6] [r2U6] B16)
+ * Encoding:
+ *             Year  = [0 .. 255]
+ *                0 = year 1900
+ *                255 = year 2155
+ *             Month = [1 .. 12]
+ *             DayOfMonth = [1 .. 31]
+ *             DayOfWeek = [0 .. 7]
+ *                1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday, 7 = Sunday, 0 = any day
+ *             Hour    = [0 .. 24]
+ *             Minutes = [0 .. 59]
+ *             Seconds = [0 .. 59]
+ *             (F)   Fault = {0, 1}
+ *                        0 = Normal (no fault)
+ *                        1 = Fault
+ *             (WD)   WorkingDay = {0, 1}
+ *                        0 = No Working Day
+ *                        1 = Working Day
+ *             (NWD)  NoWorkingDay = {0, 1}
+ *                        0 = WorkingDay field valid
+ *                        1 = WorkingDay field not valid
+ *             (NY)   NoYear = {0, 1}
+ *                        0 = Year field valid
+ *                        1 = Year field not valid
+ *             (ND)   NoDate = {0, 1}
+ *                        0 = Month and DayOfMonth fields valid
+ *                        1 = Month and DayOfMonth fields not valid
+ *             (NDoW) NoDayOfWeek = {0, 1}
+ *                        0 = DayOfWeek field valid
+ *                        1 = DayOfWeek field not valid
+ *             (NT)   NoTime = {0, 1}
+ *                        0 = Hour, Minutes and Seconds valid
+ *                        1 = Hour, Minutes and Seconds not valid
+ *             (SST)  Standard Summer Time = {0, 1}
+ *                        0 = UTC+x (standard time)
+ *                        1 = UTC+x +1h (summer daylight saving time)
+ *             (CLQ)  QualityOfClock = {0, 1}
+ *                        0 = Clock without external synchronization signal
+ *                        1 = Clock with external synchronization signal (DCF 77, VideoText, ...)
+ *             (SRC)  SynchronisationSourceReliability = {0, 1}
+ *                        0 = Unreliable Synchronisation (mains, local quartz)
+ *                        1 = Reliable Synchronisation (radio, internet)
+ * 
+ *

+ * The encoding of the hour is within the range [0 .. 24] instead of [0 .. 23]. When the hour is set to "24", the + * values of octet 3 (Minutes) and 2 (Seconds) have to be set to zero. + *

+ * "Fault" is set if one ore more supported fields of the Date & Time information are corrupted. "Fault" is set e.g. + * power-down if battery backup was not sufficient, after 1st start up of device (clock un-configured) or radio-clock + * (DCF 77) had no reception for a very long time. "Fault" is usually cleared automatically by the device if the + * local clock is set or clock data is refreshed + *

+ * The receiver (e.g. a room unit, MMI) will interpret Date&Time with "Fault" as corrupted and will either ignore + * the message or show --:--:-- or blinking 00:00:00 (as known from Video recorders after power-up). + */ +export class DPT19Result { + dateTime: Date = new Date() + dayOfWeek: number = undefined + f: boolean = false + wd: boolean = false + nwd: boolean = false + ny: boolean = false + nd: boolean = false + ndow: boolean = false + nt: boolean = false + sst: boolean = false + internalClock: boolean = true // Assume external clock + reliability: boolean = false; +} +export class DPT19 implements DPT { + id = '19'; + name = '8-byte Date+Time'; + bufferLength = 8; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): DPT19Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + const byte8 = buffer.readUInt8(0) + const byte7 = buffer.readUInt8(1) + const byte6 = buffer.readUInt8(2) + const byte5 = buffer.readUInt8(3) + const byte4 = buffer.readUInt8(4) + const byte3 = buffer.readUInt8(5) + const byte2 = buffer.readUInt8(6) + const byte1 = buffer.readUInt8(7) + + let year = byte8 + let month = byte7 & 0xF + const dayOfMonth = byte6 & 0x1F + let dayOfWeek = byte5 >> 5 + const hourOfDay = byte5 & 0x1F + const minutes = byte4 & 0x3F + const seconds = byte3 & 0x3F + const f = !!(byte2 & 0x80) + const wd = !!(byte2 & 0x40) + const nwd = !!(byte2 & 0x20) + const ny = !!(byte2 & 0x10) + const nd = !!(byte2 & 0x8) + const ndow = !!(byte2 & 0x4) + const nt = !!(byte2 & 0x2) + const suti = !!(byte2 & 0x1) + const clq = !!(byte1 & 0x80) + const reliability = !!(byte1 & 0x40) + + year += 1900 + + // Convert month from knx to JavaScript (12 => 11, 11 => 10, ...) + month -= 1 + + // Convert day of week from knx to JavaScript (7 => 0, 0 => undefined) + if (dayOfWeek === 7) { + dayOfWeek = 0 + } else if (dayOfWeek === 0) { + dayOfWeek = undefined + } + + // Check minutes and seconds if hours equals 24 + if (hourOfDay === 24 && (minutes !== 0 || seconds !== 0)) { + throw new RangeError('Invalid time (hour of day is 24, but minutes or seconds are not 0)') + } + + return { + dateTime: new Date(year, month, dayOfMonth, hourOfDay, minutes, seconds), + dayOfWeek: dayOfWeek, + f: f, + wd: wd, + nwd: nwd, + ny: ny, + nd: nd, + ndow: ndow, + nt: nt, + sst: suti, + internalClock: clq, + reliability: reliability + } + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT19Result | Date): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + let temp: DPT19Result; + + if (value.constructor.name === 'Date') { + temp = new DPT19Result() + temp.dateTime = value as Date + temp.dayOfWeek = (value as Date).getDay() + } else { + temp = value as DPT19Result + } + + let dayOfWeek = temp.dayOfWeek + const f = !!temp.f ? 1 : 0 + const wd = !!temp.wd ? 1 : 0 + const nwd = !!temp.nwd ? 1 : 0 + const ny = !!temp.ny ? 1 : 0 + const nd = !!temp.nd ? 1 : 0 + const ndow = !!temp.ndow ? 1 : 0 + const nt = !!temp.nt ? 1 : 0 + const sst = !!temp.sst ? 1 : 0 + const clq = !!temp.internalClock ? 1 : 0 + const reliability = !!temp.reliability ? 1 : 0 + + // Convert day of week from JavaScript to knx (0 => 7, undefined => 0) + if (typeof dayOfWeek === 'undefined') { + dayOfWeek = 0 + } else if (dayOfWeek === 0) { + dayOfWeek = 7 + } + + const buffer = Buffer.alloc(8, 0) + buffer.writeUInt8(temp.dateTime.getFullYear() - 1900, 0) + buffer.writeUInt8(temp.dateTime.getMonth() + 1, 1) + buffer.writeUInt8(temp.dateTime.getDate(), 2) + buffer.writeUInt8((dayOfWeek << 5) | temp.dateTime.getHours(), 3) + buffer.writeUInt8(temp.dateTime.getMinutes(), 4) + buffer.writeUInt8(temp.dateTime.getSeconds(), 5) + buffer.writeUInt8((f << 7) | (wd << 6) | (nwd << 5) | (ny << 4) | (nd << 3) | (ndow << 2) | (nt << 1) | sst, 6) + buffer.writeUInt8(clq << 7 | reliability << 6, 7) + + return buffer + } + subtypes: { + // 19.001 + '001': { + name: 'DPT_DateTime', + desc: 'datetime', + }, + }; + +} diff --git a/src/DPT2.ts b/src/DPT2.ts new file mode 100644 index 0000000..a9dcdc9 --- /dev/null +++ b/src/DPT2.ts @@ -0,0 +1,140 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export interface DPT2Result { + priority: boolean; + data: boolean; +} + +export class DPT2 implements DPT { + id = '2'; + name = '1-bit value with priority'; + bufferLength = 1; + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): DPT2Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const value = buffer.readUInt8(0) + return { + priority: ((value & 0b00000010) >> 1) === 1, + data: (value & 0b00000001) === 1, + }; + + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT2Result): Buffer { + if (!value) throw new InvalidValueError('DPT2: cannot write null value'); + + return Buffer.from([((value.priority ? 1 : 0) << 1) + ((value.data ? 1 : 0) & 0b00000001)]); + } + + subtypes: { + // 2.001 switch control + '001': { + use: 'G', + name: 'DPT_Switch_Control', + desc: 'switch with priority', + enc: { 0: 'Off', 1: 'On' }, + }, + // 2.002 boolean control + '002': { + use: 'G', + name: 'DPT_Bool_Control', + desc: 'boolean with priority', + enc: { 0: 'false', 1: 'true' }, + }, + // 2.003 enable control + '003': { + use: 'FB', + name: 'DPT_Emable_Control', + desc: 'enable with priority', + enc: { 0: 'Disabled', 1: 'Enabled' }, + }, + + // 2.004 ramp control + '004': { + use: 'FB', + name: 'DPT_Ramp_Control', + desc: 'ramp with priority', + enc: { 0: 'No ramp', 1: 'Ramp' }, + }, + + // 2.005 alarm control + '005': { + use: 'FB', + name: 'DPT_Alarm_Control', + desc: 'alarm with priority', + enc: { 0: 'No alarm', 1: 'Alarm' }, + }, + + // 2.006 binary value control + '006': { + use: 'FB', + name: 'DPT_BinaryValue_Control', + desc: 'binary value with priority', + enc: { 0: 'Off', 1: 'On' }, + }, + + // 2.007 step control + '007': { + use: 'FB', + name: 'DPT_Step_Control', + desc: 'step with priority', + enc: { 0: 'Off', 1: 'On' }, + }, + + // 2.008 Direction1 control + '008': { + use: 'FB', + name: 'DPT_Direction1_Control', + desc: 'direction 1 with priority', + enc: { 0: 'Off', 1: 'On' }, + }, + + // 2.009 Direction2 control + '009': { + use: 'FB', + name: 'DPT_Direction2_Control', + desc: 'direction 2 with priority', + enc: { 0: 'Off', 1: 'On' }, + }, + + // 2.010 start control + '010': { + use: 'FB', + name: 'DPT_Start_Control', + desc: 'start with priority', + enc: { 0: 'No control', 1: 'No control', 2: 'Off', 3: 'On' }, + }, + + // 2.011 state control + '011': { + use: 'FB', + name: 'DPT_Switch_Control', + desc: 'switch', + enc: { 0: 'No control', 1: 'No control', 2: 'Off', 3: 'On' }, + }, + + // 2.012 invert control + '012': { + use: 'FB', + name: 'DPT_Switch_Control', + desc: 'switch', + enc: { 0: 'No control', 1: 'No control', 2: 'Off', 3: 'On' }, + }, + }; +} \ No newline at end of file diff --git a/src/DPT20.ts b/src/DPT20.ts new file mode 100644 index 0000000..cde5a68 --- /dev/null +++ b/src/DPT20.ts @@ -0,0 +1,94 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +/** + * Original at https://github.com/pitschr/knx-core/blob/main/src/main/java/li/pitschmann/knx/core/datapoint/DPT20.java + * + * Data Point Type 20 for '8-Bit Enumeration' (1 Octet) + * + *

+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ * Field Names | (Field 1)                     |
+ * Encoding    | N   N   N   N   N   N   N   N |
+ *             +---+---+---+---+---+---+---+---+
+ * Format:     8 bit (N8)
+ * 
+ */ +export class DPT20 implements DPT { + id = '20'; + name = '8-Bit Enumeration'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + return buffer.readUInt8(0); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + return Buffer.from([value & 0xff]) + } + + + subtypes: { + // 20.001 SCLO Mode + 1: { + name: 'SCLO_Mode', + desc: '', + unit: '', + scalar_range: { + 0: 'Autonomous', + 1: 'Slave', + 2: 'Master' + }, + range: undefined, + }, + + // 20.001 Building Mode + 2: { + name: 'Building_Mode', + desc: '', + unit: '', + scalar_range: { + 0: 'Building in use', + 1: 'Building not used', + 2: 'Building protection' + }, + range: undefined, + }, + + // 20.102 HVAC mode + 102: { + name: 'HVAC_Mode', + desc: '', + unit: '', + scalar_range: { + 0: 'Auto', + 1: 'Comfort', + 2: 'Standby', + 3: 'Economy', + 4: 'Building protection' + }, + range: undefined, + }, + }; + +} diff --git a/src/DPT21.ts b/src/DPT21.ts new file mode 100644 index 0000000..f609e20 --- /dev/null +++ b/src/DPT21.ts @@ -0,0 +1,101 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +/** + * Original at https://github.com/pitschr/knx-core/blob/main/src/main/java/li/pitschmann/knx/core/datapoint/DPT21.java + * * Data Point Type 21 for 8-Bits flagged messages + * + *
+ *             +-7-+-6-+-5-+-4-+-3-+-2-+-1-+-0-+
+ * Field Names | b   b   b   b   b   b   b   b |
+ * Encoding    | B   B   B   B   B   B   B   B |
+ *             +---+---+---+---+---+---+---+---+
+ * Format:     8 bits (B8)
+ * 
+ */ +export class DPT21 implements DPT { + id = ''; + name = ''; + bufferLength = 0; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): boolean[] { + if (buffer.length !== 2) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected 2.`); + + const result = [ + !!(buffer[0] & 0x80), + !!(buffer[0] & 0x40), + !!(buffer[0] & 0x20), + !!(buffer[0] & 0x10), + !!(buffer[0] & 0x08), + !!(buffer[0] & 0x04), + !!(buffer[0] & 0x02), + !!(buffer[0] & 0x01), + ] + return result; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: boolean[]): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError(`Invalid value [${value}]`) + + if (value.length != 8) + throw new InvalidValueError(`Value length should be 8. Got ${value.length}.`) + + const b7 = value[0] ? 1 : 0 + const b6 = value[0] ? 1 : 0 + const b5 = value[0] ? 1 : 0 + const b4 = value[0] ? 1 : 0 + const b3 = value[0] ? 1 : 0 + const b2 = value[0] ? 1 : 0 + const b1 = value[0] ? 1 : 0 + const b0 = value[0] ? 1 : 0 + + const buf = Buffer.from([ + b7 << 7 | + b6 << 6 | + b5 << 5 | + b4 << 4 | + b3 << 3 | + b2 << 2 | + b1 << 1 | + b0 + ]) + return buf; + } + + + subtypes: { + // 21.001 status - 5 bits + "001": { + "name": "DPT_StatusGen", + "desc": "General Status", + "unit": "", + "scalar_range": undefined, + "range": undefined + }, + // 21.002 control - 3 bits + "002": { + "name": "DPT_Device_Control", + "desc": "Device Control", + "unit": "", + "scalar_range": undefined, + "range": undefined + } + }; + +} diff --git a/src/DPT232.ts b/src/DPT232.ts new file mode 100644 index 0000000..9d0f770 --- /dev/null +++ b/src/DPT232.ts @@ -0,0 +1,66 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; +export interface DPT232Result { + red: number, + green: number, + blue: number +} +export class DPT232 implements DPT { + id = '232'; + name = 'RGB array'; + bufferLength = 3 + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the on/off value + */ + decoder(buffer: Buffer): DPT232Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const result: DPT232Result = { + red: buffer.readUInt8(0), + green: buffer.readUInt8(1), + blue: buffer.readUInt8(2), + } + + return result; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT232Result): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError('Cannot write null value'); + + if (value.red < 0 || value.red > 255) + throw new InvalidValueError(`Red component out of range ${value.red}`); + if (value.blue < 0 || value.blue > 255) + throw new InvalidValueError(`Blue component out of range ${value.blue}`); + if (value.green < 0 || value.green > 255) + throw new InvalidValueError(`Green component out of range ${value.green}`); + + let buffer = Buffer.alloc(this.bufferLength) + buffer.writeUInt8(value.red, 0) + buffer.writeUInt8(value.green, 1) + buffer.writeUInt8(value.blue, 2) + + return buffer + } + + subtypes: { + '600': { + name: 'RGB', + desc: 'RGB color triplet', + unit: '', + }, + }; +} diff --git a/src/DPT237.ts b/src/DPT237.ts new file mode 100644 index 0000000..d0568a2 --- /dev/null +++ b/src/DPT237.ts @@ -0,0 +1,39 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT237 implements DPT { + id = ''; + name = ''; + bufferLength = 0; + + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT8. Expected ${this.bufferLength}.`); + + return value; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + return buf; + } + + + subtypes: { + }; + +} diff --git a/src/DPT238.ts b/src/DPT238.ts new file mode 100644 index 0000000..1947d20 --- /dev/null +++ b/src/DPT238.ts @@ -0,0 +1,74 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT238 implements DPT { + id = '238'; + name = '8-bit unsigned value'; + bufferLength = 1 + + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + return buffer.readUInt8(0) + } + + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('DPT5: cannot write null value'); + + let buf = Buffer.alloc(this.bufferLength); + buf.writeUInt8(value, 0) + return buf; + + } + + subtypes: { + // 20.102 HVAC mode + 102: { + name: 'HVAC_Mode', + desc: '', + unit: '', + //scalar_range: [,], + //range: [,], + }, + + // 5.003 angle (degrees 0=0, ff=360) + '003': { + name: 'DPT_Angle', + desc: 'angle degrees', + unit: '°', + scalar_range: [0, 360], + }, + + // 5.004 percentage (0..255%) + '004': { + name: 'DPT_Percent_U8', + desc: 'percent', + unit: '%', + }, + + // 5.005 ratio (0..255) + '005': { + name: 'DPT_DecimalFactor', + desc: 'ratio', + unit: 'ratio', + }, + + // 5.006 tariff (0..255) + '006': { + name: 'DPT_Tariff', + desc: 'tariff', + unit: 'tariff', + }, + + // 5.010 counter pulses (0..255) + '010': { + name: 'DPT_Value_1_Ucount', + desc: 'counter pulses', + unit: 'pulses', + }, + } +} \ No newline at end of file diff --git a/src/DPT3.ts b/src/DPT3.ts new file mode 100644 index 0000000..ac1ffc9 --- /dev/null +++ b/src/DPT3.ts @@ -0,0 +1,64 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export interface DPT3Result { + decr_incr: number; + data: number; +} + +export class DPT3 implements DPT { + id = '3'; + name = '4-bit relative dimming control'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): DPT3Result { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const value = buffer.readUInt8(0) + return { + decr_incr: (value & 0b00001000) >> 3, + data: value & 0b00000111, + }; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: DPT3Result): Buffer { + if (!value) + throw new InvalidValueError('DPT3: cannot write null value'); + + if (value.decr_incr > 1) + throw new InvalidValueError(`DPT3: Invalid increment/decrement value: ${value.decr_incr}. Expected 1 or 0.`); + + return Buffer.from([(value.decr_incr << 3) + (value.data & 0b00000111)]); + + } + + subtypes: { + // 3.007 dimming control + '007': { + name: 'DPT_Control_Dimming', + desc: 'dimming control', + }, + + // 3.008 blind control + '008': { + name: 'DPT_Control_Blinds', + desc: 'blinds control', + }, + }; + +} diff --git a/src/DPT4.ts b/src/DPT4.ts new file mode 100644 index 0000000..c4f0cb1 --- /dev/null +++ b/src/DPT4.ts @@ -0,0 +1,57 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT4 implements DPT { + id = '4'; + name = '8-bit character'; + bufferLength = 1; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): string { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + return String.fromCharCode(buffer[0]); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: string): Buffer { + if (!value) + throw new InvalidValueError('DPT4: cannot write null value'); + + const apdu_data = value.charCodeAt(0); + if (apdu_data > 255) + throw new InvalidValueError('DPT4: must supply an ASCII character'); + + return Buffer.from([apdu_data]); + } + + subtypes: { + // 4.001 character (ASCII) + '001': { + name: 'DPT_Char_ASCII', + desc: 'ASCII character (0-127)', + range: [0, 127], + use: 'G', + }, + // 4.002 character (ISO-8859-1) + '002': { + name: 'DPT_Char_8859_1', + desc: 'ISO-8859-1 character (0..255)', + use: 'G', + }, + }; + +} diff --git a/src/DPT5.ts b/src/DPT5.ts new file mode 100644 index 0000000..2d42fe5 --- /dev/null +++ b/src/DPT5.ts @@ -0,0 +1,73 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT5 implements DPT { + id = '5'; + name = '8-bit unsigned value'; + bufferLength = 1; + + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + return buffer.readUInt8(0) + } + + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('DPT5: cannot write null value'); + + let buf = Buffer.alloc(1); + buf.writeUInt8(value, 0) + return buf; + + } + + subtypes: { + // 5.001 percentage (0=0..ff=100%) + "001": { + "name": "DPT_Scaling", + "desc": "percent", + "unit": "%", + "scalar_range": [0, 100] + }, + + // 5.003 angle (degrees 0=0, ff=360) + "003": { + "name": "DPT_Angle", + "desc": "angle degrees", + "unit": "°", + "scalar_range": [0, 360] + }, + + // 5.004 percentage (0..255%) + "004": { + "name": "DPT_Percent_U8", + "desc": "percent", + "unit": "%", + }, + + // 5.005 ratio (0..255) + "005": { + "name": "DPT_DecimalFactor", + "desc": "ratio", + "unit": "ratio", + }, + + // 5.006 tariff (0..255) + "006": { + "name": "DPT_Tariff", + "desc": "tariff", + "unit": "tariff", + }, + + // 5.010 counter pulses (0..255) + "010": { + "name": "DPT_Value_1_Ucount", + "desc": "counter pulses", + "unit": "pulses", + }, + } +} \ No newline at end of file diff --git a/src/DPT6.ts b/src/DPT6.ts new file mode 100644 index 0000000..4fcbfac --- /dev/null +++ b/src/DPT6.ts @@ -0,0 +1,58 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT6 implements DPT { + id = '6'; + name = "8-bit signed value"; + bufferLength = 1; + range = [-128, 127]; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const value = buffer.readInt8(0) + + return value; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('DPT6: cannot write null value'); + + if (value < this.range[0] || value > this.range[1]) + throw new InvalidValueError(`DPT6: Value ${value} out of range [${this.range[0]}, ${this.range[1]}].`); + + let buf = Buffer.alloc(this.bufferLength); + buf.writeInt8(value, 0) + return buf; + } + + subtypes: { + // 6.001 percentage (-128%..127%) + "001": { + "name": "DPT_Switch", "desc": "percent", + "unit": "%", + }, + + // 6.002 counter pulses (-128..127) + "010": { + "name": "DPT_Bool", "desc": "counter pulses", + "unit": "pulses" + }, + }; +} diff --git a/src/DPT7.ts b/src/DPT7.ts new file mode 100644 index 0000000..85b7587 --- /dev/null +++ b/src/DPT7.ts @@ -0,0 +1,134 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT7 implements DPT { + id = '7'; + name = '16-bit unsigned value'; + bufferLength = 2 + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const value = buffer.readUInt16BE(0) + + return value; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('DPT7: cannot write null value'); + + if (value < 0) + throw new InvalidValueError(`DPT7: Cannot write negative value ${value}`); + + let buf = Buffer.alloc(this.bufferLength); + buf.writeUInt16BE(value, 0) + return buf; + } + + subtypes: { + // 7.001 pulses + "001": { + "use": "G", + "name": "DPT_Value_2_Ucount", + "desc": "pulses", + "unit": "pulses" + }, + + // 7.002 time(ms) + "002": { + "use": "G", + "name": "DPT_TimePeriodMsec", + "desc": "time (ms)", + "unit": "milliseconds" + }, + + // 7.003 time (10ms) + "003": { + "use": "G", + "name": "DPT_TimePeriod10Msec", + "desc": "time (10ms)", + "unit": "centiseconds" + }, + + // 7.004 time (100ms) + "004": { + "use": "G", + "name": "DPT_TimePeriod100Msec", + "desc": "time (100ms)", + "unit": "deciseconds" + }, + + // 7.005 time (sec) + "005": { + "use": "G", + "name": "DPT_TimePeriodSec", + "desc": "time (s)", + "unit": "seconds" + }, + + // 7.006 time (min) + "006": { + "use": "G", + "name": "DPT_TimePeriodMin", + "desc": "time (min)", + "unit": "minutes" + }, + + // 7.007 time (hour) + "007": { + "use": "G", + "name": "DPT_TimePeriodHrs", + "desc": "time (hrs)", + "unit": "hours" + }, + + // 7.010 DPT_PropDataType + // not to be used in runtime communications! + "010": { + "use": "FB", + "name": "DPT_PropDataType", + "desc": "Identifier Interface Object Property data type " + }, + + // 7.011 + "011": { + "use": "FB SAB", + "name": "DPT_Length_mm", + "desc": "Length in mm", + "unit": "mm" + }, + + // 7.012 + "012": { + "use": "FB", + "name": "DPT_UEICurrentmA", + "desc": "bus power supply current (mA)", + "unit": "mA" + }, + + // 7.013 + "013": { + "use": "FB", + "name": "DPT_Brightness", + "desc": "interior brightness", + "unit": "lux" + } + }; + +} diff --git a/src/DPT8.ts b/src/DPT8.ts new file mode 100644 index 0000000..5345aab --- /dev/null +++ b/src/DPT8.ts @@ -0,0 +1,111 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +export class DPT8 implements DPT { + id = '8'; + name = '16-bit signed value'; + bufferLength = 2; + "range" = [-32768, 32767]; + + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the DPT value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const value = buffer.readInt16BE(0) + + return value; + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (!value) + throw new InvalidValueError('DPT8: cannot write null value'); + + if (value < this.range[0] || value > this.range[1]) + throw new InvalidValueError(`DPT6: Value ${value} out of range [${this.range[0]}, ${this.range[1]}].`); + + let buf = Buffer.alloc(this.bufferLength); + buf.writeInt16BE(value, 0) + return buf; + } + + + subtypes: { + // 8.001 pulses difference + "001": { + "name": "DPT_Value_2_Count", + "desc": "pulses", + "unit": "pulses" + }, + + // 8.002 time lag (ms) + "002": { + "name": "DPT_DeltaTimeMsec", + "desc": "time lag(ms)", + "unit": "milliseconds" + }, + + // 8.003 time lag (10ms) + "003": { + "name": "DPT_DeltaTime10Msec", + "desc": "time lag(10ms)", + "unit": "centiseconds" + }, + + // 8.004 time lag (100ms) + "004": { + "name": "DPT_DeltaTime100Msec", + "desc": "time lag(100ms)", + "unit": "deciseconds" + }, + + // 8.005 time lag (sec) + "005": { + "name": "DPT_DeltaTimeSec", + "desc": "time lag(s)", + "unit": "seconds" + }, + + // 8.006 time lag (min) + "006": { + "name": "DPT_DeltaTimeMin", + "desc": "time lag(min)", + "unit": "minutes" + }, + + // 8.007 time lag (hour) + "007": { + "name": "DPT_DeltaTimeHrs", + "desc": "time lag(hrs)", + "unit": "hours" + }, + + // 8.010 percentage difference (%) + "010": { + "name": "DPT_Percent_V16", + "desc": "percentage difference", + "unit": "%" + }, + + // 8.011 rotation angle (deg) + "011": { + "name": "DPT_RotationAngle", + "desc": "angle(degrees)", + "unit": "°" + }, + }; + +} diff --git a/src/DPT9.ts b/src/DPT9.ts new file mode 100644 index 0000000..95a820f --- /dev/null +++ b/src/DPT9.ts @@ -0,0 +1,232 @@ +'use strict'; +import { BufferLengthError } from './errors/BufferLengthError'; +import { InvalidValueError } from './errors/InvalidValueError'; +import { DPT } from './definitions'; + +function ldexp(mantissa: number, exponent: number): number { + return exponent > 1023 // avoid multiplying by infinity + ? mantissa * Math.pow(2, 1023) * Math.pow(2, exponent - 1023) + : exponent < -1074 // avoid multiplying by zero + ? mantissa * Math.pow(2, -1074) * Math.pow(2, exponent + 1074) + : mantissa * Math.pow(2, exponent); +} +function frexp(value: number): number[] { + if (value === 0) return [0, 0]; + const data = new DataView(new ArrayBuffer(8)); + data.setFloat64(0, value); + let bits = (data.getUint32(0) >>> 20) & 0x7ff; + if (bits === 0) { + data.setFloat64(0, value * Math.pow(2, 64)); + bits = ((data.getUint32(0) >>> 20) & 0x7ff) - 64; + } + const exponent = bits - 1022; + const mantissa = ldexp(value, -exponent); + return [mantissa, exponent]; +}; + +export class DPT9 implements DPT { + id = '9'; + name = '16-bit floating point value'; + bufferLength = 2; + /** + * Decode a buffer + * + * @param buffer the buffer + * @returns the on/off value + */ + decoder(buffer: Buffer): number { + if (buffer.length !== this.bufferLength) + throw new BufferLengthError(`Invalid buffer length ${buffer.length}/${buffer} for DPT1. Expected ${this.bufferLength}.`); + + const sign = buffer[0] >> 7; + const exponent = (buffer[0] & 0b01111000) >> 3; + let mantissa = 256 * (buffer[0] & 0b00000111) + buffer[1]; + if (sign) mantissa = ~(mantissa ^ 2047); + + return parseFloat(ldexp(0.01 * mantissa, exponent).toPrecision(15)); + }; + + /** + * Encode a buffer + * + * @param value the value to be converted to buffer + * @returns the buffer + */ + encoder(value: number): Buffer { + if (value === undefined || value === null) + throw new InvalidValueError('DPT9: cannot write null value'); + + if (!isFinite(value)) + throw new InvalidValueError('DPT9: cannot write non-numeric or undefined value'); + + const arr = frexp(value); + const [mantissa, exponent] = arr; + // find the minimum exponent that will upsize the normalized mantissa (0,5 to 1 range) + // in order to fit in 11 bits ([-2048, 2047]) + let max_mantissa = 0; + let e: number + for (e = exponent; e >= -15; e--) { + max_mantissa = ldexp(100 * mantissa, e); + if (max_mantissa > -2048 && max_mantissa < 2047) break; + } + const sign = mantissa < 0 ? 1 : 0; + const mant = mantissa < 0 ? ~(max_mantissa ^ 2047) : max_mantissa; + const exp = exponent - e; + // yucks + return Buffer.from([(sign << 7) + (exp << 3) + (mant >> 8), mant % 256]); + } + + subtypes: { + // 9.001 temperature (oC) + '001': { + name: 'DPT_Value_Temp', + desc: 'temperature', + unit: '°C', + range: [-273, 670760], + }, + + // 9.002 temperature difference (oC) + '002': { + name: 'DPT_Value_Tempd', + desc: 'temperature difference', + unit: '°C', + range: [-670760, 670760], + }, + + // 9.003 kelvin/hour (K/h) + '003': { + name: 'DPT_Value_Tempa', + desc: 'kelvin/hour', + unit: '°K/h', + range: [-670760, 670760], + }, + + // 9.004 lux (Lux) + '004': { + name: 'DPT_Value_Lux', + desc: 'lux', + unit: 'lux', + range: [0, 670760], + }, + + // 9.005 speed (m/s) + '005': { + name: 'DPT_Value_Wsp', + desc: 'wind speed', + unit: 'm/s', + range: [0, 670760], + }, + + // 9.006 pressure (Pa) + '006': { + name: 'DPT_Value_Pres', + desc: 'pressure', + unit: 'Pa', + range: [0, 670760], + }, + + // 9.007 humidity (%) + '007': { + name: 'DPT_Value_Humidity', + desc: 'humidity', + unit: '%', + range: [0, 670760], + }, + + // 9.008 parts/million (ppm) + '008': { + name: 'DPT_Value_AirQuality', + desc: 'air quality', + unit: 'ppm', + range: [0, 670760], + }, + + // 9.010 time (s) + '010': { + name: 'DPT_Value_Time1', + desc: 'time(sec)', + unit: 's', + range: [-670760, 670760], + }, + + // 9.011 time (ms) + '011': { + name: 'DPT_Value_Time2', + desc: 'time(msec)', + unit: 'ms', + range: [-670760, 670760], + }, + + // 9.020 voltage (mV) + '020': { + name: 'DPT_Value_Volt', + desc: 'voltage', + unit: 'mV', + range: [-670760, 670760], + }, + + // 9.021 current (mA) + '021': { + name: 'DPT_Value_Curr', + desc: 'current', + unit: 'mA', + range: [-670760, 670760], + }, + + // 9.022 power density (W/m2) + '022': { + name: 'DPT_PowerDensity', + desc: 'power density', + unit: 'W/m²', + range: [-670760, 670760], + }, + + // 9.023 kelvin/percent (K/%) + '023': { + name: 'DPT_KelvinPerPercent', + desc: 'Kelvin / %', + unit: 'K/%', + range: [-670760, 670760], + }, + + // 9.024 power (kW) + '024': { + name: 'DPT_Power', + desc: 'power (kW)', + unit: 'kW', + range: [-670760, 670760], + }, + + // 9.025 volume flow (l/h) + '025': { + name: 'DPT_Value_Volume_Flow', + desc: 'volume flow', + unit: 'l/h', + range: [-670760, 670760], + }, + + // 9.026 rain amount (l/m2) + '026': { + name: 'DPT_Rain_Amount', + desc: 'rain amount', + unit: 'l/m²', + range: [-670760, 670760], + }, + + // 9.027 temperature (Fahrenheit) + '027': { + name: 'DPT_Value_Temp_F', + desc: 'temperature (F)', + unit: '°F', + range: [-459.6, 670760], + }, + + // 9.028 wind speed (km/h) + '028': { + name: 'DPT_Value_Wsp_kmh', + desc: 'wind speed (km/h)', + unit: 'km/h', + range: [0, 670760], + }, + }; +} diff --git a/src/DataPointType.ts b/src/DataPointType.ts new file mode 100644 index 0000000..cc380fc --- /dev/null +++ b/src/DataPointType.ts @@ -0,0 +1,113 @@ +'use strict'; + +import { Encoder, Decoder, DPT } from './definitions'; + +import { DPT1 } from './DPT1'; +import { DPT2 } from './DPT2'; +import { DPT3 } from './DPT3'; +import { DPT4 } from './DPT4'; +import { DPT5 } from './DPT5'; +import { DPT6 } from './DPT6'; +import { DPT7 } from './DPT7'; +import { DPT8 } from './DPT8'; +import { DPT9 } from './DPT9'; +import { DPT10 } from './DPT10'; +import { DPT11 } from './DPT11'; +import { DPT12 } from './DPT12'; +import { DPT13 } from './DPT13'; +import { DPT14 } from './DPT14'; +import { DPT15 } from './DPT15'; +import { DPT16 } from './DPT16'; +import { DPT17 } from './DPT17'; +import { DPT18 } from './DPT18'; +import { DPT19 } from './DPT19'; +import { DPT20 } from './DPT20'; +import { DPT21 } from './DPT21'; +//import { DPT22 } from './DPT22'; +import { DPT232 } from './DPT232'; +import { DPT237 } from './DPT237'; +import { DPT238 } from './DPT238'; + +export class DataPointType { + + get type(): string { + return this._type; + } + + get subtype(): string { + return this._subtype; + } + + /** + * @property {DPTYPE} DPT1 + * @property {DPTYPE} DPT2 + * @property {DPTYPE} DPT3 + * @property {DPTYPE} DPT4 + * @property {DPTYPE} DPT5 + * @property {DPTYPE} DPT6 + * @property {DPTYPE} DPT7 + * @property {DPTYPE} DPT8 + * @property {DPTYPE} DPT9 + * @property {DPTYPE} DPT10 + * @property {DPTYPE} DPT11 + * @property {DPTYPE} DPT12 + * @property {DPTYPE} DPT13 + * @property {DPTYPE} DPT14 + * @property {DPTYPE} DPT15 + * @property {DPTYPE} DPT16 + * @property {DPTYPE} DPT17 + * @property {DPTYPE} DPT18 + * @property {DPTYPE} DPT19 + * @property {DPTYPE} DPT20 + */ + static get TYPES(): { [index: string]: DPT | null } { + return { + DPT1: new DPT1(), + DPT2: new DPT2(), + DPT3: new DPT3(), + DPT4: new DPT4(), + DPT5: new DPT5(), + DPT6: new DPT6(), + DPT7: new DPT7(), + DPT8: new DPT8(), + DPT9: new DPT9(), + DPT10: new DPT10(), + DPT11: new DPT11(), + DPT12: new DPT12(), + DPT13: new DPT13(), + DPT14: new DPT14(), + DPT15: new DPT15(), + DPT16: new DPT16(), + DPT17: new DPT17(), + DPT18: new DPT18(), + DPT19: new DPT19(), + DPT20: new DPT20(), + DPT21: new DPT21(), + //DPT22: new DPT22(), + + DPT232: new DPT232(), + DPT237: new DPT237(), + DPT238: new DPT238() + }; + } + + constructor(private _type: string, private _subtype: string, private _encoder: Encoder, private _decoder: Decoder) { + } + + static validType(text: string): boolean { + const m = text.toUpperCase().match(/(?:DPT)?(\d+)(\.(\d+))?/); + return m != null; + } + + toString(): string { + return `${this.type}.${this.subtype}`; + } + + decode(buffer: Buffer): string | number { + return this._decoder(buffer); + } + + encode(value: string | number): Buffer { + return this._encoder(value); + } +} \ No newline at end of file diff --git a/src/definitions.ts b/src/definitions.ts new file mode 100644 index 0000000..085a04e --- /dev/null +++ b/src/definitions.ts @@ -0,0 +1,35 @@ +/** + * Definitions for the KNX library + */ + +export type Encoder = (value: any) => Buffer; +export type Decoder = (buffer: Buffer) => any; + +/** + * @property {string} use + * @property {string} name + * @property {string} desc + * @property {any} enc + */ +export interface DPTSubType { + use?: string; + name: string; + desc: string; + enc?: any; + + unit?: string; + range?: number[]; +} + +/** + * DPT generic interface + */ +export interface DPT { + id: string; + name: string; + bufferLength: number; + subtypes: { [index: string]: DPTSubType }; + + decoder: Decoder; + encoder: Encoder; +} \ No newline at end of file diff --git a/src/errors/BufferLengthError.ts b/src/errors/BufferLengthError.ts new file mode 100644 index 0000000..eb19f8b --- /dev/null +++ b/src/errors/BufferLengthError.ts @@ -0,0 +1,2 @@ +export class BufferLengthError extends Error { +} diff --git a/src/errors/InvalidValueError.ts b/src/errors/InvalidValueError.ts new file mode 100644 index 0000000..73c3f98 --- /dev/null +++ b/src/errors/InvalidValueError.ts @@ -0,0 +1,2 @@ +export class InvalidValueError extends Error { +} diff --git a/tests/DPT1.test.ts b/tests/DPT1.test.ts new file mode 100644 index 0000000..8d53d71 --- /dev/null +++ b/tests/DPT1.test.ts @@ -0,0 +1,67 @@ +import { expect } from "chai"; + +import { DPT1 } from "../src/DPT1" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferTrue = Buffer.from([1]) +let bufferFalse = Buffer.from([0]) +let bufferInvalid = Buffer.from([5]) +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + + +describe("Test DPT1", (): void => { + + let dpt = new DPT1(); + + it("Decode true", async function () { + const value = dpt.decoder(bufferTrue) + expect(value).is.equal(1); + }); + + it("Decode false", async function () { + const value = dpt.decoder(bufferFalse) + expect(value).is.equal(0); + }); + + it("Decode invalid value buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferInvalid) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("encode true", async function () { + const value = dpt.encoder(1) + expect(compareBuffers(value, bufferTrue)).is.true; + }); + + it("encode false", async function () { + const value = dpt.encoder(0) + expect(compareBuffers(value, bufferFalse)).is.true; + }); + + it("encode invalid", async function () { + var testFunction = function () { + const value = dpt.encoder(5) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT10.test.ts b/tests/DPT10.test.ts new file mode 100644 index 0000000..b6048f4 --- /dev/null +++ b/tests/DPT10.test.ts @@ -0,0 +1,106 @@ +import { expect } from "chai"; + +import { DPT10 } from "../src/DPT10" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let date = new Date(Date.parse('04 Mar 2022 00:12:00 GMT')) +let dayOfWeek = date.getDay() +let hour = date.getHours() +let minute = date.getMinutes() +let second = date.getSeconds() +let bufferValue = Buffer.from([(dayOfWeek << 5) + hour, minute, second]) + +let today = new Date() +today.setDate(today.getDate() + dayOfWeek - today.getDay()) +today.setHours(hour) +today.setMinutes(minute) +today.setSeconds(second) +today.setMilliseconds(0) + + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([0xff, 0xff, 0x63, 0xc0]) + + +describe("Test DPT10", (): void => { + + let dpt = new DPT10(); + + it("Decode buffer acceptable", async function () { + expect(dpt.decoder(bufferValue).getTime()).is.equal(today.getTime()); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode invalid buffers", async function () { + let bufferErrorHour = Buffer.from([(dayOfWeek << 5) + 24, minute, second]) + let bufferErrorMinute = Buffer.from([(dayOfWeek << 5) + hour, 70, second]) + let bufferErrorSecond = Buffer.from([(dayOfWeek << 5) + hour, minute, 70]) + + var test_bufferErrorHour = function () { + const value = dpt.decoder(bufferErrorHour) + } + var test_bufferErrorMinute = function () { + const value = dpt.decoder(bufferErrorMinute) + } + var test_bufferErrorSecond = function () { + const value = dpt.decoder(bufferErrorSecond) + } + + expect(test_bufferErrorHour).to.throw(InvalidValueError); + expect(test_bufferErrorMinute).to.throw(InvalidValueError); + expect(test_bufferErrorSecond).to.throw(InvalidValueError); + }); + + + /* Encoder tests */ + it("encode valid date", async function () { + expect(compareBuffers(dpt.encoder(date), bufferValue)).is.true; + }); + + it("encode valid number", async function () { + expect(compareBuffers(dpt.encoder(date.getTime()), bufferValue)).is.true; + }); + + it("encode valid string", async function () { + + let todayTest = new Date() + + todayTest.setHours(hour) + todayTest.setMinutes(minute) + todayTest.setSeconds(second) + todayTest.setMilliseconds(0) + let todayBuffer = dpt.encoder(todayTest) + + expect(compareBuffers(dpt.encoder(`${hour}:${minute}:${second}`), todayBuffer)).is.true; + }); + + it("encode invalid string", async function () { + var testFunction = function () { + const value = dpt.encoder("10-10-10") + } + expect(testFunction).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT11.test.ts b/tests/DPT11.test.ts new file mode 100644 index 0000000..887cb05 --- /dev/null +++ b/tests/DPT11.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT11 } from "../src/DPT11" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT11", (): void => { + + let dpt = new DPT11(); + +}); \ No newline at end of file diff --git a/tests/DPT12.test.ts b/tests/DPT12.test.ts new file mode 100644 index 0000000..6429ca0 --- /dev/null +++ b/tests/DPT12.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT12 } from "../src/DPT12" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT12", (): void => { + + let dpt = new DPT12(); + +}); \ No newline at end of file diff --git a/tests/DPT13.test.ts b/tests/DPT13.test.ts new file mode 100644 index 0000000..677b2f0 --- /dev/null +++ b/tests/DPT13.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT13 } from "../src/DPT13" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT13", (): void => { + + let dpt = new DPT13(); + +}); \ No newline at end of file diff --git a/tests/DPT14.test.ts b/tests/DPT14.test.ts new file mode 100644 index 0000000..59c7e9a --- /dev/null +++ b/tests/DPT14.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT14 } from "../src/DPT14" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT14", (): void => { + + let dpt = new DPT14(); + +}); \ No newline at end of file diff --git a/tests/DPT15.test.ts b/tests/DPT15.test.ts new file mode 100644 index 0000000..f8a5322 --- /dev/null +++ b/tests/DPT15.test.ts @@ -0,0 +1,103 @@ +import { expect } from "chai"; + +import { DPT15, DPT15Result } from "../src/DPT15" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT15", (): void => { + + let dpt = new DPT15(); + + let value: DPT15Result = { + U: 0x03, + V: 0x09, + W: 0x04, + X: 0x08, + Y: 0x00, + Z: 0x02, + E: 0x01, + P: 0x00, + D: 0x01, + C: 0x00, + N: 0x05 + } + + let bufferValid = Buffer.from([0x39, 0x48, 0x02, 0xa5]) + let bufferInvalid = Buffer.from([0x39, 0xc8, 0xa2, 0xa5]) + + let bufferEmpty = Buffer.from([]) + let bufferBiggerSize = Buffer.from([0xff, 0xff, 0x63, 0xc0, 0x00]) + + it("Decode buffer acceptable", async function () { + const decoded = dpt.decoder(bufferValid) + expect(decoded.U).is.equal(value.U); + expect(decoded.V).is.equal(value.V); + expect(decoded.W).is.equal(value.W); + expect(decoded.X).is.equal(value.X); + expect(decoded.Y).is.equal(value.Y); + expect(decoded.Z).is.equal(value.Z); + expect(decoded.E).is.equal(value.E); + expect(decoded.P).is.equal(value.P); + expect(decoded.D).is.equal(value.D); + expect(decoded.C).is.equal(value.C); + expect(decoded.N).is.equal(value.N); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode invalid buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferInvalid) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + /* Encoder */ + + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(value), bufferValid)).is.true; + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + + it("encode invalid", async function () { + var testFunction = function () { + let invalidValue: DPT15Result = { + U: 0x03, + V: 0x0a, // invalid value as per spec + W: 0x04, + X: 0x08, + Y: 0x00, + Z: 0x02, + E: 0x01, + P: 0x00, + D: 0x01, + C: 0x00, + N: 0x05 + } + const result = dpt.encoder(invalidValue) + } + expect(testFunction).to.throw(InvalidValueError); + }); + +}); \ No newline at end of file diff --git a/tests/DPT16.test.ts b/tests/DPT16.test.ts new file mode 100644 index 0000000..2c6b735 --- /dev/null +++ b/tests/DPT16.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT16 } from "../src/DPT16" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT16", (): void => { + + let dpt = new DPT16(); + +}); \ No newline at end of file diff --git a/tests/DPT17.test.ts b/tests/DPT17.test.ts new file mode 100644 index 0000000..68066c3 --- /dev/null +++ b/tests/DPT17.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT17 } from "../src/DPT17" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT17", (): void => { + + let dpt = new DPT17(); + +}); \ No newline at end of file diff --git a/tests/DPT18.test.ts b/tests/DPT18.test.ts new file mode 100644 index 0000000..126e86b --- /dev/null +++ b/tests/DPT18.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT18 } from "../src/DPT18" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT18", (): void => { + + let dpt = new DPT18(); + +}); \ No newline at end of file diff --git a/tests/DPT19.test.ts b/tests/DPT19.test.ts new file mode 100644 index 0000000..1756a5d --- /dev/null +++ b/tests/DPT19.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT19 } from "../src/DPT19" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT19", (): void => { + + let dpt = new DPT19(); + +}); \ No newline at end of file diff --git a/tests/DPT2.test.ts b/tests/DPT2.test.ts new file mode 100644 index 0000000..ea0fa91 --- /dev/null +++ b/tests/DPT2.test.ts @@ -0,0 +1,74 @@ +import { expect } from "chai"; + +import { DPT2 } from "../src/DPT2" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferZeroZero = Buffer.from([0]) +let bufferZeroOne = Buffer.from([1]) +let bufferOneZero = Buffer.from([2]) +let bufferOneOne = Buffer.from([3]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + + +describe("Test DPT2", (): void => { + + let dpt = new DPT2(); + + it("Decode buffer00", async function () { + const value = dpt.decoder(bufferZeroZero) + expect(value.data).is.false; + expect(value.priority).is.false; + }); + + it("Decode buffer01", async function () { + const value = dpt.decoder(bufferZeroOne) + expect(value.data).is.true; + expect(value.priority).is.false; + }); + + it("Decode buffer10", async function () { + const value = dpt.decoder(bufferOneZero) + expect(value.data).is.false; + expect(value.priority).is.true; + }); + + it("Decode buffer11", async function () { + const value = dpt.decoder(bufferOneOne) + expect(value.data).is.true; + expect(value.priority).is.true; + }); + + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("encode true", async function () { + expect(compareBuffers(dpt.encoder({ data: false, priority: false }), bufferZeroZero)).is.true; + expect(compareBuffers(dpt.encoder({ data: false, priority: true }), bufferOneZero)).is.true; + expect(compareBuffers(dpt.encoder({ data: true, priority: false }), bufferZeroOne)).is.true; + expect(compareBuffers(dpt.encoder({ data: true, priority: true }), bufferOneOne)).is.true; + }); + + it("encode invalid", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT20.test.ts b/tests/DPT20.test.ts new file mode 100644 index 0000000..4f9a811 --- /dev/null +++ b/tests/DPT20.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT20 } from "../src/DPT20" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT20", (): void => { + + let dpt = new DPT20(); + +}); \ No newline at end of file diff --git a/tests/DPT21.test.ts b/tests/DPT21.test.ts new file mode 100644 index 0000000..18f3427 --- /dev/null +++ b/tests/DPT21.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT21 } from "../src/DPT21" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT21", (): void => { + + let dpt = new DPT21(); + +}); \ No newline at end of file diff --git a/tests/DPT232.test.ts b/tests/DPT232.test.ts new file mode 100644 index 0000000..f7a993c --- /dev/null +++ b/tests/DPT232.test.ts @@ -0,0 +1,85 @@ +import { expect } from "chai"; + +import { DPT232, DPT232Result } from "../src/DPT232" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let value: DPT232Result = { red: 127, green: 200, blue: 20 } + +let buffer = Buffer.from([127, 200, 20]) + + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([0xff, 0xff, 0x63, 0xc0]) + +describe("Test DPT232", (): void => { + + let dpt = new DPT232(); + + it("Decode buffer acceptable", async function () { + const v = dpt.decoder(buffer) + expect(v.red).is.equal(value.red); + expect(v.green).is.equal(value.green); + expect(v.blue).is.equal(value.blue); + }); + + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(value), buffer)).is.true; + }); + + it("encode invalid", async function () { + var testFunctionRedPlus = function () { + const value = dpt.encoder({ red: 300, green: 0, blue: 0 }) + } + var testFunctionRedMinus = function () { + const value = dpt.encoder({ red: -2, green: 0, blue: 0 }) + } + + var testFunctionGreenPlus = function () { + const value = dpt.encoder({ green: 300, red: 0, blue: 0 }) + } + var testFunctionGreenMinus = function () { + const value = dpt.encoder({ green: -2, red: 0, blue: 0 }) + } + + var testFunctionBluePlus = function () { + const value = dpt.encoder({ blue: 300, green: 0, red: 0 }) + } + var testFunctionBlueMinus = function () { + const value = dpt.encoder({ blue: -2, green: 0, red: 0 }) + } + + + expect(testFunctionRedPlus).to.throw(InvalidValueError); + expect(testFunctionRedMinus).to.throw(InvalidValueError); + expect(testFunctionGreenPlus).to.throw(InvalidValueError); + expect(testFunctionGreenMinus).to.throw(InvalidValueError); + expect(testFunctionBluePlus).to.throw(InvalidValueError); + expect(testFunctionBlueMinus).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT237.test.ts b/tests/DPT237.test.ts new file mode 100644 index 0000000..e042fde --- /dev/null +++ b/tests/DPT237.test.ts @@ -0,0 +1,13 @@ +import { expect } from "chai"; + +import { DPT237 } from "../src/DPT237" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +describe("Test DPT237", (): void => { + + let dpt = new DPT237(); + +}); \ No newline at end of file diff --git a/tests/DPT238.test.ts b/tests/DPT238.test.ts new file mode 100644 index 0000000..886f491 --- /dev/null +++ b/tests/DPT238.test.ts @@ -0,0 +1,55 @@ +import { expect } from "chai"; + +import { DPT238 } from "../src/DPT238" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferA = Buffer.from([65]) +let bufferMax = Buffer.from([254]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + +describe("Test DPT238", (): void => { + + let dpt = new DPT238(); + + it("Decode buffer common", async function () { + const value = dpt.decoder(bufferA) + expect(value).is.equal(65); + }); + + it("Decode buffer max", async function () { + const value = dpt.decoder(bufferMax) + expect(value).is.equal(254); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(65), bufferA)).is.true; + expect(compareBuffers(dpt.encoder(254), bufferMax)).is.true; + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); diff --git a/tests/DPT3.test.ts b/tests/DPT3.test.ts new file mode 100644 index 0000000..71b35d6 --- /dev/null +++ b/tests/DPT3.test.ts @@ -0,0 +1,82 @@ +import { expect } from "chai"; + +import { DPT3 } from "../src/DPT3" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferDecZero = Buffer.from([0]) +let bufferDecValue = Buffer.from([5]) +let bufferIncZero = Buffer.from([8]) +let bufferIncValue = Buffer.from([13]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + +describe("Test DPT3", (): void => { + + let dpt = new DPT3(); + + it("Decode buffer dec-zero", async function () { + const value = dpt.decoder(bufferDecZero) + expect(value.data).is.equal(0); + expect(value.decr_incr).is.equal(0); + }); + + it("Decode buffer dec-value", async function () { + const value = dpt.decoder(bufferDecValue) + expect(value.data).is.equal(5); + expect(value.decr_incr).is.equal(0); + }); + + it("Decode buffer inc-zero", async function () { + const value = dpt.decoder(bufferIncZero) + expect(value.data).is.equal(0); + expect(value.decr_incr).is.equal(1); + }); + + it("Decode buffer inc-value", async function () { + const value = dpt.decoder(bufferIncValue) + expect(value.data).is.equal(5); + expect(value.decr_incr).is.equal(1); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encode tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder({ data: 0, decr_incr: 0 }), bufferDecZero)).is.true; + expect(compareBuffers(dpt.encoder({ data: 5, decr_incr: 0 }), bufferDecValue)).is.true; + expect(compareBuffers(dpt.encoder({ data: 0, decr_incr: 1 }), bufferIncZero)).is.true; + expect(compareBuffers(dpt.encoder({ data: 5, decr_incr: 1 }), bufferIncValue)).is.true; + }); + + it("encode invalid", async function () { + var testFunction = function () { + const value = dpt.encoder({ data: 0, decr_incr: 3 }) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + +}); diff --git a/tests/DPT4.test.ts b/tests/DPT4.test.ts new file mode 100644 index 0000000..5943b89 --- /dev/null +++ b/tests/DPT4.test.ts @@ -0,0 +1,57 @@ +import { expect } from "chai"; + +import { DPT4 } from "../src/DPT4" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferA = Buffer.from([65]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + +describe("Test DPT4", (): void => { + + let dpt = new DPT4(); + + it("Decode buffer with letter [A]", async function () { + const value = dpt.decoder(bufferA) + expect(value).is.equal('A'); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder('A'), bufferA)).is.true; + }); + + it("encode invalid", async function () { + var testFunction = function () { + const value = dpt.encoder("\u03c0") + } + expect(testFunction).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); + + +}); diff --git a/tests/DPT5.test.ts b/tests/DPT5.test.ts new file mode 100644 index 0000000..b1e2494 --- /dev/null +++ b/tests/DPT5.test.ts @@ -0,0 +1,55 @@ +import { expect } from "chai"; + +import { DPT5 } from "../src/DPT5" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferA = Buffer.from([65]) +let bufferMax = Buffer.from([254]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + +describe("Test DPT5", (): void => { + + let dpt = new DPT5(); + + it("Decode buffer common", async function () { + const value = dpt.decoder(bufferA) + expect(value).is.equal(65); + }); + + it("Decode buffer max", async function () { + const value = dpt.decoder(bufferMax) + expect(value).is.equal(254); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(65), bufferA)).is.true; + expect(compareBuffers(dpt.encoder(254), bufferMax)).is.true; + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); diff --git a/tests/DPT6.test.ts b/tests/DPT6.test.ts new file mode 100644 index 0000000..61af954 --- /dev/null +++ b/tests/DPT6.test.ts @@ -0,0 +1,66 @@ +import { expect } from "chai"; + +import { DPT6 } from "../src/DPT6" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let value: number = 65 +let overflowValue: number = 4000 + +let bufferPositive = Buffer.from([value]) +let bufferNegative = Buffer.from([-value]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0]) + +describe("Test DPT6", (): void => { + + let dpt = new DPT6(); + + it("Decode buffer acceptable", async function () { + expect(dpt.decoder(bufferPositive)).is.equal(value); + expect(dpt.decoder(bufferNegative)).is.equal(-value); + }); + + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(value), bufferPositive)).is.true; + expect(compareBuffers(dpt.encoder(-value), bufferNegative)).is.true; + }); + + it("encode invalid", async function () { + var testFunction1 = function () { + const value = dpt.encoder(-overflowValue) + } + var testFunction2 = function () { + const value = dpt.encoder(overflowValue) + } + + expect(testFunction1).to.throw(InvalidValueError); + expect(testFunction2).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT7.test.ts b/tests/DPT7.test.ts new file mode 100644 index 0000000..f3c9d02 --- /dev/null +++ b/tests/DPT7.test.ts @@ -0,0 +1,63 @@ +import { expect } from "chai"; + +import { DPT7 } from "../src/DPT7" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let bufferA = Buffer.from([1, 0]) +let bufferMax = Buffer.from([255, 255]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([1, 0, 2, 4]) + +describe("Test DPT7", (): void => { + + let dpt = new DPT7(); + + it("Decode buffer common", async function () { + const value = dpt.decoder(bufferA) + expect(value).is.equal(256); + }); + + it("Decode buffer max", async function () { + const value = dpt.decoder(bufferMax) + expect(value).is.equal(65535); + }); + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(256), bufferA)).is.true; + expect(compareBuffers(dpt.encoder(65535), bufferMax)).is.true; + }); + + it("encode invalid", async function () { + var testFunction = function () { + const value = dpt.encoder(-200) + } + + expect(testFunction).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); diff --git a/tests/DPT8.test.ts b/tests/DPT8.test.ts new file mode 100644 index 0000000..62f55f2 --- /dev/null +++ b/tests/DPT8.test.ts @@ -0,0 +1,66 @@ +import { expect } from "chai"; + +import { DPT8 } from "../src/DPT8" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let value: number = 256 +let overflowValue: number = 40000 + +let bufferPositive = Buffer.from([1, 0]) +let bufferNegative = Buffer.from([255, 0]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([0xff, 0xff, 0x63, 0xc0]) + +describe("Test DPT8", (): void => { + + let dpt = new DPT8(); + + it("Decode buffer acceptable", async function () { + expect(dpt.decoder(bufferPositive)).is.equal(value); + expect(dpt.decoder(bufferNegative)).is.equal(-value); + }); + + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(value), bufferPositive)).is.true; + expect(compareBuffers(dpt.encoder(-value), bufferNegative)).is.true; + }); + + it("encode invalid", async function () { + var testFunction1 = function () { + const value = dpt.encoder(-overflowValue) + } + var testFunction2 = function () { + const value = dpt.encoder(overflowValue) + } + + expect(testFunction1).to.throw(InvalidValueError); + expect(testFunction2).to.throw(InvalidValueError); + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/DPT9.test.ts b/tests/DPT9.test.ts new file mode 100644 index 0000000..598d31c --- /dev/null +++ b/tests/DPT9.test.ts @@ -0,0 +1,62 @@ +import { expect } from "chai"; + +import { DPT9 } from "../src/DPT9" +import { BufferLengthError } from "../src/errors/BufferLengthError"; +import { InvalidValueError } from "../src/errors/InvalidValueError"; + +import { compareBuffers } from "./util" + +let value: number = 21.08 +let valuemin: number = 1.0e-15 +let bufferValue = Buffer.from([0x0C, 0x1E]) +let bufferZero = Buffer.from([0x00, 0x00]) +let bufferNegative = Buffer.from([0x8b, 0xe2]) + +let bufferEmpty = Buffer.from([]) +let bufferBiggerSize = Buffer.from([0xff, 0xff, 0x63, 0xc0]) + +describe("Test DPT9", (): void => { + + let dpt = new DPT9(); + + it("Decode buffer acceptable", async function () { + expect(dpt.decoder(bufferZero)).is.equal(0); + expect(dpt.decoder(bufferValue)).is.equal(value); + expect(dpt.decoder(bufferNegative)).is.equal(-value); + }); + + + it("Decode empty buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferEmpty) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + it("Decode oversized buffer", async function () { + var testFunction = function () { + const value = dpt.decoder(bufferBiggerSize) + } + expect(testFunction).to.throw(BufferLengthError); + }); + + /* Encoder tests */ + it("encode valid", async function () { + expect(compareBuffers(dpt.encoder(0), bufferZero)).is.true; + expect(compareBuffers(dpt.encoder(value), bufferValue)).is.true; + expect(compareBuffers(dpt.encoder(-value), bufferNegative)).is.true; + }); + + it("encode undefined", async function () { + var testFunction = function () { + const value = dpt.encoder(undefined) + } + expect(testFunction).to.throw(InvalidValueError); + }); + it("encode infinite", async function () { + var testFunction = function () { + const value = dpt.encoder(Infinity) + } + expect(testFunction).to.throw(InvalidValueError); + }); +}); \ No newline at end of file diff --git a/tests/util.ts b/tests/util.ts new file mode 100644 index 0000000..687e464 --- /dev/null +++ b/tests/util.ts @@ -0,0 +1,28 @@ +'use strict'; + +export function bufferToString(buffer: Buffer): string { + let result = '[' + for (let i = 0; i < buffer.length; i++) { + if (i != 0) + result += ', ' + result += `${buffer[i]}` + } + result += ']' + return result +} + +export function compareBuffers(b1: Buffer, b2: Buffer): boolean { + if (b1.length != b2.length) + throw new Error(`Different buffer lengths: b1: ${b1.length}, b2: ${b2.length}`) + + for (let i = 0; i < b1.length; i++) { + const v1 = b1[i]; + const v2 = b2[i]; + + if (typeof v1 != typeof v2) + throw new Error(`Different type values: ${typeof v1}, ${typeof v2} @${i} - ${bufferToString(b1)} ${bufferToString(b2)}`) + if (v1 != v2) + throw new Error(`Different values: ${v1}, ${v2} @${i} - ${bufferToString(b1)} ${bufferToString(b2)}`) + } + return true; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..cd6312c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "lib": [ + "es6", + "esnext" + ], + "allowJs": true, + "declaration": true, + "sourceMap": true, + "outDir": "lib", + "rootDir": "src", + "removeComments": true, + "strict": false, + "noImplicitAny": true, + "moduleResolution": "node", + "strictNullChecks": false, + "resolveJsonModule": true, + "typeRoots": [ + "node_modules/@types" + ], + "esModuleInterop": true, + "experimentalDecorators": true, + "downlevelIteration": true, + "emitDecoratorMetadata": true + }, + "exclude": [ + "node_modules", + "lib", + "**/*.spec.ts" + ], + "include": [ + "src/**/*", + "src/types.d.ts" + ], + "ts-node": { + "files": true + }, +} \ No newline at end of file