Merge remote-tracking branch 'MichMich/develop' into develop

This commit is contained in:
Kyle Carson 2017-02-05 19:19:58 -06:00
commit cd37ba308c
52 changed files with 617 additions and 107 deletions

72
.dockerignore Normal file
View File

@ -0,0 +1,72 @@
# Various Node ignoramuses.
logs
*.log
npm-debug.log*
pids
*.pid
*.seed
lib-cov
coverage
.grunt
.lock-wscript
build/Release
node_modules
jspm_modules
.npm
.node_repl_history
# Various Windows ignoramuses.
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
*.cab
*.msi
*.msm
*.msp
*.lnk
# Various OSX ignoramuses.
.DS_Store
.AppleDouble
.LSOverride
Icon
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Various Linux ignoramuses.
.fuse_hidden*
.directory
.Trash-*
# Various Magic Mirror ignoramuses and anti-ignoramuses.
# Don't ignore the node_helper core module.
!/modules/node_helper
!/modules/node_helper/**
# Ignore all modules except the default modules.
/modules/**
!/modules/default/**
# Ignore changes to the custom css files.
/css/custom.css
# Ignore unnecessary files for docker
CHANGELOG.md
LICENSE.md
README.md
Gruntfile.js
.*

2
.gitignore vendored
View File

@ -53,7 +53,7 @@ Temporary Items
# Various Magic Mirror ignoramuses and anti-ignoramuses.
# Don't ignore the node_helper nore module.
# Don't ignore the node_helper core module.
!/modules/node_helper
!/modules/node_helper/**

View File

@ -4,6 +4,9 @@ node_js:
- "5.1"
before_script:
- npm install grunt-cli -g
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 5
script:
- grunt
- npm test

View File

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.1.1] - Unreleased
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
@ -16,8 +17,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- 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.
- Run task jsonlint to check translation files.
- Restructured Test Suite
### Added
- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673))
- Calendar-specific support for `maximumEntries`, and ` maximumNumberOfDays`
- Add loaded function to modules, providing an async callback.
- Made default newsfeed module aware of gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures)
@ -35,6 +39,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Option for colored min-temp and max-temp
- Add test e2e helloworld
- Add test e2e enviroment
- Add `chai-as-promised` npm module to devDependencies
- Basic set of tests for clock module
- Run e2e test in Travis
### Fixed
- Update .gitignore to not ignore default modules folder.

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
FROM node:latest
WORKDIR /opt/magic_mirror
COPY . .
COPY /modules unmount_modules
COPY /config unmount_config
ENV NODE_ENV production
ENV MM_PORT 8080
RUN npm install
RUN ["chmod", "+x", "docker-entrypoint.sh"]
EXPOSE $MM_PORT
ENTRYPOINT ["/opt/magic_mirror/docker-entrypoint.sh"]

View File

@ -10,6 +10,8 @@ module.exports = function(grunt) {
"serveronly/*.js", "*.js", "tests/*/*.js", "!modules/default/alert/notificationFx.js",
"!modules/default/alert/modernizr.custom.js", "!modules/default/alert/classie.js",
"config/*",
"translations/translations.js"
]
},
stylelint: {
@ -22,7 +24,7 @@ module.exports = function(grunt) {
},
jsonlint: {
main: {
src: ["package.json", ".eslintrc.json", ".stylelint"],
src: ["package.json", ".eslintrc.json", ".stylelintrc", "translations/*.json", "modules/default/*/translations/*.json"],
options: {
reporter: "jshint"
}

View File

@ -46,8 +46,41 @@ curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/master/installer
**Note:** if you want to debug on Raspberry Pi you can use `npm start dev` which will start the MagicMirror app with Dev Tools enabled.
### Server Only
In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below.
In some cases, you want to start the application without an actual app window. In this case, execute the following command from the MagicMirror folder: `node serveronly`. This will start the server, after which you can open the application in your browser of choice.
#### Docker
MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell:
```bash
docker run -d \
--publish 80:8080 \
--restart always \
--volume ~/magic_mirror/config:/opt/magic_mirror/config \
--volume ~/magic_mirror/modules:/opt/magic_mirror/modules \
--name magic_mirror \
MichMich/MagicMirror
```
| **Volumes** | **Description** |
| --- | --- |
| `/opt/magic_mirror/config` | Mount this volume to insert your own config into the docker container. |
| `/opt/magic_mirror/modules` | Mount this volume to add your own custom modules into the docker container. |
You may need to add your Docker Host IP to your `ipWhitelist` option. If you have some issues setting up this configuration, check [this forum post](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto).
```javascript
var config = {
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:172.17.0.1"]
};
```
#### Manual
1. Download and install the latest Node.js version.
2. Clone the repository and check out the master branch: `git clone https://github.com/MichMich/MagicMirror`
3. Enter the repository: `cd ~/MagicMirror`
4. Install and run the app: `npm install && node serveronly`
### Raspberry Configuration & Auto Start.

11
docker-entrypoint.sh Normal file
View File

@ -0,0 +1,11 @@
#!/bin/bash
if [ ! -f /opt/magic_mirror/modules ]; then
cp -R /opt/magic_mirror/unmount_modules/. /opt/magic_mirror/modules
fi
if [ ! -f /opt/magic_mirror/config ]; then
cp -R /opt/magic_mirror/unmount_config/. /opt/magic_mirror/config
fi
node serveronly

View File

@ -21,6 +21,11 @@ if (process.env.MM_CONFIG_FILE) {
global.configuration_file = process.env.MM_CONFIG_FILE;
}
//Hotfix PullRequest #673
if (process.env.MM_PORT) {
global.mmPort = process.env.MM_PORT;
}
// The next part is here to prevent a major exception when there
// is no internet connection. This could probable be solved better.
process.on("uncaughtException", function (err) {

View File

@ -7,8 +7,12 @@
* MIT Licensed.
*/
var port = 8080;
if (typeof(mmPort) !== "undefined") {
port = mmPort;
}
var defaults = {
port: 8080,
port: port,
kioskmode: false,
electronOptions: {},
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],

View File

@ -37,7 +37,7 @@ var Server = function(config, callback) {
app.use("/modules", express.static(path.resolve(global.root_path + "/modules")));
app.use("/vendor", express.static(path.resolve(global.root_path + "/vendor")));
app.use("/translations", express.static(path.resolve(global.root_path + "/translations")));
app.use("/tests/confs", express.static(path.resolve(global.root_path + "/tests/confs")));
app.use("/tests/configs", express.static(path.resolve(global.root_path + "/tests/configs")));
app.get("/version", function(req,res) {
res.send(global.version);

View File

@ -1,4 +1,4 @@
{
"sysTitle": "MagicMirror Уведомление",
"welcome": "Добро пожаловать, старт был успешным!""
"welcome": "Добро пожаловать, старт был успешным!"
}

View File

@ -6,7 +6,8 @@
"scripts": {
"start": "sh run-start.sh",
"postinstall": "sh installers/postinstall/postinstall.sh",
"test": "./node_modules/mocha/bin/mocha $(find tests -path '*js*' ! -ipath '*e2e*')",
"test": "./node_modules/mocha/bin/mocha tests --recursive",
"test:unit": "./node_modules/mocha/bin/mocha tests/unit --recursive",
"test:e2e": "./node_modules/mocha/bin/mocha tests/e2e --recursive"
},
"repository": {
@ -30,6 +31,7 @@
"homepage": "https://github.com/MichMich/MagicMirror#readme",
"devDependencies": {
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"grunt": "latest",
"grunt-eslint": "latest",
"grunt-jsonlint": "latest",

View File

@ -0,0 +1,29 @@
/* Magic Mirror Test config for default clock module
*
* By Sergey Morozov
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 12,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center"
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,29 @@
/* Magic Mirror Test config for default clock module
*
* By Sergey Morozov
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 24,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center"
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,32 @@
/* Magic Mirror Test config for default clock module
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 12,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center",
config: {
displaySeconds: false
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,32 @@
/* Magic Mirror Test config for default clock module
*
* By Sergey Morozov
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 12,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center",
config: {
showPeriodUpper: true
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,29 @@
/* Magic Mirror Test config for default clock module
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "es",
timeFormat: 12,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center"
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,29 @@
/* Magic Mirror Test config for default clock module
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "es",
timeFormat: 24,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center"
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -0,0 +1,32 @@
/* Magic Mirror Test config for default clock module
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
*/
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "es",
timeFormat: 12,
units: "metric",
electronOptions: {
webPreferences: {
nodeIntegration: true,
},
},
modules: [
{
module: "clock",
position: "middle_center",
config: {
showPeriodUpper: true
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = config;}

View File

@ -3,9 +3,6 @@ const path = require("path");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/confs/env.js";
var electronPath = path.join(__dirname, "../../", "node_modules", ".bin", "electron");
if (process.platform === "win32") {
@ -24,9 +21,14 @@ global.before(function () {
chai.use(chaiAsPromised);
});
describe("Test enviroment app electron", function () {
describe("Electron app environment", function () {
this.timeout(10000);
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/env.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
@ -36,12 +38,12 @@ describe("Test enviroment app electron", function () {
});
it("open a window app and test if is open", function () {
it("is set to open new app window", function () {
return app.client.waitUntilWindowLoaded()
.getWindowCount().should.eventually.equal(1);
});
it("tests the title", function () {
it("sets correct window title", function () {
return app.client.waitUntilWindowLoaded()
.getTitle().should.eventually.equal("Magic Mirror");
});

View File

@ -0,0 +1,101 @@
const Application = require("spectron").Application;
const path = require("path");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron");
if (process.platform === "win32") {
electronPath += ".cmd";
}
var appPath = path.join(__dirname, "../../../js/electron.js");
var app = new Application({
path: electronPath,
args: [appPath]
});
global.before(function () {
chai.should();
chai.use(chaiAsPromised);
});
describe("Clock set to spanish language module", function () {
this.timeout(10000);
describe("with default 24hr clock config", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows date with correct format", function () {
const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sabado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 24hr format", function() {
const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
describe("with default 12hr clock config", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows date with correct format", function () {
const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sabado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 12hr format", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
describe("with showPeriodUpper config enabled", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows 12hr time with upper case AM/PM", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
});

View File

@ -0,0 +1,123 @@
const Application = require("spectron").Application;
const path = require("path");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron");
if (process.platform === "win32") {
electronPath += ".cmd";
}
var appPath = path.join(__dirname, "../../../js/electron.js");
var app = new Application({
path: electronPath,
args: [appPath]
});
global.before(function () {
chai.should();
chai.use(chaiAsPromised);
});
describe("Clock module", function () {
this.timeout(10000);
describe("with default 24hr clock config", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows date with correct format", function () {
const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 24hr format", function() {
const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
describe("with default 12hr clock config", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows date with correct format", function () {
const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 12hr format", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
describe("with showPeriodUpper config enabled", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows 12hr time with upper case AM/PM", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
describe("with displaySeconds config disabled", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});
afterEach(function (done) {
app.stop().then(function() { done(); });
});
it("shows 12hr time without seconds am/pm", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/;
return app.client.waitUntilWindowLoaded()
.getText(".clock .time").should.eventually.match(timeRegex);
});
});
});

View File

@ -3,9 +3,6 @@ const path = require("path");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/confs/helloworld.js";
var electronPath = path.join(__dirname, "../../../", "node_modules", ".bin", "electron");
if (process.platform === "win32") {
@ -27,6 +24,11 @@ global.before(function () {
describe("Test helloworld module", function () {
this.timeout(10000);
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js";
});
beforeEach(function (done) {
app.start().then(function() { done(); } );
});

View File

@ -1,7 +1,7 @@
var chai = require("chai");
var expect = chai.expect;
var classMM = require("../../js/class.js"); // require for load module.js
var moduleMM = require("../../js/module.js")
var classMM = require("../../../js/class.js"); // require for load module.js
var moduleMM = require("../../../js/module.js")
describe("Test function cmpVersions in js/module.js", function() {

View File

@ -3,8 +3,8 @@ var path = require("path");
var chai = require("chai");
var expect = chai.expect;
describe("Test global.root_path, set in js/app.js", function() {
var appMM = require("../../js/app.js")
describe("'global.root_path' set in js/app.js", function() {
var appMM = require("../../../js/app.js")
var expectedSubPaths = [
"modules",
@ -17,7 +17,7 @@ describe("Test global.root_path, set in js/app.js", function() {
];
expectedSubPaths.forEach(subpath => {
it(`should contain a file/folder "${subpath}"`, function() {
it(`contains a file/folder "${subpath}"`, function() {
expect(fs.existsSync(path.join(global.root_path, subpath))).to.equal(true);
});
});

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Besig om te laai …",
/* CALENDAR */
"TODAY": "Vandag",
"TOMORROW": "Môre",
"DAYAFTERTOMORROW": "Oormôre",
"RUNNING": "Eindig in",
"EMPTY": "Geen komende gebeurtenisse.",
/* WEATHER */
"N": "N",
"NNE": "NNO",
"NE": "NO",
@ -27,7 +24,6 @@
"NW": "NW",
"NNW": "NNW",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² update beskikbaar.",
"UPDATE_NOTIFICATION_MODULE": "Update beskikbaar vir MODULE_NAME module.",
"UPDATE_INFO": "Die huidige installasie is COMMIT_COUNT agter op die BRANCH_NAME branch."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Indlæser …",
/* CALENDAR */
"TODAY": "I dag",
"TOMORROW": "I morgen",
"DAYAFTERTOMORROW": "I overmorgen",
"RUNNING": "Slutter om",
"EMPTY": "Ingen kommende begivenheder.",
/* WEATHER */
"N": "N",
"NNE": "NNØ",
"NE": "NØ",
@ -28,7 +25,6 @@
"NNW": "NNV",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² opdatering tilgængelig.",
"UPDATE_NOTIFICATION_MODULE": "Opdatering tilgængelig for MODULE_NAME modulet.",
"UPDATE_INFO": "Den nuværende installation er COMMIT_COUNT bagud på BRANCH_NAME branch'en."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Lade …",
/* CALENDAR */
"TODAY": "Heute",
"TOMORROW": "Morgen",
"DAYAFTERTOMORROW": "Übermorgen",
"RUNNING": "noch",
"EMPTY": "Keine Termine.",
/* WEATHER */
"N": "N",
"NNE": "NNO",
"NE": "NO",
@ -27,7 +24,6 @@
"NW": "NW",
"NNW": "NNW",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "Aktualisierung für MagicMirror² verfügbar.",
"UPDATE_NOTIFICATION_MODULE": "Aktualisierung für das MODULE_NAME Modul verfügbar.",
"UPDATE_INFO": "Die aktuelle Installation ist COMMIT_COUNT hinter dem BRANCH_NAME branch."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Loading …",
/* CALENDAR */
"TODAY": "Today",
"TOMORROW": "Tomorrow",
"DAYAFTERTOMORROW": "The day after tomorrow",
"RUNNING": "Ends in",
"EMPTY": "No upcoming events.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",
@ -27,7 +24,6 @@
"NW": "NW",
"NNW": "NNW",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² update available.",
"UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.",
"UPDATE_INFO": "The current installation is COMMIT_COUNT behind on the BRANCH_NAME branch."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Cargando …",
/* CALENDAR */
"TODAY": "Hoy",
"TOMORROW": "Mañana",
"DAYAFTERTOMORROW": "Pasado mañana",
"RUNNING": "Termina en",
"EMPTY": "No hay eventos programados.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",
@ -27,7 +24,6 @@
"NW": "NO",
"NNW": "NNO",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² actualización disponible.",
"UPDATE_NOTIFICATION_MODULE": "Disponible una actualización para el módulo MODULE_NAME.",
"UPDATE_INFO": "Tu actual instalación está COMMIT_COUNT cambios detrás de la rama BRANCH_NAME."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Lataa …",
/* CALENDAR */
"TODAY": "Tänään",
"TOMORROW": "Huomenna",
"DAYAFTERTOMORROW": "Ylihuomenna",
"RUNNING": "Meneillään",
"EMPTY": "Ei tulevia tapahtumia.",
/* WEATHER */
"N": "P",
"NNE": "PPI",
"NE": "PI",
@ -27,7 +24,6 @@
"NW": "PL",
"NNW": "PPL",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.",
"UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille MODULE_NAME."
}

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Chargement …",
/* CALENDAR */
"TODAY": "Aujourd'hui",
"TOMORROW": "Demain",
"RUNNING": "Se termine dans",
"EMPTY": "Aucun RDV.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Bezich mei laden …",
/* CALENDAR */
"TODAY": "Hjoed",
"TOMORROW": "Moarn",
"DAYAFTERTOMORROW": "Oaremoarn",
"RUNNING": "Einigest oer",
"EMPTY": "Gjin plande ôfspraken.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Φόρτωση …",
/* CALENDAR */
"TODAY": "Σήμερα",
"TOMORROW": "Αύριο",
"RUNNING": "Λήγει σε",
"EMPTY": "Δεν υπάρχουν προσεχείς εκδηλώσεις.",
/* WEATHER */
"N": "B",
"NNE": "BBA",
"NE": "BA",

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Betöltés …",
/* CALENDAR */
"TODAY": "Ma",
"TOMORROW": "Holnap",
"DAYAFTERTOMORROW": "Holnapután",
"RUNNING": "Vége lesz",
"EMPTY": "Nincs közelgő esemény.",
/* WEATHER */
"N": "É",
"NNE": "ÉÉK",
"NE": "ÉK",
@ -27,8 +24,7 @@
"NW": "ÉNy",
"NNW": "ÉÉNy",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² elérhető egy frissítés!",
"UPDATE_NOTIFICATION_MODULE": "A frissítés MODULE_NAME modul néven érhető el.",
"UPDATE_INFO": "A jelenlegi telepítés COMMIT_COUNT mögött BRANCH_NAME ágon található."
}
}

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Hleð upp …",
/* CALENDAR */
"TODAY": "Í dag",
"TOMORROW": "Á morgun",
"DAYAFTERTOMORROW": "Ekki á morgun, heldur hinn",
"RUNNING": "Endar eftir",
"EMPTY": "Ekkert framundan.",
/* WEATHER */
"N": "N",
"NNE": "NNA",
"NE": "NA",
@ -27,7 +24,6 @@
"NW": "NV",
"NNW": "NNV",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² uppfærsla í boði.",
"UPDATE_NOTIFICATION_MODULE": "Uppfærsla í boði fyrir MODULE_NAME module.",
"UPDATE_INFO": "Núverandi kerfi er COMMIT_COUNT á eftir BRANCH_NAME branchinu."

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Caricamento in corso …",
/* CALENDAR */
"TODAY": "Oggi",
"TOMORROW": "Domani",
"RUNNING": "Termina entro",
"EMPTY": "Nessun evento in arrivo.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "ローディング …",
"LOADING": "ローディング …",
/* CALENDAR */
"TODAY": "今日",
"TOMORROW": "明日",
"RUNNING": "で終わります",
"EMPTY": "直近のイベントはありません",
/* WEATHER */
"N": "北",
"NNE": "北北東",
"NE": "北東",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Laster …",
/* CALENDAR */
"TODAY": "I dag",
"TOMORROW": "I morgen",
"RUNNING": "Slutter om",
"EMPTY": "Ingen kommende arrangementer.",
/* WEATHER */
"N": "N",
"NNE": "NNØ",
"NE": "NØ",

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Bezig met laden …",
/* CALENDAR */
"TODAY": "Vandaag",
"TOMORROW": "Morgen",
"DAYAFTERTOMORROW": "Overmorgen",
"RUNNING": "Eindigt over",
"EMPTY": "Geen geplande afspraken.",
/* WEATHER */
"N": "N",
"NNE": "NNO",
"NE": "NO",
@ -27,7 +24,6 @@
"NW": "NW",
"NNW": "NNW",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² update beschikbaar.",
"UPDATE_NOTIFICATION_MODULE": "Update beschikbaar voor MODULE_NAME module.",
"UPDATE_INFO": "De huidige installatie loopt COMMIT_COUNT achter op de BRANCH_NAME branch."

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Lastar …",
/* CALENDAR */
"TODAY": "I dag",
"TOMORROW": "I morgon",
"RUNNING": "Sluttar om",
"EMPTY": "Ingen komande hendingar.",
/* WEATHER */
"N": "N",
"NNE": "NNA",
"NE": "NA",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Ładowanie …",
/* CALENDAR */
"TODAY": "Dziś",
"TOMORROW": "Jutro",
"RUNNING": "Koniec za",
"EMPTY": "Brak wydarzeń.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",
@ -26,7 +23,6 @@
"NW": "NW",
"NNW": "NNW",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "Dostępna jest aktualizacja MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Dostępna jest aktualizacja modułu MODULE_NAME.",
"UPDATE_INFO": "Zainstalowana wersja odbiega o COMMIT_COUNT commitów od gałęzi BRANCH_NAME."

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "A carregar …",
/* CALENDAR */
"TODAY": "Hoje",
"TOMORROW": "Amanhã",
"RUNNING": "Termina em",
"EMPTY": "Sem eventos a chegar.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Carregando …",
/* CALENDAR */
"TODAY": "Hoje",
"TOMORROW": "Amanhã",
"RUNNING": "Acaba em",
"EMPTY": "Nenhum evento novo.",
/* WEATHER */
"N": "N",
"NNE": "NNE",
"NE": "NE",

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Загрузка …",
/* CALENDAR */
"TODAY": "Сегодня",
"TOMORROW": "Завтра",
"DAYAFTERTOMORROW": "Послезавтра",
"RUNNING": "Заканчивается через",
"EMPTY": "Нет предстоящих событий",
/* WEATHER */
"N": "С",
"NNE": "ССВ",
"NE": "СВ",
@ -27,7 +24,6 @@
"NW": "СЗ",
"NNW": "ССЗ",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "Есть обновление для MagicMirror².",
"UPDATE_NOTIFICATION_MODULE": "Есть обновление для MODULE_NAME модуля.",
"UPDATE_INFO": "Данная инсталляция позади BRANCH_NAME ветки на COMMIT_COUNT коммитов."

View File

@ -1,15 +1,12 @@
{
/* GENERAL */
"LOADING": "Laddar …",
/* CALENDAR */
"TODAY": "Idag",
"TOMORROW": "Imorgon",
"DAYAFTERTOMORROW": "Iövermorgon",
"RUNNING": "Slutar",
"EMPTY": "Inga kommande händelser.",
/* WEATHER */
"N": "N",
"NNE": "NNO",
"NE": "NO",
@ -27,7 +24,6 @@
"NW": "NV",
"NNW": "NNV",
/* UPDATE INFO */
"UPDATE_NOTIFICATION": "MagicMirror² uppdatering finns tillgänglig.",
"UPDATE_NOTIFICATION_MODULE": "Uppdatering finns tillgänglig av MODULE_NAME modulen.",
"UPDATE_INFO": "Denna installation ligger COMMIT_COUNT steg bakom BRANCH_NAME grenen."

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "Yükleniyor …",
/* CALENDAR */
"TODAY": "Bugün",
"TOMORROW": "Yarın",
"RUNNING": "Biten",
"EMPTY": "Yakında etkinlik yok.",
/* WEATHER */
"N": "K",
"NNE": "KKD",
"NE": "KD",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "正在加载 …",
/* CALENDAR */
"TODAY": "今天",
"TOMORROW": "明天",
"RUNNING": "结束日期",
"EMPTY": "没有更多的活动。",
/* WEATHER */
"N": "北风",
"NNE": "北偏东风",
"NE": "东北风",

View File

@ -1,14 +1,11 @@
{
/* GENERAL */
"LOADING": "正在加載 …",
/* CALENDAR */
"TODAY": "今天",
"TOMORROW": "明天",
"RUNNING": "結束日期",
"EMPTY": "沒有更多的活動。",
/* WEATHER */
"N": "北風",
"NNE": "北偏東風",
"NE": "東北風",