Merge pull request #5 from MichMich/develop

Develop
This commit is contained in:
vin p 2019-04-17 21:08:04 -05:00 committed by GitHub
commit eeccca8842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 281 additions and 241 deletions

View File

@ -5,29 +5,55 @@ This project adheres to [Semantic Versioning](http://semver.org/).
---
## [2.7.0] - Unreleased
❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core.
## [2.8.0] - Unreleased
*This release is scheduled to be released on 2019-04-01.*
### Added
- Option to show event location in calendar
- Finnish translation for "Feels" and "Weeks"
- Russian translation for “Feels”
### Updated
### Fixed
- Handle SIGTERM messages
- Fixes sliceMultiDayEvents so it respects maximumNumberOfDays
## [2.7.1] - 2019-04-02
Fixed `package.json` version number.
## [2.7.0] - 2019-04-01
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
### Added
- Italian translation for "Feels"
- Disabled the screensaver on raspbian with installation script
- Basic Klingon (tlhIngan Hol) translations
- Disabled the screensaver on raspbian with installation script
- Added option to truncate the number of vertical lines a calendar item can span if `wrapEvents` is enabled.
- Added autoLocation options for weather forcast and current weather modules.
- Added autoTimezone option for the default clock module.
- Danish translation for "Feels" and "Weeks"
- Added option to split multiple day events in calendar to separate numbered events
- Slovakian translation
- Alerts now can contain Font Awesome icons
- Notifications display time can be set in request
- Newsfeed: added support for `ARTICLE_INFO_REQUEST` notification
- Add `name` config option for calendars to be sent along with event broadcasts
### Updated
- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500)
- Updated modernizr code in alert module, fixed a small typo there too
- More verbose error message on console if the config is malformed
- Updated installer script to install Node.js version 10.x
### Fixed
- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511).
- Fixed unhandled error on bad git data in updatenotiifcation module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504).
- Fixed analogue clock border display issue where non-black backgrounds used (previous fix for issue 611)
- Fixed compatibility issues caused when modules request different versions of Font Awesome, see issue [#1522](https://github.com/MichMich/MagicMirror/issues/1522). MagicMirror now uses [Font Awesome 5 with v4 shims included for backwards compatibility](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#shims).
@ -38,6 +64,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix null dereference in moduleNeedsUpdate when the module isn't visible
- Calendar: Fixed event end times by setting default calendarEndTime to "LT" (Local time format). [#1479]
- Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MichMich/MagicMirror/issues/1589)
- Notification: fixed background color (was white text on white background)
- Use getHeader instead of data.header when creating the DOM so overwriting the function also propagates into it
- Fix documentation of `useKMPHwind` option in currentweather
### New weather module
- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
@ -109,7 +138,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fixed gzip encoded calendar loading issue #1400.
- Mixup between german and spanish translation for newsfeed.
- Fixed close dates to be absolute, if no configured in the config.js - module Calendar
- Fixed the UpdateNotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
- Fixed the updatenotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MichMich/MagicMirror/issues/1374)
- Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694.
- Fix weather city ID link in sample config
@ -259,7 +288,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
- Add unit test the capitalizeFirstLetter function of newfeed module.
- Add unit test the capitalizeFirstLetter function of newsfeed module.
- Add new unit tests for function `shorten` in calendar module.
- Add new unit tests for function `getLocaleSpecification` in calendar module.
- Add unit test for js/class.js.
@ -280,7 +309,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Set version of the `express-ipfilter` on 0.3.1.
### Fixed
- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM.
- Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM.
- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
- Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
- Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc).
@ -304,7 +333,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Add unit test calendar_modules function capFirst.
- Add test for check if exists the directories present in defaults modules.
- Add support for showing wind direction as an arrow instead of abbreviation in currentWeather module.
- Add support for writing translation fucntions to support flexible word order
- Add support for writing translation functions to support flexible word order
- Add test for check if exits the directories present in defaults modules.
- Add calendar option to set a separate date format for full day events.
- Add ability for `currentweather` module to display indoor temperature via INDOOR_TEMPERATURE notification
@ -323,7 +352,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Fix double message about port when server is starting
- Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW.
- Removed unused import from js/electron.js
- Made calendar.js respect config.timeFormat irrespecive of locale setting.
- Made calendar.js respect config.timeFormat irrespective of locale setting.
- Fixed alignment of analog clock when a large calendar is displayed in the same side bar.
## [2.1.1] - 2017-04-01
@ -341,7 +370,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations.
- Run `npm test` on Travis automatically.
- Show the splash screen image even when is reboot or halted.
- Added some missing translaton strings in the sv.json file.
- Added some missing translation strings in the sv.json file.
- Run task jsonlint to check translation files.
- Restructured Test Suite.
@ -358,12 +387,12 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Option to use RegExp in Calendar's titleReplace.
- Hungarian Translation.
- Icelandic Translation.
- Add use a script to prevent when is run by SSH session set DISPLAY enviroment.
- Enable ability to set configuration file by the enviroment variable called MM_CONFIG_FILE.
- Add use a script to prevent when is run by SSH session set DISPLAY environment.
- Enable ability to set configuration file by the environment variable called MM_CONFIG_FILE.
- Option to give each calendar a different color.
- Option for colored min-temp and max-temp.
- Add test e2e helloworld.
- Add test e2e enviroment.
- Add test e2e environment.
- Add `chai-as-promised` npm module to devDependencies.
- Basic set of tests for clock module.
- Run e2e test in Travis.
@ -381,10 +410,10 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added tests for Translations, dev argument, version, dev console.
- Added test anytime feature compliments module.
- Added test ipwhitelist configuration directive.
- Added test for calendar module: default, basic-auth, backward compability, fail-basic-auth.
- Added test for calendar module: default, basic-auth, backward compatibility, fail-basic-auth.
- Added meta tags to support fullscreen mode on iOS (for server mode)
- Added `ignoreOldItems` and `ignoreOlderThan` options to the News Feed module
- Added test for MM_PORT enviroment variable.
- Added test for MM_PORT environment variable.
- Added a configurable Week section to the clock module.
### Fixed
@ -396,7 +425,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Module currentWeather: check if temperature received from api is defined.
- Fix an issue with module hidden status changing to `true` although lock string prevented showing it.
- Fix newsfeed module bug (removeStartTags)
- Fix when is set MM_PORT enviroment variable.
- Fix when is set MM_PORT environment variable.
- Fixed missing animation on `this.show(speed)` when module is alone in a region.
## [2.1.0] - 2016-12-31
@ -418,8 +447,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information.
- Possibility to use the the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information.
- Added option to show rain amount in the weatherforecast default module
- Add module `updatenotification` to get an update whenever a new version is availabe. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
- Add the abilty to set timezone on the date display in the Clock Module
- Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
- Add the ability to set timezone on the date display in the Clock Module
- Ability to set date format in calendar module
- Possibility to use currentweather for the compliments
- Added option `disabled` for modules.
@ -458,7 +487,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
- Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included).
- Added CII Badge (we are compliant with the CII Best Practices)
- Add support for doing http basic auth when loading calendars
- Add the abilty to turn off and on the date display in the Clock Module
- Add the ability to turn off and on the date display in the Clock Module
### Fixed
- Fix typo in installer.
@ -481,8 +510,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we
### Fixed
- Prevent `getModules()` selectors from returning duplicate entries.
- Append endpoints of weather modules with `/` to retreive the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
- Corrected grammer in `module.js` from 'suspend' to 'suspended'.
- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
- Corrected grammar in `module.js` from 'suspend' to 'suspended'.
- Fixed openweathermap.org URL in config sample.
- Prevent currentweather module from crashing when received data object is incorrect.
- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388))

View File

@ -128,7 +128,7 @@ The following wiki links are helpful for the initial configuration of your Magic
**Note:** If you used the installer script. This step is already done for you.
2. Modify your required settings. \
Note: You'll can check your configuration running `npm run config:check` in `/home/pi/MagicMirror`.
Note: You can check your configuration running `npm run config:check` in `/home/pi/MagicMirror`.
The following properties can be configured:

View File

@ -82,7 +82,7 @@ if $NODE_INSTALL; then
# The NODE_STABLE_BRANCH variable will need to be manually adjusted when a new branch is released. (e.g. 7.x)
# Only tested (stable) versions are recommended as newer versions could break MagicMirror.
NODE_STABLE_BRANCH="9.x"
NODE_STABLE_BRANCH="10.x"
curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash -
sudo apt-get install -y nodejs
echo -e "\e[92mNode.js installation Done!\e[0m"

View File

@ -70,7 +70,7 @@ var App = function() {
if (e.code == "ENOENT") {
console.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration."));
} else if (e instanceof ReferenceError || e instanceof SyntaxError) {
console.error(Utils.colors.error("WARNING! Could not validate config file. Please correct syntax errors. Starting with default configuration."));
console.error(Utils.colors.error("WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: " + e.stack));
} else {
console.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e));
}
@ -263,6 +263,15 @@ var App = function() {
this.stop();
process.exit(0);
});
/* We also need to listen to SIGTERM signals so we stop everything when we are asked to stop by the OS.
*/
process.on("SIGTERM", () => {
console.log("[SIGTERM] Received. Shutting down server...");
setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds
this.stop();
process.exit(0);
});
};
module.exports = new App();

View File

@ -39,9 +39,9 @@ var MM = (function() {
dom.opacity = 0;
wrapper.appendChild(dom);
if (typeof module.data.header !== "undefined" && module.data.header !== "") {
if (typeof module.getHeader() !== "undefined" && module.getHeader() !== "") {
var moduleHeader = document.createElement("header");
moduleHeader.innerHTML = module.data.header;
moduleHeader.innerHTML = module.getHeader();
moduleHeader.className = "module-header";
dom.appendChild(moduleHeader);
}

View File

@ -212,7 +212,7 @@ var Module = Class.extend({
/* setData(data)
* Set the module data.
*
* argument data obejct - Module data.
* argument data object - Module data.
*/
setData: function (data) {
this.data = data;
@ -226,7 +226,7 @@ var Module = Class.extend({
/* setConfig(config)
* Set the module config and combine it with the module defaults.
*
* argument config obejct - Module config.
* argument config object - Module config.
*/
setConfig: function (config) {
this.config = Object.assign({}, this.defaults, config);

View File

@ -43,10 +43,11 @@ self.sendNotification("SHOW_ALERT", {});
```
### Notification params
| Option | Description
| --------- | -----------
| `title` | The title of the notification. <br><br> **Possible values:** `text` or `html`
| `message` | The message of the notification. <br><br> **Possible values:** `text` or `html`
| Option | Description
| ------------------ | -----------
| `title` | The title of the notification. <br><br> **Possible values:** `text` or `html`
| `message` | The message of the notification. <br><br> **Possible values:** `text` or `html`
| `timer` (optional) | How long the notification should stay visible in ms. <br> If absent, the default `display_time` is used. <br> **Possible values:** `int` `float`
### Alert params
@ -61,4 +62,4 @@ self.sendNotification("SHOW_ALERT", {});
## Open Source Licenses
### [NotificationStyles](https://github.com/codrops/NotificationStyles)
See [ympanus.net](http://tympanus.net/codrops/licensing/) for license.
See [tympanus.net](http://tympanus.net/codrops/licensing/) for license.

View File

@ -51,7 +51,7 @@ Module.register("alert",{
message: msg,
layout: "growl",
effect: this.config.effect,
ttl: this.config.display_time
ttl: message.timer !== undefined ? message.timer : this.config.display_time
}).show();
},
show_alert: function(params, sender) {

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
/* Based on work by http://tympanus.net/codrops/licensing/ */
.ns-box {
background: #fff;
background-color: rgba(0, 0, 0, 0.93);
padding: 17px;
line-height: 1.4;
margin-bottom: 10px;
@ -12,7 +12,10 @@
display: table;
word-wrap: break-word;
max-width: 100%;
border-width: 1px;
border-radius: 5px;
border-style: solid;
border-color: #666;
}
.ns-alert {

View File

@ -30,6 +30,7 @@ The following properties can be configured:
| `maximumNumberOfDays` | The maximum number of days in the future. <br><br> **Default value:** `365`
| `displaySymbol` | Display a symbol in front of an entry. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `defaultSymbol` | The default symbol. <br><br> **Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website. <br> **Default value:** `calendar`
| `showLocation` | Whether to show event locations. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `maxTitleLength` | The maximum title length. <br><br> **Possible values:** `10` - `50` <br> **Default value:** `25`
| `wrapEvents` | Wrap event titles to multiple lines. Breaks lines at the length defined by `maxTitleLength`. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `maxTitleLines` | The maximum number of lines a title will wrap vertically before being cut (Only enabled if `wrapEvents` is also enabled). <br><br> **Possible values:** `0` - `10` <br> **Default value:** `3`
@ -53,7 +54,7 @@ The following properties can be configured:
| `hidePrivate` | Hides private calendar events. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `hideOngoing` | Hides calendar events that have already started. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown. <br><br>Additionally advanced filter objects can be passed in. Below is the configuration for the advance filtering object.<br>**Required**<br>`filterBy` - string used to determine if filter is applied.<br>**Optional**<br>`until` - Time before an event to display it Ex: [`'3 days'`, `'2 months'`, `'1 week'`]<br>`caseSensitive` - By default, excludedEvents are case insensitive, set this to true to enforce case sensitivity<br>`regex` - set to `true` if filterBy is a regex. For those not familiar with regex it is used for pattern matching, please see [here](https://regexr.com/) for more info.<br><br> **Example:** `['Birthday', 'Hide This Event', {filterBy: 'Payment', until: '6 days', caseSensitive: true}, {filterBy: '^[0-9]{1,}.*', regex: true}]` <br> **Default value:** `[]`
| `sliceMultiDayEvents` | If this is set to true, events exceeding at least one midnight will be sliced into separate events including a counter like (1/2). This is especially helpful in "dateheaders" mode. Events will be sliced at midnight, end time for all events but the last will be 23:59 **Default value:** `true`
| `sliceMultiDayEvents` | If this is set to true, events exceeding at least one midnight will be sliced into separate events including a counter like (1/2). This is especially helpful in "dateheaders" mode. Events will be sliced at midnight, end time for all events but the last will be 23:59 **Default value:** `false`
### Calendar configuration
@ -90,6 +91,7 @@ config: {
| `repeatingCountTitle` | The count title for yearly repating events in this calendar. <br><br> **Example:** `'Birthday'`
| `maximumEntries` | The maximum number of events shown. Overrides global setting. **Possible values:** `0` - `100`
| `maximumNumberOfDays` | The maximum number of days in the future. Overrides global setting
| `name` | The name of the calendar. Included in event broadcasts as `calendarName`.
| `auth` | The object containing options for authentication against the calendar.
| `symbolClass` | Add a class to the cell of symbol.
| `titleClass` | Add a class to the title's cell.

View File

@ -15,6 +15,7 @@ Module.register("calendar", {
maximumNumberOfDays: 365,
displaySymbol: true,
defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/
showLocation: false,
displayRepeatingCountTitle: false,
defaultRepeatingCountTitle: "",
maxTitleLength: 25,
@ -379,6 +380,31 @@ Module.register("calendar", {
currentFadeStep = e - startFade;
eventWrapper.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
}
if (this.config.showLocation) {
if (event.location !== false) {
var locationRow = document.createElement("tr");
locationRow.className = "normal xsmall light";
if (this.config.displaySymbol) {
var symbolCell = document.createElement("td");
locationRow.appendChild(symbolCell);
}
var descCell = document.createElement("td");
descCell.className = "location";
descCell.colSpan = "2";
descCell.innerHTML = event.location;
locationRow.appendChild(descCell);
wrapper.appendChild(locationRow);
if (e >= startFade) {
currentFadeStep = e - startFade;
locationRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep);
}
}
}
}
return wrapper;
@ -436,10 +462,11 @@ Module.register("calendar", {
var events = [];
var today = moment().startOf("day");
var now = new Date();
var future = moment().startOf("day").add(this.config.maximumNumberOfDays, "days").toDate();
for (var c in this.calendarData) {
var calendar = this.calendarData[c];
for (var e in calendar) {
var event = calendar[e];
var event = JSON.parse(JSON.stringify(calendar[e])); // clone object
if(this.config.hidePrivate) {
if(event.class === "PRIVATE") {
// do not add the current event, skip it
@ -461,23 +488,30 @@ Module.register("calendar", {
* otherwise, esp. in dateheaders mode it is not clear how long these events are.
*/
if (this.config.sliceMultiDayEvents) {
var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); //next midnight
var splitEvents = [];
var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x");
var count = 1;
var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1
if (event.endDate > midnight) {
while (event.endDate > midnight) {
var nextEvent = JSON.parse(JSON.stringify(event)); //make a copy without reference to the original event
nextEvent.startDate = midnight;
event.endDate = midnight;
event.title += " (" + count + "/" + maxCount + ")";
events.push(event);
event = nextEvent;
count += 1;
midnight = moment(midnight, "x").add(1, "day").format("x"); //move further one day for next split
}
event.title += " ("+count+"/"+maxCount+")";
}
events.push(event);
var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1;
while (event.endDate > midnight) {
var thisEvent = JSON.parse(JSON.stringify(event)) // clone object
thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < (today + 24 * 60 * 60 * 1000);
thisEvent.endDate = midnight;
thisEvent.title += " (" + count + "/" + maxCount + ")";
splitEvents.push(thisEvent);
event.startDate = midnight;
count += 1;
midnight = moment(midnight, "x").add(1, "day").format("x"); // next day
}
// Last day
event.title += " ("+count+"/"+maxCount+")";
splitEvents.push(event);
for (event of splitEvents) {
if ((event.endDate > now) && (event.endDate <= future)) {
events.push(event);
}
}
} else {
events.push(event);
}
@ -487,7 +521,6 @@ Module.register("calendar", {
events.sort(function (a, b) {
return a.startDate - b.startDate;
});
return events.slice(0, this.config.maximumEntries);
},
@ -569,6 +602,17 @@ Module.register("calendar", {
return this.getCalendarProperty(url, "timeClass", "");
},
/* calendarNameForUrl(url)
* Retrieves the calendar name for a specific url.
*
* argument url string - Url to look for.
*
* return string - The name of the calendar
*/
calendarNameForUrl: function (url) {
return this.getCalendarProperty(url, "name", "");
},
/* colorForUrl(url)
* Retrieves the color for a specific url.
*
@ -709,6 +753,7 @@ Module.register("calendar", {
for (var e in calendar) {
var event = cloneObject(calendar[e]);
event.symbol = this.symbolsForUrl(url);
event.calendarName = this.calendarNameForUrl(url);
event.color = this.colorForUrl(url);
delete event.url;
eventList.push(event);

View File

@ -273,7 +273,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri
/* isFullDayEvent(event)
* Checks if an event is a fullday event.
*
* argument event obejct - The event object to check.
* argument event object - The event object to check.
*
* return bool - The event is a fullday event.
*/

View File

@ -26,7 +26,6 @@ Module.register("clock",{
analogShowDate: "top", // options: false, 'top', or 'bottom'
secondsColor: "#888888",
timezone: null,
autoTimezone: false
},
// Define required scripts.
getScripts: function() {
@ -40,31 +39,16 @@ Module.register("clock",{
start: function() {
Log.info("Starting module: " + this.name);
if (this.config.autoTimezone) {
this.sendSocketNotification("AUTO_TIMEZONE");
} else {
// Schedule update interval.
var self = this;
setInterval(function() {
self.updateDom();
}, 1000);
}
// Schedule update interval.
var self = this;
setInterval(function() {
self.updateDom();
}, 1000);
// Set locale.
moment.locale(config.language);
},
socketNotificationReceived: function (notification, payload) {
if (notification === "UPDATE_TIMEZONE") {
var self = this;
self.config.timezone = payload.timezone;
setInterval(function() {
self.updateDom();
}, 1000);
}
},
// Override dom generator.
getDom: function() {

View File

@ -1,29 +0,0 @@
var http = require("http");
var NodeHelper = require("node_helper");
module.exports = NodeHelper.create({
start: function () {
},
socketNotificationReceived: function (notification, payload) {
var self = this;
if (notification === "AUTO_TIMEZONE") {
console.log("Loading timezone...");
http.get("http://ip-api.com/json", function (req) {
var data = "";
req.on("data", function (d) {
data += d;
});
req.on("end", function () {
var body = JSON.parse(data);
payload.timezone = body.timezone;
self.sendSocketNotification("UPDATE_TIMEZONE", payload);
});
}).on("error", function () {
payload.error = "Could not figure out the timezone.";
self.sendSocketNotification("UPDATE_TIMEZONE", payload);
});
}
}
});

View File

@ -50,7 +50,7 @@ The following properties can be configured:
| `showIndoorTemperature` | If you have another module that emits the INDOOR_TEMPERATURE notification, the indoor temperature will be displayed <br> **Default value:** `false`
| `onlyTemp` | Show only current Temperature and weather icon without windspeed, sunset, sunrise time and feels like. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `showFeelsLike` | Shows the Feels like temperature weather. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `true`
| `useKMPHWind` | Uses KMPH as units for windspeed. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `false`
| `useKMPHwind` | Uses KMPH as units for windspeed. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `false`
| `useBeaufort` | Pick between using the Beaufort scale for wind speed or using the default units. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `lang` | The language of the days. <br><br> **Possible values:** `en`, `nl`, `ru`, etc ... <br> **Default value:** uses value of _config.language_
| `decimalSymbol` | The decimal symbol to use.<br><br> **Possible values:** `.`, `,` or any other symbol.<br> **Default value:** `.`

View File

@ -11,7 +11,6 @@ Module.register("currentweather",{
// Default module config.
defaults: {
autoLocation: false,
location: false,
locationID: false,
appid: "",
@ -72,7 +71,7 @@ Module.register("currentweather",{
firstEvent: false,
// create a variable to hold the location name based on the API result.
fetchedLocatioName: "",
fetchedLocationName: "",
// Define required scripts.
getScripts: function() {
@ -110,19 +109,8 @@ Module.register("currentweather",{
this.weatherType = null;
this.feelsLike = null;
this.loaded = false;
this.scheduleUpdate(this.config.initialLoadDelay);
if (this.config.autoLocation) {
this.sendSocketNotification("AUTO_LOCATION");
} else {
this.scheduleUpdate(this.config.initialLoadDelay);
}
},
socketNotificationReceived: function (notification, payload) {
if (notification === "UPDATE_LOCATION") {
this.config.location = payload.location;
this.scheduleUpdate(this.config.initialLoadDelay);
}
},
// add extra information of current weather
@ -277,8 +265,8 @@ Module.register("currentweather",{
// Override getHeader method.
getHeader: function() {
if (this.config.appendLocationNameToHeader) {
return this.data.header + " " + this.fetchedLocatioName;
if (this.config.appendLocationNameToHeader && this.data.header !== undefined) {
return this.data.header + " " + this.fetchedLocationName;
}
return this.data.header;

View File

@ -1,29 +0,0 @@
var http = require("http");
var NodeHelper = require("node_helper");
module.exports = NodeHelper.create({
start: function () {
},
socketNotificationReceived: function (notification, payload) {
var self = this;
if (notification === "AUTO_LOCATION") {
console.log("Loading timezone...");
http.get("http://ip-api.com/json", function (req) {
var data = "";
req.on("data", function (d) {
data += d;
});
req.on("end", function () {
var body = JSON.parse(data);
payload.location = body.city + ", " + body.regionName;
self.sendSocketNotification("UPDATE_LOCATION", payload);
});
}).on("error", function () {
payload.error = "Could not figure out the timezone.";
self.sendSocketNotification("UPDATE_LOCATION", payload);
});
}
}
});

View File

@ -46,6 +46,7 @@ MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/t
| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title. <br> The module expects that the module's configuration option `showDescription` is set to `false` (default value). <br><br> When received a _second consecutive time_, shows the full news article in an IFRAME. <br> This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.<br><br>When received the _next consecutive times_, reloads the page and scrolls down by `scrollLength` pixels to paginate through the article.
| `ARTICLE_LESS_DETAILS` | Hides the summary or full news article and only displays the news title of the currently viewed news item.
| `ARTICLE_TOGGLE_FULL` | Toogles article in fullscreen.
| `ARTICLE_INFO_REQUEST` | Causes `newsfeed` to respond with the notification `ARTICLE_INFO_RESPONSE`, the payload of which provides the `title`, `source`, `date`, `desc` and `url` of the current news title.
Note the payload of the sent notification event is ignored.

View File

@ -189,7 +189,7 @@ Module.register("newsfeed",{
fullArticle.style.top = "0";
fullArticle.style.left = "0";
fullArticle.style.border = "none";
fullArticle.src = typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href;
fullArticle.src = this.getActiveItemURL()
fullArticle.style.zIndex = 1;
wrapper.appendChild(fullArticle);
}
@ -210,6 +210,10 @@ Module.register("newsfeed",{
return wrapper;
},
getActiveItemURL: function() {
return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href;
},
/* registerFeeds()
* registers the feeds to be used by the backend.
*/
@ -387,6 +391,14 @@ Module.register("newsfeed",{
} else {
this.showFullArticle();
}
} else if (notification === "ARTICLE_INFO_REQUEST"){
this.sendNotification("ARTICLE_INFO_RESPONSE", {
title: this.newsItems[this.activeItem].title,
source: this.newsItems[this.activeItem].sourceTitle,
date: this.newsItems[this.activeItem].pubdate,
desc: this.newsItems[this.activeItem].description,
url: this.getActiveItemURL()
})
} else {
Log.info(this.name + " - unknown notification, ignoring: " + notification);
}

View File

@ -1,29 +0,0 @@
var http = require("http");
var NodeHelper = require("node_helper");
module.exports = NodeHelper.create({
start: function () {
},
socketNotificationReceived: function (notification, payload) {
var self = this;
if (notification === "AUTO_LOCATION") {
console.log("Loading timezone...");
http.get("http://ip-api.com/json", function (req) {
var data = "";
req.on("data", function (d) {
data += d;
});
req.on("end", function () {
var body = JSON.parse(data);
payload.location = body.city + ", " + body.regionName;
self.sendSocketNotification("UPDATE_LOCATION", payload);
});
}).on("error", function () {
payload.error = "Could not figure out the timezone.";
self.sendSocketNotification("UPDATE_LOCATION", payload);
});
}
}
});

View File

@ -11,7 +11,6 @@ Module.register("weatherforecast",{
// Default module config.
defaults: {
autoLocation: false,
location: false,
locationID: false,
appid: "",
@ -96,20 +95,10 @@ Module.register("weatherforecast",{
this.forecast = [];
this.loaded = false;
this.scheduleUpdate(this.config.initialLoadDelay);
this.updateTimer = null;
if (this.config.autoLocation) {
this.sendSocketNotification("AUTO_LOCATION");
} else {
this.scheduleUpdate(this.config.initialLoadDelay);
}
},
socketNotificationReceived: function (notification, payload) {
if (notification === "UPDATE_LOCATION") {
this.config.location = payload.location;
this.scheduleUpdate(this.config.initialLoadDelay);
}
},
// Override dom generator.

30
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "magicmirror",
"version": "2.7.0-develop",
"version": "2.8.0-develop",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -1368,7 +1368,7 @@
"require-from-string": "^2.0.1",
"rfc6902": "^2.2.2",
"supports-hyperlinks": "^1.0.1",
"vm2": "github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
"vm2": "github:patriksimek/vm2#custom_files",
"voca": "^1.4.0"
},
"dependencies": {
@ -1427,6 +1427,11 @@
"requires": {
"has-flag": "^2.0.0"
}
},
"vm2": {
"version": "github:patriksimek/vm2#468bc1e54e75e766b842830ea775669992a979e0",
"from": "github:patriksimek/vm2#custom_files",
"dev": true
}
}
},
@ -2247,7 +2252,7 @@
},
"eventemitter2": {
"version": "0.4.14",
"resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
"integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
"dev": true
},
@ -2593,7 +2598,7 @@
},
"findup-sync": {
"version": "0.3.0",
"resolved": "http://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
"integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
"dev": true,
"requires": {
@ -2906,7 +2911,7 @@
},
"grunt-cli": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
"integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
"dev": true,
"requires": {
@ -4667,9 +4672,9 @@
}
},
"moment": {
"version": "2.23.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz",
"integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA=="
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"ms": {
"version": "2.0.0",
@ -5813,7 +5818,7 @@
},
"require-uncached": {
"version": "1.0.3",
"resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"dev": true,
"requires": {
@ -5823,7 +5828,7 @@
},
"resolve": {
"version": "1.1.7",
"resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
},
@ -7219,11 +7224,6 @@
"unist-util-stringify-position": "^1.1.1"
}
},
"vm2": {
"version": "github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
"from": "vm2@github:patriksimek/vm2#7e82f90ac705fc44fad044147cb0df09b4c79a57",
"dev": true
},
"voca": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "magicmirror",
"version": "2.7.0-develop",
"version": "2.8.0-develop",
"description": "The open source modular smart mirror platform.",
"main": "js/electron.js",
"scripts": {

View File

@ -7,6 +7,8 @@
"RUNNING": "Päättyy {timeUntilEnd} päästä",
"EMPTY": "Ei tulevia tapahtumia.",
"WEEK": "Viikko {weekNumber}",
"N": "P",
"NNE": "PPI",
"NE": "PI",
@ -25,5 +27,7 @@
"NNW": "PPL",
"UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.",
"UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}."
"UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}.",
"FEELS": "Tuntuu kuin"
}

View File

@ -25,6 +25,7 @@
"WNW": "ЗСЗ",
"NW": "СЗ",
"NNW": "ССЗ",
"FEELS": "По ощущению",
"UPDATE_NOTIFICATION": "Есть обновление для MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Есть обновление для {MODULE_NAME} модуля.",

35
translations/tlh.json Normal file
View File

@ -0,0 +1,35 @@
{
"LOADING": "loS &hellip;",
"TODAY": "DaHjaj",
"TOMORROW": "wa'leS",
"DAYAFTERTOMORROW": "cha'leS",
"RUNNING": "Dor",
"EMPTY": "Sumbe' wanI'.",
"WEEK": "Hogh (terran) {weekNumber}",
"N": "N",
"NNE": "NNE",
"NE": "NE",
"ENE": "ENE",
"E": "chan",
"ESE": "ESE",
"SE": "SE",
"SSE": "SSE",
"S": "S",
"SSW": "SSW",
"SW": "tIng",
"WSW": "WSW",
"W": "W",
"WNW": "WNW",
"NW": "'ev",
"NNW": "NNW",
"UPDATE_NOTIFICATION": " De'chu' MagicMirror² lI'laH.",
"UPDATE_NOTIFICATION_MODULE": "bobcho' {MODULE_NAME} lI'laH De'chu.",
"UPDATE_INFO_SINGLE": "The current installation is {COMMIT_COUNT} commit behind on the {BRANCH_NAME} branch.",
"UPDATE_INFO_MULTIPLE": "The current installation is {COMMIT_COUNT} commits behind on the {BRANCH_NAME} branch.",
"FEELS": "jem"
}

View File

@ -39,7 +39,8 @@ var translations = {
"bg" : "translations/bg.json", // Bulgarian
"cs" : "translations/cs.json", // Czech
"hr" : "translations/hr.json", // Croatian
"sk" : "translations/sk.json" // Slovak
"sk" : "translations/sk.json", // Slovak
"tlh" : "translations/tlh.json" // Klingon
};
if (typeof module !== "undefined") {module.exports = translations;}

71
vendor/package-lock.json generated vendored
View File

@ -193,11 +193,6 @@
"repeat-string": "^1.5.2"
}
},
"font-awesome": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
"integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -230,7 +225,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -248,11 +244,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -265,15 +263,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -376,7 +377,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -386,6 +388,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -398,17 +401,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@ -425,6 +431,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -497,7 +504,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -507,6 +515,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -582,7 +591,8 @@
},
"safe-buffer": {
"version": "5.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -612,6 +622,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -629,6 +640,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -667,11 +679,13 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true
"bundled": true,
"optional": true
},
"yallist": {
"version": "3.0.2",
"bundled": true
"bundled": true,
"optional": true
}
}
},
@ -689,6 +703,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
"optional": true,
"requires": {
"is-glob": "^2.0.0"
}
@ -702,7 +717,8 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"optional": true
},
"invert-kv": {
"version": "1.0.0",
@ -721,7 +737,8 @@
"is-buffer": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
"integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
"optional": true
},
"is-dotfile": {
"version": "1.0.3",
@ -747,7 +764,8 @@
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
@ -761,6 +779,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"optional": true,
"requires": {
"is-extglob": "^1.0.0"
}
@ -789,7 +808,8 @@
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"optional": true
},
"isobject": {
"version": "2.1.0",
@ -804,6 +824,7 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"optional": true,
"requires": {
"is-buffer": "^1.1.5"
}
@ -869,6 +890,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"optional": true,
"requires": {
"remove-trailing-separator": "^1.0.1"
}
@ -1017,12 +1039,14 @@
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"optional": true
},
"repeat-element": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo="
"integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
"optional": true
},
"repeat-string": {
"version": "1.6.1",
@ -1033,7 +1057,8 @@
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"optional": true
},
"set-immediate-shim": {
"version": "1.0.1",