From b6d333ae749274b47289cc735333ef114272667d Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 20 Oct 2021 08:49:53 +0100 Subject: [PATCH 1/6] cliock 0.14: Fix BTN1 (fix #853) Add light/dark theme support --- apps.json | 2 +- apps/cliock/ChangeLog | 2 ++ apps/cliock/app.js | 23 +++++++++++------------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/apps.json b/apps.json index d16213364..a4fc86f5b 100644 --- a/apps.json +++ b/apps.json @@ -1371,7 +1371,7 @@ "name": "Commandline-Clock", "shortName":"CLI-Clock", "icon": "app.png", - "version":"0.13", + "version":"0.14", "description": "Simple CLI-Styled Clock", "tags": "clock,cli,command,bash,shell,b2", "type":"clock", diff --git a/apps/cliock/ChangeLog b/apps/cliock/ChangeLog index 66ef62eae..2a93a0d5f 100644 --- a/apps/cliock/ChangeLog +++ b/apps/cliock/ChangeLog @@ -5,3 +5,5 @@ 0.11: added Heart Rate Monitor status and ability to turn on/off 0.12: added support for different locales 0.13: Use setUI, work with smaller screens and themes +0.14: Fix BTN1 (fix #853) + Add light/dark theme support diff --git a/apps/cliock/app.js b/apps/cliock/app.js index 6853aaf6f..0fd6ea580 100644 --- a/apps/cliock/app.js +++ b/apps/cliock/app.js @@ -20,6 +20,8 @@ const HRT_FN_MODE = "fn_hrt"; let infoMode = NONE_MODE; let functionMode = NONE_FN_MODE; +let textCol = g.theme.dark ? "#0f0" : "#080"; + function drawAll(){ updateTime(); updateRest(new Date()); @@ -45,9 +47,7 @@ function writeLineStart(line){ function writeLine(str,line){ var y = marginTop+line*fontheight; g.setFont("6x8",fontsize); - //g.setColor(0,1,0); - g.setColor("#0f0"); - g.setFontAlign(-1,-1); + g.setColor(textCol).setFontAlign(-1,-1); g.clearRect(0,y,((str.length+1)*20),y+fontheight-1); writeLineStart(line); g.drawString(str,25,y); @@ -56,7 +56,7 @@ function writeLine(str,line){ function drawInfo(line) { let val; let str = ""; - let col = "#0f0"; // green + let col = textCol; // green //console.log("drawInfo(), infoMode=" + infoMode + " funcMode=" + functionMode); @@ -64,7 +64,7 @@ function drawInfo(line) { case NONE_FN_MODE: break; case HRT_FN_MODE: - col = "#0ff"; // cyan + col = g.theme.dark ? "#0ff": "#088"; // cyan str = "HRM: " + (hrtOn ? "ON" : "OFF"); drawModeLine(line,str,col); return; @@ -72,7 +72,7 @@ function drawInfo(line) { switch(infoMode) { case NONE_MODE: - col = "#fff"; + col = g.theme.bg; str = ""; break; case HRT_MODE: @@ -104,9 +104,8 @@ function drawModeLine(line, str, col) { g.setColor(col); var y = marginTop+line*fontheight; g.fillRect(0, y, 239, y+fontheight-1); - g.setColor(0); - g.setFontAlign(0, -1); - g.drawString(str, g.getWidth()/2, y); + g.setColor(g.theme.bg).setFontAlign(0, 0); + g.drawString(str, g.getWidth()/2, y+fontheight/2); } function changeInfoMode() { @@ -193,7 +192,7 @@ Bangle.on('lcdPower',function(on) { var click = setInterval(updateTime, 1000); // Show launcher when button pressed Bangle.setUI("clockupdown", btn=>{ - if (btn==0) changeInfoMode(); - if (btn==1) changeFunctionMode(); + if (btn<0) changeInfoMode(); + if (btn>0) changeFunctionMode(); drawAll(); -}); +}); \ No newline at end of file From cf51c17dc587e23a591ac01dae20c27666ce6954 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 20 Oct 2021 08:50:51 +0100 Subject: [PATCH 2/6] Adding Bangle.js 2 firmware update app --- apps.json | 11 ++ apps/fwupdate/ChangeLog | 1 + apps/fwupdate/app.png | Bin 0 -> 1024 bytes apps/fwupdate/custom.html | 284 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 296 insertions(+) create mode 100644 apps/fwupdate/ChangeLog create mode 100644 apps/fwupdate/app.png create mode 100644 apps/fwupdate/custom.html diff --git a/apps.json b/apps.json index a4fc86f5b..a28e57c59 100644 --- a/apps.json +++ b/apps.json @@ -1,4 +1,15 @@ [ + { "id": "fwupdate", + "name": "Firmware Update", + "icon": "app.png", + "version":"0.01", + "description": "Uploads new Espruino firmwares to Bangle.js 2", + "custom": "custom.html", "customConnect":true, + "tags": "tools,system,b2", + "type": "RAM", + "storage": [ ], + "sortorder" : -20 + }, { "id": "boot", "name": "Bootloader", "tags": "tool,system,b2", diff --git a/apps/fwupdate/ChangeLog b/apps/fwupdate/ChangeLog new file mode 100644 index 000000000..ec66c5568 --- /dev/null +++ b/apps/fwupdate/ChangeLog @@ -0,0 +1 @@ +0.01: Initial version diff --git a/apps/fwupdate/app.png b/apps/fwupdate/app.png new file mode 100644 index 0000000000000000000000000000000000000000..1fabf06a231757bb3ce7c0a975acc7584b4a56f9 GIT binary patch literal 1024 zcmV+b1poVqP)uaT$&HuBly3iqutecYL@+#hAWNDI*M@qvcj z{0p#GG4V2PIwi-Bb)w2?MHL93MeBN27Y|^ytcB~M%o%9`h-?fpQR!@mGUY&6hekg8 zsE1~pi{4?W)fO+G^9FPip1;3h-3nB@#`bJZ)-R+Vvqb8da^Iy|Ar(D@#8pODO`9f~DsD2SbV9!{}uJqB$5ffXZ z0(9%v!A9CW1>6`$NMgrMP*^NYg>eJ;Ig@s8lc`!W$k6B`uBSV%3ld7aef!-cC!Pnu zJ3EJa^2adlqxF`(A9yRs&}bPILUt>KNNCJ%sZgKd+VJb*PExWablRE%<(?E|7u z0lylVIu5D*?;wujJLZp`L3F~z(x?EZTrIc7-K^+GzJ@+`yX&d=An2DKa)(o{mQA#U z?uF*_xyLQhL#oSLhU7CZlGwh}*MITbDcT=@xRMf2kQXxL6aF`8nOhGu^4V6J66^wF*Y362uo7SYt9OGurtQVS@X{qR|Yu9Cl zrR*~i4-?|gwhIA3o86>tnMF_KTulB#)XpUSpY)r1FpzRz{1kyIThaaTzACj zq(>2bW9hi)iwI5NwM^>5NZWFULG}T^EKRpP%bg6PDRe8*C}bb;R2}E)<`F5*wlAN% zRLD-)$|t@7lqa2|mCw6|wrok%*IT>#ey9(k`M|w7&+>loP3XxzneR^2qRJWVe<9W2 zGefd-Cd!nN7BG0t=vlz^F>%vFH~$u8&PWT8V$l_t@iF;cibcNyV`5@Lvg$tY^~gw{ u&Mm$1@Z8*rTBF?u{sZCyVq#)q*2Ld{{4L>OJ%qXd0000G`?< literal 0 HcmV?d00001 diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html new file mode 100644 index 000000000..5286ef062 --- /dev/null +++ b/apps/fwupdate/custom.html @@ -0,0 +1,284 @@ + + + + + +
+

Firmware updates using the App Loader are only possible on + Bangle.js 2. For firmware updates on Bangle.js 1 please + see the Bangle.js 1 instructions

+
+ + +

+
+    
+
+    
+  
+

From a94790391a9f13ab83c9658ba48080b9d5967190 Mon Sep 17 00:00:00 2001
From: Gordon Williams 
Date: Wed, 20 Oct 2021 15:11:04 +0100
Subject: [PATCH 3/6] Get rid of "b2" and "bno2" tags and add "supports" array.
 Use the opportunity to refactor apps.json so everything looks pretty

---
 README.md                             |    4 +-
 apps.json                             | 4404 +++++++++++++------------
 apps/_example_app/add_to_apps.json    |    5 +-
 apps/_example_widget/add_to_apps.json |    5 +-
 bin/create_app_supports_field.js      |   83 +
 bin/sanitycheck.js                    |   11 +-
 6 files changed, 2473 insertions(+), 2039 deletions(-)
 create mode 100644 bin/create_app_supports_field.js

diff --git a/README.md b/README.md
index 49f616964..3da301dba 100644
--- a/README.md
+++ b/README.md
@@ -217,8 +217,9 @@ and which gives information about the app for the Launcher.
 { "id": "appid",              // 7 character app id
   "name": "Readable name",    // readable name
   "shortName": "Short name",  // short name for launcher
-  "icon": "icon.png",         // icon in apps/
+  "version": "0v01",          // the version of this app
   "description": "...",       // long description (can contain markdown)
+  "icon": "icon.png",         // icon in apps/
   "type":"...",               // optional(if app) -  
                               //   'app' - an application
                               //   'widget' - a widget
@@ -226,6 +227,7 @@ and which gives information about the app for the Launcher.
                               //   'bootloader' - code that runs at startup only
                               //   'RAM' - code that runs and doesn't upload anything to storage
   "tags": "",                 // comma separated tag list for searching
+  "supports": ["BANGLEJS2"],  // List of device IDs supported, either BANGLEJS or BANGLEJS2
   "dependencies" : { "notify":"type" } // optional, app 'types' we depend on
                               // for instance this will use notify/notifyfs is they exist, or will pull in 'notify'
   "readme": "README.md",      // if supplied, a link to a markdown-style text file
diff --git a/apps.json b/apps.json
index 0c1517035..8e7c4202b 100644
--- a/apps.json
+++ b/apps.json
@@ -1,35 +1,44 @@
 [
-  { "id": "fwupdate",
+  {
+    "id": "fwupdate",
     "name": "Firmware Update",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Uploads new Espruino firmwares to Bangle.js 2",
-    "custom": "custom.html", "customConnect":true,
-    "tags": "tools,system,b2",
+    "icon": "app.png",
     "type": "RAM",
-    "storage": [ ],
-    "sortorder" : -20
+    "tags": "tools,system",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "custom": "custom.html",
+    "customConnect": true,
+    "storage": [
+      
+    ],
+    "sortorder": -20
   },
-  { "id": "boot",
+  {
+    "id": "boot",
     "name": "Bootloader",
-    "tags": "tool,system,b2",
-    "type":"bootloader",
-    "icon": "bootloader.png",
-    "version":"0.31",
+    "version": "0.31",
     "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
+    "icon": "bootloader.png",
+    "type": "bootloader",
+    "tags": "tool,system",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":".boot0","url":"boot0.js"},
       {"name":".bootcde","url":"bootloader.js"},
       {"name":"bootupdate.js","url":"bootupdate.js"}
     ],
-    "sortorder" : -10
+    "sortorder": -10
   },
-  { "id": "health",
+  {
+    "id": "health",
     "name": "Health Tracking",
-    "tags": "tool,system,b2",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Logs health data and provides an app to view it (BETA - requires firmware 2v11)",
+    "icon": "app.png",
+    "tags": "tool,system",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
     "storage": [
       {"name":"health.app.js","url":"app.js"},
@@ -37,200 +46,220 @@
       {"name":"health.boot.js","url":"boot.js"},
       {"name":"health","url":"lib.js"}
     ],
-    "sortorder" : -10
+    "sortorder": -10
   },
-  { "id": "moonphase",
+  {
+    "id": "moonphase",
     "name": "Moonphase",
-    "icon": "app.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Shows current moon phase. Now with GPS function.",
+    "icon": "app.png",
     "tags": "",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"moonphase.app.js","url":"app.js"},
       {"name":"moonphase.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "daysl",
+  {
+    "id": "daysl",
     "name": "Days left",
-    "icon": "app.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Shows you the days left until a certain date. Date can be set with a settings app and is written to a file.",
+    "icon": "app.png",
     "tags": "",
-    "allow_emulator":false,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": false,
     "storage": [
-        {"name":"daysl.app.js","url":"app.js"},
-        {"name":"daysl.img","url":"app-icon.js","evaluate":true},
-        {"name":"daysl.wid.js","url":"widget.js"}
+      {"name":"daysl.app.js","url":"app.js"},
+      {"name":"daysl.img","url":"app-icon.js","evaluate":true},
+      {"name":"daysl.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "launch",
+  {
+    "id": "launch",
     "name": "Launcher (Default)",
-    "shortName":"Launcher",
-    "icon": "app.png",
-    "version":"0.07",
+    "shortName": "Launcher",
+    "version": "0.07",
     "description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
-    "tags": "tool,system,launcher,b2",
-    "type":"launch",
+    "icon": "app.png",
+    "type": "launch",
+    "tags": "tool,system,launcher",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"launch.app.js","url":"app.js"}
     ],
-    "sortorder" : -10
+    "sortorder": -10
   },
-  { "id": "launchb2",
+  {
+    "id": "launchb2",
     "name": "Launcher (Bangle.js 2)",
-    "shortName":"Launcher",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Launcher",
+    "version": "0.03",
     "description": "This is needed by Bangle.js 2.0 to display a menu allowing you to choose your own applications. It will not work on Bangle.js 1.0.",
-    "tags": "tool,system,launcher,b2,bno1",
-    "type":"launch",
+    "icon": "app.png",
+    "type": "launch",
+    "tags": "tool,system,launcher",
+    "supports": ["BANGLEJS2"],
     "storage": [
       {"name":"launchb2.app.js","url":"app.js"}
     ],
-    "sortorder" : -10
+    "sortorder": -10
   },
-  { "id": "about",
+  {
+    "id": "about",
     "name": "About",
-    "icon": "app.png",
-    "version":"0.09",
+    "version": "0.09",
     "description": "Bangle.js About page - showing software version, stats, and a collaborative mural from the Bangle.js KickStarter backers",
-    "tags": "tool,system,b2",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "tags": "tool,system",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"about.app.js","url":"app.js"},
       {"name":"about.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "locale",
+  {
+    "id": "locale",
     "name": "Languages",
-    "icon": "locale.png",
-    "version":"0.09",
+    "version": "0.09",
     "description": "Translations for different countries",
-    "tags": "tool,system,locale,translate,b2",
+    "icon": "locale.png",
     "type": "locale",
-    "custom":"locale.html",
+    "tags": "tool,system,locale,translate",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
+    "custom": "locale.html",
     "storage": [
       {"name":"locale"}
     ],
-    "sortorder" : -10
+    "sortorder": -10
   },
-  { "id": "notify",
+  {
+    "id": "notify",
     "name": "Notifications (default)",
-    "shortName":"Notifications",
-    "icon": "notify.png",
-    "version":"0.11",
+    "shortName": "Notifications",
+    "version": "0.11",
     "description": "Provides the default `notify` module used by applications to display notifications in a bar at the top of the screen. This module is installed by default by client applications such as the Gadgetbridge app.  Installing `Fullscreen Notifications` replaces this module with a version that displays the notifications using the full screen",
-    "tags": "widget",
+    "icon": "notify.png",
     "type": "notify",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"notify","url":"notify.js"}
     ]
   },
-  { "id": "notifyfs",
+  {
+    "id": "notifyfs",
     "name": "Fullscreen Notifications",
-    "shortName":"Notifications",
-    "icon": "notify.png",
-    "version":"0.12",
+    "shortName": "Notifications",
+    "version": "0.12",
     "description": "Provides a replacement for the `Notifications (default)` `notify` module.   This version is used by applications to display notifications fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notify module.",
-    "tags": "widget,b2",
+    "icon": "notify.png",
     "type": "notify",
+    "tags": "widget",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"notify","url":"notify.js"}
     ]
   },
-  { "id": "welcome",
+  {
+    "id": "welcome",
     "name": "Welcome",
-    "icon": "app.png",
-    "version":"0.12",
+    "version": "0.12",
     "description": "Appears at first boot and explains how to use Bangle.js",
+    "icon": "app.png",
     "tags": "start,welcome",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"welcome.boot.js","url":"boot.js"},
       {"name":"welcome.app.js","url":"app.js"},
       {"name":"welcome.settings.js","url":"settings.js"},
       {"name":"welcome.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"welcome.json"}
-    ]
+    "data": [{"name":"welcome.json"}]
   },
-  { "id": "mywelcome",
+  {
+    "id": "mywelcome",
     "name": "Customised Welcome",
     "shortName": "My Welcome",
-    "icon": "app.png",
-    "version":"0.12",
+    "version": "0.12",
     "description": "Appears at first boot and explains how to use Bangle.js. Like 'Welcome', but can be customised with a greeting",
+    "icon": "app.png",
     "tags": "start,welcome",
-    "custom":"custom.html",
+    "supports": ["BANGLEJS"],
+    "custom": "custom.html",
     "storage": [
       {"name":"mywelcome.boot.js","url":"boot.js"},
       {"name":"mywelcome.app.js","url":"app.js"},
       {"name":"mywelcome.settings.js","url":"settings.js"},
       {"name":"mywelcome.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"mywelcome.json"}
-    ]
+    "data": [{"name":"mywelcome.json"}]
   },
-  { "id": "gbridge",
+  {
+    "id": "gbridge",
     "name": "Gadgetbridge",
-    "icon": "app.png",
-    "version":"0.24",
+    "version": "0.24",
     "description": "The default notification handler for Gadgetbridge notifications from Android",
-    "tags": "tool,system,android,widget,b2",
+    "icon": "app.png",
+    "type": "widget",
+    "tags": "tool,system,android,widget",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "dependencies": {"notify":"type"},
     "readme": "README.md",
-    "type":"widget",
-    "dependencies": { "notify":"type" },
     "storage": [
       {"name":"gbridge.settings.js","url":"settings.js"},
       {"name":"gbridge.img","url":"app-icon.js","evaluate":true},
       {"name":"gbridge.wid.js","url":"widget.js"}
     ],
-    "data": [
-      {"name":"gbridge.json"}
-    ]
+    "data": [{"name":"gbridge.json"}]
   },
-  { "id": "mclock",
+  {
+    "id": "mclock",
     "name": "Morphing Clock",
-    "icon": "clock-morphing.png",
-    "version":"0.07",
+    "version": "0.07",
     "description": "7 segment clock that morphs between minutes and hours",
+    "icon": "clock-morphing.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"mclock.app.js","url":"clock-morphing.js"},
       {"name":"mclock.img","url":"clock-morphing-icon.js","evaluate":true}
     ],
-    "sortorder" : -9
+    "sortorder": -9
   },
-  { "id": "setting",
+  {
+    "id": "setting",
     "name": "Settings",
-    "icon": "settings.png",
-    "version":"0.30",
+    "version": "0.30",
     "description": "A menu for setting up Bangle.js",
-    "tags": "tool,system,b2",
+    "icon": "settings.png",
+    "tags": "tool,system",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
     "storage": [
       {"name":"setting.app.js","url":"settings.js"},
       {"name":"setting.img","url":"settings-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"setting.json", "url":"settings.min.json","evaluate":true}
-    ],
-    "sortorder" : -2
+    "data": [{"name":"setting.json","url":"settings.min.json","evaluate":true}],
+    "sortorder": -2
   },
-  { "id": "alarm",
+  {
+    "id": "alarm",
     "name": "Default Alarm & Timer",
-    "shortName":"Alarms",
-    "icon": "app.png",
-    "version":"0.13",
+    "shortName": "Alarms",
+    "version": "0.13",
     "description": "Set and respond to alarms and timers",
-    "tags": "tool,alarm,widget,b2",
+    "icon": "app.png",
+    "tags": "tool,alarm,widget",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"alarm.app.js","url":"app.js"},
       {"name":"alarm.boot.js","url":"boot.js"},
@@ -238,33 +267,35 @@
       {"name":"alarm.img","url":"app-icon.js","evaluate":true},
       {"name":"alarm.wid.js","url":"widget.js"}
     ],
-    "data": [
-      {"name":"alarm.json"}
-    ]
+    "data": [{"name":"alarm.json"}]
   },
-  { "id": "wclock",
+  {
+    "id": "wclock",
     "name": "Word Clock",
-    "icon": "clock-word.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Display Time as Text",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-word.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"wclock.app.js","url":"clock-word.js"},
       {"name":"wclock.img","url":"clock-word-icon.js","evaluate":true}
     ]
   },
-  { "id": "fontclock",
+  {
+    "id": "fontclock",
     "name": "Font Clock",
-    "icon": "fontclock.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Choose the font and design of clock face from a library of available designs",
+    "icon": "fontclock.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":false,
-     "readme": "README.md",
-    "custom":"custom.html",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "custom": "custom.html",
+    "allow_emulator": false,
     "storage": [
       {"name":"fontclock.app.js","url":"fontclock.js"},
       {"name":"fontclock.img","url":"fontclock-icon.js","evaluate":true},
@@ -281,16 +312,18 @@
       {"name":"fontclock.font.vector50.js","url":"fontclock.font.vector50.js"}
     ]
   },
-  { "id": "slidingtext",
+  {
+    "id": "slidingtext",
     "name": "Sliding Clock",
-    "icon": "slidingtext.png",
-    "version":"0.07",
+    "version": "0.07",
     "description": "Inspired by the Pebble sliding clock, old times are scrolled off the screen and new times on. You are also able to change language on the fly so you can see the time written in other languages using button 1. Currently English, French, Japanese, Spanish and German are supported",
+    "icon": "slidingtext.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":false,
-     "readme": "README.md",
-    "custom":"custom.html",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "custom": "custom.html",
+    "allow_emulator": false,
     "storage": [
       {"name":"slidingtext.app.js","url":"slidingtext.js"},
       {"name":"slidingtext.img","url":"slidingtext-icon.js","evaluate":true},
@@ -304,16 +337,18 @@
       {"name":"slidingtext.dtfmt.js","url":"slidingtext.dtfmt.js"}
     ]
   },
-  { "id": "solarclock",
+  {
+    "id": "solarclock",
     "name": "Solar Clock",
-    "icon": "solar_clock.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Using your current or chosen location the solar watch face shows the Sun's sky position, time and date. Also allows you to wind backwards and forwards in time to see the sun's position",
+    "icon": "solar_clock.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":false,
-     "readme": "README.md",
-    "custom":"custom.html",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "custom": "custom.html",
+    "allow_emulator": false,
     "storage": [
       {"name":"solarclock.app.js","url":"solar_clock.js"},
       {"name":"solarclock.img","url":"solar_clock-icon.js","evaluate":true},
@@ -331,42 +366,48 @@
       {"name":"solar_loc.Seoul.json","url":"solar_loc.Seoul.json"}
     ]
   },
-  { "id": "sweepclock",
+  {
+    "id": "sweepclock",
     "name": "Sweep Clock",
-    "icon": "sweepclock.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "Smooth sweep secondhand with single hour numeral. Use button 1 to toggle the numeral font, button 3 to change the colour theme and button 4 to change the date placement",
+    "icon": "sweepclock.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
-     "readme": "README.md",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"sweepclock.app.js","url":"sweepclock.js"},
       {"name":"sweepclock.img","url":"sweepclock-icon.js","evaluate":true}
     ]
   },
-  { "id": "matrixclock",
+  {
+    "id": "matrixclock",
     "name": "Matrix Clock",
-    "icon": "matrixclock.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "inspired by The Matrix, a clock of the same style",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
-     "readme": "README.md",
+    "icon": "matrixclock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"matrixclock.app.js","url":"matrixclock.js"},
       {"name":"matrixclock.img","url":"matrixclock-icon.js","evaluate":true}
     ]
   },
-  { "id": "imgclock",
+  {
+    "id": "imgclock",
     "name": "Image background clock",
-    "shortName":"Image Clock",
-    "icon": "app.png",
-    "version":"0.08",
+    "shortName": "Image Clock",
+    "version": "0.08",
     "description": "A clock with an image as a background",
+    "icon": "app.png",
+    "type": "clock",
     "tags": "clock",
-    "type" : "clock",
+    "supports": ["BANGLEJS"],
     "custom": "custom.html",
     "storage": [
       {"name":"imgclock.app.js","url":"app.js"},
@@ -376,245 +417,261 @@
       {"name":"imgclock.face.bg","content":""}
     ]
   },
-  { "id": "impwclock",
+  {
+    "id": "impwclock",
     "name": "Imprecise Word Clock",
-    "icon": "clock-impword.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Imprecise word clock for vacations, weekends, and those who never need accurate time.",
+    "icon": "clock-impword.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"impwclock.app.js","url":"clock-impword.js"},
       {"name":"impwclock.img","url":"clock-impword-icon.js","evaluate":true}
     ]
   },
-  { "id": "aclock",
+  {
+    "id": "aclock",
     "name": "Analog Clock",
-    "icon": "clock-analog.png",
     "version": "0.15",
     "description": "An Analog Clock",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-analog.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"aclock.app.js","url":"clock-analog.js"},
       {"name":"aclock.img","url":"clock-analog-icon.js","evaluate":true}
     ]
   },
-  { "id": "clock2x3",
+  {
+    "id": "clock2x3",
     "name": "2x3 Pixel Clock",
-    "icon": "clock2x3.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "This is a simple clock using minimalist 2x3 pixel numerical digits",
-    "tags": "clock,b2",
+    "icon": "clock2x3.png",
     "type": "clock",
-    "allow_emulator":true,
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"clock2x3.app.js","url":"clock2x3-app.js"},
       {"name":"clock2x3.img","url":"clock2x3-icon.js","evaluate":true}
     ]
   },
-  { "id": "geissclk",
+  {
+    "id": "geissclk",
     "name": "Geiss Clock",
-    "icon": "clock.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "7 segment clock with animated background in the style of Ryan Geiss' music visualisation. NOTE: The first run will take ~1 minute to do some precalculation",
-    "tags": "clock,bno2",
-    "type":"clock",
+    "icon": "clock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"geissclk.app.js","url":"clock.js"},
       {"name":"geissclk.precompute.js","url":"precompute.js"},
       {"name":"geissclk.img","url":"clock-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"geissclk.0.map"},
-      {"name":"geissclk.1.map"},
-      {"name":"geissclk.2.map"},
-      {"name":"geissclk.3.map"},
-      {"name":"geissclk.4.map"},
-      {"name":"geissclk.5.map"},
-      {"name":"geissclk.0.pal"},
-      {"name":"geissclk.1.pal"},
-      {"name":"geissclk.2.pal"}
-    ]
+    "data": [{"name":"geissclk.0.map"},{"name":"geissclk.1.map"},{"name":"geissclk.2.map"},{"name":"geissclk.3.map"},{"name":"geissclk.4.map"},{"name":"geissclk.5.map"},{"name":"geissclk.0.pal"},{"name":"geissclk.1.pal"},{"name":"geissclk.2.pal"}]
   },
-  { "id": "trex",
+  {
+    "id": "trex",
     "name": "T-Rex",
-    "icon": "trex.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "T-Rex game in the style of Chrome's offline game",
-    "tags": "game,b2",
-    "allow_emulator":true,
+    "icon": "trex.png",
+    "tags": "game",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"trex.app.js","url":"trex.js"},
       {"name":"trex.img","url":"trex-icon.js","evaluate":true},
       {"name":"trex.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"trex.score", "storageFile": true}
-    ]
+    "data": [{"name":"trex.score","storageFile":true}]
   },
-  { "id": "astroid",
+  {
+    "id": "astroid",
     "name": "Asteroids!",
-    "icon": "asteroids.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Retro asteroids game",
-    "tags": "game,b2",
-    "allow_emulator":true,
+    "icon": "asteroids.png",
+    "tags": "game",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"astroid.app.js","url":"asteroids.js"},
       {"name":"astroid.img","url":"asteroids-icon.js","evaluate":true}
     ]
   },
-  { "id": "clickms",
+  {
+    "id": "clickms",
     "name": "Click Master",
-    "icon": "click-master.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
+    "icon": "click-master.png",
     "tags": "game",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"clickms.app.js","url":"click-master.js"},
       {"name":"clickms.img","url":"click-master-icon.js","evaluate":true}
     ]
   },
-  { "id": "horsey",
+  {
+    "id": "horsey",
     "name": "Horse Race!",
-    "icon": "horse-race.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
+    "icon": "horse-race.png",
     "tags": "game",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"horsey.app.js","url":"horse-race.js"},
       {"name":"horsey.img","url":"horse-race-icon.js","evaluate":true}
     ]
   },
-  { "id": "compass",
+  {
+    "id": "compass",
     "name": "Compass",
-    "icon": "compass.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Simple compass that points North",
+    "icon": "compass.png",
     "tags": "tool,outdoors",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"compass.app.js","url":"compass.js"},
       {"name":"compass.img","url":"compass-icon.js","evaluate":true}
     ]
   },
-  { "id": "gpstime",
+  {
+    "id": "gpstime",
     "name": "GPS Time",
-    "icon": "gpstime.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "Update the Bangle.js's clock based on the time from the GPS receiver",
+    "icon": "gpstime.png",
     "tags": "tool,gps",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"gpstime.app.js","url":"gpstime.js"},
       {"name":"gpstime.img","url":"gpstime-icon.js","evaluate":true}
     ]
   },
-  { "id": "openloc",
+  {
+    "id": "openloc",
     "name": "Open Location / Plus Codes",
     "shortName": "Open Location",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Convert your current GPS location to a series of characters",
+    "icon": "app.png",
     "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"openloc.app.js","url":"app.js"},
       {"name":"openloc.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "speedo",
+  {
+    "id": "speedo",
     "name": "Speedo",
-    "icon": "speedo.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "Show the current speed according to the GPS",
-    "tags": "tool,outdoors,gps,b2",
+    "icon": "speedo.png",
+    "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"speedo.app.js","url":"speedo.js"},
       {"name":"speedo.img","url":"speedo-icon.js","evaluate":true}
     ]
   },
-  { "id": "gpsrec",
+  {
+    "id": "gpsrec",
     "name": "GPS Recorder",
-    "icon": "app.png",
-    "version":"0.24",
-    "interface": "interface.html",
+    "version": "0.24",
     "description": "Application that allows you to record a GPS track. Can run in background",
+    "icon": "app.png",
     "tags": "tool,outdoors,gps,widget",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "interface": "interface.html",
     "storage": [
       {"name":"gpsrec.app.js","url":"app.js"},
       {"name":"gpsrec.img","url":"app-icon.js","evaluate":true},
       {"name":"gpsrec.wid.js","url":"widget.js"},
       {"name":"gpsrec.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"gpsrec.json"},
-      {"wildcard":".gpsrc?","storageFile": true}
-    ]
+    "data": [{"name":"gpsrec.json"},{"wildcard":".gpsrc?","storageFile":true}]
   },
-  { "id": "gpsnav",
+  {
+    "id": "gpsnav",
     "name": "GPS Navigation",
-    "icon": "icon.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording, now with waypoint editor",
+    "icon": "icon.png",
     "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
-    "interface":"waypoints.html",
+    "interface": "waypoints.html",
     "storage": [
       {"name":"gpsnav.app.js","url":"app.min.js"},
       {"name":"gpsnav.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"waypoints.json","url":"waypoints.json"}
-    ]
+    "data": [{"name":"waypoints.json","url":"waypoints.json"}]
   },
-  { "id": "heart",
+  {
+    "id": "heart",
     "name": "Heart Rate Recorder",
-    "icon": "app.png",
-    "version":"0.06",
-    "interface": "interface.html",
+    "version": "0.06",
     "description": "Application that allows you to record your heart rate. Can run in background",
+    "icon": "app.png",
     "tags": "tool,health,widget",
+    "supports": ["BANGLEJS"],
+    "interface": "interface.html",
     "storage": [
       {"name":"heart.app.js","url":"app.js"},
       {"name":"heart.img","url":"app-icon.js","evaluate":true},
       {"name":"heart.wid.js","url":"widget.js"}
     ],
-    "data": [
-      {"name":"heart.json"},
-      {"wildcard":".heart?","storageFile": true}
-    ]
+    "data": [{"name":"heart.json"},{"wildcard":".heart?","storageFile":true}]
   },
-  { "id": "slevel",
+  {
+    "id": "slevel",
     "name": "Spirit Level",
-    "icon": "spiritlevel.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat",
+    "icon": "spiritlevel.png",
     "tags": "tool",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"slevel.app.js","url":"spiritlevel.js"},
       {"name":"slevel.img","url":"spiritlevel-icon.js","evaluate":true}
     ]
   },
-  { "id": "files",
+  {
+    "id": "files",
     "name": "App Manager",
-    "icon": "files.png",
-    "version":"0.07",
+    "version": "0.07",
     "description": "Show currently installed apps, free space, and allow their deletion from the watch",
+    "icon": "files.png",
     "tags": "tool,system,files",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"files.app.js","url":"files.js"},
       {"name":"files.img","url":"files-icon.js","evaluate":true}
     ]
   },
-  { "id": "weather",
+  {
+    "id": "weather",
     "name": "Weather",
-    "icon": "icon.png",
-    "version":"0.10",
+    "version": "0.10",
     "description": "Show Gadgetbridge weather report",
-    "readme": "readme.md",
+    "icon": "icon.png",
     "tags": "widget,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "readme.md",
     "storage": [
       {"name":"weather.app.js","url":"app.js"},
       {"name":"weather.wid.js","url":"widget.js"},
@@ -622,30 +679,32 @@
       {"name":"weather.img","url":"icon.js","evaluate":true},
       {"name":"weather.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name": "weather.json"}
-    ]
+    "data": [{"name":"weather.json"}]
   },
-  { "id": "chargeanim",
+  {
+    "id": "chargeanim",
     "name": "Charge Animation",
-    "icon": "icon.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "When charging, show a sideways charging animation and keep the screen on. When removed from the charger load the clock again.",
+    "icon": "icon.png",
     "tags": "battery",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"chargeanim.app.js","url":"app.js"},
       {"name":"chargeanim.boot.js","url":"boot.js"},
       {"name":"chargeanim.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "bluetoothdock",
+  {
+    "id": "bluetoothdock",
     "name": "Bluetooth Dock",
-    "shortName":"Dock",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "Dock",
+    "version": "0.01",
     "description": "When charging shows the time, scans Bluetooth for known devices (eg temperature) and shows them on the screen",
+    "icon": "app.png",
     "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"bluetoothdock.app.js","url":"app.js"},
@@ -653,190 +712,214 @@
       {"name":"bluetoothdock.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widbat",
+  {
+    "id": "widbat",
     "name": "Battery Level Widget",
-    "icon": "widget.png",
-    "version":"0.08",
+    "version": "0.08",
     "description": "Show the current battery level and charging status in the top right of the clock",
-    "tags": "widget,battery,b2",
-    "type":"widget",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,battery",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"widbat.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "widlock",
+  {
+    "id": "widlock",
     "name": "Lock Widget",
-    "icon": "widget.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "On devices with always-on display (Bangle.js 2) this displays lock icon whenever the display is locked",
-    "tags": "widget,lock,b2",
-    "type":"widget",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,lock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"widlock.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "widbatpc",
+  {
+    "id": "widbatpc",
     "name": "Battery Level Widget (with percentage)",
     "shortName": "Battery Widget",
-    "icon": "widget.png",
-    "version":"0.13",
+    "version": "0.13",
     "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage",
-    "tags": "widget,battery,b2",
-    "type":"widget",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,battery",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
     "storage": [
       {"name":"widbatpc.wid.js","url":"widget.js"},
       {"name":"widbatpc.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"widbatpc.json"}
-    ]
+    "data": [{"name":"widbatpc.json"}]
   },
-  { "id": "widbatwarn",
+  {
+    "id": "widbatwarn",
     "name": "Battery Warning",
     "shortName": "Battery Warning",
-    "icon": "widget.png",
-    "readme": "README.md",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Show a warning when the battery runs low.",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "tool,battery",
-    "type":"widget",
-    "dependencies": { "notify":"type" },
+    "supports": ["BANGLEJS"],
+    "dependencies": {"notify":"type"},
+    "readme": "README.md",
     "storage": [
       {"name":"widbatwarn.wid.js","url":"widget.js"},
       {"name":"widbatwarn.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"widbatwarn.json"}
-    ]
+    "data": [{"name":"widbatwarn.json"}]
   },
-  { "id": "widbt",
+  {
+    "id": "widbt",
     "name": "Bluetooth Widget",
-    "icon": "widget.png",
-    "version":"0.06",
+    "version": "0.06",
     "description": "Show the current Bluetooth connection status in the top right of the clock",
-    "tags": "widget,bluetooth,b2",
-    "type":"widget",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,bluetooth",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"widbt.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "widchime",
+  {
+    "id": "widchime",
     "name": "Hour Chime",
-    "icon": "widget.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Buzz or beep on every whole hour.",
-    "tags": "widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widchime.wid.js","url":"widget.js"},
       {"name":"widchime.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"widchime.json"}
-    ]
+    "data": [{"name":"widchime.json"}]
   },
-  { "id": "widram",
+  {
+    "id": "widram",
     "name": "RAM Widget",
-    "shortName":"RAM Widget",
-    "icon": "widget.png",
-    "version":"0.01",
+    "shortName": "RAM Widget",
+    "version": "0.01",
     "description": "Display your Bangle's available RAM percentage in a widget",
-    "tags": "widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widram.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "hrm",
+  {
+    "id": "hrm",
     "name": "Heart Rate Monitor",
-    "icon": "heartrate.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "Measure your heart rate and see live sensor data",
+    "icon": "heartrate.png",
     "tags": "health",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"hrm.app.js","url":"heartrate.js"},
       {"name":"hrm.img","url":"heartrate-icon.js","evaluate":true}
     ]
   },
-  { "id": "widhrm",
+  {
+    "id": "widhrm",
     "name": "Simple Heart Rate widget",
-    "icon": "widget.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.",
-    "tags": "health,widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "health,widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widhrm.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "stetho",
+  {
+    "id": "stetho",
     "name": "Stethoscope",
-    "icon": "stetho.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Hear your heart rate",
+    "icon": "stetho.png",
     "tags": "health",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"stetho.app.js","url":"stetho.js"},
       {"name":"stetho.img","url":"stetho-icon.js","evaluate":true}
     ]
   },
-  { "id": "swatch",
+  {
+    "id": "swatch",
     "name": "Stopwatch",
-    "icon": "stopwatch.png",
-    "version":"0.07",
-    "interface": "interface.html",
+    "version": "0.07",
     "description": "Simple stopwatch with Lap Time logging to a JSON file",
+    "icon": "stopwatch.png",
     "tags": "health",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "interface": "interface.html",
+    "allow_emulator": true,
     "storage": [
       {"name":"swatch.app.js","url":"stopwatch.js"},
       {"name":"swatch.img","url":"stopwatch-icon.js","evaluate":true}
     ]
   },
-  { "id": "hidmsic",
+  {
+    "id": "hidmsic",
     "name": "Bluetooth Music Controls",
     "shortName": "Music Control",
-    "icon": "hid-music.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!",
+    "icon": "hid-music.png",
     "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"hidmsic.app.js","url":"hid-music.js"},
       {"name":"hidmsic.img","url":"hid-music-icon.js","evaluate":true}
     ]
   },
-  { "id": "hidkbd",
+  {
+    "id": "hidkbd",
     "name": "Bluetooth Keyboard",
     "shortName": "Bluetooth Kbd",
-    "icon": "hid-keyboard.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps",
+    "icon": "hid-keyboard.png",
     "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"hidkbd.app.js","url":"hid-keyboard.js"},
       {"name":"hidkbd.img","url":"hid-keyboard-icon.js","evaluate":true}
     ]
   },
-  { "id": "hidbkbd",
+  {
+    "id": "hidbkbd",
     "name": "Binary Bluetooth Keyboard",
     "shortName": "Binary BT Kbd",
-    "icon": "hid-binary-keyboard.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Enable HID in settings, pair with your phone/PC, then type messages using the onscreen keyboard by tapping repeatedly on the key you want",
+    "icon": "hid-binary-keyboard.png",
     "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"hidbkbd.app.js","url":"hid-binary-keyboard.js"},
       {"name":"hidbkbd.img","url":"hid-binary-keyboard-icon.js","evaluate":true}
     ]
   },
-  { "id": "animals",
+  {
+    "id": "animals",
     "name": "Animals Game",
-    "icon": "animals.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Simple toddler's game - displays a different number of animals each time the screen is pressed",
+    "icon": "animals.png",
     "tags": "game",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"animals.app.js","url":"animals.js"},
       {"name":"animals.img","url":"animals-icon.js","evaluate":true},
@@ -850,36 +933,43 @@
       {"name":"animals-mouse.img","url":"animals-mouse.js","evaluate":true}
     ]
   },
-  { "id": "qrcode",
+  {
+    "id": "qrcode",
     "name": "Custom QR Code",
-    "icon": "app.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Use this to upload a customised QR code to Bangle.js",
-    "tags": "qrcode,b2",
-    "custom": "custom.html", "customConnect":true,
+    "icon": "app.png",
+    "tags": "qrcode",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "custom": "custom.html",
+    "customConnect": true,
     "storage": [
       {"name":"qrcode.app.js"},
       {"name":"qrcode.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "beer",
+  {
+    "id": "beer",
     "name": "Beer Compass",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Uploads all the pubs in an area onto your watch, so it can always point you at the nearest one",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
     "custom": "custom.html",
     "storage": [
       {"name":"beer.app.js"},
       {"name":"beer.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "route",
+  {
+    "id": "route",
     "name": "Route Viewer",
-    "icon": "app.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Upload a KML file of a route, and have your watch display a map with how far around it you are",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
     "custom": "custom.html",
     "storage": [
       {"name":"route.app.js"},
@@ -889,10 +979,11 @@
   {
     "id": "ncstart",
     "name": "NCEU Startup",
-    "icon": "start.png",
-    "version":"0.06",
+    "version": "0.06",
     "description": "NodeConfEU 2019 'First Start' Sequence",
+    "icon": "start.png",
     "tags": "start,welcome",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"ncstart.app.js","url":"start.js"},
       {"name":"ncstart.boot.js","url":"boot.js"},
@@ -904,104 +995,118 @@
       {"name":"nc-nodew.img","url":"start-nodew.js","evaluate":true},
       {"name":"nc-tf.img","url":"start-tf.js","evaluate":true}
     ],
-    "data": [
-      {"name":"ncstart.json"}
-    ]
+    "data": [{"name":"ncstart.json"}]
   },
-  { "id": "ncfrun",
+  {
+    "id": "ncfrun",
     "name": "NCEU 5K Fun Run",
-    "icon": "nceu-funrun.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
+    "icon": "nceu-funrun.png",
     "tags": "health",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"ncfrun.app.js","url":"nceu-funrun.js"},
       {"name":"ncfrun.img","url":"nceu-funrun-icon.js","evaluate":true}
     ]
   },
-  { "id": "widnceu",
+  {
+    "id": "widnceu",
     "name": "NCEU Logo Widget",
-    "icon": "widget.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Show the NodeConf EU logo in the top left",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widnceu.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "sclock",
+  {
+    "id": "sclock",
     "name": "Simple Clock",
-    "icon": "clock-simple.png",
-    "version":"0.06",
+    "version": "0.06",
     "description": "A Simple Digital Clock",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-simple.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"sclock.app.js","url":"clock-simple.js"},
       {"name":"sclock.img","url":"clock-simple-icon.js","evaluate":true}
     ]
   },
-  { "id": "s7clk",
+  {
+    "id": "s7clk",
     "name": "Simple 7 segment Clock",
-    "icon": "icon.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "A simple 7 segment Clock with date",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "icon.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"s7clk.app.js","url":"app.js"},
       {"name":"s7clk.img","url":"icon.js","evaluate":true}
     ]
   },
-  { "id": "vibrclock",
+  {
+    "id": "vibrclock",
     "name": "Vibrate Clock",
-    "icon": "app.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "When BTN1 is pressed, vibrate out the time as a series of buzzes, one digit at a time. Hours, then Minutes. Zero is signified by one long buzz. Otherwise a simple digital clock.",
+    "icon": "app.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"vibrclock.app.js","url":"app.js"},
       {"name":"vibrclock.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "svclock",
+  {
+    "id": "svclock",
     "name": "Simple V-Clock",
-    "icon": "vclock-simple.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Modification of Simple Clock 0.04 to use Vectorfont",
+    "icon": "vclock-simple.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"svclock.app.js","url":"vclock-simple.js"},
       {"name":"svclock.img","url":"vclock-simple-icon.js","evaluate":true}
     ]
   },
-  { "id": "dclock",
+  {
+    "id": "dclock",
     "name": "Dev Clock",
-    "icon": "clock-dev.png",
-    "version":"0.10",
+    "version": "0.10",
     "description": "A Digital Clock including timestamp (tst), beats(@), days in current month (dm) and days since new moon (l)",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-dev.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"dclock.app.js","url":"clock-dev.js"},
       {"name":"dclock.img","url":"clock-dev-icon.js","evaluate":true}
     ]
   },
-  { "id": "gesture",
+  {
+    "id": "gesture",
     "name": "Gesture Test",
-    "icon": "gesture.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "BETA! Uploads a basic Tensorflow Gesture model, and then outputs each gesture as a message",
+    "icon": "gesture.png",
+    "type": "app",
     "tags": "gesture,ai",
-    "type":"app",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"gesture.app.js","url":"gesture.js"},
       {"name":".tfnames","url":"gesture-tfnames.js","evaluate":true},
@@ -1009,39 +1114,45 @@
       {"name":"gesture.img","url":"gesture-icon.js","evaluate":true}
     ]
   },
-  { "id": "pparrot",
+  {
+    "id": "pparrot",
     "name": "Party Parrot",
-    "icon": "party-parrot.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Party with a parrot on your wrist",
+    "icon": "party-parrot.png",
+    "type": "app",
     "tags": "party,parrot,lol",
-    "type":"app",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"pparrot.app.js","url":"party-parrot.js"},
       {"name":"pparrot.img","url":"party-parrot-icon.js","evaluate":true}
     ]
   },
-  { "id": "hrings",
+  {
+    "id": "hrings",
     "name": "Hypno Rings",
-    "icon": "hypno-rings.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Experiment with trippy rings, press buttons for change",
+    "icon": "hypno-rings.png",
+    "type": "app",
     "tags": "rings,hypnosis,psychadelic",
-    "type":"app",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"hrings.app.js","url":"hypno-rings.js"},
       {"name":"hrings.img","url":"hypno-rings-icon.js","evaluate":true}
     ]
   },
-  { "id": "morse",
+  {
+    "id": "morse",
     "name": "Morse Code",
-    "icon": "morse-code.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Learn morse code by hearing/seeing/feeling the code. Tap to toggle buzz!",
+    "icon": "morse-code.png",
+    "type": "app",
     "tags": "morse,sound,visual,input",
-    "type":"app",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"morse.app.js","url":"morse-code.js"},
       {"name":"morse.img","url":"morse-code-icon.js","evaluate":true}
@@ -1050,97 +1161,112 @@
   {
     "id": "blescan",
     "name": "BLE Scanner",
-    "icon": "blescan.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Scan for advertising BLE devices",
-    "tags" : "bluetooth",
-    "storage" : [
+    "icon": "blescan.png",
+    "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
+    "storage": [
       {"name":"blescan.app.js","url":"blescan.js"},
-      {"name":"blescan.img","url":"blescan-icon.js", "evaluate":true}
+      {"name":"blescan.img","url":"blescan-icon.js","evaluate":true}
     ]
   },
-  { "id": "mmonday",
-  "name": "Manic Monday Tone",
-  "icon": "manic-monday-icon.png",
-  "version":"0.02",
-  "description": "The Bangles make a comeback",
-  "tags": "sound",
-  "storage": [
-    {"name":"mmonday.app.js","url":"manic-monday.js"},
-    {"name":"mmonday.img","url":"manic-monday-icon.js","evaluate":true}
-  ]
-  },
-  { "id": "jbells",
-    "name": "Jingle Bells",
-    "icon": "jbells.png",
-    "version":"0.01",
-    "description": "Play Jingle Bells",
+  {
+    "id": "mmonday",
+    "name": "Manic Monday Tone",
+    "version": "0.02",
+    "description": "The Bangles make a comeback",
+    "icon": "manic-monday-icon.png",
     "tags": "sound",
-    "type":"app",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"mmonday.app.js","url":"manic-monday.js"},
+      {"name":"mmonday.img","url":"manic-monday-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "jbells",
+    "name": "Jingle Bells",
+    "version": "0.01",
+    "description": "Play Jingle Bells",
+    "icon": "jbells.png",
+    "type": "app",
+    "tags": "sound",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"jbells.app.js","url":"jbells.js"},
       {"name":"jbells.img","url":"jbells-icon.js","evaluate":true}
     ]
   },
-  { "id": "scolor",
+  {
+    "id": "scolor",
     "name": "Show Color",
-    "icon": "show-color.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Display all available Colors and Names",
+    "icon": "show-color.png",
+    "type": "app",
     "tags": "tool",
-    "type":"app",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"scolor.app.js","url":"show-color.js"},
       {"name":"scolor.img","url":"show-color-icon.js","evaluate":true}
     ]
   },
-  { "id": "miclock",
+  {
+    "id": "miclock",
     "name": "Mixed Clock",
-    "icon": "clock-mixed.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "A mix of analog and digital Clock",
+    "icon": "clock-mixed.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"miclock.app.js","url":"clock-mixed.js"},
       {"name":"miclock.img","url":"clock-mixed-icon.js","evaluate":true}
     ]
   },
-  { "id": "bclock",
+  {
+    "id": "bclock",
     "name": "Binary Clock",
-    "icon": "clock-binary.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "A simple binary clock watch face",
+    "icon": "clock-binary.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"bclock.app.js","url":"clock-binary.js"},
       {"name":"bclock.img","url":"clock-binary-icon.js","evaluate":true}
     ]
   },
-  { "id": "clotris",
+  {
+    "id": "clotris",
     "name": "Clock-Tris",
-    "icon": "clock-tris.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "A fully functional clone of a classic game of falling blocks",
+    "icon": "clock-tris.png",
     "tags": "game",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"clotris.app.js","url":"clock-tris.js"},
       {"name":"clotris.img","url":"clock-tris-icon.js","evaluate":true},
       {"name":".trishig","url":"clock-tris-high"}
     ]
   },
-  { "id": "flappy",
+  {
+    "id": "flappy",
     "name": "Flappy Bird",
-    "icon": "app.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "A Flappy Bird game clone",
-    "tags": "game,b2",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "tags": "game",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"flappy.app.js","url":"app.js"},
       {"name":"flappy.img","url":"app-icon.js","evaluate":true}
@@ -1149,137 +1275,159 @@
   {
     "id": "gpsinfo",
     "name": "GPS Info",
-    "icon": "gps-info.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "An application that displays information about altitude, lat/lon, satellites and time",
-    "tags": "gps,b2",
+    "icon": "gps-info.png",
     "type": "app",
+    "tags": "gps",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
-      {"name":"gpsinfo.app.js","url": "gps-info.js"},
-      {"name":"gpsinfo.img","url": "gps-info-icon.js","evaluate": true}
+      {"name":"gpsinfo.app.js","url":"gps-info.js"},
+      {"name":"gpsinfo.img","url":"gps-info-icon.js","evaluate":true}
     ]
   },
-  { "id": "assistedgps",
+  {
+    "id": "assistedgps",
     "name": "Assisted GPS Update (AGPS)",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Downloads assisted GPS (AGPS) data to Bangle.js for faster GPS startup and more accurate fixes. **No app will be installed**, this just uploads new data to the GPS chip.",
-    "custom": "custom.html",
-    "tags": "tool,outdoors,agps,bno2",
+    "icon": "app.png",
     "type": "RAM",
-    "storage": [ ]
+    "tags": "tool,outdoors,agps",
+    "supports": ["BANGLEJS"],
+    "custom": "custom.html",
+    "storage": [
+      
+    ]
   },
   {
     "id": "pomodo",
-    "name":"Pomodoro",
-    "icon":"pomodoro.png",
-    "version":"0.01",
+    "name": "Pomodoro",
+    "version": "0.01",
     "description": "A simple pomodoro timer.",
-    "tags": "pomodoro,cooking,tools",
+    "icon": "pomodoro.png",
     "type": "app",
-    "allow_emulator":true,
+    "tags": "pomodoro,cooking,tools",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
-      {"name":"pomodo.app.js","url": "pomodoro.js"},
-      {"name":"pomodo.img","url": "pomodoro-icon.js","evaluate": true}
+      {"name":"pomodo.app.js","url":"pomodoro.js"},
+      {"name":"pomodo.img","url":"pomodoro-icon.js","evaluate":true}
     ]
   },
-  { "id": "blobclk",
+  {
+    "id": "blobclk",
     "name": "Large Digit Blob Clock",
-    "shortName" : "Blob Clock",
-    "icon": "clock-blob.png",
-    "version":"0.06",
+    "shortName": "Blob Clock",
+    "version": "0.06",
     "description": "A clock with big digits",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-blob.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"blobclk.app.js","url":"clock-blob.js"},
       {"name":"blobclk.img","url":"clock-blob-icon.js","evaluate":true}
     ]
   },
-  { "id": "boldclk",
+  {
+    "id": "boldclk",
     "name": "Bold Clock",
-    "icon": "bold_clock.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "Simple, readable and practical clock",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "bold_clock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"boldclk.app.js","url":"bold_clock.js"},
       {"name":"boldclk.img","url":"bold_clock-icon.js","evaluate":true}
     ]
   },
-  { "id": "widclk",
+  {
+    "id": "widclk",
     "name": "Digital clock widget",
-    "icon": "widget.png",
-    "version":"0.06",
+    "version": "0.06",
     "description": "A simple digital clock widget",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,clock",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widclk.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "widpedom",
+  {
+    "id": "widpedom",
     "name": "Pedometer widget",
-    "icon": "widget.png",
-    "version":"0.19",
+    "version": "0.19",
     "description": "Daily pedometer widget",
-    "tags": "widget,b2",
-    "type":"widget",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"widpedom.wid.js","url":"widget.js"},
       {"name":"widpedom.settings.js","url":"settings.js"}
     ]
   },
-  { "id": "berlinc",
+  {
+    "id": "berlinc",
     "name": "Berlin Clock",
-    "icon": "berlin-clock.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
+    "icon": "berlin-clock.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"berlinc.app.js","url":"berlin-clock.js"},
       {"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true}
     ]
   },
-  { "id": "ctrclk",
+  {
+    "id": "ctrclk",
     "name": "Centerclock",
-    "icon": "app.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
-    "tags": "clock,bno2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"ctrclk.app.js","url":"app.js"},
       {"name":"ctrclk.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "demoapp",
+  {
+    "id": "demoapp",
     "name": "Demo Loop",
-    "icon": "app.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Simple demo app - displays Bangle.js, JS logo, graphics, and Bangle.js information",
-    "tags": "bno2",
-    "type":"app",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "type": "app",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"demoapp.app.js","url":"app.js"},
       {"name":"demoapp.img","url":"app-icon.js","evaluate":true}
     ],
-    "sortorder" : -9
+    "sortorder": -9
   },
-  { "id": "flagrse",
+  {
+    "id": "flagrse",
     "name": "Espruino Flag Raiser",
-    "icon": "app.png",
-    "version":"0.01",
-    "readme": "README.md",
+    "version": "0.01",
     "description": "App to send a command to another Espruino to cause it to raise a flag",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"flagrse.app.js","url":"app.js"},
       {"name":"flagrse.img","url":"app-icon.js","evaluate":true}
@@ -1288,64 +1436,73 @@
   {
     "id": "pipboy",
     "name": "Pipboy",
-    "icon": "app.png",
     "version": "0.04",
     "description": "Pipboy themed clock",
-    "tags": "clock,bno2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"pipboy.app.js","url":"app.js"},
       {"name":"pipboy.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "torch",
+  {
+    "id": "torch",
     "name": "Torch",
-    "shortName":"Torch",
-    "icon": "app.png",
-    "version":"0.02",
+    "shortName": "Torch",
+    "version": "0.02",
     "description": "Turns screen white to help you see in the dark. Select from the launcher or press BTN1,BTN3,BTN1,BTN3 quickly to start when in any app that shows widgets",
+    "icon": "app.png",
     "tags": "tool,torch",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"torch.app.js","url":"app.js"},
       {"name":"torch.wid.js","url":"widget.js"},
       {"name":"torch.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "rtorch",
+  {
+    "id": "rtorch",
     "name": "Red Torch",
-    "shortName":"RedTorch",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "RedTorch",
+    "version": "0.01",
     "description": "Turns screen RED to help you see in the dark without breaking your night vision. Select from the launcher or press BTN3,BTN1,BTN3,BTN1 quickly to start when in any app that shows widgets",
+    "icon": "app.png",
     "tags": "tool,torch",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"rtorch.app.js","url":"app.js"},
       {"name":"rtorch.wid.js","url":"widget.js"},
       {"name":"rtorch.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "wohrm",
+  {
+    "id": "wohrm",
     "name": "Workout HRM",
-    "icon": "app.png",
-    "version":"0.08",
-    "readme": "README.md",
+    "version": "0.08",
     "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.",
-    "tags": "hrm,workout",
+    "icon": "app.png",
     "type": "app",
-    "allow_emulator":true,
+    "tags": "hrm,workout",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"wohrm.app.js","url":"app.js"},
       {"name":"wohrm.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widid",
+  {
+    "id": "widid",
     "name": "Bluetooth ID Widget",
-    "icon": "widget.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Display the last two tuple of your Bangle.js MAC address in the widget section. This is useful for figuring out which Bangle.js to connect to if you have more than one Bangle.js!",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,address,mac",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widid.wid.js","url":"widget.js"}
     ]
@@ -1353,113 +1510,130 @@
   {
     "id": "grocery",
     "name": "Grocery",
-    "icon": "grocery.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Simple grocery (shopping) list - Display a list of product and track if you already put them in your cart.",
-    "tags": "tool,outdoors,shopping,list",
+    "icon": "grocery.png",
     "type": "app",
-    "custom":"grocery.html",
+    "tags": "tool,outdoors,shopping,list",
+    "supports": ["BANGLEJS"],
+    "custom": "grocery.html",
     "storage": [
-      {"name":"grocery.app.js", "url":"app.js"},
+      {"name":"grocery.app.js","url":"app.js"},
       {"name":"grocery.img","url":"grocery-icon.js","evaluate":true}
     ]
   },
-  { "id": "marioclock",
+  {
+    "id": "marioclock",
     "name": "Mario Clock",
-    "icon": "marioclock.png",
-    "version":"0.15",
+    "version": "0.15",
     "description": "Animated retro Mario clock, with Gameboy style 8-bit grey-scale graphics.",
-    "tags": "clock,mario,retro",
+    "icon": "marioclock.png",
     "type": "clock",
-    "allow_emulator":false,
+    "tags": "clock,mario,retro",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "allow_emulator": false,
     "storage": [
       {"name":"marioclock.app.js","url":"marioclock-app.js"},
       {"name":"marioclock.img","url":"marioclock-icon.js","evaluate":true}
     ]
   },
-  { "id": "cliock",
+  {
+    "id": "cliock",
     "name": "Commandline-Clock",
-    "shortName":"CLI-Clock",
-    "icon": "app.png",
-    "version":"0.14",
+    "shortName": "CLI-Clock",
+    "version": "0.14",
     "description": "Simple CLI-Styled Clock",
-    "tags": "clock,cli,command,bash,shell,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock,cli,command,bash,shell",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"cliock.app.js","url":"app.js"},
       {"name":"cliock.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widver",
+  {
+    "id": "widver",
     "name": "Firmware Version Widget",
-    "icon": "widget.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Display the version of the installed firmware in the top widget section.",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,tool,system",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widver.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "barclock",
+  {
+    "id": "barclock",
     "name": "Bar Clock",
-    "icon": "clock-bar.png",
-    "version":"0.08",
+    "version": "0.08",
     "description": "A simple digital clock showing seconds as a bar",
+    "icon": "clock-bar.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
-    "allow_emulator":true,
+    "allow_emulator": true,
     "storage": [
       {"name":"barclock.app.js","url":"clock-bar.js"},
       {"name":"barclock.img","url":"clock-bar-icon.js","evaluate":true}
     ]
   },
-  { "id": "dotclock",
+  {
+    "id": "dotclock",
     "name": "Dot Clock",
-    "icon": "clock-dot.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "A Minimal Dot Analog Clock",
-    "tags": "clock,b2",
-    "type":"clock",
-    "allow_emulator":true,
+    "icon": "clock-dot.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
     "storage": [
       {"name":"dotclock.app.js","url":"clock-dot.js"},
       {"name":"dotclock.img","url":"clock-dot-icon.js","evaluate":true}
     ]
   },
-  { "id": "widtbat",
+  {
+    "id": "widtbat",
     "name": "Tiny Battery Widget",
-    "icon": "widget.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Tiny blueish battery widget, vibs and changes level color when charging",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,tool,system",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widtbat.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "chrono",
+  {
+    "id": "chrono",
     "name": "Chrono",
-    "shortName":"Chrono",
-    "icon": "chrono.png",
-    "version":"0.01",
+    "shortName": "Chrono",
+    "version": "0.01",
     "description": "Single click BTN1 to add 5 minutes. Single click BTN2 to add 30 seconds. Single click BTN3 to add 5 seconds. Tap to pause or play to timer. Double click BTN1 to reset. When timer finishes the watch vibrates.",
+    "icon": "chrono.png",
     "tags": "tool",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"chrono.app.js","url":"chrono.js"},
       {"name":"chrono.img","url":"chrono-icon.js","evaluate":true}
     ]
   },
-  { "id": "astrocalc",
+  {
+    "id": "astrocalc",
     "name": "Astrocalc",
-    "icon": "astrocalc.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Calculates interesting information on the sun and moon cycles for the current day based on your location.",
+    "icon": "astrocalc.png",
     "tags": "app,sun,moon,cycles,tool,outdoors",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"astrocalc.app.js","url":"astrocalc-app.js"},
       {"name":"suncalc.js","url":"suncalc.js"},
@@ -1474,108 +1648,121 @@
       {"name":"waxing-crescent.img","url":"waxing-crescent-icon.js","evaluate":true}
     ]
   },
-  { "id": "widhwt",
+  {
+    "id": "widhwt",
     "name": "Hand Wash Timer",
-    "icon": "widget.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Swipe your wrist over the watch face to start your personal Bangle.js hand wash timer for 35 sec. Start washing after the short buzz and stop after the long buzz.",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,tool",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widhwt.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "toucher",
+  {
+    "id": "toucher",
     "name": "Touch Launcher",
-    "shortName":"Toucher",
-    "icon": "app.png",
-    "version":"0.07",
+    "shortName": "Toucher",
+    "version": "0.07",
     "description": "Touch enable left to right launcher.",
-    "tags": "tool,system,launcher,b2",
-    "type":"launch",
+    "icon": "app.png",
+    "type": "launch",
+    "tags": "tool,system,launcher",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
-    "data": [
-      {"name":"toucher.json"}
-    ],
     "storage": [
       {"name":"toucher.app.js","url":"app.js"},
       {"name":"toucher.settings.js","url":"settings.js"}
     ],
-    "sortorder" : -10
+    "data": [{"name":"toucher.json"}],
+    "sortorder": -10
   },
   {
     "id": "balltastic",
     "name": "Balltastic",
-    "icon": "app.png",
     "version": "0.02",
     "description": "Simple but fun ball eats dots game.",
-    "tags": "game,fun",
+    "icon": "app.png",
     "type": "app",
+    "tags": "game,fun",
+    "supports": ["BANGLEJS"],
     "storage": [
-        {"name":"balltastic.app.js","url":"app.js"},
-        {"name":"balltastic.img","url":"app-icon.js","evaluate":true}
-      ]
+      {"name":"balltastic.app.js","url":"app.js"},
+      {"name":"balltastic.img","url":"app-icon.js","evaluate":true}
+    ]
   },
   {
     "id": "rpgdice",
     "name": "RPG dice",
-    "icon": "rpgdice.png",
     "version": "0.02",
     "description": "Simple RPG dice rolling app.",
-    "tags": "game,fun",
+    "icon": "rpgdice.png",
     "type": "app",
+    "tags": "game,fun",
+    "supports": ["BANGLEJS"],
     "allow_emulator": true,
     "storage": [
-      {"name":"rpgdice.app.js","url": "app.js"},
-      {"name":"rpgdice.img","url": "app-icon.js","evaluate":true}
+      {"name":"rpgdice.app.js","url":"app.js"},
+      {"name":"rpgdice.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widmp",
+  {
+    "id": "widmp",
     "name": "Moon Phase Widget",
-    "icon": "widget.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Display the current moon phase in blueish for the northern hemisphere in eight phases",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget,tools",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widmp.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "minionclk",
+  {
+    "id": "minionclk",
     "name": "Minion clock",
-    "icon": "minionclk.png",
     "version": "0.05",
     "description": "Minion themed clock.",
-    "tags": "clock,minion",
+    "icon": "minionclk.png",
     "type": "clock",
+    "tags": "clock,minion",
+    "supports": ["BANGLEJS"],
     "allow_emulator": true,
     "storage": [
       {"name":"minionclk.app.js","url":"app.js"},
       {"name":"minionclk.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "openstmap",
+  {
+    "id": "openstmap",
     "name": "OpenStreetMap",
-    "shortName":"OpenStMap",
-    "icon": "app.png",
-    "version":"0.09",
+    "shortName": "OpenStMap",
+    "version": "0.09",
     "description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are",
-    "tags": "outdoors,gps,b2",
-    "custom": "custom.html", "customConnect":true,
+    "icon": "app.png",
+    "tags": "outdoors,gps",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "custom": "custom.html",
+    "customConnect": true,
     "storage": [
       {"name":"openstmap","url":"openstmap.js"},
       {"name":"openstmap.app.js","url":"app.js"},
       {"name":"openstmap.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "activepedom",
+  {
+    "id": "activepedom",
     "name": "Active Pedometer",
-    "shortName":"Active Pedometer",
-    "icon": "app.png",
-    "version":"0.09",
+    "shortName": "Active Pedometer",
+    "version": "0.09",
     "description": "Pedometer that filters out arm movement and displays a step goal progress. Steps are saved to a daily file and can be viewed as graph.",
+    "icon": "app.png",
     "tags": "outdoors,widget",
-     "readme": "README.md",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"activepedom.wid.js","url":"widget.js"},
       {"name":"activepedom.settings.js","url":"settings.js"},
@@ -1583,136 +1770,154 @@
       {"name":"activepedom.app.js","url":"app.js"}
     ]
   },
-  { "id": "chronowid",
+  {
+    "id": "chronowid",
     "name": "Chrono Widget",
-    "shortName":"Chrono Widget",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Chrono Widget",
+    "version": "0.03",
     "description": "Chronometer (timer) which runs as widget.",
-    "tags": "tool,widget,b2",
-     "readme": "README.md",
+    "icon": "app.png",
+    "tags": "tool,widget",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "readme": "README.md",
     "storage": [
       {"name":"chronowid.wid.js","url":"widget.js"},
       {"name":"chronowid.app.js","url":"app.js"},
       {"name":"chronowid.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "tabata",
+  {
+    "id": "tabata",
     "name": "Tabata",
     "shortName": "Tabata - Control High-Intensity Interval Training",
-    "icon": "tabata.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Control high-intensity interval training (according to tabata: https://en.wikipedia.org/wiki/Tabata_method).",
+    "icon": "tabata.png",
     "tags": "workout,health",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"tabata.app.js","url":"tabata.js"},
       {"name":"tabata.img","url":"tabata-icon.js","evaluate":true}
     ]
   },
-  { "id": "custom",
+  {
+    "id": "custom",
     "name": "Custom Boot Code ",
-    "icon": "custom.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Add code you want to run at boot time",
-    "tags": "tool,system",
+    "icon": "custom.png",
     "type": "bootloader",
-    "custom":"custom.html",
+    "tags": "tool,system",
+    "supports": ["BANGLEJS"],
+    "custom": "custom.html",
     "storage": [
-       {"name":"custom"}
+      {"name":"custom"}
     ]
   },
-  { "id": "devstopwatch",
-  "name": "Dev Stopwatch",
-  "shortName":"Dev Stopwatch",
-  "icon": "app.png",
-  "version":"0.03",
-  "description": "Stopwatch with 5 laps supported (cyclically replaced)",
-  "tags": "stopwatch,chrono,timer,chronometer,b2",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"devstopwatch.app.js","url":"app.js"},
-    {"name":"devstopwatch.img","url":"app-icon.js","evaluate":true}
-  ]
-  },
-  { "id": "batchart",
-    "name": "Battery Chart",
-    "shortName":"Battery Chart",
+  {
+    "id": "devstopwatch",
+    "name": "Dev Stopwatch",
+    "shortName": "Dev Stopwatch",
+    "version": "0.03",
+    "description": "Stopwatch with 5 laps supported (cyclically replaced)",
     "icon": "app.png",
-    "version":"0.10",
-    "readme": "README.md",
+    "tags": "stopwatch,chrono,timer,chronometer",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"devstopwatch.app.js","url":"app.js"},
+      {"name":"devstopwatch.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "batchart",
+    "name": "Battery Chart",
+    "shortName": "Battery Chart",
+    "version": "0.10",
     "description": "A widget and an app for recording and visualizing battery percentage over time.",
+    "icon": "app.png",
     "tags": "app,widget,battery,time,record,chart,tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"batchart.wid.js","url":"widget.js"},
       {"name":"batchart.app.js","url":"app.js"},
       {"name":"batchart.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "nato",
+  {
+    "id": "nato",
     "name": "NATO Alphabet",
-    "shortName" : "NATOAlphabet",
-    "icon": "nato.png",
-    "version":"0.01",
-    "type": "app",
+    "shortName": "NATOAlphabet",
+    "version": "0.01",
     "description": "Learn the NATO Phonetic alphabet plus some numbers.",
+    "icon": "nato.png",
+    "type": "app",
     "tags": "app,learn,visual",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"nato.app.js","url":"nato.js"},
       {"name":"nato.img","url":"nato-icon.js","evaluate":true}
     ]
   },
-  { "id": "numerals",
+  {
+    "id": "numerals",
     "name": "Numerals Clock",
     "shortName": "Numerals Clock",
-    "icon": "numerals.png",
-    "version":"0.09",
+    "version": "0.09",
     "description": "A simple big numerals clock",
+    "icon": "numerals.png",
+    "type": "clock",
     "tags": "numerals,clock",
-	"type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"numerals.app.js","url":"numerals.app.js"},
       {"name":"numerals.img","url":"numerals-icon.js","evaluate":true},
       {"name":"numerals.settings.js","url":"numerals.settings.js"}
     ],
-    "data":[
-      {"name":"numerals.json"}
-    ]
+    "data": [{"name":"numerals.json"}]
   },
-  { "id": "bledetect",
+  {
+    "id": "bledetect",
     "name": "BLE Detector",
-    "shortName":"BLE Detector",
-    "icon": "bledetect.png",
-    "version":"0.03",
+    "shortName": "BLE Detector",
+    "version": "0.03",
     "description": "Detect BLE devices and show some informations.",
+    "icon": "bledetect.png",
     "tags": "app,bluetooth,tool",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"bledetect.app.js","url":"bledetect.js"},
       {"name":"bledetect.img","url":"bledetect-icon.js","evaluate":true}
     ]
   },
-  { "id": "snake",
+  {
+    "id": "snake",
     "name": "Snake",
-    "shortName":"Snake",
-    "icon": "snake.png",
-    "version":"0.02",
+    "shortName": "Snake",
+    "version": "0.02",
     "description": "The classic snake game. Eat apples and don't bite your tail.",
+    "icon": "snake.png",
     "tags": "game,fun",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"snake.app.js","url":"snake.js"},
       {"name":"snake.img","url":"snake-icon.js","evaluate":true}
     ]
   },
-    { "id": "calculator",
+  {
+    "id": "calculator",
     "name": "Calculator",
-    "shortName":"Calculator",
-    "icon": "calculator.png",
-    "version":"0.04",
+    "shortName": "Calculator",
+    "version": "0.04",
     "description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus.",
-    "tags": "app,tool,b2",
+    "icon": "calculator.png",
+    "tags": "app,tool",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "storage": [
       {"name":"calculator.app.js","url":"app.js"},
       {"name":"calculator.img","url":"calculator-icon.js","evaluate":true}
@@ -1722,54 +1927,49 @@
     "id": "dane",
     "name": "Digital Assistant, not EDITH",
     "shortName": "DANE",
-    "icon": "app.png",
     "version": "0.16",
     "description": "A Watchface inspired by Tony Stark's EDITH and based on https://arwes.dev/",
-    "tags": "clock",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "allow_emulator": true,
     "storage": [
-      {
-        "name": "dane.app.js",
-        "url": "app.js"
-      },
-      {
-        "name": "dane.img",
-        "url": "app-icon.js",
-        "evaluate": true
-      }
+      {"name":"dane.app.js","url":"app.js"},
+      {"name":"dane.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "dane_tcr",
+  {
+    "id": "dane_tcr",
     "name": "DANE Touch Launcher",
-    "shortName":"DANE Toucher",
-    "icon": "app.png",
-    "version":"0.07",
+    "shortName": "DANE Toucher",
+    "version": "0.07",
     "description": "Touch enable left to right launcher in the style of the DANE Watchface",
+    "icon": "app.png",
+    "type": "launch",
     "tags": "tool,system,launcher",
-    "type":"launch",
-    "data": [
-      {"name":"dane_tcr.json"}
-    ],
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"dane_tcr.app.js","url":"app.js"},
       {"name":"dane_tcr.settings.js","url":"settings.js"}
     ],
-    "sortorder" : -10
+    "data": [{"name":"dane_tcr.json"}],
+    "sortorder": -10
   },
   {
     "id": "buffgym",
     "name": "BuffGym",
-    "icon": "buffgym.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "BuffGym is the famous 5x5 workout program for the BangleJS",
-    "tags": "tool,outdoors,gym,exercise",
+    "icon": "buffgym.png",
     "type": "app",
+    "tags": "tool,outdoors,gym,exercise",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "interface": "buffgym.html",
     "allow_emulator": false,
-    "readme": "README.md",
     "storage": [
-      {"name":"buffgym.app.js", "url": "buffgym.app.js"},
+      {"name":"buffgym.app.js","url":"buffgym.app.js"},
       {"name":"buffgym-set.js","url":"buffgym-set.js"},
       {"name":"buffgym-exercise.js","url":"buffgym-exercise.js"},
       {"name":"buffgym-workout.js","url":"buffgym-workout.js"},
@@ -1783,82 +1983,76 @@
     "id": "banglerun",
     "name": "BangleRun",
     "shortName": "BangleRun",
-    "icon": "banglerun.png",
     "version": "0.10",
-    "interface": "interface.html",
     "description": "An app for running sessions. Displays info and logs your run for later viewing.",
+    "icon": "banglerun.png",
     "tags": "run,running,fitness,outdoors",
+    "supports": ["BANGLEJS"],
+    "interface": "interface.html",
     "allow_emulator": false,
     "storage": [
-      {
-        "name": "banglerun.app.js",
-        "url": "app.js"
-      },
-      {
-        "name": "banglerun.img",
-        "url": "app-icon.js",
-        "evaluate": true
-      }
+      {"name":"banglerun.app.js","url":"app.js"},
+      {"name":"banglerun.img","url":"app-icon.js","evaluate":true}
     ]
   },
   {
     "id": "metronome",
     "name": "Metronome",
-    "icon": "metronome_icon.png",
     "version": "0.06",
-    "readme": "README.md",
     "description": "Makes the watch blinking and vibrating with a given rate",
+    "icon": "metronome_icon.png",
     "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-      {
-        "name": "metronome.app.js",
-        "url": "metronome.js"
-      },
-      {
-        "name": "metronome.img",
-        "url": "metronome-icon.js",
-        "evaluate": true
-      },
+      {"name":"metronome.app.js","url":"metronome.js"},
+      {"name":"metronome.img","url":"metronome-icon.js","evaluate":true},
       {"name":"metronome.settings.js","url":"settings.js"}
     ]
   },
-  { "id": "blackjack",
+  {
+    "id": "blackjack",
     "name": "Black Jack game",
-    "shortName":"Black Jack game",
-    "icon": "blackjack.png",
-    "version":"0.02",
+    "shortName": "Black Jack game",
+    "version": "0.02",
     "description": "Simple implementation of card game Black Jack",
+    "icon": "blackjack.png",
     "tags": "game",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"blackjack.app.js","url":"blackjack.app.js"},
       {"name":"blackjack.img","url":"blackjack-icon.js","evaluate":true}
     ]
   },
-  { "id": "hidcam",
+  {
+    "id": "hidcam",
     "name": "Camera shutter",
-    "shortName":"Cam shutter",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Cam shutter",
+    "version": "0.03",
     "description": "Enable HID, connect to your phone, start your camera and trigger the shot on your Bangle",
-    "readme": "README.md",
+    "icon": "app.png",
     "tags": "bluetooth,tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
-        {"name":"hidcam.app.js","url":"app.js"},
-        {"name":"hidcam.img","url":"app-icon.js","evaluate":true}
+      {"name":"hidcam.app.js","url":"app.js"},
+      {"name":"hidcam.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "swlclk",
+  {
+    "id": "swlclk",
     "name": "SWL Clock / Short Wave Listner Clock",
     "shortName": "SWL Clock",
-    "icon": "swlclk.png",
-    "version":"0.02",
+    "version": "0.02",
     "description": "Display Local, UTC time and some programs on the shorts waves along the day, with the frequencies",
+    "icon": "swlclk.png",
+    "type": "clock",
     "tags": "tool,clock",
-    "type":"clock",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
-    "allow_emulator":true,
+    "allow_emulator": true,
     "storage": [
       {"name":"swlclk.app.js","url":"app.js"},
       {"name":"swlclk.img","url":"app-icon.js","evaluate":true}
@@ -1868,11 +2062,12 @@
     "id": "rclock",
     "name": "Round clock with seconds,  minutes and date",
     "shortName": "Round Clock",
-    "icon": "app.png",
     "version": "0.06",
     "description": "Designed round clock with ticks for minutes and seconds and heart rate indication",
-    "tags": "clock",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"rclock.app.js","url":"rclock.app.js"},
       {"name":"rclock.img","url":"app-icon.js","evaluate":true}
@@ -1882,35 +2077,40 @@
     "id": "fclock",
     "name": "fclock",
     "shortName": "F Clock",
-    "icon": "app.png",
     "version": "0.02",
     "description": "Simple design of a digital clock",
-    "tags": "clock",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"fclock.app.js","url":"fclock.app.js"},
       {"name":"fclock.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "hamloc",
+  {
+    "id": "hamloc",
     "name": "QTH Locator / Maidenhead Locator System",
     "shortName": "QTH Locator",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Convert your current GPS location to the Maidenhead locator system used by HAM amateur radio operators",
+    "icon": "app.png",
     "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"hamloc.app.js","url":"app.js"},
       {"name":"hamloc.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "osmpoi",
+  {
+    "id": "osmpoi",
     "name": "POI Compass",
-    "icon": "app.png",
-    "version":"0.03",
+    "version": "0.03",
     "description": "Uploads all the points of interest in an area onto your watch, same as Beer Compass with more p.o.i.",
+    "icon": "app.png",
     "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "custom": "custom.html",
     "storage": [
@@ -1918,64 +2118,63 @@
       {"name":"osmpoi.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "pong",
+  {
+    "id": "pong",
     "name": "Pong",
     "shortName": "Pong",
-    "icon": "pong.png",
     "version": "0.03",
     "description": "A clone of the Atari game Pong",
-    "tags": "game",
+    "icon": "pong.png",
     "type": "app",
-    "allow_emulator": true,
+    "tags": "game",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"pong.app.js","url":"app.js"},
       {"name":"pong.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "ballmaze",
+  {
+    "id": "ballmaze",
     "name": "Ball Maze",
-    "icon": "icon.png",
     "version": "0.02",
     "description": "Navigate a ball through a maze by tilting your watch.",
-    "readme": "README.md",
-    "tags": "game",
+    "icon": "icon.png",
     "type": "app",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
-      {"name": "ballmaze.app.js","url":"app.js"},
-      {"name": "ballmaze.img","url":"icon.js","evaluate": true}
+      {"name":"ballmaze.app.js","url":"app.js"},
+      {"name":"ballmaze.img","url":"icon.js","evaluate":true}
     ],
-    "data": [
-      {"name": "ballmaze.json"}
-    ]
+    "data": [{"name":"ballmaze.json"}]
   },
-  { "id": "calendar",
+  {
+    "id": "calendar",
     "name": "Calendar",
-    "icon": "calendar.png",
     "version": "0.02",
     "description": "Simple calendar",
-    "tags": "calendar,b2",
+    "icon": "calendar.png",
+    "tags": "calendar",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-      {
-        "name": "calendar.app.js",
-        "url": "calendar.js"
-      },
-      {
-        "name": "calendar.img",
-        "url": "calendar-icon.js",
-        "evaluate": true
-      }
+      {"name":"calendar.app.js","url":"calendar.js"},
+      {"name":"calendar.img","url":"calendar-icon.js","evaluate":true}
     ]
   },
-  { "id": "hidjoystick",
+  {
+    "id": "hidjoystick",
     "name": "Bluetooth Joystick",
     "shortName": "Joystick",
-    "icon": "app.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Emulates a 2 axis/5 button Joystick using the accelerometer as stick input and buttons 1-3, touch left as button 4 and touch right as button 5.",
+    "icon": "app.png",
     "tags": "bluetooth",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"hidjoystick.app.js","url":"app.js"},
       {"name":"hidjoystick.img","url":"app-icon.js","evaluate":true}
@@ -1984,30 +2183,31 @@
   {
     "id": "largeclock",
     "name": "Large Clock",
-    "icon": "largeclock.png",
     "version": "0.10",
     "description": "A readable and informational digital watch, with date, seconds and moon phase",
-    "readme": "README.md",
-    "tags": "clock",
+    "icon": "largeclock.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-      {"name": "largeclock.app.js", "url": "largeclock.js"},
-      {"name": "largeclock.img", "url": "largeclock-icon.js", "evaluate": true},
-      {"name": "largeclock.settings.js", "url": "settings.js"}
+      {"name":"largeclock.app.js","url":"largeclock.js"},
+      {"name":"largeclock.img","url":"largeclock-icon.js","evaluate":true},
+      {"name":"largeclock.settings.js","url":"settings.js"}
     ],
-    "data": [
-      {"name":"largeclock.json"}
-    ]
+    "data": [{"name":"largeclock.json"}]
   },
-  { "id": "smtswch",
+  {
+    "id": "smtswch",
     "name": "Smart Switch",
-    "shortName":"Smart Switch",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "Smart Switch",
+    "version": "0.01",
     "description": "Using EspruinoHub, control your smart devices on and off via Bluetooth Low Energy!",
-    "tags": "bluetooth,btle,smart,switch",
+    "icon": "app.png",
     "type": "app",
+    "tags": "bluetooth,btle,smart,switch",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"smtswch.app.js","url":"app.js"},
@@ -2018,13 +2218,15 @@
       {"name":"switch-off.img","url":"switch-off.js","evaluate":true}
     ]
   },
-  { "id": "miplant",
+  {
+    "id": "miplant",
     "name": "Xiaomi Plant Sensor",
-    "shortName":"Mi Plant",
-    "icon": "app.png",
-    "version":"0.02",
+    "shortName": "Mi Plant",
+    "version": "0.02",
     "description": "Reads and displays data from Xiaomi bluetooth plant moisture sensors",
+    "icon": "app.png",
     "tags": "xiaomi,mi,plant,ble,bluetooth",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"miplant.app.js","url":"app.js"},
       {"name":"miplant.img","url":"app-icon.js","evaluate":true}
@@ -2033,76 +2235,63 @@
   {
     "id": "simpletimer",
     "name": "Timer",
-    "icon": "app.png",
     "version": "0.07",
     "description": "Simple timer, useful when playing board games or cooking",
+    "icon": "app.png",
     "tags": "timer",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-      {
-        "name": "simpletimer.app.js",
-        "url": "app.js"
-      },
-      {
-        "name": ".tfnames",
-        "url": "gesture-tfnames.js",
-        "evaluate": true
-      },
-      {
-        "name": ".tfmodel",
-        "url": "gesture-tfmodel.js",
-        "evaluate": true
-      },
-      {
-        "name": "simpletimer.img",
-        "url": "app-icon.js",
-        "evaluate": true
-      }
+      {"name":"simpletimer.app.js","url":"app.js"},
+      {"name":".tfnames","url":"gesture-tfnames.js","evaluate":true},
+      {"name":".tfmodel","url":"gesture-tfmodel.js","evaluate":true},
+      {"name":"simpletimer.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {
-        "name": "simpletimer.json"
-      }
-    ]
+    "data": [{"name":"simpletimer.json"}]
   },
   {
     "id": "beebclock",
     "name": "Beeb Clock",
-    "icon": "beebclock.png",
-    "version":"0.05",
+    "version": "0.05",
     "description": "Clock face that may be coincidentally familiar to BBC viewers",
-    "tags": "clock",
+    "icon": "beebclock.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "allow_emulator": true,
     "storage": [
-        {"name":"beebclock.app.js","url":"beebclock.js"},
-        {"name":"beebclock.img","url":"beebclock-icon.js","evaluate":true}
+      {"name":"beebclock.app.js","url":"beebclock.js"},
+      {"name":"beebclock.img","url":"beebclock-icon.js","evaluate":true}
     ]
   },
-  { "id": "findphone",
+  {
+    "id": "findphone",
     "name": "Find Phone",
-    "shortName":"Find Phone",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Find Phone",
+    "version": "0.03",
     "description": "Find your phone via Gadgetbridge. Click any button to let your phone ring. 📳  Note: The functionality is available even without this app, just go to Settings, App Settings, Gadgetbridge, Find Phone.",
+    "icon": "app.png",
     "tags": "tool,android",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-        {"name":"findphone.app.js","url":"app.js"},
-        {"name":"findphone.img","url":"app-icon.js","evaluate":true}
+      {"name":"findphone.app.js","url":"app.js"},
+      {"name":"findphone.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "getup",
+  {
+    "id": "getup",
     "name": "Get Up",
-    "shortName":"Get Up",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "Get Up",
+    "version": "0.01",
     "description": "Reminds you to getup every x minutes. Sitting to long is dangerous!",
+    "icon": "app.png",
     "tags": "tools,health",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
-    "allow_emulator":true,
+    "allow_emulator": true,
     "storage": [
       {"name":"getup.app.js","url":"app.js"},
       {"name":"getup.settings.js","url":"settings.js"},
@@ -2113,43 +2302,46 @@
     "id": "gallifr",
     "name": "Time Traveller's Chronometer",
     "shortName": "Time Travel Clock",
-    "icon": "gallifr.png",
     "version": "0.02",
     "description": "A clock for time travellers. The light pie segment shows the minutes, the black circle, the hour. The dial itself reads 'time' just in case you forget.",
-    "tags": "clock,b2",
-    "readme": "README.md",
+    "icon": "gallifr.png",
     "type": "clock",
-    "allow_emulator":true,
-    "storage": [
-      { "name": "gallifr.app.js", "url": "app.js" },
-      { "name": "gallifr.img", "url": "app-icon.js", "evaluate": true },
-      { "name": "gallifr.settings.js", "url": "settings.js" }
-    ],
-    "data": [
-      {"name":"gallifr.json"}
-    ]
-  },
-  { "id": "rndmclk",
-    "name": "Random Clock Loader",
-    "icon": "rndmclk.png",
-    "version":"0.03",
-    "description": "Load a different clock whenever the LCD is switched on.",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"gallifr.app.js","url":"app.js"},
+      {"name":"gallifr.img","url":"app-icon.js","evaluate":true},
+      {"name":"gallifr.settings.js","url":"settings.js"}
+    ],
+    "data": [{"name":"gallifr.json"}]
+  },
+  {
+    "id": "rndmclk",
+    "name": "Random Clock Loader",
+    "version": "0.03",
+    "description": "Load a different clock whenever the LCD is switched on.",
+    "icon": "rndmclk.png",
+    "type": "widget",
     "tags": "widget,clock",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"rndmclk.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "dotmatrixclock",
+  {
+    "id": "dotmatrixclock",
     "name": "Dotmatrix Clock",
-    "icon": "dotmatrixclock.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "A clear white-on-blue dotmatrix simulated clock",
-    "tags": "clock,dotmatrix,retro",
+    "icon": "dotmatrixclock.png",
     "type": "clock",
-    "allow_emulator":true,
+    "tags": "clock,dotmatrix,retro",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"dotmatrixclock.app.js","url":"app.js"},
       {"name":"dotmatrixclock.img","url":"dotmatrixclock-icon.js","evaluate":true}
@@ -2159,63 +2351,71 @@
     "id": "jbm8b",
     "name": "Magic 8 Ball",
     "shortName": "Magic 8 Ball",
-    "icon": "app.png",
-    "description": "A simple fortune telling app",
-    "tags": "game",
     "version": "0.03",
+    "description": "A simple fortune telling app",
+    "icon": "app.png",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
     "storage": [
-      { "name": "jbm8b.app.js", "url": "app.js" },
-      { "name": "jbm8b.img", "url": "app-icon.js",  "evaluate": true  }
-  ]
+      {"name":"jbm8b.app.js","url":"app.js"},
+      {"name":"jbm8b.img","url":"app-icon.js","evaluate":true}
+    ]
   },
   {
     "id": "jbm8b_IT",
     "name": "Magic 8 Ball Italiano",
     "shortName": "Magic 8 Ball IT",
-    "icon": "app.png",
+    "version": "0.01",
     "description": "La palla predice il futuro",
+    "icon": "app.png",
     "tags": "game",
-    "version": "0.01",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
-      { "name": "jbm8b_IT.app.js", "url": "app.js" },
-      { "name": "jbm8b_IT.img", "url": "app-icon.js",  "evaluate": true  }
-  ]
-  },
-  { "id": "BLEcontroller",
-    "name": "BLE Customisable Controller with Joystick",
-    "shortName": "BLE Controller",
-    "icon": "BLEcontroller.png",
-    "version": "0.01",
-    "description": "A configurable controller for BLE devices and robots, with a basic four direction joystick. Designed to be easy to customise so you can add your own menus.",
-    "tags": "tool,bluetooth",
-    "readme": "README.md",
-    "allow_emulator":false,
-    "storage": [
-      { "name": "BLEcontroller.app.js", "url": "app.js" },
-      { "name": "BLEcontroller.img", "url": "app-icon.js", "evaluate": true }
+      {"name":"jbm8b_IT.app.js","url":"app.js"},
+      {"name":"jbm8b_IT.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widviz",
+  {
+    "id": "BLEcontroller",
+    "name": "BLE Customisable Controller with Joystick",
+    "shortName": "BLE Controller",
+    "version": "0.01",
+    "description": "A configurable controller for BLE devices and robots, with a basic four direction joystick. Designed to be easy to customise so you can add your own menus.",
+    "icon": "BLEcontroller.png",
+    "tags": "tool,bluetooth",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": false,
+    "storage": [
+      {"name":"BLEcontroller.app.js","url":"app.js"},
+      {"name":"BLEcontroller.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "widviz",
     "name": "Widget Visibility Widget",
-    "shortName":"Viz Widget",
-    "icon": "eye.png",
-    "version":"0.02",
+    "shortName": "Viz Widget",
+    "version": "0.02",
     "description": "Swipe left to hide top bar widgets, swipe right to redisplay.",
-    "tags": "widget",
+    "icon": "eye.png",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widviz.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "binclock",
+  {
+    "id": "binclock",
     "name": "Binary Clock",
-    "shortName":"Binary Clock",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Binary Clock",
+    "version": "0.03",
     "description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
-    "tags": "clock,binary",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock,binary",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"binclock.app.js","url":"app.js"},
       {"name":"binclock.img","url":"app-icon.js","evaluate":true}
@@ -2224,25 +2424,28 @@
   {
     "id": "pizzatimer",
     "name": "Pizza Timer",
-    "shortName":"Pizza Timer",
-    "icon": "pizza.png",
-    "version":"0.01",
+    "shortName": "Pizza Timer",
+    "version": "0.01",
     "description": "A timer app for when you cook Pizza. Some say it can also time other things",
+    "icon": "pizza.png",
     "tags": "timer,tool,pizza",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"pizzatimer.app.js","url":"app.js"},
       {"name":"pizzatimer.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "animclk",
+  {
+    "id": "animclk",
     "name": "Animated Clock",
-    "shortName":"Anim Clock",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Anim Clock",
+    "version": "0.03",
     "description": "An animated clock face using Mark Ferrari's amazing 8 bit game art and palette cycling: http://www.markferrari.com/art/8bit-game-art",
-    "tags": "clock,animated,bno2",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock,animated",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"animclk.app.js","url":"app.js"},
       {"name":"animclk.pixels1","url":"animclk.pixels1"},
@@ -2251,14 +2454,16 @@
       {"name":"animclk.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "analogimgclk",
+  {
+    "id": "analogimgclk",
     "name": "Analog Clock (Image background)",
-    "shortName":"Analog Clock",
-    "icon": "app.png",
-    "version":"0.03",
+    "shortName": "Analog Clock",
+    "version": "0.03",
     "description": "An analog clock with an image background",
-    "tags": "clock,bno2",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"analogimgclk.app.js","url":"app.js"},
       {"name":"analogimgclk.bg.img","url":"bg.img"},
@@ -2268,116 +2473,131 @@
   {
     "id": "verticalface",
     "name": "Vertical watch face",
-    "shortName":"Vertical Face",
-    "icon": "app.png",
-    "version":"0.09",
+    "shortName": "Vertical Face",
+    "version": "0.09",
     "description": "A simple vertical watch face with the date. Heart rate monitor is toggled with BTN1",
+    "icon": "app.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"verticalface.app.js","url":"app.js"},
       {"name":"verticalface.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "sleepphasealarm",
+  {
+    "id": "sleepphasealarm",
     "name": "SleepPhaseAlarm",
-    "shortName":"SleepPhaseAlarm",
-    "icon": "app.png",
-    "version":"0.02",
+    "shortName": "SleepPhaseAlarm",
+    "version": "0.02",
     "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",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"sleepphasealarm.app.js","url":"app.js"},
       {"name":"sleepphasealarm.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "life",
+  {
+    "id": "life",
     "name": "Game of Life",
-    "icon": "life.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "Conway's Game of Life - 16x16 board",
+    "icon": "life.png",
     "tags": "game",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"life.app.js","url":"life.min.js"},
       {"name":"life.img","url":"life-icon.js","evaluate":true}
     ]
   },
-   { "id": "magnav",
+  {
+    "id": "magnav",
     "name": "Navigation Compass",
-    "icon": "magnav.png",
-    "version":"0.04",
+    "version": "0.04",
     "description": "Compass with linear display as for GPSNAV. Has Tilt compensation and remembers calibration.",
-    "readme": "README.md",
+    "icon": "magnav.png",
     "tags": "tool,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"magnav.app.js","url":"magnav.min.js"},
       {"name":"magnav.img","url":"magnav-icon.js","evaluate":true}
     ],
-    "data":[{"name":"magnav.json"}]
+    "data": [{"name":"magnav.json"}]
   },
-  { "id": "gpspoilog",
+  {
+    "id": "gpspoilog",
     "name": "GPS POI Logger",
-    "shortName":"GPS POI Log",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "GPS POI Log",
+    "version": "0.01",
     "description": "A simple app to log points of interest with their GPS coordinates and read them back onto your PC. Based on the https://www.espruino.com/Bangle.js+Storage tutorial",
+    "icon": "app.png",
     "tags": "outdoors",
+    "supports": ["BANGLEJS"],
     "interface": "interface.html",
     "storage": [
       {"name":"gpspoilog.app.js","url":"app.js"},
       {"name":"gpspoilog.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "miclock2",
+  {
+    "id": "miclock2",
     "name": "Mixed Clock 2",
-    "icon": "clock-mixed.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "White color variant of the Mixed Clock with thicker clock hands for better readability in the bright sunlight, extra space under the clock for widgets and seconds in the digital clock.",
+    "icon": "clock-mixed.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
     "storage": [
       {"name":"miclock2.app.js","url":"clock-mixed.js"},
       {"name":"miclock2.img","url":"clock-mixed-icon.js","evaluate":true}
     ]
   },
-  { "id": "1button",
+  {
+    "id": "1button",
     "name": "One-Button-Tracker",
-    "icon": "widget.png",
-    "version":"0.01",
-    "interface": "interface.html",
+    "version": "0.01",
     "description": "A widget that turns BTN1 into a tracker, records time of button press/release.",
-    "tags": "tool,quantifiedself,widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "tool,quantifiedself,widget",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "interface": "interface.html",
     "storage": [
       {"name":"1button.wid.js","url":"widget.js"}
     ],
-    "data": [
-      {"name":"one_button_presses.csv","storageFile": true}
-    ]
+    "data": [{"name":"one_button_presses.csv","storageFile":true}]
   },
-  { "id": "gpsautotime",
+  {
+    "id": "gpsautotime",
     "name": "GPS auto time",
-    "shortName":"GPS auto time",
-    "icon": "widget.png",
-    "version":"0.01",
+    "shortName": "GPS auto time",
+    "version": "0.01",
     "description": "A widget that automatically updates the Bangle.js time to the GPS time whenever there is a valid GPS fix.",
-    "tags": "widget,gps",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "widget,gps",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"gpsautotime.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "espruinoctrl",
+  {
+    "id": "espruinoctrl",
     "name": "Espruino Control",
-    "shortName":"Espruino Ctrl",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "Espruino Ctrl",
+    "version": "0.01",
     "description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "custom": "custom.html",
     "storage": [
@@ -2385,15 +2605,17 @@
       {"name":"espruinoctrl.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "multiclock",
+  {
+    "id": "multiclock",
     "name": "Multi Clock",
-    "icon": "multiclock.png",
-    "version":"0.13",
+    "version": "0.13",
     "description": "Clock with multiple faces - Big, Analogue, Digital, Text, Time-Date.\n Switch between faces with BTN1 & BTN3",
-    "readme": "README.md",
+    "icon": "multiclock.png",
+    "type": "clock",
     "tags": "clock",
-    "type":"clock",
-    "allow_emulator":true,
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
     "storage": [
       {"name":"multiclock.app.js","url":"clock.js"},
       {"name":"big.face.js","url":"big.js"},
@@ -2405,152 +2627,157 @@
       {"name":"multiclock.img","url":"multiclock-icon.js","evaluate":true}
     ]
   },
-   { "id": "widancs",
+  {
+    "id": "widancs",
     "name": "Apple Notification Widget",
-    "shortName":"ANCS Widget",
-    "icon": "widget.png",
-    "version":"0.07",
+    "shortName": "ANCS Widget",
+    "version": "0.07",
     "description": "Displays call, message etc notifications from a paired iPhone. Read README before installation as it only works with compatible apps",
-    "readme": "README.md",
-    "tags": "widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "storage": [
       {"name":"widancs.wid.js","url":"ancs.min.js"},
       {"name":"widancs.settings.js","url":"settings.js"}
     ]
   },
-  { "id": "accelrec",
+  {
+    "id": "accelrec",
     "name": "Acceleration Recorder",
-    "shortName":"Accel Rec",
-    "icon": "app.png",
-    "version":"0.02",
-    "interface": "interface.html",
+    "shortName": "Accel Rec",
+    "version": "0.02",
     "description": "This app puts the Bangle's accelerometer into 100Hz mode and reads 2 seconds worth of data after movement starts. The data can then be exported back to the PC.",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "interface": "interface.html",
     "storage": [
       {"name":"accelrec.app.js","url":"app.js"},
       {"name":"accelrec.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {"wildcard":"accelrec.?.csv" }
-    ]
+    "data": [{"wildcard":"accelrec.?.csv"}]
   },
-  { "id": "accellog",
+  {
+    "id": "accellog",
     "name": "Acceleration Logger",
-    "shortName":"Accel Log",
-    "icon": "app.png",
-    "version":"0.03",
-    "interface": "interface.html",
+    "shortName": "Accel Log",
+    "version": "0.03",
     "description": "Logs XYZ acceleration data to a CSV file that can be downloaded to your PC",
-    "tags": "outdoor,b2",
+    "icon": "app.png",
+    "tags": "outdoor",
+    "supports": ["BANGLEJS","BANGLEJS2"],
     "readme": "README.md",
+    "interface": "interface.html",
     "storage": [
       {"name":"accellog.app.js","url":"app.js"},
       {"name":"accellog.img","url":"app-icon.js","evaluate":true}
     ],
-    "data": [
-      {"wildcard":"accellog.?.csv" }
-    ]
+    "data": [{"wildcard":"accellog.?.csv"}]
   },
   {
     "id": "cprassist",
-    "name":"CPR Assist",
-    "icon":"cprassist-icon.png",
+    "name": "CPR Assist",
     "version": "0.01",
-    "readme": "README.md",
     "description": "Provides assistance while performing a CPR",
+    "icon": "cprassist-icon.png",
     "tags": "tool,firstaid",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
     "allow_emulator": true,
     "storage": [
-      {
-        "name": "cprassist.app.js",
-        "url": "cprassist.js"
-      },
-      {
-        "name": "cprassist.img",
-        "url": "cprassist-icon.js",
-        "evaluate": true
-      },
-      {
-        "name": "cprassist.settings.js",
-        "url": "settings.js"
-      }
+      {"name":"cprassist.app.js","url":"cprassist.js"},
+      {"name":"cprassist.img","url":"cprassist-icon.js","evaluate":true},
+      {"name":"cprassist.settings.js","url":"settings.js"}
     ]
   },
-  { "id": "osgridref",
+  {
+    "id": "osgridref",
     "name": "Ordnance Survey Grid Reference",
-    "shortName":"OS Grid ref",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "OS Grid ref",
+    "version": "0.01",
     "description": "Displays the UK Ordnance Survey grid reference of your current GPS location. Useful when in the United Kingdom with an Ordnance Survey map",
+    "icon": "app.png",
     "tags": "outdoors,gps",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"osgridref.app.js","url":"app.js"},
       {"name":"osgridref.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "openseizure",
+  {
+    "id": "openseizure",
     "name": "OpenSeizureDetector Widget",
-    "shortName":"Short Name",
-    "icon": "widget.png",
-    "version":"0.01",
+    "shortName": "Short Name",
+    "version": "0.01",
     "description": "[BETA!] A widget to work alongside [OpenSeizureDetector](https://www.openseizuredetector.org.uk/)",
-    "tags": "widget",
+    "icon": "widget.png",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"openseizure.wid.js","url":"widget.js"}
     ]
   },
-  {"id": "counter",
-  "name": "Counter",
-  "icon": "counter_icon.png",
-  "version": "0.03",
-  "description": "Simple counter",
-  "tags": "tool",
-  "allow_emulator": true,
-  "storage": [
-    {"name": "counter.app.js", "url": "counter.js"},
-    {"name": "counter.img", "url": "counter-icon.js", "evaluate": true}
-   ]
+  {
+    "id": "counter",
+    "name": "Counter",
+    "version": "0.03",
+    "description": "Simple counter",
+    "icon": "counter_icon.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"counter.app.js","url":"counter.js"},
+      {"name":"counter.img","url":"counter-icon.js","evaluate":true}
+    ]
   },
-  { "id": "bootgattbat",
+  {
+    "id": "bootgattbat",
     "name": "BLE GATT Battery Service",
-    "shortName":"BLE Battery Service",
-    "icon": "bluetooth.png",
-    "version":"0.01",
+    "shortName": "BLE Battery Service",
+    "version": "0.01",
     "description": "Adds the GATT Battery Service to advertise the percentage of battery currently remaining over Bluetooth.\n",
-    "tags": "battery,ble,bluetooth,gatt",
+    "icon": "bluetooth.png",
     "type": "bootloader",
+    "tags": "battery,ble,bluetooth,gatt",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"gattbat.boot.js","url":"boot.js"}
     ]
   },
-  { "id": "viewstl",
-  "name": "STL file viewer",
-  "shortName":"ViewSTL",
-  "icon": "icons8-octahedron-48.png",
-  "version":"0.02",
-  "description": "This app allows you to view STL 3D models on your watch",
-  "tags": "tool",
-  "readme": "README.md",
-  "storage": [
-    {"name":"viewstl.app.js","url":"viewstl.min.js"},
-    {"name":"viewstl.img","url":"viewstl-icon.js","evaluate":true},
-    {"name":"tetra.stl","url":"tetra.stl"},
-    {"name":"cube.stl","url":"cube.stl"},
-    {"name":"icosa.stl","url":"icosa.stl"}
-   ]
+  {
+    "id": "viewstl",
+    "name": "STL file viewer",
+    "shortName": "ViewSTL",
+    "version": "0.02",
+    "description": "This app allows you to view STL 3D models on your watch",
+    "icon": "icons8-octahedron-48.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"viewstl.app.js","url":"viewstl.min.js"},
+      {"name":"viewstl.img","url":"viewstl-icon.js","evaluate":true},
+      {"name":"tetra.stl","url":"tetra.stl"},
+      {"name":"cube.stl","url":"cube.stl"},
+      {"name":"icosa.stl","url":"icosa.stl"}
+    ]
   },
-  { "id": "cscsensor",
+  {
+    "id": "cscsensor",
     "name": "Cycling speed sensor",
-    "shortName":"CSCSensor",
-    "icon": "icons8-cycling-48.png",
-    "version":"0.05",
+    "shortName": "CSCSensor",
+    "version": "0.05",
     "description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch",
+    "icon": "icons8-cycling-48.png",
     "tags": "outdoors,exercise,ble,bluetooth",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"cscsensor.app.js","url":"cscsensor.app.js"},
@@ -2558,70 +2785,78 @@
       {"name":"cscsensor.img","url":"cscsensor-icon.js","evaluate":true}
     ]
   },
-  { "id": "fileman",
+  {
+    "id": "fileman",
     "name": "File manager",
-    "shortName":"FileManager",
-    "icon": "icons8-filing-cabinet-48.png",
-    "version":"0.03",
+    "shortName": "FileManager",
+    "version": "0.03",
     "description": "Simple file manager, allows user to examine watch storage and display, load or delete individual files",
+    "icon": "icons8-filing-cabinet-48.png",
     "tags": "tools",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"fileman.app.js","url":"fileman.app.js"},
       {"name":"fileman.img","url":"fileman-icon.js","evaluate":true}
     ]
   },
- { "id": "worldclock",
+  {
+    "id": "worldclock",
     "name": "World Clock - 4 time zones",
-    "shortName":"World Clock",
-    "icon": "app.png",
-    "version":"0.04",
+    "shortName": "World Clock",
+    "version": "0.04",
     "description": "Current time zone plus up to four others",
+    "icon": "app.png",
+    "type": "clock",
     "tags": "clock",
-    "type" : "clock",
-    "custom": "custom.html",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
+    "custom": "custom.html",
     "storage": [
       {"name":"worldclock.app.js","url":"app.js"},
       {"name":"worldclock.img","url":"worldclock-icon.js","evaluate":true}
     ],
-    "data": [
-      {"name":"worldclock.settings.json"}
+    "data": [{"name":"worldclock.settings.json"}]
+  },
+  {
+    "id": "digiclock",
+    "name": "Digital Clock Face",
+    "shortName": "Digi Clock",
+    "version": "0.02",
+    "description": "A simple digital clock with the time, day, month, and year",
+    "icon": "digiclock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"digiclock.app.js","url":"digiclock.js"},
+      {"name":"digiclock.img","url":"digiclock-icon.js","evaluate":true}
     ]
- },
-{ "id": "digiclock",
-  "name": "Digital Clock Face",
-  "shortName":"Digi Clock",
-  "icon": "digiclock.png",
-  "version":"0.02",
-  "description": "A simple digital clock with the time, day, month, and year",
-  "tags": "clock,bno2",
-  "type" : "clock",
-  "storage": [
-    {"name":"digiclock.app.js","url":"digiclock.js"},
-    {"name":"digiclock.img","url":"digiclock-icon.js","evaluate":true}
- ]
-},
-  { "id": "dsdrelay",
+  },
+  {
+    "id": "dsdrelay",
     "name": "DSD BLE Relay controller",
-    "shortName":"DSDRelay",
-    "icon": "icons8-relay-48.png",
-    "version":"0.01",
+    "shortName": "DSDRelay",
+    "version": "0.01",
     "description": "Control BLE relay board from the watch",
+    "icon": "icons8-relay-48.png",
     "tags": "ble,bluetooth",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"dsdrelay.app.js","url":"dsdrelay.app.js"},
       {"name":"dsdrelay.img","url":"dsdrelay-icon.js","evaluate":true}
     ]
   },
-  { "id": "mandel",
+  {
+    "id": "mandel",
     "name": "Mandelbrot",
-    "shortName":"Mandel",
-    "icon": "mandel.png",
-    "version":"0.01",
+    "shortName": "Mandel",
+    "version": "0.01",
     "description": "Draw a zoomable Mandelbrot set",
+    "icon": "mandel.png",
     "tags": "game",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"mandel.app.js","url":"mandel.min.js"},
@@ -2631,997 +2866,1100 @@
   {
     "id": "petrock",
     "name": "Pet rock",
-    "icon": "petrock.png",
     "version": "0.02",
     "description": "A virtual pet rock with wobbly eyes",
-    "tags": "game",
+    "icon": "petrock.png",
     "type": "app",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
     "storage": [
-      {"name": "petrock.app.js", "url": "app.js"},
-      {"name": "petrock.img", "url": "app-icon.js", "evaluate": true}
+      {"name":"petrock.app.js","url":"app.js"},
+      {"name":"petrock.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "smartibot",
+  {
+    "id": "smartibot",
     "name": "Smartibot controller",
-    "shortName":"Smartibot",
-    "icon": "app.png",
-    "version":"0.01",
+    "shortName": "Smartibot",
+    "version": "0.01",
     "description": "Control a [Smartibot Robot](https://thecraftyrobot.net/) straight from your Bangle.js",
+    "icon": "app.png",
     "tags": "",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"smartibot.app.js","url":"app.js"},
       {"name":"smartibot.img","url":"app-icon.js","evaluate":true}
     ]
   },
-  { "id": "widncr",
+  {
+    "id": "widncr",
     "name": "NCR Logo Widget",
-    "icon": "widget.png",
-    "version":"0.01",
+    "version": "0.01",
     "description": "Show the NodeConf Remote logo in the top left",
+    "icon": "widget.png",
+    "type": "widget",
     "tags": "widget",
-    "type":"widget",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"widncr.wid.js","url":"widget.js"}
     ]
   },
-  { "id": "ncrclk",
+  {
+    "id": "ncrclk",
     "name": "NCR Clock",
-    "shortName":"NCR Clock",
-    "icon": "app.png",
-    "version":"0.02",
+    "shortName": "NCR Clock",
+    "version": "0.02",
     "description": "NodeConf Remote clock",
-    "tags": "clock",
+    "icon": "app.png",
     "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
     "storage": [
       {"name":"ncrclk.app.js","url":"app.js"},
       {"name":"ncrclk.img","url":"app-icon.js","evaluate":true}
     ]
   },
-{ "id": "isoclock",
-  "name": "ISO Compliant Clock Face",
-  "shortName":"ISO Clock",
-  "icon": "isoclock.png",
-  "version":"0.02",
-  "description": "Tweaked fork of digiclock for ISO date and time",
-  "tags": "clock",
-  "type" : "clock",
-  "storage": [
-    {"name":"isoclock.app.js","url":"isoclock.js"},
-    {"name":"isoclock.img","url":"isoclock-icon.js","evaluate":true}
- ]
-},
-{ "id": "gpstimeserver",
-  "name": "GPS Time Server",
-  "icon": "widget.png",
-  "version":"0.01",
-  "description": "A widget which automatically starts the GPS and turns Bangle.js into a Bluetooth time server.",
-  "tags": "widget",
-  "type": "widget",
-  "readme": "README.md",
-  "storage": [
-    {"name":"gpstimeserver.wid.js","url":"widget.js"}
-  ]
-},
-{ "id": "tilthydro",
-  "name": "Tilt Hydrometer Display",
-  "shortName":"Tilt Hydro",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "A display for the [Tilt Hydrometer](https://tilthydrometer.com/) - [more info here](http://www.espruino.com/Tilt+Hydrometer+Display)",
-  "tags": "tools,bluetooth",
-  "storage": [
-    {"name":"tilthydro.app.js","url":"app.js"},
-    {"name":"tilthydro.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "supmariodark",
-  "name": "Super mario clock night mode",
-  "shortName":"supmariodark",
-  "icon": "supmariodark.png",
-  "version":"0.01",
-  "description": "Super mario clock in night mode",
-  "tags": "clock",
-  "type" : "clock",
-  "storage": [
-    {"name":"supmariodark.app.js","url":"supmariodark.js"},
-    {"name":"supmariodark.img","url":"supmariodark-icon.js","evaluate":true},
-    {"name":"supmario30x24.bin","url":"supmario30x24.bin.js"},
-    {"name":"supmario30x24.wdt","url":"supmario30x24.wdt.js"},
-    {"name":"banner-up.img","url":"banner-up.js","evaluate":true},
-    {"name":"banner-down.img","url":"banner-down.js","evaluate":true},
-    {"name":"brick2.img","url":"brick2.js","evaluate":true},
-    {"name":"enemy.img","url":"enemy.js","evaluate":true},
-    {"name":"flower.img","url":"flower.js","evaluate":true},
-    {"name":"flower_b.img","url":"flower_b.js","evaluate":true},
-    {"name":"mario_wh.img","url":"mario_wh.js","evaluate":true},
-    {"name":"pipe.img","url":"pipe.js","evaluate":true}
-  ]
-},
-{ "id": "gmeter",
-  "name": "G-Meter",
-  "shortName":"G-Meter",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "Simple G-Meter",
-  "tags": "",
-  "storage": [
-    {"name":"gmeter.app.js","url":"app.js"},
-    {"name":"gmeter.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "dtlaunch",
-  "name": "Desktop Launcher",
-  "icon": "icon.png",
-  "version":"0.04",
-  "description": "Desktop style App Launcher with six apps per page - fast access if you have lots of apps installed.",
-  "readme": "README.md",
-  "tags": "tool,system,launcher",
-  "type":"launch",
-  "storage": [
-    {"name":"dtlaunch.app.js","url":"app.js"},
-    {"name":"dtlaunch.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "HRV",
-  "name": "Heart Rate Variability monitor",
-  "shortName":"HRV monitor",
-  "icon": "hrv.png",
-  "version":"0.04",
-  "description": "Heart Rate Variability monitor, see Readme for more info",
-  "tags": "",
-  "readme": "README.md",
-  "storage": [
-    {"name":"HRV.app.js","url":"app.js"},
-    {"name":"HRV.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "hardalarm",
-  "name": "Hard Alarm",
-  "shortName":"HardAlarm",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "Make sure you wake up! Count to the right number to turn off the alarm",
-  "tags": "tool,alarm,widget",
-  "storage": [
-    {"name":"hardalarm.app.js","url":"app.js"},
-    {"name":"hardalarm.boot.js","url":"boot.js"},
-    {"name":"hardalarm.js","url":"hardalarm.js"},
-    {"name":"hardalarm.img","url":"app-icon.js","evaluate":true},
-    {"name":"hardalarm.wid.js","url":"widget.js"}
-  ],
-  "data": [
-    {"name":"hardalarm.json"}
-  ]
-},
-{ "id": "edisonsball",
-  "name": "Edison's Ball",
-  "shortName":"Edison's Ball",
-  "icon": "app-icon.png",
-  "version":"0.01",
-  "description": "Hypnagogia/Micro-Sleep alarm for experimental use in exploring sleep transition and combating drowsiness",
-  "tags": "",
-  "readme": "README.md",
-  "storage": [
-    {"name":"edisonsball.app.js","url":"app.js"},
-    {"name":"edisonsball.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "hrrawexp",
-  "name": "HRM Data Exporter",
-  "shortName":"HRM Data Exporter",
-  "icon": "app-icon.png",
-  "version":"0.01",
-  "description": "export raw hrm signal data to a csv file",
-  "tags": "",
-  "readme": "README.md",
-  "interface": "interface.html",
-  "storage": [
-    {"name":"hrrawexp.app.js","url":"app.js"},
-    {"name":"hrrawexp.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "breath",
-  "name": "Breathing App",
-  "shortName":"Breathing App",
-  "icon": "app-icon.png",
-  "version":"0.01",
-  "description": "app to aid relaxation and train breath syncronicity using haptics and visualisation, also displays HR",
-  "tags": "tools,health",
-  "readme": "README.md",
-  "storage": [
-    {"name":"breath.app.js","url":"app.js"},
-    {"name":"breath.img","url":"app-icon.js","evaluate":true}
-  ],
-  "data": [
-    {"name":"breath.settings.json","url":"settings.json"}
-  ]
-},
-{ "id": "lazyclock",
-  "name": "Lazy Clock",
-  "icon": "lazyclock.png",
-  "version":"0.03",
-  "readme": "README.md",
-  "description": "Tells the time, roughly",
-  "tags": "clock",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"lazyclock.app.js","url":"lazyclock-app.js"},
-    {"name":"lazyclock.img","url":"lazyclock-icon.js","evaluate":true}
-  ]
-},
-{ "id": "astral",
-  "name": "Astral Clock",
-  "icon": "app-icon.png",
-  "version":"0.03",
-  "readme": "README.md",
-  "description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
-  "tags": "clock",
-  "type":"clock",
-  "storage": [
-    {"name":"astral.app.js","url":"app.js"},
-    {"name":"astral.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "alpinenav",
-  "name": "Alpine Nav",
-  "icon": "app-icon.png",
-  "version":"0.01",
-  "readme": "README.md",
-  "description": "App that performs GPS monitoring to track and display position relative to a given origin in realtime",
-  "tags": "outdoors,gps",
-  "storage": [
-    {"name":"alpinenav.app.js","url":"app.js"},
-    {"name":"alpinenav.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "lifeclk",
-  "name": "Game of Life Clock",
-  "shortName":"Conway's Clock",
-  "icon": "app.png",
-  "version":"0.06",
-  "description": "Modification and clockification of Conway's Game of Life",
-  "tags": "clock",
-  "type" : "clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"lifeclk.app.js","url":"app.min.js"},
-    {"name":"lifeclk.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "speedalt",
-  "name": "GPS Adventure Sports",
-  "shortName":"GPS Adv Sport",
-  "icon": "app.png",
-  "version":"1.02",
-  "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
-  "tags": "tool,outdoors",
-  "type":"app",
-  "allow_emulator":true,
-  "readme": "README.md",
-  "storage": [
-    {"name":"speedalt.app.js","url":"app.js"},
-    {"name":"speedalt.img","url":"app-icon.js","evaluate":true},
-    {"name":"speedalt.settings.js","url":"settings.js"}
-  ],
- "data": [
-      {"name":"speedalt.json"}
+  {
+    "id": "isoclock",
+    "name": "ISO Compliant Clock Face",
+    "shortName": "ISO Clock",
+    "version": "0.02",
+    "description": "Tweaked fork of digiclock for ISO date and time",
+    "icon": "isoclock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"isoclock.app.js","url":"isoclock.js"},
+      {"name":"isoclock.img","url":"isoclock-icon.js","evaluate":true}
     ]
-},
-{ "id": "de-stress",
-  "name": "De-Stress",
-  "shortName":"De-Stress",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "Simple haptic heartbeat",
-  "storage": [
-    {"name":"de-stress.app.js","url":"app.js"},
-    {"name":"de-stress.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "mclockplus",
-  "name": "Morph Clock+",
-  "shortName":"Morph Clock+",
-  "icon": "mclockplus.png",
-  "version":"0.02",
-  "description": "Morphing Clock with more readable seconds and date and additional stopwatch",
-  "tags": "clock",
-  "type": "clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"mclockplus.app.js","url":"mclockplus.app.js"},
-    {"name":"mclockplus.img","url":"mclockplus-icon.js","evaluate":true}
-  ]
-},
-{ "id": "intervals",
-  "name": "Intervals App",
-  "shortName":"Intervals",
-  "icon": "intervals.png",
-  "version":"0.01",
-  "description": "Intervals for training. It is possible to configure work time and rest time and number of sets.",
-  "tags": "",
-  "storage": [
-    {"name":"intervals.app.js","url":"intervals.app.js"},
-    {"name":"intervals.img","url":"intervals-icon.js","evaluate":true}
-  ]
-},
-{ "id": "planetarium",
-  "name": "Planetarium",
-  "shortName":"Planetarium",
-  "icon": "planetarium.png",
-  "readme": "README.md",
-  "version":"0.03",
-  "description": "Planetarium showing up to 500 stars using the watch location and time",
-  "tags": "",
-  "storage": [
-    {"name":"planetarium.app.js","url":"planetarium.app.js"},
-    {"name":"planetarium.data.csv","url":"planetarium.data.csv"},
-    {"name":"planetarium.const.csv","url":"planetarium.const.csv"},
-    {"name":"planetarium.extra.csv","url":"planetarium.extra.csv"},
-    {"name":"planetarium.settings.js","url":"settings.js"},
-    {"name":"planetarium.img","url":"planetarium-icon.js","evaluate":true}
-  ],
-  "data":[
-    {"name":"planetarium.json"}
-  ]
-},
-{ "id": "tapelauncher",
-  "name": "Tape Launcher",
-  "icon": "icon.png",
-  "version":"0.02",
-  "description": "An App launcher, icons displayed in a horizontal tape, swipe or use buttons",
-  "readme": "README.md",
-  "tags": "tool,system,launcher",
-  "type":"launch",
-  "storage": [
-    {"name":"tapelauncher.app.js","url":"app.js"},
-    {"name":"tapelauncher.img","url":"icon.js","evaluate":true}
-  ]
-},
-{ "id": "oblique",
-  "name": "Oblique Strategies",
-  "icon": "eno.png",
-  "version": "0.01",
-  "description": "Oblique Strategies for creativity. Copied from Brian Eno.",
-  "tags": "tool",
-  "storage": [
-    {"name":"oblique.app.js","url":"app.js"},
-    {"name":"oblique.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "testuserinput",
-  "name": "Test User Input",
-  "shortName":"Test User Input",
-  "icon": "app.png",
-  "version":"0.06",
-  "description": "App to test the bangle.js input interface. It displays the user action in text, circle buttons or on/off switch UI elements.",
-  "readme": "README.md",
-  "tags": "input,interface,buttons,touch,UI",
-  "storage": [
-    {"name":"testuserinput.app.js","url":"app.js"},
-    {"name":"testuserinput.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "gpssetup",
-  "name": "GPS Setup",
-  "shortName":"GPS Setup",
-  "icon": "gpssetup.png",
-  "version":"0.02",
-  "description": "Configure the GPS power options and store them in the GPS nvram",
-  "tags": "gps,tools,outdoors,bno2",
-  "readme": "README.md",
-  "storage": [
-    {"name":"gpssetup","url":"gpssetup.js"},
-    {"name":"gpssetup.settings.js","url":"settings.js"},
-    {"name":"gpssetup.app.js","url":"app.js"},
-    {"name":"gpssetup.img","url":"icon.js","evaluate":true}
-  ],
-  "data": [
-    {"name":"gpssetup.settings.json","url":"settings.json"}
-  ]
-},
-{ "id": "walkersclock",
-  "name": "Walkers Clock",
-  "shortName":"Walkers Clock",
-  "icon": "walkersclock48.png",
-  "version":"0.04",
-  "description": "A large font watch, displays steps, can switch GPS on/off, displays grid reference",
-  "type":"clock",
-  "tags": "clock, gps, tools, outdoors",
-  "readme": "README.md",
-  "storage": [
-    {"name":"walkersclock.app.js","url":"app.js"},
-    {"name":"walkersclock.img","url":"icon.js","evaluate":true}
-  ]
-},
-{ "id": "widgps",
-  "name": "GPS Widget",
-  "icon": "widget.png",
-  "version":"0.02",
-  "description": "Tiny widget to show the power on/off status of the GPS. Require firmware v2.08.167 or later",
-  "tags": "widget,gps",
-  "type":"widget",
-  "readme": "README.md",
-  "storage": [
-    {"name":"widgps.wid.js","url":"widget.js"}
-  ]
-},
-{ "id": "widhrt",
-  "name": "HRM Widget",
-  "icon": "widget.png",
-  "version":"0.02",
-  "description": "Tiny widget to show the power on/off status of the Heart Rate Monitor. Requires firmware v2.08.167 or later",
-  "tags": "widget, hrm",
-  "type":"widget",
-  "readme": "README.md",
-  "storage": [
-    {"name":"widhrt.wid.js","url":"widget.js"}
-  ]
-},
-{ "id": "countdowntimer",
-  "name" : "Countdown Timer",
-  "icon": "countdowntimer.png",
-  "version": "0.01",
-  "description": "A simple countdown timer with a focus on usability",
-  "tags": "timer, tool",
-  "readme": "README.md",
-  "storage": [
-    {"name": "countdowntimer.app.js", "url": "countdowntimer.js"},
-    {"name": "countdowntimer.img", "url": "countdowntimer-icon.js", "evaluate": true}
-  ]
-},
-{ "id": "helloworld",
-  "name": "hello, world!",
-  "shortName":"hello world",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "A cross cultural hello world!/hola mundo! app with colors and languages",
-  "readme": "README.md",
-  "tags": "input,interface,buttons,touch",
-  "storage": [
-    {"name":"helloworld.app.js","url":"app.js"},
-    {"name":"helloworld.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "widcom",
-  "name": "Compass Widget",
-  "icon": "widget.png",
-  "version":"0.01",
-  "description": "Tiny widget to show the power on/off status of the Compass. Requires firmware v2.08.167 or later",
-  "tags": "widget, compass",
-  "type":"widget",
-  "readme": "README.md",
-  "storage": [
-    {"name":"widcom.wid.js","url":"widget.js"}
-  ]
-},
-{ "id": "arrow",
-  "name": "Arrow Compass",
-  "icon": "arrow.png",
-  "type":"app",
-  "version":"0.04",
-  "description": "Moving arrow compass that points North, shows heading, with tilt correction. Based on jeffmer's Navigation Compass",
-  "tags": "tool,outdoors",
-  "readme": "README.md",
-  "storage": [
-    {"name":"arrow.app.js","url":"app.js"},
-    {"name":"arrow.img","url":"icon.js","evaluate":true}
-  ]
-},
-{ "id": "waypointer",
-  "name": "Way Pointer",
-  "icon": "waypointer.png",
-  "version":"0.01",
-  "description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
-  "tags": "tool,outdoors,gps",
-  "readme": "README.md",
-  "interface":"waypoints.html",
-  "storage": [
-    {"name":"waypointer.app.js","url":"app.js"},
-    {"name":"waypointer.img","url":"icon.js","evaluate":true}
-  ],
-  "data": [
-    {"name":"waypoints.json","url":"waypoints.json"}
-  ]
-},
-{ "id": "color_catalog",
-  "name": "Colors Catalog",
-  "shortName":"Colors Catalog",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
-  "readme": "README.md",
-  "tags": "Color,input,buttons,touch,UI,bno2",
-  "storage": [
-    {"name":"color_catalog.app.js","url":"app.js"},
-    {"name":"color_catalog.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "UI4swatch",
-  "name": "UI 4 swatch",
-  "shortName":"UI 4 swatch",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "A UI/UX for espruino smartwatches, displays dinamically calc. x,y coordinates.",
-  "readme": "README.md",
-  "tags": "Color, input,buttons,touch,UI",
-  "storage": [
-    {"name":"UI4swatch.app.js","url":"app.js"},
-    {"name":"UI4swatch.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "simplest",
-  "name": "Simplest Clock",
-  "icon": "simplest.png",
-  "version":"0.02",
-  "description": "The simplest working clock, acts as a tutorial piece",
-  "tags": "clock",
-  "type":"clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"simplest.app.js","url":"app.js"},
-    {"name":"simplest.img","url":"icon.js","evaluate":true}
-  ]
-},
-{ "id": "stepo",
-  "name": "Stepometer Clock",
-  "icon": "stepo.png",
-  "version":"0.03",
-  "description": "A large font watch, displays step count in a doughnut guage and warns of low battery, requires one of the steps widgets to be installed",
-  "tags": "clock",
-  "type":"clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"stepo.app.js","url":"app.js"},
-    {"name":"stepo.img","url":"icon.js","evaluate":true}
-  ]
-},
-{ "id": "gbmusic",
-  "name": "Gadgetbridge Music Controls",
-  "shortName":"Music Controls",
-  "icon": "icon.png",
-  "version":"0.05",
-  "description": "Control the music on your Gadgetbridge-connected phone",
-  "tags": "tools,bluetooth,gadgetbridge,music",
-  "type":"app",
-  "allow_emulator": false,
-  "readme": "README.md",
-  "storage": [
-    {"name":"gbmusic.app.js","url":"app.js"},
-    {"name":"gbmusic.settings.js","url":"settings.js"},
-    {"name":"gbmusic.wid.js","url":"widget.js"},
-    {"name":"gbmusic.img","url":"icon.js","evaluate":true}
-  ],
-  "data": [
-    {"name":"gbmusic.json"},
-    {"name":"gbmusic.load.json"}
-  ]
-},
-{
-  "id": "battleship",
-  "name":"Battleship",
-  "icon":"battleship-icon.png",
-  "version": "0.01",
-  "readme": "README.md",
-  "description": "The classic game of battleship",
-  "tags": "game",
-  "allow_emulator": true,
-  "storage": [
-    {
-      "name": "battleship.app.js",
-      "url": "battleship.js"
-    },
-    {
-      "name": "battleship.img",
-      "url": "battleship-icon.js",
-      "evaluate": true
-    }
-  ]
-},
-{ "id": "kitchen",
-  "name": "Kitchen Combo",
-  "icon": "kitchen.png",
-  "version":"0.13",
-  "description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later",
-  "tags": "tool,outdoors,gps",
-  "type":"clock",
-  "readme": "README.md",
-  "interface":"waypoints.html",
-  "storage": [
-    {"name":"kitchen.app.js","url":"kitchen.app.js"},
-    {"name":"stepo2.kit.js","url":"stepo2.kit.js"},
-    {"name":"swatch.kit.js","url":"swatch.kit.js"},
-    {"name":"gps.kit.js","url":"gps.kit.js"},
-    {"name":"compass.kit.js","url":"compass.kit.js"},
-    {"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
-  ],
-  "data": [
-      {"name":"waypoints.json","url":"waypoints.json"}
-  ]
-},
-{ "id": "banglebridge",
-    "name": "BangleBridge",
-    "shortName":"BangleBridge",
+  },
+  {
+    "id": "gpstimeserver",
+    "name": "GPS Time Server",
+    "version": "0.01",
+    "description": "A widget which automatically starts the GPS and turns Bangle.js into a Bluetooth time server.",
     "icon": "widget.png",
-    "version":"0.01",
-    "description": "Widget that allows Bangle Js to record pair and end data using Bluetooth Low Energy in combination with the BangleBridge Android App",
-    "tags": "widget",
     "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"gpstimeserver.wid.js","url":"widget.js"}
+    ]
+  },
+  {
+    "id": "tilthydro",
+    "name": "Tilt Hydrometer Display",
+    "shortName": "Tilt Hydro",
+    "version": "0.01",
+    "description": "A display for the [Tilt Hydrometer](https://tilthydrometer.com/) - [more info here](http://www.espruino.com/Tilt+Hydrometer+Display)",
+    "icon": "app.png",
+    "tags": "tools,bluetooth",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"tilthydro.app.js","url":"app.js"},
+      {"name":"tilthydro.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "supmariodark",
+    "name": "Super mario clock night mode",
+    "shortName": "supmariodark",
+    "version": "0.01",
+    "description": "Super mario clock in night mode",
+    "icon": "supmariodark.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"supmariodark.app.js","url":"supmariodark.js"},
+      {"name":"supmariodark.img","url":"supmariodark-icon.js","evaluate":true},
+      {"name":"supmario30x24.bin","url":"supmario30x24.bin.js"},
+      {"name":"supmario30x24.wdt","url":"supmario30x24.wdt.js"},
+      {"name":"banner-up.img","url":"banner-up.js","evaluate":true},
+      {"name":"banner-down.img","url":"banner-down.js","evaluate":true},
+      {"name":"brick2.img","url":"brick2.js","evaluate":true},
+      {"name":"enemy.img","url":"enemy.js","evaluate":true},
+      {"name":"flower.img","url":"flower.js","evaluate":true},
+      {"name":"flower_b.img","url":"flower_b.js","evaluate":true},
+      {"name":"mario_wh.img","url":"mario_wh.js","evaluate":true},
+      {"name":"pipe.img","url":"pipe.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "gmeter",
+    "name": "G-Meter",
+    "shortName": "G-Meter",
+    "version": "0.01",
+    "description": "Simple G-Meter",
+    "icon": "app.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"gmeter.app.js","url":"app.js"},
+      {"name":"gmeter.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "dtlaunch",
+    "name": "Desktop Launcher",
+    "version": "0.04",
+    "description": "Desktop style App Launcher with six apps per page - fast access if you have lots of apps installed.",
+    "icon": "icon.png",
+    "type": "launch",
+    "tags": "tool,system,launcher",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"dtlaunch.app.js","url":"app.js"},
+      {"name":"dtlaunch.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "HRV",
+    "name": "Heart Rate Variability monitor",
+    "shortName": "HRV monitor",
+    "version": "0.04",
+    "description": "Heart Rate Variability monitor, see Readme for more info",
+    "icon": "hrv.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"HRV.app.js","url":"app.js"},
+      {"name":"HRV.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "hardalarm",
+    "name": "Hard Alarm",
+    "shortName": "HardAlarm",
+    "version": "0.02",
+    "description": "Make sure you wake up! Count to the right number to turn off the alarm",
+    "icon": "app.png",
+    "tags": "tool,alarm,widget",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"hardalarm.app.js","url":"app.js"},
+      {"name":"hardalarm.boot.js","url":"boot.js"},
+      {"name":"hardalarm.js","url":"hardalarm.js"},
+      {"name":"hardalarm.img","url":"app-icon.js","evaluate":true},
+      {"name":"hardalarm.wid.js","url":"widget.js"}
+    ],
+    "data": [{"name":"hardalarm.json"}]
+  },
+  {
+    "id": "edisonsball",
+    "name": "Edison's Ball",
+    "shortName": "Edison's Ball",
+    "version": "0.01",
+    "description": "Hypnagogia/Micro-Sleep alarm for experimental use in exploring sleep transition and combating drowsiness",
+    "icon": "app-icon.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"edisonsball.app.js","url":"app.js"},
+      {"name":"edisonsball.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "hrrawexp",
+    "name": "HRM Data Exporter",
+    "shortName": "HRM Data Exporter",
+    "version": "0.01",
+    "description": "export raw hrm signal data to a csv file",
+    "icon": "app-icon.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "interface": "interface.html",
+    "storage": [
+      {"name":"hrrawexp.app.js","url":"app.js"},
+      {"name":"hrrawexp.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "breath",
+    "name": "Breathing App",
+    "shortName": "Breathing App",
+    "version": "0.01",
+    "description": "app to aid relaxation and train breath syncronicity using haptics and visualisation, also displays HR",
+    "icon": "app-icon.png",
+    "tags": "tools,health",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"breath.app.js","url":"app.js"},
+      {"name":"breath.img","url":"app-icon.js","evaluate":true}
+    ],
+    "data": [{"name":"breath.settings.json","url":"settings.json"}]
+  },
+  {
+    "id": "lazyclock",
+    "name": "Lazy Clock",
+    "version": "0.03",
+    "description": "Tells the time, roughly",
+    "icon": "lazyclock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"lazyclock.app.js","url":"lazyclock-app.js"},
+      {"name":"lazyclock.img","url":"lazyclock-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "astral",
+    "name": "Astral Clock",
+    "version": "0.03",
+    "description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
+    "icon": "app-icon.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"astral.app.js","url":"app.js"},
+      {"name":"astral.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "alpinenav",
+    "name": "Alpine Nav",
+    "version": "0.01",
+    "description": "App that performs GPS monitoring to track and display position relative to a given origin in realtime",
+    "icon": "app-icon.png",
+    "tags": "outdoors,gps",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"alpinenav.app.js","url":"app.js"},
+      {"name":"alpinenav.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "lifeclk",
+    "name": "Game of Life Clock",
+    "shortName": "Conway's Clock",
+    "version": "0.06",
+    "description": "Modification and clockification of Conway's Game of Life",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"lifeclk.app.js","url":"app.min.js"},
+      {"name":"lifeclk.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "speedalt",
+    "name": "GPS Adventure Sports",
+    "shortName": "GPS Adv Sport",
+    "version": "1.02",
+    "description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
+    "icon": "app.png",
+    "type": "app",
+    "tags": "tool,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"speedalt.app.js","url":"app.js"},
+      {"name":"speedalt.img","url":"app-icon.js","evaluate":true},
+      {"name":"speedalt.settings.js","url":"settings.js"}
+    ],
+    "data": [{"name":"speedalt.json"}]
+  },
+  {
+    "id": "de-stress",
+    "name": "De-Stress",
+    "shortName": "De-Stress",
+    "version": "0.02",
+    "description": "Simple haptic heartbeat",
+    "icon": "app.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"de-stress.app.js","url":"app.js"},
+      {"name":"de-stress.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "mclockplus",
+    "name": "Morph Clock+",
+    "shortName": "Morph Clock+",
+    "version": "0.02",
+    "description": "Morphing Clock with more readable seconds and date and additional stopwatch",
+    "icon": "mclockplus.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"mclockplus.app.js","url":"mclockplus.app.js"},
+      {"name":"mclockplus.img","url":"mclockplus-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "intervals",
+    "name": "Intervals App",
+    "shortName": "Intervals",
+    "version": "0.01",
+    "description": "Intervals for training. It is possible to configure work time and rest time and number of sets.",
+    "icon": "intervals.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"intervals.app.js","url":"intervals.app.js"},
+      {"name":"intervals.img","url":"intervals-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "planetarium",
+    "name": "Planetarium",
+    "shortName": "Planetarium",
+    "version": "0.03",
+    "description": "Planetarium showing up to 500 stars using the watch location and time",
+    "icon": "planetarium.png",
+    "tags": "",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"planetarium.app.js","url":"planetarium.app.js"},
+      {"name":"planetarium.data.csv","url":"planetarium.data.csv"},
+      {"name":"planetarium.const.csv","url":"planetarium.const.csv"},
+      {"name":"planetarium.extra.csv","url":"planetarium.extra.csv"},
+      {"name":"planetarium.settings.js","url":"settings.js"},
+      {"name":"planetarium.img","url":"planetarium-icon.js","evaluate":true}
+    ],
+    "data": [{"name":"planetarium.json"}]
+  },
+  {
+    "id": "tapelauncher",
+    "name": "Tape Launcher",
+    "version": "0.02",
+    "description": "An App launcher, icons displayed in a horizontal tape, swipe or use buttons",
+    "icon": "icon.png",
+    "type": "launch",
+    "tags": "tool,system,launcher",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"tapelauncher.app.js","url":"app.js"},
+      {"name":"tapelauncher.img","url":"icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "oblique",
+    "name": "Oblique Strategies",
+    "version": "0.01",
+    "description": "Oblique Strategies for creativity. Copied from Brian Eno.",
+    "icon": "eno.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"oblique.app.js","url":"app.js"},
+      {"name":"oblique.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "testuserinput",
+    "name": "Test User Input",
+    "shortName": "Test User Input",
+    "version": "0.06",
+    "description": "App to test the bangle.js input interface. It displays the user action in text, circle buttons or on/off switch UI elements.",
+    "icon": "app.png",
+    "tags": "input,interface,buttons,touch,UI",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"testuserinput.app.js","url":"app.js"},
+      {"name":"testuserinput.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "gpssetup",
+    "name": "GPS Setup",
+    "shortName": "GPS Setup",
+    "version": "0.02",
+    "description": "Configure the GPS power options and store them in the GPS nvram",
+    "icon": "gpssetup.png",
+    "tags": "gps,tools,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"gpssetup","url":"gpssetup.js"},
+      {"name":"gpssetup.settings.js","url":"settings.js"},
+      {"name":"gpssetup.app.js","url":"app.js"},
+      {"name":"gpssetup.img","url":"icon.js","evaluate":true}
+    ],
+    "data": [{"name":"gpssetup.settings.json","url":"settings.json"}]
+  },
+  {
+    "id": "walkersclock",
+    "name": "Walkers Clock",
+    "shortName": "Walkers Clock",
+    "version": "0.04",
+    "description": "A large font watch, displays steps, can switch GPS on/off, displays grid reference",
+    "icon": "walkersclock48.png",
+    "type": "clock",
+    "tags": "clock,gps,tools,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"walkersclock.app.js","url":"app.js"},
+      {"name":"walkersclock.img","url":"icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "widgps",
+    "name": "GPS Widget",
+    "version": "0.02",
+    "description": "Tiny widget to show the power on/off status of the GPS. Require firmware v2.08.167 or later",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,gps",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"widgps.wid.js","url":"widget.js"}
+    ]
+  },
+  {
+    "id": "widhrt",
+    "name": "HRM Widget",
+    "version": "0.02",
+    "description": "Tiny widget to show the power on/off status of the Heart Rate Monitor. Requires firmware v2.08.167 or later",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,hrm",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"widhrt.wid.js","url":"widget.js"}
+    ]
+  },
+  {
+    "id": "countdowntimer",
+    "name": "Countdown Timer",
+    "version": "0.01",
+    "description": "A simple countdown timer with a focus on usability",
+    "icon": "countdowntimer.png",
+    "tags": "timer,tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"countdowntimer.app.js","url":"countdowntimer.js"},
+      {"name":"countdowntimer.img","url":"countdowntimer-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "helloworld",
+    "name": "hello, world!",
+    "shortName": "hello world",
+    "version": "0.02",
+    "description": "A cross cultural hello world!/hola mundo! app with colors and languages",
+    "icon": "app.png",
+    "tags": "input,interface,buttons,touch",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"helloworld.app.js","url":"app.js"},
+      {"name":"helloworld.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "widcom",
+    "name": "Compass Widget",
+    "version": "0.01",
+    "description": "Tiny widget to show the power on/off status of the Compass. Requires firmware v2.08.167 or later",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget,compass",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"widcom.wid.js","url":"widget.js"}
+    ]
+  },
+  {
+    "id": "arrow",
+    "name": "Arrow Compass",
+    "version": "0.04",
+    "description": "Moving arrow compass that points North, shows heading, with tilt correction. Based on jeffmer's Navigation Compass",
+    "icon": "arrow.png",
+    "type": "app",
+    "tags": "tool,outdoors",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"arrow.app.js","url":"app.js"},
+      {"name":"arrow.img","url":"icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "waypointer",
+    "name": "Way Pointer",
+    "version": "0.01",
+    "description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
+    "icon": "waypointer.png",
+    "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "interface": "waypoints.html",
+    "storage": [
+      {"name":"waypointer.app.js","url":"app.js"},
+      {"name":"waypointer.img","url":"icon.js","evaluate":true}
+    ],
+    "data": [{"name":"waypoints.json","url":"waypoints.json"}]
+  },
+  {
+    "id": "color_catalog",
+    "name": "Colors Catalog",
+    "shortName": "Colors Catalog",
+    "version": "0.01",
+    "description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
+    "icon": "app.png",
+    "tags": "Color,input,buttons,touch,UI",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"color_catalog.app.js","url":"app.js"},
+      {"name":"color_catalog.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "UI4swatch",
+    "name": "UI 4 swatch",
+    "shortName": "UI 4 swatch",
+    "version": "0.01",
+    "description": "A UI/UX for espruino smartwatches, displays dinamically calc. x,y coordinates.",
+    "icon": "app.png",
+    "tags": "Color,input,buttons,touch,UI",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"UI4swatch.app.js","url":"app.js"},
+      {"name":"UI4swatch.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "simplest",
+    "name": "Simplest Clock",
+    "version": "0.02",
+    "description": "The simplest working clock, acts as a tutorial piece",
+    "icon": "simplest.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"simplest.app.js","url":"app.js"},
+      {"name":"simplest.img","url":"icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "stepo",
+    "name": "Stepometer Clock",
+    "version": "0.03",
+    "description": "A large font watch, displays step count in a doughnut guage and warns of low battery, requires one of the steps widgets to be installed",
+    "icon": "stepo.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"stepo.app.js","url":"app.js"},
+      {"name":"stepo.img","url":"icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "gbmusic",
+    "name": "Gadgetbridge Music Controls",
+    "shortName": "Music Controls",
+    "version": "0.05",
+    "description": "Control the music on your Gadgetbridge-connected phone",
+    "icon": "icon.png",
+    "type": "app",
+    "tags": "tools,bluetooth,gadgetbridge,music",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": false,
+    "storage": [
+      {"name":"gbmusic.app.js","url":"app.js"},
+      {"name":"gbmusic.settings.js","url":"settings.js"},
+      {"name":"gbmusic.wid.js","url":"widget.js"},
+      {"name":"gbmusic.img","url":"icon.js","evaluate":true}
+    ],
+    "data": [{"name":"gbmusic.json"},{"name":"gbmusic.load.json"}]
+  },
+  {
+    "id": "battleship",
+    "name": "Battleship",
+    "version": "0.01",
+    "description": "The classic game of battleship",
+    "icon": "battleship-icon.png",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"battleship.app.js","url":"battleship.js"},
+      {"name":"battleship.img","url":"battleship-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "kitchen",
+    "name": "Kitchen Combo",
+    "version": "0.13",
+    "description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later",
+    "icon": "kitchen.png",
+    "type": "clock",
+    "tags": "tool,outdoors,gps",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "interface": "waypoints.html",
+    "storage": [
+      {"name":"kitchen.app.js","url":"kitchen.app.js"},
+      {"name":"stepo2.kit.js","url":"stepo2.kit.js"},
+      {"name":"swatch.kit.js","url":"swatch.kit.js"},
+      {"name":"gps.kit.js","url":"gps.kit.js"},
+      {"name":"compass.kit.js","url":"compass.kit.js"},
+      {"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
+    ],
+    "data": [{"name":"waypoints.json","url":"waypoints.json"}]
+  },
+  {
+    "id": "banglebridge",
+    "name": "BangleBridge",
+    "shortName": "BangleBridge",
+    "version": "0.01",
+    "description": "Widget that allows Bangle Js to record pair and end data using Bluetooth Low Energy in combination with the BangleBridge Android App",
+    "icon": "widget.png",
+    "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
     "readme": "README.md",
     "storage": [
       {"name":"banglebridge.wid.js","url":"widget.js"},
-	    {"name":"banglebridge.watch.img","url":"watch.img"},
-	    {"name":"banglebridge.heart.img","url":"heart.img"}
+      {"name":"banglebridge.watch.img","url":"watch.img"},
+      {"name":"banglebridge.heart.img","url":"heart.img"}
     ]
- },
-{ "id": "qmsched",
-  "name": "Quiet Mode Schedule and Widget",
-  "shortName":"Quiet Mode",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "Automatically turn Quiet Mode on or off at set times",
-  "readme": "README.md",
-  "tags": "tool,widget",
-  "storage": [
-    {"name":"qmsched","url":"lib.js"},
-    {"name":"qmsched.app.js","url":"app.js"},
-    {"name":"qmsched.boot.js","url":"boot.js"},
-    {"name":"qmsched.img","url":"icon.js","evaluate":true},
-    {"name":"qmsched.wid.js","url":"widget.js"}
-  ],
-  "data": [
-    {"name":"qmsched.json"}
-  ]
-},
-{
-  "id": "hourstrike",
-  "name": "Hour Strike",
-  "shortName": "Hour Strike",
-  "icon": "app-icon.png",
-  "version": "0.08",
-  "description": "Strike the clock on the hour. A great tool to remind you an hour has passed!",
-  "tags": "tool,alarm",
-  "readme": "README.md",
-  "storage": [
-    {"name":"hourstrike.app.js","url":"app.js"},
-    {"name":"hourstrike.boot.js","url":"boot.js"},
-    {"name":"hourstrike.img","url":"app-icon.js","evaluate":true},
-    {"name":"hourstrike.json","url":"hourstrike.json"}
-  ]
-},
-{ "id": "whereworld",
-  "name": "Where in the World?",
-  "shortName" : "Where World",
-  "icon": "app.png",
-  "version": "0.01",
-  "description": "Shows your current location on the world map",
-  "tags": "gps",
-  "storage": [
-    {"name":"whereworld.app.js","url":"app.js"},
-    {"name":"whereworld.img","url":"app-icon.js","evaluate":true},
-    {"name":"whereworld.worldmap","url":"worldmap"}
-  ]
-},
-{
-  "id": "omnitrix",
-  "name":"Omnitrix",
-  "icon":"omnitrix.png",
-  "version": "0.01",
-  "readme": "README.md",
-  "description": "An Omnitrix Showpiece",
-  "tags": "game",
-  "storage": [
-    {"name":"omnitrix.app.js","url":"omnitrix.app.js"},
-    {"name":"omnitrix.img","url":"omnitrix.icon.js","evaluate":true}
-  ]
-},
-{ "id": "batclock",
-  "name": "Bat Clock",
-  "shortName":"Bat Clock",
-  "icon": "bat-clock.png",
-  "version":"0.02",
-  "description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
-  "tags": "clock",
-  "type": "clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"batclock.app.js","url":"bat-clock.app.js"},
-    {"name":"batclock.img","url":"bat-clock.icon.js","evaluate":true}
-  ]
-},
-{ "id":"doztime",
-  "name":"Dozenal Time",
-  "shortName":"Dozenal Time",
-  "icon":"app.png",
-  "version":"0.04",
-  "description":"A dozenal Holocene calendar and dozenal diurnal clock",
-  "tags":"clock",
-  "type":"clock",
-  "allow_emulator":true,
-  "readme": "README.md",
-  "storage": [
-    {"name":"doztime.app.js","url":"app.js"},
-    {"name":"doztime.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id":"gbtwist",
-  "name":"Gadgetbridge Twist Control",
-  "shortName":"Twist Control",
-  "icon":"app.png",
-  "version":"0.01",
-  "description":"Shake your wrist to control your music app via Gadgetbridge",
-  "tags":"tools,bluetooth,gadgetbridge,music",
-  "type":"app",
-  "allow_emulator":false,
-  "readme": "README.md",
-  "storage": [
-    {"name":"gbtwist.app.js","url":"app.js"},
-    {"name":"gbtwist.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "thermom",
-  "name": "Thermometer",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "Displays the current temperature, updated every 20 seconds",
-  "tags": "tool",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"thermom.app.js","url":"app.js"},
-    {"name":"thermom.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "mysticdock",
-  "name": "Mystic Dock",
-  "icon": "mystic-dock.png",
-  "version":"1.00",
-  "description": "A retro-inspired dockface that displays the current time and battery charge while plugged in, and which features an interactive mode that shows the time, date, and a rotating data display line.",
-  "tags": "dock",
-  "type":"dock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"mysticdock.app.js","url":"mystic-dock-app.js"},
-    {"name":"mysticdock.boot.js","url":"mystic-dock-boot.js"},
-    {"name":"mysticdock.settings.js","url":"mystic-dock-settings.js"},
-    {"name":"mysticdock.img","url":"mystic-dock-icon.js","evaluate":true}
-  ]
-},
-{ "id": "mysticclock",
-  "name": "Mystic Clock",
-  "icon": "mystic-clock.png",
-  "version":"1.01",
-  "description": "A retro-inspired watchface featuring time, date, and an interactive data display line.",
-  "tags": "clock",
-  "type":"clock",
-  "readme": "README.md",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"mysticclock.app.js","url":"mystic-clock-app.js"},
-    {"name":"mysticclock.settings.js","url":"mystic-clock-settings.js"},
-    {"name":"mysticclock.img","url":"mystic-clock-icon.js","evaluate":true}
-  ]
-},
-{ "id": "hcclock",
-  "name": "Hi-Contrast Clock",
-  "icon": "hcclock-icon.png",
-  "version":"0.01",
-  "description": "Hi-Contrast Clock : A simple yet very bold clock that aims to be readable in high luninosity environments. Uses big 10x5 pixel digits. Use BTN 1 to switch background and foreground colors.",
-  "tags": "clock",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"hcclock.app.js","url":"hcclock.app.js"},
-    {"name":"hcclock.img","url":"hcclock-icon.js","evaluate":true}
-  ]
-},
-{ "id": "thermomF",
-  "name": "Fahrenheit Temp",
-  "icon": "thermf.png",
-  "version":"0.01",
-  "description": "A modification of the Thermometer App to display temprature in Fahrenheit",
-  "tags": "tool",
-  "storage": [
-    {"name":"thermomF.app.js","url":"app.js"},
-    {"name":"thermomF.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "nixie",
-  "name": "Nixie Clock",
-  "shortName":"Nixie",
-  "icon": "nixie.png",
-  "version":"0.01",
-  "description": "A nixie tube clock for both Bangle 1 and 2.",
-  "tags": "clock",
-  "type":"clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"nixie.app.js","url":"app.js"},
-    {"name":"nixie.img","url":"app-icon.js","evaluate":true},
-    {"name":"m_vatch.js","url":"m_vatch.js"}
-  ]
-},
-{ "id": "carcrazy",
-  "name": "Car Crazy",
-  "shortName":"Car Crazy",
-  "icon": "carcrash.png",
-  "version":"0.03",
-  "description": "A simple car game where you try to avoid the other cars by tilting your wrist left and right. Hold down button 2 to start.",
-  "tags": "game",
-  "readme": "README.md",
-  "storage": [
-    {"name":"carcrazy.app.js","url":"app.js"},
-    {"name":"carcrazy.img","url":"app-icon.js","evaluate":true},
-    {"name":"carcrazy.settings.js","url":"settings.js"}
-  ],
-  "data": [
-    {"name":"app.json"}
-  ]
-},
-{ "id": "shortcuts",
-  "name": "Shortcuts",
-  "shortName":"Shortcuts",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "Quickly load your favourite apps from (almost) any watch face.",
-  "tags": "tool",
-  "type": "bootloader",
-  "readme": "README.md",
-  "storage": [
-    {"name":"shortcuts.boot.js","url":"boot.js"},
-    {"name":"shortcuts.settings.js","url":"settings.js"}
-  ],
-  "data": [
-    {"name":"shortcuts.json"}
-  ]
-},
-{ "id": "vectorclock",
-  "name": "Vector Clock",
-  "icon": "app.png",
-  "version": "0.02",
-  "description": "A digital clock that uses the built-in vector font.",
-  "tags": "clock",
-  "type": "clock",
-  "allow_emulator": true,
-  "storage": [
-    {"name":"vectorclock.app.js","url":"app.js"},
-    {"name":"vectorclock.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "fd6fdetect",
-  "name": "fd6fdetect",
-  "shortName":"fd6fdetect",
-  "icon": "app.png",
-  "version":"0.1",
-  "description": "Allows you to see 0xFD6F beacons near you.",
-  "tags": "tool",
-  "storage": [
-    {"name":"fd6fdetect.app.js","url":"app.js"},
-    {"name":"fd6fdetect.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "choozi",
-  "name": "Choozi",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "Choose people or things at random using Bangle.js.",
-  "tags": "tool",
-  "readme": "README.md",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"choozi.app.js","url":"app.js"},
-    {"name":"choozi.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "widclkbttm",
-  "name": "Digital clock (Bottom) widget",
-  "shortName":"Digital clock Bottom Widget",
-  "icon": "widclkbttm.png",
-  "version":"0.03",
-  "description": "Displays time in the bottom area.",
-  "readme": "README.md",
-  "tags": "widget",
-  "type": "widget",
-  "storage": [
-    {"name":"widclkbttm.wid.js","url":"widclkbttm.wid.js"}
-  ]
-},
-{ "id": "pastel",
-  "name": "Pastel Clock",
-  "shortName": "Pastel",
-  "icon": "pastel.png",
-  "version":"0.05",
-  "description": "A Configurable clock with custom fonts and background",
-  "tags": "clock,b2",
-  "type":"clock",
-  "readme": "README.md",
-  "storage": [
-    {"name":"pastel.app.js","url":"pastel.app.js"},
-    {"name":"pastel.img","url":"pastel.icon.js","evaluate":true},
-    {"name":"pastel.settings.js","url":"pastel.settings.js"}
-  ],
-  "data": [
-    {"name":"pastel.json"}
-  ]
-},
-{ "id": "antonclk",
-  "name": "Anton Clock",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "A simple clock using the bold Anton font.",
-  "tags":"clock,b2",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"antonclk.app.js","url":"app.js"},
-    {"name":"antonclk.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "waveclk",
-  "name": "Wave Clock",
-  "icon": "app.png",
-  "version":"0.02",
-  "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**",
-  "tags":"clock,b2",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"waveclk.app.js","url":"app.js"},
-    {"name":"waveclk.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "floralclk",
-  "name": "Floral Clock",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**",
-  "tags":"clock,b2",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"floralclk.app.js","url":"app.js"},
-    {"name":"floralclk.img","url":"app-icon.js","evaluate":true}
-  ]
-},
-{ "id": "score",
-  "name": "Score Tracker",
-  "icon": "score.app.png",
-  "version":"0.01",
-  "description": "Score Tracker for sports that use plain numbers (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...). Also supports tennis scoring.",
-  "readme": "README.md",
-  "tags": "b2",
-  "type": "app",
-  "storage": [
-    {"name":"score.app.js","url":"score.app.js"},
-    {"name":"score.settings.js","url":"score.settings.js"},
-    {"name":"score.presets.json","url":"score.presets.json"},
-    {"name":"score.img","url":"score.app-icon.js","evaluate":true}
-  ],
-  "data": [
-    {"name":"score.json"}
-  ]
-},
-{ "id": "menusmall",
-  "name": "Small Menus",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "Replace Bangle.js 2's menus with a version that contains smaller text",
-  "tags": "b2,bno1,system",
-  "type": "boot",
-  "storage": [
-    {"name":"menusmall.boot.js","url":"boot.js"}
-  ]
-},
-{ "id": "ffcniftya",
-  "name": "Nifty-A Clock",
-  "icon": "app.png",
-  "version":"0.01",
-  "description": "A nifty clock with time and date",
-  "tags":"clock,b2",
-  "type":"clock",
-  "allow_emulator":true,
-  "storage": [
-    {"name":"ffcniftya.app.js","url":"app.js"},
-    {"name":"ffcniftya.img","url":"app-icon.js","evaluate":true}
-  ]
-}
+  },
+  {
+    "id": "qmsched",
+    "name": "Quiet Mode Schedule and Widget",
+    "shortName": "Quiet Mode",
+    "version": "0.02",
+    "description": "Automatically turn Quiet Mode on or off at set times",
+    "icon": "app.png",
+    "tags": "tool,widget",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"qmsched","url":"lib.js"},
+      {"name":"qmsched.app.js","url":"app.js"},
+      {"name":"qmsched.boot.js","url":"boot.js"},
+      {"name":"qmsched.img","url":"icon.js","evaluate":true},
+      {"name":"qmsched.wid.js","url":"widget.js"}
+    ],
+    "data": [{"name":"qmsched.json"}]
+  },
+  {
+    "id": "hourstrike",
+    "name": "Hour Strike",
+    "shortName": "Hour Strike",
+    "version": "0.08",
+    "description": "Strike the clock on the hour. A great tool to remind you an hour has passed!",
+    "icon": "app-icon.png",
+    "tags": "tool,alarm",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"hourstrike.app.js","url":"app.js"},
+      {"name":"hourstrike.boot.js","url":"boot.js"},
+      {"name":"hourstrike.img","url":"app-icon.js","evaluate":true},
+      {"name":"hourstrike.json","url":"hourstrike.json"}
+    ]
+  },
+  {
+    "id": "whereworld",
+    "name": "Where in the World?",
+    "shortName": "Where World",
+    "version": "0.01",
+    "description": "Shows your current location on the world map",
+    "icon": "app.png",
+    "tags": "gps",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"whereworld.app.js","url":"app.js"},
+      {"name":"whereworld.img","url":"app-icon.js","evaluate":true},
+      {"name":"whereworld.worldmap","url":"worldmap"}
+    ]
+  },
+  {
+    "id": "omnitrix",
+    "name": "Omnitrix",
+    "version": "0.01",
+    "description": "An Omnitrix Showpiece",
+    "icon": "omnitrix.png",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"omnitrix.app.js","url":"omnitrix.app.js"},
+      {"name":"omnitrix.img","url":"omnitrix.icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "batclock",
+    "name": "Bat Clock",
+    "shortName": "Bat Clock",
+    "version": "0.02",
+    "description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
+    "icon": "bat-clock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"batclock.app.js","url":"bat-clock.app.js"},
+      {"name":"batclock.img","url":"bat-clock.icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "doztime",
+    "name": "Dozenal Time",
+    "shortName": "Dozenal Time",
+    "version": "0.04",
+    "description": "A dozenal Holocene calendar and dozenal diurnal clock",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"doztime.app.js","url":"app.js"},
+      {"name":"doztime.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "gbtwist",
+    "name": "Gadgetbridge Twist Control",
+    "shortName": "Twist Control",
+    "version": "0.01",
+    "description": "Shake your wrist to control your music app via Gadgetbridge",
+    "icon": "app.png",
+    "type": "app",
+    "tags": "tools,bluetooth,gadgetbridge,music",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": false,
+    "storage": [
+      {"name":"gbtwist.app.js","url":"app.js"},
+      {"name":"gbtwist.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "thermom",
+    "name": "Thermometer",
+    "version": "0.02",
+    "description": "Displays the current temperature, updated every 20 seconds",
+    "icon": "app.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"thermom.app.js","url":"app.js"},
+      {"name":"thermom.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "mysticdock",
+    "name": "Mystic Dock",
+    "version": "1.00",
+    "description": "A retro-inspired dockface that displays the current time and battery charge while plugged in, and which features an interactive mode that shows the time, date, and a rotating data display line.",
+    "icon": "mystic-dock.png",
+    "type": "dock",
+    "tags": "dock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"mysticdock.app.js","url":"mystic-dock-app.js"},
+      {"name":"mysticdock.boot.js","url":"mystic-dock-boot.js"},
+      {"name":"mysticdock.settings.js","url":"mystic-dock-settings.js"},
+      {"name":"mysticdock.img","url":"mystic-dock-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "mysticclock",
+    "name": "Mystic Clock",
+    "version": "1.01",
+    "description": "A retro-inspired watchface featuring time, date, and an interactive data display line.",
+    "icon": "mystic-clock.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"mysticclock.app.js","url":"mystic-clock-app.js"},
+      {"name":"mysticclock.settings.js","url":"mystic-clock-settings.js"},
+      {"name":"mysticclock.img","url":"mystic-clock-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "hcclock",
+    "name": "Hi-Contrast Clock",
+    "version": "0.01",
+    "description": "Hi-Contrast Clock : A simple yet very bold clock that aims to be readable in high luninosity environments. Uses big 10x5 pixel digits. Use BTN 1 to switch background and foreground colors.",
+    "icon": "hcclock-icon.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"hcclock.app.js","url":"hcclock.app.js"},
+      {"name":"hcclock.img","url":"hcclock-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "thermomF",
+    "name": "Fahrenheit Temp",
+    "version": "0.01",
+    "description": "A modification of the Thermometer App to display temprature in Fahrenheit",
+    "icon": "thermf.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"thermomF.app.js","url":"app.js"},
+      {"name":"thermomF.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "nixie",
+    "name": "Nixie Clock",
+    "shortName": "Nixie",
+    "version": "0.01",
+    "description": "A nixie tube clock for both Bangle 1 and 2.",
+    "icon": "nixie.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"nixie.app.js","url":"app.js"},
+      {"name":"nixie.img","url":"app-icon.js","evaluate":true},
+      {"name":"m_vatch.js","url":"m_vatch.js"}
+    ]
+  },
+  {
+    "id": "carcrazy",
+    "name": "Car Crazy",
+    "shortName": "Car Crazy",
+    "version": "0.03",
+    "description": "A simple car game where you try to avoid the other cars by tilting your wrist left and right. Hold down button 2 to start.",
+    "icon": "carcrash.png",
+    "tags": "game",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"carcrazy.app.js","url":"app.js"},
+      {"name":"carcrazy.img","url":"app-icon.js","evaluate":true},
+      {"name":"carcrazy.settings.js","url":"settings.js"}
+    ],
+    "data": [{"name":"app.json"}]
+  },
+  {
+    "id": "shortcuts",
+    "name": "Shortcuts",
+    "shortName": "Shortcuts",
+    "version": "0.01",
+    "description": "Quickly load your favourite apps from (almost) any watch face.",
+    "icon": "app.png",
+    "type": "bootloader",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"shortcuts.boot.js","url":"boot.js"},
+      {"name":"shortcuts.settings.js","url":"settings.js"}
+    ],
+    "data": [{"name":"shortcuts.json"}]
+  },
+  {
+    "id": "vectorclock",
+    "name": "Vector Clock",
+    "version": "0.02",
+    "description": "A digital clock that uses the built-in vector font.",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"vectorclock.app.js","url":"app.js"},
+      {"name":"vectorclock.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "fd6fdetect",
+    "name": "fd6fdetect",
+    "shortName": "fd6fdetect",
+    "version": "0.1",
+    "description": "Allows you to see 0xFD6F beacons near you.",
+    "icon": "app.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "storage": [
+      {"name":"fd6fdetect.app.js","url":"app.js"},
+      {"name":"fd6fdetect.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "choozi",
+    "name": "Choozi",
+    "version": "0.01",
+    "description": "Choose people or things at random using Bangle.js.",
+    "icon": "app.png",
+    "tags": "tool",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "allow_emulator": true,
+    "storage": [
+      {"name":"choozi.app.js","url":"app.js"},
+      {"name":"choozi.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "widclkbttm",
+    "name": "Digital clock (Bottom) widget",
+    "shortName": "Digital clock Bottom Widget",
+    "version": "0.03",
+    "description": "Displays time in the bottom area.",
+    "icon": "widclkbttm.png",
+    "type": "widget",
+    "tags": "widget",
+    "supports": ["BANGLEJS"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"widclkbttm.wid.js","url":"widclkbttm.wid.js"}
+    ]
+  },
+  {
+    "id": "pastel",
+    "name": "Pastel Clock",
+    "shortName": "Pastel",
+    "version": "0.05",
+    "description": "A Configurable clock with custom fonts and background",
+    "icon": "pastel.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"pastel.app.js","url":"pastel.app.js"},
+      {"name":"pastel.img","url":"pastel.icon.js","evaluate":true},
+      {"name":"pastel.settings.js","url":"pastel.settings.js"}
+    ],
+    "data": [{"name":"pastel.json"}]
+  },
+  {
+    "id": "antonclk",
+    "name": "Anton Clock",
+    "version": "0.02",
+    "description": "A simple clock using the bold Anton font.",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"antonclk.app.js","url":"app.js"},
+      {"name":"antonclk.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "waveclk",
+    "name": "Wave Clock",
+    "version": "0.02",
+    "description": "A clock using a wave image by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"waveclk.app.js","url":"app.js"},
+      {"name":"waveclk.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "floralclk",
+    "name": "Floral Clock",
+    "version": "0.01",
+    "description": "A clock with a flower background by [Lillith May](https://www.instagram.com/_lilustrations_/). **Note: This requires firmware 2v11 or later Bangle.js 1**",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"floralclk.app.js","url":"app.js"},
+      {"name":"floralclk.img","url":"app-icon.js","evaluate":true}
+    ]
+  },
+  {
+    "id": "score",
+    "name": "Score Tracker",
+    "version": "0.01",
+    "description": "Score Tracker for sports that use plain numbers (e.g. Badminton, Volleyball, Soccer, Table Tennis, ...). Also supports tennis scoring.",
+    "icon": "score.app.png",
+    "type": "app",
+    "tags": "",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "readme": "README.md",
+    "storage": [
+      {"name":"score.app.js","url":"score.app.js"},
+      {"name":"score.settings.js","url":"score.settings.js"},
+      {"name":"score.presets.json","url":"score.presets.json"},
+      {"name":"score.img","url":"score.app-icon.js","evaluate":true}
+    ],
+    "data": [{"name":"score.json"}]
+  },
+  {
+    "id": "menusmall",
+    "name": "Small Menus",
+    "version": "0.01",
+    "description": "Replace Bangle.js 2's menus with a version that contains smaller text",
+    "icon": "app.png",
+    "type": "boot",
+    "tags": "system",
+    "supports": ["BANGLEJS2"],
+    "storage": [
+      {"name":"menusmall.boot.js","url":"boot.js"}
+    ]
+  },
+  {
+    "id": "ffcniftya",
+    "name": "Nifty-A Clock",
+    "version": "0.01",
+    "description": "A nifty clock with time and date",
+    "icon": "app.png",
+    "type": "clock",
+    "tags": "clock",
+    "supports": ["BANGLEJS","BANGLEJS2"],
+    "allow_emulator": true,
+    "storage": [
+      {"name":"ffcniftya.app.js","url":"app.js"},
+      {"name":"ffcniftya.img","url":"app-icon.js","evaluate":true}
+    ]
+  }
 ]
diff --git a/apps/_example_app/add_to_apps.json b/apps/_example_app/add_to_apps.json
index 1585ab73d..cc28e1e93 100644
--- a/apps/_example_app/add_to_apps.json
+++ b/apps/_example_app/add_to_apps.json
@@ -2,13 +2,14 @@
 { "id": "7chname",
   "name": "My app's human readable name",
   "shortName":"Short Name",
-  "icon": "app.png",
   "version":"0.01",
   "description": "A detailed description of my great app",
+  "icon": "app.png",
   "tags": "",
+  "supports" : ["BANGLEJS2"],  
   "readme": "README.md",
   "storage": [
     {"name":"7chname.app.js","url":"app.js"},
     {"name":"7chname.img","url":"app-icon.js","evaluate":true}
   ]
-}
\ No newline at end of file
+}
diff --git a/apps/_example_widget/add_to_apps.json b/apps/_example_widget/add_to_apps.json
index 527c698a0..b55adce9d 100644
--- a/apps/_example_widget/add_to_apps.json
+++ b/apps/_example_widget/add_to_apps.json
@@ -2,11 +2,12 @@
 { "id": "7chname",
   "name": "My widget's human readable name",
   "shortName":"Short Name",
-  "icon": "widget.png",
   "version":"0.01",
   "description": "A detailed description of my great widget",
-  "tags": "widget",
+  "icon": "widget.png",  
   "type": "widget",
+  "tags": "widget",
+  "supports" : ["BANGLEJS2"],
   "readme": "README.md",
   "storage": [
     {"name":"7chname.wid.js","url":"widget.js"}
diff --git a/bin/create_app_supports_field.js b/bin/create_app_supports_field.js
new file mode 100644
index 000000000..6908591a5
--- /dev/null
+++ b/bin/create_app_supports_field.js
@@ -0,0 +1,83 @@
+#!/usr/bin/nodejs
+/* Quick hack to add proper 'supports' field to apps.json
+*/
+
+var fs = require("fs");
+
+var BASEDIR = __dirname+"/../";
+
+var appsFile, apps;
+try {
+  appsFile = fs.readFileSync(BASEDIR+"apps.json").toString();
+} catch (e) {
+  ERROR("apps.json not found");
+}
+try{
+  apps = JSON.parse(appsFile);
+} catch (e) {
+  console.log(e);
+  var m = e.toString().match(/in JSON at position (\d+)/);
+  if (m) {
+    var char = parseInt(m[1]);
+    console.log("===============================================");
+    console.log("LINE "+appsFile.substr(0,char).split("\n").length);
+    console.log("===============================================");
+    console.log(appsFile.substr(char-10, 20));
+    console.log("===============================================");
+  }
+  console.log(m);
+  ERROR("apps.json not valid JSON");
+
+}
+
+apps = apps.map((app,appIdx) => {
+  var tags = [];
+  if (app.tags) tags = app.tags.split(",").map(t=>t.trim());
+  var supportsB1 = true;
+  var supportsB2 = false;
+  if (tags.includes("b2")) {
+    tags = tags.filter(x=>x!="b2");
+    supportsB2 = true;
+  }
+  if (tags.includes("bno2")) {
+    tags = tags.filter(x=>x!="bno2");
+    supportsB2 = false;
+  }
+  if (tags.includes("bno1")) {
+    tags = tags.filter(x=>x!="bno1");
+    supportsB1 = false;
+  }
+  app.tags = tags.join(",");
+  app.supports = [];
+  if (supportsB1) app.supports.push("BANGLEJS");
+  if (supportsB2) app.supports.push("BANGLEJS2");
+  return app;
+});
+
+var KEY_ORDER = [
+  "id","name","shortName","version","description","icon","type","tags","supports",
+  "dependencies", "readme", "custom", "customConnect", "interface",
+  "allow_emulator", "storage", "data", "sortorder"
+];
+
+var JS = JSON.stringify;
+var json = "[\n  "+apps.map(app=>{
+  var keys = KEY_ORDER.filter(k=>k in app);
+  Object.keys(app).forEach(k=>{
+    if (!KEY_ORDER.includes(k))
+      throw new Error(`Key named ${k} not known!`);
+  });
+
+
+  return "{\n    "+keys.map(k=>{
+    var js = JS(app[k]);
+    if (k=="storage")
+      js = "[\n      "+app.storage.map(s=>JS(s)).join(",\n      ")+"\n    ]";
+    return JS(k)+": "+js;
+  }).join(",\n    ")+"\n  }";
+}).join(",\n  ")+"\n]\n";
+
+//console.log(json);
+
+console.log("new apps.json written");
+fs.writeFileSync(BASEDIR+"apps.json", json);
diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js
index b98aa9ef3..dbce9c855 100755
--- a/bin/sanitycheck.js
+++ b/bin/sanitycheck.js
@@ -51,7 +51,8 @@ try{
 
 const APP_KEYS = [
   'id', 'name', 'shortName', 'version', 'icon', 'description', 'tags', 'type',
-  'sortorder', 'readme', 'custom', 'customConnect', 'interface', 'storage', 'data', 'allow_emulator',
+  'sortorder', 'readme', 'custom', 'customConnect', 'interface', 'storage', 'data',
+  'supports', 'allow_emulator', 
   'dependencies'
 ];
 const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite'];
@@ -81,6 +82,14 @@ apps.forEach((app,appIdx) => {
   if (!app.name) ERROR(`App ${app.id} has no name`);
   var isApp = !app.type || app.type=="app";
   if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`);
+  if (!Array.isArray(app.supports)) ERROR(`App ${app.id} has no 'supports' field or it's not an array`);
+  else {
+    app.supports.forEach(dev => {
+      if (!["BANGLEJS","BANGLEJS2"].includes(dev))
+        ERROR(`App ${app.id} has unknown device in 'supports' field - ${dev}`);
+    });
+  }
+
   if (!app.version) WARN(`App ${app.id} has no version`);
   else {
     if (!fs.existsSync(appDir+"ChangeLog")) {

From d1935c3860aecd5de7c7e2b6e11b1fe4d5919b0a Mon Sep 17 00:00:00 2001
From: Gordon Williams 
Date: Wed, 20 Oct 2021 15:20:25 +0100
Subject: [PATCH 4/6] Add filtering for Bangle.js 1 and 2

---
 core         |   2 +-
 css/main.css |   3 ++
 index.html   |  11 +++++
 loader.js    | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/core b/core
index 0fd608f08..bc5b1284f 160000
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit 0fd608f085deff9b39f2db3559ecc88edb232aba
+Subproject commit bc5b1284f41b0fcfdd264e1e2f12872e0b18c479
diff --git a/css/main.css b/css/main.css
index 0dbe8da14..90b4ff280 100644
--- a/css/main.css
+++ b/css/main.css
@@ -23,6 +23,9 @@
 .filter-nav {
   display: inline-block;
 }
+.device-nav {
+  display: inline-block;
+}
 .sort-nav {
   float: right;
 }
diff --git a/index.html b/index.html
index a5ae7bff0..0185f1bae 100644
--- a/index.html
+++ b/index.html
@@ -60,6 +60,17 @@
 
     
+
diff --git a/loader.js b/loader.js index 6528ffc98..90c1c5d96 100644 --- a/loader.js +++ b/loader.js @@ -14,6 +14,10 @@ if (window.location.host=="banglejs.com") { var RECOMMENDED_VERSION = "2v10"; // could check http://www.espruino.com/json/BANGLEJS.json for this +// We're only interested in Bangles +DEVICEINFO = DEVICEINFO.filter(x=>x.id.startsWith("BANGLEJS")); + +// Set up source code URL (function() { let username = "espruino"; let githubMatch = window.location.href.match(/\/(\w+)\.github\.io/); @@ -21,6 +25,7 @@ var RECOMMENDED_VERSION = "2v10"; Const.APP_SOURCECODE_URL = `https://github.com/${username}/BangleApps/tree/master/apps`; })(); +// When a device is found, filter the apps accordingly function onFoundDeviceInfo(deviceId, deviceVersion) { if (deviceId != "BANGLEJS" && deviceId != "BANGLEJS2") { showToast(`You're using ${deviceId}, not a Bangle.js. Did you want espruino.com/apps instead?` ,"warning", 20000); @@ -33,4 +38,110 @@ function onFoundDeviceInfo(deviceId, deviceVersion) { if (deviceId == "BANGLEJS2") { Const.MESSAGE_RELOAD = 'Hold button\nto reload'; } + + // check against features shown? + filterAppsForDevice(deviceId); + /* if we'd saved a device ID but this device is different, ensure + we ask again next time */ + var savedDeviceId = getSavedDeviceId(); + if (savedDeviceId!==undefined && savedDeviceId!=deviceId) + setSavedDeviceId(undefined); } + +var originalAppJSON = undefined; +function filterAppsForDevice(deviceId) { + if (originalAppJSON===undefined) + originalAppJSON = appJSON; + + var device = DEVICEINFO.find(d=>d.id==deviceId); + // set the device dropdown + document.querySelector(".devicetype-nav span").innerText = device ? device.name : "All apps"; + + if (!device) { + if (deviceId!==undefined) + showToast(`Device ID ${deviceId} not recognised. Some apps may not work`, "warning"); + appJSON = originalAppJSON; + } else { + // Now filter apps + appJSON = originalAppJSON.filter(app => { + var supported = ["BANGLEJS"]; + if (!app.supports) { + console.log(`App ${app.id} doesn't include a 'supports' field - ignoring`); + return false; + } + if (app.supports.includes(deviceId)) return true; + //console.log(`Dropping ${app.id} because ${deviceId} is not in supported list ${app.supports.join(",")}`); + return false; + }); + } + refreshLibrary(); +} + +// If 'remember' was checked in the window below, this is the device +function getSavedDeviceId() { + let deviceId = localStorage.getItem("deviceId"); + if (("string"==typeof deviceId) && DEVICEINFO.find(d=>d.id == deviceId)) + return deviceId; + return undefined; +} + +function setSavedDeviceId(deviceId) { + localStorage.setItem("deviceId", deviceId); +} + +// At boot, show a window to choose which type of device you have... +window.addEventListener('load', (event) => { + let deviceId = getSavedDeviceId() + if (deviceId !== undefined) + return filterAppsForDevice(deviceId); + + var html = `
+ ${DEVICEINFO.map(d=>` +
+
+
+
${d.name}
+ +
+
+ ${d.name} +
+
+
`).join("\n")} +
+
+
+ +
+
+
`; + showPrompt("Which Bangle.js?",html,{},false); + htmlToArray(document.querySelectorAll(".devicechooser")).forEach(button => { + button.addEventListener("click",event => { + let rememberDevice = document.getElementById("remember_device").checked; + + let button = event.currentTarget; + let deviceId = button.getAttribute("deviceid"); + hidePrompt(); + console.log("Chosen device", deviceId); + setSavedDeviceId(rememberDevice ? deviceId : undefined); + filterAppsForDevice(deviceId); + }); + }); +}); + +// Hook onto device chooser dropdown +window.addEventListener('load', (event) => { + htmlToArray(document.querySelectorAll(".devicetype-nav .menu-item")).forEach(button => { + button.addEventListener("click", event => { + var a = event.target; + var deviceId = a.getAttribute("dt")||undefined; + filterAppsForDevice(deviceId); // also sets the device dropdown + setSavedDeviceId(undefined); // ask at startup next time + document.querySelector(".devicetype-nav span").innerText = a.innerText; + }); + }); +}); From fc3ce860091b89230b507d1eb070864fec0a58cb Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 20 Oct 2021 20:28:28 +0100 Subject: [PATCH 5/6] misc tweaks for layout/gps time/bootloader --- apps.json | 6 +-- apps/boot/ChangeLog | 3 ++ apps/boot/bootupdate.js | 5 +- apps/gpstime/ChangeLog | 3 +- apps/gpstime/gpstime.js | 117 +++++++++++++++++++++------------------- modules/Layout.js | 23 ++++---- 6 files changed, 86 insertions(+), 71 deletions(-) diff --git a/apps.json b/apps.json index ac3911a71..7afcd9cb5 100644 --- a/apps.json +++ b/apps.json @@ -18,7 +18,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.31", + "version": "0.32", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", @@ -550,11 +550,11 @@ { "id": "gpstime", "name": "GPS Time", - "version": "0.04", + "version": "0.05", "description": "Update the Bangle.js's clock based on the time from the GPS receiver", "icon": "gpstime.png", "tags": "tool,gps", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"gpstime.app.js","url":"gpstime.js"}, {"name":"gpstime.img","url":"gpstime-icon.js","evaluate":true} diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 6cdf1b0e5..4ce4dbe65 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -31,3 +31,6 @@ Fix issues where 'Uncaught Error: Function not found' could happen with multiple .boot.js 0.30: Remove 'Get GPS time' at boot. Latest firmwares keep time through reboots, so this is not needed now 0.31: Add polyfills for g.wrapString, g.imageMetrics, g.stringMetrics +0.32: Fix single quote error in g.wrapString polyfill + improve g.stringMetrics polyfill + diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index 7210ae731..a5ec01fa4 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -143,13 +143,14 @@ if (!g.imageMetrics) { // added in 2v11 - this is a limited functionality polyfi } if (!g.stringMetrics) { // added in 2v11 - this is a limited functionality polyfill boot += `Graphics.prototype.stringMetrics=function(txt) { - return {width:this.stringWidth(txt), height:this.getFontHeight()}; + txt = txt.toString().split("\\n"); + return {width:Math.max.apply(null,txt.map(x=>g.stringWidth(x))), height:this.getFontHeight()*txt.length}; };\n`; } if (!g.wrapString) { // added in 2v11 - this is a limited functionality polyfill boot += `Graphics.prototype.wrapString=function(str, maxWidth) { var lines = []; - for (var unwrappedLine of str.split("\n")) { + for (var unwrappedLine of str.split("\\n")) { var words = unwrappedLine.split(" "); var line = words.shift(); for (var word of words) { diff --git a/apps/gpstime/ChangeLog b/apps/gpstime/ChangeLog index a3bd6351e..4d9bbc8a2 100644 --- a/apps/gpstime/ChangeLog +++ b/apps/gpstime/ChangeLog @@ -1,2 +1,3 @@ 0.03: Fix time output on new firmwares when no GPS time set (fix #104) -0.04: Fix shown UTC time zone sign \ No newline at end of file +0.04: Fix shown UTC time zone sign +0.05: Use new 'layout library for Bangle2, fix #764 by adding a back button diff --git a/apps/gpstime/gpstime.js b/apps/gpstime/gpstime.js index a061d2e23..8c80953fa 100644 --- a/apps/gpstime/gpstime.js +++ b/apps/gpstime/gpstime.js @@ -1,68 +1,75 @@ -var img = require("heatshrink").decompress(atob("mEwghC/AH8A1QWVhWq0AuVAAIuVAAIwT1WinQwTFwMzmQwTCYMjlUqGCIuBlWi0UzC6JdBIoMjC4UDmAuOkYXBPAWgmczLp2ilUiVAUDC4IwLFwIUBLoJ2BFwQwM1WjCgJ1DFwQwLFwJ1B0SQCkQWDGBQXBCgK9BDgKQBAAgwJOwUzRgIDBC54wCkZdGPBwACRgguDBIIwLFxEJBQIwLFxGaBYQwKFxQwLgAWGmQuBcAQwJC48ifYYwJgUidgsyC4L7DGBIXBdohnBCgL7BcYIXIGAqMCIoL7DL5IwERgIUBLoL7BO5QXBGAK7DkWiOxQXGFwOjFoUyFxZhDgBdCCgJ1CCxYxCgBABkcqOwIuNGAQXC0S9BLpgAFXoIwBmYuPAAYwCLp4wHFyYwDFyYwDFygwCCyoA/AFQA=")); +function satelliteImage() { + return require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4AGnE4F1wvsF34wgFldcLdyMYsoACF1WJF4YxPFzOtF4wxNFzAvKSiIvU1ovIGAkJAAQucF5QxCFwYwbF4QwLrwvjYIVfrwABrtdq9Wqwvkq4oCAAtXmYvi1teE4NXrphCrxoCGAbvdSIoAHNQNeFzQvGeRQvCsowrYYNfF8YwHZQQFCF8QwGF4owjeYovBroHEMERhEF8IwNrtWryYFF8YwCq4vhGBeJF5AwaxIwKwVXFwwvandfMJeJF8M6nZiLGQIvdstfGAVlGBZkCxJeZJQIwCGIRjMFzYACGIc6r/+FsIvGGIYABEzYvPGQYvusovkAH4A/AH4A/ACo=")); +} + +var fix; Bangle.setLCDPower(1); Bangle.setLCDTimeout(0); +var Layout = require("Layout"); +Bangle.setGPSPower(1, "app"); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +E.showMessage("Loading..."); // avoid showing rubbish on screen -g.clear(); - -var fix; -Bangle.setGPSPower(1); -Bangle.on('GPS',function(f) { - fix = f; - g.reset(1); - g.setFont("6x8",2); - g.setFontAlign(0,0); - g.clearRect(90,30,239,90); - if (fix.fix) { - g.drawString("GPS",170,40); - g.drawString("Acquired",170,60); +function setGPSTime() { + if (fix.time!==undefined) { + setTime(fix.time.getTime()/1000); + E.showMessage("System time set", {img:require("heatshrink").decompress(atob("lEo4UBvvv///vEFBYNVAAWq1QFDBAgKGrQJD0oJDtQJD1IICqwGBFoIDByocDwAJBgQeDtWoJwcqDwWq0EAgfAgEKHoQcCBIQeBGAQaBBIQzBytaEwQJDlWlrQmBBIkK0tqBI+ptRNCBIcCBKhECBIh6CAgUL8AJHl/4BI8+3gJRl/8GJH/BI8Ah6MDLIZQB+BjGAAIoBBI84BIaVCAAaVBVIYJEWYLkEXobRDAAbRBcoYACcoT5DEwYJCtQoElWpBINaDwYcB0oJBGQIzCAYIwBDwQGBAAIcCDwYACDgQACBIYIEBQYFDA="))}); } else { - g.drawString("Waiting for",170,40); - g.drawString("GPS Fix",170,60); + E.showMessage("No GPS time to set"); } - g.setFont("6x8"); - g.drawString(fix.satellites+" satellites",170,80); - g.clearRect(0,100,239,239); - var t = ["","","","---",""]; - if (fix.time!==undefined) + Bangle.removeListener('GPS',onGPS); + setTimeout(function() { + fix = undefined; + layout.forgetLazyState(); // redraw all next time + Bangle.on('GPS',onGPS); + }, 2000); +} + +var layout = new Layout( { + type:"v", c: [ + {type:"h", c:[ + {type:"img", src:satelliteImage }, + { type:"v", fillx:1, c: [ + {type:"txt", font:"6x8:2", label:"Waiting\nfor GPS", id:"status" }, + {type:"txt", font:"6x8", label:"---", id:"sat" }, + ]}, + ]}, + {type:"txt", fillx:1, filly:1, font:"6x8:2", label:"---", id:"gpstime" } + ]},{lazy:true, btns: [ + { label : "Set", cb : setGPSTime}, + { label : "Back", cb : ()=>load() } + ]}); + + +function onGPS(f) { + if (fix===undefined) { + g.clear(); + Bangle.drawWidgets(); + } + fix = f; + if (fix.fix) { + layout.status.label = "GPS\nAcquired"; + } else { + layout.status.label = "Waiting\nfor GPS"; + } + layout.sat.label = fix.satellites+" satellites"; + + var t = ["","---",""]; + if (fix.time!==undefined) { t = fix.time.toString().split(" "); - /* - [ - "Sun", - "Nov", - "10", - "2019", - "15:55:35", - "GMT+0100" - ] - */ - //g.setFont("6x8",2); - //g.drawString(t[0],120,110); // day - g.setFont("6x8",3); - g.drawString(t[1]+" "+t[2],120,135); // date - g.setFont("6x8",2); - g.drawString(t[3],120,160); // year - g.setFont("6x8",3); - g.drawString(t[4],120,185); // time - if (fix.time) { - // timezone var tz = (new Date()).getTimezoneOffset()/-60; if (tz==0) tz="UTC"; else if (tz>0) tz="UTC+"+tz; else tz="UTC"+tz; - g.setFont("6x8",2); - g.drawString(tz,120,210); // gmt - g.setFontAlign(0,0,3); - g.drawString("Set",230,120); - g.setFontAlign(0,0); - } -}); -setInterval(function() { - g.drawImage(img,48,48,{scale:1.5,rotate:Math.sin(getTime()*2)/2}); -},100); -setWatch(function() { - if (fix.time!==undefined) - setTime(fix.time.getTime()/1000); -}, BTN2, {repeat:true}); + t = [t[1]+" "+t[2],t[3],t[4],t[5],tz]; + } + + layout.gpstime.label = t.join("\n"); + layout.render(); +} + +Bangle.on('GPS',onGPS); diff --git a/modules/Layout.js b/modules/Layout.js index 03aa6249b..319f6901e 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -169,14 +169,23 @@ function Layout(layout, options) { Bangle.on('touch',Bangle.touchHandler); } - // add IDs + // recurse over layout doing some fixing up if needed var ll = this; - function idRecurser(l) { + function recurser(l) { + // add IDs if (l.id) ll[l.id] = l; + // fix type up if (!l.type) l.type=""; - if (l.c) l.c.forEach(idRecurser); + // FIXME ':'/fsz not needed in new firmwares - Font:12 is handled internally + // fix fonts for pre-2v11 firmware + if (l.font && l.font.includes(":")) { + var f = l.font.split(":"); + l.font = f[0]; + l.fsz = f[1]; + } + if (l.c) l.c.forEach(recurser); } - idRecurser(layout); + recurser(this._l); this.updateNeeded = true; } @@ -352,12 +361,6 @@ Layout.prototype.update = function() { "txt" : function(l) { if (l.font.endsWith("%")) l.font = "Vector"+Math.round(g.getHeight()*l.font.slice(0,-1)/100); - // FIXME ':'/fsz not needed in new firmwares - it's handled internally - if (l.font.includes(":")) { - var f = l.font.split(":"); - l.font = f[0]; - l.fsz = f[1]; - } if (l.wrap) { l._h = l._w = 0; } else { From 1cc7674aa7f990f88644e78d9d19cd981ea34324 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 20 Oct 2021 20:48:38 +0100 Subject: [PATCH 6/6] Fix issue where re-running bootupdate could disable existing polyfills --- apps/boot/ChangeLog | 2 +- apps/boot/bootupdate.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/boot/ChangeLog b/apps/boot/ChangeLog index 4ce4dbe65..59d9e4c65 100644 --- a/apps/boot/ChangeLog +++ b/apps/boot/ChangeLog @@ -33,4 +33,4 @@ 0.31: Add polyfills for g.wrapString, g.imageMetrics, g.stringMetrics 0.32: Fix single quote error in g.wrapString polyfill improve g.stringMetrics polyfill - + Fix issue where re-running bootupdate could disable existing polyfills diff --git a/apps/boot/bootupdate.js b/apps/boot/bootupdate.js index a5ec01fa4..269a80831 100644 --- a/apps/boot/bootupdate.js +++ b/apps/boot/bootupdate.js @@ -81,9 +81,11 @@ if (s.quiet && s.qmTimeout) boot+=`Bangle.setLCDTimeout(${s.qmTimeout});\n`; if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passkey:${s.passkey}, mitm:1, display:1});\n`; if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`; // Pre-2v10 firmwares without a theme/setUI +delete g.theme; // deleting stops us getting confused by our own decl. builtins can't be deleted if (!g.theme) { boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7,dark:true};\n`; } +delete Bangle.setUI; // deleting stops us getting confused by our own decl. builtins can't be deleted if (!Bangle.setUI) { // assume this is just for F18 - Q3 should already have it boot += `Bangle.setUI=function(mode, cb) { if (Bangle.btnWatches) { @@ -131,6 +133,7 @@ else if (mode=="updown") { throw new Error("Unknown UI mode"); };\n`; } +delete g.imageMetrics; // deleting stops us getting confused by our own decl. builtins can't be deleted if (!g.imageMetrics) { // added in 2v11 - this is a limited functionality polyfill boot += `Graphics.prototype.imageMetrics=function(src) { if (src[0]) return {width:src[0],height:src[1]}; @@ -141,12 +144,14 @@ if (!g.imageMetrics) { // added in 2v11 - this is a limited functionality polyfi return {width:im.charCodeAt(0), height:im.charCodeAt(1)}; };\n`; } +delete g.stringMetrics; // deleting stops us getting confused by our own decl. builtins can't be deleted if (!g.stringMetrics) { // added in 2v11 - this is a limited functionality polyfill boot += `Graphics.prototype.stringMetrics=function(txt) { txt = txt.toString().split("\\n"); return {width:Math.max.apply(null,txt.map(x=>g.stringWidth(x))), height:this.getFontHeight()*txt.length}; };\n`; } +delete g.wrapString; // deleting stops us getting confused by our own decl. builtins can't be deleted if (!g.wrapString) { // added in 2v11 - this is a limited functionality polyfill boot += `Graphics.prototype.wrapString=function(str, maxWidth) { var lines = [];