Fix all issues from ESLint (#4730)

* Cherry picks the ES language changes from #4690

* Fix small issues found in linting

* * Fix all but one eslint complaint in the bundled code
* Add eslint and js-beautify rc files into the repo
This commit is contained in:
Sulka Haro
2019-07-17 15:04:57 +03:00
committed by GitHub
parent b04476e1f9
commit 8f25a6e7a4
36 changed files with 2567 additions and 2946 deletions
+14
View File
@@ -0,0 +1,14 @@
module.exports = {
"plugins": [ ],
"extends": [
"eslint:recommended"
],
"parser": "babel-eslint",
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true,
"jquery": true
}
};
+16
View File
@@ -0,0 +1,16 @@
{
"indent_size": 2
, "indent_char": " "
, "comma_first": true
, "keep-array-indentation": true
, "space_after_named_function": true
, "space_after_anon_function": true
, "end_with_newline": true
, "brace_style": "collapse,preserve-inline"
, "space_in_brace": true
, "space-in-paren": false
, "break-chained-methods": false
, "max-preserve-newlines": 2
, "space-after-anon-function": false
, "indent-empty-lines": false
}
+6 -6
View File
@@ -57,7 +57,7 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
callback();
}
return;
};
}
$status.hide().text(translate('Deleting records ...')).fadeIn('slow');
$.ajax({
@@ -83,11 +83,11 @@ cleanstatusdb.actions[1].init = function init(client, callback) {
$status.hide();
var numDays = '<br/>'
+ '<label for="admin_devicestatus_days">'
+ translate('Number of Days to Keep:')
+ ' <input id="admin_devicestatus_days" value="30" size="3" min="1"/>'
+ '</label>';
var numDays = '<br/>' +
'<label for="admin_devicestatus_days">' +
translate('Number of Days to Keep:') +
' <input id="admin_devicestatus_days" value="30" size="3" min="1"/>' +
'</label>';
$('#admin_' + cleanstatusdb.name + '_1_html').html(numDays);
+4 -4
View File
@@ -18,6 +18,7 @@ futureitems.actions = [
, description: 'This task find and remove treatments in the future.'
, buttonLabel: 'Remove treatments in the future'
}
, {
name: 'Find and remove entries in the future'
, description: 'This task find and remove CGM data in the future created by uploader with wrong date/time.'
@@ -58,7 +59,7 @@ futureitems.actions[0].init = function init(client, callback) {
for (var t = 0; t < treatments.length; t++) {
showOneTreatment(treatments[t], table);
}
};
}
$status.hide().text(translate('Loading database ...')).fadeIn('slow');
var nowiso = new Date().toISOString();
@@ -89,7 +90,7 @@ futureitems.actions[0].code = function deleteRecords(client, callback) {
callback();
}
return;
};
}
function deleteRecordById (_id) {
$.ajax({
@@ -144,7 +145,7 @@ futureitems.actions[1].code = function deleteRecords(client, callback) {
callback();
}
return;
};
}
function deteleteRecordById (_id) {
$.ajax({
@@ -158,7 +159,6 @@ futureitems.actions[1].code = function deleteRecords(client, callback) {
});
}
$status.hide().text(translate('Deleting records ...')).fadeIn('slow');
for (var i = 0; i < futureitems.entriesrecords.length; i++) {
deteleteRecordById(futureitems.entriesrecords[i]._id);
+22 -19
View File
@@ -1,5 +1,7 @@
'use strict';
const _ = require('lodash');
var roles = {
name: 'roles'
, label: 'Roles - Groups of People, Devices, etc'
@@ -90,19 +92,18 @@ function reload (client, callback) {
function genDialog (client) {
var ret =
'<div id="editroledialog" style="display:none" title="' + client.translate('Edit Role') + '">'
+ ' <label for="edrole_name">'
+ client.translate('Name')
+ ' <input id="edrole_name" placeholder="' + client.translate('admin, school, family, etc') + '"/>'
+ ' </label>'
+ ' <br>'
+ ' <label for="edrole_permissions">' + client.translate('Permissions') + '</label>'
+ ' <textarea id="edrole_permissions" rows="3" style="width:300px"></textarea><br>'
+ ' <br>'
+ ' <label for="edrole_notes">' + client.translate('Additional Notes, Comments') + '</label>'
+ ' <textarea id="edrole_notes" style="width:300px"></textarea><br>'
+ ' </div>'
;
'<div id="editroledialog" style="display:none" title="' + client.translate('Edit Role') + '">' +
' <label for="edrole_name">' +
client.translate('Name') +
' <input id="edrole_name" placeholder="' + client.translate('admin, school, family, etc') + '"/>' +
' </label>' +
' <br>' +
' <label for="edrole_permissions">' + client.translate('Permissions') + '</label>' +
' <textarea id="edrole_permissions" rows="3" style="width:300px"></textarea><br>' +
' <br>' +
' <label for="edrole_notes">' + client.translate('Additional Notes, Comments') + '</label>' +
' <textarea id="edrole_notes" style="width:300px"></textarea><br>' +
' </div>';
return $(ret);
}
@@ -112,9 +113,10 @@ function openDialog (role, client) {
width: 360
, height: 360
, buttons: [
{ text: client.translate('Save'),
class: 'leftButton',
click: function() {
{
text: client.translate('Save')
, class: 'leftButton'
, click: function() {
role.name = $('#edrole_name').val();
role.permissions =
@@ -131,9 +133,10 @@ function openDialog (role, client) {
$(self).dialog('close');
});
}
},
{ text: client.translate('Cancel'),
click: function () { $( this ).dialog('close'); }
}
, {
text: client.translate('Cancel')
, click: function() { $(this).dialog('close'); }
}
]
, open: function() {
+24 -21
View File
@@ -1,5 +1,7 @@
'use strict';
const _ = require('lodash');
var subjects = {
name: 'subjects'
, label: 'Subjects - People, Devices, etc'
@@ -89,21 +91,20 @@ function reload (client, callback) {
function genDialog (client) {
var ret =
'<div id="editsubjectdialog" style="display:none" title="' + client.translate('Edit Subject') + '">'
+ ' <label for="edsub_name">'
+ client.translate('Name')
+ ' <input id="edsub_name" placeholder="' + client.translate('person, device, etc') + '"/>'
+ ' </label>'
+ ' <br>'
+ ' <label for="edsub_roles">'
+ client.translate('Roles')
+ ' <input id="edsub_roles" placeholder="' + client.translate('role1, role2') + '"/>'
+ ' </label>'
+ ' <br>'
+ ' <label for="edsub_notes">' + client.translate('Additional Notes, Comments') + '</label>'
+ ' <textarea id="edsub_notes" style="width:300px"></textarea><br>'
+ ' </div>'
;
'<div id="editsubjectdialog" style="display:none" title="' + client.translate('Edit Subject') + '">' +
' <label for="edsub_name">' +
client.translate('Name') +
' <input id="edsub_name" placeholder="' + client.translate('person, device, etc') + '"/>' +
' </label>' +
' <br>' +
' <label for="edsub_roles">' +
client.translate('Roles') +
' <input id="edsub_roles" placeholder="' + client.translate('role1, role2') + '"/>' +
' </label>' +
' <br>' +
' <label for="edsub_notes">' + client.translate('Additional Notes, Comments') + '</label>' +
' <textarea id="edsub_notes" style="width:300px"></textarea><br>' +
' </div>';
return $(ret);
}
@@ -113,9 +114,10 @@ function openDialog (subject, client) {
width: 360
, height: 300
, buttons: [
{ text: client.translate('Save'),
class: 'leftButton',
click: function() {
{
text: client.translate('Save')
, class: 'leftButton'
, click: function() {
subject.name = $('#edsub_name').val();
subject.roles =
_.chain($('#edsub_roles').val().toLowerCase().split(/[;, ]/))
@@ -130,9 +132,10 @@ function openDialog (subject, client) {
$(self).dialog('close');
});
}
},
{ text: client.translate('Cancel'),
click: function () { $( this ).dialog('close'); }
}
, {
text: client.translate('Cancel')
, click: function() { $(this).dialog('close'); }
}
]
, open: function() {
+19 -18
View File
@@ -35,15 +35,14 @@ function init(client, $) {
}
function isProfileEnabled (profiles) {
return client.settings.enable.indexOf('profile') > -1
&& client.settings.extendedSettings.profile
&& client.settings.extendedSettings.profile.multiple
&& profiles.length > 1;
return client.settings.enable.indexOf('profile') > -1 &&
client.settings.extendedSettings.profile &&
client.settings.extendedSettings.profile.multiple &&
profiles.length > 1;
}
function isTouch () {
try { document.createEvent('TouchEvent'); return true; }
catch (e) { return false; }
try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; }
}
function setDateAndTime (time) {
@@ -236,8 +235,8 @@ function init(client, $) {
$('#bc_bg').css('background-color', '');
}
$('#bc_inzulinbg').text(record.insulinbg.toFixed(2));
$('#bc_inzulinbg').attr('title',
'Target BG range: '+targetBGLow + ' - ' + targetBGHigh +
$('#bc_inzulinbg').attr('title'
, 'Target BG range: ' + targetBGLow + ' - ' + targetBGHigh +
'\nISF: ' + isf +
'\nBG diff: ' + record.bgdiff.toFixed(1)
);
@@ -351,7 +350,6 @@ function init(client, $) {
return;
}
// Calculate event time from date & time
record.eventTime = new Date();
if ($('#bc_othertime').is(':checked')) {
@@ -515,6 +513,7 @@ function init(client, $) {
function buildConfirmText (data) {
var text = [
translate('Please verify that the data entered is correct') + ': '
, translate('Event Type') + ': ' + translate(data.eventType)
];
@@ -541,8 +540,8 @@ function init(client, $) {
function confirmPost (data) {
if (window.confirm(buildConfirmText(data))) {
$.ajax({
method: 'POST',
url: '/api/v1/treatments/'
method: 'POST'
, url: '/api/v1/treatments/'
, headers: client.headers()
, data: data
}).done(function treatmentSaved (response) {
@@ -653,7 +652,7 @@ function init(client, $) {
for (var i = 0; i < records.length; i++) {
var r = records[i];
$('#bc_quickpick').append('<option value="' + i + '">' + r.name + ' (' + r.carbs + ' g)</option>');
};
}
$('#bc_quickpick').val(-1);
$('#bc_quickpick').change(quickpickChange);
};
@@ -721,8 +720,9 @@ function init(client, $) {
width: 640
, height: 400
, buttons: [
{ text: translate('Add'),
click: function() {
{
text: translate('Add')
, click: function() {
var index = $('#bc_data').val();
var portions = parseFloat($('#bc_addportions').val().replace(',', '.'));
if (index !== null && !isNaN(portions) && portions > 0) {
@@ -732,10 +732,11 @@ function init(client, $) {
boluscalc.calculateInsulin();
}
}
},
{ text: translate('Reload database'),
class: 'leftButton',
click: boluscalc.loadFoodDatabase
}
, {
text: translate('Reload database')
, class: 'leftButton'
, click: boluscalc.loadFoodDatabase
}
]
, open: function() {
+22 -25
View File
@@ -117,34 +117,32 @@ function init (client, serverSettings, $) {
}
function storeInBrowser (data) {
for (var k in data) {
if (data.hasOwnProperty(k)) {
Object.keys(data).forEach(k => {
storage.set(k, data[k]);
}
}
});
}
storeInBrowser({
units: $('input:radio[name=units-browser]:checked').val(),
alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked'),
alarmHigh: $('#alarm-high-browser').prop('checked'),
alarmLow: $('#alarm-low-browser').prop('checked'),
alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked'),
alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked'),
alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15,
alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked'),
alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30,
nightMode: $('#nightmode-browser').prop('checked'),
editMode: $('#editmode-browser').prop('checked'),
showRawbg: $('input:radio[name=show-rawbg]:checked').val(),
customTitle: $('input#customTitle').prop('value'),
theme: $('input:radio[name=theme-browser]:checked').val(),
timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val()),
language: $('#language').val(),
scaleY: $('#scaleY').val(),
basalrender: $('#basalrender').val(),
showPlugins: checkedPluginNames(),
storageVersion: STORAGE_VERSION
units: $('input:radio[name=units-browser]:checked').val()
, alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked')
, alarmHigh: $('#alarm-high-browser').prop('checked')
, alarmLow: $('#alarm-low-browser').prop('checked')
, alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked')
, alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked')
, alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15
, alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked')
, alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30
, nightMode: $('#nightmode-browser').prop('checked')
, editMode: $('#editmode-browser').prop('checked')
, showRawbg: $('input:radio[name=show-rawbg]:checked').val()
, customTitle: $('input#customTitle').prop('value')
, theme: $('input:radio[name=theme-browser]:checked').val()
, timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val())
, language: $('#language').val()
, scaleY: $('#scaleY').val()
, basalrender: $('#basalrender').val()
, showPlugins: checkedPluginNames()
, storageVersion: STORAGE_VERSION
});
event.preventDefault();
@@ -213,5 +211,4 @@ function init (client, serverSettings, $) {
return settings;
}
module.exports = init;
+5 -7
View File
@@ -13,9 +13,9 @@ function init ($) {
$('#drawer').find('.tip').tooltip();
}
$.fn.tooltip.defaults = {
fade: true,
gravity: 'n',
opacity: 0.75
fade: true
, gravity: 'n'
, opacity: 0.75
};
var querystring = queryParms();
@@ -49,11 +49,11 @@ function init ($) {
window.location.href = url;
}
function queryParms () {
var params = {};
if (location.search) {
location.search.substr(1).split('&').forEach(function(item) {
// eslint-disable-next-line no-useless-escape
params[item.split('=')[0]] = item.split('=')[1].replace(/[_\+]/g, ' ');
});
}
@@ -61,8 +61,7 @@ function init ($) {
}
function isTouch () {
try { document.createEvent('TouchEvent'); return true; }
catch (e) { return false; }
try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; }
}
function closeLastOpenedDrawer (callback) {
@@ -114,7 +113,6 @@ function init ($) {
style.width = '350px';
}
$(id).css(style);
});
+6 -4
View File
@@ -33,9 +33,9 @@ client.render = function render(xhr) {
// Convert BG to mmol/L if necessary.
if (window.serverSettings.settings.units == 'mmol') {
var displayValue = Nightscout.units.mgdlToMMOL(rec.sgv);
var displayValue = window.Nightscout.units.mgdlToMMOL(rec.sgv);
} else {
var displayValue = rec.sgv;
displayValue = rec.sgv;
}
// Insert the BG value text.
@@ -53,8 +53,8 @@ client.render = function render(xhr) {
// Generate and insert the clock.
let timeDivisor = (client.settings.timeFormat) ? client.settings.timeFormat : 12;
let today = new Date(),
h = today.getHours() % timeDivisor;
let today = new Date()
, h = today.getHours() % timeDivisor;
if (timeDivisor == 12) {
h = (h == 0) ? 12 : h; // In the case of 00:xx, change to 12:xx for 12h time
}
@@ -65,6 +65,8 @@ client.render = function render(xhr) {
if (m < 10) m = "0" + m;
$('#clock').text(h + ":" + m);
// defined in the template this is loaded into
// eslint-disable-next-line no-undef
if (clockFace == 'clock-color') {
var bgHigh = window.serverSettings.settings.thresholds.bgHigh;
+11 -16
View File
@@ -60,6 +60,7 @@ client.init = function init(callback) {
console.log('Application appears to be online');
$('#centerMessagePanel').hide();
client.load(serverSettings, callback);
// eslint-disable-next-line no-unused-vars
}).fail(function fail (jqXHR, textStatus, errorThrown) {
// check if we couldn't reach the server at all, show offline message
@@ -94,15 +95,13 @@ client.load = function load(serverSettings, callback) {
, FORMAT_TIME_12_COMPACT = '%-I:%M'
, FORMAT_TIME_24 = '%H:%M%'
, FORMAT_TIME_12_SCALE = '%-I %p'
, FORMAT_TIME_24_SCALE = '%H'
;
, FORMAT_TIME_24_SCALE = '%H';
var history = 48;
var chart
, socket
, isInitialData = false
, prevSGV
, opacity = { current: 1, DAY: 1, NIGHT: 0.5 }
, clientAlarms = {}
, alarmInProgress = false
@@ -111,8 +110,7 @@ client.load = function load(serverSettings, callback) {
, currentAnnouncement
, alarmSound = 'alarm.mp3'
, urgentAlarmSound = 'alarm2.mp3'
, previousNotifyTimestamp
;
, previousNotifyTimestamp;
client.entryToDate = function entryToDate (entry) { return new Date(entry.mills); };
@@ -130,8 +128,7 @@ client.load = function load(serverSettings, callback) {
, minorPills = $('.bgStatus .minorPills')
, statusPills = $('.status .statusPills')
, primary = $('.primary')
, editButton = $('#editbutton')
;
, editButton = $('#editbutton');
client.tooltip = d3.select('body').append('div')
.attr('class', 'tooltip')
@@ -250,8 +247,8 @@ client.load = function load(serverSettings, callback) {
client.dataExtent = function dataExtent () {
return client.entries.length > 0 ?
d3.extent(client.entries, client.entryToDate)
: d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]);
d3.extent(client.entries, client.entryToDate) :
d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]);
};
client.bottomOfPills = function bottomOfPills () {
@@ -758,8 +755,8 @@ client.load = function load(serverSettings, callback) {
}
function isStale (status) {
return client.settings.alarmTimeagoWarn && status === 'warn'
|| client.settings.alarmTimeagoUrgent && status === 'urgent';
return client.settings.alarmTimeagoWarn && status === 'warn' ||
client.settings.alarmTimeagoUrgent && status === 'urgent';
}
function notAcked (alarm) {
@@ -888,10 +885,10 @@ client.load = function load(serverSettings, callback) {
}
});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Client-side code to connect to server and handle incoming data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// eslint-disable-next-line no-undef
client.socket = socket = io.connect();
socket.on('dataUpdate', dataUpdate);
@@ -993,8 +990,7 @@ client.load = function load(serverSettings, callback) {
socket.on('notification', function(notify) {
console.log('notification from server:', notify);
if (notify.timestamp && previousNotifyTimestamp != notify.timestamp)
{
if (notify.timestamp && previousNotifyTimestamp != notify.timestamp) {
previousNotifyTimestamp = notify.timestamp;
client.plugins.visualizeAlarm(client.sbx, notify, notify.title + ' ' + notify.message);
} else {
@@ -1131,10 +1127,9 @@ client.load = function load(serverSettings, callback) {
}
if (client.ddata.sgvs) {
// change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr)
// TODO change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr)
client.ctx.data.lastUpdated = lastUpdated;
client.latestSGV = client.ddata.sgvs[client.ddata.sgvs.length - 1];
prevSGV = client.ddata.sgvs[client.ddata.sgvs.length - 2];
}
client.ddata.inRetroMode = false;
+3 -3
View File
@@ -7,19 +7,19 @@ var TWO_DAYS = 172800000;
function mergeDataUpdate (isDelta, cachedDataArray, receivedDataArray, maxAge) {
function nsArrayDiff (oldArray, newArray) {
var seen = {};
var seen = [];
var l = oldArray.length;
for (var i = 0; i < l; i++) {
if (oldArray[i] !== null) {
seen[oldArray[i].mills] = true;
seen.push(oldArray[i].mills);
}
}
var result = [];
l = newArray.length;
for (var j = 0; j < l; j++) {
if (!seen.hasOwnProperty(newArray[j].mills)) {
if (!seen.includes(newArray[j].mills)) {
result.push(newArray[j]); //console.log('delta data found');
}
}
+124 -133
View File
@@ -406,8 +406,7 @@ function init (client, d3) {
, R2 = R1
// R3/R4 determine how far from the treatment dot the labels are placed
, R3 = R1 + 8 / opts.scale
, R4 = R1 + 25 / opts.scale
;
, R4 = R1 + 25 / opts.scale;
return {
R1: R1
@@ -421,14 +420,14 @@ function init (client, d3) {
function prepareArc (treatment, radius) {
var arc_data = [
// white carb half-circle on top
{ 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 },
{ 'element': '', 'color': 'transparent', 'start': -1.5708, 'end': 1.5708, 'inner': radius.R2, 'outer': radius.R3 },
{ 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 }
, { 'element': '', 'color': 'transparent', 'start': -1.5708, 'end': 1.5708, 'inner': radius.R2, 'outer': radius.R3 },
// blue insulin half-circle on bottom
{ 'element': '', 'color': '#0099ff', 'start': 1.5708, 'end': 4.7124, 'inner': 0, 'outer': radius.R1 },
// these form a very short transparent arc along the bottom of an insulin treatment to position the label
// these used to be semicircles from 1.5708 to 4.7124, but that made the tooltip target too big
{ 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R3 },
{ 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R4 }
{ 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R3 }
, { 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R4 }
];
arc_data[0].outlineOnly = !treatment.carbs;
@@ -550,96 +549,96 @@ function init (client, d3) {
.style('top', (d3.event.pageY ? d3.event.pageY + 15 : 40) + 'px');
deleteRect = {
x: 0,
y: 0,
width: 50,
height: chart().yScale(chart().yScale.domain()[0])
x: 0
, y: 0
, width: 50
, height: chart().yScale(chart().yScale.domain()[0])
};
chart().drag.append('rect')
.attr({
class:'drag-droparea',
x: deleteRect.x,
y: deleteRect.y,
width: deleteRect.width,
height: deleteRect.height,
fill: 'red',
opacity: 0.4,
rx: 10,
ry: 10
class: 'drag-droparea'
, x: deleteRect.x
, y: deleteRect.y
, width: deleteRect.width
, height: deleteRect.height
, fill: 'red'
, opacity: 0.4
, rx: 10
, ry: 10
});
chart().drag.append('text')
.attr({
class:'drag-droparea',
x: deleteRect.x + deleteRect.width / 2,
y: deleteRect.y + deleteRect.height / 2,
'font-size': 15,
'font-weight': 'bold',
fill: 'red',
'text-anchor': 'middle',
dy: '.35em',
transform: 'rotate(-90 ' + (deleteRect.x + deleteRect.width / 2) + ',' + (deleteRect.y + deleteRect.height / 2) + ')'
class: 'drag-droparea'
, x: deleteRect.x + deleteRect.width / 2
, y: deleteRect.y + deleteRect.height / 2
, 'font-size': 15
, 'font-weight': 'bold'
, fill: 'red'
, 'text-anchor': 'middle'
, dy: '.35em'
, transform: 'rotate(-90 ' + (deleteRect.x + deleteRect.width / 2) + ',' + (deleteRect.y + deleteRect.height / 2) + ')'
})
.text(translate('Remove'));
if (treatment.insulin && treatment.carbs) {
carbsRect = {
x: 0,
y: 0,
width: chart().charts.attr('width'),
height: 50
x: 0
, y: 0
, width: chart().charts.attr('width')
, height: 50
};
insulinRect = {
x: 0,
y: chart().yScale(chart().yScale.domain()[0]) - 50,
width: chart().charts.attr('width'),
height: 50
x: 0
, y: chart().yScale(chart().yScale.domain()[0]) - 50
, width: chart().charts.attr('width')
, height: 50
};
chart().drag.append('rect')
.attr({
class:'drag-droparea',
x: carbsRect.x,
y: carbsRect.y,
width: carbsRect.width,
height: carbsRect.height,
fill: 'white',
opacity: 0.4,
rx: 10,
ry: 10
class: 'drag-droparea'
, x: carbsRect.x
, y: carbsRect.y
, width: carbsRect.width
, height: carbsRect.height
, fill: 'white'
, opacity: 0.4
, rx: 10
, ry: 10
});
chart().drag.append('text')
.attr({
class:'drag-droparea',
x: carbsRect.x + carbsRect.width / 2,
y: carbsRect.y + carbsRect.height / 2,
'font-size': 15,
'font-weight': 'bold',
fill: 'white',
'text-anchor': 'middle',
dy: '.35em'
class: 'drag-droparea'
, x: carbsRect.x + carbsRect.width / 2
, y: carbsRect.y + carbsRect.height / 2
, 'font-size': 15
, 'font-weight': 'bold'
, fill: 'white'
, 'text-anchor': 'middle'
, dy: '.35em'
})
.text(translate('Move carbs'));
chart().drag.append('rect')
.attr({
class:'drag-droparea',
x: insulinRect.x,
y: insulinRect.y,
width: insulinRect.width,
height: insulinRect.height,
fill: '#0099ff',
opacity: 0.4,
rx: 10,
ry: 10
class: 'drag-droparea'
, x: insulinRect.x
, y: insulinRect.y
, width: insulinRect.width
, height: insulinRect.height
, fill: '#0099ff'
, opacity: 0.4
, rx: 10
, ry: 10
});
chart().drag.append('text')
.attr({
class:'drag-droparea',
x: insulinRect.x + insulinRect.width / 2,
y: insulinRect.y + insulinRect.height / 2,
'font-size': 15,
'font-weight': 'bold',
fill: '#0099ff',
'text-anchor': 'middle',
dy: '.35em'
class: 'drag-droparea'
, x: insulinRect.x + insulinRect.width / 2
, y: insulinRect.y + insulinRect.height / 2
, 'font-size': 15
, 'font-weight': 'bold'
, fill: '#0099ff'
, 'text-anchor': 'middle'
, dy: '.35em'
})
.text(translate('Move insulin'));
}
@@ -670,22 +669,22 @@ function init (client, d3) {
newTime = new Date(chart().xScale.invert(x));
var minDiff = times.msecs(newTime.getTime() - treatment.mills).mins.toFixed(0);
client.tooltip.html(
'<b>' + translate('Operation') + ':</b> ' + translate(operation) + '<br>'
+ '<b>' + translate('New time') + ':</b> ' + newTime.toLocaleTimeString() + '<br>'
+ '<b>' + translate('Difference') + ':</b> ' + (minDiff > 0 ? '+' : '') + minDiff + ' ' + translate('mins')
'<b>' + translate('Operation') + ':</b> ' + translate(operation) + '<br>' +
'<b>' + translate('New time') + ':</b> ' + newTime.toLocaleTimeString() + '<br>' +
'<b>' + translate('Difference') + ':</b> ' + (minDiff > 0 ? '+' : '') + minDiff + ' ' + translate('mins')
);
chart().drag.selectAll('.arrow').remove();
chart().drag.append('line')
.attr({
'class':'arrow',
'marker-end':'url(#arrow)',
'x1': chart().xScale(new Date(treatment.mills)),
'y1': chart().yScale(client.sbx.scaleEntry(treatment)),
'x2': x,
'y2': y,
'stroke-width': 2,
'stroke': 'white'
'class': 'arrow'
, 'marker-end': 'url(#arrow)'
, 'x1': chart().xScale(new Date(treatment.mills))
, 'y1': chart().yScale(client.sbx.scaleEntry(treatment))
, 'x2': x
, 'y2': y
, 'stroke-width': 2
, 'stroke': 'white'
});
})
@@ -697,13 +696,12 @@ function init (client, d3) {
case 'Move':
if (window.confirm(translate('Change treatment time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) {
client.socket.emit(
'dbUpdate',
{
collection: 'treatments',
_id: treatment._id,
data: { created_at: newTime.toISOString() }
},
function callback(result) {
'dbUpdate', {
collection: 'treatments'
, _id: treatment._id
, data: { created_at: newTime.toISOString() }
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -715,13 +713,12 @@ function init (client, d3) {
case 'Remove insulin':
if (window.confirm(translate('Remove insulin from treatment ?'))) {
client.socket.emit(
'dbUpdateUnset',
{
collection: 'treatments',
_id: treatment._id,
data: { insulin: 1 }
},
function callback(result) {
'dbUpdateUnset', {
collection: 'treatments'
, _id: treatment._id
, data: { insulin: 1 }
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -733,13 +730,12 @@ function init (client, d3) {
case 'Remove carbs':
if (window.confirm(translate('Remove carbs from treatment ?'))) {
client.socket.emit(
'dbUpdateUnset',
{
collection: 'treatments',
_id: treatment._id,
data: { carbs: 1 }
},
function callback(result) {
'dbUpdateUnset', {
collection: 'treatments'
, _id: treatment._id
, data: { carbs: 1 }
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -751,12 +747,11 @@ function init (client, d3) {
case 'Remove':
if (window.confirm(translate('Remove treatment ?'))) {
client.socket.emit(
'dbRemove',
{
collection: 'treatments',
_id: treatment._id
},
function callback(result) {
'dbRemove', {
collection: 'treatments'
, _id: treatment._id
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -768,11 +763,10 @@ function init (client, d3) {
case 'Move insulin':
if (window.confirm(translate('Change insulin time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) {
client.socket.emit(
'dbUpdateUnset',
{
collection: 'treatments',
_id: treatment._id,
data: { insulin: 1 }
'dbUpdateUnset', {
collection: 'treatments'
, _id: treatment._id
, data: { insulin: 1 }
}
);
newTreatment = _.cloneDeep(treatment);
@@ -781,12 +775,11 @@ function init (client, d3) {
delete newTreatment.carbs;
newTreatment.created_at = newTime.toISOString();
client.socket.emit(
'dbAdd',
{
collection: 'treatments',
data: newTreatment
},
function callback(result) {
'dbAdd', {
collection: 'treatments'
, data: newTreatment
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -798,11 +791,10 @@ function init (client, d3) {
case 'Move carbs':
if (window.confirm(translate('Change carbs time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) {
client.socket.emit(
'dbUpdateUnset',
{
collection: 'treatments',
_id: treatment._id,
data: { carbs: 1 }
'dbUpdateUnset', {
collection: 'treatments'
, _id: treatment._id
, data: { carbs: 1 }
}
);
newTreatment = _.cloneDeep(treatment);
@@ -811,12 +803,11 @@ function init (client, d3) {
delete newTreatment.insulin;
newTreatment.created_at = newTime.toISOString();
client.socket.emit(
'dbAdd',
{
collection: 'treatments',
data: newTreatment
},
function callback(result) {
'dbAdd', {
collection: 'treatments'
, data: newTreatment
}
, function callback (result) {
console.log(result);
chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove();
}
@@ -895,7 +886,7 @@ function init (client, d3) {
chart().focus.selectAll('.draggable-treatment').remove();
_.forEach(client.ddata.treatments, function eachTreatment (d) {
if (Number(d.insulin) > 0 || Number(d.carbs) > 0) { treatmentCount += 1; };
if (Number(d.insulin) > 0 || Number(d.carbs) > 0) { treatmentCount += 1; }
});
// add treatment bubbles
@@ -906,7 +897,7 @@ function init (client, d3) {
, treatments: treatmentCount
}, client.sbx.data.profile.getCarbRatio(new Date()));
});
};
}
renderer.drawTreatment = function drawTreatment (treatment, opts, carbratio) {
if (!treatment.carbs && !treatment.insulin) {
@@ -929,7 +920,7 @@ function init (client, d3) {
var arc = prepareArc(treatment, radius);
var treatmentDots = appendTreatments(treatment, arc);
appendLabels(treatmentDots, arc, opts);
};
}
renderer.addBasals = function addBasals (client) {
+1
View File
@@ -11,6 +11,7 @@ var ONE_DAY = 86400000,
function uniq(a) {
var seen = {};
return a.filter(function(item) {
// eslint-disable-next-line no-prototype-builtins
return seen.hasOwnProperty(item.mills) ? false : (seen[item.mills] = true);
});
}
+16 -17
View File
@@ -8,15 +8,15 @@ var DEVICE_TYPE_FIELDS = ['uploader', 'pump', 'openaps', 'loop', 'xdripjs'];
function init () {
var ddata = {
sgvs: [],
treatments: [],
mbgs: [],
cals: [],
profiles: [],
devicestatus: [],
food: [],
activity: [],
lastUpdated: 0
sgvs: []
, treatments: []
, mbgs: []
, cals: []
, profiles: []
, devicestatus: []
, food: []
, activity: []
, lastUpdated: 0
};
ddata.clone = function clone () {
@@ -34,8 +34,8 @@ function init() {
ddata.splitRecent = function splitRecent (time, cutoff, max, treatmentsToo) {
var result = {
first: {},
rest: {}
first: {}
, rest: {}
};
function recent (item) {
@@ -67,13 +67,12 @@ function init() {
result.first.cals = ddata.cals;
var profiles = _.cloneDeep(ddata.profiles);
if (profiles && profiles[0])
for (var k in profiles[0].store) {
if (profiles[0].store.hasOwnProperty(k)) {
if (profiles && profiles[0]) {
Object.keys(profiles[0].store).forEach(k => {
if (k.indexOf('@@@@@') > 0) {
delete profiles[0].store[k];
}
}
})
}
result.first.profiles = profiles;
@@ -99,8 +98,8 @@ function init() {
})
.map(function toDeviceTypeKey (key) {
return {
device: status.device,
type: key
device: status.device
, type: key
};
})
.value();
+23 -393
View File
@@ -834,7 +834,6 @@ function init() {
,dk: 'Noter indeholder'
,fi: 'Merkinnät sisältävät'
,nb: 'Notater inneholder'
,he: 'הערות מכילות'
,pl: 'Zawierają uwagi'
,ru: 'Примечания содержат'
,sk: 'Poznámky obsahujú'
@@ -1460,7 +1459,6 @@ function init() {
,sv: 'temp basal måste vara synlig för denna rapport'
,de: 'temporäre Basalraten müssen für diesen Report sichtbar sein'
,fi: 'tämä raportti vaatii, että basaalien piirto on päällä'
,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה'
,bg: 'временните базали трябва да са показани за да се покаже тази това'
,hr: 'temp bazali moraju biti prikazani kako bi se vidio ovaj izvještaj'
,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה'
@@ -1469,7 +1467,6 @@ function init() {
}
,'Weekly success' : {
cs: 'Statistika po týdnech'
,he: 'הצלחה שבועית'
,de: 'Wöchentlicher Erfolg'
,es: 'Resultados semanales'
,fr: 'Résultat hebdomadaire'
@@ -1747,7 +1744,6 @@ function init() {
cs: 'Normální'
,de: 'Normal'
,es: 'Normal'
,he: 'נורמלי '
,fr: 'Normale'
,el: 'Εντός Στόχου'
,pt: 'Normal'
@@ -1871,7 +1867,6 @@ function init() {
}
,'Glucose Percentile report' : {
cs: 'Tabulka percentil glykémií'
,he: 'דוח אחוזוני גלוקוזה'
,de: 'Glukose-Perzentil Bericht'
,es: 'Informe de percetiles de glucemia'
,fr: 'Rapport percentiles Glycémie'
@@ -2196,7 +2191,6 @@ function init() {
}
,'Weekly Success' : {
cs: 'Týdenní úspěšnost'
,he: 'הצלחה שבועית '
,de: 'Wöchtlicher Erfolg'
,es: 'Resultados semanales'
,fr: 'Réussite hebdomadaire'
@@ -2263,7 +2257,6 @@ function init() {
,dk: 'Anvender gemt API-nøgle'
,fi: 'Tallennettu salainen API-tarkiste käytössä'
,nb: 'Bruker lagret API nøkkel'
,he: 'עורך אוכל'
,pl: 'Korzystając z zapisanego poufnego hasha API'
,ru: 'Применение сохраненного пароля API'
,sk: 'Používam uložený API hash heslo'
@@ -2275,7 +2268,6 @@ function init() {
}
,'No API secret hash stored yet. You need to enter API secret.' : {
cs: 'Není uložený žádný hash API hesla. Musíte zadat API heslo.'
,he: 'הכנס את סיסמת ממשק תכנות יישומים הסודית'
,de: 'Keine API-Prüfsumme gespeichert. Bitte API-Prüfsumme eingeben.'
,es: 'No se ha almacenado ningún hash todavía. Debe introducir su secreto API.'
,fr: 'Pas de secret API existant. Vous devez en entrer un.'
@@ -2302,7 +2294,6 @@ function init() {
}
,'Database loaded' : {
cs: 'Databáze načtena'
,he: 'אגר מידע נטען '
,de: 'Datenbank geladen'
,es: 'Base de datos cargada'
,fr: 'Base de données chargée'
@@ -2496,7 +2487,6 @@ function init() {
,pl: 'IG'
,ru: 'ГИ'
,sk: 'GI'
,he: 'GI'
,nl: 'Glycemische index '
,ko: '혈당 지수'
,tr: 'GI-Glisemik İndeks'
@@ -2638,7 +2628,6 @@ function init() {
,ro: 'Cheia API trebuie să aibă mai mult de 12 caractere'
,bg: 'Вашата АPI парола трябва да е дълга поне 12 символа'
,hr: 'Vaš tajni API mora sadržavati barem 12 znakova'
,he:' הסיסמא הסודית חייבת להיות באורך של 12 תווים לפחות'
,sv: 'Hemlig API-nyckel måsta innehålla 12 tecken'
,it: 'il vostro API secreto deve essere lungo almeno 12 caratteri'
,ja: 'APIシークレットは12文字以上の長さが必要です'
@@ -2673,7 +2662,6 @@ function init() {
,nb: 'Ugyldig API nøkkel'
,pl: 'Błędny klucz API'
,ru: 'Плохой пароль API'
,he: ' הסיסמא הסודית אינה חוקית'
,sk: 'Nesprávne API heslo'
,nl: 'Onjuist API wachtwoord'
,ko: '잘못된 API secret'
@@ -2699,7 +2687,6 @@ function init() {
,fi: 'API salaisuus talletettu'
,nb: 'API nøkkel lagret'
,pl: 'Poufne klucz API zapisane'
,he: ' הסיסמא הסודית נשמרה'
,ru: 'Хэш пароля API сохранен'
,sk: 'Hash API hesla uložený'
,nl: 'API wachtwoord opgeslagen'
@@ -2750,7 +2737,6 @@ function init() {
,dk: 'Ikke indlæst'
,fi: 'Ei ladattu'
,nb: 'Ikke lest'
,he: 'לא נטען'
,pl: 'Nie załadowany'
,ru: 'Не загружено'
,sk: 'Nenačítaný'
@@ -2773,7 +2759,6 @@ function init() {
,sv: 'Födoämneseditor'
,it: 'NS - Database Alimenti'
,ja: '食事編集'
,he: 'עורך מזון'
,dk: 'Mad editor'
,fi: 'Muokkaa ruokia'
,nb: 'Mat editor'
@@ -2973,7 +2958,6 @@ function init() {
,ro: 'Cheia API'
,bg: 'Твоята API парола'
,hr: 'Vaš tajni API'
,he: 'הסיסמא הסודית שלך'
,it: 'Il tuo API secreto'
,ja: 'あなたのAPI Secret'
,dk: 'Din API-nøgle'
@@ -3005,7 +2989,6 @@ function init() {
,dk: 'Gemme hash på denne computer (brug kun på privat computer)'
,fi: 'Tallenna avain tälle tietokoneelle (käytä vain omalla tietokoneellasi)'
,nb: 'Lagre hash på denne pc (bruk kun på privat pc)'
,he:'שמור סיסמא הסודית על המחשב ( יש להשתמש רק על מחשב פרטי)'
,pl: 'Zapisz na tym komputerze (korzystaj tylko na komputerach prywatnych)'
,ru: 'Сохранить хеш на этом ПК (только для личных компьютеров)'
,sk: 'Uložiť hash na tomto počítači (Používajte iba na súkromných počítačoch)'
@@ -7692,7 +7675,7 @@ function init() {
cs: 'Odstraňování záznamů ...'
,he: 'מוחק רשומות ... '
,nb: 'Fjerner elementer...'
,fr: 'Effacement d\événements...'
,fr: 'Effacement dévénements...'
,ro: 'Se șterg înregistrările...'
,el: 'Αφαίρεση Εγγραφών'
,de: 'Entferne Einträge ...'
@@ -7714,29 +7697,7 @@ function init() {
,zh_tw: '正在刪除記錄...'
}
,'%1 records deleted' : {
cs: '%1 records deleted'
,he: '%1 records deleted'
,nb: '%1 records deleted'
,fr: '%1 records deleted'
,ro: '%1 records deleted'
,el: '%1 records deleted'
,de: '%1 records deleted'
,es: '%1 records deleted'
,dk: '%1 records deleted'
,sv: '%1 records deleted'
,bg: '%1 records deleted'
,hr: 'obrisano %1 zapisa'
,it: '%1 records deleted'
,fi: '%1 records deleted'
,pl: '%1 records deleted'
,pt: '%1 records deleted'
,ru: '%1 records deleted'
,sk: '%1 records deleted'
,nl: '%1 records deleted'
,ko: '%1 records deleted'
,tr: '%1 records deleted'
,zh_cn: '%1 records deleted'
,zh_tw: '%1 records deleted'
hr: 'obrisano %1 zapisa'
}
,'Clean Mongo status database' : {
cs: 'Vyčištění Mongo databáze statusů'
@@ -7906,379 +7867,49 @@ function init() {
,zh_cn: '所有记录已经被清除'
}
,'Delete all documents from devicestatus collection older than 30 days' : {
cs: 'Delete all documents from devicestatus collection older than 30 days'
,he: 'Delete all documents from devicestatus collection older than 30 days'
,nb: 'Delete all documents from devicestatus collection older than 30 days'
,fr: 'Delete all documents from devicestatus collection older than 30 days'
,ro: 'Delete all documents from devicestatus collection older than 30 days'
,el: 'Delete all documents from devicestatus collection older than 30 days'
,de: 'Delete all documents from devicestatus collection older than 30 days'
,es: 'Delete all documents from devicestatus collection older than 30 days'
,dk: 'Delete all documents from devicestatus collection older than 30 days'
,sv: 'Delete all documents from devicestatus collection older than 30 days'
,bg: 'Delete all documents from devicestatus collection older than 30 days'
,hr: 'Obriši sve statuse starije od 30 dana'
,it: 'Delete all documents from devicestatus collection older than 30 days'
,fi: 'Delete all documents from devicestatus collection older than 30 days'
,pl: 'Delete all documents from devicestatus collection older than 30 days'
,pt: 'Delete all documents from devicestatus collection older than 30 days'
,ru: 'Delete all documents from devicestatus collection older than 30 days'
,sk: 'Delete all documents from devicestatus collection older than 30 days'
,nl: 'Delete all documents from devicestatus collection older than 30 days'
,ko: 'Delete all documents from devicestatus collection older than 30 days'
,tr: 'Delete all documents from devicestatus collection older than 30 days'
,zh_cn: 'Delete all documents from devicestatus collection older than 30 days'
,zh_tw: 'Delete all documents from devicestatus collection older than 30 days'
hr: 'Obriši sve statuse starije od 30 dana'
}
,'Number of Days to Keep:' : {
cs: 'Number of Days to Keep:'
,he: 'Number of Days to Keep:'
,nb: 'Number of Days to Keep:'
,fr: 'Number of Days to Keep:'
,ro: 'Number of Days to Keep:'
,el: 'Number of Days to Keep:'
,de: 'Number of Days to Keep:'
,es: 'Number of Days to Keep:'
,dk: 'Number of Days to Keep:'
,sv: 'Number of Days to Keep:'
,bg: 'Number of Days to Keep:'
,hr: 'Broj dana za sačuvati:'
,it: 'Number of Days to Keep:'
,fi: 'Number of Days to Keep:'
,pl: 'Number of Days to Keep:'
,pt: 'Number of Days to Keep:'
,ru: 'Number of Days to Keep:'
,sk: 'Number of Days to Keep:'
,nl: 'Number of Days to Keep:'
,ko: 'Number of Days to Keep:'
,tr: 'Number of Days to Keep:'
,zh_cn: 'Number of Days to Keep:'
,zh_tw: 'Number of Days to Keep:'
hr: 'Broj dana za sačuvati:'
}
,'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' : {
cs: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,he: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,nb: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,fr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,ro: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,el: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,de: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,es: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,dk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,sv: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,bg: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,hr: 'Ovo uklanja sve statuse starije od 30 dana. Korisno kada se status baterije uploadera ne osvježava ispravno.'
,it: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,fi: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,pl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,pt: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,ru: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,sk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,nl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,ko: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,tr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,zh_cn: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
,zh_tw: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
hr: 'Ovo uklanja sve statuse starije od 30 dana. Korisno kada se status baterije uploadera ne osvježava ispravno.'
}
,'Delete old documents from devicestatus collection?' : {
cs: 'Delete old documents from devicestatus collection?'
,he: 'Delete old documents from devicestatus collection?'
,nb: 'Delete old documents from devicestatus collection?'
,fr: 'Delete old documents from devicestatus collection?'
,ro: 'Delete old documents from devicestatus collection?'
,el: 'Delete old documents from devicestatus collection?'
,de: 'Delete old documents from devicestatus collection?'
,es: 'Delete old documents from devicestatus collection?'
,dk: 'Delete old documents from devicestatus collection?'
,sv: 'Delete old documents from devicestatus collection?'
,bg: 'Delete old documents from devicestatus collection?'
,hr: 'Obriši stare statuse'
,it: 'Delete old documents from devicestatus collection?'
,fi: 'Delete old documents from devicestatus collection?'
,pl: 'Delete old documents from devicestatus collection?'
,pt: 'Delete old documents from devicestatus collection?'
,ru: 'Delete old documents from devicestatus collection?'
,sk: 'Delete old documents from devicestatus collection?'
,nl: 'Delete old documents from devicestatus collection?'
,ko: 'Delete old documents from devicestatus collection?'
,tr: 'Delete old documents from devicestatus collection?'
,zh_cn: 'Delete old documents from devicestatus collection?'
,zh_tw: 'Delete old documents from devicestatus collection?'
hr: 'Obriši stare statuse'
}
,'Clean Mongo entries (glucose entries) database' : {
cs: 'Clean Mongo entries (glucose entries) database'
,he: 'Clean Mongo entries (glucose entries) database'
,nb: 'Clean Mongo entries (glucose entries) database'
,fr: 'Clean Mongo entries (glucose entries) database'
,ro: 'Clean Mongo entries (glucose entries) database'
,el: 'Clean Mongo entries (glucose entries) database'
,de: 'Clean Mongo entries (glucose entries) database'
,es: 'Clean Mongo entries (glucose entries) database'
,dk: 'Clean Mongo entries (glucose entries) database'
,sv: 'Clean Mongo entries (glucose entries) database'
,bg: 'Clean Mongo entries (glucose entries) database'
,hr: 'Obriši GUK zapise iz baze'
,it: 'Clean Mongo entries (glucose entries) database'
,fi: 'Clean Mongo entries (glucose entries) database'
,pl: 'Clean Mongo entries (glucose entries) database'
,pt: 'Clean Mongo entries (glucose entries) database'
,ru: 'Clean Mongo entries (glucose entries) database'
,sk: 'Clean Mongo entries (glucose entries) database'
,nl: 'Clean Mongo entries (glucose entries) database'
,ko: 'Clean Mongo entries (glucose entries) database'
,tr: 'Clean Mongo entries (glucose entries) database'
,zh_cn: 'Clean Mongo entries (glucose entries) database'
,zh_tw: 'Clean Mongo entries (glucose entries) database'
hr: 'Obriši GUK zapise iz baze'
}
,'Delete all documents from entries collection older than 180 days' : {
cs: 'Delete all documents from entries collection older than 180 days'
,he: 'Delete all documents from entries collection older than 180 days'
,nb: 'Delete all documents from entries collection older than 180 days'
,fr: 'Delete all documents from entries collection older than 180 days'
,ro: 'Delete all documents from entries collection older than 180 days'
,el: 'Delete all documents from entries collection older than 180 days'
,de: 'Delete all documents from entries collection older than 180 days'
,es: 'Delete all documents from entries collection older than 180 days'
,dk: 'Delete all documents from entries collection older than 180 days'
,sv: 'Delete all documents from entries collection older than 180 days'
,bg: 'Delete all documents from entries collection older than 180 days'
,hr: 'Obriši sve zapise starije od 180 dana'
,it: 'Delete all documents from entries collection older than 180 days'
,fi: 'Delete all documents from entries collection older than 180 days'
,pl: 'Delete all documents from entries collection older than 180 days'
,pt: 'Delete all documents from entries collection older than 180 days'
,ru: 'Delete all documents from entries collection older than 180 days'
,sk: 'Delete all documents from entries collection older than 180 days'
,nl: 'Delete all documents from entries collection older than 180 days'
,ko: 'Delete all documents from entries collection older than 180 days'
,tr: 'Delete all documents from entries collection older than 180 days'
,zh_cn: 'Delete all documents from entries collection older than 180 days'
,zh_tw: 'Delete all documents from entries collection older than 180 days'
hr: 'Obriši sve zapise starije od 180 dana'
}
,'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : {
cs: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,he: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,nb: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,fr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ro: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,el: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,de: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,es: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,dk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,sv: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,bg: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,hr: 'Ovo briše sve zapise starije od 180 dana. Korisno kada se status baterije uploadera ne osvježava.'
,it: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,fi: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,pl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,pt: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ru: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,sk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,nl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ko: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,tr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,zh_cn: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,zh_tw: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
hr: 'Ovo briše sve zapise starije od 180 dana. Korisno kada se status baterije uploadera ne osvježava.'
}
,'Delete old documents' : {
cs: 'Delete old documents'
,he: 'Delete old documents'
,nb: 'Delete old documents'
,fr: 'Delete old documents'
,ro: 'Delete old documents'
,el: 'Delete old documents'
,de: 'Delete old documents'
,es: 'Delete old documents'
,dk: 'Delete old documents'
,sv: 'Delete old documents'
,bg: 'Delete old documents'
,hr: 'Obriši stare zapise'
,it: 'Delete old documents'
,fi: 'Delete old documents'
,pl: 'Delete old documents'
,pt: 'Delete old documents'
,ru: 'Delete old documents'
,sk: 'Delete old documents'
,nl: 'Delete old documents'
,ko: 'Delete old documents'
,tr: 'Delete old documents'
,zh_cn: 'Delete old documents'
,zh_tw: 'Delete old documents'
hr: 'Obriši stare zapise'
}
,'Delete old documents from entries collection?' : {
cs: 'Delete old documents from entries collection?'
,he: 'Delete old documents from entries collection?'
,nb: 'Delete old documents from entries collection?'
,fr: 'Delete old documents from entries collection?'
,ro: 'Delete old documents from entries collection?'
,el: 'Delete old documents from entries collection?'
,de: 'Delete old documents from entries collection?'
,es: 'Delete old documents from entries collection?'
,dk: 'Delete old documents from entries collection?'
,sv: 'Delete old documents from entries collection?'
,bg: 'Delete old documents from entries collection?'
,hr: 'Obriši stare zapise?'
,it: 'Delete old documents from entries collection?'
,fi: 'Delete old documents from entries collection?'
,pl: 'Delete old documents from entries collection?'
,pt: 'Delete old documents from entries collection?'
,ru: 'Delete old documents from entries collection?'
,sk: 'Delete old documents from entries collection?'
,nl: 'Delete old documents from entries collection?'
,ko: 'Delete old documents from entries collection?'
,tr: 'Delete old documents from entries collection?'
,zh_cn: 'Delete old documents from entries collection?'
,zh_tw: 'Delete old documents from entries collection?'
hr: 'Obriši stare zapise?'
}
,'%1 is not a valid number' : {
cs: '%1 is not a valid number'
,he: '%1 is not a valid number'
,nb: '%1 is not a valid number'
,fr: '%1 is not a valid number'
,ro: '%1 is not a valid number'
,el: '%1 is not a valid number'
,de: '%1 is not a valid number'
,es: '%1 is not a valid number'
,dk: '%1 is not a valid number'
,sv: '%1 is not a valid number'
,bg: '%1 is not a valid number'
,hr: '%1 nije valjan broj'
,it: '%1 is not a valid number'
,fi: '%1 is not a valid number'
,pl: '%1 is not a valid number'
,pt: '%1 is not a valid number'
,ru: '%1 is not a valid number'
,sk: '%1 is not a valid number'
,nl: '%1 is not a valid number'
,ko: '%1 is not a valid number'
,tr: '%1 is not a valid number'
,zh_cn: '%1 is not a valid number'
,zh_tw: '%1 is not a valid number'
hr: '%1 nije valjan broj'
}
,'%1 is not a valid number - must be more than 2' : {
cs: '%1 is not a valid number - must be more than 2'
,he: '%1 is not a valid number - must be more than 2'
,nb: '%1 is not a valid number - must be more than 2'
,fr: '%1 is not a valid number - must be more than 2'
,ro: '%1 is not a valid number - must be more than 2'
,el: '%1 is not a valid number - must be more than 2'
,de: '%1 is not a valid number - must be more than 2'
,es: '%1 is not a valid number - must be more than 2'
,dk: '%1 is not a valid number - must be more than 2'
,sv: '%1 is not a valid number - must be more than 2'
,bg: '%1 is not a valid number - must be more than 2'
,hr: '%1 nije valjan broj - mora biti veći od 2'
,it: '%1 is not a valid number - must be more than 2'
,fi: '%1 is not a valid number - must be more than 2'
,pl: '%1 is not a valid number - must be more than 2'
,pt: '%1 is not a valid number - must be more than 2'
,ru: '%1 is not a valid number - must be more than 2'
,sk: '%1 is not a valid number - must be more than 2'
,nl: '%1 is not a valid number - must be more than 2'
,ko: '%1 is not a valid number - must be more than 2'
,tr: '%1 is not a valid number - must be more than 2'
,zh_cn: '%1 is not a valid number - must be more than 2'
,zh_tw: '%1 is not a valid number - must be more than 2'
hr: '%1 nije valjan broj - mora biti veći od 2'
}
,'Clean Mongo treatments database' : {
cs: 'Clean Mongo treatments database'
,he: 'Clean Mongo treatments database'
,nb: 'Clean Mongo treatments database'
,fr: 'Clean Mongo treatments database'
,ro: 'Clean Mongo treatments database'
,el: 'Clean Mongo treatments database'
,de: 'Clean Mongo treatments database'
,es: 'Clean Mongo treatments database'
,dk: 'Clean Mongo treatments database'
,sv: 'Clean Mongo treatments database'
,bg: 'Clean Mongo treatments database'
,hr: 'Obriši tretmane iz baze'
,it: 'Clean Mongo treatments database'
,fi: 'Clean Mongo treatments database'
,pl: 'Clean Mongo treatments database'
,pt: 'Clean Mongo treatments database'
,ru: 'Clean Mongo treatments database'
,sk: 'Clean Mongo treatments database'
,nl: 'Clean Mongo treatments database'
,ko: 'Clean Mongo treatments database'
,tr: 'Clean Mongo treatments database'
,zh_cn: 'Clean Mongo treatments database'
,zh_tw: 'Clean Mongo treatments database'
hr: 'Obriši tretmane iz baze'
}
,'Delete all documents from treatments collection older than 180 days' : {
cs: 'Delete all documents from treatments collection older than 180 days'
,he: 'Delete all documents from treatments collection older than 180 days'
,nb: 'Delete all documents from treatments collection older than 180 days'
,fr: 'Delete all documents from treatments collection older than 180 days'
,ro: 'Delete all documents from treatments collection older than 180 days'
,el: 'Delete all documents from treatments collection older than 180 days'
,de: 'Delete all documents from treatments collection older than 180 days'
,es: 'Delete all documents from treatments collection older than 180 days'
,dk: 'Delete all documents from treatments collection older than 180 days'
,sv: 'Delete all documents from treatments collection older than 180 days'
,bg: 'Delete all documents from treatments collection older than 180 days'
,hr: 'Obriši tretmane starije od 180 dana iz baze'
,it: 'Delete all documents from treatments collection older than 180 days'
,fi: 'Delete all documents from treatments collection older than 180 days'
,pl: 'Delete all documents from treatments collection older than 180 days'
,pt: 'Delete all documents from treatments collection older than 180 days'
,ru: 'Delete all documents from treatments collection older than 180 days'
,sk: 'Delete all documents from treatments collection older than 180 days'
,nl: 'Delete all documents from treatments collection older than 180 days'
,ko: 'Delete all documents from treatments collection older than 180 days'
,tr: 'Delete all documents from treatments collection older than 180 days'
,zh_cn: 'Delete all documents from treatments collection older than 180 days'
,zh_tw: 'Delete all documents from treatments collection older than 180 days'
hr: 'Obriši tretmane starije od 180 dana iz baze'
}
,'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : {
cs: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,he: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,nb: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,fr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ro: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,el: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,de: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,es: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,dk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,sv: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,bg: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,hr: 'Ovo briše sve tretmane starije od 180 dana iz baze. Korisno kada se status baterije uploadera ne osvježava.'
,it: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,fi: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,pl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,pt: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ru: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,sk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,nl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,ko: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,tr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,zh_cn: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
,zh_tw: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
hr: 'Ovo briše sve tretmane starije od 180 dana iz baze. Korisno kada se status baterije uploadera ne osvježava.'
}
,'Delete old documents from treatments collection?' : {
cs: 'Delete old documents from treatments collection?'
,he: 'Delete old documents from treatments collection?'
,nb: 'Delete old documents from treatments collection?'
,fr: 'Delete old documents from treatments collection?'
,ro: 'Delete old documents from treatments collection?'
,el: 'Delete old documents from treatments collection?'
,de: 'Delete old documents from treatments collection?'
,es: 'Delete old documents from treatments collection?'
,dk: 'Delete old documents from treatments collection?'
,sv: 'Delete old documents from treatments collection?'
,bg: 'Delete old documents from treatments collection?'
,hr: 'Obriši stare tretmane?'
,it: 'Delete old documents from treatments collection?'
,fi: 'Delete old documents from treatments collection?'
,pl: 'Delete old documents from treatments collection?'
,pt: 'Delete old documents from treatments collection?'
,ru: 'Delete old documents from treatments collection?'
,sk: 'Delete old documents from treatments collection?'
,nl: 'Delete old documents from treatments collection?'
,ko: 'Delete old documents from treatments collection?'
,tr: 'Delete old documents from treatments collection?'
,zh_cn: 'Delete old documents from treatments collection?'
,zh_tw: 'Delete old documents from treatments collection?'
hr: 'Obriši stare tretmane?'
}
,'Admin Tools' : {
cs: 'Nástroje pro správu'
@@ -10106,7 +9737,7 @@ function init() {
}
,'Profile is going to be saved in newer format used in Nightscout 0.9.0 and above and will not be usable in older versions anymore.\nAre you sure?' : {
cs: 'Profil bude uložen v novějším formátu používaném v Nightscoutu 0.9.0 a novějších. Již nebude použitelný se starší verzí.\nJste si jistý?'
,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \ האם אתה בטוח? '
,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \n האם אתה בטוח? '
,el: 'Το προφίλ πρόκειται να αποθηκευτεί με τη νέα του μορφή (έκδοση Nighscout 0.9.0 και πάνω) και δεν πρόκειται να μπορεί να χρησιμοποιηθεί σε παλαιότερες εκδόσεις. \nΕίστε σίγουροι?'
,fr: 'Le profil va être sauvegardé dans un nouveau format utilisé par Nightscout 0.9.0 et suivants, et il ne pourra plus être utilisé par les versions antérieures. \nÊtes-vous sûr?'
,ro: 'Profilul va fi salvat într-un format nou, folosit în Nightscout 0.9.0 și superior și nu va mai fi posibilă folosirea pentru versiunile mai vechi.\nSunteți de acord?'
@@ -10130,7 +9761,7 @@ function init() {
}
,'Wrong profile setting.\nNo profile defined to displayed time.\nRedirecting to profile editor to create new profile.' : {
cs: 'Chybě nastavený profil.\nNení definovaný žádný platný profil k času zobrazení.\nProvádím přesměrování na editor profilu.'
,he: 'הגדרת פרופיל שגוי. \ N פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. '
,he: 'הגדרת פרופיל שגוי. \n פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. '
,el: 'Λάθος προφίλ. Παρακαλώ δημιουργήστε ένα νέο προφίλ'
,fr: 'Erreur de réglage de profil. \nAucun profil défini pour indiquer l\'heure. \nRedirection vers la création d\'un nouveau profil. '
,de: 'Falsche Profileinstellung.\nKein Profil festgelegt zur angezeigten Zeit.\n Weiter zum Profileditor, um ein neues Profil zu erstellen.'
@@ -10709,7 +10340,6 @@ function init() {
,nb: 'Hver enkelt rolle vil ha en eller flere rettigheter. <em>*</em>-rettigheten er wildcard. Rettigheter settes hierarkisk med <em>:</em> som separator.'
,fi: 'Jokaisella roolilla on yksi tai useampia oikeuksia. <em>*</em> on jokeri (tunnistuu kaikkina oikeuksina), oikeudet ovat hierarkia joka käyttää <em>:</em> merkkiä erottimena.'
,de: 'Jede Rolle hat eine oder mehrere Berechtigungen. Die <em>*</em> Berechtigung ist ein Platzhalter, Berechtigungen sind hierachrchisch mit <em>:</em> als Separator.'
,sv: 'Hver rolle vil have en eller flere rettigheder. <em>*</em> er en joker, rettigheder sættes hierakisk med <em>:</em> som skilletegn.'
,es: 'Cada Rol tiene uno o más permisos. El permiso <em>*</em> es un marcador de posición y los permisos son jerárquicos con <em>:</em> como separador.'
,pt: 'Cada função terá uma ou mais permissões. A permissão <em>*</em> é um wildcard, permissões são uma hierarquia utilizando <em>*</em> como um separador.'
,sk: 'Každá rola má 1 alebo viac oprávnení. Oprávnenie <em>*</em> je zástupný znak, oprávnenia sú hierarchie používajúce <em>:</em> ako oddelovač.'
@@ -11994,7 +11624,6 @@ function init() {
,sk: 'Nadbytok inzulínu o %1U viac ako je potrebné na dosiahnutie spodnej cieľovej hranice. Neráta sa so sacharidmi.'
,ko: '낮은 혈당 목표에 도달하기 위해 필요한 인슐린양보다 %1U의 인슐린 양이 초과 되었고 탄수화물 양이 초과되지 않았습니다.'
,it: 'L\'eccesso d\'insulina equivalente %1U più che necessari per raggiungere l\'obiettivo basso, non rappresentano i carboidrati.'
,nl: 'Overschot insuline %1U meer dan nodig om het laag doel te bereiken, geen rekening gehouden met KH'
,tr: 'Fazla insülin: Karbonhidratları dikkate alınmadan, alt hedefe ulaşmak için gerekenden %1U\'den daha fazla' //???
,zh_cn: '胰岛素超过至血糖下限目标所需剂量%1单位,不计算碳水化合物'
, pl: 'Nadmiar insuliny, %1J więcej niż potrzeba, aby osiągnąć cel dolnej granicy, nie biorąc pod uwagę węglowodanów'
@@ -12427,7 +12056,7 @@ function init() {
,sv: 'Applicerad'
,nb: 'Satt inn'
,fi: 'Asetettu'
,es: 'Insertar'
,es: 'Insertado'
,pt: 'Inserido'
,sk: 'Zavedený'
,ko: '삽입된'
@@ -12453,7 +12082,7 @@ function init() {
,nb: 'Nål alder'
,fi: 'KIKÄ'
,pt: 'ICAT'
,es: 'Carb.desde'
,es: 'Cánula desde'
,sk: 'SET'
,ko: '주입세트사용기간'
,it: 'CAGE'
@@ -12477,7 +12106,7 @@ function init() {
,nb: 'Aktive karbohydrater'
,fi: 'AH'
,pt: 'COB'
,es: 'Carbohidratos activos'
,es: 'Carb. activos'
,sk: 'SACH'
,ko: 'COB'
,it: 'COB'
@@ -14490,6 +14119,7 @@ function init() {
}
if (options && options.params) {
for (var i = 0; i < options.params.length; i++) {
// eslint-disable-next-line no-useless-escape
var r = new RegExp('\%' + (i+1), 'g');
translated = translated.replace(r, options.params[i]);
}
+1 -6
View File
@@ -107,13 +107,8 @@ function init (env, ctx) {
return _.last(sorted);
};
notifications.registerGroup = function registerGroup (group) {
if (groups.indexOf(group) < 0) {
groups.push(group);
}
};
notifications.requestNotify = function requestNotify (notify) {
// eslint-disable-next-line no-prototype-builtins
if (!notify.hasOwnProperty('level') || !notify.title || !notify.message || !notify.plugin) {
console.error(new Error('Unable to request notification, since the notify isn\'t complete: ' + JSON.stringify(notify)));
return;
+1 -2
View File
@@ -15,6 +15,7 @@ var AR = [-0.723, 1.716];
//TODO: move this to css
var AR2_COLOR = 'cyan';
// eslint-disable-next-line no-unused-vars
function init (ctx) {
var ar2 = {
@@ -284,7 +285,6 @@ function pushPoint(result) {
return next;
}
function ar2Point (next, options) {
var step = options.step || 0;
var coneFactor = options.coneFactor || 0;
@@ -301,7 +301,6 @@ function ar2Point(next, options) {
};
}
function buildDebug (prop, sbx) {
return prop.forecast && {
forecast: {
+1
View File
@@ -8,6 +8,7 @@ function init() {
, pluginType: 'drawer'
};
// eslint-disable-next-line no-unused-vars
careportal.getEventTypes = function getEventTypes (sbx) {
//TODO: use sbx and new CAREPORTAL_EVENTTYPE_GROUPS="core temps combo dad sensor site etc"
+10 -13
View File
@@ -24,7 +24,7 @@ function init(ctx) {
cob.cobTotal = function cobTotal (treatments, devicestatus, profile, time, spec_profile) {
if (!profile || !profile.hasData()) {
if (!profile || !profile.hasData()) {
console.warn('For the COB plugin to function you need a treatment profile');
return {};
}
@@ -219,8 +219,8 @@ function init(ctx) {
var netCarbImpact = Math.max(0, rawCarbImpact - liverCarbImpact);
var totalImpact = netCarbImpact - insulinImpact;
return {
netCarbImpact: netCarbImpact,
totalImpact: totalImpact
netCarbImpact: netCarbImpact
, totalImpact: totalImpact
};
};
@@ -241,26 +241,23 @@ function init(ctx) {
decayedBy.setMinutes(decayedBy.getMinutes() + Math.max(delay, minutesleft) + treatment.carbs / carbs_min);
if (delay > minutesleft) {
initialCarbs = parseInt(treatment.carbs);
}
else {
} else {
initialCarbs = parseInt(treatment.carbs) + minutesleft * carbs_min;
}
var startDecay = new Date(carbTime);
startDecay.setMinutes(carbTime.getMinutes() + delay);
if (time < lastDecayedBy || time > startDecay) {
isDecaying = 1;
}
else {
} else {
isDecaying = 0;
}
return {
initialCarbs: initialCarbs,
decayedBy: decayedBy,
isDecaying: isDecaying,
carbTime: carbTime
initialCarbs: initialCarbs
, decayedBy: decayedBy
, isDecaying: isDecaying
, carbTime: carbTime
};
}
else {
} else {
return '';
}
};
+4 -5
View File
@@ -9,8 +9,8 @@ var _map = require('lodash/map');
function init (ctx) {
var allPlugins = [],
enabledPlugins = [];
var allPlugins = []
, enabledPlugins = [];
function plugins (name) {
if (name) {
@@ -105,16 +105,15 @@ function init(ctx) {
enabledPlugins.push(plugin);
}
});
};
plugins.isPluginEnabled = function isPluginEnabled (pluginName) {
var p = _.find(enabledPlugins, 'name', pluginName);
var p = _find(enabledPlugins, 'name', pluginName);
return (p !== null);
}
plugins.getPlugin = function getPlugin (pluginName) {
return _.find(enabledPlugins, 'name', pluginName);
return _find(enabledPlugins, 'name', pluginName);
}
plugins.eachPlugin = function eachPlugin (f) {
+3 -9
View File
@@ -262,7 +262,7 @@ function init(ctx) {
var canceled = prop.lastEnacted.rate === 0 && prop.lastEnacted.duration === 0;
var valueParts = [
, '<b>Temp Basal' + (canceled ? ' Canceled' : ' Started') + '</b>'
'<b>Temp Basal' + (canceled ? ' Canceled' : ' Started') + '</b>'
, canceled ? '' : ' ' + prop.lastEnacted.rate.toFixed(2) + 'U/hour for ' + prop.lastEnacted.duration + 'm'
, valueString(', ', prop.lastEnacted.reason)
];
@@ -284,7 +284,9 @@ function init(ctx) {
var iob = prop.lastLoop.iob;
valueParts = valueParts.concat([
', IOB: '
, sbx.roundInsulinForDisplayFormat(iob.iob) + 'U'
, iob.basaliob ? ', Basal IOB ' + sbx.roundInsulinForDisplayFormat(iob.basaliob) + 'U' : ''
]);
}
@@ -294,7 +296,6 @@ function init(ctx) {
function concatCOB (valueParts) {
if (prop.lastLoop && prop.lastLoop.cob) {
var cob = prop.lastLoop.cob;
var cob = prop.lastLoop.cob.cob;
cob = Math.round(cob);
valueParts = valueParts.concat([
@@ -364,12 +365,6 @@ function init(ctx) {
if (predicted.values) {
points = points.concat(_.map(predicted.values, toPoints(startTime, 0)));
}
// if (prop.lastPredBGs.IOB) {
// points = points.concat(_.map(prop.lastPredBGs.IOB, toPoints(moment, 3000)));
// }
// if (prop.lastPredBGs.COB) {
// points = points.concat(_.map(prop.lastPredBGs.COB, toPoints(moment, 7000)));
// }
}
return points;
@@ -523,5 +518,4 @@ function init(ctx) {
}
module.exports = init;
+32 -9
View File
@@ -27,7 +27,6 @@ function init(ctx) {
return _.isEmpty(list) || _.isEmpty(list[0]);
}
var fields = cleanList(sbx.extendedSettings.fields);
fields = isEmpty(fields) ? ['status-symbol', 'status-label', 'iob', 'meal-assist', 'rssi'] : fields;
@@ -122,8 +121,7 @@ function init(ctx) {
};
if (moments.notEnacted && (
(moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent)))
) {
(moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent)))) {
status.symbol = 'x';
status.code = 'notenacted';
status.label = 'Not Enacted';
@@ -240,18 +238,43 @@ function init(ctx) {
{
val: 'Temporary Target'
, name: 'Temporary Target'
, bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false
, targets: true, reasons: reasonconf
, bg: false
, insulin: false
, carbs: false
, prebolus: false
, duration: true
, percent: false
, absolute: false
, profile: false
, split: false
, targets: true
, reasons: reasonconf
}
, {
val: 'Temporary Target Cancel'
, name: 'Temporary Target Cancel'
, bg: false, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false
, bg: false
, insulin: false
, carbs: false
, prebolus: false
, duration: false
, percent: false
, absolute: false
, profile: false
, split: false
}
, {
val: 'OpenAPS Offline'
, name: 'OpenAPS Offline'
, bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false
, bg: false
, insulin: false
, carbs: false
, prebolus: false
, duration: true
, percent: false
, absolute: false
, profile: false
, split: false
}
];
};
@@ -464,8 +487,8 @@ function init(ctx) {
var response = translate('alexaOpenAPSForecast', {
params: [
sbx.properties.openaps.lastEventualBG
]}
);
]
});
next('Loop Forecast', response);
}
}
+1 -5
View File
@@ -1,10 +1,6 @@
'use strict';
var levels = require('../levels');
var times = require('../times');
var lastEntryValue;
var lastTime;
var lastMinutes;
var lastEntryTime;
@@ -78,7 +74,7 @@ function init(ctx) {
lastMinutes = timeMinutes;
var lastEntryString = translate('Last entry {0} minutes ago');
var sayIt = lastEntryString.replace('{0}', timeMinutes);
sayIt = lastEntryString.replace('{0}', timeMinutes);
speech.say(sayIt);
}
}
+7 -22
View File
@@ -240,7 +240,7 @@ function init (profileData) {
if (treatment.profileJson && !profile.data[0].store[treatment.profile]) {
if (treatment.profile.indexOf("@@@@@") < 0)
treatment.profile += "@@@@@" + treatment.mills;
var json = JSON.parse(treatment.profileJson);
let json = JSON.parse(treatment.profileJson);
profile.data[0].store[treatment.profile] = json;
}
}
@@ -250,7 +250,7 @@ function init (profileData) {
if (treatment.profileJson && !profile.data[0].store[treatment.profile]) {
if (treatment.profile.indexOf("@@@@@") < 0)
treatment.profile += "@@@@@" + treatment.mills;
var json = JSON.parse(treatment.profileJson);
let json = JSON.parse(treatment.profileJson);
profile.data[0].store[treatment.profile] = json;
}
}
@@ -277,7 +277,8 @@ function init (profileData) {
}
// Binary search for events for O(log n) performance
var first = 0, last = profile.tempbasaltreatments.length - 1;
var first = 0
, last = profile.tempbasaltreatments.length - 1;
while (first <= last) {
var i = first + Math.floor((last - first) / 2);
@@ -349,29 +350,13 @@ function init (profileData) {
var current = profile.activeProfileToTime();
profiles.push(current);
for (var key in profile.data[0].store) {
if (profile.data[0].store.hasOwnProperty(key) && key !== current) {
if (key.indexOf('@@@@@') < 0)
profiles.push(key);
}
}
Object.keys(profile.data[0].store).forEach(key => {
if (key !== current && key.indexOf('@@@@@') < 0) profiles.push(key);
})
}
return profiles;
};
// get original store without added profiles fro profileSwitches
profile.getProfileStore = function getProfileStore () {
var newprofiledata = _.clone(profile.data[0]);
for (var key in profile.data[0].store) {
if (profile.data[0].store.hasOwnProperty(key)) {
if (key.indexOf('@@@@@') < 0)
store[key] = profile.data[0].store[key];
}
}
return store;
};
if (profileData) { profile.loadData(profileData); }
// init treatments array
profile.updateTreatments([], []);
+4 -6
View File
@@ -17,10 +17,9 @@ module.exports = init;
calibrations.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Calibrations') + '</h2>'
+ '<div style="width:50%;height:500px;float:left;overflow:scroll;overflow-x:hidden;" id="calibrations-list"></div>'
+ '<div style="width:48%;float:right;" id="calibrations-chart"></div>'
;
'<h2>' + translate('Calibrations') + '</h2>' +
'<div style="width:50%;height:500px;float:left;overflow:scroll;overflow-x:hidden;" id="calibrations-list"></div>' +
'<div style="width:48%;float:right;" id="calibrations-chart"></div>';
return ret;
};
@@ -58,7 +57,6 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
});
mbgs.forEach(function(mbg) { calcmbg(mbg); });
var events = treatments.concat(cals).concat(mbgs).sort(function(a, b) { return a.mills - b.mills; });
var colors = ['Aqua', 'Blue', 'Brown', 'Chartreuse', 'Coral', 'CornflowerBlue', 'DarkCyan', 'DarkMagenta', 'DarkOrange', 'Fuchsia', 'Green', 'Yellow'];
@@ -90,7 +88,7 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
html += JSON.stringify(e);
}
html += '</td></tr>';
};
}
html += '</table>';
+46 -49
View File
@@ -15,25 +15,23 @@ module.exports = init;
dailystats.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Daily stats report') + '</h2>'
+ '<div id="dailystats-report"></div>'
;
'<h2>' + translate('Daily stats report') + '</h2>' +
'<div id="dailystats-report"></div>';
return ret;
};
dailystats.css =
'#dailystats-placeholder .tdborder {'
+ ' width:80px;'
+ ' border: 1px #ccc solid;'
+ ' margin: 0;'
+ ' padding: 1px;'
+ ' text-align:center;'
+ '}'
+ '#dailystats-placeholder .inlinepiechart {'
+ ' width: 2.0in;'
+ ' height: 0.9in;'
+ '}'
;
'#dailystats-placeholder .tdborder {' +
' width:80px;' +
' border: 1px #ccc solid;' +
' margin: 0;' +
' padding: 1px;' +
' text-align:center;' +
'}' +
'#dailystats-placeholder .inlinepiechart {' +
' width: 2.0in;' +
' height: 0.9in;' +
'}';
dailystats.report = function report_dailystats (datastorage, sorteddaystoshow, options) {
var Nightscout = window.Nightscout;
@@ -73,10 +71,10 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti
if (daysRecords.length === 0) {
$('<td/>').appendTo(tr);
$('<td class=\"tdborder\" style=\"width:160px\">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
$('<td class=\"tdborder\"colspan="10">'+translate('No data available')+'</td>').appendTo(tr);
$('<td class="tdborder" style="width:160px">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
$('<td class="tdborder"colspan="10">' + translate('No data available') + '</td>').appendTo(tr);
table.append(tr);
return;;
return;
}
minForDay = daysRecords[0].sgv;
@@ -101,53 +99,52 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti
sum += record.sgv;
return out;
}, {
lows: 0,
normal: 0,
highs: 0
lows: 0
, normal: 0
, highs: 0
});
var average = sum / daysRecords.length;
var bgValues = daysRecords.map(function(r) { return r.sgv; });
$('<td><div id=\"dailystat-chart-' + day.toString() + '\" class=\"inlinepiechart\"></div></td>').appendTo(tr);
$('<td><div id="dailystat-chart-' + day.toString() + '" class="inlinepiechart"></div></td>').appendTo(tr);
$('<td class=\"tdborder\" style=\"width:160px\">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
$('<td class=\"tdborder\">' + Math.round((100 * stats.lows) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class=\"tdborder\">' + Math.round((100 * stats.normal) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class=\"tdborder\">' + Math.round((100 * stats.highs) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class=\"tdborder\">' + daysRecords.length +'</td>').appendTo(tr);
$('<td class=\"tdborder\">' + minForDay +'</td>').appendTo(tr);
$('<td class=\"tdborder\">' + maxForDay +'</td>').appendTo(tr);
$('<td class=\"tdborder\">' + average.toFixed(1) +'</td>').appendTo(tr);
$('<td class=\"tdborder\">' + ss.standard_deviation(bgValues).toFixed(1) + '</td>').appendTo(tr);
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.25).toFixed(1) + '</td>').appendTo(tr);
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.5).toFixed(1) + '</td>').appendTo(tr);
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.75).toFixed(1) + '</td>').appendTo(tr);
$('<td class="tdborder" style="width:160px">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
$('<td class="tdborder">' + Math.round((100 * stats.lows) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class="tdborder">' + Math.round((100 * stats.normal) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class="tdborder">' + Math.round((100 * stats.highs) / daysRecords.length) + '%</td>').appendTo(tr);
$('<td class="tdborder">' + daysRecords.length + '</td>').appendTo(tr);
$('<td class="tdborder">' + minForDay + '</td>').appendTo(tr);
$('<td class="tdborder">' + maxForDay + '</td>').appendTo(tr);
$('<td class="tdborder">' + average.toFixed(1) + '</td>').appendTo(tr);
$('<td class="tdborder">' + ss.standard_deviation(bgValues).toFixed(1) + '</td>').appendTo(tr);
$('<td class="tdborder">' + ss.quantile(bgValues, 0.25).toFixed(1) + '</td>').appendTo(tr);
$('<td class="tdborder">' + ss.quantile(bgValues, 0.5).toFixed(1) + '</td>').appendTo(tr);
$('<td class="tdborder">' + ss.quantile(bgValues, 0.75).toFixed(1) + '</td>').appendTo(tr);
table.append(tr);
var inrange = [
{
label: translate('Low'),
data: Math.round(stats.lows * 1000 / daysRecords.length) / 10
},
{
label: translate('In Range'),
data: Math.round(stats.normal * 1000 / daysRecords.length) / 10
},
{
label: translate('High'),
data: Math.round(stats.highs * 1000 / daysRecords.length) / 10
label: translate('Low')
, data: Math.round(stats.lows * 1000 / daysRecords.length) / 10
}
, {
label: translate('In Range')
, data: Math.round(stats.normal * 1000 / daysRecords.length) / 10
}
, {
label: translate('High')
, data: Math.round(stats.highs * 1000 / daysRecords.length) / 10
}
];
$.plot(
'#dailystat-chart-' + day.toString(),
inrange,
{
'#dailystat-chart-' + day.toString()
, inrange, {
series: {
pie: {
show: true
}
},
colors: ['#f88', '#8f8', '#ff8']
}
, colors: ['#f88', '#8f8', '#ff8']
}
);
});
+68 -73
View File
@@ -20,51 +20,50 @@ module.exports = init;
daytoday.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Day to day') + '</h2>'
+ '<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>'
+ translate('Display') + ': '
+ '<input type="checkbox" id="rp_optionsinsulin" checked><span style="color:blue;opacity:0.5">'+translate('Insulin')+'</span>'
+ '<input type="checkbox" id="rp_optionscarbs" checked><span style="color:red;opacity:0.5">'+translate('Carbs')+'</span>'
+ '<input type="checkbox" id="rp_optionsbasal" checked><span style="color:#0099ff;opacity:0.5">'+translate('Basal rate')+'</span>'
+ '<input type="checkbox" id="rp_optionsnotes">'+translate('Notes')
+ '<input type="checkbox" id="rp_optionsfood" checked>'+translate('Food')
+ '<input type="checkbox" id="rp_optionsraw"><span style="color:gray;opacity:1">'+translate('Raw')+'</span>'
+ '<input type="checkbox" id="rp_optionsiob"><span style="color:blue;opacity:0.5">'+translate('IOB')+'</span>'
+ '<input type="checkbox" id="rp_optionscob"><span style="color:red;opacity:0.5">'+translate('COB')+'</span>'
+ '<input type="checkbox" id="rp_optionspredicted"><span style="color:sienna;opacity:0.5">'+translate('Predictions')+'</span>'
+ '<input type="checkbox" id="rp_optionsopenaps"><span style="color:sienna;opacity:0.5">'+translate('OpenAPS')+'</span>'
+ '<input type="checkbox" id="rp_optionsdistribution" checked><span style="color:blue;opacity:0.5">'+translate('Insulin distribution')+'</span>'
+ '&nbsp;'+translate('Size')
+ ' <select id="rp_size">'
+ ' <option x="800" y="250">800x250px</option>'
+ ' <option x="1000" y="300" selected>1000x300px</option>'
+ ' <option x="1200" y="400">1200x400px</option>'
+ ' <option x="1550" y="600">1550x600px</option>'
+ ' <option x="2400" y="800">2400x800px</option>'
+ '</select>'
+ '<br>'
+ translate('Scale') + ': '
+ '<input type="radio" name="rp_scale" id="rp_linear" checked>'
+ translate('Linear')
+ '<input type="radio" name="rp_scale" id="rp_log">'
+ translate('Logarithmic')
+ '<div id="rp_predictedSettings" style="display:none">'
+ translate('Truncate predictions: ')
+ '<input type="checkbox" id="rp_optionsPredictedTruncate" checked>'
+ '<br>'
+ translate('Predictions offset') + ': '
+ '<b><label id="rp_predictedOffset"></label> minutes</b>'
+ '&nbsp;&nbsp;&nbsp;&nbsp;'
+ '<input type="button" onclick="predictMoreBackward();" value="' + translate('-30 min')+'">'
+ '<input type="button" onclick="predictBackward();" value="' + translate('-5 min')+'">'
+ '<input type="button" onclick="predictResetToZero();" value="' + translate('Zero')+'">'
+ '<input type="button" onclick="predictForward();" value="' + translate('+5 min')+'">'
+ '<input type="button" onclick="predictMoreForward();" value="' + translate('+30 min')+'">'
+ '</div>'
+ '<br>'
+ '<div id="daytodaycharts">'
+ '</div>'
;
'<h2>' + translate('Day to day') + '</h2>' +
'<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>' +
translate('Display') + ': ' +
'<input type="checkbox" id="rp_optionsinsulin" checked><span style="color:blue;opacity:0.5">' + translate('Insulin') + '</span>' +
'<input type="checkbox" id="rp_optionscarbs" checked><span style="color:red;opacity:0.5">' + translate('Carbs') + '</span>' +
'<input type="checkbox" id="rp_optionsbasal" checked><span style="color:#0099ff;opacity:0.5">' + translate('Basal rate') + '</span>' +
'<input type="checkbox" id="rp_optionsnotes">' + translate('Notes') +
'<input type="checkbox" id="rp_optionsfood" checked>' + translate('Food') +
'<input type="checkbox" id="rp_optionsraw"><span style="color:gray;opacity:1">' + translate('Raw') + '</span>' +
'<input type="checkbox" id="rp_optionsiob"><span style="color:blue;opacity:0.5">' + translate('IOB') + '</span>' +
'<input type="checkbox" id="rp_optionscob"><span style="color:red;opacity:0.5">' + translate('COB') + '</span>' +
'<input type="checkbox" id="rp_optionspredicted"><span style="color:sienna;opacity:0.5">' + translate('Predictions') + '</span>' +
'<input type="checkbox" id="rp_optionsopenaps"><span style="color:sienna;opacity:0.5">' + translate('OpenAPS') + '</span>' +
'<input type="checkbox" id="rp_optionsdistribution" checked><span style="color:blue;opacity:0.5">' + translate('Insulin distribution') + '</span>' +
'&nbsp;' + translate('Size') +
' <select id="rp_size">' +
' <option x="800" y="250">800x250px</option>' +
' <option x="1000" y="300" selected>1000x300px</option>' +
' <option x="1200" y="400">1200x400px</option>' +
' <option x="1550" y="600">1550x600px</option>' +
' <option x="2400" y="800">2400x800px</option>' +
'</select>' +
'<br>' +
translate('Scale') + ': ' +
'<input type="radio" name="rp_scale" id="rp_linear" checked>' +
translate('Linear') +
'<input type="radio" name="rp_scale" id="rp_log">' +
translate('Logarithmic') +
'<div id="rp_predictedSettings" style="display:none">' +
translate('Truncate predictions: ') +
'<input type="checkbox" id="rp_optionsPredictedTruncate" checked>' +
'<br>' +
translate('Predictions offset') + ': ' +
'<b><label id="rp_predictedOffset"></label> minutes</b>' +
'&nbsp;&nbsp;&nbsp;&nbsp;' +
'<input type="button" onclick="predictMoreBackward();" value="' + translate('-30 min') + '">' +
'<input type="button" onclick="predictBackward();" value="' + translate('-5 min') + '">' +
'<input type="button" onclick="predictResetToZero();" value="' + translate('Zero') + '">' +
'<input type="button" onclick="predictForward();" value="' + translate('+5 min') + '">' +
'<input type="button" onclick="predictMoreForward();" value="' + translate('+30 min') + '">' +
'</div>' +
'<br>' +
'<div id="daytodaycharts">' +
'</div>';
return ret;
};
@@ -102,18 +101,17 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
var proteinAverage = proteinSum / datastorage.alldays;
var fatAverage = fatSum / datastorage.alldays;
if (options.insulindistribution)
$('#daytodaycharts').append('<br><br><b>' + translate('TDD average') + ':</b> ' + tddAverage.toFixed(1) + 'U <b>'
+ translate('Carbs average') + ':</b> ' + carbsAverage.toFixed(0) + 'g'
+ translate('Protein average') + ':</b> ' + proteinAverage.toFixed(0) + 'g'
+ translate('Fat average') + ':</b> ' + fatAverage.toFixed(0) + 'g'
$('#daytodaycharts').append('<br><br><b>' + translate('TDD average') + ':</b> ' + tddAverage.toFixed(1) + 'U <b>' +
translate('Carbs average') + ':</b> ' + carbsAverage.toFixed(0) + 'g' +
translate('Protein average') + ':</b> ' + proteinAverage.toFixed(0) + 'g' +
translate('Fat average') + ':</b> ' + fatAverage.toFixed(0) + 'g'
);
function timeTicks (n, i) {
var t12 = [
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', '',
'12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', ''
, '12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
];
if (Nightscout.client.settings.timeFormat === 24) {
return ('00' + i).slice(-2);
@@ -264,10 +262,6 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
.attr('stroke', 'grey');
});
// bind up the context chart data to an array of circles
var contextCircles = context.selectAll('circle')
.data(data.sgv);
function prepareContextCircles (sel) {
var badData = [];
sel.attr('cx', function(d) {
@@ -300,9 +294,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
.on('mouseover', function(d) {
if (options.openAps && d.openaps) {
client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9);
var text = '<b>BG:</b> ' + d.openaps.suggested.bg
+ ', ' + d.openaps.suggested.reason
+ (d.openaps.suggested.mealAssist ? ' <b>Meal Assist:</b> ' + d.openaps.suggested.mealAssist : '');
var text = '<b>BG:</b> ' + d.openaps.suggested.bg +
', ' + d.openaps.suggested.reason +
(d.openaps.suggested.mealAssist ? ' <b>Meal Assist:</b> ' + d.openaps.suggested.mealAssist : '');
client.tooltip.html(text)
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pageY + 15) + 'px');
@@ -340,7 +334,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
var predictions = [];
if (data && data.devicestatus) {
for (var i = data.devicestatus.length - 1; i >= 0; i--) {
for (i = data.devicestatus.length - 1; i >= 0; i--) {
if (data.devicestatus[i].loop && data.devicestatus[i].loop.predicted) {
predictions.push(data.devicestatus[i].loop.predicted);
} else if (data.devicestatus[i].openaps && data.devicestatus[i].openaps.suggested && data.devicestatus[i].openaps.suggested.predBGs) {
@@ -363,10 +357,11 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
// Iterate over all treatments, find the predictions for each and add them to the predicted array p
for (var treatmentsIndex = 0; treatmentsIndex < treatmentsTimestamps.length; treatmentsIndex++) {
var timestamp = treatmentsTimestamps[treatmentsIndex];
// TODO / BUG: predictedOffset is not set
var predictedIndex = findPredicted(predictions, timestamp, predictedOffset); // Find predictions offset before or after timestamp
if (predictedIndex != null) {
var entry = predictions[predictedIndex]; // Start entry
entry = predictions[predictedIndex]; // Start entry
var d = moment(entry.startDate);
var end = moment().endOf('day');
if (options.predictedTruncate) {
@@ -409,7 +404,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
}
}
} else { // If offset is positive or zero, start searching from last prediction going backward
for (var i = predictions.length - 1; i > 0; i--) {
for (i = predictions.length - 1; i > 0; i--) {
if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) >= ts) {
predicted = i;
}
@@ -420,7 +415,6 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
//
// PREDICTIONS ENDS
// bind up the context chart data to an array of circles
var contextData = (options.predicted ? data.sgv.concat(preparePredictedData()) : data.sgv);
var contextCircles = context.selectAll('circle').data(contextData);
@@ -433,7 +427,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
var to = moment(day).add(1, 'days');
var from = moment(day);
var iobpolyline = '', cobpolyline = '';
var iobpolyline = ''
, cobpolyline = '';
// basals data
var linedata = [];
@@ -502,7 +497,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
if (tempPart > 0) {
positiveTemps += tempPart;
data.netBasalPositive[hournow] += tempPart;
} if (tempPart < 0) {
}
if (tempPart < 0) {
negativeTemps += tempPart;
data.netBasalNegative[hournow] += tempPart;
}
@@ -552,8 +548,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
// Draw IOB from devicestatuses if available
if (iobStatusAvailable) {
var lastdate = 0;
var previousdate = 0;
lastdate = 0;
previousdate = 0;
var iobArray = client.plugins('iob').IOBDeviceStatusesInTimeRange(datastorage.devicestatus, from.valueOf(), to.valueOf());
_.each(iobArray, function drawCob (point) {
if (previousdate !== 0 && point.mills - previousdate > times.mins(15).msecs) {
@@ -678,7 +674,6 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
});
}
data.treatments.forEach(function(treatment) {
// Calculate bolus stats
if (treatment.insulin) {
@@ -922,11 +917,11 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
var chartData = [
{
label: translate('Basal'),
count: totalBasalInsulin,
pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0)
},
{label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0)}
label: translate('Basal')
, count: totalBasalInsulin
, pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0)
}
, { label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0) }
];
// Insulin distribution chart
+19 -21
View File
@@ -65,8 +65,7 @@ glucosedistribution.html = function html(client) {
'20<input type="checkbox" id="glucosedistribution-20" checked>' +
'21<input type="checkbox" id="glucosedistribution-21" checked>' +
'22<input type="checkbox" id="glucosedistribution-22" checked>' +
'23<input type="checkbox" id="glucosedistribution-23" checked>'
;
'23<input type="checkbox" id="glucosedistribution-23" checked>';
return ret;
};
@@ -132,13 +131,13 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
// Filter data for noise
// data cleaning pass 0 - remove duplicates and non-sgv entries, sort
var seen = {};
var seen = [];
data = data.filter(function(item) {
if (!item.sgv || !item.bgValue || !item.displayTime || item.bgValue < 39) {
if (!item.sgv || !item.bgValue || !item.displayTime || item.bgValue < 39) {
console.log(item);
return false;
}
return seen.hasOwnProperty(item.displayTime) ? false : (seen[item.displayTime] = true);
return seen.includes(item.displayTime) ? false : (seen[item.displayTime] = true);
});
data.sort(function(a, b) {
@@ -148,7 +147,7 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
var glucose_data = [data[0]];
// data cleaning pass 1 - add interpolated missing points
for (var i = 0; i <= data.length - 2; i++) {
for (i = 0; i <= data.length - 2; i++) {
var entry = data[i];
var nextEntry = data[i + 1];
@@ -186,12 +185,12 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
const maxGap = (5 * 60 * 1000) + 10000;
for (var i = 1; i <= glucose_data.length - 2; i++) {
var entry = glucose_data[i];
var nextEntry = glucose_data[i + 1];
for (i = 1; i <= glucose_data.length - 2; i++) {
let entry = glucose_data[i];
let nextEntry = glucose_data[i + 1];
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
var timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime();
let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
let timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime();
if (timeDelta > maxGap || timeDelta2 > maxGap) {
glucose_data2.push(entry);
@@ -212,7 +211,7 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
const d = (nextEntry.bgValue - prevEntry.bgValue) / 2;
const interpolatedValue = prevEntry.bgValue + d;
var newEntry = {
let newEntry = {
sgv: displayUnits === 'mmol' ? interpolatedValue / 18 : interpolatedValue
, bgValue: interpolatedValue
, displayTime: entry.displayTime
@@ -237,10 +236,10 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
});
var timeTotal = 0;
for (var i = 1; i <= glucose_data.length - 2; i++) {
var entry = glucose_data[i];
var nextEntry = glucose_data[i + 1];
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
for (i = 1; i <= glucose_data.length - 2; i++) {
let entry = glucose_data[i];
let nextEntry = glucose_data[i + 1];
let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
if (timeDelta < maxGap) {
timeTotal += timeDelta;
}
@@ -357,11 +356,10 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
var glucoseTotal = 0;
var deltaTotal = 0;
for (var i = 0; i <= glucose_data.length - 2; i++) {
var entry = glucose_data[i];
var nextEntry = glucose_data[i + 1];
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
for (i = 0; i <= glucose_data.length - 2; i++) {
const entry = glucose_data[i];
const nextEntry = glucose_data[i + 1];
const timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
// Use maxGap constant
if (timeDelta == 0 || timeDelta > maxGap) { // 6 * 60 * 1000) {
+41 -40
View File
@@ -17,22 +17,21 @@ module.exports = init;
hourlystats.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Hourly stats') + '</h2>'
+ '<div id="hourlystats-overviewchart"></div>'
+ '<div id="hourlystats-report"></div>'
;
'<h2>' + translate('Hourly stats') + '</h2>' +
'<div id="hourlystats-overviewchart"></div>' +
'<div id="hourlystats-report"></div>';
return ret;
};
hourlystats.css =
'#hourlystats-overviewchart {'
+ ' width: 100%;'
+ ' min-width: 6.5in;'
+ ' height: 5in;'
+ '}'
+ '#hourlystats-placeholder td {'
+ ' text-align:center;'
+ '}';
'#hourlystats-overviewchart {' +
' width: 100%;' +
' min-width: 6.5in;' +
' height: 5in;' +
'}' +
'#hourlystats-placeholder td {' +
' text-align:center;' +
'}';
hourlystats.report = function report_hourlystats (datastorage, sorteddaystoshow, options) {
//console.log(window);
@@ -89,15 +88,15 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
return r.sgv;
}));
stats.push([
new Date(d),
ss.quantile(pivotedByHour[hour].map(function (r) {
new Date(d)
, ss.quantile(pivotedByHour[hour].map(function(r) {
return r.sgv;
}), 0.25),
ss.quantile(pivotedByHour[hour].map(function (r) {
}), 0.25)
, ss.quantile(pivotedByHour[hour].map(function(r) {
return r.sgv;
}), 0.75),
avg - dev,
avg + dev
}), 0.75)
, avg - dev
, avg + dev
]);
var tmp;
$('<td>' + display + '</td>').appendTo(tr);
@@ -106,12 +105,15 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
$('<td>' + Math.min.apply(Math, pivotedByHour[hour].map(function(r) {
return r.sgv;
})) + '</td>').appendTo(tr);
// eslint-disable-next-line no-cond-assign
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
return r.sgv;
}), 0.25)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
// eslint-disable-next-line no-cond-assign
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
return r.sgv;
}), 0.5)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
// eslint-disable-next-line no-cond-assign
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
return r.sgv;
}), 0.75)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
@@ -126,28 +128,27 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
report.append(table);
$.plot(
'#hourlystats-overviewchart',
[{
data: stats,
candle: true
}],
{
'#hourlystats-overviewchart'
, [{
data: stats
, candle: true
}], {
series: {
candle: true,
lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;)
},
xaxis: {
mode: 'time',
timeFormat: '%h:00',
min: 0,
max: times.hours(24).msecs - times.secs(1).msecs
},
yaxis: {
min: 0,
max: options.units === 'mmol' ? 22 : 400,
show: true
},
grid: {
candle: true
, lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;)
}
, xaxis: {
mode: 'time'
, timeFormat: '%h:00'
, min: 0
, max: times.hours(24).msecs - times.secs(1).msecs
}
, yaxis: {
min: 0
, max: options.units === 'mmol' ? 22 : 400
, show: true
}
, grid: {
show: true
}
}
+148 -143
View File
@@ -47,19 +47,19 @@ loopalyzer.html = function html(client) {
ret += '<input type="number" style="width: 3.5em" value="10" id="rp_loopalyzermincarbs">' + ' ' + translate('g carbs');
ret += '&nbsp;' + translate('consumed between');
ret += ' <select id="rp_loopalyzert1">';
for (var i=0; i<24; i++) {
var H=(i<10?'0':'') + i;
for (let i = 0; i < 24; i++) {
const H = (i < 10 ? '0' : '') + i;
ret += ' <option t1="' + H + ':00"' + (i == 6 ? ' selected' : '') + '>' + H + ':00</option>';
ret += ' <option t1="' + H + ':30">' + H + ':30</option>';
}
ret += '</select>';
ret += ' ' + translate('and');
ret += ' <select id="rp_loopalyzert2">';
for (var i=0; i<24; i++) {
var H=(i<10?'0':'') + i;
for (let i = 0; i < 24; i++) {
const H = (i < 10 ? '0' : '') + i;
ret += ' <option t2="' + H + ':00"' + (i == 9 ? ' selected' : '') + '>' + H + ':00</option>';
ret += ' <option t2="' + H + ':30">' + H + ':30</option>';
};
}
ret += '</select>';
ret += '</span>'; /* timeShift */
ret += '<br/><br/>';
@@ -81,19 +81,18 @@ loopalyzer.html = function html(client) {
};
loopalyzer.css =
'#loopalyzer-charts, #loopalyzer-profiles { padding: 20px; } '
+ '#loopalyzer-basal, #loopalyzer-bg, #loopalyzer-tempbasal, #loopalyzer-iob, #loopalyzer-cob, #loopalyzer-profiles {'
+ ' width: 100%;'
+ ' height: 100%;'
+ '}'
+ '#loopalyzer-profiles-table table { margin: 0 10px; border-collapse: collapse; border: 0px; }'
+ '#loopalyzer-profiles-table td { vertical-align: top; }'
+ '#loopalyzer-profiles-table td table { margin: 0 10px; border-collapse: collapse; border: 0px; }'
+ '#loopalyzer-profiles-table td caption { text-align: left; font-weight: bold; }'
+ '#loopalyzer-profiles-table td th { background-color: #4CAF50; color: white; }'
+ '#loopalyzer-profiles-table td td { text-align: right; vertical-align: top; padding: 0 1px; }'
+ '#loopalyzer-profiles-table td td td { padding: 1px 8px; }'
;
'#loopalyzer-charts, #loopalyzer-profiles { padding: 20px; } ' +
'#loopalyzer-basal, #loopalyzer-bg, #loopalyzer-tempbasal, #loopalyzer-iob, #loopalyzer-cob, #loopalyzer-profiles {' +
' width: 100%;' +
' height: 100%;' +
'}' +
'#loopalyzer-profiles-table table { margin: 0 10px; border-collapse: collapse; border: 0px; }' +
'#loopalyzer-profiles-table td { vertical-align: top; }' +
'#loopalyzer-profiles-table td table { margin: 0 10px; border-collapse: collapse; border: 0px; }' +
'#loopalyzer-profiles-table td caption { text-align: left; font-weight: bold; }' +
'#loopalyzer-profiles-table td th { background-color: #4CAF50; color: white; }' +
'#loopalyzer-profiles-table td td { text-align: right; vertical-align: top; padding: 0 1px; }' +
'#loopalyzer-profiles-table td td td { padding: 1px 8px; }';
loopalyzer.prepareHtml = function loopalyzerPrepareHtml () {
// $('#loopalyzer-charts').append($('<table><tr><td><div id="loopalyzerchart"></div></td><td><div id="loopalyzerstatchart"></td></tr></table>'));
@@ -111,12 +110,12 @@ loopalyzer.getSGVs = function(datastorage, daysToShow) {
// Loop thru the days to show, for each day find the matching SGVs and insert into the bins entry array
daysToShow.forEach(function(day) {
var entries = []; // Array with all SGVs for this day, we'll fill this and then insert into the bins later
for (var i=0; i<288; i++) entries.push(NaN); // Fill the array with NaNs so we have something in case we don't find an SGV
for (let i = 0; i < 288; i++) entries.push(NaN); // Fill the array with NaNs so we have something in case we don't find an SGV
var fromDate = moment(day);
var toDate = moment(day);
fromDate.set({ 'hours': 0, 'minutes': 0, 'seconds': 0, 'milliseconds': 0 });
toDate.set({ 'hours': 0, 'minutes': 5, 'seconds': 0, 'milliseconds': 0 }); // toDate is 5 mins ahead
for (var i=0; i<288; i++) {
for (let i = 0; i < 288; i++) {
var found = false;
data.some(function(record) {
var recDate = moment(record.displayTime);
@@ -199,7 +198,8 @@ loopalyzer.getIOBs = function(datastorage, daysToShow, profile, client, treatmen
if (daysToShow.length === 1) loopalyzer.fillNanWithTreatments(iobs, treatments);
// Loop thru these entries and where no IOB has been found, interpolate between nearby to get a continuous array
var startIndex = 0, stopIndex = 0;
var startIndex = 0
, stopIndex = 0;
while (startIndex < iobs.length && isNaN(iobs[startIndex])) {
startIndex++; // Advance start to the first real number
}
@@ -261,7 +261,10 @@ loopalyzer.getCOBs = function(datastorage, daysToShow, profile, client, treatmen
if (daysToShow.length === 1) loopalyzer.fillNanWithTreatments(cobs, treatments);
// Loop thru these entries and where no COB has been found, interpolate between nearby to get a continuous array
var startIndex=0, stopIndex=0, k=0, m=0;
var startIndex = 0
, stopIndex = 0
, k = 0
, m = 0;
while (startIndex < cobs.length && isNaN(cobs[startIndex])) {
startIndex++; // Advance start to the first real number
@@ -315,8 +318,10 @@ loopalyzer.fillNanWithTreatments = function(array, treatments) {
var stop = index;
// Now move left and right until we find real numbers, so not NaN
while (start-- >=0 && isNaN(array[start])) {};
while (stop++ <array.length && isNaN(array[stop])) {};
// eslint-disable-next-line no-empty
while (start-- >= 0 && isNaN(array[start])) {}
// eslint-disable-next-line no-empty
while (stop++ < array.length && isNaN(array[stop])) {}
// var gap = stop - start;
// if (isNaN(array[start]) || isNaN(array[stop]) || gap > interpolationGap || (gap < interpolationGap && array[start]<array[stop])) {
// if ( isNaN(array[start]) || isNaN(array[stop]) || (array[start] < array[stop] && (gap >= interpolationGap || array[start]==0)) ) {
@@ -421,13 +426,13 @@ loopalyzer.findPredicted = function(predictions, timestamp, offset) {
var ts = moment(timestamp).add(offset, 'minutes');
var predicted = null;
if (offset && offset < 0) { // If offset is negative, start searching from first prediction going forward
for (var i = 0; i < predictions.length; i++) {
for (let i = 0; i < predictions.length; i++) {
if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) <= ts) {
predicted = i;
}
}
} else { // If offset is positive or zero, start searching from last prediction going backward
for (var i = predictions.length - 1; i > 0; i--) {
for (let i = predictions.length - 1; i > 0; i--) {
if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) >= ts) {
predicted = i;
}
@@ -436,7 +441,6 @@ loopalyzer.findPredicted = function(predictions, timestamp, offset) {
return predicted;
}
loopalyzer.getPredictions = function(datastorage, daysToShow, client) {
if (!datastorage.devicestatus)
@@ -494,7 +498,7 @@ loopalyzer.getPredictions = function(datastorage, daysToShow, client) {
}
}
}
for (var i=0; i<288; i++) {
for (let i = 0; i < 288; i++) {
bins[i][1].push(p[i]);
}
})
@@ -503,7 +507,6 @@ loopalyzer.getPredictions = function(datastorage, daysToShow, client) {
//
// PREDICTIONS ENDS
// VARIOUS UTILITY FUNCTIONS //
/* Create an empty bins array with date stamps for today */
@@ -529,7 +532,10 @@ loopalyzer.addArrayToBins = function(bins, values) {
/* Fill all NaNs in an array by interpolating between adjacent values */
loopalyzer.interpolateArray = function(values, allowNegative) {
var startIndex=0, stopIndex=0, k=0, m=0;
var startIndex = 0
, stopIndex = 0
, k = 0
, m = 0;
while (isNaN(values[startIndex])) {
startIndex++; // Advance start to the first real number
@@ -586,7 +592,7 @@ loopalyzer.avg = function(xBins) {
var sum = 0;
var count = 0;
entry[1].forEach(function(value) {
if (value && value != NaN) {
if (value && !isNaN(value)) {
sum += value;
count++;
}
@@ -608,17 +614,17 @@ loopalyzer.timeShiftBins = function(bins, timeShift) {
})
var minutesBy5 = Math.floor(minutes / 5);
if (minutesBy5 > 0) {
var count = 288-minutesBy5;
let count = 288 - minutesBy5;
// If minutes>0 it means we should shift forward in time
// Example: Shift by 15 mins = 3 buckets
// bin : 0 1 2 3 4 5 6 7 8 9 10
// tempBin: NaN NaN NaN 0 1 2 3 4 5 6 7
for (var i=0; i<count; i++) {
for (let i = 0; i < count; i++) {
tempBin[i + minutesBy5] = bins[i][1][dayIndex];
}
}
if (minutesBy5 < 0) {
var count = 288+minutesBy5;
let count = 288 + minutesBy5;
// If minutes<0 it means we should shift backward in time
// Example: Shift by 15 mins = 3 buckets
// bin : 0 1 2 3 4 5 6 7 8 9 10
@@ -628,7 +634,7 @@ loopalyzer.timeShiftBins = function(bins, timeShift) {
}
}
// Put the shifted data back into original bins variable (pass by pointer)
for (var i=0; i<288; i++) {
for (let i = 0; i < 288; i++) {
bins[i][1][dayIndex] = tempBin[i];
}
}
@@ -726,6 +732,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client
if (store) {
for (var key in store) {
if (laDebug) console.log('profile ' + key);
// eslint-disable-next-line no-prototype-builtins
if (store.hasOwnProperty(key)) {
var defaultProfile = store[key];
newEntry.profileName = key;
@@ -887,7 +894,6 @@ loopalyzer.report = function(datastorage,sorteddaystoshow,options) {
}
}
loopalyzer.generateReport = function(datastorage, daysToShow, options) {
var Nightscout = window.Nightscout;
var client = Nightscout.client;
@@ -950,7 +956,8 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
var timeShiftStartTime = null; // If timeShifting this is the average time the meals were eaten
var timeShiftStopTime = null; // and this is the start + DIA according to profile
var doTimeShift = false;
daysToShow.forEach(function(){ timeShifts.push(0); firstCarbs.push(NaN) });
daysToShow.forEach(function() { timeShifts.push(0);
firstCarbs.push(NaN) });
// Check to see if we are doing timeShift or not
if ($("#rp_loopalyzertimeshift").is(":checked") && daysToShow.length > 1) {
@@ -995,13 +1002,16 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
})
// Calculate the average starting time, in minutes after midnight
var averageMinutesAfterMidnight = 0, sum = 0, count = 0;
var sum = 0
, count = 0;
firstCarbs.forEach(function(minutesAfterMidnight) {
if (minutesAfterMidnight) { // Avoid NaN
sum += minutesAfterMidnight;
count++;
}
});
var averageMinutesAfterMidnight = Math.round(sum / count);
var dia = profile.getDIA();
@@ -1068,56 +1078,54 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
var borderWidth = 1;
var labelWidth = 25;
var xaxisCfg = {
mode: 'time',
timezone: 'browser',
timeformat: '%H:%M',
tickColor: tickColor,
tickSize: [1, "hour"],
font: { size: 0 }
mode: 'time'
, timezone: 'browser'
, timeformat: '%H:%M'
, tickColor: tickColor
, tickSize: [1, "hour"]
, font: { size: 0 }
};
var hiddenAxis = {
position: "right",
show: true,
labelWidth: 10,
tickColor: "#FFFFFF",
font: { size: 0}
position: "right"
, show: true
, labelWidth: 10
, tickColor: "#FFFFFF"
, font: { size: 0 }
}
// For drawing the carbs and insulin treatments
var markings = [];
var markingColor = "#000000";
// Chart 1: Basal
markings = [];
if (doTimeShift)
markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor });
var chartBasalData = [{
data: basalsAvg,
label: translate('Basal profile'),
id: 'basals',
color: basalColor,
points: { show: false },
bars: { show: true, fill: true, barWidth: barWidth },
yaxis: 1
data: basalsAvg
, label: translate('Basal profile')
, id: 'basals'
, color: basalColor
, points: { show: false }
, bars: { show: true, fill: true, barWidth: barWidth }
, yaxis: 1
}];
var chartBasalOptions = {
xaxis: xaxisCfg,
yaxes: [{
tickColor: tickColor,
labelWidth: labelWidth,
tickFormatter: function(val,axis) { return tickFormatter(val,axis); }
},
hiddenAxis],
grid: {
borderWidth: borderWidth,
markings: markings
xaxis: xaxisCfg
, yaxes: [{
tickColor: tickColor
, labelWidth: labelWidth
, tickFormatter: function(val, axis) { return tickFormatter(val, axis); }
}
, hiddenAxis]
, grid: {
borderWidth: borderWidth
, markings: markings
}
};
$.plot('#loopalyzer-basal', chartBasalData, chartBasalOptions);
// Chart 2: Blood glucose
markings = [];
if (doTimeShift)
@@ -1125,41 +1133,40 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
markings.push({ yaxis: { from: low, to: high }, color: glucoseRangeColor });
var chartBGData = [{
label: translate('Blood glucose'),
data: sgvAvg,
id: 'glucose',
color: glucoseColor,
points: { show: false },
lines: { show: true }
label: translate('Blood glucose')
, data: sgvAvg
, id: 'glucose'
, color: glucoseColor
, points: { show: false }
, lines: { show: true }
}];
if (predictionsAvg && predictionsAvg.length > 0) {
chartBGData.push({
label: translate('Predictions'),
data: predictionsAvg,
id: 'predictions',
color: predictionsColor,
points: { show: true, fill: true, radius: 0.75, fillColor: predictionsColor },
lines: { show: false }
label: translate('Predictions')
, data: predictionsAvg
, id: 'predictions'
, color: predictionsColor
, points: { show: true, fill: true, radius: 0.75, fillColor: predictionsColor }
, lines: { show: false }
});
}
var chartBGOptions = {
xaxis: xaxisCfg,
yaxes: [{
min: 0,
max: options.units === 'mmol' ? 20 : 400,
tickColor: tickColor,
labelWidth: labelWidth,
tickFormatter: function(val,axis) { return tickFormatter(val,axis); }
},
hiddenAxis],
grid: {
borderWidth: borderWidth,
markings: markings
xaxis: xaxisCfg
, yaxes: [{
min: 0
, max: options.units === 'mmol' ? 20 : 400
, tickColor: tickColor
, labelWidth: labelWidth
, tickFormatter: function(val, axis) { return tickFormatter(val, axis); }
}
, hiddenAxis]
, grid: {
borderWidth: borderWidth
, markings: markings
}
};
$.plot('#loopalyzer-bg', chartBGData, chartBGOptions);
// Chart 3: Delta temp basals
markings = [];
if (doTimeShift)
@@ -1167,29 +1174,28 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
markings.push({ yaxis: { from: 0, to: 0 }, color: insulinColor, lineWidth: 2 });
var chartTempBasalData = [{
data: tempBasalsAvg,
label: translate('Temp basal delta'),
id: 'tempBasals',
color: insulinColor,
points: { show: false },
bars: { show: true, barWidth: barWidth }
data: tempBasalsAvg
, label: translate('Temp basal delta')
, id: 'tempBasals'
, color: insulinColor
, points: { show: false }
, bars: { show: true, barWidth: barWidth }
}];
var chartTempBasalOptions = {
xaxis: xaxisCfg,
yaxes: [{
tickColor: tickColor,
labelWidth: labelWidth,
tickFormatter: function(val,axis) { return tickFormatter(val,axis); }
},
hiddenAxis],
grid: {
borderWidth: borderWidth,
markings: markings
xaxis: xaxisCfg
, yaxes: [{
tickColor: tickColor
, labelWidth: labelWidth
, tickFormatter: function(val, axis) { return tickFormatter(val, axis); }
}
, hiddenAxis]
, grid: {
borderWidth: borderWidth
, markings: markings
}
};
$.plot('#loopalyzer-tempbasal', chartTempBasalData, chartTempBasalOptions);
// Chart 4: IOB
markings = [];
if (doTimeShift)
@@ -1204,29 +1210,28 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
})
var chartIOBData = [{
data: iobAvg,
label: translate('IOB'),
id: 'iobs',
color: insulinColor,
points: { show: false },
bars: { show: true, fill: true, barWidth: barWidth }
data: iobAvg
, label: translate('IOB')
, id: 'iobs'
, color: insulinColor
, points: { show: false }
, bars: { show: true, fill: true, barWidth: barWidth }
}];
var chartIOBOptions = {
xaxis: xaxisCfg,
yaxes: [{
tickColor: tickColor,
labelWidth: labelWidth,
tickFormatter: function(val,axis) { return tickFormatter(val,axis); }
},
hiddenAxis],
grid: {
borderWidth: borderWidth,
markings: markings
xaxis: xaxisCfg
, yaxes: [{
tickColor: tickColor
, labelWidth: labelWidth
, tickFormatter: function(val, axis) { return tickFormatter(val, axis); }
}
, hiddenAxis]
, grid: {
borderWidth: borderWidth
, markings: markings
}
};
$.plot('#loopalyzer-iob', chartIOBData, chartIOBOptions);
// Chart 5: COB
markings = [];
if (doTimeShift)
@@ -1242,24 +1247,24 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) {
delete xaxisCfg.font; // Remove the font config so HH:MM is shown on the last chart
var chartCOBData = [{
data: cobAvg,
label: translate('COB'),
id: 'cobs',
color: carbColor,
points: { show: false },
bars: { show: true, fil: true, barWidth: barWidth }
data: cobAvg
, label: translate('COB')
, id: 'cobs'
, color: carbColor
, points: { show: false }
, bars: { show: true, fil: true, barWidth: barWidth }
}];
var chartCOBOptions = {
xaxis: xaxisCfg,
yaxes: [{
tickColor: tickColor,
labelWidth: labelWidth,
tickFormatter: function(val,axis) { return tickFormatter(val,axis); }
},
hiddenAxis],
grid: {
borderWidth: borderWidth,
markings: markings
xaxis: xaxisCfg
, yaxes: [{
tickColor: tickColor
, labelWidth: labelWidth
, tickFormatter: function(val, axis) { return tickFormatter(val, axis); }
}
, hiddenAxis]
, grid: {
borderWidth: borderWidth
, markings: markings
}
};
$.plot('#loopalyzer-cob', chartCOBData, chartCOBOptions);
+15 -17
View File
@@ -15,23 +15,22 @@ module.exports = init;
profiles.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Profiles') + '</h2>'
+ '<br>' + translate('Database records') + '&nbsp'
+ '<br><select id="profiles-databaserecords"></select>'
+ '<br><span id="profiles-default"></span>'
+ '<div id="profiles-chart">'
+ '</div>'
;
'<h2>' + translate('Profiles') + '</h2>' +
'<br>' + translate('Database records') + '&nbsp' +
'<br><select id="profiles-databaserecords"></select>' +
'<br><span id="profiles-default"></span>' +
'<div id="profiles-chart">' +
'</div>';
return ret;
};
profiles.css =
'#profiles-chart {'
+ ' width: 100%;'
+ ' height: 100%;'
+ '}'
;
'#profiles-chart {' +
' width: 100%;' +
' height: 100%;' +
'}';
// eslint-disable-next-line no-unused-vars
profiles.report = function report_profiles (datastorage, sorteddaystoshow, options) {
var Nightscout = window.Nightscout;
var client = Nightscout.client;
@@ -58,11 +57,10 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option
var tr = $('<tr>');
$('#profiles-default').val(currentrecord.defaultProfile);
for (var key in currentrecord.store) {
if (currentrecord.store.hasOwnProperty(key)) {
tr.append(displayRecord(currentrecord.store[key], key))
}
}
Object.keys(currentrecord.store).forEach(key => {
tr.append(displayRecord(currentrecord.store[key], key));
});
table.append(tr);
+66 -72
View File
@@ -17,39 +17,33 @@ module.exports = init;
success.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Weekly Success') + '</h2>'
+ '<div id="success-grid"></div>'
;
'<h2>' + translate('Weekly Success') + '</h2>' +
'<div id="success-grid"></div>';
return ret;
};
success.css =
'#success-placeholder td {'+
' border: 1px #ccc solid;'+
' margin: 0;'+
' padding: 1px;'+
' text-align:center;'+
'}'+
'#success-placeholder .bad {'+
' background-color: #fcc;'+
'}'+
'#success-placeholder .good {'+
' background-color: #cfc;'+
'}'+
'#success-placeholder th:first-child {'+
' width: 30%;'+
'}'+
'#success-placeholder th {'+
' width: 10%;'+
'}'+
'#success-placeholder table {'+
' width: 100%;'+
'}'
;
`#success-placeholder td {
border: 1px #ccc solid;
margin: 0;
padding: 1px;
text-align:center;
}
#success-placeholder .bad {
background-color: #fcc;
}
#success-placeholder .good {
background-color: #cfc;
}
#success-placeholder th:first-child {
width: 30%;
}
#success-placeholder th {
width: 10%;
}
#success-placeholder table {
width: 100%;
}`;
success.report = function report_success (datastorage, sorteddaystoshow, options) {
var Nightscout = window.Nightscout;
@@ -58,8 +52,8 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
var ss = require('simple-statistics');
var low = options.targetLow,
high = options.targetHigh;
var low = options.targetLow
, high = options.targetHigh;
var data = datastorage.allstatsrecords;
@@ -96,21 +90,21 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
}, 0);
};
var averages = {
percentLow: 0,
percentInRange: 0,
percentHigh: 0,
standardDeviation: 0,
lowerQuartile: 0,
upperQuartile: 0,
average: 0
percentLow: 0
, percentInRange: 0
, percentHigh: 0
, standardDeviation: 0
, lowerQuartile: 0
, upperQuartile: 0
, average: 0
};
quarters = dim(quarters).map(function(blank, n) {
var starting = new Date(now - (n+1) * period),
ending = new Date(now - n * period);
var starting = new Date(now - (n + 1) * period)
, ending = new Date(now - n * period);
return {
starting: starting,
ending: ending,
records: data.filter(function(record) {
starting: starting
, ending: ending
, records: data.filter(function(record) {
return record.displayTime > starting && record.displayTime <= ending;
})
};
@@ -178,38 +172,38 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
}).map(function(quarter) {
var INVERT = true;
return '<tr>' + [
quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString(),
{
klass: lowComparison(quarter, averages, 'percentLow'),
text: Math.round(quarter.percentLow) + '%'
},
{
klass: lowComparison(quarter, averages, 'percentInRange', INVERT),
text: Math.round(quarter.percentInRange) + '%'
},
{
klass: lowComparison(quarter, averages, 'percentHigh'),
text: Math.round(quarter.percentHigh) + '%'
},
{
klass: lowComparison(quarter, averages, 'standardDeviation'),
text: (quarter.standardDeviation > 10? Math.round(quarter.standardDeviation): quarter.standardDeviation.toFixed(1))
},
{
klass: lowQuartileEvaluation(quarter, averages),
text: quarter.lowerQuartile
},
{
klass: lowComparison(quarter, averages, 'average'),
text: quarter.average.toFixed(1)
},
{
klass: upperQuartileEvaluation(quarter, averages),
text: quarter.upperQuartile
quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString()
, {
klass: lowComparison(quarter, averages, 'percentLow')
, text: Math.round(quarter.percentLow) + '%'
}
, {
klass: lowComparison(quarter, averages, 'percentInRange', INVERT)
, text: Math.round(quarter.percentInRange) + '%'
}
, {
klass: lowComparison(quarter, averages, 'percentHigh')
, text: Math.round(quarter.percentHigh) + '%'
}
, {
klass: lowComparison(quarter, averages, 'standardDeviation')
, text: (quarter.standardDeviation > 10 ? Math.round(quarter.standardDeviation) : quarter.standardDeviation.toFixed(1))
}
, {
klass: lowQuartileEvaluation(quarter, averages)
, text: quarter.lowerQuartile
}
, {
klass: lowComparison(quarter, averages, 'average')
, text: quarter.average.toFixed(1)
}
, {
klass: upperQuartileEvaluation(quarter, averages)
, text: quarter.upperQuartile
}
].map(function(v) {
if (typeof v === 'object') {
return '<td class=\"' + v.klass + '\">' + v.text + '</td>';
return '<td class="' + v.klass + '">' + v.text + '</td>';
} else {
return '<td>' + v + '</td>';
}
+2 -7
View File
@@ -116,7 +116,7 @@ function init ( ) {
* @param setter
*/
sbx.offerProperty = function offerProperty (name, setter) {
if (!sbx.properties.hasOwnProperty(name)) {
if (!Object.keys(sbx.properties).includes(name)) {
var value = setter();
if (value) {
sbx.properties[name] = value;
@@ -272,14 +272,10 @@ function init ( ) {
if (sbx.properties.roundingStyle === 'medtronic') {
var denominator = 0.1;
var digits = 1;
if (insulin > 0.5 && iob < 1) {
if (insulin <= 0.5) {
denominator = 0.05;
digits = 2;
}
if (insulin <= 0.5) {
denominator = 0.025;
digits = 3;
}
return (Math.floor(insulin / denominator) * denominator).toFixed(digits);
}
@@ -299,4 +295,3 @@ function init ( ) {
}
module.exports = init;
+1
View File
@@ -28,6 +28,7 @@ CACHE MANIFEST
/css/main.css?v=<%= locals.cachebuster %>
/bundle/js/bundle.app.js?v=<%= locals.cachebuster %>
/bundle/js/bundle.clock.js?v=<%= locals.cachebuster %>
/bundle/js/bundle.report.js?v=<%= locals.cachebuster %>
/socket.io/socket.io.js?v=<%= locals.cachebuster %>
/js/client.js?v=<%= locals.cachebuster %>
/images/logo2.png
+1 -1
View File
@@ -115,7 +115,7 @@ if (process.env.NODE_ENV == 'development') {
rules.unshift({
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
exclude: [/node_modules/, /bundle/],
loader: "eslint-loader",
options: {
emitWarning: true,