├── .editorconfig
├── .github
    └── workflows
    │   ├── release.yml
    │   └── tests.yml
├── .gitignore
├── LICENSE
├── README.md
├── index.js
├── package-lock.json
├── package.json
├── src
    └── pal.js
└── tests
    ├── cli.bats
    ├── test-run.yml
    └── test-timeout.yml
/.editorconfig:
--------------------------------------------------------------------------------
 1 | root = true
 2 | 
 3 | [*]
 4 | charset = utf-8
 5 | indent_style = space
 6 | indent_size = 4
 7 | end_of_line = lf
 8 | insert_final_newline = true
 9 | trim_trailing_whitespace = true
10 | 
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
 1 | name: Create a release
 2 | 
 3 | on:
 4 |   push:
 5 |     tags:
 6 |       - 'v*'
 7 | 
 8 | jobs:
 9 | 
10 |   sanity:
11 |     runs-on: ubuntu-latest
12 |     steps:
13 |       - uses: actions/checkout@v2
14 |       - uses: actions/setup-node@v1
15 |         with:
16 |           node-version: 14
17 |       - run: npm ci
18 |       - run: npm test
19 | 
20 |   release:
21 |     needs: sanity
22 |     runs-on: ubuntu-latest
23 |     outputs:
24 |       release_url: ${{ steps.create_release.outputs.upload_url }}
25 |     steps:
26 |       - uses: actions/checkout@v2
27 |       - name: Create a release
28 |         uses: actions/create-release@v1
29 |         id: create_release
30 |         env:
31 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 |         with:
33 |           tag_name: ${{ github.ref }}
34 |           release_name: ${{ github.ref }}
35 |           draft: false
36 |           prerelease: false
37 | 
38 |   publish:
39 |     needs: release
40 |     runs-on: ubuntu-latest
41 |     steps:
42 |       - uses: actions/checkout@v2
43 |       - uses: actions/setup-node@v1
44 |         with:
45 |           node-version: 14
46 |           registry-url: https://registry.npmjs.org/
47 |       - run: npm ci
48 |       - run: npm publish --access public
49 |         env:
50 |           NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
51 | 
52 |   build:
53 |     needs: release
54 |     runs-on: ubuntu-latest
55 |     strategy:
56 |       matrix:
57 |         platform: [linux-x64, windows-x64, macos-x64]
58 |     steps:
59 |       - name: Get the version
60 |         id: get_version
61 |         run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
62 |       - uses: actions/checkout@v2
63 |       - uses: actions/setup-node@v1
64 |         with:
65 |           node-version: 14.x
66 |       - run: npm ci
67 |       - name: Build the binary
68 |         run: npm run build -- -t node14-${{ matrix.platform }}
69 |       - name: Check the binary
70 |         run: file ./dist/*
71 |       - name: Package the binary
72 |         run: |
73 |           mv dist berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}
74 |           zip -r9 berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}/
75 |       - name: Upload the binary
76 |         uses: actions/upload-release-asset@v1
77 |         env:
78 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
79 |         with:
80 |           upload_url: ${{ needs.release.outputs.release_url }}
81 |           asset_path: berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip
82 |           asset_name: berkala-${{ steps.get_version.outputs.VERSION }}-${{ matrix.platform }}.zip
83 |           asset_content_type: application/zip
84 | 
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
 1 | name: Tests
 2 | 
 3 | on: [push, pull_request]
 4 | 
 5 | jobs:
 6 |   test:
 7 |     runs-on: ubuntu-latest
 8 |     strategy:
 9 |       matrix:
10 |         node-version: [14.x]
11 | 
12 |     steps:
13 |     - uses: actions/checkout@v2
14 |     - name: Use Node.js ${{ matrix.node-version }}
15 |       uses: actions/setup-node@v1
16 |       with:
17 |         node-version: ${{ matrix.node-version }}
18 | 
19 |     - run: npm ci
20 |     - run: npm test
21 | 
22 |   build:
23 |     runs-on: ubuntu-latest
24 |     needs: test
25 |     strategy:
26 |       matrix:
27 |         platform: [linux-x64, windows-x64, macos-x64]
28 |     steps:
29 |       - uses: actions/checkout@v2
30 |       - uses: actions/setup-node@v1
31 |         with:
32 |           node-version: 14.x
33 |       - run: npm ci
34 |       - name: Build the binary
35 |         run: npm run build -- -t node14-${{ matrix.platform }}
36 |       - name: Check the binary
37 |         run: file ./dist/*
38 | 
39 |   cli-tests:
40 |     runs-on: ubuntu-latest
41 |     needs: build
42 |     strategy:
43 |       matrix:
44 |         platform: [linux-x64]
45 |     steps:
46 |       - uses: actions/checkout@v2
47 |       - uses: actions/setup-node@v1
48 |         with:
49 |           node-version: 14.x
50 |       - run: npm ci
51 |       - name: Build the binary
52 |         run: npm run build -- -t node14-${{ matrix.platform }}
53 |       - name: Run CLI tests with the binary
54 |         run: npm run cli-tests
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | # Logs
 2 | logs
 3 | *.log
 4 | npm-debug.log*
 5 | yarn-debug.log*
 6 | yarn-error.log*
 7 | 
 8 | # Runtime data
 9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 | 
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 | 
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 | 
20 | # nyc test coverage
21 | .nyc_output
22 | 
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 | 
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 | 
29 | # node-waf configuration
30 | .lock-wscript
31 | 
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 | 
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 | 
39 | # TypeScript v1 declaration files
40 | typings/
41 | 
42 | # Optional npm cache directory
43 | .npm
44 | 
45 | # Optional eslint cache
46 | .eslintcache
47 | 
48 | # Optional REPL history
49 | .node_repl_history
50 | 
51 | # Output of 'npm pack'
52 | *.tgz
53 | 
54 | # Yarn Integrity file
55 | .yarn-integrity
56 | 
57 | # dotenv environment variables file
58 | .env
59 | 
60 | # next.js build output
61 | .next
62 | 
63 | # berkala output
64 | berkala.yml
65 | 
66 | # build output
67 | dist
68 | 
69 | # DS_Store
70 | .DS_Store
71 | 
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2020 Ariya Hidayat
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | # Berkala
  2 | 
  3 | [](https://github.com/ariya/berkala/blob/main/LICENSE)
  4 | [](https://github.com/ariya/berkala/actions)
  5 | 
  6 | Berkala runs scheduled tasks specified in a YAML-based configuration.
  7 | 
  8 | To get started, first download the binary for your operating system from the [Releases page](https://github.com/ariya/berkala/releases). Unpack the ZIP file and run the executable.
  9 | 
 10 | Since a config file does not exist yet, you will be offered to create one.
 11 | Simply accept it and `berkala.yml` will be created, which may look like the following:
 12 | 
 13 | ```yml
 14 | tasks:
 15 | 
 16 |   # Without an explicit interval, the task runs immediately
 17 |   boot:
 18 |     steps:
 19 |     - notify: Berkala starts now
 20 | 
 21 |   stay-hydrated:
 22 |     interval: every 1 hour
 23 |     steps:
 24 |     - notify: Drink some water! # TODO: how much?
 25 |     - print: Reminder was sent
 26 | 
 27 |   lunch:
 28 |     interval: at 11:58am
 29 |     steps:
 30 |     - notify: It's lunch time very soon
 31 |       title: Important
 32 |     - say: Get ready for lunch
 33 | 
 34 |   sign-of-life:
 35 |     interval: every 2 hours
 36 |     steps:
 37 |     - run: ping -c 7 google.com
 38 |       timeout-minutes: 2
 39 | 
 40 |   weekend-exercise:
 41 |     cron: 0 9 * * 6  # every 9 morning on Saturday
 42 |     steps:
 43 |     - notify: Time for some exercises!
 44 |       title: Stay healthy
 45 | ```
 46 | Just like any regular YAML, everything from the `#` character until the end of the line will be ignored. Use this to insert comments.
 47 | 
 48 | The schedule for each task can be specified as:
 49 | * [a human-friendly interval](https://breejs.github.io/later/parsers.html#text),  e.g. `every 5 minutes`, `at 5pm`, or
 50 | * [a cron expression](https://crontab.guru/), e.g. `0 9 * * 6`
 51 | 
 52 | If neither is explicitly stated, then the task runs right away.
 53 | 
 54 | Each task consists of one or more steps.
 55 | 
 56 | Every step must be one of the following:
 57 | 
 58 | run: executes a shell command
 59 | 
 60 | Example:
 61 | ```yaml
 62 |   sign-of-life:
 63 |     interval: every 30 minutes
 64 |     steps:
 65 |     - run: ping -c 7 google.com
 66 | ```
 67 | Optionally, `timeout-minutes` can be used to limit the execution time and `working-directory` can be used to set the directory to start the execution from.
 68 | 
 69 | Another example:
 70 | ```yaml
 71 |   sys-resource:
 72 |     interval: every 2 hours
 73 |     steps:
 74 |     - run: |
 75 |         date >> resources.log
 76 |         top | head -n 4 >> resources.log
 77 |       timeout-minutes: 3
 78 |       working-directory: /var/log
 79 | ```
 80 | 
 81 |  
 82 | 
 83 | 
 84 | print: displays a message to the standard output
 85 | 
 86 | Example:
 87 | ```yaml
 88 |   morning:
 89 |     interval: at 7:00am
 90 |     steps:
 91 |     - print: Good morning!
 92 | ```
 93 | 
 94 |  
 95 | 
 96 | notify: sends a desktop notification
 97 | 
 98 | Optionally, `title` can be used to set the notification title.
 99 | 
100 | Example:
101 | ```yaml
102 |   mahlzeit:
103 |     interval: at 11:58am
104 |     steps:
105 |     - notify: It's lunch time very soon
106 |       title: Yummy
107 | ```
108 | 
109 | The notification is supported on the following system:
110 | 
111 | * Windows: [Windows.UI.Notifications](https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting)
112 | * macOS: `display notification` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html)
113 | * Linux: [notify-send](https://www.commandlinux.com/man-page/man1/notify-send.1.html), e.g. part of `libnotify-bin` package on Debian/Ubuntu
114 | 
115 |  
116 | 
117 | say: converts text to audible speech
118 | 
119 | Example:
120 | ```yaml
121 |   vaya-con-dios:
122 |     interval: 0 17 * * 1-5  # every workday late afternoon
123 |     steps:
124 |     - say: Time to go home
125 | ```
126 | 
127 | The text-to-speech conversion is supported on the following system:
128 | 
129 | * Windows: [System.Speech.Synthesis](https://docs.microsoft.com/en-us/dotnet/api/system.speech.synthesis) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting)
130 | * macOS: `say` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html)
131 | * Linux: [Festival speech synthesis](https://www.cstr.ed.ac.uk/projects/festival/), e.g. `festival` and `festvox-kallpc16k` on Debian/Ubuntu
132 | 
133 |  
134 | 
135 | Found a problem or have a new idea? File [an issue](https://github.com/ariya/berkala/issues)!
136 | 
137 | 
138 | Alternative way to run Berkala (with Node.js)
139 | 
140 | With [Node.js](https://nodejs.org/) v14 or later (that has [npx](https://www.npmjs.com/package/npx)):
141 | 
142 | ```bash
143 | npx @ariya/berkala
144 | ```
145 | 
146 | To run the development version, check out this repo and then:
147 | 
148 | ```bash
149 | npm install
150 | npm start
151 | ```
152 | 
153 | [](https://www.npmjs.com/package/@ariya/berkala)
154 | [](https://bundlephobia.com/result?p=@ariya/berkala)
155 | 
156 |  
157 | 
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env node
  2 | 
  3 | const fs = require('fs');
  4 | const os = require('os');
  5 | 
  6 | const manifest = require('./package.json');
  7 | const readline = require('readline-sync');
  8 | const yaml = require('js-yaml');
  9 | const Bree = require('bree');
 10 | 
 11 | const pal = require('./src/pal');
 12 | 
 13 | const CONFIG_FILENAME = 'berkala.yml';
 14 | 
 15 | const SAMPLE_CONFIG = `
 16 | tasks:
 17 | 
 18 |   # Without an explicit interval, the task runs immediately
 19 |   boot:
 20 |     steps:
 21 |     - notify: Berkala starts now
 22 |     - say: Ready to rock and roll
 23 | 
 24 |   stay-hydrated:
 25 |     interval: every 1 hour
 26 |     steps:
 27 |     - notify: Drink some water! # TODO: how much?
 28 |     - print: Reminder was sent
 29 | 
 30 |   lunch:
 31 |     interval: at 11:58am
 32 |     steps:
 33 |     - notify: It's lunch time very soon
 34 |       title: Important
 35 |     - say: Get ready for lunch
 36 | 
 37 |   sign-of-life:
 38 |     interval: every 30 minutes
 39 |     steps:
 40 |     - print: Pings
 41 |     - run: |
 42 |         ping -c 3 google.com
 43 |         ping -c 5 bing.com
 44 |       timeout-minutes: 2
 45 | 
 46 |   weekend-exercise:
 47 |     cron: 0 9 * * 6  # every 9 morning on Saturday
 48 |     steps:
 49 |     - notify: Time for some exercises!
 50 |       title: Stay healthy
 51 | `;
 52 | 
 53 | /**
 54 |  * Returns true if interactivity is permitted (i.e. not in a CI)
 55 |  */
 56 | function isInteractive() {
 57 |     const stdout = process.stdout;
 58 |     return stdout.isTTY && !('CI' in process.env) && process.env.TERM !== 'dumb';
 59 | }
 60 | 
 61 | /**
 62 |  * Retrieve the configuration from the external berkala.yml file.
 63 |  */
 64 | function getConfig() {
 65 |     const tasks = {};
 66 |     let config = { tasks };
 67 |     if (!fs.existsSync(CONFIG_FILENAME) && isInteractive()) {
 68 |         console.log(CONFIG_FILENAME, 'does not exist.');
 69 |         const answer = readline.question('Do you want to create one (Y/n)? ').toUpperCase();
 70 |         if (answer === 'Y' || answer === 'YES') {
 71 |             let conf = SAMPLE_CONFIG.trim();
 72 |             if (os.type() === 'Windows_NT') {
 73 |                 // ping on Window does not support "-c"
 74 |                 conf = conf.replace(/ping -c/gi, 'ping -n');
 75 |             }
 76 |             fs.writeFileSync(CONFIG_FILENAME, conf, 'utf-8');
 77 |             return yaml.load(SAMPLE_CONFIG);
 78 |         } else {
 79 |             console.error('Can not continue, configuration does not exist!');
 80 |             process.exit(-1);
 81 |         }
 82 |     } else {
 83 |         try {
 84 |             const contents = fs.readFileSync(CONFIG_FILENAME, 'utf-8');
 85 |             config = yaml.load(contents);
 86 |         } catch (e) {
 87 |             console.error('Can not load configuration file');
 88 |             console.error(e.toString());
 89 |             process.exit(-1);
 90 |         }
 91 |     }
 92 |     return config;
 93 | }
 94 | 
 95 | function workerMessageHandler(workerData) {
 96 |     const workerMsg = workerData.message;
 97 |     const { duty } = workerMsg;
 98 |     if (duty === 'print') {
 99 |         const { message } = workerMsg;
100 |         console.log(message);
101 |     } else if (duty === 'notify') {
102 |         const { title, message } = workerMsg;
103 |         pal.notify(title, message);
104 |     } else if (duty === 'say') {
105 |         const { message } = workerMsg;
106 |         pal.say(message);
107 |     }
108 | }
109 | 
110 | /**
111 |  * Run a task, execute the steps sequentially.
112 |  */
113 | 
114 | function runTask() {
115 |     const child_process = require('child_process');
116 |     const { workerData, parentPort } = require('worker_threads');
117 | 
118 |     const { job } = workerData;
119 |     const { steps } = job;
120 | 
121 |     steps.forEach((step) => {
122 |         if (step.print) {
123 |             parentPort.postMessage({ duty: 'print', message: step.print });
124 |         } else if (step.notify) {
125 |             const title = step.title ? step.title : 'Berkala';
126 |             const message = step.notify.trim();
127 |             parentPort.postMessage({ duty: 'notify', title, message });
128 |         } else if (step.say) {
129 |             parentPort.postMessage({ duty: 'say', message: step.say });
130 |         } else if (step.run) {
131 |             const command = step.run;
132 |             const cwd = step['working-directory'] || process.cwd();
133 |             const timeoutMinutes = step['timeout-minutes'] || 3;
134 |             const timeout = 60 * 1000 * timeoutMinutes;
135 |             const options = { cwd, timeout };
136 |             try {
137 |                 child_process.execSync(command, options);
138 |             } catch (e) {
139 |                 const { errno, stderr } = e;
140 |                 const msg = stderr ? stderr.toString() : e.toString();
141 |                 console.error(`run error: ${errno} ${msg}`);
142 |             }
143 |         } else {
144 |             console.error('Unknown step', step);
145 |         }
146 |     });
147 | }
148 | 
149 | /**
150 |  * Convert a task definition to a Bree job.
151 |  */
152 | function convert(name, task) {
153 |     const { interval, cron } = task;
154 |     let { steps } = task;
155 | 
156 |     if (!steps || !Array.isArray(steps) || steps.length === 0) {
157 |         // Migrate legacy task format
158 |         steps = [];
159 |         const { type } = task;
160 |         if (type === 'print') {
161 |             const { message } = task;
162 |             steps.push({ print: message });
163 |         } else if (type === 'notify') {
164 |             const { message, title } = task;
165 |             steps.push({ notify: message, title });
166 |         }
167 |     }
168 | 
169 |     const path = runTask;
170 |     return {
171 |         name,
172 |         path,
173 |         interval,
174 |         cron,
175 |         steps
176 |     };
177 | }
178 | 
179 | /**
180 |  * Create a Bree instance according to the configuration.
181 |  */
182 | function setupTasks(config) {
183 |     const { tasks = [] } = config;
184 |     const jobs = Object.keys(tasks).map((name) => {
185 |         return convert(name, tasks[name]);
186 |     });
187 |     const root = false;
188 |     return new Bree({ root, jobs, workerMessageHandler });
189 | }
190 | 
191 | console.log('Berkala', manifest.version);
192 | console.log();
193 | 
194 | const config = getConfig() || {};
195 | const tasks = setupTasks(config);
196 | tasks.start();
197 | 
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
   1 | {
   2 |   "name": "@ariya/berkala",
   3 |   "version": "1.3.0",
   4 |   "lockfileVersion": 1,
   5 |   "requires": true,
   6 |   "dependencies": {
   7 |     "@babel/helper-validator-identifier": {
   8 |       "version": "7.14.9",
   9 |       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
  10 |       "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
  11 |       "dev": true
  12 |     },
  13 |     "@babel/parser": {
  14 |       "version": "7.13.13",
  15 |       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz",
  16 |       "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==",
  17 |       "dev": true
  18 |     },
  19 |     "@babel/runtime": {
  20 |       "version": "7.14.8",
  21 |       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
  22 |       "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
  23 |       "requires": {
  24 |         "regenerator-runtime": "^0.13.4"
  25 |       }
  26 |     },
  27 |     "@babel/types": {
  28 |       "version": "7.13.12",
  29 |       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz",
  30 |       "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==",
  31 |       "dev": true,
  32 |       "requires": {
  33 |         "@babel/helper-validator-identifier": "^7.12.11",
  34 |         "lodash": "^4.17.19",
  35 |         "to-fast-properties": "^2.0.0"
  36 |       }
  37 |     },
  38 |     "@breejs/later": {
  39 |       "version": "4.0.2",
  40 |       "resolved": "https://registry.npmjs.org/@breejs/later/-/later-4.0.2.tgz",
  41 |       "integrity": "sha512-EN0SlbyYouBdtZis1htdsgGlwFePzkXPwdIeqaBaavxkJT1G2/bitc2LSixjv45z2njXslxlJI1mW2O/Gmrb+A=="
  42 |     },
  43 |     "@nodelib/fs.scandir": {
  44 |       "version": "2.1.5",
  45 |       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
  46 |       "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
  47 |       "dev": true,
  48 |       "requires": {
  49 |         "@nodelib/fs.stat": "2.0.5",
  50 |         "run-parallel": "^1.1.9"
  51 |       }
  52 |     },
  53 |     "@nodelib/fs.stat": {
  54 |       "version": "2.0.5",
  55 |       "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
  56 |       "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
  57 |       "dev": true
  58 |     },
  59 |     "@nodelib/fs.walk": {
  60 |       "version": "1.2.8",
  61 |       "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
  62 |       "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
  63 |       "dev": true,
  64 |       "requires": {
  65 |         "@nodelib/fs.scandir": "2.1.5",
  66 |         "fastq": "^1.6.0"
  67 |       }
  68 |     },
  69 |     "@types/lodash": {
  70 |       "version": "4.14.172",
  71 |       "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz",
  72 |       "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw=="
  73 |     },
  74 |     "agent-base": {
  75 |       "version": "6.0.2",
  76 |       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
  77 |       "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
  78 |       "dev": true,
  79 |       "requires": {
  80 |         "debug": "4"
  81 |       }
  82 |     },
  83 |     "ansi-regex": {
  84 |       "version": "5.0.0",
  85 |       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
  86 |       "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
  87 |       "dev": true
  88 |     },
  89 |     "ansi-styles": {
  90 |       "version": "4.3.0",
  91 |       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
  92 |       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
  93 |       "dev": true,
  94 |       "requires": {
  95 |         "color-convert": "^2.0.1"
  96 |       }
  97 |     },
  98 |     "aproba": {
  99 |       "version": "1.2.0",
 100 |       "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
 101 |       "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
 102 |       "dev": true
 103 |     },
 104 |     "are-we-there-yet": {
 105 |       "version": "1.1.5",
 106 |       "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
 107 |       "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
 108 |       "dev": true,
 109 |       "requires": {
 110 |         "delegates": "^1.0.0",
 111 |         "readable-stream": "^2.0.6"
 112 |       }
 113 |     },
 114 |     "argparse": {
 115 |       "version": "2.0.1",
 116 |       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
 117 |       "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
 118 |     },
 119 |     "array-union": {
 120 |       "version": "2.1.0",
 121 |       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
 122 |       "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
 123 |       "dev": true
 124 |     },
 125 |     "at-least-node": {
 126 |       "version": "1.0.0",
 127 |       "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
 128 |       "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
 129 |       "dev": true
 130 |     },
 131 |     "base64-js": {
 132 |       "version": "1.5.1",
 133 |       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
 134 |       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
 135 |       "dev": true
 136 |     },
 137 |     "bats": {
 138 |       "version": "1.4.1",
 139 |       "resolved": "https://registry.npmjs.org/bats/-/bats-1.4.1.tgz",
 140 |       "integrity": "sha512-sZgqfOHgPqtQSD84WKQiNU3a/44hQiiHGtA43gTUPeOdl5jYhnXSBNGCa8DGlKc8JpI/UUYcaPNf0Afg3OOibQ==",
 141 |       "dev": true
 142 |     },
 143 |     "bats-assert": {
 144 |       "version": "2.0.0",
 145 |       "resolved": "https://registry.npmjs.org/bats-assert/-/bats-assert-2.0.0.tgz",
 146 |       "integrity": "sha512-qO3kNilWxW8iCONu9NDUfvsCiC6JzL6DPOc/DGq9z3bZ9/A7wURJ+FnFMxGbofOmWbCoy7pVhofn0o47A95qkQ==",
 147 |       "dev": true
 148 |     },
 149 |     "bats-support": {
 150 |       "version": "0.3.0",
 151 |       "resolved": "https://registry.npmjs.org/bats-support/-/bats-support-0.3.0.tgz",
 152 |       "integrity": "sha512-z+2WzXbI4OZgLnynydqH8GpI3+DcOtepO66PlK47SfEzTkiuV9hxn9eIQX+uLVFbt2Oqoc7Ky3TJ/N83lqD+cg==",
 153 |       "dev": true
 154 |     },
 155 |     "bl": {
 156 |       "version": "4.1.0",
 157 |       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
 158 |       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
 159 |       "dev": true,
 160 |       "requires": {
 161 |         "buffer": "^5.5.0",
 162 |         "inherits": "^2.0.4",
 163 |         "readable-stream": "^3.4.0"
 164 |       },
 165 |       "dependencies": {
 166 |         "readable-stream": {
 167 |           "version": "3.6.0",
 168 |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
 169 |           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
 170 |           "dev": true,
 171 |           "requires": {
 172 |             "inherits": "^2.0.3",
 173 |             "string_decoder": "^1.1.1",
 174 |             "util-deprecate": "^1.0.1"
 175 |           }
 176 |         }
 177 |       }
 178 |     },
 179 |     "boolean": {
 180 |       "version": "3.1.2",
 181 |       "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz",
 182 |       "integrity": "sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw=="
 183 |     },
 184 |     "braces": {
 185 |       "version": "3.0.2",
 186 |       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
 187 |       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
 188 |       "dev": true,
 189 |       "requires": {
 190 |         "fill-range": "^7.0.1"
 191 |       }
 192 |     },
 193 |     "bree": {
 194 |       "version": "6.2.1",
 195 |       "resolved": "https://registry.npmjs.org/bree/-/bree-6.2.1.tgz",
 196 |       "integrity": "sha512-apgOBJp/4onxroljplYKMUP1gxxUKhoftSh63h037avAuQLM7vrtJuyB8TYE9+dzduWkjb2CCKwfOkqEpMFdAg==",
 197 |       "requires": {
 198 |         "@babel/runtime": "^7.12.5",
 199 |         "@breejs/later": "^4.0.2",
 200 |         "boolean": "^3.0.2",
 201 |         "bthreads": "^0.5.1",
 202 |         "combine-errors": "^3.0.3",
 203 |         "cron-validate": "^1.4.1",
 204 |         "debug": "^4.3.1",
 205 |         "human-interval": "^2.0.0",
 206 |         "is-string-and-not-blank": "^0.0.2",
 207 |         "is-valid-path": "^0.1.1",
 208 |         "ms": "^2.1.2",
 209 |         "p-wait-for": "3.1.0",
 210 |         "safe-timers": "^1.1.0"
 211 |       }
 212 |     },
 213 |     "bthreads": {
 214 |       "version": "0.5.1",
 215 |       "resolved": "https://registry.npmjs.org/bthreads/-/bthreads-0.5.1.tgz",
 216 |       "integrity": "sha512-nK7Jo9ll+r1FRMNPWEFRTZMQrX6HhX8JjPAofxmbTNILHqWVIJPmWzCi9JlX/K0DL5AKZTFZg2Qser5C6gVs9A==",
 217 |       "requires": {
 218 |         "bufio": "~1.0.5"
 219 |       }
 220 |     },
 221 |     "buffer": {
 222 |       "version": "5.7.1",
 223 |       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
 224 |       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
 225 |       "dev": true,
 226 |       "requires": {
 227 |         "base64-js": "^1.3.1",
 228 |         "ieee754": "^1.1.13"
 229 |       }
 230 |     },
 231 |     "bufio": {
 232 |       "version": "1.0.7",
 233 |       "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.0.7.tgz",
 234 |       "integrity": "sha512-bd1dDQhiC+bEbEfg56IdBv7faWa6OipMs/AFFFvtFnB3wAYjlwQpQRZ0pm6ZkgtfL0pILRXhKxOiQj6UzoMR7A=="
 235 |     },
 236 |     "chalk": {
 237 |       "version": "4.1.2",
 238 |       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
 239 |       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
 240 |       "dev": true,
 241 |       "requires": {
 242 |         "ansi-styles": "^4.1.0",
 243 |         "supports-color": "^7.1.0"
 244 |       }
 245 |     },
 246 |     "chownr": {
 247 |       "version": "1.1.4",
 248 |       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
 249 |       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
 250 |       "dev": true
 251 |     },
 252 |     "cliui": {
 253 |       "version": "7.0.4",
 254 |       "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
 255 |       "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
 256 |       "dev": true,
 257 |       "requires": {
 258 |         "string-width": "^4.2.0",
 259 |         "strip-ansi": "^6.0.0",
 260 |         "wrap-ansi": "^7.0.0"
 261 |       }
 262 |     },
 263 |     "code-point-at": {
 264 |       "version": "1.1.0",
 265 |       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
 266 |       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
 267 |       "dev": true
 268 |     },
 269 |     "color-convert": {
 270 |       "version": "2.0.1",
 271 |       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
 272 |       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 273 |       "dev": true,
 274 |       "requires": {
 275 |         "color-name": "~1.1.4"
 276 |       }
 277 |     },
 278 |     "color-name": {
 279 |       "version": "1.1.4",
 280 |       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
 281 |       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
 282 |       "dev": true
 283 |     },
 284 |     "combine-errors": {
 285 |       "version": "3.0.3",
 286 |       "resolved": "https://registry.npmjs.org/combine-errors/-/combine-errors-3.0.3.tgz",
 287 |       "integrity": "sha1-9N9nQAg+VwOjGBEQwrEFUfAD2oY=",
 288 |       "requires": {
 289 |         "custom-error-instance": "2.1.1",
 290 |         "lodash.uniqby": "4.5.0"
 291 |       }
 292 |     },
 293 |     "console-control-strings": {
 294 |       "version": "1.1.0",
 295 |       "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
 296 |       "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
 297 |       "dev": true
 298 |     },
 299 |     "core-util-is": {
 300 |       "version": "1.0.2",
 301 |       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 302 |       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
 303 |       "dev": true
 304 |     },
 305 |     "cron-validate": {
 306 |       "version": "1.4.3",
 307 |       "resolved": "https://registry.npmjs.org/cron-validate/-/cron-validate-1.4.3.tgz",
 308 |       "integrity": "sha512-N+qKw019oQBEPIP5Qwi8Z5XelQ00ThN6Maahwv+9UGu2u/b/MPb35zngMQI0T8pBoNiBrIXGlhvsmspNSYae/w==",
 309 |       "requires": {
 310 |         "yup": "0.32.9"
 311 |       }
 312 |     },
 313 |     "custom-error-instance": {
 314 |       "version": "2.1.1",
 315 |       "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz",
 316 |       "integrity": "sha1-PPY5FIemYppiR+sMoM4ACBt+Nho="
 317 |     },
 318 |     "debug": {
 319 |       "version": "4.3.2",
 320 |       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
 321 |       "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
 322 |       "requires": {
 323 |         "ms": "2.1.2"
 324 |       },
 325 |       "dependencies": {
 326 |         "ms": {
 327 |           "version": "2.1.2",
 328 |           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 329 |           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
 330 |         }
 331 |       }
 332 |     },
 333 |     "decompress-response": {
 334 |       "version": "4.2.1",
 335 |       "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
 336 |       "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
 337 |       "dev": true,
 338 |       "requires": {
 339 |         "mimic-response": "^2.0.0"
 340 |       }
 341 |     },
 342 |     "deep-extend": {
 343 |       "version": "0.6.0",
 344 |       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
 345 |       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
 346 |       "dev": true
 347 |     },
 348 |     "deep-is": {
 349 |       "version": "0.1.3",
 350 |       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
 351 |       "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
 352 |       "dev": true
 353 |     },
 354 |     "delegates": {
 355 |       "version": "1.0.0",
 356 |       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
 357 |       "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
 358 |       "dev": true
 359 |     },
 360 |     "detect-libc": {
 361 |       "version": "1.0.3",
 362 |       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
 363 |       "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
 364 |       "dev": true
 365 |     },
 366 |     "dir-glob": {
 367 |       "version": "3.0.1",
 368 |       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
 369 |       "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
 370 |       "dev": true,
 371 |       "requires": {
 372 |         "path-type": "^4.0.0"
 373 |       }
 374 |     },
 375 |     "emoji-regex": {
 376 |       "version": "8.0.0",
 377 |       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
 378 |       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
 379 |       "dev": true
 380 |     },
 381 |     "end-of-stream": {
 382 |       "version": "1.4.4",
 383 |       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
 384 |       "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
 385 |       "dev": true,
 386 |       "requires": {
 387 |         "once": "^1.4.0"
 388 |       }
 389 |     },
 390 |     "escalade": {
 391 |       "version": "3.1.1",
 392 |       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
 393 |       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
 394 |       "dev": true
 395 |     },
 396 |     "escodegen": {
 397 |       "version": "2.0.0",
 398 |       "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
 399 |       "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
 400 |       "dev": true,
 401 |       "requires": {
 402 |         "esprima": "^4.0.1",
 403 |         "estraverse": "^5.2.0",
 404 |         "esutils": "^2.0.2",
 405 |         "optionator": "^0.8.1",
 406 |         "source-map": "~0.6.1"
 407 |       }
 408 |     },
 409 |     "esprima": {
 410 |       "version": "4.0.1",
 411 |       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
 412 |       "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
 413 |       "dev": true
 414 |     },
 415 |     "estraverse": {
 416 |       "version": "5.2.0",
 417 |       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
 418 |       "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
 419 |       "dev": true
 420 |     },
 421 |     "esutils": {
 422 |       "version": "2.0.3",
 423 |       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
 424 |       "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
 425 |       "dev": true
 426 |     },
 427 |     "expand-template": {
 428 |       "version": "2.0.3",
 429 |       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
 430 |       "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
 431 |       "dev": true
 432 |     },
 433 |     "fast-glob": {
 434 |       "version": "3.2.7",
 435 |       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
 436 |       "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
 437 |       "dev": true,
 438 |       "requires": {
 439 |         "@nodelib/fs.stat": "^2.0.2",
 440 |         "@nodelib/fs.walk": "^1.2.3",
 441 |         "glob-parent": "^5.1.2",
 442 |         "merge2": "^1.3.0",
 443 |         "micromatch": "^4.0.4"
 444 |       }
 445 |     },
 446 |     "fast-levenshtein": {
 447 |       "version": "2.0.6",
 448 |       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
 449 |       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
 450 |       "dev": true
 451 |     },
 452 |     "fastq": {
 453 |       "version": "1.11.1",
 454 |       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz",
 455 |       "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==",
 456 |       "dev": true,
 457 |       "requires": {
 458 |         "reusify": "^1.0.4"
 459 |       }
 460 |     },
 461 |     "fill-range": {
 462 |       "version": "7.0.1",
 463 |       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 464 |       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
 465 |       "dev": true,
 466 |       "requires": {
 467 |         "to-regex-range": "^5.0.1"
 468 |       }
 469 |     },
 470 |     "from2": {
 471 |       "version": "2.3.0",
 472 |       "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
 473 |       "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
 474 |       "dev": true,
 475 |       "requires": {
 476 |         "inherits": "^2.0.1",
 477 |         "readable-stream": "^2.0.0"
 478 |       }
 479 |     },
 480 |     "fs-constants": {
 481 |       "version": "1.0.0",
 482 |       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
 483 |       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
 484 |       "dev": true
 485 |     },
 486 |     "fs-extra": {
 487 |       "version": "9.1.0",
 488 |       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
 489 |       "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
 490 |       "dev": true,
 491 |       "requires": {
 492 |         "at-least-node": "^1.0.0",
 493 |         "graceful-fs": "^4.2.0",
 494 |         "jsonfile": "^6.0.1",
 495 |         "universalify": "^2.0.0"
 496 |       }
 497 |     },
 498 |     "function-bind": {
 499 |       "version": "1.1.1",
 500 |       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
 501 |       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
 502 |       "dev": true
 503 |     },
 504 |     "gauge": {
 505 |       "version": "2.7.4",
 506 |       "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
 507 |       "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
 508 |       "dev": true,
 509 |       "requires": {
 510 |         "aproba": "^1.0.3",
 511 |         "console-control-strings": "^1.0.0",
 512 |         "has-unicode": "^2.0.0",
 513 |         "object-assign": "^4.1.0",
 514 |         "signal-exit": "^3.0.0",
 515 |         "string-width": "^1.0.1",
 516 |         "strip-ansi": "^3.0.1",
 517 |         "wide-align": "^1.1.0"
 518 |       },
 519 |       "dependencies": {
 520 |         "ansi-regex": {
 521 |           "version": "2.1.1",
 522 |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
 523 |           "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
 524 |           "dev": true
 525 |         },
 526 |         "is-fullwidth-code-point": {
 527 |           "version": "1.0.0",
 528 |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
 529 |           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
 530 |           "dev": true,
 531 |           "requires": {
 532 |             "number-is-nan": "^1.0.0"
 533 |           }
 534 |         },
 535 |         "string-width": {
 536 |           "version": "1.0.2",
 537 |           "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
 538 |           "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
 539 |           "dev": true,
 540 |           "requires": {
 541 |             "code-point-at": "^1.0.0",
 542 |             "is-fullwidth-code-point": "^1.0.0",
 543 |             "strip-ansi": "^3.0.0"
 544 |           }
 545 |         },
 546 |         "strip-ansi": {
 547 |           "version": "3.0.1",
 548 |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
 549 |           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
 550 |           "dev": true,
 551 |           "requires": {
 552 |             "ansi-regex": "^2.0.0"
 553 |           }
 554 |         }
 555 |       }
 556 |     },
 557 |     "get-caller-file": {
 558 |       "version": "2.0.5",
 559 |       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
 560 |       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
 561 |       "dev": true
 562 |     },
 563 |     "github-from-package": {
 564 |       "version": "0.0.0",
 565 |       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
 566 |       "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
 567 |       "dev": true
 568 |     },
 569 |     "glob-parent": {
 570 |       "version": "5.1.2",
 571 |       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 572 |       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
 573 |       "dev": true,
 574 |       "requires": {
 575 |         "is-glob": "^4.0.1"
 576 |       },
 577 |       "dependencies": {
 578 |         "is-extglob": {
 579 |           "version": "2.1.1",
 580 |           "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 581 |           "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
 582 |           "dev": true
 583 |         },
 584 |         "is-glob": {
 585 |           "version": "4.0.1",
 586 |           "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
 587 |           "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
 588 |           "dev": true,
 589 |           "requires": {
 590 |             "is-extglob": "^2.1.1"
 591 |           }
 592 |         }
 593 |       }
 594 |     },
 595 |     "globby": {
 596 |       "version": "11.0.4",
 597 |       "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz",
 598 |       "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==",
 599 |       "dev": true,
 600 |       "requires": {
 601 |         "array-union": "^2.1.0",
 602 |         "dir-glob": "^3.0.1",
 603 |         "fast-glob": "^3.1.1",
 604 |         "ignore": "^5.1.4",
 605 |         "merge2": "^1.3.0",
 606 |         "slash": "^3.0.0"
 607 |       }
 608 |     },
 609 |     "graceful-fs": {
 610 |       "version": "4.2.7",
 611 |       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.7.tgz",
 612 |       "integrity": "sha512-b1suB8r7mlSJQIBs6typf13fz55WYPeE7/KYlQUvqB7E3hUkXhz4D8FVHkENHTqG8+mD2yyT9HgT5bNkGNiqeQ==",
 613 |       "dev": true
 614 |     },
 615 |     "has": {
 616 |       "version": "1.0.3",
 617 |       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
 618 |       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
 619 |       "dev": true,
 620 |       "requires": {
 621 |         "function-bind": "^1.1.1"
 622 |       }
 623 |     },
 624 |     "has-flag": {
 625 |       "version": "4.0.0",
 626 |       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
 627 |       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
 628 |       "dev": true
 629 |     },
 630 |     "has-unicode": {
 631 |       "version": "2.0.1",
 632 |       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
 633 |       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
 634 |       "dev": true
 635 |     },
 636 |     "https-proxy-agent": {
 637 |       "version": "5.0.0",
 638 |       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
 639 |       "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
 640 |       "dev": true,
 641 |       "requires": {
 642 |         "agent-base": "6",
 643 |         "debug": "4"
 644 |       }
 645 |     },
 646 |     "human-interval": {
 647 |       "version": "2.0.1",
 648 |       "resolved": "https://registry.npmjs.org/human-interval/-/human-interval-2.0.1.tgz",
 649 |       "integrity": "sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==",
 650 |       "requires": {
 651 |         "numbered": "^1.1.0"
 652 |       }
 653 |     },
 654 |     "ieee754": {
 655 |       "version": "1.2.1",
 656 |       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
 657 |       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
 658 |       "dev": true
 659 |     },
 660 |     "ignore": {
 661 |       "version": "5.1.8",
 662 |       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
 663 |       "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
 664 |       "dev": true
 665 |     },
 666 |     "inherits": {
 667 |       "version": "2.0.4",
 668 |       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
 669 |       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
 670 |       "dev": true
 671 |     },
 672 |     "ini": {
 673 |       "version": "1.3.8",
 674 |       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
 675 |       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
 676 |       "dev": true
 677 |     },
 678 |     "into-stream": {
 679 |       "version": "6.0.0",
 680 |       "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz",
 681 |       "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==",
 682 |       "dev": true,
 683 |       "requires": {
 684 |         "from2": "^2.3.0",
 685 |         "p-is-promise": "^3.0.0"
 686 |       }
 687 |     },
 688 |     "is-core-module": {
 689 |       "version": "2.5.0",
 690 |       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz",
 691 |       "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==",
 692 |       "dev": true,
 693 |       "requires": {
 694 |         "has": "^1.0.3"
 695 |       }
 696 |     },
 697 |     "is-extglob": {
 698 |       "version": "1.0.0",
 699 |       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
 700 |       "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
 701 |     },
 702 |     "is-fullwidth-code-point": {
 703 |       "version": "3.0.0",
 704 |       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
 705 |       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
 706 |       "dev": true
 707 |     },
 708 |     "is-glob": {
 709 |       "version": "2.0.1",
 710 |       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
 711 |       "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
 712 |       "requires": {
 713 |         "is-extglob": "^1.0.0"
 714 |       }
 715 |     },
 716 |     "is-invalid-path": {
 717 |       "version": "0.1.0",
 718 |       "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz",
 719 |       "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=",
 720 |       "requires": {
 721 |         "is-glob": "^2.0.0"
 722 |       }
 723 |     },
 724 |     "is-number": {
 725 |       "version": "7.0.0",
 726 |       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 727 |       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 728 |       "dev": true
 729 |     },
 730 |     "is-string-and-not-blank": {
 731 |       "version": "0.0.2",
 732 |       "resolved": "https://registry.npmjs.org/is-string-and-not-blank/-/is-string-and-not-blank-0.0.2.tgz",
 733 |       "integrity": "sha512-FyPGAbNVyZpTeDCTXnzuwbu9/WpNXbCfbHXLpCRpN4GANhS00eEIP5Ef+k5HYSNIzIhdN9zRDoBj6unscECvtQ==",
 734 |       "requires": {
 735 |         "is-string-blank": "^1.0.1"
 736 |       }
 737 |     },
 738 |     "is-string-blank": {
 739 |       "version": "1.0.1",
 740 |       "resolved": "https://registry.npmjs.org/is-string-blank/-/is-string-blank-1.0.1.tgz",
 741 |       "integrity": "sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw=="
 742 |     },
 743 |     "is-valid-path": {
 744 |       "version": "0.1.1",
 745 |       "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz",
 746 |       "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=",
 747 |       "requires": {
 748 |         "is-invalid-path": "^0.1.0"
 749 |       }
 750 |     },
 751 |     "isarray": {
 752 |       "version": "1.0.0",
 753 |       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
 754 |       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
 755 |       "dev": true
 756 |     },
 757 |     "isexe": {
 758 |       "version": "2.0.0",
 759 |       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
 760 |       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
 761 |     },
 762 |     "js-yaml": {
 763 |       "version": "4.1.0",
 764 |       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
 765 |       "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
 766 |       "requires": {
 767 |         "argparse": "^2.0.1"
 768 |       }
 769 |     },
 770 |     "jsonfile": {
 771 |       "version": "6.1.0",
 772 |       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
 773 |       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
 774 |       "dev": true,
 775 |       "requires": {
 776 |         "graceful-fs": "^4.1.6",
 777 |         "universalify": "^2.0.0"
 778 |       }
 779 |     },
 780 |     "levn": {
 781 |       "version": "0.3.0",
 782 |       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
 783 |       "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
 784 |       "dev": true,
 785 |       "requires": {
 786 |         "prelude-ls": "~1.1.2",
 787 |         "type-check": "~0.3.2"
 788 |       }
 789 |     },
 790 |     "lodash": {
 791 |       "version": "4.17.21",
 792 |       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
 793 |       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
 794 |     },
 795 |     "lodash-es": {
 796 |       "version": "4.17.21",
 797 |       "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
 798 |       "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
 799 |     },
 800 |     "lodash._baseiteratee": {
 801 |       "version": "4.7.0",
 802 |       "resolved": "https://registry.npmjs.org/lodash._baseiteratee/-/lodash._baseiteratee-4.7.0.tgz",
 803 |       "integrity": "sha1-NKm1VDVycnw9sueO2uPA6eZr0QI=",
 804 |       "requires": {
 805 |         "lodash._stringtopath": "~4.8.0"
 806 |       }
 807 |     },
 808 |     "lodash._basetostring": {
 809 |       "version": "4.12.0",
 810 |       "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-4.12.0.tgz",
 811 |       "integrity": "sha1-kyfJ3FFYhmt/pLnUL0Y45XZt2d8="
 812 |     },
 813 |     "lodash._baseuniq": {
 814 |       "version": "4.6.0",
 815 |       "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
 816 |       "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=",
 817 |       "requires": {
 818 |         "lodash._createset": "~4.0.0",
 819 |         "lodash._root": "~3.0.0"
 820 |       }
 821 |     },
 822 |     "lodash._createset": {
 823 |       "version": "4.0.3",
 824 |       "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
 825 |       "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY="
 826 |     },
 827 |     "lodash._root": {
 828 |       "version": "3.0.1",
 829 |       "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
 830 |       "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI="
 831 |     },
 832 |     "lodash._stringtopath": {
 833 |       "version": "4.8.0",
 834 |       "resolved": "https://registry.npmjs.org/lodash._stringtopath/-/lodash._stringtopath-4.8.0.tgz",
 835 |       "integrity": "sha1-lBvPDmQmbl/B1m/tCmlZVExXaCQ=",
 836 |       "requires": {
 837 |         "lodash._basetostring": "~4.12.0"
 838 |       }
 839 |     },
 840 |     "lodash.uniqby": {
 841 |       "version": "4.5.0",
 842 |       "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.5.0.tgz",
 843 |       "integrity": "sha1-o6F7v2LutiQPSRhG6XwcTipeHiE=",
 844 |       "requires": {
 845 |         "lodash._baseiteratee": "~4.7.0",
 846 |         "lodash._baseuniq": "~4.6.0"
 847 |       }
 848 |     },
 849 |     "lru-cache": {
 850 |       "version": "6.0.0",
 851 |       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
 852 |       "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
 853 |       "dev": true,
 854 |       "requires": {
 855 |         "yallist": "^4.0.0"
 856 |       }
 857 |     },
 858 |     "merge2": {
 859 |       "version": "1.4.1",
 860 |       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 861 |       "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
 862 |       "dev": true
 863 |     },
 864 |     "micromatch": {
 865 |       "version": "4.0.4",
 866 |       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
 867 |       "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
 868 |       "dev": true,
 869 |       "requires": {
 870 |         "braces": "^3.0.1",
 871 |         "picomatch": "^2.2.3"
 872 |       }
 873 |     },
 874 |     "mimic-response": {
 875 |       "version": "2.1.0",
 876 |       "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
 877 |       "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
 878 |       "dev": true
 879 |     },
 880 |     "minimist": {
 881 |       "version": "1.2.5",
 882 |       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
 883 |       "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
 884 |       "dev": true
 885 |     },
 886 |     "mkdirp-classic": {
 887 |       "version": "0.5.3",
 888 |       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
 889 |       "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
 890 |       "dev": true
 891 |     },
 892 |     "ms": {
 893 |       "version": "2.1.3",
 894 |       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
 895 |       "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
 896 |     },
 897 |     "multistream": {
 898 |       "version": "4.1.0",
 899 |       "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz",
 900 |       "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==",
 901 |       "dev": true,
 902 |       "requires": {
 903 |         "once": "^1.4.0",
 904 |         "readable-stream": "^3.6.0"
 905 |       },
 906 |       "dependencies": {
 907 |         "readable-stream": {
 908 |           "version": "3.6.0",
 909 |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
 910 |           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
 911 |           "dev": true,
 912 |           "requires": {
 913 |             "inherits": "^2.0.3",
 914 |             "string_decoder": "^1.1.1",
 915 |             "util-deprecate": "^1.0.1"
 916 |           }
 917 |         }
 918 |       }
 919 |     },
 920 |     "nanoclone": {
 921 |       "version": "0.2.1",
 922 |       "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
 923 |       "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
 924 |     },
 925 |     "napi-build-utils": {
 926 |       "version": "1.0.2",
 927 |       "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
 928 |       "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
 929 |       "dev": true
 930 |     },
 931 |     "node-abi": {
 932 |       "version": "2.30.0",
 933 |       "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz",
 934 |       "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==",
 935 |       "dev": true,
 936 |       "requires": {
 937 |         "semver": "^5.4.1"
 938 |       },
 939 |       "dependencies": {
 940 |         "semver": {
 941 |           "version": "5.7.1",
 942 |           "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
 943 |           "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
 944 |           "dev": true
 945 |         }
 946 |       }
 947 |     },
 948 |     "node-fetch": {
 949 |       "version": "2.6.1",
 950 |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
 951 |       "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
 952 |       "dev": true
 953 |     },
 954 |     "noop-logger": {
 955 |       "version": "0.1.1",
 956 |       "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
 957 |       "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
 958 |       "dev": true
 959 |     },
 960 |     "npmlog": {
 961 |       "version": "4.1.2",
 962 |       "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
 963 |       "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
 964 |       "dev": true,
 965 |       "requires": {
 966 |         "are-we-there-yet": "~1.1.2",
 967 |         "console-control-strings": "~1.1.0",
 968 |         "gauge": "~2.7.3",
 969 |         "set-blocking": "~2.0.0"
 970 |       }
 971 |     },
 972 |     "number-is-nan": {
 973 |       "version": "1.0.1",
 974 |       "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
 975 |       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
 976 |       "dev": true
 977 |     },
 978 |     "numbered": {
 979 |       "version": "1.1.0",
 980 |       "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz",
 981 |       "integrity": "sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g=="
 982 |     },
 983 |     "object-assign": {
 984 |       "version": "4.1.1",
 985 |       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
 986 |       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
 987 |       "dev": true
 988 |     },
 989 |     "once": {
 990 |       "version": "1.4.0",
 991 |       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 992 |       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
 993 |       "dev": true,
 994 |       "requires": {
 995 |         "wrappy": "1"
 996 |       }
 997 |     },
 998 |     "one-time": {
 999 |       "version": "0.0.4",
1000 |       "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
1001 |       "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
1002 |     },
1003 |     "optionator": {
1004 |       "version": "0.8.3",
1005 |       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
1006 |       "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
1007 |       "dev": true,
1008 |       "requires": {
1009 |         "deep-is": "~0.1.3",
1010 |         "fast-levenshtein": "~2.0.6",
1011 |         "levn": "~0.3.0",
1012 |         "prelude-ls": "~1.1.2",
1013 |         "type-check": "~0.3.2",
1014 |         "word-wrap": "~1.2.3"
1015 |       }
1016 |     },
1017 |     "p-finally": {
1018 |       "version": "1.0.0",
1019 |       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
1020 |       "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
1021 |     },
1022 |     "p-is-promise": {
1023 |       "version": "3.0.0",
1024 |       "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
1025 |       "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==",
1026 |       "dev": true
1027 |     },
1028 |     "p-timeout": {
1029 |       "version": "3.2.0",
1030 |       "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
1031 |       "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
1032 |       "requires": {
1033 |         "p-finally": "^1.0.0"
1034 |       }
1035 |     },
1036 |     "p-wait-for": {
1037 |       "version": "3.1.0",
1038 |       "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.1.0.tgz",
1039 |       "integrity": "sha512-0Uy19uhxbssHelu9ynDMcON6BmMk6pH8551CvxROhiz3Vx+yC4RqxjyIDk2V4ll0g9177RKT++PK4zcV58uJ7A==",
1040 |       "requires": {
1041 |         "p-timeout": "^3.0.0"
1042 |       }
1043 |     },
1044 |     "path-parse": {
1045 |       "version": "1.0.7",
1046 |       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1047 |       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1048 |       "dev": true
1049 |     },
1050 |     "path-type": {
1051 |       "version": "4.0.0",
1052 |       "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
1053 |       "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
1054 |       "dev": true
1055 |     },
1056 |     "picomatch": {
1057 |       "version": "2.3.0",
1058 |       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
1059 |       "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
1060 |       "dev": true
1061 |     },
1062 |     "pkg": {
1063 |       "version": "5.3.1",
1064 |       "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.3.1.tgz",
1065 |       "integrity": "sha512-jT/sptM1ZG++FNk+jnJYNoWLDQXYd7hqpnBhd5j18SNW1jJzNYo55RahuCiD0KN0PX9mb53GWCqKM0ia/mJytA==",
1066 |       "dev": true,
1067 |       "requires": {
1068 |         "@babel/parser": "7.13.13",
1069 |         "@babel/types": "7.13.12",
1070 |         "chalk": "^4.1.0",
1071 |         "escodegen": "^2.0.0",
1072 |         "fs-extra": "^9.1.0",
1073 |         "globby": "^11.0.3",
1074 |         "into-stream": "^6.0.0",
1075 |         "minimist": "^1.2.5",
1076 |         "multistream": "^4.1.0",
1077 |         "pkg-fetch": "3.2.2",
1078 |         "prebuild-install": "6.0.1",
1079 |         "progress": "^2.0.3",
1080 |         "resolve": "^1.20.0",
1081 |         "stream-meter": "^1.0.4",
1082 |         "tslib": "2.1.0"
1083 |       }
1084 |     },
1085 |     "pkg-fetch": {
1086 |       "version": "3.2.2",
1087 |       "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.2.2.tgz",
1088 |       "integrity": "sha512-bLhFNT4cNnONxzbHo1H2mCCKuQkCR4dgQtv0gUZnWtp8TDP0v0UAXKHG7DXhAoTC5IYP3slLsFJtIda9ksny8g==",
1089 |       "dev": true,
1090 |       "requires": {
1091 |         "chalk": "^4.1.0",
1092 |         "fs-extra": "^9.1.0",
1093 |         "https-proxy-agent": "^5.0.0",
1094 |         "node-fetch": "^2.6.1",
1095 |         "progress": "^2.0.3",
1096 |         "semver": "^7.3.5",
1097 |         "yargs": "^16.2.0"
1098 |       }
1099 |     },
1100 |     "prebuild-install": {
1101 |       "version": "6.0.1",
1102 |       "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz",
1103 |       "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==",
1104 |       "dev": true,
1105 |       "requires": {
1106 |         "detect-libc": "^1.0.3",
1107 |         "expand-template": "^2.0.3",
1108 |         "github-from-package": "0.0.0",
1109 |         "minimist": "^1.2.3",
1110 |         "mkdirp-classic": "^0.5.3",
1111 |         "napi-build-utils": "^1.0.1",
1112 |         "node-abi": "^2.7.0",
1113 |         "noop-logger": "^0.1.1",
1114 |         "npmlog": "^4.0.1",
1115 |         "pump": "^3.0.0",
1116 |         "rc": "^1.2.7",
1117 |         "simple-get": "^3.0.3",
1118 |         "tar-fs": "^2.0.0",
1119 |         "tunnel-agent": "^0.6.0",
1120 |         "which-pm-runs": "^1.0.0"
1121 |       }
1122 |     },
1123 |     "prelude-ls": {
1124 |       "version": "1.1.2",
1125 |       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
1126 |       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
1127 |       "dev": true
1128 |     },
1129 |     "prettier": {
1130 |       "version": "2.3.2",
1131 |       "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
1132 |       "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
1133 |       "dev": true
1134 |     },
1135 |     "process-nextick-args": {
1136 |       "version": "2.0.1",
1137 |       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1138 |       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
1139 |       "dev": true
1140 |     },
1141 |     "progress": {
1142 |       "version": "2.0.3",
1143 |       "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
1144 |       "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
1145 |       "dev": true
1146 |     },
1147 |     "property-expr": {
1148 |       "version": "2.0.4",
1149 |       "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz",
1150 |       "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg=="
1151 |     },
1152 |     "pump": {
1153 |       "version": "3.0.0",
1154 |       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
1155 |       "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
1156 |       "dev": true,
1157 |       "requires": {
1158 |         "end-of-stream": "^1.1.0",
1159 |         "once": "^1.3.1"
1160 |       }
1161 |     },
1162 |     "queue-microtask": {
1163 |       "version": "1.2.3",
1164 |       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
1165 |       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
1166 |       "dev": true
1167 |     },
1168 |     "rc": {
1169 |       "version": "1.2.8",
1170 |       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
1171 |       "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
1172 |       "dev": true,
1173 |       "requires": {
1174 |         "deep-extend": "^0.6.0",
1175 |         "ini": "~1.3.0",
1176 |         "minimist": "^1.2.0",
1177 |         "strip-json-comments": "~2.0.1"
1178 |       }
1179 |     },
1180 |     "readable-stream": {
1181 |       "version": "2.3.7",
1182 |       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
1183 |       "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
1184 |       "dev": true,
1185 |       "requires": {
1186 |         "core-util-is": "~1.0.0",
1187 |         "inherits": "~2.0.3",
1188 |         "isarray": "~1.0.0",
1189 |         "process-nextick-args": "~2.0.0",
1190 |         "safe-buffer": "~5.1.1",
1191 |         "string_decoder": "~1.1.1",
1192 |         "util-deprecate": "~1.0.1"
1193 |       }
1194 |     },
1195 |     "readline-sync": {
1196 |       "version": "1.4.10",
1197 |       "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
1198 |       "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw=="
1199 |     },
1200 |     "regenerator-runtime": {
1201 |       "version": "0.13.9",
1202 |       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
1203 |       "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
1204 |     },
1205 |     "require-directory": {
1206 |       "version": "2.1.1",
1207 |       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1208 |       "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
1209 |       "dev": true
1210 |     },
1211 |     "resolve": {
1212 |       "version": "1.20.0",
1213 |       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
1214 |       "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
1215 |       "dev": true,
1216 |       "requires": {
1217 |         "is-core-module": "^2.2.0",
1218 |         "path-parse": "^1.0.6"
1219 |       }
1220 |     },
1221 |     "reusify": {
1222 |       "version": "1.0.4",
1223 |       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1224 |       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1225 |       "dev": true
1226 |     },
1227 |     "run-parallel": {
1228 |       "version": "1.2.0",
1229 |       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1230 |       "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1231 |       "dev": true,
1232 |       "requires": {
1233 |         "queue-microtask": "^1.2.2"
1234 |       }
1235 |     },
1236 |     "safe-buffer": {
1237 |       "version": "5.1.2",
1238 |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1239 |       "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1240 |       "dev": true
1241 |     },
1242 |     "safe-timers": {
1243 |       "version": "1.1.0",
1244 |       "resolved": "https://registry.npmjs.org/safe-timers/-/safe-timers-1.1.0.tgz",
1245 |       "integrity": "sha1-xYroMl2407BnMi8KTvOgytZ6rYM="
1246 |     },
1247 |     "say": {
1248 |       "version": "0.16.0",
1249 |       "resolved": "https://registry.npmjs.org/say/-/say-0.16.0.tgz",
1250 |       "integrity": "sha512-yEfncNu3I6lcZ6RIrXgE9DqbrEmvV5uQQ8ReM14u/DodlvJYpveqNphO55RLMSj77b06ZKNif/FLmhzQxcuUXg==",
1251 |       "requires": {
1252 |         "one-time": "0.0.4"
1253 |       }
1254 |     },
1255 |     "semver": {
1256 |       "version": "7.3.5",
1257 |       "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
1258 |       "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
1259 |       "dev": true,
1260 |       "requires": {
1261 |         "lru-cache": "^6.0.0"
1262 |       }
1263 |     },
1264 |     "set-blocking": {
1265 |       "version": "2.0.0",
1266 |       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
1267 |       "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
1268 |       "dev": true
1269 |     },
1270 |     "signal-exit": {
1271 |       "version": "3.0.3",
1272 |       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
1273 |       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
1274 |       "dev": true
1275 |     },
1276 |     "simple-concat": {
1277 |       "version": "1.0.1",
1278 |       "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
1279 |       "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
1280 |       "dev": true
1281 |     },
1282 |     "simple-get": {
1283 |       "version": "3.1.0",
1284 |       "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
1285 |       "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
1286 |       "dev": true,
1287 |       "requires": {
1288 |         "decompress-response": "^4.2.0",
1289 |         "once": "^1.3.1",
1290 |         "simple-concat": "^1.0.0"
1291 |       }
1292 |     },
1293 |     "slash": {
1294 |       "version": "3.0.0",
1295 |       "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
1296 |       "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
1297 |       "dev": true
1298 |     },
1299 |     "source-map": {
1300 |       "version": "0.6.1",
1301 |       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1302 |       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1303 |       "dev": true,
1304 |       "optional": true
1305 |     },
1306 |     "stream-meter": {
1307 |       "version": "1.0.4",
1308 |       "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz",
1309 |       "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=",
1310 |       "dev": true,
1311 |       "requires": {
1312 |         "readable-stream": "^2.1.4"
1313 |       }
1314 |     },
1315 |     "string-width": {
1316 |       "version": "4.2.2",
1317 |       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
1318 |       "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
1319 |       "dev": true,
1320 |       "requires": {
1321 |         "emoji-regex": "^8.0.0",
1322 |         "is-fullwidth-code-point": "^3.0.0",
1323 |         "strip-ansi": "^6.0.0"
1324 |       }
1325 |     },
1326 |     "string_decoder": {
1327 |       "version": "1.1.1",
1328 |       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1329 |       "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1330 |       "dev": true,
1331 |       "requires": {
1332 |         "safe-buffer": "~5.1.0"
1333 |       }
1334 |     },
1335 |     "strip-ansi": {
1336 |       "version": "6.0.0",
1337 |       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
1338 |       "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
1339 |       "dev": true,
1340 |       "requires": {
1341 |         "ansi-regex": "^5.0.0"
1342 |       }
1343 |     },
1344 |     "strip-json-comments": {
1345 |       "version": "2.0.1",
1346 |       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
1347 |       "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
1348 |       "dev": true
1349 |     },
1350 |     "supports-color": {
1351 |       "version": "7.2.0",
1352 |       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1353 |       "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1354 |       "dev": true,
1355 |       "requires": {
1356 |         "has-flag": "^4.0.0"
1357 |       }
1358 |     },
1359 |     "tar-fs": {
1360 |       "version": "2.1.1",
1361 |       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
1362 |       "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
1363 |       "dev": true,
1364 |       "requires": {
1365 |         "chownr": "^1.1.1",
1366 |         "mkdirp-classic": "^0.5.2",
1367 |         "pump": "^3.0.0",
1368 |         "tar-stream": "^2.1.4"
1369 |       }
1370 |     },
1371 |     "tar-stream": {
1372 |       "version": "2.2.0",
1373 |       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
1374 |       "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
1375 |       "dev": true,
1376 |       "requires": {
1377 |         "bl": "^4.0.3",
1378 |         "end-of-stream": "^1.4.1",
1379 |         "fs-constants": "^1.0.0",
1380 |         "inherits": "^2.0.3",
1381 |         "readable-stream": "^3.1.1"
1382 |       },
1383 |       "dependencies": {
1384 |         "readable-stream": {
1385 |           "version": "3.6.0",
1386 |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1387 |           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1388 |           "dev": true,
1389 |           "requires": {
1390 |             "inherits": "^2.0.3",
1391 |             "string_decoder": "^1.1.1",
1392 |             "util-deprecate": "^1.0.1"
1393 |           }
1394 |         }
1395 |       }
1396 |     },
1397 |     "to-fast-properties": {
1398 |       "version": "2.0.0",
1399 |       "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
1400 |       "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
1401 |       "dev": true
1402 |     },
1403 |     "to-regex-range": {
1404 |       "version": "5.0.1",
1405 |       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1406 |       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1407 |       "dev": true,
1408 |       "requires": {
1409 |         "is-number": "^7.0.0"
1410 |       }
1411 |     },
1412 |     "toposort": {
1413 |       "version": "2.0.2",
1414 |       "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
1415 |       "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
1416 |     },
1417 |     "tslib": {
1418 |       "version": "2.1.0",
1419 |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
1420 |       "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==",
1421 |       "dev": true
1422 |     },
1423 |     "tunnel-agent": {
1424 |       "version": "0.6.0",
1425 |       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1426 |       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1427 |       "dev": true,
1428 |       "requires": {
1429 |         "safe-buffer": "^5.0.1"
1430 |       }
1431 |     },
1432 |     "type-check": {
1433 |       "version": "0.3.2",
1434 |       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1435 |       "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1436 |       "dev": true,
1437 |       "requires": {
1438 |         "prelude-ls": "~1.1.2"
1439 |       }
1440 |     },
1441 |     "universalify": {
1442 |       "version": "2.0.0",
1443 |       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
1444 |       "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
1445 |       "dev": true
1446 |     },
1447 |     "util-deprecate": {
1448 |       "version": "1.0.2",
1449 |       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1450 |       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
1451 |       "dev": true
1452 |     },
1453 |     "which": {
1454 |       "version": "2.0.2",
1455 |       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1456 |       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1457 |       "requires": {
1458 |         "isexe": "^2.0.0"
1459 |       }
1460 |     },
1461 |     "which-pm-runs": {
1462 |       "version": "1.0.0",
1463 |       "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
1464 |       "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
1465 |       "dev": true
1466 |     },
1467 |     "wide-align": {
1468 |       "version": "1.1.3",
1469 |       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
1470 |       "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
1471 |       "dev": true,
1472 |       "requires": {
1473 |         "string-width": "^1.0.2 || 2"
1474 |       },
1475 |       "dependencies": {
1476 |         "ansi-regex": {
1477 |           "version": "3.0.0",
1478 |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1479 |           "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
1480 |           "dev": true
1481 |         },
1482 |         "is-fullwidth-code-point": {
1483 |           "version": "2.0.0",
1484 |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1485 |           "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
1486 |           "dev": true
1487 |         },
1488 |         "string-width": {
1489 |           "version": "2.1.1",
1490 |           "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
1491 |           "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
1492 |           "dev": true,
1493 |           "requires": {
1494 |             "is-fullwidth-code-point": "^2.0.0",
1495 |             "strip-ansi": "^4.0.0"
1496 |           }
1497 |         },
1498 |         "strip-ansi": {
1499 |           "version": "4.0.0",
1500 |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1501 |           "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1502 |           "dev": true,
1503 |           "requires": {
1504 |             "ansi-regex": "^3.0.0"
1505 |           }
1506 |         }
1507 |       }
1508 |     },
1509 |     "word-wrap": {
1510 |       "version": "1.2.3",
1511 |       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
1512 |       "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
1513 |       "dev": true
1514 |     },
1515 |     "wrap-ansi": {
1516 |       "version": "7.0.0",
1517 |       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1518 |       "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1519 |       "dev": true,
1520 |       "requires": {
1521 |         "ansi-styles": "^4.0.0",
1522 |         "string-width": "^4.1.0",
1523 |         "strip-ansi": "^6.0.0"
1524 |       }
1525 |     },
1526 |     "wrappy": {
1527 |       "version": "1.0.2",
1528 |       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1529 |       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1530 |       "dev": true
1531 |     },
1532 |     "y18n": {
1533 |       "version": "5.0.8",
1534 |       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1535 |       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1536 |       "dev": true
1537 |     },
1538 |     "yallist": {
1539 |       "version": "4.0.0",
1540 |       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1541 |       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
1542 |       "dev": true
1543 |     },
1544 |     "yargs": {
1545 |       "version": "16.2.0",
1546 |       "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
1547 |       "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
1548 |       "dev": true,
1549 |       "requires": {
1550 |         "cliui": "^7.0.2",
1551 |         "escalade": "^3.1.1",
1552 |         "get-caller-file": "^2.0.5",
1553 |         "require-directory": "^2.1.1",
1554 |         "string-width": "^4.2.0",
1555 |         "y18n": "^5.0.5",
1556 |         "yargs-parser": "^20.2.2"
1557 |       }
1558 |     },
1559 |     "yargs-parser": {
1560 |       "version": "20.2.9",
1561 |       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
1562 |       "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
1563 |       "dev": true
1564 |     },
1565 |     "yup": {
1566 |       "version": "0.32.9",
1567 |       "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.9.tgz",
1568 |       "integrity": "sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg==",
1569 |       "requires": {
1570 |         "@babel/runtime": "^7.10.5",
1571 |         "@types/lodash": "^4.14.165",
1572 |         "lodash": "^4.17.20",
1573 |         "lodash-es": "^4.17.15",
1574 |         "nanoclone": "^0.2.1",
1575 |         "property-expr": "^2.0.4",
1576 |         "toposort": "^2.0.2"
1577 |       }
1578 |     }
1579 |   }
1580 | }
1581 | 
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "@ariya/berkala",
 3 |   "version": "1.3.0",
 4 |   "description": "Run scheduled tasks",
 5 |   "main": "index.js",
 6 |   "bin": {
 7 |     "berkala": "./index.js"
 8 |   },
 9 |   "scripts": {
10 |     "start": "node index.js",
11 |     "test": "npm run check-format",
12 |     "check-format": "prettier --check \"**/*.js\"",
13 |     "format-code": "prettier --write \"**/*.js\"",
14 |     "cli-tests": "npx bats tests/cli.bats",
15 |     "build": "pkg --compress brotli ."
16 |   },
17 |   "author": "Ariya Hidayat",
18 |   "license": "MIT",
19 |   "repository": {
20 |     "type": "git",
21 |     "url": "https://github.com/ariya/berkala.git"
22 |   },
23 |   "keywords": [
24 |     "scheduler",
25 |     "tasks",
26 |     "cron",
27 |     "cronjob"
28 |   ],
29 |   "engines": {
30 |     "node": ">=14.0.0"
31 |   },
32 |   "dependencies": {
33 |     "bree": "~6.2.1",
34 |     "js-yaml": "~4.1.0",
35 |     "readline-sync": "~1.4.10",
36 |     "say": "~0.16.0",
37 |     "which": "~2.0.2"
38 |   },
39 |   "devDependencies": {
40 |     "bats": "~1.4.1",
41 |     "bats-assert": "~2.0.0",
42 |     "bats-support": "~0.3.0",
43 |     "pkg": "~5.3.1",
44 |     "prettier": "~2.3.2"
45 |   },
46 |   "pkg": {
47 |     "outputPath": "dist"
48 |   },
49 |   "prettier": {
50 |     "tabWidth": 4,
51 |     "printWidth": 120,
52 |     "quoteProps": "consistent",
53 |     "singleQuote": true,
54 |     "trailingComma": "none"
55 |   },
56 |   "volta": {
57 |     "node": "14.18.2"
58 |   }
59 | }
60 | 
--------------------------------------------------------------------------------
/src/pal.js:
--------------------------------------------------------------------------------
 1 | /** PAL - Platform Abstraction Layer */
 2 | const os = require('os');
 3 | const child_process = require('child_process');
 4 | 
 5 | const which = require('which');
 6 | const say = require('say');
 7 | 
 8 | /**
 9 |  * Escape a string for PowerShell.
10 |  * @param {string} str
11 |  * @return {string}
12 |  */
13 | function psEscape(str) {
14 |     let result = '';
15 |     for (let i = 0; i < str.length; i++) {
16 |         const ch = str[i];
17 |         if (ch.charCodeAt(0) === 39) {
18 |             // single quote, escape it with another single quote
19 |             result += ch;
20 |         }
21 |         result += ch;
22 |     }
23 |     return result;
24 | }
25 | 
26 | /**
27 |  * Send a desktop notification
28 |  * @param {string} title
29 |  * @param {string} message
30 |  */
31 | function platformNotify(title, message) {
32 |     if (os.type() === 'Linux') {
33 |         const resolved = which.sync('notify-send', { nothrow: true });
34 |         if (resolved) {
35 |             child_process.spawnSync('notify-send', ['-a', 'Berkala', title, message]);
36 |         } else {
37 |             console.error('notify: unable to locate notify-send');
38 |             console.log(title + ':', message);
39 |         }
40 |     } else if (os.type() === 'Darwin') {
41 |         const command = `display notification "${message}" with title "Berkala" subtitle "${title}"`;
42 |         child_process.spawnSync('osascript', ['-e', command]);
43 |     } else if (os.type() === 'Windows_NT') {
44 |         const script = `
45 |             [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null;
46 |             $templateType = [Windows.UI.Notifications.ToastTemplateType]::ToastText02;
47 |             $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($templateType);
48 |             $template.SelectSingleNode(\"//text[@id=1]\").InnerText = '${psEscape(title)}';
49 |             $template.SelectSingleNode(\"//text[@id=2]\").InnerText = '${psEscape(message)}';
50 |             $toast = [Windows.UI.Notifications.ToastNotification]::new($template);
51 |             $notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Berkala');
52 |             $notifier.Show($toast);`;
53 | 
54 |         child_process.execSync(script, { shell: 'powershell.exe' });
55 |     } else {
56 |         // FIXME what's this system?
57 |         console.log(title, message);
58 |     }
59 | }
60 | 
61 | /**
62 |  * Convert text to audible speech
63 |  * @param {string} message
64 |  */
65 | function platformSay(message) {
66 |     if (os.type() === 'Linux') {
67 |         const resolved = which.sync('festival', { nothrow: true });
68 |         if (resolved) {
69 |             say.speak(message);
70 |         } else {
71 |             console.error('say: unable to locate Festival');
72 |             platformNotify('Berkala', message);
73 |         }
74 |     } else if (os.type() === 'Windows_NT') {
75 |         // TODO: check for Powershell first
76 |         say.speak(psEscape(message));
77 |     } else if (os.type() === 'Darwin') {
78 |         say.speak(message, 'Samantha'); // Siri's voice
79 |     } else {
80 |         // unsupported
81 |         console.error('say: unsupport system', os.type());
82 |         platformNotify('Berkala', message);
83 |     }
84 | }
85 | 
86 | module.exports = {
87 |     notify: platformNotify,
88 |     say: platformSay
89 | };
90 | 
--------------------------------------------------------------------------------
/tests/cli.bats:
--------------------------------------------------------------------------------
 1 | setup() {
 2 |     load './node_modules/bats-support/load.bash'
 3 |     load './node_modules/bats-assert/load.bash'
 4 | }
 5 | 
 6 | teardown() {
 7 |     rm -rf berkala.yml
 8 | }
 9 | 
10 | @test "can run with an empty config" {
11 |     rm -rf berkala.yml
12 |     touch berkala.yml
13 |     run ./dist/berkala
14 |     assert_success
15 |     assert_output --partial 'Berkala 1.3'
16 | }
17 | 
18 | @test "will not create a config file automatically in non-interactive tty" {
19 |     rm -rf berkala.yml
20 |     run export CI=true
21 |     run ./dist/berkala
22 |     assert_failure 255
23 | }
24 | 
25 | @test "must run a command" {
26 |     rm -rf ./must_exist.txt ./first-file.txt ./second-file.txt
27 |     cp tests/test-run.yml berkala.yml
28 |     run ./dist/berkala
29 |     run cat ./must_exist.txt
30 |     run cat ./first_file.txt
31 |     run cat ./second_file.txt
32 |     assert_success
33 | }
34 | 
35 | @test "must support timeout" {
36 |     rm -rf ./must_exist.txt ./must_not_exist.txt
37 |     cp tests/test-timeout.yml berkala.yml
38 |     run ./dist/berkala
39 |     run cat ./must_exist.txt
40 |     assert_success
41 |     run cat ./must_not_exist.txt
42 |     assert_failure
43 | }
44 | 
--------------------------------------------------------------------------------
/tests/test-run.yml:
--------------------------------------------------------------------------------
 1 | tasks:
 2 |   boot:
 3 |     steps:
 4 |     - run: touch must_exist.txt
 5 | 
 6 |   another-boot:
 7 |     steps:
 8 |     - run: |
 9 |         touch first_file.txt
10 |         echo "Hi" > second_file.txt
11 | 
--------------------------------------------------------------------------------
/tests/test-timeout.yml:
--------------------------------------------------------------------------------
1 | tasks:
2 |   boot:
3 |     steps:
4 |     - run: |
5 |         touch must_exist.txt
6 |         sleep 7
7 |         touch must_not_exist.txt
8 |       timeout-minutes: 0.01
9 | 
--------------------------------------------------------------------------------