From dab3c045db660ae4f7837312e713fcc206dd113a Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:13:40 +0200 Subject: [PATCH 001/121] Use prompt with dimiss and pause --- apps/widbaroalarm/ChangeLog | 1 + apps/widbaroalarm/metadata.json | 2 +- apps/widbaroalarm/settings.js | 20 +++++++++++++++ apps/widbaroalarm/widget.js | 44 ++++++++++++++++++++------------- 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index 5786741c7..b61e1691b 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: Do not warn multiple times for the same exceedance 0.03: Fix crash +0.04: Use Prompt with dismiss and pause diff --git a/apps/widbaroalarm/metadata.json b/apps/widbaroalarm/metadata.json index 134f03623..9f5cffcfe 100644 --- a/apps/widbaroalarm/metadata.json +++ b/apps/widbaroalarm/metadata.json @@ -2,7 +2,7 @@ "id": "widbaroalarm", "name": "Barometer Alarm Widget", "shortName": "Barometer Alarm", - "version": "0.03", + "version": "0.04", "description": "A widget that can alarm on when the pressure reaches defined thresholds.", "icon": "widget.png", "type": "widget", diff --git a/apps/widbaroalarm/settings.js b/apps/widbaroalarm/settings.js index bea6319d1..faece90a2 100644 --- a/apps/widbaroalarm/settings.js +++ b/apps/widbaroalarm/settings.js @@ -87,6 +87,26 @@ }, onchange: x => save('buzz', x) }, + 'Dismiss delay': { + value: settings.dismissDelayMin, + min: 5, max: 60, + onchange: v => { + save('dismissDelayMin', x) + }, + format: x => { + return x + " min"; + } + }, + 'Pause delay': { + value: settings.pauseDelayMin, + min: 30, max: 240, + onchange: v => { + save('pauseDelayMin', x) + }, + format: x => { + return x + " min"; + } + }, }; E.showMenu(menu); } diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 2745db8ad..c2a9e1c54 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -32,13 +32,21 @@ let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours - function showAlarm(body, title) { + function showAlarm(body, title, key) { if (body == undefined) return; - require("notify").show({ + E.showPrompt(body, { title: title || "Pressure", - body: body, - icon: require("heatshrink").decompress(atob("jEY4cA///gH4/++mkK30kiWC4H8x3BGDmSGgYDCgmSoEAg3bsAIDpAIFkmSpMAm3btgIFDQwIGNQpTYkAIJwAHEgMoCA0JgMEyBnBCAW3KoQQDhu3oAIH5JnDBAW24IIBEYm2EYwACBCIACA")) + buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } + }).then(function (v) { + const tsNow = Math.round(Date.now() / 1000); // seconds + + if (v == 2) { + saveSetting(key, tsNow + 60 * settings('dismissDelayMin')); + } + if (v == 3) { + saveSetting(key, tsNow + 60 * settings('pauseDelayMin')); + } }); if (setting("buzz") && @@ -48,8 +56,10 @@ } - function didWeAlreadyWarn(key) { - return setting(key) == undefined || setting(key) > 0; + function doWeNeedToWarn(key) { + const tsNow = Math.round(Date.now() / 1000); // seconds + + return setting(key) == 0 || setting(key) < tsNow; } function checkForAlarms(pressure) { @@ -77,7 +87,7 @@ if (setting("lowalarm")) { // Is below the alarm threshold? if (pressure <= setting("min")) { - if (!didWeAlreadyWarn("lastLowWarningTs")) { + if (!doWeNeedToWarn("lastLowWarningTs")) { showAlarm("Pressure low: " + Math.round(pressure) + " hPa"); saveSetting("lastLowWarningTs", ts); alreadyWarned = true; @@ -92,7 +102,7 @@ if (setting("highalarm")) { // Is above the alarm threshold? if (pressure >= setting("max")) { - if (!didWeAlreadyWarn("lastHighWarningTs")) { + if (!doWeNeedToWarn("lastHighWarningTs")) { showAlarm("Pressure high: " + Math.round(pressure) + " hPa"); saveSetting("lastHighWarningTs", ts); alreadyWarned = true; @@ -122,7 +132,7 @@ // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { if (Math.abs(diff) > drop3halarm) { - if (!didWeAlreadyWarn("lastDropWarningTs")) { + if (!doWeNeedToWarn("lastDropWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop"); saveSetting("lastDropWarningTs", ts); @@ -137,7 +147,7 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { if (Math.abs(diff) > raise3halarm) { - if (!didWeAlreadyWarn("lastRaiseWarningTs")) { + if (!doWeNeedToWarn("lastRaiseWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise"); saveSetting("lastRaiseWarningTs", ts); @@ -176,7 +186,7 @@ /* turn on barometer power - take 5 measurements + take `numberOfMeasurements` measurements sort the results take the middle one (median) turn off barometer power @@ -186,11 +196,11 @@ setTimeout(function() { currentPressures = []; - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); - Bangle.getPressure().then(baroHandler); + const numberOfMeasurements = 5; + + for (let i = 0; i < numberOfMeasurements; i++) { + Bangle.getPressure().then(baroHandler); + } setTimeout(function() { Bangle.setBarometerPower(false, "widbaroalarm"); @@ -198,7 +208,7 @@ currentPressures.sort(); // take median value - medianPressure = currentPressures[3]; + medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; checkForAlarms(medianPressure); }, 1000); }, 500); From 71d9907657c820da3ad94bd5219b18777215d6b3 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:20:15 +0200 Subject: [PATCH 002/121] Fix settings --- apps/widbaroalarm/default.json | 4 +++- apps/widbaroalarm/settings.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/widbaroalarm/default.json b/apps/widbaroalarm/default.json index 3d81baa81..696c70819 100644 --- a/apps/widbaroalarm/default.json +++ b/apps/widbaroalarm/default.json @@ -7,5 +7,7 @@ "drop3halarm": 2, "raise3halarm": 0, "show": true, - "interval": 15 + "interval": 15, + "dismissDelayMin": 15, + "pauseDelayMin": 60 } diff --git a/apps/widbaroalarm/settings.js b/apps/widbaroalarm/settings.js index faece90a2..ee8ce82c2 100644 --- a/apps/widbaroalarm/settings.js +++ b/apps/widbaroalarm/settings.js @@ -91,7 +91,7 @@ value: settings.dismissDelayMin, min: 5, max: 60, onchange: v => { - save('dismissDelayMin', x) + save('dismissDelayMin', v) }, format: x => { return x + " min"; @@ -101,7 +101,7 @@ value: settings.pauseDelayMin, min: 30, max: 240, onchange: v => { - save('pauseDelayMin', x) + save('pauseDelayMin', v) }, format: x => { return x + " min"; From a29eeaca510a3386fd9794316a051d4fd0b6977e Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:25:29 +0200 Subject: [PATCH 003/121] Remove dependency --- apps/widbaroalarm/metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/widbaroalarm/metadata.json b/apps/widbaroalarm/metadata.json index 9f5cffcfe..41b8d3e17 100644 --- a/apps/widbaroalarm/metadata.json +++ b/apps/widbaroalarm/metadata.json @@ -8,7 +8,6 @@ "type": "widget", "tags": "tool,barometer", "supports": ["BANGLEJS2"], - "dependencies": {"notify":"type"}, "readme": "README.md", "storage": [ {"name":"widbaroalarm.wid.js","url":"widget.js"}, From 55a346272aaeb317a32f9d33f010f4912bbf861b Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 19:31:48 +0200 Subject: [PATCH 004/121] Update README --- apps/widbaroalarm/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index fdc239170..a74d89546 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -15,7 +15,8 @@ Get a notification when the pressure reaches defined thresholds. 0 to disable this alarm. * Show widget: Enable/disable widget visibility * Buzz on alarm: Enable/disable buzzer on alarm - +* Dismiss delay: Delay added before the next alert if the alert is dismissed. From 5 to 60 min +* Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min ## Widget The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. From 02fc7af75085581c6de5cc67c515b445331398f2 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 20:07:15 +0200 Subject: [PATCH 005/121] Fix warning --- apps/widbaroalarm/widget.js | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index c2a9e1c54..721d0bbb8 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -32,33 +32,38 @@ let history3 = storage.readJSON(LOG_FILE, true) || []; // history of recent 3 hours - function showAlarm(body, title, key) { + function showAlarm(body, key) { if (body == undefined) return; E.showPrompt(body, { - title: title || "Pressure", + title: "Pressure alarm", buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } }).then(function (v) { const tsNow = Math.round(Date.now() / 1000); // seconds + if (v == 1) { + saveSetting(key, tsNow); + } if (v == 2) { - saveSetting(key, tsNow + 60 * settings('dismissDelayMin')); + saveSetting(key, tsNow + 60 * setting('dismissDelayMin')); } if (v == 3) { - saveSetting(key, tsNow + 60 * settings('pauseDelayMin')); + saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } + load(); }); if (setting("buzz") && !(storage.readJSON('setting.json', 1) || {}).quiet) { Bangle.buzz(); } + + setTimeout(load, 20000); } function doWeNeedToWarn(key) { const tsNow = Math.round(Date.now() / 1000); // seconds - return setting(key) == 0 || setting(key) < tsNow; } @@ -88,8 +93,7 @@ // Is below the alarm threshold? if (pressure <= setting("min")) { if (!doWeNeedToWarn("lastLowWarningTs")) { - showAlarm("Pressure low: " + Math.round(pressure) + " hPa"); - saveSetting("lastLowWarningTs", ts); + showAlarm("Pressure low: " + Math.round(pressure) + " hPa", "lastLowWarningTs"); alreadyWarned = true; } } else { @@ -102,9 +106,8 @@ if (setting("highalarm")) { // Is above the alarm threshold? if (pressure >= setting("max")) { - if (!doWeNeedToWarn("lastHighWarningTs")) { - showAlarm("Pressure high: " + Math.round(pressure) + " hPa"); - saveSetting("lastHighWarningTs", ts); + if (doWeNeedToWarn("lastHighWarningTs")) { + showAlarm("Pressure high: " + Math.round(pressure) + " hPa", "lastHighWarningTs"); alreadyWarned = true; } } else { @@ -132,10 +135,9 @@ // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { if (Math.abs(diff) > drop3halarm) { - if (!doWeNeedToWarn("lastDropWarningTs")) { + if (doWeNeedToWarn("lastDropWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop"); - saveSetting("lastDropWarningTs", ts); + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop", "lastDropWarningTs"); } } else { saveSetting("lastDropWarningTs", 0); @@ -147,10 +149,9 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { if (Math.abs(diff) > raise3halarm) { - if (!doWeNeedToWarn("lastRaiseWarningTs")) { + if (doWeNeedToWarn("lastRaiseWarningTs")) { showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise"); - saveSetting("lastRaiseWarningTs", ts); + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise", "lastRaiseWarningTs"); } } else { saveSetting("lastRaiseWarningTs", 0); @@ -186,7 +187,7 @@ /* turn on barometer power - take `numberOfMeasurements` measurements + take `numberOfMeasurements` measurements with a delay of 1000ms each sort the results take the middle one (median) turn off barometer power @@ -196,10 +197,12 @@ setTimeout(function() { currentPressures = []; - const numberOfMeasurements = 5; + const numberOfMeasurements = 7; for (let i = 0; i < numberOfMeasurements; i++) { - Bangle.getPressure().then(baroHandler); + setTimeout(function() { + Bangle.getPressure().then(baroHandler); + }, i * 1000); } setTimeout(function() { @@ -210,7 +213,7 @@ // take median value medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; checkForAlarms(medianPressure); - }, 1000); + }, numberOfMeasurements * 1000 + 500); }, 500); } From 5968df327cf8001cf8e70445131a0689ad0f2035 Mon Sep 17 00:00:00 2001 From: Marco H Date: Thu, 26 May 2022 20:15:05 +0200 Subject: [PATCH 006/121] Improve changelog --- apps/widbaroalarm/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index b61e1691b..0afe4bc8b 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -2,3 +2,4 @@ 0.02: Do not warn multiple times for the same exceedance 0.03: Fix crash 0.04: Use Prompt with dismiss and pause + Improve barometer value median calculation From 069e0c13a918273f6c35e295cf3688734d75a615 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Thu, 26 May 2022 15:29:38 +0200 Subject: [PATCH 007/121] android: added calendar sync events --- apps/android/boot.js | 15 +++++++++++++++ apps/android/metadata.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index efd7e7e46..829c1b4b0 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -90,6 +90,21 @@ sched.setAlarms(alarms); sched.reload(); }, + //TODO perhaps move those in a library (like messages), used also for viewing events? + "calendar" : function() { + var cal; + try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} + if (!cal) cal = {}; // first event + cal[event.id] = event; + require("Storage").writeJSON("android.calendar.json", cal); + }, + "calendar-" : function() { + var cal; + try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} + if (!cal) return; //nothing to remove + if (event.id in cal) delete cal[event.id]; + require("Storage").writeJSON("android.calendar.json", cal); + } }; var h = HANDLERS[event.t]; if (h) h(); else console.log("GB Unknown",event); diff --git a/apps/android/metadata.json b/apps/android/metadata.json index bf37b8407..c8e404aba 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -15,6 +15,6 @@ {"name":"android.img","url":"app-icon.js","evaluate":true}, {"name":"android.boot.js","url":"boot.js"} ], - "data": [{"name":"android.settings.json"}], + "data": [{"name":"android.settings.json"}, {"name":"android.calendar.json"}], "sortorder": -8 } From 8c42e81aea127cb2cb47c30ebd30a2764d857889 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Thu, 26 May 2022 20:41:44 +0200 Subject: [PATCH 008/121] Added basic agenda --- apps/agenda/ChangeLog | 1 + apps/agenda/README.md | 3 + apps/agenda/agenda-icon.js | 1 + apps/agenda/agenda.js | 102 ++++++++++++++++++++++++++++++ apps/agenda/agenda.png | Bin 0 -> 7227 bytes apps/agenda/metadata.json | 16 +++++ apps/agenda/screenshot_agenda.png | Bin 0 -> 2584 bytes 7 files changed, 123 insertions(+) create mode 100644 apps/agenda/ChangeLog create mode 100644 apps/agenda/README.md create mode 100644 apps/agenda/agenda-icon.js create mode 100644 apps/agenda/agenda.js create mode 100644 apps/agenda/agenda.png create mode 100644 apps/agenda/metadata.json create mode 100644 apps/agenda/screenshot_agenda.png diff --git a/apps/agenda/ChangeLog b/apps/agenda/ChangeLog new file mode 100644 index 000000000..56dfffa0d --- /dev/null +++ b/apps/agenda/ChangeLog @@ -0,0 +1 @@ +0.01: Basic agenda with events from GB diff --git a/apps/agenda/README.md b/apps/agenda/README.md new file mode 100644 index 000000000..5141673c0 --- /dev/null +++ b/apps/agenda/README.md @@ -0,0 +1,3 @@ +# Calendar + +Basic agenda reading the events synchronised from GadgetBridge diff --git a/apps/agenda/agenda-icon.js b/apps/agenda/agenda-icon.js new file mode 100644 index 000000000..ed6690033 --- /dev/null +++ b/apps/agenda/agenda-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI=")) \ No newline at end of file diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js new file mode 100644 index 000000000..c7260af07 --- /dev/null +++ b/apps/agenda/agenda.js @@ -0,0 +1,102 @@ +/* CALENDAR is a list of: + {id:int, + type, + timestamp, + durationInSeconds, + title, + description, + location, + allDay: bool, + } + the file on storage has the same content but is an object indexed by id +*/ + +var FILE = "android.calendar.json" + +var fontSmall = "6x8"; +var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2"; +var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2"; +var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4"; + +//FIXME maybe write the end from GB already? Not durationInSeconds here (or do while receiving?) +var cal; +try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} +if (!cal) //cal = {}; // first event + cal = { //FIXME test + 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere"}, + 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, + 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} + }; + +function formatDateLong(timestamp) { + return new Date(timestamp*1000).toString(); +} +function formatDateShort(timestamp) { + return new Date(timestamp*1000).toISOString(); +} + +function showEvent(ev) { + var bodyFont = fontBig; + g.setFont(bodyFont); + var lines = []; + if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) + var titleCnt = lines.length; + if (titleCnt) lines.push(""); // add blank line after title + lines = lines.concat( + g.wrapString(formatDateLong(ev.timestamp)+"\n", g.getWidth()-10), + g.wrapString(formatDateLong((+ev.timestamp) + (+ev.durationInSeconds))+"\n", g.getWidth()-10), + g.wrapString(ev.location, g.getWidth()-10), + ["",/*LANG*/"< Back"]); + E.showScroller({ + h : g.getFontHeight(), // height of each menu item in pixels + c : lines.length, // number of menu items + // a function to draw a menu item + draw : function(idx, r) { + // FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12 + g.setBgColor(idx=lines.length-2) + showEvent(ev); + }, + back : () => showList() + }); +} + +CALENDAR=Object.keys(cal) + .sort((a,b)=>cal[a].timestamp - cal[b].timestamp) + .map(k=>cal[k]); //make it an array + +function showList() { + E.showScroller({ + h : 48, + c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + draw : function(idx, r) {"ram" + var ev = CALENDAR[idx]; + g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); + if (!ev) return; + var x = r.x+2, title = ev.title, body = formatDateShort(ev.timestamp)+ + "\n"+ev.location; + var m = ev.title+"\n"+ev.location, longBody=false; + if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); + if (body) { + g.setFontAlign(-1,-1).setFont("6x8"); + var l = g.wrapString(body, r.w-(x+14)); + if (l.length>3) { + l = l.slice(0,3); + l[l.length-1]+="..."; + } + longBody = l.length>2; + g.drawString(l.join("\n"), x+10,r.y+20); + } + //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); + g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items + }, + select : idx => showEvent(CALENDAR[idx]), + back : () => load() + }); +} +showList(); diff --git a/apps/agenda/agenda.png b/apps/agenda/agenda.png new file mode 100644 index 0000000000000000000000000000000000000000..ccbcce5fff4e578b44d2e1ba87d21339e5dd19e0 GIT binary patch literal 7227 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 GhyMqGu%7Dx literal 0 HcmV?d00001 diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json new file mode 100644 index 000000000..2c1bdfe9c --- /dev/null +++ b/apps/agenda/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "agenda", + "name": "Agenda", + "version": "1.01", + "description": "Simple agenda", + "icon": "agenda.png", + "screenshots": [{"url":"screenshot_agenda.png"}], + "tags": "agenda", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"agenda.app.js","url":"agenda.js"}, + {"name":"agenda.img","url":"agenda-icon.js","evaluate":true} + ] +} diff --git a/apps/agenda/screenshot_agenda.png b/apps/agenda/screenshot_agenda.png new file mode 100644 index 0000000000000000000000000000000000000000..7ef5986d4e63537cdaed0a9daa474c3e633a485b GIT binary patch literal 2584 zcmb_eeK^x=AD7jNwj|BjP{&ISG17)D)DkwHo=9Gzm@zNQMksGN=vU5SO*j!ntxS%X zxAIas_!Vbk-ZrlXVKqs~IVd^h?X0Uh*VA?NT-Wo*^T&PP*Z1YRukZJBf4<-EopRWb z1Xom3l#`Q#JJ{PEk)0JE*9NF;FRvXZ%gHH>IoMje#^g<3o4PWr2}^pjvg`T^ttZlB z4OhJ-=5%M?NaR_iW)J=epYnmlL(U6*?-UMal7{v6J8uu+$l1kK#mjGfF8(jd@kzD1 z7hB90il%~gYRxWwH^286F|$T%-bRoSVWJjfJ{IM*v&%j%sV;)x_hO6bE%LLd5*$Y# z($1bTJ7U?1?i!k^d&h+@<}el5V4aE?hHV;s5y%Knf3Lacj}DpZAimB_csZm@(M10D z>*!Lgdu0m|K^;EB(fpBmCHKV1R7RfdNf(11W!Y;_bndlzH^i0NG9<~Cbb?yY!l)+w zw=9Ml>p^RW9bo62>HR-uCCk5jAU8jhH?4A0Kdr{;Y`)ddzBQ~l+TvP$A@{RVLR(%= zEMI&PUQy8;#7J5q%t=v$Q^-=?pKG;!jP$5W6h2b4a-$Nw+G>?2_CTrY&gSFmSL)+g z{5E`n&sec)bn_vB|v(e$7UC`Q~2* z`^^l#DD77g*JM}|?TBUWCM)5NLt8OnP&jNo3V|{;(eQWm7lC2v&Ka|EkVZ1$RXkG< z7UWfaOQX%gRN94f&WmJw*#r;yG`elTR%G5B4f1###!vRnP;T`Uh}6+dV2C9|P&;ey z5xQmk;e~J#WFhA&bfv2PIzVb=CA_U+4_0p=Rsmc*8G3hD-=)oMaJ2XL3#CDlu0K(@ zXIYnhB~hJ57on(HXF-^pDO2wy;jvcT*}0@+r@y5&$EJN`_>e^<(Uq; zuRjurElSf$&5DJReJNA8%{CBj;T+@F=zDwFZ1wO_!jgTvO7JIfZ|$ycBeA<) z&|Z737tUgiZHlPx0^x!0Z@5z_hE$rQMU$(ob5wUl*Vv$?sO2W`R3@K?GS9PFFg4^R zi~)v5!T)2BYC<^q3;7(^o!6b+Mpt21%H9T4$d?#~MWLxXBJK)SpP_waP@+r0=xwV6 zCN!Y{@C2$qUgS=JGog;VXXZPc)D1sqB95H7n5xkz=y@k*hmbEmP9{iSAb%I0g+Hlj z9m=G~Rll@`c`=rqhzWWW!ti#ql5q8Lm`vonO0 zf)m{IZqU8+;d0DP0NVv>2{K>nHQg1|8Q+C1?RK3&{gtEm+N|RFae0IkfRdeo;oR|l zXcXbh_a4CX;!y$k5)m_BySZ>5GyA@Z!Hfgc{M{p*?i<+a>GSR_Zis}wgIxfrA}wf-A&Lzk|WYp0ncwdc%4)qa=a7F;(tb(`SL6lA0Qn*=-ANxL zWb>#BAA!8Npgm32n?I=MhQNgJtr2+3e{lZl0k-=~YC7hPHaq1sqy}P3cuj37Ic*GB zuh&3SH%?9&dSysU+9WHQT_K(5D)wl#J&|vrjaP+!7{pOSdHtXm;ejazu#K0oxP<0p z%nU2?Exvy@8fJQuHs5XPC73vj80f!y#j?d=Hq?I#<7(Yc6xZ+5^Ft4Kt+G0PsZWf{=3!^1VNdEx#FopJzIYp#L-|N$oS$t24>pa&y2N7> zd=^~))Q5Tj^`EPiCLv+}lY(DC^T~j30k=j{ue-XnfT;CulGop6a7;Q-9#Vj_K9pFM z8n|S@9*sdgc$Inq%b!?8B_@pcNj5fK3k?qND*FpuKmYMbW zy!b@!@-6HOs(oP`~lk>`Z_KT zAS80rY&TM?0kNV3WIYEUIXuXHK*Tu|03&9%5<8y_i7;>QlB?dj?2o%+ory z93W03WcBKu0&}5|<|hJ~=E_c6PBY2@Zs=Kd@l+|V+xc;TM66>j1oslhQ8E1eHcb^} z>q_UQbFN86?Ou(7S3b3B_i?Hg4aM?tvT9~~l~P1tTHvQnXANnR;rmq!)bOXU9#%RQ z8~97u=MBQ5Wc~0PUREGDP+K34Nl$tTdl`bgCQe{B^Sqmnq1od3eN;vRr*dMz2zrSE zgQInevj2_t#Wx-K2|Xo>FvUfjG};akU`(X(D}Q*`BJr%Jm4WxkmEb}!n>^g&DKKp%qHJq!^R&RZc8>DP=t09v^man6bcgmHg4!GTP>7Q(0!((k4iIG3gxr0 zQ|gaI1Z6?rQ40gjEKiqPw`WB<_K Date: Sat, 28 May 2022 19:43:32 +0200 Subject: [PATCH 009/121] Fixed layout in agenda --- apps/agenda/agenda.js | 62 ++++++++++++++++++++++++++++----------- apps/agenda/metadata.json | 2 +- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js index c7260af07..6bb757629 100644 --- a/apps/agenda/agenda.js +++ b/apps/agenda/agenda.js @@ -11,7 +11,12 @@ the file on storage has the same content but is an object indexed by id */ -var FILE = "android.calendar.json" +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var FILE = "android.calendar.json"; + +var Locale = require("locale"); var fontSmall = "6x8"; var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2"; @@ -23,30 +28,53 @@ var cal; try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} if (!cal) //cal = {}; // first event cal = { //FIXME test - 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere"}, + 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere", description: "something very very long"}, 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} }; -function formatDateLong(timestamp) { - return new Date(timestamp*1000).toString(); +function getDate(timestamp) { + return new Date(timestamp*1000); } -function formatDateShort(timestamp) { - return new Date(timestamp*1000).toISOString(); +function formatDateLong(date, includeDay) { + if(includeDay) + return Locale.date(date)+" "+Locale.time(date,1); + return Locale.time(date,1); +} +function formatDateShort(date) { + return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); } +var lines = []; function showEvent(ev) { var bodyFont = fontBig; g.setFont(bodyFont); - var lines = []; + //var lines = []; if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) var titleCnt = lines.length; + var start = getDate(ev.timestamp); + var end = getDate((+ev.timestamp) + (+ev.durationInSeconds)); + var includeDay = true; if (titleCnt) lines.push(""); // add blank line after title - lines = lines.concat( - g.wrapString(formatDateLong(ev.timestamp)+"\n", g.getWidth()-10), - g.wrapString(formatDateLong((+ev.timestamp) + (+ev.durationInSeconds))+"\n", g.getWidth()-10), - g.wrapString(ev.location, g.getWidth()-10), - ["",/*LANG*/"< Back"]); + if(start.getDay() == end.getDay() && start.getMonth() == end.getMonth()) + includeDay = false; + if(includeDay) { + lines = lines.concat( + /*LANG*/"Start:", + g.wrapString(formatDateLong(start, includeDay), g.getWidth()-10), + /*LANG*/"End:", + g.wrapString(formatDateLong(end, includeDay), g.getWidth()-10)); + } else { + lines = lines.concat( + g.wrapString(Locale.date(start), g.getWidth()-10), + g.wrapString(/*LANG*/"Start"+": "+formatDateLong(start, includeDay), g.getWidth()-10), + g.wrapString(/*LANG*/"End"+": "+formatDateLong(end, includeDay), g.getWidth()-10)); + } + if(ev.location) + lines = lines.concat(/*LANG*/"Location"+": ", g.wrapString(ev.location, g.getWidth()-10)); + if(ev.description) + lines = lines.concat("",g.wrapString(ev.description, g.getWidth()-10)); + lines = lines.concat(["",/*LANG*/"< Back"]); E.showScroller({ h : g.getFontHeight(), // height of each menu item in pixels c : lines.length, // number of menu items @@ -59,7 +87,7 @@ function showEvent(ev) { g.setFont(bodyFont).drawString(lines[idx], r.x, r.y); }, select : function(idx) { if (idx>=lines.length-2) - showEvent(ev); + showList(); }, back : () => showList() }); @@ -71,19 +99,19 @@ CALENDAR=Object.keys(cal) function showList() { E.showScroller({ - h : 48, + h : 52, c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) draw : function(idx, r) {"ram" var ev = CALENDAR[idx]; g.setColor(g.theme.fg); g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); if (!ev) return; - var x = r.x+2, title = ev.title, body = formatDateShort(ev.timestamp)+ - "\n"+ev.location; + var x = r.x+2, title = ev.title; + var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; var m = ev.title+"\n"+ev.location, longBody=false; if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); if (body) { - g.setFontAlign(-1,-1).setFont("6x8"); + g.setFontAlign(-1,-1).setFont(fontMedium); var l = g.wrapString(body, r.w-(x+14)); if (l.length>3) { l = l.slice(0,3); diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 2c1bdfe9c..6895bbc7c 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "1.01", + "version": "3.01", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda.png"}], From 5fee259dd0dae2e8fe5e6bdf255debe68f229493 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Mon, 30 May 2022 20:44:28 +0200 Subject: [PATCH 010/121] Changed calendar format to array and graying out old events --- apps/agenda/README.md | 2 +- apps/agenda/agenda-icon.js | 2 +- apps/agenda/agenda.js | 89 ++++++++++++++++++------------------- apps/agenda/agenda.png | Bin 7227 -> 3119 bytes apps/agenda/metadata.json | 2 +- apps/android/boot.js | 12 ++--- 6 files changed, 50 insertions(+), 57 deletions(-) diff --git a/apps/agenda/README.md b/apps/agenda/README.md index 5141673c0..a546e0a89 100644 --- a/apps/agenda/README.md +++ b/apps/agenda/README.md @@ -1,3 +1,3 @@ -# Calendar +# Agenda Basic agenda reading the events synchronised from GadgetBridge diff --git a/apps/agenda/agenda-icon.js b/apps/agenda/agenda-icon.js index ed6690033..891543955 100644 --- a/apps/agenda/agenda-icon.js +++ b/apps/agenda/agenda-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI=")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwwg1yhGIxAPMBwIPFhH//GAC5n/C4oHBC5/IGwoXBHQQAKC4OIFAWOxHv9GO9wAKI4XoC4foEIIWLC4IABC4gIBFxnuE4IqBC4gARC4ZzNAAwXaxe7ACO4C625C4m4xIJBzAeCxGbCAOIFgQOBC4pOBxe4AYIPBAYQKCAYYXE3GL/ADBx/oxb3BC4X+xG4xwOBC4uP/YDB54MBf4Po3eM/4XBx/+C4pTBGIIkBLgOYAYIvB9GJBwI6BL45zCL4aCCL4h3GU64ALdYS1CI55bBAAgXFO4mMO4QDBDIO/////YxBU53IxIVB/GfDAWYa5wtC/GPAYWIL4wXBL4oSBC4jcBC4m4QIWYSwWIIQIAG/CnMMAIAC/JLCMIIvMIwZHFJAJfLC5yPHAYIRDAoy/KCIi7BMon4d4+Od4IXBxAZBEQLtB/+YxIXDL4SLCL4WPzAXCNgRFBLIKnKLIrcEI4gXNAAp3CxGZAAzCBC5KnCKAIAICxBlBC4IAJxG/C4/4wAXLhBgD/IcD3AXMGAIqDDgRGNGAoXDFxxhEI4W4FxwwCaoYWBFx4YDAAQWRAEQ")) diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js index 6bb757629..f39e31c75 100644 --- a/apps/agenda/agenda.js +++ b/apps/agenda/agenda.js @@ -8,7 +8,6 @@ location, allDay: bool, } - the file on storage has the same content but is an object indexed by id */ Bangle.loadWidgets(); @@ -24,30 +23,26 @@ var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2"; var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4"; //FIXME maybe write the end from GB already? Not durationInSeconds here (or do while receiving?) -var cal; -try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} -if (!cal) //cal = {}; // first event - cal = { //FIXME test - 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere", description: "something very very long"}, - 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, - 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} - }; +var CALENDAR = require("Storage").readJSON("android.calendar.json",true)||[]; + +CALENDAR=CALENDAR.sort((a,b)=>a.timestamp - b.timestamp) function getDate(timestamp) { - return new Date(timestamp*1000); + return new Date(timestamp*1000); } function formatDateLong(date, includeDay) { - if(includeDay) - return Locale.date(date)+" "+Locale.time(date,1); - return Locale.time(date,1); + if(includeDay) + return Locale.date(date)+" "+Locale.time(date,1); + return Locale.time(date,1); } function formatDateShort(date) { - return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); + return Locale.date(date).replace(/\d\d\d\d/,"")+Locale.time(date,1); } var lines = []; function showEvent(ev) { var bodyFont = fontBig; + if(!ev) return; g.setFont(bodyFont); //var lines = []; if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) @@ -93,38 +88,40 @@ function showEvent(ev) { }); } -CALENDAR=Object.keys(cal) - .sort((a,b)=>cal[a].timestamp - cal[b].timestamp) - .map(k=>cal[k]); //make it an array - function showList() { - E.showScroller({ - h : 52, - c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) - draw : function(idx, r) {"ram" - var ev = CALENDAR[idx]; - g.setColor(g.theme.fg); - g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); - if (!ev) return; - var x = r.x+2, title = ev.title; - var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; - var m = ev.title+"\n"+ev.location, longBody=false; - if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); - if (body) { - g.setFontAlign(-1,-1).setFont(fontMedium); - var l = g.wrapString(body, r.w-(x+14)); - if (l.length>3) { - l = l.slice(0,3); - l[l.length-1]+="..."; - } - longBody = l.length>2; - g.drawString(l.join("\n"), x+10,r.y+20); - } - //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); - g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items - }, - select : idx => showEvent(CALENDAR[idx]), - back : () => load() - }); + if(CALENDAR.length == 0) { + E.showMessage("No events"); + return; + } + E.showScroller({ + h : 52, + c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + draw : function(idx, r) {"ram" + var ev = CALENDAR[idx]; + g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); + if (!ev) return; + var isPast = ev.timestamp + ev.durationInSeconds < (new Date())/1000; + var x = r.x+2, title = ev.title; + var body = formatDateShort(getDate(ev.timestamp))+"\n"+ev.location; + var m = ev.title+"\n"+ev.location, longBody=false; + if (title) g.setFontAlign(-1,-1).setFont(fontBig) + .setColor(isPast ? "#888" : g.theme.fg).drawString(title, x,r.y+2); + if (body) { + g.setFontAlign(-1,-1).setFont(fontMedium).setColor(isPast ? "#888" : g.theme.fg); + var l = g.wrapString(body, r.w-(x+14)); + if (l.length>3) { + l = l.slice(0,3); + l[l.length-1]+="..."; + } + longBody = l.length>2; + g.drawString(l.join("\n"), x+10,r.y+20); + } + //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); + g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items + }, + select : idx => showEvent(CALENDAR[idx]), + back : () => load() + }); } showList(); diff --git a/apps/agenda/agenda.png b/apps/agenda/agenda.png index ccbcce5fff4e578b44d2e1ba87d21339e5dd19e0..c850b0e5d1a3eb98b9c9cb68968ab554119fe23f 100644 GIT binary patch literal 3119 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 GhyMqGu%7Dx diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 6895bbc7c..0a9f6e44f 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "3.01", + "version": "2.01", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda.png"}], diff --git a/apps/android/boot.js b/apps/android/boot.js index 829c1b4b0..df21a5521 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -92,17 +92,13 @@ }, //TODO perhaps move those in a library (like messages), used also for viewing events? "calendar" : function() { - var cal; - try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} - if (!cal) cal = {}; // first event - cal[event.id] = event; + var cal = require("Storage").readJSON("android.calendar.json",true)||[]; + cal.push(event); require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { - var cal; - try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} - if (!cal) return; //nothing to remove - if (event.id in cal) delete cal[event.id]; + var cal = require("Storage").readJSON("android.calendar.json",true)||return; + cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); } }; From a50f53b15aa21d1de3dd0ffd3709b18d61056ea5 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Mon, 30 May 2022 21:36:07 +0200 Subject: [PATCH 011/121] Added screenshots and correct version number --- apps/agenda/metadata.json | 4 ++-- apps/agenda/screenshot_agenda.png | Bin 2584 -> 0 bytes apps/agenda/screenshot_agenda_event1.png | Bin 0 -> 3588 bytes apps/agenda/screenshot_agenda_event2.png | Bin 0 -> 3386 bytes apps/agenda/screenshot_agenda_overview.png | Bin 0 -> 3785 bytes apps/android/boot.js | 7 +++++-- apps/android/metadata.json | 2 +- 7 files changed, 8 insertions(+), 5 deletions(-) delete mode 100644 apps/agenda/screenshot_agenda.png create mode 100644 apps/agenda/screenshot_agenda_event1.png create mode 100644 apps/agenda/screenshot_agenda_event2.png create mode 100644 apps/agenda/screenshot_agenda_overview.png diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 0a9f6e44f..0b8ffaded 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,10 +1,10 @@ { "id": "agenda", "name": "Agenda", - "version": "2.01", + "version": "0.01", "description": "Simple agenda", "icon": "agenda.png", - "screenshots": [{"url":"screenshot_agenda.png"}], + "screenshots": [{"url":"screenshot_agenda_overview.png"}, {"url":"screenshot_agenda_event1.png"}, {"url":"screenshot_agenda_event2.png"}], "tags": "agenda", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", diff --git a/apps/agenda/screenshot_agenda.png b/apps/agenda/screenshot_agenda.png deleted file mode 100644 index 7ef5986d4e63537cdaed0a9daa474c3e633a485b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2584 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 literal 0 HcmV?d00001 diff --git a/apps/agenda/screenshot_agenda_event2.png b/apps/agenda/screenshot_agenda_event2.png new file mode 100644 index 0000000000000000000000000000000000000000..f5edcaae8e25eaa8c014ef7a77127dd91c8a7120 GIT binary patch literal 3386 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 literal 0 HcmV?d00001 diff --git a/apps/android/boot.js b/apps/android/boot.js index df21a5521..0c7dd04b5 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -92,12 +92,15 @@ }, //TODO perhaps move those in a library (like messages), used also for viewing events? "calendar" : function() { - var cal = require("Storage").readJSON("android.calendar.json",true)||[]; + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; cal.push(event); require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { - var cal = require("Storage").readJSON("android.calendar.json",true)||return; + var cal = require("Storage").readJSON("android.calendar.json",true); + //if any of those happen we are out of sync! + if (!cal || !Array.isArray(cal)) return; cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); } diff --git a/apps/android/metadata.json b/apps/android/metadata.json index c8e404aba..27b77cf2f 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "0.10", + "version": "0.11", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From e057270d01e419c5c92efa35b061afc710d5b254 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Wed, 1 Jun 2022 17:39:09 +0200 Subject: [PATCH 012/121] Added settings page to force calendar sync --- apps/agenda/metadata.json | 3 ++- apps/agenda/settings.js | 36 ++++++++++++++++++++++++++++++++++++ apps/android/boot.js | 6 +++++- apps/android/metadata.json | 2 +- 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 apps/agenda/settings.js diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json index 0b8ffaded..ce8438686 100644 --- a/apps/agenda/metadata.json +++ b/apps/agenda/metadata.json @@ -1,7 +1,7 @@ { "id": "agenda", "name": "Agenda", - "version": "0.01", + "version": "0.02", "description": "Simple agenda", "icon": "agenda.png", "screenshots": [{"url":"screenshot_agenda_overview.png"}, {"url":"screenshot_agenda_event1.png"}, {"url":"screenshot_agenda_event2.png"}], @@ -11,6 +11,7 @@ "allow_emulator": true, "storage": [ {"name":"agenda.app.js","url":"agenda.js"}, + {"name":"agenda.settings.js","url":"settings.js"}, {"name":"agenda.img","url":"agenda-icon.js","evaluate":true} ] } diff --git a/apps/agenda/settings.js b/apps/agenda/settings.js new file mode 100644 index 000000000..7edb013b9 --- /dev/null +++ b/apps/agenda/settings.js @@ -0,0 +1,36 @@ +(function(back) { + function gbSend(message) { + Bluetooth.println(""); + Bluetooth.println(JSON.stringify(message)); + } + var CALENDAR = require("Storage").readJSON("android.calendar.json",true)||[]; + var mainmenu = { + "" : { "title" : "Agenda" }, + "< Back" : back, + /*LANG*/"Connected" : { value : NRF.getSecurityStatus().connected?/*LANG*/"Yes":/*LANG*/"No" }, + /*LANG*/"Force calendar sync" : () => { + if(NRF.getSecurityStatus().connected) { + E.showPrompt(/*LANG*/"Do you want to also clear the internal database first?", { + buttons: {/*LANG*/"Yes": 1, /*LANG*/"No": 2, /*LANG*/"Cancel": 3} + }).then((v)=>{ + switch(v) { + case 1: + require("Storage").writeJSON("android.calendar.json",[]); + CALENDAR = []; + case 2: + gbSend({t:"force_calendar_sync", ids: CALENDAR.map(e=>e.id)}); + E.showAlert(/*LANG*/"Request sent to the phone").then(()=>E.showMenu(mainmenu)); + break; + case 3: + default: + E.showMenu(mainmenu); + return; + } + }); + } else { + E.showAlert(/*LANG*/"You are not connected").then(()=>E.showMenu(mainmenu)); + } + }, + }; + E.showMenu(mainmenu); +}) diff --git a/apps/android/boot.js b/apps/android/boot.js index 0c7dd04b5..72c5bc386 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -94,7 +94,11 @@ "calendar" : function() { var cal = require("Storage").readJSON("android.calendar.json",true); if (!cal || !Array.isArray(cal)) cal = []; - cal.push(event); + var i = cal.findIndex(e=>e.id==event.id); + if(i<0) + cal.push(event); + else + cal[i] = event; require("Storage").writeJSON("android.calendar.json", cal); }, "calendar-" : function() { diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 27b77cf2f..6458087e8 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "0.11", + "version": "4.01", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 9e4d58d2151795b83ee09effd10f2cad6eded415 Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Fri, 3 Jun 2022 08:44:13 +0200 Subject: [PATCH 013/121] Added simpler calendar management (all in single packet) --- apps/android/boot.js | 5 +++++ apps/android/metadata.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index 72c5bc386..191db3838 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -91,6 +91,11 @@ sched.reload(); }, //TODO perhaps move those in a library (like messages), used also for viewing events? + //simple package with events all together + "calendarevents" : function() { + require("Storage").writeJSON("android.calendar.json", event.events); + }, + //add and remove events based on activity on phone (pebble-like) "calendar" : function() { var cal = require("Storage").readJSON("android.calendar.json",true); if (!cal || !Array.isArray(cal)) cal = []; diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 6458087e8..7e4b275c5 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "4.01", + "version": "4.02", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 064b9996e7e2bd01d7fdff608bb4ff30754ae9cc Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Sun, 5 Jun 2022 18:55:26 +0200 Subject: [PATCH 014/121] Added periodic call to forceCalendarSync --- apps/agenda/settings.js | 1 + apps/android/boot.js | 11 +++++++++++ apps/android/metadata.json | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/agenda/settings.js b/apps/agenda/settings.js index 7edb013b9..fe9dab2d8 100644 --- a/apps/agenda/settings.js +++ b/apps/agenda/settings.js @@ -17,6 +17,7 @@ case 1: require("Storage").writeJSON("android.calendar.json",[]); CALENDAR = []; + /* falls through */ case 2: gbSend({t:"force_calendar_sync", ids: CALENDAR.map(e=>e.id)}); E.showAlert(/*LANG*/"Request sent to the phone").then(()=>E.showMenu(mainmenu)); diff --git a/apps/android/boot.js b/apps/android/boot.js index 191db3838..a548089cb 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -125,6 +125,17 @@ if (!settings.keep) NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect setInterval(sendBattery, 10*60*1000); + // Fix calendar every 2 days (can be done manually too) + function forceCalendarSync() { + if(NRF.getSecurityStatus().connected) { + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; + gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); + setTimeout(forceCalendarSync, 2*24*60*60*1000); + } else + NRF.once("connect", () => setTimeout(forceCalendarSync, 4000)); + } + setTimeout(forceCalendarSync, 2*24*60*60*1000); //schedule the first // Health tracking Bangle.on('health', health=>{ gbSend({ t: "act", stp: health.steps, hrm: health.bpm }); diff --git a/apps/android/metadata.json b/apps/android/metadata.json index 7e4b275c5..27b77cf2f 100644 --- a/apps/android/metadata.json +++ b/apps/android/metadata.json @@ -2,7 +2,7 @@ "id": "android", "name": "Android Integration", "shortName": "Android", - "version": "4.02", + "version": "0.11", "description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.", "icon": "app.png", "tags": "tool,system,messages,notifications,gadgetbridge", From 66bf7f3b1269bf1b2a053d6b50bb9604e2d54ba4 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:23:12 +0200 Subject: [PATCH 015/121] ClockFace_menu: use addItems for settings --- modules/ClockFace.md | 25 +++++++++++++++++++++++++ modules/ClockFace_menu.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/modules/ClockFace.md b/modules/ClockFace.md index 6b59e68e7..e5ab71179 100644 --- a/modules/ClockFace.md +++ b/modules/ClockFace.md @@ -174,4 +174,29 @@ Bangle.on('step', function(steps) { if (clock.paused === false) // draw step count }); +``` + + +ClockFace_menu +============== +If your clock comes with a settings menu, you can use this library to easily add +some common options: + +```js + +let settings = require("Storage").readJSON(".settings.json", true)||{}; +function save(key, value) { + settings[key] = value; + require("Storage").writeJSON(".settings.json", settings); +} + +let menu = { + "": {"title": /*LANG*/" Settings"}, +}; +require("ClockFace_menu").addItems(menu, save, { + showDate: settings.showDate, + loadWidgets: settings.loadWidgets, +}); +E.showMenu(menu); + ``` \ No newline at end of file diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index cd99ea39f..9fe61cac6 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -1,4 +1,31 @@ -// boolean options, which default to true +/** + * Add setting items to a menu + * + * @param {object} menu Menu to add items to + * @param {function} callback Callback when value changes + * @param {object} items Menu items to add, with their current value + */ +exports.addItems = function(menu, callback, items) { + Object.keys(items).forEach(key => { + let value = items[key]; + const label = { + showDate:/*LANG*/"Show date", + loadWidgets:/*LANG*/"Load widgets", + }[key]; + switch(key) { + case "showDate": + case "loadWidgets": + // boolean options, which default to true + if (value===undefined) value = true; + menu[label] = { + value: !!value, + onchange: v => callback(key, v), + }; + } + }); +}; + +// legacy boolean options exports.showDate = exports.loadWidgets = function(value, callback) { From c6c146029ef0e1ac6b65d33e6fd8661e2b7caf85 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:26:31 +0200 Subject: [PATCH 016/121] barclock: Use ClockFace_menu.addItems --- apps/barclock/ChangeLog | 1 + apps/barclock/metadata.json | 2 +- apps/barclock/settings.js | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog index 197a24738..ba44ecef8 100644 --- a/apps/barclock/ChangeLog +++ b/apps/barclock/ChangeLog @@ -11,3 +11,4 @@ 0.11: Use ClockFace.is12Hour 0.12: Add settings to hide date,widgets 0.13: Add font setting +0.14: Use ClockFace_menu.addItems diff --git a/apps/barclock/metadata.json b/apps/barclock/metadata.json index 0a0b73778..0c227dc52 100644 --- a/apps/barclock/metadata.json +++ b/apps/barclock/metadata.json @@ -1,7 +1,7 @@ { "id": "barclock", "name": "Bar Clock", - "version": "0.13", + "version": "0.14", "description": "A simple digital clock showing seconds as a bar", "icon": "clock-bar.png", "screenshots": [{"url":"screenshot.png"},{"url":"screenshot_pm.png"}], diff --git a/apps/barclock/settings.js b/apps/barclock/settings.js index 3e97688a1..dfe25581c 100644 --- a/apps/barclock/settings.js +++ b/apps/barclock/settings.js @@ -1,26 +1,26 @@ (function(back) { - let s = require('Storage').readJSON("barclock.settings.json", true) || {}; + let s = require("Storage").readJSON("barclock.settings.json", true) || {}; - function saver(key) { - return value => { - s[key] = value; - require('Storage').writeJSON("barclock.settings.json", s); - } + function save(key, value) { + s[key] = value; + require("Storage").writeJSON("barclock.settings.json", s); } const fonts = [/*LANG*/"Bitmap",/*LANG*/"Vector"]; - const menu = { + let menu = { "": {"title": /*LANG*/"Bar Clock"}, /*LANG*/"< Back": back, - /*LANG*/"Show date": require("ClockFace_menu").showDate(s.showDate, saver('showDate')), - /*LANG*/"Load widgets": require("ClockFace_menu").loadWidgets(s.loadWidgets, saver('loadWidgets')), /*LANG*/"Font": { value: s.font|0, - min:0,max:1,wrap:true, - format:v=>fonts[v], - onchange:saver('font'), + min: 0, max: 1, wrap: true, + format: v => fonts[v], + onchange: v => save("font", v), }, }; + require("ClockFace_menu").addItems(menu, save, { + showDate: s.showDate, + loadWidgets: s.loadWidgets, + }); E.showMenu(menu); }); From 994d9f2a0871d1fd4efe5b3d6b62ba1bb55f37b9 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:28:11 +0200 Subject: [PATCH 017/121] cogclock: Use ClockFace_menu.addItems --- apps/cogclock/ChangeLog | 1 + apps/cogclock/metadata.json | 2 +- apps/cogclock/settings.js | 16 ++++++++-------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/cogclock/ChangeLog b/apps/cogclock/ChangeLog index 3158b6116..684b22642 100644 --- a/apps/cogclock/ChangeLog +++ b/apps/cogclock/ChangeLog @@ -1,2 +1,3 @@ 0.01: New clock 0.02: Use ClockFace library, add settings +0.03: Use ClockFace_menu.addItems \ No newline at end of file diff --git a/apps/cogclock/metadata.json b/apps/cogclock/metadata.json index 40733bcd1..29000b589 100644 --- a/apps/cogclock/metadata.json +++ b/apps/cogclock/metadata.json @@ -1,7 +1,7 @@ { "id": "cogclock", "name": "Cog Clock", - "version": "0.02", + "version": "0.03", "description": "A cross-shaped clock inside a cog", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], diff --git a/apps/cogclock/settings.js b/apps/cogclock/settings.js index 4eadc32c2..a6627d6d2 100644 --- a/apps/cogclock/settings.js +++ b/apps/cogclock/settings.js @@ -1,19 +1,19 @@ (function(back) { let s = require('Storage').readJSON("cogclock.settings.json", true) || {}; - function saver(key) { - return value => { - s[key] = value; - require('Storage').writeJSON("cogclock.settings.json", s); - } + function save(key, value) { + s[key] = value; + require("Storage").writeJSON("cogclock.settings.json", s); } - const menu = { + let menu = { "": {"title": /*LANG*/"Cog Clock"}, /*LANG*/"< Back": back, - /*LANG*/"Show date": require("ClockFace_menu").showDate(s.showDate, saver('showDate')), - /*LANG*/"Load widgets": require("ClockFace_menu").loadWidgets(s.loadWidgets, saver('loadWidgets')), }; + require("ClockFace_menu").addItems(menu, save, { + showDate: s.showDate, + loadWidgets: s.loadWidgets, + }); E.showMenu(menu); }); From aded08293fca595dacfaac7705be0228a46e438b Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:29:18 +0200 Subject: [PATCH 018/121] ClockFace_menu: remove old options exports --- modules/ClockFace_menu.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index 9fe61cac6..62a3a9576 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -23,15 +23,4 @@ exports.addItems = function(menu, callback, items) { }; } }); -}; - -// legacy boolean options -exports.showDate = -exports.loadWidgets = - function(value, callback) { - if (value === undefined) value = true; - return { - value: !!value, - onchange: v=>callback(v), - }; - }; +}; \ No newline at end of file From 5ffb6117e600f593a6764fa4ff21bad0368f8012 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:43:00 +0200 Subject: [PATCH 019/121] ClockFace_menu: addSettingsFile with included Storage code --- modules/ClockFace.md | 13 +++++++++++++ modules/ClockFace_menu.js | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/modules/ClockFace.md b/modules/ClockFace.md index e5ab71179..b2332c805 100644 --- a/modules/ClockFace.md +++ b/modules/ClockFace.md @@ -199,4 +199,17 @@ require("ClockFace_menu").addItems(menu, save, { }); E.showMenu(menu); +``` + +Or even simpler, if you just want to use a basic settings file: +```js +let menu = { + "": {"title": /*LANG*/" Settings"}, + /*LANG*/"< Back": back, +}; +require("ClockFace_menu").addSettingsFile(menu, ".settings.json", [ + "showDate", "loadWidgets" +]); +E.showMenu(menu); + ``` \ No newline at end of file diff --git a/modules/ClockFace_menu.js b/modules/ClockFace_menu.js index 62a3a9576..f2267d9ca 100644 --- a/modules/ClockFace_menu.js +++ b/modules/ClockFace_menu.js @@ -23,4 +23,26 @@ exports.addItems = function(menu, callback, items) { }; } }); +}; + +/** + * Create a basic settings menu for app, reading/writing to settings file + * + * @param {object} menu Menu to add settings to + * @param {string} settingsFile File to read/write settings to/from + * @param {string[]} items List of settings to add + */ +exports.addSettingsFile = function(menu, settingsFile, items) { + let s = require("Storage").readJSON(settingsFile, true) || {}; + + function save(key, value) { + s[key] = value; + require("Storage").writeJSON(settingsFile, s); + } + + let toAdd = {}; + items.forEach(function(key) { + toAdd[key] = s[key]; + }); + exports.addItems(menu, save, toAdd); }; \ No newline at end of file From d09f85413b0f0d13307ed0fdf15039fb1f10c76e Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Tue, 7 Jun 2022 21:44:54 +0200 Subject: [PATCH 020/121] cogclock: Use ClockFace_menu.addSettingsFile --- apps/cogclock/ChangeLog | 2 +- apps/cogclock/settings.js | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/apps/cogclock/ChangeLog b/apps/cogclock/ChangeLog index 684b22642..f4bfe77a5 100644 --- a/apps/cogclock/ChangeLog +++ b/apps/cogclock/ChangeLog @@ -1,3 +1,3 @@ 0.01: New clock 0.02: Use ClockFace library, add settings -0.03: Use ClockFace_menu.addItems \ No newline at end of file +0.03: Use ClockFace_menu.addSettingsFile diff --git a/apps/cogclock/settings.js b/apps/cogclock/settings.js index a6627d6d2..a91b033d0 100644 --- a/apps/cogclock/settings.js +++ b/apps/cogclock/settings.js @@ -1,19 +1,10 @@ (function(back) { - let s = require('Storage').readJSON("cogclock.settings.json", true) || {}; - - function save(key, value) { - s[key] = value; - require("Storage").writeJSON("cogclock.settings.json", s); - } - let menu = { "": {"title": /*LANG*/"Cog Clock"}, /*LANG*/"< Back": back, }; - require("ClockFace_menu").addItems(menu, save, { - showDate: s.showDate, - loadWidgets: s.loadWidgets, - }); - + require("ClockFace_menu").addSettingsFile(menu, "cogclock.settings.json", [ + "showDate", "loadWidgets" + ]); E.showMenu(menu); }); From 48164384ebdec91e742f6d281004d6ac4b0909b8 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Thu, 2 Jun 2022 17:54:16 +0200 Subject: [PATCH 021/121] [Alarms & Timers] Add seconds to timers --- apps/alarm/ChangeLog | 1 + apps/alarm/app.js | 10 +++++++++- apps/alarm/metadata.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index 00187fa7c..1be0dcdd5 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -30,3 +30,4 @@ 0.28: Fix bug with alarms not firing when configured to fire only once 0.29: Fix wrong 'dow' handling in new timer if first day of week is Monday 0.30: Fix "Enable All" +0.31: Add seconds to timers diff --git a/apps/alarm/app.js b/apps/alarm/app.js index 2aff43de2..f39efc5fc 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -268,11 +268,19 @@ function showEditTimerMenu(selectedTimer, timerIndex) { wrap: true, onchange: v => time.m = v }, + /*LANG*/"Seconds": { + value: time.s, + min: 0, + max: 59, + step: 1, + wrap: true, + onchange: v => time.s = v + }, /*LANG*/"Enabled": { value: timer.on, onchange: v => timer.on = v }, - /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v), + /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v) }; if (!isNew) { diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json index 3c17ee177..54472a12c 100644 --- a/apps/alarm/metadata.json +++ b/apps/alarm/metadata.json @@ -2,7 +2,7 @@ "id": "alarm", "name": "Alarms & Timers", "shortName": "Alarms", - "version": "0.30", + "version": "0.31", "description": "Set alarms and timers on your Bangle", "icon": "app.png", "tags": "tool,alarm,widget", From 2247ee07bbfc5acfc4a1a7d1f174a94d28dc785e Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:56:14 +0200 Subject: [PATCH 022/121] [Alarms & Timers] Restore "Cancel" in timer view Oooops --- apps/alarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/alarm/app.js b/apps/alarm/app.js index f39efc5fc..0a7bb8f24 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -280,7 +280,8 @@ function showEditTimerMenu(selectedTimer, timerIndex) { value: timer.on, onchange: v => timer.on = v }, - /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v) + /*LANG*/"Vibrate": require("buzz_menu").pattern(timer.vibrate, v => timer.vibrate = v), + /*LANG*/"Cancel": () => showMainMenu() }; if (!isNew) { From 6e1aeed55b1bbe5bb3499db901384008bfd27ab4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Tue, 7 Jun 2022 22:34:21 +0100 Subject: [PATCH 023/121] I was right the first time with drawTimeout --- apps/bigdclock/ChangeLog | 1 + apps/bigdclock/bigdclock.app.js | 1 + apps/bigdclock/metadata.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index 2b6fcc7cb..5407fee95 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: Initial version 0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup 0.03: Internationalisation; bug fix - battery icon responds promptly to charging state +0.04: bug fix diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 7b26d4f17..014aa92af 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -16,6 +16,7 @@ var drawTimeout; function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function () { + drawTimeout = undefined; draw(); }, 60300 - (Date.now() % 60000)); // We aim for 300ms into the next minute to ensure we make it! } diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index e80dd9a04..769b05fcf 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clk", - "version":"0.03", + "version":"0.04", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From 7222465e508b0b26f0df6a1a74b1f285fc273729 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:20:02 +0200 Subject: [PATCH 024/121] [Nifty-A Clock] Use ClockFace library --- apps/ffcniftya/app.js | 118 +++++++++++++----------------------------- 1 file changed, 36 insertions(+), 82 deletions(-) diff --git a/apps/ffcniftya/app.js b/apps/ffcniftya/app.js index 4000a1578..24d26622c 100644 --- a/apps/ffcniftya/app.js +++ b/apps/ffcniftya/app.js @@ -1,22 +1,3 @@ -const locale = require("locale"); -const is12Hour = Object.assign({ "12hour": false }, require("Storage").readJSON("setting.json", true))["12hour"]; -const showWeekNum = Object.assign({ showWeekNum: true }, require('Storage').readJSON("ffcniftya.json", true))["showWeekNum"]; - -/* Clock *********************************************/ -const scale = g.getWidth() / 176; - -const widget = 24; - -const viewport = { - width: g.getWidth(), - height: g.getHeight(), -} - -const center = { - x: viewport.width / 2, - y: Math.round(((viewport.height - widget) / 2) + widget), -} - // copied from: https://gist.github.com/IamSilviu/5899269#gistcomment-3035480 function ISO8601_week_no(date) { var tdt = new Date(date.valueOf()); @@ -30,77 +11,50 @@ function ISO8601_week_no(date) { return 1 + Math.ceil((firstThursday - tdt) / 604800000); } -function d02(value) { - return ('0' + value).substr(-2); +function format(value) { + return ("0" + value).substr(-2); } -function draw() { - g.reset(); - g.clearRect(0, widget, viewport.width, viewport.height); - const now = new Date(); +const ClockFace = require("ClockFace"); +const clock = new ClockFace({ + init: function () { + const appRect = Bangle.appRect; - const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0)); - const minutes = d02(now.getMinutes()); - const day = d02(now.getDate()); - const month = d02(now.getMonth() + 1); - const year = now.getFullYear(now); - const weekNum = d02(ISO8601_week_no(now)); - const monthName = locale.month(now, 3); - const dayName = locale.dow(now, 3); + this.viewport = { + width: appRect.w, + height: appRect.h + }; - const centerTimeScaleX = center.x + 32 * scale; - g.setFontAlign(1, 0).setFont("Vector", 90 * scale); - g.drawString(hour, centerTimeScaleX, center.y - 31 * scale); - g.drawString(minutes, centerTimeScaleX, center.y + 46 * scale); + this.center = { + x: this.viewport.width / 2, + y: Math.round((this.viewport.height / 2) + appRect.y) + }; - g.fillRect(center.x + 30 * scale, center.y - 72 * scale, center.x + 32 * scale, center.y + 74 * scale); + this.scale = g.getWidth() / this.viewport.width; + this.centerTimeScaleX = this.center.x + 32 * this.scale; + this.centerDatesScaleX = this.center.x + 40 * this.scale; - const centerDatesScaleX = center.x + 40 * scale; - g.setFontAlign(-1, 0).setFont("Vector", 16 * scale); - g.drawString(year, centerDatesScaleX, center.y - 62 * scale); - g.drawString(month, centerDatesScaleX, center.y - 44 * scale); - g.drawString(day, centerDatesScaleX, center.y - 26 * scale); - if (showWeekNum) g.drawString(weekNum, centerDatesScaleX, center.y + 15 * scale); - g.drawString(monthName, centerDatesScaleX, center.y + 48 * scale); - g.drawString(dayName, centerDatesScaleX, center.y + 66 * scale); -} + this.showWeekNum = Object.assign({ showWeekNum: true }, require("Storage").readJSON("ffcniftya.json", true))["showWeekNum"]; + }, + draw: function (date) { + const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); + const month = date.getMonth() + 1; + const monthName = require("date_utils").month(month, 1); + const dayName = require("date_utils").dow(date.getDay(), 1); + g.setFontAlign(1, 0).setFont("Vector", 90 * this.scale); + g.drawString(format(hour), this.centerTimeScaleX, this.center.y - 31 * this.scale); + g.drawString(format(date.getMinutes()), this.centerTimeScaleX, this.center.y + 46 * this.scale); -/* Minute Ticker *************************************/ + g.fillRect(this.center.x + 30 * this.scale, this.center.y - 72 * this.scale, this.center.x + 32 * this.scale, this.center.y + 74 * this.scale); -let tickTimer; - -function clearTickTimer() { - if (tickTimer) { - clearTimeout(tickTimer); - tickTimer = undefined; - } -} - -function queueNextTick() { - clearTickTimer(); - tickTimer = setTimeout(tick, 60000 - (Date.now() % 60000)); -} - -function tick() { - draw(); - queueNextTick(); -} - -/* Init **********************************************/ - -// Clear the screen once, at startup -g.clear(); -tick(); - -Bangle.on('lcdPower', (on) => { - if (on) { - tick(); - } else { - clearTickTimer(); + g.setFontAlign(-1, 0).setFont("Vector", 16 * this.scale); + g.drawString(date.getFullYear(date), this.centerDatesScaleX, this.center.y - 62 * this.scale); + g.drawString(format(month), this.centerDatesScaleX, this.center.y - 44 * this.scale); + g.drawString(format(date.getDate()), this.centerDatesScaleX, this.center.y - 26 * this.scale); + if (this.showWeekNum) g.drawString(format(ISO8601_week_no(date)), this.centerDatesScaleX, this.center.y + 15 * this.scale); + g.drawString(monthName, this.centerDatesScaleX, this.center.y + 48 * this.scale); + g.drawString(dayName, this.centerDatesScaleX, this.center.y + 66 * this.scale); } }); - -Bangle.setUI("clock"); -Bangle.loadWidgets(); -Bangle.drawWidgets(); +clock.start(); \ No newline at end of file From 955bff9e520f1bda917dd153c20cc1df8ef98012 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Tue, 7 Jun 2022 21:20:22 +0200 Subject: [PATCH 025/121] [Nifty-A Clock] Update metadata and changelog --- apps/ffcniftya/ChangeLog | 2 ++ apps/ffcniftya/metadata.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/ffcniftya/ChangeLog b/apps/ffcniftya/ChangeLog index cb520193b..6d2f50119 100644 --- a/apps/ffcniftya/ChangeLog +++ b/apps/ffcniftya/ChangeLog @@ -2,3 +2,5 @@ 0.02: Shows the current week number (ISO8601), can be disabled via settings 0.03: Call setUI before loading widgets Improve settings page +0.04: Use ClockFace library + diff --git a/apps/ffcniftya/metadata.json b/apps/ffcniftya/metadata.json index 91b426cd0..015c56119 100644 --- a/apps/ffcniftya/metadata.json +++ b/apps/ffcniftya/metadata.json @@ -1,7 +1,7 @@ { "id": "ffcniftya", "name": "Nifty-A Clock", - "version": "0.03", + "version": "0.04", "description": "A nifty clock with time and date", "icon": "app.png", "screenshots": [{"url":"screenshot_nifty.png"}], From 685f3710f312f097976cf241344dc179a1546b5d Mon Sep 17 00:00:00 2001 From: Gabriele Monaco Date: Wed, 8 Jun 2022 17:45:39 +0200 Subject: [PATCH 026/121] Starting forceCalendarSync from Gadgetbridge --- apps/android/boot.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/apps/android/boot.js b/apps/android/boot.js index a548089cb..9cdc019a6 100644 --- a/apps/android/boot.js +++ b/apps/android/boot.js @@ -112,6 +112,12 @@ if (!cal || !Array.isArray(cal)) return; cal = cal.filter(e=>e.id!=event.id); require("Storage").writeJSON("android.calendar.json", cal); + }, + //triggered by GB, send all ids + "force_calendar_sync_start" : function() { + var cal = require("Storage").readJSON("android.calendar.json",true); + if (!cal || !Array.isArray(cal)) cal = []; + gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); } }; var h = HANDLERS[event.t]; @@ -125,17 +131,6 @@ if (!settings.keep) NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect setInterval(sendBattery, 10*60*1000); - // Fix calendar every 2 days (can be done manually too) - function forceCalendarSync() { - if(NRF.getSecurityStatus().connected) { - var cal = require("Storage").readJSON("android.calendar.json",true); - if (!cal || !Array.isArray(cal)) cal = []; - gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)}); - setTimeout(forceCalendarSync, 2*24*60*60*1000); - } else - NRF.once("connect", () => setTimeout(forceCalendarSync, 4000)); - } - setTimeout(forceCalendarSync, 2*24*60*60*1000); //schedule the first // Health tracking Bangle.on('health', health=>{ gbSend({ t: "act", stp: health.steps, hrm: health.bpm }); From ac084fa386a8ae135d18ebacae806f917299f440 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 8 Jun 2022 18:13:23 +0200 Subject: [PATCH 027/121] Fix regression in rgb introduced by semistandard --fix --- apps/rgb/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/rgb/app.js b/apps/rgb/app.js index aa18d93ae..373ee6f54 100644 --- a/apps/rgb/app.js +++ b/apps/rgb/app.js @@ -1,4 +1,5 @@ const rgb = [0, 0, 0]; +const hex = '0123456789ABCDEF'; const w = g.getWidth(); const h = g.getHeight(); function drawToggle (value, x, y, options) { From b793e7d6e460fb8e1ff232208220a886779079c5 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 21:03:39 +0200 Subject: [PATCH 028/121] [Nifty-A Clock] Read settings file via ClockFace --- apps/ffcniftya/app.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/ffcniftya/app.js b/apps/ffcniftya/app.js index 24d26622c..2c1a54f6e 100644 --- a/apps/ffcniftya/app.js +++ b/apps/ffcniftya/app.js @@ -33,8 +33,6 @@ const clock = new ClockFace({ this.scale = g.getWidth() / this.viewport.width; this.centerTimeScaleX = this.center.x + 32 * this.scale; this.centerDatesScaleX = this.center.x + 40 * this.scale; - - this.showWeekNum = Object.assign({ showWeekNum: true }, require("Storage").readJSON("ffcniftya.json", true))["showWeekNum"]; }, draw: function (date) { const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); @@ -55,6 +53,7 @@ const clock = new ClockFace({ if (this.showWeekNum) g.drawString(format(ISO8601_week_no(date)), this.centerDatesScaleX, this.center.y + 15 * this.scale); g.drawString(monthName, this.centerDatesScaleX, this.center.y + 48 * this.scale); g.drawString(dayName, this.centerDatesScaleX, this.center.y + 66 * this.scale); - } + }, + settingsFile: "ffcniftya.json" }); clock.start(); \ No newline at end of file From d9a0884c5a06ef5461d05f60377c9cef44b114cc Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 22:50:19 +0200 Subject: [PATCH 029/121] [Nifty-B Clock] Use ClockFace library --- apps/ffcniftyb/app.js | 160 +++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 96 deletions(-) diff --git a/apps/ffcniftyb/app.js b/apps/ffcniftyb/app.js index 65c74dbd7..540924fa5 100644 --- a/apps/ffcniftyb/app.js +++ b/apps/ffcniftyb/app.js @@ -1,20 +1,10 @@ -const is12Hour = Object.assign({ "12hour": false }, require("Storage").readJSON("setting.json", true))["12hour"]; -const color = Object.assign({ color: 63488 }, require("Storage").readJSON("ffcniftyb.json", true)).color; // Default to RED +var scale; +var screen; +var center; +var buf; +var img; -/* Clock *********************************************/ -const scale = g.getWidth() / 176; - -const screen = { - width: g.getWidth(), - height: g.getHeight() - 24, -}; - -const center = { - x: screen.width / 2, - y: screen.height / 2, -}; - -function d02(value) { +function format(value) { return ("0" + value).substr(-2); } @@ -22,91 +12,69 @@ function renderEllipse(g) { g.fillEllipse(center.x - 5 * scale, center.y - 70 * scale, center.x + 160 * scale, center.y + 90 * scale); } -function renderText(g) { - const now = new Date(); +function renderText(g, date) { + const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); + const month = date.getMonth() + 1; - const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0)); - const minutes = d02(now.getMinutes()); - const day = d02(now.getDate()); - const month = d02(now.getMonth() + 1); - const year = now.getFullYear(); - - const month2 = require("locale").month(now, 3); - const day2 = require("locale").dow(now, 3); + const monthName = require("date_utils").month(month, 1); + const dayName = require("date_utils").dow(date.getDay(), 1); g.setFontAlign(1, 0).setFont("Vector", 90 * scale); - g.drawString(hour, center.x + 32 * scale, center.y - 31 * scale); - g.drawString(minutes, center.x + 32 * scale, center.y + 46 * scale); + g.drawString(format(hour), center.x + 32 * scale, center.y - 31 * scale); + g.drawString(format(date.getMinutes()), center.x + 32 * scale, center.y + 46 * scale); g.setFontAlign(1, 0).setFont("Vector", 16 * scale); - g.drawString(year, center.x + 80 * scale, center.y - 42 * scale); - g.drawString(month, center.x + 80 * scale, center.y - 26 * scale); - g.drawString(day, center.x + 80 * scale, center.y - 10 * scale); - g.drawString(month2, center.x + 80 * scale, center.y + 44 * scale); - g.drawString(day2, center.x + 80 * scale, center.y + 60 * scale); + g.drawString(date.getFullYear(), center.x + 80 * scale, center.y - 42 * scale); + g.drawString(format(month), center.x + 80 * scale, center.y - 26 * scale); + g.drawString(format(date.getDate()), center.x + 80 * scale, center.y - 10 * scale); + g.drawString(monthName, center.x + 80 * scale, center.y + 44 * scale); + g.drawString(dayName, center.x + 80 * scale, center.y + 60 * scale); } -const buf = Graphics.createArrayBuffer(screen.width, screen.height, 1, { - msb: true +const ClockFace = require("ClockFace"); +const clock = new ClockFace({ + init: function () { + const appRect = Bangle.appRect; + + screen = { + width: appRect.w, + height: appRect.h + }; + + center = { + x: screen.width / 2, + y: screen.height / 2 + }; + + buf = Graphics.createArrayBuffer(screen.width, screen.height, 1, { msb: true }); + + scale = g.getWidth() / screen.width; + + img = { + width: screen.width, + height: screen.height, + transparent: 0, + bpp: 1, + buffer: buf.buffer + }; + + // default to RED (see settings.js) + // don't use || to default because 0 is a valid color + this.color = this.color === undefined ? 63488 : this.color; + }, + draw: function (date) { + // render outside text with ellipse + buf.clear(); + renderText(buf.setColor(1), date); + renderEllipse(buf.setColor(0)); + g.setColor(this.color).drawImage(img, 0, 24); + + // render ellipse with inside text + buf.clear(); + renderEllipse(buf.setColor(1)); + renderText(buf.setColor(0), date); + g.setColor(this.color).drawImage(img, 0, 24); + }, + settingsFile: "ffcniftyb.json" }); - -function draw() { - - const img = { - width: screen.width, - height: screen.height, - transparent: 0, - bpp: 1, - buffer: buf.buffer - }; - - // cleat screen area - g.clearRect(0, 24, g.getWidth(), g.getHeight()); - - // render outside text with ellipse - buf.clear(); - renderText(buf.setColor(1)); - renderEllipse(buf.setColor(0)); - g.setColor(color).drawImage(img, 0, 24); - - // render ellipse with inside text - buf.clear(); - renderEllipse(buf.setColor(1)); - renderText(buf.setColor(0)); - g.setColor(color).drawImage(img, 0, 24); -} - - -/* Minute Ticker *************************************/ - -let ticker; - -function stopTick() { - if (ticker) { - clearTimeout(ticker); - ticker = undefined; - } -} - -function startTick(run) { - stopTick(); - run(); - ticker = setTimeout(() => startTick(run), 60000 - (Date.now() % 60000)); -} - -/* Init **********************************************/ - -g.clear(); -startTick(draw); - -Bangle.on("lcdPower", (on) => { - if (on) { - startTick(draw); - } else { - stopTick(); - } -}); - -Bangle.setUI("clock"); -Bangle.loadWidgets(); -Bangle.drawWidgets(); +clock.start(); \ No newline at end of file From db096ea2f829a3317d572c482d94f1196190eed4 Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Wed, 8 Jun 2022 22:50:39 +0200 Subject: [PATCH 030/121] [Nifty-B Clock] Update metadata and changelog --- apps/ffcniftyb/ChangeLog | 1 + apps/ffcniftyb/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/ffcniftyb/ChangeLog b/apps/ffcniftyb/ChangeLog index 9fc7e3c5c..83b11eb78 100644 --- a/apps/ffcniftyb/ChangeLog +++ b/apps/ffcniftyb/ChangeLog @@ -3,3 +3,4 @@ 0.03: Call setUI before loading widgets Fix bug with black being unselectable Improve settings page +0.04: Use ClockFace library diff --git a/apps/ffcniftyb/metadata.json b/apps/ffcniftyb/metadata.json index 3d26c27ea..019ae6eb3 100644 --- a/apps/ffcniftyb/metadata.json +++ b/apps/ffcniftyb/metadata.json @@ -1,7 +1,7 @@ { "id": "ffcniftyb", "name": "Nifty-B Clock", - "version": "0.03", + "version": "0.04", "description": "A nifty clock (series B) with time, date and colour configuration", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], From d07580cc907d3bd7d3de221231ccf32936394d2d Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 9 Jun 2022 10:41:03 +0100 Subject: [PATCH 031/121] Add minified layout library, which should improve layout speed a lot. --- modules/Layout.js | 8 ++++++ modules/Layout.min.js | 14 ++++++++++ tests/Layout/bin/runtest.sh | 51 ++++++++++++++++++++++--------------- 3 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 modules/Layout.min.js diff --git a/modules/Layout.js b/modules/Layout.js index 19cfabe11..436b04592 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -2,6 +2,14 @@ // See Layout.md for documentation +/* Minify to 'Layout.min.js' by: + + * checking out: https://github.com/espruino/EspruinoDocs + * run: ../EspruinoDocs/bin/minify.js modules/Layout.js modules/Layout.min.js + +*/ + + function Layout(layout, options) { this._l = this.l = layout; // Do we have >1 physical buttons? diff --git a/modules/Layout.min.js b/modules/Layout.min.js new file mode 100644 index 000000000..7dd169eb9 --- /dev/null +++ b/modules/Layout.min.js @@ -0,0 +1,14 @@ +function p(b,k){function d(h){h.id&&(f[h.id]=h);h.type||(h.type="");h.c&&h.c.forEach(d)}this._l=this.l=b;this.physBtns=2==process.env.HWVERSION?1:3;this.options=k||{};this.lazy=this.options.lazy||!1;if(2!=process.env.HWVERSION){var a=[];function h(m){"btn"==m.type&&a.push(m);m.c&&m.c.forEach(h)}h(b);a.length&&(this.physBtns=0,this.buttons=a,this.selectedButton=-1)}if(this.options.btns)if(this.b=b=this.options.btns,this.physBtns>=b.length){let h=Math.floor(Bangle.appRect.h/ +this.physBtns);for(2b.length;)b.push({label:""});this._l.width=g.getWidth()-8;this._l={type:"h",filly:1,c:[this._l,{type:"v",pad:1,filly:1,c:b.map(m=>(m.type="txt",m.font="6x8",m.height=h,m.r=1,m))}]}}else this._l.width=g.getWidth()-32,this._l={type:"h",c:[this._l,{type:"v",c:b.map(h=>(h.type="btn",h.filly=1,h.width=32,h.r=1,h))}]},a&&a.push.apply(a,this._l.c[1].c);this.setUI();var f=this;d(this._l);this.updateNeeded=!0}function r(b, +k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();if(this.buttons){Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&&this.buttons[d])return this.buttons[d].cb(); +this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d});var b=!0}this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}};p.prototype.render=function(b){function k(c){"ram"; +g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0,0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>> +1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0, +0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse();for(var m of b)g.setBgColor(m.bg).clearRect.apply(g, +m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break;case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e, +n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))}; +p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&&a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()* +a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w=a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&& +(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y=Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear= +function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p \ No newline at end of file diff --git a/tests/Layout/bin/runtest.sh b/tests/Layout/bin/runtest.sh index e06dec86b..9bac72283 100755 --- a/tests/Layout/bin/runtest.sh +++ b/tests/Layout/bin/runtest.sh @@ -18,24 +18,35 @@ SRCJS=$1 SRCBMP=$SRCDIR/`basename $SRCJS .js`.bmp echo "TEST $SRCJS ($SRCBMP)" -cat ../../modules/Layout.js > $TESTJS -echo 'Bangle = { setUI : function(){}, appRect:{x:0,y:0,w:176,h:176,x2:175,y2:175} };BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS -echo 'g = Graphics.createArrayBuffer(176,176,4);' >> $TESTJS -cat $SRCJS >> $TESTJS || exit 1 -echo 'layout.render()' >> $TESTJS -#echo 'layout.debug()' >> $TESTJS -echo 'require("fs").writeFileSync("'$TESTBMP'",g.asBMP())' >> $TESTJS +run_test () { + LAYOUTFILE=$1 + echo 'exports = {};' > $TESTJS + cat $LAYOUTFILE >> $TESTJS + echo ';' >> $TESTJS + echo 'Layout = exports;' >> $TESTJS + echo 'Bangle = { setUI : function(){}, appRect:{x:0,y:0,w:176,h:176,x2:175,y2:175} };BTN1=0;process.env = process.env;process.env.HWVERSION=2;' >> $TESTJS + echo 'g = Graphics.createArrayBuffer(176,176,4);' >> $TESTJS + cat $SRCJS >> $TESTJS || exit 1 + echo 'layout.render()' >> $TESTJS + #echo 'layout.debug()' >> $TESTJS + echo 'require("fs").writeFileSync("'$TESTBMP'",g.asBMP())' >> $TESTJS + echo ============================================= + echo TESTING $LAYOUTFILE $SRCJS + bin/espruino $TESTJS || exit 1 + if ! cmp $TESTBMP $SRCBMP >/dev/null 2>&1 + then + echo ============================================= + echo $LAYOUTFILE + echo $TESTBMP $SRCBMP differ + echo ============================================== + convert "+append" $TESTBMP $SRCBMP testresult.bmp + display testresult.bmp + exit 1 + else + echo Files are the same + exit 0 + fi +} -bin/espruino $TESTJS || exit 1 -if ! cmp $TESTBMP $SRCBMP >/dev/null 2>&1 -then - echo ============================================= - echo $TESTBMP $SRCBMP differ - echo ============================================== - convert "+append" $TESTBMP $SRCBMP testresult.bmp - display testresult.bmp - exit 1 -else - echo Files are the same - exit 0 -fi +run_test ../../modules/Layout.js +run_test ../../modules/Layout.min.js From e1cc59ec4f6a969554ccfa69c63c9cdad33b33a6 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 9 Jun 2022 17:06:52 +0100 Subject: [PATCH 032/121] bootloader CRC --- apps/fwupdate/custom.html | 1 + bin/firmwaremaker_c.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html index 0321e46bc..3f8f50b3f 100644 --- a/apps/fwupdate/custom.html +++ b/apps/fwupdate/custom.html @@ -82,6 +82,7 @@ function onInit(device) { if (crc==46757280) version = "2v11.58"; if (crc==3508163280 || crc==1418074094) version = "2v12"; if (crc==4056371285) version = "2v13"; + if (crc==1038322422) version = "2v14"; if (!ok) { version += `(⚠ update required)`; } diff --git a/bin/firmwaremaker_c.js b/bin/firmwaremaker_c.js index 7940e551d..fd8072e06 100755 --- a/bin/firmwaremaker_c.js +++ b/bin/firmwaremaker_c.js @@ -1,4 +1,4 @@ -#!/usr/bin/nodejs +#!/usr/bin/node /* Mashes together a bunch of different apps into a big binary blob. We then store this *inside* the Bangle.js firmware and can use it From 53cbb2bb328ce766a94af11438a8393ddb2750b4 Mon Sep 17 00:00:00 2001 From: deirdreobyrne Date: Fri, 10 Jun 2022 05:14:22 +0100 Subject: [PATCH 033/121] Proper fix for the race condition --- apps/bigdclock/ChangeLog | 1 + apps/bigdclock/bigdclock.app.js | 7 +++---- apps/bigdclock/metadata.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/bigdclock/ChangeLog b/apps/bigdclock/ChangeLog index 5407fee95..09cc978fb 100644 --- a/apps/bigdclock/ChangeLog +++ b/apps/bigdclock/ChangeLog @@ -2,3 +2,4 @@ 0.02: setTimeout bug fix; no leading zero on date; lightmode; 12 hour format; cleanup 0.03: Internationalisation; bug fix - battery icon responds promptly to charging state 0.04: bug fix +0.05: proper fix for the race condition in queueDraw() diff --git a/apps/bigdclock/bigdclock.app.js b/apps/bigdclock/bigdclock.app.js index 014aa92af..c013c6188 100644 --- a/apps/bigdclock/bigdclock.app.js +++ b/apps/bigdclock/bigdclock.app.js @@ -12,13 +12,12 @@ Graphics.prototype.setFontOpenSans = function(scale) { var drawTimeout; -// schedule a draw for the next minute -function queueDraw() { +function queueDraw(millis_now) { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function () { drawTimeout = undefined; draw(); - }, 60300 - (Date.now() % 60000)); // We aim for 300ms into the next minute to ensure we make it! + }, 60000 - (millis_now % 60000)); } function draw() { @@ -70,7 +69,7 @@ function draw() { // widget redraw Bangle.drawWidgets(); - queueDraw(); + queueDraw(date.getTime()); } Bangle.on('lcdPower', on => { diff --git a/apps/bigdclock/metadata.json b/apps/bigdclock/metadata.json index 769b05fcf..7359bcf20 100644 --- a/apps/bigdclock/metadata.json +++ b/apps/bigdclock/metadata.json @@ -1,7 +1,7 @@ { "id": "bigdclock", "name": "Big digit clock containing just the essentials", "shortName":"Big digit clk", - "version":"0.04", + "version":"0.05", "description": "A clock containing just the essentials, made as easy to read as possible for those of us that need glasses. It contains the time, the day-of-week, the day-of-month, and the current battery state-of-charge.", "icon": "bigdclock.png", "type": "clock", From 0cc0a40356577ffa232526f23b147de9816bc3e0 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 10 Jun 2022 09:19:53 +0100 Subject: [PATCH 034/121] fix layout minification issue --- modules/Layout.js | 8 ++++---- modules/Layout.min.js | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/Layout.js b/modules/Layout.js index 436b04592..fd5809a93 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -6,9 +6,9 @@ * checking out: https://github.com/espruino/EspruinoDocs * run: ../EspruinoDocs/bin/minify.js modules/Layout.js modules/Layout.min.js - -*/ - + +*/ + function Layout(layout, options) { this._l = this.l = layout; @@ -79,7 +79,7 @@ function Layout(layout, options) { Layout.prototype.setUI = function() { Bangle.setUI(); // remove all existing input handlers - var uiSet; + let uiSet; if (this.buttons) { // multiple buttons so we'll jus use back/next/select Bangle.setUI({mode:"updown", back:this.options.back}, dir=>{ diff --git a/modules/Layout.min.js b/modules/Layout.min.js index 7dd169eb9..4523c547c 100644 --- a/modules/Layout.min.js +++ b/modules/Layout.min.js @@ -1,14 +1,14 @@ function p(b,k){function d(h){h.id&&(f[h.id]=h);h.type||(h.type="");h.c&&h.c.forEach(d)}this._l=this.l=b;this.physBtns=2==process.env.HWVERSION?1:3;this.options=k||{};this.lazy=this.options.lazy||!1;if(2!=process.env.HWVERSION){var a=[];function h(m){"btn"==m.type&&a.push(m);m.c&&m.c.forEach(h)}h(b);a.length&&(this.physBtns=0,this.buttons=a,this.selectedButton=-1)}if(this.options.btns)if(this.b=b=this.options.btns,this.physBtns>=b.length){let h=Math.floor(Bangle.appRect.h/ this.physBtns);for(2b.length;)b.push({label:""});this._l.width=g.getWidth()-8;this._l={type:"h",filly:1,c:[this._l,{type:"v",pad:1,filly:1,c:b.map(m=>(m.type="txt",m.font="6x8",m.height=h,m.r=1,m))}]}}else this._l.width=g.getWidth()-32,this._l={type:"h",c:[this._l,{type:"v",c:b.map(h=>(h.type="btn",h.filly=1,h.width=32,h.r=1,h))}]},a&&a.push.apply(a,this._l.c[1].c);this.setUI();var f=this;d(this._l);this.updateNeeded=!0}function r(b, -k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();if(this.buttons){Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&&this.buttons[d])return this.buttons[d].cb(); -this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d});var b=!0}this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}};p.prototype.render=function(b){function k(c){"ram"; -g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0,0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>> -1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0, -0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse();for(var m of b)g.setBgColor(m.bg).clearRect.apply(g, -m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break;case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e, -n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))}; -p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&&a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()* -a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w=a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&& -(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y=Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear= -function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p \ No newline at end of file +k,d,a,f){var h=null==b.bgCol?f:g.toColor(b.bgCol);if(h!=f||"txt"==b.type||"btn"==b.type||"img"==b.type||"custom"==b.type){var m=b.c;delete b.c;var c="H"+E.CRC32(E.toJS(b));m&&(b.c=m);delete k[c]||((a[c]=[b.x,b.y,b.x+b.w-1,b.y+b.h-1]).bg=null==f?g.theme.bg:f,d&&(d.push(b),d=null))}if(b.c)for(var l of b.c)r(l,k,d,a,h)}p.prototype.setUI=function(){Bangle.setUI();let b;this.buttons&&(Bangle.setUI({mode:"updown",back:this.options.back},k=>{var d=this.selectedButton,a=this.buttons.length;if(void 0===k&& +this.buttons[d])return this.buttons[d].cb();this.buttons[d]&&(delete this.buttons[d].selected,this.render(this.buttons[d]));d=(d+a+k)%a;this.buttons[d]&&(this.buttons[d].selected=1,this.render(this.buttons[d]));this.selectedButton=d}),b=!0);this.options.back&&!b&&Bangle.setUI({mode:"custom",back:this.options.back});if(this.b){function k(d,a){.75=d.x&&a.y>=d.y&&a.x<=d.x+d.w&&a.y<=d.y+d.h&&(2==a.type&&d.cbl?d.cbl(a):d.cb&&d.cb(a));d.c&&d.c.forEach(f=>k(f,a))}Bangle.touchHandler=(d,a)=>k(this._l,a);Bangle.on("touch",Bangle.touchHandler)}}; +p.prototype.render=function(b){function k(c){"ram";g.reset();void 0!==c.col&&g.setColor(c.col);void 0!==c.bgCol&&g.setBgColor(c.bgCol).clearRect(c.x,c.y,c.x+c.w-1,c.y+c.h-1);d[c.type](c)}b||(b=this._l);this.updateNeeded&&this.update();var d={"":function(){},txt:function(c){if(c.wrap){g.setFont(c.font).setFontAlign(0,-1);var l=g.wrapString(c.label,c.w),e=c.y+(c.h-g.getFontHeight()*l.length>>1);l.forEach((n,q)=>g.drawString(n,c.x+(c.w>>1),e+g.getFontHeight()*q))}else g.setFont(c.font).setFontAlign(0, +0,c.r).drawString(c.label,c.x+(c.w>>1),c.y+(c.h>>1))},btn:function(c){var l=c.x+(0|c.pad),e=c.y+(0|c.pad),n=c.w-(c.pad<<1),q=c.h-(c.pad<<1);l=[l,e+4,l+4,e,l+n-5,e,l+n-1,e+4,l+n-1,e+q-5,l+n-5,e+q-1,l+4,e+q-1,l,e+q-5,l,e+4];e=c.selected?g.theme.bgH:g.theme.bg2;g.setColor(e).fillPoly(l).setColor(c.selected?g.theme.fgH:g.theme.fg2).drawPoly(l);void 0!==c.col&&g.setColor(c.col);c.src?g.setBgColor(e).drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI* +(c.r||0)}):g.setFont(c.font||"6x8:2").setFontAlign(0,0,c.r).drawString(c.label,c.x+c.w/2,c.y+c.h/2)},img:function(c){g.drawImage("function"==typeof c.src?c.src():c.src,c.x+c.w/2,c.y+c.h/2,{scale:c.scale||void 0,rotate:.5*Math.PI*(c.r||0)})},custom:function(c){c.render(c)},h:function(c){c.c.forEach(k)},v:function(c){c.c.forEach(k)}};if(this.lazy){this.rects||(this.rects={});var a=this.rects.clone(),f=[];r(b,a,f,this.rects,null);for(var h in a)delete this.rects[h];b=Object.keys(a).map(c=>a[c]).reverse(); +for(var m of b)g.setBgColor(m.bg).clearRect.apply(g,m);f.forEach(k)}else k(b)};p.prototype.forgetLazyState=function(){this.rects={}};p.prototype.layout=function(b){switch(b.type){case "h":var k=b.x+(0|b.pad),d=0,a=b.c&&b.c.reduce((e,n)=>e+(0|n.fillx),0);a||(k+=b.w-b._w>>1,a=1);var f=k;b.c.forEach(e=>{e.x=0|f;k+=e._w;d+=0|e.fillx;f=k+Math.floor(d*(b.w-b._w)/a);e.w=0|f-e.x;e.h=0|(e.filly?b.h-(b.pad<<1):e._h);e.y=0|b.y+(0|b.pad)+((1+(0|e.valign))*(b.h-(b.pad<<1)-e.h)>>1);e.c&&this.layout(e)});break; +case "v":var h=b.y+(0|b.pad),m=0,c=b.c&&b.c.reduce((e,n)=>e+(0|n.filly),0);c||(h+=b.h-b._h>>1,c=1);var l=h;b.c.forEach(e=>{e.y=0|l;h+=e._h;m+=0|e.filly;l=h+Math.floor(m*(b.h-b._h)/c);e.h=0|l-e.y;e.w=0|(e.fillx?b.w-(b.pad<<1):e._w);e.x=0|b.x+(0|b.pad)+((1+(0|e.halign))*(b.w-(b.pad<<1)-e.w)>>1);e.c&&this.layout(e)})}};p.prototype.debug=function(b,k){b||(b=this._l);k=k||1;g.setColor(k&1,k&2,k&4).drawRect(b.x+k-1,b.y+k-1,b.x+b.w-k,b.y+b.h-k);b.pad&&g.drawRect(b.x+b.pad-1,b.y+b.pad-1,b.x+b.w-b.pad,b.y+ +b.h-b.pad);k++;b.c&&b.c.forEach(d=>this.debug(d,k))};p.prototype.update=function(){function b(a){"ram";k[a.type](a);if(a.r&1){var f=a._w;a._w=a._h;a._h=f}a._w=0|Math.max(a._w+(a.pad<<1),0|a.width);a._h=0|Math.max(a._h+(a.pad<<1),0|a.height)}delete this.updateNeeded;var k={txt:function(a){a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));if(a.wrap)a._h=a._w=0;else{var f=g.setFont(a.font).stringMetrics(a.label);a._w=f.width;a._h=f.height}},btn:function(a){a.font&& +a.font.endsWith("%")&&(a.font="Vector"+Math.round(g.getHeight()*a.font.slice(0,-1)/100));var f=a.src?g.imageMetrics("function"==typeof a.src?a.src():a.src):g.setFont(a.font||"6x8:2").stringMetrics(a.label);a._h=16+f.height;a._w=20+f.width},img:function(a){var f=g.imageMetrics("function"==typeof a.src?a.src():a.src),h=a.scale||1;a._w=f.width*h;a._h=f.height*h},"":function(a){a._w=0;a._h=0},custom:function(a){a._w=0;a._h=0},h:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>Math.max(f,h._h),0);a._w= +a.c.reduce((f,h)=>f+h._w,0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)},v:function(a){a.c.forEach(b);a._h=a.c.reduce((f,h)=>f+h._h,0);a._w=a.c.reduce((f,h)=>Math.max(f,h._w),0);null==a.fillx&&a.c.some(f=>f.fillx)&&(a.fillx=1);null==a.filly&&a.c.some(f=>f.filly)&&(a.filly=1)}},d=this._l;b(d);d.fillx||d.filly?(d.w=Bangle.appRect.w,d.h=Bangle.appRect.h,d.x=Bangle.appRect.x,d.y=Bangle.appRect.y):(d.w=d._w,d.h=d._h,d.x=Bangle.appRect.w-d.w>>1,d.y= +Bangle.appRect.y+(Bangle.appRect.h-d.h>>1));this.layout(d)};p.prototype.clear=function(b){b||(b=this._l);g.reset();void 0!==b.bgCol&&g.setBgColor(b.bgCol);g.clearRect(b.x,b.y,b.x+b.w-1,b.y+b.h-1)};exports=p From 713a2849cccd7c0ca666ac47e648e4e0da4386af Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:34:27 +0200 Subject: [PATCH 035/121] Create app.js --- apps/wristlight/app.js | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 apps/wristlight/app.js diff --git a/apps/wristlight/app.js b/apps/wristlight/app.js new file mode 100644 index 000000000..24bc1eab2 --- /dev/null +++ b/apps/wristlight/app.js @@ -0,0 +1,52 @@ +function draw(color) { + if (color == undefined) { + color = -1; + } + g.clear(); + g.setColor(color); + g.fillRect(0, 0, g.getWidth(), g.getHeight()); +} + +function draw2Pattern() { + colors = ["ff0000", "8080ff", "00ff00", + "ffffff"]; + drawPattern(2, colors); +} + +function draw3Pattern() { + colors = ["ff0000", "00ff00", "0000ff", + "ff00ff", "ffffff", "00ffff", + "ffff00", "ff8000", "ff0080"]; + drawPattern(3, colors); +} + +function drawPattern(size, colors) { + g.clear(); + var w = g.getWidth() / size; + var h = g.getHeight() / size; + for (var i = 0; i < size; i++) { + for (var j = 0; j < size; j++) { + var color = colors[i*size + j]; + g.setColor("#" + color); + g.fillRect(j * w, i * h, j * w + w, i * h + h); + } + } + Bangle.on("touch", function(btn, xy) { + var x = parseInt((xy.x) / w); + var y = parseInt((xy.y) / h); + draw("#" + colors[y * size + x]); + }); +} + +// Clear the screen once, at startup +// draw immediately at first +draw3Pattern(); + +/* +require("Storage").write("wristlight.info",{ + "id":"wristlight", + "name":"Wrist Light", + "src":"wristlight.app.js", + "icon":"wristlight.img" +}); +*/ From baf2f9a93d6eae3a6942599b57df0f2d2c38c723 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:35:54 +0200 Subject: [PATCH 036/121] Create metadata.json --- apps/wristlight/metadata.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/wristlight/metadata.json diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/apps/wristlight/metadata.json @@ -0,0 +1 @@ + From a51016d5bcf3000b03b93178cdfc348b89ca3d17 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:36:16 +0200 Subject: [PATCH 037/121] Add files via upload --- apps/wristlight/wristlight48.png | Bin 0 -> 1859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png new file mode 100644 index 0000000000000000000000000000000000000000..8f0ff59f7811dad27ad975ad452626d89aa8893f GIT binary patch literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N literal 0 HcmV?d00001 From 894df7889eb604ade9b1e9f09dcf00383547702b Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:40:33 +0200 Subject: [PATCH 038/121] Update metadata.json --- apps/wristlight/metadata.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json index 8b1378917..3a2bff048 100644 --- a/apps/wristlight/metadata.json +++ b/apps/wristlight/metadata.json @@ -1 +1,16 @@ - +{ "id": "wristlight", + "name": "Wrist Light", + "shortName":"Wrist Light", + "icon": "wristlight48.png", + "version":"0.01", + "description": "A flash light with different colors on your wrist", + "tags": "flash,light", + "allow_emulator":true, + "supports": ["BANGLEJS", "BANGLEJS2"], + "readme":"README.md", + "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" }} ], + "storage": [ + {"name":"wristlight.app.js","url":"app.js"}, + {"name":"wristlight.img","url":"wristlight-icon.js","evaluate":true} + ] +} From d623647ef3a88423302b64267e20ad62c28e54fe Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:40:56 +0200 Subject: [PATCH 039/121] Update metadata.json --- apps/wristlight/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wristlight/metadata.json b/apps/wristlight/metadata.json index 3a2bff048..af1d700df 100644 --- a/apps/wristlight/metadata.json +++ b/apps/wristlight/metadata.json @@ -8,7 +8,7 @@ "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], "readme":"README.md", - "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" }} ], + "screenshots" : [ { "url":"screenshot.png" }, { "url":"screenshot_red.png" } ], "storage": [ {"name":"wristlight.app.js","url":"app.js"}, {"name":"wristlight.img","url":"wristlight-icon.js","evaluate":true} From 21db0d3412c21a63500932aea06bb29ebe7eabb7 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:43:06 +0200 Subject: [PATCH 040/121] Create README.md --- apps/wristlight/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 apps/wristlight/README.md diff --git a/apps/wristlight/README.md b/apps/wristlight/README.md new file mode 100644 index 000000000..e69d61b76 --- /dev/null +++ b/apps/wristlight/README.md @@ -0,0 +1,9 @@ +# Wrist Light + +A flash light on your wrist with different colors + +![](screenshot.png) +![](screenshot_red.png) + +## Creator +[@pidajo](https://github.com/pidajo) From c12ece7cde5b79ce0c10efa31ce6331af6e10f96 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:44:43 +0200 Subject: [PATCH 041/121] Create wristlight-icon.js --- apps/wristlight/wristlight-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/wristlight/wristlight-icon.js diff --git a/apps/wristlight/wristlight-icon.js b/apps/wristlight/wristlight-icon.js new file mode 100644 index 000000000..689372499 --- /dev/null +++ b/apps/wristlight/wristlight-icon.js @@ -0,0 +1 @@ +atob("MDCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzMAN3d3d3d3QDu7u7u7gAAAAAADMzMzMzMDd3d3d3d3dDu7u7u7uAAAAAAzMzMzMzMDd3d3d3d3dDu7u7u7u4AAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAMzMzMzMzMDd3d3d3d3dDu7u7u7u7gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7u7uwAAAA//8AAAAHd3d3d3cAAAALu7u7u7u7AAD/////AAB3d3d3d3dwAAALu7u7u7u7AA//////8AB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7D/////////B3d3d3d3dwAAALu7u7u7u7A////////zB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AP///////wB3d3d3d3dwAAALu7u7u7u7AA//////8AB3d3d3d3dwAAALu7u7u7u7AAD/////AAB3d3d3d3dwAAAMu7u7u7u8AAACMzMgAAB3d3d3d3dwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALu7u7u7u7AIiIiIiIiACIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAALu7u7u7u7CYiIiIiIiJCIiIiIiIiAAAAAu7u7u7u7CYiIiIiIiJCIiIiIiIgAAAAAq7u7u7u7CYiIiIiIiJCIiIiIiIAAAAAAALu7u7u7CoiIiIiIiKCIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==") From d29b7596bc14b55769fad1542e6dc55624b34c86 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:46:42 +0200 Subject: [PATCH 042/121] Add files via upload --- apps/wristlight/Icon.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/Icon.png diff --git a/apps/wristlight/Icon.png b/apps/wristlight/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 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 KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From 835f62d59ad7c8ec14654dbefa3ee032151bee87 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:48:50 +0200 Subject: [PATCH 043/121] Delete wristlight48.png --- apps/wristlight/wristlight48.png | Bin 1859 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png deleted file mode 100644 index 8f0ff59f7811dad27ad975ad452626d89aa8893f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N From c191b01d2b4e69433d2182faed82242f4555acc0 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:49:19 +0200 Subject: [PATCH 044/121] Add files via upload --- apps/wristlight/screenshot.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/screenshot.png diff --git a/apps/wristlight/screenshot.png b/apps/wristlight/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 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 KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From a9922f3fa0d556c8fff49a9c633b18cd1439b547 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:50:26 +0200 Subject: [PATCH 045/121] Add files via upload --- apps/wristlight/screenshot_red.png | Bin 0 -> 47586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/screenshot_red.png diff --git a/apps/wristlight/screenshot_red.png b/apps/wristlight/screenshot_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a GIT binary patch literal 47586 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 KR__}6`+opC#zdX~ literal 0 HcmV?d00001 From 5d908f50f479be127551c208004759937305fd51 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:52:52 +0200 Subject: [PATCH 046/121] Add files via upload --- apps/wristlight/wristlight48.png | Bin 0 -> 1859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/wristlight/wristlight48.png diff --git a/apps/wristlight/wristlight48.png b/apps/wristlight/wristlight48.png new file mode 100644 index 0000000000000000000000000000000000000000..8f0ff59f7811dad27ad975ad452626d89aa8893f GIT binary patch literal 1859 zcmV-J2fX-+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TD&%c|dY11Tak~XcBf;5ET;(!Q_T!iu>ij0>Rb;c*2U>F&|8IS>WP(~R=g$JZ` z7<}=KIm)+mA}HHah*LJNuvWpR;?; z=D(cX!Xy(6kkQ`*rf(V>Sv zxQm+%{wagmGM~;)Dg*-1A*&TJBtTzNGk9b%sRSr2A;hL5V8*tR(tvs>^m-_5$974j z9;{f6=JULY==6p>Q)!t7&(VFw=kW8M=D zsLu!eE;rmkaY)w1;Rnd3tsD?5wiP810qLrl9z2X~skpe9U%!66rlzK*vZ|_TNoi?m zjase7Vh;IApjjm0c*dZ&H^uIf)I{{19q_Zq$XvBmro zfqo7vZQIDRw`5T%(i-~16zit7y=&I2(ON8)=d4!iPMuD-68nY8XlMx3-l?@{8?;^6ozYwj?hDQmwhOmeJMQR(kXCMH0_TTt!IC9Q@{LC0(%G|T z*JALim_F8>fDpp7KD0SxGMSb#9|%AJc4ZVigL-K^*0?hTs$|%Vg3r(64Fo6WXM zqtUS8mlm{{iMBhLkD6C2DyK&=tbETn`;in^l;-1jUx5KBu4K{ndFE45T#@#LNeNje zV5}-HDlaczg+oN~wU{mQsWes=$*OUabpjflR{LnR$pq%3LuXkWH(4hjN)jhYQpWR# z`A88d>-%SY0iVkw_%q*$_`40O5=;hUJSC21z`3?wqH&x%tGABS-e!zkk0q)o@}u*2ip^ z?fLWPJv2;3yolnV_Xrw5KbhgHhxrV7^MfK#S7TerszL`qxW1Zx{~5Li%w{t`Z{9r9 ztXZ=bEMB~L#exM37UPCh#_T*EkE6A<^%By2>(;H-YuBzh`}_M@5Jv4u?R%tz%*D2% zds08W8(0SFaMMC6l|ItevYw590u|+EFqw*nmj{o9pq0z*g|04k z&*WY=16li(RVsB9`wStyM>gJLEN0vGk+c@soL8w?H=C_X~r zX`t7a%hyTVGzh}DD#I{@R9Na~5`2`XPbjRyhLW+LfY}R)STnwHt}&UwMDzbiAOhix zcf<)JoQO4^z-g#=ORO@;btnzNvEyD@N+e*1yIvRcU6RGz#p!H=d-vGCcB2fR1HM!6 z-C+ueLMaD{z%Rdki|3RHguj5zC(gldUtximdr9Ed4NXn8uxso0o_6<=p6GsU?fqWhYy1g3`VQUln{c?66a-icPkwHdI!Am z);Fki#X4i8+QylVeeS5xgV8bv7MXeAM<$98+6nEQ9dP?P3dT~)3-dX`Yhr!rk*Fv* zdQY}t(+Rej)i9&F0w3|{SR$ebEiEn>7;vJ*Dp2-8H|Z;Cx;ljQvB1;SNNlLFgW0lw xyrsL|a99v*7_c+Deu@Vahb@`8JTJ2W;2--p$DOW1Az1(b002ovPDHLkV1j}@bNB!N literal 0 HcmV?d00001 From fb48fccd6cbb1360464c8794de93bc3b776fbf49 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:03:24 +0200 Subject: [PATCH 047/121] Add files via upload --- apps/wristlight/screenshot.png | Bin 47586 -> 261 bytes apps/wristlight/screenshot_red.png | Bin 47586 -> 160 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/wristlight/screenshot.png b/apps/wristlight/screenshot.png index 0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a..31850d1ca814da33ad24c5551b36f3a1539285c0 100644 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^8$g(a8A!&?{Fw`+7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0(2Ka=y{s%I^_&>vcAb=1>{Wc(DISV`@iy0XB4ude`@%$AjK*35+7srr{ zdvDJj=+*N6Gj|4v^Z`sRPawuZ#%Z=!RnS=pKoCKyQYz^U}6 z{#R@2!ZE}T>eqz-&k5mOe^tHs&5e!8$NOZh%a9l!O^zqq9GzX9JA0$eL!cuVJYD@< J);T3K0RTc%U-ke1 literal 47586 zcmeEucRbba|Mx+t>|}=|RQ47!5-O`Q$|##-93wI^j*;zI=2XZIAN`*p$LH#N0VVpiNVjOoNns7Kp>P& z_&)?~j&Ci%KQg*1KXBD{v~qPfeQXJFGPQAV6>zY0JufC8Bp_}XBw`7HRB7M3p{V2W zXf>5IMR#DJ&avn&U$L3vdEFDr&$%B!uUvY2>FtA<3-|agT?oHKC~-&eEWw)*>Xlk| zgz!Lff?4>1y8Xcm#;n#k+*kOu*+<(j%A+oF(fugx2^U`~qL4(d?vdqjyIQYwpYA#A z(IoCP$202JX)&^wo>5;9{iv~(L4Exs$C5;QAozIpcJw0E&o4N{{(ts`x3WkdRh=ju zFFl447n&!@FG=1-tW<@D$Jnaf6@NjhJYo@KBNjS*-c0E(M@{XF8=pb${*c7XzIMkF z={JMb#?dcfqrIa@=;r(7i&Wv|VK?HJ8d!)WBqYM1j8GjC#4^*!^1cKiDpDewf40l` zTd%gWzOhH@##1(#==3%Lx%8E)oDZt~MkSjO=7zLodcEiFrnk3t%+42YqkCJ~>R&Kk zzan4;dqLV_z$&%YJYwd5^V+nSumpuY{jhA2GLv@&TTHDRs&zEnEsLUd*2}u^@#Fc0 z#%`~3rNTSIEzV!l?3SM1=;UIlPkLQ0b-!{jW##J7{TYePgcj$(;kg#!NDTt#x2}B4 zMD2mQbkEM5m`#-wKp#j825?Q=+t^#$vkr3?!J6G(pKzo?g&<##L*=!`$_m^cOS`{$ zAv(!WC$HIBlhziqf2&0>%5VvzygEHP$n4ovK7VlGefeP;&y1aW%|lrS=am_B)h#EN zDd!IBlNKZwUXU)+p1d%{IuzkM=1FtEuB&>S1;I>lcq>ao^SH=))($(7y*ZAv|28MS zu*{9Xp(i^fjtf6`!;{3YN3S%JY7U)ax$oDHdc;m=`YcYBU4?1o<|uht3si7!f zb1<@nv&D0}6;Jo`$2Ow7zdk(v{&MU+E-~ro2%b9<9U)C7%stqgGMwd~5p>;-UjW19 zIeULyOlo>o-ce{fqFd4fD{m~0{((ET3oN|hTZeu9$q{=nLLw*yKhFO2g-U+dWN=j8 zRtU2@Bq{X`)sF~B4jk^U;@Dsc$Y;9Lew61i$O8^ZqzG{}X!aAj7sV6Vv*YHYx37}v~E){ z?Im=ijyAE{SyC&VP=7^hZh^|DX38Be!V=*jvzYp}`1IKY&s3Patf0HbJI2sMvLpo- zMb5ZhgF)yEC8TL{(iNlEQkbK!B<%3LdJ49~-Remu8DDP)K{JzPs|IUNA;RWCYvRE$ zM<4tSt~)6`uPwa*5u}t8;k!(&qMfsI`7p2X;=Aa57V(e$GoO5}lk2A>sHs{fN?FsE zFu;9%tE0O*A0}UcT(6NAzJIA8ZZ1Z?w*HfD-i5gD^2V?Y!I*TNWZknJ4bkwPDT@eF zXGEuhEUzEUB}DOE$4G@OlZOE&!5L3g-)tP!nn>G)X-gsvE2o1~v8e3LYs`y7d~9PL zvvTz5IVvd$VOd(Uajp;Qg5fT*hL~hIDX}4*ICPLx&q;$*NqKJv(YQ*q<9@@E(YlUe zfKCi;9OppYz;oFL$s7+j zple;Ha!$kf7rYP>SNqJ6S&F$_z28j3c;~xht{5Lkwhi6>JjoIxBO136^f^GUN4-bW z(;&-4C{_KDsYTT+OQD1mr=jb;pxbBD?a!IX;f_cIRaE?v?!?o)jpYVfL|%VR?mj

Z4(l<#_SRC=NP#HT|%7SCzUV-bA+ofbKjyW%Csr7qKC!IoFR% z9~~KboyJVJc)vn`b1OSI}0R|(QK)9Ho`lJ>{gLsg3g7pr37FH zrvgkZRFCDxwW!rp{Oe);&?Nf(fk)W!>`iNWRk^{^>Q6iQ(H&!N`V?nrm~h?uo5xRp_5>pGPni@?Il>Q8 z^XOGcs5W5)W*V@}*8ap1zqwB+LINT0{`LJspMGPJad=ZOi<>Ep{=2uKsGye8^4^Y( z7$%Z#R_WBf*>z5ly6APs)Z07P=ZHE_tj_f%MPn~hgJTb7Sk}#?UwQD_BirnGbUw`# zvH>AEFKsA0J4(oglNMzGCdHC5tpqvwtlBxnVDT-kKqWb{=WYF(iSYO+)Kuu(j4v;D z_kEi_;lB@<`=W;WKmi=h(x%f54ir$`ypnNOdpE7)+|H~6#DB?8C5@JqBbl)lGX_X_YA%!X{_O1<%%lyLDWkJaxaoB)kK?&~pfV5h?!hPB9Re(_!j z&t6IY%EhrA2X{%qy&|BFBLtvfQLdLp@ME6%g0A|#7S(?8dz;~55%sjmezcmG4$g)a zo-#>2$xai=POmeoj$fXb;w*ExDqm|iO5ifKb)CZZnBzYd-k zO0Y4iAp&{gr!$sPiI#C7#2)AevKwL!ZeHT{8&&ETfIql{@V0jXiw42Q_V=xi`kcJS zf`hXa-H$Syv)<%2o?jx(Az*^s<pN^z()SP`&35o z-LDvT(*C!*koLey60ykX{o|p7Hv)pvi2c|M37iQmQLoO zuR3qKkDaK&cn8Mh5UDF*c5d1x37*auE(NO$P*9jztb^@vMUSM^eIltv`)uUBKEFhj zL;S~X)UO2NcSGJVWGsfZINTZY&mkTnf0`E)K^RN=o|d_BBM)A`t`*qpy6a+Jpy26?l6OaK`wIZ#E(MSX&E(AUDeW0H}h`Q+XcOfz?#fIduqgQH6vL5%s?{1ZXx81aKO=Xx}Mk zJBG&Ua8U2k_B|u_drJ>IFpAvo5*M9zC|P|IUjw`EkV%+LfU0sQd+RwYrmc&kNH07F>{*`FAny4a_J$%DWZdMZAi7xF9`9;U}X z&)&zW9$SX?isg39Iqmm$GC|@GSv|TZ90lCLilB!^bgaWQi`}X&kvN0imltm*EzQXO zACs|eq6nEN~L@^N0~)FiQm15LC@&I?to6g&n)wO_H9ZV!*O# z;D@I9G;nAHEX}MznMv-jZS#4)vjSHZu8rA2Ryb}a$Vr{&A8EY4o;?FLyHFg$5-FOR zk>^2w-dEZrRSbgdfWw#4-PzVc$_^@>XBV_@8J}!({bR>h)UV7tZ-zu;`=>7V-QsOZ zCu^W}$_sl_&v{-~DME3}B(s?R5oVzqvk-PuDudpqpfCGO9kp-{-5;_wy(b(UQQub& z|De{RfpJxEKxlKmhY6eDAMRwp9jM}Nryn?$`P#&42xxG5bC{{~{p3$}3`E>i^vt6(i?}EBIG_H?O|raaf;S>afie1^PAyvWeiB>Rba zD8@}yLLXt1@^KO%>x)RsT->5m9XdK%X(ej__xeJD-andcei|F@V-LY&QB( z868*!@DZ{w;GMVw#v99a5-2G2$_QCZ%g!IN8cfz%F(-n|wthcMe&j7|vLvC9Dh%0N zf@}3~rOtN-QxvLkd2y5^Jo@KdH{N`1l>?{4lujnvKE1pwq0l=-aFL4s^yo|o4!r~i z36UO-<>&{t{_Uk4hCgI_`QBzU1%QFkDc`<`<*$xJ&Cw(Rhf4lnm&81dPJ*1iXew=1 zbx)z)Ud4T!va)dPpO6(34!4IiO8fbcwjPd&&Wn06=RMlW5`CNNDaXA8 zt3OY9%jUcUq=Mg8=mM0KB2!pQ7q$!mTlI%+9>dpcn)h*uTf+-=!7N(;yJz>uN2iSX zBJKF9D9`H}lPPbRa1?b?C}0k7Xe|6FUBb5PQrwTAo2E%I1k?kBAlCw)aolhGhanjB z5zCla(q%hVg}V%dz-|aNQJ)1MJKZ=J9DGt<%wY$5rI#$GQ4IL!Uw-=Th8|Hd0eZZU zMHZT5r!bhm{4{cnD`Q~poH!Ba@$g#1i&tP|b*40BN9*ep~!H>EQK=yjW zEtX9l$Zhy>VQ<%ui$v!KN&6!Iz=kuISuMyRADvT$Z>m`Lcf5w50ZAUU(>E2&DF}$R z=Wfdpn7Cp;-kODHpQ)w3tS!;v(+(1I|MX5)*G|J?TpbK`B~i#{$YJ`!ODs#IZ!$t~sgTW5 zh;1#wMhIlHN=5qiq9B3D$2b3Zpx6P$R*0)`N&VSSBfXsv0oO^RV{}z+uI7aw!y2URpw$ zpZ*u=y$SjZaTQ(4CfJxfkst!O_ER@M^E${~onHyYTanBBFU=u6@#KEgl)s!vnfOq+{%;mjBsm}RyOaX%{m0G%$Q3U9F6@98hvT~s;0wCkZ-|-v zZoFW)zz$MRkcyn8`xS=Ysow@EVA$`{2A^16`Sk^z#Fz9IkTZCr{ZGMshFtus0RNwZ zxB-;`_5P1W{>QZb1dspm5qul)-w^o!#79cyNKE8GRh6%Fn~aIb54hj6pDm?-{x760Rha7I6?U~<3DYPZQe$sq>sL`nQ&7cPuJrW}ALzrh#7(3AX`m&=qz z+`bv8{RPbT40yjnT;m9+_3s&kk}C{lqz*&u?fP#KH7J)%WgZP_FvHV8^Yd5lnUq4e z8G=b46zKB#=O20Ah)Y5)+DJlRkv@nI#y%5Ma7)My0Km`_1$c}V)8U~|7`yx94wtrN zx|joI_MZ+e^s~%uiObvTPs-hV*V^(d1aHun;UmkI4aH|W874300*V(NucGCKr;g-4 ze&s&aai)Hfo=<7S4#mf;434sAIX#2(Dj?h%on_7Izg$01H2v+L<=0-;W_etXirqpP zu*4W9{nJ8!Q_kOXe<+E?kFu4(u@3pkj0r*$JK(=egx@d_Kv7!WAd6ox3B#ur3z^%m z;*#yf#N$@}>i7>{e)Z~Qb^f`OYzfFmHMgi6C3X6R-kbs)Ye6s2k z;zR+ufLm-XLZerYHfxUwQdHnyT>ME{NCb3G<0k|~Da9y#%1xVO?hz~W8>iV0J8_^+ zGH+hiFQc7|RW`h65y@@*bqJML_4^Cbm+$KqIIqW#63fjtx1FT&{T@US|6P>e`4#5Z zd$Hl-89_Yk$6bVFG-5NN8lbqT8cZ;qQGD9pLz2gAcoNh&1UxW%3nv;Q^8N0aBTHG6 z!0wS5q!*J9kA3Adx*jy|s&$0_9zv3U5f!vG*P{1K(sjcGb=TIRaGO=XF?7B9mtz54 z@*Bql6dA-~G-btd2Ilk)Lj*!kzS{f4x1PnYTD{(HcCIQ;_a2_QpBDf+Wl#uzMpy=g z*i5?EUkY#G0aB3H*xLG=Vk)}-paQprr494O% z80B|2Lq8IM;cmCMy@z12Dv=`D+Kb+k2Aeh_=`WOlj-IJoPcI+ZtZt00Scfd=;hfFZ z7>qUAePXVh5l>(DR?F^sW2F=sw(HX5vVX=)jJm9-&VUHJT9K0Q(GuBUO<>kE(kA7N zMNB3hbkI_)VVk^IFgp?5%ou*%i#Nvo8ENgzG*@~Rdam1x`RqjhvZfA^1HuLa8we&A zGS(F8NQ6EOGZve5NDPt;VRUUJXf>IYGEZ=R;auYU&N<2XX*1JnJ?ged#xrVWx9!6= zsRI*ez3}tiXVn$}OT3klTJ5j-rB6%G+NBN{1d>pw=sZJ6px$1}p5Rqp8hf88Wz{m6 z)Gf8?(?O5s^JCGZ_bmR9(R_kYm8p&KLj^5jnqBP>$k@InD9-ZLhVk z^JkorOp-g)>J-Z?eeFYtFL!|{6nXf2F;-fo3z!FSevo$i%J*%nIg-{|I*LT*n-nUe ziOrE*96C%(&aB@r7s@JpG2ZpLIfa>ee%MtY|Fq}5Bz?vDuU7gjpkxSPUA^2gtCpSY z&}m`4=R=vMO~E|5(6P$R%W)jL2G5_auN*MFSxEbcw0%8nu&obCcb++_ivC(aq<$iz zdhCSIlKE0az5iy$B`1NDSi7z#Jhtp?@@9+DoUP4CcqvV_u)}~K2Ur=|$@M)$_B`mN zhk(&eW)XiKMZ?SB=nhO8leRrySs1NopOe^Gvd2yft~xo3&<;fs3NoqpjLZ-FWlNkd zxJA~5atU)Gn-d<;x|l_i$Z}*+hz00j*b<{ZdnZLcQ&*j~D;PwPu-FS-Y-we2tfAKn zjV3!cnSCoZvui%tv5wNvq3V0lm*-Cl(6t_p^3f{?Z$1#*8!}QTalVo>C|h_C8Cxh5 zM!{p%r~%Qg8{2Pj5;~I&4t4ez6{KCJ93YF;U-W#IidH|oc z5_4W_;*@@#OPtKFY1*7}^JOBBRnFv0SEK7G);N{yJ~peKBBy7HN)ad`;cYa{Pg4>u zj*>ZLaNhqlMfwFLQQ-J3oFZbuBl&R#rHxWT5p;K@&M=GHy1p!3%t@vU;71O>ep!G- z*%mqPAV(d%B1@0=M%kBF%K9|pF8CtQ<(`5QqH?72g=nK=OjUfpcn<2dpU$hnnQ}-1 zv2Paz&#AN<-8zE%UgNG?n}Xp1%ZS92UC{xbs=`sE#hk&--=3&MhLtC)i}}&d%tY(; zkfRip1|$wcK=;5b8P41=MCb$$yeyt0gZ@mE%0HlwzC_9Ta`7s2jHX)Pb zjM{5o@5|AM9(HbHC2bI>UJ;>ooAlY|%+xQnQdNwg=O?*ZU|8`;a3+0sXnSaXe|vwy z2vdWRJ+3*Hp0QJV==Bcq?&cFHelA}U9NVlJU>*MIsK!D1V3?uBFVAF%MU>{l)uGh4 z*F466kGZDOn44*Igk57+AcI~Iz!vu!soCWv8QcUO76y|eQ!r~C5sIVdnXfD@+6W$~ zsC1U*?t3i8mKta6(&ucWb1qIvDI!VhoT%ANzOc*1yOh^|t>w%UM*G-J8rjUXEsm*f zwS_fNNXiQ30Jpk^cx1x)$2~bB6gU9?+W&SEP=q%Q7oU{QiH|SZlO1OWOv!v&-Vs2PZ zEncE$h*C0>rnJ_a?bWxrDJ_5qcggivUJV@nw~r8%H8e7UrDmS3Xj?2-T3}hDh8PR< zO_$I9AV)BZOE-+zmv-JBwtZjlarkr9GBD~{RL?n# z(h!kSo`a~eKIv}=pPKCM-eRtauNPSVXb7z#!b7wX>i#T2Be)nhtIRE;&W~sIF zYf(&LaRaw{`VClv0H3F&pELG6}{#& z=G?Z+ChZDM2WGe{vzQ%wnC`vR9+K*Yvf)bcJzP|cWE3`oM4r3)I78H`BcVJL*Il0u z+-zFh6E+dJKXc8~5!lysij-tmjLY|wtL`8C?WU6|B|gO1eNQ?*w27#Mm8{0wj>=lh z>ZBS(00gZX>$bf6s#`W@C(+boCuGrN(BI`#sFQyP&e3Qi)6%_=3!>_mS9Z9R;ZXYbnnn9ETr9D8sqSUDBYBv7-_$jPmhCTp_PpGPE6HTS|F zV3~}F*&Vjq^&#og)}9oPB8KM5J*g%l_UCG^l6D2T%#2B?cE!2Ok5!R;2(p_&RjPc5 zv)fzF<%iOuxEEkq5E(Kd?J{qAO^op{gY*0>oMg=MLGZ z=9j}yd!x&P>3dF~6gcSy4TSL{B%=qF3IZ>W&PDb-c)0xG>Y7kmhEJIaCn3dc(lg}@ z>t_L5r#`-St^Jn`=C9)Q?%T! z<%DC$uOkGcH)bLP<)DWJH{VIeq1?I7dOoARyaXJll3Sd5k+ga{RcMqgX>y*kZSZsv%u( z@!Fb5AzEm>>gKs%ZUcOa}7u!X% z8lc?>o(d)@s_^T2j<5I5EJqIivQd15c!ci#{M4qP2RJsZfRNE!!3^gi^|lBZ^3-oK z2p*etSxQ#@ezuumPuZ{ncSajUf zrxwq5b!BhVQQqwPmpG!xthLJ7C`ET5?p}8gTZP~26-e);d97V_0IzLpN)opVMh(%P zJK7JM!qu(U9R&xiUq0|X@|21nn!#g%`N7tAB2TS}WS1!;DV{Eb%bd|w>#kJ0DT7Mx z51r&1EWm<)i+ORP_UJ&oS=2)LfM`!*`WKpjxFK-eI_H4XMWta-iWmp(a{l;KaKthPAj@@UFT>-yU{M?^M4v|R;r^`*GPxr z{XbE*$_?d*%+Ls?Wc|nqyJ6UCRmKXtY1j&5sqnnQ?Qf4UGJdYn4CT;l4H{%#j}a&Q zkmp^c(JxnWm4EPIenkMZfchep9)pnw6v7;EV_n<&qGkF!UDZ6Vx#df8#1SOkw)rNh z&xTGGes51X^QRP1%TpJO;H zm_VFDGCXv>+s7nowPK>|w6I)Q?>huCaAzvssLq1V6%UHdlv!9{6{6B(aNIF#K_#1s zs~2XojjC+MtB7uTqWjvuk^F2Z!y}LBo3lS&J$kzM!2HMi!aC^=Ml8y%FxAXhtD=ze z5&U>pbafeeBt4IioM5y|p_n|H*l!&vK6M!_kCXFljY6C%{A7nXS=i}CzVLqxSieOH zWkH1^Uw1-fP(7ou$X&NCB>aksibNEfu^_s6;>jJp)Hhqq#GkeeBr3vChy}53I|r$U z(Zt<$x*VQG(o>B}L>@fOx#~(SnpZ~^XRg0swhT{FJ6CNV5|%0gAR{fC45jap3MpLN zV4EW5U}w=MKn*WW*5kOHzFf`~J11gslatp7(JixH!!6M`-XD&lcUkBm>mKd2!Hyt?X zz1=y{YTDXRG4a&yx$qpRJo?j}*^5URWM0w%t>T)wX4&AoE zyf88;C?rr;uO%UH*skR(!sX-~aM_z`@@w}->E8Y}!o{<5169+Ou#sl%M43Xi&|Kvl zm0~BgFkwVA)F|!@GvXZjBJQ$UMgUVx?veP*-#K8nlD{F#gkh_zY;6I<7G`mcv*+6C zZctq=$QPV0H`22FE*`E_SHo>9==^BgU!#1k{0kVwsaFm=^`_Ztvo?c1RdUvZI?UVZsVtuQenF`zOLiQ`q z*DN$UQJVjT&!(&FmN>aaY`WdmW~|Toq0i-yJB?&u3Wh!0WfcE7`nQ}i7<3k4W77ItEqpNKPL?oXytt7wXLDK1~O#pbPSB)ln?w3-lMg%(?F8Q zErA;6J6l*_{B-dRtaih2dbE?QzPBrUrcNS!&7!5Kn(oUZ6-V9|Axx^lgwh>#3l=iI zABDe2CBL>)FCmm2sneurIS9W~R(Lp2==)@rl-=8@n+If{&BnOHAxXKTl~Q(}-GTc! zT6Dt)o~q+|+&*rlzW(t1ovmY_xC5D*))01IGToUnSIBlf0 zFjf`p#BbDR>Q+*4mC?b8i zCFiCJT^8z6ubg>}^~0zACqc>u<#OvB_@?g>U0LK&d@3k6dt-ExNN|p2iI9n=OQMCatqyKd$Gu%E$F>$lujA2P z2vENw%cQ|07f|?8Fq{>LBx~O6x#gsw9x)Y;JQk9iPr`Q=89i@C63`pXvZIpXy^<$oJ9p|M~+3oFxQGm7BtMl3#hU>YLJT|$&Y9m2v$+OCqOGU zZ?A?vR`vn3k=WUE?RjnN)HCGKCCPb|4gvMd@z`6n-kUwQ$MkQry4-frZ9zT>m*>-JDLX-T-&c*wX3KES`A_3K}{wKu)~6!1BBZvhr<_k zDu3XXfh{+8z1Oo(;a%uh4K*RjVd0aVLvcG57>N!!;N;?wLPCV3y(*ans6Mwc(;7KH ziJSuMQi4r>e<`=-Z<@SJ3-A2)B5OPg+Eq0^AZY8|R_i1^>)R_{43&V4^USDIJKy6e zIaOq=n2(U;TdgabWYa%;*X7FJDV{UA+3XAk5}pme>>{z4eE>~m^xQ_ZQaOzA zXrfW&*6v~fdI479NkdyPvJYXO+b=%J?M8EG*<@{~k6(y3?2GNL$8# zn>aKxtkTBrm6xGK&y-)#d0Z&ZwhLePnzXZP32%XsGLjl7F2jOWPx3S0_5p@)yPds!(Q8 z=R=V`=6nx}UZVYL35Ua*URAMO>VRri^3Uw$x}mPySB$r3i@eNtM`df7oHuv?cnGsV ztqj~Z=GPzZ{ycE{f#i`)`mB6M9VOD-+YKki>y}l}P@s#(Ex@tXafp|brQ2^A421|I z%z)q-v&hqU8$^krrP#8+!>UGd-(K^1FSQIlT1Ze&c#LGB_~D~0(b*e?554MGe@>VJ z7Ji0=v&h~NClPf!q1sPhRO#h6BF?xSE3I{~+-rXn%Je{$6ALwUUx^D4fNIR6&K3ZEJ*R1@QhA+I#E)6o6eM#n=#gT z_#72IB@I?pi$>T`BFHh>WdqTRm_CP3{1<)A2)BZUbJ~R5r!A$VpC@R~@dT z^{>1N;UKr;`+M({%#SP1O^O;8Mm6pOg6U;?=gs}2!gm+nBkX3Lh3H~Ix$FF35XmDyiQ z{&+_jB)26J)uG5N3L7<4Kgt6FJBRv63)3PGB^Kt8Xuj0^&h;S#j2h@?%hmnbCMV?b zqR&oSf9bGGKK3f@{+BN1%6CD^OFc}l6}x%z#+u`llaq93h0fDqF*CidiJL4c63XZkh+y~RH+nxm?zxFf5rXs7+s>)V5+4}{W{>NU< zYQ4%Ve=HLYTRsavGC1^OKOIzTgG853tpqVV8sJ$p7Vx-`{} zc=-&kktqCVbn*jczaDq&?qv*%8&06e!0YxU@))~cFE3pt4wF0IoWYCNZs-F`4Tvxo z(t$A4GxYdrB4qSSr=9cTp%1k+tYE6GBVDK)KlkaK8B1zd3)xtci85zBO?z&85(^A* z{F`mJM*+J3V77Li^o$r>%Vb%m|ckYq#@_8A4T0|c% z7w#7Y^o`cB*{Do;%!=`wof3q4iLq0%BkFpc|{$nxDEy}!~Ps2db3J`*J3UH0jI zJ5nrR>qp8zsx=mmK-OesRMoW0Xzr*awxnO4t32F^BG?gZ{pOcIE zp(_7z>s3AGyBYru?*zTWseB}K8#*yO$|Y{` zGI?lb?!!YbPZ>Z>(_gRA(*>0K(>yGiNwEu}2tM15Ba3{G6_bB1^z=NR6jU;VMiPs* zM>Q5peKMReUgnVh`btpn;i^`q$5LMIAoD>;z_-31`=HXMK*r49(sM$4pswmg3P@P# zn|{m^kZY{Sfq_EqXT)hR6aF^y_yQ2nfx2Hy|1 z*WXYj$b63eEH8kSSd#5l$@Er-?cwn)cXtH4Gzwh?nen;+h};kOy12NTxdAwE2_rNV z>Uc<6NzO;d|4VN=QiXKkz|XFJrF7n`DCE+{ zacoMyrp9+FFnU!lLNFei*2-0MF~_y&(fVj)VN*dv(dpC~cphEG`+T&#`TCnx!(phG z*-yJ^PlA~JNT)oH#1@^$&z$kOH8hKlmKyu;Unp_iv*0=C#{6Wfx}Wv!Rjj#(%pzkjFbXo@yR|_tf#o^L%C3{eVO2FtH#x&5de~7P*UUVO@up-zbY}M&; z?3gLi`|r{4BNpNF^u?!&0Do7QtazEmY$X1VHYT(Ycox%8Ol_RqyRjO29`{w$*U?^Z zFRRKE-`o7TBiDCX8$CpN*S5>X(jZ9(q$vYx{Ir$%UL^RDH_nKx32I}+w+b^2EeHh= z>J4G7cRAvlU5(Aonbp#QX*e`9U)jGn2VWPajFsC7I;sK^ljXd4tY^uDUeIsD5qO`q zbMvoTa$m$DX*EP|_K$Dv@apAHWtkWj=$GbLwBTa3(k2?Rks#i4hJ1T`6A zFwJPnc}vbtZs7FS6?`M(3Rc|vC>?i@t{O%s%<0zr{J|M*GquPtap8Sse`sdSF66`e z3}Gh7Dly(7{$|_Cit`o{Y-DQ?g3A|L$45SJ`e!4ToCI0uw(b^d>M=eY8EPuHbIvgf z*9Y5?ng*@8DSy#Y`0=vwK@@y4KUGu@@%bZ$rap|(!J`V!Bn(MMRe_yJQ%pJ!o-IA!mq=5v2BdG zsL#$Ri1UJnAo#(*gYJt93sr_N%o5)jNxQ8H>42u@i+ z1cKtN&BEV=gZ#Q5yT$Csp%na5c7>;C@Eu%jZB%I7Ze<>kRycEu|Qdj?hfQu9ylh(rlR!8cnNR3F47 zKsi;|uDI;tTQT8_`iA@y*qvPYYifU+Z4JZEG5QnU^WZv?A(Xs;xD&jqaO=-^wc9~v zX7H09@vS_#+R~^T=+Mc?VbQbINB#A^oa&@5j_7{S{l$rV-G% zSE?2nw>woo4%+ntEmAv))@e)@#M2keBk4lP?6ak2Rpk$RJB>lJ**eD(_QZrU9>~;- zSQt<~#$27w;!jEVi_bDc><>K+%M>mPo)6fwfRx?0!6SzVXAVH5@FgD1Zvw_EN>`NwK`4bN-%o?m)Je@i$9l@xp9Pd1ETj@c) z5F|d4=l|uTz>=mwa9j=J?!nW$^1$245Sij)3}qqUCS=+Dr+>aZ-x7ixHjCglCz{HF ztBu+5WAF`kL%D;wSk}ljlD_)32j3QEO|3<**>g6Jtk>>O9OszAo;V$S7leCK;SZZK zY`7`U%zr||6|}dAI|0M;Y&T&gfr1NE5PFA1!Rw7XfNH>!|9P#q%YejWyHj#9JX_Y{ z^K+H>>;sJ3;tw2{ZP`D?9q+GiO$Aa(RGg^a2O*<(1o)4)Y7&7|uS!5x0i(LvQ?wUA z!rjBq#^d9m{K67MPQ=3Cv_DA*rX(5s28yCk9vQMJ5=dueZH6L1sJMwg5$X*|1|X7* z#zq<|+;n0)vH-kBsW^FUzG60P-grz zL3G4-hR;UZU~E%kc{rdKB8d-B2OxY15#T9uKaC8$zRj8dWGmOrp%k5&*TfjhE&&L+ z_g^4H=6PhYBv9Zjp49$}j}F+Qv0!x9>lQypRdfRW7O_KeZM#F12R}BpP9#Xc05|UP z2JPloOLyy^!2e=P0qh6AL&Uo5Mbd9KA}S(cCO3FV(DNt{pSb@O0ZQWuh5 z(&wi89$F0?X`{jK>=0^rUd-l|=9aQMNOJ!gHf1mWD(%~JSbU%G(gxb1sYmcNvmPOQKy zN9KoTs$R!KMdnpt!o6la+2F0ae`r>PC#xA^U((K9?O3}zC?nxG;XTTB?Wz6M$8(?g z8T0rJk&%-tNFUilIC?rnO$8S}7hTaikr=px!z>=Q@bRPnt`OJ*I;$3)W+{bn6c~9od9BZQqBm;1di2 z4Zxoa_{FAzp3=zV7YiN)c)?(+DhjC7)Rz8Mk!OgCHd|RLE*`7_Dwho2A2mqH8H+lv zE~JzW01&&af_s0zaH12s+dxEB^sYLDYp;n7j@g{G&u$|!>Duj;=Tz*=M?S4ArazxV zEXD8(p?WBpumAg$P?7(7%Dc8dk>Z*ekq``328-v@FImNxzgb+X*Vw%`J|W{j%Zv;u z+23$~$+bU?$0Pmt6{h2EESMF&_QLIYEB$jokVhJp;n~u2?XeY66cA>-*~YPUG6GP1 zNt`4s4Q{}ytnx1+9~1Qyo42u&P_fmdGC}C=#A}y7RJ#>t*A9UJG|G^0-C+m5Qrs5h zv(?ViU39VA+(gjpd))nbkoe}xi`Lq{ZyUwW#g#-ME`ag?;xmt?Dlc>%d$hhD{Et~x z4MQ?+m4&Iy{w$fiKHL4?h8a;&F09&Zc@Wl?sT3knyY+=P`2!eIlBx|>PlBm<0l&Yy z7-dP!SOfkgC)C!=)4=q$9n`wtIwU8(U3%f5#RyM)R6a0E@h3=tD~ViULHKf6$puP9 z@md*=RO3pIVt?5aUee=kqgFu7BfHO)C`T4wYHN=8wnj3^Ja{qTIq*)`+uP1D>nk9o z^o+hZ5RUKH@&W}Kw=6)6R|X~Zdw}T!pD25$F$(V`Oj5wJ>N1!>X#bZR;Uj@1m8S-Y zLTHIl=Q-$0Mn4V7@iOuDiYLp1)iIH(2CqoY_`o6^R>K6@cfl6w8NX6kAUkv-+ zMiUj450JZx-0@DIEY7DDG@!g^Ux5ZDL*F|I7)}`<`w|GG*#Das_nKKiC?kJ0Li(?R zD+WK`4}OymiyI|LMkfdbV>Q5?ssYu;{S|=gRc|m2Su62A*t(WbQl4Fl1KcGlpKm@#o%9|4@&Zzl~2#CWCx{O&BTWU-I2VYpWbAe z^a*m#q#YT^;)fSlHvtjJinK2V{cxcxwYr*XabCi}&f4{1sg(wM&f~;yKEQam@lz<- z!zXL$AgdYD$VHXKIY4Jx7>rZQNlcgxHb)`QpO+efT6>t2l)OGc$`oUBy1Sranro=? zR~6c16d;rP(kP~F1_7+Cn)P@?hY>fBw?Y-q$Su9ia!VI7ZCrDi?-+4u38&*pMN*|JYlSWCU_8t;Lre8E(m8 zr$gA~`d%Cy;E{=3ZB5b_@GRg$2-`kn*WOS)c6aE%b(27X;qINwL>WG{?zWj6AdAs| zu(>`^WZLw>(7sqXi~tJAhRcCea+TjVrkf1aQ>DwlgY;%B*sDA~-wRJ6BO1)tcX`dV zDI5)qRk>SsyCa{$*xUINcw=F=Mi#29pfvM8K>vTS_g4W`?c4h}JPARiL?oApii(Oz zhqMK{MUai6gn)pAbT=$T6omzX3P=kI1|ibYEh;759ZL72*7}c0sC)18{%+r!@5Q+| zx?OY5PmFlRGoDeqx9zN_5&h**>6{x{qpTa*_gk-*N4`K_=ih>$Jl>VGlthQgu0-^E zf`ENtVpo4zbUanJ?6G1{!qP~Sa!{_4JJh$!WgwPQ;d!e)3tZAp1pp2-Jjnz6;w z-#n~FyLjNVB#$ZbPzyt6tGBB@jqJ+8c>BU+cR>~KH#F4#HW&0DtkMR(%4xZfI6xpm zg75I@@U+c|7upMBsWsJWYfx4R{Gk$-k&A)A^Z)1V+xQGRQA7jWH380@%L;k{Edr7-^>HyECrcB91Zch}zgWe&Iv0hVA*fWXkI%%(=lp&vyGZR+Di%$!93 z?KHR65B;ETzdneZtQM!A1A(^PNK1-d&RsIf40fRFbp<_Z@3#KRv(kPPS7XXy1x}UL zrROfCoW|~`RUrRVxe}I!Etb(@*USIM$E}BYA0^WH8qTe!Ya}fwVU=1IC~AvRJy^1Z zQ*guEaO@HpoxZHVZ~+cR1kXhd{n+%oL1{`K2c((;@nu2ZlHGf~n9cdk?$oPJJoslQ zu=Q2Ciag1XGifJBsI%OOL7QD$bUbNjcTz+%T+9S!$oR!#y>j2yioh9nc=+fiFr8=D z*nZ(^!d35C3d({Yo%9XvB z`humvRoHYp4M)gd4gbF*QG3I{*+z8{j7n=w*C-b{6eD3GUY|2g$(K z4HHQ>=5{!{c_wX#BOLbS*#7vQzZq1L$oinUc8&_w*~`yRTw%i*=3uaqQZ7Ml?FIxUM6uN6jDLhKAObYCH%j#&GtnMbqvXYy?zj(7RT* z>E-1pqI1x=we#0K{*3Ic{doK9+Qs||c83o4BEOf=(RP(C3etkIM#27?-`Yi>~7sOo_mUZM(Q7*!IRnXk+RYr4HStG z5uUhM9OSzg10eTM6$pw0oN7Ra&+Q2riusRKGixN7OVy=Sg}IP+uL7*Xl_6VeZYu@42v53e}7TR zy2a%RoZP_`UOOFbQ~kpg;ywEcz6zqox5c8?gSb3NEI@Nf@i%NvHsHH!+?mW>3)LaSd5`S zAmKFPUHD~dUr`rA*4b=4){=5F{&HB;(}7&0x|rBh3fW8~EpakP09ik_<`O8-RQl_m zl~P0l9222OW?6YScrH}J!CWSA?)&RYN;YIupE> zib#eXs*OaKY2w%0o~JHM%M=J`ck?6wt&xX@y{MRJKaFR!D;_ZJhHD)x3HVYoin92izXeD1pXZ5o90kRG{#q9R zi2xt^^u*Q$ev@AWY1VQv;|QD!JbXz}3$8C7?CfPX@L5T2fZog>)iGo2`sLx@!c8~c z#pVMWdd|n_Z-8WO+i#tEGBVk~!>tqP&04Q1bOt^LP-@!Nou{mhl**yI=nU9q$@PRA z{MCVrWhjZYG3XmJnphPG|7jRD5>*3=Xv$CpmHrn%6Jfz0Ui)H{_*{_VK<~3%xGS99gtkTOvouIW&X#b9yEa? zdF2w%X3s>XAmkamo*8Ke24746qU!=0Ld^2I zPx~+{{B}a$5CyqQMt2}QC9B;u)@b1H<=5($Qs|&@aMXZ=P9b(p5dyAtD!+NEL6!Ib zw2(>a_7;0_b-1sL$4&xky3(X6;l&cF5>EL`FOLLztoCzo zgh{6xf6aM`wgj&GQxr@}LCr>bZ^^?+pAGkbG0(as`V}(vwq}!G#|?>`=(&UBW7Eh(CbnxG&>Rj<9)nDvec@1Vzn?_X8pM~204u8pn2i;PuW%y~UkxX37Ukh;&Y=WZC< zR3W_aRHNVM0Nk4Q&g(dJtrj$vwWBuZAGe_0EOT6TX1pzZw5wvTjY7L}tXz7Oq?2_# zcT!eNJg&hn3&5#|JepaS4G`EI>4XeHa02`ahQnnnrM+PJ=X;O;kw$(3T!rr3CS>Z( zgd!96zqV3AFz>=gXaH;L4m4juG11BD2#L&7GoLxzp$q9_#NlDTpjS=@b%-dL{4?AN zxemA$!(HHgf)lm!oF_`?WODIPa9fHnz8aQcCz5toPJ!EIy<>3;W7`U>A>E3p+qxS< zAb9|)Xw($ZCQZm*I1q`@`&738fzc!%gn}m}liemdvgK={WQYxLUzAWUd>FbUJ`Dkc ztd2+P5j6F0M9fA_p?c4&E&uD<7*vHeVm8VF3!M(#O%VHn?rZAn@%HA5v!Sq;mvLMJVwyb|G=3o;Hrm7qQpgMz z5z`y*r~4}=-M}r|4&36oe$%cI!DQ3qK)0zJuiD3fd(XMASKom81&$7U?6|h;beZ-h zK0^8{k?$kOfR~0o3R54{hC_-AiKff#t;{;az*!eTd)n4Qg^a(OLwBFi`P~zZ@2}6I zOsBH@I~dfJUI@Go+_rBu#hPu6anGd zCo7Zfzg_?W8u)s&5QCabQb68>jF(H1xqrh^33`Znrg`3VNH#)g;9@Poeb&$f*mfMB zu)ug-vu*`I`F*Zy^UYC^IA;3hKzA)~KD{cN*U0orLDGj9^Xci(Hr# zc1dtCcL69mWd$ufdQ7}pt}k(8Nx49G7)C2smxzlV#6_|#EUq|BSzygyHH09)DZ25W zlz;QE`(m(exQs*HXb+bJspQE@b@o*JCPiV}?6c3IXn0okC5USe!Kq zx!VA$B)$eWJ#rRJGMoVzm^Vhu4rA118RBrGK|C7vtm@eS@yS7X=zfstTmkP!o;m*U z>&dG1FyDv)SH2mMZ{RE;22BD8v_Gj)1x~?<&d~r5;&5v4nTkD!jQgqxulokcmxP@R%@y zcBNo0<+})*wb}YZ;d87FVD$(ksriPR)c^uY0Zf@IBAHUPd$CB+uv&5kNHJ1Y5JAK; zpVV|Lni>3R*m7Z#0yEu7fTWFBJ@+ngpM_Bm;LZg!mmyWLT^C+307#dtZe6oty+Zf! zzwp)zGF-LX!xluyq{$Q(`O}z??MN+qjreFn=MjaF+Q4J&C;@PI?ngacYCwk-90^t{ zD6mDLEnUXk*OPM1!MsqR6$eU%(e* zy4ry+B|<895MR|p+JRHh?EO(MUNIsAJ(-ytP~o9fX!OH~CRIWI{z4{w$7vLW#=a0V zq)iRz{EQ~KtAO~JeZt{~03C3ygXO|U8>?zab$G8gbpN(azl}o%ga|k5_N!BeLVlXx zm18Uic-RbI6_|w!#fSPKm(DScl6K3GfR4{l^_Z^bH72ti3qB`5y~)81EVp`3grIjL z4Lw7-xVe)V^xdX%?tpL+1*%9J3UDC|D}2jQxc`AsLli@m9tKK=_m9%mD>NZvt$;M% zM2i9AXvNShSt~E&6g1^#=)G&&Z7;Zw#3<5K;hf>C|$re`LEE#$x`?r?gpeE9d^gpHv$`NJJ7Xc?9&D(kraDh)#{Oi8A z#KL|{K=m}uDCII7#tb$gquM6lh7-3YQ7|<#RLrW+{ppd*; z3#kA{{>L@6oA5H&hHh(Ehp2H#B9F7K{ZVXNuO8q32MCqseWWf9g-zNngO1>tXAg~! zm>~9CJ4B7Y>*qiyWi^Tx`kbJN+qCk6S*bU@ghpT2S2@cSfCf(8Jo#xP<}7daz;5^V z?H7IL0EdwI0VzSAE5PeEs)_39c&O)UCJvJ}tl?PDV#51%-HZQOh^y7)LvkqBG13Ne zRQ54O5=wun)Ce6+h|45-E^zKY&Iw3Q5kqRb%P&9hKv3a zGkck?gV>+(JndtSIG1jiP9eQ@px>zc##e+z0?vM1yLn0(Q@2@H?$XfO%3`fE`%-osE@yRhpBM) zvUGnrZnSuN&F(d2)N1U2_Sk)Ps8i3>DZ00wBc!8S%LC3Dy`UXxD9?AFWE_m9&bU1KZ_N5XTu>+Z#eJ6RFy%>?*U0fW&wokN^Anve zR8iZ+z^X0i=!-hfjks0#b9DEkakj+mFVBjCZ`!v`wWb>SgH5kqqGCD`k`KPkbJ-3NI?w~8Hyp;T2X5xRLg7}EMFbgq}s6voM& z6-5-9(NeFVoF&@(TfJL6YS0{oJ0_(-=s*!YD#FI!UzKby=e8@R-m_eQOk4)?I*WX3 zxTVb~xb1_Mdn(X!FlBvOhI$sggzkkC79ie{jpm)yC}{*$*4bL7jWnbZpcyK48!{|K zC-Q6{eIo<;lMr>FHRdpsOV|#t!($jjLlVb(VYs0Tncn*h_Nj-ut-!<%Wg7Py##1Tdos6B3vo3^lcB!Nk66{D8N~_ zdo>b(VD&IKQWFkMYKHRwtDY$UqKxI#>tHQ$SBQCHle33HXA`a{pk=#8RWb8V5Z?vo zug-i`x+5h!-s;WBpW0_}K+~DwKl@3B)0ZbIPjkh;{4W6!u;DvEtzj`?1x{pP;a##Y zl=+ZDjS=xZuQe`*V{3E*IFd2~Ji|lKUvT;iMGQr>sK4Yk#as8#MV`K!;q;kaLEDXYT$4a_8-m_G$))a&dqcI9MAS?$CL&Mh%vNQ?siWFOeHg;uG<~eV~_@5IUht- zCiZjh;=1ut%mz;N@V5ww#Xcyud`mlHT>`Z^X0=<{{p&4YaaLx+mYgD`pXCTX-mEGA zH3|ChggQmO08BRURG~7Cf+&N3l9W`ENcaLXNtYMKa~h#en=e(L7c>_ZW&8c23ow>` zth5__h-Z92VAixOs)Oq3v?Vu7EE>K{z*3z|IV0c#*H5(VjdcoRh=j*NYSdbxZBinI zS?T?jU7Roj$r}~60;_G^9krne1>KmknA-|#=o)?bbB(OXuyIh{5Dv5<)8k>-RYO{u zN$MxPY^3U%nRcd@fO2jM<-90y95RHdi%*ZxynvflSs$;&VYY3+mHSYALbT@X*e^~H zcxxVHxRNTuODKK7;?*aE`(v-rx}`J(VXxu{bqX=~SROwot+OtX%>V>n2d2+&X5fGz zqR<%ls+0U#HR+SuMJSIQF(+MKoGcg*kl&Xb%Xn8Ri&D}RKjmh2wZ#r_;fFU~vRI-4 zp(xl*l|*c~UE{UumjOhdxGf4YCylB)LvWtMc~n-188{!y@N?RW%*c5CBKNK{=^Ur! zIi=^L_>m;;|I%OM4^rr`GZcRIBku-CtLnwXI7sN&i!8Ud%H5S*%)_O0LrI|3>{|$b zUIh*#S}TXE2;0%KSQ=#(TS=wM@BwPm?fRtoomD;}1!#{2hn{K|X^hjY#oOXfx;ZYLbJXGnxzT_cYw+C2a%C!YL)DLQWK3 zx8e3Mf7)>ajNR(%OToIN6OKP#2S+~Nag-pp(dVW_or`A(%fd6D-eQB`4U%XprqjH7 zbCaI}|NRyW7;IK7)GcO0kpjlrSa~}4c8yAB1j9H{UCf6$JYfS=l^IifWURdZg#3Y1 z#MRlQi0OE3FfRQ^g_>_VblwK=HD?(j;Rr)7qiK}IHS-ogW(9wmlU;J{XsfN#djH*4 z3)o19O%2a6!Y`_HO7|kyg7mz0Q6F6jiT7;if1JV>7HqmgAskJ;j!)O*h*6ZAKFf10&KM0rF@?iNcgd%dT z#~3UjQ5X}l>?xEw$^w-+&6TH$;yS2q$lvw$x|-iqn;)~b=(+`_O&sv zd71?fb9e!X|Asw!ie@2bC)O_CgDxe7rTUH5@vQ|ruetgMZ9eQc!RY0^GL9Km?Ds#~ zD1MRVZ`(g3PubDq(&YSC^kL%V@lmD|+a(5`oDKc7gGI>bipkE;kO7LTT#@r-Q5I*g z1a5#XY4s-v)A5}%!4NPT4gqUR$Pf@-QC^LVu>~}Ku0{niT2X=_)hI*T@f7|+rLF$< zt(PnVzM$Z<4eR)^EDDWh*>$y?yE!hCn?1X>`tlzwA9(_Q=(>W)>y@}2+o_8Fx-1Kl zJ`UBPSaespwhaLRKpf>jR%lxmZCh1b;s?7Z<1qB?1+z9Jeu980IgCRk&Y5BH&Gohg ztQm^&cc;3)G?Nl(^M&Tak~Kn@kw%*%+!hrhwB2?WmF^i+?*L{GU3uz9w>4K&eF(K@ zYR@^9ar~oir{NS??dO)_DZlR>KtOuF-id-LmTto(HY(#o4~QV6AxNC3%8^1jKNngS zzUW5&ioL1+VOYUxvDlgremx4n4<^v{8=m#_b5sriDW35&CJ7F0*9IH6+#wrz^m8h~oy zy`5obnalLK0Ex)QF(I)0`_M>h5+bb`jX`|lM=ms~88{rQDL|M3h|Ut^&gxBHiK7%} z8x)tCMGKi2&Q_O+Y{PjptxA$UnKdC7whA3)u3^wtnNSr}3vK5iGf{Hw-^J+o*%+h(9`vEUTm1HI3gv8bS|in$iI(0bb&4c9pPZ4Euc z*cV0TCk$;@4v8-Op{85Aj(2glD&t-5*(o4Ygk0Qv{| zQQjrdX!uQ)NLwG|ZLZ!KFQLJB{gkb@LH@QR_d<4sp*>2s0Sve2GPuo1oWC&_+^CZ6 zWLB>vvSt-N@cRQ_=Bk3`-+CLJ_{32OR!vQeo_6f0M)uR7-&5$I`)J4I=kRq7_pC2t zd8uDvQ2{ZDojbh-Ka|j#@H3vCVleSF!3vA@ zN7AYwOw7e*=u&uX^z;5{HsND25RrU?vzc&b`k`e)M{W~7vHVj1AMMmThttnMEB-aH zR?F`+xGJ0(^~pO*vFUY1BOe7EN*jL58E=)op(D=ku=iy|CbL?Q^y86e;G{`_@e;Gt z(cl(eK_Qx(ijvc%o~DP|Cci-g)(mPV%)w5qE@TI&rj_4>?%$`7VOc$56f_`9%ILEv zQ)$m^&46Ixxya9(^MI`8X+{~4XQ_UpYgWY6GNtV>JBw+x-xf;%mSMzyOq&BSj3tENUI^-IP!8{KZs)trd$bV(|D*J`lDex{xIYC~}!g5RkPFy@~bv$p>u> z)m-70XKEmxUPS4!{w%;TpA9x~N>S2IU>@revZ}%%NJ~e9 zG)Zn}Dm~7r`({95B3O*}v5_QI?j){g>cvg*zCz{R9>6tanFn!*e|Gp|q0`v4Ooo5v zVHUnbeffh*b^ObngXvX-j8+$`nC2v@oLE#MS>^3kE2v3rQEn_uiM1FrNaOn}DpdGX zvy=YuAOHH^uM#^$-@hTjW+7KUlS7E9*N!UTQSMX((;vnTMKRX~Q;xWoX6M>E<>DR+ zNJ#dry>JJmjI$40)lr<{@nLVHK~0fWsf`N(0dz%vri7Qz?`>)s67+BmgyjR zN^0Pjr)rg;4S=J`ONqwP$8$qCu#QUR_qNxmrm?Q8wMc_c+j3@Tm%7(cf=+y-(pknY zCK$yoOZ`7Y8Ll2rzV>{xJae%wbiI;P&lHC)+1(m##uZg^(cff&{ex+<^_j(aW~3@L(6{%}`EE2n+T*O2O<#dzbH+x3Iq@-T#wUY0&Sc zH)y-KhEk8?-2{ZZP;|%S$#-2}v(ZDYoF}(mWGIx<-+2j8f6>@l+n)`_qhz#V(E|*m zV1lR2MRs<6m5Vh?5KHHfbhPAxU`jz|02J1wO(A9my1DSrEC>u&4sn~uYXo5Q%FJUh zcY*IPGxI*_)14;B^pf)GGEgo{5kwK6jNtHGGSe{LHfO%`2h;}%uNa#$vma_bjpX~B zZK){ook%~-@|e&WF40_=Zh2V~1A0jUef~R%=i2W7zq|oPcffyA zyl;b9+VQRP=$&k_Ts81$9dodvuhk;j3t`vWmrl>B-v%)% z^6<3N!#;Gji-_vabJ)bXPhXn|=lvTr-`TzS zQ`}EFbmT!AP5uk0IxQi6nW>xWtO?`9(TqeD#5YTJK$v6?+fLg0Dkx>Qf6q79^D=UY zi=|PG39hENG5ymPs;dqt?oTH^UCOXR%OUMr2sxw`Sh`pz`?bpc3V&XHQZ$^tkJgP` zG4$H{oc)(f@4If}yv-fn3>Df%XN;sCg?UEtr_XW?9dg=353q*R{690!xN_7_pbT4X z7EiPb{kl2r-kn)DiQ-|*3oLT;xfEWJ&6-ezUR&3rbS@hHLnTqlcOkha6iPZGFV>em zDMBQA%l3mT&B=Z9^{8Un<*+))y`E}2NR-Icq&gk120Jj+<{hf-Ws+`xx3R;^ z$G4ruPUC>q>C;0_XCcimXwP~WkZm=ICbexh^vYJGAB&-WchQp=M(lUNYq>v&nmYDx@I|*ht6p1bbs)-=Z9}6;wIT4!-TW=xr8oZaFZn-?`T98D<^E$HZC#U# z*X5@lP6>W7DSo7<$~n`vjB3z`8GBY&NKwaq4f);^OOs$(`opro(_iYta)6g$mzt%# zLcm`0y~caZYP~BkXKC2x$@|YKb00uEtOK|E3&Wva?^$&OC2WNN;76CJe6+0GBB?ax z#7+r1K_2UkgVDD-hrW2H0p8j!aHeegeR^&VWs|Bs88`z8RMm!Zugy1pN~qA@=W2P* zau?EDvng+SPCtzBorXsu2c_*G`Z831DLHzN>LiOr?BHyiVuW)qptH`?P)O!YFLqu^ z00vRp=g@914>LY;QNEvXySi=bFK6CR&Yy>-6*bcnxAe_Vyf(soMfdwDEDa&cvrk$BaY`#m#g z)?F@bc$2HD42ol3X10>zoS@udWSjZT&F>~noYalgT@Flfa#=FP2Y2jcz*RIl+ZJ5s;B>2*$uu^|4G)%*PKGXW!UXJ3z{*1`O2D-{+&t!?LA6A z+7LZ|;C)Znff#5Ss>3L4PR=s^_o^RQihQm}$3FV_aO<5M4iZ5D(_knb`m;*}adqQf zVFjEs?m1UO5{X}1d~+<=Nb~?LQjI{JwK9`Zy|uLAj2hxm?&fQ8U#apEp&%A)mOE=iX*5CAZcy zecT8fmWmcbt5{=Jt}6Y;atVp+js;~G6!D7deDXX`=Q>v;L8WrAgZY*fIrpKZ5OQ2| zMf3qWL8Gf;Fmv>L!#?j975@K31AAZqz$Rbf<-Je(?$UHx=L)GVJ=(!1QVoDg+@53F zm|fjWum}~AYMeUHI@mtY^C@M3`c^>TPdTg%305vrb+seIzura!kp7c8dDRK zoyv7NRH#U`Wu?((_X`|zp))l0@Md8f;=xGIyu4Gl7e@2A%yS-A~g48gkjOV%P;`{T}J zaTLdFSCyNY-p+4wLq4%k%C2x?3IX<^&8(XV z*mFg$X3tg3MY_yB=f@aQ%x(XSVu_}mQ(_n=r8HevT9wK2L*MQ){-6R4Fo{)bUHLwWL?tSKu*pImFN_LaQ&(4tC|fJJ!|lW z9N$3N{KQ0mXtq5#`$x>~Q4{gwGq`2r**9zN6Y&xm)5~8>NblHcar>ZJ|Ck6rzl(;w zdNc|ar4ic}OZIGEJbi<@=<$WUyK!Y#cPL$qA#u_Yz*Sl(>K-q98F0Re>z5PJ3+Mmk zL_qdku}?)G$XSfv4$rDPc~ki?W5nNL?(Syjkwcrw4oB^I<4w<}zWAfw&?2@3!te|t zV1w>xl_#hDXg0Hf4pg??SfrvXi+4!wF{}lioWJyZg9>2c>;`c?=M;*7cdYn&SNn*| zeST1eG`;I4<-_WUEcRDukQkQc(-MfiE;Y30Bb!;O{;RW#ibSsq4gR5HI_)iU4R3t5 z?K_o69NuNc1ymzn>w>=BROAQbj1~joYq&;J@hLkQ*$XBDEJfF0P{{=dCIsu8}0Q z3YaeLKN8)r9d9aYN?SaDoBAmSH)6uqllEWV$YT-T26F$VvuCP``FjbpQ>nqMhNa$$K zn{(qO{qn!Da2O9V!D1F2pwGqscqq_mT+%V+ZVS2WqaE1CEO*f|@DG$DrU$K?4$x{j zYQB)JU$mcd02n{x;|7I0kH!v@CA_i6@aZ5_!_I7!Dz^TohC=d1`X-bPfZY8Ey*c$5 zH`PQI(Ve>GXheYXj-nIKb`!PnU9n4QS|wCcAQe2NS`at$PN_l)YphC8QvO_Jj#kqB~LEXlM|IS2RtUTuNTU<hekuB%X7!4SQU6g)_cnwna7r4Caa^vd%v(FB zD%kOLd3mKLww9`rec0TRp2v=RVjS2UYK0E+xt)o9+(yMe=Lr0Pu?WwWSdz*88{bRb z*nTm;&P-a2xx(iuhNL>PVLP03ln51Ac5lz=C`QPX%S3#ACG5wtJi|y49oEr#TD&~i;6{YS>nfg0q}g0)FEb0Ur< zz)_zx_f0sKA$?YsWCG?mXsmpBCgC%dHC*kT>xsF4B}*d6%Oi>y&TdkJT77p%e^n5L z9p4tUK1zV&hfCcs=&qEnQQ}v@I#aY%ex>%Wo$lB(l$ueauJ!0x8k-iBH~V2cr#wgkGTbJeZPpm> z&~~-yj;_Zew4g}ZtY|=OpFx^qGTM~rVAA?=a6;8~(G)25spwpRbifJH5bpBCgrk`m zdS;LTH#AX~bos4m=j@qYoDu{(b&J^iMLT%0C(jWy=x34N2`xJE1m;oHB?p_(ne~kK zj`xEiU$9y8)pm)uA!Ux?{VmMj_S|o_ma>u#Pp*)zHc4TbD5HVY%6+d`|gT_R`hXF zcBuy@))xp`h-Q0Aer5;shGul35%mt!c3>`!`^JgrcDbW!|3z{&66(_(m5+a(RMm0l zgr<_ju8E8s#x5yesl;8PsW_QX4f-wVMw!WEt zvZ)^<-XEgqoPe8GJU#fD-}s>=mN^l7D}Bj zFwC_9qMQT2JNQ@Tin_>x~V{)R-)d&g{!& zo@CAQa3$8))Yr66dX}racF$A0S!(votl%mp_`HaF67T0Dw?)aXiIA>p;+>k=mhBRq z%xx00t5?HQn@`+fPFc{jND{6w2HM7+23u87Hq-O>13#6Y*i(2yYj3Jo-m5H1*IV>- z)Fi5VR=!xZa27t+i`QqIK}SnnKj%ZvGy7z@>wEJ|Gu`AM-U;utBd1XR2H41mvd3w(RSG%4%;?jz81;}H?Oq@aKWRTqNH+s2Cy+mlr z#yED#CzEoBFjp~a9p#a6aIuluVj!O|GaN$;v)0i6c8P{7RL!D94X|_{5@x28PZZ0} z=Ws9R=g#wF8`8Q zR5ZVExz}T8x;mRzy1*l`Zz`F$i+&y}He`hGB$$!cKE_nv5ha0R(#av`-bjtxD{zd7ti1CY^f(9c{Pmax^YFV5c$92(Dji)vaODx&5R5 zT=4N_ZFhpt&gn9lE=J)eR}=m&<#%9@eq>?JkX7v}65T+qZ>M@)Fa_K~a55IcEu zUgy(n|D?-|$bo%Tc^=2ucBnsMu=z1!>Xz2D=)Lh5&K&t&>LsQIK19)2ci&QCu8eVF zF$eR5tIA8mh6Q`lL#`_Hhg8V*I25p|!~|HR-7|nvin;+h1%3zf?vvhBUylsLH4pC_ zdkXUj#UO_zuX5DYicg&qUX^&8Ufs#@$6q{)7yfpn;>BTaA7WE>qk{u)>Xe~R#jpqQ z`5Q9*e)S-FSx#cSpeP9-3x^HEcU}fCXa{p&#C?~2uXnVz{Alb5mQgzFc3`g%D$Sf* z68$85H*`wUD4Fy6KXxqsR}9(6_kQ?w6Diu|t`{(0a&z+Lm+x!_Pg_Yu z!@5Vt(}N#8Vr*42G}pDge7M&8;CDG|DNRmGPZiNCoa6ENlwa4L+#T^z zak_@dotMdj*u8j;{g4TTE@#gt&;%MJ+CF&D2ZCY=_H2k^M|5l{r$C&zV-_VHMeD3r zhoQyqYT)#bR!4m~-Rk%0CH|{pRewHi$UxBLz435Id{jrO;O>>0dekkPxL2TG8bme8I&egEPg#f&^q+@ zwn5&gRjr0If2a6X$x6e*<~vy*L8V=(dQ3@1X2Uv^m|;UpUzF&MDkz^lHq; zwCf6a1EVkT-$wXcFW=#LKH{}LEVl9vO+-L_hw1W2w_(`A(M-I{-Oo$`N-_k`H)Z<$ zteCqW6$(ZDzspG&9gW;}blD6GDWwjE0(*=)P=L8KH7mRMZoBcn^?A3xi|6^~Xzq)~ zRaFMLO#@+d9w(b!*~y;p5VZDx+&1vkzl%9N#8gs`^NBEt2?jfKT4LJtY4WKeWY2g# z0#*b2R3xN0y2O#Iw_mtJ!{m0F(w1-|WLq=U#h-m?OPXIbZOtu@NNB2MJw?;kdSs$s zAkakFe0q^I;P}CqiCr5XBF8X}SI0VLywzuyeOJzO4^_<#<3;p$deWA-(L@E7ji(7O zTtXjlE3{P<8iJM@PPFOX4SL$3zA?fb#;J0~lX&>Y6EB&ICf-K=F6*W$t>7RiH{8ZwQ#2Y|*C7|aVlnkf*`^GOrb^d81 zn>gpGr_CQT!)}PRWOUROFcbX=t1>aPkVxjLVJ&>oot_>)B8r^X*dDSz>7G*yxlqwd zpm={rgH0jXPVv|3JV~yNgNMZ8XPXjlkBn8*yn@B3EVHOhi85|=N1 zAx|(tT=RCYJ+=_F3VWnBr*4Lf9JSqB!1dKuo-+2*`p3g7dOqlLN&UvByt>5JP2_F- z_38{JRaHkQ5WECOXI~djx2IZ5d;?-M$NMF88(xO&gVK6e8^KD}T(I#DS>Ztn@yA@Z zCv4LAvkIDox6TMu<&TLVihrBDJ+z@jt@xLTZ#A|cRiuzcw(?$mx*SmenGgF&jjbVd z6|5hiQgl0@6CsFbvar9^R}QNCb=XjG(N2NPkPGGDJ6qM&*Z1=-=p=qrzr>0qY9OBz z?owkdj~gJaaXV<1?y01CkxcoMHr*kUt>`Uwy=E^T>+<`9UF|Y32-n-+EBIPi&JeU8 z^B=a}OCy=;<0ZRNU`f_%t#*HP&;jX6)u3h{{1F@ z1CzM0d&w3l5c8f~8VXW@0j#ketk~uAO-Qtt9Syeo&KZ=X(71!Fu!1Gz`0T51^6dW@ z%G@E~llnhC5JofeY3wK4Pw;H{L_`?*kdno?+)3Hn?6|DA{byBGiewggQzh>$3B8C^ilKNu$E(;Mb$<}>mc@h-;x>rWd% z9Rp~J7g(_q>rO}k`q^UCH;vg0=%sWMX4>zQ80j@Qkri$WV#A7BYp)Nxf5le?zjudZ zUDVV2i%KL39$%9jY!nyCiuIFQjJM_>9)gJL!Y#BZt&w!ozH*r$wP#HccVf;%1wnS- zXCy5Rz>XyS=Tj33NGv1DU?zL4Dh6wYi=ctr?I0LyOua8P_6<|*y1MflNpr;8V~HaA z1$4WGvDlR(mUnFf*L=O+lDPauH;0~V`#z4U!{YnV^THTCmyao7+2htOjw7<)@atcIweVa`sxBeovmuhj;*rUfce}a~mV2-%X zO;YHL)N=kc7wArHS?58AY)rX;Fvg$EFN(r@_J{f27&|29V2J9U>v#c2=!Ab9FRH-Z zL7^l?{-&A*i@zm%Xc(`C9Ol?2MB5~eDAOx&|M}^lTjIVN`#O%%+%t8*^a{Of+O@fd z$VPfpQn`|fjGQ1S7p6<^u)I8xZ=$k8+nc5S@$Z9u!^7K3jiM(~f>$UpnwLl}o9~Y_ zIg{=3*p1yrd&1URW{0KD`wn-{|M3rV@rE=A^pLEKJ9ry=wf7_?H*g`3m+57J&9W!l zHETQZ5W@ah;*zno2(8c& zfw?PJEN6NT_IY8a#SvB6pae3$<-Ew1W*L=7+S~bXfBt(<{E#3L<-VF>eE&3W+m|k) zzXzpk9rOCQ^`3!}^LWm?{dS1tE^j;JFdeyob8_X{%!{ji%%lpOzt>-P&D%$&G?r)) zM_iH;Yo$b9PY|2U$&ie)QDpV5tnCqxeTe^=QhN695)Na=K(Qkak^5uE%Z{1M`S0_S zc79@9DnqO>vy3D5uMnx9y&oi?Q;~O{JgDiLOxB}EOOQl}jfG+{f$fO@FkvqB>I`%7 z90ZlW42~Z&@fitzK6#&@8-A{UxKk&Nm>NY)4q73C6}XV)ZOK19i>!*0CD~wfOwEVR zza8Mc{{vbPf1Uks$2q#`5s&h@fH=A+g8cP{g0VS|bXP(*TCnQX{m4Q2>g;U`vc0Bz zPGNexUvr2lh;HOH#twO!}diqjx%**at2q3cjx zks79K(FW5Bn5NVv-nG*lgqH5HJfg+zIXHP`EEt5 zC77+`5p|q4WL>oU`v$_~hD2rMlHp!#!#oiLMb`FVn zG)&qPm@8O^C0On^-$rd3Wa9F%iL62C1mU+u>BIE(O;Qy45Q(`&)uhW|oIC{Sd4KyG zHA6M4@|=VQ8Da-9Q+)X$RG|tp@C+mb+d{kpc~5AcJb7@}PB9Tt=RgJ7wGv(4-y8Qu zdrtIDDJzqU>RNmpVNK72@Xf>HXZPl>6lXXx6?({HxhyqRT)DBdYBO&Uz1oy)W#-T1 z4ZQczm8;u`>gFR{%Q&Q$>m{-S41GUjap*?Ba8)6~MZ+hr&c_qnOk&|+C!92$jVCi; zCO5FyhEFBIo85Ku4V*`Yht0D@t{pwsS*m;T*PC65y2uC`>>i!M%Vwu{EP;tGT(3nJ|^IGYwKFx_+-Yd_eyN_7kp5?bkt$ z&R5o&=CEqJ;3JqB<5tIE(vXW6)T?syn7b$P`C><#Up&F2bc7?2vVg{PR)d7_7CYvQ z5O0zQrSa~3w&RWb{gAJ}uJ}&|Xxfk=5Gb7<%a}CO?(iXmq{z`tyAjz^f682%>B;mm zbLZZlvkx23RpvuF8;X^(PONbhU##T#d)v7N^E0`(H#eD47@@wRkKEzb!lyz@RFO-8 z^Wo-qjde`jK&;oAW0o21o?K~u^VWmQX{x6E$(<0#JpHaNO*U0!A@H2!&5}NqM+UxNHZ|UcM`NGK^s7kx@T%H)RKxj|i4pwyF?t z^ws|2nm5FtZGtEKB&~wPi=)5G3{P^*&-P8$6I%Nwxd|p6F$E_oJ%zWme>{RMe;v?? zzRY%NlH%9=*GhD0?m0dy`hG@j^uDAxi167pkma!cG7g8!R*W+^)YYmdW+If+6${{W|t1y zuO16rC5oziT(F_sH`Da}clF^|;%ypasF34Ell0=3OR2Y!JBU@C5~DjWLB?g}MTaq$ ze@e^Jo2XB{iz{k+F(*@I;-(n?Y|UEoC(W*$$Q@ znnkAW-A5y6_!Py3MV*3tWygCScYJxvB&hqCimTeTSnSx!vjhx6AcoPuSnJ4NNe&PF zU6p8J^HHc{t=xytsS%r&@}*v^4SRg|lU+8Kswj&Je|iG0P6TR-OxT3Xsoze9uY&5`%6?4Gbsz4cS41%s zSC+E(xul0m3Ot|lvIN1g9idPa@sX)H+B+FS>Y;v&^W02zel}ILgkmPiW7&*a39F(S zCN~|cZf@ShFY`Za-j!8Q6(}vPM%^aG4%S!n?OR6j0Z~sr@T#a9NLL=)Kg#HwnuzUziglK%hi}x{c(Ni8 zJ=fhg79SZ2RwT{y+M#55D>O#eQv%BJ$YFMUiw22pN=wTVt;8WL1G4NK=GI{K<-&7i^8&zb}#HWt-L3F9o(Qm1PA^ ziR_=nMG7*48OUEi$95hKq|ZOHP;gqt*QEE^$k_8{Z-v_K>vh;(zv`t3daQHsFgj>~ z>?GPm>A9zM(eJgW81+sUZmNC3ZI?XW_5XySNxx==nrd#C7wgs!E;9>ua_usFr5;#p z#qIter>a+WxxH5WQI$|Y@u6Li{q^N&wP7h(WQS3)g*Zf#+PelmbEKClb;cyI%9LaM z=tTW+bwS+A$({w0j0-N&QcyBQE-o{fWUEt$3T2UIgX($js1bQbvE_1J3vf)zKk2GX*y~?n!btddL<4Yg-T; zG$6tB==4%<+47{FTXj)S?&_H932Xs`+!O4w^q`>iJj3}8k!IQ-%jOfq2>I6~8XFj@ zD9>hvDl~`Gz32u2KMML25du1hxOxIXkzIZvW^FHy=C(|^<**>aIx&gYKgsK?2Bv?I zF){DF{QIqIrwT{WL+29T2|2&4#q>Jtj`VZ(g%GR-IU%;gv%9+`{x=lAOGg=NzS&uU zTg_71@K>;1(NU+oRkI5%)Q|LQqjmii42L+>2vY*T$Kep`VdFy6k!P>xS6b=2oeaAp zr4t*Sm;ix|sHj8Li1VL#+-Z7on01j}i~3kM%gNmV8apCU*5=#y42 zHDgNSQuz(2&;O*ZtWl4r);(2ECuUc+yWzgi`BDZLJENErl_OIf$>;g~hQ@EmY5Z?v zHN-y(4lIstKdu@E6}gjBi#ndZ^1W7hIs&z`GU!{!n5xi8`qR<{Tmr?#q!WH_|bP?1k!?l9X>Xdhr(E@w& zj%z%im^9~7MNug~poZ-U@g)B6hR*IJX}w;FGW2~5acj4mpeh&p_%jm9Wn#=6*aQp_ zbP-}AsjISgkAPw#jfIi!fu&#n9P(-F(mr-Jt!l#LmnMDk{h3^`wah_=e@%FvvYZAI zC9PNE-6xMxFvHCnejhR(;>`+^LSSDHk_4Z25<@1Z;2Fsxd+g(Rm_`XD{D|F?mT~p4qJ3yv~6WGPVw-iT)7Cfa8 zZbNQ1d*XJ4C!a=J-i~(yvxpCO&pP~50qDtSuAzksKv1e)<9!yY>)-Xle zBjh{VR|Y=|b7e5-+4umymrc9XfM6|7L@(;+NGv-#9-iK@DM~zc_b9M2r76d8Yvof> zGo?Zr@>}E#j)e&dzVVk6aap$-oTM>m;8o9lBat2B6u)?)bA zTyPSlG?Y(YW(mHT;+Xf7T_!41|8DUEu9u;gvq6${gwUTnrP7O$__FRTeFGGm2ay&t zy_{JKgX_4(J{~GK)JeV>#5usMcbrc)mD!N3|M)S3_JAB|#V#81X#*7KRu2!_8n1L# zo4zE-NmpBBL7a?*OjFG{^V)}tDfcT9g$}7$e_4%a6*#gXdhiA*?->_CUeNFb$^}F*0`V~Jj?WxvE zEnCNki_QelWx%~6&5v%*L>v`18A>{7&avF5P}?)fVPzUC7-$+4mF#%)gC%Rio5FRx^agnM@cB8 z&YOhB2lJd+fR#98wjQ$4yL>?X-byldIZ?|BPj{M?XAMu^ZI$y|J471`Q{;l7R$?;> z9`~^Jr;;)SMR9xFWvx55GDGk(i=Rdun{L6A*+T^mJ=ZMtfH0*shbeG0z3?Y0nuybC zs4K|=@_|nWU>sP4ZBrXQlZ2qJZ9OI7Lo+igJr!~X?HY$+5q5Fya@YK7mzZRV#TmV75IXIhjNy~?XzSXr-Lz^$t$FDSia`}n<3S?^hSx+j)# z0Rwl)Y338}${SoP4^X*s;+*bP;MciNiQC07jFHiV;Dt-W&0Iy6|Jx$eHuDaL3-p2c zuW9>W3$XYldTzR0xdnJ-(0L4opnp(8pkw2>8g}nmPLZqXr{8Phu}dTI7umP`O7+8S zW9f(APb5!fmggBwu>=I~lp1|Y{P;ah-~RFDNA;+`gZ}t6ih??9TNyiX!-=B=YN>Xd zUgRcjkDPX%e6+|5^KDD+(hpEXvB{g%FN)AGg`&;*t3SB0^NJEqBvqJuzYIc0Ap?K$ zSoVjoQ!sqAl{8Me$Sx^G|KkIOIRUkaKG2q+@C47fVrK+U6Nkh5hqu2BUULrY84544 zP4gqvqU$b5E7DI#O9aK?_?4uj-B{T%437q4vkK^}L8wD<5ra#RxfG{0H*2(2oR3KX z5VBq2*e4AeOECW{!wqR>`=U%-LRB5S#GUNZfXAiizq`jkj@C5Q;dzO=wBYOHCFoSh z4Q9DnLVn;P^=y+AF-B-JtT7`SY_929y_y~6E7F=Y)-C)Rvzr>8Ys{ zrM&MbBG8Siq5dh!#iekvkMWRz8O|wab1Y_T`lE&tc*pgoRa1>cbe8G$^9S0jvEy+* z=Zb1uBBlkGFV$7qAjd*d^svwz%PaH=dn|4NVJv)v%k+PmDdU_KE3XFWx5IO~rqTRn zXZa|{pplKNg$;swx5l^~?#?ZoO0Yhi!Wx=}>qqJn>L1SoH0@{+@5AYmvHrh)Z6|7v zVd2Z0tECsFKQ|cWRou!iI8!#`;%C{=D{kz#v~az^|F#cJ(e15mLkCU1qay6IlaSVQ z*Ea_JHE13=o{*RK@hCPxdHeWHdxOKir%S7N)$Hf3y_AC5kJUf@OpX{vReQZ48yx7% zaD`}R)_&C8w^ut8R)xJ~Z;%Od&29Brt%LzHUoHRt3(UU1*-2|?4WOz!ETn^g;pL7# KR__}6`+opC#zdX~ diff --git a/apps/wristlight/screenshot_red.png b/apps/wristlight/screenshot_red.png index 0bbcd3e3681bb2c83afba7e7781a3c9587a0f91a..06ac7a190a39202403bcd9b1bd35a24805e405b0 100644 GIT binary patch delta 118 zcmaF#nP~x|VrPJ#J1>_M7Xt$WucwDg5Rl#g!Ys@{GIr+A+=+?`Jj?+;A+G-!7$hHY znoqQouvYVQaSX}0_x2zoFHqH?1>gO1`OFo7OeE0YZE9=4!1$ACc^*jA)78&qol`;+ E0NM2%-~a#s literal 47586 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 KR__}6`+opC#zdX~ From 42b3e9597dc20d994c0d3fae3519b9759f4d7a96 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:24:57 +0200 Subject: [PATCH 048/121] Update metadata.json --- apps/pongclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index dbd044517..f68246b35 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -4,6 +4,7 @@ "icon": "pongclock.png", "version":"0.01", "description": "A Pong playing clock", + "type": "clock", "tags": "", "allow_emulator":true, "supports": ["BANGLEJS", "BANGLEJS2"], From 8d588d8220a292155e8b99cf05f9aae93e7cd3af Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:25:35 +0200 Subject: [PATCH 049/121] Update ChangeLog --- apps/pongclock/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/pongclock/ChangeLog b/apps/pongclock/ChangeLog index 7b83706bf..9b83b345f 100644 --- a/apps/pongclock/ChangeLog +++ b/apps/pongclock/ChangeLog @@ -1 +1,2 @@ 0.01: First release +0.02: added missing type i metadata From f72148eea96a43bd05d761e33dcf4382cd31a1e5 Mon Sep 17 00:00:00 2001 From: pidajo <99899574+pidajo@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:25:55 +0200 Subject: [PATCH 050/121] Update metadata.json --- apps/pongclock/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/pongclock/metadata.json b/apps/pongclock/metadata.json index f68246b35..c714e9a10 100644 --- a/apps/pongclock/metadata.json +++ b/apps/pongclock/metadata.json @@ -2,7 +2,7 @@ "name": "Pong Clock", "shortName":"Pong Clock", "icon": "pongclock.png", - "version":"0.01", + "version":"0.02", "description": "A Pong playing clock", "type": "clock", "tags": "", From c28d85ad1fc18f2a326858ddc5dfc0842d7b13e5 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 11 Jun 2022 09:00:47 +0200 Subject: [PATCH 051/121] sleepphasealarm: add settings file - Vibrate with configured pattern - Add setting to defer start of algorithm --- apps/sleepphasealarm/ChangeLog | 2 + apps/sleepphasealarm/README.md | 17 +++- apps/sleepphasealarm/app.js | 130 +++++++++++++++++----------- apps/sleepphasealarm/interface.html | 1 - apps/sleepphasealarm/metadata.json | 3 +- apps/sleepphasealarm/settings.js | 37 ++++++++ 6 files changed, 135 insertions(+), 55 deletions(-) create mode 100644 apps/sleepphasealarm/settings.js diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog index 208058472..4ca4fb723 100644 --- a/apps/sleepphasealarm/ChangeLog +++ b/apps/sleepphasealarm/ChangeLog @@ -7,3 +7,5 @@ use Layout library and display ETA 0.07: Add check for day of week 0.08: Update to new time_utils module +0.09: Vibrate with configured pattern + Add setting to defer start of algorithm diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md index c33c9c807..218ce5363 100644 --- a/apps/sleepphasealarm/README.md +++ b/apps/sleepphasealarm/README.md @@ -4,10 +4,19 @@ The alarm must be in the next 24h. The display shows: -- the current time -- time of the next alarm or timer -- time difference between current time and alarm time (ETA) -- current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging +- The current time. +- Time of the next alarm or timer. +- Time difference between current time and alarm time (ETA). +- Current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging. State can also be "Deferred", see the "Run before alarm"-option. + +## Settings + +* **Keep alarm enabled** + - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00. + - No: No action at configured alarm time from scheduler. +* **Run before alarm** + - disabled: (default) The ESS algorithm starts immediately when the application starts. + - 1..23: The ESS algorithm starts the configured time before the alarm. E.g. when set to 1h for an alarm at 7:00 the ESS algorithm will start at 6:00. This improves battery life. ## Logging diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index febc8a259..23df53b22 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -1,9 +1,18 @@ const BANGLEJS2 = process.env.HWVERSION == 2; // check for bangle 2 +const CONFIGFILE = "sleepphasealarm.json"; const Layout = require("Layout"); const locale = require('locale'); const alarms = require("Storage").readJSON("sched.json",1) || []; -const config = require("Storage").readJSON("sleepphasealarm.json",1) || {logs: []}; +const config = Object.assign({ + logs: [], // array of length 31 with one entry for each day of month + settings: { + startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time + disableAlarm: false, + } +}, require("Storage").readJSON(CONFIGFILE,1) || {}); const active = alarms.filter(a=>a.on); +const schedSettings = require("sched").getSettings(); +let buzzCount = schedSettings.buzzCount; let logs = []; // Sleep/Wake detection with Estimation of Stationary Sleep-segments (ESS): @@ -43,7 +52,8 @@ function calc_ess(acc_magn) { } // locate next alarm -var nextAlarm; +var nextAlarmDate; +var nextAlarmConfig; active.forEach(alarm => { const now = new Date(); const time = require("time_utils").decodeTime(alarm.t); @@ -52,8 +62,9 @@ active.forEach(alarm => { dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000)); } if ((alarm.dow >> dateAlarm.getDay()) & 1) { // check valid day of week - if (nextAlarm === undefined || dateAlarm < nextAlarm) { - nextAlarm = dateAlarm; + if (nextAlarmDate === undefined || dateAlarm < nextAlarmDate) { + nextAlarmDate = dateAlarm; + nextAlarmConfig = alarm; } } }); @@ -69,8 +80,8 @@ var layout = new Layout({ }, {lazy:true}); function drawApp() { - var alarmHour = nextAlarm.getHours(); - var alarmMinute = nextAlarm.getMinutes(); + var alarmHour = nextAlarmDate.getHours(); + var alarmMinute = nextAlarmDate.getMinutes(); if (alarmHour < 10) alarmHour = "0" + alarmHour; if (alarmMinute < 10) alarmMinute = "0" + alarmMinute; layout.alarm_date.label = "Alarm at " + alarmHour + ":" + alarmMinute; @@ -80,7 +91,7 @@ function drawApp() { if (Bangle.isLCDOn()) { const now = new Date(); layout.date.label = locale.time(now, BANGLEJS2 && Bangle.isLocked() ? 1 : 0); // hide seconds on bangle 2 - const diff = nextAlarm - now; + const diff = nextAlarmDate - now; const diffHour = Math.floor((diff % 86400000) / 3600000).toString(); const diffMinutes = Math.floor(((diff % 86400000) % 3600000) / 60000).toString(); layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0'); @@ -92,70 +103,91 @@ function drawApp() { setInterval(drawTime, 500); // 2Hz } -var buzzCount = 19; function buzz() { if ((require('Storage').readJSON('setting.json',1)||{}).quiet>1) return; // total silence - Bangle.setLCDPower(1); - Bangle.buzz().then(()=>{ - if (buzzCount--) { - setTimeout(buzz, 500); - } else { - // back to main after finish - setTimeout(load, 1000); - } - }); + Bangle.setLCDPower(1); + require("buzz").pattern(nextAlarmConfig.vibrate || ";"); + if (buzzCount--) { + setTimeout(buzz, schedSettings.buzzIntervalMillis); + } else { + // back to main after finish + setTimeout(load, 1000); + } } function addLog(time, type) { logs.push({time: time, type: type}); - require("Storage").writeJSON("sleepphasealarm.json", config); + if (logs.length > 1) { // Do not write if there is only one state + require("Storage").writeJSON(CONFIGFILE, config); + } } // run var minAlarm = new Date(); var measure = true; -if (nextAlarm !== undefined) { - config.logs[nextAlarm.getDate()] = []; // overwrite log on each day of month - logs = config.logs[nextAlarm.getDate()]; +if (nextAlarmDate !== undefined) { + config.logs[nextAlarmDate.getDate()] = []; // overwrite log on each day of month + logs = config.logs[nextAlarmDate.getDate()]; g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); let swest_last; // minimum alert 30 minutes early - minAlarm.setTime(nextAlarm.getTime() - (30*60*1000)); - Bangle.on('accel', (accelData) => { // 12.5Hz - const now = new Date(); - const acc = accelData.mag; - const swest = calc_ess(acc); + minAlarm.setTime(nextAlarmDate.getTime() - (30*60*1000)); + run = () => { + layout.state.label = "Start"; + layout.render(); + Bangle.on('accel', (accelData) => { // 12.5Hz + const now = new Date(); + const acc = accelData.mag; + const swest = calc_ess(acc); - if (swest !== undefined) { - if (Bangle.isLCDOn()) { - layout.state.label = swest ? "Sleep" : "Awake"; - layout.render(); - } - // log - if (swest_last != swest) { - if (swest) { - addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz - } else { - addLog(now, "awake"); + if (swest !== undefined) { + if (Bangle.isLCDOn()) { + layout.state.label = swest ? "Sleep" : "Awake"; + layout.render(); + } + // log + if (swest_last != swest) { + if (swest) { + addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz + } else { + addLog(now, "awake"); + } + swest_last = swest; } - swest_last = swest; } - } - if (now >= nextAlarm) { - // The alarm widget should handle this one - addLog(now, "alarm"); - setTimeout(load, 1000); - } else if (measure && now >= minAlarm && swest === false) { - addLog(now, "alarm"); - buzz(); - measure = false; - } - }); + if (now >= nextAlarmDate) { + // The alarm widget should handle this one + addLog(now, "alarm"); + setTimeout(load, 1000); + } else if (measure && now >= minAlarm && swest_last === false) { + addLog(now, "alarm"); + buzz(); + measure = false; + if (config.settings.disableAlarm) { + // disable alarm for scheduler + nextAlarmConfig.last = now.getDate(); + require("Storage").writeJSON("sched.json", alarms); + } + } + }); + }; drawApp(); + if (config.settings.startBeforeAlarm === 0) { + // Start immediately + run(); + } else { + // defer start + layout.state.label = "Deferred"; + layout.render(); + const diff = nextAlarmDate - Date.now(); + let timeout = diff-config.settings.startBeforeAlarm*60*60*1000; + if (timeout < 0) timeout = 0; + setTimeout(run, timeout); + } } else { E.showMessage('No Alarm'); setTimeout(load, 1000); diff --git a/apps/sleepphasealarm/interface.html b/apps/sleepphasealarm/interface.html index 9a7cb0f93..f45c183e1 100644 --- a/apps/sleepphasealarm/interface.html +++ b/apps/sleepphasealarm/interface.html @@ -1,7 +1,6 @@ -

Please select a wakeup day:

diff --git a/apps/sleepphasealarm/metadata.json b/apps/sleepphasealarm/metadata.json index c74a617ab..6ec5f4180 100644 --- a/apps/sleepphasealarm/metadata.json +++ b/apps/sleepphasealarm/metadata.json @@ -2,7 +2,7 @@ "id": "sleepphasealarm", "name": "SleepPhaseAlarm", "shortName": "SleepPhaseAlarm", - "version": "0.08", + "version": "0.09", "description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.", "icon": "app.png", "tags": "alarm", @@ -11,6 +11,7 @@ "dependencies": {"scheduler":"type"}, "storage": [ {"name":"sleepphasealarm.app.js","url":"app.js"}, + {"name":"sleepphasealarm.settings.js","url":"settings.js"}, {"name":"sleepphasealarm.img","url":"app-icon.js","evaluate":true} ], "data": [{"name":"sleepphasealarm.json","storageFile":true}], diff --git a/apps/sleepphasealarm/settings.js b/apps/sleepphasealarm/settings.js new file mode 100644 index 000000000..a79abb598 --- /dev/null +++ b/apps/sleepphasealarm/settings.js @@ -0,0 +1,37 @@ +(function(back) { + const CONFIGFILE = "sleepphasealarm.json"; + // Load settings + const config = Object.assign({ + logs: [], // array of length 31 with one entry for each day of month + settings: { + startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time + disableAlarm: false, + } + }, require("Storage").readJSON(CONFIGFILE,1) || {}); + + function writeSettings() { + require('Storage').writeJSON(CONFIGFILE, config); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "SleepPhaseAlarm" }, + 'Keep alarm enabled': { + value: !!config.settings.disableAlarm, + format: v => v?"No":"Yes", + onchange: v => { + config.settings.disableAlarm = v; + writeSettings(); + } + }, "< Back" : () => back(), + 'Run before alarm': { + format: v => v === 0 ? 'disabled' : v+'h', + value: config.settings.startBeforeAlarm, + min: 0, max: 23, + onchange: v => { + config.settings.startBeforeAlarm = v; + writeSettings(); + } + }, + }); +}) From fd1cab5b96884de25435e7c633ffd257b4a3d2bf Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 11 Jun 2022 09:05:31 +0200 Subject: [PATCH 052/121] sleepphasealarm. updated documentation --- apps/sleepphasealarm/ChangeLog | 2 ++ apps/sleepphasealarm/README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog index 4ca4fb723..6bf296342 100644 --- a/apps/sleepphasealarm/ChangeLog +++ b/apps/sleepphasealarm/ChangeLog @@ -9,3 +9,5 @@ 0.08: Update to new time_utils module 0.09: Vibrate with configured pattern Add setting to defer start of algorithm + Add setting to disable scheduler alarm + diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md index 218ce5363..ecb3feb06 100644 --- a/apps/sleepphasealarm/README.md +++ b/apps/sleepphasealarm/README.md @@ -12,7 +12,7 @@ The display shows: ## Settings * **Keep alarm enabled** - - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00. + - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at the calculated time from the ESS algorithm (for example 6:45) and again at 7:00. - No: No action at configured alarm time from scheduler. * **Run before alarm** - disabled: (default) The ESS algorithm starts immediately when the application starts. From 87387d546dc06dd9659895e5b546eee3473ff584 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 15:16:18 +0200 Subject: [PATCH 053/121] Initial Release --- apps/hworldclock/ChangeLog | 1 + apps/hworldclock/README.md | 30 +++ apps/hworldclock/app.js | 266 ++++++++++++++++++++++ apps/hworldclock/app.png | Bin 0 -> 2867 bytes apps/hworldclock/custom.html | 76 +++++++ apps/hworldclock/hsuncalc.js | 298 +++++++++++++++++++++++++ apps/hworldclock/hworldclock-icon.js | 1 + apps/hworldclock/hworldclock.png | Bin 0 -> 3457 bytes apps/hworldclock/metadata.json | 21 ++ apps/hworldclock/screenshot_hworld.png | Bin 0 -> 3457 bytes 10 files changed, 693 insertions(+) create mode 100644 apps/hworldclock/ChangeLog create mode 100644 apps/hworldclock/README.md create mode 100644 apps/hworldclock/app.js create mode 100644 apps/hworldclock/app.png create mode 100644 apps/hworldclock/custom.html create mode 100644 apps/hworldclock/hsuncalc.js create mode 100644 apps/hworldclock/hworldclock-icon.js create mode 100644 apps/hworldclock/hworldclock.png create mode 100644 apps/hworldclock/metadata.json create mode 100644 apps/hworldclock/screenshot_hworld.png diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog new file mode 100644 index 000000000..5b2a1edce --- /dev/null +++ b/apps/hworldclock/ChangeLog @@ -0,0 +1 @@ +0.15: Initial release - be patient as this is the first try :) diff --git a/apps/hworldclock/README.md b/apps/hworldclock/README.md new file mode 100644 index 000000000..40af71ee3 --- /dev/null +++ b/apps/hworldclock/README.md @@ -0,0 +1,30 @@ +# Hanks World Clock - See the time in four locations + +In addition to the main clock and date in your current location, you can add up to three other locations. Great for travel or remote working. +Additionally we show the sunset/sunrise and seconds for the current location and the day name is shown in your locale. + +![](hworldclock.png) + +## Usage + +Provide names and the UTC offsets for up to three other timezones in the app store. These are stored in a json file on your watch. UTC offsets can be decimal (e.g., 5.5 for India). + +The clock does not handle summer time / daylight saving time changes automatically. If one of your three locations changes its UTC offset, you can simply change the setting in the app store and update. Currently the clock only supports 24 hour time format for the additional time zones. + + +## Requests + +Please use [the Espruino Forum](http://forum.espruino.com/microcosms/1424/) if you have feature requests or notice bugs. + +## Creator + +Created by Hank. + +Based on the great work of +================= +World Clock - 4 time zones +Made by [Scott Hale](https://www.github.com/computermacgyver), based upon the [Simple Clock](https://github.com/espruino/BangleApps/tree/master/apps/sclock). +===== a n d ===== +Sun Clock +[Sun Clock](https://github.com/espruino/BangleApps/tree/master/apps/sunclock) +================= diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js new file mode 100644 index 000000000..8122371a6 --- /dev/null +++ b/apps/hworldclock/app.js @@ -0,0 +1,266 @@ +const big = g.getWidth()>200; +// Font for primary time and date +const primaryTimeFontSize = big?6:5; +const primaryDateFontSize = big?3:2; +require("Font5x9Numeric7Seg").add(Graphics); +require("FontTeletext10x18Ascii").add(Graphics); + +// Font for single secondary time +const secondaryTimeFontSize = 4; +const secondaryTimeZoneFontSize = 2; + +// Font / columns for multiple secondary times +const secondaryRowColFontSize = 2; +const xcol1 = 10; +const xcol2 = g.getWidth() - xcol1; + +const font = "6x8"; + +/* TODO: we could totally use 'Layout' here and +avoid a whole bunch of hard-coded offsets */ + + +const xyCenter = g.getWidth() / 2; +const xyCenterSeconds = xyCenter + (big ? 85 : 68); +const yAmPm = xyCenter - (big ? 70 : 48); +const yposTime = big ? 70 : 55; +const yposTime2 = yposTime + (big ? 100 : 60); +const yposDate = big ? 135 : 95; +const yposWorld = big ? 170 : 120; + +const OFFSET_TIME_ZONE = 0; +const OFFSET_HOURS = 1; + +var offsets = require("Storage").readJSON("hworldclock.settings.json") || []; + +//=======Sun +setting = require("Storage").readJSON("setting.json",1); +E.setTimeZone(setting.timezone); // timezone = 1 for MEZ, = 2 for MESZ +SunCalc = require("hsuncalc.js"); +const LOCATION_FILE = "mylocation.json"; +var rise = "07:00"; +var set = "20:00"; +var pos = {altitude: 20, azimuth: 135}; +var noonpos = {altitude: 37, azimuth: 180}; +//=======Sun + +var ampm = "AM"; + +// TESTING CODE +// Used to test offset array values during development. +// Uncomment to override secondary offsets value +/* +const mockOffsets = { + zeroOffsets: [], + oneOffset: [["UTC", 0]], + twoOffsets: [ + ["Tokyo", 9], + ["UTC", 0], + ], + fourOffsets: [ + ["Tokyo", 9], + ["UTC", 0], + ["Denver", -7], + ["Miami", -5], + ], +};*/ + +// Uncomment one at a time to test various offsets array scenarios +//offsets = mockOffsets.zeroOffsets; // should render nothing below primary time +//offsets = mockOffsets.oneOffset; // should render larger in two rows +//offsets = mockOffsets.twoOffsets; // should render two in columns +//offsets = mockOffsets.fourOffsets; // should render in columns + +// END TESTING CODE + +// Check settings for what type our clock should be +var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; + +// timeout used to update every minute +var drawTimeout; +var drawTimeoutSeconds; + +g.setBgColor(0, 0, 0); + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +function doublenum(x) { + return x < 10 ? "0" + x : "" + x; +} + +function getCurrentTimeFromOffset(dt, offset) { + return new Date(dt.getTime() + offset * 60 * 60 * 1000); +} + +function updatePos() { + coord = require("Storage").readJSON(LOCATION_FILE,1)|| {"lat":53.3,"lon":10.1,"location":"Pattensen"}; + pos = SunCalc.getPosition(Date.now(), coord.lat, coord.lon); + times = SunCalc.getTimes(Date.now(), coord.lat, coord.lon); + rise = times.sunrise.toString().split(" ")[4].substr(0,5); + set = times.sunset.toString().split(" ")[4].substr(0,5); + noonpos = SunCalc.getPosition(times.solarNoon, coord.lat, coord.lon); +} + + +function drawSeconds() { + // get date + var d = new Date(); + var da = d.toString().split(" "); + + // default draw styles + g.reset(); + g.setBgColor(0, 0, 0); + + // drawSting centered + g.setFontAlign(0, 0); + + // draw time + var time = da[4].split(":"); + var seconds = time[2]; + + g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); + g.setColor("#22ff05"); + //g.setFont(font, primaryTimeFontSize-3); + g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); +} + +function draw() { + // get date + var d = new Date(); + var da = d.toString().split(" "); + + // default draw styles + g.reset(); + g.setBgColor(0, 0, 0); + + // drawSting centered + g.setFontAlign(0, 0); + + // draw time + var time = da[4].split(":"); + var hours = time[0], + minutes = time[1]; + + + if (_12hour){ + //do 12 hour stuff + if (hours > 12) { + ampm = "PM"; + hours = hours - 12; + } else { + ampm = "AM"; + } + } + + //g.setFont(font, primaryTimeFontSize); + g.setFont("5x9Numeric7Seg",primaryTimeFontSize); + g.setColor("#22ff05"); + g.drawString(`${doublenum(hours)}:${minutes}`, xyCenter-10, yposTime, true); + + // am / PM ? + if (_12hour){ + //do 12 hour stuff + //var ampm = require("locale").medidian(new Date()); Not working + g.setFont("Vector", 17); + g.setColor("#22ff05"); + g.drawString(ampm, xyCenterSeconds, yAmPm, true); + } + + drawSeconds(); // To make sure... + + // draw Day, name of month, Date + //DATE + var localDate = require("locale").date(new Date(), 1); + localDate = localDate.substring(0, localDate.length - 5) + g.setFont("Vector", 17); + g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); + + + + g.setFont(font, primaryDateFontSize); + // set gmt to UTC+0 + var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); + + // Loop through offset(s) and render + offsets.forEach((offset, index) => { + dx = getCurrentTimeFromOffset(gmt, offset[OFFSET_HOURS]); + hours = doublenum(dx.getHours()); + minutes = doublenum(dx.getMinutes()); + + + if (offsets.length === 1) { + var date = [require("locale").dow(new Date(), 1), require("locale").date(new Date(), 1)]; + // For a single secondary timezone, draw it bigger and drop time zone to second line + const xOffset = 30; + g.setFont(font, secondaryTimeFontSize); + g.drawString(`${hours}:${minutes}`, xyCenter, yposTime2, true); + g.setFont(font, secondaryTimeZoneFontSize); + g.drawString(offset[OFFSET_TIME_ZONE], xyCenter, yposTime2 + 30, true); + + // draw Day, name of month, Date + g.setFont(font, secondaryTimeZoneFontSize); + g.drawString(date, xyCenter, yposDate, true); + } else if (index < 3) { + // For > 1 extra timezones, render as columns / rows + g.setFont(font, secondaryRowColFontSize); + g.setFontAlign(-1, 0); + g.drawString( + offset[OFFSET_TIME_ZONE], + xcol1, + yposWorld + index * 15, + true + ); + g.setFontAlign(1, 0); + g.drawString(`${hours}:${minutes}`, xcol2, yposWorld + index * 15, true); + } + }); + + g.setFontAlign(-1, 0); + g.setFont("Vector",12); + g.drawString(`^${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw riseset + g.setFontAlign(1, 0); + g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset + + queueDraw(); +} + +// clean app screen +g.clear(); +// Show launcher when button pressed +Bangle.setUI("clock"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +updatePos(); +setInterval(drawSeconds, 1E3); + + + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + drawSeconds(); // draw immediately, queue redraw + setInterval(updatePos, 60*5E3); // refesh every 5 mins + setInterval(drawSeconds, 1E3); + updatePos(); + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + setInterval(updatePos, 60*50E3); // refesh every 50 mins + setInterval(drawSeconds, 10E3); + updatePos(); + } +}); + +// draw now +drawSeconds(); +draw(); diff --git a/apps/hworldclock/app.png b/apps/hworldclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..506fa45b917be1f40fc2e691581ff199e8144f58 GIT binary patch literal 2867 zcmV-33(WM1P)Dr$W1mWa^_`k0JNLm4i2H*_fM*v3! zLEwGx1OW&FpahUD2*R!2a`Y+yk^+F|01O21A3+eBd+V?pUIzfr1Ly#dAqaxHFL;fe zNJu7;^z3u;UwyccOe7iD*TgeO&h1lD^ZuSC8Piu}uaFGr6SCg<^(GllvfqP{EFt+= zAL{C@e^-*p_Z0-mMI?P6g09}`7(_C$w?@yB9QBYi^%}bFWO7X0^=e2C1>htI!s&-C ztfvqJp$>qYU33i;a!VYj1DYPzSkO-kFq?G#|PI850w;MkEr=)bY3i@OO50 zj??|Nj*5y(`|`^#v$C_Zvm6~Ap90`!Z*M=)&CM+WCLXSCP|v&LY3hFj1qF#JD=Xvb z>+2O#sZ`P4-hSQM+FIDRZ{LK#z(D`3tgJn*uC7BI9UXnb!opk&3JOX!8ckmR{{5d( ztJNqgE2}OnEPQ{%h7JGLb6&rGJ@?yhzkRu@t1GgosHo)YufLXrhljg(d3jA$DwU(& ze*0~SNF)+eDisC%cA~z%{z_F<)u6z@K$ToBFKKOUEtAP);vqwZ$d@l)UXqfM z;!M&`5Cr8fZ)e)HX{+n&>u<_rvM!}kNkgbqDt2{s@tbeH$%u%E_3=IMEG%5MY}pI|4xXN#uK=(GfOp@0cXDxY@s&-RHdQn=HEFhQ-+sHXv5_R1 zo14q4SFftrL)6vPbyZhaD{^vjWK*V02_-q-@GXR`U%x)>%$YMEIXgRh*3{G}jS0@4 zJ=+o*8ag61HFddMF6ZvuyN>~|l1L;Detv%ThGfHs5BHipdGd=(mo9y4<;sCCYNlTCvlYCxx(Qn6&9hXS5 zrl#iN-o1ObtXZ>WrMtU(P*0prpFVx$wQJXY$qSvGovf^^Y^$oOYEDm2zjpKHO^sTu z=2u^RReAmTb#+g=&zd!B=1C+H4`W{>|3Fd#l24L+N`GV2s8R2=wY6zdQ&SfJu_*_JI^Qi_X0VzKy< z{QUfDB$=3)m;*oS=G6@xfcLnz<>eq4h{~H z-30M6NJg3pKnDwvNHqKC(W5s=vZbY^Ln@Vi?&jtuHr4pM@4nloP$*blUf$Hw(qb~x z%H?v^>eZ{CH?*5SfBwku@bFi4f4w3iB9^`Z3t-888FOpM0(w1f_0I$9FT3};iqshK4l}dM;6OxgU@t$G(ii(P602To3 z?iGYFJUl#n0s;bJ!otG-EEbDLe(}W@ugc|eZO5&zzkREH`i7oF$XVx}u_@KHR-~_d7bxFME1= zKA{g_(Y;u5a&k5pim9%yRs!g6&L%G}FUufchJ}UsA31X5a8y)Ow_Vl{adB}^78Mnp zRjai*Ppww-`0?Xs0rb;pw$%p^OVZ@bqQ|G7ewv^cbMD-^HeX*~?|TV|iHUi-t*wnD zdHVF}Y5=y27cX9dUyHluU|CX9a@n}sc6D_zAt51xlpdKmGL6Y?6L3 z>;WW~m}5&xNtvP1Xn648!Kz7dCl-s{#A2~qFU13Zl}IGgul%gHZQJ&b{QUeM zUwY}K0Fti*Kzw}szYGI-hUD<>*a89qp1N}7irUW3?x7WT%^^BEdc42Ce;`S>*4EYq z78Vu@TwPu7EVGbYYKFtMxVX3_K0babfctr(eFBn8h7TX^1MTk5U4^Z38mvr>aC`gq z?NdocIXOAmK2(+6fZ7$q)ym4s8ff7=1#ph!#NR|&51{MTZMqt1kBy?tjECP0)K;cnykFzk-!lkm_vK!HP?FidM|UC_ zOmabAk}dhIW+#$!NSgc>eh|_@B$ttVx=)Gk^zk?!@>VWLhEuzH=--E&LrK0ta%yjF z@B6HTZd~{PXa%re5QLk(w6_H?6~H3^F6lUWeO#e04tqEQm;&wg5urWzZ~;IQfE&7N zj?f-Y@Yb~x0Ne(UF9^bw2l4;F0T_d%4YVgx1_H2$Hd(eq`=-tt?yU3${s(KJ-urwb RzLEd{002ovPDHLkV1oI8cc%aV literal 0 HcmV?d00001 diff --git a/apps/hworldclock/custom.html b/apps/hworldclock/custom.html new file mode 100644 index 000000000..896d999f5 --- /dev/null +++ b/apps/hworldclock/custom.html @@ -0,0 +1,76 @@ + + + + + + +

You can add up to 3 timezones. Please give a name and UTC offset in hours. + If you want less than 3, clear the checkbox to the left.

+ + + + + + + +
Enabled?NameUTC Offset
+ +

Click

+ + + + + + diff --git a/apps/hworldclock/hsuncalc.js b/apps/hworldclock/hsuncalc.js new file mode 100644 index 000000000..b1af0a0d9 --- /dev/null +++ b/apps/hworldclock/hsuncalc.js @@ -0,0 +1,298 @@ +/* Module suncalc.js + (c) 2011-2015, Vladimir Agafonkin + SunCalc is a JavaScript library for calculating sun/moon position and light phases. + https://github.com/mourner/suncalc + +PB: Usage: +E.setTimeZone(2); // 1 = MEZ, 2 = MESZ +SunCalc = require("suncalc.js"); +pos = SunCalc.getPosition(Date.now(), 53.3, 10.1); +times = SunCalc.getTimes(Date.now(), 53.3, 10.1); +rise = times.sunrise; // Date object +rise_str = rise.getHours() + ':' + rise.getMinutes(); //hh:mm +*/ +var exports={}; + +// shortcuts for easier to read formulas + +var PI = Math.PI, + sin = Math.sin, + cos = Math.cos, + tan = Math.tan, + asin = Math.asin, + atan = Math.atan2, + acos = Math.acos, + rad = PI / 180; + +// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas + +// date/time constants and conversions + +var dayMs = 1000 * 60 * 60 * 24, + J1970 = 2440588, + J2000 = 2451545; + +function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; } +function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); } // PB: onece removed + 0.5; included it again 4 Jan 2021 +function toDays(date) { return toJulian(date) - J2000; } + + +// general calculations for position + +var e = rad * 23.4397; // obliquity of the Earth + +function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); } +function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); } + +function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); } +function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); } + +function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; } + +function astroRefraction(h) { + if (h < 0) // the following formula works for positive altitudes only. + h = 0; // if h = -0.08901179 a div/0 would occur. + + // formula 16.4 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + // 1.02 / tan(h + 10.26 / (h + 5.10)) h in degrees, result in arc minutes -> converted to rad: + return 0.0002967 / Math.tan(h + 0.00312536 / (h + 0.08901179)); +} + +// general sun calculations + +function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); } + +function eclipticLongitude(M) { + + var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center + P = rad * 102.9372; // perihelion of the Earth + + return M + C + P + PI; +} + +function sunCoords(d) { + + var M = solarMeanAnomaly(d), + L = eclipticLongitude(M); + + return { + dec: declination(L, 0), + ra: rightAscension(L, 0) + }; +} + +// calculates sun position for a given date and latitude/longitude + +exports.getPosition = function (date, lat, lng) { + + var lw = rad * -lng, + phi = rad * lat, + d = toDays(date), + + c = sunCoords(d), + H = siderealTime(d, lw) - c.ra; + + return { + azimuth: Math.round((azimuth(H, phi, c.dec) / rad + 180) % 360), // PB: converted to deg + altitude: Math.round( altitude(H, phi, c.dec) / rad) // PB: converted to deg + }; +}; + + +// sun times configuration (angle, morning name, evening name) + +var times = [ + [-0.833, 'sunrise', 'sunset' ] +]; + +// calculations for sun times +var J0 = 0.0009; + +function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); } + +function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; } +function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); } + +function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); } +function observerAngle(height) { return -2.076 * Math.sqrt(height) / 60; } + +// returns set time for the given sun altitude +function getSetJ(h, lw, phi, dec, n, M, L) { + + var w = hourAngle(h, phi, dec), + a = approxTransit(w, lw, n); + return solarTransitJ(a, M, L); +} + + +// calculates sun times for a given date, latitude/longitude, and, optionally, +// the observer height (in meters) relative to the horizon + +exports.getTimes = function (date, lat, lng, height) { + + height = height || 0; + + var lw = rad * -lng, + phi = rad * lat, + + dh = observerAngle(height), + + d = toDays(date), + n = julianCycle(d, lw), + ds = approxTransit(0, lw, n), + + M = solarMeanAnomaly(ds), + L = eclipticLongitude(M), + dec = declination(L, 0), + + Jnoon = solarTransitJ(ds, M, L), + + i, len, time, h0, Jset, Jrise; + + + var result = { + solarNoon: fromJulian(Jnoon), + nadir: fromJulian(Jnoon - 0.5) + }; + + for (i = 0, len = times.length; i < len; i += 1) { + time = times[i]; + h0 = (time[0] + dh) * rad; + + Jset = getSetJ(h0, lw, phi, dec, n, M, L); + Jrise = Jnoon - (Jset - Jnoon); + + result[time[1]] = fromJulian(Jrise); + result[time[2]] = fromJulian(Jset); + } + + return result; +}; + + +// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas + +function moonCoords(d) { // geocentric ecliptic coordinates of the moon + + var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude + M = rad * (134.963 + 13.064993 * d), // mean anomaly + F = rad * (93.272 + 13.229350 * d), // mean distance + + l = L + rad * 6.289 * sin(M), // longitude + b = rad * 5.128 * sin(F), // latitude + dt = 385001 - 20905 * cos(M); // distance to the moon in km + + return { + ra: rightAscension(l, b), + dec: declination(l, b), + dist: dt + }; +} + +getMoonPosition = function (date, lat, lng) { + + var lw = rad * -lng, + phi = rad * lat, + d = toDays(date), + + c = moonCoords(d), + H = siderealTime(d, lw) - c.ra, + h = altitude(H, phi, c.dec), + // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + pa = atan(sin(H), tan(phi) * cos(c.dec) - sin(c.dec) * cos(H)); + + h = h + astroRefraction(h); // altitude correction for refraction + + return { + azimuth: azimuth(H, phi, c.dec), + altitude: h, + distance: c.dist, + parallacticAngle: pa + }; +}; + + +// calculations for illumination parameters of the moon, +// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and +// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. + +getMoonIllumination = function (date) { + + var d = toDays(date || new Date()), + s = sunCoords(d), + m = moonCoords(d), + + sdist = 149598000, // distance from Earth to Sun in km + + phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)), + inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)), + angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) - + cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra)); + + return { + fraction: (1 + cos(inc)) / 2, + phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI, + angle: angle + }; +}; + + +function hoursLater(date, h) { + return new Date(date.valueOf() + h * dayMs / 24); +} + +// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article + +getMoonTimes = function (date, lat, lng, inUTC) { + var t = new Date(date); + if (inUTC) t.setUTCHours(0, 0, 0, 0); + else t.setHours(0, 0, 0, 0); + + var hc = 0.133 * rad, + h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc, + h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx; + + // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set) + for (var i = 1; i <= 24; i += 2) { + h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc; + h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc; + + a = (h0 + h2) / 2 - h1; + b = (h2 - h0) / 2; + xe = -b / (2 * a); + ye = (a * xe + b) * xe + h1; + d = b * b - 4 * a * h1; + roots = 0; + + if (d >= 0) { + dx = Math.sqrt(d) / (Math.abs(a) * 2); + x1 = xe - dx; + x2 = xe + dx; + if (Math.abs(x1) <= 1) roots++; + if (Math.abs(x2) <= 1) roots++; + if (x1 < -1) x1 = x2; + } + + if (roots === 1) { + if (h0 < 0) rise = i + x1; + else set = i + x1; + + } else if (roots === 2) { + rise = i + (ye < 0 ? x2 : x1); + set = i + (ye < 0 ? x1 : x2); + } + + if (rise && set) break; + + h0 = h2; + } + + var result = {}; + + if (rise) result.rise = hoursLater(t, rise); + if (set) result.set = hoursLater(t, set); + + if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true; + + return result; +}; \ No newline at end of file diff --git a/apps/hworldclock/hworldclock-icon.js b/apps/hworldclock/hworldclock-icon.js new file mode 100644 index 000000000..6e05d254c --- /dev/null +++ b/apps/hworldclock/hworldclock-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgJC/ABEE+EA4EAj9E8HF//gn/gwP///wt/MgF//8gh/8gYLBwEP+EHAofghgFD4EOj//gEPA4ILBGgIxB/wFBgwFB/lsgCKBj/4oxHBvAFBJoV8gP4TQX+gJUBAAN/Aok+AoVgAoXogAfBjkA8AfBAoXAAoUYY4cAiCDEAooA/ABg")) diff --git a/apps/hworldclock/hworldclock.png b/apps/hworldclock/hworldclock.png new file mode 100644 index 0000000000000000000000000000000000000000..565e0dc6b8e08edffc313b889bc2e062ffc1edf7 GIT binary patch literal 3457 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 Date: Sat, 11 Jun 2022 15:23:47 +0200 Subject: [PATCH 054/121] Initial Release --- .../widget.png | Bin 0 -> 2385 bytes apps/hwid_a_battery_widget/ChangeLog | 5 ++ apps/hwid_a_battery_widget/README.md | 15 +++++ .../h_battery_widget-pic.jpg | Bin 0 -> 66429 bytes apps/hwid_a_battery_widget/metadata.json | 15 +++++ apps/hwid_a_battery_widget/widget.js | 56 ++++++++++++++++++ apps/hwid_a_battery_widget/widget.png | Bin 0 -> 877 bytes 7 files changed, 91 insertions(+) create mode 100644 apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png create mode 100644 apps/hwid_a_battery_widget/ChangeLog create mode 100644 apps/hwid_a_battery_widget/README.md create mode 100644 apps/hwid_a_battery_widget/h_battery_widget-pic.jpg create mode 100644 apps/hwid_a_battery_widget/metadata.json create mode 100644 apps/hwid_a_battery_widget/widget.js create mode 100644 apps/hwid_a_battery_widget/widget.png diff --git a/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png b/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..868628b6085cb0da28098648ae713dc1f08e44d0 GIT binary patch literal 2385 zcmaJ@3s_S}7QRV%6-6sAF<4ClyK7v@i-;0K3Ni8!q9Gtc4b~8DAdq)1aB(YAt>u%d z1QAzxOM?njO9Tu>6tPi@^y8Cq0o>m5~KlokLMAQ3HazyNs#E&zZ#FAa}`B6%T9u~JSJ#VTV!GAvi2N&pLHBBmUK zLS3?Dm5U%i%ca`iELW}fxyzlN|*w!{|p^@ z^C8AVkcvs6q@<*fQ#{E^O&o>h?d?sW(kXPh2ZHd>rYay2?4i)QO^f`Y!v(csjZ_6m zl?no?D~eGjK|Vwxy3y-49VaA}%- zo53R0G|7Az(=oEp2$)dxGIwnb9z78#m+Sq0cd}KFI#A;yHf?IRDcwX=oQiR>aFy?ugdQ6YyDM9=!Ox)6 z-QwI1%ye`nVGTAnt{o#ero6HML)Uy^Dj6ygJslhQ-l*K`UtG1cwe@N1cVDLrwdRMG z*64k76TUsT2uh&{4?j3|Ne+tME|dQYKSCDEpg8kolSq#+^^!R)ie+U z+s11v=x1NukMZ}niWUm_R2O|qOK`|UPMgE#(5}Jk;~k)HT0%l*MP+4DZAyM`Pfuxc za}bloswueJ3BW4`U0q#Co}QjDK$KIEn`0ez=clGG-0CZEQ^M%z@-?u@J`5Kt(5+iU z#uXJ8=iGmKrnyp3Bv0G-oedIQndCY+#&iwI4%dH@kxX^BbGx#&>l$)y9T~ zkjlzR27|%n@pupf>3gb(iHV6Hepx3Z=bb!xs=mG+w&RbTc;zlnU-sJ6JCs%aX z>{!HYi_>azcJKZQPoS#rbKUi=N-VU=E%-tkypQL*|~ zOUnW`T+CgsyMm664#o!`eARY=_wK;w_qw~!V2!1v9Jf`=Tt3OM-BDRvyKQ7|=fk0) z3UTLfFhy+I?6Dod#QiOvLL!Bx7oB7eSJ~g*e--e3wmRopRvE^nd$={{#|FZYOIi0` z{iDsmz26SNiEa)73wZvvR8kw&<<{1Q|u{R*kDbNFBDQ31}%3AJl^-n#&A7i zxIK5{orx`M+GVZ3ZuIbI-e`Wmh~?5m3NID^c4ADVE=l|sd~femU2l7U^9Td|Ul6ou L3->%{*S`M&n6+>< literal 0 HcmV?d00001 diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog new file mode 100644 index 000000000..84cbad8ad --- /dev/null +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -0,0 +1,5 @@ +0.01: Release for Bangle 2 (2021/11/18) +0.02: Internal id update to wid_* as per Gordon's request (2021/11/21) +0.03: Support dark themes +0.04: Increase screen update rate when charging +0.05: Deleting Background - making Font larger \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/README.md b/apps/hwid_a_battery_widget/README.md new file mode 100644 index 000000000..638272b3f --- /dev/null +++ b/apps/hwid_a_battery_widget/README.md @@ -0,0 +1,15 @@ +# A Battery Widget (with percentage) + +Show the current battery level and charging status in the top right of the clock, with charge percentage + +* Works with Bangle 2 +* Simple design, no settings + * Red when the batterly level is below 30% + * Blue when charging +* 40 pixels wide + +![](a_battery_widget-pic.jpg) + +## Creator +[@alainsaas](https://github.com/alainsaas) +Mod by Hank diff --git a/apps/hwid_a_battery_widget/h_battery_widget-pic.jpg b/apps/hwid_a_battery_widget/h_battery_widget-pic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d9a4deccf352be3086e7d8d66200a436839c8da GIT binary patch literal 66429 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�y4n1O6P<0tvFKDNAjl02*?a;Bxc?7T-^SzHp2 zZF31i1`9XzrFU|Ql3Lxu;waD0_32uE9<+y5v^LJ`9oil;al7eJ%^(T5A2uP;`mp-c zQbXp)x*0$UG8k}0HUqA$ZY<>y+^JPOhEx3NXbT_+2A?exR8X6%5w;)55wbCYXwxn&=Z%mBa{mCr!vq?ubdtL; zh>R)0jkv{4hjQ#LS``469rtt3rAXEiz6zWj`3h>4sd!u*;A5QjsSVu5Q->!UD+*2{ zM3BiLP_nlmkm`TJrr);R{Gbts7;(*0zLU-YnC+E%KXXw@sH;FyNWpU4GUVoyi!CzR ze9?kV*I~-FF3ErCpXX9VDY=D7QM7`0fz2nCANSk-`Kboa|I+%x;zG=KR1DnESnjCU z{KmXS&vY4wJo7{`NpT=l9r>oljVys98DsiY=4G?B^3dgv-fEOF9n#V-DKJUuYLw2> z5>HP`WRe$SlToq9da(<@q%0{3reu$L2BUGssi5;nezcSpv_rBf4m(m%Xc$pQT9CB> zC#@kgx%Q?|0Nr}=QQS(g##xRBT3MY|J;dM&<-A9#$uys4wyRF z*{#n6^NN>4(-u5Cp)7inNucStA>?nE^~kNrP%7gc>pG7?j8y}rI;7j}Oe31*>QmT2 zrxhHll_ca;gE{(FC-F1IkZ6_-6mAU7*c{U3OlmEe-xEAoG`J15ldDd{pzT~fgX8^f z)?&J(0()Y5g~Kg7!2TZ8yldhkad2E)Zu#7QD)i40{43I9(-pLdOmjxLbaRzz)(tHR zdKp?@h;*$+&8N4x0D+Q>c@^hAG4W#F__`}0AP`2`_CH#e#x}NI8nTx5`sO$mB6sX; zX1-|n+3_w7L&SEn_;KDOwmEjrM1)seIu|+TStfn8;d|IFERZ7rKpYQB+XHf9zGwZP zel1(-_R(70Oe48K0aAL`(E0|e4eUzUA~+#LGtI;vSlVT1t*eejfP+tk}6kRflVqH?INAQii%L~TF`-pFgU7F ztD(*h<5r;gfH*38;EIWb(RSUip-T1cYSFc3kIad=9mP18Pa`blzIcU7KiN|N}QTaQj!$r3p zz^IaK;4Q-Wa&+8k&@C9+T*(;zA=ad0qS~xgvI6vKw*euxhWUWVAa$w_zk-KyXXbDI zwOorIWfw8YxDGL%K=+^r6lv~)Nd8=_$Y40DFo^_U$+f!%UD@MiG&5p2nrg5fK(jjP8lLkEIeA{IQb2 zo`m$pARlZzv51d3Sbnw3UTvp`>cJ1LK)*YazH=CwIWRqm9^q5=c5l!LHbkZg|051MP~w_Or=^W!ooK092Dg?Fz9(oPPtT`Pb`DwYqdwlje{P8MDZ! zb75kTw|I+gZ~#2u^Pft!XCV-XrXjL&J*vv3ys;J_J{vofb50ge`31zR5DbucBigAu zg^KsEXZMj6An}FoRGmWnjJ!7l9tf*($g#?)8nHlfNvB=nLRo%%^f>84Y({SRdg%4PC&i4aj60u*!H1 z>q=Eo*^zw2C*>LGQC!%nf?(Va-YcF5;Z-bdp4Q-tgews5j`W%-7v^Icfy8zL-la#KIbrvA~B z{&-9JRXd1GH_Z>0a@+!XieIxote^MQNk{+F`jD~oqiahbNXAM1DXJbxHXtOQO1~PV zoF^n158kg4tDg0&DDtdr_9^}09GamtzG3-}D7cezZZ%n(nqp#{QZWLM^rn&s!9KJa zBrCAT9dkf9Jn|{DcB&YxerirL$4YDVppsUA9C#ekWFGX~^GTczI?}KTX(Wh{*z@%m)obg=uiM4=*poHbm6j%s+O{@~;+5?h!sB|qj@AG8&oxduNM6hY4 z6U@7xc6qLv)*%`I031;E0V9Ym(ScGGryL4K&T9##P}7{#cAigKkOS#hzBAXYv`san zk<>q6O=QtgyLKt~`^1*I4w&p*dAQ(ruO{&Rm8$sf#W^ATklAL(0B5Jxkt5Z-b>d+f z1~Koz^aDLjd#8i6D=!OZNo@>k=M~E_139eQyU^PFsIj4GmR=muqq4J&Rg__lD~I^2 zh0D|mNK(cXDANF*R|k+w~I!SQ?IRnLsIH;72_+9AYY zPB&KvDU#tznOv~y8I3}U%KKZA20oQhvWXI#l(jVNz>P67hm7=L)|q<-K$0=I9=PdA zX!69W7;aYYS};eDB#WGVpUExe1g<_$`#NW1ZOJ1A|T$!-e4-bO*gFg~|~myHLIgc0Qk4y=xQ1`=emNzbct5 z!$?42tVb$(8d&XSw^O&LboTWW2)`5qV3AMH)sz~)2bblQ+5<4i^{jhlCAUQQWjQLx zk@!}{jocSYwGXDULI^AZ5;4lT3 z_<{7Po*?7QgbW^bkKwFFmB%cQ-Ab&)A3{H^UU0Cm465o!40={nP%N{bCkXx2@G8xv z@waBSx{H!9Gt=;)j?A#O>Pcvs2p@VT>VB1G!c>8XP0CMZ8O2t07~csb4#%xcD(_Tv z&Pd}OzO;hYG@+4h*he=6e-WoLTv;#xl82Qiy;D|^RT5$l=Z6D>R*lT@kqpco3CQO- z{AdEqUR=4E93;c|4tb=OHf+fQ6qopuvwbQ%r1KG8--lkuy)C4Q>zOwR7vC75Xqm1S zUoI`L6w18r;1gPDA@buc3{D67-j$yxmo5_JO6TssaZgckZcG;iWrc^zN#>IouP>Hb zIT}zHav6G5*N+X(-#mG22L(qJlWhJ}Mm@omxC6S?>va24v_O*>9OtUi0%35GCzU){ z9Rm@;sP3R~gAm-TG6)=0wwvIL$0zUNJafqvbeO!o)?u(m-0mrJ0YPsSWkE9SEB9Ov zl-9+Y8JEq3F$Da>u0PMUQ&GISYa`evpJv6QAH$wh`qFJNn#Oin!fYzX zl7ITu3rXeN6SY!BInVI7;aBV)-&2ilH^!2c!8!c+r%7g}ZL=m=50^bnLsl6KS37S6 zyFxiRWdn-PkIR}(&=uS{We1AMyha6?j`hLD-l~1++H8go-lGpgidO>F=3~~2>qKy|1_m;6*{9vl6wz&p zKwkvl8ivLvfCroB#~$3!QBFG+iOi5YG7OiG)OuCOb!fK)Xx&ffDtY$s>6PO+^{SJ> z4D1Y>k%v+TS~mnubrd&@v&AROr_z(`(*FR@Q~6b86WGWJ%&`;LRNvZBf6oa&S}Z%C z|J3@*-4@C$yS{a5hO?+@g00f*< zSe>~hk(lDK{6(uRv~3z6obf;r_@h@_bn;_4YRJ*-CAqm1%y$xVgW8*>SsDDgDreB zq^;G$19a<>NaR;MwK^4`i(d~sFKOXT9xzZn!=Nn3t!I2f@iZE3lanHsAf9_w?;LoB zEk4ntX9h!^tD5-(_L%suAZhf=8TZd7Lojc;Ju7TI1-m&a)n-ra8}U+0`^j{TI^eM< z5<0gv;c_c8m(J|{?Dwkf^G|fsI};zn1+=OVR0bMoifr&s~` zlac(YPa&2~@q>}nRogg&V8)<7aBG@%1!4;*gRU}m_w^Md_JuIm&$z3xKt@W9ta^%` zEGm^@$?aUStkWvS4bGn|qmj^m-IVYTyI!#eDfvvkSyuAVpnAGrVn)EcjGYYURM zWP*O=gSBf6OX^F3l?)94*>Hy$;fG4GHKft7mff@8gI0uc+bY}LD3%xduA?;dfWh;u zo8dfx+*Y?tf=w~vk#Qg~$~h;cUVCFP5`4RtjmzGniU?+m5tcaXij5lL&R@7*6TxNZ z52>h?`V>QXX|iC7gWO`65Us|;+dZW zc;YtP4;ZTn8QesQr7_pIG{Y3JJ_a-VC$XzANTr9IHuH@3tG`lgMG~u`hZ~3Rx_#yP z)a44V%-e_XwLRdE%q)Wh_Z1`x$~jGhj9eQDe*Iw+%M z1~BGedBEVGO1A{Et0<8Q6W1N+8)i^)IDw&Q;d9gB=Q_mTzkch%|`HxfDh9pZW23BZg8^5~U>b-^H znf}i@g?wW@jY%pfbPRLc6+J1|w$}29`8dn3 zO#Leg+Ui8OkH|cnC{x^4v^Q|cA&Os-zUaZmPqh{ci953s9(I%1_o{P3vK`pi$~Oa7 zbtv{kuHSpJeQJ<>xeQ4(l$r)YZe@t#W4r;_^HW6MYk { + if (Bangle.isCharging()) return COLORS.charging; + if (l >= 30) return COLORS.high; + return COLORS.low; + }; + + function draw() { + var s = 29; + var x = this.x, y = this.y; + + const l = E.getBattery(); + + let xl = x+4+l*(s-12)/100; + + g.setColor(COLORS.white); + // g.fillRect(x+2,y+5,x+s-6,y+18); + + g.fillRect(x,y,xl+4,y+16+3); //Clear + + g.setColor(levelColor(l)); + // g.fillRect(x+1,y+3,x+s-5,y+4); + // g.fillRect(x+1,y+19,x+s-5,y+20); + // g.fillRect(x,y+4,x+1,y+19); + // g.fillRect(x+s-5,y+4,x+s-4,y+19); + //g.fillRect(x+s-3,y+8,x+s-2,y+16); // tip of the battery + g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar + + g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar full + + g.setColor(COLORS.black); + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(l, x + 14, y + 10); + + if (Bangle.isCharging()) changeInterval(id, intervalHigh); + else changeInterval(id, intervalLow); + } + + + Bangle.on('charging',function(charging) { draw(); }); + var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); + + WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; +})(); diff --git a/apps/hwid_a_battery_widget/widget.png b/apps/hwid_a_battery_widget/widget.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c9594b15c9832c0c5632044ae68989ff5f8cba GIT binary patch literal 877 zcmV-z1CsoSP)kEXCn{4Izi|(P5>F#v86JekZe56yURMlVS)agELvk4O>OqeiXb7r^O zZBD0i!{_sDc)i|vZ0m;R#r%97rVNWuCX>$#g~DIr5AlomNo0uc#4+)S_&~fT-Vlex zYXbj^5>JSS#6EGKxJTR}ZV@+#Ys47aH3bttea}Z(5u=6y?@9}udrqk&uCX)#V zziY8fpZW3e8$`eprVOD%1N^{XYKHc~V8Cj%8Y>oym}~~Lbvhl^@Ant>QJVv8)aMey z$*cey4UpCoP_NfnC=_BYm+J(#+s(msEEZ$sa+w8#!I^d?i9~{XKtsRjUhl5||ayh-Bmk@xLwsU-bmcPY4n42o|5oWLT@!;<1iUfk%`fgs`est4vN3 z8Uij_74X@J0QA9Ol*0+1_>SFex7*wkYT;ubgf^`T__9cVym;(5b{>m|C**X9EL5pf zShLyWAtr}fKA-2FfCzX&L%?OL0zNJhfXU^sNvG2@X;GP}(8q*;ZL0!~j0nIYuo%R< zG92_WmBA3YVpYI9qaMI69u)yQRs|ejBJ3I#Pt7YqD|N2J1JSeYf#{h%1E_>(fTwcS(5tGJMJrpWRAg68 zS7fL~sU|&7gFKdM+I^|UeTKs=)xI$zA%X8NB@Q5-ctkvqYT>)YZQ`a>4_}vR;ytM@ z-ocJ5*rWM Date: Sat, 11 Jun 2022 15:55:03 +0200 Subject: [PATCH 055/121] Improve median calculation Do no longer show 3h average pressure in widget --- apps/widbaroalarm/README.md | 2 +- apps/widbaroalarm/widget.js | 74 +++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index a74d89546..80ba35abc 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -19,7 +19,7 @@ Get a notification when the pressure reaches defined thresholds. * Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min ## Widget -The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. +The widget shows the last median pressure value ## Creator Marco ([myxor](https://github.com/myxor)) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 721d0bbb8..00456f42f 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -37,8 +37,12 @@ E.showPrompt(body, { title: "Pressure alarm", - buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } - }).then(function (v) { + buttons: { + "Ok": 1, + "Dismiss": 2, + "Pause": 3 + } + }).then(function(v) { const tsNow = Math.round(Date.now() / 1000); // seconds if (v == 1) { @@ -176,45 +180,38 @@ } - - function baroHandler(data) { - if (data) { - const pressure = Math.round(data.pressure); - if (pressure == undefined || pressure <= 0) return; - currentPressures.push(pressure); - } - } - /* turn on barometer power - take `numberOfMeasurements` measurements with a delay of 1000ms each + take multiple measurements sort the results take the middle one (median) turn off barometer power */ function check() { + const MEDIANLENGTH = 20; Bangle.setBarometerPower(true, "widbaroalarm"); - setTimeout(function() { - currentPressures = []; + Bangle.on('pressure', function(e) { + while (currentPressures.length > MEDIANLENGTH) currentPressures.pop(); + currentPressures.unshift(e.pressure); + median = currentPressures.slice().sort(); - const numberOfMeasurements = 7; - - for (let i = 0; i < numberOfMeasurements; i++) { - setTimeout(function() { - Bangle.getPressure().then(baroHandler); - }, i * 1000); + if (median.length > 10) { + var mid = median.length >> 1; + medianPressure = Math.round(E.sum(median.slice(mid - 4, mid + 5)) / 9); + if (medianPressure > 0) { + turnOff(); + checkForAlarms(medianPressure); + } } + }); - setTimeout(function() { - Bangle.setBarometerPower(false, "widbaroalarm"); + setTimeout(function() { + turnOff(); + }, 10000); + } - currentPressures.sort(); - - // take median value - medianPressure = currentPressures[Math.round(numberOfMeasurements / 2) + 1]; - checkForAlarms(medianPressure); - }, numberOfMeasurements * 1000 + 500); - }, 500); + function turnOff() { + Bangle.setBarometerPower(false, "widbaroalarm"); } function reload() { @@ -222,8 +219,8 @@ } function draw() { - if (global.WIDGETS != undefined && typeof WIDGETS === "object") { - WIDGETS["baroalarm"] = { + if (global.WIDGETS != undefined && typeof global.WIDGETS === "object") { + global.WIDGETS["baroalarm"] = { width: setting("show") ? 24 : 0, reload: reload, area: "tr", @@ -235,18 +232,13 @@ if (setting("show") && medianPressure != undefined) { g.setFont("6x8", 1).setFontAlign(1, 0); g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); - if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { - g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); - } } } - // Let's delay the first check a bit - setTimeout(function() { - check(); - if (interval > 0) { - setInterval(check, interval * 60000); - } - }, 1000); + check(); + if (interval > 0) { + setInterval(check, interval * 60000); + } + draw(); })(); From e6515080e85e4ef2d1ba081ec453abdcbec51263 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 17:46:36 +0200 Subject: [PATCH 056/121] Fixing refresh issues --- apps/hwid_a_battery_widget/ChangeLog | 3 +- apps/hwid_a_battery_widget/metadata.json | 2 +- apps/hwid_a_battery_widget/widget.js | 92 ++++++++++++------------ 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog index 84cbad8ad..3d7b39737 100644 --- a/apps/hwid_a_battery_widget/ChangeLog +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -2,4 +2,5 @@ 0.02: Internal id update to wid_* as per Gordon's request (2021/11/21) 0.03: Support dark themes 0.04: Increase screen update rate when charging -0.05: Deleting Background - making Font larger \ No newline at end of file +0.05: Deleting Background - making Font larger +0.06: Fixing refresh issues \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/metadata.json b/apps/hwid_a_battery_widget/metadata.json index 7fdd2907a..d0cb5233a 100644 --- a/apps/hwid_a_battery_widget/metadata.json +++ b/apps/hwid_a_battery_widget/metadata.json @@ -3,7 +3,7 @@ "name": "A Battery Widget (with percentage) - Hanks Mod", "shortName":"H Battery Widget", "icon": "widget.png", - "version":"0.04", + "version":"0.06", "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", diff --git a/apps/hwid_a_battery_widget/widget.js b/apps/hwid_a_battery_widget/widget.js index 0929dea41..708e8cbbf 100644 --- a/apps/hwid_a_battery_widget/widget.js +++ b/apps/hwid_a_battery_widget/widget.js @@ -1,56 +1,54 @@ (function(){ - const intervalLow = 60000; // update time when not charging - const intervalHigh = 2000; // update time when charging + const intervalLow = 60000; // update time when not charging + const intervalHigh = 2000; // update time when charging + var old_l; - let COLORS = { - 'white': g.theme.dark ? "#000" : "#fff", - 'black': g.theme.dark ? "#fff" : "#000", - 'charging': "#08f", - 'high': g.theme.dark ? "#fff" : "#000", - 'low': "#f00", - }; + let COLORS = { + 'white': g.theme.dark ? "#000" : "#fff", + 'black': g.theme.dark ? "#fff" : "#000", + 'charging': "#08f", + 'high': g.theme.dark ? "#fff" : "#000", + 'low': "#f00", + }; - const levelColor = (l) => { - if (Bangle.isCharging()) return COLORS.charging; - if (l >= 30) return COLORS.high; - return COLORS.low; - }; + const levelColor = (l) => { + if (Bangle.isCharging()) return COLORS.charging; + if (l >= 30) return COLORS.high; + return COLORS.low; + }; - function draw() { - var s = 29; - var x = this.x, y = this.y; + function draw() { + var s = 29; + var x = this.x, y = this.y; + const l = E.getBattery(); + let xl = x+4+l*(s-12)/100; + if (l != old_l){ // Delete the old value from screen + old_l = l; + let xl_old = x+4+old_l*(s-12)/100; + g.setColor(COLORS.white); + // g.fillRect(x+2,y+5,x+s-6,y+18); + g.fillRect(x,y,xl+4,y+16+3); //Clear + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(old_l, x + 14, y + 10); + g.fillRect(x+4,y+14+3,xl_old,y+16+3); // charging bar + } - const l = E.getBattery(); + g.setColor(levelColor(l)); + g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar + g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar "full mark" + // Show percentage + g.setColor(COLORS.black); + g.setFontAlign(0,0); + g.setFont('Vector',16); + g.drawString(l, x + 14, y + 10); - let xl = x+4+l*(s-12)/100; + if (Bangle.isCharging()) changeInterval(id, intervalHigh); + else changeInterval(id, intervalLow); + } - g.setColor(COLORS.white); - // g.fillRect(x+2,y+5,x+s-6,y+18); + Bangle.on('charging',function(charging) { draw(); }); + var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); - g.fillRect(x,y,xl+4,y+16+3); //Clear - - g.setColor(levelColor(l)); - // g.fillRect(x+1,y+3,x+s-5,y+4); - // g.fillRect(x+1,y+19,x+s-5,y+20); - // g.fillRect(x,y+4,x+1,y+19); - // g.fillRect(x+s-5,y+4,x+s-4,y+19); - //g.fillRect(x+s-3,y+8,x+s-2,y+16); // tip of the battery - g.fillRect(x+4,y+14+3,xl,y+16+3); // charging bar - - g.fillRect((x+4+100*(s-12)/100)-1,y+14+3,x+4+100*(s-12)/100,y+16+3); // charging bar full - - g.setColor(COLORS.black); - g.setFontAlign(0,0); - g.setFont('Vector',16); - g.drawString(l, x + 14, y + 10); - - if (Bangle.isCharging()) changeInterval(id, intervalHigh); - else changeInterval(id, intervalLow); - } - - - Bangle.on('charging',function(charging) { draw(); }); - var id = setInterval(()=>WIDGETS["wid_a_battery_widget"].draw(), intervalLow); - - WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; + WIDGETS["wid_a_battery_widget"]={area:"tr",width:30,draw:draw}; })(); From 5c8ba46ea96159da3e8fc23daf5f7845f4698435 Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 17:49:47 +0200 Subject: [PATCH 057/121] Version 0.10 - Show daily step count, temperature as well as heartrate. --- apps/cassioWatch/ChangeLog | 3 +- apps/cassioWatch/README.md | 3 +- apps/cassioWatch/app.js | 61 ++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/apps/cassioWatch/ChangeLog b/apps/cassioWatch/ChangeLog index f00b3fa0a..419810021 100644 --- a/apps/cassioWatch/ChangeLog +++ b/apps/cassioWatch/ChangeLog @@ -7,4 +7,5 @@ 0.6: Add Settings Page 0.7: Update Rocket Sequences Scope to not use memory all time 0.8: Update Some Variable Scopes to not use memory until need -0.9: Remove ESLint spaces \ No newline at end of file +0.9: Remove ESLint spaces +0.10: Show daily steps, heartrate and the temperature if weather information is available. \ No newline at end of file diff --git a/apps/cassioWatch/README.md b/apps/cassioWatch/README.md index 1342af8e6..aaeb3f122 100644 --- a/apps/cassioWatch/README.md +++ b/apps/cassioWatch/README.md @@ -6,5 +6,6 @@ Clock with Space Cassio Watch Style. It displays current temperature,day,steps,battery.heartbeat and weather. + **To-do**: -Integrate heartbeat and Weather, Align and change size of some elements. +Align and change size of some elements. diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 93538ec50..49e23c2eb 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -1,7 +1,11 @@ +const storage = require('Storage'); +const locale = require('locale'); + require("Font6x12").add(Graphics); require("Font8x12").add(Graphics); require("Font7x11Numeric7Seg").add(Graphics); + let ClockInterval; let RocketInterval; let BatteryInterval; @@ -43,7 +47,7 @@ function getRocketSequences() { let rocket_sequence = 1; -let settings = require('Storage').readJSON("cassioWatch.settings.json", true) || {}; +let settings = storage.readJSON("cassioWatch.settings.json", true) || {}; let rocketSpeed = settings.rocketSpeed || 700; delete settings; @@ -82,6 +86,43 @@ function DrawRocket() { if (rocket_sequence > 8) rocket_sequence = 1; } +function getTemperature(){ + try { + var weatherJson = storage.readJSON('weather.json'); + var weather = weatherJson.weather; + return Math.round(weather.temp-273.15); + + } catch(ex) { + print(ex) + return "?" + } +} + +function getSteps() { + var steps = 0; + try{ + if (WIDGETS.wpedom !== undefined) { + steps = WIDGETS.wpedom.getSteps(); + } else if (WIDGETS.activepedom !== undefined) { + steps = WIDGETS.activepedom.getSteps(); + } else { + steps = Bangle.getHealthStatus("day").steps; + } + } catch(ex) { + // In case we failed, we can only show 0 steps. + return "? k"; + } + + // Show always 2 digits. E.g. 1.5k if < 10000 otherwise 12k + if(steps > 10000){ + steps = Math.round(steps/1000); + } else { + steps = Math.round(steps/100) / 10; + } + return steps + "k"; +} + + function DrawScene() { g.reset(); g.clear(); @@ -94,17 +135,22 @@ function DrawScene() { g.drawString("Launching Process", 30, 20); g.setFont("8x12"); g.drawString("ACTIVATE", 40, 35); + + g.setFontAlign(0,-1); g.setFont("8x12", 2); - g.drawString("30", 142, 132); - g.drawString("55", 95, 98); - g.setFont("8x12", 1); - g.drawString(Bangle.getStepCount(), 143, 104); + g.drawString(getTemperature(), 155, 132); + g.drawString(Math.round(Bangle.getHealthStatus("last").bpm), 109, 98); + g.drawString(getSteps(), 158, 98); + + g.setFontAlign(-1,-1); ClockInterval = setInterval(DrawClock, 30000); DrawClock(); RocketInterval = setInterval(DrawRocket, rocketSpeed); DrawRocket(); BatteryInterval = setInterval(DrawBattery, 5 * 60000); DrawBattery(); + + for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } Bangle.on("lcdPower", (on) => { @@ -123,6 +169,11 @@ Bangle.on("lock", (locked) => { } }); + +// Load widgets, but don't show them +Bangle.loadWidgets(); + + g.reset(); g.clear(); Bangle.setUI("clock"); From 8295cc794e6e074735a6cbbd47c9ec316318516d Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 17:58:15 +0200 Subject: [PATCH 058/121] Update version to 0.10 --- apps/cassioWatch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cassioWatch/metadata.json b/apps/cassioWatch/metadata.json index 70cd9c242..dabdc2c93 100644 --- a/apps/cassioWatch/metadata.json +++ b/apps/cassioWatch/metadata.json @@ -4,7 +4,7 @@ "description": "Animated Clock with Space Cassio Watch Style", "screenshots": [{ "url": "screens/screen_night.png" },{ "url": "screens/screen_day.png" }], "icon": "app.png", - "version": "0.9", + "version": "0.10", "type": "clock", "tags": "clock, weather, cassio, retro", "supports": ["BANGLEJS2"], From 3ec548c922de3d9f60b6f7db55d2c15d372e2ee2 Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 17:58:18 +0200 Subject: [PATCH 059/121] Prepare new version --- apps/hwid_a_battery_widget/ChangeLog | 3 ++- apps/hwid_a_battery_widget/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/hwid_a_battery_widget/ChangeLog b/apps/hwid_a_battery_widget/ChangeLog index 3d7b39737..9d5ee1264 100644 --- a/apps/hwid_a_battery_widget/ChangeLog +++ b/apps/hwid_a_battery_widget/ChangeLog @@ -3,4 +3,5 @@ 0.03: Support dark themes 0.04: Increase screen update rate when charging 0.05: Deleting Background - making Font larger -0.06: Fixing refresh issues \ No newline at end of file +0.06: Fixing refresh issues +0.07 \ No newline at end of file diff --git a/apps/hwid_a_battery_widget/metadata.json b/apps/hwid_a_battery_widget/metadata.json index d0cb5233a..38fd503a2 100644 --- a/apps/hwid_a_battery_widget/metadata.json +++ b/apps/hwid_a_battery_widget/metadata.json @@ -3,7 +3,7 @@ "name": "A Battery Widget (with percentage) - Hanks Mod", "shortName":"H Battery Widget", "icon": "widget.png", - "version":"0.06", + "version":"0.07", "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", From 99cdfdb8d48603baae38cf9c347b79a42653933d Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:15:27 +0200 Subject: [PATCH 060/121] Removing obsolete stuff --- apps/hworldclock/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 8122371a6..1358b81d2 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -246,7 +246,6 @@ setInterval(drawSeconds, 1E3); Bangle.on('lcdPower',on=>{ if (on) { draw(); // draw immediately, queue redraw - drawSeconds(); // draw immediately, queue redraw setInterval(updatePos, 60*5E3); // refesh every 5 mins setInterval(drawSeconds, 1E3); updatePos(); @@ -262,5 +261,4 @@ Bangle.on('lcdPower',on=>{ }); // draw now -drawSeconds(); draw(); From b5c3607ca192bf3d9a37dd8b9fdf69572148e8ae Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:22:37 +0200 Subject: [PATCH 061/121] Version Info --- apps/hworldclock/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 1358b81d2..f724c35d9 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -129,6 +129,7 @@ function drawSeconds() { g.setColor("#22ff05"); //g.setFont(font, primaryTimeFontSize-3); g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); + queueDraw(); } function draw() { @@ -238,7 +239,7 @@ Bangle.setUI("clock"); Bangle.loadWidgets(); Bangle.drawWidgets(); updatePos(); -setInterval(drawSeconds, 1E3); +setInterval(drawSeconds, 1E3/2); From 3e0a5af414e57e39b55808e2d4a394e44c320fef Mon Sep 17 00:00:00 2001 From: Dennis Kueper Date: Sat, 11 Jun 2022 18:22:56 +0200 Subject: [PATCH 062/121] Version Info --- apps/hworldclock/ChangeLog | 1 + apps/hworldclock/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 5b2a1edce..e67af806a 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1 +1,2 @@ 0.15: Initial release - be patient as this is the first try :) +0.16: Fix timing \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index e9e0175f5..4f3cd80cf 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.15", + "version": "0.16", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From e1180c88d23cc21c48f99e0a9c1f8b9b25d14e78 Mon Sep 17 00:00:00 2001 From: David Peer Date: Sat, 11 Jun 2022 19:08:37 +0200 Subject: [PATCH 063/121] Use interval for animation and timeout for time to ensure that the time changes precisely. --- apps/cassioWatch/app.js | 90 ++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 49e23c2eb..75ec85503 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -1,15 +1,9 @@ const storage = require('Storage'); -const locale = require('locale'); require("Font6x12").add(Graphics); require("Font8x12").add(Graphics); require("Font7x11Numeric7Seg").add(Graphics); - -let ClockInterval; -let RocketInterval; -let BatteryInterval; - function bigThenSmall(big, small, x, y) { g.setFont("7x11Numeric7Seg", 2); g.drawString(big, x, y); @@ -18,16 +12,6 @@ function bigThenSmall(big, small, x, y) { g.drawString(small, x, y); } -function ClearIntervals(inoreclock) { - if (RocketInterval) clearInterval(RocketInterval); - if (BatteryInterval) clearInterval(BatteryInterval); - RocketInterval = undefined; - BatteryInterval = undefined; - if (inoreclock) return; - if (ClockInterval) clearInterval(ClockInterval); - ClockInterval = undefined; -} - function getBackgroundImage() { return require("heatshrink").decompress(atob("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")); } @@ -45,15 +29,31 @@ function getRocketSequences() { }; } -let rocket_sequence = 1; - +let rocketSequence = 1; let settings = storage.readJSON("cassioWatch.settings.json", true) || {}; let rocketSpeed = settings.rocketSpeed || 700; delete settings; -g.clear(); +// schedule a draw for the next minute +let rocketInterval; +var drawTimeout; +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} -function DrawClock() { + +function clearIntervals() { + if (rocketInterval) clearInterval(rocketInterval); + rocketInterval = undefined; + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; +} + +function drawClock() { g.setFont("7x11Numeric7Seg", 3); g.clearRect(80, 57, 170, 96); g.setColor(0, 255, 255); @@ -70,20 +70,20 @@ function DrawClock() { g.drawString(time < 10 ? "0" + time : time, 78, 137); } -function DrawBattery() { +function drawBattery() { bigThenSmall(E.getBattery(), "%", 135, 21); } -function DrawRocket() { +function drawRocket() { let Rocket = getRocketSequences(); g.clearRect(5, 62, 63, 115); g.setColor(0, 255, 255); g.drawRect(5, 62, 63, 115); g.fillRect(5, 62, 63, 115); - g.drawImage(Rocket[rocket_sequence], 5, 65, { scale: 0.7 }); + g.drawImage(Rocket[rocketSequence], 5, 65, { scale: 0.7 }); g.setColor(0, 0, 0); - rocket_sequence = rocket_sequence + 1; - if (rocket_sequence > 8) rocket_sequence = 1; + rocketSequence = rocketSequence + 1; + if(rocketSequence > 8) rocketSequence = 1; } function getTemperature(){ @@ -123,7 +123,9 @@ function getSteps() { } -function DrawScene() { +function draw() { + queueDraw(); + g.reset(); g.clear(); g.setColor(0, 255, 255); @@ -143,42 +145,36 @@ function DrawScene() { g.drawString(getSteps(), 158, 98); g.setFontAlign(-1,-1); - ClockInterval = setInterval(DrawClock, 30000); - DrawClock(); - RocketInterval = setInterval(DrawRocket, rocketSpeed); - DrawRocket(); - BatteryInterval = setInterval(DrawBattery, 5 * 60000); - DrawBattery(); + drawClock(); + drawRocket(); + rocketSequence -= 1; // This avoids a "jump" in the animation + drawBattery(); for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } Bangle.on("lcdPower", (on) => { - if (!on) { - g.clear(); - ClearIntervals(true); + if (on) { + draw(); + } else { + clearIntervals(); } }); + Bangle.on("lock", (locked) => { - if (locked) { - ClearIntervals(true); - } else { - ClearIntervals(); - DrawScene(); + clearIntervals(); + draw(); + if (!locked) { + rocketInterval = setInterval(drawRocket, rocketSpeed); } }); // Load widgets, but don't show them Bangle.loadWidgets(); - +Bangle.setUI("clock"); g.reset(); g.clear(); -Bangle.setUI("clock"); -DrawScene(); - -if (Bangle.isLocked()) { - ClearIntervals(true); -} \ No newline at end of file +draw(); \ No newline at end of file From 1a3b8e5446a26a7a73973d4148c7fb920dcb81ce Mon Sep 17 00:00:00 2001 From: pebl-hank Date: Sat, 11 Jun 2022 23:08:03 +0200 Subject: [PATCH 064/121] Fix hours --- apps/hworldclock/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index f724c35d9..c37ec5714 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -163,7 +163,7 @@ function draw() { //g.setFont(font, primaryTimeFontSize); g.setFont("5x9Numeric7Seg",primaryTimeFontSize); g.setColor("#22ff05"); - g.drawString(`${doublenum(hours)}:${minutes}`, xyCenter-10, yposTime, true); + g.drawString(`${hours}:${minutes}`, xyCenter-10, yposTime, true); // am / PM ? if (_12hour){ From 223ee5043535dd61f2684dbf91048865f64a6f53 Mon Sep 17 00:00:00 2001 From: pancake Date: Sun, 12 Jun 2022 02:36:39 +0200 Subject: [PATCH 065/121] football: Upgrade to 1.01. Works with BTN1 --- apps/football/ChangeLog | 1 + apps/football/app.js | 76 +++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/apps/football/ChangeLog b/apps/football/ChangeLog index 9b91672a5..66b9882cc 100644 --- a/apps/football/ChangeLog +++ b/apps/football/ChangeLog @@ -1 +1,2 @@ 1.00: Initial implementation +1.01: Bug fixes and performance and visual improvements diff --git a/apps/football/app.js b/apps/football/app.js index 8350bea88..d12f07e2b 100644 --- a/apps/football/app.js +++ b/apps/football/app.js @@ -1,4 +1,19 @@ +// globals. TODO: move into an object const digit = []; +let part = 0; +let endInc = 0; +var endGame = false; +let goalFrame = 0; +var stopped = true; +let score0 = 0; +let score1 = 0; +let inc = 0; +let msinc = 0; +let seq0 = 0; +let seq1 = 0; +let goaler = -1; +const w = g.getWidth(); +let owner = -1; const dash = { width: 75, @@ -6,6 +21,7 @@ const dash = { bpp: 1, buffer: require('heatshrink').decompress(atob('AH4A/AH4A/AH4A/AH4A/AB0D/4AB+AJEBAX/BAk/CQ8PCQ4kDCQoIDCQgkDCQgkECQgIE4ASHFxH8JRgSEEgYSEPJAkEAH4A/AH4A/AH4A/AH4A/ACg=')) }; + function loadDigits () { digit[0] = { width: 80, @@ -58,8 +74,8 @@ function loadDigits () { digit[7] = { width: 80, height: 128, - bpp: 1, - buffer: require('heatshrink').decompress(atob('AGUH/4AE/wJBgYJF/gJBgIJF+AeCBJN/BIngsAJBn4JE4HgBIMfBImBBIUPBIkDBIRQE/0HBIRQE/kPBIRQE/EfBIRQE+E/BIZQD8AJEKAfABYIJCKAYsBBIYADIAIJHKgIJHNAIJ/BP4J/BP4Jzg//4AJGgf/wAJGgP/BAwAB/wJIvgJInAJIiAJIAH5PPMZJ3JRZCfJWZLHJfM4J/BP4J/BP4JNg4JIgYJIgIJIgAJJv4JIn4JIj4JIh4JIeg4JIgYJIgIJIgAJJsAJIkAJIAH4AQA=')) + bpp: 4, + buffer : require("heatshrink").decompress(atob("AH4A/AEtVADdQE5Nf/4AayAnJgoma/J4LKDR2KKDZODUMadChKhiJwefE5RQXJwbxLKCxOEE5hQVJwgnNKCZOFE5pQTJwonOKCJOGE5xQRD4Q8EE5xQPJw4nPgFZzIAMqCdFE6IARJwgnhJwonhJwonhe5In/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4nlr4mE/NQE78FE4n1Ez5QGE0JQEJ0RQETsBQFJ0gABrJOkAH4A/AH4A/ADNZqAmkgv/yAnkr///JQjJwIABypOkAAP5J0oABUMJODKAShgEwhQiE/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/E/4n/AA+fE80JE8xQGE8JQFE8JQFE8RQEE8RQEE8ZQDE8ZQDE8hQCE8hQCE8pQBE8pQBE80JE80AE84A/AH4A/AH4A/AAQA==")) }; digit[8] = { @@ -170,9 +186,6 @@ const gol11 = { loadDigits(); -let goalFrame = 0; -let score0 = 0; -let score1 = 0; function printNumber (n, x, y, options) { if (n > 9 || n < -1) { @@ -197,13 +210,7 @@ function printNumber (n, x, y, options) { g.drawImage(img, x, y, options); } } -let inc = 0; -let msinc = 0; -let seq0 = 0; -let seq1 = 0; -let goaler = -1; -const w = g.getWidth(); -let owner = -1; + g.setBgColor(0, 0, 0); g.clear(); g.setColor(1, 1, 1); @@ -247,43 +254,63 @@ function onStop () { refresh(); refresh_ms(); } -var stopped = true; -Bangle.on('tap', function (pos) { - console.log('touch', pos); + +function onButtonPress() { + console.log('on.tap'); + setWatch(() => { + onButtonPress(); +}, BTN1); + Bangle.beep(); if (endGame) { - Bangle.beep(); score0 = 0; score1 = 0; seq0 = 0; seq1 = 0; + part = 0; inc = 0; msinc = 0; stopped = true; endGame = false; } else { if (inc == 0) { - autogame(); + // autogame(); + stopped = false; } else { onStop(); } } +} + +setWatch(() => { + onButtonPress(); +}, BTN1); +/*Bangle.on('tap', function () { + onButtonPress(); }); +*/ g.setFont12x20(3); -let part = 0; -let endInc = 0; -var endGame = false; + function refresh () { g.clear(); if (inc > 59) { inc = 0; part++; } + if (part >= 2 && inc > 30) { + part = 2; + Bangle.buzz(); + endGame = true; + endInc = inc; + inc = 0; + } if (inc > 44) { + inc = 0; if (part < 2) { part++; } if (part >= 2) { if (score0 != score1) { + Bangle.buzz(); endGame = true; endInc = inc; inc = 0; @@ -342,6 +369,12 @@ function refresh_pixels () { let bx = (owner == 0) ? w / 3 : w / 2; bx += 2; g.drawImage(frame4 ? ball0 : ball1, bx, 10, { scale: 5 }); + const liney = 60; + if (owner) { + g.drawLine(w-8, liney, 2*(w/3), liney); + } else { + g.drawLine(8, liney, w/3, liney); + } } let dots = 0; function refresh_dots () { @@ -437,4 +470,5 @@ function autogame () { } Bangle.setOptions({ lockTimeout: 0, backlightTimeout: 0 }); -autogame(); +// autogame(); + From 7fcd86b4bca38585693ca66ac17876108b60f723 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sun, 12 Jun 2022 10:39:48 +0200 Subject: [PATCH 066/121] sleepphasealarm: Replace setInterval with setTimeout --- apps/sleepphasealarm/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 23df53b22..92f4b3dc7 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -97,10 +97,13 @@ function drawApp() { layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0'); layout.render(); } + + setTimeout(()=>{ + drawTime(); + }, 1000 - (Date.now() % 1000)); } drawTime(); - setInterval(drawTime, 500); // 2Hz } function buzz() { From b5f3930c41cc7f20a14f1f5ee19ce8d3bf969abd Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 11:24:29 +0200 Subject: [PATCH 067/121] Improve widget drawing code & fix some typos --- apps/widbaroalarm/ChangeLog | 2 +- apps/widbaroalarm/README.md | 4 ++-- apps/widbaroalarm/widget.js | 19 ++++++++++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/widbaroalarm/ChangeLog b/apps/widbaroalarm/ChangeLog index 0afe4bc8b..86a902605 100644 --- a/apps/widbaroalarm/ChangeLog +++ b/apps/widbaroalarm/ChangeLog @@ -1,5 +1,5 @@ 0.01: Initial version -0.02: Do not warn multiple times for the same exceedance +0.02: Do not warn multiple times for the same exceed 0.03: Fix crash 0.04: Use Prompt with dismiss and pause Improve barometer value median calculation diff --git a/apps/widbaroalarm/README.md b/apps/widbaroalarm/README.md index 80ba35abc..59d91ff66 100644 --- a/apps/widbaroalarm/README.md +++ b/apps/widbaroalarm/README.md @@ -16,10 +16,10 @@ Get a notification when the pressure reaches defined thresholds. * Show widget: Enable/disable widget visibility * Buzz on alarm: Enable/disable buzzer on alarm * Dismiss delay: Delay added before the next alert if the alert is dismissed. From 5 to 60 min -* Pause delay: Same as Dismiss delay but longer (usefull for meetings and such). From 30 to 240 min +* Pause delay: Same as Dismiss delay but longer (useful for meetings and such). From 30 to 240 min ## Widget -The widget shows the last median pressure value +The widget shows two rows: pressure value of last measurement and pressure average of the the last three hours. ## Creator Marco ([myxor](https://github.com/myxor)) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 00456f42f..444b63ce6 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -227,11 +227,24 @@ draw: draw }; } - g.reset(); - if (setting("show") && medianPressure != undefined) { + if (setting("show")) { g.setFont("6x8", 1).setFontAlign(1, 0); - g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + if (medianPressure == undefined) { + check(); + const x = this.x, y = this.y; + g.drawString("...", x + 24, y + 6); + setTimeout(function() { + g.setFont("6x8", 1).setFontAlign(1, 0); + g.drawString(Math.round(medianPressure), x + 24, y + 6); + }, 10000); + } else { + g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + } + + if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { + g.drawString(Math.round(threeHourAvrPressure), this.x + 24, this.y + 6 + 10); + } } } From 4dba48f0ace282a1b5ec8d21a7864db251be53db Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:12:06 +0200 Subject: [PATCH 068/121] Improve rais/drop calculation and handling --- apps/widbaroalarm/widget.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 444b63ce6..590c2f316 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -103,8 +103,6 @@ } else { saveSetting("lastLowWarningTs", 0); } - } else { - saveSetting("lastLowWarningTs", 0); } if (setting("highalarm")) { @@ -117,8 +115,6 @@ } else { saveSetting("lastHighWarningTs", 0); } - } else { - saveSetting("lastHighWarningTs", 0); } if (history3.length > 0 && !alreadyWarned) { @@ -127,21 +123,22 @@ const raise3halarm = setting("raise3halarm"); if (drop3halarm > 0 || raise3halarm > 0) { // we need at least 30min of data for reliable detection - if (history3[0]["ts"] > ts - (30 * 60)) { + const diffDateAge = Math.abs(history3[0]["ts"] - ts); + if (diffDateAge < 10 * 60) { // todo change to 1800 return; } // Get oldest entry: const oldestPressure = history3[0]["p"]; if (oldestPressure != undefined && oldestPressure > 0) { - const diff = oldestPressure - pressure; + const diffPressure = Math.abs(oldestPressure - pressure); // drop alarm if (drop3halarm > 0 && oldestPressure > pressure) { - if (Math.abs(diff) > drop3halarm) { + if (diffPressure > drop3halarm) { if (doWeNeedToWarn("lastDropWarningTs")) { - showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure drop", "lastDropWarningTs"); + showAlarm((Math.round(diffPressure * 10) / 10) + " hPa/3h from " + + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "lastDropWarningTs"); } } else { saveSetting("lastDropWarningTs", 0); @@ -152,10 +149,10 @@ // raise alarm if (raise3halarm > 0 && oldestPressure < pressure) { - if (Math.abs(diff) > raise3halarm) { + if (diffPressure > raise3halarm) { if (doWeNeedToWarn("lastRaiseWarningTs")) { - showAlarm((Math.round(Math.abs(diff) * 10) / 10) + " hPa/3h from " + - Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "Pressure raise", "lastRaiseWarningTs"); + showAlarm((Math.round(diffPressure * 10) / 10) + " hPa/3h from " + + Math.round(oldestPressure) + " to " + Math.round(pressure) + " hPa", "lastRaiseWarningTs"); } } else { saveSetting("lastRaiseWarningTs", 0); From da9261446fa3da51f25be7fd738a3e4cec4fcf60 Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:34:30 +0200 Subject: [PATCH 069/121] Further improvements --- apps/widbaroalarm/widget.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 590c2f316..46ac9d480 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -49,9 +49,11 @@ saveSetting(key, tsNow); } if (v == 2) { + // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('dismissDelayMin')); } if (v == 3) { + // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } load(); @@ -196,8 +198,8 @@ var mid = median.length >> 1; medianPressure = Math.round(E.sum(median.slice(mid - 4, mid + 5)) / 9); if (medianPressure > 0) { - turnOff(); - checkForAlarms(medianPressure); + turnOff(); + checkForAlarms(medianPressure); } } }); @@ -208,7 +210,8 @@ } function turnOff() { - Bangle.setBarometerPower(false, "widbaroalarm"); + if (Bangle.isBarometerOn()) + Bangle.setBarometerPower(false, "widbaroalarm"); } function reload() { @@ -228,15 +231,16 @@ if (setting("show")) { g.setFont("6x8", 1).setFontAlign(1, 0); if (medianPressure == undefined) { - check(); - const x = this.x, y = this.y; - g.drawString("...", x + 24, y + 6); - setTimeout(function() { - g.setFont("6x8", 1).setFontAlign(1, 0); - g.drawString(Math.round(medianPressure), x + 24, y + 6); - }, 10000); + check(); + const x = this.x, + y = this.y; + g.drawString("...", x + 24, y + 6); + setTimeout(function() { + g.setFont("6x8", 1).setFontAlign(1, 0); + g.drawString(Math.round(medianPressure), x + 24, y + 6); + }, 10000); } else { - g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); + g.drawString(Math.round(medianPressure), this.x + 24, this.y + 6); } if (threeHourAvrPressure != undefined && threeHourAvrPressure > 0) { @@ -245,7 +249,6 @@ } } - check(); if (interval > 0) { setInterval(check, interval * 60000); } From 02bb0ab481cdcf26699c901ecdd140d088b7922a Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 17:46:25 +0200 Subject: [PATCH 070/121] Calculate 3h average only if data is available --- apps/widbaroalarm/widget.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index 46ac9d480..d8eb43995 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -171,11 +171,15 @@ storage.writeJSON(LOG_FILE, history3); // calculate 3h average for widget - let sum = 0; - for (let i = 0; i < history3.length; i++) { - sum += history3[i]["p"]; + if (history3.length > 0) { + let sum = 0; + for (let i = 0; i < history3.length; i++) { + sum += history3[i]["p"]; + } + threeHourAvrPressure = sum / history3.length; + } else { + threeHourAvrPressure = undefined; } - threeHourAvrPressure = sum / history3.length; } From d7e1cf704decf53bf17f4517fff87bbc09604c32 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 17:48:07 +0200 Subject: [PATCH 071/121] Fix hours --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index e67af806a..64b2be430 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,2 +1,3 @@ 0.15: Initial release - be patient as this is the first try :) -0.16: Fix timing \ No newline at end of file +0.16: Fix timing +0.17: Fix hours \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 4f3cd80cf..794992d2f 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.16", + "version": "0.17", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 85a52afbf55725bd999bb94e2e8c1b929a3cc4ed Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 17:50:43 +0200 Subject: [PATCH 072/121] Fix the const reassign bug (cutting edge firmware) and better indentation and scoping --- apps/activityreminder/ChangeLog | 1 + apps/activityreminder/app.js | 81 +++++++------- apps/activityreminder/boot.js | 122 +++++++++++---------- apps/activityreminder/lib.js | 10 +- apps/activityreminder/metadata.json | 2 +- apps/activityreminder/settings.js | 164 ++++++++++++++-------------- 6 files changed, 191 insertions(+), 189 deletions(-) diff --git a/apps/activityreminder/ChangeLog b/apps/activityreminder/ChangeLog index 4edb72aa5..da897b899 100644 --- a/apps/activityreminder/ChangeLog +++ b/apps/activityreminder/ChangeLog @@ -4,3 +4,4 @@ 0.04: Obey system quiet mode 0.05: Battery optimisation, add the pause option, bug fixes 0.06: Add a temperature threshold to detect (and not alert) if the BJS isn't worn. Better support for the peoples using the app at night +0.07: Fix bug on the cutting edge firmware \ No newline at end of file diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index f3d72976e..52dec2928 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,42 +1,43 @@ -function drawAlert() { - E.showPrompt("Inactivity detected", { - title: "Activity reminder", - buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } - }).then(function (v) { - if (v == 1) { - activityreminder_data.okDate = new Date(); +(function () { + function drawAlert() { + E.showPrompt("Inactivity detected", { + title: "Activity reminder", + buttons: { "Ok": 1, "Dismiss": 2, "Pause": 3 } + }).then(function (v) { + if (v == 1) { + activityreminder_data.okDate = new Date(); + } + if (v == 2) { + activityreminder_data.dismissDate = new Date(); + } + if (v == 3) { + activityreminder_data.pauseDate = new Date(); + } + activityreminder.saveData(activityreminder_data); + load(); + }); + + // Obey system quiet mode: + if (!(storage.readJSON('setting.json', 1) || {}).quiet) { + Bangle.buzz(400); + } + setTimeout(load, 20000); } - if (v == 2) { - activityreminder_data.dismissDate = new Date(); + + function run() { + if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { + drawAlert(); + } else { + eval(storage.read("activityreminder.settings.js"))(() => load()); + } } - if (v == 3) { - activityreminder_data.pauseDate = new Date(); - } - activityreminder.saveData(activityreminder_data); - load(); - }); - - // Obey system quiet mode: - if (!(storage.readJSON('setting.json', 1) || {}).quiet) { - Bangle.buzz(400); - } - setTimeout(load, 20000); -} - -function run() { - if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { - drawAlert(); - } else { - eval(storage.read("activityreminder.settings.js"))(() => load()); - } -} - - -const activityreminder = require("activityreminder"); -const storage = require("Storage"); -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -const activityreminder_settings = activityreminder.loadSettings(); -const activityreminder_data = activityreminder.loadData(); -run(); + + const activityreminder = require("activityreminder"); + const storage = require("Storage"); + g.clear(); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + const activityreminder_settings = activityreminder.loadSettings(); + const activityreminder_data = activityreminder.loadData(); + run(); +})(); \ No newline at end of file diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 4ae9548c2..86de0e901 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,65 +1,67 @@ -function run() { - if (isNotWorn()) return; - let now = new Date(); - let h = now.getHours(); +(function () { + function run() { + if (isNotWorn()) return; + let now = new Date(); + let h = now.getHours(); - if (isDuringAlertHours(h)) { - let health = Bangle.getHealthStatus("day"); - if (health.steps - activityreminder_data.stepsOnDate >= activityreminder_settings.minSteps // more steps made than needed - || health.steps < activityreminder_data.stepsOnDate) { // new day or reboot of the watch - activityreminder_data.stepsOnDate = health.steps; - activityreminder_data.stepsDate = now; + if (isDuringAlertHours(h)) { + let health = Bangle.getHealthStatus("day"); + if (health.steps - activityreminder_data.stepsOnDate >= activityreminder_settings.minSteps // more steps made than needed + || health.steps < activityreminder_data.stepsOnDate) { // new day or reboot of the watch + activityreminder_data.stepsOnDate = health.steps; + activityreminder_data.stepsDate = now; + activityreminder.saveData(activityreminder_data); + /* todo in a futur release + Add settimer to trigger like 30 secs after going in this part cause the person have been walking + (pass some argument to run() to handle long walks and not triggering so often) + */ + } + + if (activityreminder.mustAlert(activityreminder_data, activityreminder_settings)) { + load('activityreminder.app.js'); + } + } + + } + + function isNotWorn() { + return (Bangle.isCharging() || activityreminder_settings.tempThreshold >= E.getTemperature()); + } + + function isDuringAlertHours(h) { + if (activityreminder_settings.startHour < activityreminder_settings.endHour) { // not passing through midnight + return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) + } else { // passing through midnight + return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) + } + } + + Bangle.on('midnight', function () { + /* + Usefull trick to have the app working smothly for people using it at night + */ + let now = new Date(); + let h = now.getHours(); + if (activityreminder_settings.enabled && isDuringAlertHours(h)) { + // updating only the steps and keeping the original stepsDate on purpose + activityreminder_data.stepsOnDate = 0; activityreminder.saveData(activityreminder_data); - /* todo in a futur release - Add settimer to trigger like 30 secs after going in this part cause the person have been walking - (pass some argument to run() to handle long walks and not triggering so often) - */ } - - if(activityreminder.mustAlert(activityreminder_data, activityreminder_settings)){ - load('activityreminder.app.js'); + }); + + + const activityreminder = require("activityreminder"); + const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { + const activityreminder_data = activityreminder.loadData(); + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); } + setInterval(run, 60000); + /* todo in a futur release + increase setInterval time to something that is still sensible (5 mins ?) + when we added a settimer + */ } - -} - -function isNotWorn() { - return (Bangle.isCharging() || activityreminder_settings.tempThreshold >= E.getTemperature()); -} - -function isDuringAlertHours(h) { - if(activityreminder_settings.startHour < activityreminder_settings.endHour){ // not passing through midnight - return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) - } else{ // passing through midnight - return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) - } -} - -Bangle.on('midnight', function() { - /* - Usefull trick to have the app working smothly for people using it at night - */ - let now = new Date(); - let h = now.getHours(); - if (activityreminder_settings.enabled && isDuringAlertHours(h)){ - // updating only the steps and keeping the original stepsDate on purpose - activityreminder_data.stepsOnDate = 0; - activityreminder.saveData(activityreminder_data); - } -}); - -const activityreminder = require("activityreminder"); -const activityreminder_settings = activityreminder.loadSettings(); -if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); - if(activityreminder_data.firstLoad){ - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } - setInterval(run, 60000); - /* todo in a futur release - increase setInterval time to something that is still sensible (5 mins ?) - when we added a settimer - */ -} - +})(); diff --git a/apps/activityreminder/lib.js b/apps/activityreminder/lib.js index 08fffd5f4..e0f7caca3 100644 --- a/apps/activityreminder/lib.js +++ b/apps/activityreminder/lib.js @@ -1,5 +1,3 @@ -const storage = require("Storage"); - exports.loadSettings = function () { return Object.assign({ enabled: true, @@ -10,15 +8,15 @@ exports.loadSettings = function () { pauseDelayMin: 120, minSteps: 50, tempThreshold: 27 - }, storage.readJSON("activityreminder.s.json", true) || {}); + }, require("Storage").readJSON("activityreminder.s.json", true) || {}); }; exports.writeSettings = function (settings) { - storage.writeJSON("activityreminder.s.json", settings); + require("Storage").writeJSON("activityreminder.s.json", settings); }; exports.saveData = function (data) { - storage.writeJSON("activityreminder.data.json", data); + require("Storage").writeJSON("activityreminder.data.json", data); }; exports.loadData = function () { @@ -31,7 +29,7 @@ exports.loadData = function () { dismissDate: new Date(1970), pauseDate: new Date(1970), }, - storage.readJSON("activityreminder.data.json") || {}); + require("Storage").readJSON("activityreminder.data.json") || {}); if(typeof(data.stepsDate) == "string") data.stepsDate = new Date(data.stepsDate); diff --git a/apps/activityreminder/metadata.json b/apps/activityreminder/metadata.json index 752c6c101..fb9423e7c 100644 --- a/apps/activityreminder/metadata.json +++ b/apps/activityreminder/metadata.json @@ -3,7 +3,7 @@ "name": "Activity Reminder", "shortName":"Activity Reminder", "description": "A reminder to take short walks for the ones with a sedentary lifestyle", - "version":"0.06", + "version":"0.07", "icon": "app.png", "type": "app", "tags": "tool,activity", diff --git a/apps/activityreminder/settings.js b/apps/activityreminder/settings.js index f25697de0..b4d288500 100644 --- a/apps/activityreminder/settings.js +++ b/apps/activityreminder/settings.js @@ -1,85 +1,85 @@ (function (back) { - // Load settings - const activityreminder = require("activityreminder"); - const settings = activityreminder.loadSettings(); + // Load settings + const activityreminder = require("activityreminder"); + const settings = activityreminder.loadSettings(); - // Show the menu - E.showMenu({ - "": { "title": "Activity Reminder" }, - "< Back": () => back(), - 'Enable': { - value: settings.enabled, - format: v => v ? "Yes" : "No", - onchange: v => { - settings.enabled = v; - activityreminder.writeSettings(settings); - } - }, - 'Start hour': { - value: settings.startHour, - min: 0, max: 24, - onchange: v => { - settings.startHour = v; - activityreminder.writeSettings(settings); - } - }, - 'End hour': { - value: settings.endHour, - min: 0, max: 24, - onchange: v => { - settings.endHour = v; - activityreminder.writeSettings(settings); - } - }, - 'Max inactivity': { - value: settings.maxInnactivityMin, - min: 15, max: 120, - onchange: v => { - settings.maxInnactivityMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Dismiss delay': { - value: settings.dismissDelayMin, - min: 5, max: 60, - onchange: v => { - settings.dismissDelayMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Pause delay': { - value: settings.pauseDelayMin, - min: 30, max: 240, step: 5, - onchange: v => { - settings.pauseDelayMin = v; - activityreminder.writeSettings(settings); - }, - format: x => { - return x + " min"; - } - }, - 'Min steps': { - value: settings.minSteps, - min: 10, max: 500, step: 10, - onchange: v => { - settings.minSteps = v; - activityreminder.writeSettings(settings); - } - }, - 'Temp Threshold': { - value: settings.tempThreshold, - min: 20, max: 40, step: 0.5, - format: v => v + "°C", - onchange: v => { - settings.tempThreshold = v; - activityreminder.writeSettings(settings); - } - } - }); + // Show the menu + E.showMenu({ + "": { "title": "Activity Reminder" }, + "< Back": () => back(), + 'Enable': { + value: settings.enabled, + format: v => v ? "Yes" : "No", + onchange: v => { + settings.enabled = v; + activityreminder.writeSettings(settings); + } + }, + 'Start hour': { + value: settings.startHour, + min: 0, max: 24, + onchange: v => { + settings.startHour = v; + activityreminder.writeSettings(settings); + } + }, + 'End hour': { + value: settings.endHour, + min: 0, max: 24, + onchange: v => { + settings.endHour = v; + activityreminder.writeSettings(settings); + } + }, + 'Max inactivity': { + value: settings.maxInnactivityMin, + min: 15, max: 120, + onchange: v => { + settings.maxInnactivityMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Dismiss delay': { + value: settings.dismissDelayMin, + min: 5, max: 60, + onchange: v => { + settings.dismissDelayMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Pause delay': { + value: settings.pauseDelayMin, + min: 30, max: 240, step: 5, + onchange: v => { + settings.pauseDelayMin = v; + activityreminder.writeSettings(settings); + }, + format: x => { + return x + " min"; + } + }, + 'Min steps': { + value: settings.minSteps, + min: 10, max: 500, step: 10, + onchange: v => { + settings.minSteps = v; + activityreminder.writeSettings(settings); + } + }, + 'Temp Threshold': { + value: settings.tempThreshold, + min: 20, max: 40, step: 0.5, + format: v => v + "°C", + onchange: v => { + settings.tempThreshold = v; + activityreminder.writeSettings(settings); + } + } + }); }) From 6ef45a4258e1326d561ba8f2512157cd954d111a Mon Sep 17 00:00:00 2001 From: David Peer Date: Sun, 12 Jun 2022 18:00:41 +0200 Subject: [PATCH 073/121] Minor fix --- apps/cassioWatch/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 75ec85503..41515b48c 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -147,9 +147,9 @@ function draw() { g.setFontAlign(-1,-1); drawClock(); drawRocket(); - rocketSequence -= 1; // This avoids a "jump" in the animation drawBattery(); + // Hide widgets for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";} } From d734f921180d2d1fd094dfb17e8b99d7238a339e Mon Sep 17 00:00:00 2001 From: David Peer Date: Sun, 12 Jun 2022 18:01:47 +0200 Subject: [PATCH 074/121] Show steps in k. --- apps/cassioWatch/app.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/cassioWatch/app.js b/apps/cassioWatch/app.js index 41515b48c..6bbb9e823 100644 --- a/apps/cassioWatch/app.js +++ b/apps/cassioWatch/app.js @@ -113,12 +113,7 @@ function getSteps() { return "? k"; } - // Show always 2 digits. E.g. 1.5k if < 10000 otherwise 12k - if(steps > 10000){ - steps = Math.round(steps/1000); - } else { - steps = Math.round(steps/100) / 10; - } + steps = Math.round(steps/1000); return steps + "k"; } From 749cb2fc2a9698b7f7e0c11988f065af65f8bc0a Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 19:38:40 +0200 Subject: [PATCH 075/121] 0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. --- apps/hworldclock/ChangeLog | 3 +- apps/hworldclock/README.md | 1 + apps/hworldclock/app.js | 126 ++++++++++++++++++++++++++++----- apps/hworldclock/metadata.json | 2 +- 4 files changed, 113 insertions(+), 19 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 64b2be430..30d729cbf 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,3 +1,4 @@ 0.15: Initial release - be patient as this is the first try :) 0.16: Fix timing -0.17: Fix hours \ No newline at end of file +0.17: Fix hours +0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. \ No newline at end of file diff --git a/apps/hworldclock/README.md b/apps/hworldclock/README.md index 40af71ee3..0f4f9296c 100644 --- a/apps/hworldclock/README.md +++ b/apps/hworldclock/README.md @@ -2,6 +2,7 @@ In addition to the main clock and date in your current location, you can add up to three other locations. Great for travel or remote working. Additionally we show the sunset/sunrise and seconds for the current location and the day name is shown in your locale. +If watch is locked, seconds get refreshed every 10 seconds. ![](hworldclock.png) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index c37ec5714..6d16e2295 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -31,6 +31,8 @@ const yposWorld = big ? 170 : 120; const OFFSET_TIME_ZONE = 0; const OFFSET_HOURS = 1; +var PosInterval = 0; + var offsets = require("Storage").readJSON("hworldclock.settings.json") || []; //=======Sun @@ -79,6 +81,7 @@ var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||fal // timeout used to update every minute var drawTimeout; var drawTimeoutSeconds; +var secondsTimeout; g.setBgColor(0, 0, 0); @@ -91,6 +94,16 @@ function queueDraw() { }, 60000 - (Date.now() % 60000)); } +// schedule a draw for the next second +function queueDrawSeconds() { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = setTimeout(function() { + drawTimeoutSeconds = undefined; + drawSeconds(); + //console.log("TO: " + secondsTimeout); + }, secondsTimeout - (Date.now() % secondsTimeout)); +} + function doublenum(x) { return x < 10 ? "0" + x : "" + x; } @@ -127,9 +140,13 @@ function drawSeconds() { g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); g.setColor("#22ff05"); - //g.setFont(font, primaryTimeFontSize-3); + //console.log("---"); + //console.log(seconds); + if (Bangle.isLocked()) seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x + //console.log(seconds); g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); - queueDraw(); + queueDrawSeconds(); + } function draw() { @@ -179,7 +196,7 @@ function draw() { // draw Day, name of month, Date //DATE var localDate = require("locale").date(new Date(), 1); - localDate = localDate.substring(0, localDate.length - 5) + localDate = localDate.substring(0, localDate.length - 5); g.setFont("Vector", 17); g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); @@ -230,36 +247,111 @@ function draw() { g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset queueDraw(); + queueDrawSeconds(); } // clean app screen g.clear(); + // Show launcher when button pressed Bangle.setUI("clock"); Bangle.loadWidgets(); Bangle.drawWidgets(); -updatePos(); -setInterval(drawSeconds, 1E3/2); +// draw immediately at first, queue update +draw(); -// Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (on) { - draw(); // draw immediately, queue redraw - setInterval(updatePos, 60*5E3); // refesh every 5 mins - setInterval(drawSeconds, 1E3); - updatePos(); - } else { // stop draw timer + +if (!Bangle.isLocked()) { // Initial state + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + + secondsTimeout = 1000; if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - setInterval(updatePos, 60*50E3); // refesh every 50 mins - setInterval(drawSeconds, 10E3); + + draw(); // draw immediately, queue redraw + updatePos(); + }else{ + secondsTimeout = 10 * 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw + updatePos(); + } + + +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower',on=>{ + if (on) { + if (PosInterval != 0) clearInterval(PosInterval); + + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + secondsTimeout = 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + draw(); // draw immediately, queue redraw + updatePos(); + } else { // stop draw timer + + secondsTimeout = 1000 * 60; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw updatePos(); } }); -// draw now -draw(); + +Bangle.on('lock',on=>{ + if (!on) { // UNlocked + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + + secondsTimeout = 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + draw(); // draw immediately, queue redraw + updatePos(); + }else{ // locked + + secondsTimeout = 10 * 1000; + if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeout = undefined; + drawTimeoutSeconds = undefined; + + + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + draw(); // draw immediately, queue redraw + updatePos(); + } + }); + + + + + + + + diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 794992d2f..9eb95a0ed 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.17", + "version": "0.18", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 516814cdf80940d0c253d7ee4d4a7e6c11657157 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 19:42:48 +0200 Subject: [PATCH 076/121] Fix spaces --- apps/hworldclock/app.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 6d16e2295..6101d4427 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -277,11 +277,11 @@ if (!Bangle.isLocked()) { // Initial state updatePos(); }else{ secondsTimeout = 10 * 1000; - if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - + if (PosInterval != 0) clearInterval(PosInterval); PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins draw(); // draw immediately, queue redraw @@ -333,13 +333,12 @@ Bangle.on('lock',on=>{ draw(); // draw immediately, queue redraw updatePos(); }else{ // locked - + secondsTimeout = 10 * 1000; - if (drawTimeout) clearTimeout(drawTimeout); + if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; drawTimeoutSeconds = undefined; - if (PosInterval != 0) clearInterval(PosInterval); PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins From 59ee5b1a782d84f4e11a4d1bc94618820e728e8b Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 19:51:46 +0200 Subject: [PATCH 077/121] Moving stuff around to be sure to instanciate the variable before even referencing them in functions --- apps/activityreminder/app.js | 13 ++++++++----- apps/activityreminder/boot.js | 20 ++++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index 52dec2928..95bdfe6f0 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,4 +1,10 @@ (function () { + + const activityreminder = require("activityreminder"); + const storage = require("Storage"); + const activityreminder_settings = activityreminder.loadSettings(); + const activityreminder_data = activityreminder.loadData(); + function drawAlert() { E.showPrompt("Inactivity detected", { title: "Activity reminder", @@ -31,13 +37,10 @@ eval(storage.read("activityreminder.settings.js"))(() => load()); } } - - const activityreminder = require("activityreminder"); - const storage = require("Storage"); + g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); - const activityreminder_settings = activityreminder.loadSettings(); - const activityreminder_data = activityreminder.loadData(); run(); + })(); \ No newline at end of file diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 86de0e901..c87dde3b2 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,4 +1,15 @@ (function () { + + const activityreminder = require("activityreminder"); + const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { + const activityreminder_data = activityreminder.loadData(); + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); + } + } + function run() { if (isNotWorn()) return; let now = new Date(); @@ -49,15 +60,8 @@ } }); - - const activityreminder = require("activityreminder"); - const activityreminder_settings = activityreminder.loadSettings(); + if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); - if (activityreminder_data.firstLoad) { - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } setInterval(run, 60000); /* todo in a futur release increase setInterval time to something that is still sensible (5 mins ?) From 9b71b107cfb9ab05aeedbbe98a396933d223d209 Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:05:32 +0200 Subject: [PATCH 078/121] Use let instead of const on object that get updated --- apps/activityreminder/app.js | 4 ++-- apps/activityreminder/boot.js | 4 ++-- apps/activityreminder/lib.js | 2 +- apps/activityreminder/settings.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/activityreminder/app.js b/apps/activityreminder/app.js index 95bdfe6f0..c2b626fb3 100644 --- a/apps/activityreminder/app.js +++ b/apps/activityreminder/app.js @@ -1,9 +1,9 @@ (function () { - + // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const storage = require("Storage"); const activityreminder_settings = activityreminder.loadSettings(); - const activityreminder_data = activityreminder.loadData(); + let activityreminder_data = activityreminder.loadData(); function drawAlert() { E.showPrompt("Inactivity detected", { diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index c87dde3b2..4d6847a20 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -1,9 +1,9 @@ (function () { - + // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); if (activityreminder_settings.enabled) { - const activityreminder_data = activityreminder.loadData(); + let activityreminder_data = activityreminder.loadData(); if (activityreminder_data.firstLoad) { activityreminder_data.firstLoad = false; activityreminder.saveData(activityreminder_data); diff --git a/apps/activityreminder/lib.js b/apps/activityreminder/lib.js index e0f7caca3..704d35641 100644 --- a/apps/activityreminder/lib.js +++ b/apps/activityreminder/lib.js @@ -21,7 +21,7 @@ exports.saveData = function (data) { exports.loadData = function () { let health = Bangle.getHealthStatus("day"); - const data = Object.assign({ + let data = Object.assign({ firstLoad: true, stepsDate: new Date(), stepsOnDate: health.steps, diff --git a/apps/activityreminder/settings.js b/apps/activityreminder/settings.js index b4d288500..ce7cdc913 100644 --- a/apps/activityreminder/settings.js +++ b/apps/activityreminder/settings.js @@ -1,7 +1,7 @@ (function (back) { // Load settings const activityreminder = require("activityreminder"); - const settings = activityreminder.loadSettings(); + let settings = activityreminder.loadSettings(); // Show the menu E.showMenu({ From ea82ae3f255319e23704e041627655c7570e34f9 Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:16:14 +0200 Subject: [PATCH 079/121] Fix activityreminder_data scoping issue in boot.js --- apps/activityreminder/boot.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 4d6847a20..16c209737 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -2,8 +2,9 @@ // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); + let activityreminder_data = null; if (activityreminder_settings.enabled) { - let activityreminder_data = activityreminder.loadData(); + activityreminder_data = activityreminder.loadData(); if (activityreminder_data.firstLoad) { activityreminder_data.firstLoad = false; activityreminder.saveData(activityreminder_data); From 7ba81f1ba5b26b69a761ca07a9615c90a0b365ed Mon Sep 17 00:00:00 2001 From: Stiralbios Date: Sun, 12 Jun 2022 20:29:43 +0200 Subject: [PATCH 080/121] add missing semicolons --- apps/activityreminder/boot.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/activityreminder/boot.js b/apps/activityreminder/boot.js index 16c209737..f97cf274d 100644 --- a/apps/activityreminder/boot.js +++ b/apps/activityreminder/boot.js @@ -2,13 +2,11 @@ // load variable before defining functions cause it can trigger a ReferenceError const activityreminder = require("activityreminder"); const activityreminder_settings = activityreminder.loadSettings(); - let activityreminder_data = null; - if (activityreminder_settings.enabled) { - activityreminder_data = activityreminder.loadData(); - if (activityreminder_data.firstLoad) { - activityreminder_data.firstLoad = false; - activityreminder.saveData(activityreminder_data); - } + let activityreminder_data = activityreminder.loadData(); + + if (activityreminder_data.firstLoad) { + activityreminder_data.firstLoad = false; + activityreminder.saveData(activityreminder_data); } function run() { @@ -42,9 +40,9 @@ function isDuringAlertHours(h) { if (activityreminder_settings.startHour < activityreminder_settings.endHour) { // not passing through midnight - return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour) + return (h >= activityreminder_settings.startHour && h < activityreminder_settings.endHour); } else { // passing through midnight - return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour) + return (h >= activityreminder_settings.startHour || h < activityreminder_settings.endHour); } } From 38f23be5b4b9da4726eb53bcffd716766a5aa4d4 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 21:13:28 +0200 Subject: [PATCH 081/121] Fix PM hours --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/app.js | 16 +++------------- apps/hworldclock/metadata.json | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index 30d729cbf..fdc717c92 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -1,4 +1,5 @@ 0.15: Initial release - be patient as this is the first try :) 0.16: Fix timing 0.17: Fix hours -0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. \ No newline at end of file +0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. +0.19: Fix PM Hours \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 6101d4427..e907dd703 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -19,7 +19,6 @@ const font = "6x8"; /* TODO: we could totally use 'Layout' here and avoid a whole bunch of hard-coded offsets */ - const xyCenter = g.getWidth() / 2; const xyCenterSeconds = xyCenter + (big ? 85 : 68); const yAmPm = xyCenter - (big ? 70 : 48); @@ -171,7 +170,8 @@ function draw() { //do 12 hour stuff if (hours > 12) { ampm = "PM"; - hours = hours - 12; + hours = hours - 12; + if (hours < 10) hours = doublenum(hours); } else { ampm = "AM"; } @@ -200,8 +200,6 @@ function draw() { g.setFont("Vector", 17); g.drawString(require("locale").dow(new Date(), 1).toUpperCase() + ", " + localDate, xyCenter, yposDate, true); - - g.setFont(font, primaryDateFontSize); // set gmt to UTC+0 var gmt = new Date(d.getTime() + d.getTimezoneOffset() * 60 * 1000); @@ -345,12 +343,4 @@ Bangle.on('lock',on=>{ draw(); // draw immediately, queue redraw updatePos(); } - }); - - - - - - - - + }); \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 9eb95a0ed..1ee04b333 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.18", + "version": "0.19", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From 1d6887a4dff0f11475cc1bf21d62c59e07b75a94 Mon Sep 17 00:00:00 2001 From: Marco H Date: Sun, 12 Jun 2022 21:17:52 +0200 Subject: [PATCH 082/121] Do not check new values if alarm is shown --- apps/widbaroalarm/widget.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/widbaroalarm/widget.js b/apps/widbaroalarm/widget.js index d8eb43995..e1516b6f1 100644 --- a/apps/widbaroalarm/widget.js +++ b/apps/widbaroalarm/widget.js @@ -2,6 +2,7 @@ let medianPressure; let threeHourAvrPressure; let currentPressures = []; + let stop = false; // semaphore const LOG_FILE = "widbaroalarm.log.json"; const SETTINGS_FILE = "widbaroalarm.json"; @@ -34,6 +35,7 @@ function showAlarm(body, key) { if (body == undefined) return; + stop = true; E.showPrompt(body, { title: "Pressure alarm", @@ -56,6 +58,7 @@ // save timestamp of the future so that we do not warn again for the same event until then saveSetting(key, tsNow + 60 * setting('pauseDelayMin')); } + stop = false; load(); }); @@ -64,7 +67,10 @@ Bangle.buzz(); } - setTimeout(load, 20000); + setTimeout(function() { + stop = false; + load(); + }, 20000); } @@ -191,6 +197,7 @@ turn off barometer power */ function check() { + if (stop) return; const MEDIANLENGTH = 20; Bangle.setBarometerPower(true, "widbaroalarm"); Bangle.on('pressure', function(e) { From 19c3e0e20eb347958e523bd2d96a23d7e07109ed Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Mon, 25 Apr 2022 20:54:52 +0200 Subject: [PATCH 083/121] [Scheduler] Remove custom boolean formatter The new menu system handles booleans by default --- apps/sched/settings.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/sched/settings.js b/apps/sched/settings.js index a2b3a5241..b73cd41d1 100644 --- a/apps/sched/settings.js +++ b/apps/sched/settings.js @@ -4,11 +4,10 @@ E.showMenu({ "": { "title": /*LANG*/"Scheduler" }, - /*LANG*/"< Back": () => back(), + "< Back": () => back(), /*LANG*/"Unlock at Buzz": { value: settings.unlockAtBuzz, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.unlockAtBuzz = v; require("sched").setSettings(settings); @@ -17,7 +16,6 @@ /*LANG*/"Default Auto Snooze": { value: settings.defaultAutoSnooze, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.defaultAutoSnooze = v; require("sched").setSettings(settings); @@ -38,7 +36,6 @@ /*LANG*/"Default Repeat": { value: settings.defaultRepeat, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.defaultRepeat = v; require("sched").setSettings(settings); From c3b1a973c0bcef1ac7130e1b0df89dd3b1003703 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 22:44:32 +0200 Subject: [PATCH 084/121] Add theme support --- apps/hworldclock/ChangeLog | 3 ++- apps/hworldclock/app.js | 45 ++++++++++------------------------ apps/hworldclock/metadata.json | 2 +- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index fdc717c92..c7b1731a2 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -2,4 +2,5 @@ 0.16: Fix timing 0.17: Fix hours 0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. -0.19: Fix PM Hours \ No newline at end of file +0.19: Fix PM Hours +0.20: Add theme support \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index e907dd703..faf24e974 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -82,7 +82,7 @@ var drawTimeout; var drawTimeoutSeconds; var secondsTimeout; -g.setBgColor(0, 0, 0); +g.setBgColor(g.theme.bg); // schedule a draw for the next minute function queueDraw() { @@ -128,7 +128,7 @@ function drawSeconds() { // default draw styles g.reset(); - g.setBgColor(0, 0, 0); + g.setBgColor(g.theme.bg); // drawSting centered g.setFontAlign(0, 0); @@ -138,7 +138,11 @@ function drawSeconds() { var seconds = time[2]; g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); - g.setColor("#22ff05"); + if (g.theme.dark) { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } //console.log("---"); //console.log(seconds); if (Bangle.isLocked()) seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x @@ -155,7 +159,7 @@ function draw() { // default draw styles g.reset(); - g.setBgColor(0, 0, 0); + g.setBgColor(g.theme.bg); // drawSting centered g.setFontAlign(0, 0); @@ -179,7 +183,11 @@ function draw() { //g.setFont(font, primaryTimeFontSize); g.setFont("5x9Numeric7Seg",primaryTimeFontSize); - g.setColor("#22ff05"); + if (g.theme.dark) { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } g.drawString(`${hours}:${minutes}`, xyCenter-10, yposTime, true); // am / PM ? @@ -187,7 +195,6 @@ function draw() { //do 12 hour stuff //var ampm = require("locale").medidian(new Date()); Not working g.setFont("Vector", 17); - g.setColor("#22ff05"); g.drawString(ampm, xyCenterSeconds, yAmPm, true); } @@ -287,33 +294,7 @@ if (!Bangle.isLocked()) { // Initial state } -// Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (on) { - if (PosInterval != 0) clearInterval(PosInterval); - - PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins - secondsTimeout = 1000; - if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); - drawTimeout = undefined; - drawTimeoutSeconds = undefined; - draw(); // draw immediately, queue redraw - updatePos(); - } else { // stop draw timer - secondsTimeout = 1000 * 60; - if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); - drawTimeout = undefined; - drawTimeoutSeconds = undefined; - - if (PosInterval != 0) clearInterval(PosInterval); - PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins - draw(); // draw immediately, queue redraw - updatePos(); - } -}); Bangle.on('lock',on=>{ diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 1ee04b333..5cc2a49a8 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.19", + "version": "0.20", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", From d89ba34bb7e72f94a85780cc7a19d185137557b1 Mon Sep 17 00:00:00 2001 From: Hank Date: Sun, 12 Jun 2022 22:49:55 +0200 Subject: [PATCH 085/121] Remove --- .../Automatisch beibehalten von Corel/widget.png | Bin 2385 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png diff --git a/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png b/apps/hwid_a_battery_widget/Automatisch beibehalten von Corel/widget.png deleted file mode 100644 index 868628b6085cb0da28098648ae713dc1f08e44d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2385 zcmaJ@3s_S}7QRV%6-6sAF<4ClyK7v@i-;0K3Ni8!q9Gtc4b~8DAdq)1aB(YAt>u%d z1QAzxOM?njO9Tu>6tPi@^y8Cq0o>m5~KlokLMAQ3HazyNs#E&zZ#FAa}`B6%T9u~JSJ#VTV!GAvi2N&pLHBBmUK zLS3?Dm5U%i%ca`iELW}fxyzlN|*w!{|p^@ z^C8AVkcvs6q@<*fQ#{E^O&o>h?d?sW(kXPh2ZHd>rYay2?4i)QO^f`Y!v(csjZ_6m zl?no?D~eGjK|Vwxy3y-49VaA}%- zo53R0G|7Az(=oEp2$)dxGIwnb9z78#m+Sq0cd}KFI#A;yHf?IRDcwX=oQiR>aFy?ugdQ6YyDM9=!Ox)6 z-QwI1%ye`nVGTAnt{o#ero6HML)Uy^Dj6ygJslhQ-l*K`UtG1cwe@N1cVDLrwdRMG z*64k76TUsT2uh&{4?j3|Ne+tME|dQYKSCDEpg8kolSq#+^^!R)ie+U z+s11v=x1NukMZ}niWUm_R2O|qOK`|UPMgE#(5}Jk;~k)HT0%l*MP+4DZAyM`Pfuxc za}bloswueJ3BW4`U0q#Co}QjDK$KIEn`0ez=clGG-0CZEQ^M%z@-?u@J`5Kt(5+iU z#uXJ8=iGmKrnyp3Bv0G-oedIQndCY+#&iwI4%dH@kxX^BbGx#&>l$)y9T~ zkjlzR27|%n@pupf>3gb(iHV6Hepx3Z=bb!xs=mG+w&RbTc;zlnU-sJ6JCs%aX z>{!HYi_>azcJKZQPoS#rbKUi=N-VU=E%-tkypQL*|~ zOUnW`T+CgsyMm664#o!`eARY=_wK;w_qw~!V2!1v9Jf`=Tt3OM-BDRvyKQ7|=fk0) z3UTLfFhy+I?6Dod#QiOvLL!Bx7oB7eSJ~g*e--e3wmRopRvE^nd$={{#|FZYOIi0` z{iDsmz26SNiEa)73wZvvR8kw&<<{1Q|u{R*kDbNFBDQ31}%3AJl^-n#&A7i zxIK5{orx`M+GVZ3ZuIbI-e`Wmh~?5m3NID^c4ADVE=l|sd~femU2l7U^9Td|Ul6ou L3->%{*S`M&n6+>< From e68d04da5bb5ee2be61fa15df743d8f37fd0f2d1 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 13 Jun 2022 08:23:16 +0100 Subject: [PATCH 086/121] works on v2 --- apps/espruinoctrl/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/espruinoctrl/metadata.json b/apps/espruinoctrl/metadata.json index 5798c7842..253307fa0 100644 --- a/apps/espruinoctrl/metadata.json +++ b/apps/espruinoctrl/metadata.json @@ -6,7 +6,7 @@ "description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!", "icon": "app.png", "tags": "", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "custom": "custom.html", "storage": [ From dac6e6ec916d37908eb5cfb49bd9f90b5ef4d8bb Mon Sep 17 00:00:00 2001 From: Rarder44 Date: Mon, 13 Jun 2022 14:18:26 +0200 Subject: [PATCH 087/121] Rebble: fix battery size --- apps/rebble/rebble.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rebble/rebble.app.js b/apps/rebble/rebble.app.js index 8ba61f818..fc91fe0ac 100644 --- a/apps/rebble/rebble.app.js +++ b/apps/rebble/rebble.app.js @@ -236,7 +236,7 @@ function drawBattery(x,y,wi,hi) { g.clearRect(x+2,y+2+2,x+wi-4-2,y+2+hi-2); // centre g.setColor(g.theme.fg); g.fillRect(x+wi-3,y+2+(((hi - 1)/2)-1),x+wi-2,y+2+(((hi - 1)/2)-1)+4); // contact - g.fillRect(x+3, y+5, x +4 + E.getBattery()*(wi-12)/100, y+hi-1); // the level + g.fillRect(x+3, y+5, x +3 + E.getBattery()*(wi-10)/100, y+hi-1); // the level if( Bangle.isCharging() ) { From 988b4d478f6b58ec40b72d09f3122b2466ebd3d8 Mon Sep 17 00:00:00 2001 From: Rarder44 Date: Mon, 13 Jun 2022 14:20:40 +0200 Subject: [PATCH 088/121] changelog and metatada update --- apps/rebble/ChangeLog | 1 + apps/rebble/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/rebble/ChangeLog b/apps/rebble/ChangeLog index 4b415c1c5..4e2e76484 100644 --- a/apps/rebble/ChangeLog +++ b/apps/rebble/ChangeLog @@ -6,3 +6,4 @@ 0.06: Add 12h support and autocycle control 0.07: added localization, removed deprecated code 0.08: removed unused font, fix autocycle, imported suncalc and trimmed, removed pedometer dependency, "tap to cycle" setting +0.09: fix battery icon size \ No newline at end of file diff --git a/apps/rebble/metadata.json b/apps/rebble/metadata.json index e28c67784..ec7650f53 100644 --- a/apps/rebble/metadata.json +++ b/apps/rebble/metadata.json @@ -2,7 +2,7 @@ "id": "rebble", "name": "Rebble Clock", "shortName": "Rebble", - "version": "0.08", + "version": "0.09", "description": "A Pebble style clock, with configurable background, three sidebars including steps, day, date, sunrise, sunset, long live the rebellion", "readme": "README.md", "icon": "rebble.png", From 486d30ab5ef1b492ef19a54cc75f402ea13708db Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:14:09 +0200 Subject: [PATCH 089/121] Create app.js --- apps/novaclock/app.js | 274 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 apps/novaclock/app.js diff --git a/apps/novaclock/app.js b/apps/novaclock/app.js new file mode 100644 index 000000000..e5bd37b06 --- /dev/null +++ b/apps/novaclock/app.js @@ -0,0 +1,274 @@ +function nova() { + var nova = require("heatshrink").decompress(atob("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")); + return nova; +} + +function novaEyesStage1() { + var novaEyesStage1 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5gAFH58rDIXN5movwZRKs+oAIg/OgEr5mi1Go0V+AYIFCLN7oGABIZiK0fXAAkOh0Ph0IBQo+HDI0PhEHhEPDJpWoKQJVCh5ZHHwoZFCgcPg50BLIpYpHohVF1hFChxXODAQACL4hXsHgwABgAACBQg+HDIhuChAZEOYJYtJYkIKwo+EBoJXKJYIABDIyxGK8yUFSYpXKHwTIFKw4NFWFKUGHg0AKwaWGDIrHGWGA9QLIUIK5LJBDJAaDK9o8BhA9JHwSvLK5QQBhEOK9qVLgAMBK5bJJAAMHK9yuBJIRXWh78BDJBWBDIpXnWAIvB1hWNK4xYCOJK7BDIxYoGAZYGBQMOdg6wFBgZWFg7IGK9JYCGQI8FdYpXILAMIDI7IILFZOBAIYCBIoI8KOQ4VDYwRWtHorwCAAQ/DBohXKLAZZCLYQZKLFRZFBQo8HDJLLBDJpYlAB4ZiLE3M5moAQIAFHhgZD5oaCDofNK14/E1Go0QADHaBZDKwQBBKuTyKDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A==")); + return novaEyesStage1; +} + +function novaEyesStage0() { + var novaEyesStage0 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj64AFH58rDLBVrH6EAlYZXK0Y7KH4gZiK1MOh0Ph0IHxoZGh8Ig8Ih5YwHgpSBKoUPLI4+FDIoUDh8HOgJZFLFI9EKousIoUOK5wYCAARfEK9g8GAAMAAAQKEHw4ZENwUIDIhzBLFpLEhBWFHwgNBK5RLBAAIZGWIxXmSgqTFK5Q+CZApWHBoqwpSgw8GgBWDSwwZFY4ywwHqBZChBXJZIIZIDQZXtHgMIHpI+CV5ZXKCAMIhxXtSpcABgJXLZJIABg5XuVwJJCK60PfgIZIKwIZFK86wBF4OsKxpXGLARxJXYIZGLFAwDLAwKBhzsHWAoMDKwsHZAxXpLAQyBHgrrFK5BYBhAZHZBBYrJwIBDAQJFBHhRyHCobGCK1o9FeAQACH4YNEK5RYDLIRbCDJRYqLIoKFHg4ZJZYIZNLFYAIHhIZZLEo/LBgIZkLNw7QDLJZnAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesStage0; +} + +function novaEyesStage2() { + var novaEyesStage2 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCDwZYqKwKoGLowFDHwpWCDIRRBAQPMAwd+vANBWNRXBJASoDeRKWGDIoEBOoQDDDAQeBK9CUBJQiTCAAq2CB4Q+DDITGFCAZ2DOohYngAAVDLhWj64ACh0PhA0G6+sBoMPCQY+BgAKCBYMOhwZHBoYZFK88PAAKMHKwYABK4oZEKw5YEDIxXpHpRZChBXJZIIZIDQZXtHgMIHpI+CV5ZXKCAMIhxXtSpcABgJXLZJIABg5XuVwJJCK60PfgIZIKwIZFK86wBF4OsgErKxZXGLARxJXYIZGLEoAVDLhXk1AAC5mo0QGDABJXEBIgaBDYfMAA4ZELEouEHgIALHgsABAN+5hUB0R1CDJywlRIvNAQYECMgZXGY4ZXBCAIDCKQTIILFAAISYo8IOQYUDAoQDCBQRWrHwQABcoxdFHhJyCC4i3DDoWiK1hYDRgSQCAAgMBDJ3NDQJWE5oZMLM6ZGHaBZDOgQBBKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesStage2; +} + +function novaEyesStage3() { + var novaEyesStage3 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9A8BGIY2EABQ+DZARRBUoJVCDYzTELE49CVgo7KHosABoocFZYgBDK8yuGABJfGHwIZQLYQcDLEsAAC4ZaK8nXAAMPh8OGhHX1gPBhATCK4QZDh0PJ5IaCh4ZEK848BhCOKHwI9FOIpXKCAMIhxXpdrAZZK8mo1Gi0V+AIYABBAOiBoIAEBAJXCAwQYDDIwAFDYRXoJAozCAYRDCAAN4I4RXCJAoFELBIdBK8o+DGoyzDKQKcDHgpyBYwquECoYMCAQJWmWAgvCUYadHdgzKF5jMCAITTD5gIDK84+B5gABG4SZDd5A8FZQZLDLQIWGDJCwlLAQAC5oCDAgQABVwoZEKIQeCAYTGFDI5YmcogEEAAg8IOQYUDAoQDCBQRWrHwQABJoV+SQ48KOQRpEW4YdC0RWsLAaMCAIQAEBgIZO5oaCKwfNDJhZnTIw7QLIZ0EKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA==")); + return novaEyesStage3; +} + +function novaEyesStage4() { + var novaEyesStage4 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9EAJQg2EBAoFEHwauBUIN4p1UKoQbGaYhYnK4KvCKoQFBHYi6EHosrBQQaCYwRbBDQd4XYSwoKwIuB5oACIAJBBAYpMDAAI+BKwIKDDAJKBvC2BEgIUDEwawmdgIvDGIhVDLYYAEHoIZBVIQPBKwJeBZoLJEXgYHBK8wzBHISMF5xdFK45GCMwQDBNYonBBAN+XAV+K8wAPlYHGDKIAHV8ztCqiHBWo6gEdgOoK4SpEAgQODDwIjBAAIjBCIRXm5g1CHQQCDHgJWCAgIAD0RXDDIPM5oRC5oECDYR+CK9aVES4ZQFHQShEK4yvEAAbJGAARXlHwI9BJYIAEAwLsEql4vwBBHgZYCCQRrEEYgMDAQJWmWAgvCJQJaDUQQ8DVwYZFVAS9CAITED5gIDK84+BcIQ3CTIa5HKwjKFJYZaBCwwZIWEpYCAAXNAQYECAAJkBK4ysCYYR2DAQIICAAZXpd4zqFAAg8IOQYUDAoQDCBQRWrHwQABJoV+SQ48KOQRpEW4YdC0RWsLAaMCAIQAEBgIZO5oaCKwfNDJhZnTIw7QLIZ0EKuQ/FAAgZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA==")); + return novaEyesStage4; + +} + +function novaEyesWhiteStage0() { + var novaEyesWhiteStage0 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj64AFH58rDLBVrH6EAlYZXK0Y7KH4gZiK2Q+JDLJW0Hw4ZZK/5X6HiY+FDLJX/K/Q8VHwYZZK/5X/K/5X/K/5X/K/5X/K+Y+WHgYZZK/5X7Hyg8FDLJX/K/Y+SHg4ZZLGg8JDLJYlH5YMBDMhZuHaAZZLM4AEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A=")); + return novaEyesWhiteStage0; +} + +function novaEyesTransStage1() { + var novaEyesTransStage1 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5gAFH58rDIXN5movwZRKs+oAIg/OgEr5mi1Go0V+AYIFCLN7oGABIZiK0YRYDLJW0CY4ZZK/5X6FCoVDDLJX/K/QmXC4IZZK/5X/K/5X/K/5X/K/5X/K+YmWCoYZZK/5X7FCgTFDLJX/K/YqSCI4ZZLEoAPDMRYm5nM1ACBAAo8MDIfNDQQdD5pWvH4mo1GiAAY7QLIZWCAIJVyeRQZsAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AfA")); + return novaEyesTransStage1; +} + +function novaEyesTransStage2() { + var novaEyesTransStage2 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCDwZYqKwKoGLowFDHwpWCDIRRBAQPMAwd+vANBWNRXBJASoDeRKWGDIoEBOoQDDDAQeBK9CUBJQiTCAAq2CB4Q+DDITGFCAZ2DOohYngAAVDLhWjC7AZZK/5X/K/5X/K/5X/K/5X/K+YmBACoZcK8moAAXM1GiAwYAJK4gJEDQIbD5gAHDIhYlFwg8BABY8FgAIBv3MKgOiOoQZOWEqJF5oCDAgRkDK4zHDK4IQBAYRSCZBBYoABCTFHhByDCgYFCAYQKCK1Y+CAALlGLoo8JOQQXEW4YdC0RWsLAaMCSAQAEBgIZO5oaBKwnNDJhZnTIw7QLIZ0CAIJVyH4oAEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4A==")); + return novaEyesTransStage2; +} + +function novaEyesTransStage3() { + var novaEyesTransStage3 = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ArgAAFDNhVj5nM1ABC5g/PlYQB1AYCvwZRKsxWE0RZPBgOiv2iAQNUAYIACLN6RBHYQAETQKcDHxMAvwACLIYaEOYRWtGQYAD1BAELBKsBBgRRCWIQBCBQV+LFRWBVAxdGAoY+FKwQZCJgICB5hZCvF+qgFBWNRXBJASoDeROiK4ytDCIOoC4R5DAYQIBK9A8BGIY2EABQ+DZARRBUoJVCDYzTELE49CVgo7KHosABoocFZYgBDK8yuGABJfGHwIZQLYQcDLEsAAC4ZaK8gXYDLJX/K/jtYDLJXk1Go0WivwBDAAIIB0QNBAAgIBK4QGCDAYZGAAobCK9BIFGYQDCIYQABvBHCK4RIFAohYJDoJXlHwY1GWYZSBTgY8FOQLGFVwgVDBgQCBK0ywEF4SjDTo7sGZQvMZgQBCaYfMBAZXnHwPMAAI3CTIbvIHgrKDJYZaBCwwZIWEpYCAAXNAQYECAAKuFDIhRCDwQDCYwoZHLEzlEAggAEHhByDCgYFCAYQKCK1Y+CAAJNCvySHHhRyCNIi3DDoWiK1hYDRgQBCAAgMBDJ3NDQRWD5oZMLM6ZGHaBZDOghVyH4oAEDNgA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AD4=")); + return novaEyesTransStage3; +} + +function novaTopRedraw() { + var novaTopRedraw = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AHsAABZM/K5fM5kAv2igGi1EAvFUK/6v/K8isDAQV+BAK4BJn5XL1BOB1GoLod4LQIRE0XM5vM1HN5pX/5hXBIwJdGKwgYGA45X3TgJRDLQZXFAH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AB8AIH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4AP")); + return novaTopRedraw; +} + +function star() { + var backgroundstar = require("heatshrink").decompress(atob("rFYxH+AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A9qxA/K/5W/AH5XGLH6w/K34A/AA2BwJB/K62sIP5XWIH4AW1iv/K/5X/AHFWqwCCq2BJ4ICB1mBAAJZBAQIQBlYUCAYMrAgJZ8KQICBU4QCBLIJVBK4QOCNAJSCOQQA/XpQA/K6q3CAH5XUwJB/ACqu/V7BA/AC2BwJB/LC5A/V/4AtqxX/AC2slZB/ACuBqxB/LC5A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4Ao")); + return backgroundstar; +} + +function novaOpenEyes(speed, white, animation) { + if (!white) { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + setTimeout(function() { + g.drawImage(novaEyesStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + if (animation) { + setTimeout(function() { + g.drawImage(novaEyesStage0(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + } else {} + } else { + + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + timedraw(true); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + open = true; + }, speed * 4); + if (animation) { + setTimeout(function() { + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + open = true; + }, speed * 5); + } else {} + } +} + +function novaCloseEyes(speed, white, animation) { + if (!white) { // for other + if (animation) { + g.drawImage(novaEyesStage0(), -10, -10, { + scale: 2.2 + }); + } else {} + setTimeout(function() { + g.drawImage(novaEyesStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + g.drawImage(novaEyesStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + g.drawImage(novaEyesStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + setTimeout(function() { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + } else { // for time + + if (animation) { + timedraw(true); + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + } else {} + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + }, speed * 2); + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage2(), -10, -10, { + scale: 2.2 + }); + }, speed * 3); + setTimeout(function() { + timedraw(true); + g.drawImage(novaEyesTransStage3(), -10, -10, { + scale: 2.2 + }); + }, speed * 4); + setTimeout(function() { + g.drawImage(novaEyesStage4(), -10, -10, { + scale: 2.2 + }); + }, speed * 5); + open = false; + } +} + +function timedraw(animation) { + if (open && timemode || animation) { + g.setFont("6x8", 4); + g.setColor("#00F"); + var d = new Date(); + var h = d.getHours(), + m = d.getMinutes(); + g.drawImage(novaEyesWhiteStage0(), -10, -10, { + scale: 2.2 + }); + g.drawImage(novaEyesTransStage1(), -10, -10, { + scale: 2.2 + }); + // Check if single digit + var hourDigits = h.toString(); + if (hourDigits.length === 1) { // if hour digits only one, render in middle + g.drawString(h, 50, 66); + } else { + g.drawString(h, 38, 66); + } + var minutes = m.toString(); + if (minutes.length === 1) { // same for mins + g.drawString(m, 107, 66); + } else { + g.drawString(m, 94, 66); + } + } +} + +function main() { + Bangle.on("lock", function(lock) { + g.drawImage(novaTopRedraw(), -10, novaYPos, { + scale: 2.2 + }); + if (lock) { + novaCloseEyes(200, true, false); + setTimeout(function() { + novaOpenEyes(100, false, false); + timemode = false; + }, 1200); + }else{ + novaCloseEyes(100, false, false); + setTimeout(function() { + timemode = true; + novaOpenEyes(200, true, false); + }, 600); + } + }); +} + + +g.setFont("6x8", 4); +g.setColor("#FFF"); +var open = false; +var timemode = true; +var clockmode; +var novaYPos = -7; +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +g.drawImage(nova(), -10, -10, { + scale: 2.2 +}); +Bangle.setUI("clock"); + +g.drawImage(star(), 5, -5, {scale:0.8}); +g.drawImage(star(), -10, 120, {scale:0.8}); +g.drawImage(star(), 120, -5, {scale:0.8}); + + + +var secondInterval = setInterval(function() { + timedraw(); + g.drawImage(novaTopRedraw(), -10, novaYPos, { + scale: 2.2 + }); +}, 1000); + +novaOpenEyes(300, true, false); +main(); From 04f60a596f541c3acee476751133e9c03573348b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:17:23 +0200 Subject: [PATCH 090/121] Create app-icon.js --- apps/novaclock/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/novaclock/app-icon.js diff --git a/apps/novaclock/app-icon.js b/apps/novaclock/app-icon.js new file mode 100644 index 000000000..cf159ba1f --- /dev/null +++ b/apps/novaclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AE3N5ouuGFovuFwYwrF9wuFGFIqC5nMF9guBF9ReD43GGFJeDF9ReFGFImCFwYvBGAReqMEAdCAAwvKAA4pWFxYwNGhQoJAAouHYQYAEGBwsIFBIANGRBgLFzIwDYhoweFx4xGGC4uSGDYuFFpqTIF1BhXFzBhVXSZhNF6QuWGAgvSFzAvS4wved6KOsSDovJ5gACF9IsCBIQxFF8ItEAAYxEF7qHDFowxGBwZeaFxgPEAwYvYABAONF74PVF64RbF6IThDZYVnDIoXtAH4A/AH4AkA==")) From e0b996b75cdf894e051f9ae713c4e6243838d217 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:19:53 +0200 Subject: [PATCH 091/121] Create metadata.json --- apps/novaclock/metadata.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 apps/novaclock/metadata.json diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json new file mode 100644 index 000000000..6e41d8fed --- /dev/null +++ b/apps/novaclock/metadata.json @@ -0,0 +1,12 @@ +{ "id": "novaclock", + "name": "Nova Clock", + "shortName":"Nova Clock", + "icon": "app.png", + "version":"0.1", + "description": "A clock inspired by the Kirby series", + "tags": "clock", + "storage": [ + {"name":"timer.app.js","url":"app.js"}, + {"name":"timer.img","url":"app-icon.js","evaluate":true} + ] +} From 2410a81b1c18d93be47d5da5aaf2e5180df5d958 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:20:25 +0200 Subject: [PATCH 092/121] Add files via upload --- apps/novaclock/app.png | Bin 0 -> 1882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/novaclock/app.png diff --git a/apps/novaclock/app.png b/apps/novaclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..6270be5d37d3ec007b8c61a33f96004e1443cb98 GIT binary patch literal 1882 zcmV-g2c`IlP)F0cE(d+YrF=lsv9a~|AY|Hmt5BxhuiHWs#de)WD&J-7-$ zJGw*ef3;hL9kYl{0jP#AG7g?Lc>M6iMVVO$ft)eqc#;?)2I%9-oEKwjF%j5U{TU$% zp@l9$8-(>^KVO8Y#SlpGak>t=4%!yF2&Bgrk2px=ru=&9E z=WTEP5$NNW2@%>(^&dKwQ4G+BFV5TCTnXgOzx@hPUgs4{=Ar$$9 zsL|+x$s5O>o|oM@N+|tE0VW0A1&D=67d00`gqWaDKb)7rU2d;z8L&Y!h z#)k|||B}4-%A@{}0sOPV3!`2pTZEFN} zud0H#Ex~XI%@Ar27O)1yfH4_EM(h^GY+(5vwLQg!=CAURm*Z3f^5)TRk>u;-G$3Um zXDxxbhd!%U6Ofa7HWrEGbOVWPy}x@|qu_@_@Lt6$7L0%^MadYjQtoH4R>_G4CmCZ$ zNcyfU|K-`e32Yqg39+1_CE;RHFXsu^tpAggRLc69vq~p)FbXKc8&>V1uE17mSqwN) z;9?6Yqu&{)q^;FYUn%j*W?5dlp1W_%0pS!`9;KJ!(Ok-4EEOdwi3y>YKyryh)_a+~ z!Gl(&5CBs=UvOBfBuoKojY_U^O2*pa>kNid`$`BP|84cBjN+5DEsQz{tzK;^6{I9< zNc#hwb%`j*%Bq)r1>S*glt^9cRoNG0<=i8?U;VE#DtDj#4BmW?s)B)srUq9wt(=Bd z=5~{5!wXZQ4e1obkx~;+2>Yd4k-l^x_>Jm{e zHx8PKx4r(|_;NMR%Aqr#-}CjG?VUG|e1*t!j9VC&;iT(S$D^^{OHuXzW|k3fPMzXQ zg8Qb($g2XpeMSzR`_8`nZ)GE2T77~pJWtzccR4P-O*>XHqtZ6dN_TcJA zHgTQ+;xR zryiF2YqP?coj})rcBg@x0N4Y!EA2pCX=`xfN@&hZdaS;OEQm;+gYtc&Li~_e#%b~I0OBd;)ejm$Z=2GckCxxI)aJlyj zC6L#bYXU+aH3F#&9aZtZbt)Ze)%&hQAUH4qssO?2SQ!#zvumbE5VPd<5G&Q@MRtj6-ZQ~HfR)#>`16j;NN)?_|;+vB%Y!#x)qAn zO9ZM(hw7m+dN5fNFp>$*V?rTnptCxOg#y}`GJb=bjMZ4O4y22$zrifXElgv}z?KQeb?bQ)tpii^4 zH`6|tH;=E-jV}^P@9&Hztg)9#c2zzw+mBQE--qwu%G-ZW*BvF5gci{}Ixx6b?mE3b z%|6q!HSuAL=uaYb4Sw(%OJ+sxT{}1{cmTQc!c{qR<`@Ue3V!e!b*&B&3tfD8+I^<4 zLel>cYkP!kT>gX{Jon11p!eMNuJaqfo%zy{6GZt9h9RbUc^-S;Uboln^*^xw1D?l8 Uc_DV*Gynhq07*qoM6N<$g8EIA)c^nh literal 0 HcmV?d00001 From 0103f6a554bd4dee765ae4928761fe8ff560842b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:22:07 +0200 Subject: [PATCH 093/121] readme --- apps/novaclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 6e41d8fed..1b42f22ab 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -5,6 +5,7 @@ "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", + "readme":"README.md", "storage": [ {"name":"timer.app.js","url":"app.js"}, {"name":"timer.img","url":"app-icon.js","evaluate":true} From 4baf6b096b26b388a767819c4025ef7a277db675 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:25:06 +0200 Subject: [PATCH 094/121] Create README.md --- apps/novaclock/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 apps/novaclock/README.md diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md new file mode 100644 index 000000000..677721c66 --- /dev/null +++ b/apps/novaclock/README.md @@ -0,0 +1,6 @@ +## Nova Clock +A simple clock app that uses a clockwork star, from Kirby. + +Pixel art by me. + +*Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* From 0a7a8206453c69e9ef8ccfac2dfcc00633d05a19 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:28:34 +0200 Subject: [PATCH 095/121] supports --- apps/novaclock/metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 1b42f22ab..3ec2bb1b4 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -5,7 +5,8 @@ "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", - "readme":"README.md", + "supports": ["BANGLEJS2"], + "readme":"README.md", "storage": [ {"name":"timer.app.js","url":"app.js"}, {"name":"timer.img","url":"app-icon.js","evaluate":true} From 99600e0c6c6f250e83c1cb0a4609d2c499475801 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:31:47 +0200 Subject: [PATCH 096/121] Update metadata.json --- apps/novaclock/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 3ec2bb1b4..177772e86 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -2,6 +2,7 @@ "name": "Nova Clock", "shortName":"Nova Clock", "icon": "app.png", + "type": "clock", "version":"0.1", "description": "A clock inspired by the Kirby series", "tags": "clock", From b6d14c41046c04d07bc0ca3f559322e37e799a6b Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:36:51 +0200 Subject: [PATCH 097/121] oh. --- apps/novaclock/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/metadata.json b/apps/novaclock/metadata.json index 177772e86..c1dad60a1 100644 --- a/apps/novaclock/metadata.json +++ b/apps/novaclock/metadata.json @@ -9,7 +9,7 @@ "supports": ["BANGLEJS2"], "readme":"README.md", "storage": [ - {"name":"timer.app.js","url":"app.js"}, - {"name":"timer.img","url":"app-icon.js","evaluate":true} + {"name":"novaclock.app.js","url":"app.js"}, + {"name":"novaclock.img","url":"app-icon.js","evaluate":true} ] } From c2d8229c9ef5420d3d684421b87bea00001deab5 Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:41:56 +0200 Subject: [PATCH 098/121] Update README.md --- apps/novaclock/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md index 677721c66..be10bcd6c 100644 --- a/apps/novaclock/README.md +++ b/apps/novaclock/README.md @@ -1,6 +1,9 @@ ## Nova Clock A simple clock app that uses a clockwork star, from Kirby. -Pixel art by me. - *Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* + +# Credits +Pixel art by me, [dronesflier](https://github.com/dronesflier) + +The Kirby series belongs to Nintendo/HAL Labs From b27705eacce0da8fce77dbeb6ca791bbd574cb7c Mon Sep 17 00:00:00 2001 From: dronesflier <42714028+dronesflier@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:42:09 +0200 Subject: [PATCH 099/121] Update README.md --- apps/novaclock/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/novaclock/README.md b/apps/novaclock/README.md index be10bcd6c..b54f44241 100644 --- a/apps/novaclock/README.md +++ b/apps/novaclock/README.md @@ -1,9 +1,9 @@ -## Nova Clock +# Nova Clock A simple clock app that uses a clockwork star, from Kirby. *Note: This clock draws slightly into the widget area, but since it's in the middle, it shouln't matter that much (nobody has that many widgets... right?)* -# Credits +## Credits Pixel art by me, [dronesflier](https://github.com/dronesflier) The Kirby series belongs to Nintendo/HAL Labs From 94aff2d0154cec4cb2ee64a6141eda83429dce0c Mon Sep 17 00:00:00 2001 From: Kilrah Date: Mon, 13 Jun 2022 23:08:05 +0200 Subject: [PATCH 100/121] two of them clock * Try adding new watchface * Add real screenshot * Fix app icon? * Doc Co-authored-by: Kilrah --- apps/2ofthemclk/ChangeLog | 1 + apps/2ofthemclk/README.md | 11 ++++ apps/2ofthemclk/app-icon.js | 1 + apps/2ofthemclk/app.js | 90 +++++++++++++++++++++++++++++++++ apps/2ofthemclk/app.png | Bin 0 -> 4480 bytes apps/2ofthemclk/bg.png | Bin 0 -> 5902 bytes apps/2ofthemclk/metadata.json | 17 +++++++ apps/2ofthemclk/screenshot.png | Bin 0 -> 7273 bytes 8 files changed, 120 insertions(+) create mode 100644 apps/2ofthemclk/ChangeLog create mode 100644 apps/2ofthemclk/README.md create mode 100644 apps/2ofthemclk/app-icon.js create mode 100644 apps/2ofthemclk/app.js create mode 100644 apps/2ofthemclk/app.png create mode 100644 apps/2ofthemclk/bg.png create mode 100644 apps/2ofthemclk/metadata.json create mode 100644 apps/2ofthemclk/screenshot.png diff --git a/apps/2ofthemclk/ChangeLog b/apps/2ofthemclk/ChangeLog new file mode 100644 index 000000000..2286a7f70 --- /dev/null +++ b/apps/2ofthemclk/ChangeLog @@ -0,0 +1 @@ +0.01: New App! \ No newline at end of file diff --git a/apps/2ofthemclk/README.md b/apps/2ofthemclk/README.md new file mode 100644 index 000000000..7ac2cf779 --- /dev/null +++ b/apps/2ofthemclk/README.md @@ -0,0 +1,11 @@ +# two of them clock + +You can now wear teh memez on your wrist. + +![](screenshot.png) + +Also serves as an example of displaying seconds only when unlocked or charging and only refreshing on the minute otherwise. +Widgets not supported + +## Creator +- [Kilrah](https://github.com/kilrah) diff --git a/apps/2ofthemclk/app-icon.js b/apps/2ofthemclk/app-icon.js new file mode 100644 index 000000000..9bfb8a550 --- /dev/null +++ b/apps/2ofthemclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgZC/AH4ADkAPOgVJkgEBAQQAJiQRByEJgmQCJWSpMEAQMkyQJCpASHhAOBpAmBJJgjBCIUJCRg4CCIJxFMQ2SoARCkmACI0EBAJHCCIMLj4RFiUBskAgIXBEAU5A4P34CtCiEJsEJ/AHBCgOBAoQAEi0H////HciQsBwywICIXWzkG4A+BEY0gif46dt6/cgnIgkWnHfLIP/MoUWwHbpvC/kAjEEj0HNYQCCkEfGgP/64RB2EAifHLwMAjg1CCIMD/0H/0B8EAh+HgeAkARCE4IjC/4jBYIMPLIcIAYUPB4OBCIQABhu/AoShCHYIRBx6QBDgUw2//8OHPwcJ39//ILBCIU9LgMBSQgsBJAYRBkE/CIIABgRHD3wRFkk/2zBDAYU//3b/oRB8ARBj6ABgEE7YREEYf+oMkSwINCyClCn//z//+4RBgMkgU3EgUcwFJgEeboOXCIP2EYJCDAAVJkkGWoIuBgf2EYQPDkECCIOGd4ffyEJkgFBAAcSoEkwQCBhw+BwQaByVAkGAKwIFBBANLkEQgAyBCIVIkBpBgmSBYOQoApBgcgiQRCAQIyCCgsSjIFBCIcgRgJNCCgQyBpAgDAQT2BCgIOBBAQUCCIpfBCIwCKP4QRNpCSDCLyJBCIbjBTwYRLboJ0BCI4QD")) diff --git a/apps/2ofthemclk/app.js b/apps/2ofthemclk/app.js new file mode 100644 index 000000000..78415fba7 --- /dev/null +++ b/apps/2ofthemclk/app.js @@ -0,0 +1,90 @@ +const img = require("heatshrink").decompress(atob("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")); + +var battery = E.getBattery(); + +// Positions on screen +const timeX = 88, timeY = 52; +const dateX = 5, dateY = 180; +const battX = 172, battY = 175; + +// Draw on every second if unlocked or charging, minute otherwise, start at with seconds on load +var drawTimeout; +var drawInterval = 1000; + +// schedule a draw for the next interval +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, drawInterval - (Date.now() % drawInterval)); +} + +// Update display and timeout on lock/unlock and charge state change +Bangle.on('lock',on=>{ + draw(); +}); + +Bangle.on('charging',charging=>{ + draw(); +}); + +function draw() { + // work out how to display the current time + var d = new Date(); + var h = d.getHours(), m = d.getMinutes(); + var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2); + var seconds = ("0"+d.getSeconds()).substr(-2); + + // g.clear(); // Unneeded if background image takes the whole screen + + // Draw background + g.drawImage(img); + g.setColor(1, 1, 1); + + // draw the current time + g.setFontAlign(1,1); // align right bottom + g.setFont("6x15",3); + g.drawString(time, timeX, timeY, false); + + // Draw battery % + g.setFont("6x15",1); + var battStr = ""; + if(Bangle.isCharging()) { + battStr = "+"; + } + g.drawString(battStr + battery + "%", battX, battY, false); + + // Draw date + g.setFontAlign(-1,1); // align left bottom + g.setFont("6x15",2); + var dateStr = require("locale").date(d)+" "; + g.drawString(dateStr, dateX, dateY, false); + + // draw the seconds only if unlocked, set next timeout + if(!Bangle.isLocked() || Bangle.isCharging()) { + drawInterval = 1000; + g.setFont("6x15",2); + g.drawString(seconds, timeX+2, timeY-4, false); + } + else + drawInterval = 60000; + + // Schedule next draw + queueDraw(); + // console.log("Draw " + time + ":" + seconds); +} + +function refreshBattery() { + battery = E.getBattery(); +} + +// Only update displayed battery level every minute as it fluctuates a lot +var batteryInterval = setInterval(refreshBattery, 60000); + +Bangle.setUI("clock"); +Bangle.setLocked(false); +// Clear the screen once, at startup +g.clear(); +// draw immediately at first +draw(); diff --git a/apps/2ofthemclk/app.png b/apps/2ofthemclk/app.png new file mode 100644 index 0000000000000000000000000000000000000000..d304f27d9adcd7e680db96c18d27d8408c05c279 GIT binary patch literal 4480 zcmV-`5r6K9P)1R9J;&d1IAm^!6)RRmlIsw@ z{2%z^ApkG{fDwrB^J7eGtjP#uRVD%$te^ynY%nvoqXQHL2p|I8r<4N@W>W>jihJS@naPL} z07b_CcZkdZ;6vpf;sFzVKyhC&fk8$vGY}cshmT=KFeYZGLCDO^2nGei43K-`NdYB- zAs^cGfgAo=wQx}SDYp>-$e~ugPx${JQwWHN>|Sq1W*`;f4?Q)55=@~EAO|rsvkYUC zd=J75OaQ|U^7;@#?x%cUqM!I+VwQuhz;yWbUO`621TumGU?VdFGw8rgHZvoGIS`XE zs{ob(AOiv-gTWYPFgsvkqYnw#{lozg5s@(w1O#JN0zrOuffWET69E}ezE_1avqLSW z4CMP6VPON4T2>|l!H9_oN=Di2zTIpfW48N>-Qj_Vh}npUgoyA#vw+w^vP@W(Me?S1^VnA|VE#3RM_boWwW+5YG;#F{&lz; ztc8;yM|Dob=VUr1unK!40u$JQm{_^?3FDd6kM6d-Xz-borpMxQP&8#2L)d|ZKJ5F$wqXJh#1Zphnm~u;3{6>`qojnynki)? z2E^C_0(J$8!fAFXRi*#pvxg7PPXGFE{?C4#Sg9ynTW8Bk7?Ndjq(D?+Vq%}9NNNBH zKmHX#4#UMPL=a}?!>Y;zwKPE!Q-Vd)IHeK9j%p%jhHS}PVoxzgHCPf#iP9jt`}FB@ zF{4MPC#}=CzoxJ`ZtVQHdbslECyk>CX-HwnF{!E<5fvbDL>~7mlVD18&=ibP;hhL+ z$~i|O0@PUBx;A6Vti~h&B$FnM?42pGLQD#BUdj7RaeY$B(?31>^UwT#w^fT_9L8}Z zakEp}l-iGeJIZFCh6r-r$U6cP%t6Hh(Ikkh#A2(}a@LepDVkjhA?K)S!EpNUc)bnl z>wTY)QHZBVJegPmvu6>Fd(As1{c$S~SJme7-Pzf>EUIleYDNgwbpb#>OYFvgj042z(qrK5u{V>G?nX_HWCw{Njr*o;`mWLpSU$p>e+*>Zr>7r3JdWL!vv70yx~l5!cH7Qo=jV_5 ze$h77G)?Qx?)v(srTWo4H%@LhyJ0k^o~E!bY&=^nWB2CY{p;rsPR{@o*zAVu<0_EG zkB*LYhJc{MTRq+iKi=|HEa9 zebd2w-36~(LT%YL`@zHIBV+wV)ti&C^PN_)Zc|KJKk+)yV3g*4qfPIm@4o%E@&y1dE=3*3DQjZp-F_cqT&-5Cqs7VUxGu|a zztv%TTS9};qLs1AFqn@Rg1bvMPZ7(>pM6{BGWki<3IiH z!qJnbk1pO_h8T%x9OKaS0Af}maz%a9>s4%n=CgKs_ONOy&1q_yY}d8X&m~Y zFT5|SDyCT1RaurPMVJ;-DGEQu6VU0!cC1oz^_i!ZGgICLzUnf$nPG?qSNOI%Dwz8nU0u9a9a9Qwv|O%I&dZ|{ z@#AK*$tgHO+cZFa?Xw4px;l!%n)V5>Eo6*iZ0cgW>58&g-}QOQu567w6BdhwaIT8dvgSnW+i}lV z+wJYnT%glwShoc?i>J;>j$NJxa@gN(O)1E<6EcitRdjn@E>EVI>%tM2vv#S$c71Wz zrwDKAQ%>&NXQiNoW^kMC-^0&iZlJJXsi0%0t&r-ceQ5-Dcy8=Jf3G7%h%51g!5~w{3g0cRKWMI?xZ+=i6`^Dnnv(LA^ z``z1%S8MM0G)S$f5_|Hi#k>jKdfv$Kq8z&0>x;JrXt5sLe-K3Q#c`^|dYlsqXH(*E#ne05{Hyr5#HV8oFzSso=l{EueH+4}wNcv(~> z_x;|NM_iw8diwp>-wxyW?CJ6K^}8wLF(!byI{9u*fAyPhM)xqt(%}1HG)p2JiOTt^ zk3cbtS|+NwSPfHp{`}F^<(sx~nb@i$fAsvff4IILYjej&b&dfV3z{_d;y(E`krDf< zD0Ao^JUCTj-=6Mu^*{gmH)GV#zx?9O>zB^6E1IN^%j55^r@#G|w^w7+>CDxuX$p1W z>beYZiptZNk`*a4L8g$+s($D{dUpQg$%D(Qi!5bv^z7x^-BnjaT7cRVQylj~Q7BHa zm-e$?#c5(VX1=+-98&wy!*);TJ(Xg+{*Lj>=Svt$5_hC$n+3fYJZ+umrJbE&F@ciqyyEoU7{E4bZ z%oayZ0XBskH6`K4|Gx62sT=yCnKjqDyLC5gCLU5VX6MT?T3#J5*X!=|F-cKC6H>4kh5az>o#U(Z=KFV7FTQ<0VxDN0)W;#{ z*gFkuG3KZ_11$Xf*Om!cn2-=rxa`ZIPN@kAQ;1Vmm12JM=LCKDft92b0ju6vhO}2Wya34P+oDVb36o zA%?-?fD{3P7jd4w6QT@tK!8z(3HyT&?Erw|6hPvI%(5lRW*N+?%n&m+RRR%=knf!? zAs8QQNWcIiWPpf_gatxQz?4&rlZ8Fv1j}H8`0NU%gN3gSng~J%FBX8QDTvHSAy61) z6=vrPWg=xLG1OQLsthAK)PL^^8VCwA#lZ`{cgjtiK~!NmY8Y%9VG(2?2Vyf$AZJEI zuEogl|cqaNkPa^A~IFeNKg<`1So?@1Y$WSC1&T#9I_Fz zsF~vMt|v3hSVgmu637f$Ih!VsstMSPVWv>CoRBl1qM1a@IdjgWIJ|BE>Hh@;VHPGU SK~@g{0000(TzKf6%{@(?zwksN;3^dQ(IqP?!za>Sr zej$uyvLvpm|AWSr$trI}mLN=gd)RM(jDG=Kt>KCaR1wcr&>}tz_lLA!G0p{FNd&_= zXPjjJ@#6)s$XF`m&M*P)s+I9J>9Jk$-+r4DaGt_dt$L$EMD@*d#(UzkT|7Gx^ zVwHqc2D`T(QR%hrC&sU|umn-nF*2*7Z$syng;9`LJn-DNT#@Ie`e3@|FJOxo*v`d7 zjAhEKe_8dM6%$ngQFbSfy~)_1<@J;;7Lhj?$FLdY{0+41r4|Zgq-j5}vUg@?(|D~q zZ<2))S@z;*)v2kNcvXI>g{paaLjJ;D23x!qIY!V-=ZsW!Iow58RIx6)H>DshIKN`O zMo!-+?hFc?By~ZVKkzHt=l2X;*UdZU>ReqxE)?%5T6^08K`wHw!LF@|iWO)_4 zs#>eG(=d`-!+axh1tf+F_<;2M!4V|$Ma%4YnOQrm4R zdkkCb7OqN$I5(D%GBM7KadC;8pQ4gWWoHF1B}lB6myRgpUzdm$nI5lj4MZz{NmY-t%Cd9JMC5?U;ct==I%%EPG@7~QoXS@3fG zsV+1y*i5vuXtd%C6>pXA{((!}#vhogPjys`&A%sXDO*Se(k!AHE8~bh9`o~%SUa~2 zmf?~k&-tD(ic;9=4GN<#k^J5NxEBxeh1K^e%_T`-^OQicl3%m<&-lpVo4ft=waQi@ z@~f*@{#Epn#^;aBMgOWs6lEDr%*#+Aie;nknlF{fQsr0dRE}&bQ@GmNWLB-1nWb2~ z<}(TKC@on;x$Nt(caNs{)y+K5H(Q2lD<@NuGs1e3k|0Z15;?t-C5SQpscwV6R~W87 z19tA_n;SyXaBOz3q)_lAZLB_JW*KPqr zpiW&!H4cY^)u9vP!YGRojlc`62eeb5qEspEun!|1!^4SMz80;h))RiBhh%V&`@~ z0yn*fDqTy;5MzR$4=?DV6hhQ{yg!05O$^5NZgG@&HAfkXlJo80y@wRQ4N?Pgbn|ZM z4iCkdBeGITKYYNG5D!4}dEL`-{H2677{#b|lwu!1)q}EdJz2Mi<1+j<&(LvwT!sGt zaQRtJYKh!3)?>f>2h7ZhfsbSk=0`sadpx!2TL|KZ#y6nf_-?Kt^Y+wQvZ04?8{o!Z z@Y1GT--X|9oEb10&eG*C&qI%#=3fB!1Ky{HHVEG>LwK_?{@cF!r*jjWY4*W&)l(Si zw)t&-c)Tjh=m{$wrMr6`cZ=2drF#jPl@aixGPy3)~)rf^Z(xJ7V`SO_}B$YvUS4)%0P;1=Jm2i6~oq2n!Of^&KtQPPjy{Ws#%m!e#hu z`lv(QbzvMvSbo4`85XEm`(eNv)-cK=BUiF&0RFD`J^ct^d(@qPC)&wMX!Heu`M$g3 zaY0zdaa@ig3>114#;KLJrLTRu9;i{>N?+m!z5^xeL&wBM)*dXEGe))cepp5TFF+r` zxn_^>lZEmg*;&$Wu4JG*dR`YM*0?!P>>7lJx|vz!sD=^FTBr*ji0d*8N6@B!Xg@M; za6N@ohKV<$0Y6cSx~8;KN77B*_Tbw^V5Poq8tAkeiFsTg#BuC z#BCee&a+cZ^m3d)b^#p*Dbx&l^niu{!*M^}A~f<}{UsCS;=1Q={&*tswhOnARdJ;0 zdzp?k*BX-hSl382Jb>Cz?_t5yn&ZA<20)9(hexQ4nWfzE*T=7OIMOZNwBWNEKR%<9 z^PfrM?BmzQAD5mv&srGz29*%sbayOYtdA%$E>rdV#I7-X-L}7i3Nkau&mi24$9{?x ze|9zqetd2grJ9Fjde+vS_Vev=XeWMy_|@`Tfv&_FzZ{;PmVuSU(u9|L9P61zW**wS znr-^_4o`!{d(;zzysvw@cRU_%TLQDBKa{HZyPh3%{5sDgTb^|VWIt+WLtuuoo8xE_ z8YxLzfo=~iloq(S;~v0)TD13>@|tl#NRH3lNN;*hMEszSU^hh0q|l81@owMttl7TZ z?HdNMO~CAB(mQk-0XAV^9Q?RUu=~P6WvUfB(BE?=>Li6N;Qlf!?6)vz-8|zt(3x2w z#wa2|b+jX6m+4w+Ues-X4Q^+)4VJ2*8E$D~+Ha04#yceOz!Ync6aX2}(`4!+tFl#o z-?3^sYq-29{9^ap+}%7aOp=zs7)cboZjNg?0FML&*lt1L9KWiO;hQ6>4cS2bR^|9U zC>DM^KKD)A!H47Xz=}~*dmx+N;@o<796%YbMr@BParjsouttSOg4JlUDD4ldZkx7O z2fI7MEpykf{dtxQ@bDC(H7S@LW$`9{oFh>F#QV2t&M34&}w?3x7uSz3&k z1cuCg6rz@q(L5heD<0>z8R1xj@HXt=eblzV?g5Sa+K|~=m3NPGU_DtF>flzpm$v~8zcnfAi%E83L<)Kj2oB{g#d$@wR zyQ5w9cN)PORcCfD_SaCKF)ps=88a?{J%Nv3pZZx!ph+za+0sz>rez0#EJ3ppo~uEV zrmh1UgpKtUJ)|9Qr+SB+13hKlA2;0%_$qM``&#ki1#gf|7)^krYw_bgw5rxhp@y)G zamz^=m2J!Z-S!FUv1tZ+a{&#$p~Z|Hgkx$HxdkwX z!#2oSD8m?rj$d!?o?S za?e?FVw@33h+)%>weUujjba2_a5+cZ`H5ozt{e(OJ>Su(d%aK-KAUAdec{q+6IiB^ z(zuqE-{Kwh7QMyMuNof+JlPP`vulitUjje()R?Kqr5{M&a}t_3nDYH-KkK;k5@r&n zi4QUR?p-e6C#ghp2IksQhq0HZ%yjT6{s{Ogu+3nCSf#gtkMXsV(y}7YF2A7`fzyUo z2%JoOqj-$5Ml)`B)jij}?t>RFM*W7}kn=2sX3#wU%5Giw5*f3Yn!m&VvkrztN!(aV z#tUr30%NU1VGNmzD=ezwwa?(S^6Qu%+S;1?kS16_-^mZnQBo*TB}Jzx_QTGb7h0|Q zZFH;ALW$~aS7e&LWRL=Wn>bN1R1JF{x(U*bJ>|$E?NwXqaL?hmCmsUX6Ilf996oE1Vn z*^(MxnfAOoKto}y+wud%P~Huk=zA`m1iSbl6$3i7w53fc`yf3qM2FZgI(Z^6m$U$W zv@P=daG0XmSg-3;RJ2}T@#hp2k`#{fF%r*8sa-mzs$dHhs}x$FmvkJ*qlK*X7obfu zvcwG9STn;t8e`=2z`i1~MDlWSu;NM8YTIk#5c?Q}&@dtTm?#4)opQRdS?Fg2E;g)J zSYTnG;66#K;fJ7v==pvRwxa;-4|QBN4k|+W4o^Eq=LxvKjvBisUeBUDhQ%f={c(9L z1QL0UySLng2x>L_6bUz8?nva>onr6`ciphZat&`&PZx`ve1)GpaKTMrrx}FK@+%O@ zld#@q`;Ag_HDj?+jF?V$~tVbKH!)1wV5 z;|vJQcDhh1nAf~E8GSq3_Ns!{?U-a56;kL_gE+8^9PkH!yD~2FCl0)r>U!>5#Kx?J z3OUc8ZHLEYg;|ptEe#i9cfe#{C4UfJSUu4D%Y^K%F-tWBw%U-o9Ia7z^P|?q+}JJ3 zdj?O?9CAk10<}q`Aeb|R{hV;iEaybUS(e4#-*&U*h_-mNPDwXs(0M0>nG7kM#Ndp_ z@3{A5$-YUrg;Vf@Ld-=?t1YaV)orLB&}N_kCF2Tf4%UQ3L&oJI5(zDZ8K`MxT>i9R z`o#J`<*DYL0^7Vo=;sGvN(^p#bu1t?XGVJ9*r(RJ*5~>@1+OSRX{E$XAnj~&Jkes5 zYgeqo=r)>1`>QrVX|mJuNuAi{Yp);HevMuJ>t6fu6K{jC*Kz+`gOzU|AGHaiH7Pe1 z-KI-L+M90)%QYkSEGQ0^yOFSSzdm#2$sMNHIVY7NRXSJNP9+OHhiS(l)N2#88O;Xb z30mrYeY+~`+)v}4`(J9zS{Afi<}&HHH%H*YZn2e+gGQDeYfCl;uUE@q0l|R10vB2S z)T66$y}xPi$(q7&K&y>ptYP}PJb&o+MZT>{?MK$FZswuIaF5xnR%#=*i1Ur* zeNbJsy!SP`9-75{`Qo9QE=t3nT5Uv6FkhF9&Til=LCWk}Rj_5EaL3C`;<-CC^gqAE zB^kBL(%F4HR*Jf`P4TQO;uf!Vu{Qz^?QUTm3=8XwS}&A&MYrTFL?M(0+_Bg{reE4F zx>{42edswPV9;y!oTpe=xvP&W82B+xb9=^#}cf^6+ zC<*8J_un!BXPT~fGf%sUVBgeS_Jrmic;{l|T9m_oX#8v3GTlMN>zgj<9L4^L)5OWb)%wxuwRfcA6qt4b-&^o%fj8# zGX$Ro)eX&YZz-(aV|$k$_X2MIJBycMd-GMUyW7g8|3pcMt>u$iI*WAkDmThhXUtT8 z>v;zxcxU_U>C{NRwQ~ciN4x#+&s%kXkG-bd&@|0kgp~(&8{c6TK#(J0-ro`|k91_| zhBlTX9}b!5e0&bQjZJS6mOazG(|n6HVY9E2L>9QMfOXqTNm~3>@5}oJ+(z-uTal9% z+3DoT_CvQRvPb)|;pURU3>^;-=-2Kib(5ieQ{gh+JT1~8D&7;cpGTwV;Ee{BLZ-{C z3h*Y%pe^k7ZG}axEY8jhSs@c}9uJZ!cy_#~EYi!e{L@#qkFfs+u+%)AlW}&bMwkb% zbRr}kgo#DkZeF@8?tJzB@84panV0S8p4=K!PA6h?0?B1&>R6U#8CT|G-HiKhC@g3@ z*AP!Rl$IUo)SI1biqnN1-BD{Gl_VBpJA);ebVto3 z)^PL=%7V^xT13F<5c28BP0H#ro-TT~#Hx&iq)_DY$TwDyctA+C&7$`{+){}er#L%m z8avB-TPe;$3tW9(phYV z?sVqHU|l@?`rZVIf*9`Uy!$!fA{wKx#Cx~h)_<^FM-Q*K`Ffr*8YGs%ABkWtiskkj zgwugfJ67uAfs!8(K7aFKJ?$P3lN(_%w&EJk)4fNFEY`zPE9Vp8)0x#g9;(dNzfr;; z6OIIMl_$bgI=7l9E4y>XKX#mr$b~6!#<()PnAN8P?S;G%6htG@mdE!Et6*&@Py6BS}O-RCr$PUF(|bI0&2b{tvzTHK`kn0SRA{Ub267&eX9n$U=}b^Y8EP@4vtM zzuN;J>Vbd13*g7OeQZDaPmjr5BgdAXnd?6kNf(*@!vM~D9Dxsgo?Y)A&v@VlaEgKT z;2X3I$X1TI0i5#g4cL^sP8fUxxN-6*NF&`mI`;{P_^>5@5Wqc!*(0i1U|L07LB|c` zS?8n+!2kV+J8%E~p$h-+Z`M4!Gk8#V>mD}yU4!^q2IRb*vx5B1^L#jfEifQ}{P*Xb zzxdGY^ZEdOz@!}7h<(vvL-v0&9P@ko5CD$`wZ5Kb(UysM_SQfh-9tXOziUfq zJdoq#dD&7gKMr+dYYu%I z%t(k>YsSS_Yrj=G*s=hFA8Ft?E7^A)SyEUJsxw!Z2;f@F+HEBsxJ9RWV2F#jh}CK! zdRn)&U(Ttua1BWN@Zt=x&1&|LEmpM&!)E+5A$9Ir1c3Q;;&&c$sgq|gtB7KMXZ3F* z3DGjJ4f00^<`~-osi z@#{w>0F0R!Gq41(pXNCLdud$%{s3iN7(GQw#g-8Rw+DlfH#HF31EPW20@(7|@jITu zIr5nEK+<`@P5{_8s{dARtto9V6sKFV05P!!ZYu%Wj)BZ3QU=(+uVxgTLi^TpePE8K zP3?UgK-L9c4a63}+E>L&kAT=#9-8Mo&{~mnR>##a^Po%H5^CAEPxsoOJl+)GNsAm% z<)h8Gc+?uW29zxk+5>t>jQH^S0JfOhszp3tdKpqf1z}_@u%8j`?;YZHS;^7yohTo` z(RuTFvys#4Ydp4Oem|dqTWQd0VO_NC0IwOlW@&L;)vE-eZjBW$>rku(D4IPXAr6q^ z=N!1M0|#2kKo%Q$0LSdRg`?5Hb*kT1B;`TrJ982uvQGoj&se1hY#G}FTNIlJpsWNz zkemB?0ASx>Tx4kmuzRRp8*1O8XPWhU4y^UOUK?!$z}B_3ZMB3r_NluPo`h(x*9>eO z@^S(>VySNc$qdQ>oNe390dj(YMIsW&iyQAzii)*jt7E-Z*q9^cGH?uj$@q2q?C?eL zr`JwvrNR!X`T#@(qQT6J)ng(ckHsT1W`$)@a$)V`n>S9{U%%igC)KF$NmEO4ZZAUdoEuH)>(EdquLL-#ga= zxCZ;?$qg6!hK9_3`_H-!R|DRQiN%~&oHPO1tvfa9xOf7AzI&VzYhShV{7zu+bt;0$ayj6CK0C5osbXKQj@2 zy=vWe+yl*|6bsl9FmlZLEdchyq$Pp3UpKWjF=Dl`mJiknUe|{$5IJx%qYMdQpVF~A zWydlRJ23{AF~0?1|Ai_(fNcV)dCLQJEBE}?ns*Z{YNw4euVta*3yXpE<3Co`V2S%Yhe_r8OMfVM$dbXc;* zNOjs4bZW8(YWBhD2XGBO`xZ09uDW>kifQZjOfiqfcpztxRY?f1#j-nL9KdzEhcmAp zMZB>!J?&Kh*34P{-MhzF18X3Azn!e#MT*qgqoylJU(edD6>HO8T4Eh^kHa1q0WO~1emW2_ zaS!`idN^d@2M1Xdq?b-ujdX*SfyLZ0s~EPbL;`tXNrI@Q=8@w|U<=##|zyfR(N0st^Ykc4W^Qw zdu?HWAF(i!6jDB*8yyV;qf>E4dg^uT?_Q^iV*5LEtNddXZ+a~c&=ymB2d-q7b{|g$ zj?#^1&?=|g^X5Eo1h@Sver~4uqpi#>rH&;TJm$5u^nbFA=IK}OlriaKzDw>IYY%J! zP&AJpAgLcZ1&)<4aeHq=K%Nt-uIUlz9-*+fk!~w z2NC=2Kz(yvcU67*5C|n(%duG&pRr%={nFk_btawwU^W$7w-sl&BR5C;N`6`G=H|L` zw08?xYF*Dh44`#8vt*1fVRVP0wW|}rx}A{$@jB;3Gh0FPzsY-zjr^*Ie8>T!*1|~p zvaGGg$zric6tot%_x9FwCxE>_<`>bv{n;5QEK0BK`q|sAoa<+fI=+Eie_MPGNDfQ2 z)F_`w-7NQYj-IaL(*fX}eeKg}g{iHS%C-9cGlN{_Lg2MiuGd^&VPSU8y68gMH#@r= zAF;d6Xe;gT_h9ycnJwGp`vGd}k-K`{cVS-N4y?ZzPt6|VzgT5{O9jQKN50JVM+XCM zoaNfVZhCgQ^O(b02iX`q`6`Lwzg%XuFTMG%Vcj}99RTJ|I-9yjz+_!}UWI)wkk4dZ zmL*4G$F70KEdy}T$x>r_oq&iztP0oro!;zP<~Reu_0wkT{!q}r>GP!kmLN9EJLBHG zrK@@zj=)>y9816FfY{1r@4$XNahZM1asVR`&)$%n&;PRH%*P8?g81EU^YYPKb>M~o zoT)-*F)Qn`F=k~~DdSdvm;>)BU}QbujbEKTrU4k~*jWx?=RpAO34DCbOc3)oD0=q6 z`fzldS7f8uWY!%9FmtQ$EcTVQuq_@00Pl1A_p?CEv9DDqXM#U_tW{j=HITovHgy1a z>nm*QFd*?#NY+qhy!F7gcB(Ai82jbAa{QG5KCe~Cc>NeN8=TDQ9RTio4pkRajB$F5 zcMpC$QpUr*9`pCyvq$Z`+SXAfwtXD!=cUG<4da<JpRlc{EbDgtrV&&Z}O0GGd7gwndFO&`B60Ps??zE%fHUxxv;yMob? z$Z7g>A4EMMwjY;dbpGl(0QtqrsM0rVjLUOnKK3-T1uzY4Z%h;r#6GhC9LF>R;2e0PER!vq zqipHv?`Yp&1z?nVi-RmJ7lANhR+e?Ef*|px6V3YLI=Fs621>OS^I8W|j*H?D734Fz zJRirv9=mCWW;Gj`!L~bd+2V%PgI0kVvlPq1eu2zr{$6>&kOb@ZGA{CccCKjrG6~^o z76VvQH>CdHi3Kclh_d!za4`V3-?XDM1jD>NDL=bsG~PNCEJ2{TE1%?xxcWh!%wnEY z$j-rPSI>zv^%+X_yR8Vo_UpAY(=(crN!9qkjYg#Hx32*2hNm+C%xb7?(G@Yx%(<9w z#u}J;bCLi4479$tR}VD3QbWrF1j^BM(7rnWya&SjhOAC^^55)cGQeX36iJzl8^vZ& zK=fQ3`?3t&TI$&r6=PluX6ankUov~Flr%{O=H!D_K(T3GgDN_OnOmpc`fNb@!8-@Q zQhxQ^!ncYl{s7j`ezVv0`j%ndmsHA0i1=&X(#fn5qb!P;1%1xiIW{iR!2auHk%pJd zW&zYXbg#fCT82_O$o3@DYhKB|q=fJb3@fObeY5>o=B9=WLPl~}EIeA!#B79$H^C#$ z2|*yv${v~FyqiU1hxNFcW$Kaj5)y)M^LPenhehKeV2yw_D@jJ2D?&+36Thwt`6>g( zGk{eNO3wi!ob?()0GM|yqkXe7V?<)Gj+p7>8XU|E0`cu*_Q2}w#qLW3I+K;;wfg7P z@_~>Lv2*1{b=7I5Yk4Y}phT>~TrUrcceu*$*41)g zKIf&Pf6-|B8HmD+nkcM{Awei(ll8NgHCY*V4k6T5b^#cLgwbVNc-2D{sCq8zqQD^L zZPL&(5a-#~^NZZO2Vw-Ep29VAAkg{mC+~Cyz_tFhm^PAP za}Qj-GscH2*Ju3vWZ*o2y;I7vo>e>`5J~+TIgW9>bk2MRW`XkeZ9jS)gBpe zv8a5Xc*Ed{s_;xCQAFe?l?giRxw|jQXNs$@w z)-uA%XjbNlwEvtv%=Y-q`6dE5(qJ=9K5MS=;P->K5I|NcjoW;Vccbi$EwJxurWrU| zNE?XQ7#lr*M3e#M0ihqnp3gjKHP7bxzFsq9?c3o#uy?9Pi@VvIXSMZMZ?y-w&r;;M zVFci)rMAr^-n;QG;2y6re7{Zsur4klP|pS?noo8b*s(H|qifpF$3Tp-mUR#dXx|aM z#XsZn!Hz`t!#vV36lByY^Bj+Y8LgWEu0DWhKlbOnz^#k8a(Fx&JYT+R%WIr{H;=d> zalTT--Pp(gtT&xy+IE_qG>B0L#Oe#@m}5PNCENBLwDYgZ`B2*z`xJa9j{iQ~i$~Oh zF&g9^GcsV)0P|W&QFdU9xIX5X4`Af43>?RRgjYiI=Y5L(Nq(ubv@qHiTv*%6rtj={ zMmnHW%-EgJ8rb164042#wGROdLo^g87!SBswqty{uZqF@L?-(PSq{WVZ*Ge}R_+C^yYo;iENa0dGpNSaI5G;Y%a3}3bdD&>pjm2#6IWI|K0wz?1d{m zQJZm1U#B5jnbg2SaTv4praPVT7#C?-paE+EI0FRKw_YzH`sD-Tzw5`$Jn#d5Coa-k zSts={vc*swV=De+6Hvp5a|2OZRsWgX%mK{${=D&P{FP+jHqFVDJmL%%#9ncTIuem> zeQU1?h?EkAB*p-IJV|)?!1~=t^jcDAYlV69%b7X=Y=d~r$-7AiNV+YQT{G%QGi%oX zSQ8L?)?8oMw@ho$T&s@VaV;rV9`r5=u>&}BGlSVU0+3{SRD5OFmMQv8Yn`>DO5 z6a$s<`mBS2)>`McVFn&a-E!LufU}IN=hwF8ZpE$(0t&zXxdvd?#+3lh+S2ERP5{?3 zVgy*)Y!6hUYgjisyc-?sI}Lront#<#1GttFy#TXXaHuWk-EGPSxPaQ%#^5n-Aa&$PNdTu7-btN1xF0 zPVKlNpRGJoti zfUnP5`yM7p2k{L@!S@=rd9bJ^k415%IMN;e%W8ZA=6H2{Ip#fWWJu<=m z*0K2O`*P>kF>lSfd!KoUgwTPu9ze;TTnoUNVzGr^-iGglaNQ5~+M2m~WtOLOK`3oK z4ZyWN?!QCBw|p$NKfrzi*N0aDh<;XBKY}SG;|hOToeUq$3nav>6R5$@&3glw^AiW; z(YZ3$TOgH(=W+(lY{p3X&%@r+h1eN*Z2kM{6&^rrt0kz;4%6FcD>k_oh7b9{7IRV` z-|}HqOlHn2<;xN8eFaO}T%v(zY#3`{ySQ7S)n@GH7w51#3RbOTO9rD&koa2e<^Hzs z$k{hY9>(6ly*y-<0e(A7w#JU1Tgh-tw}18_MO+;QePe@rDCoUH`P&9?7(D0GaxcAW;V*MTUzBp8?#7w=Z#YrD05-oCQ?=$!}Ir-7JVCp&&U z@DYe3snB?%`lCZ31K$9SL)#0K-vY1&UJtPH_vq*6;|cq-`F;N#ZLPlRXJ4i5LI3uc z4lyy>xA*z1-@lURt2e&?rq{07acJkW9x2GKssX)UKcs@=HL(5fuK;is7~Vl)0gMhBI!LqD&)S?jqG7lKUxRP!`i`)W2FqTE4wdleDoM3 zH$#0RBfe%T1ET=k0FHx!{5J~7?EEa;s)Q~cHs62G=v_Gu%LZxJTL8EiH4nZubLwx+cwfM^fo%b}{@vRZaaS>LFCY=%(7dBs838W~cr+jW{K)GTSiLV9 z98B9XtlWcSWNnL*5Y}^=zWFS(^cF3nfyiFJYCJn{7T8{7*!3_l(TG+ycmS?gQ@rd( zzMIYiY68H>;QI3$z`H+Cn~w$5X92h^xGeNo@5__lQ?%=lgGeLrZoYr23-jwY$nn1l zVB{AhAz0>IwN8$vqS2})@O%ps(!kzZEo-or??1-YI$a3;Ens_+8^9bCSRiKo*?Ukp ztI?-L%5kx&+Bc-1E$(s(RDZUFB-%>oq>$aM^Cv#&3W9xs+@I~Dq!9g=Z1 zkcOL&wa Date: Tue, 14 Jun 2022 09:04:15 +0100 Subject: [PATCH 101/121] Fixing apps that use buzz after recent buzz strength PR (these apps would have previously used a low strength buzz) --- apps/messages/settings.js | 2 +- apps/messages/widget.js | 2 +- apps/multitimer/alarm.js | 2 +- apps/noteify/app.js | 14 +++++++------- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/messages/settings.js b/apps/messages/settings.js index adea36f12..1b166dcf6 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -1,7 +1,7 @@ (function(back) { function settings() { let settings = require('Storage').readJSON("messages.settings.json", true) || {}; - if (settings.vibrate===undefined) settings.vibrate="."; + if (settings.vibrate===undefined) settings.vibrate=":"; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; settings.unlockWatch=!!settings.unlockWatch; diff --git a/apps/messages/widget.js b/apps/messages/widget.js index ca02d4f1f..25573220f 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -34,7 +34,7 @@ draw:function(recall) { Bangle.drawWidgets(); },buzz:function() { if ((require('Storage').readJSON('setting.json',1)||{}).quiet) return; // never buzz during Quiet Mode - require("buzz").pattern((require('Storage').readJSON("messages.settings.json", true) || {}).vibrate || "."); + require("buzz").pattern((require('Storage').readJSON("messages.settings.json", true) || {}).vibrate || ":"); },touch:function(b,c) { var w=WIDGETS["messages"]; if (!w||!w.width||c.xw.x+w.width||c.yw.y+w.iconwidth) return; diff --git a/apps/multitimer/alarm.js b/apps/multitimer/alarm.js index 97cbaa5fa..eb1b3b259 100644 --- a/apps/multitimer/alarm.js +++ b/apps/multitimer/alarm.js @@ -120,7 +120,7 @@ function showAlarm(alarm) { Bangle.setLocked(false); } - require("buzz").pattern(alarm.vibrate === undefined ? ".." : alarm.vibrate).then(() => { + require("buzz").pattern(alarm.vibrate === undefined ? "::" : alarm.vibrate).then(() => { if (buzzCount--) { setTimeout(buzz, settings.buzzIntervalMillis); } else if (alarm.as) { // auto-snooze diff --git a/apps/noteify/app.js b/apps/noteify/app.js index c19694ea4..2b3ee64f0 100644 --- a/apps/noteify/app.js +++ b/apps/noteify/app.js @@ -5,7 +5,7 @@ var notes = require("Storage").readJSON("noteify.json", true) || []; var alarms = require("sched").getAlarms(); msg = ""; -function startNote(idx) { +function startNote(idx) { idx == undefined ? note = "" : note = notes[idx].note; require("textinput").input({text:note}).then(result => { if (result != "") { @@ -23,20 +23,20 @@ function viewNote(idx) { textY += e.dy; g.setClipRect(0, 30, g.getWidth(), g.getHeight()); if (textY > 30) textY = 30; - if (textY < textBound) textY = textBound; + if (textY < textBound) textY = textBound; g.clearRect(0, 30, g.getWidth(), g.getHeight()).setColor(g.theme.fg).setFont("6x8:2").setFontAlign(-1, -1).drawString(g.wrapString(notes[idx].note, g.getWidth()).join("\n"), 0, textY); },back:()=>{ Bangle.setUI(); showEditMenu(idx); }}); - + } function showMainMenu() { var mainMenu = { "" : { "title" : "Noteify" }, "< Back" : function() { load(); }, - "New note" : function() { + "New note" : function() { E.showMenu(); startNote(); }, @@ -187,7 +187,7 @@ function editAlarm(alarmIndex, alarm) { as : false, dow : 0b1111111, last : 0, - vibrate : ".." + vibrate : "::" }; if (msg != "") a["msg"] = msg; if (!newAlarm) Object.assign(a, alarms[alarmIndex]); @@ -195,7 +195,7 @@ function editAlarm(alarmIndex, alarm) { var t = decodeTime(a.t); var alarmTitle = (a.msg == undefined) ? 'Alarm' : (a.msg.length > 12) ? a.msg.replace(/\n/g, " ").substring(0, 12)+"..." : msg.replace(/\n/g, " ").substring(0, 12)+"..."; - + const menu = { '': { 'title': alarmTitle }, '< Back' : () => showAlarmMenu(), @@ -264,7 +264,7 @@ function editTimer(alarmIndex, alarm) { var t = decodeTime(a.timer); var timerTitle = (a.msg == undefined) ? 'Timer' : (a.msg.length > 12) ? a.msg.replace(/\n/g, " ").substring(0, 12)+"..." : msg.replace(/\n/g, " ").substring(0, 12)+"..."; - + const menu = { '': { 'title': timerTitle }, '< Back' : () => showMainMenu(), From 3c024be9c94fe021496be65c6a1b28598b269453 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 14 Jun 2022 09:54:52 +0100 Subject: [PATCH 102/121] recommend 2v14 --- loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader.js b/loader.js index e9887f3d4..0e0fdcba0 100644 --- a/loader.js +++ b/loader.js @@ -16,7 +16,7 @@ if (window.location.host=="banglejs.com") { 'This is not the official Bangle.js App Loader - you can try the
Official Version here.'; } -var RECOMMENDED_VERSION = "2v13"; +var RECOMMENDED_VERSION = "2v14"; // could check http://www.espruino.com/json/BANGLEJS.json for this // We're only interested in Bangles From fa2fa9e4a721145ceebd9536ca391f3bc1063472 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Tue, 14 Jun 2022 20:09:57 +0200 Subject: [PATCH 103/121] sleepphasealarm: set acc fixed intervall --- apps/sleepphasealarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 92f4b3dc7..9f2e6c3b4 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) { run = () => { layout.state.label = "Start"; layout.render(); - Bangle.on('accel', (accelData) => { // 12.5Hz + Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval + Bangle.on('accel', (accelData) => { const now = new Date(); const acc = accelData.mag; const swest = calc_ess(acc); From ee8f62d250b8c91732d5d21c5841b7ca31055295 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Tue, 14 Jun 2022 20:29:10 +0200 Subject: [PATCH 104/121] sleepphasealarm set powerSave=false do not dynamically change accelerometer poll interval --- apps/sleepphasealarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 9f2e6c3b4..b19799c4b 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) { run = () => { layout.state.label = "Start"; layout.render(); - Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval + Bangle.setOptions({powerSave: false}); // do not dynamically change accelerometer poll interval + Bangle.setPollInterval(80); // 12.5Hz Bangle.on('accel', (accelData) => { const now = new Date(); const acc = accelData.mag; From 9bab1477fe8dfa25c5579c6ed34715351bc38e1f Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 15 Jun 2022 08:21:39 +0100 Subject: [PATCH 105/121] vectorclock 0.09: Workaround for issue in 2v14 firmware (fix #1959) --- apps/vectorclock/ChangeLog | 1 + apps/vectorclock/app.js | 2 +- apps/vectorclock/metadata.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/vectorclock/ChangeLog b/apps/vectorclock/ChangeLog index 02831edde..6693f57ec 100644 --- a/apps/vectorclock/ChangeLog +++ b/apps/vectorclock/ChangeLog @@ -6,3 +6,4 @@ 0.06: Redraw widgets when time is updated 0.07: Fix problem with "Bangle.CLOCK": github.com/espruino/BangleApps/issues/1437 0.08: Redraw widgets only once per minute +0.09: Workaround for issue in 2v14 firmware (fix #1959) diff --git a/apps/vectorclock/app.js b/apps/vectorclock/app.js index 663a4c84f..ee3a4ea53 100644 --- a/apps/vectorclock/app.js +++ b/apps/vectorclock/app.js @@ -16,7 +16,7 @@ var commands = []; var showSeconds = true; function pushCommand(command) { - let hash = E.CRC32(E.toJS(arguments)); + var hash = E.CRC32(E.toJS(arguments)); if (!delete rectsToClear[hash]) { commands.push({hash: hash, command: Function.apply.bind(command, null, arguments.slice(1))}); } diff --git a/apps/vectorclock/metadata.json b/apps/vectorclock/metadata.json index 541766fa2..245aad044 100644 --- a/apps/vectorclock/metadata.json +++ b/apps/vectorclock/metadata.json @@ -1,7 +1,7 @@ { "id": "vectorclock", "name": "Vector Clock", - "version": "0.08", + "version": "0.09", "description": "A digital clock that uses the built-in vector font.", "icon": "app.png", "type": "clock", From 924ec23211092b304c135ff2b2e503c24f962b24 Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Wed, 15 Jun 2022 09:23:14 +0200 Subject: [PATCH 106/121] updates Github action and replaces TravisCI badge --- .github/workflows/nodejs.yml | 30 +- .gitignore | 1 - README.md | 2 +- package-lock.json | 2168 ++++++++++++++++++++++++++++++++++ 4 files changed, 2182 insertions(+), 19 deletions(-) create mode 100644 package-lock.json diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 1eb009153..a3469e7bb 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,4 +1,4 @@ -name: Node CI +name: build on: [push, pull_request] @@ -6,29 +6,25 @@ jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x] - steps: - name: Checkout repository and submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - - name: install testing dependencies - run: npm i - - name: test all apps and widgets - run: npm run test - - name: install typescript dependencies + node-version: 16.x + - name: Install testing dependencies + run: npm ci + - name: Test all apps and widgets + run: npm test + - name: Install typescript dependencies working-directory: ./typescript run: npm ci - - name: build types + - name: Build types working-directory: ./typescript run: npm run build:types - - name: build all TS apps and widgets + - name: Build all TS apps and widgets working-directory: ./typescript - run: npm run build \ No newline at end of file + run: npm run build diff --git a/.gitignore b/.gitignore index 231851dd6..a9398e871 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .htaccess node_modules -package-lock.json .DS_Store *.js.bak appdates.csv diff --git a/README.md b/README.md index b3da9f685..e8d5579c0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Bangle.js App Loader (and Apps) ================================ -[![Build Status](https://app.travis-ci.com/espruino/BangleApps.svg?branch=master)](https://app.travis-ci.com/github/espruino/BangleApps) +[![Build Status](https://github.com/espruino/BangleApps/actions/workflows/nodejs.yml/badge.svg)](https://github.com/espruino/BangleApps/actions/workflows/nodejs.yml) * Try the **release version** at [banglejs.com/apps](https://banglejs.com/apps) * Try the **development version** at [espruino.github.io](https://espruino.github.io/BangleApps/) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..6872e616c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2168 @@ +{ + "name": "BangleApps", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@eslint/eslintrc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "requires": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + } + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "nodemon": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz", + "integrity": "sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "npm-watch": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/npm-watch/-/npm-watch-0.11.0.tgz", + "integrity": "sha512-wAOd0moNX2kSA2FNvt8+7ORwYaJpQ1ZoWjUYdb1bBCxq4nkWuU0IiJa9VpVxrj5Ks+FGXQd62OC/Bjk0aSr+dg==", + "dev": true, + "requires": { + "nodemon": "^2.0.7", + "through2": "^4.0.2" + } + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} From 67e2fb24003b0d74c0100bef04e9b02fa5aaef37 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 15 Jun 2022 10:41:45 +0200 Subject: [PATCH 107/121] Add a simple watchface to learn Hiragana and Katakana --- apps/kanawatch/ChangeLog | 1 + apps/kanawatch/README.md | 12 + apps/kanawatch/app-icon.js | 1 + apps/kanawatch/app.js | 825 ++++++++++++++++++++++++++++++++++ apps/kanawatch/app.png | Bin 0 -> 15313 bytes apps/kanawatch/metadata.json | 31 ++ apps/kanawatch/screenshot.jpg | Bin 0 -> 21235 bytes 7 files changed, 870 insertions(+) create mode 100644 apps/kanawatch/ChangeLog create mode 100644 apps/kanawatch/README.md create mode 100644 apps/kanawatch/app-icon.js create mode 100644 apps/kanawatch/app.js create mode 100644 apps/kanawatch/app.png create mode 100644 apps/kanawatch/metadata.json create mode 100644 apps/kanawatch/screenshot.jpg diff --git a/apps/kanawatch/ChangeLog b/apps/kanawatch/ChangeLog new file mode 100644 index 000000000..7b83706bf --- /dev/null +++ b/apps/kanawatch/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/kanawatch/README.md b/apps/kanawatch/README.md new file mode 100644 index 000000000..1fdf1927c --- /dev/null +++ b/apps/kanawatch/README.md @@ -0,0 +1,12 @@ +# kanawatch + +A simple watchface design with hiragana and katakana +cards for learning. + +## Author + +Written by pancake in 2022, powered by insomnia + +## Screenshots + +![hiragana and katakana](screenshot.jpg) diff --git a/apps/kanawatch/app-icon.js b/apps/kanawatch/app-icon.js new file mode 100644 index 000000000..a17f21d56 --- /dev/null +++ b/apps/kanawatch/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxEBAH4A/AEn/AAgrrAA4ttGL4hF9fGsU1pMNmti43rGLwcD/3MxEAud413p6uuvFzgGI5n+GDQaD6F8i2p8KKH8Opi186AwYC4Xv08A0fnXhfn0cA0/vGCoVC7+ItHNE4vQ+oxH5toxHfGCYTC8t/xaKH5VY+CUIxd/8owSCIPxymB8wkH8UA2yTI82Byn4F6AXCwNH7YjI7UATAwAD7dHHgYuP4sAc5XLgHrBpXAjngGBwOCrmJ/whJ1syBgXw7v6Bov+xObF5rWDgHWKJWEt3l4mQjkAoHzBwvWgHhGBgMC1WIDQuw1/L427z8ygAABp+R3vqH4+I1QvO/1R5YZF+t1FINWuMAy/W+BuKZ4NRT4ReL7kc+waG/fy/n/9kA74tLAAP2jncAgPBF5W5yIeLZgPxEgf3CJOR3JTCF5WU3wvL6sA/YFC7e0CJO+ygDB94vKt3aF5fHoQDB+/dzdL4nb+YRG7VuAYP5F5VF9ovL3dP3t8pOKgFw0+CjmT84RE9tFAYP+F6/uwMm1Hd/vCk3oQYWGl3XF6aPK/e0oVwrohCmu9Bof5sVF+yPSd5PtuWA9m7o///uCwH9B4m9gHKd6W5yIuG9NV3v+//Gjn/2VA9wQF6UA2AFCyO5AYPcF5Xcjh1DAAPnp/SEYnJiy2EAAXTgGvAgP2jncAgPBF44wC/1R5a7EsZHCAAPegEA3afH4sA4wEB5dROgP/FxBgD1WIPgky/QGD5MAxYfCAAuGjnvAgNHuBLCF5nhgHWAoWvuwEC9mWLwN+Fw6aB1wEB60A44EB6ovJGAebxJSC1lF4/AyMNoXBzUN/IuF5kmyP8VgOJrgKCFxUB8QOB8Ec4CnCLIMAmWr+v/9Vy/otD+WWmu7BAXAjnFF5xgD21H7f//u+0vN/CKH9Ojse4+QHC7dH2wuPgPVCAP4yk98wqHAAf734OF82ByhCDF5pgD/9/xfhGBYAF8OLv/lFyIABU4XfxFo5ouP5toxHfFyZhE9+ngGj84tL8+jgGn94uVSQvQvkW1KUI8Opi186AIDFygwF/3MxEAuew6fp9PT2FzgGI5n+FzQwFAAPr42fu9JpN3z/G9YPFFzAxIABYtbGKItfGZYrlAH4A+A")) diff --git a/apps/kanawatch/app.js b/apps/kanawatch/app.js new file mode 100644 index 000000000..ada6aa6df --- /dev/null +++ b/apps/kanawatch/app.js @@ -0,0 +1,825 @@ +const stripe_width = 32; +const stripe_pos = 40; +const stripe2_pos = 110; +const h = g.getHeight(); +const w = g.getWidth(); + +/// ///////////////////////////////////////// +const katakana = {}; +const hiragana = {}; +katakana.A = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAjAEBfv4B/+yeAXwAOgBAAPAAAEHAAABzAAAAPgAAADgAAAAwAAAAMAAAAGAAAABgAAAAYAAAAMAAAADAAAABgAAAAYAAAAMAAAAGAAAADAAAABgAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.A = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAAAIAAAACAAAABgAAAAZ4AAGf4AAA/gAAAAQAAAAEAAAABBAAAAQwAAAN/wAADiGAADxAwABswEAAhYBgAQUAYAMHAEACBgDABh4AwAZ2AYAD4gcAAQAcAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.I = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAwAAAAGAAAADwAAAA0AAAAYAAAAUgAAAGAAAAFAAAADgAAAA8AAAA2AAAAZgAAAYYAAAMGAAAMFgAAGAYAAGAGAACABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.I = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAgAEAAEABAAAgAQAAMAGAABAAgAAYAIAAGACAAAwAQAAMAEAADABiAAQAIgAAADQAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.U = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAQAAAAHAAAAAwAAAAICAAACIAAAAgIABQa3AAP7q4ADQANAAwADAAMABgADAAYAAwAGAAMADAADAAwAAwAYAAMAGAABADAAAABgAAAAwAAAAMAAAAGAAAACQAAADAAAABgAAAAwAAAAoAAAAAAAAAAAAAAAgAAA=') +}; +hiragana.U = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAIAAAABwAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAA4YAAA4CAAAAAgAAAAIAAAACAAAAAgAAAAYAAAAGAAAABAAAAAQAAAAIAAAACAAAABAAAAAQAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.E = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAJXAAe+20ADRQAAAAOAAAABgAAAAQAAAAMAAAABAAAAAwAAAAEAACABAEAgJbvgP9qSsByAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.E = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAADgAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAdwAAAcYAAB8MAAAIGAAAADAAAABgAAAAwAAAAYAAAAMAAAAGAAAADIAAAB4gAAA4EAAAMAgAACAOGAAAB/wAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.O = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAADwAAAAOAAAADAAAAAwAAAAMAAAAjAABAAydAbff/wH/XAUAwDwAAAB0AAAA7AAAAMwAAAHMAAADjAAABkwAAA4MAAAZDAAAMEwAAGEMAAGQzAADAHwABAA8AAAAHAAAABAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.O = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADACAAAwAYAAMADAADIAQAA/AGAF+AAAAyAAAAAgAAAAIAAAACAAAAAg/gAAJwOAADgBgABgAMAAoADAAyAAwAIgAMAEIAGABCADAAJgBgAD4AgAAMAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAcGAAADgwAAB4HAAA4A4AAMgHAAHAA4ADAAXAAwAA4AYAAHAMAABwGAAAMGAAACDAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAABAACAAYAAwAGAAMABgACAAYAAgAHwAIAD4AGAfYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAOGAAQEfgAFCA8ABggPwAYG+GAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAXAAAABwAAAAYAgAAGAMAABgDgABYD0AAWF4gABvwAAAfAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAgAAal8AAD//gAAJQAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAA8BAAB2AYAABACAAAwAQAAIAEAAGAJgABACIAAwAjAAIAIYACACGABABAwAQAQEAEAEAABADAAAAAgAAEAYAABAEAAAYDAAADDgAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAAALwAYt/vAD/0DwAcABwAACAcAAAAGAAAADIAAAAwAAAAYAAAAOAAAAGAAAADgAAAAwAAAA0AAAAaAAAAOAAAAHAAAAHAAAAHAAAAGgAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAACAAAAAQAAAACAgAAAgEAAAMBgAABAYAgAwDAMAMAgBgCAAAYHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAANwAAAGHAAADA4AABwDgAIwBOADcABwQeAAHgDAAA8AIAADwAAAAeAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAIMAAAMAgAAGAGAADAAwAAAADAAAAAYAAAADgAAAAMAAAABwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAEAAAADQAAAAYAAAASAAAABgAAAAIAACAGK4A273dAHoYAAAAGAAAAAgAAAIIQAAECGAABAgwAAgYGAAIGAwAGAgGADAIBwBiCAaAYRgDAMDIAgAAeAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAQB+AAEAgAABAAQAAQAGAAIABgACAAQAAgAHwAIAD4ACAfQABAAEAAQABAAEAAQABAAGAAQABgAEAAYABAAGAAQBdgAHAg4ABwAHgAIB+OACAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAUAAAADwAAAAcAAAAGAAAABgAAAAYFABAOvwAfv9eAD6wHAAQMBwAADAYAABwGAAAYBgAAGAYAADAOAAAwDAAAYgwAAMgcAADEmAAFgzgAAwHwAA4B4ABYAcAAMABAAEAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAAAIAAAACAAAABAAAAAQAgAAMAEAAD8AwAHggGAHQIBgAECAMADAgDAAgIAQAIGAEAEBAAABAwAAAwIAAAYGAAAGBgAAADwAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAACwAAAAeAAAADgAAAAYAAAATBgAAAz8AAAP5AAxfQAAH8YAAA4GAAAABgHAAAYf4AAD+pAAF8AAMPsAAC/hgAAPAYAABAGAAAABwAAAAYAAAAHAAAAAwAAAAOAAAADAAAAAYAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAAGAAAAAgAAAAIAAAADDAAAAfwAAAeAAAA4gAAAwIAAAABAAAAAZwAAADwAAAHwAAAOGAAAAAgAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAEAAAABgAAAAPmAAAAfwAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAAHAAAAA4AAAAMAAAAHBwAAB/+AAA0XAAAaBkAAGA4AADAOAABgHAAAwBwAAYA4AAMAMAAGAHAAAADgAAABwAAAA0AAAAaAAAAOAAAAHAAAADIAAADgAAACgAAABgAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAADAAAABgAAAAQAAAAIAAAAGAAAABAAAAAgAAAAQAAAAEAAAACAAAAAQAAAAEAAAAAgAAAAEAAAABgAAAAIAAAADAAAAAYAAAAGAAAAAwAAAAMAAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAABwAAAAOAAAADgAAABwAAAAYAQAAGAAgABgF8AA79/gAb7gAAGQcQADAHgABgBgAAYAwAAZAMAAMAHAADABgAAgAwAAAAMAAAAGAAAALAAAABwAAAAYAAAAYAAAAMgAAAGAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAABAAAAAYAAIAGAAGABgABgAYAAYAGAAEAB+ABAB/gAQHmAAEABgADAAYAAgAGAAIABgACAAYAAgAGAAIABAACAAQAAgAEAAKABAADgAwAAYAIAAGACAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwCtwAH//8AA+oGAAEABgAAAAYAAAAGAAAABgAAAAQAAAAsAAAADAAIAFwADv//AAf1CQACAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/8AAAADwAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAYAAAAD8EAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAFcAIG/3ga/0h4H6gA4AcAAcACAAOAAAAHAAAYDAAAFjgAAAPgAAAB4AAAAOAAAABwAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABBAAAAf8AAD+AAAOBAAAAAQAAAAGAAAABgAAAAZwAAAHwAAB/gAAAAYAAAAGAAAABgAAAAYAAAAGAAAARgAAAR4AAAIHgAACDPAAARg4AABAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAegAAAC+gAAAB8AAAAHgAAAAYAAAAQAAAAgAAAegAAAB+AAAAD4AAAAPAAAABwAAAAMAAAAAAAAAAAAAAAAAAAUAAAAF8AAAAHwAAAAPgAAAA8AAAAHwAAAAeAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAA+YAAAEMAAAADAAAABgAAAAQAAAAMAAAACAAAABgAAAAQAAAAIAIAAGAGAADgBgAO/wQAEIH8ACEAH4AiABnAJgAQQBgAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAACgAAAAcAAAADgAAAA4AAAAcAAAAHAAAABkAAAAYAAAAMQAAADEAAABwwAAAYGAAAGAwAADAHAAAwA4AAIAOAAWBfwBBX9OAf/oDgH+gAYA6AAGAAEAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAYAAAACAAAAAgAwAAIAGAACIAwAA/gEAB+ABAB2AAAAAgAAAAYAAAAGAAAABgAAAAYAAAAGAEAABgBAAGQAQAA0AEAAFABAAAwAQAAEAMAARgCAAGWHgAA8fgAAGAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.ME = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAcAAAABgAAAAcAAAAHAAAADgAAAAwAAABcAABgGAAAfDgAAAewAAAB8AAAAPAAAAD8AAABzgAAA44AAAcHAAAGAwAADAAAACgAAABwAAAAoAAAAcAAAAMAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.ME = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABgAAAAYAABAGAAAIBAAACAwAAAgP4AAMeDgABZgMAAYQBgAOMAYAGiACADJgAgAjQAIAQcACAEGABgBBgAQARsAIAHwAEAAQAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAABAAUAASXfgAD7EQAAQwAAAAOAAAABAAAAAwAAAAEAUBADd/wNfaRID1EAAAIDAAAAAwAAAAEAAAADAAAAAQAAAAMAAAABiQAAAf+AAABKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAIAAAACAAAAB+AAAA/wAAB0AAAABAAAAAQAAAAEAAAABAAAAAQAAAAEYAAAf+AAABwAAAAMAAAACAIAAAgCAAAIAgAACAIAAAgCAAAEBAAABgwAAAP4AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAPAAAAA4AAAAOAAAADAAAAAwBAAAMQAAADAaBAT9/wf/vbcD6DAAAQAxAAAAMAAAADAAAAAwAAAAMAAAAGAAAABgAAAAYAAAAMAAAAGAAAABgAAAAwAAAAYAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAgAAAAJgAAAH4AAA/gAAAMQAIAAIABAACAAYABgACAAQAAAAMAAAACAIAAAgCAAAAAgAAAAIAAAACAAAAAgAAAPIAAAEOAAABB4AAAQTgAAD4MAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgALAANb/8AB/6pAAMAAAAAACAAAAAAAAAAAAAAAAAAAAAAABAAAIAAAJvAKN//4D/1EGAdAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAGAAAABgA/AAYBwAAEAAAABAAAAAQAAAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAAEAAAIAgAADAH/gAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFgAML38AB/9OAAOgHAAAQBgABAA4AAAAMAADoHAAAPRgAAAfYAAAB4gAAAPQAAADeAAABjwAABwcAAI4DgAA4AcAAcADAAcAAQAaAAAAWAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAABAwAAAIMAAACDf4AAg4DAAIYAYACeACAAZAAgAMQAIAFMACACSAAgBDgAIAwwOGAIMEbACHBDgAjYPsAPCABgBggAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAGAAAAA4AAAAHAAAAA4AAAAGAAAABgAAAAJYABAv/AAf+nwAD4DoAAQB4AAAA8AAAB8AAAAeAAAAPQAAAHzgAAHMeAAHDB4ADgwOAHgMBwHADAMKgAwAgAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAEAAAAAAAAAAAAA=') +}; +hiragana.NE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADAAAAAwAAAAIAAAADAHgAA8GIAA+CCAAzBAwAAhAMAAIgDAAGQAwABoAMAAsADAASAAwAFgAMAC4ACAAyAugAcgIYAGYCHABGAecABgABgAYAAIAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAABwAAAAeAAAAOAAAADgAAAAwAAAAcAAAANAAAADAAAABwAAAAYAAAAOAAAAHAAAABgAAAAwAAAAYAAAAMAAAAGAAAAGQAAADAAAADgAAAAkAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAD44AADEBAABBAIABgQBAAwMAYAICACAEBgAgAAQAIAgMACAICAAgCBgAYAwwAGAEIADABmAAgAPAAQADgAYAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAEAAQAIAANTvgAD/u0AAOAAAAAACAAAAAAABAACAAgAt4APf/vAB/UDQAIAJwAAAA4AAAAOAAAAHAAAABgAAAA4AAAAcAAAAOAAAAGgAAADQAAABoAAAA4AAAAcAAAAaAAAAMgAAAEIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAACAAAAAwAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAgAAAAYAAAAEAAAABAAAAAQAAAAEA+AADBwQAA3gCAAPgAgADAAIAAAAGAAAADAAAABgAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAQBwAAHgOAAAsDgAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAACAwAAAAYAAAAGAAAADAAAAEwAAAA0AAAAcAAAAOAAAAOAAAAOAAAAGAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAABAAAAAYAAAAGAAAABAQAAAQGAAAEAgAABAIAAAwCAAAIAgAACAIAAAoCAAAOAgAADAIAAAQCAAAEAgAAAAYAAAAGAAAABAAAAAQAAAAEAAAACAAAAAgAAAAAAAAAEAAAACAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAeAAAADgAAAA4AAAcGAAADhgAAA4YAAAMGABAGDAAwBkYAYAYGAMAMDAOADAYHAAwGDgAYBjgAMgbwADAHyABgD4AAwA4AAYAEAAMAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAO4AAA8MAAAAGAAAADAAAAAgAAAAQAAAAIAAAAGAAAABAAAAAgAAAAQAAAAIYMAAE4BgAB4AIAA4ACAAMAAgAAAAYAAAAEAAATCAAAEZAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAACgAAAAeAAAADgAAAAwAAAAMAAAADAAAAAwAAYAMAAMADAAGAAwAGAAsADgADABgAAwBwAAMBwAADA4AAAw8AAAM8AAAD8AAAA+AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAGAAAYDgAAfBIAANgiAAMQwgAAMYIAAHMCAAB2AgAAnAIAAJgCAAEwAgAAcAIAAvACAAewAggHMAIwBDADwAAwAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAYABk3/AAP/a4ADQAYAAwAGAAMABgABAAwAAwAMAAMADAABAAwAAQEMAAEASAADEt4AA/++QAGgAAADAAQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAF8wAAAwYAAAAMAAAACAAAABAAAAAwAAAAYAAAAEAAAACAAAABAAAAAg/gAARgGAAPgAgAHgAMADgADAAQAAwAAAAYAAAAOAAAAGAAAAGAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAFAAAAA4AABAHAAAdBgAABwYAAAYGAAAGBgAABgYABAYGrAYu//4H/aomA4YGAAAGBgAABgYAAAYGAAAGBgAABgwAAAYMAAACGAAAABgAAAAwAAAAYAAAAOAAAAGAAAADgAAABgAAAAgAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAGAAAABgAAAAIAAAADAAAAAQgAAAG8AAAB4AAAB8AAAPhgAAAAIAAAABAAAAAYAAAADAAAABwAAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAEAAAAAwAAAAH/AAAAHwAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAHgAAAAcAAAAjgAAAAYABAAAAAwEAAAYB4AAMAHgAGAA4ADAAWABgAAgAyAAAAYAAAAcAAAAOAAAAOAAAIHAAAUHgAABnwAAAPwAAAB4AAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAQAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAIAQAADA4AAAf4AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAEAAGC/gAE/9cAAOgOAAAgHAAAABwAAAA4AAAAcAAAAGAAAAHgAAAB2AAAA44AAAYHAAAcA4AAOAHAALAA4AHAAOAGgABgDAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAADAAAAAQAAAAEAAAABAAAAAQAAAAE/gAAf/4AH4QAAHAEAAAABAAAAAQAAAGkAAABFAAAARQAAAEcAAABDAAAAYwAAAB8AAAAGAAAABgAAAAQAAAAMAAAAGAAAABAAAABgAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAA4AAAAHgAAAA4AAAAMAAAADABAAAwG4CAN/vAw36DgH+wDgA6MBwACDA4AAAwZAAAMUAAADMAAAAyAAAAMAAAADAAAAAwAAAAMAAAADAGAAA//gAAL94AAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAgCAAAMAgAADAIAAAwCAAAMAgAADAf8AAx+AAAPhgAAPAQAA8wEAAMMBAAADAwAAAwcAAAEGAAABAAAAAQAAAACAAAAA8OAAAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAQAAAALAAIAA4ADAAeAAcAHAADIBwAAYA4AAHAOAAAwDAAAIBwAAAAYAAAAMgAAAHAAAADAAAABwAAAAYAAAAMAAAAOAAAAHAAAADgAAADgAAADgAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAYAAAAzAAAHxgAAAwwAAAAYAAAAEAAAACAAAABAAAAAgAAAAQDwAAIDwAAEGQAACOIAABeEAAAMCAAAAAAAAAAQAAAAEAAAABAAAAAYAAAADAAAAAYAAAADwAAAAMAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAOAAAABwAAAAcAAAAGBYAAB/fAAA1DgAAMA4AAGAcAABgHAAA4DAABdwwAAMPcAAGA+AADADkABgB8AAQAzAAAAMAAAAGAAAADAAAADgAAABwAAAA4AAAAYAAAAcAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAYAAAAEAAAADHgAAA/gAAH8AAAAmAAAABAAAAAQAAAAMAAAACAfgABg4AAAQAAAAEAAAADAAAAAgAAAAYAAAAEAAAADAAAAAwDjgAIAP8ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAOAAAAH4AAAPwAAAvgAADe4AAL4OAABADAAABAwAQAAMV4ECv//B7/0IwPQmAAAgDAAAAQwAAAAMAAAADAAAABgAAAAYAAAAMAAAAGAAAACgAAAAwAAAAwAAAAsAAAAMAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAABAAAAAIAAAAGAAAABgAAAAQAAAAEAAAABHAAAB/AAAH4AAAACAAAAAgAAAAQAAAAEAAAABAAAAAQAAAAIPcAACMBgAAsAIAAcACAAGAAgAAAAIAAAAGAAAADAAAABgAAABgAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAyBgAgHAOAGA4DwAwOA8AGBgcABwYHAAcADgADAA4AAQAcAAAAGAAAALgAAABwAAAAYAAAAMAAAAOAAAADAAAADgAAABwAAABwAAABwAAADRAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/HAAB4AYADwACAPwAAwBgAAMAAAADAAAAAgAAAAYAAAAEAAAADAAAADAAAADgAAADAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAACAACAn4AC3/vAAHoAAACQAAAAAAIAAAIAAAgAFfQG3+/8B/YwBAGAOAAAADgAAABgAAAAcAAAAGAAAADAAAABQAAAAYAAAAOAAAADAAAABgAAAAwAAAAwAAAAYAAAAKAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAPAAAAbgAAA5gAABwgAADwYAAHgEAAAgCAAAABAAAAAQAAAAAAAAACAAAAAgAAAAIAAAACAAAAAQAAAAEAAAAAgAAAAOAAAABwAAAAHAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAA4AAAAHgAAAA4AAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAD6AAAAzwAAAMPAAADA4AAAwHAAAMAwAADAEAAAwAAAAMAAAADAAAAAwAAAAMAAAAGAAAABwAAAAMAAAAAAAAAAAAAAAIAAAAAAAA=') +}; +hiragana.TO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAAAgAAAAMAYAABAHAAAQHAAAGDAAAAhgAAAIwAAABwAAAAYAAAAMAAAAEAAAACAAAABAAAAAQAAAAAAAAACAAAAAAAAAAGAAAAAf/wAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAACAAANACsAB7//gAPtI4AJgAOAAYADAAMABwABgAYACYAGAAOABgABgA4AAwAcAAGAHAABADgAAAAwAAAAcAAAAOAAAAHAAAADgAAADgAAADgAAAFwAAACgAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADAAAAAwAAAAMAAAADAAAAA8AAAAfAAAAfgAAAIwAAAAIDnAAGCAYACiACAArAAwATAAMAJgADAD4AAgByAAYARgAEAAYACAAGACAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAQAAAAPAAAAA4AAAAMAAAADAAAAAwAAAAsEABhLvgAP//cAB5MAAAGDAAADAwAAAQMAAAMDAAADAwcBg19/wf/7UsD1AwAAIAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAbAAAB4wAAAMIAAAACAAAABgAAAAQAAAAEAAAADAAAAA3+AAAeAwAAeAGAAZAAgAMQAMAEMADACCAAwBBgAMAwQACAIMDxgBCBGwARAQYADgCcAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAFBK4AB//+AAPUHgABADgAAARwAAAOwAAABwAAAAMAAAADAAAAAwAAAAMAAAALAAAgAyVgPv//+B/qIrgIAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAA8AAAB3AAAHhgAAAAwAAAAYAAAAMAAAAGAAAADAAAABhwAAAzDAAAaAYAAOAGAADADAAACRgAAANgAAAGAAAADAAAABgAAAAgAAAAwAcAAYAxwAfggGAOGwAwDA4AAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAABAAAgAAwAO37/AB//bwAMgAwAAABYAAgAHAAAABgAGFb4AA//uAAHQDAAAAQwAAAAYAAAAOAAAADAAAABgAAAAwAAAAsAAAAGAAAADAAAABgAAABoAAAAwAAAA4AAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAACOAAAB/AAAPwAAAAMAAAACAAAABAAAAAwAgAAIAcAAHMMAADBOAAAAeAAAAGAAAADgAAADIAAABCAAAAgAAAAIAAAACAAAAAgAAAAGBwAAAP8AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAEAAAAD4AAAAOAAAADAAAAAwAIAAGADAABgX4AAa/fAAX6OAZfwHAD9MDgAcDBgAEAwwAAAmYAAABogAAAYAAAAGAAAABgAAAAcAAAADAAAAAwAAAAOAAAADgAAAA4AAAAGAAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAgAAAAGAAAAAgAAAAMAAAQAAAAEAAAABAHGAAQOAwAGcAEAA4ADAA4AAwA7AAYA4QA4AAEAAAAAgAAAAIAAAADAAAAAQAAAAGAAAAAgAAAAMAAAADAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAC4AAd//AAH2hoAAQAyAAAAMAAAALAAAAAwAAAAMAAAADAAABAwQEABe+Bt//9wP+kAIBwAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAgAAAAIAACADAAAwD3AAIDIIACBCDAAgggQAIwIGACICBgBkAgYASAIEAEACBABQBgwAcB4YAGAGcABgB8AAYAQAACAIAAAACAAAABAAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAIAlgAD//8AAfUGAACABgAAAAYAAAAMAABABgABBLwAAf/8AAF0DAAAgAwAAAAMAAAADAAAQAwAAgAMAANN3AAD/3wAANAIAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAEAAAABgAAAAMAAAACAAAAAgAAAAIAAAACDAAAA3wAAAOAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAPCAAAEPgAABA8AAAQHwAAADPAAA/g8AAAADgAAAAYAAAAAAAAAAAAAAAAA=') +}; +katakana.N = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAEAAAABgAAAAOAAAABwAAIAMgAGADgADAAwABgAAAAwAAAAwAAABYAAABOAAAAHAAAAHAAAADgAAADkAAABwAACB4AAAx4AAAP4QAAB8AAAAOAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.N = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAACAAAABgAAAAQAAAAMAAAACAAAABAAAAAQAAAAIAAAAGAAAABAAAAAkAAAALgAAAFIAIADiAAAAwwBAAYMAQAEBAIADAQGAAgGDAAYAzgAEAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +/// ///////////////////////////////////////// + +let kana = katakana.KI; +let scroll = 0; + +function drawWheel () { + if (scroll > 20 || scroll < -20) { + scroll = 0; + next(); + } +} +let hiramode = false; +let curkana = 'KA'; +function next () { + let found = false; + for (const k of Object.keys(katakana).sort()) { + if (found) { + kana = hiramode ? hiragana[k] : katakana[k]; + curkana = k; + return; + } + if (curkana === k) { + found = true; + } + } + curkana = 'KA'; + kana = hiramode ? hiragana[curkana] : katakana[curkana]; +} + +function prev () { + let oldk = ''; + let count = 0; + for (const k of Object.keys(katakana).sort()) { + if (curkana === k) { + if (count > 0) { + curkana = oldk; + kana = katakana[curkana]; + return; + } else { + } + } + oldk = k; + count++; + } + curkana = oldk; + kana = katakana[curkana]; +} + +const kanacolors = { + A: [] +}; + +const clocktop = false; + +function updateWatch (hhmm) { + if (!hhmm) { + hhmm = ohhmm; + } + g.setBgColor(0, 0, 0); + g.setColor(0, 0, 0); + if (false) { + g.fillRect(0, 0, g.getWidth(), g.getHeight()); + g.setColor(0.3, 0.3, 0.3); + g.setColor(1, 0, 0); + + g.fillRect(stripe_pos, 0, stripe_pos + stripe_width, h); + + g.fillRect(stripe2_pos, 0, stripe2_pos + stripe_width, h); + + for (i = 0; i < h; i += 8) { + g.setColor(0.15, 0.15, 0.15); + g.fillRect(0, i, g.getWidth(), i + 3); + g.setColor(0.4, 0.4, 0.4); + g.fillRect(stripe_pos, i, stripe_pos + stripe_width, i + 3); + g.fillRect(stripe2_pos, i, stripe2_pos + stripe_width, i + 3); + } + } else { + var whitecolor = false; + if (curkana.indexOf('A') != -1) { + g.setColor(1, 0, 0); + whitecolor = true; + } else if (curkana.indexOf('I') != -1) { + g.setColor(0, 1, 0); + } else if (curkana.indexOf('U') != -1) { + g.setColor(0, 0, 1); + whitecolor = true; + } else if (curkana.indexOf('E') != -1) { + g.setColor(1, 1, 0); + } else { + g.setColor(0, 1, 1); + } + g.fillRect(0, 0, w, h); + } + + // GOOD FONT SIZE g.setFont("Vector", 62); + g.setFont('Vector', 50); + const bignumbers = false; + if (bignumbers) { + g.setColor(1, 1, 1); + g.drawString(hhmm, 12, 12); + g.setColor(0, 0, 0); + g.drawString(hhmm, 10, 10); + } else { + if (whitecolor) { + g.setColor(0, 0, 0); + } else { + g.setColor(0.5, 0.5, 0.5); + } + if (clocktop) { + x = 26; y = 26; + } else { + x = 26; y = h - 42; + } + g.drawString(hhmm, x - 3, y - 3); + if (whitecolor) { + g.setColor(1, 1, 1); + } else { + g.setColor(0, 0, 0); + } + g.drawString(hhmm, x, y - 1); + } + // drawKana(hira_a, 0, 60); + drawKana(hiragana.KA, g.getWidth() / 6, 60); + Bangle.drawWidgets(); +} +function drawKana (img, x, y) { + g.setColor(0, 0, 0); + + // g.fillRect(0,0,g.getWidth(), h); + if (clocktop) { + g.fillRect(0, h / 2.5, g.getWidth(), h); + } else { + g.fillRect(0, 0, g.getWidth(), 6 * (h / 8) + 1); + } + + if (false) { + g.drawImage(hira_a, x, y); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, x + 32, y + 4); + } else { + if (clocktop) { + g.setColor(1, 1, 1); + g.drawImage(kana, x + 8, y + 12, { scale: 3.4 }); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, 0, y + 16); + g.drawString(hiramode ? 'H' : 'K', w - 20, y + 16); + } else { + g.setColor(1, 1, 1); + g.drawImage(kana, x + 8, 26, { scale: 3.4 }); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, 4, 32); + g.drawString(hiramode ? 'H' : 'K', w - 20, 32); + } + } +} + +var ohhmm = ''; + +function tickWatch () { + const now = Date(); + function zpad (n) { + return (n < 10) ? '0' + n : n; + } + const hhmm = zpad(now.getHours()) + ':' + zpad(now.getMinutes()); + if (hhmm !== ohhmm) { + updateWatch(hhmm); + } +} + +Bangle.on('touch', function (tap, top) { + if (top.y < h / 3) { + // clocktop = !clocktop; + return; + } + if (top.x < w / 4) { + prev(); + } else if (top.x > (w - (w / 4))) { + next(); + } else { + hiramode = !hiramode; + } + kana = hiramode ? hiragana[curkana] : katakana[curkana]; + tickWatch(); +}); + +Bangle.loadWidgets(); +tickWatch(); +setInterval(tickWatch, 1000); + diff --git a/apps/kanawatch/app.png b/apps/kanawatch/app.png new file mode 100644 index 0000000000000000000000000000000000000000..cf081937b94dda9444fca31c03baa89a8df61c70 GIT binary patch literal 15313 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 Dnfa#} literal 0 HcmV?d00001 From 433f8adc187849ccb9221d129ecb6ac3d4a6f9cb Mon Sep 17 00:00:00 2001 From: julowe Date: Wed, 15 Jun 2022 10:27:51 -0700 Subject: [PATCH 108/121] qrcode: add MeCard (contact info) creation add html elements and script for First & Last Names, Phone Number, Email, and Website elements of meCard format. Bump to v0.06 --- apps/qrcode/ChangeLog | 1 + apps/qrcode/custom.html | 60 +++++++++++++++++++++++++++++++++++++-- apps/qrcode/metadata.json | 2 +- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/apps/qrcode/ChangeLog b/apps/qrcode/ChangeLog index 6d9cc0569..52eadbcf9 100644 --- a/apps/qrcode/ChangeLog +++ b/apps/qrcode/ChangeLog @@ -3,3 +3,4 @@ 0.03: Forces integer scaling and adds more configuration (error correction, description, display) 0.04: Allow scanning of QR codes from camera or file 0.05: Change brightness on touch +0.06: Add ability to generate contact info (MeCard format) QR code diff --git a/apps/qrcode/custom.html b/apps/qrcode/custom.html index 7ae3eb3af..9955ea6c9 100644 --- a/apps/qrcode/custom.html +++ b/apps/qrcode/custom.html @@ -8,6 +8,8 @@

+ +

@@ -64,6 +66,14 @@ +
+

First Name:

+

Last Name:

+

Phone Number:

+

Email:

+

Website:

+
+

Try your QR Code:

@@ -156,7 +166,7 @@ function toggleVis(id){ console.info("Got id", id); - ["srcScanFile", "srcText", "srcWifi", "srcScanCam"].forEach(function (item){ + ["srcScanFile", "srcText", "srcWifi", "srcScanCam", "srcMeCard"].forEach(function (item){ document.getElementById(item).style.display = "none"; }); if (id != undefined && id != null) document.getElementById(id).style.display = "block"; @@ -188,6 +198,37 @@ } return qrstring; } + + function generateMeCardString(meNameFirst, meNameLast, mePhoneNumber, meEmail, meWebsite){ + var meCardStringOutput = 'MECARD:'; + + //first & Last name part of string, can have one or both + if (meNameFirst.trim().length != 0 && meNameLast.trim().length != 0) { + meCardStringOutput += 'N:'+meNameLast.trim()+','+meNameFirst.trim()+';'; + } + else if (meNameLast.trim().length != 0) { + meCardStringOutput += 'N:'+meNameLast.trim()+';'; + } + else if (meNameFirst.trim().length != 0) { + meCardStringOutput += 'N:'+meNameFirst.trim()+';'; + } + + if (mePhoneNumber.trim().length != 0) { + meCardStringOutput += 'TEL:'+mePhoneNumber.trim()+';'; + } + + if (meEmail.trim().length != 0) { + meCardStringOutput += 'EMAIL:'+meEmail.trim()+';'; + } + + if (meWebsite.trim().length != 0) { + meCardStringOutput += 'URL:'+meWebsite.trim()+';'; + } + + meCardStringOutput += ';'; + return meCardStringOutput; + } + function refreshQRCode(){ if (qrcode == null){ qrcode = new QRCode("qrcode", { @@ -206,6 +247,14 @@ const hidden = document.getElementById("hidden").checked; const wifiString = generateWifiString(ssid, password, hidden, encryption); qrText= wifiString; + } else if (document.getElementById("useMECARD").checked) { + const meNameFirst = document.getElementById("meNameFirst").value; + const meNameLast = document.getElementById("meNameLast").value; + const mePhoneNumber = document.getElementById("mePhoneNumber").value; + const meEmail = document.getElementById("meEmail").value; + const meWebsite = document.getElementById("meWebsite").value; + const meCardString = generateMeCardString(meNameFirst, meNameLast, mePhoneNumber, meEmail, meWebsite); + qrText = meCardString; } else if (document.getElementById("useCAM").checked) { qrText= document.getElementById("camQrResult").innerText; } else if (document.getElementById("useFILE").checked) { @@ -258,6 +307,14 @@ } document.getElementById("useTEXT").addEventListener("change",function(){toggleVis("srcText");}); + + document.getElementById("useMECARD").addEventListener("change",function(){toggleVis("srcMeCard");}); + document.getElementById("meNameFirst").addEventListener("change",refreshQRCode); + document.getElementById("meNameLast").addEventListener("change",refreshQRCode); + document.getElementById("mePhoneNumber").addEventListener("change",refreshQRCode); + document.getElementById("meEmail").addEventListener("change",refreshQRCode); + document.getElementById("meWebsite").addEventListener("change",refreshQRCode); + document.getElementById("useCAM").addEventListener("change",function(){ initQrScanner(); initQrCam(); @@ -314,7 +371,6 @@ g.setColor(1,1,1); }); - document.getElementById('camList').addEventListener('change', event => { scanner.setCamera(event.target.value).then(updateFlashAvailability); }); diff --git a/apps/qrcode/metadata.json b/apps/qrcode/metadata.json index 22f8f7b53..24af7b813 100644 --- a/apps/qrcode/metadata.json +++ b/apps/qrcode/metadata.json @@ -1,7 +1,7 @@ { "id": "qrcode", "name": "Custom QR Code", - "version": "0.05", + "version": "0.06", "description": "Use this to upload a customised QR code to Bangle.js", "icon": "app.png", "tags": "qrcode", From 0eeb8e79768f2101ec4f662e4b3c065734b4e48b Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:30:42 +0200 Subject: [PATCH 109/121] 'Swipe to exit' now uses load() ...instead of showClock() which is now removed completely. --- apps/dtlaunch/app-b2.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/dtlaunch/app-b2.js b/apps/dtlaunch/app-b2.js index 46194ec5d..8cd5790bb 100644 --- a/apps/dtlaunch/app-b2.js +++ b/apps/dtlaunch/app-b2.js @@ -89,7 +89,7 @@ function drawPage(p){ Bangle.on("swipe",(dirLeftRight, dirUpDown)=>{ selected = 0; oldselected=-1; - if(settings.swipeExit && dirLeftRight==1) showClock(); + if(settings.swipeExit && dirLeftRight==1) load(); if (dirUpDown==-1||dirLeftRight==-1){ ++page; if (page>maxPage) page=0; drawPage(page); @@ -99,12 +99,6 @@ Bangle.on("swipe",(dirLeftRight, dirUpDown)=>{ } }); -function showClock(){ - var app = require("Storage").readJSON('setting.json', 1).clock; - if (app) load(app); - else E.showMessage("clock\nnot found"); -} - function isTouched(p,n){ if (n<0 || n>3) return false; var x1 = (n%2)*72+XOFF; var y1 = n>1?72+YOFF:YOFF; From 9e4b3925e61e7fea178b590dc771a9e099e60bbb Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:46:35 +0200 Subject: [PATCH 110/121] 'Swipe to exit' now uses load() ..instead of showClock() which has been completely removed. --- apps/dtlaunch/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/dtlaunch/ChangeLog b/apps/dtlaunch/ChangeLog index 09804b82e..c06e6fa34 100644 --- a/apps/dtlaunch/ChangeLog +++ b/apps/dtlaunch/ChangeLog @@ -12,3 +12,4 @@ 0.12: On Bangle 2 change to swiping up/down to move between pages as to match page indicator. Swiping from left to right now loads the clock. 0.13: Added swipeExit setting so that left-right to exit is an option 0.14: Don't move pages when doing exit swipe. +0.15: 'Swipe to exit'-code is slightly altered to be more reliable. From 45394ef7eefc4d3fb0a52a7e56dc9451e444154a Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:47:18 +0200 Subject: [PATCH 111/121] 'Swipe to exit' now uses load() ...instead of showClock() which has been completely removed. --- apps/dtlaunch/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dtlaunch/metadata.json b/apps/dtlaunch/metadata.json index 4a0b8067c..9711a6964 100644 --- a/apps/dtlaunch/metadata.json +++ b/apps/dtlaunch/metadata.json @@ -1,7 +1,7 @@ { "id": "dtlaunch", "name": "Desktop Launcher", - "version": "0.14", + "version": "0.15", "description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.", "screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}], "icon": "icon.png", From 978b2c804d2dead2793699c9decf3cd1a4cb8f34 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:56:47 +0200 Subject: [PATCH 112/121] Clarify Bangle 2 on 0.14 and 0.15 --- apps/dtlaunch/ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dtlaunch/ChangeLog b/apps/dtlaunch/ChangeLog index c06e6fa34..a360e4875 100644 --- a/apps/dtlaunch/ChangeLog +++ b/apps/dtlaunch/ChangeLog @@ -11,5 +11,5 @@ 0.11: Fix bangle.js 1 white icons not displaying 0.12: On Bangle 2 change to swiping up/down to move between pages as to match page indicator. Swiping from left to right now loads the clock. 0.13: Added swipeExit setting so that left-right to exit is an option -0.14: Don't move pages when doing exit swipe. -0.15: 'Swipe to exit'-code is slightly altered to be more reliable. +0.14: Don't move pages when doing exit swipe - Bangle 2. +0.15: 'Swipe to exit'-code is slightly altered to be more reliable - Bangle 2. From 5e245af74536d67d8025b0a7ffa45797119d2d67 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Wed, 15 Jun 2022 22:58:06 +0200 Subject: [PATCH 113/121] spelling --- apps/dtlaunch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dtlaunch/README.md b/apps/dtlaunch/README.md index 55c9f53b8..1835bc842 100644 --- a/apps/dtlaunch/README.md +++ b/apps/dtlaunch/README.md @@ -27,7 +27,7 @@ Bangle 2: ## Controls- Bangle 2 -**Touch** - icon to select, scond touch launches app +**Touch** - icon to select, second touch launches app **Swipe Left/Up** - move to next page of app icons From ce62d98a26a6e6e241596de52723f431e2afc835 Mon Sep 17 00:00:00 2001 From: BartS23 <10829389+BartS23@users.noreply.github.com> Date: Thu, 16 Jun 2022 08:48:40 +0200 Subject: [PATCH 114/121] Fix wrong function call --- apps/health/interface.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/health/interface.html b/apps/health/interface.html index 0791acd24..a708e2645 100644 --- a/apps/health/interface.html +++ b/apps/health/interface.html @@ -113,7 +113,7 @@ function getMonthList() { Util.showModal("Deleting..."); Util.eraseStorage(filename,()=>{ Util.hideModal(); - getTrackList(); + getMonthList(); }); } if (task=="downloadcsv") { From 267f043dfe88442efd5c2682925ba2b081e52b8f Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Thu, 16 Jun 2022 10:28:25 +0200 Subject: [PATCH 115/121] documents all four possible widget areas --- README.md | 2 +- typescript/types/globals.d.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e8d5579c0..ea485da86 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ widget bar at the top of the screen they can add themselves to the global ``` WIDGETS["mywidget"]={ - area:"tl", // tl (top left), tr (top right) + area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) sortorder:0, // (Optional) determines order of widgets in the same corner width: 24, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout draw:draw // called to draw the widget diff --git a/typescript/types/globals.d.ts b/typescript/types/globals.d.ts index e82c3da3d..e2da49a0e 100644 --- a/typescript/types/globals.d.ts +++ b/typescript/types/globals.d.ts @@ -33,7 +33,7 @@ done "heatshrink": "readonly", "Math": "readonly", "Modules": "readonly", "NRF": "readonly", - "Number": "readonly", + "Number": "readonly", "Object": "readonly", "OneWire": "readonly", "Pin": "readonly", @@ -176,8 +176,9 @@ declare type GraphicsApi = { declare const Graphics: GraphicsApi; declare const g: GraphicsApi; +type WidgetArea = 'tl' | 'tr' | 'bl' | 'br'; declare type Widget = { - area: 'tr' | 'tl'; + area: WidgetArea; width: number; draw: (this: { x: number; y: number }) => void; }; From a6a5996ce0401e4f6b7621de9a6237d01d47ef71 Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Thu, 16 Jun 2022 14:39:31 +0200 Subject: [PATCH 116/121] warn about bottom area widgets --- apps/_example_widget/widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/_example_widget/widget.js b/apps/_example_widget/widget.js index f7aed6991..226aea589 100644 --- a/apps/_example_widget/widget.js +++ b/apps/_example_widget/widget.js @@ -9,7 +9,7 @@ currently-running apps */ // add your widget WIDGETS["mywidget"]={ - area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right) + area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right), be aware that not all apps support widgets at the bottom of the screen width: 28, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout draw:draw // called to draw the widget }; From cb380b6771034f9e6c145d8213e75841264b826f Mon Sep 17 00:00:00 2001 From: Hank Date: Thu, 16 Jun 2022 17:43:30 +0200 Subject: [PATCH 117/121] Add Settings --- apps/hworldclock/ChangeLog | 3 +- apps/hworldclock/app.js | 126 ++++++++++++++++++++++++--------- apps/hworldclock/metadata.json | 8 ++- apps/hworldclock/settings.js | 59 +++++++++++++++ 4 files changed, 161 insertions(+), 35 deletions(-) create mode 100644 apps/hworldclock/settings.js diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index c7b1731a2..72b25a7c6 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -3,4 +3,5 @@ 0.17: Fix hours 0.18: Code cleanup and major changes with seconds timing. New feature: if watch is locked, seconds get refreshed every 10 seconds. 0.19: Fix PM Hours -0.20: Add theme support \ No newline at end of file +0.20: Add theme support +0.21: Add Settings \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index faf24e974..d4c677d26 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -1,3 +1,10 @@ +// ------- Settings file +const SETTINGSFILE = "hworldclock.json"; +var secondsMode; +var showSunInfo; +var colorWhenDark; +// ------- Settings file + const big = g.getWidth()>200; // Font for primary time and date const primaryTimeFontSize = big?6:5; @@ -66,6 +73,11 @@ const mockOffsets = { ], };*/ + +// Example hworldclock.settings.json +// [["London","0"],["NY","-5"],["Denver","-6"]] + + // Uncomment one at a time to test various offsets array scenarios //offsets = mockOffsets.zeroOffsets; // should render nothing below primary time //offsets = mockOffsets.oneOffset; // should render larger in two rows @@ -73,6 +85,19 @@ const mockOffsets = { //offsets = mockOffsets.fourOffsets; // should render in columns // END TESTING CODE + + +// Load settings +function loadMySettings() { + // Helper function default setting + function def (value, def) {return value !== undefined ? value : def;} + + var settings = require('Storage').readJSON(SETTINGSFILE, true) || {}; + secondsMode = def(settings.secondsMode, "when unlocked"); + showSunInfo = def(settings.showSunInfo, true); + colorWhenDark = def(settings.colorWhenDark, "green"); +} + // Check settings for what type our clock should be var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; @@ -139,13 +164,17 @@ function drawSeconds() { g.setFont("5x9Numeric7Seg",primaryTimeFontSize - 3); if (g.theme.dark) { - g.setColor("#22ff05"); + if (colorWhenDark == "green") { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } } else { g.setColor(g.theme.fg); } //console.log("---"); //console.log(seconds); - if (Bangle.isLocked()) seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x + if (Bangle.isLocked() && secondsMode != "always") seconds = seconds.slice(0, -1) + ':::'; // we use :: as the font does not have an x //console.log(seconds); g.drawString(`${seconds}`, xyCenterSeconds, yposTime+14, true); queueDrawSeconds(); @@ -184,7 +213,11 @@ function draw() { //g.setFont(font, primaryTimeFontSize); g.setFont("5x9Numeric7Seg",primaryTimeFontSize); if (g.theme.dark) { - g.setColor("#22ff05"); + if (colorWhenDark == "green") { + g.setColor("#22ff05"); + } else { + g.setColor(g.theme.fg); + } } else { g.setColor(g.theme.fg); } @@ -198,7 +231,7 @@ function draw() { g.drawString(ampm, xyCenterSeconds, yAmPm, true); } - drawSeconds(); // To make sure... + if (secondsMode != "none") drawSeconds(); // To make sure... // draw Day, name of month, Date //DATE @@ -245,19 +278,31 @@ function draw() { } }); - g.setFontAlign(-1, 0); - g.setFont("Vector",12); - g.drawString(`^${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw riseset - g.setFontAlign(1, 0); - g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset + if (showSunInfo) { + g.setFontAlign(-1, 0); + g.setFont("Vector",12); + g.drawString(`^${rise}`, 10, 3 + yposWorld + 3 * 15, true); // draw riseset + g.setFontAlign(1, 0); + g.drawString(`v${set}`, xcol2, 3 + yposWorld + 3 * 15, true); // draw riseset + } + //debug settings + //g.setFontAlign(1, 0); + //g.drawString(secondsMode, xcol2, 3 + yposWorld + 3 * 15, true); + //g.drawString(showSunInfo, xcol2, 3 + yposWorld + 3 * 15, true); + //g.drawString(colorWhenDark, xcol2, 3 + yposWorld + 3 * 15, true); + queueDraw(); - queueDrawSeconds(); + + if (secondsMode != "none") queueDrawSeconds(); } // clean app screen g.clear(); +// Init the settings of the app +loadMySettings(); + // Show launcher when button pressed Bangle.setUI("clock"); Bangle.loadWidgets(); @@ -269,28 +314,38 @@ draw(); if (!Bangle.isLocked()) { // Initial state - if (PosInterval != 0) clearInterval(PosInterval); - PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + if (showSunInfo) { + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + } - secondsTimeout = 1000; + secondsTimeout = 1000; + if (secondsMode != "none") { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = undefined; + } if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; - drawTimeoutSeconds = undefined; draw(); // draw immediately, queue redraw - updatePos(); + if (showSunInfo) updatePos(); }else{ - secondsTimeout = 10 * 1000; + if (secondsMode == "always") secondsTimeout = 1000; + if (secondsMode == "when unlocked") secondsTimeout = 10 * 1000; + + if (secondsMode != "none") { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = undefined; + } if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; - drawTimeoutSeconds = undefined; - if (PosInterval != 0) clearInterval(PosInterval); - PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + if (showSunInfo) { + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins + } draw(); // draw immediately, queue redraw - updatePos(); + if (showSunInfo) updatePos(); } @@ -299,29 +354,36 @@ if (!Bangle.isLocked()) { // Initial state Bangle.on('lock',on=>{ if (!on) { // UNlocked - - if (PosInterval != 0) clearInterval(PosInterval); - PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + if (showSunInfo) { + if (PosInterval != 0) clearInterval(PosInterval); + PosInterval = setInterval(updatePos, 60*10E3); // refesh every 10 mins + } secondsTimeout = 1000; + if (secondsMode != "none") { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = undefined; + } if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; - drawTimeoutSeconds = undefined; draw(); // draw immediately, queue redraw - updatePos(); + if (showSunInfo) updatePos(); }else{ // locked - secondsTimeout = 10 * 1000; + if (secondsMode == "always") secondsTimeout = 1000; + if (secondsMode == "when unlocked") secondsTimeout = 10 * 1000; + + if (secondsMode != "none") { + if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); + drawTimeoutSeconds = undefined; + } if (drawTimeout) clearTimeout(drawTimeout); - if (drawTimeoutSeconds) clearTimeout(drawTimeoutSeconds); drawTimeout = undefined; - drawTimeoutSeconds = undefined; if (PosInterval != 0) clearInterval(PosInterval); PosInterval = setInterval(updatePos, 60*60E3); // refesh every 60 mins draw(); // draw immediately, queue redraw - updatePos(); + if (showSunInfo) updatePos(); } }); \ No newline at end of file diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index 5cc2a49a8..f41d56932 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -2,7 +2,7 @@ "id": "hworldclock", "name": "Hanks World Clock", "shortName": "Hanks World Clock", - "version": "0.20", + "version": "0.21", "description": "Current time zone plus up to three others", "allow_emulator":true, "icon": "app.png", @@ -15,7 +15,11 @@ "storage": [ {"name":"hworldclock.app.js","url":"app.js"}, {"name":"hworldclock.img","url":"hworldclock-icon.js","evaluate":true}, + {"name":"hworldclock.settings.js","url":"settings.js"}, {"name":"hsuncalc.js","url":"hsuncalc.js"} ], - "data": [{"name":"hworldclock.settings.json"}] + "data": [ + {"name":"hworldclock.settings.json"}, + {"name":"hworldclock.json"}, + ] } diff --git a/apps/hworldclock/settings.js b/apps/hworldclock/settings.js new file mode 100644 index 000000000..60092d21e --- /dev/null +++ b/apps/hworldclock/settings.js @@ -0,0 +1,59 @@ +// Settings menu for the enhanced Anton clock + +(function(back) { + var FILE = "hworldclock.json"; + // Load settings + var settings = Object.assign({ + secondsOnUnlock: false, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + // Helper method which uses int-based menu item for set of string values + function stringItems(startvalue, writer, values) { + return { + value: (startvalue === undefined ? 0 : values.indexOf(startvalue)), + format: v => values[v], + min: 0, + max: values.length - 1, + wrap: true, + step: 1, + onchange: v => { + writer(values[v]); + writeSettings(); + } + }; + } + + // Helper method which breaks string set settings down to local settings object + function stringInSettings(name, values) { + return stringItems(settings[name], v => settings[name] = v, values); + } + + var mainmenu = { + "": { + "title": "Hanks World Clock" + }, + "< Back": () => back(), + "Seconds": stringInSettings("secondsMode", ["always", "when unlocked", "none"]), + "Color w. dark": stringInSettings("colorWhenDark", ["green", "default"]), + "Show SunInfo": { + value: (settings.showSunInfo !== undefined ? settings.showSunInfo : true), + format: v => v ? "On" : "Off", + onchange: v => { + settings.showSunInfo = v; + writeSettings(); + } + } + }; + + + + // Actually display the menu + E.showMenu(mainmenu); + +}); + +// end of file From 5aca600923f3693f8e26b2ac62202e1ccfb3d94b Mon Sep 17 00:00:00 2001 From: Hank Date: Thu, 16 Jun 2022 17:47:23 +0200 Subject: [PATCH 118/121] Fix Metadata --- apps/hworldclock/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/hworldclock/metadata.json b/apps/hworldclock/metadata.json index f41d56932..3d9be3bc7 100644 --- a/apps/hworldclock/metadata.json +++ b/apps/hworldclock/metadata.json @@ -20,6 +20,6 @@ ], "data": [ {"name":"hworldclock.settings.json"}, - {"name":"hworldclock.json"}, + {"name":"hworldclock.json"} ] -} +} \ No newline at end of file From b0b57c36f3417556d2fe43ac09d09f2fd40fd2fd Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 17 Jun 2022 07:54:55 +0100 Subject: [PATCH 119/121] fix writeStorage callback for interface/custom HTML files --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index cdab12fcf..c46b4edd2 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit cdab12fcf85bc140e1f5c3f7b15218108c3f7d32 +Subproject commit c46b4edd2052d0df37fea41f8839af8175a78ec9 From 239dc96a4993d9c3a70cb19d98cebc31da521aaf Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 17 Jun 2022 09:58:40 +0100 Subject: [PATCH 120/121] add sponsor link --- .github/FUNDING.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.xml diff --git a/.github/FUNDING.xml b/.github/FUNDING.xml new file mode 100644 index 000000000..345bce54f --- /dev/null +++ b/.github/FUNDING.xml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: espruino +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['http://www.espruino.com/Donate']# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 3bddcd402d8e3dd3e9474e022bfe86478cebf811 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 17 Jun 2022 11:44:01 +0100 Subject: [PATCH 121/121] oops --- .github/{FUNDING.xml => FUNDING.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{FUNDING.xml => FUNDING.yml} (100%) diff --git a/.github/FUNDING.xml b/.github/FUNDING.yml similarity index 100% rename from .github/FUNDING.xml rename to .github/FUNDING.yml