diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog
index 0811f2166..fcafc386f 100644
--- a/apps/alarm/ChangeLog
+++ b/apps/alarm/ChangeLog
@@ -16,3 +16,5 @@
0.15: Fix hour/minute wrapping code for new menu system
0.16: Adding alarm library
0.17: Moving alarm internals to 'sched' library
+0.18: Cope with >1 identical alarm at once (#1667)
+0.19: Ensure rescheduled alarms that already fired have 'last' reset
diff --git a/apps/alarm/app.js b/apps/alarm/app.js
index 45edd83f5..b9404358e 100644
--- a/apps/alarm/app.js
+++ b/apps/alarm/app.js
@@ -45,12 +45,22 @@ function showMainMenu() {
/*LANG*/'New Timer': ()=>editTimer(-1)
};
alarms.forEach((alarm,idx)=>{
- var txt; // a leading space is currently required (JS error in Espruino 2v12)
- if (alarm.timer)
- txt = /*LANG*/"Timer"+" "+formatTime(alarm.timer);
- else
- txt = /*LANG*/"Alarm"+" "+formatTime(alarm.t);
+ var type,txt; // a leading space is currently required (JS error in Espruino 2v12)
+ if (alarm.timer) {
+ type = /*LANG*/"Timer";
+ txt = " "+formatTime(alarm.timer);
+ } else {
+ type = /*LANG*/"Alarm";
+ txt = " "+formatTime(alarm.t);
+ }
if (alarm.rp) txt += "\0"+atob("FBaBAAABgAAcAAHn//////wAHsABzAAYwAAMAADAAAAAAwAAMAADGAAzgAN4AD//////54AAOAABgAA=");
+ // rename duplicate alarms
+ if (menu[type+txt]) {
+ var n = 2;
+ while (menu[type+" "+n+txt]) n++;
+ txt = type+" "+n+txt;
+ } else txt = type+txt;
+ // add to menu
menu[txt] = {
value : "\0"+atob(alarm.on?"EhKBAH//v/////////////5//x//j//H+eP+Mf/A//h//z//////////3//g":"EhKBAH//v//8AA8AA8AA8AA8AA8AA8AA8AA8AA8AA8AA8AA8AA8AA///3//g"),
onchange : function() {
@@ -84,7 +94,7 @@ function editAlarm(alarmIndex, alarm) {
var a = {
t : 12*3600000, // 12 o clock default
on : true,
- rp : true,
+ rp : false, // repeat not the default
as : false,
dow : 0b1111111,
last : 0,
@@ -128,8 +138,7 @@ function editAlarm(alarmIndex, alarm) {
};
menu[/*LANG*/"Save"] = function() {
a.t = encodeTime(t);
- if (a.t < getCurrentTime())
- a.day = (new Date()).getDate();
+ a.last = (a.t < getCurrentTime()) ? (new Date()).getDate() : 0;
if (newAlarm) alarms.push(a);
else alarms[alarmIndex] = a;
saveAndReload();
@@ -181,6 +190,7 @@ function editTimer(alarmIndex, alarm) {
menu[/*LANG*/"Save"] = function() {
a.timer = encodeTime(t);
a.t = getCurrentTime() + a.timer;
+ a.last = 0;
if (newAlarm) alarms.push(a);
else alarms[alarmIndex] = a;
saveAndReload();
diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json
index fe82e04c9..9636257ca 100644
--- a/apps/alarm/metadata.json
+++ b/apps/alarm/metadata.json
@@ -2,7 +2,7 @@
"id": "alarm",
"name": "Alarm & Timer",
"shortName": "Alarms",
- "version": "0.17",
+ "version": "0.19",
"description": "Set alarms and timers on your Bangle",
"icon": "app.png",
"tags": "tool,alarm,widget",
diff --git a/apps/bee/ChangeLog b/apps/bee/ChangeLog
index df0907283..cfb44c8e9 100644
--- a/apps/bee/ChangeLog
+++ b/apps/bee/ChangeLog
@@ -1,2 +1,3 @@
0.01: New app!
0.02: Fix bug with regenerating index, fix bug in word lookups
+0.03: Improve word search performance
diff --git a/apps/bee/README.md b/apps/bee/README.md
index c6461fb8e..3d0a4c14a 100644
--- a/apps/bee/README.md
+++ b/apps/bee/README.md
@@ -27,10 +27,7 @@ least once and yields an additional 7 points. Each game contains at least one pa
The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list).
The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat
slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory).
-In order to make checking the validity of a guessed word faster an index file ('bee_lindex.json') is installed with
-the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to
-replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest
-way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved,
-i.e. it only happens once) on app startup automatically, a process that takes roughly 30 seconds.
+This file can be replaced with a custom dictionary, an ASCII file containing a newline-separated (single "\n", not DOS-style "\r\n") alphabetically
+sorted (sorting is important for the word lookup algorithm) list of words.

diff --git a/apps/bee/bee.app.js b/apps/bee/bee.app.js
index ef1582baa..878e9763c 100644
--- a/apps/bee/bee.app.js
+++ b/apps/bee/bee.app.js
@@ -1,7 +1,7 @@
const S = require("Storage");
+const words = S.read("bee.words");
var letters = [];
-var letterIdx = [];
var centers = [];
@@ -12,29 +12,17 @@ var score = 0;
var intervalID = -1;
-function prepareLetterIdx () {
+function biSearch(w, ws, start, end, count) {
"compile"
- var li = [0];
- if (S.read("bee_lindex.json")!==undefined) li = S.readJSON("bee_lindex.json"); // check for cached index
- else {
- for (var i=1; i<26; ++i) {
- var prefix = String.fromCharCode(97+i%26);
- console.log(prefix);
- li.push(S.read('bee.words').indexOf("\n"+prefix, li[i-1])+1);
- }
- li.push(S.read('bee.words').length);
- S.writeJSON("bee_lindex.json", li);
- }
- for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]);
-}
-
-function findWord (w) {
- "compile"
- var ci = w.charCodeAt(0)-97;
- var f = letterIdx[ci].indexOf("\n"+w+"\n");
- if (f>=0) return true;
- if (letterIdx[ci].substr(0, w.length)==w) return true;
- return false;
+ if (start>end-w.legnth || count--<=0) return ws.substr(start, end-start).indexOf("\n"+w+"\n");
+ var mid = (end+start)>>1;
+ if (ws[mid-1]==="\n") --mid;
+ else while (mid