The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .github
    └── ISSUE_TEMPLATE.md
├── .gitignore
├── LICENSE
├── README.md
├── ansiart.js
├── arts.js
├── care.js
├── config.js
├── gitbot.js
├── package-lock.json
├── package.json
├── pomodoro.js
├── sample.env
└── twitterbot.js


/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
 1 | Please include the template below to ensure a more accurate response to your issue.
 2 | 
 3 | - **Node Version**: `node --version`
 4 | - **tiny-core-terminal version**: `npm info tiny-care-terminal | grep version:`
 5 | - **Shell**: `bash, zsh, fish, something else?`
 6 | - **Terminal Program**: `tmux, iterm, terminator, cmd, something else?`
 7 | - **Operating System**: `Mac, Windows, Linux, BSD, Really, something else?`
 8 | 
 9 | Thank you!
10 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | .DS_Store
3 | node_modules
4 | *.sh
5 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | MIT License
 2 | 
 3 | Copyright (c) 2017 Monica Dinculescu
 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 | # tiny-care-terminal
  2 | 
  3 | This is a little dashboard that tries to take care of you when you're using your terminal. It tells you cute, self care things, and tries not to stress you out. It shows:
  4 | 
  5 | - the last tweets from [@tinycarebot](https://twitter.com/tinycarebot), [@selfcare_bot](https://twitter.com/selfcare_bot) and [@magicrealismbot](https://twitter.com/magicrealismbot). The first two tend to tweet reminders about taking breaks, drinking water and looking outside, and the latter tells you strange, whimsical stories. If you don't like these bots, they're configurable!
  6 | - your `git` commits from today and the last 7 days. When I get stressed out because I think I haven't done anything, it turns out that I only think about big and serious commits, and forget about all the tiny amounts of work I've actually done throughout. Hopefully this will help you too <3
  7 | - the weather, because you might get rained on.
  8 | 
  9 | It looks like this, and updates every 20 minutes.
 10 | 
 11 | ![tiny terminal care screenshot](https://cloud.githubusercontent.com/assets/1369170/25066240/adc3b1ac-21d5-11e7-9811-508b6bcfcc89.png)
 12 | 
 13 | ## Make it go
 14 | 
 15 | ### 1\. Installation
 16 | 
 17 | ***Sadly only node.js v10.x is supported at the moment.***
 18 | 
 19 | ```sh
 20 | npm install -g tiny-care-terminal
 21 | ```
 22 | 
 23 | (`yarn` also works fine.)
 24 | 
 25 | ### 2\. Setting the environment variables
 26 | 
 27 | After installing the npm package, you need to set up the configuration in your Terminal.
 28 | 
 29 | Every OS and shell is different so I probably won't hit all of them, but the bottom line is that you should copy those environment variables wherever the rest of your system's variables live. For example,
 30 | 
 31 | - if you're using `zsh`, that's probably in your home directory's `.zshrc` file
 32 | - if you're using `bash`, that could be your `bash_profile` file
 33 | - if you're using `fish`, use `set -gx key value` in your `~/.config/fish/config.fish` file
 34 | 
 35 | Note that the `export` bit is pretty key, to make sure that they are globally available. To check that the variables have been set correctly, you can print them in the terminal -- for example, `echo $TTC_WEATHER`.
 36 | 
 37 | #### Configure the dashboard
 38 | 
 39 | All the settings the dashboard looks at are in the sample file `sample.env`. This file isn't used by the dashboard, it just lists the environment variables that you can copy in your `rc` files:
 40 | 
 41 | - `TTC_BOTS` are the 3 twitter bots to check, comma separated. The first entry in this list will be displayed in the big party parrot box.
 42 | - `TTC_SAY_BOX` defines the ASCII-Art to show. e.g. `parrot` | `bunny` | `llama` | `cat` | `yeoman` | `mario` | `ironman.ansi` | `stegosaurus.cow` See section below for all the different options.
 43 | - `TTC_REPOS`, a comma separated list of repos to look at for `git` commits.
 44 | - `TTC_REPOS_DEPTH` is the max directory-depth to look for git repositories in the directories defined with `TTC_REPOS` (by default 1). Note that the deeper the directory depth, the slower the results will be fetched. Seeing your commits in `tiny-terminal-care`, set this to `gitlog`
 45 | - `TTC_WEATHER`, the location to check the weather for. A zipcode doesn't always work, so if you can, use a location first (so prefer `Paris` over `90210`)
 46 | - `TTC_CELSIUS` (by default true)
 47 | - `TTC_APIKEYS` -- set this to false if you don't want to use Twitter API keys and want to scrape the tweets instead.
 48 | - `TTC_UPDATE_INTERVAL`, set this to change the update frequency in minutes, default is 20 minutes.
 49 | - `TTC_TERMINAL_TITLE` -- set this to false if you don't want the terminal title to be changed on startup.
 50 | 
 51 | ##### Configure the Say-box
 52 | 
 53 | There are almost endless variation of ASCII art images supported. You can select an existing image from the [cowsay library](https://github.com/piuccio/cowsay/tree/master/cows) just by defining a filename ending with ".cow". So e.g. `vader.cow` or `bunny.cow` would be two possible options. Also the [ansi-art](https://github.com/gauravchl/ansi-art) library is supported. In addition to the [existing](https://github.com/gauravchl/ansi-art/tree/master/src/arts) colorful images you can create your own image by using the [webapp](https://gauravchl.github.io/ansi-art/webapp/) and download the result. After downloading the ANSI-File you can just supply its absolute path to render it within the box. (eg: `TTC_SAY_BOX='/Users/om/desktop/cat.ansi'`). If you want the art to be selected by random use the magic word `RANDOM`.
 54 | 
 55 | In addition to this libraries the following types are supported: `bunny`, `llama`, `cat`, `yeoman`
 56 | 
 57 | #### Set up Twitter API keys
 58 | 
 59 | The dashboard has two alternatives for reading tweets: using your API keys or scraping. API keys is preferred (because lol scraping), but if you're really not into that, then skip the next section and read the bit about setting `TTC_APIKEYS`
 60 | 
 61 | You need [Twitter API keys](https://apps.twitter.com/) for the tweets to work. It should be pretty easy to create a new app, and get these 4 values. After you've set them up, set these env variables (see the [`sample.env`](sample.env) for an example):
 62 | 
 63 | ```sh
 64 | TTC_CONSUMER_KEY='...'
 65 | TTC_CONSUMER_SECRET='...'
 66 | TTC_ACCESS_TOKEN='...'
 67 | TTC_ACCESS_TOKEN_SECRET='...'
 68 | ```
 69 | 
 70 | ## 3\. Start
 71 | 
 72 | ```sh
 73 | tiny-care-terminal
 74 | ```
 75 | 
 76 | You can exit the dashboard by pressing `esc` or `q`. You can refresh it manually by pressing `r`.
 77 | 
 78 | ## 🍅 Pomodoro Mode
 79 | 
 80 | You can press `p` to switch parrot box to pomodoro mode.
 81 | 
 82 | Other commands while in pomodoro mode:
 83 | 
 84 | ```sh
 85 | s - start/pause/resume pomodoro
 86 | e - stop pomodoro
 87 | u - update pomodoro duration
 88 | b - update break time
 89 | ```
 90 | 
 91 | To change default pomodoro and break durations set following variables in minutes (these should be numbers):
 92 | 
 93 | ```sh
 94 | TTC_POMODORO=...
 95 | TTC_BREAK=...
 96 | ```
 97 | 
 98 | ## 🆘 Halp I don't see my commits
 99 | 
100 | - did you forget to export your `TTC_REPOS` environment variable? Open a new tab, and type `echo $TTC_REPOS` to make sure it's not empty. Note that spaces inside the repo names are not supported right now 😥
101 | - also there seem to be problems sometimes if the paths you're using are not fully qualified -- that is, use `/Users/notwaldorf/Code` rather than `~/Code` and see if that helps.
102 | - did you use `yarn`? I know `yarn` is cool, and I've seen it work with this, but can you double check that it still doesn't work with a basic `npm` installation instead?
103 | 
104 |   **Take care of yourself, ok? 💖**
105 | 


--------------------------------------------------------------------------------
/ansiart.js:
--------------------------------------------------------------------------------
 1 | var path = require('path');
 2 | var ansiArt = require('ansi-art').default;
 3 | var cowsay = require('cowsay');
 4 | var getCustomArt = require('./arts');
 5 | 
 6 | function getAnsiArt(art, textToSay) {
 7 |   
 8 |   if (art && (art.toUpperCase() === 'RANDOM')) {
 9 |     // show a random art
10 |     var rand = Math.random() * 100;
11 |     if (rand >= 50) { // 50%
12 |       return cowsay.say({
13 |         r: true,
14 |         text: textToSay
15 |       });
16 |     } else if (rand >= 25) { // 25%
17 |       return ansiArt.get({
18 |         speechText: textToSay
19 |       });
20 |     } else { // 25%
21 |       return getCustomArt(art, textToSay) || ansiArt.get({
22 |         speechText: textToSay
23 |       });
24 |     }
25 |   } 
26 |   
27 |   else if (/.ansi$/.test(art)) {
28 |     // if SAY ends with ".ansi" use the 'ansi-art' library
29 |     if (art === path.basename(art)) {
30 |       return ansiArt.get({
31 |         artName: art.slice(0,-5),
32 |         speechText: textToSay
33 |       });
34 |     } else {
35 |       return ansiArt.get({
36 |         filePath: art,
37 |         speechText: textToSay
38 |       });
39 |     }
40 |   }
41 | 
42 |   else if (/.cow$/.test(art)) {
43 |     // if SAY ends with ".cow" use the 'cowsay' library
44 |     return cowsay.say({
45 |       f: art.slice(0,-4),
46 |       text: textToSay
47 |     });
48 |   }
49 | 
50 |   else {
51 |     return getCustomArt(art, textToSay) || ansiArt.get({
52 |       artName: art,
53 |       speechText: textToSay
54 |     });
55 |   }
56 | }
57 | 
58 | module.exports = getAnsiArt;
59 | 


--------------------------------------------------------------------------------
/arts.js:
--------------------------------------------------------------------------------
 1 | var bunnySay = require('sign-bunny');
 2 | var yosay = require('yosay');
 3 | 
 4 | var llamaSay = function(text) {
 5 |   return `
 6 |     ${text}
 7 | 
 8 |     ∩∩
 9 |  (・ω・)
10 |   │ │
11 |   │ └─┐○
12 |    ヽ   丿
13 |     ∥ ̄∥`;
14 | }
15 | 
16 | var catSay = function(text) {
17 |   return `
18 |       ${text}
19 | 
20 |       ♪ ガンバレ! ♪
21 |   ミ ゛ミ ∧_∧ ミ゛ミ
22 |   ミ ミ ( ・∀・ )ミ゛ミ
23 |    ゛゛ \   /゛゛
24 |        i⌒ヽ |
25 |        (_) ノ
26 |          ∪`
27 |     ;
28 | }
29 | 
30 | function getCustomArt(art, textToSay) {
31 |   if (art === 'RANDOM') {
32 |     const arts = ['bunny', 'llama', 'cat', 'yeoman'];
33 |     const random = [Math.round(Math.random*arts.length)];
34 |     art = arts[random];
35 |   }
36 | 
37 |   switch (art) {
38 |     case 'bunny' : return bunnySay(textToSay);
39 |     case 'llama' : return llamaSay(textToSay);
40 |     case 'cat'   : return catSay(textToSay);
41 |     case 'yeoman': return yosay(textToSay);
42 |     default : return null;
43 |   }
44 | }
45 | 
46 | module.exports = getCustomArt;


--------------------------------------------------------------------------------
/care.js:
--------------------------------------------------------------------------------
  1 | #!/usr/bin/env node
  2 | var config = require(__dirname + '/config.js');
  3 | var twitterbot = require(__dirname + '/twitterbot.js');
  4 | var gitbot = require(__dirname + '/gitbot.js');
  5 | var pomodoro = require(__dirname + '/pomodoro.js');
  6 | var getAnsiArt = require(__dirname + '/ansiart.js');
  7 | 
  8 | var path = require('path');
  9 | var resolve = require('resolve-dir');
 10 | var notifier = require('node-notifier');
 11 | var blessed = require('blessed');
 12 | var contrib = require('blessed-contrib');
 13 | var chalk = require('chalk');
 14 | var weather = require('weather-js');
 15 | var path = require('path');
 16 | 
 17 | var inPomodoroMode = false;
 18 | 
 19 | var screen = blessed.screen({
 20 |   fullUnicode: true, // emoji or bust
 21 |   smartCSR: true,
 22 |   autoPadding: true,
 23 |   title: config.terminal_title
 24 | });
 25 | 
 26 | // Quit on Escape, q, or Control-C.
 27 | screen.key(['escape', 'q', 'C-c'], function(ch, key) {
 28 |   return process.exit(0);
 29 | });
 30 | 
 31 | // Refresh on r, or Control-R.
 32 | screen.key(['r', 'C-r'], function(ch, key) {
 33 |   tick();
 34 | });
 35 | 
 36 | screen.key(['s', 'C-s'], function(ch, key) {
 37 |   if (!inPomodoroMode) {
 38 |     return;
 39 |   } else if (pomodoroObject.isStopped()) {
 40 |     pomodoroObject.start();
 41 |   } else if (pomodoroObject.isPaused()) {
 42 |     pomodoroObject.resume();
 43 |   } else {
 44 |     pomodoroObject.pause();
 45 |     pomodoroHandlers.onTick();
 46 |   }
 47 | });
 48 | 
 49 | screen.key(['e', 'C-e'], function(ch, key) {
 50 |   if (inPomodoroMode) {
 51 |     pomodoroObject.stop();
 52 |     pomodoroHandlers.onTick();
 53 |   }
 54 | });
 55 | 
 56 | screen.key(['u', 'C-u'], function(ch, key) {
 57 |   if (inPomodoroMode) {
 58 |     pomodoroObject.updateRunningDuration();
 59 |     pomodoroHandlers.onTick();
 60 |   }
 61 | });
 62 | 
 63 | screen.key(['b', 'C-b'], function(ch, key) {
 64 |   if (inPomodoroMode) {
 65 |     pomodoroObject.updateBreakDuration();
 66 |     pomodoroHandlers.onTick()
 67 |   }
 68 | });
 69 | 
 70 | screen.key(['p', 'C-p'], function(ch, key) {
 71 |   if (inPomodoroMode) {
 72 |     pomodoroObject.stop();
 73 |     inPomodoroMode = false;
 74 |     doTheTweets();
 75 |     parrotBox.removeLabel('');
 76 |   } else {
 77 |     parrotBox.setLabel(' 🍅 ');
 78 |     inPomodoroMode = true;
 79 |     pomodoroHandlers.onTick()
 80 |   }
 81 | });
 82 | 
 83 | var grid = new contrib.grid({rows: 12, cols: 12, screen: screen});
 84 | 
 85 | // grid.set(row, col, rowSpan, colSpan, obj, opts)
 86 | var weatherBox = grid.set(0, 8, 2, 4, blessed.box, makeScrollBox(' 🌤 '));
 87 | var todayBox = grid.set(0, 0, 6, 6, blessed.box, makeScrollBox(' 📝  Last 24 hours '));
 88 | var weekBox = grid.set(6, 0, 6, 6, blessed.box, makeScrollBox(' 📝  Week '));
 89 | var commits = grid.set(0, 6, 6, 2, contrib.bar, makeGraphBox('Commits'));
 90 | var parrotBox = grid.set(6, 6, 6, 6, blessed.box, makeScrollBox(''));
 91 | 
 92 | var tweetBoxes = {}
 93 | tweetBoxes[config.twitter[1]] = grid.set(2, 8, 2, 4, blessed.box, makeBox(' 💖 '));
 94 | tweetBoxes[config.twitter[2]] = grid.set(4, 8, 2, 4, blessed.box, makeBox(' 💬 '));
 95 | 
 96 | tick();
 97 | setInterval(tick, 1000 * 60 * config.updateInterval);
 98 | 
 99 | function tick() {
100 |   doTheWeather();
101 |   doTheTweets();
102 |   doTheCodes();
103 | }
104 | 
105 | function doTheWeather() {
106 |   weather.find({search: config.weather, degreeType: config.celsius ? 'C' : 'F'}, function(err, result) {
107 |     if (result && result[0] && result[0].current) {
108 |       var json = result[0];
109 |       // TODO: add emoji for this thing.
110 |       var skytext = json.current.skytext.toLowerCase();
111 |       var currentDay = json.current.day;
112 |       var degreetype = json.location.degreetype;
113 |       var forecastString = '';
114 |       for (var i = 0; i < json.forecast.length; i++) {
115 |         var forecast = json.forecast[i];
116 |         if (forecast.day === currentDay) {
117 |           var skytextforecast = forecast.skytextday.toLowerCase();
118 |           forecastString = `Today, it will be ${skytextforecast} with a forecast high of ${forecast.high}°${degreetype} and a low of ${forecast.low}°${degreetype}.`;
119 |         }
120 |       }
121 |       weatherBox.content = `In ${json.location.name} it's ${json.current.temperature}°${degreetype} and ${skytext} right now. ${forecastString}`;
122 |     } else {
123 |       weatherBox.content = 'Having trouble fetching the weather for you :(';
124 |     }
125 |   });
126 | }
127 | 
128 | function doTheTweets() {
129 |   for (var which in config.twitter) {
130 |     // Gigantor hack: first twitter account gets spoken by the party parrot.
131 |     if (which == 0) {
132 |       if (inPomodoroMode) {
133 |         return;
134 |       }
135 |       twitterbot.getTweet(config.twitter[which]).then(function(tweet) {
136 |         parrotBox.content = getAnsiArt(config.say, tweet.text)
137 |         screen.render();
138 |       },function(error) {
139 |         // Just in case we don't have tweets.
140 |         parrotBox.content = getAnsiArt(config.say, 'Hi! You\'re doing great!!!')
141 |         screen.render();
142 |       });
143 |     } else {
144 |       twitterbot.getTweet(config.twitter[which]).then(function(tweet) {
145 |         tweetBoxes[tweet.bot.toLowerCase()].content = tweet.text;
146 |         screen.render();
147 |       },function(error) {
148 |         tweetBoxes[config.twitter[1]].content =
149 |         tweetBoxes[config.twitter[2]].content =
150 |         'Can\'t read Twitter without some API keys  🐰. Maybe try the scraping version instead?';
151 |       });
152 |     }
153 |   }
154 | }
155 | 
156 | function doTheCodes() {
157 |   var todayCommits = 0;
158 |   var weekCommits = 0;
159 | 
160 |   // show loading message while loading commits.
161 |   // Turns out blessed doesn't love it if there's emoji in this or if
162 |   // the line is super long.
163 |   todayBox.content = weekBox.content = 'tiny commit bot is looking for tiny commits! ';
164 |   screen.render();
165 | 
166 |   function getCommits(data, box) {
167 |     var content = colorizeLog(data || '');
168 |     box.content += content;
169 |     var commitRegex = /(.......) (- .*)/g;
170 |     return (box && box.content) ? (box.content.match(commitRegex) || []).length : '0';
171 |   }
172 | 
173 |   function showError(err) {
174 |     todayBox.content = 'ERROR: ' + (err.message || err);
175 |     return screen.render();
176 |   }
177 | 
178 |   gitbot.findGitRepos(config.repos, config.depth-1, (err, allRepos) => {
179 |     if (err) return showError(err);
180 |     gitbot.getCommitsFromRepos(allRepos, 1, (err, data) => {
181 |       if (err) return showError(err);
182 |       todayBox.content = '';
183 |       todayCommits = getCommits(`${data}`, todayBox);
184 |       updateCommitsGraph(todayCommits, weekCommits);
185 |       screen.render();
186 |     });
187 |     gitbot.getCommitsFromRepos(allRepos, 7, (err, data) => {
188 |       if (err) return showError(err);
189 |       weekBox.content = '';
190 |       weekCommits = getCommits(`${data}`, weekBox);
191 |       updateCommitsGraph(todayCommits, weekCommits);
192 |       screen.render();
193 |     });
194 |   });
195 | }
196 | 
197 | function makeBox(label) {
198 |   return {
199 |     label: label,
200 |     tags: true,
201 |     // draggable: true,
202 |     border: {
203 |       type: 'line'  // or bg
204 |     },
205 |     style: {
206 |       border: { fg: 'cyan' },
207 |       hover: { border: { fg: 'green' }, }
208 |     }
209 |   };
210 | }
211 | 
212 | function makeScrollBox(label) {
213 |   var options = makeBox(label);
214 |   options.scrollable = true;
215 |   options.scrollbar = { ch:' ' };
216 |   options.style.scrollbar = { bg: 'green', fg: 'white' }
217 |   options.keys = true;
218 |   options.vi = true;
219 |   options.alwaysScroll = true;
220 |   options.mouse = true;
221 |   return options;
222 | }
223 | 
224 | function makeGraphBox(label) {
225 |   var options = makeBox(label);
226 |   options.barWidth= 5;
227 |   options.xOffset= 4;
228 |   options.maxHeight= 10;
229 |   options.labelColor = 'normal';
230 |   return options;
231 | }
232 | 
233 | function updateCommitsGraph(today, week) {
234 |   commits.setData({titles: ['24h', 'week'], data: [today, week]})
235 | }
236 | 
237 | function colorizeLog(text) {
238 |   var lines = text.split('\n');
239 |   var regex = /(.......) (- .*) (\(.*\)) (<.*>)/i;
240 |   var nothingRegex = /Seems like .* did nothing/i;
241 |   for (var i = 0; i < lines.length; i++) {
242 |     // If it's a path
243 |     if (lines[i][0] === '/') {
244 |       lines[i] = formatRepoName(lines[i], '/')
245 |     } else if(lines[i][0] === '\\') {
246 |       lines[i] = formatRepoName(lines[i], '\\')
247 |     } else {
248 |       // It may be a mean "seems like .. did nothing!" message. Skip it
249 |       var nothing = lines[i].match(nothingRegex);
250 |       if (nothing) {
251 |         lines[i] = '';
252 |         continue;
253 |       }
254 | 
255 |       // It's a commit.
256 |       var matches = lines[i].match(regex);
257 |       if (matches) {
258 |         lines[i] = chalk.red(matches[1]) + ' ' + matches[2] + ' ' +
259 |           chalk.green(matches[3])
260 |       }
261 |     }
262 |   }
263 |   return lines.join('\n');
264 | }
265 | 
266 | function formatRepoName(line, divider) {
267 |   var repoPath = config.repos
268 |     .map(resolve)
269 |     .sort((a, b) => a.length < b.length) // Longest repo repoPath first
270 |     .find(repo => line.startsWith(repo));
271 |   var repoRootPath = chalk.yellow(path.basename(repoPath) + divider);
272 |   var repoChildPath = chalk.yellow.bold(
273 |     line.replace(repoPath, '').replace(new RegExp(`^${divider}`), '')
274 |   );
275 |   return `\n${repoRootPath}${repoChildPath}`;
276 | }
277 | 
278 | var pomodoroHandlers = {
279 |   onTick: function() {
280 |     if (!inPomodoroMode) return;
281 |     var remainingTime = pomodoroObject.getRemainingTime();
282 | 
283 |     var statusText = '';
284 |     if (pomodoroObject.isInBreak()) {
285 |       statusText = ' (Break Started) ';
286 |     } else if (pomodoroObject.isStopped()) {
287 |       statusText = ' (Press "s" to start) ';
288 |     } else if (pomodoroObject.isPaused()) {
289 |       statusText = ' (Press "s" to resume) ';
290 |     }
291 | 
292 |     var content = `In Pomodoro Mode: ${remainingTime} ${statusText}`;
293 |     var metaData = `Duration: ${pomodoroObject.getRunningDuration()} Minutes,  Break Time: ${pomodoroObject.getBreakDuration()} Minutes\n`;
294 |     metaData += 'commands: \n s - start/pause/resume \n e - stop \n u - update duration \n b - update break time';
295 |     parrotBox.content = getAnsiArt(config.say, content) + metaData;
296 |     screen.render();
297 |   },
298 | 
299 |   onBreakStarts: function() {
300 |     if (inPomodoroMode) {
301 |       notifier.notify({
302 |         title: 'Pomodoro Alert',
303 |         message: 'Break Time!',
304 |         sound: true,
305 |         timeout: 30,
306 |       });
307 |     }
308 |   },
309 | 
310 |   onBreakEnds: function() {
311 |     if (inPomodoroMode) {
312 |       notifier.notify({
313 |         title: 'Pomodoro Alert',
314 |         message: 'Break Time Ends!',
315 |         sound: true,
316 |         timeout: 30,
317 |       });
318 |     }
319 |   },
320 | 
321 |   runningDuration: parseInt(config.runningDuration, 10),
322 | 
323 |   breakDuration: parseInt(config.breakDuration, 10),
324 | }
325 | 
326 | var pomodoroObject = pomodoro(pomodoroHandlers);
327 | 


--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
 1 | const expandHomeDir = require('expand-home-dir');
 2 | 
 3 | var config = {
 4 |   // Accounts to read the last tweet from. The first one in the list will be
 5 |   // spoken by the party parrot.
 6 |   twitter: (process.env.TTC_BOTS || 'tinycarebot,selfcare_bot,magicrealismbot').toLowerCase().split(',').map(s => s.trim()),
 7 | 
 8 |   // Use this to have a different animal say a message in the big box.
 9 |   // regex: if TTC_SAY_BOX is a filePath, return that path
10 |   say: /(\w[~\/])/.test(process.env.TTC_SAY_BOX)
11 |     ? process.env.TTC_SAY_BOX : (process.env.TTC_SAY_BOX || 'parrot').toLowerCase(),
12 | 
13 |   // Set this to false if you want to scrape twitter.com instead of using
14 |   // API keys. The tweets may include RTs in this case :(
15 |   apiKeys: (process.env.TTC_APIKEYS || 'true') === 'true',
16 | 
17 |   // Directories in which to run git-standup on for a list of your recent commits.
18 |   repos: (process.env.TTC_REPOS || '~/Code').split(',').map(p => expandHomeDir(p)),
19 | 
20 |   // Directory-depth to look for git repositories.
21 |   depth: (process.env.TTC_REPOS_DEPTH || 1),
22 | 
23 |   // Where to check the weather for.
24 |   // It's using weather.service.msn.com behind the curtains.
25 |   weather: process.env.TTC_WEATHER || 'San Francisco',
26 | 
27 |   // Set to false if you're an imperial savage. <3
28 |   celsius: (process.env.TTC_CELSIUS || 'true') === 'true',
29 | 
30 |   terminal_title: (process.env.TTC_TERMINAL_TITLE === 'false' ? null : '✨💖 tiny care terminal 💖✨'),
31 | 
32 |   updateInterval: parseFloat(process.env.TTC_UPDATE_INTERVAL) || 20,
33 | 
34 |   keys: {
35 |     consumer_key:        process.env.TTC_CONSUMER_KEY || process.env.CONSUMER_KEY || 'none',
36 |     consumer_secret:     process.env.TTC_CONSUMER_SECRET || process.env.CONSUMER_SECRET || 'none',
37 |     access_token:        process.env.TTC_ACCESS_TOKEN || process.env.ACCESS_TOKEN || 'none',
38 |     access_token_secret: process.env.TTC_ACCESS_TOKEN_SECRET || process.env.ACCESS_TOKEN_SECRET || 'none',
39 |   },
40 | 
41 |   // Pomodoro Settings
42 |   runningDuration: process.env.TTC_POMODORO || 20,
43 |   breakDuration: process.env.TTC_BREAK || 5,
44 | 
45 | };
46 | 
47 | module.exports = config;
48 | 


--------------------------------------------------------------------------------
/gitbot.js:
--------------------------------------------------------------------------------
  1 | const resolve = require('resolve-dir');
  2 | const subdirs = require('subdirs');
  3 | const isGit = require('is-git');
  4 | const chalk = require('chalk');
  5 | const gitlog = require('gitlog').default;
  6 | const async = require("async");
  7 | const { exec } = require("child_process");
  8 | 
  9 | function craftGetGitUserErrorMessage(error, stdout) {
 10 |   return `ERROR reading git-config.
 11 |     Use e.g. 'git config --global user.name "Mona Lisa"'.
 12 |     See 'man git config' for further information.
 13 |     \n${error.message}\n${stdout}\n`;
 14 | }
 15 | 
 16 | async function getGitUser() {
 17 |   return new Promise((resolvePromise, rejectPromise) => {
 18 |     exec('git config --get user.name', (error, stdout) => {
 19 |       if (error || stdout.trim() === '') {
 20 |         rejectPromise(craftGetGitUserErrorMessage(error, stdout));
 21 |         return;
 22 |       }
 23 |       resolvePromise(stdout.trim());
 24 |     });
 25 |   });
 26 | }
 27 | 
 28 | /**
 29 |  * Go through all `repos` and look for subdirectories up to a given `depth`
 30 |  * and look for repositories.
 31 |  * Calls `callback` with array of repositories.
 32 |  */
 33 | function findGitRepos(repos, depth, callback) {
 34 |   let allRepos = [];
 35 |   async.each(repos, (repo, repoDone) => {
 36 |     repo = resolve(repo);
 37 |     subdirs(repo, depth, (err, dirs) => {
 38 |       if (err) {
 39 |         switch (err.code) {
 40 |           case 'ENOENT':
 41 |             return callback(`Could not open directory directory: ${err.path}\n`, null);
 42 |           case 'EACCES':
 43 |             return; //ignore if no access
 44 |           default:
 45 |             return callback(`Error "${err.code}" doing "${err.syscall}" on directory: ${err.path}\n`, null);
 46 |         }
 47 |       }
 48 |       if (dirs) dirs.push(repo);
 49 |       async.each(dirs, (dir, dirDone) => {
 50 |         isGit(dir, (err, isGit) => {
 51 |           if (err) {
 52 |             return callback(err, null);
 53 |           }
 54 |           if (!dir.includes('.git') && isGit) {
 55 |             allRepos.push(dir);
 56 |           }
 57 |           dirDone();
 58 |         });
 59 |       }, repoDone);
 60 |     });
 61 |   }, err => {
 62 |     callback(err, allRepos.sort().reverse());
 63 |   });
 64 | }
 65 | 
 66 | /**
 67 |  * returns all commits of the last given `days`.
 68 |  * Calls `callback` with line-seperated-strings of the formatted commits.
 69 |  */
 70 | async function getCommitsFromRepos(repos, days, callback) {
 71 |   let cmts = [];
 72 |   let errs = [];
 73 |   let gitUser;
 74 |   try {
 75 |     gitUser = await getGitUser();
 76 |   } catch( error ) {
 77 |     callback(error);
 78 |     return;
 79 |   }
 80 |   async.each(repos, (repo, repoDone) => {
 81 |     try {
 82 |       gitlog({
 83 |         repo: repo,
 84 |         all: true,
 85 |         number: 100, //max commit count
 86 |         since: `${days} days ago`,
 87 |         fields: ['abbrevHash', 'subject', 'authorDateRel', 'authorName'],
 88 |         author: gitUser
 89 |       }, (err, logs) => {
 90 |         // Error
 91 |         if (err) {
 92 |           errs.push(`${chalk.red('Oh noes 😱 :')} Getting commits from repo "${repo}" has failed: ${err.message || err}`);
 93 |           return repoDone();
 94 |         }
 95 | 
 96 |         // Find user commits
 97 |         let commits = [];
 98 |         logs.forEach(c => {
 99 |           // filter simple merge commits
100 |           if (c.status && c.status.length)
101 |             commits.push(`${c.abbrevHash} - ${c.subject} (${c.authorDateRel}) <${c.authorName.replace('@end@\n','')}>`);
102 |         });
103 | 
104 |         // Add repo name and commits
105 |         if (commits.length >= 1) {
106 |           // Repo name
107 |           cmts.push(repo);
108 |           cmts.push(...commits);
109 |         }
110 | 
111 |         repoDone();
112 |       });
113 |     } catch(err) {
114 |       callback(err, null);
115 |     }
116 |   }, err => {
117 |     const errors = errs.length > 0 ? errs.join('\n\n') : null;
118 |     const commits = cmts.length > 0 ? cmts.join('\n') : "Nothing yet. Start small!";
119 |     callback(err, errors ? [errors, commits].join('\n') : commits);
120 |   });
121 | }
122 | 
123 | module.exports.findGitRepos = findGitRepos;
124 | module.exports.getCommitsFromRepos = getCommitsFromRepos;
125 | 


--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
   1 | {
   2 |   "name": "tiny-care-terminal",
   3 |   "version": "1.8.0",
   4 |   "lockfileVersion": 1,
   5 |   "requires": true,
   6 |   "dependencies": {
   7 |     "@types/color-name": {
   8 |       "version": "1.1.1",
   9 |       "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
  10 |       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
  11 |     },
  12 |     "@types/node": {
  13 |       "version": "13.13.4",
  14 |       "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz",
  15 |       "integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA=="
  16 |     },
  17 |     "abbrev": {
  18 |       "version": "1.1.1",
  19 |       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
  20 |       "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
  21 |     },
  22 |     "ajv": {
  23 |       "version": "6.12.2",
  24 |       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
  25 |       "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
  26 |       "requires": {
  27 |         "fast-deep-equal": "^3.1.1",
  28 |         "fast-json-stable-stringify": "^2.0.0",
  29 |         "json-schema-traverse": "^0.4.1",
  30 |         "uri-js": "^4.2.2"
  31 |       }
  32 |     },
  33 |     "ansi-art": {
  34 |       "version": "1.3.0",
  35 |       "resolved": "https://registry.npmjs.org/ansi-art/-/ansi-art-1.3.0.tgz",
  36 |       "integrity": "sha512-jwad9W/z4/wFUXnPJuMmMXQdXVj73wfAlxFueDnJETbJxwgcQk89gn3H3uXduz69cotXtrxNkxr14RSbNAQHNg==",
  37 |       "requires": {
  38 |         "node-chat-bubble": "^1.0.3"
  39 |       }
  40 |     },
  41 |     "ansi-escapes": {
  42 |       "version": "4.3.1",
  43 |       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
  44 |       "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
  45 |       "requires": {
  46 |         "type-fest": "^0.11.0"
  47 |       }
  48 |     },
  49 |     "ansi-regex": {
  50 |       "version": "2.1.1",
  51 |       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
  52 |       "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
  53 |     },
  54 |     "ansi-styles": {
  55 |       "version": "2.2.1",
  56 |       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
  57 |       "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
  58 |     },
  59 |     "ansi-term": {
  60 |       "version": "0.0.2",
  61 |       "resolved": "https://registry.npmjs.org/ansi-term/-/ansi-term-0.0.2.tgz",
  62 |       "integrity": "sha1-/XU++kvq2g6smZgbxSo/b/AZ3rc=",
  63 |       "requires": {
  64 |         "x256": ">=0.0.1"
  65 |       }
  66 |     },
  67 |     "ansicolors": {
  68 |       "version": "0.3.2",
  69 |       "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
  70 |       "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk="
  71 |     },
  72 |     "asn1": {
  73 |       "version": "0.2.4",
  74 |       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
  75 |       "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
  76 |       "requires": {
  77 |         "safer-buffer": "~2.1.0"
  78 |       }
  79 |     },
  80 |     "assert-plus": {
  81 |       "version": "1.0.0",
  82 |       "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
  83 |       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
  84 |     },
  85 |     "astral-regex": {
  86 |       "version": "1.0.0",
  87 |       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
  88 |       "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg=="
  89 |     },
  90 |     "async": {
  91 |       "version": "3.2.0",
  92 |       "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
  93 |       "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
  94 |     },
  95 |     "asynckit": {
  96 |       "version": "0.4.0",
  97 |       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
  98 |       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
  99 |     },
 100 |     "aws-sign2": {
 101 |       "version": "0.7.0",
 102 |       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
 103 |       "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
 104 |     },
 105 |     "aws4": {
 106 |       "version": "1.9.1",
 107 |       "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
 108 |       "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
 109 |     },
 110 |     "balanced-match": {
 111 |       "version": "1.0.0",
 112 |       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
 113 |       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
 114 |     },
 115 |     "bcrypt-pbkdf": {
 116 |       "version": "1.0.2",
 117 |       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
 118 |       "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
 119 |       "requires": {
 120 |         "tweetnacl": "^0.14.3"
 121 |       }
 122 |     },
 123 |     "blessed": {
 124 |       "version": "0.1.81",
 125 |       "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz",
 126 |       "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk="
 127 |     },
 128 |     "blessed-contrib": {
 129 |       "version": "4.8.19",
 130 |       "resolved": "https://registry.npmjs.org/blessed-contrib/-/blessed-contrib-4.8.19.tgz",
 131 |       "integrity": "sha512-g2EVkuCd8r46XVI+pgGuTYK0MGKOn30slJTUlV4m/1d/THIb4lUbY2S+yAtqiJ1q3IFu5TfwURb9/eAKZtJLNQ==",
 132 |       "requires": {
 133 |         "ansi-term": ">=0.0.2",
 134 |         "chalk": "^1.1.0",
 135 |         "drawille-canvas-blessed-contrib": ">=0.1.3",
 136 |         "lodash": "~>=4.17.11",
 137 |         "map-canvas": ">=0.1.5",
 138 |         "marked": "^0.7.0",
 139 |         "marked-terminal": "^4.0.0",
 140 |         "memory-streams": "^0.1.0",
 141 |         "memorystream": "^0.3.1",
 142 |         "picture-tuber": "^1.0.1",
 143 |         "sparkline": "^0.1.1",
 144 |         "strip-ansi": "^3.0.0",
 145 |         "term-canvas": "0.0.5",
 146 |         "x256": ">=0.0.1"
 147 |       },
 148 |       "dependencies": {
 149 |         "chalk": {
 150 |           "version": "1.1.3",
 151 |           "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
 152 |           "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
 153 |           "requires": {
 154 |             "ansi-styles": "^2.2.1",
 155 |             "escape-string-regexp": "^1.0.2",
 156 |             "has-ansi": "^2.0.0",
 157 |             "strip-ansi": "^3.0.0",
 158 |             "supports-color": "^2.0.0"
 159 |           }
 160 |         }
 161 |       }
 162 |     },
 163 |     "bluebird": {
 164 |       "version": "3.7.2",
 165 |       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
 166 |       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
 167 |     },
 168 |     "boolbase": {
 169 |       "version": "1.0.0",
 170 |       "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
 171 |       "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
 172 |     },
 173 |     "brace-expansion": {
 174 |       "version": "1.1.11",
 175 |       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 176 |       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
 177 |       "requires": {
 178 |         "balanced-match": "^1.0.0",
 179 |         "concat-map": "0.0.1"
 180 |       }
 181 |     },
 182 |     "bresenham": {
 183 |       "version": "0.0.3",
 184 |       "resolved": "https://registry.npmjs.org/bresenham/-/bresenham-0.0.3.tgz",
 185 |       "integrity": "sha1-q9q55bGU4nx1fNMU2ERDFPKZh3o="
 186 |     },
 187 |     "buffers": {
 188 |       "version": "0.1.1",
 189 |       "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
 190 |       "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
 191 |     },
 192 |     "cardinal": {
 193 |       "version": "2.1.1",
 194 |       "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz",
 195 |       "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=",
 196 |       "requires": {
 197 |         "ansicolors": "~0.3.2",
 198 |         "redeyed": "~2.1.0"
 199 |       }
 200 |     },
 201 |     "caseless": {
 202 |       "version": "0.12.0",
 203 |       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
 204 |       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
 205 |     },
 206 |     "chalk": {
 207 |       "version": "4.0.0",
 208 |       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
 209 |       "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
 210 |       "requires": {
 211 |         "ansi-styles": "^4.1.0",
 212 |         "supports-color": "^7.1.0"
 213 |       },
 214 |       "dependencies": {
 215 |         "ansi-styles": {
 216 |           "version": "4.2.1",
 217 |           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
 218 |           "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
 219 |           "requires": {
 220 |             "@types/color-name": "^1.1.1",
 221 |             "color-convert": "^2.0.1"
 222 |           }
 223 |         },
 224 |         "color-convert": {
 225 |           "version": "2.0.1",
 226 |           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
 227 |           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 228 |           "requires": {
 229 |             "color-name": "~1.1.4"
 230 |           }
 231 |         },
 232 |         "color-name": {
 233 |           "version": "1.1.4",
 234 |           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
 235 |           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
 236 |         },
 237 |         "supports-color": {
 238 |           "version": "7.1.0",
 239 |           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
 240 |           "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
 241 |           "requires": {
 242 |             "has-flag": "^4.0.0"
 243 |           }
 244 |         }
 245 |       }
 246 |     },
 247 |     "charm": {
 248 |       "version": "0.1.2",
 249 |       "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz",
 250 |       "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY="
 251 |     },
 252 |     "cheerio": {
 253 |       "version": "1.0.0-rc.3",
 254 |       "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
 255 |       "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
 256 |       "requires": {
 257 |         "css-select": "~1.2.0",
 258 |         "dom-serializer": "~0.1.1",
 259 |         "entities": "~1.1.1",
 260 |         "htmlparser2": "^3.9.1",
 261 |         "lodash": "^4.15.0",
 262 |         "parse5": "^3.0.1"
 263 |       }
 264 |     },
 265 |     "cli-boxes": {
 266 |       "version": "1.0.0",
 267 |       "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
 268 |       "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM="
 269 |     },
 270 |     "cli-table": {
 271 |       "version": "0.3.1",
 272 |       "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
 273 |       "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
 274 |       "requires": {
 275 |         "colors": "1.0.3"
 276 |       }
 277 |     },
 278 |     "code-point-at": {
 279 |       "version": "1.1.0",
 280 |       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
 281 |       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
 282 |     },
 283 |     "color-convert": {
 284 |       "version": "1.9.3",
 285 |       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
 286 |       "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
 287 |       "requires": {
 288 |         "color-name": "1.1.3"
 289 |       }
 290 |     },
 291 |     "color-name": {
 292 |       "version": "1.1.3",
 293 |       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
 294 |       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
 295 |     },
 296 |     "colors": {
 297 |       "version": "1.0.3",
 298 |       "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
 299 |       "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
 300 |     },
 301 |     "combined-stream": {
 302 |       "version": "1.0.8",
 303 |       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
 304 |       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
 305 |       "requires": {
 306 |         "delayed-stream": "~1.0.0"
 307 |       }
 308 |     },
 309 |     "concat-map": {
 310 |       "version": "0.0.1",
 311 |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
 312 |       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
 313 |     },
 314 |     "core-util-is": {
 315 |       "version": "1.0.2",
 316 |       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 317 |       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
 318 |     },
 319 |     "cowsay": {
 320 |       "version": "1.4.0",
 321 |       "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz",
 322 |       "integrity": "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g==",
 323 |       "requires": {
 324 |         "get-stdin": "^5.0.1",
 325 |         "optimist": "~0.6.1",
 326 |         "string-width": "~2.1.1",
 327 |         "strip-eof": "^1.0.0"
 328 |       },
 329 |       "dependencies": {
 330 |         "get-stdin": {
 331 |           "version": "5.0.1",
 332 |           "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
 333 |           "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="
 334 |         },
 335 |         "minimist": {
 336 |           "version": "0.0.10",
 337 |           "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
 338 |           "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
 339 |         },
 340 |         "optimist": {
 341 |           "version": "0.6.1",
 342 |           "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
 343 |           "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
 344 |           "requires": {
 345 |             "minimist": "~0.0.1",
 346 |             "wordwrap": "~0.0.2"
 347 |           }
 348 |         }
 349 |       }
 350 |     },
 351 |     "css-select": {
 352 |       "version": "1.2.0",
 353 |       "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
 354 |       "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
 355 |       "requires": {
 356 |         "boolbase": "~1.0.0",
 357 |         "css-what": "2.1",
 358 |         "domutils": "1.5.1",
 359 |         "nth-check": "~1.0.1"
 360 |       }
 361 |     },
 362 |     "css-what": {
 363 |       "version": "2.1.3",
 364 |       "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
 365 |       "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
 366 |     },
 367 |     "dashdash": {
 368 |       "version": "1.14.1",
 369 |       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
 370 |       "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
 371 |       "requires": {
 372 |         "assert-plus": "^1.0.0"
 373 |       }
 374 |     },
 375 |     "debug": {
 376 |       "version": "4.1.1",
 377 |       "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
 378 |       "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
 379 |       "requires": {
 380 |         "ms": "^2.1.1"
 381 |       }
 382 |     },
 383 |     "delayed-stream": {
 384 |       "version": "1.0.0",
 385 |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
 386 |       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
 387 |     },
 388 |     "dom-serializer": {
 389 |       "version": "0.1.1",
 390 |       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
 391 |       "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
 392 |       "requires": {
 393 |         "domelementtype": "^1.3.0",
 394 |         "entities": "^1.1.1"
 395 |       }
 396 |     },
 397 |     "domelementtype": {
 398 |       "version": "1.3.1",
 399 |       "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
 400 |       "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
 401 |     },
 402 |     "domhandler": {
 403 |       "version": "2.4.2",
 404 |       "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
 405 |       "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
 406 |       "requires": {
 407 |         "domelementtype": "1"
 408 |       }
 409 |     },
 410 |     "domutils": {
 411 |       "version": "1.5.1",
 412 |       "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
 413 |       "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
 414 |       "requires": {
 415 |         "dom-serializer": "0",
 416 |         "domelementtype": "1"
 417 |       }
 418 |     },
 419 |     "drawille-blessed-contrib": {
 420 |       "version": "1.0.0",
 421 |       "resolved": "https://registry.npmjs.org/drawille-blessed-contrib/-/drawille-blessed-contrib-1.0.0.tgz",
 422 |       "integrity": "sha1-FcJ5NPV6AFatE1luFWFje8lB8Lc="
 423 |     },
 424 |     "drawille-canvas-blessed-contrib": {
 425 |       "version": "0.1.3",
 426 |       "resolved": "https://registry.npmjs.org/drawille-canvas-blessed-contrib/-/drawille-canvas-blessed-contrib-0.1.3.tgz",
 427 |       "integrity": "sha1-IS8HinIr/S7MJn6oarbd3BCB/Ug=",
 428 |       "requires": {
 429 |         "ansi-term": ">=0.0.2",
 430 |         "bresenham": "0.0.3",
 431 |         "drawille-blessed-contrib": ">=0.0.1",
 432 |         "gl-matrix": "^2.1.0",
 433 |         "x256": ">=0.0.1"
 434 |       }
 435 |     },
 436 |     "ecc-jsbn": {
 437 |       "version": "0.1.2",
 438 |       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
 439 |       "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
 440 |       "requires": {
 441 |         "jsbn": "~0.1.0",
 442 |         "safer-buffer": "^2.1.0"
 443 |       }
 444 |     },
 445 |     "entities": {
 446 |       "version": "1.1.2",
 447 |       "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
 448 |       "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
 449 |     },
 450 |     "es6-promise": {
 451 |       "version": "3.3.1",
 452 |       "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
 453 |       "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM="
 454 |     },
 455 |     "escape-string-regexp": {
 456 |       "version": "1.0.5",
 457 |       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
 458 |       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
 459 |     },
 460 |     "esprima": {
 461 |       "version": "4.0.1",
 462 |       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
 463 |       "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
 464 |     },
 465 |     "event-stream": {
 466 |       "version": "0.9.8",
 467 |       "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-0.9.8.tgz",
 468 |       "integrity": "sha1-XanPPHkAl1mJ21powo5bPJjr4Do=",
 469 |       "requires": {
 470 |         "optimist": "0.2"
 471 |       },
 472 |       "dependencies": {
 473 |         "optimist": {
 474 |           "version": "0.2.8",
 475 |           "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.2.8.tgz",
 476 |           "integrity": "sha1-6YGrfiaLRXlIWTtVZ0wJmoFcrDE=",
 477 |           "requires": {
 478 |             "wordwrap": ">=0.0.1 <0.1.0"
 479 |           }
 480 |         }
 481 |       }
 482 |     },
 483 |     "expand-home-dir": {
 484 |       "version": "0.0.3",
 485 |       "resolved": "https://registry.npmjs.org/expand-home-dir/-/expand-home-dir-0.0.3.tgz",
 486 |       "integrity": "sha1-ct6KBIbMKKO71wRjU5iCW1tign0="
 487 |     },
 488 |     "expand-tilde": {
 489 |       "version": "2.0.2",
 490 |       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
 491 |       "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
 492 |       "requires": {
 493 |         "homedir-polyfill": "^1.0.1"
 494 |       }
 495 |     },
 496 |     "extend": {
 497 |       "version": "3.0.2",
 498 |       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
 499 |       "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
 500 |     },
 501 |     "extsprintf": {
 502 |       "version": "1.3.0",
 503 |       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
 504 |       "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
 505 |     },
 506 |     "fast-deep-equal": {
 507 |       "version": "3.1.1",
 508 |       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
 509 |       "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
 510 |     },
 511 |     "fast-json-stable-stringify": {
 512 |       "version": "2.1.0",
 513 |       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
 514 |       "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
 515 |     },
 516 |     "forever-agent": {
 517 |       "version": "0.6.1",
 518 |       "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
 519 |       "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
 520 |     },
 521 |     "form-data": {
 522 |       "version": "2.3.3",
 523 |       "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
 524 |       "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
 525 |       "requires": {
 526 |         "asynckit": "^0.4.0",
 527 |         "combined-stream": "^1.0.6",
 528 |         "mime-types": "^2.1.12"
 529 |       }
 530 |     },
 531 |     "fs-plus": {
 532 |       "version": "3.1.1",
 533 |       "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz",
 534 |       "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==",
 535 |       "requires": {
 536 |         "async": "^1.5.2",
 537 |         "mkdirp": "^0.5.1",
 538 |         "rimraf": "^2.5.2",
 539 |         "underscore-plus": "1.x"
 540 |       },
 541 |       "dependencies": {
 542 |         "async": {
 543 |           "version": "1.5.2",
 544 |           "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
 545 |           "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
 546 |         }
 547 |       }
 548 |     },
 549 |     "fs.realpath": {
 550 |       "version": "1.0.0",
 551 |       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
 552 |       "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
 553 |     },
 554 |     "get-stdin": {
 555 |       "version": "4.0.1",
 556 |       "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
 557 |       "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
 558 |     },
 559 |     "getpass": {
 560 |       "version": "0.1.7",
 561 |       "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
 562 |       "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
 563 |       "requires": {
 564 |         "assert-plus": "^1.0.0"
 565 |       }
 566 |     },
 567 |     "git-utils": {
 568 |       "version": "5.6.2",
 569 |       "resolved": "https://registry.npmjs.org/git-utils/-/git-utils-5.6.2.tgz",
 570 |       "integrity": "sha512-3pen//xGs5ZJiXejUbx79FyRR58J6DgI7tL9Mc7YQeuF5ENXf/7k0K2M8h4JBlTKZcxxCr8MGA1Xcg4O4l/YjA==",
 571 |       "requires": {
 572 |         "fs-plus": "^3.0.0",
 573 |         "nan": "^2.14.0"
 574 |       },
 575 |       "dependencies": {
 576 |         "nan": {
 577 |           "version": "2.14.1",
 578 |           "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
 579 |           "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
 580 |         }
 581 |       }
 582 |     },
 583 |     "gitlog": {
 584 |       "version": "4.0.0",
 585 |       "resolved": "https://registry.npmjs.org/gitlog/-/gitlog-4.0.0.tgz",
 586 |       "integrity": "sha512-N6ZcvvbHsqhmM09wtzbL8v3FPwBK3EQ1xnv/2nj9JGH/YsYVn+ZkmMCxzkEjHnSFcpUk2HN2LBp76PGj3TkPag==",
 587 |       "requires": {
 588 |         "debug": "^4.1.1",
 589 |         "tslib": "^1.11.1"
 590 |       }
 591 |     },
 592 |     "gl-matrix": {
 593 |       "version": "2.8.1",
 594 |       "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.8.1.tgz",
 595 |       "integrity": "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw=="
 596 |     },
 597 |     "glob": {
 598 |       "version": "7.1.6",
 599 |       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
 600 |       "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
 601 |       "requires": {
 602 |         "fs.realpath": "^1.0.0",
 603 |         "inflight": "^1.0.4",
 604 |         "inherits": "2",
 605 |         "minimatch": "^3.0.4",
 606 |         "once": "^1.3.0",
 607 |         "path-is-absolute": "^1.0.0"
 608 |       }
 609 |     },
 610 |     "global-modules": {
 611 |       "version": "1.0.0",
 612 |       "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
 613 |       "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
 614 |       "requires": {
 615 |         "global-prefix": "^1.0.1",
 616 |         "is-windows": "^1.0.1",
 617 |         "resolve-dir": "^1.0.0"
 618 |       }
 619 |     },
 620 |     "global-prefix": {
 621 |       "version": "1.0.2",
 622 |       "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
 623 |       "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
 624 |       "requires": {
 625 |         "expand-tilde": "^2.0.2",
 626 |         "homedir-polyfill": "^1.0.1",
 627 |         "ini": "^1.3.4",
 628 |         "is-windows": "^1.0.1",
 629 |         "which": "^1.2.14"
 630 |       }
 631 |     },
 632 |     "growly": {
 633 |       "version": "1.3.0",
 634 |       "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
 635 |       "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
 636 |     },
 637 |     "har-schema": {
 638 |       "version": "2.0.0",
 639 |       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
 640 |       "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
 641 |     },
 642 |     "har-validator": {
 643 |       "version": "5.1.3",
 644 |       "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
 645 |       "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
 646 |       "requires": {
 647 |         "ajv": "^6.5.5",
 648 |         "har-schema": "^2.0.0"
 649 |       }
 650 |     },
 651 |     "has-ansi": {
 652 |       "version": "2.0.0",
 653 |       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
 654 |       "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
 655 |       "requires": {
 656 |         "ansi-regex": "^2.0.0"
 657 |       }
 658 |     },
 659 |     "has-flag": {
 660 |       "version": "4.0.0",
 661 |       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
 662 |       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
 663 |     },
 664 |     "here": {
 665 |       "version": "0.0.2",
 666 |       "resolved": "https://registry.npmjs.org/here/-/here-0.0.2.tgz",
 667 |       "integrity": "sha1-acGvPwISHz2HiOAuhNyLOQXXEZU="
 668 |     },
 669 |     "homedir-polyfill": {
 670 |       "version": "1.0.1",
 671 |       "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
 672 |       "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
 673 |       "requires": {
 674 |         "parse-passwd": "^1.0.0"
 675 |       }
 676 |     },
 677 |     "htmlparser2": {
 678 |       "version": "3.10.1",
 679 |       "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
 680 |       "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
 681 |       "requires": {
 682 |         "domelementtype": "^1.3.1",
 683 |         "domhandler": "^2.3.0",
 684 |         "domutils": "^1.5.1",
 685 |         "entities": "^1.1.1",
 686 |         "inherits": "^2.0.1",
 687 |         "readable-stream": "^3.1.1"
 688 |       },
 689 |       "dependencies": {
 690 |         "readable-stream": {
 691 |           "version": "3.6.0",
 692 |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
 693 |           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
 694 |           "requires": {
 695 |             "inherits": "^2.0.3",
 696 |             "string_decoder": "^1.1.1",
 697 |             "util-deprecate": "^1.0.1"
 698 |           }
 699 |         },
 700 |         "string_decoder": {
 701 |           "version": "1.3.0",
 702 |           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
 703 |           "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
 704 |           "requires": {
 705 |             "safe-buffer": "~5.2.0"
 706 |           }
 707 |         }
 708 |       }
 709 |     },
 710 |     "http-signature": {
 711 |       "version": "1.2.0",
 712 |       "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
 713 |       "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
 714 |       "requires": {
 715 |         "assert-plus": "^1.0.0",
 716 |         "jsprim": "^1.2.2",
 717 |         "sshpk": "^1.7.0"
 718 |       }
 719 |     },
 720 |     "inflight": {
 721 |       "version": "1.0.6",
 722 |       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
 723 |       "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
 724 |       "requires": {
 725 |         "once": "^1.3.0",
 726 |         "wrappy": "1"
 727 |       }
 728 |     },
 729 |     "inherits": {
 730 |       "version": "2.0.3",
 731 |       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
 732 |       "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
 733 |     },
 734 |     "ini": {
 735 |       "version": "1.3.4",
 736 |       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
 737 |       "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
 738 |     },
 739 |     "iniparser": {
 740 |       "version": "1.0.5",
 741 |       "resolved": "https://registry.npmjs.org/iniparser/-/iniparser-1.0.5.tgz",
 742 |       "integrity": "sha1-g21r7+bfv87gvM8c+fKsxwJ/eD0="
 743 |     },
 744 |     "is-fullwidth-code-point": {
 745 |       "version": "2.0.0",
 746 |       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
 747 |       "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
 748 |     },
 749 |     "is-git": {
 750 |       "version": "1.0.0",
 751 |       "resolved": "https://registry.npmjs.org/is-git/-/is-git-1.0.0.tgz",
 752 |       "integrity": "sha512-okW0h0hWZgRw3mCj20BzubEaPWkX79r/ZqgrzyhOlBc/mQcdJxHOoJBMFppR9WzCIjmw8kvdmyB8XM3CWzcupA==",
 753 |       "requires": {
 754 |         "iniparser": "^1.0.5"
 755 |       }
 756 |     },
 757 |     "is-typedarray": {
 758 |       "version": "1.0.0",
 759 |       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
 760 |       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
 761 |     },
 762 |     "is-windows": {
 763 |       "version": "1.0.2",
 764 |       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
 765 |       "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
 766 |     },
 767 |     "is-wsl": {
 768 |       "version": "2.1.1",
 769 |       "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
 770 |       "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog=="
 771 |     },
 772 |     "isarray": {
 773 |       "version": "0.0.1",
 774 |       "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
 775 |       "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
 776 |     },
 777 |     "isexe": {
 778 |       "version": "2.0.0",
 779 |       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
 780 |       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
 781 |     },
 782 |     "isstream": {
 783 |       "version": "0.1.2",
 784 |       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
 785 |       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
 786 |     },
 787 |     "jsbn": {
 788 |       "version": "0.1.1",
 789 |       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
 790 |       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
 791 |     },
 792 |     "json-schema": {
 793 |       "version": "0.2.3",
 794 |       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
 795 |       "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
 796 |     },
 797 |     "json-schema-traverse": {
 798 |       "version": "0.4.1",
 799 |       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
 800 |       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
 801 |     },
 802 |     "json-stringify-safe": {
 803 |       "version": "5.0.1",
 804 |       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
 805 |       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
 806 |     },
 807 |     "jsprim": {
 808 |       "version": "1.4.1",
 809 |       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
 810 |       "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
 811 |       "requires": {
 812 |         "assert-plus": "1.0.0",
 813 |         "extsprintf": "1.3.0",
 814 |         "json-schema": "0.2.3",
 815 |         "verror": "1.10.0"
 816 |       }
 817 |     },
 818 |     "lodash": {
 819 |       "version": "4.17.15",
 820 |       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
 821 |       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
 822 |     },
 823 |     "lodash.toarray": {
 824 |       "version": "4.4.0",
 825 |       "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
 826 |       "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE="
 827 |     },
 828 |     "map-canvas": {
 829 |       "version": "0.1.5",
 830 |       "resolved": "https://registry.npmjs.org/map-canvas/-/map-canvas-0.1.5.tgz",
 831 |       "integrity": "sha1-i+a63gvz6fmotW6INqHR0TPKsYY=",
 832 |       "requires": {
 833 |         "drawille-canvas-blessed-contrib": ">=0.0.1",
 834 |         "xml2js": "^0.4.5"
 835 |       }
 836 |     },
 837 |     "marked": {
 838 |       "version": "0.7.0",
 839 |       "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
 840 |       "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg=="
 841 |     },
 842 |     "marked-terminal": {
 843 |       "version": "4.1.0",
 844 |       "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.1.0.tgz",
 845 |       "integrity": "sha512-5KllfAOW02WS6hLRQ7cNvGOxvKW1BKuXELH4EtbWfyWgxQhROoMxEvuQ/3fTgkNjledR0J48F4HbapvYp1zWkQ==",
 846 |       "requires": {
 847 |         "ansi-escapes": "^4.3.1",
 848 |         "cardinal": "^2.1.1",
 849 |         "chalk": "^4.0.0",
 850 |         "cli-table": "^0.3.1",
 851 |         "node-emoji": "^1.10.0",
 852 |         "supports-hyperlinks": "^2.1.0"
 853 |       },
 854 |       "dependencies": {
 855 |         "ansi-styles": {
 856 |           "version": "4.2.1",
 857 |           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
 858 |           "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
 859 |           "requires": {
 860 |             "@types/color-name": "^1.1.1",
 861 |             "color-convert": "^2.0.1"
 862 |           }
 863 |         },
 864 |         "chalk": {
 865 |           "version": "4.0.0",
 866 |           "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
 867 |           "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
 868 |           "requires": {
 869 |             "ansi-styles": "^4.1.0",
 870 |             "supports-color": "^7.1.0"
 871 |           }
 872 |         },
 873 |         "color-convert": {
 874 |           "version": "2.0.1",
 875 |           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
 876 |           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 877 |           "requires": {
 878 |             "color-name": "~1.1.4"
 879 |           }
 880 |         },
 881 |         "color-name": {
 882 |           "version": "1.1.4",
 883 |           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
 884 |           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
 885 |         },
 886 |         "supports-color": {
 887 |           "version": "7.1.0",
 888 |           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
 889 |           "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
 890 |           "requires": {
 891 |             "has-flag": "^4.0.0"
 892 |           }
 893 |         }
 894 |       }
 895 |     },
 896 |     "memory-streams": {
 897 |       "version": "0.1.3",
 898 |       "resolved": "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.3.tgz",
 899 |       "integrity": "sha512-qVQ/CjkMyMInPaaRMrwWNDvf6boRZXaT/DbQeMYcCWuXPEBf1v8qChOc9OlEVQp2uOvRXa1Qu30fLmKhY6NipA==",
 900 |       "requires": {
 901 |         "readable-stream": "~1.0.2"
 902 |       }
 903 |     },
 904 |     "memorystream": {
 905 |       "version": "0.3.1",
 906 |       "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
 907 |       "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI="
 908 |     },
 909 |     "mime": {
 910 |       "version": "1.6.0",
 911 |       "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
 912 |       "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
 913 |     },
 914 |     "mime-db": {
 915 |       "version": "1.44.0",
 916 |       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
 917 |       "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
 918 |     },
 919 |     "mime-types": {
 920 |       "version": "2.1.27",
 921 |       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
 922 |       "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
 923 |       "requires": {
 924 |         "mime-db": "1.44.0"
 925 |       }
 926 |     },
 927 |     "minimatch": {
 928 |       "version": "3.0.4",
 929 |       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
 930 |       "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
 931 |       "requires": {
 932 |         "brace-expansion": "^1.1.7"
 933 |       }
 934 |     },
 935 |     "minimist": {
 936 |       "version": "1.2.5",
 937 |       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
 938 |       "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
 939 |     },
 940 |     "mkdirp": {
 941 |       "version": "0.5.5",
 942 |       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
 943 |       "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
 944 |       "requires": {
 945 |         "minimist": "^1.2.5"
 946 |       }
 947 |     },
 948 |     "ms": {
 949 |       "version": "2.1.2",
 950 |       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 951 |       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
 952 |     },
 953 |     "node-chat-bubble": {
 954 |       "version": "1.0.3",
 955 |       "resolved": "https://registry.npmjs.org/node-chat-bubble/-/node-chat-bubble-1.0.3.tgz",
 956 |       "integrity": "sha1-Pvx7oBMplZ/zL4/mbBDRcTXY7AE=",
 957 |       "requires": {
 958 |         "cli-boxes": "^1.0.0",
 959 |         "string-length": "^2.0.0",
 960 |         "wrap-ansi": "^3.0.1"
 961 |       }
 962 |     },
 963 |     "node-emoji": {
 964 |       "version": "1.10.0",
 965 |       "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
 966 |       "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==",
 967 |       "requires": {
 968 |         "lodash.toarray": "^4.4.0"
 969 |       }
 970 |     },
 971 |     "node-notifier": {
 972 |       "version": "7.0.0",
 973 |       "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.0.tgz",
 974 |       "integrity": "sha512-y8ThJESxsHcak81PGpzWwQKxzk+5YtP3IxR8AYdpXQ1IB6FmcVzFdZXrkPin49F/DKUCfeeiziB8ptY9npzGuA==",
 975 |       "requires": {
 976 |         "growly": "^1.3.0",
 977 |         "is-wsl": "^2.1.1",
 978 |         "semver": "^7.2.1",
 979 |         "shellwords": "^0.1.1",
 980 |         "uuid": "^7.0.3",
 981 |         "which": "^2.0.2"
 982 |       },
 983 |       "dependencies": {
 984 |         "uuid": {
 985 |           "version": "7.0.3",
 986 |           "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
 987 |           "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="
 988 |         },
 989 |         "which": {
 990 |           "version": "2.0.2",
 991 |           "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
 992 |           "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
 993 |           "requires": {
 994 |             "isexe": "^2.0.0"
 995 |           }
 996 |         }
 997 |       }
 998 |     },
 999 |     "nopt": {
1000 |       "version": "2.1.2",
1001 |       "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz",
1002 |       "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=",
1003 |       "requires": {
1004 |         "abbrev": "1"
1005 |       }
1006 |     },
1007 |     "nth-check": {
1008 |       "version": "1.0.2",
1009 |       "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
1010 |       "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
1011 |       "requires": {
1012 |         "boolbase": "~1.0.0"
1013 |       }
1014 |     },
1015 |     "number-is-nan": {
1016 |       "version": "1.0.1",
1017 |       "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
1018 |       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
1019 |     },
1020 |     "oauth-sign": {
1021 |       "version": "0.9.0",
1022 |       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
1023 |       "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
1024 |     },
1025 |     "once": {
1026 |       "version": "1.4.0",
1027 |       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1028 |       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1029 |       "requires": {
1030 |         "wrappy": "1"
1031 |       }
1032 |     },
1033 |     "optimist": {
1034 |       "version": "0.3.7",
1035 |       "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
1036 |       "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
1037 |       "requires": {
1038 |         "wordwrap": "~0.0.2"
1039 |       }
1040 |     },
1041 |     "pad-component": {
1042 |       "version": "0.0.1",
1043 |       "resolved": "https://registry.npmjs.org/pad-component/-/pad-component-0.0.1.tgz",
1044 |       "integrity": "sha1-rR8izhvw/cDW3dkIrxfzUaQEuKw="
1045 |     },
1046 |     "parse-passwd": {
1047 |       "version": "1.0.0",
1048 |       "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
1049 |       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
1050 |     },
1051 |     "parse5": {
1052 |       "version": "3.0.3",
1053 |       "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
1054 |       "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
1055 |       "requires": {
1056 |         "@types/node": "*"
1057 |       }
1058 |     },
1059 |     "path-is-absolute": {
1060 |       "version": "1.0.1",
1061 |       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1062 |       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
1063 |     },
1064 |     "performance-now": {
1065 |       "version": "2.1.0",
1066 |       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
1067 |       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
1068 |     },
1069 |     "picture-tuber": {
1070 |       "version": "1.0.2",
1071 |       "resolved": "https://registry.npmjs.org/picture-tuber/-/picture-tuber-1.0.2.tgz",
1072 |       "integrity": "sha512-49/xq+wzbwDeI32aPvwQJldM8pr7dKDRuR76IjztrkmiCkAQDaWFJzkmfVqCHmt/iFoPFhHmI9L0oKhthrTOQw==",
1073 |       "requires": {
1074 |         "buffers": "~0.1.1",
1075 |         "charm": "~0.1.0",
1076 |         "event-stream": "~0.9.8",
1077 |         "optimist": "~0.3.4",
1078 |         "png-js": "~0.1.0",
1079 |         "x256": "~0.0.1"
1080 |       }
1081 |     },
1082 |     "png-js": {
1083 |       "version": "0.1.1",
1084 |       "resolved": "https://registry.npmjs.org/png-js/-/png-js-0.1.1.tgz",
1085 |       "integrity": "sha1-HMfCEjA6yr50Jj7DrHgAlYAkLZM="
1086 |     },
1087 |     "psl": {
1088 |       "version": "1.8.0",
1089 |       "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
1090 |       "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
1091 |     },
1092 |     "punycode": {
1093 |       "version": "2.1.1",
1094 |       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
1095 |       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
1096 |     },
1097 |     "qs": {
1098 |       "version": "6.5.2",
1099 |       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
1100 |       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
1101 |     },
1102 |     "readable-stream": {
1103 |       "version": "1.0.34",
1104 |       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1105 |       "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1106 |       "requires": {
1107 |         "core-util-is": "~1.0.0",
1108 |         "inherits": "~2.0.1",
1109 |         "isarray": "0.0.1",
1110 |         "string_decoder": "~0.10.x"
1111 |       }
1112 |     },
1113 |     "redeyed": {
1114 |       "version": "2.1.1",
1115 |       "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz",
1116 |       "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=",
1117 |       "requires": {
1118 |         "esprima": "~4.0.0"
1119 |       }
1120 |     },
1121 |     "request": {
1122 |       "version": "2.88.2",
1123 |       "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
1124 |       "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
1125 |       "requires": {
1126 |         "aws-sign2": "~0.7.0",
1127 |         "aws4": "^1.8.0",
1128 |         "caseless": "~0.12.0",
1129 |         "combined-stream": "~1.0.6",
1130 |         "extend": "~3.0.2",
1131 |         "forever-agent": "~0.6.1",
1132 |         "form-data": "~2.3.2",
1133 |         "har-validator": "~5.1.3",
1134 |         "http-signature": "~1.2.0",
1135 |         "is-typedarray": "~1.0.0",
1136 |         "isstream": "~0.1.2",
1137 |         "json-stringify-safe": "~5.0.1",
1138 |         "mime-types": "~2.1.19",
1139 |         "oauth-sign": "~0.9.0",
1140 |         "performance-now": "^2.1.0",
1141 |         "qs": "~6.5.2",
1142 |         "safe-buffer": "^5.1.2",
1143 |         "tough-cookie": "~2.5.0",
1144 |         "tunnel-agent": "^0.6.0",
1145 |         "uuid": "^3.3.2"
1146 |       }
1147 |     },
1148 |     "resolve-dir": {
1149 |       "version": "1.0.1",
1150 |       "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
1151 |       "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
1152 |       "requires": {
1153 |         "expand-tilde": "^2.0.0",
1154 |         "global-modules": "^1.0.0"
1155 |       }
1156 |     },
1157 |     "rimraf": {
1158 |       "version": "2.7.1",
1159 |       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
1160 |       "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
1161 |       "requires": {
1162 |         "glob": "^7.1.3"
1163 |       }
1164 |     },
1165 |     "safe-buffer": {
1166 |       "version": "5.2.0",
1167 |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
1168 |       "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
1169 |     },
1170 |     "safer-buffer": {
1171 |       "version": "2.1.2",
1172 |       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1173 |       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1174 |     },
1175 |     "sax": {
1176 |       "version": "1.2.2",
1177 |       "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.2.tgz",
1178 |       "integrity": "sha1-/YYxojvHgmvvXYcb24c3jJVkeCg="
1179 |     },
1180 |     "semver": {
1181 |       "version": "7.3.2",
1182 |       "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
1183 |       "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
1184 |     },
1185 |     "shell-escape": {
1186 |       "version": "0.2.0",
1187 |       "resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz",
1188 |       "integrity": "sha1-aP0CXrBJC09WegJ/C/IkgLX4QTM="
1189 |     },
1190 |     "shellwords": {
1191 |       "version": "0.1.1",
1192 |       "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
1193 |       "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
1194 |     },
1195 |     "sign-bunny": {
1196 |       "version": "1.0.0",
1197 |       "resolved": "https://registry.npmjs.org/sign-bunny/-/sign-bunny-1.0.0.tgz",
1198 |       "integrity": "sha1-xFf/YNYazjnRd+I6ZPdJLJTPBKs="
1199 |     },
1200 |     "sparkline": {
1201 |       "version": "0.1.2",
1202 |       "resolved": "https://registry.npmjs.org/sparkline/-/sparkline-0.1.2.tgz",
1203 |       "integrity": "sha1-w73kYlKxNU5xDEsgDVSBa9nwejI=",
1204 |       "requires": {
1205 |         "here": "0.0.2",
1206 |         "nopt": "~2.1.2"
1207 |       }
1208 |     },
1209 |     "sshpk": {
1210 |       "version": "1.16.1",
1211 |       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
1212 |       "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
1213 |       "requires": {
1214 |         "asn1": "~0.2.3",
1215 |         "assert-plus": "^1.0.0",
1216 |         "bcrypt-pbkdf": "^1.0.0",
1217 |         "dashdash": "^1.12.0",
1218 |         "ecc-jsbn": "~0.1.1",
1219 |         "getpass": "^0.1.1",
1220 |         "jsbn": "~0.1.0",
1221 |         "safer-buffer": "^2.0.2",
1222 |         "tweetnacl": "~0.14.0"
1223 |       }
1224 |     },
1225 |     "string-length": {
1226 |       "version": "2.0.0",
1227 |       "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
1228 |       "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=",
1229 |       "requires": {
1230 |         "astral-regex": "^1.0.0",
1231 |         "strip-ansi": "^4.0.0"
1232 |       },
1233 |       "dependencies": {
1234 |         "ansi-regex": {
1235 |           "version": "3.0.0",
1236 |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1237 |           "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
1238 |         },
1239 |         "strip-ansi": {
1240 |           "version": "4.0.0",
1241 |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1242 |           "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1243 |           "requires": {
1244 |             "ansi-regex": "^3.0.0"
1245 |           }
1246 |         }
1247 |       }
1248 |     },
1249 |     "string-width": {
1250 |       "version": "2.1.1",
1251 |       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
1252 |       "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
1253 |       "requires": {
1254 |         "is-fullwidth-code-point": "^2.0.0",
1255 |         "strip-ansi": "^4.0.0"
1256 |       },
1257 |       "dependencies": {
1258 |         "ansi-regex": {
1259 |           "version": "3.0.0",
1260 |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1261 |           "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
1262 |         },
1263 |         "strip-ansi": {
1264 |           "version": "4.0.0",
1265 |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1266 |           "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1267 |           "requires": {
1268 |             "ansi-regex": "^3.0.0"
1269 |           }
1270 |         }
1271 |       }
1272 |     },
1273 |     "string_decoder": {
1274 |       "version": "0.10.31",
1275 |       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
1276 |       "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
1277 |     },
1278 |     "strip-ansi": {
1279 |       "version": "3.0.1",
1280 |       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1281 |       "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1282 |       "requires": {
1283 |         "ansi-regex": "^2.0.0"
1284 |       }
1285 |     },
1286 |     "strip-eof": {
1287 |       "version": "1.0.0",
1288 |       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
1289 |       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
1290 |     },
1291 |     "subdirs": {
1292 |       "version": "1.0.1",
1293 |       "resolved": "https://registry.npmjs.org/subdirs/-/subdirs-1.0.1.tgz",
1294 |       "integrity": "sha1-1lJkeHR25Mr378VJj7dAxp9ibUg=",
1295 |       "requires": {
1296 |         "es6-promise": "^3.0.2"
1297 |       }
1298 |     },
1299 |     "supports-color": {
1300 |       "version": "2.0.0",
1301 |       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1302 |       "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
1303 |     },
1304 |     "supports-hyperlinks": {
1305 |       "version": "2.1.0",
1306 |       "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
1307 |       "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
1308 |       "requires": {
1309 |         "has-flag": "^4.0.0",
1310 |         "supports-color": "^7.0.0"
1311 |       },
1312 |       "dependencies": {
1313 |         "supports-color": {
1314 |           "version": "7.1.0",
1315 |           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
1316 |           "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
1317 |           "requires": {
1318 |             "has-flag": "^4.0.0"
1319 |           }
1320 |         }
1321 |       }
1322 |     },
1323 |     "taketalk": {
1324 |       "version": "1.0.0",
1325 |       "resolved": "https://registry.npmjs.org/taketalk/-/taketalk-1.0.0.tgz",
1326 |       "integrity": "sha1-tNTw3u0gauffd1sSnqLKbeUvJt0=",
1327 |       "requires": {
1328 |         "get-stdin": "^4.0.1",
1329 |         "minimist": "^1.1.0"
1330 |       },
1331 |       "dependencies": {
1332 |         "minimist": {
1333 |           "version": "1.2.0",
1334 |           "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
1335 |           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
1336 |         }
1337 |       }
1338 |     },
1339 |     "term-canvas": {
1340 |       "version": "0.0.5",
1341 |       "resolved": "https://registry.npmjs.org/term-canvas/-/term-canvas-0.0.5.tgz",
1342 |       "integrity": "sha1-WXr6wvpjaabxeGC86cX2bW6gypY="
1343 |     },
1344 |     "tough-cookie": {
1345 |       "version": "2.5.0",
1346 |       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
1347 |       "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
1348 |       "requires": {
1349 |         "psl": "^1.1.28",
1350 |         "punycode": "^2.1.1"
1351 |       }
1352 |     },
1353 |     "tslib": {
1354 |       "version": "1.11.1",
1355 |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
1356 |       "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA=="
1357 |     },
1358 |     "tunnel-agent": {
1359 |       "version": "0.6.0",
1360 |       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
1361 |       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
1362 |       "requires": {
1363 |         "safe-buffer": "^5.0.1"
1364 |       }
1365 |     },
1366 |     "tweetnacl": {
1367 |       "version": "0.14.5",
1368 |       "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1369 |       "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
1370 |     },
1371 |     "twit": {
1372 |       "version": "2.2.11",
1373 |       "resolved": "https://registry.npmjs.org/twit/-/twit-2.2.11.tgz",
1374 |       "integrity": "sha512-BkdwvZGRVoUTcEBp0zuocuqfih4LB+kEFUWkWJOVBg6pAE9Ebv9vmsYTTrfXleZGf45Bj5H3A1/O9YhF2uSYNg==",
1375 |       "requires": {
1376 |         "bluebird": "^3.1.5",
1377 |         "mime": "^1.3.4",
1378 |         "request": "^2.68.0"
1379 |       }
1380 |     },
1381 |     "type-fest": {
1382 |       "version": "0.11.0",
1383 |       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
1384 |       "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ=="
1385 |     },
1386 |     "underscore": {
1387 |       "version": "1.10.2",
1388 |       "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
1389 |       "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg=="
1390 |     },
1391 |     "underscore-plus": {
1392 |       "version": "1.7.0",
1393 |       "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz",
1394 |       "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==",
1395 |       "requires": {
1396 |         "underscore": "^1.9.1"
1397 |       }
1398 |     },
1399 |     "uri-js": {
1400 |       "version": "4.2.2",
1401 |       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
1402 |       "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
1403 |       "requires": {
1404 |         "punycode": "^2.1.0"
1405 |       }
1406 |     },
1407 |     "util-deprecate": {
1408 |       "version": "1.0.2",
1409 |       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1410 |       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
1411 |     },
1412 |     "uuid": {
1413 |       "version": "3.4.0",
1414 |       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
1415 |       "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
1416 |     },
1417 |     "verror": {
1418 |       "version": "1.10.0",
1419 |       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
1420 |       "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
1421 |       "requires": {
1422 |         "assert-plus": "^1.0.0",
1423 |         "core-util-is": "1.0.2",
1424 |         "extsprintf": "^1.2.0"
1425 |       }
1426 |     },
1427 |     "weather-js": {
1428 |       "version": "2.0.0",
1429 |       "resolved": "https://registry.npmjs.org/weather-js/-/weather-js-2.0.0.tgz",
1430 |       "integrity": "sha1-DZvNsFpPhNBrm585kAKKYB6kofw=",
1431 |       "requires": {
1432 |         "request": "2.x.x",
1433 |         "xml2js": "0.4.x"
1434 |       }
1435 |     },
1436 |     "which": {
1437 |       "version": "1.3.1",
1438 |       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1439 |       "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1440 |       "requires": {
1441 |         "isexe": "^2.0.0"
1442 |       }
1443 |     },
1444 |     "wordwrap": {
1445 |       "version": "0.0.3",
1446 |       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
1447 |       "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
1448 |     },
1449 |     "wrap-ansi": {
1450 |       "version": "3.0.1",
1451 |       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
1452 |       "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
1453 |       "requires": {
1454 |         "string-width": "^2.1.1",
1455 |         "strip-ansi": "^4.0.0"
1456 |       },
1457 |       "dependencies": {
1458 |         "ansi-regex": {
1459 |           "version": "3.0.0",
1460 |           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
1461 |           "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
1462 |         },
1463 |         "strip-ansi": {
1464 |           "version": "4.0.0",
1465 |           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
1466 |           "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
1467 |           "requires": {
1468 |             "ansi-regex": "^3.0.0"
1469 |           }
1470 |         }
1471 |       }
1472 |     },
1473 |     "wrappy": {
1474 |       "version": "1.0.2",
1475 |       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1476 |       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
1477 |     },
1478 |     "x256": {
1479 |       "version": "0.0.2",
1480 |       "resolved": "https://registry.npmjs.org/x256/-/x256-0.0.2.tgz",
1481 |       "integrity": "sha1-ya8Yh296F1gB1WT+cK2egxd4STQ="
1482 |     },
1483 |     "xml2js": {
1484 |       "version": "0.4.17",
1485 |       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz",
1486 |       "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=",
1487 |       "requires": {
1488 |         "sax": ">=0.6.0",
1489 |         "xmlbuilder": "^4.1.0"
1490 |       }
1491 |     },
1492 |     "xmlbuilder": {
1493 |       "version": "4.2.1",
1494 |       "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz",
1495 |       "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=",
1496 |       "requires": {
1497 |         "lodash": "^4.0.0"
1498 |       }
1499 |     },
1500 |     "yosay": {
1501 |       "version": "2.0.2",
1502 |       "resolved": "https://registry.npmjs.org/yosay/-/yosay-2.0.2.tgz",
1503 |       "integrity": "sha512-avX6nz2esp7IMXGag4gu6OyQBsMh/SEn+ZybGu3yKPlOTE6z9qJrzG/0X5vCq/e0rPFy0CUYCze0G5hL310ibA==",
1504 |       "requires": {
1505 |         "ansi-regex": "^2.0.0",
1506 |         "ansi-styles": "^3.0.0",
1507 |         "chalk": "^1.0.0",
1508 |         "cli-boxes": "^1.0.0",
1509 |         "pad-component": "0.0.1",
1510 |         "string-width": "^2.0.0",
1511 |         "strip-ansi": "^3.0.0",
1512 |         "taketalk": "^1.0.0",
1513 |         "wrap-ansi": "^2.0.0"
1514 |       },
1515 |       "dependencies": {
1516 |         "ansi-styles": {
1517 |           "version": "3.2.1",
1518 |           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1519 |           "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1520 |           "requires": {
1521 |             "color-convert": "^1.9.0"
1522 |           }
1523 |         },
1524 |         "chalk": {
1525 |           "version": "1.1.3",
1526 |           "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
1527 |           "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
1528 |           "requires": {
1529 |             "ansi-styles": "^2.2.1",
1530 |             "escape-string-regexp": "^1.0.2",
1531 |             "has-ansi": "^2.0.0",
1532 |             "strip-ansi": "^3.0.0",
1533 |             "supports-color": "^2.0.0"
1534 |           },
1535 |           "dependencies": {
1536 |             "ansi-styles": {
1537 |               "version": "2.2.1",
1538 |               "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
1539 |               "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
1540 |             }
1541 |           }
1542 |         },
1543 |         "is-fullwidth-code-point": {
1544 |           "version": "1.0.0",
1545 |           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
1546 |           "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
1547 |           "requires": {
1548 |             "number-is-nan": "^1.0.0"
1549 |           }
1550 |         },
1551 |         "wrap-ansi": {
1552 |           "version": "2.1.0",
1553 |           "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
1554 |           "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
1555 |           "requires": {
1556 |             "string-width": "^1.0.1",
1557 |             "strip-ansi": "^3.0.1"
1558 |           },
1559 |           "dependencies": {
1560 |             "string-width": {
1561 |               "version": "1.0.2",
1562 |               "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
1563 |               "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
1564 |               "requires": {
1565 |                 "code-point-at": "^1.0.0",
1566 |                 "is-fullwidth-code-point": "^1.0.0",
1567 |                 "strip-ansi": "^3.0.0"
1568 |               }
1569 |             }
1570 |           }
1571 |         }
1572 |       }
1573 |     }
1574 |   }
1575 | }
1576 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "tiny-care-terminal",
 3 |   "version": "1.8.0",
 4 |   "description": "A terminal that tries to take care of you 💖",
 5 |   "main": "care.js",
 6 |   "author": "Monica Dinculescu <noms@google.com>",
 7 |   "license": "MIT",
 8 |   "engines": {
 9 |     "node": ">=6.10.3 <10"
10 |   },
11 |   "bin": {
12 |     "tiny-care-terminal": "care.js"
13 |   },
14 |   "repository": "https://github.com/notwaldorf/tiny-care-terminal.git",
15 |   "dependencies": {
16 |     "ansi-art": "^1.3.0",
17 |     "async": "^3.2.0",
18 |     "blessed": "^0.1.81",
19 |     "blessed-contrib": "^4.8.19",
20 |     "chalk": "^4.0.0",
21 |     "cheerio": "^1.0.0-rc.3",
22 |     "cowsay": "^1.4.0",
23 |     "expand-home-dir": "^0.0.3",
24 |     "git-utils": "^5.6.2",
25 |     "gitlog": "^4.0.0",
26 |     "is-git": "^1.0.0",
27 |     "node-notifier": "^7.0.0",
28 |     "request": "^2.88.2",
29 |     "resolve-dir": "^1.0.1",
30 |     "shell-escape": "^0.2.0",
31 |     "sign-bunny": "^1.0.0",
32 |     "subdirs": "^1.0.1",
33 |     "twit": "^2.2.11",
34 |     "weather-js": "^2.0.0",
35 |     "yosay": "^2.0.2"
36 |   },
37 |   "scripts": {
38 |     "start": "node care.js",
39 |     "debug": "node --inspect --inspect-brk care.js"
40 |   }
41 | }
42 | 


--------------------------------------------------------------------------------
/pomodoro.js:
--------------------------------------------------------------------------------
  1 | 
  2 | var States = {
  3 |   RUNNING: 'running',
  4 |   STOPPED: 'stopped',
  5 |   IN_BREAK: 'in_break',
  6 |   PAUSED: 'paused',
  7 | };
  8 | 
  9 | 
 10 | // options (object)
 11 | // options.onTick (function) -  Runs on every tick
 12 | // options.onBreakStarts (function) - Runs when break starts
 13 | // options.onBreakEnds (function) - Runs when break ends
 14 | var pomodoro = function(options) {
 15 |   var _setIntervalId = null;
 16 |   var _runningDuration = options.runningDuration; // Default pomodoro duration: 20 Min
 17 |   var _breakDuration = options.breakDuration;    // Default break duration: 5 Min
 18 |   var _runningDurationRemaining = 0; // In seconds
 19 |   var _breakDurationRemaining = 0;   // In seconds
 20 |   var _currentState = States.STOPPED;
 21 | 
 22 |   var _onTick = function() {
 23 |     switch (_currentState) {
 24 |       case States.RUNNING: _handleTickOnRunning(); break;
 25 |       case States.IN_BREAK: _handleTickOnBreak(); break;
 26 |       case States.STOPPED: _handleTickOnStopped(); break;
 27 |       case States.PAUSED: return;
 28 |     }
 29 |   }
 30 | 
 31 |   var _handleTickOnRunning = function() {
 32 |     if (_runningDurationRemaining < 1) {
 33 |       _runningDurationRemaining = 0;
 34 |       _breakDurationRemaining = _breakDuration * 60;
 35 |       _currentState = States.IN_BREAK
 36 |       options.onBreakStarts && options.onBreakStarts();
 37 |     } else {
 38 |       _runningDurationRemaining -= 1;
 39 |       if (options.onTick) options.onTick()
 40 |     }
 41 |   };
 42 | 
 43 |   var _handleTickOnBreak = function() {
 44 |     if (_breakDurationRemaining < 1) {
 45 |       _breakDurationRemaining = 0;
 46 |       _runningDurationRemaining = _runningDuration * 60;
 47 |       _currentState = States.RUNNING
 48 |       options.onBreakEnds && options.onBreakEnds();
 49 |     } else {
 50 |       _breakDurationRemaining -= 1;
 51 |       if (options.onTick) options.onTick()
 52 |     }
 53 |   };
 54 | 
 55 |   var _handleTickOnStopped = function() {
 56 |     clearInterval(_setIntervalId)
 57 |     _runningDurationRemaining = 0;
 58 |     _breakDurationRemaining = 0;
 59 |     _setIntervalId = null;
 60 |   };
 61 | 
 62 |   var exports = {
 63 |     start: function() {
 64 |       if (_setIntervalId !== null) clearInterval(_setIntervalId);
 65 |       _runningDurationRemaining = _runningDuration * 60;
 66 |       _setIntervalId = setInterval(_onTick, 1000);
 67 |       _currentState = States.RUNNING;
 68 |     },
 69 | 
 70 |     stop: function() {
 71 |       _currentState = States.STOPPED;
 72 |     },
 73 | 
 74 |     pause: function() {
 75 |       _currentState = States.PAUSED;
 76 |     },
 77 | 
 78 |     resume: function() {
 79 |       _currentState = _breakDurationRemaining ? States.IN_BREAK : States.RUNNING;
 80 |     },
 81 | 
 82 |     updateRunningDuration() {
 83 |       if (_runningDuration >= 60) _runningDuration = 1;
 84 |       else _runningDuration += 1;
 85 |     },
 86 | 
 87 |     updateBreakDuration() {
 88 |       if (_breakDuration >= 60) _breakDuration = 1;
 89 |       else _breakDuration += 1;
 90 |     },
 91 | 
 92 |     getRunningDuration() {
 93 |       return _runningDuration;
 94 |     },
 95 | 
 96 |     getBreakDuration() {
 97 |       return _breakDuration;
 98 |     },
 99 | 
100 |     getRemainingTime() {
101 |       var remainingTime;
102 |       switch (_currentState) {
103 |         case States.RUNNING: remainingTime =  _runningDurationRemaining; break;
104 |         case States.IN_BREAK: remainingTime = _breakDurationRemaining; break;
105 |         case States.STOPPED: remainingTime = _runningDuration * 60; break;
106 |         case States.PAUSED: remainingTime = _runningDurationRemaining || _breakDurationRemaining;
107 |       }
108 |       return ('0' + Math.floor(remainingTime/60)).slice(-2) + ':' + ('0' + remainingTime % 60).slice(-2);
109 |     },
110 | 
111 |     isRunning() {
112 |       return _currentState === States.RUNNING;
113 |     },
114 | 
115 |     isInBreak() {
116 |       return _currentState === States.IN_BREAK;
117 |     },
118 | 
119 |     isPaused() {
120 |       return _currentState === States.PAUSED;
121 |     },
122 | 
123 |     isStopped() {
124 |       return _currentState === States.STOPPED;
125 |     },
126 |   }
127 | 
128 |   return exports;
129 | }
130 | 
131 | 
132 | module.exports = pomodoro;
133 | 


--------------------------------------------------------------------------------
/sample.env:
--------------------------------------------------------------------------------
 1 | # List of accounts to read the last tweet from, comma separated
 2 | # The first in the list is read by the party parrot.
 3 | export TTC_BOTS='tinycarebot,selfcare_bot,magicrealismbot'
 4 | 
 5 | # Use this to have a different animal say a message in the big box.
 6 | # See README for details about supported formats.
 7 | # Use e.g 'bunny.cow', 'panda.ansi', 'llama' or 'RANDOM'.
 8 | export TTC_SAY_BOX='RANDOM'
 9 | 
10 | # List of folders to look into for `git` commits, comma separated.
11 | export TTC_REPOS='~/Work/Code,~/Fun/Code'
12 | 
13 | # The max directory-depth to look for git repositories in
14 | # the directories defined with `TTC_REPOS`. Note that the deeper
15 | # the directory depth, the slower the results will be fetched.
16 | export TTC_REPOS_DEPTH=2
17 | 
18 | # Location/zip code to check the weather for. Both 90210 and "San Francisco, CA"
19 | # _should_ be ok (the zip code doesn't always work -- use a location
20 | # first, if you can). It's using weather.service.msn.com behind the curtains.
21 | export TTC_WEATHER='Paris'
22 | 
23 | # Set to false if you're an imperial lover <3
24 | export TTC_CELSIUS=true
25 | 
26 | # Unset this if you _don't_ want to use Twitter keys and want to
27 | # use web scraping instead.
28 | export TTC_APIKEYS=true
29 | 
30 | # Refresh the dashboard every 20 minutes.
31 | export TTC_UPDATE_INTERVAL=20
32 | 
33 | # Turn off terminal title
34 | export TTC_TERMINAL_TITLE=false
35 | 
36 | # Twitter api keys
37 | export TTC_CONSUMER_KEY='...'
38 | export TTC_CONSUMER_SECRET='...'
39 | export TTC_ACCESS_TOKEN='...'
40 | export TTC_ACCESS_TOKEN_SECRET='...'
41 | 
42 | # Note: in tiny-terminal-care < 1.0.7, the recommended variables for the Twitter
43 | # API keys were the ones before. As of 1.0.8, they are deprecated
44 | # (because the names are too generic), but will still be supported
45 | # until the next major version.
46 | export CONSUMER_KEY='...'
47 | export CONSUMER_SECRET='...'
48 | export ACCESS_TOKEN='...'
49 | export ACCESS_TOKEN_SECRET='...'
50 | 
51 | # Default pomodoro is 20 minutes and default break is 5 minutes.
52 | # You can change these defaults like this.
53 | export TTC_POMODORO=25
54 | export TTC_BREAK=10
55 | 


--------------------------------------------------------------------------------
/twitterbot.js:
--------------------------------------------------------------------------------
 1 | var Twit = require('twit');
 2 | var config = require(__dirname + '/config.js');
 3 | var request = require('request');
 4 | var cheerio = require('cheerio');
 5 | 
 6 | var T = new Twit({
 7 |   consumer_key:        config.keys.consumer_key,
 8 |   consumer_secret:     config.keys.consumer_secret,
 9 |   access_token:        config.keys.access_token,
10 |   access_token_secret: config.keys.access_token_secret,
11 |   timeout_ms:          60*1000,  // optional HTTP request timeout to apply to all requests.
12 | });
13 | 
14 | var options = {exclude_replies:true, include_rts:false, count: 1, 'tweet_mode': 'extended' };
15 | 
16 | function getTweet(who) {
17 |   who = who || 'tinycarebot';
18 |   return config.apiKeys ? apiTweet(who) : scrapeTweet(who);
19 | }
20 | 
21 | function apiTweet(who) {
22 |   options.screen_name = who;
23 |   return new Promise(function (resolve, reject) {
24 |     T.get('statuses/user_timeline', options, function(err, data) {
25 |       if (err) {
26 |         reject('This didn\'t work. Maybe you didn\'t set up the twitter API keys?');
27 |       } else {
28 |         resolve({text:data[0].full_text, bot: data[0].user.screen_name});
29 |       }
30 |     });
31 |   });
32 | }
33 | 
34 | function scrapeTweet(who) {
35 |   return new Promise(function (resolve, reject) {
36 |     request({
37 |       method: 'GET',
38 |       url: 'https://twitter.com/' + who
39 |     }, (err, res, body) => {
40 |       if (err) {
41 |         reject("Can't scrape tweets. Maybe the user is private or doesn't exist?\n" + err);
42 |       }
43 |       let $ = cheerio.load(body);
44 |       let tweets = $('.js-tweet-text.tweet-text');
45 | 
46 |       randomTweetNumber = Math.round(Math.random() * tweets.length-1);
47 |       let tweet = tweets.filter(function (i, el) {
48 |         return i == randomTweetNumber
49 |       });
50 | 
51 |       resolve({
52 |         text: tweet.text(),
53 |         bot: who
54 |       });
55 |     });
56 |   });
57 | }
58 | 
59 | module.exports.getTweet = getTweet;
60 | 


--------------------------------------------------------------------------------