diff --git a/apps/2047pp/2047pp.app.js b/apps/2047pp/2047pp.app.js
index 9163aaf3a..ac7fe6391 100644
--- a/apps/2047pp/2047pp.app.js
+++ b/apps/2047pp/2047pp.app.js
@@ -1,140 +1,142 @@
-class TwoK {
- constructor() {
- this.b = Array(4).fill().map(() => Array(4).fill(0));
- this.score = 0;
- this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"};
- }
- drawBRect(x1, y1, x2, y2, th, c, cf, fill) {
- g.setColor(c);
- for (i=0; i
4) g.setColor(1, 1, 1);
- else g.setColor(0, 0, 0);
- g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7));
- if (b>0) g.drawString(b.toString(), xo+(x+0.5)*bw+1, yo+(y+0.5)*bh);
- }
- }
- shift(d) { // +/-1: shift x, +/- 2: shift y
- var crc = E.CRC32(this.b.toString());
- if (d==-1) { // shift x left
- for (y=0; y<4; ++y) {
- for (x=2; x>=0; x--)
- if (this.b[y][x]==0) {
- for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1];
- this.b[y][3] = 0;
- }
- for (x=0; x<3; ++x)
- if (this.b[y][x]==this.b[y][x+1]) {
- this.score += 2*this.b[y][x];
- this.b[y][x] += this.b[y][x+1];
- for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1];
+{ // wrap app in scope to prevent minifier from removing the class definition completely
+ class TwoK {
+ constructor() {
+ this.b = Array(4).fill().map(() => Array(4).fill(0));
+ this.score = 0;
+ this.cmap = {0: "#caa", 2:"#ccc", 4: "#bcc", 8: "#ba6", 16: "#e61", 32: "#d20", 64: "#d00", 128: "#da0", 256: "#ec0", 512: "#dd0"};
+ }
+ drawBRect(x1, y1, x2, y2, th, c, cf, fill) {
+ g.setColor(c);
+ for (i=0; i | 4) g.setColor(1, 1, 1);
+ else g.setColor(0, 0, 0);
+ g.setFont("Vector", bh*(b>8 ? (b>64 ? (b>512 ? 0.32 : 0.4) : 0.6) : 0.7));
+ if (b>0) g.drawString(b.toString(), xo+(x+0.5)*bw+1, yo+(y+0.5)*bh);
+ }
+ }
+ shift(d) { // +/-1: shift x, +/- 2: shift y
+ var crc = E.CRC32(this.b.toString());
+ if (d==-1) { // shift x left
+ for (y=0; y<4; ++y) {
+ for (x=2; x>=0; x--)
+ if (this.b[y][x]==0) {
+ for (i=x; i<3; i++) this.b[y][i] = this.b[y][i+1];
this.b[y][3] = 0;
- }
+ }
+ for (x=0; x<3; ++x)
+ if (this.b[y][x]==this.b[y][x+1]) {
+ this.score += 2*this.b[y][x];
+ this.b[y][x] += this.b[y][x+1];
+ for (j=x+1; j<3; ++j) this.b[y][j] = this.b[y][j+1];
+ this.b[y][3] = 0;
+ }
+ }
}
- }
- else if (d==1) { // shift x right
- for (y=0; y<4; ++y) {
- for (x=1; x<4; x++)
- if (this.b[y][x]==0) {
- for (i=x; i>0; i--) this.b[y][i] = this.b[y][i-1];
- this.b[y][0] = 0;
- }
- for (x=3; x>0; --x)
- if (this.b[y][x]==this.b[y][x-1]) {
- this.score += 2*this.b[y][x];
- this.b[y][x] += this.b[y][x-1] ;
- for (j=x-1; j>0; j--) this.b[y][j] = this.b[y][j-1];
- this.b[y][0] = 0;
- }
+ else if (d==1) { // shift x right
+ for (y=0; y<4; ++y) {
+ for (x=1; x<4; x++)
+ if (this.b[y][x]==0) {
+ for (i=x; i>0; i--) this.b[y][i] = this.b[y][i-1];
+ this.b[y][0] = 0;
+ }
+ for (x=3; x>0; --x)
+ if (this.b[y][x]==this.b[y][x-1]) {
+ this.score += 2*this.b[y][x];
+ this.b[y][x] += this.b[y][x-1] ;
+ for (j=x-1; j>0; j--) this.b[y][j] = this.b[y][j-1];
+ this.b[y][0] = 0;
+ }
+ }
}
- }
- else if (d==-2) { // shift y down
- for (x=0; x<4; ++x) {
- for (y=1; y<4; y++)
- if (this.b[y][x]==0) {
- for (i=y; i>0; i--) this.b[i][x] = this.b[i-1][x];
- this.b[0][x] = 0;
- }
- for (y=3; y>0; y--)
- if (this.b[y][x]==this.b[y-1][x] || this.b[y][x]==0) {
- this.score += 2*this.b[y][x];
- this.b[y][x] += this.b[y-1][x];
- for (j=y-1; j>0; j--) this.b[j][x] = this.b[j-1][x];
- this.b[0][x] = 0;
- }
+ else if (d==-2) { // shift y down
+ for (x=0; x<4; ++x) {
+ for (y=1; y<4; y++)
+ if (this.b[y][x]==0) {
+ for (i=y; i>0; i--) this.b[i][x] = this.b[i-1][x];
+ this.b[0][x] = 0;
+ }
+ for (y=3; y>0; y--)
+ if (this.b[y][x]==this.b[y-1][x] || this.b[y][x]==0) {
+ this.score += 2*this.b[y][x];
+ this.b[y][x] += this.b[y-1][x];
+ for (j=y-1; j>0; j--) this.b[j][x] = this.b[j-1][x];
+ this.b[0][x] = 0;
+ }
+ }
}
- }
- else if (d==2) { // shift y up
- for (x=0; x<4; ++x) {
- for (y=2; y>=0; y--)
- if (this.b[y][x]==0) {
- for (i=y; i<3; i++) this.b[i][x] = this.b[i+1][x];
- this.b[3][x] = 0;
- }
- for (y=0; y<3; ++y)
- if (this.b[y][x]==this.b[y+1][x] || this.b[y][x]==0) {
- this.score += 2*this.b[y][x];
- this.b[y][x] += this.b[y+1][x];
- for (j=y+1; j<3; ++j) this.b[j][x] = this.b[j+1][x];
- this.b[3][x] = 0;
- }
+ else if (d==2) { // shift y up
+ for (x=0; x<4; ++x) {
+ for (y=2; y>=0; y--)
+ if (this.b[y][x]==0) {
+ for (i=y; i<3; i++) this.b[i][x] = this.b[i+1][x];
+ this.b[3][x] = 0;
+ }
+ for (y=0; y<3; ++y)
+ if (this.b[y][x]==this.b[y+1][x] || this.b[y][x]==0) {
+ this.score += 2*this.b[y][x];
+ this.b[y][x] += this.b[y+1][x];
+ for (j=y+1; j<3; ++j) this.b[j][x] = this.b[j+1][x];
+ this.b[3][x] = 0;
+ }
+ }
}
+ return (E.CRC32(this.b.toString())!=crc);
+ }
+ addDigit() {
+ var d = Math.random()>0.9 ? 4 : 2;
+ var id = Math.floor(Math.random()*16);
+ while (this.b[Math.floor(id/4)][id%4] > 0) id = Math.floor(Math.random()*16);
+ this.b[Math.floor(id/4)][id%4] = d;
}
- return (E.CRC32(this.b.toString())!=crc);
}
- addDigit() {
- var d = Math.random()>0.9 ? 4 : 2;
- var id = Math.floor(Math.random()*16);
- while (this.b[Math.floor(id/4)][id%4] > 0) id = Math.floor(Math.random()*16);
- this.b[Math.floor(id/4)][id%4] = d;
- }
-}
-function dragHandler(e) {
- if (e.b && (Math.abs(e.dx)>7 || Math.abs(e.dy)>7)) {
- var res = false;
- if (Math.abs(e.dx)>Math.abs(e.dy)) {
- if (e.dx>0) res = twok.shift(1);
- if (e.dx<0) res = twok.shift(-1);
+ function dragHandler(e) {
+ if (e.b && (Math.abs(e.dx)>7 || Math.abs(e.dy)>7)) {
+ var res = false;
+ if (Math.abs(e.dx)>Math.abs(e.dy)) {
+ if (e.dx>0) res = twok.shift(1);
+ if (e.dx<0) res = twok.shift(-1);
+ }
+ else {
+ if (e.dy>0) res = twok.shift(-2);
+ if (e.dy<0) res = twok.shift(2);
+ }
+ if (res) twok.addDigit();
+ twok.render();
}
- else {
- if (e.dy>0) res = twok.shift(-2);
- if (e.dy<0) res = twok.shift(2);
- }
- if (res) twok.addDigit();
- twok.render();
}
-}
-function swipeHandler() {
-
-}
+ function swipeHandler() {
+
+ }
-function buttonHandler() {
-
-}
+ function buttonHandler() {
+
+ }
-var twok = new TwoK();
-twok.addDigit(); twok.addDigit();
-twok.render();
-if (process.env.HWVERSION==2) Bangle.on("drag", dragHandler);
-if (process.env.HWVERSION==1) {
- Bangle.on("swipe", (e) => { res = twok.shift(e); if (res) twok.addDigit(); twok.render(); });
- setWatch(() => { res = twok.shift(2); if (res) twok.addDigit(); twok.render(); }, BTN1, {repeat: true});
- setWatch(() => { res = twok.shift(-2); if (res) twok.addDigit(); twok.render(); }, BTN3, {repeat: true});
-}
+ var twok = new TwoK();
+ twok.addDigit(); twok.addDigit();
+ twok.render();
+ if (process.env.HWVERSION==2) Bangle.on("drag", dragHandler);
+ if (process.env.HWVERSION==1) {
+ Bangle.on("swipe", (e) => { res = twok.shift(e); if (res) twok.addDigit(); twok.render(); });
+ setWatch(() => { res = twok.shift(2); if (res) twok.addDigit(); twok.render(); }, BTN1, {repeat: true});
+ setWatch(() => { res = twok.shift(-2); if (res) twok.addDigit(); twok.render(); }, BTN3, {repeat: true});
+ }
+}
\ No newline at end of file
diff --git a/apps/2047pp/ChangeLog b/apps/2047pp/ChangeLog
index a1f88e5ec..9436289ae 100644
--- a/apps/2047pp/ChangeLog
+++ b/apps/2047pp/ChangeLog
@@ -1,2 +1,3 @@
0.01: New app!
0.02: Better support for watch themes
+0.03: Workaround minifier bug
\ No newline at end of file
diff --git a/apps/2047pp/metadata.json b/apps/2047pp/metadata.json
index 033354ac6..ac4dc70bd 100644
--- a/apps/2047pp/metadata.json
+++ b/apps/2047pp/metadata.json
@@ -2,7 +2,7 @@
"name": "2047pp",
"shortName":"2047pp",
"icon": "app.png",
- "version":"0.02",
+ "version":"0.03",
"description": "Bangle version of a tile shifting game",
"supports" : ["BANGLEJS","BANGLEJS2"],
"allow_emulator": true,
diff --git a/apps/90sclk/ChangeLog b/apps/90sclk/ChangeLog
index 057d6ff73..9718a652d 100644
--- a/apps/90sclk/ChangeLog
+++ b/apps/90sclk/ChangeLog
@@ -1,3 +1,4 @@
0.01: New App!
0.02: Fullscreen settings.
0.03: Tell clock widgets to hide.
+0.04: Use widget_utils.
diff --git a/apps/90sclk/app.js b/apps/90sclk/app.js
index 351c235e0..63a48b27a 100644
--- a/apps/90sclk/app.js
+++ b/apps/90sclk/app.js
@@ -1,6 +1,7 @@
const SETTINGS_FILE = "90sclk.setting.json";
const locale = require('locale');
const storage = require('Storage');
+const widget_utils = require('widget_utils');
/*
@@ -109,7 +110,7 @@ function draw() {
// Draw widgets if not fullscreen
if(settings.fullscreen){
- for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+ widget_utils.hide();
} else {
Bangle.drawWidgets();
}
diff --git a/apps/90sclk/metadata.json b/apps/90sclk/metadata.json
index 59b627427..bfbb6b080 100644
--- a/apps/90sclk/metadata.json
+++ b/apps/90sclk/metadata.json
@@ -1,7 +1,7 @@
{
"id": "90sclk",
"name": "90s Clock",
- "version": "0.03",
+ "version": "0.04",
"description": "A 90s style watch-face",
"readme": "README.md",
"icon": "app.png",
diff --git a/apps/agenda/ChangeLog b/apps/agenda/ChangeLog
index b53e657fd..99c44a2b1 100644
--- a/apps/agenda/ChangeLog
+++ b/apps/agenda/ChangeLog
@@ -10,4 +10,5 @@
0.09: Ensure Agenda supplies an image for clkinfo items
0.10: Update clock_info to avoid a redraw
0.11: Setting to use "Today" and "Yesterday" instead of dates
- Added dynamic, short and range fields to clkinfo
\ No newline at end of file
+ Added dynamic, short and range fields to clkinfo
+0.12: Added color field and updating clkinfo periodically (running events)
diff --git a/apps/agenda/agenda.clkinfo.js b/apps/agenda/agenda.clkinfo.js
index d203119f4..f9ea6a35d 100644
--- a/apps/agenda/agenda.clkinfo.js
+++ b/apps/agenda/agenda.clkinfo.js
@@ -5,6 +5,51 @@
if(passed<0) return 0;
return passed;
}
+
+ /*
+ * Returns the array [interval, switchTimeout]
+ * `interval` is the refresh rate (hourly or per minute)
+ * `switchTimeout` is the time before the refresh rate should change (or expiration)
+ */
+ function getRefreshIntervals(ev) {
+ const threshold = 2 * 60 * 1000; //2 mins
+ const slices = 16;
+ var now = new Date();
+ var passed = now - (ev.timestamp*1000);
+ var remaining = (ev.durationInSeconds*1000) - passed;
+ if(remaining<0)
+ return [];
+ if(passed<0) //check once it's started
+ return [ 2*-passed, -passed ];
+ var slice = Math.round(remaining/slices);
+ if(slice < threshold) { //no need to refresh frequently
+ return [ threshold, remaining ];
+ }
+ return [ slice, remaining ];
+ }
+
+ function _doInterval(interval) {
+ return setTimeout(()=>{
+ this.emit("redraw");
+ this.interval = setInterval(()=>{
+ this.emit("redraw");
+ }, interval);
+ }, interval);
+ }
+ function _doSwitchTimeout(ev, switchTimeout) {
+ return setTimeout(()=>{
+ this.emit("redraw");
+ clearInterval(this.interval);
+ this.interval = undefined;
+ var tmp = getRefreshIntervals(ev);
+ var interval = tmp[0];
+ var switchTimeout = tmp[1];
+ if(!interval) return;
+ this.interval = _doInterval.call(this, interval);
+ this.switchTimeout = _doSwitchTimeout.call(this, ev, switchTimeout);
+ }, switchTimeout);
+ }
+
var agendaItems = {
name: "Agenda",
img: atob("GBiBAAAAAAAAAADGMA///w///wf//wAAAA///w///w///w///x///h///h///j///D///X//+f//8wAABwAADw///w///wf//gAAAA=="),
@@ -23,16 +68,33 @@
var date = new Date(entry.timestamp*1000);
var dateStr = locale.date(date).replace(/\d\d\d\d/,"");
var shortStr = ((date-now) > 86400000 || entry.allDay) ? dateStr : locale.time(date,1);
+ var color = "#"+(0x1000000+Number(entry.color)).toString(16).padStart(6,"0");
dateStr += entry.durationInSeconds < 86400 ? "/ " + locale.time(date,1) : "";
+ shortStr = shortStr.trim().replace(" ", "\n");
agendaItems.items.push({
name: "Agenda "+i,
hasRange: true,
get: () => ({ text: title + "\n" + dateStr,
- img: agendaItems.img, short: shortStr.trim(),
+ img: agendaItems.img, short: shortStr,
+ color: color,
v: getPassedSec(date), min: 0, max: entry.durationInSeconds}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ var tmp = getRefreshIntervals(entry);
+ var interval = tmp[0];
+ var switchTimeout = tmp[1];
+ if(!interval) return;
+ this.interval = _doInterval.call(this, interval);
+ this.switchTimeout = _doSwitchTimeout.call(this, entry, switchTimeout);
+ },
+ hide: function() {
+ if(this.interval)
+ clearInterval(this.interval);
+ if(this.switchTimeout)
+ clearTimeout(this.switchTimeout);
+ this.interval = undefined;
+ this.switchTimeout = undefined;
+ }
});
});
diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json
index b5b7c1582..88dd2c1bc 100644
--- a/apps/agenda/metadata.json
+++ b/apps/agenda/metadata.json
@@ -1,7 +1,7 @@
{
"id": "agenda",
"name": "Agenda",
- "version": "0.11",
+ "version": "0.12",
"description": "Simple agenda",
"icon": "agenda.png",
"screenshots": [{"url":"screenshot_agenda_overview.png"}, {"url":"screenshot_agenda_event1.png"}, {"url":"screenshot_agenda_event2.png"}],
diff --git a/apps/agpsdata/ChangeLog b/apps/agpsdata/ChangeLog
index d900841d7..303fc7583 100644
--- a/apps/agpsdata/ChangeLog
+++ b/apps/agpsdata/ChangeLog
@@ -5,3 +5,4 @@
0.04: Write AGPS data chunks with delay to improve reliability
0.05: Show last success date
Do not start A-GPS update automatically
+0.06: Switch off gps after updating
\ No newline at end of file
diff --git a/apps/agpsdata/lib.js b/apps/agpsdata/lib.js
index 34608a5c6..4610331f6 100644
--- a/apps/agpsdata/lib.js
+++ b/apps/agpsdata/lib.js
@@ -10,20 +10,24 @@ readSettings();
function setAGPS(b64) {
return new Promise(function(resolve, reject) {
- var initCommands = "Bangle.setGPSPower(1);\n"; // turn GPS on
const gnsstype = settings.gnsstype || 1; // default GPS
- initCommands += `Serial1.println("${CASIC_CHECKSUM("$PCAS04," + gnsstype)}")\n`; // set GNSS mode
// What about:
// NAV-TIMEUTC (0x01 0x10)
// NAV-PV (0x01 0x03)
// or AGPS.zip uses AID-INI (0x0B 0x01)
-
- eval(initCommands);
+ Bangle.setGPSPower(1,"agpsdata"); // turn GPS on
+ Serial1.println(CASIC_CHECKSUM("$PCAS04," + gnsstype)); // set GNSS mode
try {
- writeChunks(atob(b64), resolve);
+ writeChunks(atob(b64), ()=>{
+ setTimeout(()=>{
+ Bangle.setGPSPower(0,"agpsdata");
+ resolve();
+ }, 1000);
+ });
} catch (e) {
console.log("error:", e);
+ Bangle.setGPSPower(0,"agpsdata");
reject();
}
});
@@ -36,9 +40,8 @@ function writeChunks(bin, resolve) {
setTimeout(function() {
if (chunkI < bin.length) {
var chunk = bin.substr(chunkI, chunkSize);
- js = `Serial1.write(atob("${btoa(chunk)}"))\n`;
- eval(js);
-
+ Serial1.write(atob(btoa(chunk)));
+
chunkI += chunkSize;
writeChunks(bin, resolve);
} else {
diff --git a/apps/agpsdata/metadata.json b/apps/agpsdata/metadata.json
index 7f0b53217..446661045 100644
--- a/apps/agpsdata/metadata.json
+++ b/apps/agpsdata/metadata.json
@@ -2,7 +2,7 @@
"name": "A-GPS Data Downloader App",
"shortName":"A-GPS Data",
"icon": "agpsdata.png",
- "version":"0.05",
+ "version":"0.06",
"description": "Once installed, this app allows you to download assisted GPS (A-GPS) data directly to your Bangle.js **via Gadgetbridge on an Android phone** when you run the app. If you just want to upload the latest AGPS data from this app loader, please use the `Assisted GPS Update (AGPS)` app.",
"tags": "boot,tool,assisted,gps,agps,http",
"allow_emulator":true,
diff --git a/apps/aiclock/ChangeLog b/apps/aiclock/ChangeLog
index 6d6eeb55e..43236015e 100644
--- a/apps/aiclock/ChangeLog
+++ b/apps/aiclock/ChangeLog
@@ -4,4 +4,5 @@
0.04: Use widget_utils module.
0.05: Support for clkinfo.
0.06: ClockInfo Fix: Use .get instead of .show as .show is not implemented for weather etc.
-0.07: Use clock_info.addInteractive instead of a custom implementation
\ No newline at end of file
+0.07: Use clock_info.addInteractive instead of a custom implementation
+0.08: Use clock_info module as an app
diff --git a/apps/aiclock/metadata.json b/apps/aiclock/metadata.json
index 4c01ecaa9..d8d1e9d68 100644
--- a/apps/aiclock/metadata.json
+++ b/apps/aiclock/metadata.json
@@ -3,9 +3,10 @@
"name": "AI Clock",
"shortName":"AI Clock",
"icon": "aiclock.png",
- "version":"0.07",
+ "version":"0.08",
"readme": "README.md",
"supports": ["BANGLEJS2"],
+ "dependencies" : { "clock_info":"module" },
"description": "A watch face that was designed by an AI (stable diffusion) and implemented by a human.",
"type": "clock",
"tags": "clock",
diff --git a/apps/alarmqm/ChangeLog b/apps/alarmqm/ChangeLog
new file mode 100644
index 000000000..5560f00bc
--- /dev/null
+++ b/apps/alarmqm/ChangeLog
@@ -0,0 +1 @@
+0.01: New App!
diff --git a/apps/alarmqm/app.png b/apps/alarmqm/app.png
new file mode 100644
index 000000000..ee0085206
Binary files /dev/null and b/apps/alarmqm/app.png differ
diff --git a/apps/alarmqm/boot.js b/apps/alarmqm/boot.js
new file mode 100644
index 000000000..cf35452c0
--- /dev/null
+++ b/apps/alarmqm/boot.js
@@ -0,0 +1,20 @@
+(function () {
+ function dismissAlarm(alarm) {
+ // Run only for alarms, not timers
+ if (!alarm.timer) {
+ if ("qmsched" in WIDGETS) {
+ require("qmsched").setMode(0);
+ } else {
+ // Code from qmsched.js, so we can work without it
+ require("Storage").writeJSON(
+ "setting.json",
+ Object.assign(require("Storage").readJSON("setting.json", 1) || {}, {
+ quiet: 0,
+ })
+ );
+ }
+ }
+ }
+
+ Bangle.on("alarmDismiss", dismissAlarm);
+ })();
\ No newline at end of file
diff --git a/apps/alarmqm/metadata.json b/apps/alarmqm/metadata.json
new file mode 100644
index 000000000..bae4b0807
--- /dev/null
+++ b/apps/alarmqm/metadata.json
@@ -0,0 +1,13 @@
+{ "id": "alarmqm",
+ "name": "Alarm Quiet Mode",
+ "shortName":"AlarmQM",
+ "version":"0.01",
+ "description": "Service that turns off quiet mode after alarm dismiss",
+ "icon": "app.png",
+ "tags": "quiet,alarm",
+ "supports" : ["BANGLEJS2"],
+ "type": "bootloader",
+ "storage": [
+ {"name":"alarmqm.boot.js","url":"boot.js"}
+ ]
+}
diff --git a/apps/android/ChangeLog b/apps/android/ChangeLog
index 1e0c14a5e..a651c1747 100644
--- a/apps/android/ChangeLog
+++ b/apps/android/ChangeLog
@@ -19,3 +19,6 @@
If connected to Gadgetbridge, allow GPS forwarding from phone (Gadgetbridge code still not merged)
0.19: Add automatic translation for a couple of strings.
0.20: Fix wrong event used for forwarded GPS data from Gadgetbridge and add mapper to map longitude value correctly.
+0.21: Fix broken 'Messages' button in menu
+0.22: Handle connection events for GPS forwarding from phone
+0.23: Handle 'act' Gadgetbridge messages for realtime activity monitoring
diff --git a/apps/android/boot.js b/apps/android/boot.js
index c5a9dd746..81975182d 100644
--- a/apps/android/boot.js
+++ b/apps/android/boot.js
@@ -3,8 +3,11 @@
Bluetooth.println("");
Bluetooth.println(JSON.stringify(message));
}
- var lastMsg;
+ var lastMsg; // for music messages - may not be needed now...
+ var actInterval; // Realtime activity reporting interval when `act` is true
+ var actHRMHandler; // For Realtime activity reporting
+ // this settings var is deleted after this executes to save memory
var settings = require("Storage").readJSON("android.settings.json",1)||{};
//default alarm settings
if (settings.rp == undefined) settings.rp = true;
@@ -60,6 +63,7 @@
title:event.name||/*LANG*/"Call", body:/*LANG*/"Incoming call\n"+event.number});
require("messages").pushMessage(event);
},
+ // {"t":"alarm", "d":[{h:int,m:int,rep:int},... }
"alarm" : function() {
//wipe existing GB alarms
var sched;
@@ -92,6 +96,7 @@
},
//TODO perhaps move those in a library (like messages), used also for viewing events?
//add and remove events based on activity on phone (pebble-like)
+ // {t:"calendar", id:int, type:int, timestamp:seconds, durationInSeconds, title:string, description:string,location:string,calName:string.color:int,allDay:bool
"calendar" : function() {
var cal = require("Storage").readJSON("android.calendar.json",true);
if (!cal || !Array.isArray(cal)) cal = [];
@@ -102,6 +107,7 @@
cal[i] = event;
require("Storage").writeJSON("android.calendar.json", cal);
},
+ // {t:"calendar-", id:int}
"calendar-" : function() {
var cal = require("Storage").readJSON("android.calendar.json",true);
//if any of those happen we are out of sync!
@@ -110,11 +116,13 @@
require("Storage").writeJSON("android.calendar.json", cal);
},
//triggered by GB, send all ids
+ // { t:"force_calendar_sync_start" }
"force_calendar_sync_start" : function() {
var cal = require("Storage").readJSON("android.calendar.json",true);
if (!cal || !Array.isArray(cal)) cal = [];
gbSend({t:"force_calendar_sync", ids: cal.map(e=>e.id)});
},
+ // {t:"http",resp:"......",[id:"..."]}
"http":function() {
//get the promise and call the promise resolve
if (Bangle.httpRequest === undefined) return;
@@ -127,21 +135,44 @@
else
request.r(event); //r = resolve function
},
+ // {t:"gps", lat, lon, alt, speed, course, time, satellites, hdop, externalSource:true }
"gps": function() {
const settings = require("Storage").readJSON("android.settings.json",1)||{};
if (!settings.overwriteGps) return;
delete event.t;
event.satellites = NaN;
- event.course = NaN;
+ if (!isFinite(event.course)) event.course = NaN;
event.fix = 1;
- if (event.long!==undefined) {
+ if (event.long!==undefined) { // for earlier Gadgetbridge implementations
event.lon = event.long;
delete event.long;
}
Bangle.emit('GPS', event);
},
+ // {t:"is_gps_active"}
"is_gps_active": function() {
- gbSend({ t: "gps_power", status: Bangle._PWR && Bangle._PWR.GPS && Bangle._PWR.GPS.length>0 });
+ gbSend({ t: "gps_power", status: Bangle.isGPSOn() });
+ },
+ // {t:"act", hrm:bool, stp:bool, int:int}
+ "act": function() {
+ if (actInterval) clearInterval(actInterval);
+ actInterval = undefined;
+ if (actHRMHandler)
+ actHRMHandler = undefined;
+ Bangle.setHRMPower(event.hrm,"androidact");
+ if (!(event.hrm || event.stp)) return;
+ if (!isFinite(event.int)) event.int=1;
+ var lastSteps = Bangle.getStepCount();
+ var lastBPM = 0;
+ actHRMHandler = function(e) {
+ lastBPM = e.bpm;
+ };
+ Bangle.on('HRM',actHRMHandler);
+ actInterval = setInterval(function() {
+ var steps = Bangle.getStepCount();
+ gbSend({ t: "act", stp: steps-lastSteps, hrm: lastBPM });
+ lastSteps = steps;
+ }, event.int*1000);
}
};
var h = HANDLERS[event.t];
@@ -178,21 +209,28 @@
},options.timeout||30000)};
});
return promise;
- }
+ };
// Battery monitor
function sendBattery() { gbSend({ t: "status", bat: E.getBattery(), chg: Bangle.isCharging()?1:0 }); }
+ Bangle.on("charging", sendBattery);
NRF.on("connect", () => setTimeout(function() {
sendBattery();
GB({t:"force_calendar_sync_start"}); // send a list of our calendar entries to start off the sync process
}, 2000));
- Bangle.on("charging", sendBattery);
- if (!settings.keep)
- NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect
+ NRF.on("disconnect", () => {
+ // disable HRM/activity monitoring ('act' message)
+ GB({t:"act",stp:0,hrm:0,int:0}); // just call the handler to save duplication
+ // remove all messages on disconnect (if enabled)
+ var settings = require("Storage").readJSON("android.settings.json",1)||{};
+ if (!settings.keep)
+ require("messages").clearAll();
+ });
setInterval(sendBattery, 10*60*1000);
// Health tracking
Bangle.on('health', health=>{
- gbSend({ t: "act", stp: health.steps, hrm: health.bpm });
+ if (actInterval===undefined) // if 'realtime' we do it differently
+ gbSend({ t: "act", stp: health.steps, hrm: health.bpm });
});
// Music control
Bangle.musicControl = cmd => {
@@ -207,13 +245,39 @@
};
// GPS overwrite logic
if (settings.overwriteGps) { // if the overwrite option is set../
- // Save current logic
- const originalSetGpsPower = Bangle.setGPSPower;
+ const origSetGPSPower = Bangle.setGPSPower;
+ // migrate all GPS clients to the other variant on connection events
+ let handleConnection = (state) => {
+ if (Bangle.isGPSOn()){
+ let orig = Bangle._PWR.GPS;
+ delete Bangle._PWR.GPS;
+ origSetGPSPower(state);
+ Bangle._PWR.GPS = orig;
+ }
+ };
+ NRF.on('connect', ()=>{handleConnection(0);});
+ NRF.on('disconnect', ()=>{handleConnection(1);});
+
+ // Work around Serial1 for GPS not working when connected to something
+ let serialTimeout;
+ let wrap = function(f){
+ return (s)=>{
+ if (serialTimeout) clearTimeout(serialTimeout);
+ handleConnection(1);
+ f(s);
+ serialTimeout = setTimeout(()=>{
+ serialTimeout = undefined;
+ if (NRF.getSecurityStatus().connected) handleConnection(0);
+ }, 10000);
+ };
+ };
+ Serial1.println = wrap(Serial1.println);
+ Serial1.write = wrap(Serial1.write);
+
// Replace set GPS power logic to suppress activation of gps (and instead request it from the phone)
Bangle.setGPSPower = (isOn, appID) => {
- // if not connected, use old logic
- if (!NRF.getSecurityStatus().connected) return originalSetGpsPower(isOn, appID);
- // Emulate old GPS power logic
+ // if not connected use internal GPS power function
+ if (!NRF.getSecurityStatus().connected) return origSetGPSPower(isOn, appID);
if (!Bangle._PWR) Bangle._PWR={};
if (!Bangle._PWR.GPS) Bangle._PWR.GPS=[];
if (!appID) appID="?";
@@ -222,11 +286,15 @@
let pwr = Bangle._PWR.GPS.length>0;
gbSend({ t: "gps_power", status: pwr });
return pwr;
- }
- // Replace check if the GPS is on to check the _PWR variable
+ };
+ // Allow checking for GPS via GadgetBridge
Bangle.isGPSOn = () => {
- return Bangle._PWR && Bangle._PWR.GPS && Bangle._PWR.GPS.length>0;
- }
+ return !!(Bangle._PWR && Bangle._PWR.GPS && Bangle._PWR.GPS.length>0);
+ };
+ // stop GPS on boot if not activated
+ setTimeout(()=>{
+ if (!Bangle.isGPSOn()) gbSend({ t: "gps_power", status: false });
+ },3000);
}
// remove settings object so it's not taking up RAM
diff --git a/apps/android/metadata.json b/apps/android/metadata.json
index 883a821a4..f8ea3521a 100644
--- a/apps/android/metadata.json
+++ b/apps/android/metadata.json
@@ -2,7 +2,7 @@
"id": "android",
"name": "Android Integration",
"shortName": "Android",
- "version": "0.20",
+ "version": "0.23",
"description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.",
"icon": "app.png",
"tags": "tool,system,messages,notifications,gadgetbridge",
diff --git a/apps/android/settings.js b/apps/android/settings.js
index 3e04e0f9d..0abb32249 100644
--- a/apps/android/settings.js
+++ b/apps/android/settings.js
@@ -1,6 +1,6 @@
(function(back) {
-
+
function gb(j) {
Bluetooth.println(JSON.stringify(j));
@@ -36,7 +36,7 @@
updateSettings();
}
},
- /*LANG*/"Messages" : ()=>require("message").openGUI(),
+ /*LANG*/"Messages" : ()=>require("messages").openGUI(),
};
E.showMenu(mainmenu);
})
diff --git a/apps/android/test.js b/apps/android/test.js
new file mode 100644
index 000000000..88a7c0566
--- /dev/null
+++ b/apps/android/test.js
@@ -0,0 +1,126 @@
+let result = true;
+
+function assertTrue(condition, text) {
+ if (!condition) {
+ result = false;
+ print("FAILURE: " + text);
+ } else print("OK: " + text);
+}
+
+function assertFalse(condition, text) {
+ assertTrue(!condition, text);
+}
+
+function assertUndefinedOrEmpty(array, text) {
+ assertTrue(!array || array.length == 0, text);
+}
+
+function assertNotEmpty(array, text) {
+ assertTrue(array && array.length > 0, text);
+}
+
+let internalOn = () => {
+ return getPinMode((process.env.HWVERSION==2)?D30:D26) == "input";
+};
+
+let sec = {
+ connected: false
+};
+
+NRF.getSecurityStatus = () => sec;
+
+setTimeout(() => {
+ // add an empty starting point to make the asserts work
+ Bangle._PWR={};
+
+ print("Not connected, should use internal GPS");
+ assertTrue(!NRF.getSecurityStatus().connected, "Not connected");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+
+ assertTrue(Bangle.setGPSPower(1, "test"), "Switch GPS on");
+
+ assertNotEmpty(Bangle._PWR.GPS, "GPS");
+ assertTrue(Bangle.isGPSOn(), "isGPSOn");
+ assertTrue(internalOn(), "Internal GPS on");
+
+ assertFalse(Bangle.setGPSPower(0, "test"), "Switch GPS off");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ print("Connected, should use GB GPS");
+ sec.connected = true;
+
+ assertTrue(NRF.getSecurityStatus().connected, "Connected");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ assertTrue(Bangle.setGPSPower(1, "test"), "Switch GPS on");
+
+ assertNotEmpty(Bangle._PWR.GPS, "GPS");
+ assertTrue(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ assertFalse(Bangle.setGPSPower(0, "test"), "Switch GPS off");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ print("Connected, then reconnect cycle");
+ sec.connected = true;
+
+ assertTrue(NRF.getSecurityStatus().connected, "Connected");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ assertTrue(Bangle.setGPSPower(1, "test"), "Switch GPS on");
+
+ assertNotEmpty(Bangle._PWR.GPS, "GPS");
+ assertTrue(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ NRF.emit("disconnect", {});
+ print("disconnect");
+ sec.connected = false;
+
+ setTimeout(() => {
+
+ assertNotEmpty(Bangle._PWR.GPS, "GPS");
+ assertTrue(Bangle.isGPSOn(), "isGPSOn");
+ assertTrue(internalOn(), "Internal GPS on");
+
+ print("connect");
+ sec.connected = true;
+ NRF.emit("connect", {});
+
+ setTimeout(() => {
+ assertNotEmpty(Bangle._PWR.GPS, "GPS");
+ assertTrue(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ assertFalse(Bangle.setGPSPower(0, "test"), "Switch GPS off");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ setTimeout(() => {
+ print("Test disconnect without gps on");
+
+ assertUndefinedOrEmpty(Bangle._PWR.GPS, "No GPS");
+ assertFalse(Bangle.isGPSOn(), "isGPSOn");
+ assertFalse(internalOn(), "Internal GPS off");
+
+ print("Result Overall is " + (result ? "OK" : "FAIL"));
+ }, 0);
+ }, 0);
+ }, 0);
+}, 5000);
\ No newline at end of file
diff --git a/apps/assistedgps/ChangeLog b/apps/assistedgps/ChangeLog
index 739ccf915..ff2de6f67 100644
--- a/apps/assistedgps/ChangeLog
+++ b/apps/assistedgps/ChangeLog
@@ -1,3 +1,4 @@
0.01: New App!
0.02: Update to work with Bangle.js 2
0.03: Select GNSS systems to use for Bangle.js 2
+0.04: Now turns GPS off after upload
diff --git a/apps/assistedgps/custom.html b/apps/assistedgps/custom.html
index 80d68a71f..75a4ecf32 100644
--- a/apps/assistedgps/custom.html
+++ b/apps/assistedgps/custom.html
@@ -133,7 +133,7 @@
function jsFromBase64(b64) {
var bin = atob(b64);
var chunkSize = 128;
- var js = "\x10Bangle.setGPSPower(1);\n"; // turn GPS on
+ var js = "\x10Bangle.setGPSPower(1,'agps');\n"; // turn GPS on
if (isB1) { // UBLOX
//js += `\x10Bangle.on('GPS-raw',function (d) { if (d.startsWith("\\xB5\\x62\\x05\\x01")) Terminal.println("GPS ACK"); else if (d.startsWith("\\xB5\\x62\\x05\\x00")) Terminal.println("GPS NACK"); })\n`;
//js += "\x10var t=getTime()+1;while(t>getTime());\n"; // wait 1 sec
@@ -158,6 +158,7 @@
var chunk = bin.substr(i,chunkSize);
js += `\x10Serial1.write(atob("${btoa(chunk)}"))\n`;
}
+ js = "\x10setTimeout(() => Bangle.setGPSPower(0,'agps'), 1000);\n"; // turn GPS off after a delay
return js;
}
diff --git a/apps/assistedgps/metadata.json b/apps/assistedgps/metadata.json
index 4c91dcd35..ac9fe5725 100644
--- a/apps/assistedgps/metadata.json
+++ b/apps/assistedgps/metadata.json
@@ -1,7 +1,7 @@
{
"id": "assistedgps",
"name": "Assisted GPS Updater (AGPS)",
- "version": "0.03",
+ "version": "0.04",
"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.",
"sortorder": -1,
"icon": "app.png",
diff --git a/apps/backswipe/ChangeLog b/apps/backswipe/ChangeLog
new file mode 100644
index 000000000..5560f00bc
--- /dev/null
+++ b/apps/backswipe/ChangeLog
@@ -0,0 +1 @@
+0.01: New App!
diff --git a/apps/backswipe/app.png b/apps/backswipe/app.png
new file mode 100644
index 000000000..93019e1e2
Binary files /dev/null and b/apps/backswipe/app.png differ
diff --git a/apps/backswipe/boot.js b/apps/backswipe/boot.js
new file mode 100644
index 000000000..523149e8c
--- /dev/null
+++ b/apps/backswipe/boot.js
@@ -0,0 +1,50 @@
+(function () {
+ var DEFAULTS = {
+ mode: 0,
+ apps: [],
+ };
+ var settings = require("Storage").readJSON("backswipe.json", 1) || DEFAULTS;
+
+ // Overrride the default setUI method, so we can save the back button callback
+ var setUI = Bangle.setUI;
+ Bangle.setUI = function (mode, cb) {
+ var options = {};
+ if ("object"==typeof mode) {
+ options = mode;
+ }
+
+ var currentFile = global.__FILE__ || "";
+
+ if(global.BACK) delete global.BACK;
+ if (options && options.back && enabledForApp(currentFile)) {
+ global.BACK = options.back;
+ }
+ setUI(mode, cb);
+ };
+
+ function goBack(lr, ud) {
+ // if it is a left to right swipe
+ if (lr === 1) {
+ // if we're in an app that has a back button, run the callback for it
+ if (global.BACK) {
+ global.BACK();
+ }
+ }
+ }
+
+ // Check if the back button should be enabled for the current app
+ // app is the src file of the app
+ function enabledForApp(app) {
+ if (!settings) return true;
+ if (settings.mode === 0) {
+ return !(settings.apps.filter((a) => a.src === app).length > 0);
+ } else if (settings.mode === 1) {
+ return settings.apps.filter((a) => a.src === app).length > 0;
+ } else {
+ return settings.mode === 2 ? true : false;
+ }
+ }
+
+ // Listen to left to right swipe
+ Bangle.on("swipe", goBack);
+})();
diff --git a/apps/backswipe/metadata.json b/apps/backswipe/metadata.json
new file mode 100644
index 000000000..7aa9f6247
--- /dev/null
+++ b/apps/backswipe/metadata.json
@@ -0,0 +1,17 @@
+{ "id": "backswipe",
+ "name": "Back Swipe",
+ "shortName":"BackSwipe",
+ "version":"0.01",
+ "description": "Service that allows you to use an app's back button using left to right swipe gesture",
+ "icon": "app.png",
+ "tags": "back,gesture,swipe",
+ "supports" : ["BANGLEJS2"],
+ "type": "bootloader",
+ "storage": [
+ {"name":"backswipe.boot.js","url":"boot.js"},
+ {"name":"backswipe.settings.js","url":"settings.js"}
+ ],
+ "data": [
+ {"name":"backswipe.json"}
+ ]
+}
diff --git a/apps/backswipe/settings.js b/apps/backswipe/settings.js
new file mode 100644
index 000000000..2c29e86f8
--- /dev/null
+++ b/apps/backswipe/settings.js
@@ -0,0 +1,104 @@
+(function(back) {
+ var FILE = 'backswipe.json';
+ // Mode can be 'blacklist', 'whitelist', 'on' or 'disabled'
+ // Apps is an array of app info objects, where all the apps that are there are either blocked or allowed, depending on the mode
+ var DEFAULTS = {
+ 'mode': 0,
+ 'apps': []
+ };
+
+ var settings = {};
+
+ var loadSettings = function() {
+ settings = require('Storage').readJSON(FILE, 1) || DEFAULTS;
+ }
+
+ var saveSettings = function(settings) {
+ require('Storage').write(FILE, settings);
+ }
+
+ // Get all app info files
+ var getApps = function() {
+ var apps = require('Storage').list(/\.info$/).map(appInfoFileName => {
+ var appInfo = require('Storage').readJSON(appInfoFileName, 1);
+ return appInfo && {
+ 'name': appInfo.name,
+ 'sortorder': appInfo.sortorder,
+ 'src': appInfo.src
+ };
+ }).filter(app => app && !!app.src);
+ apps.sort((a, b) => {
+ var n = (0 | a.sortorder) - (0 | b.sortorder);
+ if (n) return n; // do sortorder first
+ if (a.name < b.name) return -1;
+ if (a.name > b.name) return 1;
+ return 0;
+ });
+ return apps;
+ }
+
+ var showMenu = function() {
+ var menu = {
+ '': { 'title': 'Backswipe' },
+ '< Back': () => {
+ back();
+ },
+ 'Mode': {
+ value: settings.mode,
+ min: 0,
+ max: 3,
+ format: v => ["Blacklist", "Whitelist", "Always On", "Disabled"][v],
+ onchange: v => {
+ settings.mode = v;
+ saveSettings(settings);
+ },
+ },
+ 'App List': () => {
+ showAppSubMenu();
+ }
+ };
+
+ E.showMenu(menu);
+ }
+
+ var showAppSubMenu = function() {
+ var menu = {
+ '': { 'title': 'Backswipe' },
+ '< Back': () => {
+ showMenu();
+ },
+ 'Add App': () => {
+ showAppList();
+ }
+ };
+ settings.apps.forEach(app => {
+ menu[app.name] = () => {
+ settings.apps.splice(settings.apps.indexOf(app), 1);
+ saveSettings(settings);
+ showAppSubMenu();
+ }
+ });
+ E.showMenu(menu);
+ }
+
+ var showAppList = function() {
+ var apps = getApps();
+ var menu = {
+ '': { 'title': 'Backswipe' },
+ '< Back': () => {
+ showMenu();
+ }
+ };
+ apps.forEach(app => {
+ menu[app.name] = () => {
+ settings.apps.push(app);
+ saveSettings(settings);
+ showAppSubMenu();
+ }
+ });
+ E.showMenu(menu);
+ }
+
+ loadSettings();
+ showMenu();
+})
\ No newline at end of file
diff --git a/apps/berlinc/ChangeLog b/apps/berlinc/ChangeLog
index 9e9c1a6aa..1a0a9c9cf 100644
--- a/apps/berlinc/ChangeLog
+++ b/apps/berlinc/ChangeLog
@@ -4,3 +4,5 @@
0.05: Update *on* the minute rather than every 15 secs
Now show widgets
Make compatible with themes, and Bangle.js 2
+0.06: Enable fastloading
+0.07: Adds fullscreen mode setting
\ No newline at end of file
diff --git a/apps/berlinc/berlin-clock.js b/apps/berlinc/berlin-clock.js
index 0dd8ff8ee..9391d2cc1 100644
--- a/apps/berlinc/berlin-clock.js
+++ b/apps/berlinc/berlin-clock.js
@@ -1,32 +1,41 @@
+{
// Berlin Clock see https://en.wikipedia.org/wiki/Mengenlehreuhr
// https://github.com/eska-muc/BangleApps
+
+var settings = require('Storage').readJSON("berlinc.json", true) || {};
const fields = [4, 4, 11, 4];
-const offset = 24;
-const width = g.getWidth() - 2 * offset;
-const height = g.getHeight() - 2 * offset;
-const rowHeight = height / 4;
-var show_date = false;
-var show_time = false;
-var yy = 0;
+let fullscreen = !!settings.fullscreen;
-var rowlights = [];
-var time_digit = [];
+let show_date = false;
+let show_time = false;
+let yy = 0;
+
+let rowlights = [];
+let time_digit = [];
// timeout used to update every minute
-var drawTimeout;
+let drawTimeout;
// schedule a draw for the next minute
-function queueDraw() {
+let queueDraw = () => {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
-}
+};
-function draw() {
- g.reset().clearRect(0,24,g.getWidth(),g.getHeight());
+let draw = () => {
+ let width = Math.min(Bangle.appRect.w,Bangle.appRect.h);
+ let height = width;
+ let offset = g.getHeight() - height;
+ let x = Math.floor((g.getWidth() - width)/2);
+
+ if (show_date) height -= 8;
+ let rowHeight = (height - 1) / 4;
+ g.setBgColor(g.theme.bg);
+ g.reset().clearRect(Bangle.appRect);
var now = new Date();
// show date below the clock
@@ -37,7 +46,7 @@ function draw() {
var dateString = `${yr}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
var strWidth = g.stringWidth(dateString);
g.setColor(g.theme.fg).setFontAlign(-1,-1);
- g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
+ g.drawString(dateString, ( Bangle.appRect.x + Bangle.appRect.w - strWidth ) / 2, Bangle.appRect.y2 - 5);
}
rowlights[0] = Math.floor(now.getHours() / 5);
@@ -50,15 +59,16 @@ function draw() {
time_digit[2] = Math.floor(now.getMinutes() / 10);
time_digit[3] = now.getMinutes() % 10;
- g.drawRect(offset, offset, width + offset, height + offset);
+ g.setColor(g.theme.fg);
+ g.drawRect(x, offset, x + width - 1, height + offset - 1);
for (row = 0; row < 4; row++) {
nfields = fields[row];
- boxWidth = width / nfields;
+ boxWidth = (width - 1) / nfields;
for (col = 0; col < nfields; col++) {
- x1 = col * boxWidth + offset;
+ x1 = col * boxWidth + x;
y1 = row * rowHeight + offset;
- x2 = (col + 1) * boxWidth + offset;
+ x2 = (col + 1) * boxWidth + x;
y2 = (row + 1) * rowHeight + offset;
g.setColor(g.theme.fg).drawRect(x1, y1, x2, y2);
@@ -84,33 +94,53 @@ function draw() {
queueDraw();
}
-function toggleDate() {
+let toggleDate = () => {
show_date = ! show_date;
draw();
}
-function toggleTime() {
+let toggleTime = () => {
show_time = ! show_time;
draw();
}
-// Stop updates when LCD is off, restart when on
-Bangle.on('lcdPower',on=>{
+let clear = () => {
+ if (drawTimeout) clearTimeout(drawTimeout);
+ drawTimeout = undefined;
+}
+
+let onLcdPower = on => {
if (on) {
draw(); // draw immediately, queue redraw
} else { // stop draw timer
- if (drawTimeout) clearTimeout(drawTimeout);
- drawTimeout = undefined;
+ clear();
}
-});
+}
+
+let cleanup = () => {
+ clear();
+ Bangle.removeListener("lcdPower", onLcdPower);
+ require("widget_utils").show();
+}
+
+// Stop updates when LCD is off, restart when on
+Bangle.on('lcdPower',onLcdPower);
// Show launcher when button pressed, handle up/down
-Bangle.setUI("clockupdown", dir=> {
+Bangle.setUI({mode: "clockupdown", remove: cleanup}, dir=> {
if (dir<0) toggleTime();
if (dir>0) toggleDate();
});
g.clear();
Bangle.loadWidgets();
+
+if (fullscreen){
+ if (process.env.HWVERSION == 2) require("widget_utils").swipeOn();
+ else require("widget_utils").hide();
+}
+
Bangle.drawWidgets();
+
draw();
+}
\ No newline at end of file
diff --git a/apps/berlinc/metadata.json b/apps/berlinc/metadata.json
index 85c42fc47..85567868b 100644
--- a/apps/berlinc/metadata.json
+++ b/apps/berlinc/metadata.json
@@ -1,7 +1,7 @@
{
"id": "berlinc",
"name": "Berlin Clock",
- "version": "0.05",
+ "version": "0.07",
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
"icon": "berlin-clock.png",
"type": "clock",
@@ -12,6 +12,8 @@
"screenshots": [{"url":"berlin-clock-screenshot.png"}],
"storage": [
{"name":"berlinc.app.js","url":"berlin-clock.js"},
+ {"name":"berlinc.settings.js","url":"settings.js"},
{"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true}
- ]
+ ],
+ "data": [{"name":"berlinc.json"}]
}
diff --git a/apps/berlinc/settings.js b/apps/berlinc/settings.js
new file mode 100644
index 000000000..a1b655a62
--- /dev/null
+++ b/apps/berlinc/settings.js
@@ -0,0 +1,26 @@
+(function(back) {
+ var FILE = "berlinc.json";
+ var settings = Object.assign({
+ fullscreem: false,
+ }, require('Storage').readJSON(FILE, true) || {});
+
+ function writeSettings() {
+ require('Storage').writeJSON(FILE, settings);
+ }
+
+ var mainmenu = {
+ "": {
+ "title": "Berlin clock"
+ },
+ "< Back": () => back(),
+ "Fullscreen": {
+ value: !!settings.fullscreen,
+ onchange: v => {
+ settings.fullscreen = v;
+ writeSettings();
+ }
+ }
+ };
+ E.showMenu(mainmenu);
+
+});
diff --git a/apps/bwclk/ChangeLog b/apps/bwclk/ChangeLog
index 33cd7ef63..06f94854e 100644
--- a/apps/bwclk/ChangeLog
+++ b/apps/bwclk/ChangeLog
@@ -28,4 +28,6 @@
0.27: Clean out some leftovers in the remove function after switching to
clkinfo.addInteractive that would cause ReferenceError.
0.28: Option to show (1) time only and (2) week of year.
-0.29: use setItem of clockInfoMenu to change the active item
\ No newline at end of file
+0.29: use setItem of clockInfoMenu to change the active item
+0.30: Use widget_utils
+0.31: Use clock_info module as an app
diff --git a/apps/bwclk/app.js b/apps/bwclk/app.js
index c2518361b..770c053c2 100644
--- a/apps/bwclk/app.js
+++ b/apps/bwclk/app.js
@@ -6,7 +6,7 @@
const locale = require('locale');
const storage = require('Storage');
const clock_info = require("clock_info");
-
+const widget_utils = require("widget_utils");
/************************************************
* Globals
@@ -132,6 +132,7 @@ clockInfoItems[0].items.unshift({ name : "nop",
let clockInfoMenu = clock_info.addInteractive(clockInfoItems, {
+ app: "bwclk",
x : 0,
y: 135,
w: W,
@@ -277,7 +278,7 @@ let drawLock = function() {
let drawWidgets = function() {
if(isFullscreen()){
- for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+ widget_utils.hide();
} else {
Bangle.drawWidgets();
}
@@ -318,7 +319,7 @@ let lockListenerBw = function(isLocked) {
if(!isLocked && settings.screen.toLowerCase() == "dynamic"){
// If we have to show the widgets again, we load it from our
// cache and not through Bangle.loadWidgets as its much faster!
- for (let wd of WIDGETS) {wd.draw=wd._draw;wd.area=wd._area;}
+ widget_utils.show();
}
draw();
@@ -362,16 +363,13 @@ Bangle.setUI({
kill();
E.removeListener("kill", kill);
g.setTheme(themeBackup);
+ widget_utils.show();
}
});
// Load widgets and draw clock the first time
Bangle.loadWidgets();
-// Cache draw function for dynamic screen to hide / show widgets
-// Bangle.loadWidgets() could also be called later on but its much slower!
-for (let wd of WIDGETS) {wd._draw=wd.draw; wd._area=wd.area;}
-
// Draw first time
draw();
diff --git a/apps/bwclk/metadata.json b/apps/bwclk/metadata.json
index a29102bdf..430f466b2 100644
--- a/apps/bwclk/metadata.json
+++ b/apps/bwclk/metadata.json
@@ -1,7 +1,7 @@
{
"id": "bwclk",
"name": "BW Clock",
- "version": "0.29",
+ "version": "0.31",
"description": "A very minimalistic clock.",
"readme": "README.md",
"icon": "app.png",
@@ -9,6 +9,7 @@
"type": "clock",
"tags": "clock,clkinfo",
"supports": ["BANGLEJS2"],
+ "dependencies" : { "clock_info":"module" },
"allow_emulator": true,
"storage": [
{"name":"bwclk.app.js","url":"app.js"},
diff --git a/apps/calendar/ChangeLog b/apps/calendar/ChangeLog
index db455679c..05eca83c0 100644
--- a/apps/calendar/ChangeLog
+++ b/apps/calendar/ChangeLog
@@ -10,3 +10,4 @@
0.09: Fix scope of let variables
0.10: Use default Bangle formatter for booleans
0.11: Fix off-by-one-error on next year
+0.12: Mark dated events on a day
diff --git a/apps/calendar/calendar.js b/apps/calendar/calendar.js
index f8785e52c..b61f2089c 100644
--- a/apps/calendar/calendar.js
+++ b/apps/calendar/calendar.js
@@ -22,15 +22,17 @@ let bgColorDow = color2;
let bgColorWeekend = color3;
let fgOtherMonth = gray1;
let fgSameMonth = white;
+let bgEvent = blue;
+const eventsPerDay=6; // how much different events per day we can display
+const timeutils = require("time_utils");
let settings = require('Storage').readJSON("calendar.json", true) || {};
let startOnSun = ((require("Storage").readJSON("setting.json", true) || {}).firstDayOfWeek || 0) === 0;
-if (settings.ndColors === undefined)
- if (process.env.HWVERSION == 2) {
- settings.ndColors = true;
- } else {
- settings.ndColors = false;
- }
+const events = (require("Storage").readJSON("sched.json",1) || []).filter(a => a.on && a.date); // all alarms that run on a specific date
+
+if (settings.ndColors === undefined) {
+ settings.ndColors = !g.theme.dark;
+}
if (settings.ndColors === true) {
bgColor = white;
@@ -39,6 +41,7 @@ if (settings.ndColors === true) {
bgColorWeekend = yellow;
fgOtherMonth = blue;
fgSameMonth = black;
+ bgEvent = color2;
}
function getDowLbls(locale) {
@@ -103,6 +106,12 @@ function getDowLbls(locale) {
return dowLbls;
}
+function sameDay(d1, d2) {
+ return d1.getFullYear() === d2.getFullYear() &&
+ d1.getMonth() === d2.getMonth() &&
+ d1.getDate() === d2.getDate();
+}
+
function drawCalendar(date) {
g.setBgColor(bgColor);
g.clearRect(0, 0, maxX, maxY);
@@ -188,14 +197,15 @@ function drawCalendar(date) {
for (x = 0; x < colN; x++) {
i++;
const day = days[i];
- const isToday =
- today.year === year && today.month === month && today.day === day - 50;
+ const curMonth = day < 15 ? month+1 : day < 50 ? month-1 : month;
+ const curDay = new Date(year, curMonth, day > 50 ? day-50 : day);
+ const isToday = sameDay(curDay, new Date());
+ const x1 = x * colW;
+ const y1 = y * rowH + headerH + rowH;
+ const x2 = x * colW + colW;
+ const y2 = y * rowH + headerH + rowH + rowH;
if (isToday) {
g.setColor(red);
- let x1 = x * colW;
- let y1 = y * rowH + headerH + rowH;
- let x2 = x * colW + colW;
- let y2 = y * rowH + headerH + rowH + rowH;
g.drawRect(x1, y1, x2, y2);
g.drawRect(
x1 + 1,
@@ -204,6 +214,22 @@ function drawCalendar(date) {
y2 - 1
);
}
+
+ // Display events for this day
+ const eventsCurDay = events.filter(ev => ev.date === curDay.toLocalISOString().substr(0, 10));
+ if (eventsCurDay.length > 0) {
+ g.setColor(bgEvent);
+ eventsCurDay.forEach(ev => {
+ const time = timeutils.decodeTime(ev.t);
+ const hour = time.h + time.m/60.0;
+ const slice = hour/24*(eventsPerDay-1); // slice 0 for 0:00 up to eventsPerDay for 23:59
+ const height = (y2-2) - (y1+2); // height of a cell
+ const sliceHeight = height/eventsPerDay;
+ const ystart = (y1+2) + slice*sliceHeight;
+ g.fillRect(x1+1, ystart, x2-2, ystart+sliceHeight);
+ });
+ }
+
require("Font8x12").add(Graphics);
g.setFont("8x12", fontSize);
g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
@@ -217,11 +243,6 @@ function drawCalendar(date) {
}
const date = new Date();
-const today = {
- day: date.getDate(),
- month: date.getMonth(),
- year: date.getFullYear()
-};
drawCalendar(date);
clearWatch();
Bangle.on("touch", area => {
diff --git a/apps/calendar/metadata.json b/apps/calendar/metadata.json
index 88f20026d..5bfc422fa 100644
--- a/apps/calendar/metadata.json
+++ b/apps/calendar/metadata.json
@@ -1,7 +1,7 @@
{
"id": "calendar",
"name": "Calendar",
- "version": "0.11",
+ "version": "0.12",
"description": "Simple calendar",
"icon": "calendar.png",
"screenshots": [{"url":"screenshot_calendar.png"}],
diff --git a/apps/chargent/ChangeLog b/apps/chargent/ChangeLog
new file mode 100644
index 000000000..7f837e50e
--- /dev/null
+++ b/apps/chargent/ChangeLog
@@ -0,0 +1 @@
+0.01: First version
diff --git a/apps/chargent/README.md b/apps/chargent/README.md
new file mode 100644
index 000000000..56bc763b4
--- /dev/null
+++ b/apps/chargent/README.md
@@ -0,0 +1,13 @@
+# Charge Gently
+
+Charging Li-ion batteries to their full capacity has a significant impact on their lifespan. If possible, it is good practice to charge more often, but only to a certain lower capacity.
+
+The first stage of charging Li-ion ends at ~80% capacity when the charge voltage reaches its peak*. When that happens, the watch will buzz twice every 30s to remind you to disconnect the watch.
+
+This app has no UI and no configuration. To disable the app, you have to uninstall it.
+
+Side notes
+- Full capacity is reached after charge current drops to an insignificant level. This is quite some time after charge voltage reached its peak / `E.getBattery()` returns 100.
+- This app starts buzzing some time after `E.getBattery()` returns 100 (~15min on my watch), and at least 5min after the peak to account for noise.
+
+\* according to https://batteryuniversity.com/article/bu-409-charging-lithium-ion assuming similar characteristics and readouts from pin `D30` approximate charge voltage
\ No newline at end of file
diff --git a/apps/chargent/boot.js b/apps/chargent/boot.js
new file mode 100644
index 000000000..802c3f55a
--- /dev/null
+++ b/apps/chargent/boot.js
@@ -0,0 +1,30 @@
+(() => {
+ var id;
+ Bangle.on('charging', (charging) => {
+ if (charging) {
+ if (!id) {
+ var max = 0;
+ var count = 0;
+ id = setInterval(() => {
+ var d30 = analogRead(D30);
+ if (max < d30) {
+ max = d30;
+ count = 0;
+ } else {
+ count++;
+ if (10 <= count) { // 10 * 30s == 5 min // TODO ? customizable
+ // TODO ? customizable
+ Bangle.buzz(500);
+ setTimeout(() => Bangle.buzz(500), 1000);
+ }
+ }
+ }, 30*1000);
+ }
+ } else {
+ if (id) {
+ clearInterval(id);
+ id = undefined;
+ }
+ }
+ });
+})();
diff --git a/apps/chargent/boot.min.js b/apps/chargent/boot.min.js
new file mode 100644
index 000000000..700198146
--- /dev/null
+++ b/apps/chargent/boot.min.js
@@ -0,0 +1 @@
+(function(){var a;Bangle.on("charging",function(e){if(e){if(!a){var c=0,b=0;a=setInterval(function(){var d=analogRead(D30);c Apps -> Clock Info`
+
+* `Defocus on Lock` - (default=on) when the watch screen auto-locks, defocus
+and previously focussed Clock Infos
+* `HRM` - (default=always) when does the HRM stay on?
+ * `Always` - When a HRM ClockInfo is shown, keep the HRM on
+ * `Tap` - When a HRM ClockInfo is shown, turn HRM on for 1 minute. Turn on again when tapped.
+* `Max Altitude` - on clocks like [Circles Clock](https://banglejs.com/apps/?id=circlesclock) a
+ progress/percent indicator may be shown. The percentage for altitude will be how far towards
+ the Max Altitude you are. If you go higher than `Max Altitude` the correct altitude will still
+ be shown - the percent indicator will just read 100%
+
+## API (Software development)
+
+See http://www.espruino.com/Bangle.js+Clock+Info for details on using
+this module inside your apps (or generating your own Clock Info
+extensions).
+
+`load()` returns an array of menu objects, where each object contains a list of menu items:
+* `name` : text to display and identify menu object (e.g. weather)
+* `img` : a 24x24px image
+* `dynamic` : if `true`, items are not constant but are sorted (e.g. calendar events sorted by date)
+* `items` : menu items such as temperature, humidity, wind etc.
+
+Note that each item is an object with:
+
+* `item.name` : friendly name to identify an item (e.g. temperature)
+* `item.hasRange` : if `true`, `.get` returns `v/min/max` values (for progress bar/guage)
+* `item.get` : function that returns an object:
+
+```JS
+{
+ 'text' // the text to display for this item
+ 'short' // optional: a shorter text to display for this item (at most 6 characters)
+ 'img' // optional: a 24x24px image to display for this item
+ 'color' // optional: a color string (like "#f00") to color the icon in compatible clocks
+ 'v' // (if hasRange==true) a numerical value
+ 'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
+}
+```
+
+* `item.show` : called when item should be shown. Enables updates. Call BEFORE 'get'
+* `item.hide` : called when item should be hidden. Disables updates.
+* `.on('redraw', ...)` : event that is called when 'get' should be called again (only after 'item.show')
+* `item.run` : (optional) called if the info screen is tapped - can perform some action. Return true if the caller should feedback the user.
+
+See the bottom of `lib.js` for example usage...
+
+example.clkinfo.js :
+
+```JS
+(function() {
+ return {
+ name: "Bangle",
+ img: atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
+ items: [
+ { name : "Item1",
+ get : () => ({ text : "TextOfItem1", v : 10, min : 0, max : 100,
+ img : atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==")
+ }),
+ show : () => {},
+ hide : () => {}
+ // run : () => {} optional (called when tapped)
+ }
+ ]
+ };
+}) // must not have a semi-colon!
+```
diff --git a/apps/clock_info/app-icon.js b/apps/clock_info/app-icon.js
new file mode 100644
index 000000000..49232b838
--- /dev/null
+++ b/apps/clock_info/app-icon.js
@@ -0,0 +1 @@
+require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="))
diff --git a/apps/clock_info/app.png b/apps/clock_info/app.png
new file mode 100644
index 000000000..4013f353f
Binary files /dev/null and b/apps/clock_info/app.png differ
diff --git a/modules/clock_info.js b/apps/clock_info/lib.js
similarity index 77%
rename from modules/clock_info.js
rename to apps/clock_info/lib.js
index b28271e9c..7251f1b00 100644
--- a/modules/clock_info.js
+++ b/apps/clock_info/lib.js
@@ -1,65 +1,30 @@
-/* Module that allows for loading of clock 'info' displays
-that can be scrolled through on the clock face.
-
-`load()` returns an array of menu objects, where each object contains a list of menu items:
-* `name` : text to display and identify menu object (e.g. weather)
-* `img` : a 24x24px image
-* `dynamic` : if `true`, items are not constant but are sorted (e.g. calendar events sorted by date)
-* `items` : menu items such as temperature, humidity, wind etc.
-
-Note that each item is an object with:
-
-* `item.name` : friendly name to identify an item (e.g. temperature)
-* `item.hasRange` : if `true`, `.get` returns `v/min/max` values (for progress bar/guage)
-* `item.get` : function that returns an object:
-
-{
- 'text' // the text to display for this item
- 'short' : (optional) a shorter text to display for this item (at most 6 characters)
- 'img' // optional: a 24x24px image to display for this item
- 'v' // (if hasRange==true) a numerical value
- 'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
-}
-
-* `item.show` : called when item should be shown. Enables updates. Call BEFORE 'get'
-* `item.hide` : called when item should be hidden. Disables updates.
-* `.on('redraw', ...)` : event that is called when 'get' should be called again (only after 'item.show')
-* `item.run` : (optional) called if the info screen is tapped - can perform some action. Return true if the caller should feedback the user.
-
-See the bottom of this file for example usage...
-
-example.clkinfo.js :
-
-(function() {
- return {
- name: "Bangle",
- img: atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
- items: [
- { name : "Item1",
- get : () => ({ text : "TextOfItem1", v : 10, min : 0, max : 100,
- img : atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==")
- }),
- show : () => {},
- hide : () => {}
- // run : () => {} optional (called when tapped)
- }
- ]
- };
-}) // must not have a semi-colon!
-
-*/
+/* See the README for more info... */
let storage = require("Storage");
let stepGoal = undefined;
// Load step goal from health app and pedometer widget
let d = storage.readJSON("health.json", true) || {};
-stepGoal = d != undefined && d.settings != undefined ? d.settings.stepGoal : undefined;
+stepGoal = d.stepGoal;
if (stepGoal == undefined) {
d = storage.readJSON("wpedom.json", true) || {};
stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
}
+// Load the settings, with defaults
+exports.loadSettings = function() {
+ return Object.assign({
+ hrmOn : 0, // 0(Always), 1(Tap)
+ defocusOnLock : true,
+ maxAltitude : 3000,
+ apps : {}
+ },
+ require("Storage").readJSON("clock_info.json",1)||{}
+ );
+};
+
exports.load = function() {
+ var settings = exports.loadSettings();
+ delete settings.apps; // keep just the basic settings in memory
// info used for drawing...
var hrm = 0;
var alt = "--";
@@ -110,8 +75,31 @@ exports.load = function() {
text : (hrm||"--") + " bpm", v : hrm, min : 40, max : 200,
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==")
}},
- show : function() { Bangle.setHRMPower(1,"clkinfo"); Bangle.on("HRM", hrmUpdateHandler); hrm = Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm); hrmUpdateHandler(); },
- hide : function() { Bangle.setHRMPower(0,"clkinfo"); Bangle.removeListener("HRM", hrmUpdateHandler); hrm = 0; },
+ run : function() {
+ Bangle.setHRMPower(1,"clkinfo");
+ if (settings.hrmOn==1/*Tap*/) {
+ /* turn off after 1 minute. If Health HRM monitoring is
+ enabled we will still get HRM events every so often */
+ this.timeout = setTimeout(function() {
+ this.timeout = undefined;
+ Bangle.setHRMPower(0,"clkinfo");
+ }, 60000);
+ }
+ },
+ show : function() {
+ Bangle.on("HRM", hrmUpdateHandler);
+ hrm = Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm); hrmUpdateHandler();
+ this.run(); // start HRM
+ },
+ hide : function() {
+ Bangle.setHRMPower(0,"clkinfo");
+ Bangle.removeListener("HRM", hrmUpdateHandler);
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = undefined;
+ }
+ hrm = 0;
+ },
}
],
}];
@@ -119,8 +107,10 @@ exports.load = function() {
if (Bangle.getPressure){ // Altimeter may not exist
bangleItems.push({ name : "Altitude",
+ hasRange : true,
get : () => ({
- text : alt, v : alt,
+ text : alt, v : parseInt(alt),
+ min : 0, max : settings.maxAltitude,
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA==")
}),
show : function() { this.interval = setInterval(altUpdateHandler, 60000); alt = "--"; altUpdateHandler(); },
@@ -145,9 +135,18 @@ exports.load = function() {
return menu;
};
+
/** Adds an interactive menu that could be used on a clock face by swiping.
Simply supply the menu data (from .load) and a function to draw the clock info.
+options = {
+ app : "str", // optional: app ID used when saving clock_info positions
+ // if defined, your app will remember its own positions,
+ // otherwise all apps share the same ones
+ x : 20, y: 20, w: 80, h:80, // dimensions of area used for clock_info
+ draw : (itm, info, options) // draw function
+}
+
For example:
let clockInfoItems = require("clock_info").load();
@@ -178,7 +177,7 @@ clockInfoMenu is the 'options' parameter, with the following added:
* `redraw` : function - force a redraw
* `focus` : function - bool to show if menu is focused or not
-You can have more than one clock_info at once as well, sfor instance:
+You can have more than one clock_info at once as well, for instance:
let clockInfoDraw = (itm, info, options) => {
g.reset().setBgColor(options.bg).setColor(options.fg).clearRect(options.x, options.y, options.x+options.w-2, options.y+options.h-1);
@@ -198,19 +197,19 @@ exports.addInteractive = function(menu, options) {
options.index = 0|exports.loadCount;
exports.loadCount = options.index+1;
options.focus = options.index==0 && options.x===undefined; // focus if we're the first one loaded and no position has been defined
- const appName = "default:"+options.index;
+ const appName = (options.app||"default")+":"+options.index;
- { // load the currently showing clock_infos
- let settings = require("Storage").readJSON("clock_info.json",1)||{};
- if (settings[appName]) {
- let a = settings[appName].a|0;
- let b = settings[appName].b|0;
- if (menu[a] && menu[a].items[b]) { // all ok
- options.menuA = a;
- options.menuB = b;
- }
+ // load the currently showing clock_infos
+ let settings = exports.loadSettings()
+ if (settings.apps[appName]) {
+ let a = settings.apps[appName].a|0;
+ let b = settings.apps[appName].b|0;
+ if (menu[a] && menu[a].items[b]) { // all ok
+ options.menuA = a;
+ options.menuB = b;
}
}
+
if (options.menuA===undefined) options.menuA = 0;
if (options.menuB===undefined) options.menuB = Math.min(exports.loadCount, menu[options.menuA].items.length)-1;
function drawItem(itm) {
@@ -259,33 +258,46 @@ exports.addInteractive = function(menu, options) {
menuShowItem(menu[options.menuA].items[options.menuB]);
}
// save the currently showing clock_info
- let settings = require("Storage").readJSON("clock_info.json",1)||{};
- settings[appName] = {a:options.menuA,b:options.menuB};
+ let settings = exports.loadSettings();
+ settings.apps[appName] = {a:options.menuA,b:options.menuB};
require("Storage").writeJSON("clock_info.json",settings);
}
Bangle.on("swipe",swipeHandler);
- var touchHandler;
+ let touchHandler, lockHandler;
if (options.x!==undefined && options.y!==undefined && options.w && options.h) {
touchHandler = function(_,e) {
if (e.x(options.x+options.w) || e.y>(options.y+options.h)) {
if (options.focus) {
options.focus=false;
+ delete Bangle.CLKINFO_FOCUS;
options.redraw();
}
return; // outside area
}
if (!options.focus) {
options.focus=true; // if not focussed, set focus
- options.redraw();
+ Bangle.CLKINFO_FOCUS=true;
+ options.redraw();
} else if (menu[options.menuA].items[options.menuB].run) {
Bangle.buzz(100, 0.7);
menu[options.menuA].items[options.menuB].run(); // allow tap on an item to run it (eg home assistant)
} else {
options.focus=true;
+ Bangle.CLKINFO_FOCUS=true;
}
};
Bangle.on("touch",touchHandler);
+ if (settings.defocusOnLock) {
+ lockHandler = function() {
+ if(options.focus) {
+ options.focus=false;
+ delete Bangle.CLKINFO_FOCUS;
+ options.redraw();
+ }
+ };
+ Bangle.on("lock", lockHandler);
+ }
}
// draw the first item
menuShowItem(menu[options.menuA].items[options.menuB]);
@@ -293,6 +305,8 @@ exports.addInteractive = function(menu, options) {
options.remove = function() {
Bangle.removeListener("swipe",swipeHandler);
if (touchHandler) Bangle.removeListener("touch",touchHandler);
+ if (lockHandler) Bangle.removeListener("lock", lockHandler);
+ delete Bangle.CLKINFO_FOCUS;
menuHideItem(menu[options.menuA].items[options.menuB]);
exports.loadCount--;
};
@@ -316,6 +330,8 @@ exports.addInteractive = function(menu, options) {
return true;
}
+
+ delete settings; // don't keep settings in RAM - save space
return options;
};
diff --git a/apps/clock_info/metadata.json b/apps/clock_info/metadata.json
new file mode 100644
index 000000000..457180588
--- /dev/null
+++ b/apps/clock_info/metadata.json
@@ -0,0 +1,18 @@
+{ "id": "clock_info",
+ "name": "Clock Info Module",
+ "shortName": "Clock Info",
+ "version":"0.01",
+ "description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)",
+ "icon": "app.png",
+ "type": "module",
+ "tags": "clkinfo",
+ "supports" : ["BANGLEJS2"],
+ "provides_modules" : ["clock_info"],
+ "readme": "README.md",
+ "storage": [
+ {"name":"clock_info","url":"lib.js"},
+ {"name":"clock_info.settings.js","url":"settings.js"}
+ ], "data": [
+ {"name":"clock_info.json","url":"lib.js"}
+ ]
+}
diff --git a/apps/clock_info/settings.js b/apps/clock_info/settings.js
new file mode 100644
index 000000000..a86fae473
--- /dev/null
+++ b/apps/clock_info/settings.js
@@ -0,0 +1,30 @@
+(function(back) {
+ let settings = require("clock_info").loadSettings();
+
+ function save(key, value) {
+ settings[key] = value;
+ require('Storage').write("clock_info.json", settings);
+ }
+
+ let menu ={
+ '': { 'title': 'Clock Info' },
+ /*LANG*/'< Back': back,
+ /*LANG*/'Defocus on Lock': {
+ value: !!settings.defocusOnLock,
+ onchange: x => save('defocusOnLock', x),
+ },
+ /*LANG*/'HRM': {
+ value: settings.hrmOn,
+ min: 0, max: 1, step: 1,
+ format: v => ["Always","Tap"][v],
+ onchange: x => save('hrmOn', x),
+ },
+ /*LANG*/'Max Altitude': {
+ value: settings.maxAltitude,
+ min: 500, max: 10000, step: 500,
+ format: v => v+"m",
+ onchange: x => save('maxAltitude', x),
+ }
+ };
+ E.showMenu(menu);
+})
diff --git a/apps/contourclock/ChangeLog b/apps/contourclock/ChangeLog
index 387340d5b..d13b16702 100644
--- a/apps/contourclock/ChangeLog
+++ b/apps/contourclock/ChangeLog
@@ -8,3 +8,5 @@
0.26: Time formatted to locale
0.27: Fixed the timing code, which sometimes did not update for one minute
0.28: More config options for cleaner look, enabled fast loading
+0.29: Fixed a bug that would leave old font files in storage.
+0.30: Added options to show widgets and date on twist and tap. New fonts.
diff --git a/apps/contourclock/app.js b/apps/contourclock/app.js
index 8efa406c6..407203e6c 100644
--- a/apps/contourclock/app.js
+++ b/apps/contourclock/app.js
@@ -1,64 +1,97 @@
{
- let digits = [];
let drawTimeout;
- let fontName="";
+ let extrasTimeout;
+ let onLock;
+ let onTap;
+ let onTwist;
let settings = require('Storage').readJSON("contourclock.json", true) || {};
- if (settings.fontIndex==undefined) {
- settings.fontIndex=0;
- settings.widgets=true;
- settings.hide=false;
- settings.weekday=true;
- settings.hideWhenLocked=false;
- settings.date=true; require('Storage').writeJSON("myapp.json", settings);
+ if (settings.fontIndex == undefined) {
+ settings.fontIndex = 0;
+ settings.widgets = true;
+ settings.weekday = true;
+ settings.hideWhenLocked = false;
+ settings.tapToShow = false;
+ settings.twistToShow = false;
+ settings.date = true;
+ require('Storage').writeJSON("contourclock.json", settings);
}
-
- let queueDraw = function() {
+ require("FontTeletext10x18Ascii").add(Graphics);
+ let extrasShown = (!settings.hidewhenlocked) && (!Bangle.isLocked());
+ let installedFonts = require('Storage').readJSON("contourclock-install.json") || {};
+ if (installedFonts.n > 0) { //New install - check for unused font files
+ settings.fontIndex = E.clip(settings.fontIndex, -installedFonts.n + 1, installedFonts.n - 1);
+ require('Storage').writeJSON("contourclock.json", settings);
+ for (let n = installedFonts.n;; n++) {
+ if (require("Storage").read("contourclock-" + n + ".json") == undefined) break;
+ require("Storage").erase("contourclock-" + n + ".json");
+ }
+ require("Storage").erase("contourclock-install.json");
+ }
+ let showExtras = function() { //show extras for a limited time
+ drawExtras();
+ if (extrasTimeout) clearTimeout(extrasTimeout);
+ extrasTimeout = setTimeout(() => {
+ extrasTimeout = undefined;
+ hideExtras();
+ }, 5000);
+ };
+ let drawExtras = function() { //draw date, day of the week and widgets
+ let date = new Date();
+ g.setFont("Teletext10x18Ascii").setFontAlign(0, 1);
+ if (settings.weekday) g.drawString(require("locale").dow(date).toUpperCase(), g.getWidth() / 2, g.getHeight() - 18);
+ if (settings.date) g.drawString(require('locale').date(date, 1), g.getWidth() / 2, g.getHeight());
+ require("widget_utils").show();
+ extrasShown = true;
+ };
+ let hideExtras = function() {
+ if (extrasTimeout) clearTimeout(extrasTimeout);
+ g.clearRect(0, 138, g.getWidth() - 1, 176);
+ require("widget_utils").hide();
+ extrasShown = false;
+ };
+ let draw = function() {
+ let date = new Date();
+ g.reset();
+ if (extrasShown) drawExtras();
+ else hideExtras();
+ require('contourclock').drawClock(settings.fontIndex);
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
- queueDraw();
}, 60000 - (Date.now() % 60000));
};
-
- let draw = function() {
- var date = new Date();
- // Draw day of the week
- g.reset();
- if ((!settings.hideWhenLocked) || (!Bangle.isLocked())) {
- // Draw day of the week
- g.setFont("Teletext10x18Ascii");
- g.clearRect(0,138,g.getWidth()-1,176);
- if (settings.weekday) g.setFontAlign(0,1).drawString(require("locale").dow(date).toUpperCase(),g.getWidth()/2,g.getHeight()-18);
- // Draw Date
- if (settings.date) g.setFontAlign(0,1).drawString(require('locale').date(new Date(),1),g.getWidth()/2,g.getHeight());
- }
- require('contourclock').drawClock(settings.fontIndex);
- };
-
- require("FontTeletext10x18Ascii").add(Graphics);
- g.clear();
-
- draw();
- if (settings.hideWhenLocked) Bangle.on('lock', function (locked) {
- if (!locked) require("widget_utils").show();
- else {
+ if (settings.hideWhenLocked) {
+ onLock = locked => {
+ if (!locked) {
+ require("widget_utils").show();
+ drawExtras();
+ } else {
+ require("widget_utils").hide();
+ hideExtras();
+ }
+ };
+ Bangle.on('lock', onLock);
+ if (settings.tapToShow) Bangle.on('tap', showExtras);
+ if (settings.twistToShow) Bangle.on('twist', showExtras);
+ }
+ Bangle.setUI({
+ mode: "clock",
+ remove: function() {
+ Bangle.removeListener('lock', onLock);
+ Bangle.removeListener('tap', showExtras);
+ Bangle.removeListener('twist', showExtras);
+ if (drawTimeout) clearTimeout(drawTimeout);
+ if (extrasTimeout) clearTimeout(extrasTimeout);
+ if (settings.hideWhenLocked) require("widget_utils").show();
+ g.reset();
g.clear();
- if (settings.hide) require("widget_utils").swipeOn();
- else require("widget_utils").hide();
}
- draw();
});
- Bangle.setUI({mode:"clock", remove:function() {
- if (drawTimeout) clearTimeout(drawTimeout);
- if (settings.widgets && settings.hide) require("widget_utils").show();
- g.reset();
- g.clear();
- }});
+ g.clear();
if (settings.widgets) {
Bangle.loadWidgets();
- if (settings.hide) require("widget_utils").swipeOn();
- else Bangle.drawWidgets();
+ Bangle.drawWidgets();
}
- queueDraw();
+ draw();
}
diff --git a/apps/contourclock/contourclock.settings.js b/apps/contourclock/contourclock.settings.js
index f2a75d9b5..064167312 100644
--- a/apps/contourclock/contourclock.settings.js
+++ b/apps/contourclock/contourclock.settings.js
@@ -4,11 +4,12 @@
if (settings.fontIndex==undefined) {
settings.fontIndex=0;
settings.widgets=true;
- settings.hide=false;
settings.weekday=true;
settings.date=true;
settings.hideWhenLocked=false;
- require('Storage').writeJSON("myapp.json", settings);
+ settings.tapToShow=false;
+ settings.twistToShow=false;
+ require('Storage').writeJSON("contourclock.json", settings);
}
function mainMenu() {
E.showMenu({
@@ -18,10 +19,6 @@
value: (settings.widgets !== undefined ? settings.widgets : true),
onchange : v => {settings.widgets=v; require('Storage').writeJSON('contourclock.json', settings);}
},
- 'hide Widgets': {
- value: (settings.hide !== undefined ? settings.hide : false),
- onchange : v => {settings.hide=v; require('Storage').writeJSON('contourclock.json', settings);}
- },
'Weekday': {
value: (settings.weekday !== undefined ? settings.weekday : true),
onchange : v => {settings.weekday=v; require('Storage').writeJSON('contourclock.json', settings);}
@@ -30,10 +27,18 @@
value: (settings.date !== undefined ? settings.date : true),
onchange : v => {settings.date=v; require('Storage').writeJSON('contourclock.json', settings);}
},
- 'Hide when locked': {
+ 'Hide widgets, weekday and date when locked': {
value: (settings.hideWhenLocked !== undefined ? settings.hideWhenLocked : false),
onchange : v => {settings.hideWhenLocked=v; require('Storage').writeJSON('contourclock.json', settings);}
},
+ 'Tap to show': {
+ value: (settings.tapToShow !== undefined ? settings.tapToShow : false),
+ onchange : v => {settings.tapToShow=v; require('Storage').writeJSON('contourclock.json', settings);}
+ },
+ 'Twist to show': {
+ value: (settings.twistToShow !== undefined ? settings.twistToShow : false),
+ onchange : v => {settings.twistToShow=v; require('Storage').writeJSON('contourclock.json', settings);}
+ },
'set Font': () => fontMenu()
});
}
diff --git a/apps/contourclock/custom.html b/apps/contourclock/custom.html
index 602182573..71cc788c7 100644
--- a/apps/contourclock/custom.html
+++ b/apps/contourclock/custom.html
@@ -14,60 +14,54 @@
- Select Fonts to upload:
+ Select Fonts to upload:
diff --git a/apps/contourclock/font-Dosis.json b/apps/contourclock/font-Dosis.json
deleted file mode 100644
index c206bab7e..000000000
--- a/apps/contourclock/font-Dosis.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name":"Dosis",
- "size":"100",
- "characters":[
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf//////VVVVVVVVVVVVVVf////////1VVVVVVVVVVVX//AAAAAAD//VVVVVVVVVVf/AAAAAAAAA//VVVVVVVVV/wAAAAAAAAAAD/VVVVVVVX/AAAAAAAAAAAAD9VVVVVVX8AAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAAAP1VVVVXwAAAAAAAAAAAAAAA/VVVVXwAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAAD1V8AAAAAAAAP/AAAAAAAAA9V8AAAAAAAD///wAAAAAAAPVfAAAAAAAD/VX/wAAAAAAA9XwAAAAAAP1VVV/AAAAAAAPXwAAAAAAP1VVVV8AAAAAAD18AAAAAAPVVVVVXwAAAAAA9fAAAAAAD1VVVVVfAAAAAAD3wAAAAAD1VVVVVXwAAAAAA98AAAAAA9VVVVVVfAAAAAAPfAAAAAA9VVVVVVXwAAAAAD3wAAAAAPVVVVVVV8AAAAAA98AAAAAD1VVVVVVXwAAAAAP8AAAAAA9VVVVVVV8AAAAAD/AAAAAAPVVVVVVVfAAAAAA/wAAAAAD1VVVVVVXwAAAAAP8AAAAAA9VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVX/9VVfAAAAAA/wAAAAAPVVf//9VXwAAAAAP8AAAAAD1VfwAP1V8AAAAAD/AAAAAA9VfAAA9VfAAAAAA/wAAAAAPVXwAAD1XwAAAAAP8AAAAAD1V8AAA9V8AAAAAD/AAAAAA9V8AAAPVfAAAAAA/wAAAAAPVfAAAD1XwAAAAAP8AAAAAD1V8AAA9V8AAAAAD/AAAAAA9VfAAAPVfAAAAAA/wAAAAAPVXwAAD1XwAAAAAP8AAAAAD1V8AAD1V8AAAAAD/AAAAAA9VX8AD1VfAAAAAA/wAAAAAPVVf//1VXwAAAAAP8AAAAAD1VVf/1VV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAAPVVVVVVVfAAAAAA/wAAAAAD1VVVVVVXwAAAAAP8AAAAAA9VVVVVVV8AAAAAD/AAAAAAPVVVVVVVfAAAAAA98AAAAAD1VVVVVVfAAAAAAPfAAAAAA9VVVVVVXwAAAAAD3wAAAAAPVVVVVVV8AAAAAA98AAAAAA9VVVVVVfAAAAAAPfAAAAAAPVVVVVVfAAAAAAD3wAAAAAA9VVVVVXwAAAAAA98AAAAAAD1VVVVXwAAAAAA9fAAAAAAAPVVVVfwAAAAAAPV8AAAAAAA/VVVfwAAAAAAD1fAAAAAAAD////AAAAAAAA9XwAAAAAAAD///AAAAAAAA9VfAAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVV/AAAAAAAAAAAAAAAPVVVVVX8AAAAAAAAAAAAAAPVVVVVVXwAAAAAAAAAAAAA/VVVVVVVfwAAAAAAAAAAAD/VVVVVVVV/8AAAAAAAAAA/9VVVVVVVVV//wAAAAAAAP/1VVVVVVVVVVf//AAAAA//9VVVVVVVVVVVVV////////VVVVVVVVVVVVVVVX////9VVVVVVVVQ=="},
- {"width" : "36", "buffer":"VVVVVVVX/1VVVVVVVVV///1VVVVVVVf8AP/VVVVVVX/AAAP1VVVVVfwAAAA9VVVVX8AAAAA9VVVV/wAAAAA9VVVX8AAAAAAPVVV/AAAAAAAPVVf8AAAAAAAPVV/AAAAAAAAPVfwAAAAAAAAPV/AAAAAAAAAPXwAAAAAAAAAPfAAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAP8AAAAAAAAAAPfAAAwAAAAAAPfAAP8AAAAAAPX///fAAAAAAPV//1fAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAAPVVVVfAAAAAA9VVVVXwAAAAA9VVVVXwAAAAD9VVVVV/wAAA/1VVVVVf////9VVVVVVVf///VVVVVVVVVVVVVV"},
- {"width" : "65", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////1VVVVVVVVVVVVVVf///////1VVVVVVVVVVVV//AAAAAD//VVVVVVVVVVV/8AAAAAAAD/1VVVVVVVVV/wAAAAAAAAAP1VVVVVVVVfwAAAAAAAAAAD9VVVVVVVfwAAAAAAAAAAAD/VVVVVVX8AAAAAAAAAAAAA/VVVVVV8AAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAPVXwAAAAAAAP//AAAAAAAA9VfAAAAAAAP///wAAAAAAA9V8AAAAAAD9VVfwAAAAAAD1fAAAAAAA9VVVXwAAAAAAPV8AAAAAAPVVVVXwAAAAAA9XwAAAAAD1VVVVXwAAAAAA9fAAAAAAPVVVVVfAAAAAAD18AAAAAD1VVVVVfAAAAAAPXwAAAAAPVVVVVV8AAAAAA9fAAAAAA9VVVVVXwAAAAAD18AAAAAD1VVVVVfAAAAAAPXwAAAAAPVVVVVV8AAAAAA9fAAAAAA9VVVVVXwAAAAAD1fAAAAAPVVVVVVfAAAAAAPV8AAAAA9VVVVVXwAAAAAD1V8AAAAPVVVVVVfAAAAAAPVV8AAAP1VVVVVXwAAAAAA9VV////9VVVVVVfAAAAAAD1VV///9VVVVVVXwAAAAAAPVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVV/AAAAAAAAPVVVVVVVVVVVfwAAAAAAAD1VVVVVVVVVVXwAAAAAAAA9VVVVVVVVVVV8AAAAAAAAD1VVVVVVVVVV/AAAAAAAAA9VVVVVVVVVVfwAAAAAAAAPVVVVVVVVVVXwAAAAAAAAD1VVVVVVVVVX8AAAAAAAAA9VVVVVVVVVV/AAAAAAAAAPVVVVVVVVVVfAAAAAAAAAD1VVVVVVVVVfwAAAAAAAAA9VVVVVVVVVX8AAAAAAAAA/VVVVVVVVVV8AAAAAAAAAP1VVVVVVVVVfAAAAAAAAAD1VVVVVVVVVfwAAAAAAAAD9VVVVVVVVVX8AAAAAAAAA/VVVVVVVVVV8AAAAAAAAA/VVVVVVVVVVfAAAAAAAAAP1VVVVVVVVVXwAAAAAAAAD1VVVVVVVVVV8AAAAAAAAD9VVVVVVVVVVfAAAAAAAAA/VVVVVVVVVVXwAAAAAAAA/VVVVVVVVVVVfAAAAAAAAP1VVVVVVVVVVXwAAAAAAAP1VVVVVVVVVVV8AAAAAAAD9VVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVfAAAAAAA////////////1V8AAAAAAA////////////9XwAAAAAAAAAAAAAAAAAAD9fAAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAAD1X/AAAAAAAAAAAAAAAAAAPVV///////////////////1VVf/////////////////9VVVVVVVVVVVVVVVVVVVVVVU="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////9VVVVVVVVVVVVVV/////////9VVVVVVVVVVVX/8AAAAAAP/9VVVVVVVVVVf8AAAAAAAAAP9VVVVVVVVV/wAAAAAAAAAAP9VVVVVVVX/AAAAAAAAAAAAP9VVVVVVX8AAAAAAAAAAAAAP1VVVVVXwAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAA9VV8AAAAAAAP//wAAAAAAAPVVfAAAAAAA////wAAAAAAD1VfAAAAAAA/VVV/wAAAAAA9VXwAAAAAA9VVVV/AAAAAAPVV8AAAAAA9VVVVV8AAAAAD1VfAAAAAAPVVVVVfAAAAAAPVXwAAAAAD1VVVVV8AAAAAD1V8AAAAAD1VVVVVfAAAAAA9VfAAAAAA9VVVVVXwAAAAAPVXwAAAAAPVVVVVV8AAAAAPVV8AAAAAD1VVVVVfAAAAAD1VfAAAAAA9VVVVVXwAAAAA9VV8AAAAA9VVVVVV8AAAAAPVVXwAAAA9VVVVVVfAAAAAD1VVf////9VVVVVVXwAAAAA9VVV////9VVVVVVV8AAAAAPVVVVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVf//AAAAAAD1VVVVVVVVVVV///AAAAAAD1VVVVVVVVVVV/AAAAAAAAA9VVVVVVVVVVV8AAAAAAAAA9VVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVVVfAAAAAAAAA/VVVVVVVVVVVXwAAAAAAAA/VVVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVXwAAAAAAAA/VVVVVVVVVVVV8AAAAAAAAD/VVVVVVVVVVVfAAAAAAAAAD9VVVVVVVVVVXwAAAAAAAAAD1VVVVVVVVVVfAAAAAAAAAAPVVVVVVVVVVXwAAAAAAAAAA9VVVVVVVVVVfAAAAAAAAAAD1VVVVVVVVVV//8AAAAAAAA9VVVVVVVVVVX///AAAAAAAD1VVVVVVVVVVVVf/AAAAAAA9VVVVVVVVVVVVVX8AAAAAAD1VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVVVXwAAAAAPVX////VVVVVVVVV8AAAAAD1f/////VVVVVVVVfAAAAAA9fwAAAD9VVVVVVVXwAAAAAPfAAAAAPVVVVVVVV8AAAAAD3wAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAA9VVVVVVXwAAAAAD/AAAAAAPVVVVVVXwAAAAAD3wAAAAAA9VVVVVV8AAAAAA98AAAAAAD1VVVVX8AAAAAAPXwAAAAAAP1VVVX8AAAAAAD18AAAAAAA//1f/wAAAAAAA9fAAAAAAAA////wAAAAAAA9XwAAAAAAAAA/AAAAAAAAAPVfAAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVX8AAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAA/VVVVVVfwAAAAAAAAAAAAD/VVVVVVV/wAAAAAAAAAAAP9VVVVVVVV/wAAAAAAAAAA/1VVVVVVVVV/8AAAAAAAA//VVVVVVVVVVV//wAAAAD//9VVVVVVVVVVVVf///////9VVVVVVVVVVVVVVV/////1VVVVVVVVQ=="},
- {"width" : "73", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX//9VVVVVVVVVVVVVVVVVVVVf///9VVVVVVVVVVVVVVVVVVVfwAAP9VVVVVVVVVVVVVVVVVVfAAAAP1VVVVVVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVfAAAAAAD1VVV/VVVVVVVVVVVXwAAAAAD1VX////VVVVVVVVVXwAAAAAA9Vf/8D//VVVVVVVVV8AAAAAA9VfwAAAD9VVVVVVVV8AAAAAAPVfAAAAAD1VVVVVVVfAAAAAAPVXwAAAAA9VVVVVVVfAAAAAAD1XwAAAAAPVVVVVVVXwAAAAAD1V8AAAAAA9VVVVVVXwAAAAAA9VfAAAAAAPVVVVVVV8AAAAAA9VXwAAAAAD1VVVVVV8AAAAAAPVV8AAAAAA9VVVVVVfAAAAAAPVVfAAAAAAPVVVVVVfAAAAAAD1VXwAAAAAD1VVVVVXwAAAAAD1VV8AAAAAA9VVVVVXwAAAAAA9VVfAAAAAAPVVVVVV8AAAAAA9VVXwAAAAAD1VVVVV8AAAAAAD///wAAAAAAP/9VVVfAAAAAAAP//wAAAAAAA//9VVfAAAAAAAAAAAAAAAAAAAAP1VXwAAAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAAAA9V/wAAAAAAAAAAAAAAAAAAAD9VX///////////wAAAAAAA//9VVV///////////AAAAAAA//1VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVVVX8AAAAD9VVVVVVVVVVVVVVVVVf8AAAP9VVVVVVVVVVVVVVVVVVf////1VVVVVVVVVVVVVVVVVVVf///VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVX////////////////VVVVVV////////////////9VVVVV8AAAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAA9VVVVfAAAAAA//////////9VVVVXwAAAAA//////////9VVVVV8AAAAA9VVVVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVXwAAAAAP///VVVVVVVVVVVV8AAAAAA//////VVVVVVVVVfAAAAAAAAAD///9VVVVVVVXwAAAAAAAAAAAD//VVVVVVV8AAAAAAAAAAAAAP/1VVVVVfAAAAAAAAAAAAAAD/VVVVVXwAAAAAAAAAAAAAAA/VVVVV8AAAAAAAAAAAAAAAD9VVVVfAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAAPVVVfwAAAAAAAAAAAAAAAAD1VVV/////////wAAAAAAAAPVVVV/////////8AAAAAAAD1VVVVVVVVVVVV/8AAAAAAA9VVVVVVVVVVVVVfwAAAAAAD1VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVVVfAAAAAA9VX///9VVVVVVVVXwAAAAAPVf////9VVVVVVVV8AAAAAD1/wAAAP1VVVVVVVfAAAAAA9fAAAAA9VVVVVVVXwAAAAAPfAAAAAD1VVVVVVV8AAAAAD3wAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAAPVVVVVVV8AAAAAA/wAAAAAD1VVVVVVfAAAAAAP8AAAAAA9VVVVVVfAAAAAAPfAAAAAAD1VVVVVXwAAAAAD3wAAAAAAPVVVVVXwAAAAAA9fAAAAAAA9VVVVfwAAAAAAPXwAAAAAAD9VVVfwAAAAAAD18AAAAAAAP////AAAAAAAD1fAAAAAAAAP///AAAAAAAA9V8AAAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAPVVVVVX8AAAAAAAAAAAAAAPVVVVVVfwAAAAAAAAAAAAA/VVVVVVVfwAAAAAAAAAAAD/VVVVVVVV/8AAAAAAAAAA/9VVVVVVVVV//AAAAAAAAP/1VVVVVVVVVVf//AAAAA//9VVVVVVVVVVVVX////////VVVVVVVVVVVVVVVX////9VVVVVVVVQ=="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf//////VVVVVVVVVVVVVVX////////9VVVVVVVVVVVX//AAAAAAD//VVVVVVVVVVf/wAAAAAAAAP/VVVVVVVVV/wAAAAAAAAAAD/VVVVVVVX/AAAAAAAAAAAAD9VVVVVVX8AAAAAAAAAAAAAD9VVVVVXwAAAAAAAAAAAAAAP1VVVVXwAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAAD1XwAAAAAAAAP/8AAAAAAAA9V8AAAAAAAD////AAAAAAAD18AAAAAAAP/VVf8AAAAAAA9fAAAAAAAP1VVVXwAAAAAAPXwAAAAAAPVVVVVfAAAAAAD18AAAAAAPVVVVVV8AAAAAA98AAAAAAPVVVVVVXwAAAAAPfAAAAAAD1VVVVVV8AAAAAA/wAAAAAD1VVVVVVXwAAAAAP8AAAAAA9VVVVVVV8AAAAAD/AAAAAAPVVVVVVVfAAAAAD3wAAAAAPVVVVVVVXwAAAAA98AAAAAD1VVVVVVV8AAAAAPfAAAAAA9VVVVVVVXwAAAAD3wAAAAAPVVVVVVVVfwAAAP18AAAAAD1VVVVVVVV//8//1fAAAAAA9VVVVVVVVV////VXwAAAAAPVVVVVVVVVVVdVVV8AAAAAD1VVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVVVXwAAAAAPVVVf///9VVVVVVV8AAAAAD1Vf//////1VVVVVfAAAAAA9X//AAAAP/9VVVVXwAAAAAPX/AAAAAAA/9VVVV8AAAAAA/wAAAAAAAAP9VVVfAAAAAADwAAAAAAAAAP1VVXwAAAAAAAAAAAAAAAAAP1VV8AAAAAAAAAAAAAAAAAA/VVfAAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAAD18AAAAAAAAD//8AAAAAAAA9fAAAAAAAAP///8AAAAAAAPXwAAAAAAA/1VVfwAAAAAAA98AAAAAAA/VVVVfAAAAAAAPfAAAAAAA9VVVVV8AAAAAAD3wAAAAAA9VVVVVXwAAAAAA98AAAAAAPVVVVVVfAAAAAAPfAAAAAAPVVVVVVXwAAAAAD3wAAAAAD1VVVVVVfAAAAAA98AAAAAD1VVVVVVXwAAAAAPfAAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAA98AAAAAD1VVVVVVXwAAAAAPfAAAAAAPVVVVVVV8AAAAAD3wAAAAAD1VVVVVVfAAAAAA98AAAAAA9VVVVVVXwAAAAAPXwAAAAAD1VVVVVXwAAAAAD18AAAAAA9VVVVVXwAAAAAA9fAAAAAAD1VVVVV8AAAAAAPXwAAAAAAPVVVVX8AAAAAAPV8AAAAAAA/VVVX8AAAAAAD1XwAAAAAAD/1V/wAAAAAAA9V8AAAAAAAD///wAAAAAAA9VfAAAAAAAAA/8AAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAPVVVVVX8AAAAAAAAAAAAAA/VVVVVVfwAAAAAAAAAAAAA/VVVVVVVfwAAAAAAAAAAAD9VVVVVVVV/8AAAAAAAAAA/9VVVVVVVVV//AAAAAAAA//1VVVVVVVVVVf//AAAAA//9VVVVVVVVVVVVX///////9VVVVVVVVVVVVVVVX////9VVVVVVVVQ=="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVV//////////////////9VVX///////////////////9VX8AAAAAAAAAAAAAAAAAAP9XwAAAAAAAAAAAAAAAAAAAP3wAAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAP8AAAAAAP//////8AAAAAAD/AAAAAAP///////wAAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAAP8AAAAAD1VVVVVVV8AAAAAD/AAAAAA9VVVVVVVfAAAAAA/wAAAAAPVVVVVVVXwAAAAA98AAAAAD1VVVVVVXwAAAAAPfAAAAAA9VVVVVVV8AAAAAD3wAAAAAPVVVVVVVfAAAAAA98AAAAAPVVVVVVVfAAAAAA9XwAAAAD1VVVVVVXwAAAAAPVfwAAA/1VVVVVVXwAAAAAD1V/////1VVVVVVXwAAAAAD1VV///9VVVVVVVV8AAAAAA9VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVVVV/AAAAD1VVVVVVVVVVVVVVVX/AAAA9VVVVVVVVVVVVVVVVX/AAD9VVVVVVVVVVVVVVVVVX///9VVVVVVVVVVVVVVVVVVX//1VVVVVVVVVVVVQ=="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////9VVVVVVVVVVVVVVf////////1VVVVVVVVVVVX/8AAAAAAP/9VVVVVVVVVVf/AAAAAAAAA/9VVVVVVVVV/wAAAAAAAAAAP9VVVVVVVX/AAAAAAAAAAAAP1VVVVVVX8AAAAAAAAAAAAAPVVVVVVXwAAAAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAPVVV8AAAAAAAP//AAAAAAAA9VVfAAAAAAAP///AAAAAAAPVVXwAAAAAAPVVX8AAAAAAD1VXwAAAAAAPVVVXwAAAAAA9VV8AAAAAAPVVVVfAAAAAAPVVfAAAAAAPVVVVV8AAAAAD1VXwAAAAAPVVVVVfAAAAAAPVV8AAAAAD1VVVVXwAAAAAD1VfAAAAAA9VVVVVfAAAAAA9VXwAAAAAPVVVVVXwAAAAAPVV8AAAAAD1VVVVV8AAAAAPVVfAAAAAA9VVVVVfAAAAAD1VXwAAAAAPVVVVVXwAAAAA9VVfAAAAAD1VVVVXwAAAAAPVVXwAAAAA9VVVVV8AAAAAD1VV8AAAAAD1VVVVfAAAAAA9VVfAAAAAA9VVVVfAAAAAA9VVV8AAAAAD1VVVfAAAAAAPVVVfAAAAAAP1VV/AAAAAAD1VVXwAAAAAA////AAAAAAD1VVVfAAAAAAA//8AAAAAAA9VVVV8AAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAAAA9VVVVVX8AAAAAAAAAAAAAA9VVVVVVf8AAAAAAAAAAAAD9VVVVVVVfwAAAAAAAAAAAD9VVVVVVVVfAAAAAAAAAAAD1VVVVVVVVXwAAAAAAAAAAA9VVVVVVVVXwAAAAAAAAAAAD1VVVVVVVfwAAAAAAAAAAAAP1VVVVVVfwAAAAAAAAAAAAA/VVVVVV/AAAAAAAAAAAAAAA/VVVVV/AAAAAAAAAAAAAAAD9VVVV8AAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVV8AAAAAAAP//wAAAAAAD1VVfAAAAAAA////wAAAAAAPVVfAAAAAAD/VVV/AAAAAAD1VXwAAAAAD9VVVV8AAAAAAPVXwAAAAAD1VVVVXwAAAAAD1V8AAAAAD1VVVVVfAAAAAAPV8AAAAAA9VVVVVV8AAAAAD1fAAAAAA9VVVVVVfAAAAAAPXwAAAAAPVVVVVVV8AAAAAD18AAAAAPVVVVVVVfAAAAAA98AAAAAD1VVVVVVXwAAAAAPfAAAAAA9VVVVVVV8AAAAAD3wAAAAAPVVVVVVVfAAAAAA98AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAD1VVVVVVfAAAAAAP8AAAAAA9VVVVVVfAAAAAAD/AAAAAAPVVVVVVXwAAAAAD3wAAAAAA9VVVVVXwAAAAAA98AAAAAAD1VVVVV8AAAAAAPXwAAAAAAPVVVVX8AAAAAAD18AAAAAAA/VVVX8AAAAAAA9fAAAAAAAD/VV/wAAAAAAAPXwAAAAAAAD///wAAAAAAAPVfAAAAAAAAD/8AAAAAAAAD1XwAAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAP1VVVXwAAAAAAAAAAAAAAAP1VVVVfwAAAAAAAAAAAAAAPVVVVVV/wAAAAAAAAAAAAA/VVVVVVV/wAAAAAAAAAAAD/VVVVVVVV/wAAAAAAAAAAP9VVVVVVVVV//AAAAAAAAP/1VVVVVVVVVV//8AAAAA///VVVVVVVVVVVVX////////VVVVVVVVVVVVVVVf////9VVVVVVVVQ=="},
- {"width" : "67", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////9VVVVVVVVVVVVVVf////////1VVVVVVVVVVVf/8AAAAAAP/9VVVVVVVVVV//AAAAAAAAA/9VVVVVVVVX/AAAAAAAAAAAP9VVVVVVVX8AAAAAAAAAAAAP9VVVVVVXwAAAAAAAAAAAAAP1VVVVVfwAAAAAAAAAAAAAAPVVVVVfwAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAA9VfAAAAAAAAP//wAAAAAAAPVXwAAAAAAA////AAAAAAAA9V8AAAAAAD/VVV/AAAAAAAPV8AAAAAAD9VVVX8AAAAAAD1fAAAAAAD1VVVVXwAAAAAAPXwAAAAAD1VVVVVfAAAAAAD18AAAAAA9VVVVVV8AAAAAA9fAAAAAA9VVVVVVfAAAAAAPfAAAAAAPVVVVVVV8AAAAAD3wAAAAAD1VVVVVVfAAAAAA98AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAA/wAAAAAPVVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAAPVVVVVVV8AAAAAA/wAAAAAD1VVVVVVfAAAAAAP8AAAAAA9VVVVVVfAAAAAAD/AAAAAAD1VVVVVXwAAAAAA/wAAAAAAPVVVVVXwAAAAAAPfAAAAAAA9VVVVXwAAAAAAD3wAAAAAAD1VVVfwAAAAAAA98AAAAAAAP9VX/wAAAAAAAPfAAAAAAAA////AAAAAAAAD18AAAAAAAAP/wAAAAAAAAA9fAAAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1VX8AAAAAAAAAAAAAAAAAA9VVfwAAAAAAAAAAAAAAAAAPVVVfwAAAAAAAAA8AAAAAAD1VVV/wAAAAAAAD/wAAAAAA9VVVV//AAAAAAP9fAAAAAAPVVVVV///8AD//1XwAAAAAD1VVVVVX//////VV8AAAAAA9VVVVVVVVf/1VVVfAAAAAAPVVVVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVVVV8AAAAAA9VX//9VVVVVVVVVfAAAAAAPVf////VVVVVVVVXwAAAAAD1/wAAP9VVVVVVVV8AAAAAA9/AAAAD1VVVVVVVfAAAAAAPfAAAAAPVVVVVVVXwAAAAAD/AAAAAD1VVVVVVV8AAAAAA/wAAAAA9VVVVVVVfAAAAAAP8AAAAAD1VVVVVVXwAAAAAD/AAAAAA9VVVVVVV8AAAAAD3wAAAAAPVVVVVVV8AAAAAA98AAAAAD1VVVVVVfAAAAAAPfAAAAAAPVVVVVVfAAAAAAD3wAAAAAA9VVVVVfAAAAAAA98AAAAAAD1VVVVfAAAAAAAPfAAAAAAAP1VVV/AAAAAAAPV8AAAAAAA/////AAAAAAAD1fAAAAAAAA///8AAAAAAAA9XwAAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAA9VVVVVfwAAAAAAAAAAAAAA9VVVVVV/AAAAAAAAAAAAAD9VVVVVVV/AAAAAAAAAAAAP9VVVVVVVX/wAAAAAAAAAD/1VVVVVVVVX/8AAAAAAAD//VVVVVVVVVVV//wAAAAD//1VVVVVVVVVVVVf///////1VVVVVVVVVVVVVVV/////1VVVVVVVVQ=="},
- {"width" : "21", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf//VVVX///9VVfwAA/VV8AAAD1XwAAAA9fAAAAAPfAAAAAPfAAAAAP8AAAAAP8AAAAAD8AAAAAD8AAAAAD8AAAAADfAAAAAPfAAAAAPfAAAAAPXwAAAA9XwAAAD1V/AAAP1Vf/AP9VVV///1VVVV/1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/1VVVV///1VVf/AP/VV/AAAP1XwAAAA9XwAAAA9fAAAAAPfAAAAAPfAAAAAP8AAAAAD8AAAAAD8AAAAAD8AAAAAD8AAAAAPfAAAAAPfAAAAAPfAAAAA9XwAAAA9V8AAAD1VfwAA/VVX///9VVVf//VV"},
- ]
-}
-
diff --git a/apps/contourclock/font-SairaCond.json b/apps/contourclock/font-SairaCond.json
deleted file mode 100644
index b6757f7ad..000000000
--- a/apps/contourclock/font-SairaCond.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name":"SairaCond",
- "size":"98",
- "characters":[
- {"width" : "61", "buffer":"VVVVf///////////VVVVVVVV/////////////VVVVVVX/AAAAAAAAAAAD/VVVVVX8AAAAAAAAAAAAD9VVVVXwAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAA/8AAAAAAAA9fAAAAAAAA//wAAAAAAAD3wAAAAAAA9VfAAAAAAAA98AAAAAAAPVV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA/wAAAAAAA9VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAD/AAAAAAAD1VXwAAAAAAA98AAAAAAAPVV8AAAAAAAPfAAAAAAAD1V8AAAAAAAD3wAAAAAAAP/8AAAAAAAD18AAAAAAAA/8AAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAPVVVVfwAAAAAAAAAAAAA/VVVVV/AAAAAAAAAAAAA/VVVVVV/wAAAAAAAAAAD9VVVVVVX////////////9VVVVVVVV///////////1VVVUA==" },
- {"width" : "42", "buffer":"VVVVVVX///////VVVVVV////////VVVVVf8AAAAAAPVVVVX/AAAAAAAPVVVV/wAAAAAAAPVVVf8AAAAAAAAPVVX/AAAAAAAAAPVV/wAAAAAAAAAPVf8AAAAAAAAAAPX/AAAAAAAAAAAPfwAAAAAAAAAAAPfAAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAAAAAAAAAAP8AAAMAAAAAAAAP8AAD/AAAAAAAAP8AD/3wAAAAAAAP8D/9XwAAAAAAAP8/9VXwAAAAAAAPf9VVXwAAAAAAAPfVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVXwAAAAAAAPVVVVX/////////VVVVV/////////" },
- {"width" : "59", "buffer":"Vf/////////////1VVVVf//////////////9VVVV8AAAAAAAAAAAAAD/VVVXwAAAAAAAAAAAAAA/VVVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD1/////////wAAAAAAAAPX/////////wAAAAAAAA9VVVVVVVVVXwAAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAA9VVVVVVVVX8AAAAAAAAD1VVVVVVVX/AAAAAAAAAPVVVVVVVV/AAAAAAAAAD1VVVVVVV/AAAAAAAAAAPVVVVVVV/wAAAAAAAAAA9VVVVVV/wAAAAAAAAAAD1VVVVV/wAAAAAAAAAAA9VVVVV/wAAAAAAAAAAAD1VVVV/wAAAAAAAAAAAAPVVVV/wAAAAAAAAAAAAD1VVVfwAAAAAAAAAAAAAPVVVfwAAAAAAAAAAAAAD1VVX8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAP1VVV8AAAAAAAAAAAAAP9VVVXwAAAAAAAAAAAAP9VVVV8AAAAAAAAAAAAP9VVVVXwAAAAAAAAAAAP9VVVVVfAAAAAAAAAAAP9VVVVVV8AAAAAAAAAAP9VVVVVVfAAAAAAAAAAP9VVVVVVV8AAAAAAAAAP9VVVVVVVXwAAAAAAAAP9VVVVVVVVfAAAAAAAAD9VVVVVVVVV8AAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAD1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAA//////////3wAAAAAAAA///////////AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP///////////////////////////////////////w" },
- {"width" : "59", "buffer":"V//////////////VVVVV///////////////1VVVXwAAAAAAAAAAAAAP9VVVfAAAAAAAAAAAAAAD9VVV8AAAAAAAAAAAAAAA/VVXwAAAAAAAAAAAAAAA/VVfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAPX/////////AAAAAAAAA9f/////////AAAAAAAAD1VVVVVVVVVfAAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVf/////8AAAAAAAA9VVVX//////AAAAAAAAPVVVVfAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAA/VVVVVV8AAAAAAAAAAAP1VVVVVXwAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAP1VVVVVXwAAAAAAAAAAAP9VVVVVfAAAAAAAAAAAAD9VVVVV8AAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV//////wAAAAAAAA9VVVV//////wAAAAAAAA9VVVVVVVVVXwAAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVV8AAAAAAAA9//////////AAAAAAAAD//////////wAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAA/VV8AAAAAAAAAAAAAAAP1VXwAAAAAAAAAAAAAAP1VVf/AAAAAAAAAAAAA/9VVVf//////////////9VVVVVf////////////1VVVVQ" },
- {"width" : "66", "buffer":"VVVVVX/////////VVVVVVVVVVVVf/////////VVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVXwAAAAAAAD1VVVVVVVVVVVXwAAAAAAAD1VVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVXwAAAAAAAD1VVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVVV8AAAAAAAPVVf/////1VVVV8AAAAAAAPVV//////9VVVV8AAAAAAAPVV8AAAAA9VVVXwAAAAAAA9VV8AAAAA9VVVXwAAAAAAA9VXwAAAAA9VVVXwAAAAAAA9VXwAAAAA9VVVfAAAAAAAA9VfAAAAAA9VVVfAAAAAAAD1VfAAAAAA9VVVfAAAAAAAD1VfAAAAAA9VVVfAAAAAAAPVV8AAAAAA9VVVfAAAAAAAPVV8AAAAAA9VVV8AAAAAAAPVV8AAAAAA9VVV8AAAAAAAPVXwAAAAAA9VVXwAAAAAAA9VXwAAAAAA9VVXwAAAAAAA9VXwAAAAAA9VVXwAAAAAAA9VfAAAAAAA9VVXwAAAAAAD1VfAAAAAAA9VVfAAAAAAAD1V8AAAAAAA9VVfAAAAAAAD1V8AAAAAAA9VVfAAAAAAAPVXwAAAAAAA9VVfAAAAAAAD//AAAAAAAAP//8AAAAAAAA/8AAAAAAAAD//8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAP//////////8AAAAAAAAD/////////////AAAAAAAAP//VVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVVX////////9VVVVVVVVVVVVX////////9VV" },
- {"width" : "59", "buffer":"f/////////////////VV//////////////////VXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAD/////////VV8AAAAAAA/////////1VXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9Vf/1VVVVVVV8AAAAAAA//////VVVVVXwAAAAAAA/8AD//9VVVVfAAAAAAAAAAAAAP/VVVV8AAAAAAAAAAAAAA/1VVXwAAAAAAAAAAAAAAP1VVfAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD1/////////wAAAAAAAAPX/////////wAAAAAAAA9VVVVVVVVVXwAAAAAAAA9VVVVVVVVVXwAAAAAAAD1VVVVVVVVVfAAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAD3/////////8AAAAAAAAPf/////////AAAAAAAAA98AAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD9VV8AAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA/VVVf8AAAAAAAAAAAAA/1VVVf//////////////1VVVVV/////////////1VVVVQ" },
- {"width" : "62", "buffer":"VVVVVV////////////1VVVVVVV//////////////VVVVVV/wAAAAAAAAAAAD/VVVVVfwAAAAAAAAAAAAA9VVVVfwAAAAAAAAAAAAAD1VVVX8AAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAD///////8PVXwAAAAAAAA/////////9VfAAAAAAAAPVVVVVVVV/VV8AAAAAAAD1VVVVVVVVVVXwAAAAAAA9VVVVVVVVVVV8AAAAAAAD1VVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVX/9VVVVVV8AAAAAAAPVV/////1VVVXwAAAAAAA9V//AA//9VVVfAAAAAAAD1/wAAAAD/VVXwAAAAAAAPfwAAAAAA/1VfAAAAAAAAPwAAAAAAAP1V8AAAAAAAAMAAAAAAAAPVXwAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAA//wAAAAAAAD/AAAAAAAAP//wAAAAAAAP8AAAAAAAD1VXwAAAAAAA/wAAAAAAAPVVfAAAAAAAD/AAAAAAAA9VVfAAAAAAAP8AAAAAAAD1VV8AAAAAAA/wAAAAAAAPVVXwAAAAAAD/AAAAAAAA9VVfAAAAAAAPfAAAAAAAD1VV8AAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAPfAAAAAAAD1VV8AAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAPfAAAAAAAD1VV8AAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAPfAAAAAAAD1VV8AAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAPXwAAAAAAD1VXwAAAAAAA9fAAAAAAAD1V8AAAAAAAD18AAAAAAAD//AAAAAAAAPXwAAAAAAAD/wAAAAAAAA9fAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAPVVVVV/AAAAAAAAAAAAAP1VVVVV/AAAAAAAAAAAAP9VVVVVVfwAAAAAAAAAAP9VVVVVVVf///////////9VVVVVVVVX//////////9VVVVQ==" },
- {"width" : "58", "buffer":"///////////////////////////////////////wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP/////////8AAAAAAAAD3/////////wAAAAAAAD1VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAAPVVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVfAAAAAAAAD1VVVVVVVVXwAAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAAPVVVVVVVVVf/////////VVVVVVVVVX/////////1VVVVVVVU=" },
- {"width" : "64", "buffer":"VVVVX///////////1VVVVVVVVf////////////9VVVVVVV/wAAAAAAAAAAA/9VVVVVV/AAAAAAAAAAAAAP1VVVVV8AAAAAAAAAAAAAAPVVVVX8AAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAAD1fAAAAAAAAA/AAAAAAAAAPXwAAAAAAAD//AAAAAAAAD18AAAAAAAD9X8AAAAAAAA9fAAAAAAAD1VXwAAAAAAAPXwAAAAAAA9VV8AAAAAAAD18AAAAAAAPVVXwAAAAAAA9fAAAAAAAD1VV8AAAAAAAPXwAAAAAAA9VVfAAAAAAAD18AAAAAAAPVVXwAAAAAAA9fAAAAAAAD1VV8AAAAAAAPXwAAAAAAA9VVfAAAAAAAD18AAAAAAAPVVXwAAAAAAA9fAAAAAAAD1VV8AAAAAAAPXwAAAAAAA9VVfAAAAAAAD18AAAAAAAPVVXwAAAAAAD1fAAAAAAAD1VV8AAAAAAA9XwAAAAAAA9VVfAAAAAAAPVfAAAAAAAPVVXwAAAAAAD1XwAAAAAAD1VXwAAAAAAA9V8AAAAAAAPVV8AAAAAAA9VXwAAAAAAA//8AAAAAAAPVV8AAAAAAAD/8AAAAAAAPVVXwAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAD9VVVVX8AAAAAAAAAAAAAD9VVVVVfwAAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAAD9VVVVV/AAAAAAAAAAAAAAP9VVVV/AAAAAAAAAAAAAAAP1VVV8AAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAAPVXwAAAAAAAD/8AAAAAAAA9XwAAAAAAAD//wAAAAAAAPV8AAAAAAAD1VfAAAAAAAA9fAAAAAAAD1VV8AAAAAAAPXwAAAAAAA9VVfAAAAAAAD3wAAAAAAAPVVXwAAAAAAA98AAAAAAAD1VV8AAAAAAAPfAAAAAAAA9VVfAAAAAAAD3wAAAAAAAPVVXwAAAAAAAP8AAAAAAAPVVV8AAAAAAAD/AAAAAAAD1VVfAAAAAAAA/wAAAAAAA9VVXwAAAAAAAP8AAAAAAAPVVV8AAAAAAAD/AAAAAAAA9VVfAAAAAAAA/wAAAAAAAPVVXwAAAAAAAP8AAAAAAAD1VV8AAAAAAAD/AAAAAAAA9VVfAAAAAAAA/wAAAAAAAPVVXwAAAAAAAP8AAAAAAAD1VV8AAAAAAAD/AAAAAAAA9VV8AAAAAAAA/wAAAAAAAD//8AAAAAAAAP8AAAAAAAAP/8AAAAAAAAD/AAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAA9VVVVfwAAAAAAAAAAAAAA9VVVVV/wAAAAAAAAAAAAD9VVVVVV/wAAAAAAAAAAA/9VVVVVVV/////////////1VVVVVVVV///////////9VVVVU=" },
- {"width" : "62", "buffer":"VVVVX///////////VVVVVVVVX////////////1VVVVVVX/AAAAAAAAAAAP9VVVVVV/AAAAAAAAAAAAD9VVVVVfAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAPV8AAAAAAAA/8AAAAAAAA9XwAAAAAAAP/8AAAAAAAA9fAAAAAAAD1V8AAAAAAAD18AAAAAAA9VV8AAAAAAAPXwAAAAAAD1VXwAAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAPfAAAAAAAD1VV8AAAAAAA98AAAAAAAPVVXwAAAAAAD3wAAAAAAA9VVfAAAAAAAD/AAAAAAAD1VV8AAAAAAAP8AAAAAAAPVVXwAAAAAAA/wAAAAAAA9VVfAAAAAAAD/AAAAAAAD1VV8AAAAAAAP8AAAAAAAPVVXwAAAAAAA/wAAAAAAA9VVfAAAAAAAD/AAAAAAAD1VV8AAAAAAAP8AAAAAAAPVVXwAAAAAAA/wAAAAAAA9VVfAAAAAAAD/AAAAAAAD1VV8AAAAAAAP8AAAAAAAPVVfAAAAAAAA/wAAAAAAA9VV8AAAAAAAD/AAAAAAAA///AAAAAAAAP8AAAAAAAA//wAAAAAAAA/wAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAA9VfAAAAAAAAAwAAAAAAAD1VfAAAAAAAA/wAAAAAAAPVVfwAAAAAAP3wAAAAAAA9VVf/AAAAAP1fAAAAAAAD1VVX//////9V8AAAAAAAPVVVVf////9VXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVV8AAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVXwAAAAAAAPVVVVVVVVVVV8AAAAAAAA9Vf/VVVVVVVfAAAAAAAAPVX/////////wAAAAAAAA9VfAP//////8AAAAAAAAD1V8AAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAA/VVVVXwAAAAAAAAAAAAA/1VVVVX/AAAAAAAAAAAA/1VVVVVf/////////////1VVVVVVVf///////////1VVVVVQ==" },
- {"width" : "26", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///////9/////////AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/////////3////////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/////////////////AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP8AAAAAAA/wAAAAAAD/AAAAAAAP/////////////////w==" }
- ]
-}
diff --git a/apps/contourclock/fonts/Anton-p1.png b/apps/contourclock/fonts/Anton-p1.png
new file mode 100644
index 000000000..c049dd4a5
Binary files /dev/null and b/apps/contourclock/fonts/Anton-p1.png differ
diff --git a/apps/contourclock/fonts/Anton-p2.png b/apps/contourclock/fonts/Anton-p2.png
new file mode 100644
index 000000000..ac00cd840
Binary files /dev/null and b/apps/contourclock/fonts/Anton-p2.png differ
diff --git a/apps/contourclock/fonts/ArchivoNarrow-p1.png b/apps/contourclock/fonts/ArchivoNarrow-p1.png
new file mode 100644
index 000000000..909245a2a
Binary files /dev/null and b/apps/contourclock/fonts/ArchivoNarrow-p1.png differ
diff --git a/apps/contourclock/fonts/ArchivoNarrow-p2.png b/apps/contourclock/fonts/ArchivoNarrow-p2.png
new file mode 100644
index 000000000..c73725c58
Binary files /dev/null and b/apps/contourclock/fonts/ArchivoNarrow-p2.png differ
diff --git a/apps/contourclock/fonts/Bangers-p1.png b/apps/contourclock/fonts/Bangers-p1.png
new file mode 100644
index 000000000..e57f725f0
Binary files /dev/null and b/apps/contourclock/fonts/Bangers-p1.png differ
diff --git a/apps/contourclock/fonts/Bangers-p2.png b/apps/contourclock/fonts/Bangers-p2.png
new file mode 100644
index 000000000..b25d4f511
Binary files /dev/null and b/apps/contourclock/fonts/Bangers-p2.png differ
diff --git a/apps/contourclock/fonts/FjallaOne-p1.png b/apps/contourclock/fonts/FjallaOne-p1.png
new file mode 100644
index 000000000..382a3f271
Binary files /dev/null and b/apps/contourclock/fonts/FjallaOne-p1.png differ
diff --git a/apps/contourclock/fonts/FjallaOne-p2.png b/apps/contourclock/fonts/FjallaOne-p2.png
new file mode 100644
index 000000000..34a964cca
Binary files /dev/null and b/apps/contourclock/fonts/FjallaOne-p2.png differ
diff --git a/apps/contourclock/fonts/LuckiestGuy-p1.png b/apps/contourclock/fonts/LuckiestGuy-p1.png
new file mode 100644
index 000000000..0d082e40e
Binary files /dev/null and b/apps/contourclock/fonts/LuckiestGuy-p1.png differ
diff --git a/apps/contourclock/fonts/LuckiestGuy-p2.png b/apps/contourclock/fonts/LuckiestGuy-p2.png
new file mode 100644
index 000000000..3b93f83d6
Binary files /dev/null and b/apps/contourclock/fonts/LuckiestGuy-p2.png differ
diff --git a/apps/contourclock/fonts/MouseMemoirs-p1.png b/apps/contourclock/fonts/MouseMemoirs-p1.png
new file mode 100644
index 000000000..fc9bdedc0
Binary files /dev/null and b/apps/contourclock/fonts/MouseMemoirs-p1.png differ
diff --git a/apps/contourclock/fonts/MouseMemoirs-p2.png b/apps/contourclock/fonts/MouseMemoirs-p2.png
new file mode 100644
index 000000000..511e6addf
Binary files /dev/null and b/apps/contourclock/fonts/MouseMemoirs-p2.png differ
diff --git a/apps/contourclock/fonts/NerkoOne-p1.png b/apps/contourclock/fonts/NerkoOne-p1.png
new file mode 100644
index 000000000..44f91aca9
Binary files /dev/null and b/apps/contourclock/fonts/NerkoOne-p1.png differ
diff --git a/apps/contourclock/fonts/NerkoOne-p2.png b/apps/contourclock/fonts/NerkoOne-p2.png
new file mode 100644
index 000000000..c931116d8
Binary files /dev/null and b/apps/contourclock/fonts/NerkoOne-p2.png differ
diff --git a/apps/contourclock/fonts/Oswald-p1.png b/apps/contourclock/fonts/Oswald-p1.png
new file mode 100644
index 000000000..872e72d26
Binary files /dev/null and b/apps/contourclock/fonts/Oswald-p1.png differ
diff --git a/apps/contourclock/fonts/Oswald-p2.png b/apps/contourclock/fonts/Oswald-p2.png
new file mode 100644
index 000000000..a7b353b9f
Binary files /dev/null and b/apps/contourclock/fonts/Oswald-p2.png differ
diff --git a/apps/contourclock/fonts/RubikOne-p1.png b/apps/contourclock/fonts/RubikOne-p1.png
new file mode 100644
index 000000000..376909fe1
Binary files /dev/null and b/apps/contourclock/fonts/RubikOne-p1.png differ
diff --git a/apps/contourclock/fonts/RubikOne-p2.png b/apps/contourclock/fonts/RubikOne-p2.png
new file mode 100644
index 000000000..89a7453db
Binary files /dev/null and b/apps/contourclock/fonts/RubikOne-p2.png differ
diff --git a/apps/contourclock/fonts/TitanOne-p1.png b/apps/contourclock/fonts/TitanOne-p1.png
new file mode 100644
index 000000000..a9f3ec1a8
Binary files /dev/null and b/apps/contourclock/fonts/TitanOne-p1.png differ
diff --git a/apps/contourclock/fonts/TitanOne-p2.png b/apps/contourclock/fonts/TitanOne-p2.png
new file mode 100644
index 000000000..a52b11e1c
Binary files /dev/null and b/apps/contourclock/fonts/TitanOne-p2.png differ
diff --git a/apps/contourclock/fonts/font-Anton.json b/apps/contourclock/fonts/font-Anton.json
new file mode 100644
index 000000000..5013839b2
--- /dev/null
+++ b/apps/contourclock/fonts/font-Anton.json
@@ -0,0 +1,17 @@
+{
+ "name":"Anton",
+ "size":"100",
+ "characters":[
+ {"width" : "53", "buffer":"VVVVVV/////9VVVVVVVVVVX///////1VVVVVVVVX/wAAAAA//VVVVVVVX/AAAAAAAD/VVVVVVV/AAAAAAAAAP1VVVVVfAAAAAAAAAAP1VVVVXwAAAAAAAAAAD1VVVV8AAAAAAAAAAAD1VVVfAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAPV8AAAAAAP/wAAAAAA9fAAAAAAD//wAAAAAD18AAAAAA9VXwAAAAAPXwAAAAAPVVfAAAAAA9fAAAAAA9VVfAAAAAA98AAAAAD1VV8AAAAAD3wAAAAA9VVXwAAAAAPfAAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD3wAAAAAPVVXwAAAAAPfAAAAAA9VVfAAAAAA98AAAAAD1VXwAAAAAD3wAAAAAD1V8AAAAAAPfAAAAAAD9fAAAAAAD18AAAAAAD/wAAAAAAPV8AAAAAAA8AAAAAAA9XwAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAD1VXwAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAD1VVXwAAAAAAAAAAAA9VVVfAAAAAAAAAAAAPVVVVfwAAAAAAAAAAD1VVVVfwAAAAAAAAAA9VVVVVX8AAAAAAAAA/VVVVVVX/AAAAAAAA/1VVVVVVV/8AAAAAD/1VVVVVVVVf///////1VVVVVVVVVV//////VVVVVU="},
+ {"width" : "34", "buffer":"VVVVVV/////VVVVVV/////9VVVVV8AAAAPVVVVVfAAAAD1VVVVfAAAAA9VVVVfAAAAAPVVVVfAAAAAD1VVVfAAAAAA9VVVfAAAAAAPVVV/AAAAAAD1VX/AAAAAAA9Vf8AAAAAAAPX/wAAAAAAAD//AAAAAAAAA/wAAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAMAAAAAAP8AAPwAAAAAD/AA/fAAAAAA/wP/XwAAAAAP//9V8AAAAAD//VVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVXwAAAAAPVVVV8AAAAAD1VVVfAAAAAA9VVVX///////VVVVf//////Q=="},
+ {"width" : "52", "buffer":"VVVVVVX///9VVVVVVVVVVVX//////1VVVVVVVVV//wAAAP/9VVVVVVVX/wAAAAAA/9VVVVVVX8AAAAAAAAP1VVVVVfwAAAAAAAAAP1VVVVfwAAAAAAAAAA/VVVVfAAAAAAAAAAAA9VVVXwAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVXwAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAD1fAAAAAAA8AAAAAAA9fAAAAAAD/8AAAAAAD3wAAAAAD9fwAAAAAA98AAAAAD1VfAAAAAAPfAAAAAA9VV8AAAAAD3wAAAAA9VVfAAAAAA/wAAAAAPVVXwAAAAAP8AAAAAD1VVfAAAAAD/AAAAAA9VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVV8AAAAAD/AAAAAD1VVfAAAAAA/wAAAAA9VVXwAAAAAP8AAAAAPVVV8AAAAAD/AAAAAD1VVfAAAAAD3//////9VVfAAAAAA9///////VVXwAAAAAPVVVVVVVVVV8AAAAAD1VVVVVVVVV8AAAAAD1VVVVVVVVVfAAAAAA9VVVVVVVVVfAAAAAAPVVVVVVVVVXwAAAAAPVVVVVVVVVXwAAAAAD1VVVVVVVVV8AAAAAD1VVVVVVVVV8AAAAAA9VVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVV8AAAAAA9VVVVVVVVVfAAAAAA9VVVVVVVVVfAAAAAAPVVVVVVVVVXwAAAAAA////////9XwAAAAAAD////////18AAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA///////////////////////////////////Q=="},
+ {"width" : "53", "buffer":"VVVVVVVX//1VVVVVVVVVVVVf/////9VVVVVVVVVV///AAD//1VVVVVVVV/8AAAAAA/9VVVVVVV/wAAAAAAAD/VVVVVVfwAAAAAAAAA/VVVVVXwAAAAAAAAAAPVVVVV8AAAAAAAAAAAPVVVVfAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAPVVXwAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAA9V8AAAAAAD/AAAAAAD1fAAAAAAA//AAAAAAD18AAAAAAPVfAAAAAAPXwAAAAAD1VfAAAAAA9fAAAAAA9VV8AAAAAD18AAAAAD1VV8AAAAAPXwAAAAA9VVXwAAAAA9fAAAAAD1VVfAAAAAD18AAAAAPVVV8AAAAAPXwAAAAA9VVXwAAAAA9fAAAAAD1VVfAAAAAD18AAAAAPVVV8AAAAAPX//////9VVXwAAAAA9f//////1VVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVfAAAAAAPVVVVVVVVVfwAAAAAD1VVVVVVVX/8AAAAAAPVVVVVVVX/8AAAAAAA9VVVVVVVfAAAAAAAAD1VVVVVVV8AAAAAAAA9VVVVVVVXwAAAAAAAD1VVVVVVVfAAAAAAAA9VVVVVVVV8AAAAAAAPVVVVVVVVXwAAAAAAP1VVVVVVVVfAAAAAAD9VVVVVVVVV8AAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVfAAAAAAA/VVVVVVVVV8AAAAAAA/VVVVVVVVXwAAAAAAAPVVVVVVVVfAAAAAAAA9VVVVVVVV8AAAAAAAA9VVVVVVVXwAAAAAAAD1VVVVVVVf/AAAAAAAD1VVVVVVV//wAAAAAAPVVVVVVVVVfwAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVV8AAAAAPX//////1VVXwAAAAA9///////VVVfAAAAAD3wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAPVVVfAAAAAA/wAAAAA9VVV8AAAAAD/AAAAAD1VVXwAAAAAP8AAAAAPVVVfAAAAAA/wAAAAA9VVV8AAAAAD/AAAAAD1VVXwAAAAAP8AAAAAPVVVfAAAAAD3wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAPVVVfAAAAAD3wAAAAA9VVV8AAAAAPXwAAAAA9VVXwAAAAA9fAAAAAD1VV8AAAAAD18AAAAAPVVXwAAAAAPXwAAAAAPVV8AAAAAA9fAAAAAAPVfAAAAAAPV8AAAAAAP/wAAAAAA9XwAAAAAAP8AAAAAAD1XwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAD1VVV8AAAAAAAAAAAA9VVVV8AAAAAAAAAAAP1VVVV8AAAAAAAAAAD9VVVVV/AAAAAAAAAA9VVVVVV/wAAAAAAAA/VVVVVVVf8AAAAAAD/1VVVVVVVX////////1VVVVVVVVV///////VVVVVU="},
+ {"width" : "55", "buffer":"VVVVVVf/////////1VVVVVVVf//////////VVVVVVVXwAAAAAAAAD1VVVVVVV8AAAAAAAAA9VVVVVVV8AAAAAAAAAPVVVVVVVfAAAAAAAAAD1VVVVVVXwAAAAAAAAA9VVVVVVXwAAAAAAAAAPVVVVVVV8AAAAAAAAAD1VVVVVVfAAAAAAAAAA9VVVVVVXwAAAAAAAAAPVVVVVVXwAAAAAAAAAD1VVVVVV8AAAAAAAAAA9VVVVVVfAAAAAAAAAAPVVVVVVXwAAAAAAAAAD1VVVVVXwAAAAAAAAAA9VVVVVV8AAAAAAAAAAPVVVVVVfAAAAAAAAAAD1VVVVVfAAAAAAAAAAA9VVVVVXwAAAAAAAAAAPVVVVVV8AAAAAAAAAAD1VVVVVfAAAAMAAAAAA9VVVVVfAAAAPwAAAAAPVVVVVXwAAAPfAAAAAD1VVVVV8AAAD3wAAAAA9VVVVV8AAAA98AAAAAPVVVVVfAAAAPfAAAAAD1VVVVXwAAAPXwAAAAA9VVVVV8AAAD18AAAAAPVVVVV8AAAA9fAAAAAD1VVVVfAAAAPXwAAAAA9VVVVXwAAAPV8AAAAAPVVVVV8AAAD1fAAAAAD1VVVV8AAAA9XwAAAAA9VVVVfAAAAPV8AAAAAPVVVVXwAAAPVfAAAAAD1VVVXwAAAD1XwAAAAA9VVVV8AAAA9V8AAAAAPVVVVfAAAAPVfAAAAAD1VVVXwAAAD1XwAAAAA9VVVXwAAAD1V8AAAAAPVVVV8AAAA9VfAAAAAD1VVVfAAAAPVXwAAAAA9VVVXwAAAD1V8AAAAAPVVVXwAAAD1VfAAAAAD1VVV8AAAA9VXwAAAAA9VVVfAAAAPVV8AAAAAPVVVfAAAAD1VfAAAAAD1VVXwAAAD1VXwAAAAA9VVV8AAAA9VV8AAAAAPVVVfAAAAPVVfAAAAAD1VVfAAAAD1VXwAAAAA9VVXwAAAA9VV8AAAAAPVVV8AAAA9VVfAAAAAD1VVfAAAAPVVXwAAAAA9VVfAAAAD1VV8AAAAAPVVXwAAAA9VVfAAAAAD1VV8AAAA9VVXwAAAAA9VV8AAAAPVVV8AAAAAPVVfAAAAD1VVfAAAAAD1VXwAAAA9VVXwAAAAA9VV8AAAA9VVV8AAAAAPVV8AAAAPVVVfAAAAAD1VfAAAAD1VVXwAAAAA9VXwAAAA9VVV8AAAAAPVXwAAAA9VVVfAAAAAD1V8AAAAPVVVXwAAAAA9VfAAAAA////wAAAAAD//wAAAAD///wAAAAAAP/8AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAD//////////AAAAAAA///////////8AAAAAA//VVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVf//////1VVVVVVVVVVX//////1VQ=="},
+ {"width" : "53", "buffer":"V///////////////1Vf///////////////1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAA/////////9VfAAAAAP/////////VV8AAAAD1VVVVVVVVVVXwAAAAPVVVVVVVVVVVfAAAAA9VVVVVVVVVVV8AAAAD1VVVVVVVVVVXwAAAAPVVVVVVVVVVVfAAAAA9VVVVVVVVVVV8AAAAD1VVVVVVVVVVXwAAAAPVVVVVVVVVVVfAAAAA9VVf/VVVVVVV8AAAAD1X////1VVVVXwAAAAPV/8AP/9VVVVfAAAAA9/AAAAD/VVVV8AAAAA/wAAAAA/VVVXwAAAAAwAAAAAAPVVVfAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9VfAAAAAAA8AAAAAAA9V8AAAAAA//AAAAAAD1XwAAAAAP1/AAAAAAPVfAAAAAD1VfAAAAAA9V8AAAAA9VV8AAAAAA9XwAAAAD1VV8AAAAAD1fAAAAA9VVXwAAAAAPV8AAAAD1VVfAAAAAA9X//////VVVfAAAAAD1f/////9VVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAP///////VVVfAAAAAA///////9VVV8AAAAAD/AAAAAD1VVXwAAAAAP8AAAAAPVVVfAAAAAA/wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAPVVVfAAAAAD3wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAPVVVfAAAAAD3wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAPVVVfAAAAAD3wAAAAA9VVV8AAAAAPfAAAAAD1VVXwAAAAA98AAAAAD1VV8AAAAAD3wAAAAAPVVXwAAAAA9fAAAAAAPVV8AAAAAD18AAAAAAPVfAAAAAAPXwAAAAAAP/wAAAAAA9fAAAAAAAP8AAAAAAD1fAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAPVVV8AAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVVXwAAAAAAAAAAAD1VVVX8AAAAAAAAAAA9VVVVX/AAAAAAAAAA/VVVVVV/wAAAAAAAAP1VVVVVVf8AAAAAAA/1VVVVVVVX////////9VVVVVVVVV///////1VVVVU="},
+ {"width" : "53", "buffer":"VVVVVV/////9VVVVVVVVVVX///////1VVVVVVVVX/wAAAAA//VVVVVVVX/AAAAAAAD/VVVVVVV/AAAAAAAAAP1VVVVV/AAAAAAAAAAP1VVVVfwAAAAAAAAAAD1VVVXwAAAAAAAAAAAD1VVVfAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVfAAAAAAD/8AAAAAA9V8AAAAAA//8AAAAAD1XwAAAAAPVV8AAAAAPVfAAAAAD1VXwAAAAA9XwAAAAA9VVXwAAAAD1fAAAAAD1VVfAAAAAPV8AAAAAPVVV8AAAAA9XwAAAAA9VVXwAAAAD1fAAAAAD1VVXwAAAAPV8AAAAAPVVVfAAAAA9XwAAAAA9VVV8AAAAD18AAAAAD1VVXwAAAAPXwAAAAAPVVVf/////9fAAAAAA9VVV//////18AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VX///1VVVV8AAAAAD1f/////VVVXwAAAAAPX/AAAD/1VVfAAAAAA98AAAAAP1VV8AAAAAA/AAAAAAD1VXwAAAAAAwAAAAAAD1VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA98AAAAAAA/wAAAAAAD3wAAAAAAP/wAAAAAAPfAAAAAAD1XwAAAAAA98AAAAAA9VXwAAAAAD3wAAAAAPVVXwAAAAAPfAAAAAA9VVfAAAAAA98AAAAAD1VV8AAAAAA/wAAAAAPVVXwAAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAA98AAAAAD1VV8AAAAAD3wAAAAAPVVXwAAAAAPfAAAAAA9VVfAAAAAA9fAAAAAD1VV8AAAAAD18AAAAAPVVXwAAAAAPXwAAAAAPVV8AAAAAD1fAAAAAAP1fAAAAAAPV8AAAAAAP/wAAAAAA9V8AAAAAAD8AAAAAAD1XwAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAD1VVVfAAAAAAAAAAAA9VVVV/AAAAAAAAAAAPVVVVV/AAAAAAAAAAD1VVVVVfwAAAAAAAAD9VVVVVVf8AAAAAAAD/VVVVVVVX/wAAAAAD/VVVVVVVVV////////VVVVVVVVVVX//////VVVVVU="},
+ {"width" : "51", "buffer":"f///////////////9/////////////////8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAA9/////////wAAAAAA9/////////8AAAAAA9VVVVVVVVVfAAAAAA9VVVVVVVVVfAAAAAA9VVVVVVVVV8AAAAAD1VVVVVVVVV8AAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAD1VVVVVVVVX///////1VVVVVVVVX///////VVVVVVVV"},
+ {"width" : "52", "buffer":"VVVVVf//////VVVVVVVVVX////////1VVVVVVVf/AAAAAAD/1VVVVVV/wAAAAAAAA/1VVVVX/AAAAAAAAAA/VVVVX8AAAAAAAAAAA9VVVXwAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVV8AAAAAAAAAAAAA9VV8AAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAPXwAAAAAAPwAAAAAAD3wAAAAAAP/wAAAAAA98AAAAAAPV/AAAAAAPfAAAAAAPVV8AAAAAD3wAAAAAPVVfAAAAAA98AAAAAD1VV8AAAAAD/AAAAAD1VVfAAAAAA/wAAAAA9VVXwAAAAAP8AAAAAPVVV8AAAAAD/AAAAAD1VVfAAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVV8AAAAAD/AAAAAD1VVfAAAAAA/wAAAAA9VVXwAAAAAP8AAAAAPVVV8AAAAAPfAAAAAD1VVfAAAAAD3wAAAAAPVVXwAAAAA98AAAAAD1VXwAAAAAPfAAAAAAPVXwAAAAAD18AAAAAA//wAAAAAA9fAAAAAAD/wAAAAAA9XwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAD9VVXwAAAAAAAAAAAD9VVVfAAAAAAAAAAAD1VVVV8AAAAAAAAAAD1VVVV8AAAAAAAAAAAP1VVV8AAAAAAAAAAAA/VVV8AAAAAAAAAAAAA9VV8AAAAAAAAAAAAAD1V8AAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAA9XwAAAAAAP8AAAAAAD18AAAAAA//wAAAAAA9fAAAAAA/VfAAAAAAPfAAAAAA9VV8AAAAAD3wAAAAAPVVXwAAAAA98AAAAAPVVV8AAAAAPfAAAAAD1VVfAAAAAA/wAAAAA9VVXwAAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVVfAAAAAD/AAAAAD1VVXwAAAAA/wAAAAA9VVV8AAAAAP8AAAAAPVVV8AAAAAD/AAAAAD1VVfAAAAAD3wAAAAAPVVXwAAAAA98AAAAAD1VXwAAAAAPfAAAAAAPVV8AAAAAD18AAAAAA/X8AAAAAA9fAAAAAAD/8AAAAAAPXwAAAAAADwAAAAAAPV8AAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VfAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAA9VVfAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAPVVVXwAAAAAAAAAAAPVVVV8AAAAAAAAAAAPVVVVX8AAAAAAAAAAPVVVVVfwAAAAAAAAA/VVVVVVfwAAAAAAAD/VVVVVVV/8AAAAAAP9VVVVVVVV////////1VVVVVVVVVf//////VVVVVQ=="},
+ {"width" : "53", "buffer":"VVVVVV/////9VVVVVVVVVVX///////1VVVVVVVVf/wAAAAA//VVVVVVVX/AAAAAAAD/VVVVVVX8AAAAAAAAAP1VVVVV/AAAAAAAAAAP1VVVVfAAAAAAAAAAAD1VVVXwAAAAAAAAAAAD1VVVfAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAPVVXwAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAA9XwAAAAAAP/AAAAAAD1fAAAAAAD//AAAAAAPV8AAAAAA9VfAAAAAAPXwAAAAAPVVfAAAAAA9fAAAAAA9VV8AAAAAD3wAAAAAPVVV8AAAAAPfAAAAAA9VVXwAAAAA98AAAAAD1VVfAAAAAD3wAAAAAPVVV8AAAAAPfAAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAA9VVXwAAAAAP8AAAAAD1VVfAAAAAA/wAAAAAPVVV8AAAAAD/AAAAAAPVVfAAAAAAP8AAAAAA9VV8AAAAAA/wAAAAAA9VfAAAAAAD/AAAAAAA//wAAAAAAPfAAAAAAA/8AAAAAAA98AAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAD1V8AAAAAAAMAAAAAAPVV8AAAAAAD8AAAAAA9VV/AAAAAA98AAAAAD1VV/8AAAA/XwAAAAAPVVVf/////1fAAAAAA9VVVV////1V8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1//////9VVV8AAAAAPX//////1VVXwAAAAA9fAAAAAPVVVfAAAAAD18AAAAA9VVV8AAAAAPXwAAAAD1VVXwAAAAA9fAAAAAPVVVfAAAAAD18AAAAA9VVV8AAAAAPXwAAAAD1VVXwAAAAA9fAAAAAPVVVfAAAAAPV8AAAAAPVVXwAAAAA9XwAAAAA9VVfAAAAAD1fAAAAAA9VXwAAAAAPV8AAAAAA/f8AAAAAA9XwAAAAAA//AAAAAAPVXwAAAAAAMAAAAAAA9VfAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAD1VVV8AAAAAAAAAAAA9VVVV8AAAAAAAAAAAPVVVVV/AAAAAAAAAAD1VVVVV/wAAAAAAAAD9VVVVVVf8AAAAAAAD/VVVVVVVX/wAAAAAP/VVVVVVVVV////////VVVVVVVVVVX/////9VVVVVU="},
+ {"width" : "20", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////////////8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA//////////////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////////////AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP/////////////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="}
+ ]
+}
diff --git a/apps/contourclock/fonts/font-ArchivoNarrow.json b/apps/contourclock/fonts/font-ArchivoNarrow.json
new file mode 100644
index 000000000..9de7d4c53
--- /dev/null
+++ b/apps/contourclock/fonts/font-ArchivoNarrow.json
@@ -0,0 +1,17 @@
+{
+ "name":"Archivo Narrow",
+ "size":"100",
+ "characters":[
+ {"width" : "57", "buffer":"VVVVVVX/////1VVVVVVVVVVVX///////1VVVVVVVVVV/8AAAAAP/VVVVVVVVVX8AAAAAAAP9VVVVVVVV/AAAAAAAAA/VVVVVVVX8AAAAAAAAAD1VVVVVVfAAAAAAAAAAA9VVVVVV8AAAAAAAAAAAPVVVVVV8AAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAPVVVV8AAAAAAMAAAAAAPVVVV8AAAAAP//AAAAAD1VVXwAAAAA/3/wAAAAD1VVXwAAAAD1VV8AAAAD1VVXwAAAAPVVVfAAAAA9VVfAAAAA9VVVXwAAAA9VVfAAAAD1VVVXwAAAA9VVfAAAAD1VVVV8AAAAPVV8AAAAPVVVVV8AAAAPVV8AAAAPVVVVVfAAAAPVV8AAAA9VVVVVfAAAAD1V8AAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVXwAAAD1XwAAAA9VVVVVXwAAAD1XwAAAA9VVVVVXwAAAA9XwAAAD1VVVVVXwAAAA9XwAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAP8AAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVV8AAAAPfAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVXwAAAAPfAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9fAAAAD1VVVVVXwAAAA9XwAAAD1VVVVVXwAAAA9XwAAAA9VVVVVXwAAAA9XwAAAA9VVVVVXwAAAA9XwAAAA9VVVVVXwAAAD1XwAAAA9VVVVVXwAAAD1XwAAAA9VVVVVfAAAAD1V8AAAA9VVVVVfAAAAD1V8AAAAPVVVVVfAAAAD1V8AAAAPVVVVVfAAAAPVV8AAAAPVVVVV8AAAAPVVfAAAAD1VVVV8AAAAPVVfAAAAD1VVVXwAAAA9VVfAAAAA9VVVXwAAAA9VVXwAAAAPVVVfAAAAA9VVXwAAAAD1VV8AAAAD1VVXwAAAAA///wAAAAD1VVV8AAAAAP//AAAAAD1VVV8AAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAD1VVVVVfAAAAAAAAAAAPVVVVVVfAAAAAAAAAAA9VVVVVVX8AAAAAAAAAD1VVVVVVV/AAAAAAAAA/VVVVVVVVX/AAAAAAAP9VVVVVVVVV//AAAAAP/VVVVVVVVVVV///////1VVVVVVVVVVVV/////1VVVVVV"},
+ {"width" : "60", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV///1VVVVVVVVVVVVVVVf///1VVVVVVVVVVVVVVV/AAD1VVVVVVVVVVVVVV/wAAD1VVVVVVVVVVVVVf/AAAD1VVVVVVVVVVVVX/AAAAD1VVVVVVVVVVVX/wAAAAD1VVVVVVVVVVX/8AAAAAD1VVVVVVVVVX/8AAAAAAD1VVVVVVVVX/8AAAAAAAD1VVVVVVV//8AAAAAAAAD1VVVVVV//8AAAAAAAAAD1VVVVVV/AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAD1VVVVVV///////wAAAAD1VVVVVV///////8AAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVfAAAAD1VVVVVV///////8AAAAA//////////////wAAAAAP//////8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAP////////////////////f///////////////////VVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "56", "buffer":"VVVVVVX//////VVVVVVVVVVVf///////9VVVVVVVVVf/AAAAAAP/VVVVVVVVf8AAAAAAAA/1VVVVVVX8AAAAAAAAAP1VVVVVX8AAAAAAAAAAD1VVVVV/AAAAAAAAAAAD1VVVVfAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAA9VV8AAAAAA//wAAAAAA9VfAAAAAAP//8AAAAAD1V8AAAAAD1VX8AAAAAD1XwAAAAA9VVV8AAAAAPV8AAAAAPVVVV8AAAAA9XwAAAAD1VVVV8AAAAD1fAAAAA9VVVVXwAAAAPXwAAAAD1VVVVfAAAAA9fAAAAAPVVVVVfAAAAA98AAAAD1VVVVV8AAAAD3wAAAAPVVVVVXwAAAAPfAAAAA9VVVVVfAAAAA98AAAAPVVVVVV8AAAAD3wAAAA9VVVVVXwAAAAPfAAAAD1VVVVVfAAAAA98AAAAPVVVVVV8AAAAD3wAAAA9VVVVVXwAAAA9fAAAAD1VVVVVfAAAAD18AAAAPVVVVVXwAAAAPXwAAAA9VVVVVfAAAAA9f/////1VVVVV8AAAAD1//////VVVVVXwAAAAPVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVXwAAAAPVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVXwAAAAPVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVXwAAAAD1VVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVV8AAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAPVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAA///////////18AAAAAA///////////fAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA//////////////////////////////////////VVVVVVVVVVVVVVVVVVU="},
+ {"width" : "58", "buffer":"VVVVVVX/////9VVVVVVVVVVVV////////VVVVVVVVVVX/wAAAAAP/VVVVVVVVVX8AAAAAAAD/VVVVVVVVfwAAAAAAAAD9VVVVVVVfwAAAAAAAAAD9VVVVVVfAAAAAAAAAAAP1VVVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVXwAAAAAAPAAAAAAA9VVV8AAAAAD//wAAAAAD1VV8AAAAAD/X/AAAAAA9VVfAAAAAD1VV8AAAAAD1VfAAAAAD1VVXwAAAAA9VXwAAAAD1VVVfAAAAAPVV8AAAAD1VVVV8AAAAD1VfAAAAA9VVVVfAAAAAPVXwAAAA9VVVVV8AAAAD1XwAAAAPVVVVVfAAAAA9V8AAAAD1VVVVXwAAAAPVfAAAAA9VVVVV8AAAAD1XwAAAAPVVVVVfAAAAA9V8AAAAD1VVVVXwAAAAPVfAAAAD1VVVVV8AAAAD1XwAAAA9VVVVVfAAAAA9V8AAAAPVVVVVXwAAAAPVf/////1VVVVV8AAAAD1X/////9VVVVVfAAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVV8AAAAD1VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVX8AAAAA9VVVVVVVVVX//8AAAAAPVVVVVVVVVV//wAAAAAPVVVVVVVVVVfAAAAAAA/VVVVVVVVVVXwAAAAAA/VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAA9VVVVVVVVVVVXwAAAAA9VVVVVVVVVVVV8AAAAAD9VVVVVVVVVVVfAAAAAAP9VVVVVVVVVVXwAAAAAAP1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAD1VVVVVVVVV///AAAAAAPVVVVVVVVVf///AAAAAA9VVVVVVVVVVVX/AAAAAPVVVVVVVVVVVVX8AAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAD3//////VVVVVVXwAAAA9//////1VVVVVV8AAAAD/AAAAA9VVVVVVfAAAAA/wAAAAPVVVVVVXwAAAAP8AAAAD1VVVVVV8AAAAD/AAAAA9VVVVVVfAAAAA/wAAAAPVVVVVVXwAAAAP8AAAAD1VVVVVV8AAAAD3wAAAA9VVVVVVfAAAAD18AAAAPVVVVVVXwAAAA9fAAAAA9VVVVVXwAAAAPXwAAAAPVVVVVV8AAAAD18AAAAA9VVVVVfAAAAA9XwAAAAPVVVVVfAAAAAPV8AAAAA9VVVVfAAAAAPVfAAAAAD1VVVfAAAAAD1V8AAAAAP1VV/AAAAAA9VfAAAAAA////AAAAAA9VV8AAAAAA//8AAAAAAPVVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAD1VVVVVX8AAAAAAAAAAP1VVVVVVfwAAAAAAAAAP1VVVVVVVf8AAAAAAAD/VVVVVVVVV//AAAAAA//VVVVVVVVVVf///////1VVVVVVVVVVVX/////9VVVVVVQ=="},
+ {"width" : "63", "buffer":"VVVVVVVVf/////VVVVVVVVVVVVVVV//////VVVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVVV8AAAAPVV//9VVVVVVVVVXwAAAA9VX//9VVVVVVVVVXwAAAA9VXwA9VVVVVVVVVXwAAAA9VXwA9VVVVVVVVVfAAAAD1VXwA9VVVVVVVVVfAAAAD1VfAA9VVVVVVVVVfAAAAD1VfAA9VVVVVVVVV8AAAAPVVfAA9VVVVVVVVV8AAAAPVV8AA9VVVVVVVVV8AAAA9VV8AA9VVVVVVVVXwAAAA9VV8AA9VVVVVVVVXwAAAA9VXwAA9VVVVVVVVXwAAAD1VXwAA9VVVVVVVVfAAAAD1VXwAA9VVVVVVVVfAAAAPVVfAAA9VVVVVVVV8AAAAPVVfAAA9VVVVVVVV8AAAA9VVfAAA9VVVVVVVV8AAAA9VV8AAA9VVVVVVVXwAAAA9VV8AAA9VVVVVVVXwAAAD1VXwAAA9VVVVVVVfAAAAD1VXwAAA9VVVVVVVfAAAAPVVXwAAA9VVVVVVVfAAAAPVVfAAAA9VVVVVVV8AAAA9VVfAAAA9VVVVVVV8AAAA9VV8AAAA9VVVVVVXwAAAD1VV8AAAA9VVVVVVXwAAAD1VV8AAAA9VVVVVVXwAAAPVVV8AAAA9VVVVVVfAAAAPVVV8AAAA9VVVVVVfAAAAPVVV8AAAA9VVVVVV8AAAA9VVV8AAAA9VVVVVV8AAAA9VVV8AAAA9VVVVVXwAAAD1VVV8AAAA9VVVVVXwAAAD1VVV8AAAA9VVVVVXwAAAPVVVV8AAAA9VVVVVfAAAA9VVVV8AAAA9VVVVVfAAAA9VVVV8AAAA9VVVVV8AAAD1VVVV8AAAA9VVVVV8AAAD1VVVV8AAAA9VVVVXwAAAPVVVVV8AAAA9VVVVXwAAAPVVVVV8AAAA9VVVVfAAAA9VVVVV8AAAA9VVVVfAAAA9VVVVV8AAAA9VVVV8AAAD1VVVVV8AAAA9VVVV8AAAPVVVVVV8AAAA9VVVXwAAAPVVVVVV8AAAA9VVVXwAAA9VVVVVV8AAAA9VVVfAAAA9VVVVVXwAAAA9VVVfAAAAP//////AAAAAP///8AAAAD/////8AAAAAD///8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAP///////////8AAAAAD///f///////////AAAAAP///VVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVVV/////9VVVVVVVVVVVVVVV/////9VVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "58", "buffer":"VVVVVVVVVVVVVVVVVVVVVf///////////////1VVX///////////////9VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVV8AAAAD//////////1VVfAAAAD//////////1VVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAD1VVVVVVVVVVVVVfAAAA9VVVVVVVVVVVVVXwAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VV///9VVVVVVVfAAAAPVf/////VVVVVVXwAAAD1/8AAAP/VVVVVV8AAAA9/AAAAAD/VVVVVfAAAAD8AAAAAAD9VVVVXwAAAAMAAAAAAAD9VVVV8AAAAAAAAAAAAAP1VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VV8AAAAAAD//AAAAAAD1VfAAAAAAP///AAAAAA9VXwAAAAAP1VX8AAAAAPVV8AAAAAPVVVXwAAAAA9VfAAAAAPVVVVfAAAAAPVXwAAAAD1VVVXwAAAAD1V//wAAD1VVVVfAAAAAPVf////D1VVVVXwAAAAD1VVV///9VVVVVfAAAAA9VVVVVX9VVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA//////9VVVVVVXwAAAAP//////1VVVVVV8AAAAD/AAAAA9VVVVVVfAAAAA/wAAAAPVVVVVVXwAAAAP8AAAAD1VVVVVV8AAAAD/AAAAA9VVVVVVfAAAAA98AAAAPVVVVVVXwAAAA9fAAAAD1VVVVVV8AAAAPXwAAAAPVVVVVV8AAAAD18AAAAD1VVVVVfAAAAA9fAAAAA9VVVVVXwAAAAPXwAAAAD1VVVVXwAAAAPVfAAAAA9VVVVV8AAAAD1XwAAAAD1VVVV8AAAAA9V8AAAAA9VVVV8AAAAA9VXwAAAAD1VVV8AAAAAPVV8AAAAAP1VV8AAAAAD1VXwAAAAA/9f8AAAAAD1VV8AAAAAA//8AAAAAA9VVXwAAAAAAPAAAAAAA9VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAPVVVVVfwAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAPVVVVVVV/AAAAAAAAAAPVVVVVVVX8AAAAAAAAA/VVVVVVVVX8AAAAAAAD/VVVVVVVVVf/wAAAAA/9VVVVVVVVVVf///////1VVVVVVVVVVVV/////9VVVVVVQ=="},
+ {"width" : "56", "buffer":"VVVVVVX/////1VVVVVVVVVVVf//////9VVVVVVVVVVf/AAAAAD/VVVVVVVVVX8AAAAAAA/1VVVVVVVX8AAAAAAAAP1VVVVVVV/AAAAAAAAAD1VVVVVVfAAAAAAAAAAD1VVVVVXwAAAAAAAAAAD1VVVVVfAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAPVVVV8AAAAAAwAAAAAA9VVVXwAAAAD//AAAAAA9VVV8AAAAA/3/AAAAAD1VVXwAAAAPVVfAAAAAPVVV8AAAAD1VVfAAAAAPVVXwAAAA9VVVfAAAAA9VVfAAAAPVVVVfAAAAD1VXwAAAA9VVVV8AAAAD1VfAAAAPVVVVXwAAAAPVV8AAAA9VVVVXwAAAA9VfAAAAD1VVVVfAAAAD1V8AAAAPVVVVV8AAAAPVXwAAAD1VVVVXwAAAA9VfAAAAPVVVVVfAAAAA9V8AAAA9VVVVV8AAAAD1fAAAAD1VVVVXwAAAAPV8AAAAPVVVVVXwAAAA9XwAAAA9VVVVVfAAAAD1fAAAAD1VVVVV//////V8AAAAPVVVVVX/////9XwAAAA9VVVVVVVVVVVVfAAAAPVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVfAAAAD1VVVVVVVVVVVV8AAAAPVVVVVVVVVVVVXwAAAA9VVVf//VVVVVVfAAAAD1VX/////VVVVV8AAAAPVX/8AAP/1VVVXwAAAA9V/AAAAAP9VVVfAAAAD1/AAAAAAD9VVV8AAAAPfwAAAAAAA9VVXwAAAAPwAAAAAAAA9VVfAAAAAMAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAPVfAAAAAAAD//AAAAAAPV8AAAAAAA///AAAAAA9XwAAAAAAPVVfAAAAAA9fAAAAAAD1VVfAAAAAD18AAAAAA9VVVfAAAAAPXwAAAAAPVVVVfAAAAAPfAAAAAD1VVVVfAAAAA98AAAAAPVVVVV8AAAAD3wAAAAA9VVVVV8AAAAD/AAAAAPVVVVVXwAAAAP8AAAAA9VVVVVfAAAAA/wAAAAD1VVVVV8AAAAD/AAAAAPVVVVVV8AAAAP8AAAAD1VVVVVXwAAAA/wAAAAPVVVVVVfAAAAD/AAAAA9VVVVVV8AAAAP8AAAAD1VVVVVXwAAAA/wAAAAPVVVVVVfAAAAD/AAAAA9VVVVVV8AAAAPfAAAAD1VVVVVXwAAAA98AAAAPVVVVVVfAAAAD3wAAAA9VVVVVV8AAAAPfAAAAD1VVVVVXwAAAA98AAAAPVVVVVVfAAAAD3wAAAA9VVVVVV8AAAAPXwAAAA9VVVVVXwAAAA9fAAAAD1VVVVV8AAAAD18AAAAPVVVVVXwAAAAPXwAAAA9VVVVVfAAAAD1XwAAAA9VVVVXwAAAAPVfAAAAD1VVVVfAAAAA9V8AAAAD1VVVXwAAAAD1V8AAAAD1VVVfAAAAA9VXwAAAAPVVVXwAAAAD1VfAAAAAP1VX8AAAAA9VVfAAAAAP///AAAAAD1VV8AAAAAD//AAAAAA9VVV8AAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAD1VVVVVfwAAAAAAAAAA9VVVVVVfwAAAAAAAAAPVVVVVVVX8AAAAAAAAP1VVVVVVVX/AAAAAAAP9VVVVVVVVV/8AAAAA/9VVVVVVVVVVf//////9VVVVVVVVVVVV/////1VVVVVU="},
+ {"width" : "59", "buffer":"VVVVVVVVVVVVVVVVVVVX///////////////////////////////////////8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAPX////////////8AAAAA9X////////////8AAAAPVVVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVXwAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAD1VVVVVVVVVVVVV8AAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVf//////VVVVVVVVVVVVV//////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "57", "buffer":"VVVVVVf/////1VVVVVVVVVVVf///////1VVVVVVVVVX/wAAAAAP/VVVVVVVVVfwAAAAAAAP1VVVVVVVX8AAAAAAAAA/VVVVVVVfwAAAAAAAAAP1VVVVVV8AAAAAAAAAAA9VVVVVXwAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAPVVVXwAAAAAD/AAAAAAPVVVfAAAAAA//8AAAAAD1VVfAAAAAD9V/AAAAAD1VVfAAAAAPVVXwAAAAA9VV8AAAAA9VVV8AAAAA9VV8AAAAD1VVVfAAAAA9VV8AAAAD1VVVXwAAAAPVXwAAAAPVVVVXwAAAAPVXwAAAAPVVVVV8AAAAPVXwAAAA9VVVVV8AAAAPVXwAAAA9VVVVV8AAAAPVXwAAAA9VVVVV8AAAAPVXwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAD1XwAAAA9VVVVVfAAAAPVXwAAAA9VVVVV8AAAAPVXwAAAA9VVVVV8AAAAPVXwAAAA9VVVVV8AAAAPVV8AAAAPVVVVV8AAAAPVV8AAAAPVVVVXwAAAA9VV8AAAAPVVVVXwAAAA9VVfAAAAD1VVVXwAAAA9VVfAAAAD1VVVfAAAAD1VVfAAAAA9VVV8AAAAD1VVXwAAAAPVVXwAAAAPVVVXwAAAAD///AAAAAPVVVV8AAAAA//8AAAAA9VVVVfAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAPVVVVVV8AAAAAAAAAAA9VVVVVVfAAAAAAAAAAD1VVVVVVXwAAAAAAAAAPVVVVVVVfAAAAAAAAAAD1VVVVVV8AAAAAAAAAAA9VVVVVfwAAAAAAAAAAAP1VVVV/AAAAAAAAAAAAD9VVVXwAAAAAAAAAAAAAPVVVXwAAAAAD/AAAAAAD1VVfAAAAAD///AAAAAD1VV8AAAAAP9V/wAAAAA9VV8AAAAA9VVV8AAAAA9VXwAAAAD1VVVfAAAAAPVXwAAAAPVVVVXwAAAAPVXwAAAA9VVVVV8AAAAD1fAAAAA9VVVVV8AAAAD1fAAAAD1VVVVVfAAAAD1fAAAAD1VVVVVfAAAAA98AAAAD1VVVVVfAAAAA98AAAAD1VVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAAP8AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAPVVVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVfAAAAA98AAAAD1VVVVVfAAAAA98AAAAD1VVVVVfAAAAA9fAAAAA9VVVVV8AAAAA9fAAAAA9VVVVV8AAAAD1fAAAAAPVVVVXwAAAAD1XwAAAAD1VVVfAAAAAD1XwAAAAA/VVV8AAAAAPVXwAAAAAP/X/wAAAAAPVV8AAAAAA///AAAAAAPVV8AAAAAAA8AAAAAAA9VVfAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAD9VVVVXwAAAAAAAAAAAP1VVVVV/AAAAAAAAAAA9VVVVVVfwAAAAAAAAAP1VVVVVVV/AAAAAAAAD/VVVVVVVVf/wAAAAAD/1VVVVVVVVV////////9VVVVVVVVVVVf/////9VVVVVV"},
+ {"width" : "57", "buffer":"VVVVVVf/////VVVVVVVVVVVVX///////VVVVVVVVVVV/wAAAAA/9VVVVVVVVVf8AAAAAAA/1VVVVVVVV/AAAAAAAAD9VVVVVVVfwAAAAAAAAAPVVVVVVV/AAAAAAAAAAD9VVVVVXwAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAA9VVVXwAAAAAAMAAAAAAPVVVfAAAAAA//8AAAAAPVVVfAAAAAD/3/AAAAAD1VV8AAAAAPVVXwAAAAD1VV8AAAAA9VVV8AAAAA9VXwAAAAD1VVVfAAAAA9VXwAAAAPVVVVXwAAAA9VXwAAAAPVVVVXwAAAAPVfAAAAA9VVVVV8AAAAPVfAAAAA9VVVVV8AAAAPVfAAAAA9VVVVVfAAAAD1fAAAAD1VVVVVfAAAAD1fAAAAD1VVVVVfAAAAD1fAAAAD1VVVVVfAAAAD18AAAAD1VVVVVfAAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAA98AAAAD1VVVVVXwAAAAP8AAAAD1VVVVVfAAAAAPfAAAAD1VVVVVfAAAAAPfAAAAD1VVVVVfAAAAAPfAAAAD1VVVVVfAAAAAPfAAAAA9VVVVVfAAAAAPfAAAAA9VVVVV8AAAAAPfAAAAA9VVVVV8AAAAAPfAAAAAPVVVVV8AAAAAPXwAAAAPVVVVXwAAAAAPXwAAAAD1VVVXwAAAAAPXwAAAAD1VVVfAAAAAAPV8AAAAA9VVV8AAAAAAPV8AAAAAP1VfwAAAAAAPV8AAAAAD///AAAAAAAPVfAAAAAAP/wAAAAAAAPVfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAPVVfAAAAAAAAADAAAAAPVVXwAAAAAAAAPwAAAAPVVX8AAAAAAAA98AAAAPVVVfAAAAAAAD18AAAAPVVVX8AAAAAA/V8AAAAPVVVV/wAAAAP9V8AAAAPVVVVX/8AA//VV8AAAAPVVVVVf////1VV8AAAAPVVVVVVX//VVVXwAAAAPVVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVXwAAAA9VVVVVVVVVVVVXwAAAA9V//////VVVVVXwAAAA9V//////VVVVVXwAAAA9V8AAAAPVVVVVXwAAAA9V8AAAAPVVVVVXwAAAD1V8AAAAPVVVVVXwAAAD1V8AAAAPVVVVVXwAAAD1V8AAAAPVVVVVXwAAAD1V8AAAAPVVVVVfAAAAD1V8AAAAD1VVVVfAAAAPVV8AAAAD1VVVVfAAAAPVVfAAAAD1VVVVfAAAAPVVfAAAAD1VVVV8AAAAPVVfAAAAA9VVVV8AAAA9VVfAAAAA9VVVXwAAAA9VVXwAAAAPVVVXwAAAA9VVXwAAAAPVVVfAAAAD1VVXwAAAAD9VV8AAAAD1VVV8AAAAA///wAAAAPVVVV8AAAAAD//AAAAAPVVVVfAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAPVVVVVVfAAAAAAAAAAA9VVVVVVXwAAAAAAAAAD1VVVVVVV8AAAAAAAAAPVVVVVVVVfwAAAAAAAD9VVVVVVVVX/AAAAAAA/1VVVVVVVVVf8AAAAA/9VVVVVVVVVVV///////VVVVVVVVVVVVX/////VVVVVVV"},
+ {"width" : "20", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////////////AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP//////9//////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////////////8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA//////////////VVVVVVU="}
+ ]
+}
diff --git a/apps/contourclock/fonts/font-Bangers.json b/apps/contourclock/fonts/font-Bangers.json
new file mode 100644
index 000000000..73f2ca1dd
--- /dev/null
+++ b/apps/contourclock/fonts/font-Bangers.json
@@ -0,0 +1,17 @@
+{
+ "name":"Bangers",
+ "size":"100",
+ "characters":[
+ {"width" : "60", "buffer":"VVVVVVVVVVVVX//VVVVVVVVVVVVVVVVX////VVVVVVVVVVVVVVX/8AA/1VVVVVVVVVVVVV/8AAAA/VVVVVVVVVVVVX8AAAAAP1VVVVVVVVVVVfAAAAAAA9VVVVVVVVVVX8AAAAAAA9VVVVVVVVVVfwAAAAAAAPVVVVVVVVVV8AAAAAAAAD1VVVVVVVVXwAAAAAAAAD1VVVVVVVVfAAAAAAAAAA9VVVVVVVV8AAAAAAAAAA9VVVVVVVXwAAAAAAAAAA9VVVVVVVXwAAAAAAAAAAPVVVVVVVfAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAA9VVVXwAAAAAAD/wAAAAA9VVVfAAAAAAA//8AAAAA9VVVfAAAAAAP9VfAAAAAPVVV8AAAAAA/VVXwAAAAPVVV8AAAAAD1VVV8AAAAPVVV8AAAAAD1VVVfAAAAPVVXwAAAAAPVVVVfAAAAPVVXwAAAAA9VVVVXwAAAPVVfAAAAAD1VVVVXwAAAPVVfAAAAAD1VVVVXwAAAPVV8AAAAAPVVVVVXwAAAPVV8AAAAA9VVVVVV8AAA9VV8AAAAA9VVVVVV8AAA9VXwAAAAD1VVVVVV8AAA9VXwAAAAD1VVVVVV8AAA9VXwAAAAPVVVVVVV8AAA9VfAAAAAPVVVVVVV8AAA9VfAAAAAPVVVVVVV8AAA9VfAAAAA9VVVVVVV8AAA9VfAAAAA9VVVVVVV8AAA9V8AAAAA9VVVVVVV8AAA9V8AAAAD1VVVVVVXwAAD1V8AAAAD1VVVVVVXwAAD1V8AAAAD1VVVVVVXwAAD1XwAAAAPVVVVVVVXwAAD1XwAAAAPVVVVVVVXwAAD1XwAAAAPVVVVVVVfAAAD1XwAAAAPVVVVVVVfAAAPVXwAAAA9VVVVVVVfAAAPVXwAAAA9VVVVVVVfAAAPVfAAAAA9VVVVVVV8AAAPVfAAAAA9VVVVVVV8AAA9VfAAAAA9VVVVVVV8AAA9VfAAAAA9VVVVVVXwAAA9VfAAAAD1VVVVVVXwAAA9VfAAAAD1VVVVVVfAAAD1VfAAAAD1VVVVVVfAAAD1VfAAAAD1VVVVVV8AAAD1V8AAAAD1VVVVVV8AAAPVV8AAAAD1VVVVVXwAAAPVV8AAAAD1VVVVVfAAAAPVV8AAAAD1VVVVVfAAAA9VV8AAAAA9VVVVV8AAAA9VV8AAAAA9VVVVXwAAAA9VV8AAAAA9VVVVfAAAAD1VV8AAAAA9VVVV8AAAAD1VV8AAAAAPVVVXwAAAAPVVVfAAAAAD1VV/AAAAAPVVVfAAAAAA9Vf8AAAAA9VVVfAAAAAAP//AAAAAA9VVVfAAAAAAD/wAAAAAD1VVVfAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAPVVVVVVVXwAAAAAAAAAA9VVVVVVVXwAAAAAAAAAD1VVVVVVVV8AAAAAAAAAPVVVVVVVVVfAAAAAAAAA9VVVVVVVVVXwAAAAAAAP1VVVVVVVVVV8AAAAAAD/VVVVVVVVVVVfwAAAAA/1VVVVVVVVVVVX/wAAA/9VVVVVVVVVVVVVf/////VVVVVVVVVVVVVVVf///VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "40", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/VVVVVVVVVVf//1VVVVVVVV///89VVVVVVf///AAPVVVVX///8AAAPVVVf///AAAAAD1Vf//wAAAAAAA9V//AAAAAAAAAPVfAAAAAAAAAAPVXwAAAAAAAAAD1V8AAAAAAAAAA9VfAAAAAAAAAAPVfAAAAAAAAAAD1XwAAAAAAAAAA9V8AAAAAAAAAA9VfAAAAAAAAAAPVXwAAAAAAAAAD1V8AAAAAAAAAA9VfAAAAAAAAAAPVXwAAAAAAAAAPVXwAAAAAAAAAD1V8AAAAAAAAAA9VfAAAAAAAAAAPVXwAAAAAAAAAD1V8AAAAAAAAAD1VfAAAAAAAAAA9VXwAAAAAAAAAPVXwAD/8AAAAAD1V8P///wAAAAA9Vf//1VfAAAAA9VX/VVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAA9VVVVVVXwAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVV8AAAAAPVVVVVVfAAAAAD1VVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVVfAAAAAPVVVVVVXwAAAAD1VVVVVXwAAAAA9VVVVVV8AAAAAPVVVVVVfAAAAAD1VVVVVXwAAAAD1VVVVVV8AAAAA9VVVVVV8AAAAAPVVVVVVfAAAAAD1VVVVVXwAAAAA9VVVVVV8AAAAAPVVVVVVfAAAAAPVVVVVVfAAAAAD1VVVVVXwAAAAA9VVVVVV8AAAAAPVVVVVVfAAAAAD1VVVVVXwAAAAA9VVVVVXwAAAAD/VVVVVV8AAAD//VVVVVVfAAD//1VVVVVVXwD//1VVVVVVVV///1VVVVVVVVV//1VVVVVVVVVVXVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "65", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///1VVVVVVVVVVVVVVVV//////VVVVVVVVVVVVVVV//AAAD/9VVVVVVVVVVVVV/wAAAAAP9VVVVVVVVVVVV/wAAAAAAA/VVVVVVVVVVV/wAAAAAAAA/VVVVVVVVVVfwAAAAAAAAAPVVVVVVVVVXwAAAAAAAAAAPVVVVVVVVX8AAAAAAAAAAAPVVVVVVVV/AAAAAAAAAAAA9VVVVVVVXwAAAAAAAAAAAA9VVVVVVV8AAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAA9VVVXwAAAAAAAMAAAAAAAD1VVVfAAAAAAA//AAAAAAAPVVVXwAAAAAAP9/AAAAAAA9VVVfAAAAAAD1VfAAAAAAD1VVV8AAAAAA9VVfAAAAAAPVVVXwAAAAAPVVV8AAAAAA9VVVfAAAAAA9VVV8AAAAAD1VVXwAAAAAPVVVXwAAAAAPVVVfAAAAAA9VVVfAAAAAA9VVV8AAAAAD1VVV8AAAAAD1VVXwAAAAAPVVVXwAAAAAPVVVfAAAAAA9VVVfAAAAAA9VVV8AAAAAD1VVV8AAAAAPVVVXwAAAAD/VVVfAAAAAA9VVVfAA////9VVXwAAAAAD1VVV//////VVVVfAAAAAAPVVVX//1VVVVVVXwAAAAAD1VVVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVXwAAAAAAPVVVVVVVVVVVVV8AAAAAAD1VVVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVV8AAAAAAAPVVVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVX8AAAAAAAD1VVVVVVVVVVV/AAAAAAAA9VVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVXwAAAAAAAD1VVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVV/AAAAAAAAD1VVVVVVVVVVfwAAAAAAAA9VVVVVVVVVVXwAAAAAAAAPVVVVVVVVVVV8AAAAAAAAD1VVVVVVVVVVfAAAAAAAAA9VVVVVVVVVVXwAAAAAAAA/VVVVVVVVVVV8AAAAAAAAP1VVVVVVVVVVfAAAAAAAAD1VVVVVVVVVVXwAAAAAAAA9VVVVVVVVVVV8AAAAAAAAPVVVVVVVVVVVfAAAAAAAAP1VVVVVVVVVVXwAAAAAAAD9VVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVfAAAAAAAA/VVVVVVVVVVVXwAAAAAAAP1VVVVVVVVVVV8AAAAAAAP1VVVVVVVVVVVfAAAAAAAD9VVVVVVVVVVVV8AAAAAAD9VVVVVVVVVVVVfAAAAAAA/VVVVVVVVVVVVXwAAAAAA/VVVVVVVVVVVVV8AAAAAAP1VVVVVVVVVVVVXwAAAAAD1VVVVVV//1VVVV8AAAAAA9VVf//////VVVVXwAAAAAA///////wA9VVVV8AAAAAAA//8AAAAAD1VVVXwAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAD9VVVV8AAAAAAAAAD//////1VVVXwAAAAAA/////////VVVVVfAA////////VVVVVVVVVVV///////1VVVVVVVVVVVVVX//1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "62", "buffer":"VVVVVVVVVVVVVVVV////1VVVVVVVX////////////1VVVX///////////wAAAPVVVVf///AAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAD1VVVVfAAA//wAAAAAAAAPVVVVV//////wAAAAAAAA9VVVVX///1VXwAAAAAAAD1VVVVVVVVVV8AAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVXwAAAAAAAAP1VVVVVVVVV8AAAAAAAAD9VVVVVVVVVfAAAAAAAAD9VVVVVVVVVfwAAAAAAAD/VVVVVVVVVX8AAAAAAAA/VVVVVVVVVV8AAAAAAAA/VVVVVVVVVVfAAAAAAAA/1VVVVVVVVVfwAAAAAAAP1VVVVVVVVVX8AAAAAAAP1VVVVVVVVVV8AAAAAAAP9VVVVVVVVVV/AAAAAAAP9VVVVVVVVVVfwAAAAAAD9VVVVVVVVVVfwAAAAAAD9VVVVVVVVVVX8AAAAAAA/VVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVV8AAAAAAAP1VVVVVVVVVVXwAAAAAAAP/1VVVVVVVVV8AAAAAAAAD/9VVVVVVVVXwAAAAAAAAAD/VVVVVVVVfAAAAAAAAAAA/1VVVVVVV8AAAAAAAAAAAP1VVVVVVXwAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAD/8AAAAAAAAD1VVVV8AP////8AAAAAAAPVVVVX////VV//AAAAAAAPVVVVf/9VVVVV/AAAAAAA9VVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVfAAAAAD1VVVVVf//9VVVXwAAAAA9VVf//////9VVV8AAAAAD1VV///8AAD1VVfAAAAAA9VVfAAAAAAD1VXwAAAAAD1VV8AAAAAAD1X8AAAAAA9VVXwAAAAAAD//AAAAAAD1VVfAAAAAAAD/AAAAAAA9VVV8AAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAP1VVVVVVV8AAAAAAAAAAD9VVVVVVVV8AAAAAAAAAD9VVVVVVVVV8AAAAAAAAD/VVVVVVVVVV/AAAAAAAD/VVVVVVVVVVV/wAAAAAP/VVVVVVVVVVVVf///////VVVVVVVVVVVVVX/////9VVVVVVVVVVU="},
+ {"width" : "59", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/1VVVVVVVVVVVVf//////VVVVVVVVVVVVV////8D1VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVV8AAAAD1VVVVVf/1VVVVXwAAAAPVVVf////VVVVVfAAAAA9V////8A9VVVVXwAAAAD1f/8AAAD1VVVVfAAAAA9V8AAAAAPVVVVV8AAAAD1XwAAAAA9VVVVXwAAAAPV8AAAAAPVVVVV8AAAAD1XwAAAAA9VVVVXwAAAAPVfAAAAAD1VVVVfAAAAA9V8AAAAAPVVVVXwAAAAPVXwAAAAA9VVVVfAAAAA9V8AAAAAD1VVVV8AAAAD1XwAAAAA9VVVVXwAAAA9VfAAAAAD1VVVV8AAAAD1V8AAAAAPVVVVXwAAAAPVXwAAAAA9VVVVfAAAAA9VfAAAAAD1VVVXwAAAAPVXwAAAAAPVVVVfAAAAA9VfAAAAAD1VVVV8AAAAD1V8AAAAAPVVVVfAAAAA9VXwAAAAA9VVVV8AAAAD1VfAAAAAD1VVVXwAAAAPVV8AAAAAPVVVVfAAAAD1VfAAAAAA9VVVXwAAAAPVV8AAAAAD1VVVfAAAAA9VXwAAAAA9VVVV8AAAAD1VfAAAAAD1VVVfAAAAA9VV8AAAAAPVVVV8AAAAD1VXwAAAAA9VVVXwAAAAPVV8AAAAAD1VVV8AAAAD1VXwAAAAAPVVVXwAAAAPVVfAAAAAD1VVVfAAAAA9VV8AAAAAPVVVV8AAAAD1VXwAAAAA9VVVfAAAAA9VVfAAAAAD1VVV8AAAAD1VXwAAAAAPVVVXwAAAAPVVfAAAAAD1VVV8AAAAD1VV8AAAAAPVVVXwAAAAPVVXwAAAAA9VVVfAAAAA9VVfAAAAAD1VVXwAAAAA///wAAAAAD//VfAAAAAA//8AAAAAAD//V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAPVVV8AAAAA/wAAAAAAD/9VVXwD/////wAAAAAA//1VVX/////1XwAAAAAPVVVVVf/VVVVVfAAAAAD1VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVXwAAAAAD1VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVV8AAAAAA9VVVVVVVVVVVXwAAAA//VVVVVVVVVVVVfAAA///1VVVVVVVVVVVV8A///1VVVVVVVVVVVVVX///1VVVVVVVVVVVVVVVf/1VVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "57", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX////VVVVVVf////////////VVVX//////////8AAAPVVVf//wAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAD1VVfAAAAAAAD///////1VVfAAAAAA/////////VVVfAAAAAD/9VVVVVVVVVVfAAAAAPVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVXwAAAAAP/1VVVVVVVVVXwAAAAAD///1VVVVVVVXwAAAAAAAP//9VVVVVVXwAAAAAAAAAP/1VVVVVXwAAAAAAAAAAD/VVVVVXwAAAAAAAAAAAP9VVVVfAAAAAAAAAAAAA/VVVVfAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAPVV8AAP///8AAAAAAAAPVV8P//////8AAAAAAAPVV///1VVVX/AAAAAAAPVV/1VVVVVVXwAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAA9V//1VVVVVVVXwAAAAA9V/////1VVVVXwAAAAA9V8AP///1VVVXwAAAAA9V8AAAAP1VVVfAAAAAD1V8AAAAD1VVVfAAAAAD1V8AAAAD1VVV8AAAAAD1V8AAAAD1VVV8AAAAAPVV8AAAAD1VVXwAAAAAPVV8AAAAA9VVfAAAAAA9VV8AAAAAPVX8AAAAAA9VV8AAAAAD//wAAAAAA9VV8AAAAAA/8AAAAAAD1VV8AAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAA9VVVVVXwAAAAAAAAAAD1VVVVVXwAAAAAAAAAAPVVVVVVV8AAAAAAAAAA9VVVVVVVfAAAAAAAAAD1VVVVVVVfAAAAAAAAAPVVVVVVVVXwAAAAAAAD9VVVVVVVVV8AAAAAAAP1VVVVVVVVVfwAAAAAD9VVVVVVVVVVX/AAAAA/1VVVVVVVVVVVf/AAD/9VVVVVVVVVVVVV/////VVVVVVVVVVVVVVV//9VVVVVVVVVVV"},
+ {"width" : "59", "buffer":"VVVVVVVVVVVX///1VVVVVVVVVVVVVVf/////VVVVVVVVVVVVVf/AAAD/VVVVVVVVVVVVf8AAAAAPVVVVVVVVVVVf8AAAAAAPVVVVVVVVVVX8AAAAAAAPVVVVVVVVVX8AAAAAAAAPVVVVVVVVV/AAAAAAAAAPVVVVVVVVfAAAAAAAAAAPVVVVVVVXwAAAAAAAAAA9VVVVVVV8AAAAAAAAAAA9VVVVVVfAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAA/AAAAAA9VVV8AAAAAAAP/AAAAAD1VVXwAAAAAAD1fAAAAD/VVV8AAAAAAA9VfAAAD/VVVXwAAAAAAPVVfAAA/VVVV8AAAAAAD1VV8AA/VVVVXwAAAAAAPVVXwA/1VVVV8AAAAAAD1VVfA/1VVVVXwAAAAAAPVVVf/1VVVVV8AAAAAAD1VVV/1VVVVVXwAAAAAAPVVVX1VVVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAA9VVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVfAAAAAAD3////1VVVVVV8AAAAAAD//////VVVVVXwAAAAAADAAAAD/VVVVV8AAAAAAAAAAAAAP1VVVXwAAAAAAAAAAAAAP1VVVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAP///8AAAAAPVfAAAAAAD/////AAAAA9V8AAAAAA9VVVV/AAAAD1XwAAAAAPVVVVVfAAAAPVfAAAAAA9VVVVV8AAAA9V8AAAAAD1VVVVV8AAAD1XwAAAAAPVVVVVXwAAAPVfAAAAAA9VVVVVfAAAA9V8AAAAAA9VVVVV8AAAD1V8AAAAAD1VVVVfAAAAPVXwAAAAAPVVVVV8AAAA9VfAAAAAA9VVVVfAAAAD1V8AAAAAD1VVVV8AAAAPVXwAAAAAD1VVVfAAAAA9VfAAAAAAPVVVfwAAAAD1VfAAAAAAPVVX8AAAAAPVV8AAAAAAP1/8AAAAAD1VXwAAAAAAP//AAAAAAPVVfAAAAAAADwAAAAAAA9VVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAA9VVVVVVXwAAAAAAAAAA/VVVVVVVX8AAAAAAAAAP1VVVVVVVX8AAAAAAAAP1VVVVVVVVV/AAAAAAAP9VVVVVVVVVV/8AAAAA/9VVVVVVVVVVVf/8AA//9VVVVVVVVVVVVV/////1VVVVVVVVVVVVVVV//1VVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "53", "buffer":"VVVVVVVVVVVVVV///9VVVVVVVVVV///////VVVVVVVf//////wAA9VVVf//////wAAAAAD1VVV///8AAAAAAAAA9VVVfAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAPVVVXwAAAAAAAAAAAD1VVVfAAAAAAAAAAAAPVVVV8AAAAAAAAAAAA9VVVXwAAAAAAAAAAAPVVVV8AAAAAAAAAAAA9VVVXwAAAAAAAAAAAD1VVVfAAAAAAAAAAAAPVVVV8AAAAAAAAAAAD1VVVXwAAAAAAAAAAAPVVVVfAAAAAAAAAAAA9VVVV8AAAAAAAAAAAPVVVVfAAAAAAAAAAAA9VVVV8AAAAAAAAAAAD1VVVXwAAAAAAAAAAA9VVVVfAAAAAAAAAAAD1VVVV8AAAAAAAAAAAPVVVVXwAAA/AAAAAAD1VVVV8AA///AAAAAAPVVVVXz///1fAAAAAA9VVVVf//1VV8AAAAAPVVVVV/VVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAA9VVVVVVVVVV8AAAAP/1VVVVVVVVVXwD////9VVVVVVVVVV/////9VVVVVVVVVVVX//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "69", "buffer":"VVVVVVVVVVVVV//////VVVVVVVVVVVVVVVV////////VVVVVVVVVVVVVVf/AAAAAA/1VVVVVVVVVVVVX/AAAAAAAA/VVVVVVVVVVVV/wAAAAAAAAP1VVVVVVVVVVf8AAAAAAAAAA9VVVVVVVVVV/AAAAAAAAAAA9VVVVVVVVVfwAAAAAAAAAAAPVVVVVVVVV/AAAAAAAAAAAAD1VVVVVVVXwAAAAAAAAAAAAD1VVVVVVVfAAAAAAAAAAAAAA9VVVVVVV8AAAAAAAAAAAAAA9VVVVVVXwAAAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAAPVVVVXwAAAAAAD//wAAAAAAPVVVVXwAAAAAA////AAAAAAPVVVVfAAAAAAD9VVfwAAAAAPVVVVfAAAAAAPVVVV8AAAAAPVVVVfAAAAAA9VVVVfAAAAAPVVVVfAAAAAD1VVVVfAAAAAPVVVV8AAAAAPVVVVVXwAAAAPVVVV8AAAAAPVVVVVXwAAAA9VVVV8AAAAA9VVVVVXwAAAA9VVVV8AAAAA9VVVVVfAAAAA9VVVV8AAAAA9VVVVVfAAAAD1VVVV8AAAAA9VVVVVfAAAAD1VVVV8AAAAA9VVVVV8AAAAPVVVVV8AAAAA9VVVVXwAAAAPVVVVVfAAAAA9VVVVXwAAAA9VVVVVfAAAAA9VVVVfAAAAA9VVVVVfAAAAAPVVVV8AAAAD1VVVVVfAAAAAD1VVfwAAAAPVVVVVVXwAAAAA9VV/AAAAA9VVVVVVXwAAAAAP//wAAAAD1VVVVVVV8AAAAAD//AAAAAPVVVVVVVVfAAAAAAAAAAAAD9VVVVVVVVfAAAAAAAAAAAAP1VVVVVVVVXwAAAAAAAAAAA9VVVVVVVVVV8AAAAAAAAAAA9VVVVVVVVVVfAAAAAAAAAAA9VVVVVVVVVX8AAAAAAAAAAAPVVVVVVVVV/wAAAAAAAAAAAD1VVVVVVVX8AAAAAAAAAAAAD1VVVVVVVfAAAAAAAAAAAAAA9VVVVVVX8AAAAAAAAAAAAAA9VVVVVVfwAAAAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAAAAAD1VVVVXwAAAAAAP//AAAAAAD1VVVVfAAAAAAD///8AAAAAD1VVVV8AAAAAA/1VV/AAAAAA9VVVV8AAAAAD9VVVXwAAAAA9VVVXwAAAAA/VVVVV8AAAAA9VVVXwAAAAD9VVVVV8AAAAA9VVVfAAAAAPVVVVVVfAAAAA9VVVfAAAAA9VVVVVVfAAAAAPVVV8AAAAD1VVVVVVXwAAAAPVVV8AAAAD1VVVVVVXwAAAAPVVXwAAAAPVVVVVVVXwAAAAPVVXwAAAA9VVVVVVVXwAAAAPVVXwAAAA9VVVVVVVXwAAAAPVVXwAAAD1VVVVVVVXwAAAAPVVfAAAAD1VVVVVVVXwAAAAPVVfAAAAD1VVVVVVVXwAAAA9VVfAAAAD1VVVVVVVXwAAAA9VVfAAAAD1VVVVVVVfAAAAA9VVfAAAAD1VVVVVVVfAAAAA9VV8AAAAD1VVVVVVV8AAAAA9VV8AAAAD1VVVVVVV8AAAAA9VV8AAAAA9VVVVVVXwAAAAD1VV8AAAAA9VVVVVVfAAAAAD1VV8AAAAAPVVVVVX8AAAAAPVVV8AAAAAD9VVVV/wAAAAAPVVV8AAAAAA/////8AAAAAA9VVV8AAAAAAD////AAAAAAA9VVV8AAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAA9VVVVVV8AAAAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAAAAPVVVVVVVfAAAAAAAAAAAAAA9VVVVVVVfAAAAAAAAAAAAAP1VVVVVVVXwAAAAAAAAAAAA/VVVVVVVVV/AAAAAAAAAAAP1VVVVVVVVVf8AAAAAAAAAD/VVVVVVVVVVV/wAAAAAAAD/1VVVVVVVVVVVX/wAAAAAD/9VVVVVVVVVVVVVf///////9VVVVVVVVVVVVVVVf/////9VVVVVVVVVVV"},
+ {"width" : "58", "buffer":"VVVVVVV/////9VVVVVVVVVVVVf///////VVVVVVVVVVV/8AAAAAP/VVVVVVVVVX/AAAAAAAD9VVVVVVVVX8AAAAAAAAD9VVVVVVVfwAAAAAAAAAP1VVVVVVfwAAAAAAAAAAPVVVVVVfAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VXwAAAAAAA/wAAAAAAPVXwAAAAAAD//wAAAAAD1V8AAAAAAP9V/AAAAAAPVfAAAAAAP1VV8AAAAAD1fAAAAAAPVVVXwAAAAA9XwAAAAAPVVVV8AAAAAD18AAAAAPVVVVXwAAAAA9fAAAAAD1VVVV8AAAAAPXwAAAAD1VVVVfAAAAAD18AAAAA9VVVVXwAAAAAPfAAAAAPVVVVVfAAAAAD/AAAAAD1VVVVXwAAAAA/wAAAAA9VVVVV8AAAAAP8AAAAAPVVVVV8AAAAAD/AAAAAD1VVVVfAAAAAA/wAAAAAPVVVVXwAAAAAP8AAAAAA9VVVXwAAAAAD3wAAAAAD1VVXwAAAAAA98AAAAAAP1VfwAAAAAAPfAAAAAAA///wAAAAAAD3wAAAAAAA//AAAAAAAA98AAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAD1VV/AAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAPVVVVfwAAAAA8AAAAAAD1VVVV/8AAAP/wAAAAAA9VVVVV/////9fAAAAAAPVVVVVVf///VXwAAAAAD1VVVVVVVVVVV8AAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVfwAAAAAAPVVVVVVVVVVfwAAAAAAD1VVVVVVVVVfAAAAAAAD1VVVVVVVVV/AAAAAAAD1VVVVVVVVf/AAAAAAAA9VVVVVVV//8AAAAAAAA9VVVVVVV//AAAAAAAAAPVVVVVVVfAAAAAAAAAAPVVVVVVVXwAAAAAAAAAPVVVVVVVV8AAAAAAAAAPVVVVVVVVfAAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVVfAAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAP1VVVVVVVVVXwAAAAAAP1VVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAA/VVVVVVVVVVVXwAAAAD/VVVVVVVVVVVV8AAAAP9VVVVVVVVVVVVfAAAA/1VVVVVVVVVVVVXwAAP/VVVVVVVVVVVVVV8AD/9VVVVVVVVVVVVVVf///VVVVVVVVVVVVVVVX//1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "28", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX9VVVVVVf//VVVX////z1VVX///AA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAD1VVV8AAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAD1VVV8AAAA9VVVfAAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAPVVVXwAAAD1VVV8AAAA9VVVfAAAAPVVVf/////1VVX/////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/////1VVX/////9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AAAAPVVVfAAAAD1VVXwAAAA9VVV8AD//9VVV8P////VVVf//1VVVVVX/VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="}
+ ]
+}
diff --git a/apps/contourclock/font-BarlowCond.json b/apps/contourclock/fonts/font-BarlowCond.json
similarity index 99%
rename from apps/contourclock/font-BarlowCond.json
rename to apps/contourclock/fonts/font-BarlowCond.json
index 2388b7383..bc1d9ddf3 100644
--- a/apps/contourclock/font-BarlowCond.json
+++ b/apps/contourclock/fonts/font-BarlowCond.json
@@ -1,5 +1,5 @@
{
- "name":"BarlowCond",
+ "name":"Barlow Cond",
"size":"100",
"characters":[
{"width" : "61", "buffer":"VVVVVVX//////1VVVVVVVVVVVVf///////9VVVVVVVVVVX/wAAAAAA/9VVVVVVVVVX/AAAAAAAAP9VVVVVVVVfwAAAAAAAAAP9VVVVVVVfwAAAAAAAAAAP1VVVVVV/AAAAAAAAAAAAPVVVVVV/AAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAA/AAAAAAAAD3wAAAAAAAA/8AAAAAAAA98AAAAAAAA9XwAAAAAAAD/AAAAAAAAPV8AAAAAAAA/wAAAAAAAPVfAAAAAAAAP8AAAAAAAD1XwAAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9VfAAAAAAAA/wAAAAAAAPVXwAAAAAAAP8AAAAAAAD1V8AAAAAAAD/AAAAAAAA9V8AAAAAAAA/wAAAAAAAPVfAAAAAAAAP8AAAAAAAA9XwAAAAAAAD/AAAAAAAAPXwAAAAAAAD3wAAAAAAAA/wAAAAAAAA9fAAAAAAAADwAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAP1VVVVVVfwAAAAAAAAAAP1VVVVVVV/wAAAAAAAAA/VVVVVVVVV/wAAAAAAAD/VVVVVVVVVV/////////9VVVVVVVVVVV////////1VVVVVQ=="},
diff --git a/apps/contourclock/font-BebasNeue.json b/apps/contourclock/fonts/font-BebasNeue.json
similarity index 99%
rename from apps/contourclock/font-BebasNeue.json
rename to apps/contourclock/fonts/font-BebasNeue.json
index 1109f1523..8be708322 100644
--- a/apps/contourclock/font-BebasNeue.json
+++ b/apps/contourclock/fonts/font-BebasNeue.json
@@ -1,5 +1,5 @@
{
- "name":"BebasNeue",
+ "name":"Bebas Neue",
"size":"98",
"characters":[
{"width" : "47", "buffer":"VVVVf//////VVVVVVVVf///////1VVVVVVf8AAAAAAP9VVVVVX8AAAAAAAD9VVVVV8AAAAAAAAA/VVVV/AAAAAAAAAA/VVVXwAAAAAAAAAAPVVV8AAAAAAAAAAA9VVfAAAAAAAAAAAA9VXwAAAAAAAAAAAA9VfAAAAAAAAAAAAD1V8AAAAAAAAAAAAPVfAAAAAAAAAAAAAPV8AAAAAP/wAAAAA9fAAAAAD//wAAAAA98AAAAA9VXwAAAAD3wAAAAPVVXwAAAAPfAAAAD1VVXwAAAA98AAAA9VVVXwAAAA/wAAAD1VVVfAAAAD/AAAAPVVVV8AAAAP8AAAA9VVVXwAAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAPVVVVXwAAAD/AAAA9VVVVfAAAAP8AAAD1VVVV8AAAA/wAAAD1VVVXwAAAD/AAAAPVVVV8AAAAP8AAAA9VVVXwAAAA/wAAAD1VVVfAAAAD/AAAAD1VVXwAAAA98AAAAPVVVfAAAAD3wAAAAP1VfwAAAAPfAAAAAP//8AAAAA9fAAAAAD/8AAAAAD18AAAAAAAAAAAAA9XwAAAAAAAAAAAAD1XwAAAAAAAAAAAA9VfAAAAAAAAAAAAD1VfAAAAAAAAAAAA9VVfAAAAAAAAAAAPVVV8AAAAAAAAAAA9VVV8AAAAAAAAAAPVVVV/AAAAAAAAAP1VVVV/AAAAAAAAD9VVVVVfwAAAAAAD9VVVVVVf////////VVVVVVVX///////VVVVQ" },
diff --git a/apps/contourclock/font-Dekko.json b/apps/contourclock/fonts/font-Dekko.json
similarity index 100%
rename from apps/contourclock/font-Dekko.json
rename to apps/contourclock/fonts/font-Dekko.json
diff --git a/apps/contourclock/font-DinAlternate.json b/apps/contourclock/fonts/font-DinAlternate.json
similarity index 100%
rename from apps/contourclock/font-DinAlternate.json
rename to apps/contourclock/fonts/font-DinAlternate.json
diff --git a/apps/contourclock/fonts/font-FjallaOne.json b/apps/contourclock/fonts/font-FjallaOne.json
new file mode 100644
index 000000000..2ff8240e0
--- /dev/null
+++ b/apps/contourclock/fonts/font-FjallaOne.json
@@ -0,0 +1,17 @@
+{
+ "name":"Fjalla One",
+ "size":"100",
+ "characters":[
+ {"width" : "49", "buffer":"VVVVV//////9VVVVVVVVX///////9VVVVVVVf8AAAAAAP9VVVVVV/wAAAAAAAP1VVVVV/AAAAAAAAAPVVVVV8AAAAAAAAAA9VVVV8AAAAAAAAAAD1VVVfAAAAAAAAAAAPVVVfAAAAAAAAAAAA9VVfAAAAAP/wAAAAPVVXwAAAA///wAAAA9VXwAAAA/VV/AAAAPVV8AAAA9VVV8AAAA9V8AAAA9VVVXwAAAPVfAAAA9VVVVfAAAD1XwAAA9VVVVXwAAAPXwAAAPVVVVV8AAAD18AAAD1VVVVXwAAA9fAAAA9VVVVV8AAAPXwAAA9VVVVVfAAAA98AAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAPfAAAD1VVVVV8AAAD3wAAA9VVVVVfAAAA98AAAPVVVVVXwAAA9fAAAA9VVVVV8AAAPXwAAAPVVVVVfAAAD1fAAAD1VVVVfAAAA9XwAAAPVVVVXwAAA9V8AAAD1VVVXwAAAPVXwAAAPVVVXwAAAD1V8AAAA/VVXwAAAD1VXwAAAD///wAAAA9VV8AAAAD//wAAAA9VVXwAAAAAAAAAAAPVVV8AAAAAAAAAAAPVVVXwAAAAAAAAAAPVVVVfAAAAAAAAAAPVVVVV8AAAAAAAAAPVVVVVX8AAAAAAAA/VVVVVVf8AAAAAAA/VVVVVVVf8AAAAAP9VVVVVVVVf//////9VVVVVVVVVf/////VVVVVQ=="},
+ {"width" : "46", "buffer":"VVVVVVVf///9VVVVVVVVVVf////VVVVVVVVVVfAAAD1VVVVVVVVVfAAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVXwAAAA9VVVVVVVVXwAAAAPVVVVVVVVXwAAAAD1VVVVVVVXwAAAAA9VVVVVVVXwAAAAAPVVVVVVVXwAAAAAD1VVVVVVXwAAAAAA9VVVVVVXwAAAAAAPVVVVVVXwAAAAAAD1VVVVVXwAAAAAAA9VVVVVXwAAAAAAAPVVVVVXwAAAAAAAD1VVVVXwAAAAAAAA9VVVVXwAAAAAAAAPVVVVXwAAADAAAAD1VVVXwAAAD8AAAA9VVVXwAAAP3wAAAPVVVXwAAAP18AAAD1VVVfAAAPVfAAAA9VVVV8AAPVXwAAAPVVVVXwAPVV8AAAD1VVVV8APVVfAAAA9VVVVXwPVVXwAAAPVVVVVf/VVV8AAAD1VVVVV/VVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVV////AAAAD///9VVf///AAAAAP///VVXwAAAAAAAAAAD1VV8AAAAAAAAAAA9VVfAAAAAAAAAAAPVVXwAAAAAAAAAAD1VV8AAAAAAAAAAA9VVfAAAAAAAAAAAPVVXwAAAAAAAAAAD1VV8AAAAAAAAAAA9VVf////////////VVX////////////w=="},
+ {"width" : "48", "buffer":"VVVVX//////9VVVVVVVX////////1VVVVVVf8AAAAAAD/VVVVVX8AAAAAAAAP9VVVVfwAAAAAAAAA/VVVV8AAAAAAAAAAD1VVXwAAAAAAAAAAA9VVfAAAAAAAAAAAA9VVfAAAAAAAAAAAAPVV8AAAAD//wAAAAD1V8AAAA///8AAAAD1XwAAAD9VVfAAAAA9XwAAAPVVVXwAAAA9fAAAA9VVVV8AAAA9fAAAD1VVVV8AAAA9fAAAD1VVVVfAAAAP8AAAD1VVVVfAAAAP8AAAPVVVVVfAAAAP8AAAPVVVVVfAAAAP8AAAPVVVVVfAAAAP8AAA9VVVVVfAAAAP8AAA9VVVVVfAAAAP8AAA9VVVVVfAAAAP8AAA9VVVVVfAAAAP8AAA9VVVVVfAAAAP8AAA9VVVVVfAAAAPfAAA9VVVVVfAAAAPfAAA9VVVVVfAAAAPfAAA9VVVVV8AAAA9fAAA9VVVVV8AAAA9fAAA9VVVVV8AAAA9X///9VVVVXwAAAA9X///9VVVVXwAAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAD1VVVVVVVVVfAAAAPVVVVVVVVVV8AAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAPVVVVVVVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAPVVVVVVVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAPVVVVVVVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAPVVVVVVVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAPVVVVVVVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAD1VVVVVVVVVfAAAAA/////////9fAAAAAP////////98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA98AAAAAAAAAAAAAA9///////////////9///////////////9"},
+ {"width" : "49", "buffer":"VVVVX//////9VVVVVVVVf///////9VVVVVVV/wAAAAAAP9VVVVVX/AAAAAAAAP9VVVVX8AAAAAAAAAP1VVVXwAAAAAAAAAAPVVVXwAAAAAAAAAAA9VVV8AAAAAAAAAAAPVVV8AAAAAAAAAAAA9VV8AAAAD//AAAAAPVVfAAAAD///AAAAA9VfAAAAD1VX8AAAAPVXwAAAD1VVXwAAAA9XwAAAD1VVVfAAAAPV8AAAD1VVVXwAAAD1fAAAD1VVVVfAAAA9fAAAA9VVVVXwAAAPXwAAA9VVVVV8AAAA98AAAPVVVVVXwAAAPfAAAD1VVVVV8AAAD3wAAA9VVVVVfAAAA98AAAPVVVVVXwAAAPfAAAPVVVVVV8AAAD3wAAD1VVVVVfAAAA98AAA9VVVVVXwAAAPfAAAPVVVVVV8AAAD18AAD1VVVVVfAAAA9fAAA9VVVVVXwAAAPXwAAPVVVVVV8AAAD18AAD1VVVVVfAAAA9fAAA9VVVVVXwAAAPV////VVVVVV8AAAD1f///1VVVVVfAAAD1VVVVVVVVVVXwAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1VVVVVVVVVVfAAAD1VVVVVVVVVVXwAAA9VVVVVVVVVVXwAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVXwAAAPVVVVVVVVVVXwAAAPVVVVVVVX///wAAAD1VVVVVVX///wAAAP1VVVVVVV8AAAAAAP1VVVVVVVfAAAAAA/VVVVVVVVXwAAAAA/VVVVVVVVV8AAAAA9VVVVVVVVVfAAAAAD9VVVVVVVVXwAAAAAP1VVVVVVVV8AAAAAAP1VVVVVVVfAAAAAAA/VVVVVVVX///wAAAA9VVVVVVVf///wAAAD1VVVVVVVVVV/AAAAPVVVVVVVVVVV8AAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVVfAAAA9VVVVVVVVVVV8AAAPVVVVVVVVVVVfAAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVVfAAAD1VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1VVVVVVVVVVfAAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1////VVVVVVfAAAA9f///1VVVVVXwAAAPfAAA9VVVVVV8AAAD3wAAPVVVVVVfAAAA98AAD1VVVVVXwAAAPfAAA9VVVVVV8AAAD3wAAPVVVVVVfAAAA98AAD1VVVVVXwAAAPfAAAPVVVVVV8AAAD/AAAD1VVVVVfAAAA/wAAA9VVVVVXwAAAP8AAAPVVVVVV8AAAD/AAAD1VVVVVfAAAA/wAAA9VVVVVXwAAAP8AAAD1VVVVV8AAAD3wAAA9VVVVVfAAAA98AAAPVVVVVfAAAA9fAAAA9VVVVXwAAAPXwAAAPVVVVXwAAAD18AAAA9VVVXwAAAA9XwAAAD9VVXwAAAA9V8AAAAP/X/wAAAAPVfAAAAAP//wAAAAPVV8AAAAADwAAAAAD1VXwAAAAAAAAAAAD1VV8AAAAAAAAAAAD1VVXwAAAAAAAAAAD1VVVfAAAAAAAAAAD9VVVV/AAAAAAAAAP1VVVVX/AAAAAAAA/1VVVVVX/wAAAAAP/VVVVVVVX///////9VVVVVVVVV//////VVVVVQ=="},
+ {"width" : "57", "buffer":"VVVVVVVVVX//////VVVVVVVVVVVVX//////VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVV8AAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAA8AAAPVVVVVVVVVVfAAD/AAAPVVVVVVVVVVfAAPXwAAPVVVVVVVVVV8AAPXwAAPVVVVVVVVVV8AAPfAAAPVVVVVVVVVV8AA9fAAAPVVVVVVVVVXwAA9fAAAPVVVVVVVVVXwAA9fAAAPVVVVVVVVVfAAD1fAAAPVVVVVVVVVfAAD1fAAAPVVVVVVVVVfAAD1fAAAPVVVVVVVVV8AAPVfAAAPVVVVVVVVV8AAPVfAAAPVVVVVVVVXwAAPVfAAAPVVVVVVVVXwAA9VfAAAPVVVVVVVVXwAA9VfAAAPVVVVVVVVfAAA9VfAAAPVVVVVVVVfAAD1VfAAAPVVVVVVVV8AAD1VfAAAPVVVVVVVV8AAD1VfAAAPVVVVVVVV8AAPVVfAAAPVVVVVVVXwAAPVVfAAAPVVVVVVVXwAAPVVfAAAPVVVVVVVfAAA9VVfAAAPVVVVVVVfAAA9VVfAAAPVVVVVVVfAAA9VVfAAAPVVVVVVV8AAD1VVfAAAPVVVVVVV8AAD1VVfAAAPVVVVVVXwAAD1VVfAAAPVVVVVVXwAAPVVVfAAAPVVVVVVXwAAPVVVfAAAPVVVVVVfAAAPVVVfAAAPVVVVVVfAAA9VVVfAAAPVVVVVV8AAA9VVVfAAAPVVVVVV8AAA9VVV8AAAPVVVVVV8AAD1VVV8AAAPVVVVVXwAAD1VVV8AAAPVVVVVXwAAD1VVV8AAAPVVVVVXwAAPVVVV8AAAPVVVVVfAAAPVVVV8AAAPVVVVVfAAAPVVVV8AAAPVVVVV8AAA9VVVV8AAAPVVVVV8AAA9VVVV8AAAPVVVVV8AAA9VVVV8AAAPVVVVXwAAD1VVVV8AAAPVVVVXwAAD1VVVV8AAAPVVVVfAAAD1VVVV8AAAPVVVVfAAAPVVVVV8AAAPVVVVfAAAPVVVVV8AAAPVVVV8AAAPVVVVV8AAAPVVVV8AAA9VVVVV8AAAPVVVXwAAA9VVVVV8AAAPVVVXwAAA9VVVVV8AAAD1VVXwAAAP/////wAAAA///fAAAAD/////AAAAAP//fAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP///////////AAAAA///f//////////wAAAD///VVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV8AAAPVVVVVVVVVVVVVV/////VVVVVVVVVVVVVVf////VVV"},
+ {"width" : "47", "buffer":"X//////////////Vf/////////////9V8AAAAAAAAAAAAD1XwAAAAAAAAAAAAPVfAAAAAAAAAAAAA9V8AAAAAAAAAAAAD1XwAAAAAAAAAAAAPVfAAAAAAAAAAAAA9V8AAAAAAAAAAAAD1XwAAAAAAAAAAAAPVfAAAAAAAAAAAAA9V8AAAAAAAAAAAAD1XwAAA//////////VfAAAP/////////9V8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VVVVVVVVVVXwAAPVVVVVVVVVVVfAAA9VVVVVVVVVVV8AAD1VV////VVVVXwAAPVX/////1VVVfAAA9V/wAAAP9VVV8AAD1/AAAAAD9VVXwAAPfwAAAAAA9VVfAAAPwAAAAAAA9VV8AAAMAAAAAAAA9VXwAAAAAAAAAAAD1VfAAAAAAAAAAAAD1V8AAAAAAAAAAAAPVXwAAAAAAAAAAAAPVfAAAAAP/wAAAAA9V8AAAAP//8AAAAD1XwAAAD9VX8AAAAD1fAAAA9VVV8AAAAPV8AAAPVVVV8AAAA9XwAAD1VVVXwAAAD1f///9VVVVXwAAAD1////VVVVVfAAAAPVVVVVVVVVV8AAAA9VVVVVVVVVXwAAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAA9VVVVVVVVVV8AAAD1VVVVVVVVVXwAAAPVVVVVVVVVVfAAAA9f///1VVVVV8AAAD3////VVVVVXwAAAPfAAA9VVVVVfAAAA98AAD1VVVVV8AAAD3wAAPVVVVVXwAAAP8AAA9VVVVVfAAAA/wAAD1VVVVV8AAAD/AAAPVVVVVXwAAAP8AAA9VVVVVfAAAA/wAAD1VVVVV8AAAD/AAAPVVVVVXwAAAP8AAA9VVVVVfAAAA/wAAD1VVVVXwAAAD/AAAPVVVVVfAAAAP8AAA9VVVVV8AAAD3wAAA9VVVVXwAAAPfAAAD1VVVVfAAAA98AAAPVVVVXwAAAD18AAAPVVVVfAAAA9XwAAAPVVVXwAAAD1fAAAAPVVV8AAAA9VfAAAAP9f/AAAAD1V8AAAAP//wAAAAPVV8AAAAA8AAAAAD1VXwAAAAAAAAAAA9VVXwAAAAAAAAAAD1VVXwAAAAAAAAAA9VVVXwAAAAAAAAAPVVVVXwAAAAAAAAP1VVVVX/AAAAAAAP9VVVVVX/wAAAAA/9VVVVVVVf//////9VVVVVVVVX/////1VVVVU="},
+ {"width" : "49", "buffer":"VVVVV///////VVVVVVVVX////////VVVVVVVf8AAAAAAD/VVVVVV/wAAAAAAAD/VVVVV/AAAAAAAAAD9VVVV8AAAAAAAAAAD1VVV8AAAAAAAAAAAPVVV8AAAAAAAAAAAD1VVfAAAAAP/AAAAAPVVfAAAAA///wAAAD1VfAAAAD/VX/AAAAPVXwAAAD9VVV8AAAD1V8AAAD1VVVXwAAA9V8AAAD1VVVVfAAAD1fAAAA9VVVVXwAAA9fAAAA9VVVVV8AAAPXwAAAPVVVVVXwAAD18AAAPVVVVVV8AAA9fAAAD1VVVVVfAAAPXwAAA9VVVVVXwAAD3wAAAPVVVVVV8AAA98AAAD1VVVVVfAAAPfAAAA9VVVVVV8AAD3wAAAPVVVVVVfAAA98AAAD1VVVVVXwAAPfAAAA9VVVVVV8AAPXwAAAPVVVVVVf///18AAAD1VVVVVX///9fAAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1VVVVVVVVVVfAAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1VVVVVVVVVVfAAAA9VVVVVVVVVVXwAAAPVVVVVVVVVVV8AAAD1VVVVVVVVVVfAAAA9VVX//9VVVVXwAAAPVX/////VVVV8AAAD1X/wAAP/VVVfAAAA9fwAAAAD/VVXwAAAPfwAAAAAD9VV8AAAA/AAAAAAAD1VfAAAADAAAAAAAAPVXwAAAAAAAAAAAAA9V8AAAAAAAAAAAAAPVfAAAAAAAAAAAAAA9XwAAAAAA//AAAAAD18AAAAAD///AAAAA9fAAAAAD9VX8AAAAPXwAAAAP1VVXwAAAA98AAAAP1VVVfAAAAPfAAAAPVVVVXwAAAD3wAAAPVVVVVfAAAA98AAAD1VVVVXwAAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA/wAAAPVVVVVXwAAAP8AAAD1VVVVV8AAAD/AAAA9VVVVVfAAAA98AAAPVVVVVXwAAAPfAAAD1VVVVV8AAAPXwAAAPVVVVVfAAAD18AAAD1VVVVfAAAA9fAAAA9VVVVXwAAAPV8AAAD1VVVXwAAAPVfAAAAPVVVV8AAAD1V8AAAA9VVX8AAAA9VfAAAAD/1/8AAAA9VXwAAAAP//wAAAAPVVfAAAAAA8AAAAAPVVV8AAAAAAAAAAAD1VVfAAAAAAAAAAAD1VVV8AAAAAAAAAAD1VVVXwAAAAAAAAAD1VVVVfwAAAAAAAAD1VVVVV/wAAAAAAAP1VVVVVV/8AAAAAD/1VVVVVVV////////VVVVVVVVVf/////1VVVVQ=="},
+ {"width" : "46", "buffer":"///////////////////////////////wAAAAAAAAAAAAAP8AAAAAAAAAAAAAD/AAAAAAAAAAAAAA/wAAAAAAAAAAAAAP8AAAAAAAAAAAAAD/AAAAAAAAAAAAAA/wAAAAAAAAAAAAAP8AAAAAAAAAAAAAPfAAAAAAAAAAAAAD3wAAAAAAAAAAAAA9/////////8AAAAPf/////////wAAAPVVVVVVVVVVfAAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAA9VVVVVVVVVV8AAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAPVVVVVVVVVV8AAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAA9VVVVVVVVVXwAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAD1VVVVVVVVVfAAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAAPVVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVXwAAAD1VVVVVVVVV8AAAA9VVVVVVVVVfAAAAPVVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVV8AAAA9VVVVVVVVV8AAAA9VVVVVVVVVfAAAAPVVVVVVVVVXwAAAD1VVVVVVVVXwAAAA9VVVVVVVVV8AAAA9VVVVVVVVVf/////VVVVVVVVVX/////VVVVVVVVVQ=="},
+ {"width" : "51", "buffer":"VVVVV///////VVVVVVVVV////////9VVVVVVVX/AAAAAAA/1VVVVVV/AAAAAAAAD/VVVVVX8AAAAAAAAAP1VVVVfAAAAAAAAAAA9VVVV8AAAAAAAAAAAPVVVXwAAAAAAAAAAAD1VVfAAAAAAAAAAAAD1VVfAAAAAP/8AAAAA9VV8AAAAD///wAAAA9VV8AAAAP1VX8AAAAPVV8AAAA9VVVfAAAAPVXwAAAD1VVVXwAAAD1XwAAAD1VVVXwAAAD1XwAAAPVVVVV8AAAD1XwAAAPVVVVV8AAAD1fAAAAPVVVVV8AAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9XwAAA9VVVVVfAAAD1XwAAA9VVVVVfAAAD1XwAAA9VVVVV8AAAD1XwAAAPVVVVV8AAAPVV8AAAPVVVVV8AAAPVV8AAAPVVVVXwAAAPVVfAAAD1VVVXwAAA9VVfAAAA9VVVfAAAA9VVXwAAAPVVV8AAAD1VVV8AAAD///wAAAPVVVV/AAAA///AAAA9VVVVfwAAAAAAAAAD1VVVVV8AAAAAAAAA/VVVVVVfAAAAAAAAD9VVVVVVXwAAAAAAAPVVVVVVVXwAAAAAAAD1VVVVVV/AAAAAAAAA/VVVVVX8AAAAAAAAAP1VVVVfAAAAAAAAAAA9VVVV8AAAA///AAAAPVVVXwAAAD///wAAAD1VVfAAAA/VVV8AAAA9VV8AAAD9VVVfAAAAPVV8AAAPVVVVXwAAAPVXwAAAPVVVVV8AAAD1XwAAA9VVVVVfAAAD1fAAAA9VVVVVfAAAA9fAAAD1VVVVVfAAAA9fAAAD1VVVVVXwAAA9fAAAD1VVVVVXwAAA98AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVXwAAAP8AAAD1VVVVVfAAAAP8AAAA9VVVVVfAAAA9fAAAA9VVVVVfAAAA9fAAAA9VVVVV8AAAA9fAAAAPVVVVV8AAAA9fAAAAD1VVVXwAAAD1XwAAAA9VVV/AAAAD1XwAAAAP/V/8AAAAD1V8AAAAD///AAAAAPVV8AAAAAA/AAAAAA9VVfAAAAAAAAAAAAA9VVXwAAAAAAAAAAAD1VVX8AAAAAAAAAAAPVVVV/AAAAAAAAAAA9VVVVX8AAAAAAAAAP1VVVVV/wAAAAAAAD/VVVVVVX/wAAAAAD/1VVVVVVVf///////9VVVVVVVVVf/////9VVVVV"},
+ {"width" : "50", "buffer":"VVVVX//////9VVVVVVVVX////////VVVVVVVX/AAAAAAA/1VVVVVV/AAAAAAAAP9VVVVVfAAAAAAAAAD9VVVVXwAAAAAAAAAA9VVVV8AAAAAAAAAAA9VVVfAAAAAAAAAAAA9VVXwAAAAAAAAAAAD1VVfAAAAD//8AAAAD1VXwAAAA////AAAAPVVfAAAAPVVV/AAAAPVXwAAAD1VVVfAAAA9VfAAAA9VVVVfAAAA9V8AAAD1VVVV8AAAD1fAAAA9VVVVV8AAAPV8AAAD1VVVVXwAAA9XwAAAPVVVVVfAAAA9fAAAD1VVVVV8AAAD18AAAPVVVVVV8AAAPXwAAA9VVVVVXwAAA9fAAAD1VVVVVfAAAD3wAAAPVVVVVV8AAAPfAAAA9VVVVVXwAAA98AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA/wAAAPVVVVVV8AAAD/AAAA9VVVVVXwAAAP8AAAD1VVVVVfAAAA98AAAD1VVVVV8AAAD3wAAAPVVVVVXwAAAPfAAAA9VVVVV8AAAA98AAAA9VVVVXwAAAD3wAAAD1VVVV8AAAAPfAAAAD1VVV/AAAAA9fAAAAD1VVfwAAAAD18AAAAD/V/wAAAAAPV8AAAAD//8AAAAAA9XwAAAAAPwAAAAAAD1XwAAAAAAAAAAAAAPVfAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAD1VfAAAAAAAA8AAAAPVVfAAAAAAAP8AAAA9VVfwAAAAAP18AAAD1VVf8AAAAP9XwAAAPVVVX//AD/9VfAAAA9VVVV////9VV8AAAD1VVVVVf/VVVXwAAAPVVVVVVVVVVVfAAAA9VVVVVVVVVVV8AAAD1VVVVVVVVVVXwAAAPVVVVVVVVVVVfAAAA9VVVVVVVVVVV8AAAD1VVVVVVVVVVXwAAAPVVVVVVVVVVVfAAAA9VVVVVVVVVVV8AAAD1VVVVVVVVVVXwAAAPX////VVVVVVfAAAA9f///9VVVVVV8AAAD18AAD1VVVVVXwAAAPXwAAPVVVVVVfAAAA98AAA9VVVVVV8AAAPXwAAD1VVVVVXwAAA9fAAAPVVVVVV8AAAD18AAA9VVVVVXwAAAPXwAAD1VVVVVfAAAA9fAAAPVVVVVV8AAAD18AAAPVVVVVXwAAA9XwAAA9VVVVV8AAAD1fAAAD1VVVVXwAAAPV8AAAD1VVVV8AAAD1V8AAAD1VVVfAAAAPVXwAAAD1VVXwAAAA9VfAAAAD/1/8AAAAPVVfAAAAD///AAAAA9VV8AAAAADwAAAAAPVVV8AAAAAAAAAAAA9VVXwAAAAAAAAAAAPVVVXwAAAAAAAAAAD1VVVXwAAAAAAAAAA9VVVVX8AAAAAAAAA/VVVVVX/AAAAAAAA/1VVVVVV/8AAAAAA/1VVVVVVVf///////1VVVVVVVVV//////1VVVVU="},
+ {"width" : "18", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX//1VV////VX8AAP1XwAAA9fAAAA9fAAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAPfAAAAPfAAAA9XwAAA9V/AAP1Vf///VVV//1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/VVVf//9VV/wA/1XwAAD9fAAAA9fAAAAPfAAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAPfAAAAPfAAAAPXwAAA9X8AAD1V////VVX//9V"}
+ ]
+}
diff --git a/apps/contourclock/font-Impact.json b/apps/contourclock/fonts/font-Impact.json
similarity index 100%
rename from apps/contourclock/font-Impact.json
rename to apps/contourclock/fonts/font-Impact.json
diff --git a/apps/contourclock/fonts/font-LuckiestGuy.json b/apps/contourclock/fonts/font-LuckiestGuy.json
new file mode 100644
index 000000000..a5aac8567
--- /dev/null
+++ b/apps/contourclock/fonts/font-LuckiestGuy.json
@@ -0,0 +1,17 @@
+{
+ "name":"Luckiest Guy",
+ "size":"100",
+ "characters":[
+ {"width" : "65", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVdVVVVVVVVVVVVVVVVVVV////9VVVVVVVVVVVVVVVX//8///VVVVVVVVVVVVVVX/wAAAA/1VVVVVVVVVVVVX/AAAAAAP9VVVVVVVVVVVV/AAAAAAAD9VVVVVVVVVVVfAAAAAAAAA/VVVVVVVVVVXwAAAAAAAAA/VVVVVVVVVX8AAAAAAAAAAPVVVVVVVVVfAAAAAAAAAAAPVVVVVVVVXwAAAAAAAAAAAPVVVVVVVV8AAAAAAAAAAAAPVVVVVVVfAAAAAAAAAAAAA9VVVVVVXwAAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAD1VfAAAAAAAAP8AAAAAAAAPVV8AAAAAAAP//AAAAAAAAPVfAAAAAAAD9V/AAAAAAAA9V8AAAAAAA9VVfAAAAAAAD1XwAAAAAAPVVVfAAAAAAAPVfAAAAAAD1VVVfAAAAAAAPV8AAAAAAPVVVVfAAAAAAA9fAAAAAAD1VVVV8AAAAAAD18AAAAAAPVVVVV8AAAAAAPXwAAAAAD1VVVVXwAAAAAA9fAAAAAAPVVVVVXwAAAAAD18AAAAAD1VVVVVfAAAAAAD3wAAAAAPVVVVVV8AAAAAAP8AAAAAA9VVVVVV8AAAAAA/wAAAAAD1VVVVVXwAAAAAD/AAAAAA9VVVVVVfAAAAAAP8AAAAAD1VVVVVV8AAAAAA/wAAAAAPVVVVVVXwAAAAAD/AAAAAA9VVVVVVfAAAAAAP8AAAAAD1VVVVVVfAAAAAA/wAAAAAPVVVVVVV8AAAAAD/AAAAAA9VVVVVVXwAAAAAP8AAAAAD1VVVVVVfAAAAAA/wAAAAAPVVVVVVV8AAAAAD/AAAAAA9VVVVVVXwAAAAAP8AAAAAD1VVVVVV8AAAAAA/wAAAAAPVVVVVVXwAAAAAD3wAAAAA9VVVVVVfAAAAAAPfAAAAAD1VVVVVV8AAAAAD18AAAAAD1VVVVVXwAAAAAPXwAAAAAPVVVVVV8AAAAAA9fAAAAAA9VVVVVXwAAAAAD18AAAAAA9VVVVVfAAAAAAPV8AAAAAD1VVVVXwAAAAAA9XwAAAAAPVVVVVfAAAAAAPVfAAAAAAPVVVVXwAAAAAA9V8AAAAAA9VVVVfAAAAAAD1V8AAAAAA9VVVXwAAAAAAPVXwAAAAAA9VVVfAAAAAAD1VfAAAAAAA9VVXwAAAAAAPVVfAAAAAAA9VX8AAAAAAA9VV8AAAAAAA///AAAAAAAPVVXwAAAAAAA//AAAAAAAA9VVXwAAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAAA9VVVVVV8AAAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAAA9VVVVVVXwAAAAAAAAAAAAPVVVVVVVXwAAAAAAAAAAAD1VVVVVVVXwAAAAAAAAAAA9VVVVVVVVXwAAAAAAAAAAPVVVVVVVVVXwAAAAAAAAAD1VVVVVVVVVX8AAAAAAAAA9VVVVVVVVVVX/AAAAAAAA/VVVVVVVVVVVV/AAAAAAA/1VVVVVVVVVVVVf8AAAAA/1VVVVVVVVVVVVVf/wAAD/1VVVVVVVVVVVVVVV/////1VVVVVVVVVVVVVVVVX///VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "41", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/9VVVVVVVVVVV////////1VVVVfAA//////VVVVXwAAAAAAA9VVVV8AAAAAAAD1VVVfAAAAAAAAPVVVXwAAAAAAAA9VVV8AAAAAAAAD1VVfAAAAAAAAAPVVfwAAAAAAAAA9VX8AAAAAAAAAD1V8AAAAAAAAAAPVfAAAAAAAAAAA9XwAAAAAAAAAAD18AAAAAAAAAAAPfAAAAAAAAAAAA/wAAAAAAAAAAAD3wAAAAAAAAAAAPfAAAAAAAAAAAA98AAAAAAAAAAAD18AAAAAAAAAAAPXwAAAAAAAAAAA9fAAAAAAAAAAAD1fAAAAAAAAAAAPV8AAAAAAAAAAA9XwAAAAAAAAAAD1XwAAAAAAAAAAPVfAAAAAAAAAAA9V8AAAAAAAAAAD1V8AAAAAAAAAAPVXwAAAAAAAAAA9VXwADAAAAAAAD1VfAA/AAAAAAAPVV8APfAAAAAAA9VV8D18AAAAAAPVVXz9XwAAAAAA9VVf/VfAAAAAAD1VVfVV8AAAAAAPVVV1VXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAPVVVVVV8AAAAAA9VVVVVXwAAAAAD1VVVVVfAAAAAAPVVVVVV8AAAAAA9VVVVVXwAAAAAD1VVVVVfAAAAAAPVVVVVV8AAAAAA9VVVVVXwAAAAAD1VVVVVfAAAAAAPVVVVVV8AAAAAA9VVVVVXwAAAAAD1VVVVVfAAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVfAAAAAAD1VVVVV8AAAAAAPVVVVVXwAAAAAA9VVVVVf///////1VVVVVX//////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "52", "buffer":"VVVVVVVVVVVVVVVVVVVVVVf////VVVVVVVVVVVf//////1VVVVVVVVV//AAAAD/1VVVVVVVX/AAAAAAA/1VVVVVVX8AAAAAAAA/1VVVVVfwAAAAAAAAA/VVVVVfwAAAAAAAAAA9VVVVfAAAAAAAAAAAD1VVVXwAAAAAAAAAAAPVVVV8AAAAAAAAAAAA9VVVfAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVV8AAAAAAAAAAAAD1VVfAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAD1VfAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAA9VXwAADwAAAAAAAAAPVV8AD///AAAAAAAAD1VfAP/1/8AAAAAAAA9VXwP1VVXwAAAAAAAD1V8/VVVVfAAAAAAAA9Vf/VVVVV8AAAAAAAPVV9VVVVVfAAAAAAAD1VdVVVVVV8AAAAAAA9VVVVVVVVfAAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVV8AAAAAAD1VVVVVVVV8AAAAAAA9VVVVVVVVfAAAAAAA9VVVVVVVVfAAAAAAAPVVVVVVVVfAAAAAAAPVVVVVVVVfAAAAAAAD1VVVVVVVXwAAAAAAD1VVVVVVVXwAAAAAAD1VVVVVVVXwAAAAAAA9VVVVVVVfwAAAAAAA9VVVVVVVfwAAAAAAA9VVVVVVVfAAAAAAAA9VVVVVVVfAAAAAAAA9VVVVVVV/AAAAAAAA9VVVVVVV/AAAAAAAA9VVVVVVX8AAAAAAAA9VVVVVVf8AAAAAAAA9VVVVVV/wAAAAAAAAD/////X/AAAAAAAAAAP////38AAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAD1/////AAAAAAAAAAA9X//////////wAAAAPVVVVVX///////////1VVVVVVVVVVV/////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "54", "buffer":"VVVVX//////1VVVVVVVVVV////////1VVVVVVVVf8AAAAAAP/VVVVVVVX/AAAAAAAAP9VVVVVV/wAAAAAAAAA/VVVVVX8AAAAAAAAAAD1VVVVfAAAAAAAAAAAA9VVVX8AAAAAAAAAAAAPVVVfwAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAA9VfAAAD//wAAAAAAAA9VfAAD////AAAAAAAA9VfAA/9VVfwAAAAAAA9VfAP9VVVV8AAAAAAA9VfA/VVVVVfAAAAAAA9VX/1VVVVVXwAAAAAA9VX/VVVVVVV8AAAAAA9VX1VVVVVVV8AAAAAA9VX1VVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVX8AAAAAAD1VVVVVVVVfwAAAAAAPVVVVVVVV/8AAAAAAAPVVVVVX///wAAAAAAA9VVVVVX//AAAAAAAAD1VVVVVXwAAAAAAAAAD1VVVVVXwAAAAAAAAAPVVVVVVXwAAAAAAAAA9VVVVVVXwAAAAAAAAAPVVVVVVXwAAAAAAAAAD1VVVVVXwAAAAAAAAAA9VVVVVXwAAAAAAAAAAPVVVVVXwAAAAAAAAAAPVVVVVXwAAAAAAAAAAD1VVVVXwAAAAAAAAAAD1VVVVXwAAAAAAAAAAA9VVVVXwAAAAAAAAAAA9VVVVXwAAAAAAAAAAA9VVVVXw//AAAAAAAAA9VVVVX///8AAAAAAAAPVVVVX/VV/wAAAAAAAPVVVVVVVVX8AAAAAAAPVVVVVVVVVfAAAAAAAPVVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAPX1VVVVVVVV8AAAAAAPX9VVVVVVVV8AAAAAAPX/VVVVVVVV8AAAAAAPXz9VVVVVVV8AAAAAAPXw/1VVVVVV8AAAAAAPXwD/VVVVVXwAAAAAAPfAAP9VVVVfAAAAAAAPfAAA//VVX8AAAAAAAPfAAAD////wAAAAAAAPfAAAAA//8AAAAAAAAPfAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAA9VV/AAAAAAAAAAAAAD1VVX8AAAAAAAAAAAAP1VVV/AAAAAAAAAAAA9VVVVX8AAAAAAAAAAP1VVVVV/wAAAAAAAAA/VVVVVVX/wAAAAAAA/1VVVVVVVf/wAAAAAP/VVVVVVVVVf//AAP//VVVVVVVVVVVf/////1VVVVVVVVVVVVV//1VVVVVVVV"},
+ {"width" : "56", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///////1VVVVVVVVVVf///////VVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAD1VVV//////9fAAAAAAPVVVX//////18AAAAAA9VVVfAAAAAPXwAAAAAD1VVXwAAAAA9fAAAAAAPVVVfAAAAAD18AAAAAA9VVV8AAAAA9XwAAAAAD1VVXwAAAAD1fAAAAAAPVVVfAAAAAPV8AAAAAA9VVV8AAAAA9XwAAAAAD1VVXwAAAAD1fAAAAAAPVVV8AAAAAPV8AAAAAA9VVXwAAAAA9XwAAAAAD1VVfAAAAAPVfAAAAAAPVVV8AAAAA9V8AAAAAA9VVXwAAAAD1XwAAAAAD1VVfAAAAAPVfAAAAAAPVVV8AAAAA9V8AAAAAA9VVXwAAAAD1fAAAAAAD1VV8AAAAAPV8AAAAAAPVVXwAAAAD1XwAAAAAA9VVfAAAAAPVfAAAAAAD1VV8AAAAA9V8AAAAAAPVVXwAAAAD1XwAAAAAA9VVfAAAAAPVfAAAAAAD1VV8AAAAA9V8AAAAAAPVVfAAAAAD1XwAAAAAA9VV8AAAAA9VfAAAAAAD1VXwAAAAD1V8AAAAAAPVVfAAAAAPVXwAAAAAA9VV8AAAAA9VfAAAAAAD1VXwAAAAD1V8AAAAAAPVVfAAAAAPVXwAAAAAA9VV8AAAAD1VfAAAAAAPVVfAAAAAPVV8AAAAAA9VV8AAAAA9VXwAAAAAD1VXwAAAAD1VfAAAAAAPVVfAAAAAPVV8AAAAAA9VV8AAAAA9VXwAAAAAD1VXwAAAAD1VfAAAAAAD31fAAAAAPVV8AAAAAAD/XwAAAAAP//AAAAAAAD9fAAAAAAP/wAAAAAAAD18AAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAP8AAAAP///wAAAAAAAP//////////wAAAAAAD9f////9VVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAP/9VVVVVVVVVVfAP/////VVVVVVVVVVV/////9VVVVVVVVVVVVX/9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "55", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV9VVVVVVVf//////////VVVV//////////////1VVVf///AAAAAAAAAA9VVVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAD1VVVfAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAD1VVVfAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAPVVVfAAAAAD////AAAD1VVXwAAAAD////////9VVV8AAAAD1VVVX////VVVfAAAAA9VVVVVVVVVVVXwAAAAPVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVfAAAAA9VVVVVVVVVVVXwAAAAPVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVfAAAAA9VVVVVVVVVVVXwAAAAPVVVVVVVVVVVV8AAAAD1f///VVVVVVVfAAAAAP/////1VVVVVXwAAAAA/AAAD/1VVVVV8AAAAAAAAAAA/VVVVVfAAAAAAAAAAAA/VVVVXwAAAAAAAAAAAD9VVVV8AAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAPVV8////8AAAAAAAAAA9Vf//////wAAAAAAAAPVX9VVVVf/wAAAAAAAD1VVVVVVVV/wAAAAAAAPVVVVVVVVV/AAAAAAAD1VVVVVVVVV8AAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAAPX1VVVVVVVV8AAAAAAPX/VVVVVVVV8AAAAAAD18/1VVVVVV8AAAAAAA9fD/1VVVVV8AAAAAAAPXwA/9VVVX8AAAAAAAD18AA/////8AAAAAAAA9fAAAP///wAAAAAAAAPXwAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAP1VVfwAAAAAAAAAAAAP1VVV/wAAAAAAAAAAAPVVVVV/8AAAAAAAAAA/VVVVVV/8AAAAAAAAD/VVVVVVVf/wAAAAAA/9VVVVVVVVf/8AAAA//1VVVVVVVVVV//////9VVVVVVVVVVVVf///9VVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "59", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX////1VVVVVVVVVVVVV///////1VVVVVVVVVVV//AAAAD//VVVVVVVVVV/wAAAAAAD/1VVVVVVVVfwAAAAAAAAP9VVVVVVVfwAAAAAAAAAD1VVVVVVX8AAAAAAAAAAPVVVVVVV8AAAAAAAAAAA9VVVVVVfAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAADwAAAA9VVVfAAAAAAAA////AAD1VVV8AAAAAAA//X//8APVVVXwAAAAAAP1VVVf/w9VVV8AAAAAAD1VVVVV//1VVXwAAAAAA9VVVVVVX/VVVfAAAAAAPVVVVVVVV9VVV8AAAAAD1VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVfAAAAAA9VVV//9VVVVVV8AAAAAD1VX////9VVVVXwAAAAAPVf/wAA//VVVVfAAAAAD1f/AAAAA/1VVV8AAAAAPf8AAAAAAP1VVXwAAAAAP8AAAAAAAD1VVfAAAAAAMAAAAAAAAD1VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAPfAAAAAAAAD/wAAAAAAA98AAAAAAAD//8AAAAAAD3wAAAAAAA/VX8AAAAAAPfAAAAAAAPVVV8AAAAAA98AAAAAAD1VVV8AAAAAD3wAAAAAA9VVVV8AAAAAPfAAAAAAD1VVVXwAAAAA98AAAAAA9VVVVXwAAAAD3wAAAAAD1VVVVfAAAAAPfAAAAAAPVVVVV8AAAAA98AAAAAA9VVVVXwAAAAD3wAAAAAD1VVVVfAAAAAPXwAAAAAPVVVVV8AAAAA9fAAAAAAPVVVVfAAAAAD18AAAAAA9VVVV8AAAAAPXwAAAAAA9VVVfAAAAAA9fAAAAAAA9VVXwAAAAAD1fAAAAAAA/VX8AAAAAAPV8AAAAAAA///AAAAAAA9XwAAAAAAAP/AAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAA/VVVVVVVfAAAAAAAAAAP1VVVVVVVfAAAAAAAAAD1VVVVVVVVfwAAAAAAAD9VVVVVVVVVf8AAAAAAD/VVVVVVVVVVX/AAAAAP/VVVVVVVVVVVV///////VVVVVVVVVVVVVf////9VVVVVVU="},
+ {"width" : "52", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//////////////////////////////////8AAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAD3wAAAAAP/8AAAAAAA98A///////wAAAAAAPf//////VVfAAAAAAPX/9VVVVVVXwAAAAAD1VVVVVVVVV8AAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAPVVVVVVVVVXwAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVfAAAAAAAPVVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVV8AAAAAAA9VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVXwAAAAAAD1VVVVVVVV8AAAAAAA9VVVVVVVV8AAAAAAA9VVVVVVVVfAAAAAAAPVVVVVVVVXwAAAAAAD1VVVVVVVXwAAAAAAD1VVVVVVVV8AAAAAAA9VVVVVVVVfAAAAAAAPVVVVVVVVfAAAAAAAD1VVVVVVVXwAAAAAAD1VVVVVVVXwAAAAAAA9VVVVVVVV8AAAAAAAPVVVVVVVVfAAAAAAAPVVVVVVVVfAAAAAAAD1VVVVVVVXwAAAAAAA9VVVVVVVV8AAAAAAAPVVVVVVVV8AAAAAAAPVVVVVVVVfAAAAAAAD1VVVVVVVfAAAAAAAA9VVVVVVVXwAAAAAAA9VVVVVVVV8AAAAAAAPVVVVVVVV8AAAAAAAD1VVVVVVVfAAAAAAAA9VVVVVVVXwAAAAAAA9VVVVVVVXwAAAAAAAPVVVVVVVV8AAAAAAAD1VVVVVVVfAAAAAAAD1VVVVVVVfAAAAAAAA9VVVVVVVXwAAAAAAAPVVVVVVVXwAAAAAAAD1VVVVVVV8AAAAAAAD1VVVVVVVfAAAAAAAA9VVVVVVVfwAAAAAAAPVVVVVVVX////wAAAPVVVVVVVVV////////1VVVVVVVVVVVV////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "58", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/1VVVVVVVVVVVVVVV/////1VVVVVVVVVVVVf//AA//9VVVVVVVVVVV/8AAAAA/9VVVVVVVVVX/AAAAAAAP1VVVVVVVVf8AAAAAAAAP1VVVVVVVfwAAAAAAAAA/VVVVVVVfAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAA/8AAAAAAA9VfAAAAAAD//8AAAAAAD1XwAAAAAD9VfwAAAAAA9V8AAAAAD1VVfAAAAAAPVfAAAAAD1VVV8AAAAAD1XwAAAAD1VVVXwAAAAA9V8AAAAA9VVVVfAAAAAPVfAAAAA9VVVVXwAAAAD1XwAAAAPVVVVVfAAAAA9V8AAAAD1VVVVXwAAAA9VfAAAAD1VVVVV8AAAAPVXwAAAA9VVVVVfAAAAD1VfAAAAD1VVVVXwAAAA9VXwAAAA9VVVVV8AAAAPVV8AAAAPVVVVV8AAAAPVVfAAAAA9VVVVfAAAAD1VV8AAAAPVVVVfAAAAA9VVfAAAAA9VVVfAAAAA9VVV8AAAAD9VVfAAAAAPVVVfAAAAAP9V/AAAAAPVVVV8AAAAAP//AAAAAD1VVVfAAAAAAP8AAAAAD1VVVV8AAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAA9VXwAAAAAA//wAAAAAAD1XwAAAAAA///wAAAAAA9V8AAAAAA9VV/AAAAAAPV8AAAAAA9VVV8AAAAAA9fAAAAAA9VVVXwAAAAAPXwAAAAA9VVVVfAAAAAD18AAAAA9VVVVXwAAAAAP8AAAAAPVVVVV8AAAAAD/AAAAAD1VVVVXwAAAAA/wAAAAA9VVVVV8AAAAAP8AAAAAPVVVVVfAAAAAD/AAAAAD1VVVVXwAAAAA/wAAAAA9VVVVV8AAAAAP8AAAAAPVVVVV8AAAAAD/AAAAAA9VVVVfAAAAAA/wAAAAAPVVVVfAAAAAAP8AAAAAA9VVVXwAAAAAD/AAAAAAD1VVfwAAAAAA/wAAAAAAP1VfwAAAAAAP8AAAAAAA///AAAAAAAD/AAAAAAAA//AAAAAAAA98AAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAA/VVVVVV/AAAAAAAAAAA/VVVVVVX/AAAAAAAAAD9VVVVVVVX/AAAAAAAAP9VVVVVVVVX/wAAAAAP/1VVVVVVVVVX//AAAP//VVVVVVVVVVVV//////VVVVVVVVVVVVVVX///VVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "57", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf//VVVVVVVVVVVVVVX/////1VVVVVVVVVVVV//wAA//VVVVVVVVVVVf8AAAAAP9VVVVVVVVVX/AAAAAAA/1VVVVVVVVfwAAAAAAAD9VVVVVVVV8AAAAAAAAAPVVVVVVVfwAAAAAAAAAD1VVVVVV/AAAAAAAAAAA9VVVVVXwAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVfAAAAAAA//wAAAAAAD1fAAAAAAD//8AAAAAAD1fAAAAAAPVVfAAAAAAD1fAAAAAA9VVXwAAAAAD1fAAAAAD1VVV8AAAAAA9fAAAAAPVVVVfAAAAAA98AAAAAPVVVVfAAAAAA98AAAAA9VVVVfAAAAAA98AAAAA9VVVVXwAAAAA98AAAAA9VVVVXwAAAAA98AAAAA9VVVVXwAAAAAP8AAAAA9VVVVXwAAAAAP8AAAAAPVVVVfAAAAAAP8AAAAAPVVVVfAAAAAAP8AAAAAD1VVV8AAAAAAPfAAAAAA9VVXwAAAAAAPfAAAAAAPVVfAAAAAAAPfAAAAAAD//8AAAAAAAPfAAAAAAA//wAAAAAAAPfAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA9VVV/AAAAAAA8AAAAAA9VVVf8AAAAAP/AAAAAA9VVVV/8AAA//XwAAAAA9VVVVX/////1XwAAAAA9VVVVVX///VVXwAAAAA9VVVVVVVVVVVXwAAAAD1VVVVVVVVVVVfAAAAAD1VVVVVVVVVVVfAAAAAD1VVVVVVVVVVV8AAAAAD1VVVVVVVVVVV8AAAAAD1VVdVVVVVVVXwAAAAAPVVVf1VVVVVVfAAAAAAPVVV//VVVVVVfAAAAAAPVVV8P/VVVVX8AAAAAAPVVV8A//VVV/wAAAAAA9VVV8AA////8AAAAAAA9VVV8AAA///AAAAAAAA9VVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAD1VVVVVfAAAAAAAAAAA/VVVVVVX8AAAAAAAAAD9VVVVVVV/wAAAAAAAA/VVVVVVVVX/AAAAAAAP9VVVVVVVVVf/8AAAAP/VVVVVVVVVVV///////1VVVVVVVVVVVVX////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "22", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/1VVVVf//1VVV/wA/1VV/AAA/VV8AAAD1VfAAAAPVfAAAAA9XwAAAAPXwAAAAA98AAAAAPfAAAAAD/AAAAAA/wAAAAAP8AAAAAD/AAAAAA/wAAAAAP8AAAAAD3wAAAAA98AAAAAPfAAAAAD3wAAAAD1fAAAAA9XwAAAAPVfAAAAPVV8AAAPVVXwAA/VVVf///VVVV//9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/9VVVV///9VVV/AAP1VV8AAAPVV8AAAA9V8AAAAPVfAAAAA9fAAAAAPXwAAAAA98AAAAAPfAAAAAD/AAAAAA/wAAAAAP8AAAAAD/AAAAAA/wAAAAAP8AAAAAD3wAAAAA98AAAAAPfAAAAAD18AAAAD1fAAAAA9V8AAAA9VfAAAAPVV/AAA/VVX/AD/VVVX//9VVVVX/1VVVVVVVVVQ=="}
+ ]
+}
diff --git a/apps/contourclock/fonts/font-MouseMemoirs.json b/apps/contourclock/fonts/font-MouseMemoirs.json
new file mode 100644
index 000000000..e98b6712e
--- /dev/null
+++ b/apps/contourclock/fonts/font-MouseMemoirs.json
@@ -0,0 +1,17 @@
+{
+ "name":"Mouse Memoirs",
+ "size":"100",
+ "characters":[
+ {"width" : "63", "buffer":"VVVVVVVVX///1VVVVVVVVVVVVVVVf/////9VVVVVVVVVVVVVX/8AAAP/1VVVVVVVVVVVV/wAAAAAD/VVVVVVVVVVVf8AAAAAAAP9VVVVVVVVVV/AAAAAAAAA/VVVVVVVVVXwAAAAAAAAAD9VVVVVVVVfAAAAAAAAAAA/VVVVVVVV8AAAAAAAAAAAD1VVVVVVXwAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAA9VVVVVV8AAAAAA/AAAAAAPVVVVVXwAAAAAP/8AAAAAD1VVVVXwAAAAA/V/AAAAAD1VVVVfAAAAAD1VXwAAAAA9VVVVfAAAAAPVVV8AAAAA9VVVV8AAAAAPVVVfAAAAAPVVVV8AAAAA9VVVfAAAAAPVVVXwAAAAD1VVVXwAAAAD1VVXwAAAAD1VVVXwAAAAD1VVXwAAAAPVVVVV8AAAAA9VVfAAAAAPVVVVV8AAAAA9VVfAAAAAPVVVVVfAAAAA9VVfAAAAA9VVVVVfAAAAAPVV8AAAAA9VVVVVfAAAAAPVV8AAAAA9VVVVVfAAAAAPVV8AAAAA9VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAA9fAAAAAD1VVVVVV8AAAAA9fAAAAAD1VVVVVV8AAAAA9fAAAAAPVVVVVVV8AAAAA9fAAAAAPVVVVVVV8AAAAA9fAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVVfAAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAP8AAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAAPfAAAAAPVVVVVVV8AAAAA9fAAAAAPVVVVVVV8AAAAA9fAAAAAD1VVVVVV8AAAAA9fAAAAAD1VVVVVV8AAAAA9XwAAAAD1VVVVVXwAAAAA9XwAAAAD1VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAD1XwAAAAD1VVVVVXwAAAAD1V8AAAAD1VVVVVXwAAAAD1V8AAAAA9VVVVVfAAAAAD1V8AAAAA9VVVVVfAAAAAPVVfAAAAA9VVVVVfAAAAAPVVfAAAAAPVVVVVfAAAAAPVVfAAAAAPVVVVV8AAAAA9VVfAAAAAPVVVVV8AAAAA9VVXwAAAAD1VVVV8AAAAD1VVXwAAAAD1VVVXwAAAAD1VVV8AAAAA9VVVXwAAAAD1VVV8AAAAA9VVVfAAAAAPVVVVfAAAAAPVVVfAAAAAPVVVVfAAAAAD1VV8AAAAA9VVVVXwAAAAA9VXwAAAAA9VVVVXwAAAAAP3/AAAAAD1VVVVV8AAAAAD/8AAAAAPVVVVVVfAAAAAAMAAAAAAPVVVVVVXwAAAAAAAAAAAA9VVVVVVXwAAAAAAAAAAAD1VVVVVVV8AAAAAAAAAAAPVVVVVVVVfwAAAAAAAAAA9VVVVVVVVX8AAAAAAAAAP1VVVVVVVVVfwAAAAAAAA/VVVVVVVVVVX/AAAAAAAP1VVVVVVVVVVVf8AAAAAP/VVVVVVVVVVVVV//AAA//1VVVVVVVVVVVVVX/////1VVVVVVVVVVVVVVVV///VVVVVVVVV"},
+ {"width" : "43", "buffer":"VVVVVVVVVVVVVVVVVVVVVVf////9VVVVVVVVf//////VVVVVVV/AAAAAP1VVVVVV/AAAAAA9VVVVVX8AAAAAAPVVVVVX8AAAAAAD1VVVVXwAAAAAAA9VVVVfwAAAAAAAPVVVVfwAAAAAAAD1VVV/AAAAAAAAA9VVV/AAAAAAAAAPVVX8AAAAAAAAAD1VX8AAAAAAAAAA9VfwAAAAAAAAAAPVfwAAAAAAAAAAD1/AAAAAAAAAAAA9/AAAAAAAAAAAAP8AAAAAAAAAAAAPfAAAAAAAAAAAAD18AAAAAPAAAAAA9XwAAAA/8AAAAAPVfAAAA/XwAAAAD1V8AAD9V8AAAAA9VfAAD9VfAAAAAPVV8AP1VXwAAAAD1VX8P1VV8AAAAA9VVf/VVVfAAAAAPVVVfVVVXwAAAAD1VVVVVVV8AAAAA9VVVVVVVfAAAAAPVVVVVVVXwAAAAD1VVVVVVV8AAAAA9VVVVVVVfAAAAAPVVVVVVVXwAAAAD1VVVVVVV8AAAAA9VVVVVVVfAAAAAPVVVVVVVXwAAAAD1VVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVV8AAAAPVVVVVVVVfAAAAD1VVVVVVVXwAAAA9VVVVVVVV8AAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAD1VVVVVVVfAAAAA9VVVVVVVXwAAAAPVVVVVVVV8AAAAP1VVVVVVVf/////9VVVVVVVVf////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "50", "buffer":"VVVVVVf//9VVVVVVVVVVV///////VVVVVVVVX//8AAA//1VVVVVVf/wAAAAAAP9VVVVVf/AAAAAAAAD/VVVVX8AAAAAAAAAA/VVVX8AAAAAAAAAAAPVVV/AAAAAAAAAAAAPVVfAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAPVXwAAAAAAAAAAAAA9VfAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAD1XwAAAAAAAAAAAAAPVfAAAAD///AAAAAAPVfAAAP////AAAAAA9V8AAP/VVVfAAAAAD1XwAP9VVVVfAAAAAD1XwD9VVVVVfAAAAAPVfD9VVVVVVfAAAAA9V//VVVVVVV8AAAAD1V/VVVVVVVV8AAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAA9VVVVVVVVVV8AAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAA9VVVVVVVVVV8AAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAA9VVVVVVVVVV8AAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAD1VVVVVVVVVV8AAAAPVVVVVVVVVVfAAAAA9VVVVVVVVVV8AAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAD1VVVVVVVVVXwAAAAPVVVVVVVVVVfAAAAA9VVVVVVVVVV8AAAAD1VVVVVVVVVfAAAAAPVVVVVVVVVV8AAAAD1VVVVVVVVVfAAAAAPVVVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAPVVVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVXwAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVfAAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVfAAAAAD1VVVVVVVVV8AAAAA9VVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVVfAAAAAPVVVVVVVVVXwAAAAA9VVVVVVVVV8AAAAAPVVVVVVVVVfAAAAAD1VVVVVVVVV8AAAAAPVVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVV8AAAAAPVVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAAPVVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVV8AAAAAPVVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVVfAAAAAD1VVVVVVVVXwAAAAA9VVVVVVVVV8AAAAAD1VVVVVVVVXwAAAAAD////////1fAAAAAAD////////V8AAAAAAAAAAAAAA9XwAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAA9XwAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAA9XwAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAPV///////////////9X///////////////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "54", "buffer":"VVVVVX/////1VVVVVVVVVVX///////1VVVVVVVVX/8AAAAAP/VVVVVVVX/8AAAAAAAP9VVVVVV/8AAAAAAAAA/VVVVVX8AAAAAAAAAAD1VVVV/AAAAAAAAAAAA/VVVX8AAAAAAAAAAAAP1VVfAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAP//wAAAAAAA9VXwAAD////AAAAAAA9VV8AA/1VVfwAAAAAAPVV8AP9VVVV8AAAAAAPVVfA/VVVVVfAAAAAAPVVfP1VVVVVXwAAAAAPVVX/VVVVVVV8AAAAAPVVX1VVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVXwAAAAD1VVVVVVVVVVfAAAAAD1VVVVVVVVVVfAAAAAPVVVVVVVVVVV8AAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVV/AAAAAD1VVVVVVVVVf8AAAAA/VVVVVVVVVV/AAAAAD9VVVVVVVVVXwAAAAA/VVVVVVVVVVXwAAAAD9VVVVVVVVVVXwAAAAPVVVVVVVVVVVXwAAAAPVVVVVVVVVVVXwAAAAD1VVVVVVVVVVXwAAAAA/VVVVVVVVVVXwAAAAAP9VVVVVVVVVXwAAAAAA/1VVVVVVVVXwAAAAAAD9VVVVVVVVXwAAAAAAAP1VVVVVVVX/8AAAAAAD9VVVVVVVV//8AAAAAAPVVVVVVVVVX/wAAAAAD1VVVVVVVVVX/AAAAAA9VVVVVVVVVVfwAAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAAPVVVVVVVVVVVXwAAAAPVVVVVVVVVVVXwAAAAD1VVVVVVVVVVV8AAAAD1VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAA9VVVVVVVVVVXwAAAAA9VXVVVVVVVVXwAAAAA9Vf9VVVVVVVfAAAAAA9Vf/VVVVVVVfAAAAAA9VfD9VVVVVV8AAAAAA9V8A/1VVVVfwAAAAAD1V8AD/VVVV/AAAAAAD1V8AAP/1V/wAAAAAAD1V8AAA////AAAAAAAPVV8AAAAP/AAAAAAAA9VV8AAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAD9VVXwAAAAAAAAAAAAPVVVXwAAAAAAAAAAAD9VVVX/AAAAAAAAAAAP1VVVVf8AAAAAAAAAD9VVVVVV/8AAAAAAAD/1VVVVVVX//AAAAAD/9VVVVVVVVX///////9VVVVVVVVVVV/////9VVVVVVV"},
+ {"width" : "54", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////9VVVVVVVVVVVf//////VVVVVVVVVVVfAAAAAPVVV/////VVVfAAAAAPVVf/////9VVfAAAAAPVV/AAAAA9VVfAAAAAPVV8AAAAA9VVfAAAAAPVV8AAAAA9VVfAAAAAPVV8AAAAA9VVfAAAAAPVV8AAAAD1VVfAAAAAPVV8AAAAD1VVfAAAAAPVV8AAAAD1VVfAAAAAPVV8AAAAD1VVfAAAAA9VV8AAAAD1VVfAAAAA9VV8AAAAD1VVfAAAAA9VV8AAAAPVVVfAAAAA9VV8AAAAPVVVfAAAAA9VV8AAAAPVVVfAAAAA9VV8AAAAPVVVfAAAAA9VXwAAAAPVVVfAAAAA9VXwAAAAPVVVfAAAAA9VXwAAAAPVVVfAAAAA9VXwAAAAPVVVfAAAAA9VXwAAAA9VVVfAAAAA9VXwAAAA9VVVfAAAAA9VXwAAAA9VVVfAAAAA9VXwAAAA9VVVfAAAAA9VXwAAAA9VVVfAAAAA9VfAAAAA9VVVfAAAAA9VfAAAAA9VVVXwAAAA9VfAAAAA9VVVXwAAAA9VfAAAAA9VVVXwAAAA9VfAAAAA9VVVXwAAAA9VfAAAAD1VVVXwAAAA9VfAAAAD1VVVXwAAAA9VfAAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVXwAAAA9V8AAAAD1VVVfAAAAA9XwAAAAD1VVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAD1f//8AAAAA9XwAAAAA////wAAAAA9fAAAAAAPwAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAA9///////////wAAAAA9f//////////8AAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVV//////9VVVVVVVVVVV//////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "52", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////////////9VVVV/////////////VVVVfAAAAAAAAAAAD1VVVfAAAAAAAAAAAA9VVVXwAAAAAAAAAAAPVVVV8AAAAAAAAAAAD1VVVfAAAAAAAAAAAA9VVVXwAAAAAAAAAAAPVVVV8AAAAAAAAAAAD1VVVfAAAAAAAAAAAA9VVVXwAAAAAAAAAAAPVVVV8AAAAA///////1VVVfAAAAA///////1VVVXwAAAA9VVVVVVVVVVV8AAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAD1VVVVVVVVVVXwAAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAD1VVVVVVVVVVXwAAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAPVVVVVVVVVVVXwAAAD1VVVVVVVVVVXwAAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAD1VVVVVVVVVVXwAAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAD1VVVVVVVVVVXwAAAA9VVVVVVVVVVV8AAAAPVVVVVVVVVVVfAAAAD1VVVVVVVVVVXwAAAAP//9VVVVVVVV8AAAAA////1VVVVVV8AAAAAAAAP/1VVVVVfAAAAAAAAAA/1VVVVXwAAAAAAAAAA/1VVVV8AAAAAAAAAAA/VVVVfAAAAAAAAAAAA9VVVXwAAAAAAAAAAAD9VVV8AAAAAAAAAAAAP1VVfAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAD1VV8AD///AAAAAAAAPVV8D/////wAAAAAAA9Vf//1VVX/wAAAAAAPVX/1VVVVV/AAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVVXwAAAAAA9VVVVVVVVVfAAAAAAPVVVVVVVVVV8AAAAAD1VVVVVVVVVXwAAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVVfAAAAAPVVVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAA9VVVVVVVVVVfAAAAAPVVVVVVVVVVXwAAAAD1VVVVVVVVVV8AAAAA9VVVVVVVVVVfAAAAAPVVVVVVVVVVXwAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVVfAAAAAD1VVVVVVVVVXwAAAAD1VVVVVVVVVXwAAAAA9VVVVVVVVVV8AAAAAPVVVVVVVVVV8AAAAAD1VVVVVVVVVfAAAAAD1VVVVVVVVVfAAAAAA9VVVVVVVVVfAAAAAAPV/9VVVVVVfAAAAAAPVf/9VVVVV/AAAAAAD1XwP/VVVX/AAAAAAD1V8AP////8AAAAAAA9VfAAD///wAAAAAAA9VXwAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAPVVfAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAPVVV8AAAAAAAAAAAAPVVVfAAAAAAAAAAAA/VVVX/AAAAAAAAAAD/VVVVX/wAAAAAAAAP9VVVVVX//AAAAAAP/1VVVVVVV/////////VVVVVVVVVX//////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "59", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/////1VVVVVVVVVVVVf///////9VVVVVVVVVVf/wAAAAD//1VVVVVVVVf8AAAAAAAA/VVVVVVVVf8AAAAAAAAA9VVVVVVVX8AAAAAAAAAD1VVVVVVX8AAAAAAAAAAPVVVVVVV/AAAAAAAAAAD1VVVVVVfAAAAAAAAAAAPVVVVVVXwAAAAAAAAAAA9VVVVVV8AAAAAAAAAAAD1VVVVVXwAAAAAAAP//APVVVVVV8AAAAAAA////89VVVVVfAAAAAAA/9VVf/VVVVVV8AAAAAAP1VVVV1VVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVfAAAAAA9VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVXwAAAAD1VV///VVVVVVVfAAAAAPVf/////VVVVVV8AAAAA9f/wAAP/9VVVVXwAAAAA/8AAAAAP/VVVV8AAAAAA8AAAAAAA/VVVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAA//AAAAAAA9XwAAAAAAA///wAAAAAD1fAAAAAAAP1VfwAAAAAD18AAAAAAD1VVXwAAAAAPXwAAAAAA9VVVXwAAAAA9fAAAAAAPVVVVXwAAAAA98AAAAAD1VVVVfAAAAAD3wAAAAA9VVVVVfAAAAAPfAAAAAD1VVVVV8AAAAA98AAAAA9VVVVVV8AAAAA/wAAAAD1VVVVVXwAAAAD/AAAAAPVVVVVVfAAAAAP8AAAAA9VVVVVV8AAAAA/wAAAAD1VVVVVV8AAAAD/AAAAAPVVVVVVXwAAAAP8AAAAA9VVVVVVfAAAAA98AAAAD1VVVVVV8AAAAD3wAAAAPVVVVVVXwAAAAPfAAAAA9VVVVVVfAAAAA98AAAAD1VVVVVV8AAAAD3wAAAAPVVVVVVXwAAAAPfAAAAA9VVVVVVfAAAAA98AAAAD1VVVVVV8AAAAD3wAAAAD1VVVVVXwAAAAPXwAAAAPVVVVVVfAAAAA9fAAAAA9VVVVVXwAAAAD18AAAAD1VVVVVfAAAAAPXwAAAAPVVVVVV8AAAAA9fAAAAAPVVVVVXwAAAAPVfAAAAA9VVVVVfAAAAA9V8AAAAD1VVVVXwAAAAD1XwAAAAPVVVVVfAAAAAPVfAAAAAPVVVVV8AAAAD1VfAAAAA9VVVVfAAAAAPVV8AAAAA9VVVV8AAAAA9VXwAAAAA9VVVfAAAAAPVVXwAAAAD1VVXwAAAAA9VVfAAAAAD1VV8AAAAAPVVVfAAAAAD9V/AAAAAA9VVV8AAAAAD//wAAAAAPVVVV8AAAAAA/wAAAAAA9VVVXwAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAD9VVVVVVfwAAAAAAAAAA/VVVVVVVfwAAAAAAAAA/VVVVVVVVX8AAAAAAAA/1VVVVVVVVX/wAAAAAD/1VVVVVVVVVV//AAAAP/1VVVVVVVVVVVX//////VVVVVVVVVVVVVVf///9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "45", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf///9f////////////////////////wAAAP8AAAAAAAAAAAAA98AAAAAAAAAAAAA98AAAAAAAAAAAAA98AAAAAAAAAAAAA98AAAAAAAAAAAAD18AAAAAAAAAAAAD18AAAAAAAAAAAAD18AAAAAAAAAAAAPV8AAAAAAAAAAAAPV8AAAAAAAAAAAAPV///////8AAAAAPVf///////AAAAA9VVVVVVVVXwAAAA9VVVVVVVVXwAAAA9VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVV8AAAAPVVVVVVVVV8AAAAPVVVVVVVVV8AAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAPVVVVVVVVV8AAAAPVVVVVVVVV8AAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAD1VVVVVVVVfAAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVfAAAAAPVVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVV8AAAAA9VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVV8AAAAD1VVVVVVVXwAAAAD1VVVVVVVXwAAAAD1VVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVXwAAAAPVVVVVVVVfAAAAAPVVVVVVVVfAAAAAPVVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVVfAAAAA9VVVVVVVV8AAAAA9VVVVVVVV8AAAAA9VVVVVVVV8AAAAA9VVVVVVVV8AAAAA9VVVVVVVV8AAAAD1VVVVVVVXwAAAAD1VVVVVVVXwAAAAD1VVVVVVVXwAAAAD1VVVVVVVX//////1VVVVVVVV//////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "54", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVX//1VVVVVVVVVVVVX//////1VVVVVVVVVX//8AAP//1VVVVVVVV/8AAAAAAP/VVVVVVVf8AAAAAAAAP9VVVVVV/AAAAAAAAAA/VVVVVXwAAAAAAAAAAD1VVVVfAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVfAAAAAA//AAAAAA9VV8AAAAAD//wAAAAAPVV8AAAAAPVV8AAAAAPVXwAAAAA9VVfAAAAAD1XwAAAAD1VVXwAAAAD1XwAAAAD1VVV8AAAAD1XwAAAAPVVVV8AAAAA9fAAAAAPVVVVfAAAAA9fAAAAA9VVVVfAAAAA9fAAAAA9VVVVfAAAAAPfAAAAA9VVVVfAAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAPfAAAAD1VVVVXwAAAAPfAAAAD1VVVVXwAAAAPfAAAAA9VVVVXwAAAA9fAAAAA9VVVVfAAAAA9XwAAAA9VVVVfAAAAA9XwAAAA9VVVVfAAAAD1XwAAAAPVVVV8AAAAD1V8AAAAPVVVV8AAAAPVV8AAAAD1VVV8AAAAPVVfAAAAD1VVXwAAAAPVVfAAAAA9VVfAAAAA9VVXwAAAAPVV8AAAAD1VVV8AAAAD1XwAAAAD1VVVfAAAAA//AAAAAPVVVVfAAAAAP8AAAAA9VVVVXwAAAAAAAAAAD1VVVVV8AAAAAAAAAAPVVVVVVfAAAAAAAAAA9VVVVVVXwAAAAAAAAD1VVVVVVXwAAAAAAAAD1VVVVVVfAAAAAAAAAA/VVVVVX8AAAAAAAAAAP1VVVVfwAAAAAAAAAAA9VVVV8AAAAAAAAAAAAPVVVXwAAAAA//AAAAAD1VVfAAAAAD//wAAAAA9VVfAAAAAPVV8AAAAA9VV8AAAAA9VVfAAAAAPVV8AAAAD1VVXwAAAAD1XwAAAAPVVVV8AAAAD1XwAAAAPVVVV8AAAAA9fAAAAA9VVVVfAAAAA9fAAAAA9VVVVfAAAAA9fAAAAA9VVVVfAAAAAPfAAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAP8AAAAD1VVVVXwAAAAPfAAAAA9VVVVXwAAAAPfAAAAA9VVVVfAAAAA9fAAAAA9VVVVfAAAAA9XwAAAAPVVVVfAAAAA9XwAAAAPVVVV8AAAAD1V8AAAAD1VVXwAAAAD1V8AAAAA9VVfAAAAAPVVfAAAAAP1X8AAAAAPVVXwAAAAD//wAAAAA9VVXwAAAAAP8AAAAAD1VVV8AAAAAAAAAAAAPVVVVfwAAAAAAAAAAA9VVVVX/AAAAAAAAAAP1VVVVVf8AAAAAAAAD/VVVVVVV/wAAAAAAD/1VVVVVVVX/8AAAAD/9VVVVVVVVVf//////9VVVVVVVVVVVX////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "59", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX////1VVVVVVVVVVVVV///////VVVVVVVVVVVV//AAAAD/1VVVVVVVVVV/wAAAAAAP9VVVVVVVVV/wAAAAAAAD/VVVVVVVVfwAAAAAAAAA/VVVVVVVfwAAAAAAAAAAPVVVVVVX8AAAAAAAAAAAPVVVVVV8AAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAA9VVVXwAAAAAD/wAAAAAD1VVVfAAAAAA//8AAAAAD1VVXwAAAAAPVX8AAAAAD1VVfAAAAAD1VV8AAAAAPVVXwAAAAA9VVV8AAAAA9VVfAAAAAPVVVV8AAAAA9VXwAAAAA9VVVXwAAAAD1VfAAAAAPVVVVXwAAAAD1V8AAAAA9VVVVfAAAAAPVfAAAAAPVVVVVfAAAAA9V8AAAAA9VVVVV8AAAAD1XwAAAAPVVVVVXwAAAAD1fAAAAA9VVVVVXwAAAAPV8AAAAD1VVVVVfAAAAA9fAAAAAPVVVVVV8AAAAD18AAAAA9VVVVVXwAAAAPXwAAAAD1VVVVVfAAAAAPfAAAAA9VVVVVVfAAAAA98AAAAD1VVVVVV8AAAAD3wAAAAPVVVVVVXwAAAAPfAAAAA9VVVVVVfAAAAA98AAAAD1VVVVVV8AAAAD3wAAAAPVVVVVVXwAAAAD/AAAAA9VVVVVVfAAAAAP8AAAAD1VVVVVV8AAAAA/wAAAAPVVVVVVXwAAAAD/AAAAAPVVVVVVfAAAAAP8AAAAA9VVVVVV8AAAAA/wAAAAD1VVVVVXwAAAAD/AAAAAPVVVVVVfAAAAAP8AAAAA9VVVVVV8AAAAA98AAAAA9VVVVVXwAAAAD3wAAAAD1VVVVV8AAAAAPfAAAAAPVVVVVXwAAAAA98AAAAAPVVVVV8AAAAAD18AAAAAPVVVVfAAAAAAPXwAAAAA9VVVXwAAAAAA9fAAAAAA9VVV8AAAAAAD1fAAAAAA/VV/AAAAAAAPV8AAAAAA///wAAAAAAA9V8AAAAAAP/wAAAAAAAD1XwAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVVfwAAAAAAAAAAAAAA9VVVf8AAAAAADwAAAAAD1VVVX/wAAAAP/wAAAAAPVVVVV///AD//XwAAAAD1VVVVVX////9VfAAAAAPVVVVVVVVf/VVV8AAAAA9VVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVfAAAAAD1VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVX1VVVV/AAAAAAD1VVVVVf/VVV/wAAAAAAPVVVVVV/////wAAAAAAD1VVVVVfAP//wAAAAAAA9VVVVVV8AAAAAAAAAAAD1VVVVVXwAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAP1VVVVVVXwAAAAAAAAAD9VVVVVVV8AAAAAAAAAD9VVVVVVVXwAAAAAAAAD/VVVVVVVVf8AAAAAAAD/VVVVVVVVVf//AAAAA//VVVVVVVVVVV////////VVVVVVVVVVVVVf////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "20", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX//1VVX///9VX/AAD/V/AAAA/XwAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA98AAAAPV/AAAP1V////9VVf//9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf//VVVf///1Vf8AAP9X8AAAD9fAAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD3wAAAA9X8AAA/VX/8D/1VV///1VVVV/VVU="}
+ ]
+}
diff --git a/apps/contourclock/fonts/font-NerkoOne.json b/apps/contourclock/fonts/font-NerkoOne.json
new file mode 100644
index 000000000..14fb84fcb
--- /dev/null
+++ b/apps/contourclock/fonts/font-NerkoOne.json
@@ -0,0 +1,17 @@
+{
+ "name":"Nerko One",
+ "size":"99",
+ "characters":[
+ {"width" : "60", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf////VVVVVVVVVVVVVVf//////VVVVVVVVVVVVX/wAAAA/9VVVVVVVVVVV/wAAAAAA/1VVVVVVVVVf8AAAAAAAD9VVVVVVVVV/AAAAAAAAAP1VVVVVVVXwAAAAAAAAAD9VVVVVVVfAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAD1VVVV8AAAAAAP8AAAAAA9VVVXwAAAAAA//AAAAAA9VVVXwAAAAAD1XwAAAAAPVVVXwAAAAAPVXwAAAAAPVVVfAAAAAAPVV8AAAAAD1VVfAAAAAA9VVfAAAAAD1VV8AAAAAA9VVfAAAAAD1VV8AAAAAA9VVfAAAAAA9VV8AAAAAD1VVXwAAAAA9VV8AAAAAD1VVXwAAAAAPVXwAAAAAD1VVXwAAAAAPVXwAAAAAD1VVXwAAAAAPVXwAAAAAD1VVXwAAAAAPVXwAAAAAD1VVV8AAAAAD1fAAAAAAPVVVV8AAAAAD1fAAAAAAPVVVV8AAAAAD1fAAAAAAPVVVV8AAAAAD1fAAAAAAPVVVV8AAAAAD1fAAAAAAPVVVV8AAAAAD1fAAAAAAPVVVV8AAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAAPVVVVfAAAAAA98AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAAP8AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAA98AAAAAA9VVVVfAAAAAA9fAAAAAA9VVVVfAAAAAA9fAAAAAA9VVVVfAAAAAA9fAAAAAA9VVVVfAAAAAA9fAAAAAA9VVVV8AAAAAA9fAAAAAAPVVVV8AAAAAA9fAAAAAAPVVVV8AAAAAA9fAAAAAAPVVVV8AAAAAA9XwAAAAAPVVVV8AAAAAA9XwAAAAAPVVVV8AAAAAD1XwAAAAAPVVVV8AAAAAD1XwAAAAAPVVVV8AAAAAD1XwAAAAAPVVVXwAAAAAD1V8AAAAAPVVVXwAAAAAD1V8AAAAAD1VVXwAAAAAD1V8AAAAAD1VVXwAAAAAD1V8AAAAAD1VVXwAAAAAPVVfAAAAAD1VVXwAAAAAPVVfAAAAAD1VVfAAAAAAPVVfAAAAAA9VVfAAAAAAPVVXwAAAAA9VV8AAAAAA9VVXwAAAAAPVV8AAAAAA9VVXwAAAAAPVXwAAAAAA9VVV8AAAAAD//AAAAAAD1VVV8AAAAAA/8AAAAAAD1VVVfAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAPVVVVVVVfAAAAAAAAAAD9VVVVVVVX8AAAAAAAAAP1VVVVVVVV/AAAAAAAAD9VVVVVVVVVX/AAAAAAA/1VVVVVVVVVV////////9VVVVVVVVVVVV///////VVVVVV"},
+ {"width" : "42", "buffer":"VVVVVVf//9VVVVVVVVVX////1VVVVVVVV/wAAD9VVVVVVVX8AAAAPVVVVVVVfAAAAAD1VVVVVVfAAAAAD1VVVVVV8AAAAAD1VVVVVXwAAAAAD1VVVVVXwAAAAAA9VVVVVfAAAAAAA9VVVVVfAAAAAAA9VVVVV8AAAAAAA9VVVVV8AAAAAAA9VVVVXwAAAAAAA9VVVVXwAAAAAAA9VVVVfAAAAAAAA9VVVVfAAAAAAAA9VVVVfAAAAAAAA9VVVV8AAAAAAAA9VVVV8AAAAAAAA9VVVV8AAAAAAAA9VVVXwAAAAAAAA9VVVXwAAAAAAAAPVVVXwAAAAAAAAPVVVfAAAAAAAAAPVVVfAAAAAAAAAPVVVfAAAAAAAAAPVVV8AAAAAAAAAPVVV8AAAAAAAAAPVVV8AAAAAAAAAPVVV8AAAAAAAAAPVVXwAAAAAAAAAD1VXwAAAAAAAAAD1VXwAAAAAAAAAD1VfAAAAAAAAAAD1VfAAAAAAAAAAD1VfAAAAAAAAAAD1VfAAAAAAAAAAD1V8AAAAAAAAAAD1V8AAAAAAAAAAD1V8AAAAAAAAAAD1V8AAAAAAAAAAD1V8AAAAAAAAAAD1V8AAAAAAAAAAA9V8AAAAAAAAAAA9VfAAAAAAAAAAA9VfwAAAAAAAAAA9VV/wAAAAAAAAA9VVf//8AAAAAAA9VVVf//AAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAAPVVVVVXwAAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVfAAAAAAD1VVVVVXwAAAAAD1VVVVVXwAAAAAD1VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVXwAAAAAA9VVVVVV8AAAAAA9VVVVVV8AAAAAA9VVVVVV8AAAAAA9VVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVV8AAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAPVVVVVVfAAAAAAPVVVVVVXwAAAAAPVVVVVVXwAAAAAPVVVVVVXwAAAAA9VVVVVVV8AAAAA9VVVVVVV/AAAAA9VVVVVVVf/////1VVVVVVVV/////VA="},
+ {"width" : "57", "buffer":"VVVVVX/////1VVVVVVVVVVVX///////9VVVVVVVVVV/8AAAAAP/9VVVVVVVVf8AAAAAAAD/1VVVVVVV/AAAAAAAAAD/VVVVVVfwAAAAAAAAAAP9VVVVV/AAAAAAAAAAAA/VVVVXwAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAD1VXwAAAAAAD/AAAAAAA9VXwAAAAAA//wAAAAAAPVfAAAAAAD9V8AAAAAAPVfAAAAAAPVV8AAAAAAPVfAAAAAA9VVfAAAAAAD18AAAAAA9VVfAAAAAAD18AAAAAD1VVfAAAAAAD18AAAAAD1VVfAAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA98AAAAAD1VVXwAAAAAA9fAAAAAPVVVXwAAAAAA9fAAAAAPVVVXwAAAAAA9XwAAAD9VVVfAAAAAAD1V/AAA/1VVVfAAAAAAD1Vf///9VVVVfAAAAAAD1VV///VVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAD1VVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAA9VVV//9VVVVV8AAAAAA9VX////9VVVXwAAAAAAP///AAD/VVVXwAAAAAAD/8AAAAD1VVfAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAD9XwAAAAAAAAAAAAAAA/1XwAAAAAAAAAAAAA//9VXwAAAAAAAAAAD////VVV8AAAAAAAAA////VVVVV8AAAAAAD///9VVVVVVVf/////////VVVVVVVVVX//////9VVVVVVVVVVA=="},
+ {"width" : "57", "buffer":"VVVVVX////1VVVVVVVVVVVV///////9VVVVVVVVVV//8AAAAP/1VVVVVVVVf/AAAAAAAD/VVVVVVVX/AAAAAAAAAP9VVVVVVfwAAAAAAAAAA/VVVVVV8AAAAAAAAAAAD1VVVVXwAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAD1VVfAAAAD/8AAAAAAAD1VVf8AA////wAAAAAAD1VVX////9VX8AAAAAAA9VVVX//VVVVfAAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVX8AAAAAAD1VVVVVVVVX/wAAAAAAD1VVVVVVVV/8AAAAAAAD1VVVVVVVX8AAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAD1VVVVVVV8AAAAAAAAAA9VVVVVVV8AAAAAAAAAAPVVVVVVV8AAAAAAAAAAD1VVVVVV8AAAAAAAAAAA9VVVVVV8AAAAAAAAAAAPVVVVVVfAAAAAAAAAAAPVVVVVVf/AAAAAAAAAAPVVVVVVV///wAAAAAAAD1VVVVVVV//8AAAAAAAD1VVVVVVVVVfAAAAAAAD1VVVVVVVVVXwAAAAAAA9VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVVVVVVVVVVfAAAAAAPVVV//9VVVVVfAAAAAAPVV////9VVVVfAAAAAAPVX/AAD/VVVVfAAAAAAPVfAAAAD1VVVfAAAAAAPV8AAAAA9VVVfAAAAAAPXwAAAAA9VVVfAAAAAAPXwAAAAA9VVVfAAAAAAPfAAAAAAPVVVfAAAAAAPfAAAAAAPVVVfAAAAAAPfAAAAAAPVVVfAAAAAAPfAAAAAAPVVVfAAAAAAPfAAAAAAPVVVfAAAAAAPfAAAAAAD1VVfAAAAAAPfAAAAAAD1VVfAAAAAA9fAAAAAAA9VV8AAAAAA9fAAAAAAA9VV8AAAAAA9XwAAAAAAPVXwAAAAAA9XwAAAAAAD//AAAAAAA9XwAAAAAAA/8AAAAAAD1V8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA9VVV/AAAAAAAAAAAAAD1VVVfwAAAAAAAAAAAAPVVVVV/AAAAAAAAAAAA9VVVVVf8AAAAAAAAAAP1VVVVVV/wAAAAAAAAD/VVVVVVVX//////////1VVVVVVVVf////////9VVVVA=="},
+ {"width" : "56", "buffer":"VVVVVVVVVVVVVVVVVVVVVf//VVVVVVVVVVVVVVVf///9VVVVVVVVVVVVVX8AAP9VVVVVVVVVVVVV8AAAA9VVVVVVVVVVVVfAAAAD1VVVVVVVVVVVXwAAAAD1VVVVVVVVVVVfAAAAAPVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVV8AAAAAPVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAD1VVVVVVVVVVV8AAAAAPVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAD1VVVVX//1VVV8AAAAAPVVVV/////VVXwAAAAA9VVVf/AAD/VVfAAAAAD1VVXwAAAAPVV8AAAAAPVVV8AAAAAPVXwAAAAA9VVfAAAAAA9VfAAAAAPVVV8AAAAAA9V8AAAAA9VVXwAAAAAD1XwAAAAD1VVfAAAAAAPVfAAAAAPVVV8AAAAAA9V8AAAAA9VVXwAAAAAD1XwAAAAD1VVfAAAAAAPVfAAAAAPVVV8AAAAAA9V8AAAAA9VVXwAAAAAA9XwAAAAD1VVfAAAAAAD1fAAAAAPVVV8AAAAAAPXwAAAAA9VVXwAAAAAA9fAAAAAD1VVfAAAAAAD18AAAAA9VVV8AAAAAAPXwAAAAD1VVXwAAAAAA9fAAAAAPVVVfAAAAAAD18AAAAA9VVV8AAAAAAPXwAAAAD1VVXwAAAAAA9fAAAAAPVVVfAAAAAAD18AAAAA9VVV8AAAAAAPXwAAAAD1VVXwAAAAAA9fAAAAAPVVVfAAAAAAD18AAAAA9VVV8AAAAAAPXwAAAAD1VVXwAAAAAA9fAAAAA9VVVfAAAAAAD18AAAAD1VVV8AAAAAAPXwAAAAPVVVXwAAAAAA9fAAAAA9VVVfAAAAAAD18AAAAD1VVV8AAAAAAPXwAAAAPVVVXwAAAAAA9fAAAAA9VVVXwAAAAAD18AAAAD1VVVfAAAAAAD3wAAAAPVVVXwAAAAAAPfAAAAA9X//8AAAAAAA98AAAAA////AAAAAAAD3wAAAAA/AAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD18AAAAAAA//AAAAAAAPV/AAAA/////AAAAAAA9V///////1VfAAAAAAD1Vf///1VVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVV8AAAAAAPVVVVVVVVVVXwAAAAAA9VVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAPVVVVVVVVVVV8AAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVVXwAAAAA9VVVVVVVVVVVfAAAAAPVVVVVVVVVVVVf/////9VVVVVVVVVVVVf////9V"},
+ {"width" : "58", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////VVVVVVf/////////////1VVVX////////wAAAAD/VVVX/AAAAAAAAAAAAAA/VVXwAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAP1V8AAAAAAAAAAAAAAA/1VfAAAAAAAAAAAAAAP/VVXwAAAAAD////////9VVV8AAAAAD////////VVVVfAAAAAD1VVVVVVVVVVVXwAAAAA9VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVfAAAAAA9VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVfAAAAAA9VVVVVVVVVVVXwAAAAAPVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVfAAAAAA9VVVVVVVVVVVXwAAAAA9VVVVVVVVVVVV8AAAAAPVVVVVVVVVVVVfAAAAAA/////1VVVVVVfAAAAAAD//////VVVVVXwAAAAAAAAAAA//VVVVV8AAAAAAAAAAAAD9VVVVfAAAAAAAAAAAAAD9VVVXwAAAAAAAAAAAAAP1VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9V8AAAAAAAP8AAAAAAAPVXwAAAAAAP/wAAAAAAA9V8AAAAAAPVfAAAAAAAPVfAAAAAAPVV8AAAAAAD1XwAAAAAPVVXwAAAAAAPVfAAAAAPVVVfAAAAAAD1V/AAAAPVVVXwAAAAAA9VX/AAAP1VVV8AAAAAAD1VX/8D/VVVVXwAAAAAA9VVX///VVVVV8AAAAAAPVVVVf1VVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVXwAAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAAPVVVVVVVVVVVXwAAAAAD1VVVVVVVVVVV8AAAAAA9VVVVVVVVVVVfAAAAAAPVVVX/9VVVVVXwAAAAAD1VV////VVVVXwAAAAAA9VX/wAP9VVVV8AAAAAA9VX8AAAD1VVVfAAAAAAPVXwAAAAPVVVfAAAAAAD1XwAAAAA9VVXwAAAAAD1V8AAAAAD1VXwAAAAAA9VfAAAAAAP//wAAAAAAPVXwAAAAAA//wAAAAAAPVV8AAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAPVVVVfwAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAPVVVVVV/AAAAAAAAAAA/VVVVVVX8AAAAAAAAAA/VVVVVVVX/AAAAAAAAP9VVVVVVVVf/////////9VVVVVVVVVX////////VVVVVVA="},
+ {"width" : "58", "buffer":"VVVVVVVVV//1VVVVVVVVVVVVVVVf///1VVVVVVVVVVVVVVf8AA/1VVVVVVVVVVVVVfAAAA/VVVVVVVVVVVVVfAAAAA/VVVVVVVVVVVVfAAAAAD9VVVVVVVVVVVfAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAA9VVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAD1VVVVVVVVVfAAAAAAAD1VVVVVVVVVXwAAAAAAD1VVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVV8AAAAAAD1VVVVVVVVVV8AAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAA////1VVVVVV8AAAAAAAD////9VVVVVfAAAAAAAAAAAA/9VVVVfAAAAAAAAAAAAAP1VVVXwAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VfAAAAAAAA/8AAAAAAD1XwAAAAAAD//8AAAAAA9V8AAAAAAD9VfwAAAAAPV8AAAAAAD1VVfAAAAAA9fAAAAAAD1VVV8AAAAAPXwAAAAAD1VVVXwAAAAA98AAAAAA9VVVV8AAAAAPfAAAAAA9VVVVXwAAAAD3wAAAAAPVVVVV8AAAAA98AAAAAD1VVVVfAAAAAPfAAAAAD1VVVVXwAAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAA9VVVVV8AAAAA/wAAAAAPVVVVVfAAAAAPfAAAAAD1VVVVXwAAAAD3wAAAAA9VVVVXwAAAAA98AAAAAPVVVVV8AAAAAPfAAAAAA9VVVVfAAAAAPXwAAAAAPVVVVXwAAAAD1fAAAAAD1VVVXwAAAAA9XwAAAAAPVVVV8AAAAAPV8AAAAAD1VVV8AAAAAD1fAAAAAAPVVVfAAAAAD1V8AAAAAA9VVfAAAAAA9VfAAAAAAD1V/AAAAAAPVXwAAAAAAP//AAAAAAPVVfAAAAAAA/8AAAAAAD1VXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAA9VVVVVfAAAAAAAAAAAA9VVVVVV8AAAAAAAAAAA9VVVVVVX8AAAAAAAAAA9VVVVVVVfwAAAAAAAAA9VVVVVVVVfwAAAAAAAD9VVVVVVVVV/wAAAAAAP9VVVVVVVVVV////////1VVVVVVVVVVV///////VVVVVVA="},
+ {"width" : "55", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf1VVVVVVVVVVVV///////VVVVVVV/////////A//VVVV//////8AAAAAAD/VVf//8AAAAAAAAAAAD9Vf8AAAAAAAAAAAAAAPV/AAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAD3wAAAAAP/8AAAAAAAD1f8D//////wAAAAAAA9V//////VVfAAAAAAA9VVf1VVVVVXwAAAAAAPVVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAA9VVVVVVVVVXwAAAAAAPVVVVVVVVVV8AAAAAAD1VVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAA9VVVVVVVVVV8AAAAAAPVVVVVVVVVVfAAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVV//////1VVVVVVVVVVVX/////VVVVVVVVA"},
+ {"width" : "58", "buffer":"VVVVVVVVf//9VVVVVVVVVVVVVV//////1VVVVVVVVVVVX//AAAP/9VVVVVVVVVVf8AAAAAA/1VVVVVVVVV/wAAAAAAAP1VVVVVVVX/AAAAAAAAA/1VVVVVVX8AAAAAAAAAA/VVVVVVXwAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAD1VVVVXwAAAAAPwAAAAAPVVVVXwAAAAA//AAAAAA9VVVV8AAAAA/V8AAAAAPVVVV8AAAAA9VXwAAAAA9VVV8AAAAA9VVfAAAAAD1VVfAAAAAPVVV8AAAAA9VVfAAAAAPVVVXwAAAAD1VXwAAAAD1VVV8AAAAA9VV8AAAAA9VVVfAAAAAPVV8AAAAA9VVVXwAAAAA9VfAAAAAPVVVV8AAAAAPVXwAAAAD1VVVfAAAAAD1V8AAAAA9VVVV8AAAAA9V8AAAAAPVVVVfAAAAAPVfAAAAAD1VVVXwAAAAD1XwAAAAA9VVVV8AAAAA9V8AAAAAPVVVVfAAAAAPVfAAAAAD1VVVXwAAAAD1XwAAAAA9VVVXwAAAAA9V8AAAAAPVVVV8AAAAAPVfAAAAAD1VVVfAAAAAD1XwAAAAA9VVVXwAAAAA9V8AAAAAD1VVV8AAAAAPVXwAAAAA9VVV8AAAAAD1V8AAAAAD1VVfAAAAAD1VfAAAAAAPVVfAAAAAA9VXwAAAAAA9VfAAAAAAPVVfAAAAAAD//AAAAAAD1VXwAAAAAAP/AAAAAAD1VV8AAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VV8AAAAAAD/AAAAAAAPVV8AAAAAAP//AAAAAAA9VfAAAAAAP1X8AAAAAAPVfAAAAAAPVVXwAAAAAA9XwAAAAAPVVVfAAAAAAPV8AAAAAD1VVV8AAAAAD1fAAAAAD1VVVXwAAAAA9fAAAAAA9VVVV8AAAAAPXwAAAAA9VVVVXwAAAAA98AAAAAPVVVVV8AAAAAPfAAAAAD1VVVVfAAAAAD3wAAAAD1VVVVV8AAAAA98AAAAA9VVVVVfAAAAAPfAAAAAPVVVVVXwAAAAD3wAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD/AAAAAD1VVVVV8AAAAA/wAAAAA9VVVVVfAAAAAP8AAAAAPVVVVVXwAAAAD3wAAAAD1VVVVV8AAAAA98AAAAA9VVVVVfAAAAA9fAAAAAPVVVVVXwAAAAPXwAAAAD1VVVVV8AAAAD18AAAAA9VVVVV8AAAAA9fAAAAAPVVVVVfAAAAAPV8AAAAD1VVVVXwAAAAPVfAAAAAPVVVVV8AAAAD1XwAAAAD1VVVV8AAAAA9VfAAAAAPVVVVfAAAAA9VXwAAAAD1VVVfAAAAAPVVfAAAAAPVVVfAAAAAD1VXwAAAAA9VVXwAAAAD1VV8AAAAAD/VfwAAAAA9VVXwAAAAAP//wAAAAA9VVVfAAAAAAD/AAAAAAPVVVXwAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAP1VVVVVV/AAAAAAAAAAP1VVVVVVX/AAAAAAAAAPVVVVVVVVX/AAAAAAAD/VVVVVVVVVX/////////VVVVVVVVVVX///////1VVVVVA="},
+ {"width" : "61", "buffer":"VVVVVVVVV///1VVVVVVVVVVVVVVf//////1VVVVVVVVVVVX//8AAA//1VVVVVVVVVVf/AAAAAAA/1VVVVVVVVV/wAAAAAAAA/1VVVVVVVX/AAAAAAAAAA/VVVVVVVf8AAAAAAAAAAA9VVVVVVfwAAAAAAAAAAAD1VVVVV/AAAAAAAAAAAAAPVVVVV/AAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VV8AAAAAAA//AAAAAAAD1VfAAAAAAA///AAAAAAA9VfAAAAAAA9VX8AAAAAAPVXwAAAAAA9VVXwAAAAAA9V8AAAAAA9VVV8AAAAAAPV8AAAAAAPVVVXwAAAAAD1fAAAAAAPVVVVfAAAAAAPXwAAAAAD1VVVXwAAAAAD18AAAAAD1VVVV8AAAAAA9fAAAAAA9VVVVfAAAAAAPXwAAAAAPVVVVV8AAAAAD18AAAAAD1VVVVfAAAAAAPfAAAAAA9VVVVXwAAAAAD3wAAAAAPVVVVV8AAAAAA98AAAAAD1VVVVfAAAAAAPfAAAAAA9VVVVXwAAAAAD3wAAAAAPVVVVVfAAAAAA98AAAAAD1VVVVXwAAAAAPfAAAAAA9VVVVV8AAAAAD3wAAAAAD1VVVVfAAAAAA9fAAAAAA9VVVVXwAAAAAPXwAAAAAD1VVVV8AAAAAA98AAAAAAPVVVVfAAAAAAPfAAAAAAA9VVVfAAAAAAD18AAAAAAD/VX/AAAAAAA9fAAAAAAAP///AAAAAAAPXwAAAAAAAD/wAAAAAAAD1fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAPVVV/AAAAAAAAAAAAAAAD1VVX/AAAAAAAAAAAAAAA9VVVX/wAAAAAAAAAAAAAPVVVVX//AAAAAAAAAAAAD1VVVVV//////8AAAAAAA9VVVVVVX/////wAAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVV8AAAAAAPVVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVX//////VVVVVVVVVVVVVVf////9VA=="},
+ {"width" : "25", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////VVVX/////VVX8AAAD9VXwAAAAD1V8AAAAAPV8AAAAAA9fAAAAAAPXwAAAAAD18AAAAAAPfAAAAAAD3wAAAAAA98AAAAAAPfAAAAAAD18AAAAAD1fAAAAAA9V8AAAAA9VX8AAAD/VVf////9VVVf///1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/9VVVVV////VVVX/8AP/VVX8AAAD/VXwAAAAD9V8AAAAAPVfAAAAAA9fAAAAAAPXwAAAAAD18AAAAAA9fAAAAAAPXwAAAAAD18AAAAAA9XwAAAAAPV8AAAAAD1fAAAAAA9V8AAAAA/VX/AAAD/VVf////9VVVX///1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVA=="}
+ ]
+}
diff --git a/apps/contourclock/font-Nunito.json b/apps/contourclock/fonts/font-Nunito.json
similarity index 100%
rename from apps/contourclock/font-Nunito.json
rename to apps/contourclock/fonts/font-Nunito.json
diff --git a/apps/contourclock/font-OpenSansEC.json b/apps/contourclock/fonts/font-OpenSansEC.json
similarity index 100%
rename from apps/contourclock/font-OpenSansEC.json
rename to apps/contourclock/fonts/font-OpenSansEC.json
diff --git a/apps/contourclock/fonts/font-Oswald.json b/apps/contourclock/fonts/font-Oswald.json
new file mode 100644
index 000000000..97c61911c
--- /dev/null
+++ b/apps/contourclock/fonts/font-Oswald.json
@@ -0,0 +1,17 @@
+{
+ "name":"Oswald",
+ "size":"100",
+ "characters":[
+ {"width" : "54", "buffer":"VVVVVf//////9VVVVVVVVVX////////9VVVVVVVV/wAAAAAAD/1VVVVVVf8AAAAAAAAD9VVVVVV/AAAAAAAAAAPVVVVVXwAAAAAAAAAAD9VVVVfAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAA9XwAAAAAA//AAAAAAA9fAAAAAAD//wAAAAAA9fAAAAAAPVV8AAAAAA9fAAAAAA9VVfAAAAAAPfAAAAAA9VVXwAAAAAPfAAAAAD1VVXwAAAAAPfAAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVV8AAAAAP8AAAAAD1VVXwAAAAAPfAAAAAA9VVXwAAAAAPfAAAAAA9VVXwAAAAAPfAAAAAAPVVfAAAAAAPfAAAAAAD1V8AAAAAA9fAAAAAAA//wAAAAAA9XwAAAAAAP/AAAAAAA9XwAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAD1VVV8AAAAAAAAAAAAPVVVVfAAAAAAAAAAAA9VVVVX8AAAAAAAAAAD1VVVVV/AAAAAAAAAA/VVVVVVX8AAAAAAAAP9VVVVVVV/8AAAAAAD/VVVVVVVVX////////1VVVVVVVVVX//////9VVVVV"},
+ {"width" : "34", "buffer":"VVVVVV/////1VVVVV/////9VVVVX8AAAAPVVVVX8AAAAD1VVVfwAAAAA9VVV/wAAAAAPVVV/AAAAAAD1VX8AAAAAAA9Vf8AAAAAAAPV/wAAAAAAAD3/AAAAAAAAA/8AAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAAAAAAAAP8AAAAAAAAAD/AAAAAAAAAA/wAAPAAAAAAP8AA/8AAAAAD/AP/XwAAAAA/w/9V8AAAAAP//VVfAAAAAD/9VVXwAAAAA/1VVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVXwAAAAA9VVVV8AAAAAPVVVVfAAAAAD1VVVX//////9VVVV///////VVVVVVVVVVVQ=="},
+ {"width" : "55", "buffer":"VVVVVX///////1VVVVVVVVVf////////1VVVVVVVV/wAAAAAAA/1VVVVVVX/AAAAAAAAA/1VVVVVX8AAAAAAAAAA/VVVVVXwAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAA9V8AAAAAAD/wAAAAAAPV8AAAAAAP//AAAAAAD1fAAAAAAP1V8AAAAAAPXwAAAAAPVVXwAAAAAD3wAAAAAPVVVfAAAAAA98AAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAA98AAAAA9VVVV8AAAAAPfAAAAAPVVVVXwAAAAD/AAAAAD1VVVV8AAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVfAAAAAA/wAAAAA9VVVXwAAAAAP///////VVVV8AAAAAPf//////1VVV8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAA9VVVVVVVVVVfAAAAAA9VVVVVVVVVVfAAAAAAPVVVVVVVVVVfAAAAAAPVVVVVVVVVVXwAAAAAPVVVVVVVVVVXwAAAAAD1VVVVVVVVVXwAAAAAD1VVVVVVVVVV8AAAAAA9VVVVVVVVVV8AAAAAAD/////////1fAAAAAAAP////////9fAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAA9f/////////////////X/////////////////1VVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "54", "buffer":"VVVVVf//////9VVVVVVVVVf////////9VVVVVVVX/wAAAAAAD/1VVVVVVfwAAAAAAAAD9VVVVVX8AAAAAAAAAAP1VVVVfwAAAAAAAAAAD9VVVV8AAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAD1fAAAAAAA//AAAAAAA9fAAAAAAD//wAAAAAA9fAAAAAAPVV8AAAAAA9fAAAAAA9VVfAAAAAAP8AAAAAD1VVXwAAAAAP8AAAAAD1VVXwAAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP///////VVVV8AAAAAP///////VVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVXwAAAAD1VVVVVVVVVVfAAAAAD1VVVVVVVVVV8AAAAAPVVVVVVVVVVfwAAAAAPVVVVVVVX///AAAAAA9VVVVVVVf//wAAAAAD1VVVVVVVfAAAAAAAAP1VVVVVVVfAAAAAAAA/VVVVVVVVfAAAAAAAP1VVVVVVVVfAAAAAAA/VVVVVVVVVfAAAAAAD1VVVVVVVVVfAAAAAAA/VVVVVVVVVfAAAAAAAP9VVVVVVVVfAAAAAAAA/VVVVVVVVfAAAAAAAAD1VVVVVVVfAAAAAAAAA9VVVVVVVfAAAAAAAAA9VVVVVVVf//AAAAAAAPVVVVVVVX///AAAAAAD1VVVVVVVVV/wAAAAAD1VVVVVVVVVV8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAPVVVVVVVVVVV8AAAAAP//////9VVVV8AAAAAP///////VVVV8AAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVVfAAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAPVVVV8AAAAAP8AAAAAD1VVV8AAAAAPfAAAAAD1VVXwAAAAA9fAAAAAA9VVXwAAAAA9fAAAAAAPVV/AAAAAA9fAAAAAAD//8AAAAAA9XwAAAAAA//AAAAAAD1XwAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAA9VVVVfwAAAAAAAAAAD1VVVVX8AAAAAAAAAAPVVVVVVfwAAAAAAAAD9VVVVVVX/AAAAAAAD/1VVVVVVVf////////9VVVVVVVVV///////9VVVVV"},
+ {"width" : "59", "buffer":"VVVVVVVVX///////9VVVVVVVVVVVf///////1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVfAAAAAAAD1VVVVVVVVVV8AAAAAAAPVVVVVVVVVVfAAAAAAAA9VVVVVVVVVV8AAAAAAAD1VVVVVVVVVfAAAAAAAAPVVVVVVVVVV8AAAAAAAA9VVVVVVVVVXwAAAAAAAD1VVVVVVVVV8AAAAAAAAPVVVVVVVVVXwAAAAAAAA9VVVVVVVVV8AAAAAAAAD1VVVVVVVVXwAAAAAAAAPVVVVVVVVV8AAAAAAAAA9VVVVVVVVXwAAAAAAAAD1VVVVVVVVfAAAAAAAAAPVVVVVVVVXwAAAAAAAAA9VVVVVVVVfAAADAAAAAD1VVVVVVVXwAAA/AAAAAPVVVVVVVVfAAAPfAAAAA9VVVVVVVXwAAA98AAAAD1VVVVVVVfAAAPXwAAAAPVVVVVVVV8AAA9fAAAAA9VVVVVVVfAAAD18AAAAD1VVVVVVV8AAA9XwAAAAPVVVVVVVfAAAD1fAAAAA9VVVVVVV8AAAPV8AAAAD1VVVVVVXwAAD1XwAAAAPVVVVVVV8AAAPVfAAAAA9VVVVVVXwAAD1V8AAAAD1VVVVVV8AAAPVXwAAAAPVVVVVVXwAAA9VfAAAAA9VVVVVV8AAAPVV8AAAAD1VVVVVXwAAA9VXwAAAAPVVVVVVfAAAD1VfAAAAA9VVVVVXwAAA9VV8AAAAD1VVVVVfAAAD1VXwAAAAPVVVVVXwAAAPVVfAAAAA9VVVVVfAAAD1VV8AAAAD1VVVVV8AAAPVVXwAAAAPVVVVVfAAAD1VVfAAAAA9VVVVV8AAAPVVV8AAAAD1VVVVfAAAA9VVXwAAAAPVVVVV8AAAPVVVfAAAAA9VVVVfAAAA9VVV8AAAAD1VVVV8AAAD1VVXwAAAAPVVVVXwAAA9VVVfAAAAA9VVVV8AAAD1VVV8AAAAD1VVVXwAAAPVVVXwAAAAPVVVV8AAAD1VVVfAAAAA9VVVXwAAAPVVVV8AAAAD1VVVfAAAA9VVVXwAAAAPVVVXwAAAPVVVVfAAAAA9VVVfAAAA9VVVV8AAAAD1VVXwAAAPVVVVXwAAAAPVVVfAAAA9VVVVfAAAAA9VVXwAAAA/////wAAAAA////AAAAA////8AAAAAA///8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAP//////////AAAAAAD/////////////AAAAAA///1VVVVVVVVVfAAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVV//////1VVVVVVVVVVVVX//////VVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "54", "buffer":"V///////////////1VV///////////////1VV8AAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VXwAAAAD/////////1VXwAAAAP/////////1VXwAAAA9VVVVVVVVVVVXwAAAA9VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VVVVVVVVVVVXwAAAD1VX///9VVVVVXwAAAD1X/////9VVVVXwAAAD1/8AAAD/1VVVfAAAAA/8AAAAAD9VVVfAAAAAPAAAAAAAPVVVfAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAPVfAAAAAAA/8AAAAAAPVfAAAAAAP//wAAAAAPVfAAAAAA/VX8AAAAAD1fAAAAAD1VVfAAAAAD1fAAAAAPVVVfAAAAAD1fAAAAAPVVVXwAAAAD1fAAAAA9VVVXwAAAAA9fAAAAA9VVVV8AAAAA9fAAAAA9VVVV8AAAAA9f/////1VVVV8AAAAA9f/////1VVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVV8AAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAAPVVVVVVVVVVVfAAAAA9VVVVVVVVVVVfAAAAA9///////VVVVfAAAAA9///////VVVVfAAAAA98AAAAAPVVVVfAAAAA98AAAAAPVVVVfAAAAA98AAAAAPVVVVfAAAAA98AAAAAPVVVV8AAAAA98AAAAAPVVVV8AAAAA9fAAAAAPVVVV8AAAAA9fAAAAAPVVVV8AAAAA9fAAAAAPVVVV8AAAAA9fAAAAAPVVVV8AAAAD1fAAAAAD1VVXwAAAAD1fAAAAAD1VVXwAAAAD1fAAAAAA9VVfAAAAAD1XwAAAAAPVV8AAAAAPVXwAAAAAD//wAAAAAPVXwAAAAAA//AAAAAAPVV8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAA9VVVVfAAAAAAAAAAAD1VVVVXwAAAAAAAAAA/VVVVVV/AAAAAAAAAP9VVVVVVf8AAAAAAAD/VVVVVVVV/////////1VVVVVVVVX///////9VVVVV"},
+ {"width" : "55", "buffer":"VVVVVf///////VVVVVVVVVV/////////1VVVVVVVX/AAAAAAAD/1VVVVVVf8AAAAAAAAA/VVVVVVfwAAAAAAAAAA9VVVVVfAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAPVVfAAAAAAD/wAAAAAA9VXwAAAAAD//wAAAAAPVXwAAAAAD1V/AAAAAD1V8AAAAAD1VV8AAAAA9VfAAAAAD1VVfAAAAAPVfAAAAAA9VVXwAAAAA9XwAAAAAPVVVfAAAAAPV8AAAAAPVVVXwAAAAD1fAAAAAD1VVV8AAAAA9XwAAAAA9VVVfAAAAAPV8AAAAAPVVVXwAAAAD18AAAAAD1VVV8AAAAA9fAAAAAA9VVVf//////XwAAAAAPVVVV//////V8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAAPVVVVVVVVVVV8AAAAAD1VVVVVVVVVVfAAAAAA9VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VV///1VVVVXwAAAAA9Vf////9VVVV8AAAAAPV/8AAA/9VVVfAAAAAD1/AAAAAP9VVXwAAAAAP8AAAAAAP1VV8AAAAAA8AAAAAAAPVVfAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAD18AAAAAAAD8AAAAAAA9fAAAAAAAP/8AAAAAAPXwAAAAAAP1fwAAAAAD18AAAAAAPVVfAAAAAAPfAAAAAAPVVV8AAAAAD3wAAAAAPVVVfAAAAAA98AAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAAP8AAAAAPVVVV8AAAAAD/AAAAAD1VVVfAAAAAA/wAAAAA9VVVXwAAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAA9VVVXwAAAAD3wAAAAAPVVVV8AAAAA98AAAAAD1VVV8AAAAAPXwAAAAA9VVVfAAAAAD18AAAAAPVVVXwAAAAA9fAAAAAD1VVV8AAAAAPXwAAAAA9VVVfAAAAAD18AAAAAD1VVXwAAAAD1XwAAAAA9VVXwAAAAA9V8AAAAAPVVV8AAAAAPVfAAAAAA9VV8AAAAAD1V8AAAAAD1V8AAAAAD1VfAAAAAAP/8AAAAAA9VV8AAAAAA/8AAAAAA9VVfAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAD1VVVfAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAA9VVVVXwAAAAAAAAAAA9VVVVVfwAAAAAAAAAA9VVVVVV/AAAAAAAAAD9VVVVVVV/AAAAAAAAP9VVVVVVVX/wAAAAAA/1VVVVVVVVX////////VVVVVVVVVVV//////9VVVVVQ=="},
+ {"width" : "48", "buffer":"f///////////////////////////////8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP8AAAAAAAAAAAAAAP/////////AAAAAAP/////////wAAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAAPVVVVVVVVV8AAAAA9VVVVVVVVV8AAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAA9VVVVVVVVXwAAAAD1VVVVVVVVXwAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAD1VVVVVVVVfAAAAAPVVVVVVVVVfAAAAAPVVVVVVVVV///////VVVVVVVVV///////VVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "55", "buffer":"VVVVVX//////9VVVVVVVVVV////////9VVVVVVVVX/wAAAAAAP9VVVVVVVX8AAAAAAAAP9VVVVVVXwAAAAAAAAAP1VVVVVXwAAAAAAAAAAPVVVVVXwAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAPVVfAAAAAAD/wAAAAAD1VXwAAAAAD//AAAAAAPVV8AAAAAD1V8AAAAAD1VfAAAAAD1VXwAAAAA9VfAAAAAD1VV8AAAAAPVXwAAAAA9VVXwAAAAD1V8AAAAA9VVV8AAAAAPVfAAAAAPVVVXwAAAAD1XwAAAAD1VVV8AAAAA9V8AAAAA9VVVfAAAAAPVfAAAAA9VVVXwAAAAD1XwAAAAPVVVV8AAAAA9V8AAAAD1VVVfAAAAAPVfAAAAA9VVVXwAAAAD1XwAAAAPVVVV8AAAAA9V8AAAAD1VVVfAAAAAPVfAAAAAPVVVXwAAAAD1XwAAAAD1VVV8AAAAA9V8AAAAA9VVVfAAAAA9VfAAAAAPVVVXwAAAAPVV8AAAAD1VVXwAAAAD1VfAAAAA9VVV8AAAAA9VXwAAAAD1VVfAAAAAPVV8AAAAA9VVfAAAAAPVVXwAAAAD1VXwAAAAD1VV8AAAAAPVXwAAAAD1VVXwAAAAA/fwAAAAA9VVV8AAAAAD/wAAAAA9VVVXwAAAAADAAAAAAPVVVVfAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAPVVVVVfAAAAAAAAAAAD1VVVVV8AAAAAAAAAAD1VVVVVXwAAAAAAAAAD1VVVVVVfAAAAAAAAAD1VVVVVV/AAAAAAAAAAP1VVVVV/AAAAAAAAAAA/VVVVV8AAAAAAAAAAAA9VVVV8AAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAD1VVfAAAAAADwAAAAAAPVVfAAAAAAP/8AAAAAA9VXwAAAAAP1/wAAAAAPVXwAAAAAPVVfAAAAAD1V8AAAAAPVVV8AAAAAPVfAAAAAD1VVfAAAAAD1fAAAAAD1VVV8AAAAA9XwAAAAA9VVVfAAAAAD18AAAAAPVVVXwAAAAA9fAAAAAPVVVV8AAAAAPXwAAAAD1VVVXwAAAAD3wAAAAA9VVVV8AAAAA98AAAAAPVVVVfAAAAAPfAAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAD/AAAAAD1VVVXwAAAAA/wAAAAA9VVVV8AAAAAP8AAAAAPVVVVfAAAAAPfAAAAAD1VVVXwAAAAD18AAAAA9VVVV8AAAAA9fAAAAAPVVVV8AAAAAPXwAAAAA9VVVfAAAAAD18AAAAAPVVVXwAAAAA9fAAAAAD1VVXwAAAAAPV8AAAAAPVVV8AAAAAPVfAAAAAD1VV8AAAAAD1XwAAAAAP1V8AAAAAA9V8AAAAAA//8AAAAAA9VXwAAAAAA/8AAAAAAPVV8AAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAPVVVVV/AAAAAAAAAAA/VVVVVX8AAAAAAAAAA/VVVVVVX8AAAAAAAAD9VVVVVVVf/AAAAAAA/9VVVVVVVVf////////1VVVVVVVVVX//////9VVVVVQ=="},
+ {"width" : "55", "buffer":"VVVVVX//////9VVVVVVVVVV/////////VVVVVVVVV/wAAAAAAP/VVVVVVVX8AAAAAAAAD9VVVVVVX8AAAAAAAAAD9VVVVVXwAAAAAAAAAAP1VVVVXwAAAAAAAAAAAPVVVVXwAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAD1VXwAAAAAD/8AAAAAA9VXwAAAAAD//wAAAAAD1V8AAAAAD1VfAAAAAA9VfAAAAAD1VV8AAAAAPVfAAAAAD1VVfAAAAAA9XwAAAAA9VVV8AAAAAPV8AAAAAPVVVfAAAAAD1fAAAAAPVVVXwAAAAA9fAAAAAD1VVV8AAAAAPXwAAAAA9VVVXwAAAAA98AAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAA98AAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAA98AAAAAPVVVV8AAAAAP8AAAAAD1VVVfAAAAAD/AAAAAA9VVVXwAAAAA/wAAAAAPVVVV8AAAAAP8AAAAAD1VVVfAAAAAD/AAAAAA9VVVXwAAAAA/wAAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAA98AAAAAPVVVV8AAAAAPfAAAAAD1VVVfAAAAAD3wAAAAA9VVVXwAAAAA98AAAAAD1VVV8AAAAAPfAAAAAA9VVVfAAAAAD3wAAAAAPVVVfAAAAAA9fAAAAAA9VVfAAAAAAPXwAAAAAD1VfAAAAAAD18AAAAAAP//AAAAAAA9fAAAAAAA//AAAAAAAPV8AAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAPVVXwAAAAAADwAAAAAD1VVfwAAAAAD/AAAAAA9VVV/wAAAA/18AAAAAPVVVV//wA//1fAAAAAD1VVVV////9VXwAAAAA9VVVVVV/9VVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1VVVVVVVVVVXwAAAAA9VVVVVVVVVVV8AAAAAPVVVVVVVVVVVfAAAAAD1f/////9VVVXwAAAAA9f//////VVVV8AAAAAPXwAAAAD1VVVfAAAAAD18AAAAA9VVVfAAAAAA9fAAAAAPVVVXwAAAAA9V8AAAAD1VVV8AAAAAPVfAAAAA9VVVfAAAAAD1XwAAAAD1VVXwAAAAA9V8AAAAA9VVV8AAAAAPVfAAAAAPVVV8AAAAAPVXwAAAAA9VV8AAAAAD1V8AAAAAD9V8AAAAAA9VfAAAAAAP/8AAAAAAPVV8AAAAAAP8AAAAAAPVVfAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAPVVVVVX8AAAAAAAAAA/VVVVVVf8AAAAAAAAD/VVVVVVVf/AAAAAAA/9VVVVVVVVf////////1VVVVVVVVVX//////9VVVVVQ=="},
+ {"width" : "18", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////////////8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP////////////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV////////////8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP8AAAAP//////f/////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"}
+ ]
+}
diff --git a/apps/contourclock/font-Phosphate.json b/apps/contourclock/fonts/font-Phosphate.json
similarity index 100%
rename from apps/contourclock/font-Phosphate.json
rename to apps/contourclock/fonts/font-Phosphate.json
diff --git a/apps/contourclock/font-Quicksand.json b/apps/contourclock/fonts/font-Quicksand.json
similarity index 100%
rename from apps/contourclock/font-Quicksand.json
rename to apps/contourclock/fonts/font-Quicksand.json
diff --git a/apps/contourclock/fonts/font-RubikOne.json b/apps/contourclock/fonts/font-RubikOne.json
new file mode 100644
index 000000000..1077ad566
--- /dev/null
+++ b/apps/contourclock/fonts/font-RubikOne.json
@@ -0,0 +1,17 @@
+{
+ "name":"Rubik One",
+ "size":"100",
+ "characters":[
+ {"width" : "57", "buffer":"VVVVVVX/////9VVVVVVVVVVVX///////1VVVVVVVVVVf8AAAAAD/VVVVVVVVVX8AAAAAAAP9VVVVVVVVfwAAAAAAAA/VVVVVVVV8AAAAAAAAAD1VVVVVVXwAAAAAAAAAA9VVVVVV/AAAAAAAAAAAPVVVVVV8AAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAA9fAAAAAAAA/wAAAAAAA9fAAAAAAAD/8AAAAAAAPfAAAAAAAPVfAAAAAAAPfAAAAAAA9VXwAAAAAAPfAAAAAAD1VXwAAAAAAP8AAAAAAD1VXwAAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAPVVV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VV8AAAAAAP8AAAAAAD1VXwAAAAAAPfAAAAAAD1VXwAAAAAAPfAAAAAAA9VXwAAAAAAPfAAAAAAAPVfAAAAAAAPfAAAAAAAD/8AAAAAAAPfAAAAAAAA/wAAAAAAA9fAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAPVVVVVVfAAAAAAAAAAA9VVVVVVXwAAAAAAAAAD9VVVVVVV/AAAAAAAAAPVVVVVVVVfwAAAAAAAD9VVVVVVVVV/wAAAAAA/1VVVVVVVVVf///////9VVVVVVVVVVVf//////VVVVVV"},
+ {"width" : "45", "buffer":"VVVVVVVV//////1VVVVVVVX//////9VVVVVVVfAAAAAAPVVVVVVV8AAAAAAPVVVVVVXwAAAAAAPVVVVVVXwAAAAAAPVVVVVVfAAAAAAAPVVVVVV8AAAAAAAPVVVVVXwAAAAAAAPVVVVVXwAAAAAAAPVVVVV/AAAAAAAAPVVVVV8AAAAAAAAPVVVVXwAAAAAAAAPVVVVfAAAAAAAAAPVVVV8AAAAAAAAAPVVVXwAAAAAAAAAPVVVXwAAAAAAAAAPVVVfAAAAAAAAAAPVVV8AAAAAAAAAAPVVXwAAAAAAAAAAPVVfAAAAAAAAAAAPVVfAAAAAAAAAAAPVX8AAAAAAAAAAAPVXwAAAAAAAAAAAPVfAAAAAAAAAAAAPV8AAAAAAAAAAAAPXwAAAAAAAAAAAAPfAAAAAAAAAAAAAPfAAAAAAAAAAAAAP8AAAAAAAAAAAAAP8AAAAAAAAAAAAAP8AAAAAAAAAAAAAP8AAAAAAAAAAAAAP8AAAAAAAAAAAAAPfAAAAAAAAAAAAAPfAAAAAAAAAAAAAPfAAAAAAAAAAAAAPXwAAAAAAAAAAAAPV8AAAAAAAAAAAAPV8AAAAAwAAAAAAPV8AAAAD8AAAAAAPVfAAAAPfAAAAAAPVfAAAA9fAAAAAAPVXwAAD1fAAAAAAPVV8AAPVfAAAAAAPVV8AAPVfAAAAAAPVV8AA9VfAAAAAAPVVfAD1VfAAAAAAPVVXwPVVfAAAAAAPVVXw9VVfAAAAAAPVVX/1VVfAAAAAAPVVV/1VVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVfAAAAAAPVVVVVVVX///////VVVVVVVX//////1"},
+ {"width" : "58", "buffer":"VVVVVVf//////1VVVVVVVVVVV////////1VVVVVVVVVX/AAAAAAA/1VVVVVVVVX8AAAAAAAA/VVVVVVVVXwAAAAAAAAA9VVVVVVVfwAAAAAAAAAD1VVVVVVXwAAAAAAAAAAPVVVVVVXwAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VfAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVfAAAAAAAD/AAAAAAAD1XwAAAAAAD/8AAAAAAA9XwAAAAAAD1XwAAAAAAPV8AAAAAAD1V8AAAAAAD1fAAAAAAA9VfAAAAAAA9XwAAAAAA9VXwAAAAAAPV8AAAAAAPVV8AAAAAAD1fAAAAAAD1VfAAAAAAA9XwAAAAAD1VXwAAAAAAPV8AAAAAA9VV8AAAAAAD1X///////VVfAAAAAAA9V//////9VVXwAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVfAAAAAAAD1VVVVVVVVVfAAAAAAAD1VVVVVVVVVfAAAAAAAA9VVVVVVVVVfAAAAAAAAPVVVVVVVVVXwAAAAAAAPVVVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAA9VVVVVVVXwAAAAAAAAAD//////VXwAAAAAAAAAAP/////9V8AAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAD1//////////////////9f/////////////////9Q=="},
+ {"width" : "59", "buffer":"VV///////////////9VVV////////////////9VVXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VVf///////wAAAAAAAPVVVf///////wAAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVX8AAAAAAD1VVVVVVVVVV/AAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVfwAAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVV/AAAAAAAPVVVVVVVVVVfwAAAAAAA9VVVVVVVVVV8AAAAAAAA9VVVVVVVVVXwAAAAAAAA/VVVVVVVVV8AAAAAAAAA/1VVVVVVVXwAAAAAAAAAP1VVVVVVVfAAAAAAAAAAD1VVVVVVV8AAAAAAAAAAD1VVVVVVXwAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAPVVVVVVXwAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAPVVVVVX/////wAAAAAAA9VVVVVX/////wAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVfAAAAAAD3//////9VVVV8AAAAAAP///////9VVVfAAAAAAA/wAAAAAA9VVV8AAAAAAD/AAAAAAA9VVfAAAAAAAP8AAAAAAA///wAAAAAAA/wAAAAAAA//8AAAAAAAD/AAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAD9VVVVVV8AAAAAAAAAAA/VVVVVVV/AAAAAAAAAAPVVVVVVVV/wAAAAAAAA/1VVVVVVVVf8AAAAAAA/9VVVVVVVVVX////////1VVVVVVVVVVV///////1VVVVVU="},
+ {"width" : "62", "buffer":"VVVVVVVVVX//////9VVVVVVVVVVVVV///////9VVVVVVVVVVVVfAAAAAAD1VVVVVVVVVVVXwAAAAAAD1VVVVVVVVVVVfAAAAAAAPVVVVVVVVVVVXwAAAAAAA9VVVVVVVVVVVfAAAAAAAD1VVVVVVVVVVXwAAAAAAAPVVVVVVVVVVVfAAAAAAAA9VVVVVVVVVVXwAAAAAAAD1VVVVVVVVVVfAAAAAAAAPVVVVVVVVVVXwAAAAAAAA9VVVVVVVVVVfAAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVfAAAAAAAAAPVVVVVVVVVXwAAAAAAAAA9VVVVVVVVVfAAAAAAAAAD1VVVVVVVVXwAAAAAAAAAPVVVVVVVVVfAAAAAAAAAA9VVVVVVVVV8AAAAAAAAAD1VVVVVVVVfAAAAAAAAAAPVVVVVVVVXwAAAAAAAAAA9VVVVVVVVfAAAAAAAAAAD1VVVVVVVV8AAAAAAAAAAPVVVVVVVVfAAAAAAAAAAA9VVVVVVVXwAAAAAAAAAAD1VVVVVVVfAAAAAAAAAAAPVVVVVVVV8AAAAAAAAAAA9VVVVVVVfAAAAAAAAAAAD1VVVVVVV8AAAAAAAAAAAPVVVVVVVfAAAAAAAAAAAA9VVVVVVV8AAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAPVVVVVVV8AAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAAPVVVVVVfAAAAAAwAAAAAA9VVVVVV8AAAAAPwAAAAAD1VVVVVfAAAAAD3wAAAAAPVVVVVV8AAAAAPfAAAAAA9VVVVVfAAAAAD18AAAAAD1VVVVV8AAAAAPXwAAAAAPVVVVVfAAAAAD1fAAAAAA9VVVVV8AAAAAPV8AAAAAD1VVVVfAAAAAD1XwAAAAAPVVVVV8AAAAAPVfAAAAAA9VVVVfAAAAAD1V8AAAAAD1VVVV8AAAAAPVXwAAAAAPVVVVfAAAAAA9VfAAAAAA9VVVV8AAAAAPVV8AAAAAD1VVVfAAAAAA9VXwAAAAAPVVVV8AAAAAPVVfAAAAAA9VVVfAAAAAA9VV8AAAAAD1VVV8AAAAAPVVXwAAAAAD///XwAAAAAP//8AAAAAAD///8AAAAAAP//AAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA9/////////wAAAAAAA///3/////////wAAAAAAP//9VVVVVVVVVXwAAAAAD1VVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVfAAAAAA9VVVVVVVVVVVVV8AAAAAD1VVVVVVVVVVVVXwAAAAAPVVVVVVVVVVVVVf//////1VVVVVVVVVVVVVf/////9VVVU="},
+ {"width" : "59", "buffer":"VVVf/////////////1VVVVX//////////////1VVVV8AAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAD1VVV8AAAAAP////////9VVVXwAAAAD/////////1VVVfAAAAA9VVVVVVVVVVVVV8AAAAD1VVVVVVVVVVVVXwAAAAPVVVVVVVVVVVVVfAAAAA9VVVVVVVVVVVVXwAAAAD1V///9VVVVVVVfAAAAAPV/////VVVVVVV8AAAAA9fwAAA/1VVVVVXwAAAAD3wAAAAP1VVVVVfAAAAAD8AAAAAD9VVVVV8AAAAADAAAAAAD9VVVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAPVV8AAAAAAA/AAAAAAAAPVXwAAAAAAP/AAAAAAAA9VfAAAAAAP1fAAAAAAAD1V8AAAAAD9VfAAAAAAAPVV//////9VVfAAAAAAA9VV//////VVVfAAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVVfAAAAAAD1VVVVVVVVVVV8AAAAAAPX//////9VVVXwAAAAAA9///////9VVV8AAAAAAD3wAAAAAA9VVXwAAAAAAP8AAAAAAD1VVfAAAAAAA/wAAAAAAD1VXwAAAAAAD/AAAAAAAPVVfAAAAAAAPfAAAAAAAP//wAAAAAAD18AAAAAAAP/8AAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAA9VVVVV8AAAAAAAAAAAAPVVVVVV8AAAAAAAAAAAD9VVVVVV8AAAAAAAAAAA9VVVVVVV/AAAAAAAAAAPVVVVVVVV/wAAAAAAAAP1VVVVVVVVf8AAAAAAAP9VVVVVVVVVX////////9VVVVVVVVVVV///////9VVVVVU="},
+ {"width" : "59", "buffer":"VVVVVVVVX//////VVVVVVVVVVVVV///////1VVVVVVVVVVV/AAAAAAPVVVVVVVVVVVXwAAAAAA9VVVVVVVVVVV8AAAAAAD1VVVVVVVVVVXwAAAAAAPVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVV8AAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAD1VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAAP1VVVVVVVVVfAAAAAAAAP/VVVVVVVVXwAAAAAAAAD/VVVVVVVVfAAAAAAAAAAP1VVVVVVXwAAAAAAAAAAP1VVVVVVfAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAA/8AAAAAAAD18AAAAAAAP/8AAAAAAAPfAAAAAAAD1V8AAAAAAA98AAAAAAA9VV8AAAAAAA/wAAAAAAPVVV8AAAAAAD/AAAAAAA9VVXwAAAAAAP8AAAAAAPVVVXwAAAAAA/wAAAAAA9VVVfAAAAAAD/AAAAAAD1VVV8AAAAAAP8AAAAAAPVVVXwAAAAAA/wAAAAAA9VVVfAAAAAAD/AAAAAAD1VVV8AAAAAAP8AAAAAAPVVVXwAAAAAA/wAAAAAA9VVVfAAAAAAD/AAAAAAD1VVV8AAAAAAP8AAAAAAD1VVfAAAAAAA/wAAAAAAD1VXwAAAAAAPfAAAAAAAD1V8AAAAAAA98AAAAAAAD//AAAAAAAD3wAAAAAAAD/wAAAAAAAPXwAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAPVVVVVVVfAAAAAAAAAAD1VVVVVVVfwAAAAAAAAD9VVVVVVVVf8AAAAAAAA/VVVVVVVVVX/AAAAAAD/VVVVVVVVVVV////////1VVVVVVVVVVVf//////VVVVVVU="},
+ {"width" : "52", "buffer":"X///////////////9X////////////////3wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAD3////////wAAAAAAD1/////////AAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVV8AAAAAAPVVVVVVVVV8AAAAAAD1VVVVVVVVfAAAAAAD1VVVVVVVVXwAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVXwAAAAAAPVVVVVVVVV8AAAAAAPVVVVVVVVVfAAAAAAD1VVVVVVVVfAAAAAAA9VVVVVVVVV8AAAAAA9VVVVVVVVVf//////9VVVVVVVVVV//////9VVVVVVVQ=="},
+ {"width" : "58", "buffer":"VVVVVV///////VVVVVVVVVVVX////////VVVVVVVVVVf8AAAAAAD/VVVVVVVVV/wAAAAAAAD9VVVVVVVV/AAAAAAAAAD9VVVVVVV8AAAAAAAAAAP1VVVVVV8AAAAAAAAAAAPVVVVVV8AAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAA9VfAAAAAAA//wAAAAAAPVXwAAAAAA///AAAAAAD1V8AAAAAA9VV8AAAAAA9VfAAAAAA9VVXwAAAAAPVXwAAAAAPVVV8AAAAAD1V8AAAAAD1VVfAAAAAA9VfAAAAAA9VVV8AAAAAPVXwAAAAA9VVVfAAAAAD1V8AAAAAD1VVXwAAAAA9VfAAAAAA9VVXwAAAAAPVXwAAAAAPVVV8AAAAAD1V8AAAAAD1VVfAAAAAA9VfAAAAAAPVVfAAAAAAPVXwAAAAAD1VfAAAAAAPVVfAAAAAAP1fAAAAAAD1VXwAAAAAA//AAAAAAA9VV8AAAAAAA/AAAAAAAPVVfAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAA98AAAAAAAD/8AAAAAAAPfAAAAAAAP//wAAAAAAD3wAAAAAAP1VfAAAAAAA98AAAAAAPVVV8AAAAAAD/AAAAAAD1VVfAAAAAAA/wAAAAAD1VVV8AAAAAAP8AAAAAA9VVVfAAAAAAD/AAAAAAPVVVXwAAAAAA/wAAAAAD1VVV8AAAAAAP8AAAAAA9VVVfAAAAAAD/AAAAAAPVVVXwAAAAAA/wAAAAAD1VVV8AAAAAAP8AAAAAA9VVVfAAAAAAD/AAAAAAD1VVfAAAAAAA/wAAAAAAPVVXwAAAAAA98AAAAAAA9VfwAAAAAAPfAAAAAAAD//wAAAAAAD3wAAAAAAAP/AAAAAAAA98AAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAD1VVVVVVX/AAAAAAAAA/1VVVVVVVf/AAAAAAAD/1VVVVVVVVX////////9VVVVVVVVVVX///////1VVVVVQ=="},
+ {"width" : "58", "buffer":"VVVVVVf/////9VVVVVVVVVVVV////////VVVVVVVVVVX/AAAAAAP/VVVVVVVVVX8AAAAAAAD/VVVVVVVVfwAAAAAAAAD9VVVVVVVfwAAAAAAAAAD1VVVVVVfAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAD3wAAAAAAAP/AAAAAAAA98AAAAAAAP/8AAAAAAAPfAAAAAAAPVXwAAAAAAD3wAAAAAAPVVfAAAAAAAP8AAAAAAPVVV8AAAAAAD/AAAAAAD1VVfAAAAAAA/wAAAAAA9VVV8AAAAAAP8AAAAAAPVVVfAAAAAAD/AAAAAAPVVVXwAAAAAA/wAAAAAD1VVV8AAAAAAP8AAAAAA9VVVfAAAAAAD/AAAAAAPVVVXwAAAAAA/wAAAAAA9VVV8AAAAAAP8AAAAAAPVVV8AAAAAAD/AAAAAAD1VVfAAAAAAA/wAAAAAAPVVXwAAAAAA98AAAAAAD1VXwAAAAAAPfAAAAAAAPVXwAAAAAAD3wAAAAAAA//wAAAAAAA98AAAAAAAD/wAAAAAAAPfAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAA9VVVVV/AAAAAAAAAAAA9VVVVVX8AAAAAAAAAAA9VVVVVVX8AAAAAAAAAAPVVVVVVVfwAAAAAAAAAD1VVVVVVVfwAAAAAAAAD1VVVVVVVV/8AAAAAAAA9VVVVVVVVV/wAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAAPVVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAAPVVVVVVVVVVXwAAAAAAD1VVVVVVVVVV8AAAAAAD1VVVVVVVVVVfAAAAAAA9VVVVVVVVVVXwAAAAAA9VVVVVVVVVVVf//////9VVVVVVVVVVVX//////9VVVVVVVVQ=="},
+ {"width" : "20", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/////////////8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA9//////1/////9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/////////////wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD/AAAAAP8AAAAA/wAAAAD///////f/////8="}
+ ]
+}
diff --git a/apps/contourclock/font-SairaEC.json b/apps/contourclock/fonts/font-SairaEC.json
similarity index 99%
rename from apps/contourclock/font-SairaEC.json
rename to apps/contourclock/fonts/font-SairaEC.json
index ec3f6c990..7ba7fec3d 100644
--- a/apps/contourclock/font-SairaEC.json
+++ b/apps/contourclock/fonts/font-SairaEC.json
@@ -1,5 +1,5 @@
{
- "name":"SairaEC",
+ "name":"Saira EC",
"size":"100",
"characters":[
{"width" : "51", "buffer":"VVVVf///////9VVVVVVVf/////////1VVVVVV/wAAAAAAAD/VVVVVfwAAAAAAAAAP1VVVV/AAAAAAAAAAA9VVVV8AAAAAAAAAAAPVVVXwAAAAAAAAAAAPVVVfAAAAAAAAAAAAD1VVfAAAAAAAAAAAAA9VV8AAAAAAAAAAAAA9VV8AAAAAAAAAAAAAPVXwAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAA9fAAAAAAA/AAAAAAA9fAAAAAAD/wAAAAAA9fAAAAAAPV8AAAAAA98AAAAAA9V8AAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAAP8AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAD1VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9VfAAAAAA98AAAAAA9V8AAAAAA9fAAAAAAPXwAAAAAA9fAAAAAAD/AAAAAAA9fAAAAAAA8AAAAAAA9fAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAPVV8AAAAAAAAAAAAA9VVfAAAAAAAAAAAAA9VVfAAAAAAAAAAAAD1VVXwAAAAAAAAAAAD1VVV8AAAAAAAAAAAPVVVV/AAAAAAAAAAD9VVVVfwAAAAAAAAAP1VVVVV/wAAAAAAAP9VVVVVVf/////////1VVVVVVVf///////1VVVV"},
diff --git a/apps/contourclock/font-Teko.json b/apps/contourclock/fonts/font-Teko.json
similarity index 100%
rename from apps/contourclock/font-Teko.json
rename to apps/contourclock/fonts/font-Teko.json
diff --git a/apps/contourclock/fonts/font-TitanOne.json b/apps/contourclock/fonts/font-TitanOne.json
new file mode 100644
index 000000000..147d9624b
--- /dev/null
+++ b/apps/contourclock/fonts/font-TitanOne.json
@@ -0,0 +1,17 @@
+{
+ "name":"Titan One",
+ "size":"100",
+ "characters":[
+ {"width" : "74", "buffer":"VVVVVVVVX///////VVVVVVVVVVVVVVVVf////////9VVVVVVVVVVVVVV//AAAAAAAP/1VVVVVVVVVVVV/8AAAAAAAAA/9VVVVVVVVVVV/wAAAAAAAAAAD/VVVVVVVVVVfwAAAAAAAAAAAA/VVVVVVVVVfwAAAAAAAAAAAAAP1VVVVVVVX8AAAAAAAAAAAAAAP1VVVVVVV8AAAAAAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAPAAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VXwAAAAAAAAA9fAAAAAAAAAD1VfAAAAAAAAAPVfAAAAAAAAAPVV8AAAAAAAAA9V8AAAAAAAAA9VXwAAAAAAAAD1V8AAAAAAAAD1V8AAAAAAAAA9VXwAAAAAAAAD1XwAAAAAAAAD1VfAAAAAAAAAPVfAAAAAAAAAPVV8AAAAAAAAA9V8AAAAAAAAA9VXwAAAAAAAAD1XwAAAAAAAAD1VfAAAAAAAAAD18AAAAAAAAAPVV8AAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9fAAAAAAAAAPVVXwAAAAAAAAD18AAAAAAAAA9VVfAAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9fAAAAAAAAAPVVXwAAAAAAAAD18AAAAAAAAA9VVfAAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9fAAAAAAAAAPVVXwAAAAAAAAA98AAAAAAAAA9VVfAAAAAAAAAD3wAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA/wAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA/wAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA/wAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA/wAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA/wAAAAAAAAA9VVfAAAAAAAAAD/AAAAAAAAAD1VV8AAAAAAAAAP8AAAAAAAAAPVVXwAAAAAAAAA98AAAAAAAAA9VVfAAAAAAAAAD3wAAAAAAAAD1VV8AAAAAAAAAPfAAAAAAAAAPVVXwAAAAAAAAA98AAAAAAAAA9VVfAAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9fAAAAAAAAAPVVXwAAAAAAAAD18AAAAAAAAA9VVfAAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9fAAAAAAAAAPVVXwAAAAAAAAD18AAAAAAAAA9VVfAAAAAAAAAPXwAAAAAAAAD1VV8AAAAAAAAA9XwAAAAAAAAD1VfAAAAAAAAAD1fAAAAAAAAAPVV8AAAAAAAAA9V8AAAAAAAAA9VXwAAAAAAAAD1XwAAAAAAAAD1VfAAAAAAAAAPVfAAAAAAAAAPVV8AAAAAAAAA9VfAAAAAAAAA9VXwAAAAAAAAD1V8AAAAAAAAA9VfAAAAAAAAA9VXwAAAAAAAAD1XwAAAAAAAAD1VfAAAAAAAAAD1fAAAAAAAAAPVVfAAAAAAAAAD/wAAAAAAAAA9VV8AAAAAAAAAD8AAAAAAAAAPVVXwAAAAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAAAAAAA9VVVVVV/AAAAAAAAAAAAAAAAPVVVVVVV/AAAAAAAAAAAAAAAP1VVVVVVVfAAAAAAAAAAAAAAD9VVVVVVVVfwAAAAAAAAAAAAD9VVVVVVVVVf8AAAAAAAAAAAA/VVVVVVVVVVX/AAAAAAAAAAD/VVVVVVVVVVVV//AAAAAAAAP/1VVVVVVVVVVVVf//////////VVVVVVVVVVVVVVVf///////9VVVVVVVU="},
+ {"width" : "44", "buffer":"VVVVVVVVVVVVVVVVVVVVVVf////9VVVVVVX////////1VVVX///8AAAAA/1VVf//AAAAAAAAD1V//AAAAAAAAAAPV/8AAAAAAAAAAA9fwAAAAAAAAAAAD18AAAAAAAAAAAAPXwAAAAAAAAAAAA9fAAAAAAAAAAAAD3wAAAAAAAAAAAAPfAAAAAAAAAAAAA98AAAAAAAAAAAAD3wAAAAAAAAAAAAPfAAAAAAAAAAAAA98AAAAAAAAAAAAD3wAAAAAAAAAAAAP8AAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAP8AAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAP8AAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAP8AAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAP8AAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAPfAAAAAAAAAAAAA98AAAAAAAAAAAAD3///8AAAAAAAAAPX///8AAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAAA9VVVV8AAAAAAAAD1VVVXwAAAAAAAAPVVVVfAAAAAAAD/9VVVVf/////////VVVVVf///////VVVVVVVVVVVVVVVVU="},
+ {"width" : "61", "buffer":"VVVVVV///////VVVVVVVVVVVX/////////9VVVVVVVVV//8AAAAAAD//VVVVVVVf/wAAAAAAAAAP/VVVVVV/8AAAAAAAAAAAD/VVVVV/AAAAAAAAAAAAAD9VVVX8AAAAAAAAAAAAAAD1VVX8AAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAD1fAAAAAD/wAAAAAAAAAA9XwAAAA///wAAAAAAAAAPVfAAAP/1V/AAAAAAAAAD1XwAA/9VVV8AAAAAAAAA9V8AA/VVVVfAAAAAAAAAPVXwD9VVVVXwAAAAAAAAD1VfP9VVVVV8AAAAAAAAA9VX/1VVVVVfAAAAAAAAA9VVXVVVVVVXwAAAAAAAAPVVVVVVVVVV8AAAAAAAAD1VVVVVVVVV8AAAAAAAAA9VVVVVVVVVfAAAAAAAAA9VVVVVVVVVfAAAAAAAAAPVVVVVVVVVfAAAAAAAAAD1VVVVVVVVXwAAAAAAAAD1VVVVVVVVXwAAAAAAAAA9VVVVVVVVXwAAAAAAAAA9VVVVVVVVXwAAAAAAAAAPVVVVVVVVXwAAAAAAAAAPVVVVVVVVV8AAAAAAAAAD1VVVVVVVV8AAAAAAAAAD1VVVVVVVV8AAAAAAAAAA9VVVVVVVV8AAAAAAAAAA9VVVVVVVV8AAAAAAAAAA9VVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAAPVVVVVVVV8AAAAAAAAAA/VVVVVVVV8AAAAAAAAAA/VVVVVVVV8AAAAAAAAAD9VVVVVVVV8AAAAAAAAAD9VVVVVVVV8AAAAAAAAAP1VVVVVVVV8AAAAAAAAAP1VVVVVVVV8AAAAAAAAAPVVVVVVVVV8AAAAAAAAAA///////1V8AAAAAAAAAAD///////VfAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1VX/////////////////9VVf////////////////9VVVVVVVVVVVVVVVVVVVVVQ=="},
+ {"width" : "61", "buffer":"VVVVVf///////VVVVVVVVVVVf/////////9VVVVVVVVX//AAAAAAAD//VVVVVVVf/AAAAAAAAAAP/VVVVVVfwAAAAAAAAAAAD9VVVVV/AAAAAAAAAAAAAD9VVVV/AAAAAAAAAAAAAAP1VVV8AAAAAAAAAAAAAAAPVVV8AAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAD1XwAAAAD/8AAAAAAAAAA9V8AAAA///wAAAAAAAAAPVXwAAP/1VfAAAAAAAAAD1V8AA/9VVV8AAAAAAAAD1VfAD/VVVVXwAAAAAAAA9VV8P9VVVVV8AAAAAAAAPVVf/1VVVVVfAAAAAAAAD1VV/VVVVVVXwAAAAAAAA9VVVVVVVVVXwAAAAAAAAPVVVVVVVVVfwAAAAAAAAPVVVVVVVVX/wAAAAAAAAD1VVVVX////AAAAAAAAAA9VVVVX///wAAAAAAAAAA9VVVVV8AAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAPVVVVVVXwAAAAAAAAAAAA9VVVVVV8AAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAD1VVVVV8AAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAA9VVVVf///wAAAAAAAAAAD1VVVV////wAAAAAAAAAA9VVVVVVVV/wAAAAAAAAAPVVVVVVVVV/AAAAAAAAAD1VVVVVVVVV8AAAAAAAAA9VVVVVVVVVfAAAAAAAAAPVVXVVVVVVV8AAAAAAAAD1Vf/1VVVVVfAAAAAAAAAPVfz/1VVVVXwAAAAAAAAD1XwA/9VVVXwAAAAAAAAA9XwAA//VVXwAAAAAAAAAPV8AAAP///wAAAAAAAAAD18AAAAD//wAAAAAAAAAA9fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAP1VVV/AAAAAAAAAAAAAA/1VVVX/wAAAAAAAAAAAD/VVVVVX/8AAAAAAAAAAP9VVVVVVV//8AAAAAAAP/1VVVVVVVVf//////////VVVVVVVVVVVf///////VVVVVVVQ=="},
+ {"width" : "62", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/////1VVVVVVVVVVVVf////////VVVVVVVVVVX//8AAAAAD/VVVVVVVVVf/8AAAAAAAAPVVVVVVVVf/AAAAAAAAAAPVVVVVVVf8AAAAAAAAAAA9VVVVVVX8AAAAAAAAAAAD1VVVVVVfAAAAAAAAAAAAPVVVVVVXwAAAAAAAAAAAA9VVVVVVfAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAPVVVVVVfAAAAAAAAAAAAA9VVVVVXwAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAA9VVVVVfAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAPVVVfAAAAAADAAAAAAAAA9VVV8AAAAAA/AAAAAAAAD1VVfAAAAAAPfAAAAAAAAPVVV8AAAAAA98AAAAAAAA9VVfAAAAAAD3wAAAAAAAD1VV8AAAAAAPfAAAAAAAAPVVXwAAAAAD18AAAAAAAA9VV8AAAAAAPXwAAAAAAAD1VXwAAAAAA9fAAAAAAAAPVV8AAAAAAD18AAAAAAAA9VXwAAAAAA9XwAAAAAAAD1V8AAAAAAD1fAAAAAAAAPVXwAAAAAAPV8AAAAAAAA9VfAAAAAAA9XwAAAAAAAD1XwAAAAAAPVfAAAAAAAAPVfAAAAAAA9V8AAAAAAAA9XwAAAAAAD1XwAAAAAAAD1fAAAAAAAPVfAAAAAAAAPXwAAAAAAD1V8AAAAAAAA9fAAAAAAAPVXwAAAAAAAD18AAAAAAA9VfAAAAAAAAPfAAAAAAAD1V8AAAAAAAA98AAAAAAA9VXwAAAAAAAD3wAAAAAAD1VfAAAAAAAAP8AAAAAAAPVV8AAAAAAAA/wAAAAAAA9VXwAAAAAAAD/AAAAAAAPVVfAAAAAAAAP8AAAAAAAP//wAAAAAAAA/wAAAAAAAP/8AAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAD1/////////8AAAAAAAAAPV/////////8AAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAAA9VVVVVVVVVV8AAAAAAAAD1VVVVVVVVVXwAAAAAAAAPVVVVVVVVVVfAAAAAAAD/9VVVVVVVVVVf/////////VVVVVVVVVVVf///////VVVVVVVVVVVVVVVVVVVVVVU="},
+ {"width" : "61", "buffer":"VVVVVVVVVVVVVVVVVVVVVVf////////////////1VVX/////////////////VVXwAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAA9VV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAA9VVfAAAAAA//////////9VVXwAAAAA///////////VVV8AAAAA9VVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVV8AAAAA9VVVVVVVVVVVVVfAAAAAPVVVVVVVVVVVVVXwAAAAD1VVVVVVVVVVVVV8AAAAAP////VVVVVVVVVfAAAAAA/////9VVVVVVVXwAAAAAAAAAD//1VVVVVV8AAAAAAAAAAAP/1VVVVVfAAAAAAAAAAAAA/1VVVVXwAAAAAAAAAAAAA/1VVVV8AAAAAAAAAAAAAA/VVVVfAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAA9VVf/AAAAAAAAAAAAAAAD1VV////AAAAAAAAAAAAA9VVVX///8AAAAAAAAAAAPVVVVVVX/8AAAAAAAAAAA9VVVVVVVf8AAAAAAAAAAPVVVVVVVVfwAAAAAAAAAD1VVVVVVVVfAAAAAAAAAA9VVVVVVVVV8AAAAAAAAAPVV9VVVVVVXwAAAAAAAAD1V/9VVVVVV8AAAAAAAAA9V8P9VVVVVXwAAAAAAAAPVfAP9VVVVXwAAAAAAAAD1fAAP9VVVV8AAAAAAAAA9XwAAP9VVV8AAAAAAAAAPV8AAAP/VX8AAAAAAAAAD18AAAAP//8AAAAAAAAAA9fAAAAAD/wAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAAD3wAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAPXwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAD1VV8AAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAP1VVVfwAAAAAAAAAAAAAP1VVVV/wAAAAAAAAAAAA/VVVVVV/8AAAAAAAAAAP/VVVVVVV//wAAAAAAAP/9VVVVVVVVf//////////VVVVVVVVVVV////////VVVVVVVQ=="},
+ {"width" : "67", "buffer":"VVVVVVVVf///////1VVVVVVVVVVVVf//////////1VVVVVVVVVV//AAAAAAAA//9VVVVVVVVX/AAAAAAAAAAA//VVVVVVVX8AAAAAAAAAAAAP9VVVVVVfwAAAAAAAAAAAAAD1VVVVVfwAAAAAAAAAAAAAAPVVVVVfAAAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAD1VVVXwAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVV8AAAAAAAAAAP//AAAA9VVVfAAAAAAAAAD/////wAPVVVXwAAAAAAAAD/VVX///D1VVXwAAAAAAAAD1VVVVV//1VVV8AAAAAAAAD1VVVVVVX1VVVfAAAAAAAAD1VVVVVVVVVVVXwAAAAAAAA9VVVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAAD1VVVVVVVVVVVXwAAAAAAAA9VVV///9VVVVV8AAAAAAAAPVV//////VVVVfAAAAAAAAPVX/8AAAP/VVVXwAAAAAAAD1f8AAAAAD9VVV8AAAAAAAA9/wAAAAAAD1VVfAAAAAAAAD/AAAAAAAAPVVXwAAAAAAAAMAAAAAAAAA9VV8AAAAAAAAAAAAAAAAAAD1VfAAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAAAPXwAAAAAAAAADwAAAAAAAAD18AAAAAAAAAD/AAAAAAAAAPfAAAAAAAAAD18AAAAAAAAD3wAAAAAAAAD1fAAAAAAAAA98AAAAAAAAA9V8AAAAAAAAPfAAAAAAAAAPVfAAAAAAAAD18AAAAAAAAPVXwAAAAAAAA9fAAAAAAAAD1V8AAAAAAAAD3wAAAAAAAA9VfAAAAAAAAA98AAAAAAAAPVV8AAAAAAAAPfAAAAAAAAD1VfAAAAAAAAD3wAAAAAAAA9VXwAAAAAAAA98AAAAAAAAPVV8AAAAAAAAPfAAAAAAAAD1VfAAAAAAAAD3wAAAAAAAA9VXwAAAAAAAA98AAAAAAAAPVV8AAAAAAAAPXwAAAAAAAD1VfAAAAAAAAD18AAAAAAAA9VXwAAAAAAAA9fAAAAAAAAPVV8AAAAAAAAPXwAAAAAAAD1VfAAAAAAAAD18AAAAAAAA9VXwAAAAAAAA9fAAAAAAAAPVV8AAAAAAAAPV8AAAAAAAD1VfAAAAAAAAD1fAAAAAAAA9VfAAAAAAAAA9XwAAAAAAAPVXwAAAAAAAAPV8AAAAAAAD1V8AAAAAAAAPVXwAAAAAAAPVfAAAAAAAAD1V8AAAAAAAD1XwAAAAAAAA9VfAAAAAAAA9V8AAAAAAAAPVV8AAAAAAAD18AAAAAAAAD1VfAAAAAAAAP8AAAAAAAAA9VXwAAAAAAAA8AAAAAAAAA9VVfAAAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAAAD1VVfAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVV8AAAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAAD1VVVVVfAAAAAAAAAAAAAAD1VVVVVV8AAAAAAAAAAAAAD1VVVVVVXwAAAAAAAAAAAAP1VVVVVVVfwAAAAAAAAAAAP1VVVVVVVV/wAAAAAAAAAA/VVVVVVVVVV/wAAAAAAAAP/VVVVVVVVVVV//AAAAAAD/9VVVVVVVVVVVV/////////VVVVVVVVVVVVVVX//////1VVVVVVQ=="},
+ {"width" : "57", "buffer":"VVVVVVVVVVVVVVVVVVVV////////////////9VV/////////////////1XwAAAAAAAAAAAAAAAD9XwAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAPfAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAA98AAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAD18AAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAD1fAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVfAAAAAAAAAAAAAAAAPVX///////wAAAAAAAAPVX///////8AAAAAAAAPVVVVVVVVVfAAAAAAAAPVVVVVVVVVfAAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVV8AAAAAAAA9VVVVVVVVXwAAAAAAAA9VVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVXwAAAAAAAD1VVVVVVVVfAAAAAAAAD1VVVVVVVVfAAAAAAAAD1VVVVVVVVfAAAAAAAAPVVVVVVVVVfAAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVXwAAAAAAAA9VVVVVVVVXwAAAAAAAA9VVVVVVVVXwAAAAAAAA9VVVVVVVVXwAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAD1VVVVVVVVfAAAAAAAAD1VVVVVVVVfAAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAPVVVVVVVVV8AAAAAAAAPVVVVVVVVXwAAAAAAAAPVVVVVVVVXwAAAAAAAAPVVVVVVVVXwAAAAAAAAPVVVVVVVVXwAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVVfAAAAAAAAA9VVVVVVVV8AAAAAAAAA9VVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVV8AAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAPVVVVVVVVXwAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVVfAAAAAAAAAPVVVVVVVV8AAAAAAAAA9VVVVVVVV8AAAAAAAAA9VVVVVVVV8AAAAAAAAA9VVVVVVVV8AAAAAAAAA9VVVVVVVV8AAAAAAAAA9VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVXwAAAAAAAAD1VVVVVVVfAAAAAAAAAD1VVVVVVVXwAAAAAAD//VVVVVVVVX/////////9VVVVVVVVV///////9VVVVVVVVVVVVVVVVVVVVVVVVVV"},
+ {"width" : "66", "buffer":"VVVVVVVX//////1VVVVVVVVVVVVVf/////////VVVVVVVVVVVf/8AAAAAAP/9VVVVVVVVVX/wAAAAAAAAA/9VVVVVVVV/wAAAAAAAAAAD/VVVVVVVX8AAAAAAAAAAAAD9VVVVVV/AAAAAAAAAAAAAA/VVVVVX8AAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAAA9VVVVfAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAwAAAAAAAAD1XwAAAAAAAAP8AAAAAAAAD1XwAAAAAAAA/fAAAAAAAAD1XwAAAAAAAD1XwAAAAAAAA9XwAAAAAAAD1V8AAAAAAAA9XwAAAAAAAD1V8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAPVV8AAAAAAAA9XwAAAAAAAD1V8AAAAAAAA9XwAAAAAAAD1XwAAAAAAAA9XwAAAAAAAA9XwAAAAAAAA9XwAAAAAAAAP/AAAAAAAAD1XwAAAAAAAAD8AAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAA9VVfAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAAAAAAAAAAA9fAAAAAAAAAAwAAAAAAAAA9fAAAAAAAAAP8AAAAAAAAAPfAAAAAAAAA/fAAAAAAAAAPfAAAAAAAAD1XwAAAAAAAAPfAAAAAAAAD1V8AAAAAAAAP8AAAAAAAAD1V8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAP8AAAAAAAAPVV8AAAAAAAAPfAAAAAAAAPVV8AAAAAAAAPfAAAAAAAAD1V8AAAAAAAAPfAAAAAAAAD1V8AAAAAAAAPfAAAAAAAAD1XwAAAAAAAA9fAAAAAAAAA9XwAAAAAAAA9XwAAAAAAAAP/AAAAAAAAA9XwAAAAAAAAD8AAAAAAAAA9XwAAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAAPVVfAAAAAAAAAAAAAAAAAA9VVXwAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAA9VVVVX8AAAAAAAAAAAAAAD1VVVVV/AAAAAAAAAAAAAA/VVVVVVX8AAAAAAAAAAAAD9VVVVVVV/wAAAAAAAAAAA/VVVVVVVVX/AAAAAAAAAA/9VVVVVVVVVf/wAAAAAAA//VVVVVVVVVVV//////////VVVVVVVVVVVVVf///////VVVVVVV"},
+ {"width" : "67", "buffer":"VVVVVVVX//////VVVVVVVVVVVVVVX////////1VVVVVVVVVVVVf/wAAAAAD/9VVVVVVVVVVV/wAAAAAAAA/9VVVVVVVVVX/AAAAAAAAAAP1VVVVVVVVX8AAAAAAAAAAAP1VVVVVVVXwAAAAAAAAAAAA/VVVVVVVXwAAAAAAAAAAAAA9VVVVVVXwAAAAAAAAAAAAAD1VVVVVXwAAAAAAAAAAAAAAPVVVVVXwAAAAAAAAAAAAAAA9VVVVXwAAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAAA9VVVV8AAAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAAPVVXwAAAAAAAAAAAAAAAAAD1VV8AAAAAAAAD8AAAAAAAA9VVfAAAAAAAAD/wAAAAAAAD1VfAAAAAAAAD1fAAAAAAAA9VXwAAAAAAAA9XwAAAAAAAD1V8AAAAAAAAPVfAAAAAAAA9V8AAAAAAAAPVXwAAAAAAAPVfAAAAAAAAD1V8AAAAAAAD1XwAAAAAAAA9VfAAAAAAAAPV8AAAAAAAAPVXwAAAAAAAD1fAAAAAAAAD1V8AAAAAAAA9XwAAAAAAAA9VfAAAAAAAAPV8AAAAAAAAPVXwAAAAAAAA98AAAAAAAAD1VfAAAAAAAAPfAAAAAAAAA9VXwAAAAAAAD3wAAAAAAAAPVV8AAAAAAAA98AAAAAAAAD1VfAAAAAAAAPfAAAAAAAAA9VXwAAAAAAAD3wAAAAAAAAPVV8AAAAAAAA9fAAAAAAAAD1VfAAAAAAAAPXwAAAAAAAA9VfAAAAAAAAA98AAAAAAAAPVXwAAAAAAAAPfAAAAAAAAD1V8AAAAAAAAD3wAAAAAAAA9VfAAAAAAAAA98AAAAAAAAPVXwAAAAAAAAPfAAAAAAAAD1V8AAAAAAAAD3wAAAAAAAA9VfAAAAAAAAA98AAAAAAAAD1XwAAAAAAAAPXwAAAAAAAA9XwAAAAAAAAD18AAAAAAAAD18AAAAAAAAA9fAAAAAAAAAP8AAAAAAAAAPXwAAAAAAAAA8AAAAAAAAAD1fAAAAAAAAAAAAAAAAAAAA9XwAAAAAAAAAAAAAAAAAAAPV8AAAAAAAAAAAAAAAAAAAD1XwAAAAAAAAAAAAAAAAAAA9V8AAAAAAAAAAAAAAAAAAAPVXwAAAAAAAAAAAAAAAAAAD1V8AAAAAAAAAAAAAAAAAAA9VXwAAAAAAAAAAAAAAAAAAPVV8AAAAAAAAAAAAAAAAAAD1VXwAAAAAAAAAAAAAAAAAA9VVfAAAAAAAADAAAAAAAAAPVVV8AAAAAAAP8AAAAAAAAD1VVX8AAAAAP/3wAAAAAAAA9VVVf/AAAP//V8AAAAAAAAPVVVVf/////VVfAAAAAAAAPVVVVVX///VVVXwAAAAAAAD1VVVVVVVVVVVV8AAAAAAAA9VVVVVVVVVVVVfAAAAAAAAPVVVVVVVVVVVVfAAAAAAAAD1VVVVVVVVVVVXwAAAAAAAA9VVVVVVVVVVVV8AAAAAAAAPVVVVVVVVVVVV8AAAAAAAAD1VVVVVVVVVVVfAAAAAAAAD1VVVf9VVVVVV/AAAAAAAAA9VVVf///1VVX/AAAAAAAAAPVVVXwP/////8AAAAAAAAAD1VVXwAAA///wAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAPVVVfAAAAAAAAAAAAAAAAAD1VVXwAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAA9VVVfAAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAPVVVXwAAAAAAAAAAAAAAAAD1VVV8AAAAAAAAAAAAAAAAD1VVVfAAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAA9VVVXwAAAAAAAAAAAAAAAAPVVVV8AAAAAAAAAAAAAAAAPVVVVfAAAAAAAAAAAAAAAAPVVVVXwAAAAAAAAAAAAAAAD1VVVV8AAAAAAAAAAAAAAAD1VVVVfAAAAAAAAAAAAAAAD1VVVVXwAAAAAAAAAAAAAAP1VVVVV8AAAAAAAAAAAAAAP1VVVVVf8AAAAAAAAAAAAA/VVVVVVVf/AAAAAAAAAAAD/VVVVVVVVf//AAAAAAAAD/9VVVVVVVVVX///////////1VVVVVVVVVVVX////////1VVVVVVVQ=="},
+ {"width" : "23", "buffer":"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///9VVX/////VV/AAAA/VfAAAAAPV8AAAAAPfAAAAAA98AAAAAD3wAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA/wAAAAAD3wAAAAAPfAAAAAA98AAAAAD18AAAAAPXwAAAAD1XwAAAA9VX/AAD/VVX////1VVVf//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//VVVVX////VVX/wAP/VV/AAAAPVfAAAAAPV8AAAAAPfAAAAAA98AAAAAD3wAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA/wAAAAAD/AAAAAAP8AAAAAA98AAAAAD3wAAAAAPfAAAAAA98AAAAAD18AAAAA9XwAAAAD1X8AAAD9VX/////VVV////VU="}
+ ]
+}
diff --git a/apps/contourclock/font-Yumaro.json b/apps/contourclock/fonts/font-Yumaro.json
similarity index 100%
rename from apps/contourclock/font-Yumaro.json
rename to apps/contourclock/fonts/font-Yumaro.json
diff --git a/apps/contourclock/font-YuseiMagic.json b/apps/contourclock/fonts/font-YuseiMagic.json
similarity index 99%
rename from apps/contourclock/font-YuseiMagic.json
rename to apps/contourclock/fonts/font-YuseiMagic.json
index 5aa3ee6e4..9289a8a99 100644
--- a/apps/contourclock/font-YuseiMagic.json
+++ b/apps/contourclock/fonts/font-YuseiMagic.json
@@ -1,5 +1,5 @@
{
- "name":"YuseiMagic",
+ "name":"Yusei Magic",
"size":"96",
"characters":[
{"width" : "67", "buffer":"VVVVVVVVVX///1VVVVVVVVVVVVVVVVf//////VVVVVVVVVVVVVVX//wAAA//1VVVVVVVVVVVV//AAAAAAD/1VVVVVVVVVVX/wAAAAAAAA/1VVVVVVVVVX8AAAAAAAAAA/VVVVVVVVVfwAAAAAAAAAAA/VVVVVVVVfwAAAAAAAAAAAD9VVVVVVVfAAAAAAAAAAAAAD1VVVVVVfAAAAAA//8AAAAA9VVVVVVfAAAAAD///wAAAAD1VVVVVfAAAAAD9VVfAAAAAPVVVVVXwAAAAD1VVV8AAAAA9VVVVXwAAAAD1VVVXwAAAAPVVVVV8AAAAD1VVVVfAAAAA9VVVV8AAAAD1VVVVXwAAAAPVVVV8AAAAA9VVVVVfAAAAA9VVVfAAAAA9VVVVVV8AAAAD1VVfAAAAA9VVVVVVfAAAAA9VVXwAAAAPVVVVVVV8AAAAPVVXwAAAAPVVVVVVVfAAAAA9VV8AAAAD1VVVVVVXwAAAAPVVfAAAAD1VVVVVVVfAAAAD1VfAAAAA9VVVVVVVXwAAAAPVXwAAAAPVVVVVVVV8AAAAD1V8AAAAPVVVVVVVVXwAAAA9V8AAAAD1VVVVVVVV8AAAAD1fAAAAA9VVVVVVVVfAAAAA9XwAAAAPVVVVVVVVXwAAAAPV8AAAAPVVVVVVVVVfAAAAD1fAAAAD1VVVVVVVVXwAAAA9fAAAAA9VVVVVVVVV8AAAAPXwAAAAPVVVVVVVVVfAAAAA98AAAAD1VVVVVVVVXwAAAAPfAAAAD1VVVVVVVVV8AAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAAP8AAAAPVVVVVVVVVV8AAAAD/AAAAD1VVVVVVVVVfAAAAA/wAAAA9VVVVVVVVVXwAAAAP8AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVV8AAAAPfAAAAD1VVVVVVVVVfAAAAD3wAAAA9VVVVVVVVVXwAAAA98AAAAPVVVVVVVVVXwAAAAPfAAAAD1VVVVVVVVV8AAAAD3wAAAAPVVVVVVVVVfAAAAA98AAAAD1VVVVVVVVXwAAAAPfAAAAA9VVVVVVVVV8AAAAPXwAAAAPVVVVVVVVVfAAAAD1fAAAAD1VVVVVVVVXwAAAA9XwAAAA9VVVVVVVVXwAAAAPV8AAAAD1VVVVVVVV8AAAAD1fAAAAA9VVVVVVVVfAAAAA9XwAAAAPVVVVVVVVXwAAAA9VfAAAAD1VVVVVVVXwAAAAPVXwAAAAPVVVVVVVV8AAAAD1V8AAAAD1VVVVVVVfAAAAA9VfAAAAA9VVVVVVVXwAAAA9VV8AAAAD1VVVVVVXwAAAAPVVfAAAAA9VVVVVVV8AAAAD1VXwAAAAPVVVVVVVfAAAAD1VVfAAAAA9VVVVVVfAAAAA9VVXwAAAAPVVVVVVXwAAAAPVVVfAAAAA9VVVVVXwAAAAPVVVXwAAAAPVVVVVV8AAAAD1VVVfAAAAA9VVVVV8AAAAD1VVVXwAAAAPVVVVVfAAAAA9VVVVfAAAAA9VVVVfAAAAA9VVVVXwAAAAD1VVVfAAAAAPVVVVVfAAAAAPVVVfAAAAAPVVVVVXwAAAAA9VVfAAAAAPVVVVVVfAAAAAD1VfAAAAAD1VVVVVV8AAAAAP//AAAAAD1VVVVVVXwAAAAA//AAAAAD1VVVVVVVfAAAAAAAAAAAAD1VVVVVVVV8AAAAAAAAAAAD1VVVVVVVVX8AAAAAAAAAAP1VVVVVVVVVf8AAAAAAAAA/1VVVVVVVVVVf8AAAAAAAD/VVVVVVVVVVVVf/AAAAAA/9VVVVVVVVVVVVVf///////1VVVVVVVVVVVVVVX/////9VVVVVVVV" },
diff --git a/apps/contourclock/fonts/temp b/apps/contourclock/fonts/temp
deleted file mode 100644
index 8b1378917..000000000
--- a/apps/contourclock/fonts/temp
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/contourclock/metadata.json b/apps/contourclock/metadata.json
index 6b2b51991..d59999c04 100644
--- a/apps/contourclock/metadata.json
+++ b/apps/contourclock/metadata.json
@@ -1,7 +1,7 @@
{ "id": "contourclock",
"name": "Contour Clock",
"shortName" : "Contour Clock",
- "version":"0.28",
+ "version":"0.30",
"icon": "app.png",
"readme": "README.md",
"description": "A Minimalist clockface with large Digits.",
diff --git a/apps/contourclock/screenshot.png b/apps/contourclock/screenshot.png
deleted file mode 100644
index 9e263152c..000000000
Binary files a/apps/contourclock/screenshot.png and /dev/null differ
diff --git a/apps/daisy/ChangeLog b/apps/daisy/ChangeLog
index 61a09a18d..751164c07 100644
--- a/apps/daisy/ChangeLog
+++ b/apps/daisy/ChangeLog
@@ -7,3 +7,4 @@
0.07: Use default Bangle formatter for booleans
0.08: fix idle timer always getting set to true
0.09: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps
+0.10: Use widget_utils.
diff --git a/apps/daisy/app.js b/apps/daisy/app.js
index c99b19228..3b3975105 100644
--- a/apps/daisy/app.js
+++ b/apps/daisy/app.js
@@ -1,6 +1,7 @@
var SunCalc = require("suncalc"); // from modules folder
const storage = require('Storage');
const locale = require("locale");
+const widget_utils = require('widget_utils');
const SETTINGS_FILE = "daisy.json";
const LOCATION_FILE = "mylocation.json";
const h = g.getHeight();
@@ -547,8 +548,6 @@ g.clear();
Bangle.loadWidgets();
/*
* we are not drawing the widgets as we are taking over the whole screen
- * so we will blank out the draw() functions of each widget and change the
- * area to the top bar doesn't get cleared.
*/
-for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+widget_utils.hide();
draw();
diff --git a/apps/daisy/metadata.json b/apps/daisy/metadata.json
index 0bad50151..471f8e56f 100644
--- a/apps/daisy/metadata.json
+++ b/apps/daisy/metadata.json
@@ -1,6 +1,6 @@
{ "id": "daisy",
"name": "Daisy",
- "version":"0.09",
+ "version":"0.10",
"dependencies": {"mylocation":"app"},
"description": "A beautiful digital clock with large ring guage, idle timer and a cyclic information line that includes, day, date, steps, battery, sunrise and sunset times",
"icon": "app.png",
diff --git a/apps/entonclk/ChangeLog b/apps/entonclk/ChangeLog
index e16defa54..8c737cb68 100644
--- a/apps/entonclk/ChangeLog
+++ b/apps/entonclk/ChangeLog
@@ -1,2 +1,3 @@
0.1: New App!
0.2: Now with timer function
+0.3: Fix HRM
diff --git a/apps/entonclk/app.js b/apps/entonclk/app.js
index 292030b86..d3e18ae91 100644
--- a/apps/entonclk/app.js
+++ b/apps/entonclk/app.js
@@ -101,7 +101,7 @@ Bangle.on('touch',t => {
g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y+28);
g.setFontAlign(0, 0).setFont("6x8", 2);
g.drawString(getSteps(), 50, y+70);
- g.drawString(Math.round(Bangle.getHealthStatus("last").bpm), g.getWidth() -37, y + 70);
+ g.drawString(Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm), g.getWidth() -37, y + 70);
// queue next draw
if (drawTimeout) clearTimeout(drawTimeout);
@@ -124,4 +124,4 @@ Bangle.on('touch',t => {
Bangle.loadWidgets();
draw();
setTimeout(Bangle.drawWidgets,0);
-}
\ No newline at end of file
+}
diff --git a/apps/entonclk/metadata.json b/apps/entonclk/metadata.json
index 4b7174263..159f0c605 100644
--- a/apps/entonclk/metadata.json
+++ b/apps/entonclk/metadata.json
@@ -1,7 +1,7 @@
{
"id": "entonclk",
"name": "Enton Clock",
- "version": "0.2",
+ "version": "0.3",
"description": "A simple clock using the Audiowide font with timer. ",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
diff --git a/apps/espruinoctrl/ChangeLog b/apps/espruinoctrl/ChangeLog
index 5560f00bc..819ae56cb 100644
--- a/apps/espruinoctrl/ChangeLog
+++ b/apps/espruinoctrl/ChangeLog
@@ -1 +1,2 @@
0.01: New App!
+0.02: Disable not existing BTN3 on Bangle.js 2, set maximum transmit power
diff --git a/apps/espruinoctrl/custom.html b/apps/espruinoctrl/custom.html
index f8e7e38b9..2329ad214 100644
--- a/apps/espruinoctrl/custom.html
+++ b/apps/espruinoctrl/custom.html
@@ -164,6 +164,7 @@ function cmd(cmd,mac,rx) {
if (mac) {
E.showMessage("Connecting\\n"+mac);
if (mac.length==17) mac+=" random";
+ NRF.setTxPower(process.env.HWVERSION == 2 ? 8 : 4);
NRF.connect(mac).then(dev=>send(dev,cmd,onDone)).catch(err);
} else {
E.showMessage("Scanning...");
@@ -193,14 +194,16 @@ function sendCommandRX(device, text, callback) {
function done() {
Terminal.println("\\n============\\n Disconnected");
device.disconnect();
- setTimeout(function() {
- setWatch(function() {
- if (callback) callback();
- resolve();
- }, BTN3);
- g.reset().setFont("6x8",2).setFontAlign(0,0,1);
- g.drawString("Back", g.getWidth()-10, g.getHeight()-50);
- }, 200);
+ if (global.BTN3 !== undefined) {
+ setTimeout(function() {
+ setWatch(function() {
+ if (callback) callback();
+ resolve();
+ }, BTN3);
+ g.reset().setFont("6x8",2).setFontAlign(0,0,1);
+ g.drawString("Back", g.getWidth()-10, g.getHeight()-50);
+ }, 200);
+ }
}
device.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e").then(function(s) {
service = s;
diff --git a/apps/espruinoctrl/metadata.json b/apps/espruinoctrl/metadata.json
index 5107bc6ae..9308b4a46 100644
--- a/apps/espruinoctrl/metadata.json
+++ b/apps/espruinoctrl/metadata.json
@@ -2,7 +2,7 @@
"id": "espruinoctrl",
"name": "Espruino Control",
"shortName": "Espruino Ctrl",
- "version": "0.01",
+ "version": "0.02",
"description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!",
"icon": "app.png",
"tags": "tool,bluetooth",
diff --git a/apps/fuzzyw/ChangeLog b/apps/fuzzyw/ChangeLog
index 0e5b66949..206efb10f 100644
--- a/apps/fuzzyw/ChangeLog
+++ b/apps/fuzzyw/ChangeLog
@@ -1,2 +1,3 @@
0.01: First release
0.02: Move translations to locale module (removed watch settings, now pick language in Bangle App Loader, More..., Settings)
+0.03: Change for fast loading, use widget_utils to hide widgets
\ No newline at end of file
diff --git a/apps/fuzzyw/fuzzyw.app.js b/apps/fuzzyw/fuzzyw.app.js
index debcb3c4d..e185e2ccf 100644
--- a/apps/fuzzyw/fuzzyw.app.js
+++ b/apps/fuzzyw/fuzzyw.app.js
@@ -1,6 +1,8 @@
// adapted from https://github.com/hallettj/Fuzzy-Text-International/
+{
+ const SETTINGS_FILE = "fuzzyw.settings.json";
-let fuzzy_string = {
+ let fuzzy_string = {
"hours":[
/*LANG*/"twelve",
/*LANG*/"one",
@@ -35,7 +37,11 @@ let text_scale = 3.5;
let timeout = 2.5*60;
let drawTimeout;
-function queueDraw(seconds) {
+let loadSettings = function() {
+ settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'showWidgets': false};
+}
+
+let queueDraw = function(seconds) {
let millisecs = seconds * 1000;
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
@@ -47,7 +53,7 @@ function queueDraw(seconds) {
const h = g.getHeight();
const w = g.getWidth();
-function getTimeString(date) {
+let getTimeString = function(date) {
let segment = Math.round((date.getMinutes()*60 + date.getSeconds() + 1)/300);
let hour = date.getHours() + Math.floor(segment/12);
f_string = fuzzy_string.minutes[segment % 12];
@@ -59,7 +65,7 @@ function getTimeString(date) {
return f_string;
}
-function draw() {
+let draw = function() {
let time_string = getTimeString(new Date()).replace('*', '');
// print(time_string);
g.setFont('Vector', (h-24*2)/text_scale);
@@ -71,7 +77,7 @@ function draw() {
}
g.clear();
-draw();
+loadSettings();
// Stop updates when LCD is off, restart when on
Bangle.on('lcdPower',on=>{
@@ -83,6 +89,22 @@ Bangle.on('lcdPower',on=>{
}
});
-Bangle.setUI('clock');
+Bangle.setUI({
+ mode : 'clock',
+ remove : function() {
+ // Called to unload all of the clock app
+ if (drawTimeout) clearTimeout(drawTimeout);
+ drawTimeout = undefined;
+ require('widget_utils').show(); // re-show widgets
+ }
+});
+
Bangle.loadWidgets();
-Bangle.drawWidgets();
+if (settings.showWidgets) {
+ Bangle.drawWidgets();
+} else {
+ require("widget_utils").swipeOn(); // hide widgets, make them visible with a swipe
+}
+
+draw();
+}
\ No newline at end of file
diff --git a/apps/fuzzyw/fuzzyw.settings.js b/apps/fuzzyw/fuzzyw.settings.js
new file mode 100644
index 000000000..8feb30bfb
--- /dev/null
+++ b/apps/fuzzyw/fuzzyw.settings.js
@@ -0,0 +1,33 @@
+(function(back) {
+ const SETTINGS_FILE = "fuzzy.settings.json";
+
+ // initialize with default settings...
+ let s = {'showWidgets': false}
+
+ // ...and overwrite them with any saved values
+ // This way saved values are preserved if a new version adds more settings
+ const storage = require('Storage')
+ let settings = storage.readJSON(SETTINGS_FILE, 1) || s;
+ const saved = settings || {}
+ for (const key in saved) {
+ s[key] = saved[key]
+ }
+
+ function save() {
+ settings = s
+ storage.write(SETTINGS_FILE, settings)
+ }
+
+ E.showMenu({
+ '': { 'title': 'Fuzzy Word Clock' },
+ '< Back': back,
+ 'Show Widgets': {
+ value: settings.showWidgets,
+ format: () => (settings.showWidgets ? 'Yes' : 'No'),
+ onchange: () => {
+ settings.showWidgets = !settings.showWidgets;
+ save();
+ }
+ },
+ });
+})
diff --git a/apps/fuzzyw/metadata.json b/apps/fuzzyw/metadata.json
index 5d3045edb..d1040fda3 100644
--- a/apps/fuzzyw/metadata.json
+++ b/apps/fuzzyw/metadata.json
@@ -2,7 +2,7 @@
"id":"fuzzyw",
"name":"Fuzzy Text Clock",
"shortName": "Fuzzy Text",
- "version": "0.02",
+ "version": "0.03",
"description": "An imprecise clock for when you're not in a rush",
"readme": "README.md",
"icon":"fuzzyw.png",
@@ -13,6 +13,10 @@
"allow_emulator": true,
"storage": [
{"name":"fuzzyw.app.js","url":"fuzzyw.app.js"},
+ {"name":"fuzzyw.settings.js","url":"fuzzyw.settings.js"},
{"name":"fuzzyw.img","url":"fuzzyw.icon.js","evaluate":true}
+ ],
+ "data": [
+ {"name":"fuzzyw.settings.json"}
]
}
diff --git a/apps/gpsinfo/ChangeLog b/apps/gpsinfo/ChangeLog
index 827c13cdb..d5abdf5d6 100644
--- a/apps/gpsinfo/ChangeLog
+++ b/apps/gpsinfo/ChangeLog
@@ -8,3 +8,4 @@
0.09: Fix FIFO_FULL error
0.10: Show satellites "in view" separated by GNS-system
0.11: Show number of packets received
+0.12: Fix number of packets received
diff --git a/apps/gpsinfo/gps-info.js b/apps/gpsinfo/gps-info.js
index 28cb60d8d..bbe043913 100644
--- a/apps/gpsinfo/gps-info.js
+++ b/apps/gpsinfo/gps-info.js
@@ -61,6 +61,7 @@ function getMaidenHead(param1,param2){
return U[fLon]+U[fLat]+sqLon+sqLat+L[subLon]+L[subLat]+extLon+extLat;
}
function onGPS(fix) {
+ dataCounter++;
if (lastFix.fix != fix.fix) {
// if fix is different, change the layout
if (fix.fix && leaveNofixLayout) {
@@ -127,10 +128,10 @@ function onGPS(fix) {
layout.progress.label = "in view GP/BD/GL: " + nofGP + " " + nofBD + " " + nofGL;
// console.log("in view GP/BD/GL: " + nofGP + " " + nofBD + " " + nofGL);
layout.render(layout.progress);
- layout.clear(layout.dataCounter);
- layout.dataCounter.label = ++dataCounter;
- layout.render(layout.dataCounter);
}
+ layout.clear(layout.dataCounter);
+ layout.dataCounter.label = dataCounter;
+ layout.render(layout.dataCounter);
}
if (listenerGPSraw == 0 && !fix.fix) {
@@ -157,6 +158,7 @@ Bangle.on('GPS', onGPS);
//Bangle.on('GPS-raw', onGPSraw);
Bangle.setGPSPower(1, "app");
+
function exitApp() {
load();
}
diff --git a/apps/gpsinfo/metadata.json b/apps/gpsinfo/metadata.json
index e426f5740..815cdbf21 100644
--- a/apps/gpsinfo/metadata.json
+++ b/apps/gpsinfo/metadata.json
@@ -1,7 +1,7 @@
{
"id": "gpsinfo",
"name": "GPS Info",
- "version": "0.11",
+ "version": "0.12",
"description": "An application that displays information about latitude, longitude, altitude, speed, satellites and time",
"icon": "gps-info.png",
"type": "app",
diff --git a/apps/ha/ChangeLog b/apps/ha/ChangeLog
index c0d58e5bc..2a911c207 100644
--- a/apps/ha/ChangeLog
+++ b/apps/ha/ChangeLog
@@ -5,3 +5,5 @@
0.05: Clkinfo improvements.
0.06: Updated clkinfo icon.
0.07: Update clock_info to avoid a redraw
+0.08: Allow swiping to switch triggers
+0.09: Improve web interface, arrows in UI
diff --git a/apps/ha/README.md b/apps/ha/README.md
index 654a262c8..b0309b040 100644
--- a/apps/ha/README.md
+++ b/apps/ha/README.md
@@ -1,28 +1,30 @@
# Home Assistant
-This app integrates your BangleJs into the HomeAssistant.
+This app integrates your Bangle.js into the Home Assistant.
# How to use
-Click on the left and right side of the screen to select the triggers that you
-configured. Click in the middle of the screen to send the trigger to HomeAssistant.
+Click on the left or right side of the screen to select the triggers that you configured.
+Swiping left or right works as well.
+
+Click in the middle of the screen to send the trigger to Home Assistant via Gadgetbridge.

# Initial Setup
-1.) First of all, make sure that HomeAssistant and the HomeAssistant Android App works.
+1.) First of all, make sure that Home Assistant and the Home Assistant Android Companion App work.
-2.) Open your BangleJs Gadgetbridge App, click on the Settings icon of your BangleJs and enable "Allow Intent Access"
+2.) Open your Bangle.js Gadgetbridge App, click on the Settings icon of your Bangle.js and enable "Allow Intent Access"
-3.) Enable sensor in HomeAssistant Andoird App/Configuration/Companion App/Manage Sensors/LastUpdate Trigger
+3.) Enable sensor in Home Assistant Android App/Configuration/Companion App/Manage Sensors/LastUpdate Trigger
4.) At the bottom of the same screen click on "Add New Intent" and enter "com.espruino.gadgetbridge.banglejs.HA"
-5.) The HomeAssistant Android app must be restarted in order to listen for those actions
+5.) The Home Assistant Android app must be restarted in order to listen for those actions
-- a "Force Stop" is necessary (through Android App settings) or restart your phone!
This setup must be done only once -- now you are ready to configure your BangleJS to
-control some devices or entities in your HomeAssistant :)
+control some devices or entities in your Home Assistant :)
# Setup Trigger
@@ -35,7 +37,7 @@ The following icons are currently supported:
- fire
-2.) Create an "automation" in the HomeAssistant WebUI for each trigger that you created on your BangleJs in order to tell HomeAssistant what you want to control. A sample configuration is shown in the image below -- I use this trigger to open the door:
+2.) Create an "automation" in the Home Assistant WebUI for each trigger that you created on your Bangle.js in order to tell Home Assistant what you want to control. A sample configuration is shown in the image below -- I use this trigger to open the door:

@@ -48,7 +50,7 @@ This app also implements two default trigger that can always be used:
- TRIGGER -- Will be sent whenever some trigger is executed. So you could generically listen to that.
-# How to use the library (ha.lib.js) in my own app/clk
+# How to use the library (ha.lib.js) in my own app/clock
This app inlcludes a library that can be used by other apps or clocks
to read all configured intents or to send a trigger. Example code:
@@ -74,17 +76,20 @@ ha.sendTrigger("MY_CUSTOM_TRIGGER");
# FAQ
## Sometimes the trigger is not executed
-While playing and testing a bit I found that it is very important that you allow the android HomeAssistant app, as well as BangleJs Gadgetbridge app to (1) run in background and (2), disable energy optimizations for both apps.
-Otherwise, Android could stop one of both apps and the trigger will never be sent to HomeAssistant...
+While playing and testing a bit I found that it is very important that you allow the android Home Assistant app, as well as Bangle.js Gadgetbridge app to (1) run in background and (2), disable energy optimizations for both apps.
+Otherwise, Android could stop one of both apps and the trigger will never be sent to Home Assistant...
If you still have problems, you can try another trick:
-Install "MacroDroid" from the Android AppStore and start the HomeAssistant App
+Install "MacroDroid" from the Android AppStore and start the Home Assistant App
each time the "com.espruino.gadgetbridge.banglejs.HA" intent is send together
-with the extra trigger: APP_STARTED. Then whenever you open the app on your BangleJs
-it is ensured that HomeAssistant is running...
+with the extra trigger: APP_STARTED. Then whenever you open the app on your Bangle.js
+it is ensured that Home Assistant is running...
## Thanks to
Icons created by Flaticon
## Creator
- [David Peer](https://github.com/peerdavid).
+
+## Contributor
+- [myxor](https://github.com/myxor)
diff --git a/apps/ha/custom.html b/apps/ha/custom.html
deleted file mode 100644
index 49f5a2eb8..000000000
--- a/apps/ha/custom.html
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
- Upload Tigger
-
-
-
-
-
-
-
-
diff --git a/apps/ha/ha.app.js b/apps/ha/ha.app.js
index d9199fb0e..14c6dc3be 100644
--- a/apps/ha/ha.app.js
+++ b/apps/ha/ha.app.js
@@ -17,39 +17,41 @@ function draw() {
g.setFontAlign(-1,-1);
var icon = trigger.getIcon();
- g.setColor(g.theme.fg).drawImage(icon, 12, H/5-2);
- g.drawString("Home", icon.width + 20, H/5);
- g.drawString("Assistant", icon.width + 18, H/5+24);
+ g.setColor(g.theme.fg).drawImage(icon, 12, H/5-2-5);
+ g.drawString("Home", icon.width + 20, H/5-5);
+ g.drawString("Assistant", icon.width + 18, H/5+24-5);
g.setFontAlign(0,0);
- var ypos = H/5*3+20;
+ var ypos = H/5*3+23;
g.drawRect(W/2-w/2-8, ypos-h/2-8, W/2+w/2+5, ypos+h/2+5);
g.fillRect(W/2-w/2-6, ypos-h/2-6, W/2+w/2+3, ypos+h/2+3);
g.setColor(g.theme.bg).drawString(trigger.display, W/2, ypos);
+
+ // draw arrows
+ g.setColor(g.theme.fg);
+ if (position > 0) {
+ g.drawLine(10, H/2, 20, H/2 - 10);
+ g.drawLine(10, H/2, 20, H/2 + 10);
+ }
+ if (position < triggers.length -1) {
+ g.drawLine(W - 10, H/2, W - 20, H/2 - 10);
+ g.drawLine(W - 10, H/2, W - 20, H/2 + 10);
+ }
}
-
-Bangle.on('touch', function(btn, e){
- var left = parseInt(g.getWidth() * 0.3);
- var right = g.getWidth() - left;
- var isLeft = e.x < left;
- var isRight = e.x > right;
-
- if(isRight){
- Bangle.buzz(40, 0.6);
- position += 1;
- position = position >= triggers.length ? 0 : position;
- draw();
- }
-
- if(isLeft){
+function toLeft() {
Bangle.buzz(40, 0.6);
position -= 1;
position = position < 0 ? triggers.length-1 : position;
draw();
- }
-
- if(!isRight && !isLeft){
+}
+function toRight() {
+ Bangle.buzz(40, 0.6);
+ position += 1;
+ position = position >= triggers.length ? 0 : position;
+ draw();
+}
+function sendTrigger() {
ha.sendTrigger("TRIGGER");
// Now send the selected trigger
@@ -59,9 +61,34 @@ Bangle.on('touch', function(btn, e){
Bangle.buzz(80, 0.6);
}, 250);
});
+}
+
+Bangle.on('touch', function(btn, e){
+ var left = parseInt(g.getWidth() * 0.3);
+ var right = g.getWidth() - left;
+ var isLeft = e.x < left;
+ var isRight = e.x > right;
+
+ if(isLeft){
+ toLeft();
+ }
+ if(isRight){
+ toRight();
+ }
+ if(!isRight && !isLeft){
+ sendTrigger();
}
});
+Bangle.on("swipe", (lr,ud) => {
+ if (lr == -1) {
+ toLeft();
+ }
+ if (lr == 1) {
+ toRight();
+ }
+ });
+
// Send intent that the we started the app.
ha.sendTrigger("APP_STARTED");
diff --git a/apps/ha/interface.html b/apps/ha/interface.html
new file mode 100644
index 000000000..3520b217b
--- /dev/null
+++ b/apps/ha/interface.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+ Home Assistant trigger config
+
+
+
+
+
+
+
+
diff --git a/apps/ha/metadata.json b/apps/ha/metadata.json
index 1432e010e..d44b4b6f8 100644
--- a/apps/ha/metadata.json
+++ b/apps/ha/metadata.json
@@ -1,14 +1,14 @@
{
"id": "ha",
- "name": "HomeAssistant",
- "version": "0.07",
- "description": "Integrates your BangleJS into HomeAssistant.",
+ "name": "Home Assistant",
+ "version": "0.09",
+ "description": "Integrates your Bangle.js into Home Assistant.",
"icon": "ha.png",
"type": "app",
- "tags": "tool,clkinfo",
+ "tags": "tool,clkinfo,bluetooth",
"readme": "README.md",
"supports": ["BANGLEJS2"],
- "custom": "custom.html",
+ "interface": "interface.html",
"screenshots": [
{"url":"screenshot.png"},
{"url":"screenshot_2.png"},
diff --git a/apps/health/ChangeLog b/apps/health/ChangeLog
index 7ea528ca6..921b2b682 100644
--- a/apps/health/ChangeLog
+++ b/apps/health/ChangeLog
@@ -20,3 +20,4 @@
0.19: Can show notification when daily step goal is reached
0.20: Fix the settings page, it would not update settings correctly.
0.21: Update boot.min.js.
+0.22: Fix timeout for heartrate sensor on 3 minute setting (#2435)
\ No newline at end of file
diff --git a/apps/health/boot.js b/apps/health/boot.js
index 74ac7c894..ae9a7cdc9 100644
--- a/apps/health/boot.js
+++ b/apps/health/boot.js
@@ -11,7 +11,7 @@
Bangle.setHRMPower(1, "health");
setTimeout(()=>{
Bangle.setHRMPower(0, "health");
- }, (i * 200000) + 60000);
+ }, 60000);
}, (i * 200000));
}
}
diff --git a/apps/health/boot.min.js b/apps/health/boot.min.js
index f255f271e..e3e45c400 100644
--- a/apps/health/boot.min.js
+++ b/apps/health/boot.min.js
@@ -1,5 +1,5 @@
function l(){var a=require("Storage").readJSON("health.json",1)||{},d=Bangle.getHealthStatus("day").steps;a.stepGoalNotification&&0=a.stepGoal&&(d=(new Date(Date.now())).toISOString().split("T")[0],!a.stepGoalNotificationDate||a.stepGoalNotificationDate=b;b++)setTimeout(function(){Bangle.setHRMPower(1,"health");setTimeout(function(){Bangle.setHRMPower(0,"health")},2E5*b+6E4)},2E5*b)};Bangle.on("health",d);Bangle.on("HRM",function(b){80>8,c.steps&255,c.bpm,Math.min(c.movement/8,255))}var b=new Date(Date.now()-59E4);a&&0k;k++)e=g.substr(h,4),"\u00ff\u00ff\u00ff\u00ff"!=e&&(a.steps+=(e.charCodeAt(0)<<8)+e.charCodeAt(1),a.movement+=e.charCodeAt(2),a.movCnt++,e=e.charCodeAt(2),a.bpm+=e,e&&a.bpmCnt++),h-=4;a.bpmCnt&&(a.bpm/=
-a.bpmCnt);a.movCnt&&(a.movement/=a.movCnt);require("Storage").write(b,d(a),f,17988)}})
+a))}(function(){var a=0|(require("Storage").readJSON("health.json",1)||{}).hrm;if(1==a||2==a){function d(){Bangle.setHRMPower(1,"health");setTimeout(()=>Bangle.setHRMPower(0,"health"),6E4*a);if(1==a)for(var b=1;2>=b;b++)setTimeout(()=>{Bangle.setHRMPower(1,"health");setTimeout(()=>{Bangle.setHRMPower(0,"health")},6E4)},2E5*b)}Bangle.on("health",d);Bangle.on("HRM",b=>{80{function d(c){return String.fromCharCode(c.steps>>8,c.steps&255,c.bpm,Math.min(c.movement/8,255))}var b=new Date(Date.now()-59E4);a&&0k;k++)e=g.substr(h,4),"\u00ff\u00ff\u00ff\u00ff"!=e&&(a.steps+=(e.charCodeAt(0)<<8)+e.charCodeAt(1),a.movement+=e.charCodeAt(2),a.movCnt++,e=e.charCodeAt(2),a.bpm+=e,e&&a.bpmCnt++),h-=4;a.bpmCnt&&(a.bpm/=a.bpmCnt);a.movCnt&&(a.movement/=a.movCnt);
+require("Storage").write(b,d(a),f,17988)}})
\ No newline at end of file
diff --git a/apps/health/metadata.json b/apps/health/metadata.json
index 482d72ec4..d80585200 100644
--- a/apps/health/metadata.json
+++ b/apps/health/metadata.json
@@ -2,7 +2,7 @@
"id": "health",
"name": "Health Tracking",
"shortName": "Health",
- "version": "0.21",
+ "version": "0.22",
"description": "Logs health data and provides an app to view it",
"icon": "app.png",
"tags": "tool,system,health",
diff --git a/apps/inspire/ChangeLog b/apps/inspire/ChangeLog
new file mode 100644
index 000000000..267ee22c2
--- /dev/null
+++ b/apps/inspire/ChangeLog
@@ -0,0 +1 @@
+0.01: First public version
diff --git a/apps/inspire/README.md b/apps/inspire/README.md
new file mode 100644
index 000000000..f5f8e3aa9
--- /dev/null
+++ b/apps/inspire/README.md
@@ -0,0 +1,17 @@
+# Inspire
+
+A minimalistic app that will help you practive breathing.
+
+Author: Written by pancake in 2022, powered by insomnia
+
+## Features
+
+* [x] Practice breathing 3 times
+* [x] Tap to start
+* [x] Subtle vibrations
+* [x] Drag to pause breathing
+* [ ] Automatic buzz every hour during day
+
+## Screenshots
+
+
diff --git a/apps/inspire/app-icon.js b/apps/inspire/app-icon.js
new file mode 100644
index 000000000..e40d74718
--- /dev/null
+++ b/apps/inspire/app-icon.js
@@ -0,0 +1 @@
+require("heatshrink").decompress(atob("mEwxH+AH4ACxIAIFlgyjFp4xdEI9lsteAAQFBGLosHFYYAHGQ4uYFpgxKFyotQGJIuTr4uTAANfGCIREFqoADGB4ueGCAufGAouMXazDMF5VlDptlCIRBNCIQvHRp4aC2fX6+zIhxgJLxwuBFoQADGIIWNF4xeNVAOtFooAD1rWLMA5eNLg5iHMCJeMspdKMIhKLF4iOMIYIuNAAJ7KSAqOMRpqROSAovLdgIuPMATyIF5BBJLyBgCSBgvNLyRgCF/6Pwd95BKMCGzPpQvHCRZeQRxgvCYBgwB1ouN1ouJXwqQOSJyNKRwyQOeQRhK1rsJRxBgPI4RiGLgIWNFwxgODIgxCFoIuMLxJgQSgQyCsqKKLxhgFDpoAQawIvKSKAARFxgvEGDggEF5IwfFx4wGYay7EFxowGsouTsouTGAwxRFoouRGA4xNFowuTGJIyBGYgFBB44tVGJYALFrIxTFroyOFkQAfA"))
diff --git a/apps/inspire/app-icon.png b/apps/inspire/app-icon.png
new file mode 100644
index 000000000..9b851c860
Binary files /dev/null and b/apps/inspire/app-icon.png differ
diff --git a/apps/inspire/app.js b/apps/inspire/app.js
new file mode 100644
index 000000000..92b2c4ef2
--- /dev/null
+++ b/apps/inspire/app.js
@@ -0,0 +1,125 @@
+// inspire breathing app -- by pancake
+
+var w = g.getWidth();
+var h = g.getHeight();
+var w2 = w/2;
+var h2 = h/ 2;
+var fs = 24;
+var tx = (w/3)-10;
+var ty = (h)-fs;
+var radius = (w/2)-6;
+var breathing = false;
+var count = 0;
+var mode = 0;
+var sin = 0;
+var dragged = 0;
+var lastTime = Date.now();
+function breath(t) {
+ var r = Math.abs(Math.sin(t / 100)) * w2;
+ g.fillCircle(w/2,h/2, r);
+ return r;
+}
+
+// subtle vibration
+Bangle.buzz(100);
+setTimeout(()=>{Bangle.buzz(60);}, 500);
+
+function showTouchScreen() {
+ g.setColor(1,1,1);
+ g.fillCircle (w2, h2, h2-5);
+ g.setColor(0,0,0);
+ g.setFont("Vector", 32);
+ g.drawString("Tap to", w/6, h2-fs);
+ g.drawString("breath", w/4, h2);
+}
+
+g.setBgColor(0,0,0);
+g.setColor(0);
+g.clear();
+
+function animateCircle() {
+ g.clear();
+ g.setColor(1,1,1);
+ g.fillCircle (w2, h2, radius);
+ radius-=2;
+ if (radius < 40) {
+ breathing = true;
+ startBreathing();
+ return;
+ }
+ setTimeout(animateCircle, 50);
+}
+
+Bangle.on("drag", function(pos) {
+ if (breathing) {
+ dragged = 1;
+ if (pos.dx == -pos.dy) {
+ count += pos.dx;
+ } else {
+ count+=(pos.dx + pos.dy);
+ }
+ }
+});
+
+function main() {
+ var started = false;
+ function onTouch() {
+ if (started) {
+ return;
+ }
+ started = true;
+ animateCircle();
+ Bangle.buzz(40);
+ }
+ Bangle.on("touch", onTouch);
+ showTouchScreen();
+}
+
+main();
+
+function startBreathing() {
+var cicles = 3;
+g.setFont("Vector", fs);
+
+var interval = setInterval(function() {
+if (lastTime + 10 > Date.now()) {
+ return;
+}
+ lastTime = Date.now();
+ g.setColor(0, 0, 0);
+ g.clear();
+
+ g.setColor(0, 0.5, 1);
+ var b = breath(count);
+ g.setColor(0.5, 0.5, 1);
+ var c = breath(count + 50);
+ count++;
+ g.setColor(1, 1, 1);
+ if (b < c) {
+ g.drawString("inspire",8,ty);
+ if (mode) {
+ mode = 0;
+ Bangle.buzz(20);
+ if (!dragged ) {
+ cicles--;
+ }
+ }
+ } else {
+ g.drawString("expire",8,ty);
+ if (!mode) {
+ mode = 1;
+ Bangle.buzz(20);
+ }
+ }
+ g.drawString(cicles, w-fs, ty);
+ if (cicles < 1) {
+ clearInterval(interval);
+ g.clear();
+ g.drawString("Thanks for",20,h/3);
+ g.drawString(" breathing!",20,(h/3) + 16);
+ Bangle.showClock();
+ }
+ dragged = 0;
+
+}, 4);
+}
diff --git a/apps/inspire/metadata.json b/apps/inspire/metadata.json
new file mode 100644
index 000000000..85b7365be
--- /dev/null
+++ b/apps/inspire/metadata.json
@@ -0,0 +1,16 @@
+{
+ "id": "inspire",
+ "name": "Inspire Breathing",
+ "shortName": "Inspire",
+ "version": "0.01",
+ "description": "exercise breathing every now and then",
+ "icon": "app-icon.png",
+ "tags": "tools,health",
+ "screenshots": [{"url":"screenshot.png"}],
+ "supports": ["BANGLEJS", "BANGLEJS2"],
+ "readme": "README.md",
+ "storage": [
+ {"name":"inspire.app.js","url":"app.js"},
+ {"name":"inspire.img","url":"app-icon.js","evaluate":true}
+ ]
+}
diff --git a/apps/inspire/screenshot.png b/apps/inspire/screenshot.png
new file mode 100644
index 000000000..69fbe7d26
Binary files /dev/null and b/apps/inspire/screenshot.png differ
diff --git a/apps/lato/ChangeLog b/apps/lato/ChangeLog
new file mode 100644
index 000000000..7e6c3b0d5
--- /dev/null
+++ b/apps/lato/ChangeLog
@@ -0,0 +1,2 @@
+0.01: first release
+0.02: Use clock_info module as an app
diff --git a/apps/lato/metadata.json b/apps/lato/metadata.json
index 0b5e4a0f3..e4def2df9 100644
--- a/apps/lato/metadata.json
+++ b/apps/lato/metadata.json
@@ -1,7 +1,7 @@
{
"id": "lato",
"name": "Lato",
- "version": "0.01",
+ "version": "0.02",
"description": "A Lato Font clock with fast load and clock_info",
"readme": "README.md",
"icon": "app.png",
@@ -9,6 +9,7 @@
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
+ "dependencies" : { "clock_info":"module" },
"storage": [
{"name":"lato.app.js","url":"app.js"},
{"name":"lato.img","url":"icon.js","evaluate":true}
diff --git a/apps/lcars/ChangeLog b/apps/lcars/ChangeLog
index 31ce16903..7deef5a4b 100644
--- a/apps/lcars/ChangeLog
+++ b/apps/lcars/ChangeLog
@@ -23,3 +23,4 @@
0.23: Add warning for low flash memory.
0.24: Add ability to disable alarm functionality.
0.25: Add more colors to the settings and add the ability to disable the data charts+Markup.
+0.26: Use widget_utils.
diff --git a/apps/lcars/lcars.app.js b/apps/lcars/lcars.app.js
index e796e84a7..4a5539c7a 100644
--- a/apps/lcars/lcars.app.js
+++ b/apps/lcars/lcars.app.js
@@ -2,6 +2,7 @@ const TIMER_IDX = "lcars";
const SETTINGS_FILE = "lcars.setting.json";
const locale = require('locale');
const storage = require('Storage')
+const widget_utils = require('widget_utils');
let settings = {
alarm: -1,
dataRow1: "Steps",
@@ -552,7 +553,7 @@ function draw(){
// After drawing the watch face, we can draw the widgets
if(settings.fullscreen){
- for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+ widget_utils.hide();
} else {
Bangle.drawWidgets();
}
diff --git a/apps/lcars/metadata.json b/apps/lcars/metadata.json
index 577621df0..787ca9046 100644
--- a/apps/lcars/metadata.json
+++ b/apps/lcars/metadata.json
@@ -3,7 +3,7 @@
"name": "LCARS Clock",
"shortName":"LCARS",
"icon": "lcars.png",
- "version":"0.25",
+ "version":"0.26",
"readme": "README.md",
"supports": ["BANGLEJS2"],
"description": "Library Computer Access Retrieval System (LCARS) clock.",
diff --git a/apps/lcdclock/ChangeLog b/apps/lcdclock/ChangeLog
index 5560f00bc..220369925 100644
--- a/apps/lcdclock/ChangeLog
+++ b/apps/lcdclock/ChangeLog
@@ -1 +1,2 @@
0.01: New App!
+0.02: Use clock_info module as an app
diff --git a/apps/lcdclock/metadata.json b/apps/lcdclock/metadata.json
index d7d09b106..e286dc017 100644
--- a/apps/lcdclock/metadata.json
+++ b/apps/lcdclock/metadata.json
@@ -1,12 +1,13 @@
{ "id": "lcdclock",
"name": "LCD Clock",
- "version":"0.01",
+ "version":"0.02",
"description": "A Casio-style clock, with ClockInfo areas at the top and bottom. Tap them and swipe up/down to toggle between different information",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
"type": "clock",
"tags": "clock,clkinfo",
"supports" : ["BANGLEJS2"],
+ "dependencies" : { "clock_info":"module" },
"storage": [
{"name":"lcdclock.app.js","url":"app.js"},
{"name":"lcdclock.img","url":"app-icon.js","evaluate":true}
diff --git a/apps/limelight/ChangeLog b/apps/limelight/ChangeLog
index 8fe3a0b2c..de8caf9c4 100644
--- a/apps/limelight/ChangeLog
+++ b/apps/limelight/ChangeLog
@@ -1,2 +1,4 @@
0.01: first release
0.02: Tell clock widgets to hide.
+0.03: Use widget_utils.
+
diff --git a/apps/limelight/limelight.app.js b/apps/limelight/limelight.app.js
index 84ded1039..dbc784e23 100644
--- a/apps/limelight/limelight.app.js
+++ b/apps/limelight/limelight.app.js
@@ -14,6 +14,7 @@ Bangle.setUI('clock');
g.clear();
+const widget_utils = require('widget_utils');
const SETTINGS_FILE = "limelight.json";
var UPDATE_PERIOD;
var drawTimeout;
@@ -84,10 +85,8 @@ if (settings.fullscreen) {
/*
* We load the widgets as some like widpedom accumualte the step count.
* we are not drawing the widgets as we are taking over the whole screen
- * so we will blank out the draw() functions of each widget and change the
- * widgets area to the top bar doesn't get cleared.
*/
- for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+ widget_utils.hide();
}
function debug(o) {
diff --git a/apps/limelight/metadata.json b/apps/limelight/metadata.json
index e484a2825..0e5dfd565 100644
--- a/apps/limelight/metadata.json
+++ b/apps/limelight/metadata.json
@@ -1,7 +1,7 @@
{
"id": "limelight",
"name": "Limelight",
- "version": "0.02",
+ "version": "0.03",
"description": "Simple analogue clock (with configurable fonts) based on the work of @Andreas_Rozek (Simple_Clock)",
"icon": "limelight.png",
"readme":"README.md",
diff --git a/apps/linuxclock/ChangeLog b/apps/linuxclock/ChangeLog
index 71ca3afbb..5529034be 100644
--- a/apps/linuxclock/ChangeLog
+++ b/apps/linuxclock/ChangeLog
@@ -1,4 +1,5 @@
0.01: New App.
0.02: Performance improvements.
0.03: Update clock_info to avoid a redraw
-0.04: Fix clkinfo -- use .get instead of .show
\ No newline at end of file
+0.04: Fix clkinfo -- use .get instead of .show
+0.05: Use clock_info module as an app
diff --git a/apps/linuxclock/metadata.json b/apps/linuxclock/metadata.json
index 68915b832..412fd53b4 100644
--- a/apps/linuxclock/metadata.json
+++ b/apps/linuxclock/metadata.json
@@ -1,7 +1,7 @@
{
"id": "linuxclock",
"name": "Linux Clock",
- "version": "0.04",
+ "version": "0.05",
"description": "A Linux inspired clock.",
"readme": "README.md",
"icon": "app.png",
@@ -9,7 +9,7 @@
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
- "allow_emulator": true,
+ "dependencies" : { "clock_info":"module" },
"storage": [
{"name":"linuxclock.app.js","url":"app.js"},
{"name":"linuxclock.img","url":"app-icon.js","evaluate":true},
diff --git a/apps/magnav/ChangeLog b/apps/magnav/ChangeLog
index 2b2782c7b..14a6eb2a2 100644
--- a/apps/magnav/ChangeLog
+++ b/apps/magnav/ChangeLog
@@ -2,6 +2,5 @@
0.02: Course marker
0.03: Tilt compensation and calibration
0.04: Fix Font size
-0.05: Inital portable version
-
-
+0.05: Initial portable version
+0.06: Outsource tilt compensation to library
diff --git a/apps/magnav/lib.js b/apps/magnav/lib.js
new file mode 100644
index 000000000..e3fe8fccb
--- /dev/null
+++ b/apps/magnav/lib.js
@@ -0,0 +1,41 @@
+exports.calibrate = () => {
+ var max={x:-32000, y:-32000, z:-32000},
+ min={x:32000, y:32000, z:32000};
+ var ref = setInterval(()=>{
+ var m = Bangle.getCompass();
+ max.x = m.x>max.x?m.x:max.x;
+ max.y = m.y>max.y?m.y:max.y;
+ max.z = m.z>max.z?m.z:max.z;
+ min.x = m.x {
+ setTimeout(()=>{
+ if(ref) clearInterval(ref);
+ var offset = {x:(max.x+min.x)/2,y:(max.y+min.y)/2,z:(max.z+min.z)/2};
+ var delta = {x:(max.x-min.x)/2,y:(max.y-min.y)/2,z:(max.z-min.z)/2};
+ var avg = (delta.x+delta.y+delta.z)/3;
+ var scale = {x:avg/delta.x, y:avg/delta.y, z:avg/delta.z};
+ resolve({offset:offset,scale:scale});
+ },20000);
+ });
+}
+
+exports.tiltfixread = (O,S) => {
+ "ram"
+ var m = Bangle.getCompass();
+ var g = Bangle.getAccel();
+ m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
+ var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
+ if (d<0) d+=360;
+ var phi = Math.atan(-g.x/-g.z);
+ var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
+ var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
+ var costheta = Math.cos(theta), sintheta = Math.sin(theta);
+ var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
+ var yh = m.dz*sinphi - m.dx*cosphi;
+ var psi = Math.atan2(yh,xh)*180/Math.PI;
+ if (psi<0) psi+=360;
+ return psi;
+}
diff --git a/apps/magnav/magnav_b1.js b/apps/magnav/magnav_b1.js
index 739ff881f..0ec49014f 100644
--- a/apps/magnav/magnav_b1.js
+++ b/apps/magnav/magnav_b1.js
@@ -61,24 +61,7 @@ function newHeading(m,h){
var candraw = false;
var CALIBDATA = require("Storage").readJSON("magnav.json",1)||null;
-
-function tiltfixread(O,S){
- "ram"
- var m = Bangle.getCompass();
- var g = Bangle.getAccel();
- m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
- var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
- if (d<0) d+=360;
- var phi = Math.atan(-g.x/-g.z);
- var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
- var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
- var costheta = Math.cos(theta), sintheta = Math.sin(theta);
- var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
- var yh = m.dz*sinphi - m.dx*cosphi;
- var psi = Math.atan2(yh,xh)*180/Math.PI;
- if (psi<0) psi+=360;
- return psi;
-}
+const tiltfixread = require("magnav").tiltfixread;
// Note actual mag is 360-m, error in firmware
function reading() {
@@ -97,30 +80,6 @@ function reading() {
flip(buf,Yoff+80);
}
-function calibrate(){
- var max={x:-32000, y:-32000, z:-32000},
- min={x:32000, y:32000, z:32000};
- var ref = setInterval(()=>{
- var m = Bangle.getCompass();
- max.x = m.x>max.x?m.x:max.x;
- max.y = m.y>max.y?m.y:max.y;
- max.z = m.z>max.z?m.z:max.z;
- min.x = m.x {
- setTimeout(()=>{
- if(ref) clearInterval(ref);
- var offset = {x:(max.x+min.x)/2,y:(max.y+min.y)/2,z:(max.z+min.z)/2};
- var delta = {x:(max.x-min.x)/2,y:(max.y-min.y)/2,z:(max.z-min.z)/2};
- var avg = (delta.x+delta.y+delta.z)/3;
- var scale = {x:avg/delta.x, y:avg/delta.y, z:avg/delta.z};
- resolve({offset:offset,scale:scale});
- },20000);
- });
-}
-
var calibrating=false;
function docalibrate(first){
calibrating=true;
@@ -139,7 +98,7 @@ function docalibrate(first){
buf.drawString("Fig 8s to",120,0);
buf.drawString("Calibrate",120,26);
flip(buf,Yoff);
- calibrate().then((r)=>{
+ require("magnav").calibrate().then((r)=>{
CALIBDATA=r;
require("Storage").write("magnav.json",r);
restart()
diff --git a/apps/magnav/magnav_b2.js b/apps/magnav/magnav_b2.js
index e54280796..319860159 100644
--- a/apps/magnav/magnav_b2.js
+++ b/apps/magnav/magnav_b2.js
@@ -53,24 +53,7 @@ function newHeading(m,h){
var candraw = false;
var CALIBDATA = require("Storage").readJSON("magnav.json",1)||null;
-
-function tiltfixread(O,S){
- "ram"
- var m = Bangle.getCompass();
- var g = Bangle.getAccel();
- m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
- var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
- if (d<0) d+=360;
- var phi = Math.atan(-g.x/-g.z);
- var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
- var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
- var costheta = Math.cos(theta), sintheta = Math.sin(theta);
- var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
- var yh = m.dz*sinphi - m.dx*cosphi;
- var psi = Math.atan2(yh,xh)*180/Math.PI;
- if (psi<0) psi+=360;
- return psi;
-}
+const tiltfixread = require("magnav").tiltfixread;
// Note actual mag is 360-m, error in firmware
function reading() {
@@ -94,30 +77,6 @@ function reading() {
g.flip();
}
-function calibrate(){
- var max={x:-32000, y:-32000, z:-32000},
- min={x:32000, y:32000, z:32000};
- var ref = setInterval(()=>{
- var m = Bangle.getCompass();
- max.x = m.x>max.x?m.x:max.x;
- max.y = m.y>max.y?m.y:max.y;
- max.z = m.z>max.z?m.z:max.z;
- min.x = m.x {
- setTimeout(()=>{
- if(ref) clearInterval(ref);
- var offset = {x:(max.x+min.x)/2,y:(max.y+min.y)/2,z:(max.z+min.z)/2};
- var delta = {x:(max.x-min.x)/2,y:(max.y-min.y)/2,z:(max.z-min.z)/2};
- var avg = (delta.x+delta.y+delta.z)/3;
- var scale = {x:avg/delta.x, y:avg/delta.y, z:avg/delta.z};
- resolve({offset:offset,scale:scale});
- },20000);
- });
-}
-
var calibrating=false;
function docalibrate(first){
calibrating=true;
@@ -137,7 +96,7 @@ function docalibrate(first){
g.drawString("Fig 8s to",88,Ypos);
g.drawString("Calibrate",88,Ypos+18);
g.flip();
- calibrate().then((r)=>{
+ require("magnav").calibrate().then((r)=>{
CALIBDATA=r;
require("Storage").write("magnav.json",r);
restart();
diff --git a/apps/magnav/metadata.json b/apps/magnav/metadata.json
index cba9a1ac3..bd40a08fd 100644
--- a/apps/magnav/metadata.json
+++ b/apps/magnav/metadata.json
@@ -1,7 +1,7 @@
{
"id": "magnav",
"name": "Navigation Compass",
- "version": "0.05",
+ "version": "0.06",
"description": "Compass with linear display as for GPSNAV. Has Tilt compensation and remembers calibration.",
"screenshots": [{"url":"screenshot-b2.png"},{"url":"screenshot-light-b2.png"}],
"icon": "magnav.png",
@@ -11,6 +11,7 @@
"storage": [
{"name":"magnav.app.js","url":"magnav_b1.js","supports":["BANGLEJS"]},
{"name":"magnav.app.js","url":"magnav_b2.js","supports":["BANGLEJS2"]},
+ {"name":"magnav","url":"lib.js"},
{"name":"magnav.img","url":"magnav-icon.js","evaluate":true}
],
"data": [{"name":"magnav.json"}]
diff --git a/apps/messagegui/ChangeLog b/apps/messagegui/ChangeLog
index 228a952de..d061e6642 100644
--- a/apps/messagegui/ChangeLog
+++ b/apps/messagegui/ChangeLog
@@ -86,3 +86,4 @@
0.61: Fix regression where loading into messages app stops back from working (#2398)
0.62: Remove '.show' field, tidyup and fix .open if fast load not enabled
0.63: Fix messages app loading on clock without fast load
+0.64: Ensure we don't get 'undefined' as the message body
diff --git a/apps/messagegui/app.js b/apps/messagegui/app.js
index b158310a1..e944aff3c 100644
--- a/apps/messagegui/app.js
+++ b/apps/messagegui/app.js
@@ -263,6 +263,12 @@ function showMessage(msgid) {
active = "message";
// Normal text message display
var title=msg.title, titleFont = fontLarge, lines;
+ var body=msg.body, bodyFont = fontLarge;
+ // If no body, use the title text instead...
+ if (body===undefined) {
+ body = title;
+ title = undefined;
+ }
if (title) {
var w = g.getWidth()-48;
if (g.setFont(titleFont).stringWidth(title) > w) {
@@ -276,7 +282,7 @@ function showMessage(msgid) {
}
}
// If body of message is only two lines long w/ large font, use large font.
- var body=msg.body, bodyFont = fontLarge;
+
if (body) {
var w = g.getWidth()-10;
if (g.setFont(bodyFont).stringWidth(body) > w * 2) {
diff --git a/apps/messagegui/metadata.json b/apps/messagegui/metadata.json
index 1a7a6c750..3504122f9 100644
--- a/apps/messagegui/metadata.json
+++ b/apps/messagegui/metadata.json
@@ -2,7 +2,7 @@
"id": "messagegui",
"name": "Message UI",
"shortName": "Messages",
- "version": "0.63",
+ "version": "0.64",
"description": "Default app to display notifications from iOS and Gadgetbridge/Android",
"icon": "app.png",
"type": "app",
diff --git a/apps/messageicons/ChangeLog b/apps/messageicons/ChangeLog
index c923b169f..1dd1f3d9e 100644
--- a/apps/messageicons/ChangeLog
+++ b/apps/messageicons/ChangeLog
@@ -2,4 +2,4 @@
0.02: Added several new icons and colors
0.03: Fix icons broken in 0v02 (#2386)
Store all icons in a separate binary file (much faster lookup)
-
+0.04: Add message icon for 'clock'
diff --git a/apps/messageicons/icons/icon_names.json b/apps/messageicons/icons/icon_names.json
index 0085731cc..f7a743e85 100644
--- a/apps/messageicons/icons/icon_names.json
+++ b/apps/messageicons/icons/icon_names.json
@@ -12,8 +12,9 @@
{ "app":"bring", "icon":"bring.png" },
{ "app":"calendar", "icon":"etar.png" },
{ "app":"etar", "icon":"etar.png" },
- { "app":"chat", "icon":"google chat.png" },
+ { "app":"chat", "icon":"google chat.png" },
{ "app":"chrome", "icon":"chrome.png" },
+ { "app":"clock", "icon":"alarm.png" },
{ "app":"corona-warn", "icon":"coronavirus.png" },
{ "app":"bmo", "icon":"bank.png" },
{ "app":"desjardins", "icon":"bank.png" },
diff --git a/apps/messageicons/lib.js b/apps/messageicons/lib.js
index c5be21bb0..314840c13 100644
--- a/apps/messageicons/lib.js
+++ b/apps/messageicons/lib.js
@@ -2,7 +2,7 @@ exports.getImage = function(msg) {
if (msg.img) return atob(msg.img);
let s = (("string"=== typeof msg) ? msg : (msg.src || "")).toLowerCase();
if (msg.id=="music") s="music";
- let match = ",default|0,airbnb|1,alarm|2,alarmclockreceiver|2,amazon shopping|3,bibel|4,bitwarden|5,1password|5,lastpass|5,dashlane|5,bring|6,calendar|7,etar|7,chat|8,chrome|9,corona-warn|10,bmo|11,desjardins|11,rbc mobile|11,nbc|11,rabobank|11,scotiabank|11,td (canada)|11,discord|12,drive|13,element|14,facebook|15,messenger|16,firefox|17,firefox beta|17,firefox nightly|17,f-droid|5,neo store|5,aurora droid|5,github|18,gitlab|19,gmx|20,google|21,google home|22,google play store|23,home assistant|24,instagram|25,kalender|26,keep notes|27,lieferando|28,linkedin|29,maps|30,organic maps|30,osmand|30,mastodon|31,fedilab|31,tooot|31,tusky|31,mattermost|32,n26|33,netflix|34,news|35,cbc news|35,rc info|35,reuters|35,ap news|35,la presse|35,nbc news|35,nextbike|36,nina|37,outlook mail|38,paypal|39,phone|40,plex|41,pocket|42,post & dhl|43,proton mail|44,reddit|45,sync pro|45,sync dev|45,boost|45,infinity|45,slide|45,signal|46,skype|47,slack|48,snapchat|49,starbucks|50,steam|51,teams|52,telegram|53,telegram foss|53,threema|54,tiktok|55,to do|56,opentasks|56,tasks|56,transit|57,twitch|58,twitter|59,uber|60,lyft|60,vlc|61,warnapp|62,whatsapp|63,wordfeud|64,youtube|65,newpipe|65,zoom|66,meet|66,music|67,sms message|0,mail|0,gmail|0,".match(new RegExp(`,${s}\\|(\\d+)`))
+ let match = ",default|0,airbnb|1,alarm|2,alarmclockreceiver|2,amazon shopping|3,bibel|4,bitwarden|5,1password|5,lastpass|5,dashlane|5,bring|6,calendar|7,etar|7,chat|8,chrome|9,clock|2,corona-warn|10,bmo|11,desjardins|11,rbc mobile|11,nbc|11,rabobank|11,scotiabank|11,td (canada)|11,discord|12,drive|13,element|14,facebook|15,messenger|16,firefox|17,firefox beta|17,firefox nightly|17,f-droid|5,neo store|5,aurora droid|5,github|18,gitlab|19,gmx|20,google|21,google home|22,google play store|23,home assistant|24,instagram|25,kalender|26,keep notes|27,lieferando|28,linkedin|29,maps|30,organic maps|30,osmand|30,mastodon|31,fedilab|31,tooot|31,tusky|31,mattermost|32,n26|33,netflix|34,news|35,cbc news|35,rc info|35,reuters|35,ap news|35,la presse|35,nbc news|35,nextbike|36,nina|37,outlook mail|38,paypal|39,phone|40,plex|41,pocket|42,post & dhl|43,proton mail|44,reddit|45,sync pro|45,sync dev|45,boost|45,infinity|45,slide|45,signal|46,skype|47,slack|48,snapchat|49,starbucks|50,steam|51,teams|52,telegram|53,telegram foss|53,threema|54,tiktok|55,to do|56,opentasks|56,tasks|56,transit|57,twitch|58,twitter|59,uber|60,lyft|60,vlc|61,warnapp|62,whatsapp|63,wordfeud|64,youtube|65,newpipe|65,zoom|66,meet|66,music|67,sms message|0,mail|0,gmail|0,".match(new RegExp(`,${s}\\|(\\d+)`))
return require("Storage").read("messageicons.img", (match===null)?0:match[1]*76, 76);
};
diff --git a/apps/messageicons/metadata.json b/apps/messageicons/metadata.json
index 079835a0b..0d1db227b 100644
--- a/apps/messageicons/metadata.json
+++ b/apps/messageicons/metadata.json
@@ -1,7 +1,7 @@
{
"id": "messageicons",
"name": "Message Icons",
- "version": "0.03",
+ "version": "0.04",
"description": "Library containing a list of icons and colors for apps",
"icon": "app.png",
"type": "module",
diff --git a/apps/mixdiganclock/ChangeLog b/apps/mixdiganclock/ChangeLog
index 5354e44a7..13f27c06c 100644
--- a/apps/mixdiganclock/ChangeLog
+++ b/apps/mixdiganclock/ChangeLog
@@ -1,3 +1,4 @@
0.01: fork from miclock, Added compatib with b widgets, devices(dynamic x,y) and themes(dynamic colors)
0.02: Code refactored, change colors in real time
-0.03: Hour point size can be modified on real time.
\ No newline at end of file
+0.03: Hour point size can be modified on real time.
+0.04: Background color can be changed on real time, it will change also the list of fg color
\ No newline at end of file
diff --git a/apps/mixdiganclock/README.md b/apps/mixdiganclock/README.md
index aa860b4d4..d5efbc126 100644
--- a/apps/mixdiganclock/README.md
+++ b/apps/mixdiganclock/README.md
@@ -6,26 +6,28 @@ Compatible with BangleJS1,BangleJS2,and EMSCRIPTENx emulators
## Pictures:
-Bangle JS1
-
+Bangle.JS1

-Screenshot emulator BJS2
-
+Screenshot emulator (BJS2)

-Screenshot emulator BJS1
-
+Screenshot emulator (BJS1)

+SS emulator (BJS1) -color ans aspect changed
+
-SS emulator -color change
-
+SS emulator (BJS1) -Background color changed
+
-SS emulator -color change
+SS emulator (BJS2) -color change

-SS emulator -color change
+SS emulator (BJS2) -Background color changed
+
+
+SS emulator (BJS2) -color changed

## Usage
@@ -35,7 +37,8 @@ Open and see
## Features
Compatibility with devices
-Dynamic Colours and positions
+Dynamic positions x,y for different devices
+Dynamic Colours (FG and BG) and positions
Support for bottom widgets
@@ -43,16 +46,16 @@ Support for bottom widgets
Exit : BTN2 (BJS1)
Exit/launcher : left area
-Change Color : right area
-Increase Hour Points : swipe right
-Decrease Hour Points : swipe left
+Change FG Color : right area
+Increase/Decrease Hour circle/Points : swipe right
+Change BG Color : swipe left
## Coming soon
-A better color combination
+A better combination of colors and aspect for the initial screen (help of designer is welcome)
## Support
This app is so basic that probably the easiest is to just edit the code ;)
-Otherwise you can contact me [here](https://github.com/dapgo/my_espruino_smartwatch_things)
\ No newline at end of file
+Otherwise you can submit issues, request features or make suggestions [here](https://github.com/dapgo/my_espruino_smartwatch_things) or in the global bangle.apps repository
\ No newline at end of file
diff --git a/apps/mixdiganclock/metadata.json b/apps/mixdiganclock/metadata.json
index 8fae2dd8f..daf0924ec 100644
--- a/apps/mixdiganclock/metadata.json
+++ b/apps/mixdiganclock/metadata.json
@@ -1,12 +1,12 @@
{
"id": "mixdiganclock",
"name": "Mix Dig&Anal Clock",
- "version": "0.03",
- "description": "A dual Analog and Digital Clock, based in Mixed Clock, but with more compatibility, change of colors, thicker clock hands... ",
+ "version": "0.04",
+ "description": "A dual Analog and Digital Clock, that gives the user the power to improve the UI/UX on realtime. Too much sun and polarized sunglasses should not be a problem to read the time anymore if you change colors or aspect. Originally based in Mixed Clock ",
"icon": "mixdiganclock.png",
"type": "clock",
"tags": "clock",
- "screenshots": [{"url":"pic_mixdigan_bjs1.jpg"}],
+ "screenshots": [{"url":"ss_mixdigan_ems.png"}],
"supports": ["BANGLEJS","BANGLEJS"],
"readme": "README.md",
"allow_emulator": true,
diff --git a/apps/mixdiganclock/mixdiganclock.app.js b/apps/mixdiganclock/mixdiganclock.app.js
index bd36c0f32..940e1a7e2 100644
--- a/apps/mixdiganclock/mixdiganclock.app.js
+++ b/apps/mixdiganclock/mixdiganclock.app.js
@@ -2,37 +2,47 @@
compatible with BJS1, BJS2 and bottom widgets
*/
var locale = require("locale");
-var v_mode_debug=0; //, 0=no, 1 min, 2 prone detail
+var v_mode_debug=0 //, 0=no, 1 min, 2 prone detail
var v_model=process.env.BOARD;
+var v_array4colors=0; // 0 undef, 1 forDark, 2 forLight
+var a_colors=[]; //new Array(), values will depend on b_isarray4dark
var LastDrawDay; // to notice a change and repaint static texts
-//RGB565 0x White , black, 'Orange',blue,red, olive,...
-var a_colors= [0xFFFF,0x0000, 0xFD20, 0x001F,0xF800,0x7be0,0x780F,0x07E0]; //new Array(0xFFFF
var Radius= []; //new Array();
var TxtPosition=[];
var v_bfont_size;
var v_vfont_size;
+var v_str_pix_width; // to clear timer area
var v_color1;
var v_color2;
var v_color3;
-var v_color_erase;
+var v_color_erase; //dynamic
var v_count_col;
var rect = Bangle.appRect;
var v_center_x;
var v_center_y;
-if (v_mode_debug>0) console.log("a_colors.length "+a_colors.length);
-g.clear();
+g.clear(); //ONLY 1ST TIME
//show the exit button
-//Bangle.setUI();
Bangle.setUI("clock"); //implies center button for launcher
-/*{
- mode : "custom",
- back : Bangle.showLauncher
-});*/
Bangle.loadWidgets();
-
+function getColorArray4BG() { //1st=0 1st compatible color (dark/light theme)
+ var var_bg=g.getBgColor();
+ if (v_mode_debug>1) console.log(g.theme);
+ if (v_mode_debug>0) console.log("func getbgcolor: "+var_bg+" g.theme.bg: "+g.theme.bg);
+ if (v_array4colors==0) {
+ if (g.theme.dark==1) v_array4colors=1;
+ else if (g.theme.dark==0) v_array4colors=2;
+ }
+ //for dark/black bg
+ if (v_array4colors==1) a_colors= [0xFFFF, 0x0000, 0xFD20, 0x001F,0xF800,0x7be0,0x780F,0x07E0,0x07FF,0x7BEF,0xFFE0,0xFFBF00];
+ //for light/white theme
+ if (v_array4colors==2) a_colors= [0x0000, 0xFFFF, 0xFD20, 0x001F,0xF800,0x000F,0x780F,0x07E0,0xFFBF00];
+ v_color_erase=a_colors[1];
+ if (v_mode_debug>1) console.log(" erase: "+v_color_erase);
+ return (v_array4colors); //opt as using global vars
+}
function setVariables() {
// different values depending on loaded widgets or not, so after load widgets
@@ -43,30 +53,52 @@ function setVariables() {
TxtPosition = {
"x1": 3, "x2": g.getWidth()-3,
"y1": rect.y+17, "y2": rect.y2-6,
- "x_HH": g.getWidth()/2 ,"y_mm": v_center_y+32
+ "x_HH": g.getWidth()/2 ,"y_mm": v_center_y+32 //center position for setFontAlign0,0
};
- //emuls EMSCRIPTEN,EMSCRIPTEN2
- v_count_col=2; //1st=0 1st compatible color (dark/light theme)
- v_color_erase=g.getBgColor();
+ v_count_col=2; //realtime colors(avoid b/w) begin from this array position
+ getColorArray4BG(); //set colors
+ //v_color_erase=g.getBgColor();
+
if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') {
Radius = { "center": 7, "hour": 50, "min": 70, "dots": 88,"circleH":6,"circleM":2 };
v_bfont_size=3;
v_vfont_size=35;
- v_color1=2; // orange
- v_color2=4;
- v_color3=0; //white , for hands PEND replace hardcoded by logic
+ //1st watchface is multicolor
+ v_color1=3; //ring orange
+ v_color2=5; //text red
+ v_color3=0; //hands, opposite to bg
}else{
Radius = { "center": 5, "hour": 35, "min": 50, "dots": 60, "circleH":5,"circleM":2 };
v_bfont_size=2;
v_vfont_size=22;
- v_color1=3; // blue
- v_color2=1;
- v_color3=1; //opposite to bg, for hands PEND replace hardcoded by logic
+ v_color1=4; //ring
+ v_color2=8; //text
+ v_color3=0; //hands, opposite to bg
}
- if (v_mode_debug>0) console.log("set vars for: "+v_model);
}
+function ClearScreen(){
+ //avoid widget areas
+ // var var_bg=g.getBgColor();
+ if (v_mode_debug>1) console.log("ClearScreen getbgcolor: "+g.getBgColor()+" erasecl: "+v_color_erase);
+ if (v_mode_debug>1) console.log("rect: "+rect.y+" "+rect.x2+" "+rect.y2);
+ //g.setColor(v_color_erase);
+ g.setBgColor(v_color_erase);
+ //Fill a rectangular area in the Background Color
+ g.clearRect(rect.x, rect.y, rect.x2, rect.y2);
+ g.flip();
+}
+
+function ClearTimerArea(){
+ g.setBgColor(v_color_erase);
+ // g.setBgColor(0xFFFFFF-a_colors[v_color1]); //kind of inverted clr just for testing
+ if (v_mode_debug>1) console.log("ClearTimerArea getbgcolor: "+g.getBgColor()+" erasecl: "+v_color_erase);
+ if (v_mode_debug>1) console.log("txt x: "+TxtPosition.x_HH+" y "+TxtPosition.y_mm+" w "+v_str_pix_width);
+ //Fill a rectangular area in the Background Color, coords depends of setFontAlign 0,0=center
+ g.clearRect(TxtPosition.x_HH-(v_str_pix_width/2), TxtPosition.y_mm-(v_vfont_size/2), TxtPosition.x_HH+(v_str_pix_width/2), TxtPosition.y_mm+(v_vfont_size/2));
+ g.flip();
+}
function rotatePoint(x, y, d) {
rad = -1 * d / 180 * Math.PI;
@@ -130,8 +162,7 @@ function drawMixedClock() {
var radius;
//Call function only after a change of day
if (LastDrawDay!=locale.dow(date,true)) drawDailyTxt();
- //ERASE previous hands
- // erase last MINutes hand
+ //ERASE previous last MINutes hand
g.setColor(v_color_erase);
point = rotatePoint(0, Radius.min, (minute - 1) * 6);
g.drawLine(v_center_x, v_center_y, point[0], point[1]);
@@ -149,8 +180,6 @@ function drawMixedClock() {
//to increase thicknes
g.drawLine(v_center_x+1, v_center_y, point[0]+1, point[1]);
- // here time DIGITs are draw under hands
-
// draw new MINute hand
point = rotatePoint(0, Radius.min, minute * 6);
g.setColor(a_colors[v_color3]);
@@ -164,13 +193,20 @@ function drawMixedClock() {
//to increase thicknes
g.drawLine(v_center_x+1, v_center_y, point[0]+1, point[1]);
- // draw DIGITs of time above hands for better UX
+
+ //drawing Time DIGITs above hands for allegedly better UX
//g.setFont("6x8", 3); 3 bigger size
+ ClearTimerArea();
g.setFontVector(v_vfont_size);
g.setColor(a_colors[v_color2]);
g.setFontAlign(0, 0);
- //by default 24H, to use format config 12H 24H read from locale
- g.drawString(dateArray[4].substr(0, 5), TxtPosition.x_HH, TxtPosition.y_mm, true);
+ //by default 24H, to use format config 12H 24H read from locale
+ //x,y,solid - For bitmap fonts, true empty pixels be filled with bgcolor¿theme?
+ //true clean previous text but default is not our erase
+ //false write oiver previus text
+ //g.drawString(dateArray[4].substr(0, 5), TxtPosition.x_HH, TxtPosition.y_mm, false);
+ v_str_pix_width=g.stringWidth(dateArray[4].substr(0, 5));
+ g.drawString(dateArray[4].substr(0, 5), TxtPosition.x_HH, TxtPosition.y_mm);
// the central point requires redrawing because hands draw over it
g.setColor(a_colors[v_color1]);
g.fillCircle(v_center_x, v_center_y, Radius.center);
@@ -182,7 +218,7 @@ function UserInput(){
Bangle.showLauncher();
break;
case 2:
- //testing to improve
+ //change color but monocolor watchface
if (v_mode_debug>0) console.log("v_count_col/total: "+v_count_col+"/"+a_colors.length);
if (v_count_col {
if(dir == 1) {
drawStaticRing(v_color_erase);
- if (Radius.circleH<13) Radius.circleH++;
+ if (Radius.circleH<13) Radius.circleH++
+ else Radius.circleH=2;
if (v_mode_debug>0) console.log("radio: "+Radius.circleH);
drawStaticRing(a_colors[v_color1]);
}
- else {
- drawStaticRing(v_color_erase);
- if (Radius.circleH>1) Radius.circleH--;
- if (v_mode_debug>0) console.log("radio: "+Radius.circleH);
- drawStaticRing(a_colors[v_color1]);
+ else { //swipe left, pend to refactor
+ if (v_array4colors==1) { //if black bg
+ v_array4colors=2; // then white
+ getColorArray4BG(); //set new list of colors
+ g.setBgColor( v_color_erase);// 0 white, 1 black
+ ClearScreen();
+ //g.clear();//impact on widgets
+ drawStaticRing(a_colors[v_color1]);
+ drawDailyTxt(); //1st time
+ drawMixedClock();
+ } else if (v_array4colors==2) { //if white bg
+ v_array4colors=1;
+ getColorArray4BG();
+ console.log(a_colors[1]);
+ g.setBgColor(v_color_erase);// 0 white, 1 black
+ //g.clear();
+ ClearScreen();
+ drawStaticRing(a_colors[v_color1]);
+ drawDailyTxt(); //1st time
+ drawMixedClock(); //or just wait?
+ }
}
});
}
@@ -223,8 +277,7 @@ Bangle.on('lcdPower', function(on) {
setVariables();
Bangle.drawWidgets();
UserInput();
-
-setInterval(drawMixedClock, 5E3);
-drawStaticRing(a_colors[v_color1]);
-drawDailyTxt(); //1st time
+setInterval(drawMixedClock, 30000);//not realtime update
+drawStaticRing(a_colors[v_color1]);
+drawDailyTxt();
drawMixedClock();
diff --git a/apps/mixdiganclock/mixdiganclock.info b/apps/mixdiganclock/mixdiganclock.info
index f9057ef5a..9675614c1 100644
--- a/apps/mixdiganclock/mixdiganclock.info
+++ b/apps/mixdiganclock/mixdiganclock.info
@@ -1 +1 @@
-{"id":"mixdiganclock","name":"Mix Dig&Anal","type":"clock","src":"mixdiganclock.app.js","icon":"mixdiganclock.img","version":"0.02","tags":"clock","files":"mixdiganclock.info,mixdiganclock.app.js,mixdiganclock.img"}
\ No newline at end of file
+{"id":"mixdiganclock","name":"Mix Dig&Anal","type":"clock","src":"mixdiganclock.app.js","icon":"mixdiganclock.img","version":"0.04","tags":"clock","files":"mixdiganclock.info,mixdiganclock.app.js,mixdiganclock.img"}
\ No newline at end of file
diff --git a/apps/mixdiganclock/photo_mixdigan_bjs1.jpg b/apps/mixdiganclock/photo_mixdigan_bjs1.jpg
new file mode 100644
index 000000000..023183a59
Binary files /dev/null and b/apps/mixdiganclock/photo_mixdigan_bjs1.jpg differ
diff --git a/apps/mixdiganclock/pic_mixdigan_bjs1.jpg b/apps/mixdiganclock/pic_mixdigan_bjs1.jpg
deleted file mode 100644
index eeb23a8ee..000000000
Binary files a/apps/mixdiganclock/pic_mixdigan_bjs1.jpg and /dev/null differ
diff --git a/apps/mixdiganclock/ss_mixdigan_ems_2_bgcl.png b/apps/mixdiganclock/ss_mixdigan_ems_2_bgcl.png
new file mode 100644
index 000000000..8be96ae57
Binary files /dev/null and b/apps/mixdiganclock/ss_mixdigan_ems_2_bgcl.png differ
diff --git a/apps/mixdiganclock/ss_mixdigan_ems_aspect.png b/apps/mixdiganclock/ss_mixdigan_ems_aspect.png
new file mode 100644
index 000000000..05784b606
Binary files /dev/null and b/apps/mixdiganclock/ss_mixdigan_ems_aspect.png differ
diff --git a/apps/mixdiganclock/ss_mixdigan_ems_bgcl.png b/apps/mixdiganclock/ss_mixdigan_ems_bgcl.png
new file mode 100644
index 000000000..8111162b3
Binary files /dev/null and b/apps/mixdiganclock/ss_mixdigan_ems_bgcl.png differ
diff --git a/apps/mosaic/ChangeLog b/apps/mosaic/ChangeLog
index f26a9df0a..acebd4321 100644
--- a/apps/mosaic/ChangeLog
+++ b/apps/mosaic/ChangeLog
@@ -1,2 +1,3 @@
0.01: First release
0.02: Use locale time
+0.03: Change for fast loading, use widget_utils to hide widgets
\ No newline at end of file
diff --git a/apps/mosaic/README.md b/apps/mosaic/README.md
index b2f31aef2..05a39c556 100644
--- a/apps/mosaic/README.md
+++ b/apps/mosaic/README.md
@@ -4,7 +4,7 @@ A fabulously colourful clock!
* Clearly shows the time on a colourful background that changes every minute.
* Dark and Light theme compatible, with a setting to override the digit colour scheme.
-* Show or hide widgets with a setting (default shows widgets).
+* Show or hide widgets with a setting (default hides widgets, swipe down to show them thanks to `widget_utils`).


diff --git a/apps/mosaic/metadata.json b/apps/mosaic/metadata.json
index 92548ce9c..d6eff12a7 100644
--- a/apps/mosaic/metadata.json
+++ b/apps/mosaic/metadata.json
@@ -2,7 +2,7 @@
"id":"mosaic",
"name":"Mosaic Clock",
"shortName": "Mosaic Clock",
- "version": "0.02",
+ "version": "0.03",
"description": "A fabulously colourful clock",
"readme": "README.md",
"icon":"mosaic.png",
@@ -15,5 +15,8 @@
{"name":"mosaic.app.js","url":"mosaic.app.js"},
{"name":"mosaic.settings.js","url":"mosaic.settings.js"},
{"name":"mosaic.img","url":"mosaic.icon.js","evaluate":true}
+ ],
+ "data": [
+ {"name":"mosaic.settings.json"}
]
}
diff --git a/apps/mosaic/mosaic.app.js b/apps/mosaic/mosaic.app.js
index 03eb417fd..7fcb631f1 100644
--- a/apps/mosaic/mosaic.app.js
+++ b/apps/mosaic/mosaic.app.js
@@ -2,6 +2,7 @@ Array.prototype.sample = function(){
return this[Math.floor(Math.random()*this.length)];
};
+{
const SETTINGS_FILE = "mosaic.settings.json";
let settings;
let theme;
@@ -24,11 +25,11 @@ let digits = [
E.toArrayBuffer(atob("BQcB/Gsex+A="))
];
-function loadSettings() {
+let loadSettings = function() {
settings = require("Storage").readJSON(SETTINGS_FILE,1)|| {'showWidgets': false, 'theme':'System'};
}
-function loadThemeColors() {
+let loadThemeColors = function() {
theme = {fg: g.theme.fg, bg: g.theme.bg};
if (settings.theme === "Dark") {
theme.fg = g.toColor(1,1,1);
@@ -40,7 +41,7 @@ function loadThemeColors() {
}
}
-function queueDraw(seconds) {
+let queueDraw = function(seconds) {
let millisecs = seconds * 1000;
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
@@ -49,7 +50,7 @@ function queueDraw(seconds) {
}, millisecs - (Date.now() % millisecs));
}
-function draw() {
+let draw = function() {
// draw colourful grid
for (let i_x = 0; i_x < num_squares_w; i_x++) {
for (let i_y = 0; i_y < num_squares_h; i_y++) {
@@ -87,8 +88,6 @@ let o_h = Math.floor((g.getHeight() - num_squares_h * s+offset_widgets)/2);
let mid_x = Math.floor(num_squares_w/2);
let mid_y = Math.floor((num_squares_h-1)/2);
-draw();
-
Bangle.on('lcdPower',on=>{
if (on) {
draw(); // draw immediately, queue redraw
@@ -98,8 +97,23 @@ Bangle.on('lcdPower',on=>{
}
});
-Bangle.setUI('clock');
+Bangle.setUI({
+ mode : 'clock',
+ remove : function() {
+ // Called to unload all of the clock app
+ if (drawTimeout) clearTimeout(drawTimeout);
+ drawTimeout = undefined;
+ delete Array.prototype.sample;
+ require('widget_utils').show(); // re-show widgets
+ }
+});
+
+Bangle.loadWidgets();
if (settings.showWidgets) {
- Bangle.loadWidgets();
Bangle.drawWidgets();
+} else {
+ require("widget_utils").swipeOn(); // hide widgets, make them visible with a swipe
}
+
+draw();
+}
\ No newline at end of file
diff --git a/apps/neonx/ChangeLog b/apps/neonx/ChangeLog
index c1a50ecd7..e78686a00 100644
--- a/apps/neonx/ChangeLog
+++ b/apps/neonx/ChangeLog
@@ -2,4 +2,5 @@
0.02: Optional fullscreen mode
0.03: Optional show lock status via color
0.04: Ensure that widgets are always hidden in fullscreen mode
-0.05: Better lock/unlock animation
\ No newline at end of file
+0.05: Better lock/unlock animation
+0.06: Use widget_utils.
diff --git a/apps/neonx/metadata.json b/apps/neonx/metadata.json
index ee99f98b8..c273cb05a 100644
--- a/apps/neonx/metadata.json
+++ b/apps/neonx/metadata.json
@@ -2,7 +2,7 @@
"id": "neonx",
"name": "Neon X & IO X Clock",
"shortName": "Neon X Clock",
- "version": "0.05",
+ "version": "0.06",
"description": "Pebble Neon X & Neon IO X for Bangle.js",
"icon": "neonx.png",
"type": "clock",
diff --git a/apps/neonx/neonx.app.js b/apps/neonx/neonx.app.js
index fd30fa30f..7fcf01bde 100644
--- a/apps/neonx/neonx.app.js
+++ b/apps/neonx/neonx.app.js
@@ -19,6 +19,7 @@ let saved_settings = require('Storage').readJSON('neonx.json', 1) || settings;
for (const key in saved_settings) {
settings[key] = saved_settings[key]
}
+let widget_utils = require('widget_utils');
const digits = {
@@ -133,7 +134,7 @@ function drawAnimated(){
function _draw(date, xc){
// Depending on the settings, we clear all widgets or draw those.
if(settings.fullscreen){
- for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+ widget_utils.hide();
} else {
Bangle.drawWidgets();
}
@@ -210,4 +211,4 @@ g.clear(1);
Bangle.setUI("clock");
Bangle.loadWidgets();
-draw();
\ No newline at end of file
+draw();
diff --git a/apps/notanalog/ChangeLog b/apps/notanalog/ChangeLog
index 07430406a..094125f52 100644
--- a/apps/notanalog/ChangeLog
+++ b/apps/notanalog/ChangeLog
@@ -2,4 +2,5 @@
0.02: 12k steps are 360 degrees - improves readability of steps.
0.03: Battery improvements through sleep (no minute updates) and partial updates of drawing.
0.04: Use alarm for timer instead of own alarm implementation.
-0.05: Use internal step counter if no widget is available.
\ No newline at end of file
+0.05: Use internal step counter if no widget is available.
+0.06: Use widget_utils.
diff --git a/apps/notanalog/metadata.json b/apps/notanalog/metadata.json
index 81d79f4f2..319d396a9 100644
--- a/apps/notanalog/metadata.json
+++ b/apps/notanalog/metadata.json
@@ -3,7 +3,7 @@
"name": "Not Analog",
"shortName":"Not Analog",
"icon": "notanalog.png",
- "version":"0.05",
+ "version":"0.06",
"readme": "README.md",
"supports": ["BANGLEJS2"],
"description": "An analog watch face for people that can not read analog watch faces.",
diff --git a/apps/notanalog/notanalog.app.js b/apps/notanalog/notanalog.app.js
index 3c01a921e..29fb1730f 100644
--- a/apps/notanalog/notanalog.app.js
+++ b/apps/notanalog/notanalog.app.js
@@ -4,6 +4,7 @@
const TIMER_IDX = "notanalog";
const locale = require('locale');
const storage = require('Storage')
+const widget_utils = require('widget_utils');
const SETTINGS_FILE = "notanalog.setting.json";
let settings = {
alarm: -1,
@@ -460,10 +461,8 @@ Bangle.setUI("clock");
Bangle.loadWidgets();
/*
* we are not drawing the widgets as we are taking over the whole screen
- * so we will blank out the draw() functions of each widget and change the
- * area to the top bar doesn't get cleared.
*/
-for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+widget_utils.hide();
// Clear the screen once, at startup and draw clock
// g.setTheme({bg:"#fff",fg:"#000",dark:false}).clear();
diff --git a/apps/pinsafe/ChangeLog b/apps/pinsafe/ChangeLog
new file mode 100644
index 000000000..ec66c5568
--- /dev/null
+++ b/apps/pinsafe/ChangeLog
@@ -0,0 +1 @@
+0.01: Initial version
diff --git a/apps/pinsafe/README.md b/apps/pinsafe/README.md
new file mode 100644
index 000000000..bebeaeeb3
--- /dev/null
+++ b/apps/pinsafe/README.md
@@ -0,0 +1,8 @@
+# PIN safe
+Stores several encrypted PINs on your watch. You can use one key to decode them all.
+This is safe, as long as:
+- None of the PINs can be guessed by a brute force attack.
+- All of the PINs are random.
+- Your key is long enough (preferably as long as your PINs).
+
+This app requires a keyboard!
diff --git a/apps/pinsafe/app-icon.js b/apps/pinsafe/app-icon.js
new file mode 100644
index 000000000..03a88f805
--- /dev/null
+++ b/apps/pinsafe/app-icon.js
@@ -0,0 +1 @@
+atob("MDCBAAAAB+AAAAAAH/gAAAAAfD4AAAAB8A+AAAAHwAPgAAAfAAD4AAD4AAAfAA/gAAAH8B8AAAAA+BgAAAAAGBgAAAAAGBgAAAAAGBgAAAAAGBgAAAAAGBgAAAAAGBgAAAOAGAwAAAMAMAwAAAYAMAwAAAYAMAwAAAwAMAwAABwAMAwAABgAYAYAQDAAYAYAYHAAYAYAcGAAYAMAGMAAwAMAD8AAwAMAB4ABgAGAAwABgAGAAAABgADAAAADAADAAAAHAABgAAAGAABgAAAMAAAwAAAMAAAYAAAYAAAcAAAwAAAMAABwAAAGAABgAAADAADAAAADgAGAAAABwAMAAAAA4A4AAAAAOBwAAAAAHDgAAAAAD/AAAAAAA8AAAAAAAYAAAA==")
diff --git a/apps/pinsafe/app.js b/apps/pinsafe/app.js
new file mode 100644
index 000000000..873eb5c57
--- /dev/null
+++ b/apps/pinsafe/app.js
@@ -0,0 +1,163 @@
+var Layout = require("Layout");
+var myTimeout;
+var pins = Object.assign(require('Storage').readJSON("pinsafe.json", true) || {});
+function mainMenu() {
+ if (myTimeout) clearTimeout(myTimeout);
+ var menu = {
+ "" : {title : "Decode:"},
+ "< Back" : Bangle.load
+ };
+ if (Object.keys(pins).length==0) Object.assign(menu, {"NO CARDS":""});
+ else for (let id in pins) {
+ let p=pins[id];
+ menu[id]=()=>{decode(p);};
+ }
+ menu["Add Card"]=addCard;
+ menu["Remove Card"]=removeCard;
+ g.clear();
+ E.showMenu(menu);
+}
+function decode(pin) {
+ showNumpad("Key:", function() {
+ if (key.length==0) mainMenu();
+ else {
+ var pinDecrypted="";
+ for (let n=0;n{mainMenu();}}
+ ], lazy:true});
+ g.clear();
+ showPin.render();
+ myTimeout = setTimeout(Bangle.load, 10000);
+ }
+ });
+}
+function showNumpad(text, callback) {
+ E.showMenu();
+ key="";
+ function addDigit(digit) {
+ key+=digit;
+ Bangle.buzz(20);
+ update();
+ }
+ function update() {
+ g.reset();
+ g.clearRect(0,0,g.getWidth(),23);
+ g.setFont("Vector:24").setFontAlign(1,0).drawString(text+key,g.getWidth(),12);
+ }
+ ds="12%";
+ var numPad = new Layout ({
+ type:"v", c: [{
+ type:"v", c: [
+ {type:"", height:24},
+ {type:"h",filly:1, c: [
+ {type:"btn", font:ds, width:58, label:"7", cb:l=>{addDigit("7");}},
+ {type:"btn", font:ds, width:58, label:"8", cb:l=>{addDigit("8");}},
+ {type:"btn", font:ds, width:58, label:"9", cb:l=>{addDigit("9");}}
+ ]},
+ {type:"h",filly:1, c: [
+ {type:"btn", font:ds, width:58, label:"4", cb:l=>{addDigit("4");}},
+ {type:"btn", font:ds, width:58, label:"5", cb:l=>{addDigit("5");}},
+ {type:"btn", font:ds, width:58, label:"6", cb:l=>{addDigit("6");}}
+ ]},
+ {type:"h",filly:1, c: [
+ {type:"btn", font:ds, width:58, label:"1", cb:l=>{addDigit("1");}},
+ {type:"btn", font:ds, width:58, label:"2", cb:l=>{addDigit("2");}},
+ {type:"btn", font:ds, width:58, label:"3", cb:l=>{addDigit("3");}}
+ ]},
+ {type:"h",filly:1, c: [
+ {type:"btn", font:ds, width:58, label:"0", cb:l=>{addDigit("0");}},
+ {type:"btn", font:ds, width:58, label:"C", cb:l=>{key=key.slice(0,-1); update();}},
+ {type:"btn", font:ds, width:58, id:"OK", label:"OK", cb:callback}
+ ]}
+ ]}
+ ], lazy:true});
+ g.clear();
+ numPad.render();
+ update();
+}
+function removeCard() {
+ var menu = {
+ "" : {title : "select card"},
+ "< Back" : mainMenu
+ };
+ if (Object.keys(pins).length==0) Object.assign(menu, {"NO CARDS":""});
+ else for (let c in pins) {
+ let card=c;
+ menu[c]=()=>{
+ E.showMenu();
+ var confirmRemove = new Layout (
+ {type:"v", c: [
+ {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Delete"},
+ {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:card+"?"},
+ {type:"h", c: [
+ {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{
+ delete pins[card];
+ require('Storage').writeJSON("pinsafe.json", pins);
+ mainMenu();
+ }},
+ {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{mainMenu();}}
+ ]}
+ ], lazy:true});
+ g.clear();
+ confirmRemove.render();
+ };
+ }
+ E.showMenu(menu);
+}
+function addCard() {
+ var infoScreen = new Layout({
+ type:"v", c: [
+ {type:"txt", font:"10%", label:"Enter a name, PIN\nand key for your\ncard. The PIN will\nbe stored on your\ndevice in encrypted\nform.\nTap to continue!", cb:l=>{
+ require("textinput").input({text:""}).then(result => {
+ if (pins[result]!=undefined) {
+ E.showMenu();
+ var alreadyExists = new Layout (
+ {type:"v", c: [
+ {type:"txt", font:Math.min(15,100/result.length)+"%", pad:1, fillx:1, filly:1, label:result},
+ {type:"txt", font:"12%", pad:1, fillx:1, filly:1, label:"already exists."},
+ {type:"h", c: [
+ {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{encodeCard(result);}},
+ {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "CANCEL", cb:l=>{mainMenu();}}
+ ]}
+ ], lazy:true});
+ g.clear();
+ alreadyExists.render();
+ } else
+ encodeCard(result);
+ });
+ }}
+ ]
+ });
+ g.clear();
+ infoScreen.render();
+}
+function encodeCard(name) {
+ showNumpad("PIN:", function() {
+ if (key.length==0) mainMenu();
+ else {
+ var pin=key;
+ showNumpad("Key:", function() {
+ if (key.length==0) mainMenu();
+ else {
+ var pinEncrypted="";
+ for (let n=0;ne);
log_debug("Loading "+lines.length+" slides");
slides = lines.map(line=>{let s=line.split(";");return [+s[0],s[1]];});
+ //all numbers and always strictly increasing
+ if(slides.filter(s=>isNaN(+s[1])).length == 0 &&
+ slides.map((p,i,a)=>p[1]-(a[i-1]?a[i-1][1]:undefined)).filter(p=>p<=0).length == 0) {
+ slides = fillBlanks(slides);
+ }
}
@@ -147,6 +191,7 @@ function stopStart() {
} else {
draw();
}
+ saveState();
}
function setButtonImages() {
@@ -171,6 +216,7 @@ function lapReset() {
g.clearRect(0,24,w,h);
draw();
}
+ saveState();
}
// simple on screen button class
@@ -268,5 +314,10 @@ g.fillRect(0,0,w,h);
Bangle.loadWidgets();
Bangle.drawWidgets();
readSlides();
-draw();
+setButtonImages();
+if (running) {
+ startTimer();
+} else {
+ draw();
+}
setWatch(() => load(), BTN, { repeat: false, edge: "falling" });
diff --git a/apps/quicklaunch/ChangeLog b/apps/quicklaunch/ChangeLog
index 3dcb9a2d2..2f9f648dd 100644
--- a/apps/quicklaunch/ChangeLog
+++ b/apps/quicklaunch/ChangeLog
@@ -6,3 +6,4 @@
0.06: Use Bangle.load() to allow 'fast switch' for apps where it's available.
0.07: Revert version 0.06. This version is the same as 0.05.
0.08: Respect appRect on touch events
+0.09: Do not react if clkinfo is focused
diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js
index b00e76e23..774b41d3d 100644
--- a/apps/quicklaunch/boot.js
+++ b/apps/quicklaunch/boot.js
@@ -10,6 +10,7 @@
Bangle.on("touch", (_,e) => {
if (!Bangle.CLOCK) return;
+ if (Bangle.CLKINFO_FOCUS) return;
let R = Bangle.appRect;
if (e.x < R.x || e.x > R.x2 || e.y < R.y || e.y > R.y2 ) return;
if (settings.tapapp.src){ if (!storage.read(settings.tapapp.src)) reset("tapapp"); else load(settings.tapapp.src); }
@@ -17,6 +18,7 @@
Bangle.on("swipe", (lr,ud) => {
if (!Bangle.CLOCK) return;
+ if (Bangle.CLKINFO_FOCUS) return;
if (lr == -1 && settings.leftapp && settings.leftapp.src){ if (settings.leftapp.name == "Show Launcher") Bangle.showLauncher(); else if (!storage.read(settings.leftapp.src)) reset("leftapp"); else load(settings.leftapp.src); }
if (lr == 1 && settings.rightapp && settings.rightapp.src){ if (settings.rightapp.name == "Show Launcher") Bangle.showLauncher(); else if (!storage.read(settings.rightapp.src)) reset("rightapp"); else load(settings.rightapp.src); }
diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json
index 033eaaf25..599929cda 100644
--- a/apps/quicklaunch/metadata.json
+++ b/apps/quicklaunch/metadata.json
@@ -2,7 +2,7 @@
"id": "quicklaunch",
"name": "Quick Launch",
"icon": "app.png",
- "version":"0.08",
+ "version":"0.09",
"description": "Tap or swipe left/right/up/down on your clock face to launch up to five apps of your choice. Configurations can be accessed through Settings->Apps.",
"type": "bootloader",
"tags": "tools, system",
diff --git a/apps/recorder/ChangeLog b/apps/recorder/ChangeLog
index a4d0b7e88..c4d1fa8c1 100644
--- a/apps/recorder/ChangeLog
+++ b/apps/recorder/ChangeLog
@@ -24,3 +24,4 @@
0.18: Improve widget load speed, allow currently recording track to be plotted in openstmap
0.19: Fix track plotting code
0.20: Automatic translation of some more strings.
+0.21: Speed report now uses speed units from locale
diff --git a/apps/recorder/app.js b/apps/recorder/app.js
index 8dcc4c3ed..8ac3ff627 100644
--- a/apps/recorder/app.js
+++ b/apps/recorder/app.js
@@ -348,7 +348,12 @@ function viewTrack(filename, info) {
infc[i]++;
}
} else if (style=="Speed") {
- title = /*LANG*/"Speed (m/s)";
+ // use locate to work out units
+ var localeStr = require("locale").speed(1,5); // get what 1kph equates to
+ let units = localeStr.replace(/[0-9.]*/,"");
+ var factor = parseFloat(localeStr)*3.6; // m/sec to whatever out units are
+ // title
+ title = /*LANG*/"Speed"+` (${units})`;
var latIdx = info.fields.indexOf("Latitude");
var lonIdx = info.fields.indexOf("Longitude");
// skip until we find our first data
@@ -381,7 +386,7 @@ function viewTrack(filename, info) {
} else throw new Error("Unknown type "+style);
var min=100000,max=-100000;
for (var i=0;i0) infn[i]/=infc[i];
+ if (infc[i]>0) infn[i]=factor*infn[i]/infc[i];
var n = infn[i];
if (n>max) max=n;
if (n {
g.setClipRect(0,0,g.getWidth()-1, g.getHeight()-1);
};
let clockInfoItems = require("clock_info").load();
-let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { x:126, y:24, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#f00"/*red*/ });
-let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { x:0, y:115, w:50, h:40, draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (bgColor=="#000")?"#f00"/*red*/:g.theme.fg });
+let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { app:"slopeclockpp",x:126, y:24, w:50, h:40, draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl : "#f00"/*red*/ });
+let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { app:"slopeclockpp",x:0, y:115, w:50, h:40, draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (bgColor=="#000")?"#f00"/*red*/:g.theme.fg });
// Show launcher when middle button pressed
Bangle.setUI({
diff --git a/apps/slopeclockpp/metadata.json b/apps/slopeclockpp/metadata.json
index fbab02fca..30bc2ea3e 100644
--- a/apps/slopeclockpp/metadata.json
+++ b/apps/slopeclockpp/metadata.json
@@ -1,12 +1,13 @@
{ "id": "slopeclockpp",
"name": "Slope Clock ++",
- "version":"0.08",
+ "version":"0.09",
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which shows extra information and allows the colors to be selected.",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
"type": "clock",
"tags": "clock",
"supports" : ["BANGLEJS2"],
+ "dependencies" : { "clock_info":"module" },
"readme": "README.md",
"storage": [
{"name":"slopeclockpp.app.js","url":"app.js"},
diff --git a/apps/stopwatch/ChangeLog b/apps/stopwatch/ChangeLog
index 14c84afd5..c4f382aa9 100644
--- a/apps/stopwatch/ChangeLog
+++ b/apps/stopwatch/ChangeLog
@@ -1,3 +1,4 @@
0.01: first release
0.02: Adjust for touch events outside of screen g dimensions
0.03: Do not register as watch, manually start clock on button
+0.04: Keep running in background by saving state
diff --git a/apps/stopwatch/metadata.json b/apps/stopwatch/metadata.json
index 7840dd9b5..bbc2dc181 100644
--- a/apps/stopwatch/metadata.json
+++ b/apps/stopwatch/metadata.json
@@ -1,7 +1,7 @@
{
"id": "stopwatch",
"name": "Stopwatch Touch",
- "version": "0.03",
+ "version": "0.04",
"description": "A touch based stop watch for Bangle JS 2",
"icon": "stopwatch.png",
"screenshots": [{"url":"screenshot1.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"}],
@@ -11,5 +11,8 @@
"storage": [
{"name":"stopwatch.app.js","url":"stopwatch.app.js"},
{"name":"stopwatch.img","url":"stopwatch.icon.js","evaluate":true}
+ ],
+ "data": [
+ {"name":"stopwatch.json"}
]
}
diff --git a/apps/stopwatch/stopwatch.app.js b/apps/stopwatch/stopwatch.app.js
index 92e7a9977..d98f06cdd 100644
--- a/apps/stopwatch/stopwatch.app.js
+++ b/apps/stopwatch/stopwatch.app.js
@@ -1,9 +1,21 @@
+const CONFIGFILE = "stopwatch.json";
+
+const now = Date.now();
+const config = Object.assign({
+ state: {
+ total: now,
+ start: now,
+ current: now,
+ running: false,
+ }
+}, require("Storage").readJSON(CONFIGFILE,1) || {});
+
let w = g.getWidth();
let h = g.getHeight();
-let tTotal = Date.now();
-let tStart = tTotal;
-let tCurrent = tTotal;
-let running = false;
+let tTotal = config.state.total;
+let tStart = config.state.start;
+let tCurrent = config.state.current;
+let running = config.state.running;
let timeY = 2*h/5;
let displayInterval;
let redrawButtons = true;
@@ -15,6 +27,14 @@ const pause_img = atob("GBiBAf////////////////wYP/wYP/wYP/wYP/wYP/wYP/wYP/wYP/wY
const play_img = atob("GBjBAP//AAAAAAAAAAAIAAAOAAAPgAAP4AAP+AAP/AAP/wAP/8AP//AP//gP//gP//AP/8AP/wAP/AAP+AAP4AAPgAAOAAAIAAAAAAAAAAA=");
const reset_img = atob("GBiBAf////////////AAD+AAB+f/5+f/5+f/5+cA5+cA5+cA5+cA5+cA5+cA5+cA5+cA5+f/5+f/5+f/5+AAB/AAD////////////w==");
+function saveState() {
+ config.state.total = tTotal;
+ config.state.start = tStart;
+ config.state.current = tCurrent;
+ config.state.running = running;
+ require("Storage").writeJSON(CONFIGFILE, config);
+}
+
function log_debug(o) {
//console.log(o);
}
@@ -106,6 +126,7 @@ function stopStart() {
} else {
draw();
}
+ saveState();
}
function setButtonImages() {
@@ -130,6 +151,7 @@ function lapReset() {
g.clearRect(0,24,w,h);
draw();
}
+ saveState();
}
// simple on screen button class
@@ -226,5 +248,10 @@ g.fillRect(0,0,w,h);
Bangle.loadWidgets();
Bangle.drawWidgets();
-draw();
+setButtonImages();
+if (running) {
+ startTimer();
+} else {
+ draw();
+}
setWatch(() => load(), BTN, { repeat: false, edge: "falling" });
diff --git a/apps/thering/ChangeLog b/apps/thering/ChangeLog
new file mode 100644
index 000000000..25c572560
--- /dev/null
+++ b/apps/thering/ChangeLog
@@ -0,0 +1,2 @@
+0.01: Initial release.
+0.02: Use widget_utils.
diff --git a/apps/thering/app.js b/apps/thering/app.js
index f7cfaa015..8767941b2 100644
--- a/apps/thering/app.js
+++ b/apps/thering/app.js
@@ -1,5 +1,6 @@
const h = g.getHeight();
const w = g.getWidth();
+const widget_utils = require('widget_utils');
// palette for 0-40%
const pal1 = new Uint16Array([g.theme.bg, g.toColor("#020"), g.toColor("#0f0"), g.toColor("#00f")]);
// palette for 50-100%
@@ -215,10 +216,8 @@ Bangle.setUI("clock");
Bangle.loadWidgets();
/*
* we are not drawing the widgets as we are taking over the whole screen
- * so we will blank out the draw() functions of each widget and change the
- * area to the top bar doesn't get cleared.
*/
-for (let wd of WIDGETS) {wd.draw=()=>{};wd.area="";}
+widget_utils.hide();
draw();
setInterval(draw, 60000);
diff --git a/apps/thering/metadata.json b/apps/thering/metadata.json
index 32b1dae4b..6118a90f9 100644
--- a/apps/thering/metadata.json
+++ b/apps/thering/metadata.json
@@ -1,6 +1,6 @@
{ "id": "thering",
"name": "The Ring",
- "version":"0.01",
+ "version":"0.02",
"description": "A proof of concept clock with large ring guage for steps using pre-set images, acts as a tutorial piece for discussion",
"icon": "app.png",
"tags": "clock",
diff --git a/apps/waypointer/ChangeLog b/apps/waypointer/ChangeLog
index 8613ef799..60e8bfab0 100644
--- a/apps/waypointer/ChangeLog
+++ b/apps/waypointer/ChangeLog
@@ -5,3 +5,4 @@
0.05: Fix not displaying of wpindex = 0
0.06: Added adjustment for Bangle.js magnetometer heading fix
0.07: Add settings file with the option to disable the slow direction updates
+0.08: Use tilt compensation from new magnav library
diff --git a/apps/waypointer/app.js b/apps/waypointer/app.js
index de6bfdcaa..40e4cf974 100644
--- a/apps/waypointer/app.js
+++ b/apps/waypointer/app.js
@@ -85,31 +85,22 @@ function newHeading(m,h){
}
var CALIBDATA = require("Storage").readJSON("magnav.json",1) || {};
-
-function tiltfixread(O,S){
- var m = Bangle.getCompass();
- if (O === undefined || S === undefined) {
- // no valid calibration from magnav, use built in
- return m.heading;
- }
- var g = Bangle.getAccel();
- m.dx =(m.x-O.x)*S.x; m.dy=(m.y-O.y)*S.y; m.dz=(m.z-O.z)*S.z;
- var d = Math.atan2(-m.dx,m.dy)*180/Math.PI;
- if (d<0) d+=360;
- var phi = Math.atan(-g.x/-g.z);
- var cosphi = Math.cos(phi), sinphi = Math.sin(phi);
- var theta = Math.atan(-g.y/(-g.x*sinphi-g.z*cosphi));
- var costheta = Math.cos(theta), sintheta = Math.sin(theta);
- var xh = m.dy*costheta + m.dx*sinphi*sintheta + m.dz*cosphi*sintheta;
- var yh = m.dz*sinphi - m.dx*cosphi;
- var psi = Math.atan2(yh,xh)*180/Math.PI;
- if (psi<0) psi+=360;
- return psi;
+let tiltfixread;
+try {
+ tiltfixread = require("magnav").tiltfixread;
+} catch(e) {
+ // magnav not installed
}
// Note actual mag is 360-m, error in firmware
function read_compass() {
- var d = tiltfixread(CALIBDATA.offset,CALIBDATA.scale);
+ let d;
+ if (tiltfixread === undefined || CALIBDATA.offset === undefined || CALIBDATA.scale === undefined) {
+ // magnav not installed or no valid calibration, use built in
+ d = Bangle.getCompass().heading;
+ } else {
+ d = tiltfixread(CALIBDATA.offset,CALIBDATA.scale);
+ }
if (isNaN(d)) return; // built in compass heading can return NaN when uncalibrated
heading = newHeading(d,heading);
direction = wp_bearing - heading;
@@ -278,6 +269,9 @@ function doselect(){
wp = waypoints[wpindex];
require("waypoints").save(waypoints);
}
+ if (selected) {
+ Bangle.resetCompass(); // reset built in compass when a waypoint is selected
+ }
selected=!selected;
drawN();
}
@@ -294,6 +288,7 @@ Bangle.drawWidgets();
// load widgets can turn off GPS
Bangle.setGPSPower(1);
Bangle.setCompassPower(1);
+Bangle.resetCompass() // reset built in compass on start in case we are not using tilt compensation
drawAll();
startTimers();
Bangle.on('GPS', onGPS);
diff --git a/apps/waypointer/metadata.json b/apps/waypointer/metadata.json
index 0bbc42322..e21c5f10f 100644
--- a/apps/waypointer/metadata.json
+++ b/apps/waypointer/metadata.json
@@ -1,12 +1,12 @@
{
"id": "waypointer",
"name": "Way Pointer",
- "version": "0.07",
+ "version": "0.08",
"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", "BANGLEJS2"],
- "dependencies" : { "waypoints":"type" },
+ "dependencies" : { "waypoints":"type", "magnav" : "app" },
"readme": "README.md",
"storage": [
{"name":"waypointer.app.js","url":"app.js"},
diff --git a/apps/weather/ChangeLog b/apps/weather/ChangeLog
index 4b70d3531..0010a58fd 100644
--- a/apps/weather/ChangeLog
+++ b/apps/weather/ChangeLog
@@ -20,3 +20,4 @@
0.21: Updated clkinfo icon.
0.22: Automatic translation of strings, some left untranslated.
0.23: Update clock_info to avoid a redraw
+0.24: Redraw clock_info on update and provide color field for condition
diff --git a/apps/weather/clkinfo.js b/apps/weather/clkinfo.js
index f40924e06..ef3b7d139 100644
--- a/apps/weather/clkinfo.js
+++ b/apps/weather/clkinfo.js
@@ -1,28 +1,36 @@
(function() {
- var weather = {
- temp: "?",
- hum: "?",
- wind: "?",
- txt: "?",
- };
+ var weather;
+ var weatherLib = require("weather");
- var weatherJson = require("Storage").readJSON('weather.json');
- if(weatherJson !== undefined && weatherJson.weather !== undefined){
- weather = weatherJson.weather;
+ function updateWeather() {
+ weather = weatherLib.get();
+ if(weather){
weather.temp = require("locale").temp(weather.temp-273.15);
weather.hum = weather.hum + "%";
weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/);
weather.wind = Math.round(weather.wind[1]) + "kph";
+ } else {
+ weather = {
+ temp: "?",
+ hum: "?",
+ wind: "?",
+ txt: "?",
+ };
+ }
}
+ updateWeather();
function weatherIcon(code) {
var ovr = Graphics.createArrayBuffer(24,24,1,{msb:true});
- require("weather").drawIcon({code:code},12,12,12,ovr);
+ weatherLib.drawIcon({code:code},12,12,12,ovr);
var img = ovr.asImage();
img.transparent = 0;
- //for (var i=0;i ({ text: weather.temp, img: weatherIcon(weather.code),
+ color: weatherLib.getColor(weather.code),
v: parseInt(weather.temp), min: -30, max: 55}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ this.updater = _updater.bind(this);
+ weatherLib.on("update", this.updater);
+ },
+ hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "condition",
get: () => ({ text: weather.txt, img: weatherIcon(weather.code),
+ color: weatherLib.getColor(weather.code),
v: weather.code}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ this.updater = _updater.bind(this);
+ weatherLib.on("update", this.updater);
+ },
+ hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "temperature",
hasRange : true,
get: () => ({ text: weather.temp, img: atob("GBiBAAA8AAB+AADnAADDAADDAADDAADDAADDAADbAADbAADbAADbAADbAADbAAHbgAGZgAM8wAN+wAN+wAM8wAGZgAHDgAD/AAA8AA=="),
v: parseInt(weather.temp), min: -30, max: 55}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ this.updater = _updater.bind(this);
+ weatherLib.on("update", this.updater);
+ },
+ hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "humidity",
hasRange : true,
get: () => ({ text: weather.hum, img: atob("GBiBAAAEAAAMAAAOAAAfAAAfAAA/gAA/gAI/gAY/AAcfAA+AQA+A4B/A4D/B8D/h+D/j+H/n/D/n/D/n/B/H/A+H/AAH/AAD+AAA8A=="),
v: parseInt(weather.hum), min: 0, max: 100}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ this.updater = _updater.bind(this);
+ weatherLib.on("update", this.updater);
+ },
+ hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "wind",
hasRange : true,
get: () => ({ text: weather.wind, img: atob("GBiBAAHgAAPwAAYYAAwYAAwMfAAY/gAZh3/xg//hgwAAAwAABg///g//+AAAAAAAAP//wH//4AAAMAAAMAAYMAAYMAAMcAAP4AADwA=="),
v: parseInt(weather.wind), min: 0, max: 118}),
- show: function() {},
- hide: function () {}
+ show: function() {
+ this.updater = _updater.bind(this);
+ weatherLib.on("update", this.updater);
+ },
+ hide: function () { weatherLib.removeListener("update", this.updater); }
},
]
};
diff --git a/apps/weather/lib.js b/apps/weather/lib.js
index 8c59fd3e3..14ca77ec6 100644
--- a/apps/weather/lib.js
+++ b/apps/weather/lib.js
@@ -53,6 +53,98 @@ exports.get = function() {
scheduleExpiry(storage.readJSON('weather.json')||{});
+function getPalette(monochrome, ovr) {
+ var palette;
+ if(monochrome) {
+ palette = {
+ sun: '#FFF',
+ cloud: '#FFF',
+ bgCloud: '#FFF',
+ rain: '#FFF',
+ lightning: '#FFF',
+ snow: '#FFF',
+ mist: '#FFF',
+ background: '#000'
+ };
+ } else {
+ if (B2) {
+ if (ovr.theme.dark) {
+ palette = {
+ sun: '#FF0',
+ cloud: '#FFF',
+ bgCloud: '#777', // dithers on B2, but that's ok
+ rain: '#0FF',
+ lightning: '#FF0',
+ snow: '#FFF',
+ mist: '#FFF'
+ };
+ } else {
+ palette = {
+ sun: '#FF0',
+ cloud: '#777', // dithers on B2, but that's ok
+ bgCloud: '#000',
+ rain: '#00F',
+ lightning: '#FF0',
+ snow: '#0FF',
+ mist: '#0FF'
+ };
+ }
+ } else {
+ if (ovr.theme.dark) {
+ palette = {
+ sun: '#FE0',
+ cloud: '#BBB',
+ bgCloud: '#777',
+ rain: '#0CF',
+ lightning: '#FE0',
+ snow: '#FFF',
+ mist: '#FFF'
+ };
+ } else {
+ palette = {
+ sun: '#FC0',
+ cloud: '#000',
+ bgCloud: '#777',
+ rain: '#07F',
+ lightning: '#FC0',
+ snow: '#CCC',
+ mist: '#CCC'
+ };
+ }
+ }
+ }
+ return palette;
+}
+
+exports.getColor = function(code) {
+ const codeGroup = Math.round(code / 100);
+ const palette = getPalette(0, g);
+ const cloud = g.blendColor(palette.cloud, palette.bgCloud, .5); //theme independent
+ switch (codeGroup) {
+ case 2: return g.blendColor(cloud, palette.lightning, .5);
+ case 3: return palette.rain;
+ case 5:
+ switch (code) {
+ case 511: return palette.snow;
+ case 520: return g.blendColor(palette.rain, palette.sun, .5);
+ case 521: return g.blendColor(palette.rain, palette.sun, .5);
+ case 522: return g.blendColor(palette.rain, palette.sun, .5);
+ case 531: return g.blendColor(palette.rain, palette.sun, .5);
+ default: return palette.rain;
+ }
+ case 6: return palette.snow;
+ case 7: return palette.mist;
+ case 8:
+ switch (code) {
+ case 800: return palette.sun;
+ case 801: return palette.sun;
+ case 802: return cloud;
+ default: return cloud;
+ }
+ default: return cloud;
+ }
+}
+
/**
*
* @param cond Weather condition, as one of:
@@ -71,63 +163,8 @@ exports.drawIcon = function(cond, x, y, r, ovr) {
ovr = g;
monochrome=0;
}
- if(monochrome) {
- palette = {
- sun: '#FFF',
- cloud: '#FFF',
- bgCloud: '#FFF',
- rain: '#FFF',
- lightning: '#FFF',
- snow: '#FFF',
- mist: '#FFF',
- background: '#000'
- };
- } else
- if (B2) {
- if (ovr.theme.dark) {
- palette = {
- sun: '#FF0',
- cloud: '#FFF',
- bgCloud: '#777', // dithers on B2, but that's ok
- rain: '#0FF',
- lightning: '#FF0',
- snow: '#FFF',
- mist: '#FFF'
- };
- } else {
- palette = {
- sun: '#FF0',
- cloud: '#777', // dithers on B2, but that's ok
- bgCloud: '#000',
- rain: '#00F',
- lightning: '#FF0',
- snow: '#0FF',
- mist: '#0FF'
- };
- }
- } else {
- if (ovr.theme.dark) {
- palette = {
- sun: '#FE0',
- cloud: '#BBB',
- bgCloud: '#777',
- rain: '#0CF',
- lightning: '#FE0',
- snow: '#FFF',
- mist: '#FFF'
- };
- } else {
- palette = {
- sun: '#FC0',
- cloud: '#000',
- bgCloud: '#777',
- rain: '#07F',
- lightning: '#FC0',
- snow: '#CCC',
- mist: '#CCC'
- };
- }
- }
+
+ palette = getPalette(monochrome, ovr);
function drawSun(x, y, r) {
ovr.setColor(palette.sun);
diff --git a/apps/weather/metadata.json b/apps/weather/metadata.json
index 77ca37721..bcb2fe109 100644
--- a/apps/weather/metadata.json
+++ b/apps/weather/metadata.json
@@ -1,7 +1,7 @@
{
"id": "weather",
"name": "Weather",
- "version": "0.23",
+ "version": "0.24",
"description": "Show Gadgetbridge weather report",
"icon": "icon.png",
"screenshots": [{"url":"screenshot.png"}],
diff --git a/apps/widalarmeta/ChangeLog b/apps/widalarmeta/ChangeLog
new file mode 100644
index 000000000..37b619f7f
--- /dev/null
+++ b/apps/widalarmeta/ChangeLog
@@ -0,0 +1,4 @@
+0.01: New App!
+0.02: Change font to 5x9 7 segment-style
+ Add settings page
+ Add option to show seconds
diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json
index ef9f55ba8..79387c1c5 100644
--- a/apps/widalarmeta/metadata.json
+++ b/apps/widalarmeta/metadata.json
@@ -2,8 +2,8 @@
"id": "widalarmeta",
"name": "Alarm & Timer ETA",
"shortName": "Alarm ETA",
- "version": "0.01",
- "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h",
+ "version": "0.02",
+ "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).",
"icon": "widget.png",
"type": "widget",
"tags": "widget",
@@ -11,6 +11,8 @@
"provides_widgets" : ["alarm"],
"screenshots" : [ { "url":"screenshot.png" } ],
"storage": [
- {"name":"widalarmeta.wid.js","url":"widget.js"}
- ]
+ {"name":"widalarmeta.wid.js","url":"widget.js"},
+ {"name":"widalarmeta.settings.js","url":"settings.js"}
+ ],
+ "data": [{"name":"widalarmeta.json"}]
}
diff --git a/apps/widalarmeta/screenshot.png b/apps/widalarmeta/screenshot.png
index 41a109557..3a23b757a 100644
Binary files a/apps/widalarmeta/screenshot.png and b/apps/widalarmeta/screenshot.png differ
diff --git a/apps/widalarmeta/settings.js b/apps/widalarmeta/settings.js
new file mode 100644
index 000000000..5922d159d
--- /dev/null
+++ b/apps/widalarmeta/settings.js
@@ -0,0 +1,45 @@
+(function(back) {
+ const CONFIGFILE = "widalarmeta.json";
+ // Load settings
+ const settings = Object.assign({
+ maxhours: 24,
+ drawBell: false,
+ showSeconds: 0, // 0=never, 1=only when display is unlocked, 2=for less than a minute
+ }, require("Storage").readJSON(CONFIGFILE,1) || {});
+
+ function writeSettings() {
+ require('Storage').writeJSON(CONFIGFILE, settings);
+ }
+
+ // Show the menu
+ E.showMenu({
+ "" : { "title" : "Alarm & Timer ETA" },
+ "< Back" : () => back(),
+ /*LANG*/'Maximum hours': {
+ format: v => v === 0 ? /*LANG*/'disabled' : v,
+ value: settings.maxhours,
+ min: 0, max: 24,
+ onchange: v => {
+ settings.maxhours = v;
+ writeSettings();
+ }
+ },
+ /*LANG*/'Draw bell': {
+ value: !!settings.drawBell,
+ format: v => v?/*LANG*/"Yes":/*LANG*/"No",
+ onchange: v => {
+ settings.drawBell = v;
+ writeSettings();
+ }
+ },
+ /*LANG*/'Show seconds': {
+ value: settings.showSeconds,
+ min: 0, max: 2,
+ format: v => [/*LANG*/"Never", /*LANG*/"Unlocked", /*LANG*/"Last minute"][v || 0],
+ onchange: v => {
+ settings.showSeconds = v;
+ writeSettings();
+ }
+ },
+ });
+});
diff --git a/apps/widalarmeta/widget.js b/apps/widalarmeta/widget.js
index 0cddf953a..ff3390d89 100644
--- a/apps/widalarmeta/widget.js
+++ b/apps/widalarmeta/widget.js
@@ -1,35 +1,68 @@
(() => {
+ require("Font5x9Numeric7Seg").add(Graphics);
const alarms = require("Storage").readJSON("sched.json",1) || [];
+ const config = Object.assign({
+ maxhours: 24,
+ drawBell: false,
+ showSeconds: 0, // 0=never, 1=only when display is unlocked, 2=for less than a minute
+ }, require("Storage").readJSON("widalarmeta.json",1) || {});
function draw() {
const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm)).filter(a => a !== undefined);
const next = Math.min.apply(null, times);
- if (next > 0 && next < 86400000) {
- const hours = Math.floor((next % 86400000) / 3600000).toString();
- const minutes = Math.floor(((next % 86400000) % 3600000) / 60000).toString();
+ let calcWidth = 0;
+ let drawSeconds = false;
+
+ if (next > 0 && next < config.maxhours*60*60*1000) {
+ const hours = Math.floor((next-1) / 3600000).toString();
+ const minutes = Math.floor(((next-1) % 3600000) / 60000).toString();
+ const seconds = Math.floor(((next-1) % 60000) / 1000).toString();
+ drawSeconds = (config.showSeconds & 0b01 && !Bangle.isLocked()) || (config.showSeconds & 0b10 && next <= 1000*60);
g.reset(); // reset the graphics context to defaults (color/font/etc)
g.setFontAlign(0,0); // center fonts
g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23);
var text = hours.padStart(2, '0') + ":" + minutes.padStart(2, '0');
- g.setFont("6x8:1x2");
- g.drawString(text, this.x+this.width/2, this.y+12);
- if (this.width === 0) {
- this.width = 6*5+2;
- Bangle.drawWidgets(); // width changed, re-layout
+ if (drawSeconds) {
+ text += ":" + seconds.padStart(2, '0');
}
+ g.setFont("5x9Numeric7Seg:1x2");
+ g.drawString(text, this.x+this.width/2, this.y+12);
+
+ calcWidth = 5*5+2;
+ if (drawSeconds) {
+ calcWidth += 3*5;
+ }
+ } else if (times.length > 0 && config.drawBell) {
+ // next alarm too far in future, draw only widalarm bell
+ g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
+ calcWidth = 24;
}
+
+ if (this.width !== calcWidth) {
+ // width changed, re-layout
+ this.width = calcWidth;
+ Bangle.drawWidgets();
+ }
+
+ // redraw next full minute or second
+ const period = drawSeconds ? 1000 : 60000;
+ let timeout = next > 0 ? next % period : period - (Date.now() % period);
+ if (timeout === 0) {
+ timeout += period;
+ }
+ setTimeout(()=>{
+ WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]);
+ }, timeout);
+ } /* draw */
+
+ if (config.maxhours > 0) {
+ // add your widget
+ WIDGETS["widalarmeta"]={
+ area:"tl",
+ width: 0, // hide by default = assume no timer
+ draw:draw
+ };
}
-
- setInterval(function() {
- WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]);
- }, 30000); // update every half minute
-
- // add your widget
- WIDGETS["widalarmeta"]={
- area:"tl",
- width: 0, // hide by default = assume no timer
- draw:draw
- };
})();
diff --git a/apps/widbgjs/ChangeLog b/apps/widbgjs/ChangeLog
new file mode 100644
index 000000000..7b83706bf
--- /dev/null
+++ b/apps/widbgjs/ChangeLog
@@ -0,0 +1 @@
+0.01: First release
diff --git a/apps/widbgjs/README.md b/apps/widbgjs/README.md
new file mode 100644
index 000000000..dbb8cd9e4
--- /dev/null
+++ b/apps/widbgjs/README.md
@@ -0,0 +1,29 @@
+# Prerequisites
+For this widget to work and to get data from the phone, you need:
+- An Android phone
+ - with xDrip and the helper app installed.
+ - the Gadgetbridge app (bangle version) for the Android phone
+- A BangleJS
+ - With this widget installed
+
+# Widget
+
+## How to use it
+Make sure you have all the prerequisites from above.
+
+The watch should automatically start displaying values, if there is an arrow visible behind the value, the value is within the not-expired-yet time range changeable in the settings standard is 15 minutes. (I will probably change this in the future, to strike through the text to make expired values clearer).
+
+## Settings
+In the settings, you can:
+- Disable/hide the widget
+- Change the unit from mmol/L to mg/dL
+- Set a time at which old BG values expire
+
+
+# Developer
+Developed by Phil Roggenbuck (phrogg)
+
+
+# Disclaimer
+As well as xdrip you should not use this app to make medical decisions!
+
diff --git a/apps/widbgjs/metadata.json b/apps/widbgjs/metadata.json
new file mode 100644
index 000000000..0639b5a51
--- /dev/null
+++ b/apps/widbgjs/metadata.json
@@ -0,0 +1,22 @@
+{
+ "id": "widbgjs",
+ "name": "Blood Glucose Widget (xdrip)",
+ "shortName":"BG Widget",
+ "icon": "screenshot.png",
+ "screenshots": [{"url":"screenshot.png"}],
+ "version":"0.01",
+ "type": "widget",
+ "supports": ["BANGLEJS", "BANGLEJS2"],
+ "readme": "README.md",
+ "allow_emulator":true,
+ "description": "Displays the current blood glucose received from xdrip and send over via a helper app on the watch.",
+ "tags": "widget",
+ "storage": [
+ {"name":"widbgjs.wid.js","url":"widget.js"},
+ {"name":"widbgjs.settings.js","url":"settings.js"}
+ ],
+ "data": [
+ {"name":"widbgjs.json"},
+ {"name":"widbgjs.settings.json"}
+ ]
+ }
diff --git a/apps/widbgjs/screenshot.png b/apps/widbgjs/screenshot.png
new file mode 100644
index 000000000..b6e092af2
Binary files /dev/null and b/apps/widbgjs/screenshot.png differ
diff --git a/apps/widbgjs/settings.js b/apps/widbgjs/settings.js
new file mode 100644
index 000000000..f2eb190bc
--- /dev/null
+++ b/apps/widbgjs/settings.js
@@ -0,0 +1,54 @@
+(function (back) {
+ const SAVEFILE = "wpbgjs.settings.json";
+
+ // initialize with default settings...
+ let s = {
+ 'unitIsMmol': true,
+ 'expireThreshold': 600000,
+ 'hide': false
+ };
+ // ...and overwrite them with any saved values
+ // This way saved values are preserved if a new version adds more settings
+ const storage = require('Storage');
+ const d = storage.readJSON(SAVEFILE, 1) || {};
+ const saved = d.settings || {};
+ for (const key in saved) {
+ s[key] = saved[key];
+ }
+
+ function save() {
+ d.settings = s;
+ storage.write(SAVEFILE, d);
+ WIDGETS['widbgjs'].draw();
+ }
+
+ E.showMenu({
+ '': { 'title': 'BG widget' },
+ 'Unit': {
+ value: s.unitIsMmol,
+ format: () => (s.unitIsMmol ? 'mmol/L' : 'mg/dL'),
+ onchange: () => {
+ s.unitIsMmol = !s.unitIsMmol;
+ save();
+ },
+ },
+ 'Exp. BG': {
+ value: s.expireThreshold,
+ min: 18000, step: 60000,
+ format: s => (s ? s / 60000 + ' min' : '0'),
+ onchange: (g) => {
+ s.expireThreshold = g;
+ save();
+ },
+ },
+ 'Hide Widget': {
+ value: s.hide,
+ format: () => (s.hide ? 'Yes' : 'No'),
+ onchange: () => {
+ s.hide = !s.hide;
+ save();
+ },
+ },
+ '< Back': back,
+ });
+});
\ No newline at end of file
diff --git a/apps/widbgjs/widget.js b/apps/widbgjs/widget.js
new file mode 100644
index 000000000..1a1df002d
--- /dev/null
+++ b/apps/widbgjs/widget.js
@@ -0,0 +1,143 @@
+//WIDGETS = {}; // <-- for development only
+
+(() => {
+ // persistant vals
+ let storedData;
+ let settings;
+
+ function loadSettings() { // stolen from https://github.com/espruino/BangleApps/blob/master/apps/widpedom/widget.js
+ const d = require('Storage').readJSON("widbgjs.settings.json", 1) || {};
+ settings = Object.assign({
+ 'unitIsMmol': true,
+ 'expireThreshold': 600000,
+ 'reloadInterval': 5 * 60000,
+ 'hide': false
+ }, d || {});
+ return d;
+ }
+
+ function loadVals() {
+ try {
+ const d = require('Storage').readJSON("widbgjs.json", 1) || {};
+ storedData = Object.assign({
+ 'bg': null,
+ 'bgTimeStamp': null,
+ 'bgDirection': null
+ }, d || {});
+ return d;
+ } catch(e) {
+ Bangle.removeFile("widbgjs.json");
+ }
+ return null;
+ }
+
+ function calculateRotation(bgDirection) {
+ var a = 90;
+ // get the arrow right (https://github.com/StephenBlackWasAlreadyTaken/NightWatch/blob/6de1d3775c6e447177c12f387f647628cc8e24ce/mobile/src/main/java/com/dexdrip/stephenblack/nightwatch/Bg.java)
+ switch (bgDirection) {
+ case ("DoubleDown"):
+ g.setColor("#f00");
+ a = 180;
+ break;
+ case ("SingleDown"):
+ a = 180;
+ break;
+ case ("DoubleUp"):
+ g.setColor("#f00");
+ a = 0;
+ break;
+ case ("SingleUp"):
+ a = 0;
+ break;
+ case ("FortyFiveUp"):
+ a = 45;
+ break;
+ case ("FortyFiveDown"):
+ a = 135;
+ break;
+ case ("Flat"):
+ a = 90;
+ break;
+ }
+ // turn the arrow thanks to (https://forum.espruino.com/conversations/344607/)
+ const p180 = Math.PI / 180;
+ // a is defined above
+ var r = 21;
+ var x = r * Math.sin(a * p180);
+ var y = r * Math.cos(a * p180);
+
+ return a * p180;
+ }
+
+ function getBG(bg) {
+ var tmp = null;
+
+ try {
+ if (storedData.bg !== null) {
+ tmp = bg;
+
+ if (settings.unitIsMmol) {
+ tmp /= 18;
+ tmp = tmp.toFixed(1);
+ }
+ }
+
+ } catch (e) { }
+ return tmp;
+ }
+
+ function isBgTooOld(bgTimeStamp) {
+ var currTimeInMilli = new Date().valueOf();
+
+ try {
+ if (bgTimeStamp === null) {
+ return true;
+ }
+
+ if (currTimeInMilli - settings.expireThreshold <= bgTimeStamp) {
+ return false;
+ }
+ } catch (e) { }
+ return true;
+ }
+
+ function draw() {
+ loadSettings();
+ try {
+ if (settings.hide) return;
+ } catch (e) { }
+ loadVals();
+
+ outpt = getBG(storedData.bg);
+
+ if (outpt === null) { // this means no value has been received yet
+ outpt = "BG";
+ bgTimeStamp = "0";
+ }
+
+ // prepare to write on the screen
+ g.reset().clearRect(this.x, this.y, this.x + this.width, this.y + 23); // erase background
+ g.setFont('Vector', 22);
+ g.setColor(g.theme.fg);
+
+ // check if the value is too old
+ if (!isBgTooOld(storedData.bgTimeStamp)) {
+ g.drawImage(atob("FBQBAGAADwAB+AA/wAduAGZgAGAABgAAYAAGAABgAAYAAGAABgAAYAAGAABgAAYAAGAABgA="), this.x + 60, this.y + 9, { rotate: calculateRotation(storedData.bgDirection) });
+ }
+ g.setColor(g.theme.fg).drawString(outpt, this.x + 5, this.y);
+ }
+
+ setInterval(function () {
+ WIDGETS["widbgjs"].draw(WIDGETS["widbgjs"]);
+ }, 5 * 60000); // update every 5 minutes (%* 60000
+
+
+ // add your widget
+ WIDGETS["widbgjs"] = {
+ area: "tl",
+ width: 72,
+ draw: draw
+ };
+})();
+
+//Bangle.drawWidgets(); // <-- for development only
diff --git a/apps/widviz/ChangeLog b/apps/widviz/ChangeLog
index 9785f4d84..5df89e719 100644
--- a/apps/widviz/ChangeLog
+++ b/apps/widviz/ChangeLog
@@ -1,3 +1,4 @@
0.01: New Widget
0.02: swipe left,right update
0.03: Fix widget visibility code to the top bar isn't cleared by drawWidgets
+0.04: Use widget_utils.
diff --git a/apps/widviz/metadata.json b/apps/widviz/metadata.json
index ba9cf793b..4d88c4d5f 100644
--- a/apps/widviz/metadata.json
+++ b/apps/widviz/metadata.json
@@ -2,7 +2,7 @@
"id": "widviz",
"name": "Widget Visibility Widget",
"shortName": "Viz Widget",
- "version": "0.03",
+ "version": "0.04",
"description": "Swipe left to hide top bar widgets, swipe right to redisplay.",
"icon": "eye.png",
"type": "widget",
diff --git a/apps/widviz/widget.js b/apps/widviz/widget.js
index 1490cf11a..7b9f55053 100644
--- a/apps/widviz/widget.js
+++ b/apps/widviz/widget.js
@@ -1,28 +1,20 @@
(() => {
+ let widget_utils = require('widget_utils');
- var saved = null;
+ var saved = false;
function hide(){
if (!Bangle.isLCDOn() || saved) return;
- saved = [];
- for (var wd of WIDGETS) {
- saved.push({d:wd.draw,a:wd.area});
- wd.draw=()=>{};
- wd.area="";
- }
+ saved = true;
+ widget_utils.hide();
g.setColor(0,0,0);
g.fillRect(0,0,g.getWidth(),23);
}
function reveal(){
if (!Bangle.isLCDOn() || !saved) return;
- for (var wd of WIDGETS) {
- var o = saved.shift();
- wd.draw = o.d;
- wd.area = o.a;
- }
- Bangle.drawWidgets();
- saved=null;
+ widget_utils.show();
+ saved = false;
}
function draw(){
diff --git a/apps/widviztime/ChangeLog b/apps/widviztime/ChangeLog
index 287061d0c..be95ed81c 100644
--- a/apps/widviztime/ChangeLog
+++ b/apps/widviztime/ChangeLog
@@ -1 +1,2 @@
0.01: New Widget, forked from widviz
+0.02: Use widget_utils.
diff --git a/apps/widviztime/metadata.json b/apps/widviztime/metadata.json
index b364bbd74..669c8fc12 100644
--- a/apps/widviztime/metadata.json
+++ b/apps/widviztime/metadata.json
@@ -2,7 +2,7 @@
"id": "widviztime",
"name": "Widget Autohide Widget",
"shortName": "Viz Time Widget",
- "version": "0.01",
+ "version": "0.02",
"description": "The widgets will be shown for four seconds after the device is unlocked.",
"icon": "eye.png",
"type": "widget",
diff --git a/apps/widviztime/widget.js b/apps/widviztime/widget.js
index 5e81af611..8422a3842 100644
--- a/apps/widviztime/widget.js
+++ b/apps/widviztime/widget.js
@@ -1,32 +1,21 @@
(() => {
+ let widget_utils = require('widget_utils');
- var saved = null;
+ var saved = false;
function hide() {
if (!Bangle.isLCDOn() || saved) return;
- saved = [];
- for (var wd of WIDGETS) {
- saved.push({
- d: wd.draw,
- a: wd.area
- });
- wd.draw = () => {};
- wd.area = "";
- }
+ saved = true;
+ widget_utils.hide();
g.setColor(0, 0, 0);
g.fillRect(0, 0, g.getWidth(), 23);
}
function reveal() {
if (!Bangle.isLCDOn() || !saved) return;
- for (var wd of WIDGETS) {
- var o = saved.shift();
- wd.draw = o.d;
- wd.area = o.a;
- }
- Bangle.drawWidgets();
- saved = null;
+ widget_utils.show();
+ saved = false;
}
function draw() {
diff --git a/bin/lib/apploader.js b/bin/lib/apploader.js
index 6bf74eb7e..329ece7b7 100644
--- a/bin/lib/apploader.js
+++ b/bin/lib/apploader.js
@@ -22,6 +22,7 @@ global.Const = {
};
var apps = [];
+var device = { id : DEVICEID, appsInstalled : [] };
// call with {DEVICEID:"BANGLEJS/BANGLEJS2"}
exports.init = function(options) {
@@ -67,10 +68,28 @@ function fileGetter(url) {
}
exports.getAppFiles = function(app) {
- return AppInfo.getFiles(app, {
+ var allFiles = [];
+ var uploadOptions = {
+ apps : apps,
+ needsApp : app => {
+ if (app.provides_modules) {
+ if (!app.files) app.files="";
+ app.files = app.files.split(",").concat(app.provides_modules).join(",");
+ }
+ return AppInfo.getFiles(app, {
+ fileGetter:fileGetter,
+ settings : SETTINGS,
+ device : { id : DEVICEID }
+ }).then(files => { allFiles = allFiles.concat(files); return app; });
+ }
+ };
+ return AppInfo.checkDependencies(app, device, uploadOptions).then(() => AppInfo.getFiles(app, {
fileGetter:fileGetter,
settings : SETTINGS,
- device : { id : DEVICEID }
+ device : device
+ })).then(files => {
+ allFiles = allFiles.concat(files);
+ return allFiles;
});
};
diff --git a/bin/runapptests.js b/bin/runapptests.js
index 8a415b109..b50a7e15c 100755
--- a/bin/runapptests.js
+++ b/bin/runapptests.js
@@ -20,17 +20,31 @@ TODO:
*/
-// A si
-var TEST = {
+// A simpletest
+/*var TEST = {
app : "android",
tests : [ {
- load : "messagesgui.app.js",
steps : [
+ {t:"load", fn:"messagesgui.app.js"},
{t:"gb", "obj":{"t":"notify","id":1234,"src":"Twitter","title":"A Name","body":"message contents"}},
{t:"cmd", "js":"X='hello';"},
{t:"eval", "js":"X", eq:"hello"}
]
}]
+};*/
+var TEST = {
+ app : "antonclk",
+ tests : [ {
+ steps : [
+ {t:"cmd", "js": "Bangle.loadWidgets()"},
+ {t:"cmd", "js": "eval(require('Storage').read('antonclk.app.js'))"},
+ {t:"cmd", "js":"Bangle.setUI()"}, // load and free
+ {t:"saveMemoryUsage"},
+ {t:"cmd", "js": "eval(require('Storage').read('antonclk.app.js'))"},
+ {t:"cmd", "js":"Bangle.setUI()"}, // load and free
+ {t:"checkMemoryUsage"}, // check memory usage is the same
+ ]
+ }]
};
var EMULATOR = "banglejs2";
@@ -73,34 +87,57 @@ function runTest(test) {
console.log(`"${test.app}" Test ${subtestIdx}`);
console.log(`==============================`);
emu.factoryReset();
- console.log("Sending app "+test.app);
+ console.log("> Sending app "+test.app);
emu.tx(command);
- console.log("Sent app");
- emu.tx(test.load ? `load(${JSON.stringify(test.load)})\n` : "load()\n");
- console.log("App Loaded.");
+ console.log("> Sent app");
+ emu.tx("reset()\n");
+ console.log("> Reset.");
var ok = true;
subtest.steps.forEach(step => {
if (ok) switch(step.t) {
- case "cmd" : emu.tx(`${step.js}\n`); break;
+ case "load" :
+ console.log(`> Loading file "${step.fn}"`);
+ emu.tx(`load(${JSON.stringify(step.fn)})\n`);
+ break;
+ case "cmd" :
+ console.log(`> Sending JS "${step.js}"`);
+ emu.tx(`${step.js}\n`);
+ break;
case "gb" : emu.tx(`GB(${JSON.stringify(step.obj)})\n`); break;
case "tap" : emu.tx(`Bangle.emit(...)\n`); break;
case "eval" :
+ console.log(`> Evaluate "${step.js}"`);
emu.tx(`\x10print(JSON.stringify(${step.js}))\n`);
var result = emu.getLastLine();
var expected = JSON.stringify(step.eq);
- console.log("GOT "+result);
+ console.log("> GOT "+result);
if (result!=expected) {
- console.log("EXPECTED "+expected);
+ console.log("> FAIL: EXPECTED "+expected);
ok = false;
}
break;
// tap/touch/drag/button press
// delay X milliseconds?
case "screenshot" :
- console.log("Compare screenshots");
+ console.log(`> Compare screenshots - UNIMPLEMENTED`);
+ break;
+ case "saveMemoryUsage" :
+ emu.tx(`\x10print(process.memory().usage)\n`);
+ subtest.memUsage = parseInt( emu.getLastLine());
+ console.log("> CURRENT MEMORY USAGE", subtest.memUsage);
+ break;
+ case "checkMemoryUsage" :
+ emu.tx(`\x10print(process.memory().usage)\n`);
+ var memUsage = emu.getLastLine();
+ console.log("> CURRENT MEMORY USAGE", memUsage);
+ if (subtest.memUsage != memUsage ) {
+ console.log("> FAIL: EXPECTED MEMORY USAGE OF "+subtest.memUsage);
+ ok = false;
+ }
break;
default: ERROR("Unknown step type "+step.t);
}
+ emu.idle();
});
});
emu.stopIdle();
diff --git a/core b/core
index 376824068..893c2dbbe 160000
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit 376824068d90986c245b46970fd80ccdca44e431
+Subproject commit 893c2dbbe5a93fbb80d035a695663b4f4cca8875
diff --git a/loader.js b/loader.js
index a6e51192e..414aa99d1 100644
--- a/loader.js
+++ b/loader.js
@@ -72,6 +72,7 @@ var submittedUsageInfo = "";
function sendUsageStats() {
if (!SETTINGS.sendUsageStats) return; // not allowed!
if (device.uid === undefined) return; // no data yet!
+ if (!device.appsInstalled.length) return; // no installed apps or disconnected
/* Work out what we'll send:
* A suitably garbled UID so we can avoid too many duplicates
* firmware version
@@ -248,23 +249,27 @@ window.addEventListener('load', (event) => {
// BLE Compatibility
var selectBLECompat = document.getElementById("settings-ble-compat");
- Puck.increaseMTU = !SETTINGS.bleCompat;
- selectBLECompat.checked = !!SETTINGS.bleCompat;
- selectBLECompat.addEventListener("change",event=>{
- console.log("BLE compatibility mode "+(event.target.checked?"on":"off"));
- SETTINGS.bleCompat = event.target.checked;
+ if (selectBLECompat) {
Puck.increaseMTU = !SETTINGS.bleCompat;
- saveSettings();
- });
+ selectBLECompat.checked = !!SETTINGS.bleCompat;
+ selectBLECompat.addEventListener("change",event=>{
+ console.log("BLE compatibility mode "+(event.target.checked?"on":"off"));
+ SETTINGS.bleCompat = event.target.checked;
+ Puck.increaseMTU = !SETTINGS.bleCompat;
+ saveSettings();
+ });
+ }
// Sending usage stats
var selectUsageStats = document.getElementById("settings-usage-stats");
- selectUsageStats.checked = !!SETTINGS.sendUsageStats;
- selectUsageStats.addEventListener("change",event=>{
- console.log("Send Usage Stats "+(event.target.checked?"on":"off"));
- SETTINGS.sendUsageStats = event.target.checked;
- saveSettings();
- });
+ if (selectUsageStats) {
+ selectUsageStats.checked = !!SETTINGS.sendUsageStats;
+ selectUsageStats.addEventListener("change",event=>{
+ console.log("Send Usage Stats "+(event.target.checked?"on":"off"));
+ SETTINGS.sendUsageStats = event.target.checked;
+ saveSettings();
+ });
+ }
// Load language list
httpGet("lang/index.json").then(languagesJSON=>{
diff --git a/modules/Layout.js b/modules/Layout.js
index 4cf8752a3..5afcce410 100644
--- a/modules/Layout.js
+++ b/modules/Layout.js
@@ -186,8 +186,12 @@ Layout.prototype.render = function (l) {
x+4,y+h-1,
x,y+h-5,
x,y+4
- ], bg = l.selected?gfx.theme.bgH:gfx.theme.bg2;
- gfx.setColor(bg).fillPoly(poly).setColor(l.selected ? gfx.theme.fgH : gfx.theme.fg2).drawPoly(poly);
+ ], bg = l.bgCol!==undefined?l.bgCol:gfx.theme.bg2,
+ btnborder = l.btnBorder!==undefined?l.btnBorder:gfx.theme.fg2;
+ if(l.selected){
+ bg = gfx.theme.bgH, btnborder = gfx.theme.fgH;
+ }
+ gfx.setColor(bg).fillPoly(poly).setColor(btnborder).drawPoly(poly);
if (l.col!==undefined) gfx.setColor(l.col);
if (l.src) gfx.setBgColor(bg).drawImage(
"function"==typeof l.src?l.src():l.src,
diff --git a/modules/Layout.md b/modules/Layout.md
index 67db21858..95bf116dc 100644
--- a/modules/Layout.md
+++ b/modules/Layout.md
@@ -46,7 +46,8 @@ layout.render();
- A `r` field to set rotation of text or images (0: 0°, 1: 90°, 2: 180°, 3: 270°).
- A `wrap` field to enable line wrapping. Requires some combination of `width`/`height` and `fillx`/`filly` to be set. Not compatible with text rotation.
- A `col` field, eg `#f00` for red
-- A `bgCol` field for background color (will automatically fill on render)
+- A `bgCol` field for background color (will automatically fill on render). When `type:"btn"`, this sets the background color of the button, and will not change color on press
+- A `btnBorder` field for button border color (will default to theme if not set)
- A `halign` field to set horizontal alignment WITHIN a `v` container. `-1`=left, `1`=right, `0`=center
- A `valign` field to set vertical alignment WITHIN a `h` container. `-1`=top, `1`=bottom, `0`=center
- A `pad` integer field to set pixels padding
diff --git a/modules/graphics_utils.js b/modules/graphics_utils.js
index 5c08188bc..f573cf0cf 100644
--- a/modules/graphics_utils.js
+++ b/modules/graphics_utils.js
@@ -1,6 +1,6 @@
// draw an arc between radii minR and maxR, and between angles minAngle and maxAngle centered at X,Y. All angles are radians.
exports.fillArc = function(graphics, X, Y, minR, maxR, minAngle, maxAngle, stepAngle) {
- var step = stepAngle || 0.2;
+ var step = stepAngle || 0.21;
var angle = minAngle;
var inside = [];
var outside = [];
@@ -31,5 +31,5 @@ exports.degreesToRadians = function(degrees){
}
exports.radiansToDegrees = function(radians){
- return 180/Math.PI * degrees;
+ return 180/Math.PI * radians;
}
\ No newline at end of file
diff --git a/modules/widget_utils.js b/modules/widget_utils.js
index 154a95f68..2a6a407be 100644
--- a/modules/widget_utils.js
+++ b/modules/widget_utils.js
@@ -145,4 +145,5 @@ exports.swipeOn = function(autohide) {
};
Bangle.on("swipe", exports.swipeHandler);
+ Bangle.drawWidgets();
};
|