From 377251ae0187d532346cdacb6cd420766ce37ae8 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 17 Oct 2021 10:04:29 -0700 Subject: [PATCH 01/23] Tell the script context to use the classloader of the current class. Fixes #11222 Signed-off-by: Dan Cunningham --- .../jsscripting/internal/OpenhabGraalJSScriptEngine.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 7ba654eec7cf..aa62c1308592 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -70,6 +70,7 @@ public OpenhabGraalJSScriptEngine() { .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to ease // migration .option("js.commonjs-require", "true") // enable CommonJS module support + .hostClassLoader(getClass().getClassLoader()) .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { @Override public SeekableByteChannel newByteChannel(Path path, Set options, From 394de638410bfac4e58b2a363d496578417a7783 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Wed, 20 Oct 2021 14:37:43 -0700 Subject: [PATCH 02/23] Protoype of merging OHJ with jsscripting Signed-off-by: Dan Cunningham --- .../javascript/LICENSE | 277 ++ .../javascript/README.md | 82 + .../javascript/actions.js | 49 + .../javascript/docs_config.json | 26 + .../javascript/fluent/condition-conf.js | 60 + .../javascript/fluent/fluent.js | 265 ++ .../javascript/fluent/operation-conf.js | 254 ++ .../javascript/fluent/package-lock.json | 1548 +++++++ .../javascript/fluent/package.json | 19 + .../javascript/fluent/trigger-conf.js | 136 + .../javascript/index.js | 23 + .../javascript/itemchannellink.js | 22 + .../javascript/itemhistory.js | 34 + .../javascript/items/items-provider.js | 116 + .../javascript/items/items.js | 10 + .../javascript/items/managed.js | 471 +++ .../javascript/items/package.json | 5 + .../javascript/log.js | 232 ++ .../javascript/metadata/metadata-provider.js | 36 + .../javascript/metadata/metadata.js | 76 + .../javascript/metadata/package.json | 5 + .../javascript/osgi.js | 138 + .../javascript/package-lock.json | 3557 +++++++++++++++++ .../javascript/package.json | 32 + .../javascript/provider.js | 116 + .../javascript/rules.js | 285 ++ .../javascript/test/condition-conf.test.js | 117 + .../javascript/test/fluent.test.js | 0 .../javascript/test/operation-conf.test.js | 228 ++ .../javascript/test/rewiremock.js | 7 + .../javascript/test/trigger-conf.test.js | 43 + .../javascript/things/package.json | 5 + .../javascript/things/things.js | 104 + .../javascript/triggers.js | 153 + .../javascript/utils.js | 133 + .../javascript/webpack.config.js | 50 + .../pom.xml | 60 + .../internal/OpenhabGraalJSScriptEngine.java | 75 +- 38 files changed, 8829 insertions(+), 20 deletions(-) create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/LICENSE create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/README.md create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/actions.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/docs_config.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/index.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/items.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/managed.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/package.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/log.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/osgi.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/package-lock.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/package.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/provider.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/rules.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/things/package.json create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/things/things.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/triggers.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/utils.js create mode 100644 bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js diff --git a/bundles/org.openhab.automation.jsscripting/javascript/LICENSE b/bundles/org.openhab.automation.jsscripting/javascript/LICENSE new file mode 100644 index 000000000000..d3087e4c5404 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/LICENSE @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. diff --git a/bundles/org.openhab.automation.jsscripting/javascript/README.md b/bundles/org.openhab.automation.jsscripting/javascript/README.md new file mode 100644 index 000000000000..766e753d9580 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/README.md @@ -0,0 +1,82 @@ +[![Build Status](https://travis-ci.org/jpg0/ohj.svg?branch=master)](https://travis-ci.org/jpg0/ohj) +# Openhab Javascript Library + +This library aims to be a fairly high-level ES6 library to support automation in Openhab. + +[API Documentation](https://jpg0.github.io/ohj/ohj/0.1.1/) + +## Requirements + +- ES6 (e.g. GraalJS) +- CommonJS support + +## Installation + +- Install the Openhab 'Experimental Rule Engine' in Paper UI +- Install the [GraalJS bundle](https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/addons/bundles/org.openhab.automation.module.script.graaljs/2.5.0-SNAPSHOT/org.openhab.automation.module.script.graaljs-2.5.0-SNAPSHOT.jar) to upgrade JS runtime to ES6 +- Ensure that you have created the automation scripting directories +- Go to the javascript community lib directory: `cd $OPENHAB_CONF/automation/lib/javascript/community` +- `npm i ohj` (you may need to install npm) + +## Usage + +You should create scripts in $OPENHAB_CONF/automation/jsr223/javascript/personal. + +The API can be imported as a standard CommonJS module: `require('ohj')`. The ohj module itself has various sections that +can be imported as properties of the primary import, e.g. + +``` +//use destructing +const { rules, triggers } = require('ohj'); +//or simply +const rules = require('ohj').rules; +``` + +## Fluent API + +The fluent section of the API can be used to write rules in a high-level, readable style. + +The cleanest way to use the API is with a `with` statement. This is so that it's possible to use the exported functions +without a prefix. An alternative approach (to allow `'use strict'`) would be to explicitly import the functions that you +use, such as `const {when, then} = require('ohj').fluent`. The following examples will use the `with` style of importing. + +Note that for the `timeOfDay` API, you must create a `vTimeOfDay` String item, which is updated like in [the Openhab pattern](https://community.openhab.org/t/design-pattern-time-of-day/15407). A future release will check this. + + +## Fluent Examples + +``` +with(require('ohj').fluent){ + + //turn on the kitchen light at SUNSET + when(timeOfDay("SUNSET")).then(sendOn().toItem("KitchenLight")); + + //turn off the kitchen light at 9PM + when(cron("0 0 21 * * ?")).then(sendOff().toItem("KitchenLight")); + + //set the colour of the hall light to pink at 9PM + when(cron("0 0 21 * * ?")).then(send("300,100,100").toItem("HallLight") + + //when the switch S1 status changes to ON, then turn on the HallLight + when(item('S1').changed().toOn()).then(sendOn().toItem('HallLight')); + + //when the HallLight colour changes pink, if the function fn returns true, then toggle the state of the OutsideLight + when(item('HallLight').changed().to("300,100,100")).if(fn).then(sendToggle().toItem('OutsideLight')); +} + +//and some rules which can be toggled by the items created in the 'gRules' Group: + +with(require('ohj').fluent.withToggle) { + + //when the HallLight receives a command, send the same command to the KitchenLight + when(item('HallLight').receivedCommand()).then(sendIt().toItem('KitchenLight')); + + //when the HallLight is updated to ON, make sure that BedroomLight1 is set to the same state as the BedroomLight2 + when(item('HallLight').receivedUpdate()).then(copyState().fromItem('BedroomLight1').toItem('BedroomLight2')); + + //when the BedroomLight1 is changed, run a custom function + when(item('BedroomLight1').changed()).then(() => { + // do stuff + }); +} +``` diff --git a/bundles/org.openhab.automation.jsscripting/javascript/actions.js b/bundles/org.openhab.automation.jsscripting/javascript/actions.js new file mode 100644 index 000000000000..6b28837191c9 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/actions.js @@ -0,0 +1,49 @@ +/** + * Actions namespace. + * This namespace provides access to Openhab actions. All available actions can be accessed as direct properties of this + * object (via their simple class name). + * + * @example Sends a broadcast notification + * let { actions } = require('ohj'); + * actions.NotificationAction.sendBroadcastNotification("Hello World!") + * + * @example Sends a PushSafer notification + * let { actions } = require('ohj'); + * actions.Pushsafer.pushsafer("", "", "", "", "", "", "") + * + * @namespace actions + */ + + + +const osgi = require('./osgi'); +const utils = require('./utils'); +const { actions } = require('@runtime/Defaults'); +const log = require('./log')('actions'); + +const Things = utils.typeBySuffix('core.model.script.actions.Things'); + +const oh1_actions = osgi.findServices("org.openhab.core.scriptengine.action.ActionService", null) || []; +const oh2_actions = osgi.findServices("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || []; + +oh1_actions.concat(oh2_actions).forEach(function (item) { + try { + //if an action fails to activate, then warn and continue so that other actions are available + exports[item.getActionClass().getSimpleName()] = item.getActionClass().static; + } catch(e) { + log.warn("Failed to activate action {} due to {}", item, e); + } +}); + +let Exec = utils.typeWithFallback('org.openhab.core.model.script.actions.Exec', 'org.eclipse.smarthome.model.script.actions.Exec'); +let HTTP = utils.typeWithFallback('org.openhab.core.model.script.actions.HTTP', 'org.eclipse.smarthome.model.script.actions.HTTP'); +let LogAction = utils.typeWithFallback('org.openhab.core.model.script.actions.Log', 'org.eclipse.smarthome.model.script.actions.LogAction'); +let Ping = utils.typeWithFallback('org.openhab.core.model.script.actions.Ping', 'org.eclipse.smarthome.model.script.actions.Ping'); + +[Exec, HTTP, LogAction, Ping].forEach(function (item) { + exports[item.class.getSimpleName()] = item.class.static; +}); + +exports.get = (...args) => actions.get(...args) + +exports.thingActions = (bindingId, thingUid) => Things.getActions(bindingId,thingUid) diff --git a/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json b/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json new file mode 100644 index 000000000000..397f37672c63 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json @@ -0,0 +1,26 @@ +{ + "tags": { + "allowUnknownTags": true, + "dictionaries": ["jsdoc"] + }, + "source": { + "include": [".", "package.json", "README.md"], + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": [ + "plugins/markdown" + ], + "templates": { + "cleverLinks": false, + "monospaceLinks": true, + "useLongnameInNav": false + }, + "opts": { + "destination": "./out/", + "encoding": "utf8", + "private": false, + "recurse": true, + "template": "./node_modules/minami" + } +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js new file mode 100644 index 000000000000..8399935b0c88 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js @@ -0,0 +1,60 @@ +const log = require('../log')('condition-conf') +const items = require('../items') + +/** + * Condition that wraps a function to determine whether if passes + * @memberof fluent + * @hideconstructor + */ +class FunctionConditionConf { + /** + * Creates a new function condition. Don't call directly. + * + * @param {*} fn callback which determines whether the condition passes + */ + constructor(fn) { + this.fn = fn; + } + + /** + * Checks whether the rule operations should be run + * + * @private + * @param {...any} args rule trigger arguments + * @returns {Boolean} true only if the operations should be run + */ + check(...args) { + let answer = this.fn(args); + log.debug("Condition returning {}", answer); + return answer; + } +} + +class ItemStateConditionConf { + constructor(item_name) { + this.item_name = item_name; + } + + is(value) { + this.values = [value]; + return this; + } + + in(...values) { + this.values = values; + return this; + } + + check(...args) { + let item = items.getItem(this.item_name); + if(typeof item === 'undefined' || item === null) { + throw Error(`Cannot find item: ${this.item_name}`); + } + return this.values.includes(item.state); + } +} + +module.exports = { + FunctionConditionConf, + ItemStateConditionConf +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js new file mode 100644 index 000000000000..3b57e06be00d --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js @@ -0,0 +1,265 @@ +/** + * Allows creation of rules in a fluent, human-readable style. + * + * @namespace fluent + */ + +const log = require('../log')('fluent'); + +const items = require('../items'); +const rules = require('../rules'); + +const triggers = require('./trigger-conf'); +const operations = require('./operation-conf'); +const conditions = require('./condition-conf'); + +/** + * Creates rules in a fluent style. + */ +class FluentRule { + constructor(triggerConf, toggleable) { + this._triggerConfs = []; + this.toggleable = toggleable; + this.or(triggerConf); + } + + or(triggerConf) { + if (!triggerConf._complete()) { + throw Error("Trigger is not complete!"); + } + this._triggerConfs.push(triggerConf); + return this; + } + + if(condition) { + if(typeof condition === 'function') { + condition = new conditions.FunctionConditionConf(condition); + } + + log.debug("Setting condition on rule: {}", condition); + + this.condition = condition; + return this; + } + + then(operation, optionalRuleGroup) { + if (typeof operation === 'function') { + let operationFunction = operation; + operation = { + _complete: () => true, + _run: x => operationFunction(x), + describe: () => "custom function" + } + } else { + //first check complete + if (!operation._complete()) { + throw Error("Operation is not complete!"); + } + } + + this.operation = operation; + this.optionalRuleGroup = optionalRuleGroup; + + let generatedTriggers = this._triggerConfs.flatMap(x => x._toOHTriggers()) + + const ruleClass = this.toggleable ? rules.SwitchableJSRule : rules.JSRule; + + let fnToExecute = operation._run.bind(operation); //bind the function to it's instance + + //chain (of responsibility for) the execute hooks + for(let triggerConf of this._triggerConfs) { + let next = fnToExecute; + if(typeof triggerConf._executeHook === 'function') { + let maybeHook = triggerConf._executeHook(); + if(maybeHook) { + let hook = maybeHook.bind(triggerConf); //bind the function to it's instance + fnToExecute = function(args) { + return hook(next, args); + } + } + } + } + + if(typeof this.condition !== 'undefined'){ //if conditional, check it first + log.debug("Adding condition to rule: {}", this.condition); + let fnWithoutCheck = fnToExecute; + fnToExecute = (x) => this.condition.check(x) && fnWithoutCheck(x) + } + + return ruleClass({ + name: items.safeItemName(this.describe(true)), + description: this.describe(true), + triggers: generatedTriggers, + ruleGroup: optionalRuleGroup, + execute: function (data) { + fnToExecute(data); + } + }); + } + + describe(compact) { + return (compact ? "": "When ") + + this._triggerConfs.map(t => t.describe(compact)).join(" or ") + + (compact ? "→" : " then ") + + this.operation.describe(compact) + + ((!compact && this.optionalRuleGroup) ? ` (in group ${this.optionalRuleGroup})` : ""); + } +} + +const fluentExports = { + /** + * Specifies a period of day for the rule to fire. Note that this functionality depends on a 'vTimeOfDay' String item + * existing and being updated. + * + * @memberof fluent + * @param {String} period the period, such as 'SUNSET' + * @returns {ItemTriggerConfig} the trigger config + */ + timeOfDay: s => new triggers.ItemTriggerConfig('vTimeOfDay').changed().to(s), + + /** + * Specifies a cron schedule for the rule to fire. + * + * @memberof fluent + * @param {String} cronExpression the cron expression + * @returns {ItemTriggerConfig} the trigger config + */ + cron: s => new triggers.CronTriggerConfig(s), + + /** + * Specifies a rule group (for toggling) that this rule should belong to. + * + * @memberof fluent + * @param {String} groupName the group name + * @returns {*} the group config + */ + inGroup: g => g, + + /** + * Specifies that a command should be sent as a result of this rule firing. + * + * @memberof fluent + * @param {String} command the command to send + * @returns {SendCommandOrUpdateOperation} the operation + */ + send: c => new operations.SendCommandOrUpdateOperation(c), + + /** + * Specifies that an update should be posted as a result of this rule firing. + * + * @memberof fluent + * @param {String} update the update to send + * @returns {SendCommandOrUpdateOperation} the operation + */ + postUpdate: c => new operations.SendCommandOrUpdateOperation(c, false), + + /** + * Specifies the a command 'ON' should be sent as a result of this rule firing. + * + * @memberof fluent + * @returns {SendCommandOrUpdateOperation} the operation + */ + sendOn: () => new operations.SendCommandOrUpdateOperation("ON"), + + /** + * Specifies the a command 'OFF' should be sent as a result of this rule firing. + * + * @memberof fluent + * @returns {SendCommandOrUpdateOperation} the operation + */ + sendOff: () => new operations.SendCommandOrUpdateOperation("OFF"), + + /** + * Specifies a command should be sent to toggle the state of the target object + * as a result of this rule firing. + * + * @memberof fluent + * @returns {ToggleOperation} the operation + */ + sendToggle: () => new operations.ToggleOperation(), + + /** + * Specifies a command should be forwarded to the state of the target object + * as a result of this rule firing. This relies on the trigger being the result + * of a command itself. + * + * @memberof fluent + * @returns {SendCommandOrUpdateOperation} the operation + */ + sendIt: () => new operations.SendCommandOrUpdateOperation(args => args.it.toString(), true, "it"), + + /** + * Specifies a command state should be posted to the target object + * as a result of this rule firing. This relies on the trigger being the result + * of a command itself. + * + * @memberof fluent + * @returns {SendCommandOrUpdateOperation} the operation + */ + postIt: () => new operations.SendCommandOrUpdateOperation(args => args.it.toString(), false, "it"), + + + /** + * Specifies an item as the source of changes to trigger a rule. + * + * @memberof fluent + * @param {String} itemName the name of the item + * @returns {ItemTriggerConfig} the trigger config + */ + item: s => new triggers.ItemTriggerConfig(s), + + /** + * Copies the state from one item to another. Can be used to proxy item state. State is updated, not + * sent as a command. + * + * @memberof fluent + * @returns {CopyStateOperation} the operation config + */ + copyState: () => new operations.CopyStateOperation(false), + + /** + * Sends the state from one item to another. Can be used to proxy item state. State is + * sent as a command. + * + * @memberof fluent + * @returns {CopyStateOperation} the operation config + */ + copyAndSendState: () => new operations.CopyStateOperation(true), + + /** + * Condition of an item in determining whether to process rule. + * + * @memberof fluent + * @param {String} itemName the name of the item to assess the state + * @returns {ItemStateConditionConf} the operation config + */ + stateOfItem: s => new conditions.ItemStateConditionConf(s) +} + +module.exports = Object.assign({ + /** + * Specifies when the rule should occur. Will create a standard rule. + * + * @memberof fluent + * @param {ItemTriggerConfig|CronTriggerConfig} config specifies the rule triggers + * @returns {FluentRule} the fluent rule builder + */ + when: o => new FluentRule(o, false), +}, fluentExports); + +/** + * Switches on toggle-able rules for all items created in this namespace. + * + * @memberof fluent + * @name withToggle + */ +module.exports.withToggle = Object.assign({ + /** + * Specifies when the rule should occur. Will create a toggle-able rule. + * + * @memberof fluent + * @param {ItemTriggerConfig|CronTriggerConfig} config specifies the rule triggers + * @returns {FluentRule} the fluent rule builder + */ + when: o => new FluentRule(o, true), +}, fluentExports); \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js new file mode 100644 index 000000000000..d9e3347a4681 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js @@ -0,0 +1,254 @@ +const parse_duration = require('parse-duration'); +const log = require('../log')('operation-conf'); +const items = require('../items'); + +/** + * Copies state from one item to another item + * + * @memberof fluent + * @hideconstructor + */ +class CopyStateOperation { + + /** + * Creates a new operation. Don't use constructor directly. + * + * @param {Boolean} send whether to send (or post update) the state + */ + constructor(send) { + this.send = send; + } + + /** + * Sets the item to copy the state from + * @param {String} item_name the item to copy state from + * @returns {CopyStateOperation} this + */ + fromItem(item_name){ + this.from_item = item_name; + return this; + } + + /** + * Sets the item to copy the state to + * @param {String} item_name the item to copy state to + * @returns {CopyStateOperation} this + */ + toItem(item_name){ + this.to_item = item_name; + return this; + } + + /** + * Appends another operation to execute when the rule fires + * @param {CopyStateOperation|SendCommandOperation|ToggleOperation} next + * @returns {CopyStateOperation} this + */ + and(next) { + this.next = next; + return this; + } + + /** + * Runs the operation. Don't call directly. + * + * @private + * @param {Object} args rule firing args + */ + _run(args){ + + if(typeof this.from_item === 'undefined' || this.from_item === null) { + throw Error("From item not set"); + } + + if(typeof this.to_item === 'undefined' || this.to_item === null) { + throw Error("To item not set"); + } + + let from = items.getItem(this.from_item); + if(typeof from === 'undefined' || from === null) { + throw Error(`Cannot find (from) item ${this.from_item}`); + } + + let to = items.getItem(this.to_item); + if(typeof to === 'undefined' || to === null) { + throw Error(`Cannot find (to) item ${this.to_item}`); + } + + if(this.send) { + to.sendCommand(from.state); + } else { + to.postUpdate(from.state); + } + if(this.next){ + this.next.execute(args); + } + } + + /** + * Checks that the operation configuration is complete. Don't call directly. + * + * @private + * @returns true only if the operation is ready to run + */ + _complete(){ + return this.from_item && this.to_item; + } + + /** + * Describes the operation. + * + * @private + * @returns a description of the operation + */ + describe(){ + return `copy state from ${this.from_item} to ${this.to_item}` + } +} + +class SendCommandOrUpdateOperation { + constructor(dataOrSupplier, isCommand = true, optionalDesc) { + this.isCommand = isCommand; + if (typeof dataOrSupplier === 'function') { + this.dataFn = dataOrSupplier; + this.dataDesc = optionalDesc || '[something]'; + } else { + this.dataFn = () => dataOrSupplier; + this.dataDesc = optionalDesc || dataOrSupplier; + } + } + + toItems(itemsOrNames) { + this.toItemNames = itemsOrNames.map(i => (typeof i === 'string') ? i : i.name) + return this; + } + + toItem(itemOrName) { + this.toItemNames = [(typeof itemOrName === 'string') ? itemOrName : itemOrName.name]; + return this; + } + + and(next) { + this.next = next; + return this; + } + + _run(args) { + for(let toItemName of this.toItemNames) { + let item = items.getItem(toItemName); + let data = this.dataFn(args); + + if(this.isCommand) { + item.sendCommand(data) + } else { + item.postUpdate(data); + } + } + + this.next && this.next.execute(args); + } + + _complete() { + return (typeof this.toItemNames) !== 'undefined'; + } + + describe(compact) { + if(compact) { + return this.dataDesc + (this.isCommand ? '⌘' : '↻') + this.toItemNames + (this.next ? this.next.describe() : "") + } else { + return (this.isCommand ? 'send command' : 'post update') + ` ${this.dataDesc} to ${this.toItemNames}` + (this.next ? ` and ${this.next.describe()}` : "") + } + } +} + +class ToggleOperation { + constructor() { + this.next = null; + this.toItem = function (itemName) { + this.itemName = itemName; + return this; + }; + this.and = function (next) { + this.next = next; + return this; + }; + this._run = () => this.doToggle() && (this.next && this.next.execute()) + this._complete = () => true; + this.describe = () => `toggle ${this.itemName}` + (this.next ? ` and ${this.next.describe()}` : "") + } + + doToggle(){ + let item = items.getItem(this.itemName); + + switch(item.type) { + case "SwitchItem": { + let toSend = ('ON' == item.state) ? 'OFF' : 'ON'; + item.sendCommand(toSend); + break; + } + case "ColorItem": { + let toSend = ('0' != item.rawState.getBrightness().toString()) ? 'OFF' : 'ON'; + item.sendCommand(toSend); + break; + } + default: + throw error(`Toggle not supported for items of type ${item.type}`); + } + } +} + +class TimingItemStateOperation { + constructor(item_changed_trigger_config, duration) { + + if(typeof item_changed_trigger_config.to_value === 'undefined') { + throw error("Must specify item state value to wait for!"); + } + + this.item_changed_trigger_config = item_changed_trigger_config; + this.duration_ms = (typeof duration === 'Number' ? duration : parse_duration.parse(duration)) + + this._complete = item_changed_trigger_config._complete; + this.describe = () => item_changed_trigger_config.describe() + " for " + duration; + } + + _toOHTriggers() { + //each time we're triggered, set a callback. + //If the item changes to something else, cancel the callback. + //If the callback executes, run the operation + + //register for all changes as we need to know when it changes away + switch (this.op_type) { + case "changed": + return [triggers.ChangedEventTrigger(this.item_name)]; + default: + throw error("Unknown operation type: " + this.op_type); + } + } + + _executeHook(next) { + if(items.get(this.item_changed_trigger_config.item_name).toString() === this.item_changed_trigger_config.to_value) { + _start_wait(next); + } else { + _cancel_wait(); + } + } + + _start_wait(next) { + this.current_wait = setTimeout(next, this.duration_ms); + } + + _cancel_wait() { + if(this.current_wait) { + cancelTimeout(this.current_wait); + } + } + + +} + +module.exports = { + SendCommandOrUpdateOperation, + TimingItemStateOperation, + ToggleOperation, + CopyStateOperation +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json new file mode 100644 index 000000000000..614d641c584a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json @@ -0,0 +1,1548 @@ +{ + "name": "fluent", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "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==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "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==" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.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==", + "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=" + }, + "compare-module-exports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", + "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", + "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=" + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "core-js": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cronstrue": { + "version": "1.84.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.84.0.tgz", + "integrity": "sha512-yfQowBKKZGCZ6Ia2zlpDKhT7Eq4Lq4gzFBmJTrHMNgZh+vkSvmI6NtCvXR21JM00tp6afyY04VEgHaaqlE9oIg==" + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "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=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", + "requires": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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==" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==" + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "requires": { + "chalk": "^2.0.1" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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==" + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "requires": { + "minimist": "^1.2.5" + } + }, + "mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + } + }, + "module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=" + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "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 + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.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==" + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-duration": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", + "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "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=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", + "requires": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" + } + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "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" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.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 + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "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==" + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "rewiremock": { + "version": "3.13.9", + "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.13.9.tgz", + "integrity": "sha512-FDk5uCyvfwgYZtZ9MKdpg6QiSSdjB/a/vU5luKjoJddaqcZz5+u4dXhc3Qf4vNMvDXvnOyodNd1riE5yeqoxaA==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "compare-module-exports": "^2.1.0", + "lodash.some": "^4.6.0", + "lodash.template": "^4.4.0", + "node-libs-browser": "^2.1.0", + "path-parse": "^1.0.5", + "wipe-node-cache": "^2.1.0", + "wipe-webpack-cache": "^2.1.0" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", + "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", + "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "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=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wipe-node-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.0.tgz", + "integrity": "sha512-Vdash0WV9Di/GeYW9FJrAZcPjGK4dO7M/Be/sJybguEgcM7As0uwLyvewZYqdlepoh7Rj4ZJKEdo8uX83PeNIw==", + "dev": true + }, + "wipe-webpack-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", + "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", + "dev": true, + "requires": { + "wipe-node-cache": "^2.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.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": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + } + } +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json new file mode 100644 index 000000000000..18335ade1c4a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json @@ -0,0 +1,19 @@ +{ + "name": "fluent", + "version": "0.0.1", + "description": "Fluent API for Openhab", + "main": "fluent.js", + "private": true, + "dependencies": { + "cronstrue": "^1.84.0", + "mocha": "^6.2.3", + "parse-duration": "^0.1.1", + "proxyquire": "^2.1.3" + }, + "scripts": { + "test": "mocha" + }, + "devDependencies": { + "rewiremock": "^3.13.9" + } +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js new file mode 100644 index 000000000000..55bc6e3256cb --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js @@ -0,0 +1,136 @@ +const triggers = require('../triggers'); +const log = require('../log')('trigger-conf'); + +class CronTriggerConfig { + constructor(timeStr) { + this.timeStr = timeStr; + this._complete = () => true + this._toOHTriggers = () => [triggers.GenericCronTrigger(this.timeStr)] + this.describe = (compact) => compact ? this.timeStr : `matches cron "${this.timeStr}"` + } +}; + + +class ItemTriggerConfig { + constructor(itemOrName) { + if(typeof itemOrName !== 'string') { + itemOrName = itemOrName.name; + } + + this.item_name = itemOrName; + this.describe = () => `item ${this.item_name} changed` + this.of = this.to; //receivedCommand().of(..) + } + + to(value) { + this.to_value = value; + return this; + } + + from(value) { + if(this.op_type != 'changed') { + throw ".from(..) only available for .changed()"; + } + this.from_value = value; + return this; + } + + toOff() { + return this.to('OFF'); + } + + toOn() { + return this.to('ON'); + } + + receivedCommand() { + this.op_type = 'receivedCommand'; + return this; + } + + receivedUpdate() { + this.op_type = 'receivedUpdate'; + return this; + } + + changed() { + this.op_type = 'changed'; + return this; + } + + _complete() { + return typeof (this.op_type) !== 'undefined'; + } + + describe(compact) { + switch (this.op_type) { + case "changed": + if(compact) { + let transition = this.from_value + '=>' || ''; + if(this.to_value) { + transition = (transition || '=>') + this.to_value; + } + + return `${this.item_name} ${transition}/Δ`; + } else { + let transition = 'changed'; + if(this.from_value) { + transition += ` from ${this.from_value}`; + } + + if(this.to_value) { + transition += ` to ${this.to_value}`; + } + + return `${this.item_name} ${transition}`; + } + case "receivedCommand": + return compact ? `${this.item_name}/⌘` : `item ${this.item_name} received command`; + case "receivedUpdate": + return compact ? `${this.item_name}/↻` : `item ${this.item_name} received update`; + default: + throw error("Unknown operation type: " + this.op_type); + } + } + + for(timespan) { + return new TimingItemStateOperation(this, timespan); + } + + _toOHTriggers() { + switch (this.op_type) { + case "changed": + return [triggers.ItemStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; + case 'receivedCommand': + return [triggers.ItemCommandTrigger(this.item_name, this.to_value)] + case 'receivedUpdate': + return [triggers.ItemStateUpdateTrigger(this.item_name, this.to_value)] + default: + throw error("Unknown operation type: " + this.op_type); + } + } + + _executeHook() { + + const getReceivedCommand = function(args){ + return args.receivedCommand; + }; + + if(this.op_type === 'receivedCommand') { //add the received command as 'it' + return function(next, args){ + let it = getReceivedCommand(args); + return next({ + ...args, + it + }); + } + } else { + return null; + } + } +} + +module.exports = { + ItemTriggerConfig, + CronTriggerConfig +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/index.js b/bundles/org.openhab.automation.jsscripting/javascript/index.js new file mode 100644 index 000000000000..2f3a772f73f6 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/index.js @@ -0,0 +1,23 @@ +/** + * @typedef {Object} HostState Native Java Openhab State (instance of org.openhab.core.types.State) + * @typedef {Object} HostItem Native Java Openhab Item (instance of org.openhab.core.items.Item) + * @typedef {Object} HostClass Native Java Class Object (instance of java.lang.Class) + * @typedef {Object} HostRule Native Jave Openhab Rule (instance of org.openhab.core.automation.Rule) + * @typedef {Object} HostTrigger Native Jave Openhab Trigger (instance of org.openhab.core.automation.Trigger) + */ + +// lazy getters to avoid any reference loading all submodules +module.exports = { + get log() { return require('./log') }, + get fluent() { return require('./fluent') }, + get rules() { return require('./rules') }, + get items() { return require('./items') }, + get things() { return require('./things') }, + get metadata() { return require('./metadata') }, + get triggers() { return require('./triggers') }, + get actions() { return require('./actions') }, + get utils() { return require('./utils') }, + get osgi() { return require('./osgi') }, + get provider() { return require('./provider') }, + get itemchannellink() { return require('./itemchannellink') } +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js b/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js new file mode 100644 index 000000000000..202547c9686c --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js @@ -0,0 +1,22 @@ +/** + * Items' metadata namespace. + * This namespace provides access to metadata on items. + * + * @private + * @namespace metadata + */ + +const osgi = require('./osgi'); +const utils = require('./utils'); +const log = require('./log')('itemchannellink'); + +let ItemChannelLink = utils.typeWithFallback("org.openhab.core.thing.link.ItemChannelLink", "org.eclipse.smarthome.core.thing.link.ItemChannelLink"); + +let createItemChannelLink = function(itemName, channel) { + log.debug("Creating item channel link {} -> {}", itemName, channel.uid); + return new ItemChannelLink(itemName, channel.rawChannel.getUID()); +} + +module.exports = { + createItemChannelLink +}; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js b/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js new file mode 100644 index 000000000000..e462f7678ccf --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js @@ -0,0 +1,34 @@ +/** + * Items' history module. + * This module provides access to historic state of items. + * + * @private + * @namespace itemshistory + */ + +const utils = require('./utils'); + +const PersistenceExtensions = utils.typeBySuffix("persistence.extensions.PersistenceExtensions"); + +const timeClazz = utils.typeWithFallback("org.joda.time.DateTime", "java.time.Instant"); //remove JodaTime when remove support for OH 2.5.x + +let historicState = function (item, timestamp) { + //todo: check item param + let history = PersistenceExtensions.historicState(item.rawItem, timestamp); + + return history === null ? null : history.state; +}; + +let previousState = function(item, skipEqual = false) { + let result = PersistenceExtensions.previousState(item.rawItem, skipEqual) + + return result === null ? null : result.state; +} + +let latestState = (item) => historicState(item, timeClazz.now()); + +module.exports = { + historicState, + latestState, + previousState +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js b/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js new file mode 100644 index 000000000000..448286bacdc6 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js @@ -0,0 +1,116 @@ +const osgi = require('../osgi'); +const items = require('./managed'); +const utils = require('../utils'); +const { AbstractProvider } = require('../provider'); + +const ITEM_PROVIDER_CLASS = "org.eclipse.smarthome.core.items.ItemProvider"; + + +class StaticItemProvider extends AbstractProvider { + constructor(items) { + super(ITEM_PROVIDER_CLASS); + this.items = items; + this.registerService(); + } + + addProviderChangeListener(listener) { + } + + removeProviderChangeListener(listener) { + } + + getAll(){ + return this.items; + } +} + + +class ManagedItemProvider extends AbstractProvider { + constructor() { + super(ITEM_PROVIDER_CLASS); + this.items = new Set(); + this.listeners = new Set(); + this.registerService(); + } + + addProviderChangeListener(listener) { + this.listeners.add(listener) + } + + removeProviderChangeListener(listener) { + this.listeners.delete(listener); + } + + add(item) { + if (item instanceof items.OHItem) { + item = item.rawItem; + } + + if (!this.items.has(item)) { + this.items.add(item); + for (let listener of this.listeners) { + listener.added(this.hostProvider, item); + } + } + } + + remove(itemOrName) { + if (typeof itemOrName === 'string') { + this.items.forEach(i => { if (i.name === itemOrName) this.remove(i) }); + } else { + if (itemOrName instanceof items.OHItem) { + itemOrName = itemOrName.rawItem; + } + + if (this.items.has(itemOrName)) { + this.items.delete(itemOrName); + + for (let listener of this.listeners) { + listener.removed(this.hostProvider, item); + } + } + } + } + + update(item) { + if (item instanceof items.OHItem) { + item = item.rawItem; + } + + for (let listener of this.listeners) { + listener.updated(this.hostProvider, item); + } + } + + getAll() { + return utils.jsSetToJavaSet(this.items); + } +} + +class StaticCallbackItemProvider extends AbstractProvider { + constructor() { + super(ITEM_PROVIDER_CLASS); + this.itemsCallbacks = []; + } + + addProviderChangeListener(listener) { + } + + removeProviderChangeListener(listener) { + } + + addItemsCallback(callback) { + this.itemsCallbacks.push(callback); + } + + getAll(){ + return utils.jsArrayToJavaList(this.itemsCallbacks.flatMap(c => c())); + } +} + +module.exports = { + staticItemProvider: items => new StaticItemProvider(items), + managedItemProvider: () => new ManagedItemProvider(), + staticCallbackItemProvider: () => new StaticCallbackItemProvider() +} + \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/items.js b/bundles/org.openhab.automation.jsscripting/javascript/items/items.js new file mode 100644 index 000000000000..46122bcd18bb --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/items.js @@ -0,0 +1,10 @@ +/** + * Items namespace. + * This namespace handles querying and updating Openhab Items. + * @namespace items + */ + +module.exports = { + ...require('./managed'), + provider: require('./items-provider') +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js new file mode 100644 index 000000000000..eec25b6d9ad2 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js @@ -0,0 +1,471 @@ + + +const osgi = require('../osgi'); +const utils = require('../utils'); +const log = require('../log')('items'); +const metadata = require('../metadata'); +const itemhistory = require('../itemhistory'); + +const { UnDefType, events, itemRegistry } = require('@runtime'); + +const itemBuilderFactory = osgi.getService( + "org.openhab.core.items.ItemBuilderFactory", + "org.eclipse.smarthome.core.items.ItemBuilderFactory" +); + +const managedItemProvider = osgi.getService( + "org.openhab.core.items.ManagedItemProvider", + "org.eclipse.smarthome.core.items.ManagedItemProvider" +); + +/** + * Tag value to be attached to all dynamically created items. + * @memberOf items + */ +const DYNAMIC_ITEM_TAG = "_DYNAMIC_"; + +/** + * Class representing an Openhab Item + * @memberOf items + */ +class OHItem { + /** + * Create an OHItem, wrapping a native Java Openhab Item. Don't use this constructor, instead call {@link getItem}. + * @param {HostItem} rawItem Java Item from Host + * @hideconstructor + */ + constructor(rawItem) { + if (typeof rawItem === 'undefined') { + throw Error("Supplied item is undefined"); + } + this.rawItem = rawItem; + } + + /** + * The type of the item: the Simple (without package) name of the Java item type, such as 'Switch'. + * @return {String} the type + */ + get type() { + return this.rawItem.getClass().getSimpleName(); + } + + /** + * The name of the item. + * @return {String} the name + */ + get name() { + return this.rawItem.getName(); + } + + /** + * The label attached to the item + * @return {String} the label + */ + get label() { + return this.rawItem.getLabel(); + } + + /** + * The state of the item, as a string. + * @return {String} the item's state + */ + get state() { + return this.rawState.toString(); + } + + get previousState() { + return itemhistory.previousState(this).toString(); + } + + /** + * The raw state of the item, as a java object. + * @return {HostState} the item's state + */ + get rawState() { + return this.rawItem.state; + } + + /** + * Members / children / direct descendents of the current group item (as returned by 'getMembers()'). Must be a group item. + * @returns {OHItem[]} member items + */ + get members() { + return utils.javaSetToJsArray(this.rawItem.getMembers()).map(raw => new OHItem(raw)); + } + + /** + * All descendents of the current group item (as returned by 'getAllMembers()'). Must be a group item. + * @returns {OHItem[]} all descendent items + */ + get descendents() { + return utils.javaSetToJsArray(this.rawItem.getAllMembers()).map(raw => new OHItem(raw)); + } + + /** + * Whether this item is initialized. + * @type {Boolean} + * @returns true iff the item has not been initialized + */ + get isUninitialized() { + if (this.rawItem.state instanceof UnDefType + || this.rawItem.state.toString() == "Undefined" + || this.rawItem.state.toString() == "Uninitialized" + ) { + return true; + } else { + return false; + } + } + + /** + * Gets metadata values for this item. + * @param {String} namespace The namespace for the metadata to retreive + * @returns {String} the metadata associated with this item and namespace + */ + getMetadataValue(namespace) { + return metadata.getValue(this.name, namespace); + } + + /** + * Updates metadata values for this item. + * @param {String} namespace The namespace for the metadata to update + * @param {String} value the value to update the metadata to + * @returns {String} the updated value + */ + updateMetadataValue(namespace, value) { + return metadata.updateValue(this.name, namespace, value); + } + + /** + * Inserts or updates metadata values for this item. + * @param {String} namespace The namespace for the metadata to update + * @param {String} value the value to update the metadata to + * @returns {Boolean} true iff a new value was inserted + */ + upsertMetadataValue(namespace, value) { + return metadata.upsertValue(this.name, namespace, value); + } + + /** + * Updates metadata values for this item. + * @param {Map} namespaceToValues A map of namespaces to values to update + */ + updateMetadataValues(namespaceToValues) { + for(let k in namespaceToValues) { + metadata.updateValue(this.name, k, namespaceToValues[k]); + } + } + + /** + * Sends a command to the item + * @param {String|HostState} value the value of the command to send, such as 'ON' + * @see sendCommandIfDifferent + * @see postUpdate + */ + sendCommand(value) { + log.debug("Sending command {} to {}", value, this.name); + events.sendCommand(this.rawItem, value); + } + + /** + * Sends a command to the item, but only if the current state is not what is being sent. + * Note + * @param {String|HostState} value the value of the command to send, such as 'ON' + * @returns {Boolean} true if the command was sent, false otherwise + * @see sendCommand + */ + sendCommandIfDifferent(value) { + if (value.toString() != this.state.toString()) { + this.sendCommand(value); + return true; + } + + return false; + } + + /** + * Posts an update to the item + * @param {String|HostState} value the value of the command to send, such as 'ON' + * @see sendCommand + */ + postUpdate(value) { + events.postUpdate(this.rawItem, value); + log.debug("Posted update {} to {}", value, this.name); + } + + /** + * Adds groups to this item + * @param {Array} groupNamesOrItems names of the groups (or the group items themselves) + */ + addGroups(...groupNamesOrItems) { + let groupNames = groupNamesOrItems.map((x) => (typeof x === 'string') ? x : x.name); + this.rawItem.addGroupNames(groupNames); + managedItemProvider.update(this.rawItem); + } + + /** + * Removes groups from this item + * @param {Array} groupNamesOrItems names of the groups (or the group items themselves) + */ + removeGroups(...groupNamesOrItems) { + let groupNames = groupNamesOrItems.map((x) => (typeof x === 'string') ? x : x.name); + for(let groupName of groupNames) { + this.rawItem.removeGroupName(groupName); + } + managedItemProvider.update(this.rawItem); + } + + /** + * Gets the tags from this item + */ + get tags() { + return utils.javaSetToJsArray(this.rawItem.getTags()); + } + + /** + * Adds tags to this item + * @param {Array} tagNames names of the tags to add + */ + addTags(...tagNames) { + this.rawItem.addTags(tagNames); + managedItemProvider.update(this.rawItem); + } + + /** + * Removes tags from this item + * @param {Array} tagNames names of the tags to remove + */ + removeTags(...tagNames) { + for(let tagName of tagNames) { + this.rawItem.removeTag(tagName); + } + managedItemProvider.update(this.rawItem); + } +} + +/** + * Creates a new item within OpenHab. This item is not registered with any provider. + * + * Note that all items created this way have an additional tag attached, for simpler retrieval later. This tag is + * created with the value {@link DYNAMIC_ITEM_TAG}. + * + * @memberOf items + * @param {String} itemName Item name for the Item to create + * @param {String} [itemType] the type of the Item + * @param {String} [category] the category (icon) for the Item + * @param {String[]} [groups] an array of groups the Item is a member of + * @param {String} [label] the label for the Item + * @param {String[]} [tags] an array of tags for the Item + * @param {HostItem} [giBaseType] the group Item base type for the Item + * @param {HostGroupFunction} [groupFunction] the group function used by the Item + * @param {Map} [itemMetadata] a map of metadata to set on the item + */ +const createItem = function (itemName, itemType, category, groups, label, tags, giBaseType, groupFunction, itemMetadata) { + itemName = safeItemName(itemName); + + let baseItem; + if (itemType === 'Group' && typeof giBaseType !== 'undefined') { + baseItem = itemBuilderFactory.newItemBuilder(giBaseType, itemName + "_baseItem").build() + } + + if (itemType !== 'Group') { + groupFunction = undefined; + } + + if (typeof tags === 'undefined') { + tags = []; + } + + tags.push(DYNAMIC_ITEM_TAG); + + try { + var builder = itemBuilderFactory.newItemBuilder(itemType, itemName). + withCategory(category). + withLabel(label); + + builder = builder.withTags(utils.jsArrayToJavaSet(tags)); + + if (typeof groups !== 'undefined') { + builder = builder.withGroups(utils.jsArrayToJavaList(groups)); + } + + if (typeof baseItem !== 'undefined') { + builder = builder.withBaseItem(baseItem); + } + if (typeof groupFunction !== 'undefined') { + builder = builder.withGroupFunction(groupFunction); + } + + var item = builder.build(); + + return new OHItem(item); + } catch (e) { + log.error("Failed to create item: " + e); + throw e; + } +} + +/** + * Creates a new item within OpenHab. This item will persist regardless of the lifecycle of the script creating it. + * + * Note that all items created this way have an additional tag attached, for simpler retrieval later. This tag is + * created with the value {@link DYNAMIC_ITEM_TAG}. + * + * @memberOf items + * @param {String} itemName Item name for the Item to create + * @param {String} [itemType] the type of the Item + * @param {String} [category] the category (icon) for the Item + * @param {String[]} [groups] an array of groups the Item is a member of + * @param {String} [label] the label for the Item + * @param {String[]} [tags] an array of tags for the Item + * @param {HostItem} [giBaseType] the group Item base type for the Item + * @param {HostGroupFunction} [groupFunction] the group function used by the Item + */ +const addItem = function (itemName, itemType, category, groups, label, tags, giBaseType, groupFunction) { + let item = createItem(...arguments); + managedItemProvider.add(item.rawItem); + log.debug("Item added: {}", item.name); + return item; +} + +/** + * Removes an item from OpenHab. The item is removed immediately and cannot be recoved. + * + * @memberOf items + * @param {String|HostItem} itemOrItemName the item to remove + * @returns {Boolean} true iff the item is actually removed + */ +const removeItem = function (itemOrItemName) { + + var itemName; + + if (typeof itemOrItemName === 'string') { + itemName = itemOrItemName; + } else if (itemOrItemName.hasOwnProperty('name')) { + itemName = itemOrItemName.name; + } else { + log.warn('Item not registered (or supplied name is not a string) so cannot be removed'); + return false; + } + + if (typeof getItem(itemName) === 'undefined') { + log.warn('Item not registered so cannot be removed'); + return false; + } + + managedItemProvider.remove(itemName); + + if (typeof itemRegistry.getItem(itemName) === 'undefined') { + log.debug("Item removed: " + itemName); + return true; + } else { + log.warn("Failed to remove item: " + itemName); + return false; + } +} + +/** + * Replaces (upserts) an item. If an item exists with the same name, it will be removed and a new item with + * the supplied parameters will be created in it's place. If an item does not exist with this name, a new + * item will be created with the supplied parameters. + * + * This function can be useful in scripts which create a static set of items which may need updating either + * periodically, during startup or even during development of the script. Using fixed item names will ensure + * that the items remain up-to-date, but won't fail with issues related to duplicate items. + * + * @param {String} itemName Item name for the Item to create + * @param {String} [itemType] the type of the Item + * @param {String} [category] the category (icon) for the Item + * @param {String[]} [groups] an array of groups the Item is a member of + * @param {String} [label] the label for the Item + * @param {String[]} [tags] an array of tags for the Item + * @param {HostItem} [giBaseType] the group Item base type for the Item + * @param {HostGroupFunction} [groupFunction] the group function used by the Item + */ +/* above params copied from addItem */ +const replaceItem = function (/* same args as addItem */) { + var itemName = arguments[0]; + try { + var item = getItem(itemName); + if (typeof item !== 'undefined') { + log.debug("Removing existing item " + itemName + "[" + item + "] to replace with updated one"); + removeItem(itemName); + } + } catch (e) { + if (("" + e).startsWith("org.openhab.core.items.ItemNotFoundException") || ("" + e).startsWith("org.eclipse.smarthome.core.items.ItemNotFoundException")) { + // item not present + } else { + throw e; + } + } + + return addItem.apply(this, arguments); +} + +/** + * Gets an Openhab Item. + * @param {String} name the name of the item + * @param {String} nullIfMissing whether to return null if the item cannot be found (default is to throw an exception) + * @return {OHItem} the item + * @alias module:ohj/items.getItem + */ +const getItem = (name, nullIfMissing = false) => { + try { + if (typeof name === 'string' || name instanceof String) { + return new OHItem(itemRegistry.getItem(name)); + } + } catch(e) { + if(nullIfMissing) { + return null; + } else { + throw e; + } + } +} + +/** + * Gets all Openhab Items with a specific tag. + * @param {String[]} tagNames an array of tags to match against + * @return {OHItem[]} the items with a tag that is included in the passed tags + * @alias module:ohj/items.getItemsByTag + */ +const getItemsByTag = (...tagNames) => { + return utils.javaSetToJsArray(itemRegistry.getItemsByTag(tagNames)).map(i => new OHItem(i)); +} + + /** + * Helper function to ensure an item name is valid. All invalid characters are replaced with an underscore. + * @param {String} s the name to make value + * @returns {String} a valid item name + */ +const safeItemName = s => s. + replace(/[\"\']/g, ''). //delete + replace(/[^a-zA-Z0-9]/g, '_'); //replace with underscore + +module.exports = { + safeItemName, + getItem, + addItem, + getItemsByTag, + replaceItem, + createItem, + removeItem, + OHItem, + /** + * Custom indexer, to allow static item lookup. + * @example + * let { my_object_name } = require('ohj').items.objects; + * ... + * let my_state = my_object_name.state; //my_object_name is an OHItem + * + * @returns {Object} a collection of items allowing indexing by item name + */ + objects: () => new Proxy({}, { + get: function (target, name) { + if (typeof name === 'string' && /^-?\d+$/.test(name)) + return getItem(name); + + throw Error("unsupported function call: " + name); + } + }) +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/package.json b/bundles/org.openhab.automation.jsscripting/javascript/items/package.json new file mode 100644 index 000000000000..a777cb96debc --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/package.json @@ -0,0 +1,5 @@ +{ + "name": "items", + "version": "0.0.1", + "main": "items.js" +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/log.js b/bundles/org.openhab.automation.jsscripting/javascript/log.js new file mode 100644 index 000000000000..2bf604866c0b --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/log.js @@ -0,0 +1,232 @@ +/** + * Log namespace. + * This namespace provides loggers to log messages to the Openhab Log. + * + * @example Basic logging + * let log = require('ohj').log('my_logger'); + * log.info("Hello World!") + * + * @namespace log + */ + +/** + * Logger prefix + * @memberOf log + */ +const LOGGER_PREFIX = "script.js"; + +//const RuntimeExceptionEx = require('@runtime/osgi').classutil.extend(Java.type('java.lang.RuntimeException')); + +const MessageFormatter = Java.type("org.slf4j.helpers.MessageFormatter"); + +/** + * Logger class. A named logger providing the ability to log formatted messages. + * + * @memberof log + * @hideconstructor + */ +class Logger { + /** + * Creates a new logger. Don't use directly, use {@link log} on module. + * + * @param {String} _name the name of the logger. Will be prefixed by {@link LOGGER_PREFIX} + * @param {*} _listener a callback to receive logging calls. Can be used to send calls elsewhere, such as escalate errors. + */ + constructor(_name, appenderProvider) { + this._name = _name || this._getCallerDetails("", 3).fileName.replace(/\.[^/.]+$/, "") + this.appenderProvider = appenderProvider; + this._logger = Java.type("org.slf4j.LoggerFactory").getLogger(LOGGER_PREFIX + "." + this.name.toString().toLowerCase()); + } + + /** + * Method to determine caller. Don't use directly. + * + * @private + * @param {Object} msg the message to get caller details for + * @param {Number} ignoreStackDepth the number of stack frames which to ignore in calculating caller + * @returns {Error} message as an error object, with fileName, caller and optional lineNumber properties + */ + _getCallerDetails(msg, ignoreStackDepth) { + let stackLine = null; + + if (!(msg instanceof Error)) { + msg = Error(msg); + stackLine = msg.stack.split('\n')[ignoreStackDepth]; + } else { + stackLine = msg.stack.split('\n')[1]; + } + + //pick out the call, fileName & lineNumber from the specific frame + let match = stackLine.match(/^\s+at\s*(?[^ ]*) \(?(?[^:]+):(?[0-9]+):[0-9]+\)?/); + + if (match) { + Object.assign(msg, match.groups); + } else { //won't match an 'eval'd string, so retry + match = stackLine.match(/\s+at\s+\:(?[0-9]+):[0-9]+/) + if (match) { + Object.assign(msg, { + fileName: "", + caller: "" + }, match.groups) + } else { + Object.assign(msg, { + fileName: "", + caller: "" + }) + } //throw Error(`Failed to parse stack line: ${stackLine}`); + } + + return msg; + } + + /** + * Method to format a log message. Don't use directly. + * + * @private + * @param {Object} msg the message to get caller details for + * @param {String} levelString the level being logged at + * @param {Number} ignoreStackDepth the number of stack frames which to ignore in calculating caller + * @param {String} [prefix=log] the prefix type, such as none, level, short or log. + * @returns {Error} message with 'message' String property + */ + _formatLogMessage(msg, levelString, ignoreStackDepth, prefix = "log") { + + let clazz = this; + let msgData = { + message: msg.toString(), + get caller() {//don't run this unless we need to, then cache it + this.cached = this.cached || clazz._getCallerDetails(msg, ignoreStackDepth) + return this.cached; + } + }; + + levelString = levelString.toUpperCase(); + + switch (prefix) { + case "none": return msgData.message; + case "level": return `[${levelString}] ${msgData.message}` + case "short": return `${msgData.message}\t\t[${this.name}, ${msgData.caller.fileName}:${msgData.caller.lineNumber}]` + case "log": return `${msgData.message}\t\t[${this.name} at source ${msgData.caller.fileName}, line ${msgData.caller.lineNumber}]` + default: throw Error(`Unknown prefix type ${prefix}`) + } + } + + /** + * Logs at ERROR level. + * @see atLevel + */ + error() { this.atLevel('error', ...arguments) } + /** + * Logs at ERROR level. + * @see atLevel + */ + warn() { this.atLevel('warn', ...arguments) } + /** + * Logs at INFO level. + * @see atLevel + */ + info() { this.atLevel('info', ...arguments) } + /** + * Logs at DEBUG level. + * @see atLevel + */ + debug() { this.atLevel('debug', ...arguments) } + /** + * Logs at TRACE level. + * @see atLevel + */ + trace() { this.atLevel('trace', ...arguments) } + + /** + * Logs a message at the supplied level. The message may include placeholders {} which + * will be substituted into the message string only if the message is actually logged. + * + * @example + * log.atLevel('INFO', 'The widget was created as {}', widget); + * + * + * @param {String} level The level at which to log, such as 'INFO', or 'DEBUG' + * @param {String|Error} msg the message to log, possibly with object placeholders + * @param {Object[]} [objects] the objects to substitute into the log message + */ + atLevel(level, msg, ...objects) { + let titleCase = level[0].toUpperCase() + level.slice(1) + try { + if (this._logger[`is${titleCase}Enabled`]()) { + + this.maybeLogWithThrowable(level, msg, objects) || + this.writeLogLine(level, this._formatLogMessage(msg, level, 6), objects); + } + } catch (err) { + this._logger.error(this._formatLogMessage(err, "error", 0)); + } + } + + maybeLogWithThrowable(level, msg, objects) { + if(objects.length === 1){ + let obj = objects[0]; + if((obj instanceof Error || (obj.message && obj.name && obj.stack)) && !msg.includes("{}")) { //todo: better substitution detected + //log the basic message + this.writeLogLine(level, msg, objects); + + //and log the exception + this.writeLogLine(level, `${obj.name} : ${obj.message}\n${obj.stack}`); + return true; + } + } + return false; + } + + writeLogLine(level, message, objects = []) { + let formatted = MessageFormatter.arrayFormat(message, objects).getMessage(); + + this._logger[level](formatted); + + if (this.appenderProvider) { + let appender = this.appenderProvider(level); + if(appender != null) { + appender.logAt(level, formatted) + } + } + } + + /** + * The listener function attached to this logger. + * @return {*} the listener function + */ + get listener() { return this._listener } + + /** + * The name of this logger + * @return {String} the logger name + */ + get name() { return this._name } +} + +let appenderForLevel = null +//attempt to load & cache appender as module +let getAppenderForLevel = function(){ + if(appenderForLevel === null) { + appenderForLevel = () => null; + + // try { + // appenderForLevel = require('log_appenders').forLevel; + // } catch(e) { + // new Logger("log", () => null).debug("No appenders found for log", e); + // } + } + + return appenderForLevel; +} + +/** + * Creates a logger. + * @see Logger + * @name default + * @param {string} name the name of the logger + * @param {*} [_listener] an optional listener to process log events. + * @memberof log + */ +module.exports = function (_name, appenderProvider = getAppenderForLevel()) { + return new Logger(_name, appenderProvider); +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js new file mode 100644 index 000000000000..37f54b6d722a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js @@ -0,0 +1,36 @@ +const { AbstractProvider } = require('../provider'); + +const METADATA_PROVIDER_CLASS = "org.eclipse.smarthome.core.items.MetadataProvider"; + +class StaticCallbackMetadataProvider extends AbstractProvider { + constructor(){ + super(METADATA_PROVIDER_CLASS); + this.metadataCallbacks = []; + } + + addProviderChangeListener(listener) { + } + + removeProviderChangeListener(listener) { + } + + addMetadataCallback(callback) { + this.metadataCallbacks.push(callback); + } + + getAll(){ + require('../log')('metadata-provider').debug("///"+this.metadataCallbacks.length); + require('../log')('metadata-provider').debug("///"+this.metadataCallbacks.flatMap(c => c()).length); + + for(let x of this.metadataCallbacks.flatMap(c => c())) { + require('../log')('metadata-provider').debug(x); + } + + return utils.jsArrayToJavaList(this.metadataCallbacks.flatMap(c => c())); + } +} + +module.exports = { + staticCallbackMetadataProvider: () => new StaticCallbackMetadataProvider() + +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js new file mode 100644 index 000000000000..19c15a0288cd --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js @@ -0,0 +1,76 @@ +/** + * Items' metadata namespace. + * This namespace provides access to metadata on items. + * + * @private + * @namespace metadata + */ + +const osgi = require('../osgi'); +const utils = require('../utils'); +const log = require('../log')('metadata'); + +let MetadataRegistry = osgi.getService("org.openhab.core.items.MetadataRegistry", "org.eclipse.smarthome.core.items.MetadataRegistry"); +let Metadata = utils.typeWithFallback("org.openhab.core.items.Metadata", "org.eclipse.smarthome.core.items.Metadata"); +let MetadataKey = utils.typeWithFallback("org.openhab.core.items.MetadataKey", "org.eclipse.smarthome.core.items.MetadataKey"); + + +/** + * This function will return the Metadata object associated with the + * specified Item. + * + * @memberof metadata + * @param {String} name of the Item + * @param {String} namespace name of the namespace + * @returns {String|null} the metadata as a string, or null + */ +let getValue = function(itemName, namespace) { + let result = MetadataRegistry.get(new MetadataKey(namespace, itemName)); + return result ? result.value : null; +}; + +let addValue = function(itemName, namespace, value) { + let key = new MetadataKey(namespace, itemName); + MetadataRegistry.add(new Metadata(key, value, {})); +} + +let updateValue = function(itemName, namespace, value) { + let metadata = createMetadata(itemName, namespace, value); + let result = MetadataRegistry.update(metadata); + return result ? result.value : null; +} + +/** + * Adds (inserts) or updates a metadata value. + * + * @param {String} itemName the name of the item + * @param {String} namespace the name of the namespace + * @param {String} value the value to insert or update + * @returns {Boolean} true if the value was added, false if it was updated + */ +let upsertValue = function(itemName, namespace, value) { + let existing = getValue(itemName, namespace); + + if (existing === null) { + addValue(itemName, namespace, value); + return true; + } else { + updateValue(itemName, namespace, value); + return false; + } +} + +let createMetadata = function(itemName, namespace, value) { + log.debug("Creating metadata {}:{} = {}", namespace, itemName, value); + let key = new MetadataKey(namespace, itemName); + return new Metadata(key, value, {}); +} + +module.exports = { + getValue, + addValue, + updateValue, + upsertValue, + createMetadata, + provider: require('./metadata-provider') +}; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json b/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json new file mode 100644 index 000000000000..affb9fbb7d11 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json @@ -0,0 +1,5 @@ +{ + "name": "metadata", + "version": "0.0.1", + "main": "metadata.js" +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/osgi.js b/bundles/org.openhab.automation.jsscripting/javascript/osgi.js new file mode 100644 index 000000000000..deba53534478 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/osgi.js @@ -0,0 +1,138 @@ +/** + * OSGi module. + * This module provides access to OSGi services. + * + * @namespace osgi + */ + +const log = require('./log')('osgi'); +const bundleContext = require('@runtime/osgi').bundleContext; +const lifecycle = require('@runtime/osgi').lifecycle; +const Hashtable = Java.type('java.util.Hashtable'); + +/** + * Map of interface names to sets of services registered (by this module) + */ +let registeredServices = {}; + + +let jsObjectToHashtable = function(obj) { + if(obj === null) { + return null; + } + + let rv = new Hashtable(); + for(let k in obj) { + rv.put(k, obj[k]); + } + return rv; +} + +/** + * Gets a service registered with OSGi. + * + * @private + * @param {String|HostClass} classOrName the class of the service to get + * @returns an instance of the service, or null if it cannot be found + * @memberOf osgi + */ +let lookupService = function (classOrName) { + var bc = bundleContext; + if(bundleContext === undefined) { + log.warn("bundleContext is undefined"); + var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil"); + var _bundle = FrameworkUtil.getBundle(scriptExtension.class); + bc = (_bundle !== null) ? _bundle.getBundleContext() : null; + } + if (bc !== null) { + var classname = (typeof classOrName === "object") ? classOrName.getName() : classOrName; + var ref = bc.getServiceReference(classname); + return (ref !== null) ? bc.getService(ref) : null; + } +} + +/** + * Gets a service registered with OSGi. Allows providing multiple classes/names to try for lookup. + * + * @param {Array} classOrNames the class of the service to get + * + * @returns an instance of the service, or null if it cannot be found + * @throws {Error} if no services of the requested type(s) can be found + * @memberOf osgi + */ +let getService = function (...classOrNames) { + let rv = null; + + for(let classOrName of classOrNames) { + try { + rv = lookupService(classOrName) + } catch(e) { + log.warn(`Failed to get service ${classOrName}: {}`, e); + } + + if(typeof rv !== 'undefined' && rv !== null) { + return rv; + } + } + + throw Error(`Failed to get any services of type(s): ${classOrNames}`); +} + +/** + * Finds services registered with OSGi. + * + * @param {String} className the class of the service to get + * @param {*} [filter] an optional filter used to filter the returned services + * @returns {Object[]} any instances of the service that can be found + * @memberOf osgi + */ +let findServices = function (className, filter) { + if (bundleContext !== null) { + var refs = bundleContext.getAllServiceReferences(className, filter); + return refs != null ? [...refs].map(ref => bundleContext.getService(ref)) : []; + } +} + +let registerService = function(service, ...interfaceNames) { + lifecycle.addDisposeHook(() => unregisterService(service)); + registerPermanentService(service, interfaceNames, null); +} + +let registerPermanentService = function(service, interfaceNames, properties = null) { + + let registration = bundleContext.registerService(interfaceNames, service, jsObjectToHashtable(properties)); + + for (let interfaceName of interfaceNames) { + if(typeof registeredServices[interfaceName] === 'undefined') { + registeredServices[interfaceName] = new Set(); + } + registeredServices[interfaceName].add({service, registration}); + log.debug("Registered service {} of as {}", service, interfaceName) + } + return registration; +} + +let unregisterService = function(serviceToUnregister) { + + log.debug("Unregistering service {}", serviceToUnregister); + + for(let interfaceName in registeredServices) { + let servicesForInterface = registeredServices[interfaceName]; + + servicesForInterface.forEach(({service, registration}) => { + if (service == serviceToUnregister) { + servicesForInterface.delete({service, registration}); + registration.unregister(); + log.debug("Unregistered service: {}", service); + } + }); + } +} + +module.exports = { + getService, + findServices, + registerService, + registerPermanentService, + unregisterService +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json b/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json new file mode 100644 index 000000000000..c97872c9af0d --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json @@ -0,0 +1,3557 @@ +{ + "name": "oh", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", + "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.4", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/generator": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", + "requires": { + "@babel/types": "^7.7.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", + "requires": { + "@babel/types": "^7.7.4" + } + }, + "@babel/helpers": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", + "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", + "requires": { + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", + "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==" + }, + "@babel/polyfill": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.7.0.tgz", + "integrity": "sha512-/TS23MVvo34dFmf8mwCisCbWGrfhbiWZSwBo6HkADTBhUa2Q/jWltyY/tpofz/b6/RIhqaqQcquptCirqIhOaQ==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } + } + }, + "@babel/runtime": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", + "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } + } + }, + "@babel/template": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" + } + }, + "@babel/traverse": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", + "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", + "dev": true + }, + "@types/babel-types": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", + "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==" + }, + "@types/babylon": { + "version": "6.16.5", + "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz", + "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==", + "requires": { + "@types/babel-types": "*" + } + }, + "@types/eslint": { + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", + "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "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/node": { + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "dev": true + }, + "@webpack-cli/info": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "dev": true + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "^4.0.4" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "ast-types": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.12.4.tgz", + "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "better-docs": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/better-docs/-/better-docs-1.4.7.tgz", + "integrity": "sha512-LQjdTcZT+G4IG6LihCtQqnGChghBRVy63f91YDFK8+ggPlVPt10mXEZTHwE56PMlisKlVb/1Ky6V+dZOoJ+qVw==", + "requires": { + "brace": "^0.11.1", + "react-ace": "^6.5.0", + "react-docgen": "^4.1.1", + "react-frame-component": "^4.1.1", + "underscore": "^1.9.1", + "vue-docgen-api": "^3.22.0", + "vue2-ace-editor": "^0.0.13" + } + }, + "bluebird": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", + "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz", + "integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "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 + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^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 + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001269", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", + "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "dev": true + }, + "catharsis": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", + "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "requires": { + "is-regex": "^1.0.3" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "requires": { + "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==" + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "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==", + "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=" + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "compare-module-exports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", + "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", + "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=" + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constantinople": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", + "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", + "requires": { + "@types/babel-types": "^7.0.0", + "@types/babylon": "^6.16.2", + "babel-types": "^6.26.0", + "babylon": "^6.18.0" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "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==" + } + } + }, + "core-js": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", + "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cronstrue": { + "version": "1.84.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.84.0.tgz", + "integrity": "sha512-yfQowBKKZGCZ6Ia2zlpDKhT7Eq4Lq4gzFBmJTrHMNgZh+vkSvmI6NtCvXR21JM00tp6afyY04VEgHaaqlE9oIg==" + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diff-match-patch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz", + "integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.872", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.872.tgz", + "integrity": "sha512-qG96atLFY0agKyEETiBFNhpRLSXGSXOBuhXWpbkYqrLKKASpRyRBUtfkn0ZjIf/yXfA7FA4nScVOMpXSHFlUCQ==", + "dev": true + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + } + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "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" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "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==" + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "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-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 + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "fill-keys": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", + "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", + "dev": true, + "requires": { + "is-object": "~1.0.1", + "merge-descriptors": "~1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "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": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "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 + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", + "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", + "requires": { + "acorn": "~4.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "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-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jest-worker": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", + "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "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" + } + } + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "js2xmlparser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", + "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.0" + } + }, + "jsdoc": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", + "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", + "dev": true, + "requires": { + "@babel/parser": "^7.4.4", + "bluebird": "^3.5.4", + "catharsis": "^0.8.11", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.0", + "klaw": "^3.0.0", + "markdown-it": "^8.4.2", + "markdown-it-anchor": "^5.0.2", + "marked": "^0.7.0", + "mkdirp": "^0.5.1", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.0.1", + "taffydb": "2.6.2", + "underscore": "~1.9.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "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 + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + } + } + }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", + "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==", + "dev": true + }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "dev": true + }, + "mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dev": true, + "requires": { + "mime-db": "1.50.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minami": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/minami/-/minami-1.2.3.tgz", + "integrity": "sha1-mbbc37LwpU2hycj3qjoyd4eq+fg=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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==" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", + "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.0", + "yargs-parser": "13.1.1", + "yargs-unparser": "1.6.0" + } + }, + "module-not-found-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", + "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "requires": { + "minimatch": "^3.0.2" + } + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node-releases": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.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 + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-duration": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", + "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "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-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" + } + }, + "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 + } + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proxyquire": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", + "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", + "dev": true, + "requires": { + "fill-keys": "^1.0.2", + "module-not-found-error": "^1.0.1", + "resolve": "^1.11.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pug": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz", + "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==", + "requires": { + "pug-code-gen": "^2.0.2", + "pug-filters": "^3.1.1", + "pug-lexer": "^4.1.0", + "pug-linker": "^3.0.6", + "pug-load": "^2.0.12", + "pug-parser": "^5.0.1", + "pug-runtime": "^2.0.5", + "pug-strip-comments": "^1.0.4" + } + }, + "pug-attrs": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", + "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", + "requires": { + "constantinople": "^3.0.1", + "js-stringify": "^1.0.1", + "pug-runtime": "^2.0.5" + } + }, + "pug-code-gen": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz", + "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==", + "requires": { + "constantinople": "^3.1.2", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.1", + "pug-attrs": "^2.0.4", + "pug-error": "^1.3.3", + "pug-runtime": "^2.0.5", + "void-elements": "^2.0.1", + "with": "^5.0.0" + } + }, + "pug-error": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", + "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==" + }, + "pug-filters": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz", + "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==", + "requires": { + "clean-css": "^4.1.11", + "constantinople": "^3.0.1", + "jstransformer": "1.0.0", + "pug-error": "^1.3.3", + "pug-walk": "^1.1.8", + "resolve": "^1.1.6", + "uglify-js": "^2.6.1" + } + }, + "pug-lexer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz", + "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==", + "requires": { + "character-parser": "^2.1.1", + "is-expression": "^3.0.0", + "pug-error": "^1.3.3" + } + }, + "pug-linker": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz", + "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==", + "requires": { + "pug-error": "^1.3.3", + "pug-walk": "^1.1.8" + } + }, + "pug-load": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", + "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", + "requires": { + "object-assign": "^4.1.0", + "pug-walk": "^1.1.8" + } + }, + "pug-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz", + "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==", + "requires": { + "pug-error": "^1.3.3", + "token-stream": "0.0.1" + } + }, + "pug-runtime": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", + "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==" + }, + "pug-strip-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", + "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", + "requires": { + "pug-error": "^1.3.3" + } + }, + "pug-walk": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", + "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "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" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "react-ace": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-6.6.0.tgz", + "integrity": "sha512-Jehhp8bxa8kqiXk07Jzy+uD5qZMBwo43O+raniGHjdX7Qk93xFkKaAz8LxtUVZPJGlRnV5ODMNj0qHwDSN+PBw==", + "requires": { + "@babel/polyfill": "^7.4.4", + "brace": "^0.11.1", + "diff-match-patch": "^1.0.4", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "prop-types": "^15.7.2" + } + }, + "react-docgen": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-4.1.1.tgz", + "integrity": "sha512-o1wdswIxbgJRI4pckskE7qumiFyqkbvCO++TylEDOo2RbMiueIOg8YzKU4X9++r0DjrbXePw/LHnh81GRBTWRw==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/runtime": "^7.0.0", + "async": "^2.1.4", + "commander": "^2.19.0", + "doctrine": "^3.0.0", + "node-dir": "^0.1.10", + "recast": "^0.17.3" + } + }, + "react-frame-component": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.1.tgz", + "integrity": "sha512-NfJp90AvYA1R6+uSYafQ+n+UM2HjHqi4WGHeprVXa6quU9d8o6ZFRzQ36uemY82dlkZFzf2jigFx6E4UzNFajA==" + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.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 + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "recast": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.17.6.tgz", + "integrity": "sha512-yoQRMRrK1lszNtbkGyM4kN45AwylV5hMiuEveUBlxytUViWevjvX6w+tzJt1LH4cfUhWt4NZvy3ThIhu6+m5wQ==", + "requires": { + "ast-types": "0.12.4", + "esprima": "~4.0.0", + "private": "^0.1.8", + "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==" + } + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "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 + }, + "requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.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 + }, + "rewiremock": { + "version": "3.13.9", + "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.13.9.tgz", + "integrity": "sha512-FDk5uCyvfwgYZtZ9MKdpg6QiSSdjB/a/vU5luKjoJddaqcZz5+u4dXhc3Qf4vNMvDXvnOyodNd1riE5yeqoxaA==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "compare-module-exports": "^2.1.0", + "lodash.some": "^4.6.0", + "lodash.template": "^4.4.0", + "node-libs-browser": "^2.1.0", + "path-parse": "^1.0.5", + "wipe-node-cache": "^2.1.0", + "wipe-webpack-cache": "^2.1.0" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "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 + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "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.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", + "dev": true, + "requires": { + "jest-worker": "^27.0.6", + "p-limit": "^3.1.0", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "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=" + }, + "token-stream": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", + "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" + }, + "ts-map": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-map/-/ts-map-1.0.3.tgz", + "integrity": "sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typescript": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", + "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" + }, + "vue-docgen-api": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-3.26.0.tgz", + "integrity": "sha512-ujdg4i5ZI/wE46RZQMFzKnDGyhEuPCu+fMA86CAd9EIek/6+OqraSVBm5ZkLrbEd5f8xxdnqMU4yiSGHHeao/Q==", + "requires": { + "@babel/parser": "^7.2.3", + "@babel/types": "^7.0.0", + "ast-types": "^0.12.2", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.5", + "pug": "^2.0.3", + "recast": "^0.17.3", + "ts-map": "^1.0.3", + "typescript": "^3.2.2", + "vue-template-compiler": "^2.0.0" + } + }, + "vue-template-compiler": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", + "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==", + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "vue2-ace-editor": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/vue2-ace-editor/-/vue2-ace-editor-0.0.13.tgz", + "integrity": "sha512-uQICyvJzYNix16xeYjNAINuNUQhPbqMR7UQsJeI+ycpEd2otsiNNU73jcZqHkpjuz0uaHDHnrpzQuI/RApsKXA==", + "requires": { + "brace": "^0.11.0" + } + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.58.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.58.2.tgz", + "integrity": "sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^3.2.0" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", + "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.0", + "@webpack-cli/info": "^1.4.0", + "@webpack-cli/serve": "^1.6.0", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", + "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "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 + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wipe-node-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.0.tgz", + "integrity": "sha512-Vdash0WV9Di/GeYW9FJrAZcPjGK4dO7M/Be/sJybguEgcM7As0uwLyvewZYqdlepoh7Rj4ZJKEdo8uX83PeNIw==", + "dev": true + }, + "wipe-webpack-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", + "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", + "dev": true, + "requires": { + "wipe-node-cache": "^2.1.0" + } + }, + "with": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", + "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", + "requires": { + "acorn": "^3.1.0", + "acorn-globals": "^3.0.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xmlcreate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", + "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.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": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, + "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/bundles/org.openhab.automation.jsscripting/javascript/package.json b/bundles/org.openhab.automation.jsscripting/javascript/package.json new file mode 100644 index 000000000000..f94b7f16b666 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/package.json @@ -0,0 +1,32 @@ +{ + "name": "oh", + "version": "0.1.0", + "description": "JavaScript Library for openHAB", + "private": false, + "license": "EPL-2.0", + "main": "dist/oh.js", + "repository": { + "type": "git", + "url": "git://github.com/jpg0/ohj.git" + }, + "dependencies": { + "better-docs": "^1.4.7", + "cronstrue": "^1.84.0", + "parse-duration": "^0.1.1", + "minimist": "^1.2.5" + }, + "scripts": { + "test": "mocha", + "docs": "./node_modules/.bin/jsdoc --configure docs_config.json", + "deploy": "npm test && npm run docs" + }, + "devDependencies": { + "jsdoc": "^3.6.3", + "minami": "^1.2.3", + "mocha": "^6.2.2", + "proxyquire": "^2.1.3", + "rewiremock": "^3.13.9", + "webpack": "^5.58.2", + "webpack-cli": "^4.9.1" + } +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/provider.js b/bundles/org.openhab.automation.jsscripting/javascript/provider.js new file mode 100644 index 000000000000..02021271f44d --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/provider.js @@ -0,0 +1,116 @@ +const osgi = require('./osgi'); +const log = require('./log')('provider'); +const utils = require('./utils'); + +function getAllFunctionNames(obj) { + var props = []; + var o = obj; + do { + props = props.concat(Object.getOwnPropertyNames(o)); + o = Object.getPrototypeOf(o); + } while (o.constructor.name !== 'AbstractProvider'); + + return props.filter(p => typeof obj[p] === 'function'); +} + +class AbstractProvider { + constructor(type) { + this.typeName = type.class.getName(); + this.javaType = Java.extend(type);//require('@runtime/osgi').classutil.extend(type); + } + + register() { + let javaConfig = {}; + + let functionNamesToBind = getAllFunctionNames(this). + filter(f => f !== 'constructor'). + filter(f => f !== 'javaType'); + + for(let fn of functionNamesToBind) { + javaConfig[fn] = this[fn].bind(this); + } + + let hostProvider = this.processHostProvider(new this.javaType(javaConfig)); + + this.hostProvider = hostProvider; + + osgi.registerService(this.hostProvider, this.typeName); + } + + processHostProvider(hostProvider) { + return hostProvider; + } +} + +class CallbackProvider extends AbstractProvider { + constructor(type){ + super(type); + this.callbacks = []; + } + + addProviderChangeListener(listener) { + } + + removeProviderChangeListener(listener) { + } + + addCallback(callback) { + this.callbacks.push(callback); + } + + getAll(){ + log.debug(`Providing ${utils.jsArrayToJavaList(this.callbacks.flatMap(c => c())).length} for ${this.typeName}`) + return utils.jsArrayToJavaList(this.callbacks.flatMap(c => c())); + } +} + +class ItemProvider extends CallbackProvider { + constructor(ctxName = "JSAPI") { + super(utils.typeBySuffix('core.items.ItemProvider')) + this.ctxName = ctxName; + } + + processHostProvider(hostProvider) { + return require('@runtime/provider').itemBinding.create(this.ctxName, super.processHostProvider(hostProvider)); + } +} + +class StateDescriptionFragmentProvider extends AbstractProvider { + constructor() { + super(utils.typeBySuffix('core.types.StateDescriptionFragmentProvider')); + this.callbacks = []; + } + + addCallback(callback) { + this.callbacks.push(callback); + } + + getStateDescriptionFragment(itemName, locale) { + for(let c of this.callbacks) { + let result = c(itemName, locale); + if(typeof result !== 'undefined') { + return result; + } + } + + return null; + } + + getRank() { + return 0; + } + +} + +let ItemChannelLinkProviderClass = utils.typeBySuffix('core.thing.link.ItemChannelLinkProvider'); +let MetadataProviderClass = utils.typeBySuffix('core.items.MetadataProvider'); +let ThingProviderClass = utils.typeBySuffix('core.thing.ThingProvider'); + +module.exports = { + AbstractProvider, + newCallbackItemChannelLinkProvider: () => new CallbackProvider(ItemChannelLinkProviderClass), + newCallbackMetadataProvider: () => new CallbackProvider(MetadataProviderClass), + newCallbackItemProvider: c => new ItemProvider(c), + newCallbackThingProvider: () => new CallbackProvider(ThingProviderClass), + newCallbackStateDescriptionFragmentProvider: () => new StateDescriptionFragmentProvider +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/rules.js b/bundles/org.openhab.automation.jsscripting/javascript/rules.js new file mode 100644 index 000000000000..53c181966ba8 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/rules.js @@ -0,0 +1,285 @@ + +/** + * Rules namespace. + * This namespace allows creation of Openhab rules. + * + * @namespace rules + */ + +const GENERATED_RULE_ITEM_TAG = "GENERATED_RULE_ITEM"; + +const items = require('./items'); +const utils = require('./utils'); +const log = require('./log')('rules'); +const itemhistory = require('./itemhistory'); +const osgi = require('./osgi'); +const triggers = require('./triggers'); +const { automationManager } = require('@runtime/RuleSupport'); + +let RuleManager = osgi.getService("org.openhab.core.automation.RuleManager","org.eclipse.smarthome.automation.RuleManager"); + +/** + * Generates an item name given it's configuration. + * + * @memberOf rules + * @private + * @param {Object} ruleConfig The rule config + * @param {String} userInfo.name The name of the rule. + */ +const itemNameForRule = function (ruleConfig) { + return "vRuleItemFor" + items.safeItemName(ruleConfig.name); +} + +/** + * Links an item to a rule. When the item is switched on or off, so will the rule be. + * + * @memberOf rules + * @private + * @param {HostRule} rule The rule to link to the item. + * @param {OHItem} item the item to link to the rule. + */ +const linkItemToRule = function (rule, item) { + JSRule({ + name: "vProxyRuleFor" + rule.getName(), + description: "Generated Rule to toggle real rule for " + rule.getName(), + triggers: [ + triggers.ItemStateUpdateTrigger(item.name) + ], + execute: function (data) { + try { + var itemState = data.state; + log.debug("Rule toggle item state received as " + itemState); + RuleManager.setEnabled(rule.getUID(), itemState == 'OFF' ? false : true); + log.info((itemState == 'OFF' ? "Disabled" : "Enabled") + " rule " + rule.getName() + " [" + rule.getUID() + "]"); + } catch (e) { + log.error("Failed to toggle rule " + rule.getName() + ": " + e); + } + } + }); +}; + +/** + * Gets the groups that an rule-toggling-item should be a member of. Will create the group item if necessary. + * + * @memberOf rules + * @private + * @param {Object} ruleConfig The rule config describing the rule + * @param {String} ruleConfig.ruleGroup the name of the rule group to use. + * @returns {String[]} the group names to put the item in + */ +const getGroupsForItem = function (ruleConfig) { + if (ruleConfig.ruleGroup) { + var groupName = "gRules" + items.safeItemName(ruleConfig.ruleGroup); + log.debug("Creating rule group " + ruleConfig.ruleGroup); + items.replaceItem(groupName, "Group", null, ["gRules"], ruleConfig.ruleGroup, [GENERATED_RULE_ITEM_TAG]); + return [groupName]; + } + + return ["gRules"]; +} + +/** + * Creates a rule. The rule will be created and immediately available. + * + * @example + * import { rules, triggers } = require('ohj'); + * + * rules.JSRule({ + * name: "my_new_rule", + * description": "this rule swizzles the swallows", + * triggers: triggers.GenericCronTrigger("0 30 16 * * ? *"), + * execute: triggerConfig => { //do stuff } + * }); + * + * @memberOf rules + * @param {Object} ruleConfig The rule config describing the rule + * @param {String} ruleConfig.name the name of the rule + * @param {String} ruleConfig.description a description of the rule + * @param {*} ruleConfig.execute callback that will be called when the rule fires + * @param {HostTrigger[]} ruleConfig.triggers triggers which will define when to fire the rule + * @returns {HostRule} the created rule + */ +let JSRule = function (ruleConfig) { + let ruid = ruleConfig.id || ruleConfig.name.replace(/[^\w]/g, "-") + "-" + utils.randomUUID(); + let ruTemplateid = ruleConfig.name.replace(/[^\w]/g, "-") + "-" + utils.randomUUID(); + log.info("Adding rule: {}", ruleConfig.name ? ruleConfig.name : ruid); + + let SimpleRule = Java.extend(Java.type('org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule')); + + let doExecute = function (module, input) { + try { + return ruleConfig.execute(getTriggeredData(input)); + } catch (error) { + log.error(`Failed to execute rule ${ruid}: ${error}: ${error.stack}`); + throw error; + } + }; + + var rule = new SimpleRule({ + execute: doExecute, + getUID: () => ruid + }); + + var triggers = ruleConfig.triggers ? ruleConfig.triggers : ruleConfig.getEventTrigger(); + + rule.setTemplateUID(ruTemplateid); + + if (ruleConfig.description) { + rule.setDescription(ruleConfig.description); + } + if (ruleConfig.name) { + rule.setName(ruleConfig.name); + } + + //Register rule here + if (triggers && triggers.length > 0) { + rule.setTriggers(triggers); + rule = registerRule(rule); + } + + return rule; +}; + +let currentProvider = automationManager; + +let withManagedProvider = function(fn) { + let previousProvider = currentProvider; + currentProvider = automationManager; + + try { + fn(); + } finally { + currentProvider = previousProvider; + } +} + +let registerRule = function(rule) { + return currentProvider.addRule(rule); +} + +/** + * Creates a rule, with an associated SwitchItem that can be used to toggle the rule's enabled state. + * The rule will be created and immediately available. + * + * @memberOf rules + * @param {Object} ruleConfig The rule config describing the rule + * @param {String} ruleConfig.name the name of the rule + * @param {String} ruleConfig.description a description of the rule + * @param {*} ruleConfig.execute callback that will be called when the rule fires + * @param {HostTrigger[]} ruleConfig.triggers triggers which will define when to fire the rule + * @param {String} ruleConfig.ruleGroup the name of the rule group to use. + * @returns {HostRule} the created rule + */ +let SwitchableJSRule = function (ruleConfig) { + + if (!ruleConfig.name) { + throw Error("No name specified for rule!"); + } + + //first create a toggling item + var itemName = itemNameForRule(ruleConfig); + + //then add the item + var item = items.replaceItem(itemName, "Switch", null, getGroupsForItem(ruleConfig), ruleConfig.description, [GENERATED_RULE_ITEM_TAG]); + + //create the real rule + var rule = JSRule(ruleConfig); + + //hook up a rule to link the item to the actual rule + linkItemToRule(rule, item); + + if (item.isUninitialized) { + //possibly load item's prior state + let historicState = itemhistory.latestState(item); + + if (historicState !== null) { + item.postUpdate(historicState); + } else { + item.sendCommand('ON'); + } + } +} + +const getTriggeredData = function (input) { + let event = input.get('event'); + + if(event && Java.typeName(event.class) === 'org.eclipse.smarthome.core.items.events.ItemCommandEvent') { + return { + eventType: "command", + triggerType: "ItemCommandTrigger", + receivedCommand: event.getItemCommand(), + oldState: input.get("oldState") + "", + newState: input.get("newState") + "", + itemName: event.getItemName() + } + } + + var ev = event + ""; + //log.debug("event",ev.split("'").join("").split("Item ").join("").split(" ")); + var evArr = []; + if (ev.includes("triggered")) { + var atmp = ev.split(" triggered "); //astro:sun:local:astroDawn#event triggered START + evArr = [atmp[0], "triggered", atmp[1]]; + } else { + evArr = ev.split("'").join("").split("Item ").join("").split(" "); //Item 'benqth681_switch' received command ON + } + + var d = { + //size: input.size(), + oldState: input.get("oldState") + "", + newState: input.get("newState") + "", + state: input.get("state") + "", //this occurs on an ItemStateUpdateTrigger + receivedCommand: null, + receivedState: null, + receivedTrigger: null, + itemName: evArr[0] + }; + + try { + if (event !== null && event.getPayload()) { + d.payload = JSON.parse(event.getPayload()); + log.debug("Extracted event payload {}", JSON.stringify(d.payload)); + } + } catch (e) { + log.warn("Failed to extract payload: {}", e.message); + } + + switch (evArr[1]) { + case "received": + d.eventType = "command"; + d.triggerType = "ItemCommandTrigger"; + d.receivedCommand = input.get("command") + ""; + break; + case "updated": + d.eventType = "update"; + d.triggerType = "ItemStateUpdateTrigger"; + d.receivedState = input.get("state") + ""; + break; + case "changed": + d.eventType = "change"; + d.triggerType = "ItemStateChangeTrigger"; + break; + case "triggered": + d.eventType = "triggered"; + d.triggerType = "ChannelEventTrigger"; + d.receivedTrigger = evArr[2]; + break; + default: + if (input.size() == 0) { + d.eventType = "time"; + d.triggerType = "GenericCronTrigger"; + d.triggerTypeOld = "TimerTrigger"; + } else { + d.eventType = ""; + d.triggerType = ""; + } + } + + + return d; +}; + +module.exports = { + JSRule, + SwitchableJSRule +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js new file mode 100644 index 000000000000..54fa9836a793 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js @@ -0,0 +1,117 @@ +const assert = require('assert'); +var proxyquire = require('proxyquire').noCallThru(); + +describe('Conditionals', function () { + + const createLogMock = () => { + let messages = []; + + return { + messages, + mock:function(name){ + return { + error: a => messages.push(a) + } + } + }; + } + + function itemMock(nameToState) { + return { + getItem: function(name){ + return nameToState(name); + } + } + } + + describe('Function Conditions', function () { + it('Should pass when the function returns true', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock() + }); + + let conf = new condition_conf.FunctionConditionConf(() => true); + assert.strictEqual(conf.check(), true); + }); + + it('Should not pass when the function returns false', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock() + }); + + let conf = new condition_conf.FunctionConditionConf(() => false); + assert.strictEqual(conf.check(), false); + }); + }); + + describe('Item Conditions', function () { + it('Should pass when the item state matches', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + assert.strictEqual(name, 'myitem'); + return { + state: "mystate" + } + }) + }); + + let conf = new condition_conf.ItemStateConditionConf('myitem'); + + assert.strictEqual(conf.is('mystate').check(), true); + }); + + it('Should not pass when the item state doesnt matches', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + assert.strictEqual(name, 'myitem'); + return { + state: "mystate2" + } + }) + }); + + let conf = new condition_conf.ItemStateConditionConf('myitem'); + + assert.strictEqual(conf.is('mystate').check(), false); + }); + + it('Should not pass when the item doesnt exist', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + assert.strictEqual(name, 'myitem'); + return undefined; + }) + }); + + let conf = new condition_conf.ItemStateConditionConf('myitem'); + + assert.throws(() => conf.is('mystate').check(), {message: /myitem/}); + }); + + it('Should not pass when the item is null', function () { + + const condition_conf = proxyquire('../fluent/condition-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + assert.strictEqual(name, 'myitem'); + return null; + }) + }); + + let conf = new condition_conf.ItemStateConditionConf('myitem'); + + assert.throws(() => conf.is('mystate').check(), {message: /myitem/}); + }); + + }); +}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js new file mode 100644 index 000000000000..7a68abd3701e --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js @@ -0,0 +1,228 @@ +const assert = require('assert'); +var proxyquire = require('proxyquire').noCallThru(); + +describe('Operations', function () { + + const createLogMock = () => { + let messages = []; + + return { + messages, + mock:function(name){ + return { + error: a => messages.push(a) + } + } + }; + } + + function itemMock(nameToState) { + return { + getItem: function(name){ + return nameToState(name); + } + } + } + + describe('Copy State Operation', function () { + it('Should copy state via send when everything set up correctly', function (done) { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: "test1" + } + } else if(name == 'item2') { + return { + sendCommand: (state) => { + assert.strictEqual(state, "test1"); + done(); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + conf.fromItem('item1').toItem('item2')._run(); + }); + + it('Should copy state via update when everything set up correctly', function (done) { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: "test1" + } + } else if(name == 'item2') { + return { + postUpdate: (state) => { + assert.strictEqual(state, "test1"); + done(); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(false); + + conf.fromItem('item1').toItem('item2')._run(); + }); + + it('Should copy null state', function (done) { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: null + } + } else if(name == 'item2') { + return { + sendCommand: (state) => { + assert.strictEqual(state, null); + done(); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + conf.fromItem('item1').toItem('item2')._run(); + }); + + it('Should disallow omission of to item', function () { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: "test1" + } + } else if(name == 'item2') { + return { + sendCommand: (state) => { + assert.strictEqual(state, "test1"); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + assert.throws(() => conf.fromItem('item1')._run(), {message: /[Tt]o/}); + }); + + it('Should disallow omission of from item', function () { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: "test1" + } + } else if(name == 'item2') { + return { + sendCommand: (state) => { + assert.strictEqual(state, "test1"); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + assert.throws(() => conf.toItem('item1')._run(), {message: /[Ff]rom/}); + }); + + it('Should disallow omission of both items', function () { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return { + state: "test1" + } + } else if(name == 'item2') { + return { + sendCommand: (state) => { + assert.strictEqual(state, "test1"); + } + } + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + assert.throws(() => conf._run()); + }); + + it('Should tell you if from item doesnt exist', function () { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return undefined; + } else if(name == 'item2') { + return {} + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + assert.throws(() => conf.fromItem('item1').toItem('item2')._run(), {message: /item1/}); + }); + + it('Should tell you if to item doesnt exist', function () { + + const operation_conf = proxyquire('../fluent/operation-conf', { + '../log': createLogMock().mock, + '../items': itemMock((name) => { + if(name == 'item1') { + return {}; + } else if(name == 'item2') { + return undefined + } else { + assert.fail("wrong item requested " + name); + } + }) + }); + + let conf = new operation_conf.CopyStateOperation(true); + + assert.throws(() => conf.fromItem('item1').toItem('item2')._run(), {message: /item2/}); + }); + + }); +}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js b/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js new file mode 100644 index 000000000000..b8160046b19e --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js @@ -0,0 +1,7 @@ +// rewiremock.cjs.js +const rewiremock = require('rewiremock/node'); +/// settings +rewiremock.isolation(); + +//rewiremock.overrideEntryPoint(module); // this is important +module.exports = rewiremock; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js new file mode 100644 index 000000000000..215119ed89e8 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js @@ -0,0 +1,43 @@ +const assert = require('assert'); +var proxyquire = require('proxyquire').noCallThru(); + +describe('Triggers', function () { + + const createLogMock = () => { + let messages = []; + + return { + messages, + mock:function(name){ + return { + error: a => messages.push(a) + } + } + }; + } + + function triggersMock(lookup) { + return x => lookup(x); + } + + describe('Item Triggers', function () { + it('Should create correct item trigger', function (done) { + + const trigger_conf = proxyquire('../fluent/trigger-conf', { + '../log': createLogMock().mock, + '../triggers': { + ItemStateChangeTrigger: (name, from, to) => { + assert.strictEqual(name, 'item1'); + assert.strictEqual(from, undefined); + assert.strictEqual(to, 'state1'); + done(); + } + } + }); + + new trigger_conf.ItemTriggerConfig('item1').changed().to('state1')._toOHTriggers(); + }); + + }); + +}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/things/package.json b/bundles/org.openhab.automation.jsscripting/javascript/things/package.json new file mode 100644 index 000000000000..648b3c36318d --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/things/package.json @@ -0,0 +1,5 @@ +{ + "name": "things", + "version": "0.0.1", + "main": "things.js" +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/things/things.js b/bundles/org.openhab.automation.jsscripting/javascript/things/things.js new file mode 100644 index 000000000000..c485284a523a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/things/things.js @@ -0,0 +1,104 @@ +const utils = require('../utils'); + +const JavaThingBuilder = utils.typeBySuffix('core.thing.binding.builder.ThingBuilder'); +const ThingTypeUID = utils.typeBySuffix('core.thing.ThingTypeUID'); +const JavaChannelBuilder = utils.typeBySuffix('core.thing.binding.builder.ChannelBuilder'); +const ChannelUID = utils.typeBySuffix('core.thing.ChannelUID'); +const ThingUID = utils.typeBySuffix('core.thing.ThingUID'); +const ChannelKind = utils.typeBySuffix('core.thing.type.ChannelKind'); +const ChannelTypeUID = utils.typeBySuffix('core.thing.type.ChannelTypeUID'); +const Configuration = utils.typeBySuffix('core.config.core.Configuration'); + +class OHThing { + constructor(rawThing) { + this.rawThing = rawThing; + } +} + +class OHChannel { + constructor(rawChannel) { + this.rawChannel = rawChannel; + } + + get uid(){ + return this.rawChannel.getUID().toString(); + } +} + +class ThingBuilder { + constructor(thingTypeUID, thingId, bridgeUID) { + if(typeof thingTypeUID === 'string') { + thingTypeUID = new ThingTypeUID(...thingTypeUID.split(':')); + } + + this.thingTypeUID = thingTypeUID; + this.thingId = thingId; + + + if(typeof bridgeUID !== 'undefined') { + if(typeof bridgeUID === 'string') { + let [bridgeBindingId, bridgeThingTypeId, bringThingId] = bridgeUID.split(':'); + bridgeUID = new ThingUID(new ThingTypeUID(bridgeBindingId, bridgeThingTypeId), bringThingId); + } + this.thingUID = new ThingUID(thingTypeUID, bridgeUID, thingId); + this.rawBuilder = JavaThingBuilder.create(thingTypeUID, this.thingUID); + this.rawBuilder.withBridge(bridgeUID); + } else { + this.thingUID = new ThingUID(thingTypeUID, thingId); + this.rawBuilder = JavaThingBuilder.create(thingTypeUID, this.thingUID); + } + } + + withChannel(channel) { + this.rawBuilder.withChannel(channel.rawChannel); + return this; + } + + withLabel(label) { + this.rawBuilder.withLabel(label); + return this; + } + + build() { + return new OHThing(this.rawBuilder.build()); + } +} + +class ChannelBuilder { + constructor(thingUID, channelId, acceptedItemType) { + let channelUID = new ChannelUID(thingUID, channelId); + this.rawBuilder = JavaChannelBuilder.create(channelUID, acceptedItemType); + } + + withConfiguration(config){ + this.rawBuilder.withConfiguration(new Configuration(config)); + return this; + } + + withKind(stateOrTrigger){ + this.rawBuilder.withKind(ChannelKind.parse(stateOrTrigger)); + return this; + } + + withLabel(label){ + this.rawBuilder.withLabel(label); + return this; + } + + withType(channelType){ + if(typeof channelType === 'string') { + channelType = new ChannelTypeUID(channelType); + } + this.rawBuilder.withType(channelType); + return this; + } + + build(){ + return new OHChannel(this.rawBuilder.build()); + } +} + +module.exports = { + newThingBuilder: (thingTypeUID, id, bridgeUID) => new ThingBuilder(thingTypeUID, id, bridgeUID), + newChannelBuilder: (thingUID, channelId, acceptedItemType) => new ChannelBuilder(thingUID, channelId, acceptedItemType) +} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/triggers.js b/bundles/org.openhab.automation.jsscripting/javascript/triggers.js new file mode 100644 index 000000000000..50928c73203a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/triggers.js @@ -0,0 +1,153 @@ + +/** + * Triggers namespace. + * This namespace allows creation of Openhab rule triggers. + * + * @namespace triggers + */ + +const utils = require('./utils'); + +const ModuleBuilder = utils.typeWithFallback( + "org.eclipse.smarthome.automation.core.util.ModuleBuilder", + "org.openhab.core.automation.util.ModuleBuilder"); + +const Configuration = utils.typeBySuffix("config.core.Configuration"); + +/** + * Creates a trigger. Internal function, instead use predefined trigger types. + * + * @memberof triggers + * @private + * @param {String} typeString the type of trigger to create + * @param {String} [name] the name of the trigger + * @param {Configuration} config the trigger configuration + */ +let createTrigger = function(typeString, name, config) { + if(typeof name === 'undefined' || name === null) { + name = utils.randomUUID().toString(); + } + + return ModuleBuilder.createTrigger() + .withId(name) + .withTypeUID(typeString) + .withConfiguration(new Configuration(config)) + .build(); +} + +module.exports = { + + /** + * Creates a trigger that fires upon specific events in a channel. + * + * @example + * ChannelEventTrigger('astro:sun:local:rise#event', 'START') + * + * @name ChannelEventTrigger + * @memberof triggers + * @param {String} channel the name of the channel + * @param {String} event the name of the event to listen for + * @param {String} [triggerName] the name of the trigger to create + * + */ + ChannelEventTrigger: (channel, event, triggerName) => createTrigger("core.ChannelEventTrigger", triggerName, { + "channelUID": channel, + "event": event + }), + + /** + * Creates a trigger that fires upon an item changing state. + * + * @example + * ItemStateChangeTrigger('my_item', 'OFF', 'ON') + * + * @name ItemStateChangeTrigger + * @memberof triggers + * @param {String} itemName the name of the item to monitor for change + * @param {String} [oldState] the previous state of the item + * @param {String} [newState] the new state of the item + * @param {String} [triggerName] the name of the trigger to create + */ + ItemStateChangeTrigger: (itemName, oldState, newState, triggerName) => createTrigger("core.ItemStateChangeTrigger", triggerName, { + "itemName": itemName, + "state": newState, + "oldState": oldState + }), + + /** + * Creates a trigger that fires upon an item receiving a state update. Note that the item does not need to change state. + * + * @example + * ItemStateUpdateTrigger('my_item', 'OFF') + * + * @name ItemStateUpdateTrigger + * @memberof triggers + * @param {String} itemName the name of the item to monitor for change + * @param {String} [state] the new state of the item + * @param {String} [triggerName] the name of the trigger to create + */ + ItemStateUpdateTrigger: (itemName, state, triggerName) => createTrigger("core.ItemStateUpdateTrigger", triggerName, { + "itemName": itemName, + "state": state + }), + + /** + * Creates a trigger that fires upon an item receiving a command. Note that the item does not need to change state. + * + * @example + * ItemCommandTrigger('my_item', 'OFF') + * + * @name ItemCommandTrigger + * @memberof triggers + * @param {String} itemName the name of the item to monitor for change + * @param {String} [command] the command received + * @param {String} [triggerName] the name of the trigger to create + */ + ItemCommandTrigger: (itemName, command, triggerName) => createTrigger("core.ItemCommandTrigger", triggerName, { + "itemName": itemName, + "command": command + }), + + /** + * Creates a trigger that fires on a cron schedule. The supplied cron expression defines when the trigger will fire. + * + * @example + * GenericCronTrigger('0 30 16 * * ? *') + * + * @name GenericCronTrigger + * @memberof triggers + * @param {String} expression the cron expression defining the triggering schedule + */ + GenericCronTrigger: (expression, triggerName) => createTrigger("timer.GenericCronTrigger", triggerName, { + "cronExpression": expression + }), + + /** + * Creates a trigger that fires daily at a specific time. The supplied time defines when the trigger will fire. + * + * @example + * TimeOfDayTrigger('19:00') + * + * @name TimeOfDayTrigger + * @memberof triggers + * @param {String} time the time expression defining the triggering schedule + */ + TimeOfDayTrigger: (time, triggerName) => createTrigger("timer.TimeOfDayTrigger", triggerName, { + "time": time + }), + + /* not yet tested + ItemStateCondition: (itemName, state, triggerName) => createTrigger("core.ItemStateCondition", triggerName, { + "itemName": itemName, + "operator": "=", + "state": state + }), + + GenericCompareCondition: (itemName, state, operator, triggerName) => createTrigger("core.GenericCompareCondition", triggerName, { + "itemName": itemName, + "operator": operator,// matches, ==, <, >, =<, => + "state": state + }) + */ + createTrigger, +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/utils.js b/bundles/org.openhab.automation.jsscripting/javascript/utils.js new file mode 100644 index 000000000000..71b80c60695a --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/utils.js @@ -0,0 +1,133 @@ + +const log = require('./log')('utils'); + +const HashSet = Java.type("java.util.HashSet"); +const ArrayList = Java.type("java.util.ArrayList"); + +function getAllPropertyNames (obj) { + const proto = Object.getPrototypeOf(obj); + const inherited = (proto) ? getAllPropertyNames(proto) : []; + return [...new Set(Object.getOwnPropertyNames(obj).concat(inherited))]; +} + +let jsSetToJavaSet = function(set) { + let rv = new HashSet(); + + set.forEach(e => rv.add(e)); + + return rv; +} + +let jsArrayToJavaSet = function (arr) { + let set = new HashSet(); + + for (let i of arr) { + set.add(i); + } + + return set; +}; + +let jsArrayToJavaList = function (arr) { + let list = new ArrayList(); + + for (let i of arr) { + list.add(i); + } + + return list; +} + +let javaSetToJsArray = function(set) { + return Java.from(new ArrayList(set)); +} + +let javaSetToJsSet = function(set) { + return new Set(exports.javaSetToJsArray(set)); +} + +let randomUUID = () => Java.type("java.util.UUID").randomUUID(); + +let dumpObject = function (obj) { + try { + log.info("Dumping object..."); + log.info(" typeof obj = {}", (typeof obj)); + let isJavaObject = Java.isJavaObject(obj); + log.info(" Java.isJavaObject(obj) = {}", isJavaObject) + let isJavaType = Java.isType(obj); + log.info(" Java.isType(obj) = {}", isJavaType) + if (isJavaObject) { + if (isJavaType) { + log.info(" Java.typeName(obj) = {}", Java.typeName(obj)); + } else { + log.info(" Java.typeName(obj.class) = {}", Java.typeName(obj.class)); + if(Java.typeName(obj.class) == 'java.util.HashMap'){ + log.info("Dumping contents..."); + let keys = obj.keySet().toArray(); + for (var key in keys) { + log.info(`${keys[key]}(${typeof keys[key]}) = ${obj.get(keys[key])}(${typeof obj.get(keys[key])})`); + if(typeof keys[key] === 'object') { + log.info("Dumping key..."); + exports.dumpObject(keys[key]); + } + } + } + } + } else if (typeof obj === 'string'){ + log.info("String value = " + obj); + } + + log.info("getAllPropertyNames(obj) = {}", getAllPropertyNames(obj)); + // log.info("obj.toString() = {}", obj.toString()); + // log.info("JSON.stringify(obj) = {}", JSON.stringify(obj)); + } catch(e) { + log.info("Failed to dump object: " + e.message); + } +} + +let typeBySuffix = function(typeSuffix) { + return typeWithFallback(`org.eclipse.smarthome.${typeSuffix}`, `org.openhab.${typeSuffix}`, `org.openhab.core.${typeSuffix}`); +} + +let typeWithFallback = function(...typeList) { + let rv; + + for(let type of typeList) { + try { + rv = Java.type(type); + if (rv === null) { + throw error("not found"); + } + return rv; + } catch(e) { + continue; + } + } + + throw `Failed to lookup types ${typeList.join(',')}` +} + +let isJsInstanceOfJava = function(instance, type) { + if(!Java.isType(type)) { + throw error("type is not a java class"); + } + + if(instance === null || instance === undefined || instance.class === null || instance.class === undefined) { + return false; + } + + return type.class.isAssignableFrom(instance.class); +} + +module.exports = { + jsSetToJavaSet, + jsArrayToJavaSet, + jsArrayToJavaList, + javaSetToJsArray, + javaSetToJsSet, + randomUUID, + dumpObject, + typeWithFallback, + typeBySuffix, + isJsInstanceOfJava +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js new file mode 100644 index 000000000000..9611d72f96d1 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js @@ -0,0 +1,50 @@ +const path = require('path'); + +module.exports = { + entry: './index.js', + mode: 'development', + externals: [ + { + ["@runtime"]: { + root: "@runtime", + commonjs: '@runtime', + commonjs2: '@runtime', + amd: '@runtime', + }, + ["@runtime/Defaults"]: { + root: "@runtime/Defaults", + commonjs: '@runtime/Defaults', + commonjs2: '@runtime/Defaults', + amd: '@runtime/Defaults', + }, + ["@runtime/provider"]: { + root: "@runtime/provider", + commonjs: '@runtime/provider', + commonjs2: '@runtime/provider', + amd: '@runtime/provider', + }, + ["@runtime/RuleSupport"]: { + root: "@runtime/RuleSupport", + commonjs: '@runtime/RuleSupport', + commonjs2: '@runtime/RuleSupport', + amd: '@runtime/RuleSupport', + }, + ["@runtime/osgi"]: { + root: "@runtime/osgi", + commonjs: '@runtime/osgi', + commonjs2: '@runtime/osgi', + amd: '@runtime/osgi', + } + } + ], + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'oh.js', + library: { + name: "oh", + type: "umd" + }, + globalObject: 'this', + } +}; + diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index e8868bb24bdb..37c04ecbe9d9 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -44,6 +44,66 @@ + + com.github.eirslett + frontend-maven-plugin + 1.12.0 + + + v12.16.1 + javascript + + + + + Install node and npm + + install-node-and-npm + + generate-sources + + + + npm install + + npm + + + install + + + + + npx webpack + + npx + + + webpack + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + + add-resource + + generate-sources + + + + javascript/dist + . + + + + + + diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index aa62c1308592..beb3b48f8177 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -17,10 +17,14 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.URI; import java.nio.channels.SeekableByteChannel; import java.nio.file.FileSystems; +import java.nio.file.Files; import java.nio.file.OpenOption; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; import java.util.Set; import java.util.function.Consumer; @@ -65,29 +69,60 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi */ public OpenhabGraalJSScriptEngine() { super(null); // delegate depends on fields not yet initialised, so we cannot set it immediately - delegate = GraalJSScriptEngine.create(null, - Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) - .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to ease - // migration - .option("js.commonjs-require", "true") // enable CommonJS module support - .hostClassLoader(getClass().getClassLoader()) - .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { - @Override - public SeekableByteChannel newByteChannel(Path path, Set options, - FileAttribute... attrs) throws IOException { - if (scriptDependencyListener != null) { - scriptDependencyListener.accept(path.toString()); + + try { + File tmpDir = Files.createTempDirectory(null).toFile(); + tmpDir.deleteOnExit(); + InputStream is = getClass().getResourceAsStream("/oh.js"); + if (is != null) { + File ohFile = new File(tmpDir, "oh.js"); + ohFile.deleteOnExit(); + LOGGER.debug("writing globals to {}", ohFile); + Files.write(ohFile.toPath(), is.readAllBytes()); + } + + delegate = GraalJSScriptEngine.create(null, + Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) + .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to + // ease + // migration + .option("js.commonjs-require", "true") // enable CommonJS module support + .hostClassLoader(getClass().getClassLoader()) + .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { + @Override + public SeekableByteChannel newByteChannel(Path path, Set options, + FileAttribute... attrs) throws IOException { + if (scriptDependencyListener != null) { + scriptDependencyListener.accept(path.toString()); + } + + if (path.toString().endsWith(".js")) { + return new PrefixedSeekableByteChannel( + ("require=" + REQUIRE_WRAPPER_NAME + "(require);").getBytes(), + super.newByteChannel(path, options, attrs)); + } else { + return super.newByteChannel(path, options, attrs); + } + } + + @Override + public Path parsePath(URI uri) { + return parsePath(uri.toString()); } - if (path.toString().endsWith(".js")) { - return new PrefixedSeekableByteChannel( - ("require=" + REQUIRE_WRAPPER_NAME + "(require);").getBytes(), - super.newByteChannel(path, options, attrs)); - } else { - return super.newByteChannel(path, options, attrs); + @Override + public Path parsePath(String path) { + if (path.indexOf(tmpDir.getPath()) != 0 + && path.indexOf(MODULE_DIR.toString()) != 0) { + return tmpDir.toPath(); + } + return Paths.get(path); } - } - })); + })); + } catch (IOException e) { + LOGGER.error("Could not load gloabls", e); + throw new RuntimeException("Could not load gloabls", e); + } } @Override From 18237a1f3e02568ebd0a3b4c555273a46ff91026 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sat, 23 Oct 2021 13:53:51 -0700 Subject: [PATCH 03/23] Load OH JS file directly from resource, use @oh namespace Signed-off-by: Dan Cunningham --- .../internal/OpenhabGraalJSScriptEngine.java | 109 ++++++++++-------- .../fs/ReadOnlySeekableByteArrayChannel.java | 93 +++++++++++++++ 2 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index beb3b48f8177..2556f0b80f88 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -18,14 +18,16 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.URI; import java.nio.channels.SeekableByteChannel; +import java.nio.file.AccessMode; import java.nio.file.FileSystems; -import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; +import java.util.Collections; +import java.util.Map; import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; @@ -36,6 +38,7 @@ import org.graalvm.polyglot.Context; import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem; import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel; +import org.openhab.automation.jsscripting.internal.fs.ReadOnlySeekableByteArrayChannel; import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable; import org.openhab.core.OpenHAB; import org.openhab.core.automation.module.script.ScriptExtensionAccessor; @@ -56,7 +59,10 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi private static final String REQUIRE_WRAPPER_NAME = "__wraprequire__"; private static final String MODULE_DIR = String.join(File.separator, OpenHAB.getConfigFolder(), "automation", "lib", "javascript", "personal"); - + // final CommonJS search path for our library + private static final Path OH_NODE_PATH = Paths.get("/node_modules/@oh.js"); + // resource path of our oh js library + private static final Path OH_FILE_PATH = Paths.get("/oh.js"); // these fields start as null because they are populated on first use private @NonNullByDefault({}) String engineIdentifier; private @NonNullByDefault({}) Consumer scriptDependencyListener; @@ -69,60 +75,65 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi */ public OpenhabGraalJSScriptEngine() { super(null); // delegate depends on fields not yet initialised, so we cannot set it immediately + delegate = GraalJSScriptEngine.create(null, + Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) + .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to + // ease + // migration + .option("js.commonjs-require", "true") // enable CommonJS module support + .hostClassLoader(getClass().getClassLoader()) + .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { + @Override + public SeekableByteChannel newByteChannel(Path path, Set options, + FileAttribute... attrs) throws IOException { + LOGGER.debug("SeekableByteChannel {}", path); + if (scriptDependencyListener != null) { + scriptDependencyListener.accept(path.toString()); + } - try { - File tmpDir = Files.createTempDirectory(null).toFile(); - tmpDir.deleteOnExit(); - InputStream is = getClass().getResourceAsStream("/oh.js"); - if (is != null) { - File ohFile = new File(tmpDir, "oh.js"); - ohFile.deleteOnExit(); - LOGGER.debug("writing globals to {}", ohFile); - Files.write(ohFile.toPath(), is.readAllBytes()); - } - - delegate = GraalJSScriptEngine.create(null, - Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) - .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to - // ease - // migration - .option("js.commonjs-require", "true") // enable CommonJS module support - .hostClassLoader(getClass().getClassLoader()) - .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { - @Override - public SeekableByteChannel newByteChannel(Path path, Set options, - FileAttribute... attrs) throws IOException { - if (scriptDependencyListener != null) { - scriptDependencyListener.accept(path.toString()); + if (path.toString().endsWith(".js")) { + SeekableByteChannel sbc = null; + if (OH_FILE_PATH.equals(path)) { + InputStream is = getClass().getResourceAsStream(OH_FILE_PATH.toString()); + if (is != null) { + sbc = new ReadOnlySeekableByteArrayChannel(is.readAllBytes()); + } } - - if (path.toString().endsWith(".js")) { - return new PrefixedSeekableByteChannel( - ("require=" + REQUIRE_WRAPPER_NAME + "(require);").getBytes(), - super.newByteChannel(path, options, attrs)); - } else { - return super.newByteChannel(path, options, attrs); + if (sbc == null) { + sbc = super.newByteChannel(path, options, attrs); } + return new PrefixedSeekableByteChannel( + ("require=" + REQUIRE_WRAPPER_NAME + "(require);").getBytes(), sbc); + } else { + return super.newByteChannel(path, options, attrs); } + } - @Override - public Path parsePath(URI uri) { - return parsePath(uri.toString()); + @Override + public void checkAccess(Path path, Set modes, + LinkOption... linkOptions) throws IOException { + if (!OH_NODE_PATH.equals(path)) { + super.checkAccess(path, modes, linkOptions); } + } - @Override - public Path parsePath(String path) { - if (path.indexOf(tmpDir.getPath()) != 0 - && path.indexOf(MODULE_DIR.toString()) != 0) { - return tmpDir.toPath(); - } - return Paths.get(path); + @Override + public Map readAttributes(Path path, String attributes, + LinkOption... options) throws IOException { + if (OH_NODE_PATH.equals(path)) { + return Collections.singletonMap("isRegularFile", true); } - })); - } catch (IOException e) { - LOGGER.error("Could not load gloabls", e); - throw new RuntimeException("Could not load gloabls", e); - } + return super.readAttributes(path, attributes, options); + } + + @Override + public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException { + if (OH_NODE_PATH.equals(path)) { + return OH_FILE_PATH; + } + return super.toRealPath(path, linkOptions); + } + })); } @Override diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java new file mode 100644 index 000000000000..9b39065699d6 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.fs; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SeekableByteChannel; + +/** + * + * @author daniel + * + */ +public class ReadOnlySeekableByteArrayChannel implements SeekableByteChannel { + private byte[] data; + private int position; + private boolean closed; + + public ReadOnlySeekableByteArrayChannel(byte[] data) { + this.data = data; + } + + @Override + public long position() { + return position; + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + ensureOpen(); + position = (int) Math.max(0, Math.min(newPosition, size())); + return this; + } + + @Override + public long size() { + return data.length; + } + + @Override + public int read(ByteBuffer buf) throws IOException { + ensureOpen(); + int remaining = (int) size() - position; + if (remaining <= 0) { + return -1; + } + int readBytes = buf.remaining(); + if (readBytes > remaining) { + readBytes = remaining; + } + buf.put(data, position, readBytes); + position += readBytes; + return readBytes; + } + + @Override + public void close() { + closed = true; + } + + @Override + public boolean isOpen() { + return !closed; + } + + @Override + public int write(ByteBuffer b) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public SeekableByteChannel truncate(long newSize) { + throw new UnsupportedOperationException(); + } + + private void ensureOpen() throws ClosedChannelException { + if (!isOpen()) { + throw new ClosedChannelException(); + } + } +} From 74be9175e10d154ae37f3a272cd5bc91a962d4a6 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sat, 23 Oct 2021 16:32:33 -0700 Subject: [PATCH 04/23] Remove debug statement Signed-off-by: Dan Cunningham --- .../jsscripting/internal/OpenhabGraalJSScriptEngine.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 2556f0b80f88..0d83fd70ae22 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -86,7 +86,6 @@ public OpenhabGraalJSScriptEngine() { @Override public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IOException { - LOGGER.debug("SeekableByteChannel {}", path); if (scriptDependencyListener != null) { scriptDependencyListener.accept(path.toString()); } From 57d4c80ccfa7fd6f5ed6e6ddab79ace6459bd89f Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 24 Oct 2021 20:49:51 -0700 Subject: [PATCH 05/23] add allItems Signed-off-by: Dan Cunningham --- .../javascript/items/managed.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js index eec25b6d9ad2..d04197bf9d21 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js @@ -433,6 +433,15 @@ const getItemsByTag = (...tagNames) => { return utils.javaSetToJsArray(itemRegistry.getItemsByTag(tagNames)).map(i => new OHItem(i)); } +/** + * Gets all Openhab Items with a specific tag. + * @return {OHItem[]} all items + * @alias module:ohj/items.getItems + */ +const getItems = () => { + return utils.javaSetToJsArray(itemRegistry.getItems()).map(i => new OHItem(i)); +} + /** * Helper function to ensure an item name is valid. All invalid characters are replaced with an underscore. * @param {String} s the name to make value @@ -447,6 +456,7 @@ module.exports = { getItem, addItem, getItemsByTag, + getItems, replaceItem, createItem, removeItem, From ed51c5d4ac8595403556761cf9de6601aee4d509 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Wed, 3 Nov 2021 10:47:08 -0700 Subject: [PATCH 06/23] JS changes Signed-off-by: Dan Cunningham --- .../javascript/actions.js | 7 +- .../javascript/docs_config.json | 2 +- .../javascript/fluent/fluent.js | 39 +++- .../javascript/fluent/trigger-conf.js | 179 ++++++++++++++++-- .../javascript/items/items-provider.js | 2 +- .../javascript/items/managed.js | 12 +- .../javascript/triggers.js | 108 ++++++++++- .../javascript/webpack.config.js | 1 + .../internal/OpenhabGraalJSScriptEngine.java | 4 +- 9 files changed, 323 insertions(+), 31 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/javascript/actions.js b/bundles/org.openhab.automation.jsscripting/javascript/actions.js index 6b28837191c9..92475d12b729 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/actions.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/actions.js @@ -25,8 +25,8 @@ const Things = utils.typeBySuffix('core.model.script.actions.Things'); const oh1_actions = osgi.findServices("org.openhab.core.scriptengine.action.ActionService", null) || []; const oh2_actions = osgi.findServices("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || []; - -oh1_actions.concat(oh2_actions).forEach(function (item) { +const oh3_actions = osgi.findServices("org.openhab.core.model.script.engine.action.ActionService", null) || []; +[...oh1_actions, ...oh2_actions, ...oh3_actions].forEach(function (item) { try { //if an action fails to activate, then warn and continue so that other actions are available exports[item.getActionClass().getSimpleName()] = item.getActionClass().static; @@ -39,8 +39,9 @@ let Exec = utils.typeWithFallback('org.openhab.core.model.script.actions.Exec', let HTTP = utils.typeWithFallback('org.openhab.core.model.script.actions.HTTP', 'org.eclipse.smarthome.model.script.actions.HTTP'); let LogAction = utils.typeWithFallback('org.openhab.core.model.script.actions.Log', 'org.eclipse.smarthome.model.script.actions.LogAction'); let Ping = utils.typeWithFallback('org.openhab.core.model.script.actions.Ping', 'org.eclipse.smarthome.model.script.actions.Ping'); +let ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); -[Exec, HTTP, LogAction, Ping].forEach(function (item) { +[Exec, HTTP, LogAction, Ping, ScriptExecution].forEach(function (item) { exports[item.class.getSimpleName()] = item.class.static; }); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json b/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json index 397f37672c63..21c05ee2ff0a 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json +++ b/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json @@ -6,7 +6,7 @@ "source": { "include": [".", "package.json", "README.md"], "includePattern": ".js$", - "excludePattern": "(node_modules/|docs)" + "excludePattern": "(node_modules/|docs|dist)" }, "plugins": [ "plugins/markdown" diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js index 3b57e06be00d..d76e75b34b11 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js @@ -117,6 +117,15 @@ const fluentExports = { */ timeOfDay: s => new triggers.ItemTriggerConfig('vTimeOfDay').changed().to(s), + /** + * Specifies a channel event as a source for the rule to fire. + * + * @memberof fluent + * @param {String} channelName the name of the channel + * @returns {ItemTriggerConfig} the trigger config + */ + channel: s => new triggers.ChannelTriggerConfig(s), + /** * Specifies a cron schedule for the rule to fire. * @@ -207,7 +216,16 @@ const fluentExports = { * @returns {ItemTriggerConfig} the trigger config */ item: s => new triggers.ItemTriggerConfig(s), - + + /** + * Specifies an group member as the source of changes to trigger a rule. + * + * @memberof fluent + * @param {String} groupName the name of the group + * @returns {ItemTriggerConfig} the trigger config + */ + memberOf: s => new triggers.ItemTriggerConfig(s, true), + /** * Copies the state from one item to another. Can be used to proxy item state. State is updated, not * sent as a command. @@ -233,7 +251,24 @@ const fluentExports = { * @param {String} itemName the name of the item to assess the state * @returns {ItemStateConditionConf} the operation config */ - stateOfItem: s => new conditions.ItemStateConditionConf(s) + stateOfItem: s => new conditions.ItemStateConditionConf(s), + + /** + * Specifies a Thing status event as a source for the rule to fire. + * + * @memberof fluent + * @param {String} thingUID the UID of the Thing + * @returns {ItemTriggerConfig} the trigger config + */ + thing: s => new triggers.ThingTriggerConfig(s), + + /** + * Specifies a system event as a source for the rule to fire. + * + * @memberof fluent + * @returns {ItemTriggerConfig} the trigger config + */ + system: () => new triggers.SystemTriggerConfig() } module.exports = Object.assign({ diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js index 55bc6e3256cb..98c9e6fd3dcb 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js @@ -1,6 +1,34 @@ const triggers = require('../triggers'); const log = require('../log')('trigger-conf'); +class ChannelTriggerConfig { + constructor(channelName) { + this.channelName = channelName; + this._toOHTriggers = () => [triggers.ChannelEventTrigger(this.channelName, this.eventName)] + } + + describe(compact) { + if (compact) { + return this.channelName + (this.eventName ? `:${this.eventName}` : "") + } else { + return `matches channel "${this.channelName}"` + (this.eventName ? `for event ${this.eventName}` : "") + } + } + + to(eventName) { + return this.triggered(eventName); + } + + triggered(eventName) { + this.eventName = eventName || ""; + return this; + } + + _complete() { + return typeof (this.eventName) !== 'undefined'; + } +}; + class CronTriggerConfig { constructor(timeStr) { this.timeStr = timeStr; @@ -10,15 +38,15 @@ class CronTriggerConfig { } }; - class ItemTriggerConfig { - constructor(itemOrName) { + constructor(itemOrName, isGroup) { + this.type = isGroup ? 'memberOf' : 'item'; if(typeof itemOrName !== 'string') { itemOrName = itemOrName.name; } this.item_name = itemOrName; - this.describe = () => `item ${this.item_name} changed` + this.describe = () => `${this.type} ${this.item_name} changed` this.of = this.to; //receivedCommand().of(..) } @@ -85,9 +113,9 @@ class ItemTriggerConfig { return `${this.item_name} ${transition}`; } case "receivedCommand": - return compact ? `${this.item_name}/⌘` : `item ${this.item_name} received command`; + return compact ? `${this.item_name}/⌘` : `${this.type} ${this.item_name} received command`; case "receivedUpdate": - return compact ? `${this.item_name}/↻` : `item ${this.item_name} received update`; + return compact ? `${this.item_name}/↻` : `${this.type} ${this.item_name} received update`; default: throw error("Unknown operation type: " + this.op_type); } @@ -98,15 +126,28 @@ class ItemTriggerConfig { } _toOHTriggers() { - switch (this.op_type) { - case "changed": - return [triggers.ItemStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; - case 'receivedCommand': - return [triggers.ItemCommandTrigger(this.item_name, this.to_value)] - case 'receivedUpdate': - return [triggers.ItemStateUpdateTrigger(this.item_name, this.to_value)] - default: - throw error("Unknown operation type: " + this.op_type); + if (this.type === "memberOf") { + switch (this.op_type) { + case "changed": + return [triggers.GroupStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; + case 'receivedCommand': + return [triggers.GroupCommandTrigger(this.item_name, this.to_value)] + case 'receivedUpdate': + return [triggers.GroupStateUpdateTrigger(this.item_name, this.to_value)] + default: + throw error("Unknown operation type: " + this.op_type); + } + } else { + switch (this.op_type) { + case "changed": + return [triggers.ItemStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; + case 'receivedCommand': + return [triggers.ItemCommandTrigger(this.item_name, this.to_value)] + case 'receivedUpdate': + return [triggers.ItemStateUpdateTrigger(this.item_name, this.to_value)] + default: + throw error("Unknown operation type: " + this.op_type); + } } } @@ -130,7 +171,115 @@ class ItemTriggerConfig { } } +class ThingTriggerConfig { + constructor(thingUID) { + this.thingUID = thingUID; + } + + _complete() { + return typeof (this.op_type) !== 'undefined'; + } + + describe(compact) { + switch (this.op_type) { + case "changed": + let transition = 'changed'; + + if (this.to_value) { + transition += ` to ${this.to_value}`; + } + + if (this.from_value) { + transition += ` from ${this.from_value}`; + } + + return `${this.thingUID} ${transition}`; + case "updated": + return compact ? `${this.thingUID}/updated` : `Thing ${this.thingUID} received update`; + default: + throw error("Unknown operation type: " + this.op_type); + } + } + + changed() { + this.op_type = 'changed'; + return this; + } + + updated() { + this.op_type = 'updated'; + return this; + } + + from(value) { + if (this.op_type != 'changed') { + throw ".from(..) only available for .changed()"; + } + this.from_value = value; + return this; + } + + to(value) { + this.to_value = value; + return this; + } + + _toOHTriggers() { + switch (this.op_type) { + case "changed": + return [triggers.ThingStatusChangeTrigger(this.thingUID, this.to_value, this.from_value)]; + case 'updated': + return [triggers.ThingStatusUpdateTrigger(this.thingUID, this.to_value)] + default: + throw error("Unknown operation type: " + this.op_type); + } + } +}; + +class SystemTriggerConfig { + constructor() { + this._toOHTriggers = () => [triggers.SystemStartlevelTrigger(this.level)] + this.describe = (compact) => compact ? `SystemLevel:${this.level}` : `system level "${this.level}"` + } + _complete() { + return typeof (this.level) !== 'undefined'; + } + + rulesLoaded() { + this.level = 40; + return this; + } + + ruleEngineStarted() { + this.level = 50; + return this; + } + + userInterfacesStarted() { + this.level = 70; + return this; + } + + thingsInitialized() { + this.level = 80; + return this; + } + + startupComplete() { + this.level = 100; + return this; + } + + startLevel(level) { + this.level = level; + return this; + } +}; + module.exports = { + CronTriggerConfig, + ChannelTriggerConfig, ItemTriggerConfig, - CronTriggerConfig + ThingTriggerConfig, + SystemTriggerConfig } \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js b/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js index 448286bacdc6..217747bf6578 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js @@ -3,7 +3,7 @@ const items = require('./managed'); const utils = require('../utils'); const { AbstractProvider } = require('../provider'); -const ITEM_PROVIDER_CLASS = "org.eclipse.smarthome.core.items.ItemProvider"; +const ITEM_PROVIDER_CLASS = "org.openhab.core.items.ItemProvider"; class StaticItemProvider extends AbstractProvider { diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js index d04197bf9d21..d676f62bda03 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js @@ -434,7 +434,7 @@ const getItemsByTag = (...tagNames) => { } /** - * Gets all Openhab Items with a specific tag. + * Gets all Openhab Items * @return {OHItem[]} all items * @alias module:ohj/items.getItems */ @@ -442,11 +442,11 @@ const getItems = () => { return utils.javaSetToJsArray(itemRegistry.getItems()).map(i => new OHItem(i)); } - /** - * Helper function to ensure an item name is valid. All invalid characters are replaced with an underscore. - * @param {String} s the name to make value - * @returns {String} a valid item name - */ +/** + * Helper function to ensure an item name is valid. All invalid characters are replaced with an underscore. + * @param {String} s the name to make value + * @returns {String} a valid item name + */ const safeItemName = s => s. replace(/[\"\']/g, ''). //delete replace(/[^a-zA-Z0-9]/g, '_'); //replace with underscore diff --git a/bundles/org.openhab.automation.jsscripting/javascript/triggers.js b/bundles/org.openhab.automation.jsscripting/javascript/triggers.js index 50928c73203a..efb55bbc4e10 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/triggers.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/triggers.js @@ -106,7 +106,60 @@ module.exports = { ItemCommandTrigger: (itemName, command, triggerName) => createTrigger("core.ItemCommandTrigger", triggerName, { "itemName": itemName, "command": command - }), + }), + + /** + * Creates a trigger that fires upon a member of a group changing state. + * + * @example + * GroupStateChangeTrigger('my_group', 'OFF', 'ON') + * + * @name GroupStateChangeTrigger + * @memberof triggers + * @param {String} groupName the name of the group to monitor for change + * @param {String} [oldState] the previous state of the group + * @param {String} [newState] the new state of the group + * @param {String} [triggerName] the name of the trigger to create + */ + GroupStateChangeTrigger: (groupName, oldState, newState, triggerName) => createTrigger("core.GroupStateChangeTrigger", triggerName, { + "groupName": groupName, + "state": newState, + "oldState": oldState + }), + + /** + * Creates a trigger that fires upon a member of a group receiving a state update. Note that group item does not need to change state. + * + * @example + * GroupStateUpdateTrigger('my_group', 'OFF') + * + * @name GroupStateUpdateTrigger + * @memberof triggers + * @param {String} groupName the name of the group to monitor for change + * @param {String} [state] the new state of the group + * @param {String} [triggerName] the name of the trigger to create + */ + GroupStateUpdateTrigger: (groupName, state, triggerName) => createTrigger("core.GroupStateUpdateTrigger", triggerName, { + "groupName": groupName, + "state": state + }), + /** + * Creates a trigger that fires upon a member of a group receiving a command. Note that the group does not need to change state. + * + * @example + * GroupCommandTrigger('my_group', 'OFF') + * + * @name GroupCommandTrigger + * @memberof triggers + * @param {String} groupName the name of the group to monitor for change + * @param {String} [command] the command received + * @param {String} [triggerName] the name of the trigger to create + */ + GroupCommandTrigger: (groupName, command, triggerName) => createTrigger("core.GroupCommandTrigger", triggerName, { + "groupName": groupName, + "command": command + }), + /** * Creates a trigger that fires on a cron schedule. The supplied cron expression defines when the trigger will fire. @@ -136,6 +189,59 @@ module.exports = { "time": time }), + + /** + * Creates a trigger that fires upon an Thing status updating + * + * @example + * ThingStatusUpdateTrigger('some:thing:uuid','OFFLINE') + * + * @name ThingStatusUpdateTrigger + * @memberof triggers + * @param {String} thingUID the name of the thing to monitor for a status updating + * @param {String} [status] the optional status to monitor for + * @param {String} [triggerName] the name of the trigger to create + */ + ThingStatusUpdateTrigger: (thingUID, status, triggerName) => createTrigger("core.ThingStatusUpdateTrigger", triggerName, { + "thingUID": thingUID, + "status": status, + }), + + /** + * Creates a trigger that fires upon an Thing status changing + * + * @example + * ThingStatusChangeTrigger('some:thing:uuid','ONLINE','OFFLINE') + * + * @name ThingStatusChangeTrigger + * @memberof triggers + * @param {String} thingUID the name of the thing to monitor for a status change + * @param {String} [status] the optional status to monitor for + * @param {String} [previousStatus] the optional previous state to monitor from + * @param {String} [triggerName] the optional name of the trigger to create + */ + ThingStatusChangeTrigger: (thingUID, status, previousStatus, triggerName) => createTrigger("core.ThingStatusChangeTrigger", triggerName, { + "thingUID": thingUID, + "status": status, + "previousStatus": previousStatus, + }), + + /** + * Creates a trigger that fires if a given start level is reached by the system + * + * @example + * SystemStartlevelTrigger('100') //Startup Complete + * + * @name SystemStartlevelTrigger + * @memberof triggers + * @param {String} startlevel the name of the thing to monitor for a status updating + * @param {String} [triggerName] the name of the trigger to create + */ + SystemStartlevelTrigger: (thingUID, status, triggerName) => createTrigger("core.SystemStartlevelTrigger", triggerName, { + "thingUID": thingUID, + "status": status, + }), + /* not yet tested ItemStateCondition: (itemName, state, triggerName) => createTrigger("core.ItemStateCondition", triggerName, { "itemName": itemName, diff --git a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js index 9611d72f96d1..be57c38b9022 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js @@ -3,6 +3,7 @@ const path = require('path'); module.exports = { entry: './index.js', mode: 'development', + devtool: 'source-map', externals: [ { ["@runtime"]: { diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 0d83fd70ae22..2ee0fb56b969 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -78,8 +78,8 @@ public OpenhabGraalJSScriptEngine() { delegate = GraalJSScriptEngine.create(null, Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to - // ease - // migration + // ease + // migration .option("js.commonjs-require", "true") // enable CommonJS module support .hostClassLoader(getClass().getClassLoader()) .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { From 1a14a3d66ec967104b9f10347536d730e883c05b Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Wed, 10 Nov 2021 21:51:47 -0800 Subject: [PATCH 07/23] Adds injection code and makes this a configurable service Signed-off-by: Dan Cunningham --- .../internal/GraalJSScriptEngineFactory.java | 41 +++++++++++++++++-- .../internal/OpenhabGraalJSScriptEngine.java | 17 +++++++- .../main/resources/OH-INF/config/config.xml | 25 +++++++++++ 3 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java index 14e9f783e834..51ea76dbbe03 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java @@ -20,7 +20,14 @@ import javax.script.ScriptEngine; import org.openhab.core.automation.module.script.ScriptEngineFactory; +import org.openhab.core.config.core.ConfigurableService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Modified; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory; @@ -29,8 +36,15 @@ * * @author Jonathan Gilbert - Initial contribution */ -@Component(service = ScriptEngineFactory.class) +@Component(service = ScriptEngineFactory.class, configurationPid = "org.openhab.automation.jsscripting", property = Constants.SERVICE_PID + + "=org.openhab.automation.jsscripting") +@ConfigurableService(category = "automation", label = "JS Scripting", description_uri = "automation:jsscripting") public final class GraalJSScriptEngineFactory implements ScriptEngineFactory { + private static final Logger LOGGER = LoggerFactory.getLogger(GraalJSScriptEngineFactory.class); + private static final String CFG_INJECTION_ENABLED = "injectionEnabled"; + private static final String CFG_INJECTION_CODE = "injectionCode"; + + private String injectionCode; @Override public List getScriptTypes() { @@ -50,7 +64,28 @@ public void scopeValues(ScriptEngine scriptEngine, Map scopeValu @Override public ScriptEngine createScriptEngine(String scriptType) { - OpenhabGraalJSScriptEngine engine = new OpenhabGraalJSScriptEngine(); - return new DebuggingGraalScriptEngine<>(engine); + return new DebuggingGraalScriptEngine<>(new OpenhabGraalJSScriptEngine(injectionCode)); + } + + @Activate + protected void activate(BundleContext context, Map config) { + modified(config); + } + + @Modified + protected void modified(Map config) { + Object injectionEnabled = config.get(CFG_INJECTION_ENABLED); + boolean enabled = injectionEnabled != null && (Boolean) injectionEnabled; + if (enabled) { + Object injectionCodeObj = config.get(CFG_INJECTION_CODE); + if (injectionCodeObj != null) { + LOGGER.debug("Adding code {}", injectionCodeObj); + injectionCode = (String) injectionCodeObj; + } else { + injectionCode = null; + } + } else { + injectionCode = null; + } } } diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 2ee0fb56b969..710a678a8d80 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -33,8 +33,10 @@ import java.util.function.Function; import javax.script.ScriptContext; +import javax.script.ScriptException; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.graalvm.polyglot.Context; import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem; import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel; @@ -62,21 +64,24 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi // final CommonJS search path for our library private static final Path OH_NODE_PATH = Paths.get("/node_modules/@oh.js"); // resource path of our oh js library - private static final Path OH_FILE_PATH = Paths.get("/oh.js"); + private static final Path OH_FILE_PATH = Paths.get("/@oh.js"); // these fields start as null because they are populated on first use private @NonNullByDefault({}) String engineIdentifier; private @NonNullByDefault({}) Consumer scriptDependencyListener; private boolean initialized = false; + private @Nullable String injectionCode; /** * Creates an implementation of ScriptEngine (& Invocable), wrapping the contained engine, that tracks the script * lifecycle and provides hooks for scripts to do so too. */ - public OpenhabGraalJSScriptEngine() { + public OpenhabGraalJSScriptEngine(String injectionCode) { super(null); // delegate depends on fields not yet initialised, so we cannot set it immediately + this.injectionCode = injectionCode; delegate = GraalJSScriptEngine.create(null, Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) + .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to // ease // migration @@ -173,5 +178,13 @@ protected void beforeInvocation() { delegate.put("require", wrapRequireFn.apply((Function) delegate.get("require"))); initialized = true; + + if (injectionCode != null) { + try { + eval(injectionCode); + } catch (ScriptException e) { + LOGGER.error("Could not inject code", e); + } + } } } diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml new file mode 100644 index 000000000000..d289602846f1 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml @@ -0,0 +1,25 @@ + + + + + + + Helper libraries can be imported manually using "require(@oh)" + ]]> + + + + + true + + + + Injection code used to expose helper variables + Object.assign(this, require('@oh')); this.log = require("@oh").log("default"); + + + From 831bb7ff7140eb5c5e903b5869211b791bbcf046 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Wed, 10 Nov 2021 21:56:36 -0800 Subject: [PATCH 08/23] revert small typor Signed-off-by: Dan Cunningham --- .../jsscripting/internal/OpenhabGraalJSScriptEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 710a678a8d80..e69fe61352b8 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -64,7 +64,7 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi // final CommonJS search path for our library private static final Path OH_NODE_PATH = Paths.get("/node_modules/@oh.js"); // resource path of our oh js library - private static final Path OH_FILE_PATH = Paths.get("/@oh.js"); + private static final Path OH_FILE_PATH = Paths.get("/oh.js"); // these fields start as null because they are populated on first use private @NonNullByDefault({}) String engineIdentifier; private @NonNullByDefault({}) Consumer scriptDependencyListener; From 91e10330b25397a84e6c1c8c44fdfe602b746933 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Fri, 19 Nov 2021 14:35:51 -0800 Subject: [PATCH 09/23] adds global vars, cleans up local library loading Signed-off-by: Dan Cunningham --- .../javascript/webpack.config.js | 4 +- .../pom.xml | 2 +- .../internal/OpenhabGraalJSScriptEngine.java | 40 ++-- .../main/resources/OH-INF/config/config.xml | 12 +- .../main/resources/node_modules/@globals.js | 172 ++++++++++++++++++ 5 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js diff --git a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js index be57c38b9022..71ef86c0486c 100644 --- a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js +++ b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js @@ -40,9 +40,9 @@ module.exports = { ], output: { path: path.resolve(__dirname, 'dist'), - filename: 'oh.js', + filename: '@oh.js', library: { - name: "oh", + name: "@oh", type: "umd" }, globalObject: 'this', diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index 0c6ec0965356..abf39dd6c6a0 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -97,7 +97,7 @@ javascript/dist - . + node_modules diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index d145ed4f72c4..e40ffef078ae 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -22,6 +22,7 @@ import java.nio.file.AccessMode; import java.nio.file.FileSystems; import java.nio.file.LinkOption; +import java.nio.file.NoSuchFileException; import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; @@ -63,28 +64,26 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi private static final String MODULE_DIR = String.join(File.separator, OpenHAB.getConfigFolder(), "automation", "lib", "javascript", "personal"); // final CommonJS search path for our library - private static final Path OH_NODE_PATH = Paths.get("/node_modules/@oh.js"); - // resource path of our oh js library - private static final Path OH_FILE_PATH = Paths.get("/oh.js"); + private static final Path LOCAL_NODE_PATH = Paths.get("/node_modules"); + // these fields start as null because they are populated on first use private @NonNullByDefault({}) String engineIdentifier; private @NonNullByDefault({}) Consumer scriptDependencyListener; private boolean initialized = false; - private @Nullable String injectionCode; + private String globalScript; /** * Creates an implementation of ScriptEngine (& Invocable), wrapping the contained engine, that tracks the script * lifecycle and provides hooks for scripts to do so too. */ - public OpenhabGraalJSScriptEngine(String injectionCode) { + public OpenhabGraalJSScriptEngine(@Nullable String injectionCode) { super(null); // delegate depends on fields not yet initialised, so we cannot set it immediately - this.injectionCode = injectionCode; + this.globalScript = "require(\"@globals\");" + (injectionCode != null ? injectionCode : ""); delegate = GraalJSScriptEngine.create( Engine.newBuilder().allowExperimentalOptions(true).option("engine.WarnInterpreterOnly", "false") .build(), Context.newBuilder("js").allowExperimentalOptions(true).allowAllAccess(true) - .option("js.commonjs-require-cwd", MODULE_DIR).option("js.nashorn-compat", "true") // to // ease // migration @@ -99,11 +98,10 @@ public SeekableByteChannel newByteChannel(Path path, Set o if (scriptDependencyListener != null) { scriptDependencyListener.accept(path.toString()); } - if (path.toString().endsWith(".js")) { SeekableByteChannel sbc = null; - if (OH_FILE_PATH.equals(path)) { - InputStream is = getClass().getResourceAsStream(OH_FILE_PATH.toString()); + if (path.startsWith(LOCAL_NODE_PATH)) { + InputStream is = getClass().getResourceAsStream(path.toString()); if (is != null) { sbc = new ReadOnlySeekableByteArrayChannel(is.readAllBytes()); } @@ -121,7 +119,11 @@ public SeekableByteChannel newByteChannel(Path path, Set o @Override public void checkAccess(Path path, Set modes, LinkOption... linkOptions) throws IOException { - if (!OH_NODE_PATH.equals(path)) { + if (path.startsWith(LOCAL_NODE_PATH)) { + if (getClass().getResource(path.toString()) == null) { + throw new NoSuchFileException(path.toString()); + } + } else { super.checkAccess(path, modes, linkOptions); } } @@ -129,7 +131,7 @@ public void checkAccess(Path path, Set modes, @Override public Map readAttributes(Path path, String attributes, LinkOption... options) throws IOException { - if (OH_NODE_PATH.equals(path)) { + if (path.startsWith(LOCAL_NODE_PATH)) { return Collections.singletonMap("isRegularFile", true); } return super.readAttributes(path, attributes, options); @@ -137,8 +139,8 @@ public Map readAttributes(Path path, String attributes, @Override public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException { - if (OH_NODE_PATH.equals(path)) { - return OH_FILE_PATH; + if (path.startsWith(LOCAL_NODE_PATH)) { + return path; } return super.toRealPath(path, linkOptions); } @@ -184,12 +186,10 @@ protected void beforeInvocation() { initialized = true; - if (injectionCode != null) { - try { - eval(injectionCode); - } catch (ScriptException e) { - LOGGER.error("Could not inject code", e); - } + try { + eval(globalScript); + } catch (ScriptException e) { + LOGGER.error("Could not inject gloabl script", e); } } } diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml index d289602846f1..7d521f03bd79 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml @@ -6,20 +6,20 @@ https://openhab.org/schemas/config-description-1.0.0.xsd"> - - - Helper libraries can be imported manually using "require(@oh)" + + + If disabled, the OH scriptig library can be imported manually using "require(@oh)" ]]> - - + + true Injection code used to expose helper variables - Object.assign(this, require('@oh')); this.log = require("@oh").log("default"); + Object.assign(this, require('@oh')); diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js new file mode 100644 index 000000000000..fff5f692aa18 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js @@ -0,0 +1,172 @@ + +const System = Java.type('java.lang.System'); +const log = Java.type("org.slf4j.LoggerFactory").getLogger("script.js.console"); +const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); +const ZonedDateTime = Java.type('java.time.ZonedDateTime'); + +log.debug("loading globals"); +const formatRegExp = /%[sdj%]/g; + +function stringify(value) { + try { + if (Java.isJavaObject(value)) { + return value.toString(); + } else { + // special cases + if (value === undefined) { + return "undefined" + } + if (typeof value === 'function') { + return "[Function]" + } + if (value instanceof RegExp) { + return value.toString(); + } + // fallback to JSON + return JSON.stringify(value, null, 2); + } + } catch (e) { + return '[Circular: ' + e + ']'; + } +} + +function format(f) { + if (typeof f !== 'string') { + var objects = []; + for (var index = 0; index < arguments.length; index++) { + objects.push(stringify(arguments[index])); + } + return objects.join(' '); + } + + if (arguments.length === 1) return f; + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function (x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + // falls through + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { + str += ' ' + x; + } else { + str += ' ' + stringify(x); + } + } + return str; +} + +const counters = {}; +const timers = {}; + +const console = { + 'assert': function (expression, message) { + if (!expression) { + log.error(message); + } + }, + + count: function (label) { + let counter; + + if (label) { + if (counters.hasOwnProperty(label)) { + counter = counters[label]; + } else { + counter = 0; + } + + // update + counters[label] = ++counter; + log.debug(format.apply(null, [label + ':', counter])); + } + }, + + debug: function () { + log.debug(format.apply(null, arguments)); + }, + + info: function () { + log.info(format.apply(null, arguments)); + }, + + log: function () { + log.info(format.apply(null, arguments)); + }, + + warn: function () { + log.warn(format.apply(null, arguments)); + }, + + error: function () { + log.error(format.apply(null, arguments)); + }, + + trace: function (e) { + if (Java.isJavaObject(e)) { + log.trace(e.getLocalizedMessage(), e); + } else { + if (e.stack) { + log.trace(e.stack); + } else { + if (e.message) { + log.trace(format.apply(null, [(e.name || 'Error') + ':', e.message])); + } else { + log.trace((e.name || 'Error')); + } + } + } + }, + + time: function (label) { + if (label) { + timers[label] = System.currentTimeMillis(); + } + }, + timeEnd: function (label) { + if (label) { + const now = System.currentTimeMillis(); + if (timers.hasOwnProperty(label)) { + log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms'])); + delete timers[label]; + } else { + log.info(format.apply(null, [label + ':', ''])); + } + } + } +}; + +function setTimeout(cb, delay) { + return ScriptExecution.createTimer( + ZonedDateTime.now().plusNanos(delay * 1000000), + cb + ); +} + +function clearTimeout(timer) { + if (timer.isActive() && !timer.isRunning()) { + timer.cancel(); + } +} +globalThis.console = console; +globalThis.setTimeout = setTimeout; +globalThis.clearTimeout = clearTimeout; +globalThis.global = globalThis; +globalThis.process = { env: { NODE_ENV: '' } }; + +module.exports = {} \ No newline at end of file From f99e8affce197a95d4b829b31b1907cefce10819 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Fri, 19 Nov 2021 14:44:45 -0800 Subject: [PATCH 10/23] Typo Signed-off-by: Dan Cunningham --- .../src/main/resources/OH-INF/config/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml index 7d521f03bd79..e53ca0044164 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml @@ -8,7 +8,7 @@ - If disabled, the OH scriptig library can be imported manually using "require(@oh)" + If disabled, the OH scripting library can be imported manually using "require(@oh)" ]]> From 003f650b624a749cd0a08280cba76276e3c8e644 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 28 Nov 2021 13:44:57 -0800 Subject: [PATCH 11/23] Use npm supplied `openhab` scripting library Signed-off-by: Dan Cunningham --- .../javascript/LICENSE | 277 -- .../javascript/README.md | 82 - .../javascript/actions.js | 50 - .../javascript/docs_config.json | 26 - .../javascript/fluent/condition-conf.js | 60 - .../javascript/fluent/fluent.js | 300 -- .../javascript/fluent/operation-conf.js | 254 -- .../javascript/fluent/package-lock.json | 1548 ------- .../javascript/fluent/package.json | 19 - .../javascript/fluent/trigger-conf.js | 285 -- .../javascript/index.js | 23 - .../javascript/itemchannellink.js | 22 - .../javascript/itemhistory.js | 34 - .../javascript/items/items-provider.js | 116 - .../javascript/items/items.js | 10 - .../javascript/items/managed.js | 481 --- .../javascript/items/package.json | 5 - .../javascript/log.js | 232 -- .../javascript/metadata/metadata-provider.js | 36 - .../javascript/metadata/metadata.js | 76 - .../javascript/metadata/package.json | 5 - .../javascript/osgi.js | 138 - .../javascript/package-lock.json | 3557 ----------------- .../javascript/package.json | 32 - .../javascript/provider.js | 116 - .../javascript/rules.js | 285 -- .../javascript/test/condition-conf.test.js | 117 - .../javascript/test/fluent.test.js | 0 .../javascript/test/operation-conf.test.js | 228 -- .../javascript/test/rewiremock.js | 7 - .../javascript/test/trigger-conf.test.js | 43 - .../javascript/things/package.json | 5 - .../javascript/things/things.js | 104 - .../javascript/triggers.js | 259 -- .../javascript/utils.js | 133 - .../javascript/webpack.config.js | 51 - .../pom.xml | 13 +- .../internal/GraalJSScriptEngineFactory.java | 21 +- .../internal/OpenhabGraalJSScriptEngine.java | 12 +- .../main/resources/OH-INF/config/config.xml | 7 +- .../{@globals.js => @jsscripting-globals.js} | 2 +- .../dto/VenstarAwayModeSerializer.java | 6 +- 42 files changed, 23 insertions(+), 9054 deletions(-) delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/LICENSE delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/README.md delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/actions.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/docs_config.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/index.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/items.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/managed.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/items/package.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/log.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/osgi.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/package-lock.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/package.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/provider.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/rules.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/things/package.json delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/things/things.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/triggers.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/utils.js delete mode 100644 bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js rename bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/{@globals.js => @jsscripting-globals.js} (97%) diff --git a/bundles/org.openhab.automation.jsscripting/javascript/LICENSE b/bundles/org.openhab.automation.jsscripting/javascript/LICENSE deleted file mode 100644 index d3087e4c5404..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/LICENSE +++ /dev/null @@ -1,277 +0,0 @@ -Eclipse Public License - v 2.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE - PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION - OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - - a) in the case of the initial Contributor, the initial content - Distributed under this Agreement, and - - b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; - where such changes and/or additions to the Program originate from - and are Distributed by that particular Contributor. A Contribution - "originates" from a Contributor if it was added to the Program by - such Contributor itself or anyone acting on such Contributor's behalf. - Contributions do not include changes or additions to the Program that - are not Modified Works. - -"Contributor" means any person or entity that Distributes the Program. - -"Licensed Patents" mean patent claims licensable by a Contributor which -are necessarily infringed by the use or sale of its Contribution alone -or when combined with the Program. - -"Program" means the Contributions Distributed in accordance with this -Agreement. - -"Recipient" means anyone who receives the Program under this Agreement -or any Secondary License (as applicable), including Contributors. - -"Derivative Works" shall mean any work, whether in Source Code or other -form, that is based on (or derived from) the Program and for which the -editorial revisions, annotations, elaborations, or other modifications -represent, as a whole, an original work of authorship. - -"Modified Works" shall mean any work in Source Code or other form that -results from an addition to, deletion from, or modification of the -contents of the Program, including, for purposes of clarity any new file -in Source Code form that contains any contents of the Program. Modified -Works shall not include works that contain only declarations, -interfaces, types, classes, structures, or files of the Program solely -in each case in order to link to, bind by name, or subclass the Program -or Modified Works thereof. - -"Distribute" means the acts of a) distributing or b) making available -in any manner that enables the transfer of a copy. - -"Source Code" means the form of a Program preferred for making -modifications, including but not limited to software source code, -documentation source, and configuration files. - -"Secondary License" means either the GNU General Public License, -Version 2.0, or any later versions of that license, including any -exceptions or additional permissions as identified by the initial -Contributor. - -2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free copyright - license to reproduce, prepare Derivative Works of, publicly display, - publicly perform, Distribute and sublicense the Contribution of such - Contributor, if any, and such Derivative Works. - - b) Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such Contributor, - if any, in Source Code or other form. This patent license shall - apply to the combination of the Contribution and the Program if, at - the time the Contribution is added by the Contributor, such addition - of the Contribution causes such combination to be covered by the - Licensed Patents. The patent license shall not apply to any other - combinations which include the Contribution. No hardware per se is - licensed hereunder. - - c) Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. - Each Contributor disclaims any liability to Recipient for claims - brought by any other entity based on infringement of intellectual - property rights or otherwise. As a condition to exercising the - rights and licenses granted hereunder, each Recipient hereby - assumes sole responsibility to secure any other intellectual - property rights needed, if any. For example, if a third party - patent license is required to allow Recipient to Distribute the - Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - - d) Each Contributor represents that to its knowledge it has - sufficient copyright rights in its Contribution, if any, to grant - the copyright license set forth in this Agreement. - - e) Notwithstanding the terms of any Secondary License, no - Contributor makes additional grants to any Recipient (other than - those set forth in this Agreement) as a result of such Recipient's - receipt of the Program under the terms of a Secondary License - (if permitted under the terms of Section 3). - -3. REQUIREMENTS - -3.1 If a Contributor Distributes the Program in any form, then: - - a) the Program must also be made available as Source Code, in - accordance with section 3.2, and the Contributor must accompany - the Program with a statement that the Source Code for the Program - is available under this Agreement, and informs Recipients how to - obtain it in a reasonable manner on or through a medium customarily - used for software exchange; and - - b) the Contributor may Distribute the Program under a license - different than this Agreement, provided that such license: - i) effectively disclaims on behalf of all other Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and fitness - for a particular purpose; - - ii) effectively excludes on behalf of all other Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - - iii) does not attempt to limit or alter the recipients' rights - in the Source Code under section 3.2; and - - iv) requires any subsequent distribution of the Program by any - party to be under a license that satisfies the requirements - of this section 3. - -3.2 When the Program is Distributed as Source Code: - - a) it must be made available under this Agreement, or if the - Program (i) is combined with other material in a separate file or - files made available under a Secondary License, and (ii) the initial - Contributor attached to the Source Code the notice described in - Exhibit A of this Agreement, then the Program may be made available - under the terms of such Secondary Licenses, and - - b) a copy of this Agreement must be included with each copy of - the Program. - -3.3 Contributors may not remove or alter any copyright, patent, -trademark, attribution notices, disclaimers of warranty, or limitations -of liability ("notices") contained within the Program from any copy of -the Program which they Distribute, provided that Contributors may add -their own appropriate notices. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain responsibilities -with respect to end users, business partners and the like. While this -license is intended to facilitate the commercial use of the Program, -the Contributor who includes the Program in a commercial product -offering should do so in a manner which does not create potential -liability for other Contributors. Therefore, if a Contributor includes -the Program in a commercial product offering, such Contributor -("Commercial Contributor") hereby agrees to defend and indemnify every -other Contributor ("Indemnified Contributor") against any losses, -damages and costs (collectively "Losses") arising from claims, lawsuits -and other legal actions brought by a third party against the Indemnified -Contributor to the extent caused by the acts or omissions of such -Commercial Contributor in connection with its distribution of the Program -in a commercial product offering. The obligations in this section do not -apply to any claims or Losses relating to any actual or alleged -intellectual property infringement. In order to qualify, an Indemnified -Contributor must: a) promptly notify the Commercial Contributor in -writing of such claim, and b) allow the Commercial Contributor to control, -and cooperate with the Commercial Contributor in, the defense and any -related settlement negotiations. The Indemnified Contributor may -participate in any such claim at its own expense. - -For example, a Contributor might include the Program in a commercial -product offering, Product X. That Contributor is then a Commercial -Contributor. If that Commercial Contributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Contributor's responsibility -alone. Under this section, the Commercial Contributor would have to -defend claims against the other Contributors related to those performance -claims and warranties, and if a court requires any other Contributor to -pay any damages as a result, the Commercial Contributor must pay -those damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" -BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR -IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF -TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR -PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the Program and assumes all -risks associated with its exercise of rights under this Agreement, -including but not limited to the risks and costs of program errors, -compliance with applicable laws, damage to or loss of data, programs -or equipment, and unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT -PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS -SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST -PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE -EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - -7. GENERAL - -If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further -action by the parties hereto, such provision shall be reformed to the -minimum extent necessary to make such provision valid and enforceable. - -If Recipient institutes patent litigation against any entity -(including a cross-claim or counterclaim in a lawsuit) alleging that the -Program itself (excluding combinations of the Program with other software -or hardware) infringes such Recipient's patent(s), then such Recipient's -rights granted under Section 2(b) shall terminate as of the date such -litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of -time after becoming aware of such noncompliance. If all Recipient's -rights under this Agreement terminate, Recipient agrees to cease use -and distribution of the Program as soon as reasonably practicable. -However, Recipient's obligations under this Agreement and any licenses -granted by Recipient relating to the Program shall continue and survive. - -Everyone is permitted to copy and distribute copies of this Agreement, -but in order to avoid inconsistency the Agreement is copyrighted and -may only be modified in the following manner. The Agreement Steward -reserves the right to publish new versions (including revisions) of -this Agreement from time to time. No one other than the Agreement -Steward has the right to modify this Agreement. The Eclipse Foundation -is the initial Agreement Steward. The Eclipse Foundation may assign the -responsibility to serve as the Agreement Steward to a suitable separate -entity. Each new version of the Agreement will be given a distinguishing -version number. The Program (including Contributions) may always be -Distributed subject to the version of the Agreement under which it was -received. In addition, after a new version of the Agreement is published, -Contributor may elect to Distribute the Program (including its -Contributions) under the new version. - -Except as expressly stated in Sections 2(a) and 2(b) above, Recipient -receives no rights or licenses to the intellectual property of any -Contributor under this Agreement, whether expressly, by implication, -estoppel or otherwise. All rights in the Program not expressly granted -under this Agreement are reserved. Nothing in this Agreement is intended -to be enforceable by any entity that is not a Contributor or Recipient. -No third-party beneficiary rights are created under this Agreement. - -Exhibit A - Form of Secondary Licenses Notice - -"This Source Code may also be made available under the following -Secondary Licenses when the conditions for such availability set forth -in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), -version(s), and exceptions or additional permissions here}." - - Simply including a copy of this Agreement, including this Exhibit A - is not sufficient to license the Source Code under Secondary Licenses. - - If it is not possible or desirable to put the notice in a particular - file, then You may include the notice in a location (such as a LICENSE - file in a relevant directory) where a recipient would be likely to - look for such a notice. - - You may add additional accurate notices of copyright ownership. diff --git a/bundles/org.openhab.automation.jsscripting/javascript/README.md b/bundles/org.openhab.automation.jsscripting/javascript/README.md deleted file mode 100644 index 766e753d9580..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/README.md +++ /dev/null @@ -1,82 +0,0 @@ -[![Build Status](https://travis-ci.org/jpg0/ohj.svg?branch=master)](https://travis-ci.org/jpg0/ohj) -# Openhab Javascript Library - -This library aims to be a fairly high-level ES6 library to support automation in Openhab. - -[API Documentation](https://jpg0.github.io/ohj/ohj/0.1.1/) - -## Requirements - -- ES6 (e.g. GraalJS) -- CommonJS support - -## Installation - -- Install the Openhab 'Experimental Rule Engine' in Paper UI -- Install the [GraalJS bundle](https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/addons/bundles/org.openhab.automation.module.script.graaljs/2.5.0-SNAPSHOT/org.openhab.automation.module.script.graaljs-2.5.0-SNAPSHOT.jar) to upgrade JS runtime to ES6 -- Ensure that you have created the automation scripting directories -- Go to the javascript community lib directory: `cd $OPENHAB_CONF/automation/lib/javascript/community` -- `npm i ohj` (you may need to install npm) - -## Usage - -You should create scripts in $OPENHAB_CONF/automation/jsr223/javascript/personal. - -The API can be imported as a standard CommonJS module: `require('ohj')`. The ohj module itself has various sections that -can be imported as properties of the primary import, e.g. - -``` -//use destructing -const { rules, triggers } = require('ohj'); -//or simply -const rules = require('ohj').rules; -``` - -## Fluent API - -The fluent section of the API can be used to write rules in a high-level, readable style. - -The cleanest way to use the API is with a `with` statement. This is so that it's possible to use the exported functions -without a prefix. An alternative approach (to allow `'use strict'`) would be to explicitly import the functions that you -use, such as `const {when, then} = require('ohj').fluent`. The following examples will use the `with` style of importing. - -Note that for the `timeOfDay` API, you must create a `vTimeOfDay` String item, which is updated like in [the Openhab pattern](https://community.openhab.org/t/design-pattern-time-of-day/15407). A future release will check this. - - -## Fluent Examples - -``` -with(require('ohj').fluent){ - - //turn on the kitchen light at SUNSET - when(timeOfDay("SUNSET")).then(sendOn().toItem("KitchenLight")); - - //turn off the kitchen light at 9PM - when(cron("0 0 21 * * ?")).then(sendOff().toItem("KitchenLight")); - - //set the colour of the hall light to pink at 9PM - when(cron("0 0 21 * * ?")).then(send("300,100,100").toItem("HallLight") - - //when the switch S1 status changes to ON, then turn on the HallLight - when(item('S1').changed().toOn()).then(sendOn().toItem('HallLight')); - - //when the HallLight colour changes pink, if the function fn returns true, then toggle the state of the OutsideLight - when(item('HallLight').changed().to("300,100,100")).if(fn).then(sendToggle().toItem('OutsideLight')); -} - -//and some rules which can be toggled by the items created in the 'gRules' Group: - -with(require('ohj').fluent.withToggle) { - - //when the HallLight receives a command, send the same command to the KitchenLight - when(item('HallLight').receivedCommand()).then(sendIt().toItem('KitchenLight')); - - //when the HallLight is updated to ON, make sure that BedroomLight1 is set to the same state as the BedroomLight2 - when(item('HallLight').receivedUpdate()).then(copyState().fromItem('BedroomLight1').toItem('BedroomLight2')); - - //when the BedroomLight1 is changed, run a custom function - when(item('BedroomLight1').changed()).then(() => { - // do stuff - }); -} -``` diff --git a/bundles/org.openhab.automation.jsscripting/javascript/actions.js b/bundles/org.openhab.automation.jsscripting/javascript/actions.js deleted file mode 100644 index 92475d12b729..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/actions.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Actions namespace. - * This namespace provides access to Openhab actions. All available actions can be accessed as direct properties of this - * object (via their simple class name). - * - * @example Sends a broadcast notification - * let { actions } = require('ohj'); - * actions.NotificationAction.sendBroadcastNotification("Hello World!") - * - * @example Sends a PushSafer notification - * let { actions } = require('ohj'); - * actions.Pushsafer.pushsafer("", "", "", "", "", "", "") - * - * @namespace actions - */ - - - -const osgi = require('./osgi'); -const utils = require('./utils'); -const { actions } = require('@runtime/Defaults'); -const log = require('./log')('actions'); - -const Things = utils.typeBySuffix('core.model.script.actions.Things'); - -const oh1_actions = osgi.findServices("org.openhab.core.scriptengine.action.ActionService", null) || []; -const oh2_actions = osgi.findServices("org.eclipse.smarthome.model.script.engine.action.ActionService", null) || []; -const oh3_actions = osgi.findServices("org.openhab.core.model.script.engine.action.ActionService", null) || []; -[...oh1_actions, ...oh2_actions, ...oh3_actions].forEach(function (item) { - try { - //if an action fails to activate, then warn and continue so that other actions are available - exports[item.getActionClass().getSimpleName()] = item.getActionClass().static; - } catch(e) { - log.warn("Failed to activate action {} due to {}", item, e); - } -}); - -let Exec = utils.typeWithFallback('org.openhab.core.model.script.actions.Exec', 'org.eclipse.smarthome.model.script.actions.Exec'); -let HTTP = utils.typeWithFallback('org.openhab.core.model.script.actions.HTTP', 'org.eclipse.smarthome.model.script.actions.HTTP'); -let LogAction = utils.typeWithFallback('org.openhab.core.model.script.actions.Log', 'org.eclipse.smarthome.model.script.actions.LogAction'); -let Ping = utils.typeWithFallback('org.openhab.core.model.script.actions.Ping', 'org.eclipse.smarthome.model.script.actions.Ping'); -let ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); - -[Exec, HTTP, LogAction, Ping, ScriptExecution].forEach(function (item) { - exports[item.class.getSimpleName()] = item.class.static; -}); - -exports.get = (...args) => actions.get(...args) - -exports.thingActions = (bindingId, thingUid) => Things.getActions(bindingId,thingUid) diff --git a/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json b/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json deleted file mode 100644 index 21c05ee2ff0a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/docs_config.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true, - "dictionaries": ["jsdoc"] - }, - "source": { - "include": [".", "package.json", "README.md"], - "includePattern": ".js$", - "excludePattern": "(node_modules/|docs|dist)" - }, - "plugins": [ - "plugins/markdown" - ], - "templates": { - "cleverLinks": false, - "monospaceLinks": true, - "useLongnameInNav": false - }, - "opts": { - "destination": "./out/", - "encoding": "utf8", - "private": false, - "recurse": true, - "template": "./node_modules/minami" - } -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js deleted file mode 100644 index 8399935b0c88..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/condition-conf.js +++ /dev/null @@ -1,60 +0,0 @@ -const log = require('../log')('condition-conf') -const items = require('../items') - -/** - * Condition that wraps a function to determine whether if passes - * @memberof fluent - * @hideconstructor - */ -class FunctionConditionConf { - /** - * Creates a new function condition. Don't call directly. - * - * @param {*} fn callback which determines whether the condition passes - */ - constructor(fn) { - this.fn = fn; - } - - /** - * Checks whether the rule operations should be run - * - * @private - * @param {...any} args rule trigger arguments - * @returns {Boolean} true only if the operations should be run - */ - check(...args) { - let answer = this.fn(args); - log.debug("Condition returning {}", answer); - return answer; - } -} - -class ItemStateConditionConf { - constructor(item_name) { - this.item_name = item_name; - } - - is(value) { - this.values = [value]; - return this; - } - - in(...values) { - this.values = values; - return this; - } - - check(...args) { - let item = items.getItem(this.item_name); - if(typeof item === 'undefined' || item === null) { - throw Error(`Cannot find item: ${this.item_name}`); - } - return this.values.includes(item.state); - } -} - -module.exports = { - FunctionConditionConf, - ItemStateConditionConf -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js deleted file mode 100644 index d76e75b34b11..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/fluent.js +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Allows creation of rules in a fluent, human-readable style. - * - * @namespace fluent - */ - -const log = require('../log')('fluent'); - -const items = require('../items'); -const rules = require('../rules'); - -const triggers = require('./trigger-conf'); -const operations = require('./operation-conf'); -const conditions = require('./condition-conf'); - -/** - * Creates rules in a fluent style. - */ -class FluentRule { - constructor(triggerConf, toggleable) { - this._triggerConfs = []; - this.toggleable = toggleable; - this.or(triggerConf); - } - - or(triggerConf) { - if (!triggerConf._complete()) { - throw Error("Trigger is not complete!"); - } - this._triggerConfs.push(triggerConf); - return this; - } - - if(condition) { - if(typeof condition === 'function') { - condition = new conditions.FunctionConditionConf(condition); - } - - log.debug("Setting condition on rule: {}", condition); - - this.condition = condition; - return this; - } - - then(operation, optionalRuleGroup) { - if (typeof operation === 'function') { - let operationFunction = operation; - operation = { - _complete: () => true, - _run: x => operationFunction(x), - describe: () => "custom function" - } - } else { - //first check complete - if (!operation._complete()) { - throw Error("Operation is not complete!"); - } - } - - this.operation = operation; - this.optionalRuleGroup = optionalRuleGroup; - - let generatedTriggers = this._triggerConfs.flatMap(x => x._toOHTriggers()) - - const ruleClass = this.toggleable ? rules.SwitchableJSRule : rules.JSRule; - - let fnToExecute = operation._run.bind(operation); //bind the function to it's instance - - //chain (of responsibility for) the execute hooks - for(let triggerConf of this._triggerConfs) { - let next = fnToExecute; - if(typeof triggerConf._executeHook === 'function') { - let maybeHook = triggerConf._executeHook(); - if(maybeHook) { - let hook = maybeHook.bind(triggerConf); //bind the function to it's instance - fnToExecute = function(args) { - return hook(next, args); - } - } - } - } - - if(typeof this.condition !== 'undefined'){ //if conditional, check it first - log.debug("Adding condition to rule: {}", this.condition); - let fnWithoutCheck = fnToExecute; - fnToExecute = (x) => this.condition.check(x) && fnWithoutCheck(x) - } - - return ruleClass({ - name: items.safeItemName(this.describe(true)), - description: this.describe(true), - triggers: generatedTriggers, - ruleGroup: optionalRuleGroup, - execute: function (data) { - fnToExecute(data); - } - }); - } - - describe(compact) { - return (compact ? "": "When ") + - this._triggerConfs.map(t => t.describe(compact)).join(" or ") + - (compact ? "→" : " then ") + - this.operation.describe(compact) + - ((!compact && this.optionalRuleGroup) ? ` (in group ${this.optionalRuleGroup})` : ""); - } -} - -const fluentExports = { - /** - * Specifies a period of day for the rule to fire. Note that this functionality depends on a 'vTimeOfDay' String item - * existing and being updated. - * - * @memberof fluent - * @param {String} period the period, such as 'SUNSET' - * @returns {ItemTriggerConfig} the trigger config - */ - timeOfDay: s => new triggers.ItemTriggerConfig('vTimeOfDay').changed().to(s), - - /** - * Specifies a channel event as a source for the rule to fire. - * - * @memberof fluent - * @param {String} channelName the name of the channel - * @returns {ItemTriggerConfig} the trigger config - */ - channel: s => new triggers.ChannelTriggerConfig(s), - - /** - * Specifies a cron schedule for the rule to fire. - * - * @memberof fluent - * @param {String} cronExpression the cron expression - * @returns {ItemTriggerConfig} the trigger config - */ - cron: s => new triggers.CronTriggerConfig(s), - - /** - * Specifies a rule group (for toggling) that this rule should belong to. - * - * @memberof fluent - * @param {String} groupName the group name - * @returns {*} the group config - */ - inGroup: g => g, - - /** - * Specifies that a command should be sent as a result of this rule firing. - * - * @memberof fluent - * @param {String} command the command to send - * @returns {SendCommandOrUpdateOperation} the operation - */ - send: c => new operations.SendCommandOrUpdateOperation(c), - - /** - * Specifies that an update should be posted as a result of this rule firing. - * - * @memberof fluent - * @param {String} update the update to send - * @returns {SendCommandOrUpdateOperation} the operation - */ - postUpdate: c => new operations.SendCommandOrUpdateOperation(c, false), - - /** - * Specifies the a command 'ON' should be sent as a result of this rule firing. - * - * @memberof fluent - * @returns {SendCommandOrUpdateOperation} the operation - */ - sendOn: () => new operations.SendCommandOrUpdateOperation("ON"), - - /** - * Specifies the a command 'OFF' should be sent as a result of this rule firing. - * - * @memberof fluent - * @returns {SendCommandOrUpdateOperation} the operation - */ - sendOff: () => new operations.SendCommandOrUpdateOperation("OFF"), - - /** - * Specifies a command should be sent to toggle the state of the target object - * as a result of this rule firing. - * - * @memberof fluent - * @returns {ToggleOperation} the operation - */ - sendToggle: () => new operations.ToggleOperation(), - - /** - * Specifies a command should be forwarded to the state of the target object - * as a result of this rule firing. This relies on the trigger being the result - * of a command itself. - * - * @memberof fluent - * @returns {SendCommandOrUpdateOperation} the operation - */ - sendIt: () => new operations.SendCommandOrUpdateOperation(args => args.it.toString(), true, "it"), - - /** - * Specifies a command state should be posted to the target object - * as a result of this rule firing. This relies on the trigger being the result - * of a command itself. - * - * @memberof fluent - * @returns {SendCommandOrUpdateOperation} the operation - */ - postIt: () => new operations.SendCommandOrUpdateOperation(args => args.it.toString(), false, "it"), - - - /** - * Specifies an item as the source of changes to trigger a rule. - * - * @memberof fluent - * @param {String} itemName the name of the item - * @returns {ItemTriggerConfig} the trigger config - */ - item: s => new triggers.ItemTriggerConfig(s), - - /** - * Specifies an group member as the source of changes to trigger a rule. - * - * @memberof fluent - * @param {String} groupName the name of the group - * @returns {ItemTriggerConfig} the trigger config - */ - memberOf: s => new triggers.ItemTriggerConfig(s, true), - - /** - * Copies the state from one item to another. Can be used to proxy item state. State is updated, not - * sent as a command. - * - * @memberof fluent - * @returns {CopyStateOperation} the operation config - */ - copyState: () => new operations.CopyStateOperation(false), - - /** - * Sends the state from one item to another. Can be used to proxy item state. State is - * sent as a command. - * - * @memberof fluent - * @returns {CopyStateOperation} the operation config - */ - copyAndSendState: () => new operations.CopyStateOperation(true), - - /** - * Condition of an item in determining whether to process rule. - * - * @memberof fluent - * @param {String} itemName the name of the item to assess the state - * @returns {ItemStateConditionConf} the operation config - */ - stateOfItem: s => new conditions.ItemStateConditionConf(s), - - /** - * Specifies a Thing status event as a source for the rule to fire. - * - * @memberof fluent - * @param {String} thingUID the UID of the Thing - * @returns {ItemTriggerConfig} the trigger config - */ - thing: s => new triggers.ThingTriggerConfig(s), - - /** - * Specifies a system event as a source for the rule to fire. - * - * @memberof fluent - * @returns {ItemTriggerConfig} the trigger config - */ - system: () => new triggers.SystemTriggerConfig() -} - -module.exports = Object.assign({ - /** - * Specifies when the rule should occur. Will create a standard rule. - * - * @memberof fluent - * @param {ItemTriggerConfig|CronTriggerConfig} config specifies the rule triggers - * @returns {FluentRule} the fluent rule builder - */ - when: o => new FluentRule(o, false), -}, fluentExports); - -/** - * Switches on toggle-able rules for all items created in this namespace. - * - * @memberof fluent - * @name withToggle - */ -module.exports.withToggle = Object.assign({ - /** - * Specifies when the rule should occur. Will create a toggle-able rule. - * - * @memberof fluent - * @param {ItemTriggerConfig|CronTriggerConfig} config specifies the rule triggers - * @returns {FluentRule} the fluent rule builder - */ - when: o => new FluentRule(o, true), -}, fluentExports); \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js deleted file mode 100644 index d9e3347a4681..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/operation-conf.js +++ /dev/null @@ -1,254 +0,0 @@ -const parse_duration = require('parse-duration'); -const log = require('../log')('operation-conf'); -const items = require('../items'); - -/** - * Copies state from one item to another item - * - * @memberof fluent - * @hideconstructor - */ -class CopyStateOperation { - - /** - * Creates a new operation. Don't use constructor directly. - * - * @param {Boolean} send whether to send (or post update) the state - */ - constructor(send) { - this.send = send; - } - - /** - * Sets the item to copy the state from - * @param {String} item_name the item to copy state from - * @returns {CopyStateOperation} this - */ - fromItem(item_name){ - this.from_item = item_name; - return this; - } - - /** - * Sets the item to copy the state to - * @param {String} item_name the item to copy state to - * @returns {CopyStateOperation} this - */ - toItem(item_name){ - this.to_item = item_name; - return this; - } - - /** - * Appends another operation to execute when the rule fires - * @param {CopyStateOperation|SendCommandOperation|ToggleOperation} next - * @returns {CopyStateOperation} this - */ - and(next) { - this.next = next; - return this; - } - - /** - * Runs the operation. Don't call directly. - * - * @private - * @param {Object} args rule firing args - */ - _run(args){ - - if(typeof this.from_item === 'undefined' || this.from_item === null) { - throw Error("From item not set"); - } - - if(typeof this.to_item === 'undefined' || this.to_item === null) { - throw Error("To item not set"); - } - - let from = items.getItem(this.from_item); - if(typeof from === 'undefined' || from === null) { - throw Error(`Cannot find (from) item ${this.from_item}`); - } - - let to = items.getItem(this.to_item); - if(typeof to === 'undefined' || to === null) { - throw Error(`Cannot find (to) item ${this.to_item}`); - } - - if(this.send) { - to.sendCommand(from.state); - } else { - to.postUpdate(from.state); - } - if(this.next){ - this.next.execute(args); - } - } - - /** - * Checks that the operation configuration is complete. Don't call directly. - * - * @private - * @returns true only if the operation is ready to run - */ - _complete(){ - return this.from_item && this.to_item; - } - - /** - * Describes the operation. - * - * @private - * @returns a description of the operation - */ - describe(){ - return `copy state from ${this.from_item} to ${this.to_item}` - } -} - -class SendCommandOrUpdateOperation { - constructor(dataOrSupplier, isCommand = true, optionalDesc) { - this.isCommand = isCommand; - if (typeof dataOrSupplier === 'function') { - this.dataFn = dataOrSupplier; - this.dataDesc = optionalDesc || '[something]'; - } else { - this.dataFn = () => dataOrSupplier; - this.dataDesc = optionalDesc || dataOrSupplier; - } - } - - toItems(itemsOrNames) { - this.toItemNames = itemsOrNames.map(i => (typeof i === 'string') ? i : i.name) - return this; - } - - toItem(itemOrName) { - this.toItemNames = [(typeof itemOrName === 'string') ? itemOrName : itemOrName.name]; - return this; - } - - and(next) { - this.next = next; - return this; - } - - _run(args) { - for(let toItemName of this.toItemNames) { - let item = items.getItem(toItemName); - let data = this.dataFn(args); - - if(this.isCommand) { - item.sendCommand(data) - } else { - item.postUpdate(data); - } - } - - this.next && this.next.execute(args); - } - - _complete() { - return (typeof this.toItemNames) !== 'undefined'; - } - - describe(compact) { - if(compact) { - return this.dataDesc + (this.isCommand ? '⌘' : '↻') + this.toItemNames + (this.next ? this.next.describe() : "") - } else { - return (this.isCommand ? 'send command' : 'post update') + ` ${this.dataDesc} to ${this.toItemNames}` + (this.next ? ` and ${this.next.describe()}` : "") - } - } -} - -class ToggleOperation { - constructor() { - this.next = null; - this.toItem = function (itemName) { - this.itemName = itemName; - return this; - }; - this.and = function (next) { - this.next = next; - return this; - }; - this._run = () => this.doToggle() && (this.next && this.next.execute()) - this._complete = () => true; - this.describe = () => `toggle ${this.itemName}` + (this.next ? ` and ${this.next.describe()}` : "") - } - - doToggle(){ - let item = items.getItem(this.itemName); - - switch(item.type) { - case "SwitchItem": { - let toSend = ('ON' == item.state) ? 'OFF' : 'ON'; - item.sendCommand(toSend); - break; - } - case "ColorItem": { - let toSend = ('0' != item.rawState.getBrightness().toString()) ? 'OFF' : 'ON'; - item.sendCommand(toSend); - break; - } - default: - throw error(`Toggle not supported for items of type ${item.type}`); - } - } -} - -class TimingItemStateOperation { - constructor(item_changed_trigger_config, duration) { - - if(typeof item_changed_trigger_config.to_value === 'undefined') { - throw error("Must specify item state value to wait for!"); - } - - this.item_changed_trigger_config = item_changed_trigger_config; - this.duration_ms = (typeof duration === 'Number' ? duration : parse_duration.parse(duration)) - - this._complete = item_changed_trigger_config._complete; - this.describe = () => item_changed_trigger_config.describe() + " for " + duration; - } - - _toOHTriggers() { - //each time we're triggered, set a callback. - //If the item changes to something else, cancel the callback. - //If the callback executes, run the operation - - //register for all changes as we need to know when it changes away - switch (this.op_type) { - case "changed": - return [triggers.ChangedEventTrigger(this.item_name)]; - default: - throw error("Unknown operation type: " + this.op_type); - } - } - - _executeHook(next) { - if(items.get(this.item_changed_trigger_config.item_name).toString() === this.item_changed_trigger_config.to_value) { - _start_wait(next); - } else { - _cancel_wait(); - } - } - - _start_wait(next) { - this.current_wait = setTimeout(next, this.duration_ms); - } - - _cancel_wait() { - if(this.current_wait) { - cancelTimeout(this.current_wait); - } - } - - -} - -module.exports = { - SendCommandOrUpdateOperation, - TimingItemStateOperation, - ToggleOperation, - CopyStateOperation -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json deleted file mode 100644 index 614d641c584a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package-lock.json +++ /dev/null @@ -1,1548 +0,0 @@ -{ - "name": "fluent", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "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==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "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==" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.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==", - "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=" - }, - "compare-module-exports": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", - "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", - "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=" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cronstrue": { - "version": "1.84.0", - "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.84.0.tgz", - "integrity": "sha512-yfQowBKKZGCZ6Ia2zlpDKhT7Eq4Lq4gzFBmJTrHMNgZh+vkSvmI6NtCvXR21JM00tp6afyY04VEgHaaqlE9oIg==" - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "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=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "fill-keys": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", - "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", - "requires": { - "is-object": "~1.0.1", - "merge-descriptors": "~1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "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==" - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "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==" - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "requires": { - "chalk": "^2.0.1" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "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==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.4", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "module-not-found-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", - "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "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 - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.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==" - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-duration": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", - "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "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=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "proxyquire": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", - "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", - "requires": { - "fill-keys": "^1.0.2", - "module-not-found-error": "^1.0.1", - "resolve": "^1.11.1" - } - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "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" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.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 - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "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==" - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "rewiremock": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.13.9.tgz", - "integrity": "sha512-FDk5uCyvfwgYZtZ9MKdpg6QiSSdjB/a/vU5luKjoJddaqcZz5+u4dXhc3Qf4vNMvDXvnOyodNd1riE5yeqoxaA==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "compare-module-exports": "^2.1.0", - "lodash.some": "^4.6.0", - "lodash.template": "^4.4.0", - "node-libs-browser": "^2.1.0", - "path-parse": "^1.0.5", - "wipe-node-cache": "^2.1.0", - "wipe-webpack-cache": "^2.1.0" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz", - "integrity": "sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz", - "integrity": "sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "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=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wipe-node-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.0.tgz", - "integrity": "sha512-Vdash0WV9Di/GeYW9FJrAZcPjGK4dO7M/Be/sJybguEgcM7As0uwLyvewZYqdlepoh7Rj4ZJKEdo8uX83PeNIw==", - "dev": true - }, - "wipe-webpack-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", - "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", - "dev": true, - "requires": { - "wipe-node-cache": "^2.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.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": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json b/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json deleted file mode 100644 index 18335ade1c4a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "fluent", - "version": "0.0.1", - "description": "Fluent API for Openhab", - "main": "fluent.js", - "private": true, - "dependencies": { - "cronstrue": "^1.84.0", - "mocha": "^6.2.3", - "parse-duration": "^0.1.1", - "proxyquire": "^2.1.3" - }, - "scripts": { - "test": "mocha" - }, - "devDependencies": { - "rewiremock": "^3.13.9" - } -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js b/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js deleted file mode 100644 index 98c9e6fd3dcb..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/fluent/trigger-conf.js +++ /dev/null @@ -1,285 +0,0 @@ -const triggers = require('../triggers'); -const log = require('../log')('trigger-conf'); - -class ChannelTriggerConfig { - constructor(channelName) { - this.channelName = channelName; - this._toOHTriggers = () => [triggers.ChannelEventTrigger(this.channelName, this.eventName)] - } - - describe(compact) { - if (compact) { - return this.channelName + (this.eventName ? `:${this.eventName}` : "") - } else { - return `matches channel "${this.channelName}"` + (this.eventName ? `for event ${this.eventName}` : "") - } - } - - to(eventName) { - return this.triggered(eventName); - } - - triggered(eventName) { - this.eventName = eventName || ""; - return this; - } - - _complete() { - return typeof (this.eventName) !== 'undefined'; - } -}; - -class CronTriggerConfig { - constructor(timeStr) { - this.timeStr = timeStr; - this._complete = () => true - this._toOHTriggers = () => [triggers.GenericCronTrigger(this.timeStr)] - this.describe = (compact) => compact ? this.timeStr : `matches cron "${this.timeStr}"` - } -}; - -class ItemTriggerConfig { - constructor(itemOrName, isGroup) { - this.type = isGroup ? 'memberOf' : 'item'; - if(typeof itemOrName !== 'string') { - itemOrName = itemOrName.name; - } - - this.item_name = itemOrName; - this.describe = () => `${this.type} ${this.item_name} changed` - this.of = this.to; //receivedCommand().of(..) - } - - to(value) { - this.to_value = value; - return this; - } - - from(value) { - if(this.op_type != 'changed') { - throw ".from(..) only available for .changed()"; - } - this.from_value = value; - return this; - } - - toOff() { - return this.to('OFF'); - } - - toOn() { - return this.to('ON'); - } - - receivedCommand() { - this.op_type = 'receivedCommand'; - return this; - } - - receivedUpdate() { - this.op_type = 'receivedUpdate'; - return this; - } - - changed() { - this.op_type = 'changed'; - return this; - } - - _complete() { - return typeof (this.op_type) !== 'undefined'; - } - - describe(compact) { - switch (this.op_type) { - case "changed": - if(compact) { - let transition = this.from_value + '=>' || ''; - if(this.to_value) { - transition = (transition || '=>') + this.to_value; - } - - return `${this.item_name} ${transition}/Δ`; - } else { - let transition = 'changed'; - if(this.from_value) { - transition += ` from ${this.from_value}`; - } - - if(this.to_value) { - transition += ` to ${this.to_value}`; - } - - return `${this.item_name} ${transition}`; - } - case "receivedCommand": - return compact ? `${this.item_name}/⌘` : `${this.type} ${this.item_name} received command`; - case "receivedUpdate": - return compact ? `${this.item_name}/↻` : `${this.type} ${this.item_name} received update`; - default: - throw error("Unknown operation type: " + this.op_type); - } - } - - for(timespan) { - return new TimingItemStateOperation(this, timespan); - } - - _toOHTriggers() { - if (this.type === "memberOf") { - switch (this.op_type) { - case "changed": - return [triggers.GroupStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; - case 'receivedCommand': - return [triggers.GroupCommandTrigger(this.item_name, this.to_value)] - case 'receivedUpdate': - return [triggers.GroupStateUpdateTrigger(this.item_name, this.to_value)] - default: - throw error("Unknown operation type: " + this.op_type); - } - } else { - switch (this.op_type) { - case "changed": - return [triggers.ItemStateChangeTrigger(this.item_name, this.from_value, this.to_value)]; - case 'receivedCommand': - return [triggers.ItemCommandTrigger(this.item_name, this.to_value)] - case 'receivedUpdate': - return [triggers.ItemStateUpdateTrigger(this.item_name, this.to_value)] - default: - throw error("Unknown operation type: " + this.op_type); - } - } - } - - _executeHook() { - - const getReceivedCommand = function(args){ - return args.receivedCommand; - }; - - if(this.op_type === 'receivedCommand') { //add the received command as 'it' - return function(next, args){ - let it = getReceivedCommand(args); - return next({ - ...args, - it - }); - } - } else { - return null; - } - } -} - -class ThingTriggerConfig { - constructor(thingUID) { - this.thingUID = thingUID; - } - - _complete() { - return typeof (this.op_type) !== 'undefined'; - } - - describe(compact) { - switch (this.op_type) { - case "changed": - let transition = 'changed'; - - if (this.to_value) { - transition += ` to ${this.to_value}`; - } - - if (this.from_value) { - transition += ` from ${this.from_value}`; - } - - return `${this.thingUID} ${transition}`; - case "updated": - return compact ? `${this.thingUID}/updated` : `Thing ${this.thingUID} received update`; - default: - throw error("Unknown operation type: " + this.op_type); - } - } - - changed() { - this.op_type = 'changed'; - return this; - } - - updated() { - this.op_type = 'updated'; - return this; - } - - from(value) { - if (this.op_type != 'changed') { - throw ".from(..) only available for .changed()"; - } - this.from_value = value; - return this; - } - - to(value) { - this.to_value = value; - return this; - } - - _toOHTriggers() { - switch (this.op_type) { - case "changed": - return [triggers.ThingStatusChangeTrigger(this.thingUID, this.to_value, this.from_value)]; - case 'updated': - return [triggers.ThingStatusUpdateTrigger(this.thingUID, this.to_value)] - default: - throw error("Unknown operation type: " + this.op_type); - } - } -}; - -class SystemTriggerConfig { - constructor() { - this._toOHTriggers = () => [triggers.SystemStartlevelTrigger(this.level)] - this.describe = (compact) => compact ? `SystemLevel:${this.level}` : `system level "${this.level}"` - } - _complete() { - return typeof (this.level) !== 'undefined'; - } - - rulesLoaded() { - this.level = 40; - return this; - } - - ruleEngineStarted() { - this.level = 50; - return this; - } - - userInterfacesStarted() { - this.level = 70; - return this; - } - - thingsInitialized() { - this.level = 80; - return this; - } - - startupComplete() { - this.level = 100; - return this; - } - - startLevel(level) { - this.level = level; - return this; - } -}; - -module.exports = { - CronTriggerConfig, - ChannelTriggerConfig, - ItemTriggerConfig, - ThingTriggerConfig, - SystemTriggerConfig -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/index.js b/bundles/org.openhab.automation.jsscripting/javascript/index.js deleted file mode 100644 index 2f3a772f73f6..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/index.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @typedef {Object} HostState Native Java Openhab State (instance of org.openhab.core.types.State) - * @typedef {Object} HostItem Native Java Openhab Item (instance of org.openhab.core.items.Item) - * @typedef {Object} HostClass Native Java Class Object (instance of java.lang.Class) - * @typedef {Object} HostRule Native Jave Openhab Rule (instance of org.openhab.core.automation.Rule) - * @typedef {Object} HostTrigger Native Jave Openhab Trigger (instance of org.openhab.core.automation.Trigger) - */ - -// lazy getters to avoid any reference loading all submodules -module.exports = { - get log() { return require('./log') }, - get fluent() { return require('./fluent') }, - get rules() { return require('./rules') }, - get items() { return require('./items') }, - get things() { return require('./things') }, - get metadata() { return require('./metadata') }, - get triggers() { return require('./triggers') }, - get actions() { return require('./actions') }, - get utils() { return require('./utils') }, - get osgi() { return require('./osgi') }, - get provider() { return require('./provider') }, - get itemchannellink() { return require('./itemchannellink') } -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js b/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js deleted file mode 100644 index 202547c9686c..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/itemchannellink.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Items' metadata namespace. - * This namespace provides access to metadata on items. - * - * @private - * @namespace metadata - */ - -const osgi = require('./osgi'); -const utils = require('./utils'); -const log = require('./log')('itemchannellink'); - -let ItemChannelLink = utils.typeWithFallback("org.openhab.core.thing.link.ItemChannelLink", "org.eclipse.smarthome.core.thing.link.ItemChannelLink"); - -let createItemChannelLink = function(itemName, channel) { - log.debug("Creating item channel link {} -> {}", itemName, channel.uid); - return new ItemChannelLink(itemName, channel.rawChannel.getUID()); -} - -module.exports = { - createItemChannelLink -}; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js b/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js deleted file mode 100644 index e462f7678ccf..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/itemhistory.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Items' history module. - * This module provides access to historic state of items. - * - * @private - * @namespace itemshistory - */ - -const utils = require('./utils'); - -const PersistenceExtensions = utils.typeBySuffix("persistence.extensions.PersistenceExtensions"); - -const timeClazz = utils.typeWithFallback("org.joda.time.DateTime", "java.time.Instant"); //remove JodaTime when remove support for OH 2.5.x - -let historicState = function (item, timestamp) { - //todo: check item param - let history = PersistenceExtensions.historicState(item.rawItem, timestamp); - - return history === null ? null : history.state; -}; - -let previousState = function(item, skipEqual = false) { - let result = PersistenceExtensions.previousState(item.rawItem, skipEqual) - - return result === null ? null : result.state; -} - -let latestState = (item) => historicState(item, timeClazz.now()); - -module.exports = { - historicState, - latestState, - previousState -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js b/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js deleted file mode 100644 index 217747bf6578..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/items-provider.js +++ /dev/null @@ -1,116 +0,0 @@ -const osgi = require('../osgi'); -const items = require('./managed'); -const utils = require('../utils'); -const { AbstractProvider } = require('../provider'); - -const ITEM_PROVIDER_CLASS = "org.openhab.core.items.ItemProvider"; - - -class StaticItemProvider extends AbstractProvider { - constructor(items) { - super(ITEM_PROVIDER_CLASS); - this.items = items; - this.registerService(); - } - - addProviderChangeListener(listener) { - } - - removeProviderChangeListener(listener) { - } - - getAll(){ - return this.items; - } -} - - -class ManagedItemProvider extends AbstractProvider { - constructor() { - super(ITEM_PROVIDER_CLASS); - this.items = new Set(); - this.listeners = new Set(); - this.registerService(); - } - - addProviderChangeListener(listener) { - this.listeners.add(listener) - } - - removeProviderChangeListener(listener) { - this.listeners.delete(listener); - } - - add(item) { - if (item instanceof items.OHItem) { - item = item.rawItem; - } - - if (!this.items.has(item)) { - this.items.add(item); - for (let listener of this.listeners) { - listener.added(this.hostProvider, item); - } - } - } - - remove(itemOrName) { - if (typeof itemOrName === 'string') { - this.items.forEach(i => { if (i.name === itemOrName) this.remove(i) }); - } else { - if (itemOrName instanceof items.OHItem) { - itemOrName = itemOrName.rawItem; - } - - if (this.items.has(itemOrName)) { - this.items.delete(itemOrName); - - for (let listener of this.listeners) { - listener.removed(this.hostProvider, item); - } - } - } - } - - update(item) { - if (item instanceof items.OHItem) { - item = item.rawItem; - } - - for (let listener of this.listeners) { - listener.updated(this.hostProvider, item); - } - } - - getAll() { - return utils.jsSetToJavaSet(this.items); - } -} - -class StaticCallbackItemProvider extends AbstractProvider { - constructor() { - super(ITEM_PROVIDER_CLASS); - this.itemsCallbacks = []; - } - - addProviderChangeListener(listener) { - } - - removeProviderChangeListener(listener) { - } - - addItemsCallback(callback) { - this.itemsCallbacks.push(callback); - } - - getAll(){ - return utils.jsArrayToJavaList(this.itemsCallbacks.flatMap(c => c())); - } -} - -module.exports = { - staticItemProvider: items => new StaticItemProvider(items), - managedItemProvider: () => new ManagedItemProvider(), - staticCallbackItemProvider: () => new StaticCallbackItemProvider() -} - \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/items.js b/bundles/org.openhab.automation.jsscripting/javascript/items/items.js deleted file mode 100644 index 46122bcd18bb..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/items.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Items namespace. - * This namespace handles querying and updating Openhab Items. - * @namespace items - */ - -module.exports = { - ...require('./managed'), - provider: require('./items-provider') -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js b/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js deleted file mode 100644 index d676f62bda03..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/managed.js +++ /dev/null @@ -1,481 +0,0 @@ - - -const osgi = require('../osgi'); -const utils = require('../utils'); -const log = require('../log')('items'); -const metadata = require('../metadata'); -const itemhistory = require('../itemhistory'); - -const { UnDefType, events, itemRegistry } = require('@runtime'); - -const itemBuilderFactory = osgi.getService( - "org.openhab.core.items.ItemBuilderFactory", - "org.eclipse.smarthome.core.items.ItemBuilderFactory" -); - -const managedItemProvider = osgi.getService( - "org.openhab.core.items.ManagedItemProvider", - "org.eclipse.smarthome.core.items.ManagedItemProvider" -); - -/** - * Tag value to be attached to all dynamically created items. - * @memberOf items - */ -const DYNAMIC_ITEM_TAG = "_DYNAMIC_"; - -/** - * Class representing an Openhab Item - * @memberOf items - */ -class OHItem { - /** - * Create an OHItem, wrapping a native Java Openhab Item. Don't use this constructor, instead call {@link getItem}. - * @param {HostItem} rawItem Java Item from Host - * @hideconstructor - */ - constructor(rawItem) { - if (typeof rawItem === 'undefined') { - throw Error("Supplied item is undefined"); - } - this.rawItem = rawItem; - } - - /** - * The type of the item: the Simple (without package) name of the Java item type, such as 'Switch'. - * @return {String} the type - */ - get type() { - return this.rawItem.getClass().getSimpleName(); - } - - /** - * The name of the item. - * @return {String} the name - */ - get name() { - return this.rawItem.getName(); - } - - /** - * The label attached to the item - * @return {String} the label - */ - get label() { - return this.rawItem.getLabel(); - } - - /** - * The state of the item, as a string. - * @return {String} the item's state - */ - get state() { - return this.rawState.toString(); - } - - get previousState() { - return itemhistory.previousState(this).toString(); - } - - /** - * The raw state of the item, as a java object. - * @return {HostState} the item's state - */ - get rawState() { - return this.rawItem.state; - } - - /** - * Members / children / direct descendents of the current group item (as returned by 'getMembers()'). Must be a group item. - * @returns {OHItem[]} member items - */ - get members() { - return utils.javaSetToJsArray(this.rawItem.getMembers()).map(raw => new OHItem(raw)); - } - - /** - * All descendents of the current group item (as returned by 'getAllMembers()'). Must be a group item. - * @returns {OHItem[]} all descendent items - */ - get descendents() { - return utils.javaSetToJsArray(this.rawItem.getAllMembers()).map(raw => new OHItem(raw)); - } - - /** - * Whether this item is initialized. - * @type {Boolean} - * @returns true iff the item has not been initialized - */ - get isUninitialized() { - if (this.rawItem.state instanceof UnDefType - || this.rawItem.state.toString() == "Undefined" - || this.rawItem.state.toString() == "Uninitialized" - ) { - return true; - } else { - return false; - } - } - - /** - * Gets metadata values for this item. - * @param {String} namespace The namespace for the metadata to retreive - * @returns {String} the metadata associated with this item and namespace - */ - getMetadataValue(namespace) { - return metadata.getValue(this.name, namespace); - } - - /** - * Updates metadata values for this item. - * @param {String} namespace The namespace for the metadata to update - * @param {String} value the value to update the metadata to - * @returns {String} the updated value - */ - updateMetadataValue(namespace, value) { - return metadata.updateValue(this.name, namespace, value); - } - - /** - * Inserts or updates metadata values for this item. - * @param {String} namespace The namespace for the metadata to update - * @param {String} value the value to update the metadata to - * @returns {Boolean} true iff a new value was inserted - */ - upsertMetadataValue(namespace, value) { - return metadata.upsertValue(this.name, namespace, value); - } - - /** - * Updates metadata values for this item. - * @param {Map} namespaceToValues A map of namespaces to values to update - */ - updateMetadataValues(namespaceToValues) { - for(let k in namespaceToValues) { - metadata.updateValue(this.name, k, namespaceToValues[k]); - } - } - - /** - * Sends a command to the item - * @param {String|HostState} value the value of the command to send, such as 'ON' - * @see sendCommandIfDifferent - * @see postUpdate - */ - sendCommand(value) { - log.debug("Sending command {} to {}", value, this.name); - events.sendCommand(this.rawItem, value); - } - - /** - * Sends a command to the item, but only if the current state is not what is being sent. - * Note - * @param {String|HostState} value the value of the command to send, such as 'ON' - * @returns {Boolean} true if the command was sent, false otherwise - * @see sendCommand - */ - sendCommandIfDifferent(value) { - if (value.toString() != this.state.toString()) { - this.sendCommand(value); - return true; - } - - return false; - } - - /** - * Posts an update to the item - * @param {String|HostState} value the value of the command to send, such as 'ON' - * @see sendCommand - */ - postUpdate(value) { - events.postUpdate(this.rawItem, value); - log.debug("Posted update {} to {}", value, this.name); - } - - /** - * Adds groups to this item - * @param {Array} groupNamesOrItems names of the groups (or the group items themselves) - */ - addGroups(...groupNamesOrItems) { - let groupNames = groupNamesOrItems.map((x) => (typeof x === 'string') ? x : x.name); - this.rawItem.addGroupNames(groupNames); - managedItemProvider.update(this.rawItem); - } - - /** - * Removes groups from this item - * @param {Array} groupNamesOrItems names of the groups (or the group items themselves) - */ - removeGroups(...groupNamesOrItems) { - let groupNames = groupNamesOrItems.map((x) => (typeof x === 'string') ? x : x.name); - for(let groupName of groupNames) { - this.rawItem.removeGroupName(groupName); - } - managedItemProvider.update(this.rawItem); - } - - /** - * Gets the tags from this item - */ - get tags() { - return utils.javaSetToJsArray(this.rawItem.getTags()); - } - - /** - * Adds tags to this item - * @param {Array} tagNames names of the tags to add - */ - addTags(...tagNames) { - this.rawItem.addTags(tagNames); - managedItemProvider.update(this.rawItem); - } - - /** - * Removes tags from this item - * @param {Array} tagNames names of the tags to remove - */ - removeTags(...tagNames) { - for(let tagName of tagNames) { - this.rawItem.removeTag(tagName); - } - managedItemProvider.update(this.rawItem); - } -} - -/** - * Creates a new item within OpenHab. This item is not registered with any provider. - * - * Note that all items created this way have an additional tag attached, for simpler retrieval later. This tag is - * created with the value {@link DYNAMIC_ITEM_TAG}. - * - * @memberOf items - * @param {String} itemName Item name for the Item to create - * @param {String} [itemType] the type of the Item - * @param {String} [category] the category (icon) for the Item - * @param {String[]} [groups] an array of groups the Item is a member of - * @param {String} [label] the label for the Item - * @param {String[]} [tags] an array of tags for the Item - * @param {HostItem} [giBaseType] the group Item base type for the Item - * @param {HostGroupFunction} [groupFunction] the group function used by the Item - * @param {Map} [itemMetadata] a map of metadata to set on the item - */ -const createItem = function (itemName, itemType, category, groups, label, tags, giBaseType, groupFunction, itemMetadata) { - itemName = safeItemName(itemName); - - let baseItem; - if (itemType === 'Group' && typeof giBaseType !== 'undefined') { - baseItem = itemBuilderFactory.newItemBuilder(giBaseType, itemName + "_baseItem").build() - } - - if (itemType !== 'Group') { - groupFunction = undefined; - } - - if (typeof tags === 'undefined') { - tags = []; - } - - tags.push(DYNAMIC_ITEM_TAG); - - try { - var builder = itemBuilderFactory.newItemBuilder(itemType, itemName). - withCategory(category). - withLabel(label); - - builder = builder.withTags(utils.jsArrayToJavaSet(tags)); - - if (typeof groups !== 'undefined') { - builder = builder.withGroups(utils.jsArrayToJavaList(groups)); - } - - if (typeof baseItem !== 'undefined') { - builder = builder.withBaseItem(baseItem); - } - if (typeof groupFunction !== 'undefined') { - builder = builder.withGroupFunction(groupFunction); - } - - var item = builder.build(); - - return new OHItem(item); - } catch (e) { - log.error("Failed to create item: " + e); - throw e; - } -} - -/** - * Creates a new item within OpenHab. This item will persist regardless of the lifecycle of the script creating it. - * - * Note that all items created this way have an additional tag attached, for simpler retrieval later. This tag is - * created with the value {@link DYNAMIC_ITEM_TAG}. - * - * @memberOf items - * @param {String} itemName Item name for the Item to create - * @param {String} [itemType] the type of the Item - * @param {String} [category] the category (icon) for the Item - * @param {String[]} [groups] an array of groups the Item is a member of - * @param {String} [label] the label for the Item - * @param {String[]} [tags] an array of tags for the Item - * @param {HostItem} [giBaseType] the group Item base type for the Item - * @param {HostGroupFunction} [groupFunction] the group function used by the Item - */ -const addItem = function (itemName, itemType, category, groups, label, tags, giBaseType, groupFunction) { - let item = createItem(...arguments); - managedItemProvider.add(item.rawItem); - log.debug("Item added: {}", item.name); - return item; -} - -/** - * Removes an item from OpenHab. The item is removed immediately and cannot be recoved. - * - * @memberOf items - * @param {String|HostItem} itemOrItemName the item to remove - * @returns {Boolean} true iff the item is actually removed - */ -const removeItem = function (itemOrItemName) { - - var itemName; - - if (typeof itemOrItemName === 'string') { - itemName = itemOrItemName; - } else if (itemOrItemName.hasOwnProperty('name')) { - itemName = itemOrItemName.name; - } else { - log.warn('Item not registered (or supplied name is not a string) so cannot be removed'); - return false; - } - - if (typeof getItem(itemName) === 'undefined') { - log.warn('Item not registered so cannot be removed'); - return false; - } - - managedItemProvider.remove(itemName); - - if (typeof itemRegistry.getItem(itemName) === 'undefined') { - log.debug("Item removed: " + itemName); - return true; - } else { - log.warn("Failed to remove item: " + itemName); - return false; - } -} - -/** - * Replaces (upserts) an item. If an item exists with the same name, it will be removed and a new item with - * the supplied parameters will be created in it's place. If an item does not exist with this name, a new - * item will be created with the supplied parameters. - * - * This function can be useful in scripts which create a static set of items which may need updating either - * periodically, during startup or even during development of the script. Using fixed item names will ensure - * that the items remain up-to-date, but won't fail with issues related to duplicate items. - * - * @param {String} itemName Item name for the Item to create - * @param {String} [itemType] the type of the Item - * @param {String} [category] the category (icon) for the Item - * @param {String[]} [groups] an array of groups the Item is a member of - * @param {String} [label] the label for the Item - * @param {String[]} [tags] an array of tags for the Item - * @param {HostItem} [giBaseType] the group Item base type for the Item - * @param {HostGroupFunction} [groupFunction] the group function used by the Item - */ -/* above params copied from addItem */ -const replaceItem = function (/* same args as addItem */) { - var itemName = arguments[0]; - try { - var item = getItem(itemName); - if (typeof item !== 'undefined') { - log.debug("Removing existing item " + itemName + "[" + item + "] to replace with updated one"); - removeItem(itemName); - } - } catch (e) { - if (("" + e).startsWith("org.openhab.core.items.ItemNotFoundException") || ("" + e).startsWith("org.eclipse.smarthome.core.items.ItemNotFoundException")) { - // item not present - } else { - throw e; - } - } - - return addItem.apply(this, arguments); -} - -/** - * Gets an Openhab Item. - * @param {String} name the name of the item - * @param {String} nullIfMissing whether to return null if the item cannot be found (default is to throw an exception) - * @return {OHItem} the item - * @alias module:ohj/items.getItem - */ -const getItem = (name, nullIfMissing = false) => { - try { - if (typeof name === 'string' || name instanceof String) { - return new OHItem(itemRegistry.getItem(name)); - } - } catch(e) { - if(nullIfMissing) { - return null; - } else { - throw e; - } - } -} - -/** - * Gets all Openhab Items with a specific tag. - * @param {String[]} tagNames an array of tags to match against - * @return {OHItem[]} the items with a tag that is included in the passed tags - * @alias module:ohj/items.getItemsByTag - */ -const getItemsByTag = (...tagNames) => { - return utils.javaSetToJsArray(itemRegistry.getItemsByTag(tagNames)).map(i => new OHItem(i)); -} - -/** - * Gets all Openhab Items - * @return {OHItem[]} all items - * @alias module:ohj/items.getItems - */ -const getItems = () => { - return utils.javaSetToJsArray(itemRegistry.getItems()).map(i => new OHItem(i)); -} - -/** - * Helper function to ensure an item name is valid. All invalid characters are replaced with an underscore. - * @param {String} s the name to make value - * @returns {String} a valid item name - */ -const safeItemName = s => s. - replace(/[\"\']/g, ''). //delete - replace(/[^a-zA-Z0-9]/g, '_'); //replace with underscore - -module.exports = { - safeItemName, - getItem, - addItem, - getItemsByTag, - getItems, - replaceItem, - createItem, - removeItem, - OHItem, - /** - * Custom indexer, to allow static item lookup. - * @example - * let { my_object_name } = require('ohj').items.objects; - * ... - * let my_state = my_object_name.state; //my_object_name is an OHItem - * - * @returns {Object} a collection of items allowing indexing by item name - */ - objects: () => new Proxy({}, { - get: function (target, name) { - if (typeof name === 'string' && /^-?\d+$/.test(name)) - return getItem(name); - - throw Error("unsupported function call: " + name); - } - }) -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/items/package.json b/bundles/org.openhab.automation.jsscripting/javascript/items/package.json deleted file mode 100644 index a777cb96debc..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/items/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "items", - "version": "0.0.1", - "main": "items.js" -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/log.js b/bundles/org.openhab.automation.jsscripting/javascript/log.js deleted file mode 100644 index 2bf604866c0b..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/log.js +++ /dev/null @@ -1,232 +0,0 @@ -/** - * Log namespace. - * This namespace provides loggers to log messages to the Openhab Log. - * - * @example Basic logging - * let log = require('ohj').log('my_logger'); - * log.info("Hello World!") - * - * @namespace log - */ - -/** - * Logger prefix - * @memberOf log - */ -const LOGGER_PREFIX = "script.js"; - -//const RuntimeExceptionEx = require('@runtime/osgi').classutil.extend(Java.type('java.lang.RuntimeException')); - -const MessageFormatter = Java.type("org.slf4j.helpers.MessageFormatter"); - -/** - * Logger class. A named logger providing the ability to log formatted messages. - * - * @memberof log - * @hideconstructor - */ -class Logger { - /** - * Creates a new logger. Don't use directly, use {@link log} on module. - * - * @param {String} _name the name of the logger. Will be prefixed by {@link LOGGER_PREFIX} - * @param {*} _listener a callback to receive logging calls. Can be used to send calls elsewhere, such as escalate errors. - */ - constructor(_name, appenderProvider) { - this._name = _name || this._getCallerDetails("", 3).fileName.replace(/\.[^/.]+$/, "") - this.appenderProvider = appenderProvider; - this._logger = Java.type("org.slf4j.LoggerFactory").getLogger(LOGGER_PREFIX + "." + this.name.toString().toLowerCase()); - } - - /** - * Method to determine caller. Don't use directly. - * - * @private - * @param {Object} msg the message to get caller details for - * @param {Number} ignoreStackDepth the number of stack frames which to ignore in calculating caller - * @returns {Error} message as an error object, with fileName, caller and optional lineNumber properties - */ - _getCallerDetails(msg, ignoreStackDepth) { - let stackLine = null; - - if (!(msg instanceof Error)) { - msg = Error(msg); - stackLine = msg.stack.split('\n')[ignoreStackDepth]; - } else { - stackLine = msg.stack.split('\n')[1]; - } - - //pick out the call, fileName & lineNumber from the specific frame - let match = stackLine.match(/^\s+at\s*(?[^ ]*) \(?(?[^:]+):(?[0-9]+):[0-9]+\)?/); - - if (match) { - Object.assign(msg, match.groups); - } else { //won't match an 'eval'd string, so retry - match = stackLine.match(/\s+at\s+\:(?[0-9]+):[0-9]+/) - if (match) { - Object.assign(msg, { - fileName: "", - caller: "" - }, match.groups) - } else { - Object.assign(msg, { - fileName: "", - caller: "" - }) - } //throw Error(`Failed to parse stack line: ${stackLine}`); - } - - return msg; - } - - /** - * Method to format a log message. Don't use directly. - * - * @private - * @param {Object} msg the message to get caller details for - * @param {String} levelString the level being logged at - * @param {Number} ignoreStackDepth the number of stack frames which to ignore in calculating caller - * @param {String} [prefix=log] the prefix type, such as none, level, short or log. - * @returns {Error} message with 'message' String property - */ - _formatLogMessage(msg, levelString, ignoreStackDepth, prefix = "log") { - - let clazz = this; - let msgData = { - message: msg.toString(), - get caller() {//don't run this unless we need to, then cache it - this.cached = this.cached || clazz._getCallerDetails(msg, ignoreStackDepth) - return this.cached; - } - }; - - levelString = levelString.toUpperCase(); - - switch (prefix) { - case "none": return msgData.message; - case "level": return `[${levelString}] ${msgData.message}` - case "short": return `${msgData.message}\t\t[${this.name}, ${msgData.caller.fileName}:${msgData.caller.lineNumber}]` - case "log": return `${msgData.message}\t\t[${this.name} at source ${msgData.caller.fileName}, line ${msgData.caller.lineNumber}]` - default: throw Error(`Unknown prefix type ${prefix}`) - } - } - - /** - * Logs at ERROR level. - * @see atLevel - */ - error() { this.atLevel('error', ...arguments) } - /** - * Logs at ERROR level. - * @see atLevel - */ - warn() { this.atLevel('warn', ...arguments) } - /** - * Logs at INFO level. - * @see atLevel - */ - info() { this.atLevel('info', ...arguments) } - /** - * Logs at DEBUG level. - * @see atLevel - */ - debug() { this.atLevel('debug', ...arguments) } - /** - * Logs at TRACE level. - * @see atLevel - */ - trace() { this.atLevel('trace', ...arguments) } - - /** - * Logs a message at the supplied level. The message may include placeholders {} which - * will be substituted into the message string only if the message is actually logged. - * - * @example - * log.atLevel('INFO', 'The widget was created as {}', widget); - * - * - * @param {String} level The level at which to log, such as 'INFO', or 'DEBUG' - * @param {String|Error} msg the message to log, possibly with object placeholders - * @param {Object[]} [objects] the objects to substitute into the log message - */ - atLevel(level, msg, ...objects) { - let titleCase = level[0].toUpperCase() + level.slice(1) - try { - if (this._logger[`is${titleCase}Enabled`]()) { - - this.maybeLogWithThrowable(level, msg, objects) || - this.writeLogLine(level, this._formatLogMessage(msg, level, 6), objects); - } - } catch (err) { - this._logger.error(this._formatLogMessage(err, "error", 0)); - } - } - - maybeLogWithThrowable(level, msg, objects) { - if(objects.length === 1){ - let obj = objects[0]; - if((obj instanceof Error || (obj.message && obj.name && obj.stack)) && !msg.includes("{}")) { //todo: better substitution detected - //log the basic message - this.writeLogLine(level, msg, objects); - - //and log the exception - this.writeLogLine(level, `${obj.name} : ${obj.message}\n${obj.stack}`); - return true; - } - } - return false; - } - - writeLogLine(level, message, objects = []) { - let formatted = MessageFormatter.arrayFormat(message, objects).getMessage(); - - this._logger[level](formatted); - - if (this.appenderProvider) { - let appender = this.appenderProvider(level); - if(appender != null) { - appender.logAt(level, formatted) - } - } - } - - /** - * The listener function attached to this logger. - * @return {*} the listener function - */ - get listener() { return this._listener } - - /** - * The name of this logger - * @return {String} the logger name - */ - get name() { return this._name } -} - -let appenderForLevel = null -//attempt to load & cache appender as module -let getAppenderForLevel = function(){ - if(appenderForLevel === null) { - appenderForLevel = () => null; - - // try { - // appenderForLevel = require('log_appenders').forLevel; - // } catch(e) { - // new Logger("log", () => null).debug("No appenders found for log", e); - // } - } - - return appenderForLevel; -} - -/** - * Creates a logger. - * @see Logger - * @name default - * @param {string} name the name of the logger - * @param {*} [_listener] an optional listener to process log events. - * @memberof log - */ -module.exports = function (_name, appenderProvider = getAppenderForLevel()) { - return new Logger(_name, appenderProvider); -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js deleted file mode 100644 index 37f54b6d722a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata-provider.js +++ /dev/null @@ -1,36 +0,0 @@ -const { AbstractProvider } = require('../provider'); - -const METADATA_PROVIDER_CLASS = "org.eclipse.smarthome.core.items.MetadataProvider"; - -class StaticCallbackMetadataProvider extends AbstractProvider { - constructor(){ - super(METADATA_PROVIDER_CLASS); - this.metadataCallbacks = []; - } - - addProviderChangeListener(listener) { - } - - removeProviderChangeListener(listener) { - } - - addMetadataCallback(callback) { - this.metadataCallbacks.push(callback); - } - - getAll(){ - require('../log')('metadata-provider').debug("///"+this.metadataCallbacks.length); - require('../log')('metadata-provider').debug("///"+this.metadataCallbacks.flatMap(c => c()).length); - - for(let x of this.metadataCallbacks.flatMap(c => c())) { - require('../log')('metadata-provider').debug(x); - } - - return utils.jsArrayToJavaList(this.metadataCallbacks.flatMap(c => c())); - } -} - -module.exports = { - staticCallbackMetadataProvider: () => new StaticCallbackMetadataProvider() - -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js b/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js deleted file mode 100644 index 19c15a0288cd..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/metadata/metadata.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Items' metadata namespace. - * This namespace provides access to metadata on items. - * - * @private - * @namespace metadata - */ - -const osgi = require('../osgi'); -const utils = require('../utils'); -const log = require('../log')('metadata'); - -let MetadataRegistry = osgi.getService("org.openhab.core.items.MetadataRegistry", "org.eclipse.smarthome.core.items.MetadataRegistry"); -let Metadata = utils.typeWithFallback("org.openhab.core.items.Metadata", "org.eclipse.smarthome.core.items.Metadata"); -let MetadataKey = utils.typeWithFallback("org.openhab.core.items.MetadataKey", "org.eclipse.smarthome.core.items.MetadataKey"); - - -/** - * This function will return the Metadata object associated with the - * specified Item. - * - * @memberof metadata - * @param {String} name of the Item - * @param {String} namespace name of the namespace - * @returns {String|null} the metadata as a string, or null - */ -let getValue = function(itemName, namespace) { - let result = MetadataRegistry.get(new MetadataKey(namespace, itemName)); - return result ? result.value : null; -}; - -let addValue = function(itemName, namespace, value) { - let key = new MetadataKey(namespace, itemName); - MetadataRegistry.add(new Metadata(key, value, {})); -} - -let updateValue = function(itemName, namespace, value) { - let metadata = createMetadata(itemName, namespace, value); - let result = MetadataRegistry.update(metadata); - return result ? result.value : null; -} - -/** - * Adds (inserts) or updates a metadata value. - * - * @param {String} itemName the name of the item - * @param {String} namespace the name of the namespace - * @param {String} value the value to insert or update - * @returns {Boolean} true if the value was added, false if it was updated - */ -let upsertValue = function(itemName, namespace, value) { - let existing = getValue(itemName, namespace); - - if (existing === null) { - addValue(itemName, namespace, value); - return true; - } else { - updateValue(itemName, namespace, value); - return false; - } -} - -let createMetadata = function(itemName, namespace, value) { - log.debug("Creating metadata {}:{} = {}", namespace, itemName, value); - let key = new MetadataKey(namespace, itemName); - return new Metadata(key, value, {}); -} - -module.exports = { - getValue, - addValue, - updateValue, - upsertValue, - createMetadata, - provider: require('./metadata-provider') -}; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json b/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json deleted file mode 100644 index affb9fbb7d11..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/metadata/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "metadata", - "version": "0.0.1", - "main": "metadata.js" -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/osgi.js b/bundles/org.openhab.automation.jsscripting/javascript/osgi.js deleted file mode 100644 index deba53534478..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/osgi.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * OSGi module. - * This module provides access to OSGi services. - * - * @namespace osgi - */ - -const log = require('./log')('osgi'); -const bundleContext = require('@runtime/osgi').bundleContext; -const lifecycle = require('@runtime/osgi').lifecycle; -const Hashtable = Java.type('java.util.Hashtable'); - -/** - * Map of interface names to sets of services registered (by this module) - */ -let registeredServices = {}; - - -let jsObjectToHashtable = function(obj) { - if(obj === null) { - return null; - } - - let rv = new Hashtable(); - for(let k in obj) { - rv.put(k, obj[k]); - } - return rv; -} - -/** - * Gets a service registered with OSGi. - * - * @private - * @param {String|HostClass} classOrName the class of the service to get - * @returns an instance of the service, or null if it cannot be found - * @memberOf osgi - */ -let lookupService = function (classOrName) { - var bc = bundleContext; - if(bundleContext === undefined) { - log.warn("bundleContext is undefined"); - var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil"); - var _bundle = FrameworkUtil.getBundle(scriptExtension.class); - bc = (_bundle !== null) ? _bundle.getBundleContext() : null; - } - if (bc !== null) { - var classname = (typeof classOrName === "object") ? classOrName.getName() : classOrName; - var ref = bc.getServiceReference(classname); - return (ref !== null) ? bc.getService(ref) : null; - } -} - -/** - * Gets a service registered with OSGi. Allows providing multiple classes/names to try for lookup. - * - * @param {Array} classOrNames the class of the service to get - * - * @returns an instance of the service, or null if it cannot be found - * @throws {Error} if no services of the requested type(s) can be found - * @memberOf osgi - */ -let getService = function (...classOrNames) { - let rv = null; - - for(let classOrName of classOrNames) { - try { - rv = lookupService(classOrName) - } catch(e) { - log.warn(`Failed to get service ${classOrName}: {}`, e); - } - - if(typeof rv !== 'undefined' && rv !== null) { - return rv; - } - } - - throw Error(`Failed to get any services of type(s): ${classOrNames}`); -} - -/** - * Finds services registered with OSGi. - * - * @param {String} className the class of the service to get - * @param {*} [filter] an optional filter used to filter the returned services - * @returns {Object[]} any instances of the service that can be found - * @memberOf osgi - */ -let findServices = function (className, filter) { - if (bundleContext !== null) { - var refs = bundleContext.getAllServiceReferences(className, filter); - return refs != null ? [...refs].map(ref => bundleContext.getService(ref)) : []; - } -} - -let registerService = function(service, ...interfaceNames) { - lifecycle.addDisposeHook(() => unregisterService(service)); - registerPermanentService(service, interfaceNames, null); -} - -let registerPermanentService = function(service, interfaceNames, properties = null) { - - let registration = bundleContext.registerService(interfaceNames, service, jsObjectToHashtable(properties)); - - for (let interfaceName of interfaceNames) { - if(typeof registeredServices[interfaceName] === 'undefined') { - registeredServices[interfaceName] = new Set(); - } - registeredServices[interfaceName].add({service, registration}); - log.debug("Registered service {} of as {}", service, interfaceName) - } - return registration; -} - -let unregisterService = function(serviceToUnregister) { - - log.debug("Unregistering service {}", serviceToUnregister); - - for(let interfaceName in registeredServices) { - let servicesForInterface = registeredServices[interfaceName]; - - servicesForInterface.forEach(({service, registration}) => { - if (service == serviceToUnregister) { - servicesForInterface.delete({service, registration}); - registration.unregister(); - log.debug("Unregistered service: {}", service); - } - }); - } -} - -module.exports = { - getService, - findServices, - registerService, - registerPermanentService, - unregisterService -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json b/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json deleted file mode 100644 index c97872c9af0d..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/package-lock.json +++ /dev/null @@ -1,3557 +0,0 @@ -{ - "name": "oh", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", - "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", - "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==" - }, - "@babel/polyfill": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.7.0.tgz", - "integrity": "sha512-/TS23MVvo34dFmf8mwCisCbWGrfhbiWZSwBo6HkADTBhUa2Q/jWltyY/tpofz/b6/RIhqaqQcquptCirqIhOaQ==", - "requires": { - "core-js": "^2.6.5", - "regenerator-runtime": "^0.13.2" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" - } - } - }, - "@babel/runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", - "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", - "requires": { - "regenerator-runtime": "^0.13.2" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" - } - } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", - "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", - "dev": true - }, - "@types/babel-types": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz", - "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==" - }, - "@types/babylon": { - "version": "6.16.5", - "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz", - "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==", - "requires": { - "@types/babel-types": "*" - } - }, - "@types/eslint": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", - "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "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/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", - "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", - "dev": true - }, - "@webpack-cli/info": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", - "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", - "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" - }, - "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "requires": { - "acorn": "^4.0.4" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" - } - } - }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "ast-types": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.12.4.tgz", - "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - } - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "better-docs": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/better-docs/-/better-docs-1.4.7.tgz", - "integrity": "sha512-LQjdTcZT+G4IG6LihCtQqnGChghBRVy63f91YDFK8+ggPlVPt10mXEZTHwE56PMlisKlVb/1Ky6V+dZOoJ+qVw==", - "requires": { - "brace": "^0.11.1", - "react-ace": "^6.5.0", - "react-docgen": "^4.1.1", - "react-frame-component": "^4.1.1", - "underscore": "^1.9.1", - "vue-docgen-api": "^3.22.0", - "vue2-ace-editor": "^0.0.13" - } - }, - "bluebird": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", - "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "brace": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz", - "integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "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 - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^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 - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", - "dev": true - }, - "catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "character-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", - "requires": { - "is-regex": "^1.0.3" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "requires": { - "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==" - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "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==", - "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=" - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "compare-module-exports": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", - "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", - "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=" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constantinople": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", - "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", - "requires": { - "@types/babel-types": "^7.0.0", - "@types/babylon": "^6.16.2", - "babel-types": "^6.26.0", - "babylon": "^6.18.0" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "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==" - } - } - }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cronstrue": { - "version": "1.84.0", - "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-1.84.0.tgz", - "integrity": "sha512-yfQowBKKZGCZ6Ia2zlpDKhT7Eq4Lq4gzFBmJTrHMNgZh+vkSvmI6NtCvXR21JM00tp6afyY04VEgHaaqlE9oIg==" - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diff-match-patch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.4.tgz", - "integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.872", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.872.tgz", - "integrity": "sha512-qG96atLFY0agKyEETiBFNhpRLSXGSXOBuhXWpbkYqrLKKASpRyRBUtfkn0ZjIf/yXfA7FA4nScVOMpXSHFlUCQ==", - "dev": true - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - } - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "es-abstract": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", - "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.0", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.6.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "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" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "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.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "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==" - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "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-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 - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "fill-keys": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", - "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", - "dev": true, - "requires": { - "is-object": "~1.0.1", - "merge-descriptors": "~1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "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-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "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-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "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": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "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 - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", - "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", - "requires": { - "acorn": "~4.0.2", - "object-assign": "^4.0.1" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" - } - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "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-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "jest-worker": { - "version": "27.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", - "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "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" - } - } - } - }, - "js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "js2xmlparser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", - "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.0" - } - }, - "jsdoc": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", - "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", - "dev": true, - "requires": { - "@babel/parser": "^7.4.4", - "bluebird": "^3.5.4", - "catharsis": "^0.8.11", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.0", - "klaw": "^3.0.0", - "markdown-it": "^8.4.2", - "markdown-it-anchor": "^5.0.2", - "marked": "^0.7.0", - "mkdirp": "^0.5.1", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.0.1", - "taffydb": "2.6.2", - "underscore": "~1.9.1" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "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 - }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", - "requires": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - } - } - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, - "lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" - }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", - "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==", - "dev": true - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "requires": { - "mime-db": "1.50.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minami": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/minami/-/minami-1.2.3.tgz", - "integrity": "sha1-mbbc37LwpU2hycj3qjoyd4eq+fg=", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "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==" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", - "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.0", - "yargs-parser": "13.1.1", - "yargs-unparser": "1.6.0" - } - }, - "module-not-found-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", - "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", - "requires": { - "minimatch": "^3.0.2" - } - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.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 - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-duration": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", - "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "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-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" - } - }, - "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 - } - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "proxyquire": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.3.tgz", - "integrity": "sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==", - "dev": true, - "requires": { - "fill-keys": "^1.0.2", - "module-not-found-error": "^1.0.1", - "resolve": "^1.11.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pug": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz", - "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==", - "requires": { - "pug-code-gen": "^2.0.2", - "pug-filters": "^3.1.1", - "pug-lexer": "^4.1.0", - "pug-linker": "^3.0.6", - "pug-load": "^2.0.12", - "pug-parser": "^5.0.1", - "pug-runtime": "^2.0.5", - "pug-strip-comments": "^1.0.4" - } - }, - "pug-attrs": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz", - "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==", - "requires": { - "constantinople": "^3.0.1", - "js-stringify": "^1.0.1", - "pug-runtime": "^2.0.5" - } - }, - "pug-code-gen": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz", - "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==", - "requires": { - "constantinople": "^3.1.2", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.1", - "pug-attrs": "^2.0.4", - "pug-error": "^1.3.3", - "pug-runtime": "^2.0.5", - "void-elements": "^2.0.1", - "with": "^5.0.0" - } - }, - "pug-error": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz", - "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==" - }, - "pug-filters": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz", - "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==", - "requires": { - "clean-css": "^4.1.11", - "constantinople": "^3.0.1", - "jstransformer": "1.0.0", - "pug-error": "^1.3.3", - "pug-walk": "^1.1.8", - "resolve": "^1.1.6", - "uglify-js": "^2.6.1" - } - }, - "pug-lexer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz", - "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==", - "requires": { - "character-parser": "^2.1.1", - "is-expression": "^3.0.0", - "pug-error": "^1.3.3" - } - }, - "pug-linker": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz", - "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==", - "requires": { - "pug-error": "^1.3.3", - "pug-walk": "^1.1.8" - } - }, - "pug-load": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz", - "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==", - "requires": { - "object-assign": "^4.1.0", - "pug-walk": "^1.1.8" - } - }, - "pug-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz", - "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==", - "requires": { - "pug-error": "^1.3.3", - "token-stream": "0.0.1" - } - }, - "pug-runtime": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz", - "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==" - }, - "pug-strip-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz", - "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==", - "requires": { - "pug-error": "^1.3.3" - } - }, - "pug-walk": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz", - "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "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" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "react-ace": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-6.6.0.tgz", - "integrity": "sha512-Jehhp8bxa8kqiXk07Jzy+uD5qZMBwo43O+raniGHjdX7Qk93xFkKaAz8LxtUVZPJGlRnV5ODMNj0qHwDSN+PBw==", - "requires": { - "@babel/polyfill": "^7.4.4", - "brace": "^0.11.1", - "diff-match-patch": "^1.0.4", - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", - "prop-types": "^15.7.2" - } - }, - "react-docgen": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-4.1.1.tgz", - "integrity": "sha512-o1wdswIxbgJRI4pckskE7qumiFyqkbvCO++TylEDOo2RbMiueIOg8YzKU4X9++r0DjrbXePw/LHnh81GRBTWRw==", - "requires": { - "@babel/core": "^7.0.0", - "@babel/runtime": "^7.0.0", - "async": "^2.1.4", - "commander": "^2.19.0", - "doctrine": "^3.0.0", - "node-dir": "^0.1.10", - "recast": "^0.17.3" - } - }, - "react-frame-component": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.1.tgz", - "integrity": "sha512-NfJp90AvYA1R6+uSYafQ+n+UM2HjHqi4WGHeprVXa6quU9d8o6ZFRzQ36uemY82dlkZFzf2jigFx6E4UzNFajA==" - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.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 - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "recast": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.17.6.tgz", - "integrity": "sha512-yoQRMRrK1lszNtbkGyM4kN45AwylV5hMiuEveUBlxytUViWevjvX6w+tzJt1LH4cfUhWt4NZvy3ThIhu6+m5wQ==", - "requires": { - "ast-types": "0.12.4", - "esprima": "~4.0.0", - "private": "^0.1.8", - "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==" - } - } - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "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 - }, - "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.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 - }, - "rewiremock": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.13.9.tgz", - "integrity": "sha512-FDk5uCyvfwgYZtZ9MKdpg6QiSSdjB/a/vU5luKjoJddaqcZz5+u4dXhc3Qf4vNMvDXvnOyodNd1riE5yeqoxaA==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "compare-module-exports": "^2.1.0", - "lodash.some": "^4.6.0", - "lodash.template": "^4.4.0", - "node-libs-browser": "^2.1.0", - "path-parse": "^1.0.5", - "wipe-node-cache": "^2.1.0", - "wipe-webpack-cache": "^2.1.0" - } - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "requires": { - "align-text": "^0.1.1" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "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 - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "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.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "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 - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "terser": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", - "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", - "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", - "dev": true, - "requires": { - "jest-worker": "^27.0.6", - "p-limit": "^3.1.0", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "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" - } - }, - "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 - } - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "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=" - }, - "token-stream": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", - "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=" - }, - "ts-map": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-map/-/ts-map-1.0.3.tgz", - "integrity": "sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==" - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==" - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" - }, - "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" - }, - "dependencies": { - "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 - } - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" - }, - "vue-docgen-api": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/vue-docgen-api/-/vue-docgen-api-3.26.0.tgz", - "integrity": "sha512-ujdg4i5ZI/wE46RZQMFzKnDGyhEuPCu+fMA86CAd9EIek/6+OqraSVBm5ZkLrbEd5f8xxdnqMU4yiSGHHeao/Q==", - "requires": { - "@babel/parser": "^7.2.3", - "@babel/types": "^7.0.0", - "ast-types": "^0.12.2", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.5", - "pug": "^2.0.3", - "recast": "^0.17.3", - "ts-map": "^1.0.3", - "typescript": "^3.2.2", - "vue-template-compiler": "^2.0.0" - } - }, - "vue-template-compiler": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", - "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==", - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "vue2-ace-editor": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/vue2-ace-editor/-/vue2-ace-editor-0.0.13.tgz", - "integrity": "sha512-uQICyvJzYNix16xeYjNAINuNUQhPbqMR7UQsJeI+ycpEd2otsiNNU73jcZqHkpjuz0uaHDHnrpzQuI/RApsKXA==", - "requires": { - "brace": "^0.11.0" - } - }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.58.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.58.2.tgz", - "integrity": "sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^3.2.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - } - } - }, - "webpack-cli": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.1.tgz", - "integrity": "sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.0", - "@webpack-cli/info": "^1.4.0", - "@webpack-cli/serve": "^1.6.0", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", - "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "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 - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" - }, - "wipe-node-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.0.tgz", - "integrity": "sha512-Vdash0WV9Di/GeYW9FJrAZcPjGK4dO7M/Be/sJybguEgcM7As0uwLyvewZYqdlepoh7Rj4ZJKEdo8uX83PeNIw==", - "dev": true - }, - "wipe-webpack-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", - "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", - "dev": true, - "requires": { - "wipe-node-cache": "^2.1.0" - } - }, - "with": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", - "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", - "requires": { - "acorn": "^3.1.0", - "acorn-globals": "^3.0.0" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xmlcreate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", - "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.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": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - }, - "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/bundles/org.openhab.automation.jsscripting/javascript/package.json b/bundles/org.openhab.automation.jsscripting/javascript/package.json deleted file mode 100644 index f94b7f16b666..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "oh", - "version": "0.1.0", - "description": "JavaScript Library for openHAB", - "private": false, - "license": "EPL-2.0", - "main": "dist/oh.js", - "repository": { - "type": "git", - "url": "git://github.com/jpg0/ohj.git" - }, - "dependencies": { - "better-docs": "^1.4.7", - "cronstrue": "^1.84.0", - "parse-duration": "^0.1.1", - "minimist": "^1.2.5" - }, - "scripts": { - "test": "mocha", - "docs": "./node_modules/.bin/jsdoc --configure docs_config.json", - "deploy": "npm test && npm run docs" - }, - "devDependencies": { - "jsdoc": "^3.6.3", - "minami": "^1.2.3", - "mocha": "^6.2.2", - "proxyquire": "^2.1.3", - "rewiremock": "^3.13.9", - "webpack": "^5.58.2", - "webpack-cli": "^4.9.1" - } -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/provider.js b/bundles/org.openhab.automation.jsscripting/javascript/provider.js deleted file mode 100644 index 02021271f44d..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/provider.js +++ /dev/null @@ -1,116 +0,0 @@ -const osgi = require('./osgi'); -const log = require('./log')('provider'); -const utils = require('./utils'); - -function getAllFunctionNames(obj) { - var props = []; - var o = obj; - do { - props = props.concat(Object.getOwnPropertyNames(o)); - o = Object.getPrototypeOf(o); - } while (o.constructor.name !== 'AbstractProvider'); - - return props.filter(p => typeof obj[p] === 'function'); -} - -class AbstractProvider { - constructor(type) { - this.typeName = type.class.getName(); - this.javaType = Java.extend(type);//require('@runtime/osgi').classutil.extend(type); - } - - register() { - let javaConfig = {}; - - let functionNamesToBind = getAllFunctionNames(this). - filter(f => f !== 'constructor'). - filter(f => f !== 'javaType'); - - for(let fn of functionNamesToBind) { - javaConfig[fn] = this[fn].bind(this); - } - - let hostProvider = this.processHostProvider(new this.javaType(javaConfig)); - - this.hostProvider = hostProvider; - - osgi.registerService(this.hostProvider, this.typeName); - } - - processHostProvider(hostProvider) { - return hostProvider; - } -} - -class CallbackProvider extends AbstractProvider { - constructor(type){ - super(type); - this.callbacks = []; - } - - addProviderChangeListener(listener) { - } - - removeProviderChangeListener(listener) { - } - - addCallback(callback) { - this.callbacks.push(callback); - } - - getAll(){ - log.debug(`Providing ${utils.jsArrayToJavaList(this.callbacks.flatMap(c => c())).length} for ${this.typeName}`) - return utils.jsArrayToJavaList(this.callbacks.flatMap(c => c())); - } -} - -class ItemProvider extends CallbackProvider { - constructor(ctxName = "JSAPI") { - super(utils.typeBySuffix('core.items.ItemProvider')) - this.ctxName = ctxName; - } - - processHostProvider(hostProvider) { - return require('@runtime/provider').itemBinding.create(this.ctxName, super.processHostProvider(hostProvider)); - } -} - -class StateDescriptionFragmentProvider extends AbstractProvider { - constructor() { - super(utils.typeBySuffix('core.types.StateDescriptionFragmentProvider')); - this.callbacks = []; - } - - addCallback(callback) { - this.callbacks.push(callback); - } - - getStateDescriptionFragment(itemName, locale) { - for(let c of this.callbacks) { - let result = c(itemName, locale); - if(typeof result !== 'undefined') { - return result; - } - } - - return null; - } - - getRank() { - return 0; - } - -} - -let ItemChannelLinkProviderClass = utils.typeBySuffix('core.thing.link.ItemChannelLinkProvider'); -let MetadataProviderClass = utils.typeBySuffix('core.items.MetadataProvider'); -let ThingProviderClass = utils.typeBySuffix('core.thing.ThingProvider'); - -module.exports = { - AbstractProvider, - newCallbackItemChannelLinkProvider: () => new CallbackProvider(ItemChannelLinkProviderClass), - newCallbackMetadataProvider: () => new CallbackProvider(MetadataProviderClass), - newCallbackItemProvider: c => new ItemProvider(c), - newCallbackThingProvider: () => new CallbackProvider(ThingProviderClass), - newCallbackStateDescriptionFragmentProvider: () => new StateDescriptionFragmentProvider -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/rules.js b/bundles/org.openhab.automation.jsscripting/javascript/rules.js deleted file mode 100644 index 53c181966ba8..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/rules.js +++ /dev/null @@ -1,285 +0,0 @@ - -/** - * Rules namespace. - * This namespace allows creation of Openhab rules. - * - * @namespace rules - */ - -const GENERATED_RULE_ITEM_TAG = "GENERATED_RULE_ITEM"; - -const items = require('./items'); -const utils = require('./utils'); -const log = require('./log')('rules'); -const itemhistory = require('./itemhistory'); -const osgi = require('./osgi'); -const triggers = require('./triggers'); -const { automationManager } = require('@runtime/RuleSupport'); - -let RuleManager = osgi.getService("org.openhab.core.automation.RuleManager","org.eclipse.smarthome.automation.RuleManager"); - -/** - * Generates an item name given it's configuration. - * - * @memberOf rules - * @private - * @param {Object} ruleConfig The rule config - * @param {String} userInfo.name The name of the rule. - */ -const itemNameForRule = function (ruleConfig) { - return "vRuleItemFor" + items.safeItemName(ruleConfig.name); -} - -/** - * Links an item to a rule. When the item is switched on or off, so will the rule be. - * - * @memberOf rules - * @private - * @param {HostRule} rule The rule to link to the item. - * @param {OHItem} item the item to link to the rule. - */ -const linkItemToRule = function (rule, item) { - JSRule({ - name: "vProxyRuleFor" + rule.getName(), - description: "Generated Rule to toggle real rule for " + rule.getName(), - triggers: [ - triggers.ItemStateUpdateTrigger(item.name) - ], - execute: function (data) { - try { - var itemState = data.state; - log.debug("Rule toggle item state received as " + itemState); - RuleManager.setEnabled(rule.getUID(), itemState == 'OFF' ? false : true); - log.info((itemState == 'OFF' ? "Disabled" : "Enabled") + " rule " + rule.getName() + " [" + rule.getUID() + "]"); - } catch (e) { - log.error("Failed to toggle rule " + rule.getName() + ": " + e); - } - } - }); -}; - -/** - * Gets the groups that an rule-toggling-item should be a member of. Will create the group item if necessary. - * - * @memberOf rules - * @private - * @param {Object} ruleConfig The rule config describing the rule - * @param {String} ruleConfig.ruleGroup the name of the rule group to use. - * @returns {String[]} the group names to put the item in - */ -const getGroupsForItem = function (ruleConfig) { - if (ruleConfig.ruleGroup) { - var groupName = "gRules" + items.safeItemName(ruleConfig.ruleGroup); - log.debug("Creating rule group " + ruleConfig.ruleGroup); - items.replaceItem(groupName, "Group", null, ["gRules"], ruleConfig.ruleGroup, [GENERATED_RULE_ITEM_TAG]); - return [groupName]; - } - - return ["gRules"]; -} - -/** - * Creates a rule. The rule will be created and immediately available. - * - * @example - * import { rules, triggers } = require('ohj'); - * - * rules.JSRule({ - * name: "my_new_rule", - * description": "this rule swizzles the swallows", - * triggers: triggers.GenericCronTrigger("0 30 16 * * ? *"), - * execute: triggerConfig => { //do stuff } - * }); - * - * @memberOf rules - * @param {Object} ruleConfig The rule config describing the rule - * @param {String} ruleConfig.name the name of the rule - * @param {String} ruleConfig.description a description of the rule - * @param {*} ruleConfig.execute callback that will be called when the rule fires - * @param {HostTrigger[]} ruleConfig.triggers triggers which will define when to fire the rule - * @returns {HostRule} the created rule - */ -let JSRule = function (ruleConfig) { - let ruid = ruleConfig.id || ruleConfig.name.replace(/[^\w]/g, "-") + "-" + utils.randomUUID(); - let ruTemplateid = ruleConfig.name.replace(/[^\w]/g, "-") + "-" + utils.randomUUID(); - log.info("Adding rule: {}", ruleConfig.name ? ruleConfig.name : ruid); - - let SimpleRule = Java.extend(Java.type('org.openhab.core.automation.module.script.rulesupport.shared.simple.SimpleRule')); - - let doExecute = function (module, input) { - try { - return ruleConfig.execute(getTriggeredData(input)); - } catch (error) { - log.error(`Failed to execute rule ${ruid}: ${error}: ${error.stack}`); - throw error; - } - }; - - var rule = new SimpleRule({ - execute: doExecute, - getUID: () => ruid - }); - - var triggers = ruleConfig.triggers ? ruleConfig.triggers : ruleConfig.getEventTrigger(); - - rule.setTemplateUID(ruTemplateid); - - if (ruleConfig.description) { - rule.setDescription(ruleConfig.description); - } - if (ruleConfig.name) { - rule.setName(ruleConfig.name); - } - - //Register rule here - if (triggers && triggers.length > 0) { - rule.setTriggers(triggers); - rule = registerRule(rule); - } - - return rule; -}; - -let currentProvider = automationManager; - -let withManagedProvider = function(fn) { - let previousProvider = currentProvider; - currentProvider = automationManager; - - try { - fn(); - } finally { - currentProvider = previousProvider; - } -} - -let registerRule = function(rule) { - return currentProvider.addRule(rule); -} - -/** - * Creates a rule, with an associated SwitchItem that can be used to toggle the rule's enabled state. - * The rule will be created and immediately available. - * - * @memberOf rules - * @param {Object} ruleConfig The rule config describing the rule - * @param {String} ruleConfig.name the name of the rule - * @param {String} ruleConfig.description a description of the rule - * @param {*} ruleConfig.execute callback that will be called when the rule fires - * @param {HostTrigger[]} ruleConfig.triggers triggers which will define when to fire the rule - * @param {String} ruleConfig.ruleGroup the name of the rule group to use. - * @returns {HostRule} the created rule - */ -let SwitchableJSRule = function (ruleConfig) { - - if (!ruleConfig.name) { - throw Error("No name specified for rule!"); - } - - //first create a toggling item - var itemName = itemNameForRule(ruleConfig); - - //then add the item - var item = items.replaceItem(itemName, "Switch", null, getGroupsForItem(ruleConfig), ruleConfig.description, [GENERATED_RULE_ITEM_TAG]); - - //create the real rule - var rule = JSRule(ruleConfig); - - //hook up a rule to link the item to the actual rule - linkItemToRule(rule, item); - - if (item.isUninitialized) { - //possibly load item's prior state - let historicState = itemhistory.latestState(item); - - if (historicState !== null) { - item.postUpdate(historicState); - } else { - item.sendCommand('ON'); - } - } -} - -const getTriggeredData = function (input) { - let event = input.get('event'); - - if(event && Java.typeName(event.class) === 'org.eclipse.smarthome.core.items.events.ItemCommandEvent') { - return { - eventType: "command", - triggerType: "ItemCommandTrigger", - receivedCommand: event.getItemCommand(), - oldState: input.get("oldState") + "", - newState: input.get("newState") + "", - itemName: event.getItemName() - } - } - - var ev = event + ""; - //log.debug("event",ev.split("'").join("").split("Item ").join("").split(" ")); - var evArr = []; - if (ev.includes("triggered")) { - var atmp = ev.split(" triggered "); //astro:sun:local:astroDawn#event triggered START - evArr = [atmp[0], "triggered", atmp[1]]; - } else { - evArr = ev.split("'").join("").split("Item ").join("").split(" "); //Item 'benqth681_switch' received command ON - } - - var d = { - //size: input.size(), - oldState: input.get("oldState") + "", - newState: input.get("newState") + "", - state: input.get("state") + "", //this occurs on an ItemStateUpdateTrigger - receivedCommand: null, - receivedState: null, - receivedTrigger: null, - itemName: evArr[0] - }; - - try { - if (event !== null && event.getPayload()) { - d.payload = JSON.parse(event.getPayload()); - log.debug("Extracted event payload {}", JSON.stringify(d.payload)); - } - } catch (e) { - log.warn("Failed to extract payload: {}", e.message); - } - - switch (evArr[1]) { - case "received": - d.eventType = "command"; - d.triggerType = "ItemCommandTrigger"; - d.receivedCommand = input.get("command") + ""; - break; - case "updated": - d.eventType = "update"; - d.triggerType = "ItemStateUpdateTrigger"; - d.receivedState = input.get("state") + ""; - break; - case "changed": - d.eventType = "change"; - d.triggerType = "ItemStateChangeTrigger"; - break; - case "triggered": - d.eventType = "triggered"; - d.triggerType = "ChannelEventTrigger"; - d.receivedTrigger = evArr[2]; - break; - default: - if (input.size() == 0) { - d.eventType = "time"; - d.triggerType = "GenericCronTrigger"; - d.triggerTypeOld = "TimerTrigger"; - } else { - d.eventType = ""; - d.triggerType = ""; - } - } - - - return d; -}; - -module.exports = { - JSRule, - SwitchableJSRule -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js deleted file mode 100644 index 54fa9836a793..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/test/condition-conf.test.js +++ /dev/null @@ -1,117 +0,0 @@ -const assert = require('assert'); -var proxyquire = require('proxyquire').noCallThru(); - -describe('Conditionals', function () { - - const createLogMock = () => { - let messages = []; - - return { - messages, - mock:function(name){ - return { - error: a => messages.push(a) - } - } - }; - } - - function itemMock(nameToState) { - return { - getItem: function(name){ - return nameToState(name); - } - } - } - - describe('Function Conditions', function () { - it('Should pass when the function returns true', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock() - }); - - let conf = new condition_conf.FunctionConditionConf(() => true); - assert.strictEqual(conf.check(), true); - }); - - it('Should not pass when the function returns false', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock() - }); - - let conf = new condition_conf.FunctionConditionConf(() => false); - assert.strictEqual(conf.check(), false); - }); - }); - - describe('Item Conditions', function () { - it('Should pass when the item state matches', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - assert.strictEqual(name, 'myitem'); - return { - state: "mystate" - } - }) - }); - - let conf = new condition_conf.ItemStateConditionConf('myitem'); - - assert.strictEqual(conf.is('mystate').check(), true); - }); - - it('Should not pass when the item state doesnt matches', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - assert.strictEqual(name, 'myitem'); - return { - state: "mystate2" - } - }) - }); - - let conf = new condition_conf.ItemStateConditionConf('myitem'); - - assert.strictEqual(conf.is('mystate').check(), false); - }); - - it('Should not pass when the item doesnt exist', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - assert.strictEqual(name, 'myitem'); - return undefined; - }) - }); - - let conf = new condition_conf.ItemStateConditionConf('myitem'); - - assert.throws(() => conf.is('mystate').check(), {message: /myitem/}); - }); - - it('Should not pass when the item is null', function () { - - const condition_conf = proxyquire('../fluent/condition-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - assert.strictEqual(name, 'myitem'); - return null; - }) - }); - - let conf = new condition_conf.ItemStateConditionConf('myitem'); - - assert.throws(() => conf.is('mystate').check(), {message: /myitem/}); - }); - - }); -}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/fluent.test.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js deleted file mode 100644 index 7a68abd3701e..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/test/operation-conf.test.js +++ /dev/null @@ -1,228 +0,0 @@ -const assert = require('assert'); -var proxyquire = require('proxyquire').noCallThru(); - -describe('Operations', function () { - - const createLogMock = () => { - let messages = []; - - return { - messages, - mock:function(name){ - return { - error: a => messages.push(a) - } - } - }; - } - - function itemMock(nameToState) { - return { - getItem: function(name){ - return nameToState(name); - } - } - } - - describe('Copy State Operation', function () { - it('Should copy state via send when everything set up correctly', function (done) { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: "test1" - } - } else if(name == 'item2') { - return { - sendCommand: (state) => { - assert.strictEqual(state, "test1"); - done(); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - conf.fromItem('item1').toItem('item2')._run(); - }); - - it('Should copy state via update when everything set up correctly', function (done) { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: "test1" - } - } else if(name == 'item2') { - return { - postUpdate: (state) => { - assert.strictEqual(state, "test1"); - done(); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(false); - - conf.fromItem('item1').toItem('item2')._run(); - }); - - it('Should copy null state', function (done) { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: null - } - } else if(name == 'item2') { - return { - sendCommand: (state) => { - assert.strictEqual(state, null); - done(); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - conf.fromItem('item1').toItem('item2')._run(); - }); - - it('Should disallow omission of to item', function () { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: "test1" - } - } else if(name == 'item2') { - return { - sendCommand: (state) => { - assert.strictEqual(state, "test1"); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - assert.throws(() => conf.fromItem('item1')._run(), {message: /[Tt]o/}); - }); - - it('Should disallow omission of from item', function () { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: "test1" - } - } else if(name == 'item2') { - return { - sendCommand: (state) => { - assert.strictEqual(state, "test1"); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - assert.throws(() => conf.toItem('item1')._run(), {message: /[Ff]rom/}); - }); - - it('Should disallow omission of both items', function () { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return { - state: "test1" - } - } else if(name == 'item2') { - return { - sendCommand: (state) => { - assert.strictEqual(state, "test1"); - } - } - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - assert.throws(() => conf._run()); - }); - - it('Should tell you if from item doesnt exist', function () { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return undefined; - } else if(name == 'item2') { - return {} - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - assert.throws(() => conf.fromItem('item1').toItem('item2')._run(), {message: /item1/}); - }); - - it('Should tell you if to item doesnt exist', function () { - - const operation_conf = proxyquire('../fluent/operation-conf', { - '../log': createLogMock().mock, - '../items': itemMock((name) => { - if(name == 'item1') { - return {}; - } else if(name == 'item2') { - return undefined - } else { - assert.fail("wrong item requested " + name); - } - }) - }); - - let conf = new operation_conf.CopyStateOperation(true); - - assert.throws(() => conf.fromItem('item1').toItem('item2')._run(), {message: /item2/}); - }); - - }); -}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js b/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js deleted file mode 100644 index b8160046b19e..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/test/rewiremock.js +++ /dev/null @@ -1,7 +0,0 @@ -// rewiremock.cjs.js -const rewiremock = require('rewiremock/node'); -/// settings -rewiremock.isolation(); - -//rewiremock.overrideEntryPoint(module); // this is important -module.exports = rewiremock; \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js b/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js deleted file mode 100644 index 215119ed89e8..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/test/trigger-conf.test.js +++ /dev/null @@ -1,43 +0,0 @@ -const assert = require('assert'); -var proxyquire = require('proxyquire').noCallThru(); - -describe('Triggers', function () { - - const createLogMock = () => { - let messages = []; - - return { - messages, - mock:function(name){ - return { - error: a => messages.push(a) - } - } - }; - } - - function triggersMock(lookup) { - return x => lookup(x); - } - - describe('Item Triggers', function () { - it('Should create correct item trigger', function (done) { - - const trigger_conf = proxyquire('../fluent/trigger-conf', { - '../log': createLogMock().mock, - '../triggers': { - ItemStateChangeTrigger: (name, from, to) => { - assert.strictEqual(name, 'item1'); - assert.strictEqual(from, undefined); - assert.strictEqual(to, 'state1'); - done(); - } - } - }); - - new trigger_conf.ItemTriggerConfig('item1').changed().to('state1')._toOHTriggers(); - }); - - }); - -}); diff --git a/bundles/org.openhab.automation.jsscripting/javascript/things/package.json b/bundles/org.openhab.automation.jsscripting/javascript/things/package.json deleted file mode 100644 index 648b3c36318d..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/things/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "things", - "version": "0.0.1", - "main": "things.js" -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/things/things.js b/bundles/org.openhab.automation.jsscripting/javascript/things/things.js deleted file mode 100644 index c485284a523a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/things/things.js +++ /dev/null @@ -1,104 +0,0 @@ -const utils = require('../utils'); - -const JavaThingBuilder = utils.typeBySuffix('core.thing.binding.builder.ThingBuilder'); -const ThingTypeUID = utils.typeBySuffix('core.thing.ThingTypeUID'); -const JavaChannelBuilder = utils.typeBySuffix('core.thing.binding.builder.ChannelBuilder'); -const ChannelUID = utils.typeBySuffix('core.thing.ChannelUID'); -const ThingUID = utils.typeBySuffix('core.thing.ThingUID'); -const ChannelKind = utils.typeBySuffix('core.thing.type.ChannelKind'); -const ChannelTypeUID = utils.typeBySuffix('core.thing.type.ChannelTypeUID'); -const Configuration = utils.typeBySuffix('core.config.core.Configuration'); - -class OHThing { - constructor(rawThing) { - this.rawThing = rawThing; - } -} - -class OHChannel { - constructor(rawChannel) { - this.rawChannel = rawChannel; - } - - get uid(){ - return this.rawChannel.getUID().toString(); - } -} - -class ThingBuilder { - constructor(thingTypeUID, thingId, bridgeUID) { - if(typeof thingTypeUID === 'string') { - thingTypeUID = new ThingTypeUID(...thingTypeUID.split(':')); - } - - this.thingTypeUID = thingTypeUID; - this.thingId = thingId; - - - if(typeof bridgeUID !== 'undefined') { - if(typeof bridgeUID === 'string') { - let [bridgeBindingId, bridgeThingTypeId, bringThingId] = bridgeUID.split(':'); - bridgeUID = new ThingUID(new ThingTypeUID(bridgeBindingId, bridgeThingTypeId), bringThingId); - } - this.thingUID = new ThingUID(thingTypeUID, bridgeUID, thingId); - this.rawBuilder = JavaThingBuilder.create(thingTypeUID, this.thingUID); - this.rawBuilder.withBridge(bridgeUID); - } else { - this.thingUID = new ThingUID(thingTypeUID, thingId); - this.rawBuilder = JavaThingBuilder.create(thingTypeUID, this.thingUID); - } - } - - withChannel(channel) { - this.rawBuilder.withChannel(channel.rawChannel); - return this; - } - - withLabel(label) { - this.rawBuilder.withLabel(label); - return this; - } - - build() { - return new OHThing(this.rawBuilder.build()); - } -} - -class ChannelBuilder { - constructor(thingUID, channelId, acceptedItemType) { - let channelUID = new ChannelUID(thingUID, channelId); - this.rawBuilder = JavaChannelBuilder.create(channelUID, acceptedItemType); - } - - withConfiguration(config){ - this.rawBuilder.withConfiguration(new Configuration(config)); - return this; - } - - withKind(stateOrTrigger){ - this.rawBuilder.withKind(ChannelKind.parse(stateOrTrigger)); - return this; - } - - withLabel(label){ - this.rawBuilder.withLabel(label); - return this; - } - - withType(channelType){ - if(typeof channelType === 'string') { - channelType = new ChannelTypeUID(channelType); - } - this.rawBuilder.withType(channelType); - return this; - } - - build(){ - return new OHChannel(this.rawBuilder.build()); - } -} - -module.exports = { - newThingBuilder: (thingTypeUID, id, bridgeUID) => new ThingBuilder(thingTypeUID, id, bridgeUID), - newChannelBuilder: (thingUID, channelId, acceptedItemType) => new ChannelBuilder(thingUID, channelId, acceptedItemType) -} diff --git a/bundles/org.openhab.automation.jsscripting/javascript/triggers.js b/bundles/org.openhab.automation.jsscripting/javascript/triggers.js deleted file mode 100644 index efb55bbc4e10..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/triggers.js +++ /dev/null @@ -1,259 +0,0 @@ - -/** - * Triggers namespace. - * This namespace allows creation of Openhab rule triggers. - * - * @namespace triggers - */ - -const utils = require('./utils'); - -const ModuleBuilder = utils.typeWithFallback( - "org.eclipse.smarthome.automation.core.util.ModuleBuilder", - "org.openhab.core.automation.util.ModuleBuilder"); - -const Configuration = utils.typeBySuffix("config.core.Configuration"); - -/** - * Creates a trigger. Internal function, instead use predefined trigger types. - * - * @memberof triggers - * @private - * @param {String} typeString the type of trigger to create - * @param {String} [name] the name of the trigger - * @param {Configuration} config the trigger configuration - */ -let createTrigger = function(typeString, name, config) { - if(typeof name === 'undefined' || name === null) { - name = utils.randomUUID().toString(); - } - - return ModuleBuilder.createTrigger() - .withId(name) - .withTypeUID(typeString) - .withConfiguration(new Configuration(config)) - .build(); -} - -module.exports = { - - /** - * Creates a trigger that fires upon specific events in a channel. - * - * @example - * ChannelEventTrigger('astro:sun:local:rise#event', 'START') - * - * @name ChannelEventTrigger - * @memberof triggers - * @param {String} channel the name of the channel - * @param {String} event the name of the event to listen for - * @param {String} [triggerName] the name of the trigger to create - * - */ - ChannelEventTrigger: (channel, event, triggerName) => createTrigger("core.ChannelEventTrigger", triggerName, { - "channelUID": channel, - "event": event - }), - - /** - * Creates a trigger that fires upon an item changing state. - * - * @example - * ItemStateChangeTrigger('my_item', 'OFF', 'ON') - * - * @name ItemStateChangeTrigger - * @memberof triggers - * @param {String} itemName the name of the item to monitor for change - * @param {String} [oldState] the previous state of the item - * @param {String} [newState] the new state of the item - * @param {String} [triggerName] the name of the trigger to create - */ - ItemStateChangeTrigger: (itemName, oldState, newState, triggerName) => createTrigger("core.ItemStateChangeTrigger", triggerName, { - "itemName": itemName, - "state": newState, - "oldState": oldState - }), - - /** - * Creates a trigger that fires upon an item receiving a state update. Note that the item does not need to change state. - * - * @example - * ItemStateUpdateTrigger('my_item', 'OFF') - * - * @name ItemStateUpdateTrigger - * @memberof triggers - * @param {String} itemName the name of the item to monitor for change - * @param {String} [state] the new state of the item - * @param {String} [triggerName] the name of the trigger to create - */ - ItemStateUpdateTrigger: (itemName, state, triggerName) => createTrigger("core.ItemStateUpdateTrigger", triggerName, { - "itemName": itemName, - "state": state - }), - - /** - * Creates a trigger that fires upon an item receiving a command. Note that the item does not need to change state. - * - * @example - * ItemCommandTrigger('my_item', 'OFF') - * - * @name ItemCommandTrigger - * @memberof triggers - * @param {String} itemName the name of the item to monitor for change - * @param {String} [command] the command received - * @param {String} [triggerName] the name of the trigger to create - */ - ItemCommandTrigger: (itemName, command, triggerName) => createTrigger("core.ItemCommandTrigger", triggerName, { - "itemName": itemName, - "command": command - }), - - /** - * Creates a trigger that fires upon a member of a group changing state. - * - * @example - * GroupStateChangeTrigger('my_group', 'OFF', 'ON') - * - * @name GroupStateChangeTrigger - * @memberof triggers - * @param {String} groupName the name of the group to monitor for change - * @param {String} [oldState] the previous state of the group - * @param {String} [newState] the new state of the group - * @param {String} [triggerName] the name of the trigger to create - */ - GroupStateChangeTrigger: (groupName, oldState, newState, triggerName) => createTrigger("core.GroupStateChangeTrigger", triggerName, { - "groupName": groupName, - "state": newState, - "oldState": oldState - }), - - /** - * Creates a trigger that fires upon a member of a group receiving a state update. Note that group item does not need to change state. - * - * @example - * GroupStateUpdateTrigger('my_group', 'OFF') - * - * @name GroupStateUpdateTrigger - * @memberof triggers - * @param {String} groupName the name of the group to monitor for change - * @param {String} [state] the new state of the group - * @param {String} [triggerName] the name of the trigger to create - */ - GroupStateUpdateTrigger: (groupName, state, triggerName) => createTrigger("core.GroupStateUpdateTrigger", triggerName, { - "groupName": groupName, - "state": state - }), - /** - * Creates a trigger that fires upon a member of a group receiving a command. Note that the group does not need to change state. - * - * @example - * GroupCommandTrigger('my_group', 'OFF') - * - * @name GroupCommandTrigger - * @memberof triggers - * @param {String} groupName the name of the group to monitor for change - * @param {String} [command] the command received - * @param {String} [triggerName] the name of the trigger to create - */ - GroupCommandTrigger: (groupName, command, triggerName) => createTrigger("core.GroupCommandTrigger", triggerName, { - "groupName": groupName, - "command": command - }), - - - /** - * Creates a trigger that fires on a cron schedule. The supplied cron expression defines when the trigger will fire. - * - * @example - * GenericCronTrigger('0 30 16 * * ? *') - * - * @name GenericCronTrigger - * @memberof triggers - * @param {String} expression the cron expression defining the triggering schedule - */ - GenericCronTrigger: (expression, triggerName) => createTrigger("timer.GenericCronTrigger", triggerName, { - "cronExpression": expression - }), - - /** - * Creates a trigger that fires daily at a specific time. The supplied time defines when the trigger will fire. - * - * @example - * TimeOfDayTrigger('19:00') - * - * @name TimeOfDayTrigger - * @memberof triggers - * @param {String} time the time expression defining the triggering schedule - */ - TimeOfDayTrigger: (time, triggerName) => createTrigger("timer.TimeOfDayTrigger", triggerName, { - "time": time - }), - - - /** - * Creates a trigger that fires upon an Thing status updating - * - * @example - * ThingStatusUpdateTrigger('some:thing:uuid','OFFLINE') - * - * @name ThingStatusUpdateTrigger - * @memberof triggers - * @param {String} thingUID the name of the thing to monitor for a status updating - * @param {String} [status] the optional status to monitor for - * @param {String} [triggerName] the name of the trigger to create - */ - ThingStatusUpdateTrigger: (thingUID, status, triggerName) => createTrigger("core.ThingStatusUpdateTrigger", triggerName, { - "thingUID": thingUID, - "status": status, - }), - - /** - * Creates a trigger that fires upon an Thing status changing - * - * @example - * ThingStatusChangeTrigger('some:thing:uuid','ONLINE','OFFLINE') - * - * @name ThingStatusChangeTrigger - * @memberof triggers - * @param {String} thingUID the name of the thing to monitor for a status change - * @param {String} [status] the optional status to monitor for - * @param {String} [previousStatus] the optional previous state to monitor from - * @param {String} [triggerName] the optional name of the trigger to create - */ - ThingStatusChangeTrigger: (thingUID, status, previousStatus, triggerName) => createTrigger("core.ThingStatusChangeTrigger", triggerName, { - "thingUID": thingUID, - "status": status, - "previousStatus": previousStatus, - }), - - /** - * Creates a trigger that fires if a given start level is reached by the system - * - * @example - * SystemStartlevelTrigger('100') //Startup Complete - * - * @name SystemStartlevelTrigger - * @memberof triggers - * @param {String} startlevel the name of the thing to monitor for a status updating - * @param {String} [triggerName] the name of the trigger to create - */ - SystemStartlevelTrigger: (thingUID, status, triggerName) => createTrigger("core.SystemStartlevelTrigger", triggerName, { - "thingUID": thingUID, - "status": status, - }), - - /* not yet tested - ItemStateCondition: (itemName, state, triggerName) => createTrigger("core.ItemStateCondition", triggerName, { - "itemName": itemName, - "operator": "=", - "state": state - }), - - GenericCompareCondition: (itemName, state, operator, triggerName) => createTrigger("core.GenericCompareCondition", triggerName, { - "itemName": itemName, - "operator": operator,// matches, ==, <, >, =<, => - "state": state - }) - */ - createTrigger, -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/utils.js b/bundles/org.openhab.automation.jsscripting/javascript/utils.js deleted file mode 100644 index 71b80c60695a..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/utils.js +++ /dev/null @@ -1,133 +0,0 @@ - -const log = require('./log')('utils'); - -const HashSet = Java.type("java.util.HashSet"); -const ArrayList = Java.type("java.util.ArrayList"); - -function getAllPropertyNames (obj) { - const proto = Object.getPrototypeOf(obj); - const inherited = (proto) ? getAllPropertyNames(proto) : []; - return [...new Set(Object.getOwnPropertyNames(obj).concat(inherited))]; -} - -let jsSetToJavaSet = function(set) { - let rv = new HashSet(); - - set.forEach(e => rv.add(e)); - - return rv; -} - -let jsArrayToJavaSet = function (arr) { - let set = new HashSet(); - - for (let i of arr) { - set.add(i); - } - - return set; -}; - -let jsArrayToJavaList = function (arr) { - let list = new ArrayList(); - - for (let i of arr) { - list.add(i); - } - - return list; -} - -let javaSetToJsArray = function(set) { - return Java.from(new ArrayList(set)); -} - -let javaSetToJsSet = function(set) { - return new Set(exports.javaSetToJsArray(set)); -} - -let randomUUID = () => Java.type("java.util.UUID").randomUUID(); - -let dumpObject = function (obj) { - try { - log.info("Dumping object..."); - log.info(" typeof obj = {}", (typeof obj)); - let isJavaObject = Java.isJavaObject(obj); - log.info(" Java.isJavaObject(obj) = {}", isJavaObject) - let isJavaType = Java.isType(obj); - log.info(" Java.isType(obj) = {}", isJavaType) - if (isJavaObject) { - if (isJavaType) { - log.info(" Java.typeName(obj) = {}", Java.typeName(obj)); - } else { - log.info(" Java.typeName(obj.class) = {}", Java.typeName(obj.class)); - if(Java.typeName(obj.class) == 'java.util.HashMap'){ - log.info("Dumping contents..."); - let keys = obj.keySet().toArray(); - for (var key in keys) { - log.info(`${keys[key]}(${typeof keys[key]}) = ${obj.get(keys[key])}(${typeof obj.get(keys[key])})`); - if(typeof keys[key] === 'object') { - log.info("Dumping key..."); - exports.dumpObject(keys[key]); - } - } - } - } - } else if (typeof obj === 'string'){ - log.info("String value = " + obj); - } - - log.info("getAllPropertyNames(obj) = {}", getAllPropertyNames(obj)); - // log.info("obj.toString() = {}", obj.toString()); - // log.info("JSON.stringify(obj) = {}", JSON.stringify(obj)); - } catch(e) { - log.info("Failed to dump object: " + e.message); - } -} - -let typeBySuffix = function(typeSuffix) { - return typeWithFallback(`org.eclipse.smarthome.${typeSuffix}`, `org.openhab.${typeSuffix}`, `org.openhab.core.${typeSuffix}`); -} - -let typeWithFallback = function(...typeList) { - let rv; - - for(let type of typeList) { - try { - rv = Java.type(type); - if (rv === null) { - throw error("not found"); - } - return rv; - } catch(e) { - continue; - } - } - - throw `Failed to lookup types ${typeList.join(',')}` -} - -let isJsInstanceOfJava = function(instance, type) { - if(!Java.isType(type)) { - throw error("type is not a java class"); - } - - if(instance === null || instance === undefined || instance.class === null || instance.class === undefined) { - return false; - } - - return type.class.isAssignableFrom(instance.class); -} - -module.exports = { - jsSetToJavaSet, - jsArrayToJavaSet, - jsArrayToJavaList, - javaSetToJsArray, - javaSetToJsSet, - randomUUID, - dumpObject, - typeWithFallback, - typeBySuffix, - isJsInstanceOfJava -} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js b/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js deleted file mode 100644 index 71ef86c0486c..000000000000 --- a/bundles/org.openhab.automation.jsscripting/javascript/webpack.config.js +++ /dev/null @@ -1,51 +0,0 @@ -const path = require('path'); - -module.exports = { - entry: './index.js', - mode: 'development', - devtool: 'source-map', - externals: [ - { - ["@runtime"]: { - root: "@runtime", - commonjs: '@runtime', - commonjs2: '@runtime', - amd: '@runtime', - }, - ["@runtime/Defaults"]: { - root: "@runtime/Defaults", - commonjs: '@runtime/Defaults', - commonjs2: '@runtime/Defaults', - amd: '@runtime/Defaults', - }, - ["@runtime/provider"]: { - root: "@runtime/provider", - commonjs: '@runtime/provider', - commonjs2: '@runtime/provider', - amd: '@runtime/provider', - }, - ["@runtime/RuleSupport"]: { - root: "@runtime/RuleSupport", - commonjs: '@runtime/RuleSupport', - commonjs2: '@runtime/RuleSupport', - amd: '@runtime/RuleSupport', - }, - ["@runtime/osgi"]: { - root: "@runtime/osgi", - commonjs: '@runtime/osgi', - commonjs2: '@runtime/osgi', - amd: '@runtime/osgi', - } - } - ], - output: { - path: path.resolve(__dirname, 'dist'), - filename: '@oh.js', - library: { - name: "@oh", - type: "umd" - }, - globalObject: 'this', - } -}; - diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index abf39dd6c6a0..841b452a146b 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -25,6 +25,7 @@ 21.3.0 6.2.1 ${project.version} + openhab@0.0.1-beta.1 @@ -48,12 +49,10 @@ com.github.eirslett frontend-maven-plugin 1.12.0 - v12.16.1 - javascript + target/js - Install node and npm @@ -62,24 +61,22 @@ generate-sources - npm install npm - install + install ${ohjs.version} webpack webpack-cli - npx webpack npx - webpack + webpack -c ./node_modules/openhab/webpack.config.js --entry ./node_modules/openhab/ -o ./dist @@ -96,7 +93,7 @@ - javascript/dist + target/js/dist node_modules diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java index 51ea76dbbe03..2b33ced4b4bc 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java @@ -42,9 +42,8 @@ public final class GraalJSScriptEngineFactory implements ScriptEngineFactory { private static final Logger LOGGER = LoggerFactory.getLogger(GraalJSScriptEngineFactory.class); private static final String CFG_INJECTION_ENABLED = "injectionEnabled"; - private static final String CFG_INJECTION_CODE = "injectionCode"; - - private String injectionCode; + private static final String INJECTION_CODE = "Object.assign(this, require('openhab'));"; + private boolean injectionEnabled; @Override public List getScriptTypes() { @@ -64,7 +63,8 @@ public void scopeValues(ScriptEngine scriptEngine, Map scopeValu @Override public ScriptEngine createScriptEngine(String scriptType) { - return new DebuggingGraalScriptEngine<>(new OpenhabGraalJSScriptEngine(injectionCode)); + return new DebuggingGraalScriptEngine<>( + new OpenhabGraalJSScriptEngine(injectionEnabled ? INJECTION_CODE : null)); } @Activate @@ -75,17 +75,6 @@ protected void activate(BundleContext context, Map config) { @Modified protected void modified(Map config) { Object injectionEnabled = config.get(CFG_INJECTION_ENABLED); - boolean enabled = injectionEnabled != null && (Boolean) injectionEnabled; - if (enabled) { - Object injectionCodeObj = config.get(CFG_INJECTION_CODE); - if (injectionCodeObj != null) { - LOGGER.debug("Adding code {}", injectionCodeObj); - injectionCode = (String) injectionCodeObj; - } else { - injectionCode = null; - } - } else { - injectionCode = null; - } + this.injectionEnabled = injectionEnabled != null && (Boolean) injectionEnabled; } } diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index e40ffef078ae..68c21c2b1a07 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -59,7 +59,7 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngineWithInvocable { private static final Logger LOGGER = LoggerFactory.getLogger(OpenhabGraalJSScriptEngine.class); - + private static final String GLOBAL_REQUIRE = "require(\"@jsscripting-globals\");"; private static final String REQUIRE_WRAPPER_NAME = "__wraprequire__"; private static final String MODULE_DIR = String.join(File.separator, OpenHAB.getConfigFolder(), "automation", "lib", "javascript", "personal"); @@ -79,7 +79,7 @@ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngi */ public OpenhabGraalJSScriptEngine(@Nullable String injectionCode) { super(null); // delegate depends on fields not yet initialised, so we cannot set it immediately - this.globalScript = "require(\"@globals\");" + (injectionCode != null ? injectionCode : ""); + this.globalScript = GLOBAL_REQUIRE + (injectionCode != null ? injectionCode : ""); delegate = GraalJSScriptEngine.create( Engine.newBuilder().allowExperimentalOptions(true).option("engine.WarnInterpreterOnly", "false") .build(), @@ -102,11 +102,11 @@ public SeekableByteChannel newByteChannel(Path path, Set o SeekableByteChannel sbc = null; if (path.startsWith(LOCAL_NODE_PATH)) { InputStream is = getClass().getResourceAsStream(path.toString()); - if (is != null) { - sbc = new ReadOnlySeekableByteArrayChannel(is.readAllBytes()); + if (is == null) { + throw new IOException("Could not read " + path.toString()); } - } - if (sbc == null) { + sbc = new ReadOnlySeekableByteArrayChannel(is.readAllBytes()); + } else { sbc = super.newByteChannel(path, options, attrs); } return new PrefixedSeekableByteChannel( diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml index e53ca0044164..79ff8f2b67e4 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml @@ -8,7 +8,7 @@ - If disabled, the OH scripting library can be imported manually using "require(@oh)" + If disabled, the OH scripting library can be imported manually using "require('openhab')" ]]> @@ -16,10 +16,5 @@ true - - - Injection code used to expose helper variables - Object.assign(this, require('@oh')); - diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js similarity index 97% rename from bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js rename to bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index fff5f692aa18..2565309bde49 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,6 +1,6 @@ const System = Java.type('java.lang.System'); -const log = Java.type("org.slf4j.LoggerFactory").getLogger("script.js.console"); +const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.jsscripting.js"); const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); const ZonedDateTime = Java.type('java.time.ZonedDateTime'); diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java index 8ae818805d45..41a19fc2072e 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java @@ -30,6 +30,10 @@ public class VenstarAwayModeSerializer implements JsonDeserializer Date: Sun, 28 Nov 2021 14:05:14 -0800 Subject: [PATCH 12/23] Update author headers Signed-off-by: Dan Cunningham --- .../jsscripting/internal/GraalJSScriptEngineFactory.java | 1 + .../jsscripting/internal/OpenhabGraalJSScriptEngine.java | 1 + .../internal/fs/ReadOnlySeekableByteArrayChannel.java | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java index 2b33ced4b4bc..33c5a171b54f 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java @@ -35,6 +35,7 @@ * An implementation of {@link ScriptEngineFactory} with customizations for GraalJS ScriptEngines. * * @author Jonathan Gilbert - Initial contribution + * @author Dan Cunningham - Script injections */ @Component(service = ScriptEngineFactory.class, configurationPid = "org.openhab.automation.jsscripting", property = Constants.SERVICE_PID + "=org.openhab.automation.jsscripting") diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 68c21c2b1a07..ab1734189106 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -55,6 +55,7 @@ * GraalJS Script Engine implementation * * @author Jonathan Gilbert - Initial contribution + * @author Dan Cunningham - Script injections */ public class OpenhabGraalJSScriptEngine extends InvocationInterceptingScriptEngineWithInvocable { diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java index 9b39065699d6..f150632f6a66 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/fs/ReadOnlySeekableByteArrayChannel.java @@ -19,9 +19,9 @@ import java.nio.channels.SeekableByteChannel; /** + * Simple wrapper around a byte array to provide a SeekableByteChannel for consumption * - * @author daniel - * + * @author Dan Cunningham - Initial contribution */ public class ReadOnlySeekableByteArrayChannel implements SeekableByteChannel { private byte[] data; From fce7efc347fad26356de9f488bb133235fd5d16d Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 28 Nov 2021 15:34:43 -0800 Subject: [PATCH 13/23] Revert unattended change Signed-off-by: Dan Cunningham --- .../internal/dto/VenstarAwayModeSerializer.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java index 41a19fc2072e..8ae818805d45 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java @@ -30,10 +30,6 @@ public class VenstarAwayModeSerializer implements JsonDeserializer Date: Fri, 3 Dec 2021 16:27:11 -0800 Subject: [PATCH 14/23] adds setInterval and supports arguments for timers Signed-off-by: Dan Cunningham --- .../node_modules/@jsscripting-globals.js | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index 2565309bde49..7ee1331b9656 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -152,21 +152,50 @@ const console = { }; function setTimeout(cb, delay) { - return ScriptExecution.createTimer( + const args = Array.prototype.slice.call(arguments, 2); + return ScriptExecution.createTimerWithArgument( ZonedDateTime.now().plusNanos(delay * 1000000), - cb + args, + function (args) { + cb(...args); + } ); } function clearTimeout(timer) { - if (timer.isActive() && !timer.isRunning()) { + if (timer.isActive()) { timer.cancel(); } } + +function setInterval(cb, delay) { + const args = Array.prototype.slice.call(arguments, 2); + const delayNanos = delay * 1000000 + let timer = ScriptExecution.createTimerWithArgument( + ZonedDateTime.now().plusNanos(delayNanos), + args, + function (args) { + cb(...args); + if (!timer.isCancelled()) { + timer.reschedule(ZonedDateTime.now().plusNanos(delayNanos)); + } + } + ); + return timer; +} + +function clearInterval(interval) { + if (interval.isActive()) { + interval.cancel(); + } +} + globalThis.console = console; globalThis.setTimeout = setTimeout; globalThis.clearTimeout = clearTimeout; +globalThis.setInterval = setInterval; +globalThis.clearInterval = clearInterval; globalThis.global = globalThis; globalThis.process = { env: { NODE_ENV: '' } }; -module.exports = {} \ No newline at end of file +module.exports = {} From f299e2b76d87ba50934fe597df0ab17a8357369c Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Fri, 3 Dec 2021 16:29:20 -0800 Subject: [PATCH 15/23] change console logging to "org.openhab.automation.script' Signed-off-by: Dan Cunningham --- .../src/main/resources/node_modules/@jsscripting-globals.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index 7ee1331b9656..ae07b3753f41 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,10 +1,9 @@ const System = Java.type('java.lang.System'); -const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.jsscripting.js"); +const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.script"); const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); const ZonedDateTime = Java.type('java.time.ZonedDateTime'); -log.debug("loading globals"); const formatRegExp = /%[sdj%]/g; function stringify(value) { From 707342157b89d9a587ed86194096ca6005112136 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sat, 4 Dec 2021 12:31:17 -0800 Subject: [PATCH 16/23] Wrap logic in function for safety, apply callback in safer way Signed-off-by: Dan Cunningham --- .../node_modules/@jsscripting-globals.js | 342 +++++++++--------- 1 file changed, 173 insertions(+), 169 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index ae07b3753f41..70c7aa0c4e8c 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,200 +1,204 @@ -const System = Java.type('java.lang.System'); -const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.script"); -const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); -const ZonedDateTime = Java.type('java.time.ZonedDateTime'); - -const formatRegExp = /%[sdj%]/g; - -function stringify(value) { - try { - if (Java.isJavaObject(value)) { - return value.toString(); - } else { - // special cases - if (value === undefined) { - return "undefined" - } - if (typeof value === 'function') { - return "[Function]" - } - if (value instanceof RegExp) { +(function (global) { + 'use strict'; + + const System = Java.type('java.lang.System'); + const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.jsscripting.js"); + const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); + const ZonedDateTime = Java.type('java.time.ZonedDateTime'); + + const formatRegExp = /%[sdj%]/g; + + function stringify(value) { + try { + if (Java.isJavaObject(value)) { return value.toString(); + } else { + // special cases + if (value === undefined) { + return "undefined" + } + if (typeof value === 'function') { + return "[Function]" + } + if (value instanceof RegExp) { + return value.toString(); + } + // fallback to JSON + return JSON.stringify(value, null, 2); } - // fallback to JSON - return JSON.stringify(value, null, 2); + } catch (e) { + return '[Circular: ' + e + ']'; } - } catch (e) { - return '[Circular: ' + e + ']'; } -} -function format(f) { - if (typeof f !== 'string') { - var objects = []; - for (var index = 0; index < arguments.length; index++) { - objects.push(stringify(arguments[index])); + function format(f) { + if (typeof f !== 'string') { + var objects = []; + for (var index = 0; index < arguments.length; index++) { + objects.push(stringify(arguments[index])); + } + return objects.join(' '); } - return objects.join(' '); - } - if (arguments.length === 1) return f; - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function (x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - // falls through - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { - str += ' ' + x; - } else { - str += ' ' + stringify(x); + if (arguments.length === 1) return f; + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function (x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + // falls through + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { + str += ' ' + x; + } else { + str += ' ' + stringify(x); + } } + return str; } - return str; -} -const counters = {}; -const timers = {}; + const counters = {}; + const timers = {}; -const console = { - 'assert': function (expression, message) { - if (!expression) { - log.error(message); - } - }, + const console = { + 'assert': function (expression, message) { + if (!expression) { + log.error(message); + } + }, - count: function (label) { - let counter; + count: function (label) { + let counter; - if (label) { - if (counters.hasOwnProperty(label)) { - counter = counters[label]; - } else { - counter = 0; + if (label) { + if (counters.hasOwnProperty(label)) { + counter = counters[label]; + } else { + counter = 0; + } + + // update + counters[label] = ++counter; + log.debug(format.apply(null, [label + ':', counter])); } + }, - // update - counters[label] = ++counter; - log.debug(format.apply(null, [label + ':', counter])); - } - }, - - debug: function () { - log.debug(format.apply(null, arguments)); - }, - - info: function () { - log.info(format.apply(null, arguments)); - }, - - log: function () { - log.info(format.apply(null, arguments)); - }, - - warn: function () { - log.warn(format.apply(null, arguments)); - }, - - error: function () { - log.error(format.apply(null, arguments)); - }, - - trace: function (e) { - if (Java.isJavaObject(e)) { - log.trace(e.getLocalizedMessage(), e); - } else { - if (e.stack) { - log.trace(e.stack); + debug: function () { + log.debug(format.apply(null, arguments)); + }, + + info: function () { + log.info(format.apply(null, arguments)); + }, + + log: function () { + log.info(format.apply(null, arguments)); + }, + + warn: function () { + log.warn(format.apply(null, arguments)); + }, + + error: function () { + log.error(format.apply(null, arguments)); + }, + + trace: function (e) { + if (Java.isJavaObject(e)) { + log.trace(e.getLocalizedMessage(), e); } else { - if (e.message) { - log.trace(format.apply(null, [(e.name || 'Error') + ':', e.message])); + if (e.stack) { + log.trace(e.stack); } else { - log.trace((e.name || 'Error')); + if (e.message) { + log.trace(format.apply(null, [(e.name || 'Error') + ':', e.message])); + } else { + log.trace((e.name || 'Error')); + } } } - } - }, + }, - time: function (label) { - if (label) { - timers[label] = System.currentTimeMillis(); - } - }, - timeEnd: function (label) { - if (label) { - const now = System.currentTimeMillis(); - if (timers.hasOwnProperty(label)) { - log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms'])); - delete timers[label]; - } else { - log.info(format.apply(null, [label + ':', ''])); + time: function (label) { + if (label) { + timers[label] = System.currentTimeMillis(); + } + }, + timeEnd: function (label) { + if (label) { + const now = System.currentTimeMillis(); + if (timers.hasOwnProperty(label)) { + log.info(format.apply(null, [label + ':', (now - timers[label]) + 'ms'])); + delete timers[label]; + } else { + log.info(format.apply(null, [label + ':', ''])); + } } } + }; + + function setTimeout(cb, delay) { + const args = Array.prototype.slice.call(arguments, 2); + return ScriptExecution.createTimerWithArgument( + ZonedDateTime.now().plusNanos(delay * 1000000), + args, + function (args) { + cb.apply(global, args); + } + ); } -}; - -function setTimeout(cb, delay) { - const args = Array.prototype.slice.call(arguments, 2); - return ScriptExecution.createTimerWithArgument( - ZonedDateTime.now().plusNanos(delay * 1000000), - args, - function (args) { - cb(...args); - } - ); -} -function clearTimeout(timer) { - if (timer.isActive()) { - timer.cancel(); + function clearTimeout(timer) { + if (timer !== undefined && timer.isActive()) { + timer.cancel(); + } } -} - -function setInterval(cb, delay) { - const args = Array.prototype.slice.call(arguments, 2); - const delayNanos = delay * 1000000 - let timer = ScriptExecution.createTimerWithArgument( - ZonedDateTime.now().plusNanos(delayNanos), - args, - function (args) { - cb(...args); - if (!timer.isCancelled()) { - timer.reschedule(ZonedDateTime.now().plusNanos(delayNanos)); + + function setInterval(cb, delay) { + const args = Array.prototype.slice.call(arguments, 2); + const delayNanos = delay * 1000000 + let timer = ScriptExecution.createTimerWithArgument( + ZonedDateTime.now().plusNanos(delayNanos), + args, + function (args) { + cb.apply(global, args); + if (!timer.isCancelled()) { + timer.reschedule(ZonedDateTime.now().plusNanos(delayNanos)); + } } - } - ); - return timer; -} + ); + return timer; + } -function clearInterval(interval) { - if (interval.isActive()) { - interval.cancel(); + function clearInterval(timer) { + clearTimeout(timer); } -} -globalThis.console = console; -globalThis.setTimeout = setTimeout; -globalThis.clearTimeout = clearTimeout; -globalThis.setInterval = setInterval; -globalThis.clearInterval = clearInterval; -globalThis.global = globalThis; -globalThis.process = { env: { NODE_ENV: '' } }; + //Polyfil common functions onto the global object + globalThis.console = console; + globalThis.setTimeout = setTimeout; + globalThis.clearTimeout = clearTimeout; + globalThis.setInterval = setInterval; + globalThis.clearInterval = clearInterval; + + //Support legacy NodeJS libraries + globalThis.global = globalThis; + globalThis.process = { env: { NODE_ENV: '' } }; -module.exports = {} +})(this); From 2465d92fd193c047cd7e7e5bc9250688c29a411a Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sat, 4 Dec 2021 16:33:58 -0800 Subject: [PATCH 17/23] Change scripting logger name Signed-off-by: Dan Cunningham --- .../src/main/resources/node_modules/@jsscripting-globals.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index 70c7aa0c4e8c..fb13a66c5017 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,9 +1,8 @@ - (function (global) { 'use strict'; const System = Java.type('java.lang.System'); - const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.jsscripting.js"); + const log = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.automation.script"); const ScriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution'); const ZonedDateTime = Java.type('java.time.ZonedDateTime'); From d149195ac6c4ac8fe1fb1e11fb5805435d340aad Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 5 Dec 2021 14:16:51 -0800 Subject: [PATCH 18/23] Add lifecyle and bundle context support, cleans up global scripting a bit. This also includes an upcoming PR for cache support, which i will remove from here after it gets merged. Signed-off-by: Dan Cunningham --- .../internal/GraalJSScriptEngineFactory.java | 5 +- .../AbstractScriptExtensionProvider.java | 89 ++++++++++++++ .../internal/scope/ClassExtender.java | 25 ++++ .../jsscripting/internal/scope/Lifecycle.java | 62 ++++++++++ .../scope/OSGiScriptExtensionProvider.java | 40 +++++++ .../ProvidersScriptExtensionProvider.java | 48 ++++++++ .../internal/scope/ScriptDisposalAware.java | 32 +++++ ...tDisposalAwareScriptExtensionProvider.java | 98 +++++++++++++++ .../internal/scope/SharedCache.java | 101 ++++++++++++++++ .../binding/BindingItemProviderDelegate.java | 113 ++++++++++++++++++ .../BindingItemProviderDelegateFactory.java | 81 +++++++++++++ .../scope/binding/BindingSupport.java | 32 +++++ .../node_modules/@jsscripting-globals.js | 1 + 13 files changed, 723 insertions(+), 4 deletions(-) create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java create mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java index 33c5a171b54f..db3f0a184e21 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/GraalJSScriptEngineFactory.java @@ -26,8 +26,6 @@ import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Modified; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.oracle.truffle.js.scriptengine.GraalJSEngineFactory; @@ -41,7 +39,6 @@ + "=org.openhab.automation.jsscripting") @ConfigurableService(category = "automation", label = "JS Scripting", description_uri = "automation:jsscripting") public final class GraalJSScriptEngineFactory implements ScriptEngineFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(GraalJSScriptEngineFactory.class); private static final String CFG_INJECTION_ENABLED = "injectionEnabled"; private static final String INJECTION_CODE = "Object.assign(this, require('openhab'));"; private boolean injectionEnabled; @@ -76,6 +73,6 @@ protected void activate(BundleContext context, Map config) { @Modified protected void modified(Map config) { Object injectionEnabled = config.get(CFG_INJECTION_ENABLED); - this.injectionEnabled = injectionEnabled != null && (Boolean) injectionEnabled; + this.injectionEnabled = injectionEnabled == null || (Boolean) injectionEnabled; } } diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java new file mode 100644 index 000000000000..3c2a13eac0e2 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2010-2019 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +import org.openhab.core.automation.module.script.ScriptExtensionProvider; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.annotations.Activate; + +/** + * Base class to offer support for script extension providers + * + * @author Jonathan Gilbert + */ +public abstract class AbstractScriptExtensionProvider implements ScriptExtensionProvider { + private Map> types; + private Map> idToTypes = new ConcurrentHashMap<>(); + + protected abstract String getPresetName(); + + protected abstract void initializeTypes(final BundleContext context); + + protected void addType(String name, Function value) { + types.put(name, value); + } + + @Activate + public void activate(final BundleContext context) { + types = new HashMap<>(); + initializeTypes(context); + } + + @Override + public Collection getDefaultPresets() { + return Collections.emptyList(); + } + + @Override + public Collection getPresets() { + return Collections.singleton(getPresetName()); + } + + @Override + public Collection getTypes() { + return types.keySet(); + } + + @Override + public Object get(String scriptIdentifier, String type) throws IllegalArgumentException { + + Map forScript = idToTypes.computeIfAbsent(scriptIdentifier, k -> new HashMap<>()); + return forScript.computeIfAbsent(type, k -> types.get(k).apply(scriptIdentifier)); + } + + @Override + public Map importPreset(String scriptIdentifier, String preset) { + if (getPresetName().equals(preset)) { + Map results = new HashMap<>(types.size()); + for (String type : types.keySet()) { + results.put(type, get(scriptIdentifier, type)); + } + return results; + } + + return Collections.emptyMap(); + } + + @Override + public void unload(String scriptIdentifier) { + // ignore by default + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java new file mode 100644 index 000000000000..3cb6587340c9 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.automation.jsscripting.internal.scope; + +//import com.oracle.truffle.js.runtime.java.adapter.JavaAdapterFactory; + +/** + * Class utility to allow creation of 'extendable' classes with a classloader of the current bundle, rather than the + * classloader of the file being extended. + * + * @author Jonathan Gilbert - Initial contribution + */ +public class ClassExtender { + private ClassLoader classLoader = getClass().getClassLoader(); +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java new file mode 100644 index 000000000000..4f941d0f8749 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.automation.jsscripting.internal.scope; + +import java.util.*; +import java.util.function.Consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Allows scripts to register for lifecycle events + * + * @author Jonathan Gilbert + */ +public class Lifecycle implements ScriptDisposalAware { + private static final Logger logger = LoggerFactory.getLogger(Lifecycle.class); + public static final int DEFAULT_PRIORITY = 50; + private List listeners = new ArrayList<>(); + + public void addDisposeHook(Consumer listener, int priority) { + addListener(listener, priority); + } + + public void addDisposeHook(Consumer listener) { + addDisposeHook(listener, DEFAULT_PRIORITY); + } + + private void addListener(Consumer listener, int priority) { + listeners.add(new Hook(priority, listener)); + } + + @Override + public void unload(String scriptIdentifier) { + try { + listeners.stream().sorted(Comparator.comparingInt(h -> h.priority)) + .forEach(h -> h.fn.accept(scriptIdentifier)); + } catch (RuntimeException ex) { + logger.warn("Script unloading halted due to exception in disposal: {}: {}", ex.getClass(), ex.getMessage()); + } + } + + private static class Hook { + public Hook(int priority, Consumer fn) { + this.priority = priority; + this.fn = fn; + } + + int priority; + Consumer fn; + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java new file mode 100644 index 000000000000..e5f53526da41 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.automation.jsscripting.internal.scope; + +import org.openhab.core.automation.module.script.ScriptExtensionProvider; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.annotations.Component; + +/** + * ScriptExtensionProvider which provides various functions to help scripts to work with OSGi + * + * @author Jonathan Gilbert - Initial contribution + */ +@Component(immediate = true, service = ScriptExtensionProvider.class) +public class OSGiScriptExtensionProvider extends ScriptDisposalAwareScriptExtensionProvider { + + @Override + protected String getPresetName() { + return "osgi"; + } + + @Override + protected void initializeTypes(final BundleContext context) { + ClassExtender classExtender = new ClassExtender(); + + addType("bundleContext", k -> context); + addType("lifecycle", k -> new Lifecycle()); + addType("classutil", k -> classExtender); + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java new file mode 100644 index 000000000000..2ddf49e34302 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.automation.jsscripting.internal.scope; + +import static org.osgi.service.component.annotations.ReferenceCardinality.MANDATORY; + +import org.openhab.automation.jsscripting.internal.scope.binding.BindingItemProviderDelegateFactory; +import org.openhab.core.automation.module.script.ScriptExtensionProvider; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * ScriptExtensionProvider which provides support for object providers + * + * @author Jonathan Gilbert - Initial contribution + */ +@Component(immediate = true, service = ScriptExtensionProvider.class) +public class ProvidersScriptExtensionProvider extends ScriptDisposalAwareScriptExtensionProvider { + + private BindingItemProviderDelegateFactory bindingItemProviderDelegateFactory; + + @Reference(cardinality = MANDATORY) + public void setBindingItemProviderDelegateFactory( + BindingItemProviderDelegateFactory bindingItemProviderDelegateFactory) { + this.bindingItemProviderDelegateFactory = bindingItemProviderDelegateFactory; + } + + @Override + protected String getPresetName() { + return "provider"; + } + + @Override + protected void initializeTypes(final BundleContext context) { + addType("itemBinding", k -> bindingItemProviderDelegateFactory); + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java new file mode 100644 index 000000000000..a82edd766dab --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Specifies that an object is aware of script disposal events + * + * @author Jonathan Gilbert - Initial contribution + */ +@NonNullByDefault +public interface ScriptDisposalAware { + + /** + * Indicates that the script has been disposed + * + * @param scriptIdentifier the identifier for the script + */ + void unload(String scriptIdentifier); +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java new file mode 100644 index 000000000000..8439439fec1e --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +import org.openhab.core.automation.module.script.ScriptExtensionProvider; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.annotations.Activate; + +/** + * Base class to offer support for script extension providers + * + * @author Jonathan Gilbert + */ +public abstract class ScriptDisposalAwareScriptExtensionProvider + implements ScriptExtensionProvider, ScriptDisposalAware { + private Map> types; + private Map> idToTypes = new ConcurrentHashMap<>(); + + protected abstract String getPresetName(); + + protected abstract void initializeTypes(final BundleContext context); + + protected void addType(String name, Function value) { + types.put(name, value); + } + + @Activate + public void activate(final BundleContext context) { + types = new HashMap<>(); + initializeTypes(context); + } + + @Override + public Collection getDefaultPresets() { + return Collections.emptyList(); + } + + @Override + public Collection getPresets() { + return Collections.singleton(getPresetName()); + } + + @Override + public Collection getTypes() { + return types.keySet(); + } + + @Override + public Object get(String scriptIdentifier, String type) throws IllegalArgumentException { + + Map forScript = idToTypes.computeIfAbsent(scriptIdentifier, k -> new HashMap<>()); + return forScript.computeIfAbsent(type, k -> types.get(k).apply(scriptIdentifier)); + } + + @Override + public Map importPreset(String scriptIdentifier, String preset) { + if (getPresetName().equals(preset)) { + Map results = new HashMap<>(types.size()); + for (String type : types.keySet()) { + results.put(type, get(scriptIdentifier, type)); + } + return results; + } + + return Collections.emptyMap(); + } + + @Override + public void unload(String scriptIdentifier) { + Map forScript = idToTypes.remove(scriptIdentifier); + + if (forScript != null) { + for (Object o : forScript.values()) { + if (o instanceof ScriptDisposalAware) { + ((ScriptDisposalAware) o).unload(scriptIdentifier); + } + } + } + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java new file mode 100644 index 000000000000..7050b01f66fe --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.automation.jsscripting.internal.scope; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.automation.module.script.ScriptExtensionProvider; +import org.osgi.service.component.annotations.Component; + +/** + * Shared Cache implementation for JS scripting. + * + * @author Jonathan Gilbert - Initial contribution + */ +@Component(immediate = true) +@NonNullByDefault +public class SharedCache implements ScriptExtensionProvider { + + private static final String PRESET_NAME = "cache"; + private static final String OBJECT_NAME = "sharedcache"; + + private JSCache cache = new JSCache(); + + @Override + public Collection getDefaultPresets() { + return Set.of(PRESET_NAME); + } + + @Override + public Collection getPresets() { + return Set.of(PRESET_NAME); + } + + @Override + public Collection getTypes() { + return Set.of(OBJECT_NAME); + } + + @Override + public @Nullable Object get(String scriptIdentifier, String type) throws IllegalArgumentException { + if (OBJECT_NAME.equals(type)) { + return cache; + } + + return null; + } + + @Override + public Map importPreset(String scriptIdentifier, String preset) { + if (PRESET_NAME.equals(preset)) { + final Object requestedType = get(scriptIdentifier, OBJECT_NAME); + if (requestedType != null) { + return Map.of(OBJECT_NAME, requestedType); + } + } + + return Collections.emptyMap(); + } + + @Override + public void unload(String scriptIdentifier) { + // ignore for now + } + + public static class JSCache { + private Map backingMap = new HashMap<>(); + + public void put(String k, Object v) { + backingMap.put(k, v); + } + + public @Nullable Object remove(String k) { + return backingMap.remove(k); + } + + public @Nullable Object get(String k) { + return backingMap.get(k); + } + + public @Nullable Object get(String k, Supplier supplier) { + return backingMap.computeIfAbsent(k, (unused_key) -> supplier.get()); + } + } +} \ No newline at end of file diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java new file mode 100644 index 000000000000..14adfeab2cf1 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope.binding; + +import java.util.Collection; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.common.registry.AbstractProvider; +import org.openhab.core.common.registry.Provider; +import org.openhab.core.common.registry.ProviderChangeListener; +import org.openhab.core.config.core.Configuration; +import org.openhab.core.items.Item; +import org.openhab.core.items.ItemProvider; +import org.openhab.core.items.Metadata; +import org.openhab.core.items.MetadataKey; +import org.openhab.core.model.item.BindingConfigReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Item provider which binds items based on metadata they have attached + * + * @author Jonathan Gilbert + */ +@NonNullByDefault +public class BindingItemProviderDelegate extends AbstractProvider implements ItemProvider { + + private final Logger logger = LoggerFactory.getLogger(BindingItemProviderDelegate.class); + + private ItemProvider delegate; + private String contextName; + private boolean bound = false; // binds lazily + + private BindingSupport bindingSupport; + + BindingItemProviderDelegate(String contextName, ItemProvider delegate, BindingSupport bindingSupport) { + this.delegate = delegate; + this.contextName = contextName; + this.bindingSupport = bindingSupport; + delegate.addProviderChangeListener(new ProviderChangeListener() { + @Override + public void added(Provider provider, Item item) { + bindAll(); + notifyListenersAboutAddedElement(item); + } + + @Override + public void removed(Provider provider, Item item) { + bindAll(); + notifyListenersAboutRemovedElement(item); + } + + @Override + public void updated(Provider provider, Item oldItem, Item newItem) { + bindAll(); + notifyListenersAboutUpdatedElement(oldItem, newItem); + } + }); + } + + private void bindAll() { + for (BindingConfigReader reader : bindingSupport.getBindingConfigReaders().values()) { + bindForReader(reader); + } + } + + private void bindForReader(BindingConfigReader reader) { + reader.startConfigurationUpdate(contextName); + + for (Item item : delegate.getAll()) { + Metadata metadata = bindingSupport.getMetadataRegistry() + .get(new MetadataKey(reader.getBindingType(), item.getName())); + if (metadata != null) { + bindItemForReader(reader, item, metadata.getValue()); + } + } + + reader.stopConfigurationUpdate(contextName); + } + + private void bindItemForReader(BindingConfigReader reader, Item item, String config) { + try { + reader.validateItemType(item.getType(), config); + reader.processBindingConfiguration(contextName, item.getType(), item.getName(), config, + new Configuration()); + } catch (Exception e) { + logger.error("Binding configuration of type '{}' of item '{}' could not be parsed correctly.", + reader.getBindingType(), item.getName(), e); + } // Catch badly behaving binding exceptions and continue processing + } + + @Override + public Collection getAll() { + + if (!bound) { + bindAll(); + bound = true; + } + + return delegate.getAll(); + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java new file mode 100644 index 000000000000..21ff595604f4 --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope.binding; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.items.ItemProvider; +import org.openhab.core.items.MetadataRegistry; +import org.openhab.core.model.item.BindingConfigReader; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory to allowing wrapping of basic ItemProviders to add functionality for them to bind their items. + * + * @author Jonathan Gilbert + */ +@Component(service = BindingItemProviderDelegateFactory.class) +@NonNullByDefault +public class BindingItemProviderDelegateFactory { + + private final Logger logger = LoggerFactory.getLogger(BindingItemProviderDelegateFactory.class); + + private Map bindingConfigReaders = new HashMap<>(); + @NonNullByDefault({}) + private MetadataRegistry metadataRegistry; + + private BindingSupport bindingSupport = new BindingSupport() { + @Override + public MetadataRegistry getMetadataRegistry() { + return metadataRegistry; + } + + @Override + public Map getBindingConfigReaders() { + return bindingConfigReaders; + } + }; + + public BindingItemProviderDelegate create(String contextName, ItemProvider delegate) { + return new BindingItemProviderDelegate(contextName, delegate, bindingSupport); + } + + @Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) + public void setMetadataRegistry(MetadataRegistry metadataRegistry) { + this.metadataRegistry = metadataRegistry; + } + + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) + public void addBindingConfigReader(BindingConfigReader reader) { + if (!bindingConfigReaders.containsKey(reader.getBindingType())) { + bindingConfigReaders.put(reader.getBindingType(), reader); + } else { + logger.warn("Attempted to register a second BindingConfigReader of type '{}'." + + " The primary reader will remain active!", reader.getBindingType()); + } + } + + public void removeBindingConfigReader(BindingConfigReader reader) { + if (bindingConfigReaders.get(reader.getBindingType()).equals(reader)) { + bindingConfigReaders.remove(reader.getBindingType()); + } + } +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java new file mode 100644 index 000000000000..a9696def17be --- /dev/null +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ + +package org.openhab.automation.jsscripting.internal.scope.binding; + +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.items.MetadataRegistry; +import org.openhab.core.model.item.BindingConfigReader; + +/** + * Interface to provide access to multiple objects to support bindings + * + * @author Jonathan Gilbert + */ +@NonNullByDefault +interface BindingSupport { + MetadataRegistry getMetadataRegistry(); + + Map getBindingConfigReaders(); +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js index fb13a66c5017..d60a90517402 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/node_modules/@jsscripting-globals.js @@ -1,3 +1,4 @@ + (function (global) { 'use strict'; From 52dcb723a8903c932f261e3c99e41e9cd81895da Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 5 Dec 2021 14:41:03 -0800 Subject: [PATCH 19/23] Bump openhab-js version Signed-off-by: Dan Cunningham --- bundles/org.openhab.automation.jsscripting/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index 841b452a146b..100764cd0ffd 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -25,7 +25,7 @@ 21.3.0 6.2.1 ${project.version} - openhab@0.0.1-beta.1 + openhab@0.0.1-beta.2 From d60e0715e2fac5a2765835db860236a34b2c2af2 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 5 Dec 2021 14:58:30 -0800 Subject: [PATCH 20/23] spotless Signed-off-by: Dan Cunningham --- .../internal/scope/AbstractScriptExtensionProvider.java | 2 +- .../jsscripting/internal/scope/ClassExtender.java | 2 +- .../automation/jsscripting/internal/scope/Lifecycle.java | 6 ++++-- .../internal/scope/OSGiScriptExtensionProvider.java | 2 +- .../internal/scope/ProvidersScriptExtensionProvider.java | 2 +- .../jsscripting/internal/scope/ScriptDisposalAware.java | 4 ++-- .../scope/ScriptDisposalAwareScriptExtensionProvider.java | 2 +- .../automation/jsscripting/internal/scope/SharedCache.java | 2 +- .../internal/scope/binding/BindingItemProviderDelegate.java | 2 +- .../scope/binding/BindingItemProviderDelegateFactory.java | 2 +- .../jsscripting/internal/scope/binding/BindingSupport.java | 2 +- 11 files changed, 15 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java index 3c2a13eac0e2..f25a341dc5f8 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2019 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java index 3cb6587340c9..ee67607c894d 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ClassExtender.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java index 4f941d0f8749..046799c4a669 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. @@ -12,7 +12,9 @@ */ package org.openhab.automation.jsscripting.internal.scope; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import java.util.function.Consumer; import org.slf4j.Logger; diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java index e5f53526da41..5ec867ba70fd 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/OSGiScriptExtensionProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java index 2ddf49e34302..fada2c87551b 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java index a82edd766dab..6c18c598cc0b 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAware.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. @@ -25,7 +25,7 @@ public interface ScriptDisposalAware { /** * Indicates that the script has been disposed - * + * * @param scriptIdentifier the identifier for the script */ void unload(String scriptIdentifier); diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java index 8439439fec1e..c2db05ca7124 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java index 7050b01f66fe..225e5fddf20f 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/SharedCache.java @@ -98,4 +98,4 @@ public void put(String k, Object v) { return backingMap.computeIfAbsent(k, (unused_key) -> supplier.get()); } } -} \ No newline at end of file +} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java index 14adfeab2cf1..439354241d55 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java index 21ff595604f4..2e211d6e8aaa 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java index a9696def17be..58e96e1215e7 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010-2020 Contributors to the openHAB project + * Copyright (c) 2010-2021 Contributors to the openHAB project * * See the NOTICE file(s) distributed with this work for additional * information. From 88a712c104dc64d4a1467b4497110c0a4ad46ebd Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 12 Dec 2021 16:10:56 -0800 Subject: [PATCH 21/23] remove unessesary binding provider classes, updated class docs Signed-off-by: Dan Cunningham --- .../AbstractScriptExtensionProvider.java | 2 +- .../jsscripting/internal/scope/Lifecycle.java | 2 +- .../ProvidersScriptExtensionProvider.java | 48 -------- ...tDisposalAwareScriptExtensionProvider.java | 2 +- .../binding/BindingItemProviderDelegate.java | 113 ------------------ .../BindingItemProviderDelegateFactory.java | 81 ------------- .../scope/binding/BindingSupport.java | 32 ----- .../main/resources/OH-INF/config/config.xml | 2 +- 8 files changed, 4 insertions(+), 278 deletions(-) delete mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java delete mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java delete mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java delete mode 100644 bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java index f25a341dc5f8..0592076ff8f6 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/AbstractScriptExtensionProvider.java @@ -27,7 +27,7 @@ /** * Base class to offer support for script extension providers * - * @author Jonathan Gilbert + * @author Jonathan Gilbert - Initial contribution */ public abstract class AbstractScriptExtensionProvider implements ScriptExtensionProvider { private Map> types; diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java index 046799c4a669..859029543832 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/Lifecycle.java @@ -23,7 +23,7 @@ /** * Allows scripts to register for lifecycle events * - * @author Jonathan Gilbert + * @author Jonathan Gilbert - Initial contribution */ public class Lifecycle implements ScriptDisposalAware { private static final Logger logger = LoggerFactory.getLogger(Lifecycle.class); diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java deleted file mode 100644 index fada2c87551b..000000000000 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ProvidersScriptExtensionProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.openhab.automation.jsscripting.internal.scope; - -import static org.osgi.service.component.annotations.ReferenceCardinality.MANDATORY; - -import org.openhab.automation.jsscripting.internal.scope.binding.BindingItemProviderDelegateFactory; -import org.openhab.core.automation.module.script.ScriptExtensionProvider; -import org.osgi.framework.BundleContext; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; - -/** - * ScriptExtensionProvider which provides support for object providers - * - * @author Jonathan Gilbert - Initial contribution - */ -@Component(immediate = true, service = ScriptExtensionProvider.class) -public class ProvidersScriptExtensionProvider extends ScriptDisposalAwareScriptExtensionProvider { - - private BindingItemProviderDelegateFactory bindingItemProviderDelegateFactory; - - @Reference(cardinality = MANDATORY) - public void setBindingItemProviderDelegateFactory( - BindingItemProviderDelegateFactory bindingItemProviderDelegateFactory) { - this.bindingItemProviderDelegateFactory = bindingItemProviderDelegateFactory; - } - - @Override - protected String getPresetName() { - return "provider"; - } - - @Override - protected void initializeTypes(final BundleContext context) { - addType("itemBinding", k -> bindingItemProviderDelegateFactory); - } -} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java index c2db05ca7124..29ac13a93f97 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/ScriptDisposalAwareScriptExtensionProvider.java @@ -27,7 +27,7 @@ /** * Base class to offer support for script extension providers * - * @author Jonathan Gilbert + * @author Jonathan Gilbert - Initial contribution */ public abstract class ScriptDisposalAwareScriptExtensionProvider implements ScriptExtensionProvider, ScriptDisposalAware { diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java deleted file mode 100644 index 439354241d55..000000000000 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegate.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.openhab.automation.jsscripting.internal.scope.binding; - -import java.util.Collection; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.common.registry.AbstractProvider; -import org.openhab.core.common.registry.Provider; -import org.openhab.core.common.registry.ProviderChangeListener; -import org.openhab.core.config.core.Configuration; -import org.openhab.core.items.Item; -import org.openhab.core.items.ItemProvider; -import org.openhab.core.items.Metadata; -import org.openhab.core.items.MetadataKey; -import org.openhab.core.model.item.BindingConfigReader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Item provider which binds items based on metadata they have attached - * - * @author Jonathan Gilbert - */ -@NonNullByDefault -public class BindingItemProviderDelegate extends AbstractProvider implements ItemProvider { - - private final Logger logger = LoggerFactory.getLogger(BindingItemProviderDelegate.class); - - private ItemProvider delegate; - private String contextName; - private boolean bound = false; // binds lazily - - private BindingSupport bindingSupport; - - BindingItemProviderDelegate(String contextName, ItemProvider delegate, BindingSupport bindingSupport) { - this.delegate = delegate; - this.contextName = contextName; - this.bindingSupport = bindingSupport; - delegate.addProviderChangeListener(new ProviderChangeListener() { - @Override - public void added(Provider provider, Item item) { - bindAll(); - notifyListenersAboutAddedElement(item); - } - - @Override - public void removed(Provider provider, Item item) { - bindAll(); - notifyListenersAboutRemovedElement(item); - } - - @Override - public void updated(Provider provider, Item oldItem, Item newItem) { - bindAll(); - notifyListenersAboutUpdatedElement(oldItem, newItem); - } - }); - } - - private void bindAll() { - for (BindingConfigReader reader : bindingSupport.getBindingConfigReaders().values()) { - bindForReader(reader); - } - } - - private void bindForReader(BindingConfigReader reader) { - reader.startConfigurationUpdate(contextName); - - for (Item item : delegate.getAll()) { - Metadata metadata = bindingSupport.getMetadataRegistry() - .get(new MetadataKey(reader.getBindingType(), item.getName())); - if (metadata != null) { - bindItemForReader(reader, item, metadata.getValue()); - } - } - - reader.stopConfigurationUpdate(contextName); - } - - private void bindItemForReader(BindingConfigReader reader, Item item, String config) { - try { - reader.validateItemType(item.getType(), config); - reader.processBindingConfiguration(contextName, item.getType(), item.getName(), config, - new Configuration()); - } catch (Exception e) { - logger.error("Binding configuration of type '{}' of item '{}' could not be parsed correctly.", - reader.getBindingType(), item.getName(), e); - } // Catch badly behaving binding exceptions and continue processing - } - - @Override - public Collection getAll() { - - if (!bound) { - bindAll(); - bound = true; - } - - return delegate.getAll(); - } -} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java deleted file mode 100644 index 2e211d6e8aaa..000000000000 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingItemProviderDelegateFactory.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.openhab.automation.jsscripting.internal.scope.binding; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.items.ItemProvider; -import org.openhab.core.items.MetadataRegistry; -import org.openhab.core.model.item.BindingConfigReader; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; -import org.osgi.service.component.annotations.ReferencePolicy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Factory to allowing wrapping of basic ItemProviders to add functionality for them to bind their items. - * - * @author Jonathan Gilbert - */ -@Component(service = BindingItemProviderDelegateFactory.class) -@NonNullByDefault -public class BindingItemProviderDelegateFactory { - - private final Logger logger = LoggerFactory.getLogger(BindingItemProviderDelegateFactory.class); - - private Map bindingConfigReaders = new HashMap<>(); - @NonNullByDefault({}) - private MetadataRegistry metadataRegistry; - - private BindingSupport bindingSupport = new BindingSupport() { - @Override - public MetadataRegistry getMetadataRegistry() { - return metadataRegistry; - } - - @Override - public Map getBindingConfigReaders() { - return bindingConfigReaders; - } - }; - - public BindingItemProviderDelegate create(String contextName, ItemProvider delegate) { - return new BindingItemProviderDelegate(contextName, delegate, bindingSupport); - } - - @Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) - public void setMetadataRegistry(MetadataRegistry metadataRegistry) { - this.metadataRegistry = metadataRegistry; - } - - @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) - public void addBindingConfigReader(BindingConfigReader reader) { - if (!bindingConfigReaders.containsKey(reader.getBindingType())) { - bindingConfigReaders.put(reader.getBindingType(), reader); - } else { - logger.warn("Attempted to register a second BindingConfigReader of type '{}'." - + " The primary reader will remain active!", reader.getBindingType()); - } - } - - public void removeBindingConfigReader(BindingConfigReader reader) { - if (bindingConfigReaders.get(reader.getBindingType()).equals(reader)) { - bindingConfigReaders.remove(reader.getBindingType()); - } - } -} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java deleted file mode 100644 index 58e96e1215e7..000000000000 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scope/binding/BindingSupport.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) 2010-2021 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.openhab.automation.jsscripting.internal.scope.binding; - -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.items.MetadataRegistry; -import org.openhab.core.model.item.BindingConfigReader; - -/** - * Interface to provide access to multiple objects to support bindings - * - * @author Jonathan Gilbert - */ -@NonNullByDefault -interface BindingSupport { - MetadataRegistry getMetadataRegistry(); - - Map getBindingConfigReaders(); -} diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml index 79ff8f2b67e4..3348680be332 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.automation.jsscripting/src/main/resources/OH-INF/config/config.xml @@ -6,7 +6,7 @@ https://openhab.org/schemas/config-description-1.0.0.xsd"> - + If disabled, the OH scripting library can be imported manually using "require('openhab')" ]]> From 4afd5c9fb6d568eac16c60ad34f8922a46a3cd36 Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Sun, 12 Dec 2021 16:30:14 -0800 Subject: [PATCH 22/23] Bump openhab NPM version Signed-off-by: Dan Cunningham --- bundles/org.openhab.automation.jsscripting/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index 100764cd0ffd..dde3319bf46d 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -25,7 +25,7 @@ 21.3.0 6.2.1 ${project.version} - openhab@0.0.1-beta.2 + openhab@0.0.1-beta.3 From 2054bca34f09bf447fe655bb0f012a243a5bf2ec Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Mon, 13 Dec 2021 08:12:06 +0100 Subject: [PATCH 23/23] Update bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java --- .../jsscripting/internal/OpenhabGraalJSScriptEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index 7f36c6980a2b..f4939baa0f08 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -185,7 +185,7 @@ protected void beforeInvocation() { try { eval(globalScript); } catch (ScriptException e) { - LOGGER.error("Could not inject gloabl script", e); + LOGGER.error("Could not inject global script", e); } } }