diff --git a/apps.json b/apps.json index 6866ee2b0..960951dc0 100644 --- a/apps.json +++ b/apps.json @@ -3,7 +3,7 @@ "id": "fwupdate", "name": "Firmware Update", "version": "0.02", - "description": "Uploads new Espruino firmwares to Bangle.js 2", + "description": "[BETA] Uploads new Espruino firmwares to Bangle.js 2. For now, please use the instructions under https://www.espruino.com/Bangle.js2#firmware-updates", "icon": "app.png", "type": "RAM", "tags": "tools,system", @@ -11,7 +11,7 @@ "custom": "custom.html", "customConnect": true, "storage": [], - "sortorder": -20 + "sortorder": 20 }, { "id": "boot", @@ -33,10 +33,11 @@ "id": "hebrew_calendar", "name": "Hebrew Calendar", "shortName": "HebCal", - "version": "0.03", + "version": "0.04", "description": "lists the date according to the hebrew calendar", "icon": "app.png", - "tags": "", + "allow_emulator": false, + "tags": "tool,locale", "supports": [ "BANGLEJS", "BANGLEJS2" @@ -47,6 +48,10 @@ "name": "hebrew_calendar.app.js", "url": "app.js" }, + { + "name": "hebrewDate", + "url": "hebrewDate.js" + }, { "name": "hebrew_calendar.img", "url": "app-icon.js", @@ -54,6 +59,21 @@ } ] }, + { "id": "golfscore", + "name": "Golf Score", + "shortName":"golfscore", + "version":"0.02", + "description": "keeps track of strokes during a golf game", + "icon": "app.png", + "tags": "outdoors", + "allow_emulator": true, + "supports" : ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"golfscore.app.js","url":"app.js"}, + {"name":"golfscore.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "messages", "name": "Messages", @@ -282,7 +302,7 @@ { "id": "gbridge", "name": "Gadgetbridge", - "version": "0.24", + "version": "0.25", "description": "(NOT RECOMMENDED) Handles Gadgetbridge notifications from Android. This is now replaced by the 'Android' app.", "icon": "app.png", "type": "widget", @@ -538,7 +558,7 @@ "icon": "clock-impword.png", "type": "clock", "tags": "clock", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "screenshots": [{"url":"bangle1-impercise-word-clock-screenshot.png"}], "allow_emulator": true, "storage": [ @@ -824,7 +844,7 @@ { "id": "weather", "name": "Weather", - "version": "0.12", + "version": "0.13", "description": "Show Gadgetbridge weather report", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], @@ -1127,7 +1147,7 @@ { "id": "qrcode", "name": "Custom QR Code", - "version": "0.03", + "version": "0.04", "description": "Use this to upload a customised QR code to Bangle.js", "icon": "app.png", "tags": "qrcode", @@ -3871,7 +3891,7 @@ "id": "qmsched", "name": "Quiet Mode Schedule and Widget", "shortName": "Quiet Mode", - "version": "0.04", + "version": "0.05", "description": "Automatically turn Quiet Mode on or off at set times, and change LCD options while Quiet Mode is active.", "icon": "app.png", "screenshots": [{"url":"screenshot_b1_main.png"},{"url":"screenshot_b1_edit.png"},{"url":"screenshot_b1_lcd.png"}, @@ -4118,14 +4138,17 @@ { "id": "vectorclock", "name": "Vector Clock", - "version": "0.02", + "version": "0.03", "description": "A digital clock that uses the built-in vector font.", "icon": "app.png", "type": "clock", "tags": "clock", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "allow_emulator": true, - "screenshots": [{"url":"bangle1-vector-clock-screenshot.png"}], + "screenshots": [ + {"url":"bangle2-vector-clock-screenshot.png"}, + {"url":"bangle1-vector-clock-screenshot.png"} + ], "storage": [ {"name":"vectorclock.app.js","url":"app.js"}, {"name":"vectorclock.img","url":"app-icon.js","evaluate":true} @@ -4443,9 +4466,9 @@ "name": "A Battery Widget (with percentage)", "shortName":"A Battery Widget", "icon": "widget.png", - "version":"1.01", + "version":"1.02", "type": "widget", - "supports": ["BANGLEJS2"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "description": "Simple and slim battery widget with charge status and percentage", "tags": "widget,battery", @@ -4712,7 +4735,7 @@ { "id": "pooqroman", "name": "pooq Roman watch face", "shortName":"pooq Roman", - "version":"0.0.0", + "version":"0.02", "description": "A classic watch face with a certain dynamicity. Most amusing in 24h mode. Slide up to show more hands, down for less(!). By design does not support standard widgets, sorry!", "icon": "app.png", "type": "clock", @@ -4747,7 +4770,7 @@ { "id": "weatherClock", "name": "Weather Clock", - "version": "0.03", + "version": "0.04", "description": "A clock which displays current weather conditions (requires Gadgetbridge and Weather apps).", "icon": "app.png", "screenshots": [{"url":"screens/screen1.png"}], @@ -4830,9 +4853,10 @@ "id": "ptlaunch", "name": "Pattern Launcher", "shortName": "Pattern Launcher", - "version": "0.02", + "version": "0.10", "description": "Directly launch apps from the clock screen with custom patterns.", "icon": "app.png", + "screenshots": [{"url":"main_menu_add.png"}, {"url":"add_pattern.png"}, {"url":"select_app.png"}, {"url":"main_menu_manage.png"}, {"url":"manage_patterns.png"}], "tags": "tools", "supports": ["BANGLEJS2"], "readme": "README.md", @@ -4843,22 +4867,6 @@ ], "data": [{"name":"ptlaunch.patterns.json"}] }, - { "id": "clicompleteclk", - "name": "CLI complete clock", - "shortName":"CLI cmplt clock", - "version":"0.02", - "description": "Command line styled clock with lots of information", - "icon": "app.png", - "allow_emulator": true, - "type": "clock", - "tags": "clock,cli,command,bash,shell,weather,hrt", - "supports" : ["BANGLEJS", "BANGLEJS2"], - "readme": "README.md", - "storage": [ - {"name":"clicompleteclk.app.js","url":"app.js"}, - {"name":"clicompleteclk.img","url":"app-icon.js","evaluate":true} - ] - }, { "id": "rebble", "name": "Rebble Clock", @@ -4877,5 +4885,52 @@ {"name":"rebble.settings.js","url":"rebble.settings.js"}, {"name":"rebble.img","url":"rebble.icon.js","evaluate":true} ] + }, + { "id": "snaky", + "name": "Snaky", + "shortName":"Snaky", + "version":"0.01", + "description": "The classic snake game. Eat apples and don't bite your tail. Control the snake with the touch screen.", + "tags": "game,fun", + "icon": "snaky.png", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"snaky.app.js","url":"snaky.js"}, + {"name":"snaky.img","url":"snaky-icon.js","evaluate":true} + ] + }, + { + "id": "clicompleteclk", + "name": "CLI complete clock", + "shortName":"CLI cmplt clock", + "version":"0.03", + "description": "Command line styled clock with lots of information", + "icon": "app.png", + "allow_emulator": true, + "type": "clock", + "tags": "clock,cli,command,bash,shell,weather,hrt", + "supports" : ["BANGLEJS", "BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"clicompleteclk.img","url":"app-icon.js","evaluate":true}, + {"name":"clicompleteclk.settings.js","url":"settings.js"} + ], + "data": [{"name":"clicompleteclk.json"}] + }, + { + "id":"awairmonitor", + "name":"Awair Monitor", + "icon": "app.png", + "allow_emulator": true, + "version":"0.01", + "description": "Displays the level of CO2, VOC, PM 2.5, Humidity and Temperature, from your Awair device.", + "tags": "tool,health", + "readme":"README.md", + "supports":["BANGLEJS2"], + "storage": [ + {"name":"awairmonitor.app.js","url":"app.js"}, + {"name":"awairmonitor.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/awairmonitor/ChangeLog b/apps/awairmonitor/ChangeLog new file mode 100644 index 000000000..0cc9a42b0 --- /dev/null +++ b/apps/awairmonitor/ChangeLog @@ -0,0 +1 @@ +0.01: Beta version for Bangle 2 paired with Chrome (2021/12/11) diff --git a/apps/awairmonitor/README.md b/apps/awairmonitor/README.md new file mode 100644 index 000000000..8d6e25633 --- /dev/null +++ b/apps/awairmonitor/README.md @@ -0,0 +1,20 @@ +# Awair Monitor + +Displays the level of CO2, VOC, PM 2.5, Humidity and Temperature, from your Awair device. + +* What you need: + * A BangleJS 2 + * An Awair device [with local API enabled](https://support.getawair.com/hc/en-us/articles/360049221014-Awair-Local-API-Feature) + * The web app [awair_to_bangle.html](awair_to_bangle.html) that will retrive the data from your Awair device and sent it to your BangleJS 2 through Chrome's Bluetooth LE connection +* How to get started + * Open awair_to_bangle.html with a text/code editor and input the IP address of your Awair on top (const awair_ip_1 = "192.168.xx.xx") + * Launch the Awair Monitor app on your BangleJS + * Open awair_to_bangle.html on Chrome and click "Connect BangleJS" - it connects to your watch the same way as the Bangle app store + * Once connected to the watch with the app running, the watch app is updated once per second + +![](screenshot.png) + +## Creator +[@alainsaas](https://github.com/alainsaas) + +Contributions are welcome, send me your Pull Requests! diff --git a/apps/awairmonitor/app-icon.js b/apps/awairmonitor/app-icon.js new file mode 100644 index 000000000..9d4dcf4a3 --- /dev/null +++ b/apps/awairmonitor/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgP/AD38g4FD8EAAoeAgE/AoUD/EfAgP+AYMPDgQPBw4FB/F///DAoPwAQPjAQPBAQPxDgJVCAoP4gYaCCwIcBAoM/8P8h0HjEP8f4h0Gp0H4/44lj5+H4/54lzj/jx/5/lyDgIFDh/xAoQRBAoXsuY8Bx4jCAoeEkYFB447CAoRxBOAPxM4RmC8IFD4ZZD/8H/DHDh/+AoaSBUAIABCoYATVwS2Ct4FE84REXQQLCk4RJAo0XGxY=")) diff --git a/apps/awairmonitor/app.js b/apps/awairmonitor/app.js new file mode 100644 index 000000000..a5a1d1a72 --- /dev/null +++ b/apps/awairmonitor/app.js @@ -0,0 +1,98 @@ +Graphics.prototype.setFontMichroma36 = function() { +g.setFontCustom(atob("AAAAAAAAAAAAAAAAeAAAAAeAAAAAeAAAAAeAAAAAAAAAAAAAAAAAAAAAAAGAAAAA+AAAAD+AAAAP+AAAA/8AAAD/wAAAf/AAAB/4AAAH/gAAAf+AAAB/4AAAH/gAAAf+AAAAfwAAAAfAAAAAcAAAAAAAAAAAAAAAAAAAAAAAA///AAD///wAH///4AP///8APwAD+APAAAeAeAAAeAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAPAeAAAeAPAAAeAPwAD+AP///8AH///4AD///wAA///AAAAAAAAAAAAAAAAAAAAAEAAAAAOAAAAAfAAAAA+AAAAB8AAAAD8AAAAH4AAAAPwAAAAPgAAAAfAAAAAf///+Af///+Af///+Af///+AAAAAAAAAAAAAAAAAAAAAAAAAA/Af+AD/A/+AH/B/+AP/D/+APwD4eAPADweAfADweAeADweAeADweAeADweAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAHgeAeAPgeAeAPAeAeAPAeAeAPAeAeAPAeAfAPAeAPw/AeAP/+AeAH/+AeAD/8AeAB/wAOAAAAAAAAAAAAAAAAAAAAAAAAAB8APgAD8AP4AH8AP8AP8AP8APgAB+AfAAAeAeAAAeAeAAAPAeAAAPAeAAAPAeAAAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAPAeAeAeAfAeAeAPx/h+AP///+AH///8AD///4AB/h/gAAAAAAAAAAAAAAAAAAAAAAeAAAAA/AAAAA/AAAAB/AAAAD/AAAAH/AAAAPvAAAAPPAAAAfPAAAA+PAAAB8PAAAD4PAAADwPAAAHwPAAAPgPAAAfAPAAA+APAAA8APAAB8APAAD4APAAHwAPAAPgAPAAPAAPAAfAAPAAf///+Af///+Af///+Af///+AAAAPAAAAAPAAAAAPAAAAAPAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAf/8PgAf/8P4Af/8P8Af/8P8AeB4A+AeB4AeAeDwAeAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAPAeDwAfAeDwAeAeD4A+AeD+D+AeB//8AeB//4AeA//4AAAP/AAAAAAAAAAAAAAAAAAAAAAAAAAA///AAD///wAH///4AH///8AP4fB+APAeAeAfA8AeAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAfA8APAPA+AeAPgeAeAP8fh+AH8f/8AD8P/8AA8H/4AAAB/gAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAeAAAAAeAAAAAeAAAAAeAAAAAeAAACAeAAAGAeAAAOAeAAAeAeAAA+AeAAD+AeAAH8AeAAP4AeAAfwAeAA/gAeAB/AAeAD+AAeAP4AAeAfwAAeA/gAAeB/AAAeD+AAAeH8AAAefwAAAe/gAAAf/AAAAf+AAAAf8AAAAf4AAAAfgAAAAfAAAAAAAAAAAAAAAAAAAAAAAAAAMAAB+B/wAD/j/4AH/3/8AP///+AP//A+AfB+AeAeA+AeAeA+APAeA+APAeA+APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA8APAeA+APAeA+APAeA+APAeA+AOAeA+AeAPh/A+AP///+AP/3/8AH/3/8AB/D/wAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAD/4HAAH/8HwAP/+H4AP5/H8AfAfA8AeAPAeAeAPAeAeAPAeAeAHgfAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHgPAeAHAPAeAPAOAeAPAeAPAPAeAPwfB+AP///8AH///4AD///wAA///AAAAAAAAAAAAAAAAAAAAAAAAAAAB8DwAAB8HwAAB8HwAAB8DwAAAAAAAAAAAAA"), 46, atob("CBIkESMjJCMjIyMjCA=="), 36+(1<<8)+(1<<16)); +}; + +var drawTimeout; + +function queueNextDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 1000 - (Date.now() % 1000)); +} + +var locale = require("locale"); + +var bt_current_co2 = 0; +var bt_current_voc = 0; +var bt_current_pm25 = 0; +var bt_current_humi = 0; +var bt_current_temp = 0; +var bt_last_update = 0; + +var last_update = 0; +var bt_co2_history = new Array(10).fill(0); +var bt_voc_history = new Array(10).fill(0); +var bt_pm25_history = new Array(10).fill(0); +var bt_humi_history = new Array(10).fill(0); +var bt_temp_history = new Array(10).fill(0); + +var internal_last_update = -1; + +function draw() { + g.reset().clearRect(0,24,g.getWidth(),g.getHeight()); + + var date = new Date(); + g.setFontAlign(0,0); + g.setFont("Michroma36").drawString(locale.time(date,1), g.getWidth()/2, 56); + + g.setFont("6x8"); + g.drawString(locale.date(new Date(),1), g.getWidth()/2, 80); + + g.setFont("6x8"); + g.drawString("CO2", 20, 100); + g.drawString("VOC", 55, 100); + g.drawString("PM25", 90, 100); + g.drawString("Humi", 125, 100); + g.drawString("Temp", 160, 100); + + g.setFont("HaxorNarrow7x17"); + g.drawString(""+bt_current_co2, 18, 110); + g.drawString(""+bt_current_voc, 53, 110); + g.drawString(""+bt_current_pm25, 88, 110); + g.drawString(""+bt_current_humi, 123, 110); + g.drawString(""+bt_current_temp, 158, 110); + + if (last_update != bt_last_update) { + last_update = bt_last_update; + internal_last_update = last_update; + if (last_update % 10 == 0) { + bt_co2_history.shift(); bt_co2_history.push(bt_current_co2); + bt_voc_history.shift(); bt_voc_history.push(bt_current_voc); + bt_pm25_history.shift(); bt_pm25_history.push(bt_current_pm25); + bt_humi_history.shift(); bt_humi_history.push(bt_current_humi); + bt_temp_history.shift(); bt_temp_history.push(bt_current_temp); + } + } + + if (internal_last_update == -1) { + g.drawString("Waiting for connection", 88, 164); + } else if (internal_last_update > last_update + 5) { + g.drawString("Trying to reconnect since " + (internal_last_update - last_update), 88, 164); + } + + + for (i = 0; i < 10; i++) { + // max height = 32 + g.drawLine(10+i*2, 150-(Math.min(Math.max(bt_co2_history[i],400), 1200)-400)/25, 10+i*2, 150); + g.drawLine(45+i*2, 150-(Math.min(Math.max(bt_voc_history[i],0), 1440)-0)/45, 45+i*2, 150); + g.drawLine(80+i*2, 150-(Math.min(Math.max(bt_pm25_history[i],0), 32)-0)/1, 80+i*2, 150); + g.drawLine(115+i*2, 150-(Math.min(Math.max(bt_humi_history[i],20), 60)-20)/1.25, 115+i*2, 150); + g.drawLine(150+i*2, 150-(Math.min(Math.max(bt_temp_history[i],19), 27)-19)*4, 150+i*2, 150); + + // target humidity level + g.setColor("#00F").drawLine(115, 150-(40-20)/1.25, 115+18, 150-(40-20)/1.25); + g.reset(); + } + + if (internal_last_update != -1) { internal_last_update++; } + queueNextDraw(); +} + +// init +require("FontHaxorNarrow7x17").add(Graphics); +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +draw(); diff --git a/apps/awairmonitor/app.png b/apps/awairmonitor/app.png new file mode 100644 index 000000000..26a5d0cff Binary files /dev/null and b/apps/awairmonitor/app.png differ diff --git a/apps/awairmonitor/awair_to_bangle.html b/apps/awairmonitor/awair_to_bangle.html new file mode 100644 index 000000000..2926cca9e --- /dev/null +++ b/apps/awairmonitor/awair_to_bangle.html @@ -0,0 +1,195 @@ + + + + + + + + + + +

+How to use +

+Step 1: Enable the Local API on your Awair: https://support.getawair.com/hc/en-us/articles/360049221014-Awair-Local-API-Feature +

+Step 2: Modify this HTML file to input the IP address of your Awair on top (const awair_ip_1 = "192.168.xx.xx") +

+Step 3: Launch the Awair Monitor app on your BangleJS +

+Step 4: Click "Connect BangleJS" +

+Step 5: Optionally, open the web inspector's console (Right click > Inspector > Console) to read the bluetooth logs +

+ +
+ + +
+ +

+ +
+
+
+
+
+ + diff --git a/apps/awairmonitor/screenshot.png b/apps/awairmonitor/screenshot.png new file mode 100644 index 000000000..51ca0aa44 Binary files /dev/null and b/apps/awairmonitor/screenshot.png differ diff --git a/apps/clicompleteclk/README.md b/apps/clicompleteclk/README.md index 62fdbbc61..8b8094633 100644 --- a/apps/clicompleteclk/README.md +++ b/apps/clicompleteclk/README.md @@ -3,12 +3,14 @@ Command line styled clock with lots of information: It can show the following (depending on availability) information: -* Time -* Day of week -* Date -* Weather conditions and temperature (requires app [Weather](https://banglejs.com/apps/#weather)) -* Steps (requires app [Health Tracking](https://banglejs.com/apps/#health%20tracking) or a step widget) -* Heart rate (when screen is on and unlocked) +* Time data: + * Time + * Day of week + * Date +* Additional information (can be toggled via settings): + * Weather conditions and temperature (requires app [Weather](https://banglejs.com/apps/#weather)) + * Steps (requires app [Health Tracking](https://banglejs.com/apps/#health%20tracking) or a step widget) + * Heart rate (when screen is on and unlocked) ## TODO * Make time font bigger diff --git a/apps/clicompleteclk/app.js b/apps/clicompleteclk/app.js index 7fbdabcc1..a39b37e58 100644 --- a/apps/clicompleteclk/app.js +++ b/apps/clicompleteclk/app.js @@ -1,31 +1,60 @@ const storage = require('Storage'); const locale = require("locale"); -const font = "12x20"; -const fontsize = 1; +const font12 = g.getFonts().includes("12x20"); +const font = font12 ? "12x20" : "6x8"; +const fontsize = font12 ? 1: 2; const fontheight = 19; -const marginTop = 10; +const marginTop = 5; const marginLeftTopic = 3; // margin of topics -const marginLeftData = 68; // margin of data values +const marginLeftData = font12 ? 64 : 75; // margin of data values const topicColor = g.theme.dark ? "#fff" : "#000"; const textColor = g.theme.dark ? "#0f0" : "#080"; +const textColorRed = g.theme.dark ? "#FF0000" : "#FF0000"; let hrtValue; let hrtValueIsOld = false; + let localTempValue; let weatherTempString; let lastHeartRateRowIndex; +let lastStepsRowIndex; +let i = 2; + +let settings; + +function loadSettings() { + settings = storage.readJSON('clicompleteclk.json', 1) || {}; +} + +function setting(key) { + if (!settings) { loadSettings(); } + const DEFAULTS = { + 'battery': true, + 'batteryLvl': 30, + 'weather': true, + 'steps': true, + 'heartrate': true + }; + return (key in settings) ? settings[key] : DEFAULTS[key]; +} + + +let showBattery = setting('battery'); +let batteryWarnLevel = setting('batteryLvl'); +let showWeather = setting('weather'); +let showSteps = setting('steps'); +let showHeartRate = setting('heartrate'); + -// timeout used to update every minute var drawTimeout; -// schedule a draw for the next minute function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function() { drawTimeout = undefined; - drawAll(false); + drawAll(true); }, 60000 - (Date.now() % 60000)); } @@ -42,15 +71,13 @@ function updateTime(now){ if (!Bangle.isLCDOn()) return; writeLineTopic("TIME", 1); writeLine(locale.time(now,1),1); - if(now.getMinutes() == 0) - drawInfo(now); } function drawInfo(now) { - if (now == undefined) + if (now == undefined) now = new Date(); - let i = 2; + i = 2; writeLineTopic("DOWK", i); writeLine(locale.dow(now),i); @@ -60,14 +87,28 @@ function drawInfo(now) { writeLine(locale.date(now,1),i); i++; - /* - writeLineTopic("BAT", i); - const b = E.getBattery(); - writeLine(b + "%", i); // TODO make bars - i++; - */ + if (showBattery) { + writeLineTopic("BATT", i); + const b = E.getBattery(); + writeLine(b + "%", i, b < batteryWarnLevel ? textColorRed : textColor); + i++; + } - // weather + if (showWeather) { + drawWeather(); + } + + if (showSteps) { + drawSteps(i); + i++; + } + + if (showHeartRate) { + drawHeartRate(i); + } +} + +function drawWeather() { const weatherJson = getWeather(); if(weatherJson && weatherJson.weather){ const currentWeather = weatherJson.weather; @@ -82,19 +123,22 @@ function drawInfo(now) { writeLine(weatherTempValue,i); i++; } +} - // steps +function drawSteps(i) { + if (!showSteps) return; + if (i == undefined) + i = lastStepsRowIndex; const steps = getSteps(); if (steps != undefined) { writeLineTopic("STEP", i); writeLine(steps, i); - i++; } - - drawHeartRate(i); + lastStepsRowIndex = i; } function drawHeartRate(i) { + if (!showHeartRate) return; if (i == undefined) i = lastHeartRateRowIndex; writeLineTopic("HRTM", i); @@ -155,15 +199,21 @@ function getWeather() { // turn on HRM when the LCD is unlocked Bangle.on('lock', function(isLocked) { if (!isLocked) { - Bangle.setHRMPower(1,"clicompleteclk"); - if (hrtValue == undefined) - hrtValue = "..."; - else - hrtValueIsOld = true; + if (showHeartRate) { + Bangle.setHRMPower(1,"clicompleteclk"); + if (hrtValue == undefined) + hrtValue = "..."; + else + hrtValueIsOld = true; + } } else { - hrtValueIsOld = true; - Bangle.setHRMPower(0,"clicompleteclk"); + if (showHeartRate) { + hrtValueIsOld = true; + Bangle.setHRMPower(0,"clicompleteclk"); + } } + // Update steps and heart rate + drawSteps(); drawHeartRate(); }); @@ -171,25 +221,30 @@ Bangle.on('lcdPower',function(on) { if (on) { drawAll(true); } else { - hrtValueIsOld = true; + if (showHeartRate) { + hrtValueIsOld = true; + } if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; } }); -Bangle.on('HRM', function(hrm) { - //if(hrm.confidence > 90){ - hrtValueIsOld = false; - hrtValue = hrm.bpm; - if (Bangle.isLCDOn()) - drawHeartRate(); - //} else { - // hrtValue = undefined; - //} -}); +if (showHeartRate) { + Bangle.on('HRM', function(hrm) { + //if(hrm.confidence > 90){ + hrtValueIsOld = false; + hrtValue = hrm.bpm; + if (Bangle.isLCDOn()) + drawHeartRate(); + //} else { + // hrtValue = undefined; + //} + }); +} g.clear(); Bangle.setUI("clock"); Bangle.loadWidgets(); Bangle.drawWidgets(); +loadSettings(); drawAll(true); diff --git a/apps/clicompleteclk/settings.js b/apps/clicompleteclk/settings.js new file mode 100644 index 000000000..2df20ed3e --- /dev/null +++ b/apps/clicompleteclk/settings.js @@ -0,0 +1,54 @@ +(function(back) { + const storage = require('Storage'); + let settings = storage.readJSON('clicompleteclk.json', 1) || {}; + function save(key, value) { + settings[key] = value; + storage.write('clicompleteclk.json', settings); + } + E.showMenu({ + '': { 'title': 'CLI complete clk' }, + 'Show battery': { + value: "battery" in settings ? settings.battery : false, + format: () => (settings.battery ? 'Yes' : 'No'), + onchange: () => { + settings.battery = !settings.battery; + save('battery', settings.battery); + }, + }, + 'Battery warn': { + value: "batteryLvl" in settings ? settings.batteryLvl : 30, + min: 0, + max : 100, + step: 10, + format: x => { + return x + "%"; + }, + onchange: x => save('batteryLvl', x), + }, + 'Show weather': { + value: "weather" in settings ? settings.weather : false, + format: () => (settings.weather ? 'Yes' : 'No'), + onchange: () => { + settings.weather = !settings.weather; + save('weather', settings.weather); + }, + }, + 'Show steps': { + value: "steps" in settings ? settings.steps : false, + format: () => (settings.steps ? 'Yes' : 'No'), + onchange: () => { + settings.steps = !settings.steps; + save('steps', settings.steps); + }, + }, + 'Show heartrate': { + value: "heartrate" in settings ? settings.heartrate : false, + format: () => (settings.heartrate ? 'Yes' : 'No'), + onchange: () => { + settings.heartrate = !settings.heartrate; + save('heartrate', settings.heartrate); + }, + }, + '< Back': back, + }); +}); diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html index b5c79a325..8c2008e54 100644 --- a/apps/fwupdate/custom.html +++ b/apps/fwupdate/custom.html @@ -3,6 +3,8 @@ +

THIS IS CURRENTLY BETA - PLEASE USE THE NORMAL FIRMWARE UPDATE + INSTRUCTIONS FOR BANGLE.JS 1 AND BANGLE.JS 2. For usage on Bangle.js 2 you'll likely need to have an updated bootloader.

Firmware updates using the App Loader are only possible on Bangle.js 2. For firmware updates on Bangle.js 1 please diff --git a/apps/gbridge/ChangeLog b/apps/gbridge/ChangeLog index fddb1eb80..67d421f33 100644 --- a/apps/gbridge/ChangeLog +++ b/apps/gbridge/ChangeLog @@ -24,3 +24,5 @@ 0.22: Respect Quiet Mode 0.23: Allow notification dismiss to remove from phone too 0.24: tag HRM power requests to allow this to work alongside other widgets/apps (fix #799) +0.25: workaround call notification + Fix inflated step number diff --git a/apps/gbridge/widget.js b/apps/gbridge/widget.js index 53f832b07..7cb7147ec 100644 --- a/apps/gbridge/widget.js +++ b/apps/gbridge/widget.js @@ -184,7 +184,7 @@ case "call": var note = { size: 55, title: event.name, id: "call", body: event.number, icon:require("heatshrink").decompress(atob("jEYwIMJj4CCwACJh4CCCIMOAQMGAQMHAQMDAQMBCIMB4PwgHz/EAn4CBj4CBg4CBgACCAAw="))} - if (event.cmd === "incoming") { + if (event.cmd === "incoming" || event.cmd === "") { require("notify").show(note); if (!(require('Storage').readJSON('setting.json',1)||{}).quiet) { Bangle.buzz(); @@ -262,7 +262,7 @@ // Send a summary of activity to Gadgetbridge function sendActivity(hrm) { var steps = currentSteps - lastSentSteps; - lastSentSteps = 0; + lastSentSteps = currentSteps; gbSend({ t: "act", stp: steps, hrm:hrm }); } diff --git a/apps/golfscore/ChangeLog b/apps/golfscore/ChangeLog new file mode 100644 index 000000000..4995dd59a --- /dev/null +++ b/apps/golfscore/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App! +0.02: multiple player score support \ No newline at end of file diff --git a/apps/golfscore/README.md b/apps/golfscore/README.md new file mode 100644 index 000000000..68552ad4b --- /dev/null +++ b/apps/golfscore/README.md @@ -0,0 +1,37 @@ +# Golf Score + +Lets you keep track of strokes during a game of Golf. + +![](mainmenu.png) +![](setupmenu.png) +![](scorecard.png) +![](holemenu.png) + +## Usage + +1. Open the app, +1. scroll to setup +2. set the number of holes (18 by default, but can be configured) +3. set the number of players (4 by default, but can be 1-20) +4. click back +5. scroll to a hole (hole 1) +6. scroll to a player and set the number of strokes they took (repeat as needed) +7. click next hole and repeat #6 and #7 as needed; or click back +8. at any time, check the score card for a sum total of all the strokes for each player + +## Features + +Track strokes for multiple players (1-20) +Set number of holes on course + +## Controls + +N/A + +## Requests + +Michael Salaverry (github.com/barakplasma) + +## Creator + +Michael Salaverry diff --git a/apps/golfscore/app-icon.js b/apps/golfscore/app-icon.js new file mode 100644 index 000000000..238001688 --- /dev/null +++ b/apps/golfscore/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwIEBgOABQcD4AFDg1wAokYDokOAokDDwkBDwkADwn4nAFD/geDgP8gYFEDwn8gFgDocA+AFCkE/A4IABg//Aoc//4RDn/+Goc/8AFJj4FLEQYFGh4FLIAYFGg4FKh5sBApEfnhTEAok+Aol8vihEAon4AocB+F4ZQYFF8AFDg/AAocPAouAKYcfXQQFHjzEEhjvDA")) diff --git a/apps/golfscore/app.js b/apps/golfscore/app.js new file mode 100644 index 000000000..7c5c2d0e8 --- /dev/null +++ b/apps/golfscore/app.js @@ -0,0 +1,113 @@ +// @ts-check +// @ts-ignore +const menu = require("graphical_menu"); +/** + * @type {{showMenu: (config) => void}} + */ +let E; +/** + * @type {{clear: () => void}} + */ +let g; + +let holes_count = 18; +let player_count = 4; +/** + * @type {number[][]} + */ +let course = new Array(holes_count).map(() => new Array(player_count).fill(0)); + +const main_menu = { + "": { + "title": "-- Golf --" + }, + "Setup": function () { E.showMenu(setup_menu); }, + "Score Card": function () { + calculate_score(); + E.showMenu(score_card); + }, +}; + +function calculate_score() { + let scores = course.reduce((acc, hole) => { + hole.forEach((stroke_count, player) => { + acc[player] = acc[player]+stroke_count; + }); + return acc; + }, new Array(player_count).fill(0)); + + score_card = { + "": { + "title": "score card" + }, + "< Back": function () { E.showMenu(main_menu); }, + }; + + for (let player = 0; player < player_count; player++) { + score_card["Player - " + (player + 1)] = { + value: scores[player] + }; + } +} + +let score_card = {}; + +const setup_menu = { + "": { + "title": "-- Golf Setup --" + }, + "Holes": { + value: holes_count, + min: 1, max: 20, step: 1, wrap: true, + onchange: v => { holes_count = v; add_holes(); } + }, + "Players": { + value: player_count, + min: 1, max: 10, step: 1, wrap: true, + onchange: v => { player_count = v; } + }, + "< Back": function () { E.showMenu(main_menu); }, +}; + +function inc_hole(i, player) { return function (v) { course[i][player] = v; }; } + +function add_holes() { + for (let j = 0; j < 20; j++) { + delete main_menu["Hole - " + (j + 1)]; + } + for (let i = 0; i < holes_count; i++) { + course[i] = new Array(player_count).fill(0); + main_menu["Hole - " + (i + 1)] = goto_hole_menu(i); + } + E.showMenu(main_menu); +} + +function goto_hole_menu(i) { + return function () { + E.showMenu(hole_menu(i)); + }; +} + +function hole_menu(i) { + let menu = { + "": { + "title": `-- Hole ${i + 1}--` + }, + "Next hole": goto_hole_menu(i + 1), + "< Back": function () { E.showMenu(main_menu); }, + }; + + for (let player = 0; player < player_count; player++) { + menu[`player - ${player + 1}`] = { + value: course[i][player], + min: 1, max: 20, step: 1, wrap: true, + onchange: inc_hole(i, player) + }; + } + + return menu; +} + +// @ts-ignore +g.clear(); +add_holes(); \ No newline at end of file diff --git a/apps/golfscore/app.png b/apps/golfscore/app.png new file mode 100644 index 000000000..fc5d51557 Binary files /dev/null and b/apps/golfscore/app.png differ diff --git a/apps/golfscore/holemenu.png b/apps/golfscore/holemenu.png new file mode 100644 index 000000000..ac214f182 Binary files /dev/null and b/apps/golfscore/holemenu.png differ diff --git a/apps/golfscore/mainmenu.png b/apps/golfscore/mainmenu.png new file mode 100644 index 000000000..3ebeb0ca7 Binary files /dev/null and b/apps/golfscore/mainmenu.png differ diff --git a/apps/golfscore/scorecard.png b/apps/golfscore/scorecard.png new file mode 100644 index 000000000..9e7ff1130 Binary files /dev/null and b/apps/golfscore/scorecard.png differ diff --git a/apps/golfscore/setupmenu.png b/apps/golfscore/setupmenu.png new file mode 100644 index 000000000..13158e2e7 Binary files /dev/null and b/apps/golfscore/setupmenu.png differ diff --git a/apps/hebrew_calendar/ChangeLog b/apps/hebrew_calendar/ChangeLog index d7dbc19e3..fdd29db66 100644 --- a/apps/hebrew_calendar/ChangeLog +++ b/apps/hebrew_calendar/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: using TS and rollup to bundle -0.03: bug fixes and support bangle 1 \ No newline at end of file +0.03: bug fixes and support bangle 1 +0.04: removing TS \ No newline at end of file diff --git a/apps/hebrew_calendar/LICENSE b/apps/hebrew_calendar/LICENSE index cd6624ad4..bdcdec9e4 100644 --- a/apps/hebrew_calendar/LICENSE +++ b/apps/hebrew_calendar/LICENSE @@ -1,5 +1,5 @@ The MIT License (MIT) - +Copyright (c) 2021 Michael Salaverry Copyright (c) 2016-20 Ionică Bizău (https://ionicabizau.net) Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/apps/hebrew_calendar/app.js b/apps/hebrew_calendar/app.js index 9c21fa89b..399d124f3 100644 --- a/apps/hebrew_calendar/app.js +++ b/apps/hebrew_calendar/app.js @@ -1,17 +1,26 @@ -!function(){"use strict"; -/*! - * This script was taked from this page and ported to Node.js by Ionic Bizu - * http://www.shamash.org/help/javadate.shtml - * - * This script was adapted from C sources written by - * Scott E. Lee, which contain the following copyright notice: - * - * Copyright 1993-1995, Scott E. Lee, all rights reserved. - * Permission granted to use, copy, modify, distribute and sell so long as - * the above copyright and this permission statement are retained in all - * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK. - * - * Bill Hastings - * RBI Software Systems - * bhastings@rbi.com - */var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};var i=new function(t,i,e,o,r,n,h,a,s,f,u,l,v,c){this[0]=t,this[1]=i,this[2]=e,this[3]=o,this[4]=r,this[5]=n,this[6]=h,this[7]=a,this[8]=s,this[9]=f,this[10]=u,this[11]=l,this[12]=v,this[13]=c}("Tishri","Heshvan","Kislev","Tevet","Shevat","AdarI","AdarII","Nisan","Iyyar","Sivan","Tammuz","Av","Elul"),e=new function(t,i,e,o,r,n,h,a,s,f,u,l,v,c,y,d,m,M,b){this[0]=t,this[1]=i,this[2]=e,this[3]=o,this[4]=r,this[5]=n,this[6]=h,this[7]=a,this[8]=s,this[9]=f,this[10]=u,this[11]=l,this[12]=v,this[13]=c,this[14]=y,this[15]=d,this[16]=m,this[17]=M,this[18]=b}(12,12,13,12,12,13,12,13,12,12,13,12,12,13,12,12,13,12,13);g.clear();let o=new Date,r=function(o){var r,n,h=0,a=0,s=0,f=0,u=0,l=0,v=0;function c(t){var i,o,r,n;for(f=Math.floor((t+310)/6940),r=void 0,n=void 0,r=31524,n=(r+=45971*f)>>16,n+=2744*f,o=Math.floor(n/25920),r=(n-=25920*o)<<16|65535&r,i=Math.floor(r/25920),l=o<<16|i,v=r-=25920*i;lt-74);u++)v+=765433*e[u],l+=Math.floor(v/25920),v%=25920}function y(t,i,e){var o=i,r=o%7;return(e>=19440||!(2==t||5==t||7==t||10==t||13==t||16==t||18==t)&&2==r&&e>=9924||(3==t||6==t||8==t||11==t||14==t||17==t||0==t)&&1==r&&e>=16789)&&(o++,7==++r&&(r=0)),3!=r&&5!=r&&0!=r||o++,o}var d=o;return"object"===(void 0===d?"undefined":t(d))&&(r=o.getMonth()+1,n=o.getDate(),d=o.getFullYear()),function(t){var i,o=0,r=0,n=t-347997;if(c(n),n>=(o=y(u,l,v))){if(s=19*f+u+1,n=o-177)return void(n>o-30?(h=13,a=n-o+30):n>o-60?(h=12,a=n-o+60):n>o-89?(h=11,a=n-o+89):n>o-119?(h=10,a=n-o+119):n>o-148?(h=9,a=n-o+148):(h=8,a=n-o+178));if(13==e[(s-1)%19]){if(h=7,(a=n-o+207)>0)return;if(h--,(a+=30)>0)return;h--,a+=30}else{if(h=6,(a=n-o+207)>0)return;h--,a+=30}if(a>0)return;if(h--,(a+=29)>0)return;r=o,c(l-365),o=y(u,l,v)}if(l=n-o-29,355==(i=r-o)||385==i){if(l<=30)return h=2,void(a=l);l-=30}else{if(l<=29)return h=2,void(a=l);l-=29}h=3,a=l}(function(t,i,e){var o=0,r=0,n=void 0;return o=t<0?t+4801:t+4800,i>2?r=i-3:(r=i+9,o--),n=Math.floor(146097*Math.floor(o/100)/4),n+=Math.floor(o%100*1461/4),n+=Math.floor((153*r+2)/5),n+=e-32045}(d,r,n)),{year:s,month:h,date:a,month_name:i[h-1]}}(o);var n={"":{title:"Hebrew Date"},cal:{value:require("locale").date(o,1),onchange:()=>{}},date:{value:r.date,onchange:()=>{}},month:{value:r.month_name,onchange:()=>{}},year:{value:r.year,onchange:()=>{}}};E.showMenu(n)}(); +g.clear(); + +let now = new Date(); + +let today = require('hebrewDate').hebrewDate(now); + +var mainmenu = { + "": { + "title": "Hebrew Date" + }, + greg: { + // @ts-ignore + value: require('locale').date(now, 1), + }, + date: { + value: today.date, + }, + month: { + value: today.month_name, + }, + year: { + value: today.year, + } +}; +// @ts-ignore +E.showMenu(mainmenu); \ No newline at end of file diff --git a/apps/hebrew_calendar/src/hebrewDate.ts b/apps/hebrew_calendar/hebrewDate.js similarity index 77% rename from apps/hebrew_calendar/src/hebrewDate.ts rename to apps/hebrew_calendar/hebrewDate.js index cc3a5ed78..da0c9cf50 100644 --- a/apps/hebrew_calendar/src/hebrewDate.ts +++ b/apps/hebrew_calendar/hebrewDate.js @@ -1,6 +1,5 @@ /*! - * This script was taked from this page and ported to Node.js by Ionic Bizu - * http://www.shamash.org/help/javadate.shtml + * This script was taked from this page http://www.shamash.org/help/javadate.shtml and ported to Node.js by Ionică Bizău in https://github.com/IonicaBizau/hebrew-date * * This script was adapted from C sources written by * Scott E. Lee, which contain the following copyright notice: @@ -14,33 +13,11 @@ * RBI Software Systems * bhastings@rbi.com */ - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var GREG_SDN_OFFSET = 32045, - DAYS_PER_5_MONTHS = 153, - DAYS_PER_4_YEARS = 1461, - DAYS_PER_400_YEARS = 146097; - -var HALAKIM_PER_HOUR = 1080, - HALAKIM_PER_DAY = 25920, - HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, - HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7); - -var HEB_SDN_OFFSET = 347997, - NEW_MOON_OF_CREATION = 31524, - NOON = 18 * HALAKIM_PER_HOUR, - AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, - AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589; - -var SUN = 0, - MON = 1, - TUES = 2, - WED = 3, - THUR = 4, - FRI = 5, - SAT = 6; - +var GREG_SDN_OFFSET = 32045, DAYS_PER_5_MONTHS = 153, DAYS_PER_4_YEARS = 1461, DAYS_PER_400_YEARS = 146097; +var HALAKIM_PER_HOUR = 1080, HALAKIM_PER_DAY = 25920, HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7); +var HEB_SDN_OFFSET = 347997, NEW_MOON_OF_CREATION = 31524, NOON = 18 * HALAKIM_PER_HOUR, AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589; +var SUN = 0, MON = 1, TUES = 2, WED = 3, THUR = 4, FRI = 5, SAT = 6; function weekdayarr(d0, d1, d2, d3, d4, d5, d6) { this[0] = d0; this[1] = d1; @@ -50,7 +27,6 @@ function weekdayarr(d0, d1, d2, d3, d4, d5, d6) { this[5] = d5; this[6] = d6; } - function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { this[0] = m0; this[1] = m1; @@ -65,8 +41,7 @@ function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) { this[10] = m10; this[11] = m11; } - -function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13?: any) { +function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) { this[0] = m0; this[1] = m1; this[2] = m2; @@ -82,7 +57,6 @@ function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m this[12] = m12; this[13] = m13; } - function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18) { this[0] = m0; this[1] = m1; @@ -104,12 +78,7 @@ function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, this[17] = m17; this[18] = m18; } - -var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), - gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), - hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), - mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13); - +var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13); /** * hebrewDate * Convert the Gregorian dates into Hebrew calendar dates. @@ -124,55 +93,36 @@ var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "S * - `month_name`: The Hebrew month name. * - `date`: The Hebrew date. */ -export const hebrewDate = function (inputDateOrYear: Date) { +function hebrewDate(inputDateOrYear) { var inputMonth, inputDate; - - var hebrewMonth = 0, - hebrewDate = 0, - hebrewYear = 0, - metonicCycle = 0, - metonicYear = 0, - moladDay = 0, - moladHalakim = 0; - + var hebrewMonth = 0, hebrewDate = 0, hebrewYear = 0, metonicCycle = 0, metonicYear = 0, moladDay = 0, moladHalakim = 0; function GregorianToSdn(inputYear, inputMonth, inputDay) { - - var year = 0, - month = 0, - sdn = void 0; - + var year = 0, month = 0, sdn = void 0; // Make year a positive number if (inputYear < 0) { year = inputYear + 4801; - } else { + } + else { year = inputYear + 4800; } - // Adjust the start of the year if (inputMonth > 2) { month = inputMonth - 3; - } else { + } + else { month = inputMonth + 9; year--; } - sdn = Math.floor(Math.floor(year / 100) * DAYS_PER_400_YEARS / 4); sdn += Math.floor(year % 100 * DAYS_PER_4_YEARS / 4); sdn += Math.floor((month * DAYS_PER_5_MONTHS + 2) / 5); sdn += inputDay - GREG_SDN_OFFSET; - return sdn; } - function SdnToHebrew(sdn) { - var tishri1 = 0, - tishri1After = 0, - yearLength = 0, - inputDay = sdn - HEB_SDN_OFFSET; - + var tishri1 = 0, tishri1After = 0, yearLength = 0, inputDay = sdn - HEB_SDN_OFFSET; FindTishriMolad(inputDay); tishri1 = Tishri1(metonicYear, moladDay, moladHalakim); - if (inputDay >= tishri1) { // It found Tishri 1 at the start of the year. hebrewYear = metonicCycle * 19 + metonicYear + 1; @@ -180,7 +130,8 @@ export const hebrewDate = function (inputDateOrYear: Date) { if (inputDay < tishri1 + 30) { hebrewMonth = 1; hebrewDate = inputDay - tishri1 + 1; - } else { + } + else { hebrewMonth = 2; hebrewDate = inputDay - tishri1 - 29; } @@ -191,7 +142,8 @@ export const hebrewDate = function (inputDateOrYear: Date) { moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); moladHalakim = moladHalakim % HALAKIM_PER_DAY; tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); - } else { + } + else { // It found Tishri 1 at the end of the year. hebrewYear = metonicCycle * 19 + metonicYear; if (inputDay >= tishri1 - 177) { @@ -199,44 +151,56 @@ export const hebrewDate = function (inputDateOrYear: Date) { if (inputDay > tishri1 - 30) { hebrewMonth = 13; hebrewDate = inputDay - tishri1 + 30; - } else if (inputDay > tishri1 - 60) { + } + else if (inputDay > tishri1 - 60) { hebrewMonth = 12; hebrewDate = inputDay - tishri1 + 60; - } else if (inputDay > tishri1 - 89) { + } + else if (inputDay > tishri1 - 89) { hebrewMonth = 11; hebrewDate = inputDay - tishri1 + 89; - } else if (inputDay > tishri1 - 119) { + } + else if (inputDay > tishri1 - 119) { hebrewMonth = 10; hebrewDate = inputDay - tishri1 + 119; - } else if (inputDay > tishri1 - 148) { + } + else if (inputDay > tishri1 - 148) { hebrewMonth = 9; hebrewDate = inputDay - tishri1 + 148; - } else { + } + else { hebrewMonth = 8; hebrewDate = inputDay - tishri1 + 178; } return; - } else { + } + else { if (mpy[(hebrewYear - 1) % 19] == 13) { hebrewMonth = 7; hebrewDate = inputDay - tishri1 + 207; - if (hebrewDate > 0) return; + if (hebrewDate > 0) + return; hebrewMonth--; hebrewDate += 30; - if (hebrewDate > 0) return; - hebrewMonth--; - hebrewDate += 30; - } else { - hebrewMonth = 6; - hebrewDate = inputDay - tishri1 + 207; - if (hebrewDate > 0) return; + if (hebrewDate > 0) + return; hebrewMonth--; hebrewDate += 30; } - if (hebrewDate > 0) return; + else { + hebrewMonth = 6; + hebrewDate = inputDay - tishri1 + 207; + if (hebrewDate > 0) + return; + hebrewMonth--; + hebrewDate += 30; + } + if (hebrewDate > 0) + return; hebrewMonth--; hebrewDate += 29; - if (hebrewDate > 0) return; + if (hebrewDate > 0) + return; // We need the length of the year to figure this out,so find Tishri 1 of this year. tishri1After = tishri1; FindTishriMolad(moladDay - 365); @@ -253,7 +217,8 @@ export const hebrewDate = function (inputDateOrYear: Date) { return; } moladDay -= 30; - } else { + } + else { // Heshvan has 29 days if (moladDay <= 29) { hebrewMonth = 2; @@ -266,7 +231,6 @@ export const hebrewDate = function (inputDateOrYear: Date) { hebrewMonth = 3; hebrewDate = moladDay; } - function FindTishriMolad(inputDay) { // Estimate the metonic cycle number. Note that this may be an under // estimate because there are 6939.6896 days in a metonic cycle not @@ -287,18 +251,15 @@ export const hebrewDate = function (inputDateOrYear: Date) { } // Find the molad of Tishri closest to this date. for (metonicYear = 0; metonicYear < 18; metonicYear++) { - if (moladDay > inputDay - 74) break; + if (moladDay > inputDay - 74) + break; moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear]; moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY); moladHalakim = moladHalakim % HALAKIM_PER_DAY; } } - function MoladOfMetonicCycle() { - var r1 = void 0, - r2 = void 0, - d1 = void 0, - d2 = void 0; + var r1 = void 0, r2 = void 0, d1 = void 0, d2 = void 0; // Start with the time of the first molad after creation. r1 = NEW_MOON_OF_CREATION; // Calculate gMetonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 @@ -317,42 +278,34 @@ export const hebrewDate = function (inputDateOrYear: Date) { moladDay = d2 << 16 | d1; moladHalakim = r1; } - function Tishri1(metonicYear, moladDay, moladHalakim) { - var tishri1 = moladDay, - dow = tishri1 % 7, - leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, - lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0; - + var tishri1 = moladDay, dow = tishri1 % 7, leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0; // Apply rules 2,3 and 4 if (moladHalakim >= NOON || !leapYear && dow == TUES && moladHalakim >= AM3_11_20 || lastWasLeapYear && dow == MON && moladHalakim >= AM9_32_43) { tishri1++; dow++; - if (dow == 7) dow = 0; + if (dow == 7) + dow = 0; } - // Apply rule 1 after the others because it can cause an additional delay of one day. if (dow == WED || dow == FRI || dow == SUN) { tishri1++; } - return tishri1; } - - var inputYear: Date | number = inputDateOrYear; - + var inputYear = inputDateOrYear; if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") { inputMonth = inputDateOrYear.getMonth() + 1; inputDate = inputDateOrYear.getDate(); inputYear = inputDateOrYear.getFullYear(); } - SdnToHebrew(GregorianToSdn(inputYear, inputMonth, inputDate)); - return { year: hebrewYear, month: hebrewMonth, date: hebrewDate, month_name: hMonth[hebrewMonth - 1] }; -}; \ No newline at end of file +} + +exports.hebrewDate = hebrewDate; diff --git a/apps/hebrew_calendar/package.json b/apps/hebrew_calendar/package.json deleted file mode 100644 index 85e9ebbf0..000000000 --- a/apps/hebrew_calendar/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "hebrew_calendar", - "version": "0.0.3", - "description": "Bangle.js app for seeing hebrew calendar", - "main": "app.js", - "types": "app.d.ts", - "scripts": { - "build": "rollup -c" - }, - "author": { - "name": "Michael Salaverry", - "url": "https://github.com/barakplasma" - }, - "license": "MIT", - "devDependencies": { - "@rollup/plugin-typescript": "^4.1.1", - "rollup": "^2.10.2", - "rollup-plugin-terser": "^5.3.0", - "terser": "^4.7.0", - "tslib": "^2.0.0", - "typescript": "^3.9.2" - } -} diff --git a/apps/hebrew_calendar/rollup.config.mjs b/apps/hebrew_calendar/rollup.config.mjs deleted file mode 100644 index 5f7f0746f..000000000 --- a/apps/hebrew_calendar/rollup.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import { terser } from 'rollup-plugin-terser'; - -export default { - input: './src/app.ts', - output: { - dir: '.', - format: 'iife', - name: 'hebrew_calendar' - }, - plugins: [ - typescript(), - terser(), - ] -}; diff --git a/apps/hebrew_calendar/src/app.ts b/apps/hebrew_calendar/src/app.ts deleted file mode 100644 index 51314e337..000000000 --- a/apps/hebrew_calendar/src/app.ts +++ /dev/null @@ -1,34 +0,0 @@ -declare var Bangle: any; -declare var g: any; -declare var E: any; -declare var require: any; - -g.clear(); - -let now = new Date(); -import { hebrewDate } from "./hebrewDate"; - -let today = hebrewDate(now); - -var mainmenu = { - "" : { - "title" : "Hebrew Date" - }, - cal: { - value: require('locale').date(now,1), - onchange : () => {} - }, - date: { - value : today.date, - onchange : () => {} - }, - month: { - value : today.month_name, - onchange : () => {} - }, - year: { - value : today.year, - onchange : () => {} - } -}; -E.showMenu(mainmenu); diff --git a/apps/hebrew_calendar/tsconfig.json b/apps/hebrew_calendar/tsconfig.json deleted file mode 100644 index 30a9e35f4..000000000 --- a/apps/hebrew_calendar/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "module": "es2015", - "noImplicitAny": false, - "target": "es2015" - }, - "include": [ - "src" - ] -} diff --git a/apps/impwclock/ChangeLog b/apps/impwclock/ChangeLog index 0592d4d04..7bc119426 100644 --- a/apps/impwclock/ChangeLog +++ b/apps/impwclock/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Stopped watchface from flashing every interval 0.03: Move to Bangle.setUI to launcher support +0.04: Tweaks for compatibility with BangleJS2 diff --git a/apps/impwclock/README.md b/apps/impwclock/README.md index 30e42c95e..ac1341097 100644 --- a/apps/impwclock/README.md +++ b/apps/impwclock/README.md @@ -1,4 +1,4 @@ # Imprecise Word Clock -This clock tells time in very rough approximation, as in "Late morning" or "Early afternoon." Good for vacations and weekends. Press button 1 to see the time in accurate, digital form. But do you really need to know the exact time? +This clock tells time in very rough approximation, as in "Late morning" or "Early afternoon." Good for vacations and weekends. Touch the screen to see the time in accurate, digital form. But do you really need to know the exact time? diff --git a/apps/impwclock/clock-impword.js b/apps/impwclock/clock-impword.js index 5492eac15..8bb5da6ba 100644 --- a/apps/impwclock/clock-impword.js +++ b/apps/impwclock/clock-impword.js @@ -2,7 +2,7 @@ A remix of word clock by Gordon Williams https://github.com/gfwilliams - Changes the representation of time to be more general -- Shows accurate digital time when button 1 is pressed +- Toggles showing of accurate digital time when screen touched. */ /* jshint esversion: 6 */ @@ -34,14 +34,16 @@ const timeOfDay = { }; +var big = g.getWidth()>200; // offsets and increments -const xs = 35; -const ys = 31; -const dy = 22; -const dx = 25; +const xs = big ? 35 : 20; +const ys = big ? 31 : 28; +const dx = big ? 25 : 20; +const dy = big ? 22 : 16; + // font size and color -const fontSize = 3; // "6x8" +const fontSize = big ? 3 : 2; // "6x8" const passivColor = 0x3186 /*grey*/ ; const activeColorNight = 0xF800 /*red*/ ; const activeColorDay = 0xFFFF /* white */; @@ -115,6 +117,8 @@ function drawWordClock() { // check whether we need to redraw the watchface if (hidx !== hidxPrev) { + // Turn off showDigitalTime + showDigitalTime = false; // draw allWords var c; var y = ys; @@ -138,15 +142,14 @@ function drawWordClock() { hidxPrev = hidx; } - // Display digital time while button 1 is pressed - g.clearRect(0, 215, 240, 240); + // Display digital time when button is pressed or screen touched + g.clearRect(0, big ? 215 : 160, big ? 240 : 176, big ? 240 : 176); if (showDigitalTime){ g.setColor(activeColor); - g.drawString(time, 120, 215); + g.drawString(time, big ? 120 : 90, big ? 215 : 160); } } - Bangle.on('lcdPower', function(on) { if (on) drawWordClock(); }); @@ -157,17 +160,14 @@ Bangle.drawWidgets(); setInterval(drawWordClock, 1E4); drawWordClock(); -// Show digital time while top button is pressed (if we have physical buttons) -if (global.BTN3) setWatch(function() { - showDigitalTime = BTN1.read(); - drawWordClock(); -}, BTN1, {repeat:true,edge:"both"}); -// If LCD pressed (on Bangle.js 2) draw digital time -Bangle.on('drag',e=>{ - var pressed = e.b!=0; - if (pressed!=showDigitalTime) { - showDigitalTime = pressed; +// If LCD pressed, toggle drawing digital time +Bangle.on('touch',e=>{ + if (showDigitalTime){ + showDigitalTime = false; + drawWordClock(); + } else { + showDigitalTime = true; drawWordClock(); } }); diff --git a/apps/locale/locales.js b/apps/locale/locales.js index f4ee1fb43..2e1429ef8 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -40,7 +40,16 @@ const charFallbacks = { "č":"c", "ř":"r", "ő":"o", - "ě":"e" + "ě":"e", + "ę":"e", + "ą":"a", + "ó":"o", + "ż":"z", + "ź":"z", + "ń":"n", + "ł":"l", + "ś":"s", + "ć":"c", }; /* @@ -603,6 +612,24 @@ var locales = { day: "Domingo,Segunda-feira,Terça-feira,Quarta-feira,Quinta-feira,Sexta-feira,Sábado", trans: { yes: "sim", Yes: "Sim", no: "não", No: "Não", ok: "ok", on: "on", off: "off" } }, + "pl_PL": { + lang: "pl_PL", + decimal_point: ",", + thousands_sep: " ", + currency_symbol: "zł", + int_curr_symbol: "PLN", + speed: "kmh", + distance: { 0: "m", 1: "km" }, + temperature: "°C", + ampm: { 0: "", 1: "" }, + timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" }, + datePattern: { 0: "%d. %b %Y", "1": "%d.%m.%Y" }, // 1. Mar 2021 // 01.03.2021 + abmonth: "Sty,Lut,Mar,Kwi,Maj,Cze,Lip,Sie,Wrz,Paź,Lis,Gru", + month: "Styczeń,Luty,Marzec,Kwiecień,Maj,Czerwiec,Lipiec,Sierpień,Wrzesień,Październik,Listopad,Grudzień", + abday: "Ndz,Pon,Wt,Śr,Czw,Pt,Sob", + day: "Niedziela,Poniedziałek,Wtorek,Środa,Czwartek,Piątek,Sobota", + trans: { yes: "tak", Yes: "Tak", no: "nie", No: "Nie", ok: "ok", on: "on", off: "off", "< Back": "< Wstecz" } + }, /*, "he_IL": { // This won't work until we get a font - see https://github.com/espruino/BangleApps/issues/399 codePage : "ISO8859-8", diff --git a/apps/pooqroman/ChangeLog b/apps/pooqroman/ChangeLog new file mode 100644 index 000000000..9debf0efe --- /dev/null +++ b/apps/pooqroman/ChangeLog @@ -0,0 +1,2 @@ +0.01: New App! +0.02: Make internal menu time out + small fixes diff --git a/apps/pooqroman/app.js b/apps/pooqroman/app.js index d25fcf1a8..d59d4ef6c 100644 --- a/apps/pooqroman/app.js +++ b/apps/pooqroman/app.js @@ -1,3 +1,4 @@ +/* -*- mode: Javascript; c-basic-offset: 2; indent-tabs-mode: nil; coding: latin-1 -*- */ // pooqRoman // // Copyright (c) 2021 Stephen P Spackman @@ -54,8 +55,9 @@ class Options { this.id = this.constructor.id; this.file = `${this.id}.json`; this.backing = storage.readJSON(this.file, true) || {}; - this.defaults = this.constructor.defaults; - Object.keys(this.defaults).forEach(k => this.bless(k)); + Object.setPrototypeOf(this.backing, this.constructor.defaults); + this.reactivator = _ => this.active(); + Object.keys(this.constructor.defaults).forEach(k => this.bless(k)); } writeBack(delay) { @@ -71,29 +73,41 @@ class Options { bless(k) { Object.defineProperty(this, k, { - get: () => this.backing[k] == null ? this.defaults[k] : this.backing[k], + get: () => this.backing[k], set: v => { this.backing[k] = v; // Ten second writeback delay, since the user will roll values up and down. this.writeBack(10000); } }); - } + } showMenu(m) { + if (m instanceof Function) m = m(); if (m) { for (const k in m) if ('init' in m[k]) m[k].value = m[k].init(); m[''].selected = -1; // Workaround for self-selection bug. + Bangle.on('drag', this.reactivator); + this.active(); + } else { + if (this.bored) clearTimeout(this.bored); + this.bored = null; + Bangle.removeListener('drag', this.reactivator); + this.emit('done'); } + g.clear(true); E.showMenu(m); } - reset() { - this.backing = {}; - this.writeBack(0); + active() { + if (this.bored) clearTimeout(this.bored); + this.bored = setTimeout(_ => this.showMenu(), 15000); } - interact() {this.showMenu(this.menu);} + reset() { + this.backing = {__proto__: this.constructor.defaults}; + this.writeBack(0); + } } class RomanOptions extends Options { @@ -101,7 +115,7 @@ class RomanOptions extends Options { super(); this.menu = { '': {title: '* face options *'}, - '< Back': _ => {this.showMenu(); this.emit('done');}, + '< Back': _ => this.showMenu(), Ticks: { init: _ => this.resolution, min: 0, max: 3, @@ -124,9 +138,11 @@ class RomanOptions extends Options { onchange: x => this.calendric = x, format: x => ['none', 'day', 'date'][x] }, - Defaults: _ => {this.reset();} + Defaults: _ => {this.reset(); this.interact();} }; } + + interact() {this.showMenu(this.menu);} } RomanOptions.id = 'pooqroman'; @@ -147,7 +163,7 @@ RomanOptions.defaults = { hubFg: g.theme.fg, alarmFg: '#f00', timerFg: '#0f0', - active: g.theme.fg2, + activeFg: g.theme.fg2, }; ////////////////////////////////////////////////////////////////////////////// @@ -434,7 +450,7 @@ class Sidebar { } static gpsColour(o) { const fix = Bangle.getGPSFix(); - return fix && fix.fix ? o.active : o.barFg; + return fix && fix.fix ? o.activeFg : o.barFg; } doPower() { const c = Bangle.isCharging(); @@ -455,7 +471,7 @@ class Sidebar { if (Bangle.isCompassOn()) { const c = Bangle.getCompass(); const a = c && this.rate <= 1000; - this.g.setColor(a ? this.options.active : this.options.barFg).drawImage( + this.g.setColor(a ? this.options.activeFg : this.options.barFg).drawImage( compassI, this.x + 4 + imageWidth(compassI) / 2, this.y + 4 + imageHeight(compassI) / 2, @@ -470,7 +486,7 @@ class Sidebar { class Roman { constructor(g, events) { this.g = g; - this.state = {}; + this.state = null; const options = this.options = new RomanOptions(); this.events = events.loadFromSystem(this.options); this.timescales = [1000, [1000, 60000], 60000, 3600000]; @@ -480,7 +496,7 @@ class Roman { this.seconds = Roman.hand(g, 1, 0.9, 60, _ => options.secondFg); } - reset() {this.state = {}; this.g.clear(true);} + reset() {this.state = null;} doIcons(which) {this.state.iconsOk = null;} @@ -544,7 +560,7 @@ class Roman { render(d, rate) { const g = this.g; - const state = this.state; + const state = this.state || (g.clear(true), this.state = {}); const options = this.options; const events = this.events; events.clean(d, -39600000); // 11h @@ -654,8 +670,8 @@ class Clock { drag: e => { if (this.t0) { if (e.b) { - e.x > this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); - e.y > this.yN && (this.yN = e.y) || e.y > this.yX && (this.xY = e.y); + e.x < this.xN && (this.xN = e.x) || e.x > this.xX && (this.xX = e.x); + e.y < this.yN && (this.yN = e.y) || e.y > this.yX && (this.yX = e.y); } else if (this.xX - this.xN < 20) { if (e.y - this.e0.y < -50) { this.options.resolution > 0 && this.options.resolution--; @@ -697,6 +713,7 @@ class Clock { this.exception && clearTimeout(this.exception); this.interval && clearInterval(this.interval); this.timeout = this.exception = this.interval = this.rate = null; + this.face.reset(); // Cancel any ongoing background rendering return this; } diff --git a/apps/ptlaunch/ChangeLog b/apps/ptlaunch/ChangeLog index f50936885..de38d715a 100644 --- a/apps/ptlaunch/ChangeLog +++ b/apps/ptlaunch/ChangeLog @@ -1,2 +1,4 @@ 0.01: Initial creation of the pattern launch app 0.02: Turn on lcd when launching an app if the lock screen was disabled in the settings +0.03: Make tap to confirm new pattern more reliable. Also allow for easier creation of single circle patterns. +0.10: Improve the management of existing patterns: Draw the linked pattern on the left hand side of the app name within a scroller, similar to the default launcher. Slighlty clean up the code to make it less horrible. \ No newline at end of file diff --git a/apps/ptlaunch/README.md b/apps/ptlaunch/README.md index a69492782..8d61afece 100644 --- a/apps/ptlaunch/README.md +++ b/apps/ptlaunch/README.md @@ -8,25 +8,32 @@ Create patterns and link them to apps in the Pattern Launcher app. Then launch the linked apps directly from the clock screen by simply drawing the desired pattern. -## Screenshots and detailed steps +## Add Pattern Screenshots -![](main_menu.png) +![](main_menu_add.png) ![](add_pattern.png) ![](select_app.png) +## Manage Pattern Screenshots + +![](main_menu_manage.png) +![](manage_patterns.png) + +## Detailed Steps + From the main menu you can: - Add a new pattern and link it to an app (first entry) - To create a new pattern first select "Add Pattern" - Now draw any pattern you like, this will later launch the linked app from the clock screen + - You can also draw a single-circle pattern (meaning a single tap on one circle) instead of drawing a 'complex' pattern - If you don't like the pattern, simply re-draw it. The previous pattern will be discarded. - If you are happy with the pattern tap on screen or press the button to continue - Now select the app you want to launch with the pattern. - Note, you can bind multiple patterns to the same app. -- Remove linked patterns (second entry) - - To remove a pattern first select "Remove Pattern" - - You will now see a list of apps that have patterns linked to them - - Simply select the app that you want to unlink. This will remove the saved pattern, but not the app itself! - - Note, that you can not actually preview the patterns. This makes removing patterns that are linked to the same app annoying. sorry! +- Manage created patterns (second entry) + - To manage your patterns first select "Manage Patterns" + - You will now see a scrollabe list of patterns + linked apps + - If you want to deletion a pattern (and unlink the app) simply tap on it, and confirm the deletion - Disable the lock screen on the clock screen from the settings (third entry) - To launch the app from the pattern on the clock screen the watch must be unlocked. - If this annoys you, you can disable the lock on the clock screen from the setting here diff --git a/apps/ptlaunch/app.js b/apps/ptlaunch/app.js index 8ba1adf81..b5a3bf610 100644 --- a/apps/ptlaunch/app.js +++ b/apps/ptlaunch/app.js @@ -1,26 +1,6 @@ -var storage = require("Storage"); - var DEBUG = false; -var log = (message) => { - if (DEBUG) { - console.log(JSON.stringify(message)); - } -}; -var CIRCLE_RADIUS = 25; -var CIRCLE_RADIUS_2 = CIRCLE_RADIUS * CIRCLE_RADIUS; - -var CIRCLES = [ - { x: 25, y: 25, i: 0 }, - { x: 87, y: 25, i: 1 }, - { x: 150, y: 25, i: 2 }, - { x: 25, y: 87, i: 3 }, - { x: 87, y: 87, i: 4 }, - { x: 150, y: 87, i: 5 }, - { x: 25, y: 150, i: 6 }, - { x: 87, y: 150, i: 7 }, - { x: 150, y: 150, i: 8 }, -]; +var storage = require("Storage"); var showMainMenu = () => { log("loading patterns"); @@ -36,7 +16,7 @@ var showMainMenu = () => { }, "Add Pattern": () => { log("creating pattern"); - createPattern().then((pattern) => { + recognizeAndDrawPattern().then((pattern) => { log("got pattern"); log(pattern); log(pattern.length); @@ -73,17 +53,32 @@ var showMainMenu = () => { }); }); }, - "Remove Pattern": () => { + "Manage Patterns": () => { log("selecting pattern through app"); - getStoredPatternViaApp(storedPatterns).then((pattern) => { - E.showMessage("Deleting..."); - delete storedPatterns[pattern]; - storage.writeJSON("ptlaunch.patterns.json", storedPatterns); - showMainMenu(); + showScrollerContainingAppsWithPatterns().then((selected) => { + var pattern = selected.pattern; + var appName = selected.appName; + if (pattern === "back") { + showMainMenu(); + } else { + E.showPrompt(appName + "\n\npattern:\n" + pattern, { + title: "Delete?", + buttons: { Yes: true, No: false }, + }).then((confirm) => { + if (confirm) { + E.showMessage("Deleting..."); + delete storedPatterns[pattern]; + storage.writeJSON("ptlaunch.patterns.json", storedPatterns); + showMainMenu(); + } else { + showMainMenu(); + } + }); + } }); }, Settings: () => { - var settings = storedPatterns["settings"] || {}; + var settings = storedPatterns.settings || {}; var settingsmenu = { "": { @@ -98,7 +93,7 @@ var showMainMenu = () => { if (settings.lockDisabled) { settingsmenu["Enable lock"] = () => { settings.lockDisabled = false; - storedPatterns["settings"] = settings; + storedPatterns.settings = settings; Bangle.setOptions({ lockTimeout: 1000 * 30 }); storage.writeJSON("ptlaunch.patterns.json", storedPatterns); showMainMenu(); @@ -106,7 +101,7 @@ var showMainMenu = () => { } else { settingsmenu["Disable lock"] = () => { settings.lockDisabled = true; - storedPatterns["settings"] = settings; + storedPatterns.settings = settings; storage.writeJSON("ptlaunch.patterns.json", storedPatterns); Bangle.setOptions({ lockTimeout: 1000 * 60 * 60 * 24 * 365 }); showMainMenu(); @@ -119,12 +114,8 @@ var showMainMenu = () => { E.showMenu(mainmenu); }; -var drawCircle = (circle) => { - g.fillCircle(circle.x, circle.y, CIRCLE_RADIUS); -}; - var positions = []; -var createPattern = () => { +var recognizeAndDrawPattern = () => { return new Promise((resolve) => { E.showMenu(); g.clear(); @@ -147,13 +138,29 @@ var createPattern = () => { setWatch(() => finishHandler(), BTN); setTimeout(() => Bangle.on("tap", finishHandler), 250); + positions = []; var dragHandler = (position) => { + log(position); positions.push(position); debounce().then(() => { if (isFinished) { return; } + + // This might actually be a 'tap' event. + // Use this check in addition to the actual tap handler to make it more reliable + if (pattern.length > 0 && positions.length === 2) { + if ( + positions[0].x === positions[1].x && + positions[0].y === positions[1].y + ) { + finishHandler(); + positions = []; + return; + } + } + E.showMessage("Calculating..."); var t0 = Date.now(); @@ -269,18 +276,7 @@ var createPattern = () => { log("redrawing"); g.clear(); - g.setColor(0, 0, 0); - CIRCLES.forEach((circle) => drawCircle(circle)); - - g.setColor(1, 1, 1); - g.setFontAlign(0, 0); - g.setFont("6x8", 4); - pattern.forEach((circleIndex, patternIndex) => { - var circle = CIRCLES[circleIndex]; - g.drawString(patternIndex + 1, circle.x, circle.y); - }); - var t2 = Date.now(); - log(t2 - t0); + drawCirclesWithPattern(pattern); }); }; @@ -341,56 +337,256 @@ var getSelectedApp = () => { }); }; -var getStoredPatternViaApp = (storedPatterns) => { - E.showMessage("Loading patterns..."); - log("getStoredPatternViaApp"); +////// +// manage pattern related variables and functions +// - draws all saved patterns and their linked app names +// - uses the scroller to allow the user to browse through them +////// + +var scrollerFont = g.getFonts().includes("12x20") ? "12x20" : "6x8:2"; + +var drawBackButton = (r) => { + g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); + g.setFont(scrollerFont) + .setFontAlign(-1, 0) + .drawString("< Back", 64, r.y + 32); +}; + +var drawAppWithPattern = (i, r, storedPatterns) => { + log("draw app with pattern"); + log({ i: i, r: r, storedPatterns: storedPatterns }); + var storedPattern = storedPatterns[i]; + var pattern = storedPattern.pattern; + var app = storedPattern.app; + + g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); + + g.drawLine(r.x, r.y, 176, r.y); + + drawCirclesWithPattern(pattern, { + enableCaching: true, + scale: 0.33, + offset: { x: 1, y: 3 + r.y }, + }); + + g.setColor(0, 0, 0); + if (!storedPattern.wrappedAppName) { + storedPattern.wrappedAppName = g + .wrapString(app.name, g.getWidth() - 64) + .join("\n"); + } + log(g.getWidth()); + log(storedPattern.wrappedAppName); + g.setFont(scrollerFont) + .setFontAlign(-1, 0) + .drawString(storedPattern.wrappedAppName, 64, r.y + 32); +}; + +var showScrollerContainingAppsWithPatterns = () => { + var storedPatternsArray = getStoredPatternsArray(); + log("drawing scroller for stored patterns"); + log(storedPatternsArray); + log(storedPatternsArray.length); + + g.clear(); + + var c = Math.max(storedPatternsArray.length + 1, 3); + return new Promise((resolve) => { - var selectPatternMenu = { - "": { - title: "Select App", - }, - "< Cancel": () => { - log("cancel"); - showMainMenu(); - }, - }; - - log(storedPatterns); - var patterns = Object.keys(storedPatterns); - log(patterns); - - patterns.forEach((pattern) => { - if (pattern) { - if (storedPatterns[pattern]) { - var app = storedPatterns[pattern].app; - if (!!app && !!app.name) { - var appName = app.name; - var i = 0; - while (appName in selectPatternMenu[app.name]) { - appName = app.name + i; - i++; - } - selectPatternMenu[appName] = () => { - log("pattern via app selected"); - log(pattern); - log(app); - resolve(pattern); - }; - } + E.showScroller({ + h: 64, + c: c, + draw: (i, r) => { + log("draw"); + log({ i: i, r: r }); + if (i <= 0) { + drawBackButton(r); + } else if (i <= storedPatternsArray.length) { + drawAppWithPattern(i - 1, r, storedPatternsArray); } - } + }, + select: (i) => { + log("selected: " + i); + var pattern = "back"; + var appName = ""; + if (i > 0) { + var storedPattern = storedPatternsArray[i - 1]; + pattern = storedPattern.pattern.join(""); + appName = storedPattern.app.name; + } + clearCircleDrawingCache(); + resolve({ pattern: pattern, appName: appName }); + }, }); - - E.showMenu(selectPatternMenu); }); }; -showMainMenu(); +////// +// storage related functions: +// - stored patterns +// - stored settings +////// + +var getStoredPatternsMap = () => { + log("loading stored patterns map"); + var storedPatternsMap = storage.readJSON("ptlaunch.patterns.json", 1) || {}; + delete storedPatternsMap.settings; + log(storedPatternsMap); + return storedPatternsMap; +}; + +var getStoredPatternsArray = () => { + var storedPatternsMap = getStoredPatternsMap(); + log("converting stored patterns map to array"); + var patterns = Object.keys(storedPatternsMap); + var storedPatternsArray = []; + for (var i = 0; i < patterns.length; i++) { + var pattern = "" + patterns[i]; + storedPatternsArray.push({ + pattern: pattern + .split("") + .map((circleIndex) => parseInt(circleIndex, 10)), + app: storedPatternsMap[pattern].app, + }); + } + log(storedPatternsArray); + return storedPatternsArray; +}; ////// -// lib functions +// circle related variables and functions: +// - the circle array itself +// - the radius and the squared radius of the circles +// - circle draw function ////// +var CIRCLE_RADIUS = 25; +var CIRCLE_RADIUS_2 = CIRCLE_RADIUS * CIRCLE_RADIUS; + +var CIRCLES = [ + { x: 25, y: 25, i: 0 }, + { x: 87, y: 25, i: 1 }, + { x: 150, y: 25, i: 2 }, + { x: 25, y: 87, i: 3 }, + { x: 87, y: 87, i: 4 }, + { x: 150, y: 87, i: 5 }, + { x: 25, y: 150, i: 6 }, + { x: 87, y: 150, i: 7 }, + { x: 150, y: 150, i: 8 }, +]; + +var drawCircle = (circle, drawBuffer, scale) => { + if (!drawBuffer) { + drawBuffer = g; + } + if (!scale) { + scale = 1; + } + + var x = circle.x * scale; + var y = circle.y * scale; + var r = CIRCLE_RADIUS * scale; + + log("drawing circle"); + log({ x: x, y: y, r: r }); + + drawBuffer.fillCircle(x, y, r); +}; + +var cachedCirclesDrawings = {}; + +var clearCircleDrawingCache = () => { + cachedCirclesDrawings = {}; +}; + +var drawCirclesWithPattern = (pattern, options) => { + if (!pattern || pattern.length === 0) { + pattern = []; + } + if (!options) { + options = {}; + } + var enableCaching = options.enableCaching; + var scale = options.scale; + var offset = options.offset; + if (!enableCaching) { + enableCaching = false; + } + if (!scale) { + scale = 1; + } + if (!offset) { + offset = { x: 0, y: 0 }; + } + + log("drawing circles with pattern, scale and offset"); + log(pattern); + log(scale); + log(offset); + + // cache drawn patterns. especially useful for the manage pattern menu + var image = cachedCirclesDrawings[pattern.join("")]; + if (!image) { + log("circle image not cached"); + var drawBuffer = Graphics.createArrayBuffer( + g.getWidth() * scale, + g.getHeight() * scale, + 1, + { msb: true } + ); + + drawBuffer.setColor(1); + CIRCLES.forEach((circle) => drawCircle(circle, drawBuffer, scale)); + + drawBuffer.setColor(0); + drawBuffer.setFontAlign(0, 0); + drawBuffer.setFont("6x8", 4 * scale); + pattern.forEach((circleIndex, patternIndex) => { + var circle = CIRCLES[circleIndex]; + drawBuffer.drawString( + patternIndex + 1, + circle.x * scale, + circle.y * scale + ); + }); + + image = { + width: drawBuffer.getWidth(), + height: drawBuffer.getHeight(), + bpp: 1, + buffer: drawBuffer.buffer, + }; + + if (enableCaching) { + cachedCirclesDrawings[pattern.join("")] = image; + } + } else { + log("using cached circle image"); + } + + g.drawImage(image, offset.x, offset.y); +}; + +var cloneCirclesArray = () => { + var circlesClone = Array(CIRCLES.length); + + for (var i = 0; i < CIRCLES.length; i++) { + circlesClone[i] = CIRCLES[i]; + } + + return circlesClone; +}; + +////// +// misc lib functions +////// + +var log = (message) => { + if (DEBUG) { + console.log(JSON.stringify(message)); + } +}; + var debounceTimeoutId; var debounce = (delay) => { if (debounceTimeoutId) { @@ -405,12 +601,8 @@ var debounce = (delay) => { }); }; -var cloneCirclesArray = () => { - var circlesClone = Array(CIRCLES.length); +////// +// run main function +////// - for (var i = 0; i < CIRCLES.length; i++) { - circlesClone[i] = CIRCLES[i]; - } - - return circlesClone; -}; +showMainMenu(); diff --git a/apps/ptlaunch/boot.js b/apps/ptlaunch/boot.js index 14d390b13..a23607768 100644 --- a/apps/ptlaunch/boot.js +++ b/apps/ptlaunch/boot.js @@ -5,21 +5,6 @@ var log = (message) => { } }; -var CIRCLE_RADIUS = 25; -var CIRCLE_RADIUS_2 = CIRCLE_RADIUS * CIRCLE_RADIUS; - -var CIRCLES = [ - { x: 25, y: 25, i: 0 }, - { x: 87, y: 25, i: 1 }, - { x: 150, y: 25, i: 2 }, - { x: 25, y: 87, i: 3 }, - { x: 87, y: 87, i: 4 }, - { x: 150, y: 87, i: 5 }, - { x: 25, y: 150, i: 6 }, - { x: 87, y: 150, i: 7 }, - { x: 150, y: 150, i: 8 }, -]; - var storedPatterns; var positions = []; var dragHandler = (position) => { @@ -28,7 +13,20 @@ var dragHandler = (position) => { debounce().then(() => { log(positions.length); - var circlesClone = cloneCirclesArray(); + var CIRCLE_RADIUS = 25; + var CIRCLE_RADIUS_2 = CIRCLE_RADIUS * CIRCLE_RADIUS; + + var circles = [ + { x: 25, y: 25, i: 0 }, + { x: 87, y: 25, i: 1 }, + { x: 150, y: 25, i: 2 }, + { x: 25, y: 87, i: 3 }, + { x: 87, y: 87, i: 4 }, + { x: 150, y: 87, i: 5 }, + { x: 25, y: 150, i: 6 }, + { x: 87, y: 150, i: 7 }, + { x: 150, y: 150, i: 8 }, + ]; var pattern = []; var step = Math.floor(positions.length / 100) + 1; @@ -38,92 +36,92 @@ var dragHandler = (position) => { for (var i = 0; i < positions.length; i += step) { p = positions[i]; - circle = circlesClone[0]; + circle = circles[0]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(0, 1); + circles.splice(0, 1); } } - circle = circlesClone[1]; + circle = circles[1]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(1, 1); + circles.splice(1, 1); } } - circle = circlesClone[2]; + circle = circles[2]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(2, 1); + circles.splice(2, 1); } } - circle = circlesClone[3]; + circle = circles[3]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(3, 1); + circles.splice(3, 1); } } - circle = circlesClone[4]; + circle = circles[4]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(4, 1); + circles.splice(4, 1); } } - circle = circlesClone[5]; + circle = circles[5]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(5, 1); + circles.splice(5, 1); } } - circle = circlesClone[6]; + circle = circles[6]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(6, 1); + circles.splice(6, 1); } } - circle = circlesClone[7]; + circle = circles[7]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(7, 1); + circles.splice(7, 1); } } - circle = circlesClone[8]; + circle = circles[8]; if (circle) { a = p.x - circle.x; b = p.y - circle.y; if (CIRCLE_RADIUS_2 - (a * a + b * b) >= 0) { pattern.push(circle.i); - circlesClone.splice(8, 1); + circles.splice(8, 1); } } } @@ -163,16 +161,6 @@ var debounce = (delay) => { }); }; -var cloneCirclesArray = () => { - var circlesClone = Array(CIRCLES.length); - - for (var i = 0; i < CIRCLES.length; i++) { - circlesClone[i] = CIRCLES[i]; - } - - return circlesClone; -}; - (function () { var sui = Bangle.setUI; Bangle.setUI = function (mode, cb) { diff --git a/apps/ptlaunch/main_menu.png b/apps/ptlaunch/main_menu.png deleted file mode 100644 index a4ecebb0f..000000000 Binary files a/apps/ptlaunch/main_menu.png and /dev/null differ diff --git a/apps/ptlaunch/main_menu_add.png b/apps/ptlaunch/main_menu_add.png new file mode 100644 index 000000000..e9a5c52a9 Binary files /dev/null and b/apps/ptlaunch/main_menu_add.png differ diff --git a/apps/ptlaunch/main_menu_manage.png b/apps/ptlaunch/main_menu_manage.png new file mode 100644 index 000000000..a6aee1427 Binary files /dev/null and b/apps/ptlaunch/main_menu_manage.png differ diff --git a/apps/ptlaunch/manage_patterns.png b/apps/ptlaunch/manage_patterns.png new file mode 100644 index 000000000..82b10ad43 Binary files /dev/null and b/apps/ptlaunch/manage_patterns.png differ diff --git a/apps/qmsched/ChangeLog b/apps/qmsched/ChangeLog index 0b8d67e76..f41fe3416 100644 --- a/apps/qmsched/ChangeLog +++ b/apps/qmsched/ChangeLog @@ -2,3 +2,4 @@ 0.02: Add widget 0.03: Bangle.js 2 support 0.04: Move Quiet Mode LCD options from global settings to this app +0.05: Avoid immediately redrawing widgets on load \ No newline at end of file diff --git a/apps/qmsched/widget.js b/apps/qmsched/widget.js index 8a8333ba5..b25192b06 100644 --- a/apps/qmsched/widget.js +++ b/apps/qmsched/widget.js @@ -1,32 +1,36 @@ -WIDGETS["qmsched"] = { - area: "tl", width: 24, draw: function() { - const mode = (require("Storage").readJSON("setting.json", 1) || {}).quiet|0; - if (mode===0) { // Off - if (this.width!==0) { - this.width = 0; - Bangle.drawWidgets(); +(function() { + WIDGETS["qmsched"] = { + area: "tl", + width: ((require("Storage").readJSON("setting.json", 1) || {}).quiet|0) ? 24 : 0, + draw: function() { + const mode = (require("Storage").readJSON("setting.json", 1) || {}).quiet|0; + if (mode===0) { // Off + if (this.width!==0) { + this.width = 0; + Bangle.drawWidgets(); + } + return; } - return; - } - // not Off: make sure width is correct - if (this.width!==24) { - this.width = 24; - Bangle.drawWidgets(); - return; // drawWidgets will call draw again - } - let x = this.x, y = this.y; - g.clearRect(x, y, x+23, y+23); - // quiet mode: draw red one-way-street sign (dim red on Bangle.js 1) - x = this.x+11;y = this.y+11; // center of widget - g.setColor(process.env.HWVERSION===2 ? 1 : 0.8, 0, 0).fillCircle(x, y, 8); - g.setColor(g.theme.bg).fillRect(x-6, y-2, x+6, y+2); - if (mode>1) {return;} // no alarms - // alarms still on: draw alarm icon in bottom-right corner - x = this.x+18;y = this.y+17; // center of alarm - g.setColor(1, 1, 0) - .fillCircle(x, y, 3) // alarm body - .fillRect(x-5, y+2, x+5, y+3) // bottom ridge - .fillRect(x-1, y-5, x+1, y+5).drawLine(x, y-6, x, y+6) // top+bottom - .drawLine(x+5, y-3, x+3, y-5).drawLine(x-5, y-3, x-3, y-5); // wriggles - }, -}; \ No newline at end of file + // not Off: make sure width is correct + if (this.width!==24) { + this.width = 24; + Bangle.drawWidgets(); + return; // drawWidgets will call draw again + } + let x = this.x, y = this.y; + g.clearRect(x, y, x+23, y+23); + // quiet mode: draw red one-way-street sign (dim red on Bangle.js 1) + x = this.x+11;y = this.y+11; // center of widget + g.setColor(process.env.HWVERSION===2 ? 1 : 0.8, 0, 0).fillCircle(x, y, 8); + g.setColor(g.theme.bg).fillRect(x-6, y-2, x+6, y+2); + if (mode>1) {return;} // no alarms + // alarms still on: draw alarm icon in bottom-right corner + x = this.x+18;y = this.y+17; // center of alarm + g.setColor(1, 1, 0) + .fillCircle(x, y, 3) // alarm body + .fillRect(x-5, y+2, x+5, y+3) // bottom ridge + .fillRect(x-1, y-5, x+1, y+5).drawLine(x, y-6, x, y+6) // top+bottom + .drawLine(x+5, y-3, x+3, y-5).drawLine(x-5, y-3, x-3, y-5); // wriggles + }, + }; +})(); \ No newline at end of file diff --git a/apps/qrcode/ChangeLog b/apps/qrcode/ChangeLog index 91121ac6e..edcc41cfd 100644 --- a/apps/qrcode/ChangeLog +++ b/apps/qrcode/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Add posibillity to generate Wifi code. 0.03: Forces integer scaling and adds more configuration (error correction, description, display) +0.04: Allow scanning of QR codes from camera or file diff --git a/apps/qrcode/custom.html b/apps/qrcode/custom.html index eb9906f57..4920be655 100644 --- a/apps/qrcode/custom.html +++ b/apps/qrcode/custom.html @@ -3,34 +3,71 @@ + Datasource:
- - -


- +
- - -

Wifi password:

-
- -
- -
+
+ +
+ +
+
+ +
+

Text/URL:

-
- - + +
+
+ +
+
+ +
+
+ +
+
+ Detected QR code: + None +
+ +
- + +
+ +
+ Detected QR code: + None +
+ +
+

Wifi name:

+

Wifi password:

+
+ +
+ +
+ +
+
+ + +
+
+

Try your QR Code:

- +

Additional options:

@@ -51,7 +88,7 @@ -
+

Click

@@ -59,25 +96,75 @@ - + + diff --git a/apps/qrcode/qr-scanner-worker.min.js b/apps/qrcode/qr-scanner-worker.min.js new file mode 100644 index 000000000..0d026ac07 --- /dev/null +++ b/apps/qrcode/qr-scanner-worker.min.js @@ -0,0 +1,87 @@ +'use strict';(function(){function T(a,b){let c=[],d="";b=a.readBits([8,16,16][b]);for(let d=0;d`%${("0"+a.toString(16)).substr(-2)}`).join(""))}catch(e){}return{bytes:c,text:d}}function U(a,b){a=new V(a);let c=9>=b?0:26>=b?1:2;for(b={text:"",bytes:[],chunks:[],version:b};4<=a.available();){var d=a.readBits(4);if(d===t.Terminator)return b;if(d===t.ECI)0===a.readBits(1)?b.chunks.push({type:r.ECI,assignmentNumber:a.readBits(7)}): +0===a.readBits(1)?b.chunks.push({type:r.ECI,assignmentNumber:a.readBits(14)}):0===a.readBits(1)?b.chunks.push({type:r.ECI,assignmentNumber:a.readBits(21)}):b.chunks.push({type:r.ECI,assignmentNumber:-1});else if(d===t.Numeric){var e=a;d=[];for(var f="",g=e.readBits([10,12,14][c]);3<=g;){var h=e.readBits(10);if(1E3<=h)throw Error("Invalid numeric value above 999");var k=Math.floor(h/100),n=Math.floor(h/10)%10;h%=10;d.push(48+k,48+n,48+h);f+=k.toString()+n.toString()+h.toString();g-=3}if(2===g){g=e.readBits(7); +if(100<=g)throw Error("Invalid numeric value above 99");e=Math.floor(g/10);g%=10;d.push(48+e,48+g);f+=e.toString()+g.toString()}else if(1===g){e=e.readBits(4);if(10<=e)throw Error("Invalid numeric value above 9");d.push(48+e);f+=e.toString()}d={bytes:d,text:f};b.text+=d.text;b.bytes.push(...d.bytes);b.chunks.push({type:r.Numeric,text:d.text})}else if(d===t.Alphanumeric){e=a;d=[];f="";for(g=e.readBits([9,11,13][c]);2<=g;)n=e.readBits(11),k=Math.floor(n/45),n%=45,d.push(B[k].charCodeAt(0),B[n].charCodeAt(0)), +f+=B[k]+B[n],g-=2;1===g&&(e=e.readBits(6),d.push(B[e].charCodeAt(0)),f+=B[e]);d={bytes:d,text:f};b.text+=d.text;b.bytes.push(...d.bytes);b.chunks.push({type:r.Alphanumeric,text:d.text})}else if(d===t.Byte)d=T(a,c),b.text+=d.text,b.bytes.push(...d.bytes),b.chunks.push({type:r.Byte,bytes:d.bytes,text:d.text});else if(d===t.Kanji){f=a;d=[];e=f.readBits([8,10,12][c]);for(g=0;gk?k+33088:k+49472,d.push(k>>8,k&255);f=(new TextDecoder("shift-jis")).decode(Uint8Array.from(d)); +d={bytes:d,text:f};b.text+=d.text;b.bytes.push(...d.bytes);b.chunks.push({type:r.Kanji,bytes:d.bytes,text:d.text})}else d===t.StructuredAppend&&b.chunks.push({type:r.StructuredAppend,currentSequence:a.readBits(4),totalSequence:a.readBits(4),parity:a.readBits(8)})}if(0===a.available()||0===a.readBits(a.available()))return b}function J(a,b){return a^b}function W(a,b,c,d){b.degree()=d/2;){var g=b;let d=e;b=c;e=f;if(b.isZero())return null; +c=g;f=a.zero;g=b.getCoefficient(b.degree());for(g=a.inverse(g);c.degree()>=b.degree()&&!c.isZero();){let d=c.degree()-b.degree(),e=a.multiply(c.getCoefficient(c.degree()),g);f=f.addOrSubtract(a.buildMonomial(d,e));c=c.addOrSubtract(b.multiplyByMonomial(d,e))}f=f.multiplyPoly(e).addOrSubtract(d);if(c.degree()>=b.degree())return null}d=f.getCoefficient(0);if(0===d)return null;a=a.inverse(d);return[f.multiply(a),c.multiply(a)]}function X(a,b){let c=new Uint8ClampedArray(a.length);c.set(a);a=new Y(285, +256,0);var d=new w(a,c),e=new Uint8ClampedArray(b),f=!1;for(var g=0;gf)return null;c[f]^=d[e]}return c}function E(a,b){a^=b;for(b=0;a;)b++,a&=a-1;return b}function C(a,b){return b<<1|a}function Z(a,b,c){c=aa[c.dataMask];let d=a.height;var e=17+4*b.versionNumber,f=A.createEmpty(e,e);f.setRegion(0,0,9,9,!0);f.setRegion(e-8,0,8,9,!0);f.setRegion(0,e-8,9,8,!0);for(var g of b.alignmentPatternCenters)for(var h of b.alignmentPatternCenters)6=== +g&&6===h||6===g&&h===e-7||g===e-7&&6===h||f.setRegion(g-2,h-2,5,5,!0);f.setRegion(6,9,1,e-17,!0);f.setRegion(9,6,e-17,1,!0);6d;d++){let f=k-d;if(!b.get(f,m)){e++;let b=a.get(f,m);c({y:m,x:f})&&(b=!b);h=h<<1|b;8===e&&(g.push(h),h=e=0)}}}f=!f}return g}function ba(a){var b=a.height,c=Math.floor((b-17)/4);if(6>=c)return K[c- +1];c=0;for(var d=5;0<=d;d--)for(var e=b-9;e>=b-11;e--)c=C(a.get(e,d),c);d=0;for(e=5;0<=e;e--)for(let c=b-9;c>=b-11;c--)d=C(a.get(e,c),d);a=Infinity;let f;for(let e of K){if(e.infoBits===c||e.infoBits===d)return e;b=E(c,e.infoBits);b=a)return f}function ca(a){let b=0;for(var c=0;8>=c;c++)6!==c&&(b=C(a.get(c,8),b));for(c=7;0<=c;c--)6!==c&&(b=C(a.get(8,c),b));var d=a.height;c=0;for(var e=d-1;e>=d-7;e--)c=C(a.get(8,e),c);for(e=d-8;e=a?d:null}function ea(a,b,c){let d=b.errorCorrectionLevels[c],e=[],f=0;d.ecBlocks.forEach(a=>{for(let b=0;ba+b.numDataCodewords,0);c=new Uint8ClampedArray(c);a=0;for(let b of d){d=X(b.codewords,b.codewords.length-b.numDataCodewords);if(!d)return null;for(let e= +0;e{const c=g*a+n*b+p;return{x:(e*a+h*b+m)/c,y:(f*a+k*b+l)/c}};for(let e=0;ea+c)}function ia(a,b,c){let d=y(a,b),e=y(b,c),f=y(a,c),g,h,k;e>=d&&e>=f?[g,h,k]=[b,a,c]:f>=e&&f>=d?[g,h,k]=[a,b,c]:[g,h,k]=[a,c,b];0>(k.x-h.x)*(g.y-h.y)-(k.y-h.y)*(g.x-h.x)&&([g,k]=[k,g]);return{bottomLeft:g,topLeft:h,topRight:k}}function ja(a,b,c,d){d=(x(z(a,c,d,5))/7+x(z(a,b,d,5))/7+x(z(c,a,d,5))/7+x(z(b,a,d,5))/7)/4;if(1>d)throw Error("Invalid module size");b=Math.round(y(a,b)/d);a=Math.round(y(a,c)/d);a= +Math.floor((b+a)/2)+7;switch(a%4){case 0:a++;break;case 2:a--}return{dimension:a,moduleSize:d}}function N(a,b,c,d){let e=[{x:Math.floor(a.x),y:Math.floor(a.y)}];var f=Math.abs(b.y-a.y)>Math.abs(b.x-a.x);if(f){var g=Math.floor(a.y);var h=Math.floor(a.x);a=Math.floor(b.y);b=Math.floor(b.x)}else g=Math.floor(a.x),h=Math.floor(a.y),a=Math.floor(b.x),b=Math.floor(b.y);let k=Math.abs(a-g),n=Math.abs(b-h),m=Math.floor(-k/2),l=g{d+=Math.pow(a[f]-b*c,2)});return{averageSize:c,error:d}}function O(a,b,c){try{let d=z(a,{x:-1,y:a.y},c,b.length), +e=z(a,{x:a.x,y:-1},c,b.length),f=z(a,{x:Math.max(0,a.x-a.y)-1,y:Math.max(0,a.y-a.x)-1},c,b.length),g=z(a,{x:Math.min(c.width,a.x+a.y)+1,y:Math.min(c.height,a.y+a.x)+1},c,b.length),h=F(d,b),k=F(e,b),n=F(f,b),m=F(g,b),l=(h.averageSize+k.averageSize+n.averageSize+m.averageSize)/4;return Math.sqrt(h.error*h.error+k.error*k.error+n.error*n.error+m.error*m.error)+(Math.pow(h.averageSize-l,2)+Math.pow(k.averageSize-l,2)+Math.pow(n.averageSize-l,2)+Math.pow(m.averageSize-l,2))/l}catch(d){return Infinity}} +function H(a,b){for(var c=Math.round(b.x);a.get(c,Math.round(b.y));)c--;for(var d=Math.round(b.x);a.get(d,Math.round(b.y));)d++;c=(c+d)/2;for(d=Math.round(b.y);a.get(Math.round(c),d);)d--;for(b=Math.round(b.y);a.get(Math.round(c),b);)b++;return{x:c,y:(d+b)/2}}function ka(a){var b=[],c=[];let d=[];var e=[];for(let m=0;m<=a.height;m++){var f=0,g=!1;let l=[0,0,0,0,0];for(let b=-1;b<=a.width;b++){var h=a.get(b,m);if(h===g)f++;else{l=[l[1],l[2],l[3],l[4],f];f=1;g=h;var k=x(l)/7;k=Math.abs(l[0]-k)d>=b.bottom.startX&&d<=b.bottom.endX||a>=b.bottom.startX&&d<=b.bottom.endX||d<=b.bottom.startX&&a>=b.bottom.endX&&1.5>l[2]/(b.bottom.endX-b.bottom.startX)&&.5c>=b.bottom.startX&&c<=b.bottom.endX||a>=b.bottom.startX&&c<=b.bottom.endX||c<=b.bottom.startX&&a>=b.bottom.endX&&1.5>l[2]/(b.bottom.endX-b.bottom.startX)&&.5a.bottom.y!==m&&2<=a.bottom.y-a.top.y));c=c.filter(a=>a.bottom.y===m);d.push(...e.filter(a=>a.bottom.y!==m));e=e.filter(a=>a.bottom.y===m)}b.push(...c.filter(a=>2<=a.bottom.y-a.top.y));d.push(...e); +c=[];for(var m of b)2>m.bottom.y-m.top.y||(b=(m.top.startX+m.top.endX+m.bottom.startX+m.bottom.endX)/4,e=(m.top.y+m.bottom.y+1)/2,a.get(Math.round(b),Math.round(e))&&(f=[m.top.endX-m.top.startX,m.bottom.endX-m.bottom.startX,m.bottom.y-m.top.y+1],f=x(f)/f.length,g=O({x:Math.round(b),y:Math.round(e)},[1,1,3,1,1],a),c.push({score:g,x:b,y:e,size:f})));if(3>c.length)return null;c.sort((a,b)=>a.score-b.score);m=[];for(b=0;ba.score-b.score);m.push({points:[e,f[0],f[1]],score:e.score+f[0].score+f[1].score})}m.sort((a,b)=>a.score-b.score);let {topRight:p,topLeft:q,bottomLeft:v}=ia(...m[0].points);m=P(a,d,p,q,v);l=[];m&&l.push({alignmentPattern:{x:m.alignmentPattern.x,y:m.alignmentPattern.y},bottomLeft:{x:v.x,y:v.y},dimension:m.dimension,topLeft:{x:q.x,y:q.y},topRight:{x:p.x,y:p.y}});m=H(a,p);b=H(a,q);c=H(a,v);(a=P(a,d,m,b,c))&&l.push({alignmentPattern:{x:a.alignmentPattern.x, +y:a.alignmentPattern.y},bottomLeft:{x:c.x,y:c.y},topLeft:{x:b.x,y:b.y},topRight:{x:m.x,y:m.y},dimension:a.dimension});return 0===l.length?null:l}function P(a,b,c,d,e){let f,g;try{({dimension:f,moduleSize:g}=ja(d,c,e,a))}catch(m){return null}var h=c.x-d.x+e.x,k=c.y-d.y+e.y;c=(y(d,e)+y(d,c))/2/g;e=1-3/c;let n={x:d.x+e*(h-d.x),y:d.y+e*(k-d.y)};b=b.map(b=>{const c=(b.top.startX+b.top.endX+b.bottom.startX+b.bottom.endX)/4;b=(b.top.y+b.bottom.y+1)/2;if(a.get(Math.floor(c),Math.floor(b))){var d=O({x:Math.floor(c), +y:Math.floor(b)},[1,1,1],a)+y({x:c,y:b},n);return{x:c,y:b,score:d}}}).filter(a=>!!a).sort((a,b)=>a.score-b.score);return{alignmentPattern:15<=c&&b.length?b[0]:n,dimension:f}}function Q(a){var b=ka(a);if(!b)return null;for(let e of b){b=ha(a,e);var c=b.matrix;if(null==c)c=null;else{var d=L(c);if(d)c=d;else{for(d=0;d{a[c]=b[c]})}function I(a,b,c,d={}){let e=Object.create(null);R(e,la);R(e,d); +d="onlyInvert"===e.inversionAttempts||"invertFirst"===e.inversionAttempts;var f="attemptBoth"===e.inversionAttempts||d;var g=e.greyScaleWeights,h=e.canOverwriteImage,k=b*c;if(a.length!==4*k)throw Error("Malformed data passed to binarizer.");var n=0;if(h){var m=new Uint8ClampedArray(a.buffer,n,k);n+=k}m=new S(b,c,m);if(g.useIntegerApproximation)for(var l=0;l>8)}else for(l=0;lt;t++)for(let a=0;8>a;a++){let b=m.get(8*q+a,8*p+t);u=Math.min(u,b);r=Math.max(r,b)}t=(u+r)/2;t=Math.min(255,1.11*t);24>=r-u&&(t=u/2,0a?2:a>c?c:a;h=l-3;h=2>b?2:b>h?h:b;k=0;for(n=-2;2>=n;n++)for(u=-2;2>=u;u++)k+=v.get(c+n,h+u);c=k/25;for(h=0;8>h;h++)for(k=0;8>k;k++)n=8*a+h,u=8*b+k,r=m.get(n,u),p.set(n,u,r<=c),f&&q.set(n,u,!(r<=c))}f=f?{binarized:p,inverted:q}:{binarized:p};let {binarized:w,inverted:x}=f;(f=Q(d?x:w))||"attemptBoth"!==e.inversionAttempts&&"invertFirst"!==e.inversionAttempts|| +(f=Q(d?w:x));return f}class A{constructor(a,b){this.width=b;this.height=a.length/b;this.data=a}static createEmpty(a,b){return new A(new Uint8ClampedArray(a*b),a)}get(a,b){return 0>a||a>=this.width||0>b||b>=this.height?!1:!!this.data[b*this.width+a]}set(a,b,c){this.data[b*this.width+a]=c?1:0}setRegion(a,b,c,d,e){for(let f=b;fa||32this.available())throw Error("Cannot read "+a.toString()+" bits");var b=0;if(0>8-c<>b;a-=c;this.bitOffset+=c;8===this.bitOffset&&(this.bitOffset=0,this.byteOffset++)}if(0>c<>c,this.bitOffset+=a)}return b}available(){return 8*(this.bytes.length-this.byteOffset)-this.bitOffset}}var r;(function(a){a.Numeric="numeric";a.Alphanumeric="alphanumeric";a.Byte="byte";a.Kanji="kanji";a.ECI="eci";a.StructuredAppend="structuredappend"})(r||(r={}));var t;(function(a){a[a.Terminator=0]="Terminator";a[a.Numeric=1]="Numeric";a[a.Alphanumeric=2]="Alphanumeric";a[a.Byte=4]="Byte";a[a.Kanji=8]="Kanji";a[a.ECI=7]="ECI";a[a.StructuredAppend= +3]="StructuredAppend"})(t||(t={}));let B="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split("");class w{constructor(a,b){if(0===b.length)throw Error("No coefficients.");this.field=a;let c=b.length;if(1a.length&&([b,a]=[a,b]);let c=new Uint8ClampedArray(a.length),d=a.length-b.length;for(var e=0;ea)throw Error("Invalid degree less than 0");if(0===b)return this.field.zero; +let c=this.coefficients.length;a=new Uint8ClampedArray(c+a);for(let d=0;d{b^=a}),b;b=this.coefficients[0];for(let d=1;d=this.size&&(a=(a^this.primitive)&this.size-1);for(a=0;aa)throw Error("Invalid monomial degree less than 0");if(0===b)return this.zero;a=new Uint8ClampedArray(a+1);a[0]=b;return new w(this,a)}log(a){if(0===a)throw Error("Can't take log(0)");return this.logTable[a]}exp(a){return this.expTable[a]}}let K=[{infoBits:null,versionNumber:1,alignmentPatternCenters:[],errorCorrectionLevels:[{ecCodewordsPerBlock:7,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:19}]},{ecCodewordsPerBlock:10,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:16}]},{ecCodewordsPerBlock:13, +ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:13}]},{ecCodewordsPerBlock:17,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:9}]}]},{infoBits:null,versionNumber:2,alignmentPatternCenters:[6,18],errorCorrectionLevels:[{ecCodewordsPerBlock:10,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:34}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:28}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:22}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:16}]}]}, +{infoBits:null,versionNumber:3,alignmentPatternCenters:[6,22],errorCorrectionLevels:[{ecCodewordsPerBlock:15,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:55}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:13}]}]},{infoBits:null,versionNumber:4,alignmentPatternCenters:[6,26],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:1, +dataCodewordsPerBlock:80}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:32}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:9}]}]},{infoBits:null,versionNumber:5,alignmentPatternCenters:[6,30],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:43}]},{ecCodewordsPerBlock:18, +ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:15},{numBlocks:2,dataCodewordsPerBlock:16}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:11},{numBlocks:2,dataCodewordsPerBlock:12}]}]},{infoBits:null,versionNumber:6,alignmentPatternCenters:[6,34],errorCorrectionLevels:[{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:68}]},{ecCodewordsPerBlock:16,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:27}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:19}]}, +{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:15}]}]},{infoBits:31892,versionNumber:7,alignmentPatternCenters:[6,22,38],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:78}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:31}]},{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:14},{numBlocks:4,dataCodewordsPerBlock:15}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:13}, +{numBlocks:1,dataCodewordsPerBlock:14}]}]},{infoBits:34236,versionNumber:8,alignmentPatternCenters:[6,24,42],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:97}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:38},{numBlocks:2,dataCodewordsPerBlock:39}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:18},{numBlocks:2,dataCodewordsPerBlock:19}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:14}, +{numBlocks:2,dataCodewordsPerBlock:15}]}]},{infoBits:39577,versionNumber:9,alignmentPatternCenters:[6,26,46],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:36},{numBlocks:2,dataCodewordsPerBlock:37}]},{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:16},{numBlocks:4,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:12}, +{numBlocks:4,dataCodewordsPerBlock:13}]}]},{infoBits:42195,versionNumber:10,alignmentPatternCenters:[6,28,50],errorCorrectionLevels:[{ecCodewordsPerBlock:18,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:68},{numBlocks:2,dataCodewordsPerBlock:69}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:43},{numBlocks:1,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:19},{numBlocks:2,dataCodewordsPerBlock:20}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6, +dataCodewordsPerBlock:15},{numBlocks:2,dataCodewordsPerBlock:16}]}]},{infoBits:48118,versionNumber:11,alignmentPatternCenters:[6,30,54],errorCorrectionLevels:[{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:81}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:50},{numBlocks:4,dataCodewordsPerBlock:51}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:22},{numBlocks:4,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:3, +dataCodewordsPerBlock:12},{numBlocks:8,dataCodewordsPerBlock:13}]}]},{infoBits:51042,versionNumber:12,alignmentPatternCenters:[6,32,58],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:92},{numBlocks:2,dataCodewordsPerBlock:93}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:36},{numBlocks:2,dataCodewordsPerBlock:37}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:20},{numBlocks:6,dataCodewordsPerBlock:21}]}, +{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:14},{numBlocks:4,dataCodewordsPerBlock:15}]}]},{infoBits:55367,versionNumber:13,alignmentPatternCenters:[6,34,62],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:107}]},{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:37},{numBlocks:1,dataCodewordsPerBlock:38}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:20},{numBlocks:4,dataCodewordsPerBlock:21}]}, +{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:11},{numBlocks:4,dataCodewordsPerBlock:12}]}]},{infoBits:58893,versionNumber:14,alignmentPatternCenters:[6,26,46,66],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:115},{numBlocks:1,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:40},{numBlocks:5,dataCodewordsPerBlock:41}]},{ecCodewordsPerBlock:20,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:16}, +{numBlocks:5,dataCodewordsPerBlock:17}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:12},{numBlocks:5,dataCodewordsPerBlock:13}]}]},{infoBits:63784,versionNumber:15,alignmentPatternCenters:[6,26,48,70],errorCorrectionLevels:[{ecCodewordsPerBlock:22,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:87},{numBlocks:1,dataCodewordsPerBlock:88}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:41},{numBlocks:5,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:30, +ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:24},{numBlocks:7,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:12},{numBlocks:7,dataCodewordsPerBlock:13}]}]},{infoBits:68472,versionNumber:16,alignmentPatternCenters:[6,26,50,74],errorCorrectionLevels:[{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:98},{numBlocks:1,dataCodewordsPerBlock:99}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:45},{numBlocks:3,dataCodewordsPerBlock:46}]}, +{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:19},{numBlocks:2,dataCodewordsPerBlock:20}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:15},{numBlocks:13,dataCodewordsPerBlock:16}]}]},{infoBits:70749,versionNumber:17,alignmentPatternCenters:[6,30,54,78],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:107},{numBlocks:5,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:46}, +{numBlocks:1,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:22},{numBlocks:15,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:14},{numBlocks:17,dataCodewordsPerBlock:15}]}]},{infoBits:76311,versionNumber:18,alignmentPatternCenters:[6,30,56,82],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:120},{numBlocks:1,dataCodewordsPerBlock:121}]},{ecCodewordsPerBlock:26, +ecBlocks:[{numBlocks:9,dataCodewordsPerBlock:43},{numBlocks:4,dataCodewordsPerBlock:44}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:22},{numBlocks:1,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:14},{numBlocks:19,dataCodewordsPerBlock:15}]}]},{infoBits:79154,versionNumber:19,alignmentPatternCenters:[6,30,58,86],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:113},{numBlocks:4, +dataCodewordsPerBlock:114}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:44},{numBlocks:11,dataCodewordsPerBlock:45}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:21},{numBlocks:4,dataCodewordsPerBlock:22}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:9,dataCodewordsPerBlock:13},{numBlocks:16,dataCodewordsPerBlock:14}]}]},{infoBits:84390,versionNumber:20,alignmentPatternCenters:[6,34,62,90],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3, +dataCodewordsPerBlock:107},{numBlocks:5,dataCodewordsPerBlock:108}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:41},{numBlocks:13,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:24},{numBlocks:5,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:15},{numBlocks:10,dataCodewordsPerBlock:16}]}]},{infoBits:87683,versionNumber:21,alignmentPatternCenters:[6,28,50,72,94],errorCorrectionLevels:[{ecCodewordsPerBlock:28, +ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:116},{numBlocks:4,dataCodewordsPerBlock:117}]},{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:42}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:22},{numBlocks:6,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:16},{numBlocks:6,dataCodewordsPerBlock:17}]}]},{infoBits:92361,versionNumber:22,alignmentPatternCenters:[6,26,50,74,98],errorCorrectionLevels:[{ecCodewordsPerBlock:28, +ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:111},{numBlocks:7,dataCodewordsPerBlock:112}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:24},{numBlocks:16,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:24,ecBlocks:[{numBlocks:34,dataCodewordsPerBlock:13}]}]},{infoBits:96236,versionNumber:23,alignmentPatternCenters:[6,30,54,74,102],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4, +dataCodewordsPerBlock:121},{numBlocks:5,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:47},{numBlocks:14,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:24},{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:16,dataCodewordsPerBlock:15},{numBlocks:14,dataCodewordsPerBlock:16}]}]},{infoBits:102084,versionNumber:24,alignmentPatternCenters:[6,28,54,80,106],errorCorrectionLevels:[{ecCodewordsPerBlock:30, +ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:117},{numBlocks:4,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:45},{numBlocks:14,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:24},{numBlocks:16,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:30,dataCodewordsPerBlock:16},{numBlocks:2,dataCodewordsPerBlock:17}]}]},{infoBits:102881,versionNumber:25,alignmentPatternCenters:[6, +32,58,84,110],errorCorrectionLevels:[{ecCodewordsPerBlock:26,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:106},{numBlocks:4,dataCodewordsPerBlock:107}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:47},{numBlocks:13,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:24},{numBlocks:22,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:15},{numBlocks:13,dataCodewordsPerBlock:16}]}]}, +{infoBits:110507,versionNumber:26,alignmentPatternCenters:[6,30,58,86,114],errorCorrectionLevels:[{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:114},{numBlocks:2,dataCodewordsPerBlock:115}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:46},{numBlocks:4,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:28,dataCodewordsPerBlock:22},{numBlocks:6,dataCodewordsPerBlock:23}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:33,dataCodewordsPerBlock:16}, +{numBlocks:4,dataCodewordsPerBlock:17}]}]},{infoBits:110734,versionNumber:27,alignmentPatternCenters:[6,34,62,90,118],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:122},{numBlocks:4,dataCodewordsPerBlock:123}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:45},{numBlocks:3,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:8,dataCodewordsPerBlock:23},{numBlocks:26,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:30, +ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:15},{numBlocks:28,dataCodewordsPerBlock:16}]}]},{infoBits:117786,versionNumber:28,alignmentPatternCenters:[6,26,50,74,98,122],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:117},{numBlocks:10,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:3,dataCodewordsPerBlock:45},{numBlocks:23,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:24},{numBlocks:31, +dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:15},{numBlocks:31,dataCodewordsPerBlock:16}]}]},{infoBits:119615,versionNumber:29,alignmentPatternCenters:[6,30,54,78,102,126],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:7,dataCodewordsPerBlock:116},{numBlocks:7,dataCodewordsPerBlock:117}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:21,dataCodewordsPerBlock:45},{numBlocks:7,dataCodewordsPerBlock:46}]},{ecCodewordsPerBlock:30, +ecBlocks:[{numBlocks:1,dataCodewordsPerBlock:23},{numBlocks:37,dataCodewordsPerBlock:24}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:15},{numBlocks:26,dataCodewordsPerBlock:16}]}]},{infoBits:126325,versionNumber:30,alignmentPatternCenters:[6,26,52,78,104,130],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:5,dataCodewordsPerBlock:115},{numBlocks:10,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:47}, +{numBlocks:10,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:15,dataCodewordsPerBlock:24},{numBlocks:25,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:23,dataCodewordsPerBlock:15},{numBlocks:25,dataCodewordsPerBlock:16}]}]},{infoBits:127568,versionNumber:31,alignmentPatternCenters:[6,30,56,82,108,134],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:115},{numBlocks:3,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28, +ecBlocks:[{numBlocks:2,dataCodewordsPerBlock:46},{numBlocks:29,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:42,dataCodewordsPerBlock:24},{numBlocks:1,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:23,dataCodewordsPerBlock:15},{numBlocks:28,dataCodewordsPerBlock:16}]}]},{infoBits:133589,versionNumber:32,alignmentPatternCenters:[6,34,60,86,112,138],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:115}]}, +{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:46},{numBlocks:23,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:24},{numBlocks:35,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:15},{numBlocks:35,dataCodewordsPerBlock:16}]}]},{infoBits:136944,versionNumber:33,alignmentPatternCenters:[6,30,58,86,114,142],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:115}, +{numBlocks:1,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:14,dataCodewordsPerBlock:46},{numBlocks:21,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:29,dataCodewordsPerBlock:24},{numBlocks:19,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:11,dataCodewordsPerBlock:15},{numBlocks:46,dataCodewordsPerBlock:16}]}]},{infoBits:141498,versionNumber:34,alignmentPatternCenters:[6,34,62,90,118,146],errorCorrectionLevels:[{ecCodewordsPerBlock:30, +ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:115},{numBlocks:6,dataCodewordsPerBlock:116}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:14,dataCodewordsPerBlock:46},{numBlocks:23,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:44,dataCodewordsPerBlock:24},{numBlocks:7,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:59,dataCodewordsPerBlock:16},{numBlocks:1,dataCodewordsPerBlock:17}]}]},{infoBits:145311,versionNumber:35,alignmentPatternCenters:[6, +30,54,78,102,126,150],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:121},{numBlocks:7,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:12,dataCodewordsPerBlock:47},{numBlocks:26,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:39,dataCodewordsPerBlock:24},{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:22,dataCodewordsPerBlock:15},{numBlocks:41,dataCodewordsPerBlock:16}]}]}, +{infoBits:150283,versionNumber:36,alignmentPatternCenters:[6,24,50,76,102,128,154],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:121},{numBlocks:14,dataCodewordsPerBlock:122}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:6,dataCodewordsPerBlock:47},{numBlocks:34,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:46,dataCodewordsPerBlock:24},{numBlocks:10,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:2, +dataCodewordsPerBlock:15},{numBlocks:64,dataCodewordsPerBlock:16}]}]},{infoBits:152622,versionNumber:37,alignmentPatternCenters:[6,28,54,80,106,132,158],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:17,dataCodewordsPerBlock:122},{numBlocks:4,dataCodewordsPerBlock:123}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:29,dataCodewordsPerBlock:46},{numBlocks:14,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:49,dataCodewordsPerBlock:24},{numBlocks:10,dataCodewordsPerBlock:25}]}, +{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:24,dataCodewordsPerBlock:15},{numBlocks:46,dataCodewordsPerBlock:16}]}]},{infoBits:158308,versionNumber:38,alignmentPatternCenters:[6,32,58,84,110,136,162],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:4,dataCodewordsPerBlock:122},{numBlocks:18,dataCodewordsPerBlock:123}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:13,dataCodewordsPerBlock:46},{numBlocks:32,dataCodewordsPerBlock:47}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:48, +dataCodewordsPerBlock:24},{numBlocks:14,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:42,dataCodewordsPerBlock:15},{numBlocks:32,dataCodewordsPerBlock:16}]}]},{infoBits:161089,versionNumber:39,alignmentPatternCenters:[6,26,54,82,110,138,166],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:20,dataCodewordsPerBlock:117},{numBlocks:4,dataCodewordsPerBlock:118}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:40,dataCodewordsPerBlock:47},{numBlocks:7,dataCodewordsPerBlock:48}]}, +{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:43,dataCodewordsPerBlock:24},{numBlocks:22,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:10,dataCodewordsPerBlock:15},{numBlocks:67,dataCodewordsPerBlock:16}]}]},{infoBits:167017,versionNumber:40,alignmentPatternCenters:[6,30,58,86,114,142,170],errorCorrectionLevels:[{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:19,dataCodewordsPerBlock:118},{numBlocks:6,dataCodewordsPerBlock:119}]},{ecCodewordsPerBlock:28,ecBlocks:[{numBlocks:18, +dataCodewordsPerBlock:47},{numBlocks:31,dataCodewordsPerBlock:48}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:34,dataCodewordsPerBlock:24},{numBlocks:34,dataCodewordsPerBlock:25}]},{ecCodewordsPerBlock:30,ecBlocks:[{numBlocks:20,dataCodewordsPerBlock:15},{numBlocks:61,dataCodewordsPerBlock:16}]}]}],da=[{bits:21522,formatInfo:{errorCorrectionLevel:1,dataMask:0}},{bits:20773,formatInfo:{errorCorrectionLevel:1,dataMask:1}},{bits:24188,formatInfo:{errorCorrectionLevel:1,dataMask:2}},{bits:23371,formatInfo:{errorCorrectionLevel:1, +dataMask:3}},{bits:17913,formatInfo:{errorCorrectionLevel:1,dataMask:4}},{bits:16590,formatInfo:{errorCorrectionLevel:1,dataMask:5}},{bits:20375,formatInfo:{errorCorrectionLevel:1,dataMask:6}},{bits:19104,formatInfo:{errorCorrectionLevel:1,dataMask:7}},{bits:30660,formatInfo:{errorCorrectionLevel:0,dataMask:0}},{bits:29427,formatInfo:{errorCorrectionLevel:0,dataMask:1}},{bits:32170,formatInfo:{errorCorrectionLevel:0,dataMask:2}},{bits:30877,formatInfo:{errorCorrectionLevel:0,dataMask:3}},{bits:26159, +formatInfo:{errorCorrectionLevel:0,dataMask:4}},{bits:25368,formatInfo:{errorCorrectionLevel:0,dataMask:5}},{bits:27713,formatInfo:{errorCorrectionLevel:0,dataMask:6}},{bits:26998,formatInfo:{errorCorrectionLevel:0,dataMask:7}},{bits:5769,formatInfo:{errorCorrectionLevel:3,dataMask:0}},{bits:5054,formatInfo:{errorCorrectionLevel:3,dataMask:1}},{bits:7399,formatInfo:{errorCorrectionLevel:3,dataMask:2}},{bits:6608,formatInfo:{errorCorrectionLevel:3,dataMask:3}},{bits:1890,formatInfo:{errorCorrectionLevel:3, +dataMask:4}},{bits:597,formatInfo:{errorCorrectionLevel:3,dataMask:5}},{bits:3340,formatInfo:{errorCorrectionLevel:3,dataMask:6}},{bits:2107,formatInfo:{errorCorrectionLevel:3,dataMask:7}},{bits:13663,formatInfo:{errorCorrectionLevel:2,dataMask:0}},{bits:12392,formatInfo:{errorCorrectionLevel:2,dataMask:1}},{bits:16177,formatInfo:{errorCorrectionLevel:2,dataMask:2}},{bits:14854,formatInfo:{errorCorrectionLevel:2,dataMask:3}},{bits:9396,formatInfo:{errorCorrectionLevel:2,dataMask:4}},{bits:8579,formatInfo:{errorCorrectionLevel:2, +dataMask:5}},{bits:11994,formatInfo:{errorCorrectionLevel:2,dataMask:6}},{bits:11245,formatInfo:{errorCorrectionLevel:2,dataMask:7}}],aa=[a=>0===(a.y+a.x)%2,a=>0===a.y%2,a=>0===a.x%3,a=>0===(a.y+a.x)%3,a=>0===(Math.floor(a.y/2)+Math.floor(a.x/3))%2,a=>0===a.x*a.y%2+a.x*a.y%3,a=>0===(a.y*a.x%2+a.y*a.x%3)%2,a=>0===((a.y+a.x)%2+a.y*a.x%3)%2],y=(a,b)=>Math.sqrt(Math.pow(b.x-a.x,2)+Math.pow(b.y-a.y,2)),la={inversionAttempts:"attemptBoth",greyScaleWeights:{red:.2126,green:.7152,blue:.0722,useIntegerApproximation:!1}, +canOverwriteImage:!0};I.default=I;let G="dontInvert",D={red:77,green:150,blue:29,useIntegerApproximation:!0};self.onmessage=a=>{let b=a.data.data;switch(a.data.type){case "decode":a=I(b.data,b.width,b.height,{inversionAttempts:G,greyScaleWeights:D});self.postMessage({type:"qrResult",data:a?a.data:null});break;case "grayscaleWeights":D.red=b.red;D.green=b.green;D.blue=b.blue;D.useIntegerApproximation=b.useIntegerApproximation;break;case "inversionMode":switch(b){case "original":G="dontInvert";break; +case "invert":G="onlyInvert";break;case "both":G="attemptBoth";break;default:throw Error("Invalid inversion mode");}break;case "close":self.close()}}})() +//# sourceMappingURL=qr-scanner-worker.min.js.map diff --git a/apps/qrcode/qr-scanner-worker.min.js.map b/apps/qrcode/qr-scanner-worker.min.js.map new file mode 100644 index 000000000..dbf29b5cd --- /dev/null +++ b/apps/qrcode/qr-scanner-worker.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"qr-scanner-worker.min.js","sources":["node_modules/jsqr-es6/src/decoder/decodeData/index.ts","node_modules/jsqr-es6/src/decoder/reedsolomon/GenericGF.ts","node_modules/jsqr-es6/src/decoder/reedsolomon/index.ts","node_modules/jsqr-es6/src/decoder/decoder.ts","node_modules/jsqr-es6/src/extractor/index.ts","node_modules/jsqr-es6/src/locator/index.ts","node_modules/jsqr-es6/src/index.ts","node_modules/jsqr-es6/src/binarizer/index.ts","node_modules/jsqr-es6/src/BitMatrix.ts","node_modules/jsqr-es6/src/decoder/decodeData/BitStream.ts","node_modules/jsqr-es6/src/decoder/reedsolomon/GenericGFPoly.ts","node_modules/jsqr-es6/src/decoder/version.ts","src/worker.js"],"sourcesContent":["// tslint:disable:no-bitwise\nimport { BitStream } from \"./BitStream\";\n\nexport interface Chunk {\n type: Mode;\n text: string;\n}\n\nexport interface ByteChunk {\n type: Mode.Byte | Mode.Kanji;\n bytes: number[];\n}\n\nexport interface ECIChunk {\n type: Mode.ECI;\n assignmentNumber: number;\n}\n\nexport interface StructuredAppend {\n type: Mode.StructuredAppend;\n currentSequence: number;\n totalSequence: number;\n parity: number;\n}\n\nexport type Chunks = Array;\n\nexport interface DecodedQR {\n text: string;\n bytes: number[];\n chunks: Chunks;\n version: number;\n}\n\nexport enum Mode {\n Numeric = \"numeric\",\n Alphanumeric = \"alphanumeric\",\n Byte = \"byte\",\n Kanji = \"kanji\",\n ECI = \"eci\",\n StructuredAppend = \"structuredappend\",\n}\n\nenum ModeByte {\n Terminator = 0x0,\n Numeric = 0x1,\n Alphanumeric = 0x2,\n Byte = 0x4,\n Kanji = 0x8,\n ECI = 0x7,\n StructuredAppend = 0x3,\n // FNC1FirstPosition = 0x5,\n // FNC1SecondPosition = 0x9,\n}\n\nfunction decodeNumeric(stream: BitStream, size: number) {\n const bytes: number[] = [];\n let text = \"\";\n\n const characterCountSize = [10, 12, 14][size];\n let length = stream.readBits(characterCountSize);\n // Read digits in groups of 3\n while (length >= 3) {\n const num = stream.readBits(10);\n if (num >= 1000) {\n throw new Error(\"Invalid numeric value above 999\");\n }\n\n const a = Math.floor(num / 100);\n const b = Math.floor(num / 10) % 10;\n const c = num % 10;\n\n bytes.push(48 + a, 48 + b, 48 + c);\n text += a.toString() + b.toString() + c.toString();\n length -= 3;\n }\n\n // If the number of digits aren't a multiple of 3, the remaining digits are special cased.\n if (length === 2) {\n const num = stream.readBits(7);\n if (num >= 100) {\n throw new Error(\"Invalid numeric value above 99\");\n }\n\n const a = Math.floor(num / 10);\n const b = num % 10;\n\n bytes.push(48 + a, 48 + b);\n text += a.toString() + b.toString();\n } else if (length === 1) {\n const num = stream.readBits(4);\n if (num >= 10) {\n throw new Error(\"Invalid numeric value above 9\");\n }\n\n bytes.push(48 + num);\n text += num.toString();\n }\n\n return { bytes, text };\n}\n\nconst AlphanumericCharacterCodes = [\n \"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\",\n \"9\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\",\n \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\",\n \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\",\n \" \", \"$\", \"%\", \"*\", \"+\", \"-\", \".\", \"/\", \":\",\n];\n\nfunction decodeAlphanumeric(stream: BitStream, size: number) {\n const bytes: number[] = [];\n let text = \"\";\n\n const characterCountSize = [9, 11, 13][size];\n let length = stream.readBits(characterCountSize);\n while (length >= 2) {\n const v = stream.readBits(11);\n\n const a = Math.floor(v / 45);\n const b = v % 45;\n\n bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0));\n text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b];\n length -= 2;\n }\n\n if (length === 1) {\n const a = stream.readBits(6);\n bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0));\n text += AlphanumericCharacterCodes[a];\n }\n\n return { bytes, text };\n}\n\nfunction decodeByte(stream: BitStream, size: number) {\n const bytes: number[] = [];\n let text = \"\";\n\n const characterCountSize = [8, 16, 16][size];\n const length = stream.readBits(characterCountSize);\n for (let i = 0; i < length; i++) {\n const b = stream.readBits(8);\n bytes.push(b);\n }\n try {\n text += decodeURIComponent(bytes.map(b => `%${(\"0\" + b.toString(16)).substr(-2)}`).join(\"\"));\n } catch {\n // failed to decode\n }\n\n return { bytes, text };\n}\n\nfunction decodeKanji(stream: BitStream, size: number) {\n const bytes: number[] = [];\n\n const characterCountSize = [8, 10, 12][size];\n const length = stream.readBits(characterCountSize);\n for (let i = 0; i < length; i++) {\n const k = stream.readBits(13);\n\n let c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0);\n if (c < 0x1F00) {\n c += 0x8140;\n } else {\n c += 0xC140;\n }\n\n bytes.push(c >> 8, c & 0xFF);\n }\n\n const text = new TextDecoder(\"shift-jis\").decode(Uint8Array.from(bytes));\n return { bytes, text };\n}\n\nexport function decode(data: Uint8ClampedArray, version: number): DecodedQR {\n const stream = new BitStream(data);\n\n // There are 3 'sizes' based on the version. 1-9 is small (0), 10-26 is medium (1) and 27-40 is large (2).\n const size = version <= 9 ? 0 : version <= 26 ? 1 : 2;\n\n const result: DecodedQR = {\n text: \"\",\n bytes: [],\n chunks: [],\n version,\n };\n\n while (stream.available() >= 4) {\n const mode = stream.readBits(4);\n if (mode === ModeByte.Terminator) {\n return result;\n } else if (mode === ModeByte.ECI) {\n if (stream.readBits(1) === 0) {\n result.chunks.push({\n type: Mode.ECI,\n assignmentNumber: stream.readBits(7),\n });\n } else if (stream.readBits(1) === 0) {\n result.chunks.push({\n type: Mode.ECI,\n assignmentNumber: stream.readBits(14),\n });\n } else if (stream.readBits(1) === 0) {\n result.chunks.push({\n type: Mode.ECI,\n assignmentNumber: stream.readBits(21),\n });\n } else {\n // ECI data seems corrupted\n result.chunks.push({\n type: Mode.ECI,\n assignmentNumber: -1,\n });\n }\n } else if (mode === ModeByte.Numeric) {\n const numericResult = decodeNumeric(stream, size);\n result.text += numericResult.text;\n result.bytes.push(...numericResult.bytes);\n result.chunks.push({\n type: Mode.Numeric,\n text: numericResult.text,\n });\n } else if (mode === ModeByte.Alphanumeric) {\n const alphanumericResult = decodeAlphanumeric(stream, size);\n result.text += alphanumericResult.text;\n result.bytes.push(...alphanumericResult.bytes);\n result.chunks.push({\n type: Mode.Alphanumeric,\n text: alphanumericResult.text,\n });\n } else if (mode === ModeByte.Byte) {\n const byteResult = decodeByte(stream, size);\n result.text += byteResult.text;\n result.bytes.push(...byteResult.bytes);\n result.chunks.push({\n type: Mode.Byte,\n bytes: byteResult.bytes,\n text: byteResult.text,\n });\n } else if (mode === ModeByte.Kanji) {\n const kanjiResult = decodeKanji(stream, size);\n result.text += kanjiResult.text;\n result.bytes.push(...kanjiResult.bytes);\n result.chunks.push({\n type: Mode.Kanji,\n bytes: kanjiResult.bytes,\n text: kanjiResult.text,\n });\n } else if (mode === ModeByte.StructuredAppend) {\n result.chunks.push({\n type: Mode.StructuredAppend,\n currentSequence: stream.readBits(4),\n totalSequence: stream.readBits(4),\n parity: stream.readBits(8),\n });\n }\n }\n\n // If there is no data left, or the remaining bits are all 0, then that counts as a termination marker\n if (stream.available() === 0 || stream.readBits(stream.available()) === 0) {\n return result;\n }\n}\n","import GenericGFPoly from \"./GenericGFPoly\";\n\nexport function addOrSubtractGF(a: number, b: number) {\n return a ^ b; // tslint:disable-line:no-bitwise\n}\n\nexport default class GenericGF {\n public primitive: number;\n public size: number;\n public generatorBase: number;\n public zero: GenericGFPoly;\n public one: GenericGFPoly;\n\n private expTable: number[];\n private logTable: number[];\n\n constructor(primitive: number, size: number, genBase: number) {\n this.primitive = primitive;\n this.size = size;\n this.generatorBase = genBase;\n this.expTable = new Array(this.size);\n this.logTable = new Array(this.size);\n\n let x = 1;\n for (let i = 0; i < this.size; i++) {\n this.expTable[i] = x;\n x = x * 2;\n if (x >= this.size) {\n x = (x ^ this.primitive) & (this.size - 1); // tslint:disable-line:no-bitwise\n }\n }\n\n for (let i = 0; i < this.size - 1; i++) {\n this.logTable[this.expTable[i]] = i;\n }\n this.zero = new GenericGFPoly(this, Uint8ClampedArray.from([0]));\n this.one = new GenericGFPoly(this, Uint8ClampedArray.from([1]));\n }\n\n public multiply(a: number, b: number) {\n if (a === 0 || b === 0) {\n return 0;\n }\n return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)];\n }\n\n public inverse(a: number) {\n if (a === 0) {\n throw new Error(\"Can't invert 0\");\n }\n return this.expTable[this.size - this.logTable[a] - 1];\n }\n\n public buildMonomial(degree: number, coefficient: number): GenericGFPoly {\n if (degree < 0) {\n throw new Error(\"Invalid monomial degree less than 0\");\n }\n if (coefficient === 0) {\n return this.zero;\n }\n const coefficients = new Uint8ClampedArray(degree + 1);\n coefficients[0] = coefficient;\n return new GenericGFPoly(this, coefficients);\n }\n\n public log(a: number) {\n if (a === 0) {\n throw new Error(\"Can't take log(0)\");\n }\n return this.logTable[a];\n }\n\n public exp(a: number) {\n return this.expTable[a];\n }\n}\n","import GenericGF, { addOrSubtractGF } from \"./GenericGF\";\nimport GenericGFPoly from \"./GenericGFPoly\";\n\nfunction runEuclideanAlgorithm(field: GenericGF, a: GenericGFPoly, b: GenericGFPoly, R: number): GenericGFPoly[] {\n // Assume a's degree is >= b's\n if (a.degree() < b.degree()) {\n [a, b] = [b, a];\n }\n\n let rLast = a;\n let r = b;\n let tLast = field.zero;\n let t = field.one;\n\n // Run Euclidean algorithm until r's degree is less than R/2\n while (r.degree() >= R / 2) {\n const rLastLast = rLast;\n const tLastLast = tLast;\n rLast = r;\n tLast = t;\n\n // Divide rLastLast by rLast, with quotient in q and remainder in r\n if (rLast.isZero()) {\n // Euclidean algorithm already terminated?\n return null;\n }\n r = rLastLast;\n let q = field.zero;\n const denominatorLeadingTerm = rLast.getCoefficient(rLast.degree());\n const dltInverse = field.inverse(denominatorLeadingTerm);\n while (r.degree() >= rLast.degree() && !r.isZero()) {\n const degreeDiff = r.degree() - rLast.degree();\n const scale = field.multiply(r.getCoefficient(r.degree()), dltInverse);\n q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));\n r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));\n }\n\n t = q.multiplyPoly(tLast).addOrSubtract(tLastLast);\n\n if (r.degree() >= rLast.degree()) {\n return null;\n }\n }\n\n const sigmaTildeAtZero = t.getCoefficient(0);\n if (sigmaTildeAtZero === 0) {\n return null;\n }\n\n const inverse = field.inverse(sigmaTildeAtZero);\n return [t.multiply(inverse), r.multiply(inverse)];\n}\n\nfunction findErrorLocations(field: GenericGF, errorLocator: GenericGFPoly): number[] {\n // This is a direct application of Chien's search\n const numErrors = errorLocator.degree();\n if (numErrors === 1) {\n return [errorLocator.getCoefficient(1)];\n }\n const result: number[] = new Array(numErrors);\n let errorCount = 0;\n for (let i = 1; i < field.size && errorCount < numErrors; i++) {\n if (errorLocator.evaluateAt(i) === 0) {\n result[errorCount] = field.inverse(i);\n errorCount++;\n }\n }\n if (errorCount !== numErrors) {\n return null;\n }\n return result;\n}\n\nfunction findErrorMagnitudes(field: GenericGF, errorEvaluator: GenericGFPoly, errorLocations: number[]): number[] {\n // This is directly applying Forney's Formula\n const s = errorLocations.length;\n const result: number[] = new Array(s);\n for (let i = 0; i < s; i++) {\n const xiInverse = field.inverse(errorLocations[i]);\n let denominator = 1;\n for (let j = 0; j < s; j++) {\n if (i !== j) {\n denominator = field.multiply(denominator, addOrSubtractGF(1, field.multiply(errorLocations[j], xiInverse)));\n }\n }\n result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator));\n if (field.generatorBase !== 0) {\n result[i] = field.multiply(result[i], xiInverse);\n }\n }\n return result;\n}\n\nexport function decode(bytes: number[], twoS: number) {\n const outputBytes = new Uint8ClampedArray(bytes.length);\n outputBytes.set(bytes);\n\n const field = new GenericGF(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1\n const poly = new GenericGFPoly(field, outputBytes);\n\n const syndromeCoefficients = new Uint8ClampedArray(twoS);\n let error = false;\n for (let s = 0; s < twoS; s++) {\n const evaluation = poly.evaluateAt(field.exp(s + field.generatorBase));\n syndromeCoefficients[syndromeCoefficients.length - 1 - s] = evaluation;\n if (evaluation !== 0) {\n error = true;\n }\n }\n if (!error) {\n return outputBytes;\n }\n\n const syndrome = new GenericGFPoly(field, syndromeCoefficients);\n\n const sigmaOmega = runEuclideanAlgorithm(field, field.buildMonomial(twoS, 1), syndrome, twoS);\n if (sigmaOmega === null) {\n return null;\n }\n\n const errorLocations = findErrorLocations(field, sigmaOmega[0]);\n if (errorLocations == null) {\n return null;\n }\n\n const errorMagnitudes = findErrorMagnitudes(field, sigmaOmega[1], errorLocations);\n for (let i = 0; i < errorLocations.length; i++) {\n const position = outputBytes.length - 1 - field.log(errorLocations[i]);\n if (position < 0) {\n return null;\n }\n outputBytes[position] = addOrSubtractGF(outputBytes[position], errorMagnitudes[i]);\n }\n\n return outputBytes;\n}\n","import { BitMatrix } from \"../BitMatrix\";\nimport { Point } from \"../Point\";\nimport { decode as decodeData, DecodedQR } from \"./decodeData\";\nimport { decode as rsDecode } from \"./reedsolomon\";\nimport { Version, VERSIONS } from \"./version\";\n\n// tslint:disable:no-bitwise\nfunction numBitsDiffering(x: number, y: number) {\n let z = x ^ y;\n let bitCount = 0;\n while (z) {\n bitCount++;\n z &= z - 1;\n }\n return bitCount;\n}\n\nfunction pushBit(bit: any, byte: number) {\n return (byte << 1) | bit;\n}\n// tslint:enable:no-bitwise\n\nconst FORMAT_INFO_TABLE = [\n { bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } },\n { bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } },\n { bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } },\n { bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } },\n { bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } },\n { bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } },\n { bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } },\n { bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } },\n { bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } },\n { bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } },\n { bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } },\n { bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } },\n { bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } },\n { bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } },\n { bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } },\n { bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } },\n { bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } },\n { bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } },\n { bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } },\n { bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } },\n { bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } },\n { bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } },\n { bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } },\n { bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } },\n { bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } },\n { bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } },\n { bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } },\n { bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } },\n { bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } },\n { bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } },\n { bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } },\n { bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } },\n];\n\nconst DATA_MASKS = [\n (p: Point) => ((p.y + p.x) % 2) === 0,\n (p: Point) => (p.y % 2) === 0,\n (p: Point) => p.x % 3 === 0,\n (p: Point) => (p.y + p.x) % 3 === 0,\n (p: Point) => (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0,\n (p: Point) => ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0,\n (p: Point) => ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0,\n (p: Point) => ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0,\n];\n\ninterface FormatInformation {\n errorCorrectionLevel: number;\n dataMask: number;\n}\n\nfunction buildFunctionPatternMask(version: Version): BitMatrix {\n const dimension = 17 + 4 * version.versionNumber;\n const matrix = BitMatrix.createEmpty(dimension, dimension);\n\n matrix.setRegion(0, 0, 9, 9, true); // Top left finder pattern + separator + format\n matrix.setRegion(dimension - 8, 0, 8, 9, true); // Top right finder pattern + separator + format\n matrix.setRegion(0, dimension - 8, 9, 8, true); // Bottom left finder pattern + separator + format\n\n // Alignment patterns\n for (const x of version.alignmentPatternCenters) {\n for (const y of version.alignmentPatternCenters) {\n if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) {\n matrix.setRegion(x - 2, y - 2, 5, 5, true);\n }\n }\n }\n\n matrix.setRegion(6, 9, 1, dimension - 17, true); // Vertical timing pattern\n matrix.setRegion(9, 6, dimension - 17, 1, true); // Horizontal timing pattern\n\n if (version.versionNumber > 6) {\n matrix.setRegion(dimension - 11, 0, 3, 6, true); // Version info, top right\n matrix.setRegion(0, dimension - 11, 6, 3, true); // Version info, bottom left\n }\n\n return matrix;\n}\n\nfunction readCodewords(matrix: BitMatrix, version: Version, formatInfo: FormatInformation) {\n const dataMask = DATA_MASKS[formatInfo.dataMask];\n const dimension = matrix.height;\n\n const functionPatternMask = buildFunctionPatternMask(version);\n\n const codewords: number[] = [];\n let currentByte = 0;\n let bitsRead = 0;\n\n // Read columns in pairs, from right to left\n let readingUp = true;\n for (let columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) {\n if (columnIndex === 6) { // Skip whole column with vertical alignment pattern;\n columnIndex--;\n }\n for (let i = 0; i < dimension; i++) {\n const y = readingUp ? dimension - 1 - i : i;\n for (let columnOffset = 0; columnOffset < 2; columnOffset++) {\n const x = columnIndex - columnOffset;\n if (!functionPatternMask.get(x, y)) {\n bitsRead++;\n let bit = matrix.get(x, y);\n if (dataMask({y, x})) {\n bit = !bit;\n }\n currentByte = pushBit(bit, currentByte);\n if (bitsRead === 8) { // Whole bytes\n codewords.push(currentByte);\n bitsRead = 0;\n currentByte = 0;\n }\n }\n }\n }\n readingUp = !readingUp;\n }\n return codewords;\n}\n\nfunction readVersion(matrix: BitMatrix): Version {\n const dimension = matrix.height;\n\n const provisionalVersion = Math.floor((dimension - 17) / 4);\n if (provisionalVersion <= 6) { // 6 and under dont have version info in the QR code\n return VERSIONS[provisionalVersion - 1];\n }\n\n let topRightVersionBits = 0;\n for (let y = 5; y >= 0; y--) {\n for (let x = dimension - 9; x >= dimension - 11; x--) {\n topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits);\n }\n }\n\n let bottomLeftVersionBits = 0;\n for (let x = 5; x >= 0; x--) {\n for (let y = dimension - 9; y >= dimension - 11; y--) {\n bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits);\n }\n }\n\n let bestDifference = Infinity;\n let bestVersion: Version;\n for (const version of VERSIONS) {\n if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) {\n return version;\n }\n\n let difference = numBitsDiffering(topRightVersionBits, version.infoBits);\n if (difference < bestDifference) {\n bestVersion = version;\n bestDifference = difference;\n }\n\n difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits);\n if (difference < bestDifference) {\n bestVersion = version;\n bestDifference = difference;\n }\n }\n // We can tolerate up to 3 bits of error since no two version info codewords will\n // differ in less than 8 bits.\n if (bestDifference <= 3) {\n return bestVersion;\n }\n}\n\nfunction readFormatInformation(matrix: BitMatrix) {\n let topLeftFormatInfoBits = 0;\n for (let x = 0; x <= 8; x++) {\n if (x !== 6) { // Skip timing pattern bit\n topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits);\n }\n }\n for (let y = 7; y >= 0; y--) {\n if (y !== 6) { // Skip timing pattern bit\n topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits);\n }\n }\n\n const dimension = matrix.height;\n let topRightBottomRightFormatInfoBits = 0;\n for (let y = dimension - 1; y >= dimension - 7; y--) { // bottom left\n topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits);\n }\n for (let x = dimension - 8; x < dimension; x++) { // top right\n topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits);\n }\n\n let bestDifference = Infinity;\n let bestFormatInfo = null;\n for (const {bits, formatInfo} of FORMAT_INFO_TABLE) {\n if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) {\n return formatInfo;\n }\n let difference = numBitsDiffering(topLeftFormatInfoBits, bits);\n if (difference < bestDifference) {\n bestFormatInfo = formatInfo;\n bestDifference = difference;\n }\n if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { // also try the other option\n difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits);\n if (difference < bestDifference) {\n bestFormatInfo = formatInfo;\n bestDifference = difference;\n }\n }\n }\n // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match\n if (bestDifference <= 3) {\n return bestFormatInfo;\n }\n return null;\n}\n\nfunction getDataBlocks(codewords: number[], version: Version, ecLevel: number) {\n const ecInfo = version.errorCorrectionLevels[ecLevel];\n const dataBlocks: Array<{\n numDataCodewords: number;\n codewords: number[];\n }> = [];\n\n let totalCodewords = 0;\n ecInfo.ecBlocks.forEach(block => {\n for (let i = 0; i < block.numBlocks; i++) {\n dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] });\n totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock;\n }\n });\n\n // In some cases the QR code will be malformed enough that we pull off more or less than we should.\n // If we pull off less there's nothing we can do.\n // If we pull off more we can safely truncate\n if (codewords.length < totalCodewords) {\n return null;\n }\n codewords = codewords.slice(0, totalCodewords);\n\n const shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock;\n // Pull codewords to fill the blocks up to the minimum size\n for (let i = 0; i < shortBlockSize; i++) {\n for (const dataBlock of dataBlocks) {\n dataBlock.codewords.push(codewords.shift());\n }\n }\n\n // If there are any large blocks, pull codewords to fill the last element of those\n if (ecInfo.ecBlocks.length > 1) {\n const smallBlockCount = ecInfo.ecBlocks[0].numBlocks;\n const largeBlockCount = ecInfo.ecBlocks[1].numBlocks;\n for (let i = 0; i < largeBlockCount; i++) {\n dataBlocks[smallBlockCount + i].codewords.push(codewords.shift());\n }\n }\n\n // Add the rest of the codewords to the blocks. These are the error correction codewords.\n while (codewords.length > 0) {\n for (const dataBlock of dataBlocks) {\n dataBlock.codewords.push(codewords.shift());\n }\n }\n\n return dataBlocks;\n}\n\nfunction decodeMatrix(matrix: BitMatrix) {\n const version = readVersion(matrix);\n if (!version) {\n return null;\n }\n\n const formatInfo = readFormatInformation(matrix);\n if (!formatInfo) {\n return null;\n }\n\n const codewords = readCodewords(matrix, version, formatInfo);\n const dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel);\n if (!dataBlocks) {\n return null;\n }\n\n // Count total number of data bytes\n const totalBytes = dataBlocks.reduce((a, b) => a + b.numDataCodewords, 0);\n const resultBytes = new Uint8ClampedArray(totalBytes);\n\n let resultIndex = 0;\n for (const dataBlock of dataBlocks) {\n const correctedBytes = rsDecode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords);\n if (!correctedBytes) {\n return null;\n }\n for (let i = 0; i < dataBlock.numDataCodewords; i++) {\n resultBytes[resultIndex++] = correctedBytes[i];\n }\n }\n\n try {\n return decodeData(resultBytes, version.versionNumber);\n } catch {\n return null;\n }\n}\n\nexport function decode(matrix: BitMatrix): DecodedQR {\n if (matrix == null) {\n return null;\n }\n const result = decodeMatrix(matrix);\n if (result) {\n return result;\n }\n // Decoding didn't work, try mirroring the QR across the topLeft -> bottomRight line.\n for (let x = 0; x < matrix.width; x++) {\n for (let y = x + 1; y < matrix.height; y++) {\n if (matrix.get(x, y) !== matrix.get(y, x)) {\n matrix.set(x, y, !matrix.get(x, y));\n matrix.set(y, x, !matrix.get(y, x));\n }\n }\n }\n return decodeMatrix(matrix);\n}\n","import {BitMatrix} from \"../BitMatrix\";\nimport {Point, QRLocation} from \"../locator\";\n\ninterface PerspectiveTransform {\n a11: number;\n a21: number;\n a31: number;\n a12: number;\n a22: number;\n a32: number;\n a13: number;\n a23: number;\n a33: number;\n}\n\nfunction squareToQuadrilateral(p1: Point, p2: Point, p3: Point, p4: Point): PerspectiveTransform {\n const dx3 = p1.x - p2.x + p3.x - p4.x;\n const dy3 = p1.y - p2.y + p3.y - p4.y;\n if (dx3 === 0 && dy3 === 0) { // Affine\n return {\n a11: p2.x - p1.x,\n a12: p2.y - p1.y,\n a13: 0,\n a21: p3.x - p2.x,\n a22: p3.y - p2.y,\n a23: 0,\n a31: p1.x,\n a32: p1.y,\n a33: 1,\n };\n } else {\n const dx1 = p2.x - p3.x;\n const dx2 = p4.x - p3.x;\n const dy1 = p2.y - p3.y;\n const dy2 = p4.y - p3.y;\n const denominator = dx1 * dy2 - dx2 * dy1;\n const a13 = (dx3 * dy2 - dx2 * dy3) / denominator;\n const a23 = (dx1 * dy3 - dx3 * dy1) / denominator;\n return {\n a11: p2.x - p1.x + a13 * p2.x,\n a12: p2.y - p1.y + a13 * p2.y,\n a13,\n a21: p4.x - p1.x + a23 * p4.x,\n a22: p4.y - p1.y + a23 * p4.y,\n a23,\n a31: p1.x,\n a32: p1.y,\n a33: 1,\n };\n }\n}\n\nfunction quadrilateralToSquare(p1: Point, p2: Point, p3: Point, p4: Point): PerspectiveTransform {\n // Here, the adjoint serves as the inverse:\n const sToQ = squareToQuadrilateral(p1, p2, p3, p4);\n return {\n a11: sToQ.a22 * sToQ.a33 - sToQ.a23 * sToQ.a32,\n a12: sToQ.a13 * sToQ.a32 - sToQ.a12 * sToQ.a33,\n a13: sToQ.a12 * sToQ.a23 - sToQ.a13 * sToQ.a22,\n a21: sToQ.a23 * sToQ.a31 - sToQ.a21 * sToQ.a33,\n a22: sToQ.a11 * sToQ.a33 - sToQ.a13 * sToQ.a31,\n a23: sToQ.a13 * sToQ.a21 - sToQ.a11 * sToQ.a23,\n a31: sToQ.a21 * sToQ.a32 - sToQ.a22 * sToQ.a31,\n a32: sToQ.a12 * sToQ.a31 - sToQ.a11 * sToQ.a32,\n a33: sToQ.a11 * sToQ.a22 - sToQ.a12 * sToQ.a21,\n };\n}\n\nfunction times(a: PerspectiveTransform, b: PerspectiveTransform): PerspectiveTransform {\n return {\n a11: a.a11 * b.a11 + a.a21 * b.a12 + a.a31 * b.a13,\n a12: a.a12 * b.a11 + a.a22 * b.a12 + a.a32 * b.a13,\n a13: a.a13 * b.a11 + a.a23 * b.a12 + a.a33 * b.a13,\n a21: a.a11 * b.a21 + a.a21 * b.a22 + a.a31 * b.a23,\n a22: a.a12 * b.a21 + a.a22 * b.a22 + a.a32 * b.a23,\n a23: a.a13 * b.a21 + a.a23 * b.a22 + a.a33 * b.a23,\n a31: a.a11 * b.a31 + a.a21 * b.a32 + a.a31 * b.a33,\n a32: a.a12 * b.a31 + a.a22 * b.a32 + a.a32 * b.a33,\n a33: a.a13 * b.a31 + a.a23 * b.a32 + a.a33 * b.a33,\n };\n}\n\nexport function extract(image: BitMatrix, location: QRLocation) {\n const qToS = quadrilateralToSquare(\n {x: 3.5, y: 3.5},\n {x: location.dimension - 3.5, y: 3.5},\n {x: location.dimension - 6.5, y: location.dimension - 6.5},\n {x: 3.5, y: location.dimension - 3.5},\n );\n const sToQ = squareToQuadrilateral(location.topLeft, location.topRight, location.alignmentPattern, location.bottomLeft);\n const transform = times(sToQ, qToS);\n\n const matrix = BitMatrix.createEmpty(location.dimension, location.dimension);\n const mappingFunction = (x: number, y: number) => {\n const denominator = transform.a13 * x + transform.a23 * y + transform.a33;\n return {\n x: (transform.a11 * x + transform.a21 * y + transform.a31) / denominator,\n y: (transform.a12 * x + transform.a22 * y + transform.a32) / denominator,\n };\n };\n\n for (let y = 0; y < location.dimension; y++) {\n for (let x = 0; x < location.dimension; x++) {\n const xValue = x + 0.5;\n const yValue = y + 0.5;\n const sourcePixel = mappingFunction(xValue, yValue);\n matrix.set(x, y, image.get(Math.floor(sourcePixel.x), Math.floor(sourcePixel.y)));\n }\n }\n\n return {\n matrix,\n mappingFunction,\n };\n}\n","import { BitMatrix } from \"../BitMatrix\";\n\nconst MAX_FINDERPATTERNS_TO_SEARCH = 5;\nconst MIN_QUAD_RATIO = 0.5;\nconst MAX_QUAD_RATIO = 1.5;\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface QRLocation {\n topRight: Point;\n bottomLeft: Point;\n topLeft: Point;\n alignmentPattern: Point;\n dimension: number;\n}\n\nconst distance = (a: Point, b: Point) => Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2);\n\nfunction sum(values: number[]) {\n return values.reduce((a, b) => a + b);\n}\n\n// Takes three finder patterns and organizes them into topLeft, topRight, etc\nfunction reorderFinderPatterns(pattern1: Point, pattern2: Point, pattern3: Point) {\n // Find distances between pattern centers\n const oneTwoDistance = distance(pattern1, pattern2);\n const twoThreeDistance = distance(pattern2, pattern3);\n const oneThreeDistance = distance(pattern1, pattern3);\n\n let bottomLeft: Point;\n let topLeft: Point;\n let topRight: Point;\n\n // Assume one closest to other two is B; A and C will just be guesses at first\n if (twoThreeDistance >= oneTwoDistance && twoThreeDistance >= oneThreeDistance) {\n [bottomLeft, topLeft, topRight] = [pattern2, pattern1, pattern3];\n } else if (oneThreeDistance >= twoThreeDistance && oneThreeDistance >= oneTwoDistance) {\n [bottomLeft, topLeft, topRight] = [pattern1, pattern2, pattern3];\n } else {\n [bottomLeft, topLeft, topRight] = [pattern1, pattern3, pattern2];\n }\n\n // Use cross product to figure out whether bottomLeft (A) and topRight (C) are correct or flipped in relation to topLeft (B)\n // This asks whether BC x BA has a positive z component, which is the arrangement we want. If it's negative, then\n // we've got it flipped around and should swap topRight and bottomLeft.\n if (((topRight.x - topLeft.x) * (bottomLeft.y - topLeft.y)) - ((topRight.y - topLeft.y) * (bottomLeft.x - topLeft.x)) < 0) {\n [bottomLeft, topRight] = [topRight, bottomLeft];\n }\n\n return { bottomLeft, topLeft, topRight };\n}\n\n// Computes the dimension (number of modules on a side) of the QR Code based on the position of the finder patterns\nfunction computeDimension(topLeft: Point, topRight: Point, bottomLeft: Point, matrix: BitMatrix) {\n const moduleSize = (\n sum(countBlackWhiteRun(topLeft, bottomLeft, matrix, 5)) / 7 + // Divide by 7 since the ratio is 1:1:3:1:1\n sum(countBlackWhiteRun(topLeft, topRight, matrix, 5)) / 7 +\n sum(countBlackWhiteRun(bottomLeft, topLeft, matrix, 5)) / 7 +\n sum(countBlackWhiteRun(topRight, topLeft, matrix, 5)) / 7\n ) / 4;\n\n if (moduleSize < 1) {\n throw new Error(\"Invalid module size\");\n }\n\n const topDimension = Math.round(distance(topLeft, topRight) / moduleSize);\n const sideDimension = Math.round(distance(topLeft, bottomLeft) / moduleSize);\n let dimension = Math.floor((topDimension + sideDimension) / 2) + 7;\n switch (dimension % 4) {\n case 0:\n dimension++;\n break;\n case 2:\n dimension--;\n break;\n }\n return { dimension, moduleSize };\n}\n\n// Takes an origin point and an end point and counts the sizes of the black white run from the origin towards the end point.\n// Returns an array of elements, representing the pixel size of the black white run.\n// Uses a variant of http://en.wikipedia.org/wiki/Bresenham's_line_algorithm\nfunction countBlackWhiteRunTowardsPoint(origin: Point, end: Point, matrix: BitMatrix, length: number) {\n const switchPoints: Point[] = [{x: Math.floor(origin.x), y: Math.floor(origin.y)}];\n const steep = Math.abs(end.y - origin.y) > Math.abs(end.x - origin.x);\n\n let fromX: number;\n let fromY: number;\n let toX: number;\n let toY: number;\n if (steep) {\n fromX = Math.floor(origin.y);\n fromY = Math.floor(origin.x);\n toX = Math.floor(end.y);\n toY = Math.floor(end.x);\n } else {\n fromX = Math.floor(origin.x);\n fromY = Math.floor(origin.y);\n toX = Math.floor(end.x);\n toY = Math.floor(end.y);\n }\n\n const dx = Math.abs(toX - fromX);\n const dy = Math.abs(toY - fromY);\n let error = Math.floor(-dx / 2);\n const xStep = fromX < toX ? 1 : -1;\n const yStep = fromY < toY ? 1 : -1;\n\n let currentPixel = true;\n // Loop up until x == toX, but not beyond\n for (let x = fromX, y = fromY; x !== toX + xStep; x += xStep) {\n // Does current pixel mean we have moved white to black or vice versa?\n // Scanning black in state 0,2 and white in state 1, so if we find the wrong\n // color, advance to next state or end if we are in state 2 already\n const realX = steep ? y : x;\n const realY = steep ? x : y;\n if (matrix.get(realX, realY) !== currentPixel) {\n currentPixel = !currentPixel;\n switchPoints.push({x: realX, y: realY});\n if (switchPoints.length === length + 1) {\n break;\n }\n }\n error += dy;\n if (error > 0) {\n if (y === toY) {\n break;\n }\n y += yStep;\n error -= dx;\n }\n }\n const distances: number[] = [];\n for (let i = 0; i < length; i++) {\n if (switchPoints[i] && switchPoints[i + 1]) {\n distances.push(distance(switchPoints[i], switchPoints[i + 1]));\n } else {\n distances.push(0);\n }\n }\n return distances;\n}\n\n// Takes an origin point and an end point and counts the sizes of the black white run in the origin point\n// along the line that intersects with the end point. Returns an array of elements, representing the pixel sizes\n// of the black white run. Takes a length which represents the number of switches from black to white to look for.\nfunction countBlackWhiteRun(origin: Point, end: Point, matrix: BitMatrix, length: number) {\n const rise = end.y - origin.y;\n const run = end.x - origin.x;\n\n const towardsEnd = countBlackWhiteRunTowardsPoint(origin, end, matrix, Math.ceil(length / 2));\n const awayFromEnd = countBlackWhiteRunTowardsPoint(origin, {x: origin.x - run, y: origin.y - rise}, matrix, Math.ceil(length / 2));\n\n const middleValue = towardsEnd.shift() + awayFromEnd.shift() - 1; // Substract one so we don't double count a pixel\n return awayFromEnd.concat(middleValue).concat(...towardsEnd);\n}\n\n// Takes in a black white run and an array of expected ratios. Returns the average size of the run as well as the \"error\" -\n// that is the amount the run diverges from the expected ratio\nfunction scoreBlackWhiteRun(sequence: number[], ratios: number[]) {\n const averageSize = sum(sequence) / sum(ratios);\n let error = 0;\n ratios.forEach((ratio, i) => {\n error += (sequence[i] - ratio * averageSize) ** 2;\n });\n\n return { averageSize, error };\n}\n\n// Takes an X,Y point and an array of sizes and scores the point against those ratios.\n// For example for a finder pattern takes the ratio list of 1:1:3:1:1 and checks horizontal, vertical and diagonal ratios\n// against that.\nfunction scorePattern(point: Point, ratios: number[], matrix: BitMatrix) {\n try {\n const horizontalRun = countBlackWhiteRun(point, {x: -1, y: point.y}, matrix, ratios.length);\n const verticalRun = countBlackWhiteRun(point, {x: point.x, y: -1}, matrix, ratios.length);\n\n const topLeftPoint = {\n x: Math.max(0, point.x - point.y) - 1,\n y: Math.max(0, point.y - point.x) - 1,\n };\n const topLeftBottomRightRun = countBlackWhiteRun(point, topLeftPoint, matrix, ratios.length);\n\n const bottomLeftPoint = {\n x: Math.min(matrix.width, point.x + point.y) + 1,\n y: Math.min(matrix.height, point.y + point.x) + 1,\n };\n const bottomLeftTopRightRun = countBlackWhiteRun(point, bottomLeftPoint, matrix, ratios.length);\n\n const horzError = scoreBlackWhiteRun(horizontalRun, ratios);\n const vertError = scoreBlackWhiteRun(verticalRun, ratios);\n const diagDownError = scoreBlackWhiteRun(topLeftBottomRightRun, ratios);\n const diagUpError = scoreBlackWhiteRun(bottomLeftTopRightRun, ratios);\n\n const ratioError = Math.sqrt(horzError.error * horzError.error +\n vertError.error * vertError.error +\n diagDownError.error * diagDownError.error +\n diagUpError.error * diagUpError.error);\n\n const avgSize = (horzError.averageSize + vertError.averageSize + diagDownError.averageSize + diagUpError.averageSize) / 4;\n\n const sizeError = ((horzError.averageSize - avgSize) ** 2 +\n (vertError.averageSize - avgSize) ** 2 +\n (diagDownError.averageSize - avgSize) ** 2 +\n (diagUpError.averageSize - avgSize) ** 2) / avgSize;\n return ratioError + sizeError;\n } catch {\n return Infinity;\n }\n}\n\nfunction recenterLocation(matrix: BitMatrix, p: Point): Point {\n let leftX = Math.round(p.x);\n while (matrix.get(leftX, Math.round(p.y))) {\n leftX--;\n }\n let rightX = Math.round(p.x);\n while (matrix.get(rightX, Math.round(p.y))) {\n rightX++;\n }\n const x = (leftX + rightX) / 2;\n\n let topY = Math.round(p.y);\n while (matrix.get(Math.round(x), topY)) {\n topY--;\n }\n let bottomY = Math.round(p.y);\n while (matrix.get(Math.round(x), bottomY)) {\n bottomY++;\n }\n const y = (topY + bottomY) / 2;\n\n return { x, y };\n}\n\ninterface Quad {\n top: {\n startX: number;\n endX: number;\n y: number;\n };\n bottom: {\n startX: number;\n endX: number;\n y: number;\n };\n}\n\nexport function locate(matrix: BitMatrix): QRLocation[] {\n const finderPatternQuads: Quad[] = [];\n let activeFinderPatternQuads: Quad[] = [];\n const alignmentPatternQuads: Quad[] = [];\n let activeAlignmentPatternQuads: Quad[] = [];\n\n for (let y = 0; y <= matrix.height; y++) {\n let length = 0;\n let lastBit = false;\n let scans = [0, 0, 0, 0, 0];\n\n for (let x = -1; x <= matrix.width; x++) {\n const v = matrix.get(x, y);\n if (v === lastBit) {\n length++;\n } else {\n scans = [scans[1], scans[2], scans[3], scans[4], length];\n length = 1;\n lastBit = v;\n\n // Do the last 5 color changes ~ match the expected ratio for a finder pattern? 1:1:3:1:1 of b:w:b:w:b\n const averageFinderPatternBlocksize = sum(scans) / 7;\n const validFinderPattern =\n Math.abs(scans[0] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&\n Math.abs(scans[1] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&\n Math.abs(scans[2] - 3 * averageFinderPatternBlocksize) < 3 * averageFinderPatternBlocksize &&\n Math.abs(scans[3] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&\n Math.abs(scans[4] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize &&\n !v; // And make sure the current pixel is white since finder patterns are bordered in white\n\n // Do the last 3 color changes ~ match the expected ratio for an alignment pattern? 1:1:1 of w:b:w\n const averageAlignmentPatternBlocksize = sum(scans.slice(-3)) / 3;\n const validAlignmentPattern =\n Math.abs(scans[2] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&\n Math.abs(scans[3] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&\n Math.abs(scans[4] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize &&\n v; // Is the current pixel black since alignment patterns are bordered in black\n\n if (validFinderPattern) {\n // Compute the start and end x values of the large center black square\n const endX = x - scans[3] - scans[4];\n const startX = endX - scans[2];\n\n const line = { startX, endX, y };\n // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with\n // that line as the starting point.\n const matchingQuads = activeFinderPatternQuads.filter(q =>\n (startX >= q.bottom.startX && startX <= q.bottom.endX) ||\n (endX >= q.bottom.startX && startX <= q.bottom.endX) ||\n (startX <= q.bottom.startX && endX >= q.bottom.endX && (\n (scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO &&\n (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO\n )),\n );\n if (matchingQuads.length > 0) {\n matchingQuads[0].bottom = line;\n } else {\n activeFinderPatternQuads.push({ top: line, bottom: line });\n }\n }\n if (validAlignmentPattern) {\n // Compute the start and end x values of the center black square\n const endX = x - scans[4];\n const startX = endX - scans[3];\n\n const line = { startX, y, endX };\n // Is there a quad directly above the current spot? If so, extend it with the new line. Otherwise, create a new quad with\n // that line as the starting point.\n const matchingQuads = activeAlignmentPatternQuads.filter(q =>\n (startX >= q.bottom.startX && startX <= q.bottom.endX) ||\n (endX >= q.bottom.startX && startX <= q.bottom.endX) ||\n (startX <= q.bottom.startX && endX >= q.bottom.endX && (\n (scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO &&\n (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO\n )),\n );\n if (matchingQuads.length > 0) {\n matchingQuads[0].bottom = line;\n } else {\n activeAlignmentPatternQuads.push({ top: line, bottom: line });\n }\n }\n }\n }\n finderPatternQuads.push(...activeFinderPatternQuads.filter(q => q.bottom.y !== y && q.bottom.y - q.top.y >= 2));\n activeFinderPatternQuads = activeFinderPatternQuads.filter(q => q.bottom.y === y);\n\n alignmentPatternQuads.push(...activeAlignmentPatternQuads.filter(q => q.bottom.y !== y));\n activeAlignmentPatternQuads = activeAlignmentPatternQuads.filter(q => q.bottom.y === y);\n\n }\n\n finderPatternQuads.push(...activeFinderPatternQuads.filter(q => q.bottom.y - q.top.y >= 2));\n alignmentPatternQuads.push(...activeAlignmentPatternQuads);\n\n // Refactored from cozmo/jsQR to (hopefully) circumvent an issue in Safari 13+ on both Mac and iOS (also including\n // iOS Chrome and other Safari iOS derivatives). Safari was very occasionally and apparently not deterministically\n // throwing a \"RangeError: Array size is not a small enough positive integer.\" exception seemingly within the second\n // .map of the original code (here the second for-loop). This second .map contained a nested .map call over the same\n // array instance which was the chained result from previous calls to .map, .filter and .sort which potentially caused\n // this bug in Safari?\n // Also see https://github.com/cozmo/jsQR/issues/157 and https://bugs.webkit.org/show_bug.cgi?id=211619#c3\n const scoredFinderPatternPositions: Array = [];\n for (const quad of finderPatternQuads) {\n if (quad.bottom.y - quad.top.y < 2) {\n // All quads must be at least 2px tall since the center square is larger than a block\n continue;\n }\n\n // calculate quad center\n const x = (quad.top.startX + quad.top.endX + quad.bottom.startX + quad.bottom.endX) / 4;\n const y = (quad.top.y + quad.bottom.y + 1) / 2;\n if (!matrix.get(Math.round(x), Math.round(y))) {\n continue;\n }\n\n const lengths = [quad.top.endX - quad.top.startX, quad.bottom.endX - quad.bottom.startX, quad.bottom.y - quad.top.y + 1];\n const size = sum(lengths) / lengths.length;\n // Initial scoring of finder pattern quads by looking at their ratios, not taking into account position\n const score = scorePattern({x: Math.round(x), y: Math.round(y)}, [1, 1, 3, 1, 1], matrix);\n scoredFinderPatternPositions.push({ score, x, y, size });\n }\n if (scoredFinderPatternPositions.length < 3) {\n // A QR code has 3 finder patterns, therefore we need at least 3 candidates.\n return null;\n }\n scoredFinderPatternPositions.sort((a, b) => a.score - b.score);\n\n // Now take the top finder pattern options and try to find 2 other options with a similar size.\n const finderPatternGroups: Array<{ points: [Point, Point, Point], score: number }> = [];\n for (let i = 0; i < Math.min(scoredFinderPatternPositions.length, MAX_FINDERPATTERNS_TO_SEARCH); ++i) {\n const point = scoredFinderPatternPositions[i];\n const otherPoints: typeof scoredFinderPatternPositions = [];\n\n for (const otherPoint of scoredFinderPatternPositions) {\n if (otherPoint === point) {\n continue;\n }\n otherPoints.push({\n ...otherPoint,\n score: otherPoint.score + ((otherPoint.size - point.size) ** 2) / point.size, // score similarity of sizes\n });\n }\n otherPoints.sort((a, b) => a.score - b.score);\n\n finderPatternGroups.push({\n points: [point, otherPoints[0], otherPoints[1]], // note that otherPoints.length >= 2 as scoredFinderPatternPositions.length >= 3\n score: point.score + otherPoints[0].score + otherPoints[1].score, // total combined score of the three points in the group\n });\n }\n finderPatternGroups.sort((a, b) => a.score - b.score);\n const bestFinderPatternGroup = finderPatternGroups[0];\n\n const { topRight, topLeft, bottomLeft } = reorderFinderPatterns(...bestFinderPatternGroup.points);\n const alignment = findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft);\n const result: QRLocation[] = [];\n if (alignment) {\n result.push({\n alignmentPattern: { x: alignment.alignmentPattern.x, y: alignment.alignmentPattern.y },\n bottomLeft: {x: bottomLeft.x, y: bottomLeft.y },\n dimension: alignment.dimension,\n topLeft: {x: topLeft.x, y: topLeft.y },\n topRight: {x: topRight.x, y: topRight.y },\n });\n }\n\n // We normally use the center of the quads as the location of the tracking points, which is optimal for most cases and will account\n // for a skew in the image. However, In some cases, a slight skew might not be real and instead be caused by image compression\n // errors and/or low resolution. For those cases, we'd be better off centering the point exactly in the middle of the black area. We\n // compute and return the location data for the naively centered points as it is little additional work and allows for multiple\n // attempts at decoding harder images.\n const midTopRight = recenterLocation(matrix, topRight);\n const midTopLeft = recenterLocation(matrix, topLeft);\n const midBottomLeft = recenterLocation(matrix, bottomLeft);\n const centeredAlignment = findAlignmentPattern(matrix, alignmentPatternQuads, midTopRight, midTopLeft, midBottomLeft);\n if (centeredAlignment) {\n result.push({\n alignmentPattern: { x: centeredAlignment.alignmentPattern.x, y: centeredAlignment.alignmentPattern.y },\n bottomLeft: { x: midBottomLeft.x, y: midBottomLeft. y },\n topLeft: { x: midTopLeft.x, y: midTopLeft. y },\n topRight: { x: midTopRight.x, y: midTopRight. y },\n dimension: centeredAlignment.dimension,\n });\n }\n\n if (result.length === 0) {\n return null;\n }\n\n return result;\n}\n\nfunction findAlignmentPattern(matrix: BitMatrix, alignmentPatternQuads: Quad[], topRight: Point, topLeft: Point, bottomLeft: Point) {\n // Now that we've found the three finder patterns we can determine the blockSize and the size of the QR code.\n // We'll use these to help find the alignment pattern but also later when we do the extraction.\n let dimension: number;\n let moduleSize: number;\n try {\n ({ dimension, moduleSize } = computeDimension(topLeft, topRight, bottomLeft, matrix));\n } catch (e) {\n return null;\n }\n\n // Now find the alignment pattern\n const bottomRightFinderPattern = { // Best guess at where a bottomRight finder pattern would be\n x: topRight.x - topLeft.x + bottomLeft.x,\n y: topRight.y - topLeft.y + bottomLeft.y,\n };\n const modulesBetweenFinderPatterns = ((distance(topLeft, bottomLeft) + distance(topLeft, topRight)) / 2 / moduleSize);\n const correctionToTopLeft = 1 - (3 / modulesBetweenFinderPatterns);\n const expectedAlignmentPattern = {\n x: topLeft.x + correctionToTopLeft * (bottomRightFinderPattern.x - topLeft.x),\n y: topLeft.y + correctionToTopLeft * (bottomRightFinderPattern.y - topLeft.y),\n };\n\n const alignmentPatterns = alignmentPatternQuads\n .map(q => {\n const x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4;\n const y = (q.top.y + q.bottom.y + 1) / 2;\n if (!matrix.get(Math.floor(x), Math.floor(y))) {\n return;\n }\n\n const sizeScore = scorePattern({x: Math.floor(x), y: Math.floor(y)}, [1, 1, 1], matrix);\n const score = sizeScore + distance({x, y}, expectedAlignmentPattern);\n return { x, y, score };\n })\n .filter(v => !!v)\n .sort((a, b) => a.score - b.score);\n\n // If there are less than 15 modules between finder patterns it's a version 1 QR code and as such has no alignmemnt pattern\n // so we can only use our best guess.\n const alignmentPattern = modulesBetweenFinderPatterns >= 15 && alignmentPatterns.length ? alignmentPatterns[0] : expectedAlignmentPattern;\n\n return { alignmentPattern, dimension };\n}\n","import {binarize} from \"./binarizer\";\nimport {BitMatrix} from \"./BitMatrix\";\nimport {Chunks} from \"./decoder/decodeData\";\nimport {decode} from \"./decoder/decoder\";\nimport { Version } from \"./decoder/version\";\nimport {extract} from \"./extractor\";\nimport {locate, Point} from \"./locator\";\n\nexport interface QRCode {\n binaryData: number[];\n data: string;\n chunks: Chunks;\n version: number;\n location: {\n topRightCorner: Point;\n topLeftCorner: Point;\n bottomRightCorner: Point;\n bottomLeftCorner: Point;\n\n topRightFinderPattern: Point;\n topLeftFinderPattern: Point;\n bottomLeftFinderPattern: Point;\n\n bottomRightAlignmentPattern?: Point;\n };\n matrix: BitMatrix;\n}\n\nfunction scan(matrix: BitMatrix): QRCode | null {\n const locations = locate(matrix);\n if (!locations) {\n return null;\n }\n\n for (const location of locations) {\n const extracted = extract(matrix, location);\n const decoded = decode(extracted.matrix);\n if (decoded) {\n return {\n binaryData: decoded.bytes,\n data: decoded.text,\n chunks: decoded.chunks,\n version: decoded.version,\n location: {\n topRightCorner: extracted.mappingFunction(location.dimension, 0),\n topLeftCorner: extracted.mappingFunction(0, 0),\n bottomRightCorner: extracted.mappingFunction(location.dimension, location.dimension),\n bottomLeftCorner: extracted.mappingFunction(0, location.dimension),\n\n topRightFinderPattern: location.topRight,\n topLeftFinderPattern: location.topLeft,\n bottomLeftFinderPattern: location.bottomLeft,\n\n bottomRightAlignmentPattern: location.alignmentPattern,\n },\n matrix: extracted.matrix,\n };\n }\n }\n return null;\n}\n\nexport interface Options {\n inversionAttempts?: \"dontInvert\" | \"onlyInvert\" | \"attemptBoth\" | \"invertFirst\";\n greyScaleWeights?: GreyscaleWeights;\n canOverwriteImage?: boolean;\n}\n\nexport interface GreyscaleWeights {\n red: number;\n green: number;\n blue: number;\n useIntegerApproximation?: boolean;\n}\n\nconst defaultOptions: Options = {\n inversionAttempts: \"attemptBoth\",\n greyScaleWeights: {\n red: 0.2126,\n green: 0.7152,\n blue: 0.0722,\n useIntegerApproximation: false,\n },\n canOverwriteImage: true,\n};\n\nfunction mergeObject(target: any, src: any) {\n Object.keys(src).forEach(opt => { // Sad implementation of Object.assign since we target es5 not es6\n target[opt] = src[opt];\n });\n}\n\nfunction jsQR(data: Uint8ClampedArray, width: number, height: number, providedOptions: Options = {}): QRCode | null {\n const options = Object.create(null);\n mergeObject(options, defaultOptions);\n mergeObject(options, providedOptions);\n\n const tryInvertedFirst = options.inversionAttempts === \"onlyInvert\" || options.inversionAttempts === \"invertFirst\";\n const shouldInvert = options.inversionAttempts === \"attemptBoth\" || tryInvertedFirst;\n const {binarized, inverted} = binarize(data, width, height, shouldInvert, options.greyScaleWeights,\n options.canOverwriteImage);\n let result = scan(tryInvertedFirst ? inverted : binarized);\n if (!result && (options.inversionAttempts === \"attemptBoth\" || options.inversionAttempts === \"invertFirst\")) {\n result = scan(tryInvertedFirst ? binarized : inverted);\n }\n return result;\n}\n\n(jsQR as any).default = jsQR;\nexport default jsQR;\n","import {BitMatrix} from \"../BitMatrix\";\nimport {GreyscaleWeights} from \"../index\";\n\nconst REGION_SIZE = 8;\nconst MIN_DYNAMIC_RANGE = 24;\n\nfunction numBetween(value: number, min: number, max: number): number {\n return value < min ? min : value > max ? max : value;\n}\n\n// Like BitMatrix but accepts arbitry Uint8 values\nclass Matrix {\n private data: Uint8ClampedArray;\n private width: number;\n constructor(width: number, height: number, buffer?: Uint8ClampedArray) {\n this.width = width;\n const bufferSize = width * height;\n if (buffer && buffer.length !== bufferSize) {\n throw new Error(\"Wrong buffer size\");\n }\n this.data = buffer || new Uint8ClampedArray(bufferSize);\n }\n public get(x: number, y: number) {\n return this.data[y * this.width + x];\n }\n public set(x: number, y: number, value: number) {\n this.data[y * this.width + x] = value;\n }\n}\n\nexport function binarize(data: Uint8ClampedArray, width: number, height: number, returnInverted: boolean,\n greyscaleWeights: GreyscaleWeights, canOverwriteImage: boolean) {\n const pixelCount = width * height;\n if (data.length !== pixelCount * 4) {\n throw new Error(\"Malformed data passed to binarizer.\");\n }\n // assign the greyscale and binary image within the rgba buffer as the rgba image will not be needed after conversion\n let bufferOffset = 0;\n // Convert image to greyscale\n let greyscaleBuffer: Uint8ClampedArray;\n if (canOverwriteImage) {\n greyscaleBuffer = new Uint8ClampedArray(data.buffer, bufferOffset, pixelCount);\n bufferOffset += pixelCount;\n }\n const greyscalePixels = new Matrix(width, height, greyscaleBuffer);\n if (greyscaleWeights.useIntegerApproximation) {\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const pixelPosition = (y * width + x) * 4;\n const r = data[pixelPosition];\n const g = data[pixelPosition + 1];\n const b = data[pixelPosition + 2];\n greyscalePixels.set(x, y,\n // tslint:disable-next-line no-bitwise\n (greyscaleWeights.red * r + greyscaleWeights.green * g + greyscaleWeights.blue * b + 128) >> 8);\n }\n }\n } else {\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const pixelPosition = (y * width + x) * 4;\n const r = data[pixelPosition];\n const g = data[pixelPosition + 1];\n const b = data[pixelPosition + 2];\n greyscalePixels.set(x, y,\n greyscaleWeights.red * r + greyscaleWeights.green * g + greyscaleWeights.blue * b);\n }\n }\n }\n const horizontalRegionCount = Math.ceil(width / REGION_SIZE);\n const verticalRegionCount = Math.ceil(height / REGION_SIZE);\n const blackPointsCount = horizontalRegionCount * verticalRegionCount;\n\n let blackPointsBuffer: Uint8ClampedArray;\n if (canOverwriteImage) {\n blackPointsBuffer = new Uint8ClampedArray(data.buffer, bufferOffset, blackPointsCount);\n bufferOffset += blackPointsCount;\n }\n const blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount, blackPointsBuffer);\n for (let verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {\n for (let hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {\n let min = Infinity;\n let max = 0;\n for (let y = 0; y < REGION_SIZE; y++) {\n for (let x = 0; x < REGION_SIZE; x++) {\n const pixelLumosity =\n greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y);\n min = Math.min(min, pixelLumosity);\n max = Math.max(max, pixelLumosity);\n }\n }\n // We could also compute the real average of all pixels but following the assumption that the qr code consists\n // of bright and dark pixels and essentially not much in between, by (min + max)/2 we make the cut really between\n // those two classes. If using the average over all pixel in a block of mostly bright pixels and few dark pixels,\n // the avg would tend to the bright side and darker bright pixels could be interpreted as dark.\n let average = (min + max) / 2;\n // Small bias towards black by moving the threshold up. We do this, as in the finder patterns white holes tend\n // to appear which makes them undetectable.\n const blackBias = 1.11;\n average = Math.min(255, average * blackBias);\n if (max - min <= MIN_DYNAMIC_RANGE) {\n // If variation within the block is low, assume this is a block with only light or only\n // dark pixels. In that case we do not want to use the average, as it would divide this\n // low contrast area into black and white pixels, essentially creating data out of noise.\n //\n // Default the blackpoint for these blocks to be half the min - effectively white them out\n average = min / 2;\n\n if (verticalRegion > 0 && hortizontalRegion > 0) {\n // Correct the \"white background\" assumption for blocks that have neighbors by comparing\n // the pixels in this block to the previously calculated black points. This is based on\n // the fact that dark barcode symbology is always surrounded by some amount of light\n // background for which reasonable black point estimates were made. The bp estimated at\n // the boundaries is used for the interior.\n\n // The (min < bp) is arbitrary but works better than other heuristics that were tried.\n const averageNeighborBlackPoint = (\n blackPoints.get(hortizontalRegion, verticalRegion - 1) +\n (2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) +\n blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)\n ) / 4;\n if (min < averageNeighborBlackPoint) {\n average = averageNeighborBlackPoint; // no need to apply black bias as already applied to neighbors\n }\n }\n }\n blackPoints.set(hortizontalRegion, verticalRegion, average);\n }\n }\n\n let binarized: BitMatrix;\n if (canOverwriteImage) {\n const binarizedBuffer = new Uint8ClampedArray(data.buffer, bufferOffset, pixelCount);\n bufferOffset += pixelCount;\n binarized = new BitMatrix(binarizedBuffer, width);\n } else {\n binarized = BitMatrix.createEmpty(width, height);\n }\n\n let inverted: BitMatrix = null;\n if (returnInverted) {\n if (canOverwriteImage) {\n const invertedBuffer = new Uint8ClampedArray(data.buffer, bufferOffset, pixelCount);\n inverted = new BitMatrix(invertedBuffer, width);\n } else {\n inverted = BitMatrix.createEmpty(width, height);\n }\n }\n\n for (let verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {\n for (let hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {\n const left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3);\n const top = numBetween(verticalRegion, 2, verticalRegionCount - 3);\n let sum = 0;\n for (let xRegion = -2; xRegion <= 2; xRegion++) {\n for (let yRegion = -2; yRegion <= 2; yRegion++) {\n sum += blackPoints.get(left + xRegion, top + yRegion);\n }\n }\n const threshold = sum / 25;\n for (let xRegion = 0; xRegion < REGION_SIZE; xRegion++) {\n for (let yRegion = 0; yRegion < REGION_SIZE; yRegion++) {\n const x = hortizontalRegion * REGION_SIZE + xRegion;\n const y = verticalRegion * REGION_SIZE + yRegion;\n const lum = greyscalePixels.get(x, y);\n binarized.set(x, y, lum <= threshold);\n if (returnInverted) {\n inverted.set(x, y, !(lum <= threshold));\n }\n }\n }\n }\n }\n if (returnInverted) {\n return { binarized, inverted };\n }\n return { binarized };\n}\n","export class BitMatrix {\n public static createEmpty(width: number, height: number) {\n return new BitMatrix(new Uint8ClampedArray(width * height), width);\n }\n\n public width: number;\n public height: number;\n private data: Uint8ClampedArray;\n\n constructor(data: Uint8ClampedArray, width: number) {\n this.width = width;\n this.height = data.length / width;\n this.data = data;\n }\n\n public get(x: number, y: number): boolean {\n if (x < 0 || x >= this.width || y < 0 || y >= this.height) {\n return false;\n }\n return !!this.data[y * this.width + x];\n }\n\n public set(x: number, y: number, v: boolean) {\n this.data[y * this.width + x] = v ? 1 : 0;\n }\n\n public setRegion(left: number, top: number, width: number, height: number, v: boolean) {\n for (let y = top; y < top + height; y++) {\n for (let x = left; x < left + width; x++) {\n this.set(x, y, !!v);\n }\n }\n }\n}\n","// tslint:disable:no-bitwise\n\nexport class BitStream {\n private bytes: Uint8ClampedArray;\n private byteOffset: number = 0;\n private bitOffset: number = 0;\n\n constructor(bytes: Uint8ClampedArray) {\n this.bytes = bytes;\n }\n\n public readBits(numBits: number): number {\n if (numBits < 1 || numBits > 32 || numBits > this.available()) {\n throw new Error(\"Cannot read \" + numBits.toString() + \" bits\");\n }\n\n let result = 0;\n // First, read remainder from current byte\n if (this.bitOffset > 0) {\n const bitsLeft = 8 - this.bitOffset;\n const toRead = numBits < bitsLeft ? numBits : bitsLeft;\n const bitsToNotRead = bitsLeft - toRead;\n const mask = (0xFF >> (8 - toRead)) << bitsToNotRead;\n result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead;\n numBits -= toRead;\n this.bitOffset += toRead;\n if (this.bitOffset === 8) {\n this.bitOffset = 0;\n this.byteOffset++;\n }\n }\n\n // Next read whole bytes\n if (numBits > 0) {\n while (numBits >= 8) {\n result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF);\n this.byteOffset++;\n numBits -= 8;\n }\n\n // Finally read a partial byte\n if (numBits > 0) {\n const bitsToNotRead = 8 - numBits;\n const mask = (0xFF >> bitsToNotRead) << bitsToNotRead;\n result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead);\n this.bitOffset += numBits;\n }\n }\n return result;\n }\n\n public available(): number {\n return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset;\n }\n}\n","import GenericGF, { addOrSubtractGF } from \"./GenericGF\";\n\nexport default class GenericGFPoly {\n private field: GenericGF;\n private coefficients: Uint8ClampedArray;\n\n constructor(field: GenericGF, coefficients: Uint8ClampedArray) {\n if (coefficients.length === 0) {\n throw new Error(\"No coefficients.\");\n }\n this.field = field;\n const coefficientsLength = coefficients.length;\n if (coefficientsLength > 1 && coefficients[0] === 0) {\n // Leading term must be non-zero for anything except the constant polynomial \"0\"\n let firstNonZero = 1;\n while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {\n firstNonZero++;\n }\n if (firstNonZero === coefficientsLength) {\n this.coefficients = field.zero.coefficients;\n } else {\n this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero);\n for (let i = 0; i < this.coefficients.length; i++) {\n this.coefficients[i] = coefficients[firstNonZero + i];\n }\n }\n } else {\n this.coefficients = coefficients;\n }\n }\n\n public degree() {\n return this.coefficients.length - 1;\n }\n\n public isZero() {\n return this.coefficients[0] === 0;\n }\n\n public getCoefficient(degree: number) {\n return this.coefficients[this.coefficients.length - 1 - degree];\n }\n\n public addOrSubtract(other: GenericGFPoly) {\n if (this.isZero()) {\n return other;\n }\n if (other.isZero()) {\n return this;\n }\n\n let smallerCoefficients = this.coefficients;\n let largerCoefficients = other.coefficients;\n if (smallerCoefficients.length > largerCoefficients.length) {\n [smallerCoefficients, largerCoefficients] = [largerCoefficients, smallerCoefficients];\n }\n const sumDiff = new Uint8ClampedArray(largerCoefficients.length);\n const lengthDiff = largerCoefficients.length - smallerCoefficients.length;\n for (let i = 0; i < lengthDiff; i++) {\n sumDiff[i] = largerCoefficients[i];\n }\n\n for (let i = lengthDiff; i < largerCoefficients.length; i++) {\n sumDiff[i] = addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);\n }\n\n return new GenericGFPoly(this.field, sumDiff);\n }\n\n public multiply(scalar: number) {\n if (scalar === 0) {\n return this.field.zero;\n }\n if (scalar === 1) {\n return this;\n }\n const size = this.coefficients.length;\n const product = new Uint8ClampedArray(size);\n for (let i = 0; i < size; i++) {\n product[i] = this.field.multiply(this.coefficients[i], scalar);\n }\n\n return new GenericGFPoly(this.field, product);\n }\n\n public multiplyPoly(other: GenericGFPoly): GenericGFPoly {\n if (this.isZero() || other.isZero()) {\n return this.field.zero;\n }\n const aCoefficients = this.coefficients;\n const aLength = aCoefficients.length;\n const bCoefficients = other.coefficients;\n const bLength = bCoefficients.length;\n const product = new Uint8ClampedArray(aLength + bLength - 1);\n for (let i = 0; i < aLength; i++) {\n const aCoeff = aCoefficients[i];\n for (let j = 0; j < bLength; j++) {\n product[i + j] = addOrSubtractGF(product[i + j],\n this.field.multiply(aCoeff, bCoefficients[j]));\n }\n }\n return new GenericGFPoly(this.field, product);\n }\n\n public multiplyByMonomial(degree: number, coefficient: number) {\n if (degree < 0) {\n throw new Error(\"Invalid degree less than 0\");\n }\n if (coefficient === 0) {\n return this.field.zero;\n }\n const size = this.coefficients.length;\n const product = new Uint8ClampedArray(size + degree);\n for (let i = 0; i < size; i++) {\n product[i] = this.field.multiply(this.coefficients[i], coefficient);\n }\n return new GenericGFPoly(this.field, product);\n }\n\n public evaluateAt(a: number) {\n let result = 0;\n if (a === 0) {\n // Just return the x^0 coefficient\n return this.getCoefficient(0);\n }\n const size = this.coefficients.length;\n if (a === 1) {\n // Just the sum of the coefficients\n this.coefficients.forEach((coefficient) => {\n result = addOrSubtractGF(result, coefficient);\n });\n return result;\n }\n result = this.coefficients[0];\n for (let i = 1; i < size; i++) {\n result = addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]);\n }\n return result;\n }\n}\n","export interface Version {\n infoBits: number;\n versionNumber: number;\n alignmentPatternCenters: number[];\n errorCorrectionLevels: Array<{\n ecCodewordsPerBlock: number;\n ecBlocks: Array<{\n numBlocks: number;\n dataCodewordsPerBlock: number;\n }>\n }>;\n}\n\nexport const VERSIONS: Version[] = [\n {\n infoBits: null,\n versionNumber: 1,\n alignmentPatternCenters: [],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 7,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 19 }],\n },\n {\n ecCodewordsPerBlock: 10,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }],\n },\n {\n ecCodewordsPerBlock: 13,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 13 }],\n },\n {\n ecCodewordsPerBlock: 17,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 9 }],\n },\n ],\n },\n {\n infoBits: null,\n versionNumber: 2,\n alignmentPatternCenters: [6, 18],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 10,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 34 }],\n },\n {\n ecCodewordsPerBlock: 16,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 28 }],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 22 }],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }],\n },\n ],\n },\n {\n infoBits: null,\n versionNumber: 3,\n alignmentPatternCenters: [6, 22],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 15,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 55 }],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 44 }],\n },\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 17 }],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 13 }],\n },\n ],\n },\n {\n infoBits: null,\n versionNumber: 4,\n alignmentPatternCenters: [6, 26],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 20,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 80 }],\n },\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 32 }],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 24 }],\n },\n {\n ecCodewordsPerBlock: 16,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 9 }],\n },\n ],\n },\n {\n infoBits: null,\n versionNumber: 5,\n alignmentPatternCenters: [6, 30],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 108 }],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 43 }],\n },\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 15 },\n { numBlocks: 2, dataCodewordsPerBlock: 16 },\n ],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 11 },\n { numBlocks: 2, dataCodewordsPerBlock: 12 },\n ],\n },\n ],\n },\n {\n infoBits: null,\n versionNumber: 6,\n alignmentPatternCenters: [6, 34],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 68 }],\n },\n {\n ecCodewordsPerBlock: 16,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 27 }],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 19 }],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 15 }],\n },\n ],\n },\n {\n infoBits: 0x07C94,\n versionNumber: 7,\n alignmentPatternCenters: [6, 22, 38],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 20,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 78 }],\n },\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 31 }],\n },\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 14 },\n { numBlocks: 4, dataCodewordsPerBlock: 15 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 13 },\n { numBlocks: 1, dataCodewordsPerBlock: 14 },\n ],\n },\n ],\n },\n {\n infoBits: 0x085BC,\n versionNumber: 8,\n alignmentPatternCenters: [6, 24, 42],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 97 }],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 38 },\n { numBlocks: 2, dataCodewordsPerBlock: 39 },\n ],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 18 },\n { numBlocks: 2, dataCodewordsPerBlock: 19 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 14 },\n { numBlocks: 2, dataCodewordsPerBlock: 15 },\n ],\n },\n ],\n },\n {\n infoBits: 0x09A99,\n versionNumber: 9,\n alignmentPatternCenters: [6, 26, 46],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 116 }],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 36 },\n { numBlocks: 2, dataCodewordsPerBlock: 37 },\n ],\n },\n {\n ecCodewordsPerBlock: 20,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 16 },\n { numBlocks: 4, dataCodewordsPerBlock: 17 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 12 },\n { numBlocks: 4, dataCodewordsPerBlock: 13 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0A4D3,\n versionNumber: 10,\n alignmentPatternCenters: [6, 28, 50],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 18,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 68 },\n { numBlocks: 2, dataCodewordsPerBlock: 69 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 43 },\n { numBlocks: 1, dataCodewordsPerBlock: 44 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 19 },\n { numBlocks: 2, dataCodewordsPerBlock: 20 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 15 },\n { numBlocks: 2, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0BBF6,\n versionNumber: 11,\n alignmentPatternCenters: [6, 30, 54],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 20,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 81 }],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 1, dataCodewordsPerBlock: 50 },\n { numBlocks: 4, dataCodewordsPerBlock: 51 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 22 },\n { numBlocks: 4, dataCodewordsPerBlock: 23 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 12 },\n { numBlocks: 8, dataCodewordsPerBlock: 13 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0C762,\n versionNumber: 12,\n alignmentPatternCenters: [6, 32, 58],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 92 },\n { numBlocks: 2, dataCodewordsPerBlock: 93 },\n ],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 36 },\n { numBlocks: 2, dataCodewordsPerBlock: 37 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 20 },\n { numBlocks: 6, dataCodewordsPerBlock: 21 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 7, dataCodewordsPerBlock: 14 },\n { numBlocks: 4, dataCodewordsPerBlock: 15 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0D847,\n versionNumber: 13,\n alignmentPatternCenters: [6, 34, 62],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 107 }],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 37 },\n { numBlocks: 1, dataCodewordsPerBlock: 38 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 20 },\n { numBlocks: 4, dataCodewordsPerBlock: 21 },\n ],\n },\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 12, dataCodewordsPerBlock: 11 },\n { numBlocks: 4, dataCodewordsPerBlock: 12 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0E60D,\n versionNumber: 14,\n alignmentPatternCenters: [6, 26, 46, 66],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 115 },\n { numBlocks: 1, dataCodewordsPerBlock: 116 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 40 },\n { numBlocks: 5, dataCodewordsPerBlock: 41 },\n ],\n },\n {\n ecCodewordsPerBlock: 20,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 16 },\n { numBlocks: 5, dataCodewordsPerBlock: 17 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 12 },\n { numBlocks: 5, dataCodewordsPerBlock: 13 },\n ],\n },\n ],\n },\n {\n infoBits: 0x0F928,\n versionNumber: 15,\n alignmentPatternCenters: [6, 26, 48, 70],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 22,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 87 },\n { numBlocks: 1, dataCodewordsPerBlock: 88 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 41 },\n { numBlocks: 5, dataCodewordsPerBlock: 42 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 24 },\n { numBlocks: 7, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 12 },\n { numBlocks: 7, dataCodewordsPerBlock: 13 },\n ],\n },\n ],\n },\n {\n infoBits: 0x10B78,\n versionNumber: 16,\n alignmentPatternCenters: [6, 26, 50, 74],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 98 },\n { numBlocks: 1, dataCodewordsPerBlock: 99 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 7, dataCodewordsPerBlock: 45 },\n { numBlocks: 3, dataCodewordsPerBlock: 46 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [\n { numBlocks: 15, dataCodewordsPerBlock: 19 },\n { numBlocks: 2, dataCodewordsPerBlock: 20 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 15 },\n { numBlocks: 13, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1145D,\n versionNumber: 17,\n alignmentPatternCenters: [6, 30, 54, 78],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 1, dataCodewordsPerBlock: 107 },\n { numBlocks: 5, dataCodewordsPerBlock: 108 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 10, dataCodewordsPerBlock: 46 },\n { numBlocks: 1, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 1, dataCodewordsPerBlock: 22 },\n { numBlocks: 15, dataCodewordsPerBlock: 23 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 14 },\n { numBlocks: 17, dataCodewordsPerBlock: 15 },\n ],\n },\n ],\n },\n {\n infoBits: 0x12A17,\n versionNumber: 18,\n alignmentPatternCenters: [6, 30, 56, 82],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 120 },\n { numBlocks: 1, dataCodewordsPerBlock: 121 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 9, dataCodewordsPerBlock: 43 },\n { numBlocks: 4, dataCodewordsPerBlock: 44 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 17, dataCodewordsPerBlock: 22 },\n { numBlocks: 1, dataCodewordsPerBlock: 23 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 14 },\n { numBlocks: 19, dataCodewordsPerBlock: 15 },\n ],\n },\n ],\n },\n {\n infoBits: 0x13532,\n versionNumber: 19,\n alignmentPatternCenters: [6, 30, 58, 86],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 113 },\n { numBlocks: 4, dataCodewordsPerBlock: 114 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 44 },\n { numBlocks: 11, dataCodewordsPerBlock: 45 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 17, dataCodewordsPerBlock: 21 },\n { numBlocks: 4, dataCodewordsPerBlock: 22 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 9, dataCodewordsPerBlock: 13 },\n { numBlocks: 16, dataCodewordsPerBlock: 14 },\n ],\n },\n ],\n },\n {\n infoBits: 0x149A6,\n versionNumber: 20,\n alignmentPatternCenters: [6, 34, 62, 90],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 107 },\n { numBlocks: 5, dataCodewordsPerBlock: 108 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 41 },\n { numBlocks: 13, dataCodewordsPerBlock: 42 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 15, dataCodewordsPerBlock: 24 },\n { numBlocks: 5, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 15, dataCodewordsPerBlock: 15 },\n { numBlocks: 10, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x15683,\n versionNumber: 21,\n alignmentPatternCenters: [6, 28, 50, 72, 94],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 116 },\n { numBlocks: 4, dataCodewordsPerBlock: 117 },\n ],\n },\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 42 }],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 17, dataCodewordsPerBlock: 22 },\n { numBlocks: 6, dataCodewordsPerBlock: 23 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 16 },\n { numBlocks: 6, dataCodewordsPerBlock: 17 },\n ],\n },\n ],\n },\n {\n infoBits: 0x168C9,\n versionNumber: 22,\n alignmentPatternCenters: [6, 26, 50, 74, 98],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 111 },\n { numBlocks: 7, dataCodewordsPerBlock: 112 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 46 }],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 7, dataCodewordsPerBlock: 24 },\n { numBlocks: 16, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 24,\n ecBlocks: [{ numBlocks: 34, dataCodewordsPerBlock: 13 }],\n },\n ],\n },\n {\n infoBits: 0x177EC,\n versionNumber: 23,\n alignmentPatternCenters: [6, 30, 54, 74, 102],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 121 },\n { numBlocks: 5, dataCodewordsPerBlock: 122 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 47 },\n { numBlocks: 14, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 24 },\n { numBlocks: 14, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 16, dataCodewordsPerBlock: 15 },\n { numBlocks: 14, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x18EC4,\n versionNumber: 24,\n alignmentPatternCenters: [6, 28, 54, 80, 106],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 117 },\n { numBlocks: 4, dataCodewordsPerBlock: 118 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 45 },\n { numBlocks: 14, dataCodewordsPerBlock: 46 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 24 },\n { numBlocks: 16, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 30, dataCodewordsPerBlock: 16 },\n { numBlocks: 2, dataCodewordsPerBlock: 17 },\n ],\n },\n ],\n },\n {\n infoBits: 0x191E1,\n versionNumber: 25,\n alignmentPatternCenters: [6, 32, 58, 84, 110],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 26,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 106 },\n { numBlocks: 4, dataCodewordsPerBlock: 107 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 47 },\n { numBlocks: 13, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 7, dataCodewordsPerBlock: 24 },\n { numBlocks: 22, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 22, dataCodewordsPerBlock: 15 },\n { numBlocks: 13, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1AFAB,\n versionNumber: 26,\n alignmentPatternCenters: [6, 30, 58, 86, 114],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 10, dataCodewordsPerBlock: 114 },\n { numBlocks: 2, dataCodewordsPerBlock: 115 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 46 },\n { numBlocks: 4, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 28, dataCodewordsPerBlock: 22 },\n { numBlocks: 6, dataCodewordsPerBlock: 23 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 33, dataCodewordsPerBlock: 16 },\n { numBlocks: 4, dataCodewordsPerBlock: 17 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1B08E,\n versionNumber: 27,\n alignmentPatternCenters: [6, 34, 62, 90, 118],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 122 },\n { numBlocks: 4, dataCodewordsPerBlock: 123 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 22, dataCodewordsPerBlock: 45 },\n { numBlocks: 3, dataCodewordsPerBlock: 46 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 8, dataCodewordsPerBlock: 23 },\n { numBlocks: 26, dataCodewordsPerBlock: 24 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 12, dataCodewordsPerBlock: 15 },\n { numBlocks: 28, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1CC1A,\n versionNumber: 28,\n alignmentPatternCenters: [6, 26, 50, 74, 98, 122],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 117 },\n { numBlocks: 10, dataCodewordsPerBlock: 118 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 3, dataCodewordsPerBlock: 45 },\n { numBlocks: 23, dataCodewordsPerBlock: 46 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 24 },\n { numBlocks: 31, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 15 },\n { numBlocks: 31, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1D33F,\n versionNumber: 29,\n alignmentPatternCenters: [6, 30, 54, 78, 102, 126],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 7, dataCodewordsPerBlock: 116 },\n { numBlocks: 7, dataCodewordsPerBlock: 117 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 21, dataCodewordsPerBlock: 45 },\n { numBlocks: 7, dataCodewordsPerBlock: 46 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 1, dataCodewordsPerBlock: 23 },\n { numBlocks: 37, dataCodewordsPerBlock: 24 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 15 },\n { numBlocks: 26, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1ED75,\n versionNumber: 30,\n alignmentPatternCenters: [6, 26, 52, 78, 104, 130],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 5, dataCodewordsPerBlock: 115 },\n { numBlocks: 10, dataCodewordsPerBlock: 116 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 47 },\n { numBlocks: 10, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 15, dataCodewordsPerBlock: 24 },\n { numBlocks: 25, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 23, dataCodewordsPerBlock: 15 },\n { numBlocks: 25, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x1F250,\n versionNumber: 31,\n alignmentPatternCenters: [6, 30, 56, 82, 108, 134],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 13, dataCodewordsPerBlock: 115 },\n { numBlocks: 3, dataCodewordsPerBlock: 116 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 46 },\n { numBlocks: 29, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 42, dataCodewordsPerBlock: 24 },\n { numBlocks: 1, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 23, dataCodewordsPerBlock: 15 },\n { numBlocks: 28, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x209D5,\n versionNumber: 32,\n alignmentPatternCenters: [6, 34, 60, 86, 112, 138],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 115 }],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 10, dataCodewordsPerBlock: 46 },\n { numBlocks: 23, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 10, dataCodewordsPerBlock: 24 },\n { numBlocks: 35, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 15 },\n { numBlocks: 35, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x216F0,\n versionNumber: 33,\n alignmentPatternCenters: [6, 30, 58, 86, 114, 142],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 17, dataCodewordsPerBlock: 115 },\n { numBlocks: 1, dataCodewordsPerBlock: 116 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 14, dataCodewordsPerBlock: 46 },\n { numBlocks: 21, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 29, dataCodewordsPerBlock: 24 },\n { numBlocks: 19, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 11, dataCodewordsPerBlock: 15 },\n { numBlocks: 46, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x228BA,\n versionNumber: 34,\n alignmentPatternCenters: [6, 34, 62, 90, 118, 146],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 13, dataCodewordsPerBlock: 115 },\n { numBlocks: 6, dataCodewordsPerBlock: 116 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 14, dataCodewordsPerBlock: 46 },\n { numBlocks: 23, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 44, dataCodewordsPerBlock: 24 },\n { numBlocks: 7, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 59, dataCodewordsPerBlock: 16 },\n { numBlocks: 1, dataCodewordsPerBlock: 17 },\n ],\n },\n ],\n },\n {\n infoBits: 0x2379F,\n versionNumber: 35,\n alignmentPatternCenters: [6, 30, 54, 78, 102, 126, 150],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 12, dataCodewordsPerBlock: 121 },\n { numBlocks: 7, dataCodewordsPerBlock: 122 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 12, dataCodewordsPerBlock: 47 },\n { numBlocks: 26, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 39, dataCodewordsPerBlock: 24 },\n { numBlocks: 14, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 22, dataCodewordsPerBlock: 15 },\n { numBlocks: 41, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x24B0B,\n versionNumber: 36,\n alignmentPatternCenters: [ 6, 24, 50, 76, 102, 128, 154 ],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 121 },\n { numBlocks: 14, dataCodewordsPerBlock: 122 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 6, dataCodewordsPerBlock: 47 },\n { numBlocks: 34, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 46, dataCodewordsPerBlock: 24 },\n { numBlocks: 10, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 2, dataCodewordsPerBlock: 15 },\n { numBlocks: 64, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x2542E,\n versionNumber: 37,\n alignmentPatternCenters: [ 6, 28, 54, 80, 106, 132, 158 ],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 17, dataCodewordsPerBlock: 122 },\n { numBlocks: 4, dataCodewordsPerBlock: 123 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 29, dataCodewordsPerBlock: 46 },\n { numBlocks: 14, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 49, dataCodewordsPerBlock: 24 },\n { numBlocks: 10, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 24, dataCodewordsPerBlock: 15 },\n { numBlocks: 46, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x26A64,\n versionNumber: 38,\n alignmentPatternCenters: [ 6, 32, 58, 84, 110, 136, 162 ],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 4, dataCodewordsPerBlock: 122 },\n { numBlocks: 18, dataCodewordsPerBlock: 123 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 13, dataCodewordsPerBlock: 46 },\n { numBlocks: 32, dataCodewordsPerBlock: 47 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 48, dataCodewordsPerBlock: 24 },\n { numBlocks: 14, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 42, dataCodewordsPerBlock: 15 },\n { numBlocks: 32, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x27541,\n versionNumber: 39,\n alignmentPatternCenters: [ 6, 26, 54, 82, 110, 138, 166 ],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 20, dataCodewordsPerBlock: 117 },\n { numBlocks: 4, dataCodewordsPerBlock: 118 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 40, dataCodewordsPerBlock: 47 },\n { numBlocks: 7, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 43, dataCodewordsPerBlock: 24 },\n { numBlocks: 22, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 10, dataCodewordsPerBlock: 15 },\n { numBlocks: 67, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n {\n infoBits: 0x28C69,\n versionNumber: 40,\n alignmentPatternCenters: [ 6, 30, 58, 86, 114, 142, 170 ],\n errorCorrectionLevels: [\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 19, dataCodewordsPerBlock: 118 },\n { numBlocks: 6, dataCodewordsPerBlock: 119 },\n ],\n },\n {\n ecCodewordsPerBlock: 28,\n ecBlocks: [\n { numBlocks: 18, dataCodewordsPerBlock: 47 },\n { numBlocks: 31, dataCodewordsPerBlock: 48 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 34, dataCodewordsPerBlock: 24 },\n { numBlocks: 34, dataCodewordsPerBlock: 25 },\n ],\n },\n {\n ecCodewordsPerBlock: 30,\n ecBlocks: [\n { numBlocks: 20, dataCodewordsPerBlock: 15 },\n { numBlocks: 61, dataCodewordsPerBlock: 16 },\n ],\n },\n ],\n },\n];\n","import jsQR from '../node_modules/jsqr-es6/dist/jsQR.js';\n\nlet inversionAttempts = 'dontInvert';\nlet grayscaleWeights = {\n // weights for quick luma integer approximation (https://en.wikipedia.org/wiki/YUV#Full_swing_for_BT.601)\n red: 77,\n green: 150,\n blue: 29,\n useIntegerApproximation: true,\n};\n\nself.onmessage = event => {\n const type = event['data']['type'];\n const data = event['data']['data'];\n\n switch (type) {\n case 'decode':\n decode(data);\n break;\n case 'grayscaleWeights':\n setGrayscaleWeights(data);\n break;\n case 'inversionMode':\n setInversionMode(data);\n break;\n case 'close':\n // close after earlier messages in the event loop finished processing\n self.close();\n break;\n }\n};\n\nfunction decode(data) {\n const rgbaData = data['data'];\n const width = data['width'];\n const height = data['height'];\n const result = jsQR(rgbaData, width, height, {\n inversionAttempts: inversionAttempts,\n greyScaleWeights: grayscaleWeights,\n });\n self.postMessage({\n type: 'qrResult',\n data: result? result.data : null,\n });\n}\n\nfunction setGrayscaleWeights(data) {\n // update grayscaleWeights in a closure compiler compatible fashion\n grayscaleWeights.red = data['red'];\n grayscaleWeights.green = data['green'];\n grayscaleWeights.blue = data['blue'];\n grayscaleWeights.useIntegerApproximation = data['useIntegerApproximation'];\n}\n\nfunction setInversionMode(inversionMode) {\n switch (inversionMode) {\n case 'original':\n inversionAttempts = 'dontInvert';\n break;\n case 'invert':\n inversionAttempts = 'onlyInvert';\n break;\n case 'both':\n inversionAttempts = 'attemptBoth';\n break;\n default:\n throw new Error('Invalid inversion mode');\n }\n}\n"],"names":["decodeByte","stream","size","text","i","length","bytes","push","b","decodeURIComponent","map","substr","toString","join","decode","data","version","chunks","available","mode","ModeByte","Terminator","result","ECI","readBits","type","Mode","assignmentNumber","Numeric","num","Error","a","c","numericResult","Alphanumeric","AlphanumericCharacterCodes","charCodeAt","alphanumericResult","Byte","byteResult","Kanji","Math","floor","k","kanjiResult","StructuredAppend","currentSequence","totalSequence","parity","addOrSubtractGF","runEuclideanAlgorithm","field","R","degree","tLast","zero","t","one","r","rLast","isZero","rLastLast","q","dltInverse","addOrSubtract","buildMonomial","degreeDiff","scale","multiplyByMonomial","multiplyPoly","tLastLast","sigmaTildeAtZero","multiply","inverse","twoS","outputBytes","set","error","s","syndromeCoefficients","evaluation","syndrome","sigmaOmega","numErrors","errorLocator","getCoefficient","errorCount","evaluateAt","errorLocations","denominator","j","xiInverse","errorEvaluator","generatorBase","position","numBitsDiffering","x","y","z","bitCount","pushBit","bit","byte","readCodewords","matrix","formatInfo","dimension","setRegion","versionNumber","bitsRead","currentByte","readingUp","columnIndex","columnOffset","get","dataMask","codewords","readVersion","provisionalVersion","VERSIONS","topRightVersionBits","bottomLeftVersionBits","bestDifference","Infinity","bestVersion","infoBits","difference","readFormatInformation","topLeftFormatInfoBits","topRightBottomRightFormatInfoBits","bestFormatInfo","bits","getDataBlocks","ecLevel","totalCodewords","ecInfo","ecBlocks","forEach","block","numBlocks","dataBlocks","numDataCodewords","dataCodewordsPerBlock","ecCodewordsPerBlock","slice","shortBlockSize","dataBlock","shift","largeBlockCount","smallBlockCount","decodeMatrix","errorCorrectionLevel","resultIndex","correctedBytes","resultBytes","decodeData","squareToQuadrilateral","p1","p2","p3","p4","dx3","dy3","a11","a12","a13","a21","a22","a23","a31","a32","a33","quadrilateralToSquare","sToQ","extract","image","location","topRight","alignmentPattern","bottomLeft","qToS","sourcePixel","mappingFunction","sum","values","reduce","reorderFinderPatterns","pattern1","pattern2","pattern3","topLeft","twoThreeDistance","oneTwoDistance","oneThreeDistance","computeDimension","countBlackWhiteRun","moduleSize","topDimension","sideDimension","countBlackWhiteRunTowardsPoint","origin","end","steep","fromX","fromY","toX","toY","dx","currentPixel","xStep","realX","realY","switchPoints","dy","yStep","distances","distance","ceil","awayFromEnd","concat","middleValue","towardsEnd","scoreBlackWhiteRun","sequence","ratios","ratio","pow","averageSize","scorePattern","point","max","min","width","height","vertError","diagDownError","diagUpError","avgSize","recenterLocation","p","leftX","round","rightX","topY","bottomY","locate","activeFinderPatternQuads","activeAlignmentPatternQuads","lastBit","scans","v","abs","averageFinderPatternBlocksize","averageAlignmentPatternBlocksize","validFinderPattern","startX","endX","bottom","matchingQuads","line","top","validAlignmentPattern","finderPatternQuads","filter","alignmentPatternQuads","quad","scoredFinderPatternPositions","score","sort","otherPoint","otherPoints","finderPatternGroups","points","alignment","midTopRight","midTopLeft","midBottomLeft","centeredAlignment","findAlignmentPattern","e","correctionToTopLeft","sizeScore","expectedAlignmentPattern","scan","locations","decoded","binaryData","topRightCorner","extracted","topLeftCorner","bottomRightCorner","bottomLeftCorner","topRightFinderPattern","topLeftFinderPattern","bottomLeftFinderPattern","bottomRightAlignmentPattern","mergeObject","target","src","Object","keys","opt","jsQR","providedOptions","options","defaultOptions","shouldInvert","greyScaleWeights","canOverwriteImage","pixelCount","bufferOffset","greyscaleBuffer","Uint8ClampedArray","buffer","greyscaleWeights","useIntegerApproximation","greyscalePixels","red","green","blue","blackPointsBuffer","blackPointsCount","verticalRegionCount","verticalRegion","hortizontalRegion","horizontalRegionCount","pixelLumosity","average","blackPoints","averageNeighborBlackPoint","binarized","BitMatrix","binarizedBuffer","createEmpty","inverted","returnInverted","invertedBuffer","xRegion","yRegion","left","lum","threshold","tryInvertedFirst","inversionAttempts","Matrix","bufferSize","value","BitStream","bitOffset","byteOffset","numBits","bitsToNotRead","toRead","GenericGFPoly","coefficients","coefficientsLength","firstNonZero","other","smallerCoefficients","largerCoefficients","lengthDiff","sumDiff","scalar","product","aLength","bLength","aCoeff","bCoefficients","coefficient","GenericGF","primitive","genBase","expTable","Array","logTable","from","alignmentPatternCenters","errorCorrectionLevels","default","grayscaleWeights","self","onmessage","event","self.onmessage","postMessage","close"],"mappings":"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"} \ No newline at end of file diff --git a/apps/qrcode/qr-scanner.umd.min.js b/apps/qrcode/qr-scanner.umd.min.js new file mode 100644 index 000000000..70d61f6f1 --- /dev/null +++ b/apps/qrcode/qr-scanner.umd.min.js @@ -0,0 +1,20 @@ +'use strict';(function(d,a){"object"===typeof exports&&"undefined"!==typeof module?module.exports=a():"function"===typeof define&&define.amd?define(a):(d=d||self,d.QrScanner=a())})(this,function(){class d{static hasCamera(){return d.listCameras(!1).then(a=>!!a.length).catch(()=>!1)}static listCameras(a=!1){if(!navigator.mediaDevices)return Promise.resolve([]);let b=null;return(a?navigator.mediaDevices.getUserMedia({audio:!1,video:!0}).then(a=>b=a).catch(()=>{}):Promise.resolve()).then(()=>navigator.mediaDevices.enumerateDevices()).then(a=> +a.filter(a=>"videoinput"===a.kind).map((a,b)=>({id:a.deviceId,label:a.label||(0===b?"Default Camera":`Camera ${b+1}`)}))).finally(()=>{if(b)for(let a of b.getTracks())a.stop(),b.removeTrack(a)})}constructor(a,b,c=this._onDecodeError,f=this._calculateScanRegion,k="environment"){this.$video=a;this.$canvas=document.createElement("canvas");this._onDecode=b;this._legacyCanvasSize=d.DEFAULT_CANVAS_SIZE;this._preferredCamera=k;this._flashOn=this._paused=this._active=!1;"number"===typeof c?(this._legacyCanvasSize= +c,console.warn("You're using a deprecated version of the QrScanner constructor which will be removed in the future")):this._onDecodeError=c;"number"===typeof f?(this._legacyCanvasSize=f,console.warn("You're using a deprecated version of the QrScanner constructor which will be removed in the future")):this._calculateScanRegion=f;this._scanRegion=this._calculateScanRegion(a);this._onPlay=this._onPlay.bind(this);this._onLoadedMetaData=this._onLoadedMetaData.bind(this);this._onVisibilityChange=this._onVisibilityChange.bind(this); +a.disablePictureInPicture=!0;a.playsInline=!0;a.muted=!0;let g=!1;a.hidden&&(a.hidden=!1,g=!0);document.body.contains(a)||(document.body.appendChild(a),g=!0);requestAnimationFrame(()=>{let b=window.getComputedStyle(a);"none"===b.display&&(a.style.setProperty("display","block","important"),g=!0);"visible"!==b.visibility&&(a.style.setProperty("visibility","visible","important"),g=!0);g&&(console.warn("QrScanner has overwritten the video hiding style to avoid Safari stopping the playback."),a.style.opacity= +0,a.style.width=0,a.style.height=0)});a.addEventListener("play",this._onPlay);a.addEventListener("loadedmetadata",this._onLoadedMetaData);document.addEventListener("visibilitychange",this._onVisibilityChange);this._qrEnginePromise=d.createQrEngine()}hasFlash(){let a=null;return(this.$video.srcObject?Promise.resolve(this.$video.srcObject.getVideoTracks()[0]):this._getCameraStream().then(({stream:b})=>{console.warn("Call hasFlash after successfully starting the scanner to avoid creating a temporary video stream"); +a=b;return b.getVideoTracks()[0]})).then(a=>"torch"in a.getSettings()).catch(()=>!1).finally(()=>{if(a)for(let b of a.getTracks())b.stop(),a.removeTrack(b)})}isFlashOn(){return this._flashOn}toggleFlash(){return this._flashOn?this.turnFlashOff():this.turnFlashOn()}turnFlashOn(){if(this._flashOn)return Promise.resolve();this._flashOn=!0;return!this._active||this._paused?Promise.resolve():this.hasFlash().then(a=>a?this.$video.srcObject.getVideoTracks()[0].applyConstraints({advanced:[{torch:!0}]}):Promise.reject("No flash available")).catch(()=> +{this._flashOn=!1;throw e;})}turnFlashOff(){if(this._flashOn)return this._flashOn=!1,this._restartVideoStream()}destroy(){this.$video.removeEventListener("loadedmetadata",this._onLoadedMetaData);this.$video.removeEventListener("play",this._onPlay);document.removeEventListener("visibilitychange",this._onVisibilityChange);this.stop();d._postWorkerMessage(this._qrEnginePromise,"close")}start(){if(this._active&&!this._paused)return Promise.resolve();"https:"!==window.location.protocol&&console.warn("The camera stream is only accessible if the page is transferred via https."); +this._active=!0;if(document.hidden)return Promise.resolve();this._paused=!1;return this.$video.srcObject?(this.$video.play(),Promise.resolve()):this._getCameraStream().then(({stream:a,facingMode:b})=>{this.$video.srcObject=a;this.$video.play();this._setVideoMirror(b);this._flashOn&&(this._flashOn=!1,this.turnFlashOn().catch(()=>{}))}).catch(a=>{this._active=!1;throw a;})}stop(){this.pause();this._active=!1}pause(a=!1){this._paused=!0;if(!this._active)return Promise.resolve(!0);this.$video.pause(); +let b=()=>{const a=this.$video.srcObject?this.$video.srcObject.getTracks():[];for(const b of a)b.stop(),this.$video.srcObject.removeTrack(b);this.$video.srcObject=null};return a?(b(),Promise.resolve(!0)):(new Promise(a=>setTimeout(a,300))).then(()=>{if(!this._paused)return!1;b();return!0})}setCamera(a){if(a===this._preferredCamera)return Promise.resolve();this._preferredCamera=a;return this._restartVideoStream()}static scanImage(a,b=null,c=null,f=null,k=!1,g=!1){let h=c instanceof Worker,l=Promise.all([c|| +d.createQrEngine(),d._loadImage(a)]).then(([a,g])=>{c=a;let l;[f,l]=this._drawToCanvas(g,b,f,k);return c instanceof Worker?(h||c.postMessage({type:"inversionMode",data:"both"}),new Promise((a,b)=>{let k,g,h;g=f=>{"qrResult"===f.data.type&&(c.removeEventListener("message",g),c.removeEventListener("error",h),clearTimeout(k),null!==f.data.data?a(f.data.data):b(d.NO_QR_CODE_FOUND))};h=a=>{c.removeEventListener("message",g);c.removeEventListener("error",h);clearTimeout(k);b("Scanner error: "+(a?a.message|| +a:"Unknown Error"))};c.addEventListener("message",g);c.addEventListener("error",h);k=setTimeout(()=>h("timeout"),1E4);let m=l.getImageData(0,0,f.width,f.height);c.postMessage({type:"decode",data:m},[m.data.buffer])})):new Promise((a,b)=>{let k=setTimeout(()=>b("Scanner error: timeout"),1E4);c.detect(f).then(c=>{c.length?a(c[0].rawValue):b(d.NO_QR_CODE_FOUND)}).catch(a=>b("Scanner error: "+(a.message||a))).finally(()=>clearTimeout(k))})});b&&g&&(l=l.catch(()=>d.scanImage(a,null,c,f,k)));return l=l.finally(()=> +{h||d._postWorkerMessage(c,"close")})}setGrayscaleWeights(a,b,c,f=!0){d._postWorkerMessage(this._qrEnginePromise,"grayscaleWeights",{red:a,green:b,blue:c,useIntegerApproximation:f})}setInversionMode(a){d._postWorkerMessage(this._qrEnginePromise,"inversionMode",a)}static createQrEngine(a=d.WORKER_PATH){return("BarcodeDetector"in window&&BarcodeDetector.getSupportedFormats?BarcodeDetector.getSupportedFormats():Promise.resolve([])).then(b=>-1!==b.indexOf("qr_code")?new BarcodeDetector({formats:["qr_code"]}): +new Worker(a))}_onPlay(){this._scanRegion=this._calculateScanRegion(this.$video);this._scanFrame()}_onLoadedMetaData(){this._scanRegion=this._calculateScanRegion(this.$video)}_onVisibilityChange(){document.hidden?this.pause():this._active&&this.start()}_calculateScanRegion(a){let b=Math.round(2/3*Math.min(a.videoWidth,a.videoHeight));return{x:Math.round((a.videoWidth-b)/2),y:Math.round((a.videoHeight-b)/2),width:b,height:b,downScaledWidth:this._legacyCanvasSize,downScaledHeight:this._legacyCanvasSize}}_scanFrame(){if(!this._active|| +this.$video.paused||this.$video.ended)return!1;requestAnimationFrame(()=>{1>=this.$video.readyState?this._scanFrame():this._qrEnginePromise.then(a=>d.scanImage(this.$video,this._scanRegion,a,this.$canvas)).then(this._onDecode,a=>{this._active&&(-1!==(a.message||a).indexOf("service unavailable")&&(this._qrEnginePromise=d.createQrEngine()),this._onDecodeError(a))}).then(()=>this._scanFrame())})}_onDecodeError(a){a!==d.NO_QR_CODE_FOUND&&console.log(a)}_getCameraStream(){if(!navigator.mediaDevices)return Promise.reject("Camera not found."); +let a="environment"===this._preferredCamera||"user"===this._preferredCamera?"facingMode":"deviceId",b=[{width:{min:1024}},{width:{min:768}},{}];return[...b.map(b=>Object.assign({},b,{[a]:{exact:this._preferredCamera}})),...b].reduceRight((a,b)=>()=>navigator.mediaDevices.getUserMedia({video:b,audio:!1}).then(a=>({stream:a,facingMode:this._getFacingMode(a)||(b.facingMode?this._preferredCamera:"environment"===this._preferredCamera?"user":"environment")})).catch(a),()=>Promise.reject("Camera not found."))()}_restartVideoStream(){let a= +this._paused;return this.pause(!0).then(b=>{if(b&&!a&&this._active)return this.start()})}_setVideoMirror(a){this.$video.style.transform="scaleX("+("user"===a?-1:1)+")"}_getFacingMode(a){return(a=a.getVideoTracks()[0])?/rear|back|environment/i.test(a.label)?"environment":/front|user|face/i.test(a.label)?"user":null:null}static _drawToCanvas(a,b=null,c=null,f=!1){c=c||document.createElement("canvas");let d=b&&b.x?b.x:0,g=b&&b.y?b.y:0,h=b&&b.width?b.width:a.width||a.videoWidth,l=b&&b.height?b.height: +a.height||a.videoHeight;f||(f=b&&b.downScaledWidth?b.downScaledWidth:h,b=b&&b.downScaledHeight?b.downScaledHeight:l,c.width!==f&&(c.width=f),c.height!==b&&(c.height=b));b=c.getContext("2d",{alpha:!1});b.imageSmoothingEnabled=!1;b.drawImage(a,d,g,h,l,0,0,c.width,c.height);return[c,b]}static _loadImage(a){if(a instanceof HTMLCanvasElement||a instanceof HTMLVideoElement||window.ImageBitmap&&a instanceof window.ImageBitmap||window.OffscreenCanvas&&a instanceof window.OffscreenCanvas)return Promise.resolve(a); +if(a instanceof Image)return d._awaitImageLoad(a).then(()=>a);if(a instanceof File||a instanceof Blob||a instanceof URL||"string"===typeof a){let b=new Image;b.src=a instanceof File||a instanceof Blob?URL.createObjectURL(a):a;return d._awaitImageLoad(b).then(()=>{(a instanceof File||a instanceof Blob)&&URL.revokeObjectURL(b.src);return b})}return Promise.reject("Unsupported image type.")}static _awaitImageLoad(a){return new Promise((b,c)=>{if(a.complete&&0!==a.naturalWidth)b();else{let f,d;f=()=> +{a.removeEventListener("load",f);a.removeEventListener("error",d);b()};d=()=>{a.removeEventListener("load",f);a.removeEventListener("error",d);c("Image load error")};a.addEventListener("load",f);a.addEventListener("error",d)}})}static _postWorkerMessage(a,b,c){return Promise.resolve(a).then(a=>{a instanceof Worker&&a.postMessage({type:b,data:c})})}}d.DEFAULT_CANVAS_SIZE=400;d.NO_QR_CODE_FOUND="No QR code found";d.WORKER_PATH="qr-scanner-worker.min.js";return d}) +//# sourceMappingURL=qr-scanner.umd.min.js.map diff --git a/apps/qrcode/qr-scanner.umd.min.js.map b/apps/qrcode/qr-scanner.umd.min.js.map new file mode 100644 index 000000000..c4f086333 --- /dev/null +++ b/apps/qrcode/qr-scanner.umd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"qr-scanner.umd.min.js","sources":["src/qr-scanner.js"],"sourcesContent":["export default class QrScanner {\n /* async */\n static hasCamera() {\n return QrScanner.listCameras(false)\n .then(cameras => !!cameras.length)\n .catch(() => false);\n }\n\n /* async */\n static listCameras(requestLabels = false) {\n if (!navigator.mediaDevices) return Promise.resolve([]);\n\n // Note that enumerateDevices can always be called and does not prompt the user for permission.\n // However, enumerateDevices only includes device labels if served via https and an active media stream exists\n // or permission to access the camera was given. Therefore, ask for camera permission by opening a stream, if\n // labels were requested.\n let openedStream = null;\n return (requestLabels\n ? navigator.mediaDevices.getUserMedia({ audio: false, video: true })\n .then(stream => openedStream = stream)\n // Fail gracefully, especially if the device has no camera or on mobile when the camera is already in\n // use and some browsers disallow a second stream.\n .catch(() => {})\n : Promise.resolve()\n )\n .then(() => navigator.mediaDevices.enumerateDevices())\n .then(devices => devices.filter(device => device.kind === 'videoinput').map((device, i) => ({\n id: device.deviceId,\n label: device.label || (i === 0 ? 'Default Camera' : `Camera ${i + 1}`),\n })))\n .finally(() => {\n // close the stream we just opened for getting camera access for listing the device labels\n if (!openedStream) return;\n for (const track of openedStream.getTracks()) {\n track.stop();\n openedStream.removeTrack(track);\n }\n });\n }\n\n constructor(\n video,\n onDecode,\n canvasSizeOrOnDecodeError = this._onDecodeError,\n canvasSizeOrCalculateScanRegion = this._calculateScanRegion,\n preferredCamera = 'environment'\n ) {\n this.$video = video;\n this.$canvas = document.createElement('canvas');\n this._onDecode = onDecode;\n this._legacyCanvasSize = QrScanner.DEFAULT_CANVAS_SIZE;\n this._preferredCamera = preferredCamera;\n this._active = false;\n this._paused = false;\n this._flashOn = false;\n\n if (typeof canvasSizeOrOnDecodeError === 'number') {\n // legacy function signature where the third argument is the canvas size\n this._legacyCanvasSize = canvasSizeOrOnDecodeError;\n console.warn('You\\'re using a deprecated version of the QrScanner constructor which will be removed in '\n + 'the future');\n } else {\n this._onDecodeError = canvasSizeOrOnDecodeError;\n }\n\n if (typeof canvasSizeOrCalculateScanRegion === 'number') {\n // legacy function signature where the fourth argument is the canvas size\n this._legacyCanvasSize = canvasSizeOrCalculateScanRegion;\n console.warn('You\\'re using a deprecated version of the QrScanner constructor which will be removed in '\n + 'the future');\n } else {\n this._calculateScanRegion = canvasSizeOrCalculateScanRegion;\n }\n\n this._scanRegion = this._calculateScanRegion(video);\n\n this._onPlay = this._onPlay.bind(this);\n this._onLoadedMetaData = this._onLoadedMetaData.bind(this);\n this._onVisibilityChange = this._onVisibilityChange.bind(this);\n\n video.disablePictureInPicture = true;\n // Allow inline playback on iPhone instead of requiring full screen playback,\n // see https://webkit.org/blog/6784/new-video-policies-for-ios/\n video.playsInline = true;\n // Allow play() on iPhone without requiring a user gesture. Should not really be needed as camera stream\n // includes no audio, but just to be safe.\n video.muted = true;\n\n // Avoid Safari stopping the video stream on a hidden video.\n // See https://github.com/cozmo/jsQR/issues/185\n let shouldHideVideo = false;\n if (video.hidden) {\n video.hidden = false;\n shouldHideVideo = true;\n }\n if (!document.body.contains(video)) {\n document.body.appendChild(video);\n shouldHideVideo = true;\n }\n requestAnimationFrame(() => {\n // Checking in requestAnimationFrame which should avoid a potential additional re-flow for getComputedStyle.\n const computedStyle = window.getComputedStyle(video);\n if (computedStyle.display === 'none') {\n video.style.setProperty('display', 'block', 'important');\n shouldHideVideo = true;\n }\n if (computedStyle.visibility !== 'visible') {\n video.style.setProperty('visibility', 'visible', 'important');\n shouldHideVideo = true;\n }\n if (shouldHideVideo) {\n // Hide the video in a way that doesn't cause Safari to stop the playback.\n console.warn('QrScanner has overwritten the video hiding style to avoid Safari stopping the playback.');\n video.style.opacity = 0;\n video.style.width = 0;\n video.style.height = 0;\n }\n });\n\n video.addEventListener('play', this._onPlay);\n video.addEventListener('loadedmetadata', this._onLoadedMetaData);\n document.addEventListener('visibilitychange', this._onVisibilityChange);\n\n this._qrEnginePromise = QrScanner.createQrEngine();\n }\n\n /* async */\n hasFlash() {\n let openedStream = null;\n return (this.$video.srcObject\n ? Promise.resolve(this.$video.srcObject.getVideoTracks()[0])\n : this._getCameraStream().then(({ stream }) => {\n console.warn('Call hasFlash after successfully starting the scanner to avoid creating '\n + 'a temporary video stream');\n openedStream = stream;\n return stream.getVideoTracks()[0];\n })\n )\n .then((track) => 'torch' in track.getSettings())\n .catch(() => false)\n .finally(() => {\n // close the stream we just opened for detecting whether it supports flash\n if (!openedStream) return;\n for (const track of openedStream.getTracks()) {\n track.stop();\n openedStream.removeTrack(track);\n }\n });\n }\n\n isFlashOn() {\n return this._flashOn;\n }\n\n /* async */\n toggleFlash() {\n if (this._flashOn) {\n return this.turnFlashOff();\n } else {\n return this.turnFlashOn();\n }\n }\n\n /* async */\n turnFlashOn() {\n if (this._flashOn) return Promise.resolve();\n this._flashOn = true;\n if (!this._active || this._paused) return Promise.resolve(); // flash will be turned on later on .start()\n return this.hasFlash().then((hasFlash) => {\n if (!hasFlash) return Promise.reject('No flash available');\n // Note that the video track is guaranteed to exist at this point\n return this.$video.srcObject.getVideoTracks()[0].applyConstraints({\n advanced: [{ torch: true }],\n });\n }).catch(() => {\n this._flashOn = false;\n throw e;\n });\n }\n\n /* async */\n turnFlashOff() {\n if (!this._flashOn) return;\n // applyConstraints with torch: false does not work to turn the flashlight off, as a stream's torch stays\n // continuously on, see https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#torch. Therefore,\n // we have to stop the stream to turn the flashlight off.\n this._flashOn = false;\n return this._restartVideoStream();\n }\n\n destroy() {\n this.$video.removeEventListener('loadedmetadata', this._onLoadedMetaData);\n this.$video.removeEventListener('play', this._onPlay);\n document.removeEventListener('visibilitychange', this._onVisibilityChange);\n\n this.stop();\n QrScanner._postWorkerMessage(this._qrEnginePromise, 'close');\n }\n\n /* async */\n start() {\n if (this._active && !this._paused) {\n return Promise.resolve();\n }\n if (window.location.protocol !== 'https:') {\n // warn but try starting the camera anyways\n console.warn('The camera stream is only accessible if the page is transferred via https.');\n }\n this._active = true;\n if (document.hidden) {\n // camera will be started as soon as tab is in foreground\n return Promise.resolve();\n }\n this._paused = false;\n if (this.$video.srcObject) {\n // camera stream already/still set\n this.$video.play();\n return Promise.resolve();\n }\n\n return this._getCameraStream()\n .then(({ stream, facingMode }) => {\n this.$video.srcObject = stream;\n this.$video.play();\n this._setVideoMirror(facingMode);\n\n // Restart the flash if it was previously on\n if (this._flashOn) {\n this._flashOn = false; // force turnFlashOn to restart the flash\n this.turnFlashOn().catch(() => {});\n }\n })\n .catch(e => {\n this._active = false;\n throw e;\n });\n }\n\n stop() {\n this.pause();\n this._active = false;\n }\n\n /* async */\n pause(stopStreamImmediately = false) {\n this._paused = true;\n if (!this._active) {\n return Promise.resolve(true);\n }\n this.$video.pause();\n\n const stopStream = () => {\n const tracks = this.$video.srcObject ? this.$video.srcObject.getTracks() : [];\n for (const track of tracks) {\n track.stop(); // note that this will also automatically turn the flashlight off\n this.$video.srcObject.removeTrack(track);\n }\n this.$video.srcObject = null;\n };\n\n if (stopStreamImmediately) {\n stopStream();\n return Promise.resolve(true);\n }\n\n return new Promise((resolve) => setTimeout(resolve, 300))\n .then(() => {\n if (!this._paused) return false;\n stopStream();\n return true;\n });\n }\n\n /* async */\n setCamera(facingModeOrDeviceId) {\n if (facingModeOrDeviceId === this._preferredCamera) return Promise.resolve();\n this._preferredCamera = facingModeOrDeviceId;\n // Restart the scanner with the new camera which will also update the video mirror and the scan region.\n return this._restartVideoStream();\n }\n\n /* async */\n static scanImage(imageOrFileOrUrl, scanRegion=null, qrEngine=null, canvas=null, disallowCanvasResizing=false,\n alsoTryWithoutScanRegion=false) {\n const gotExternalWorker = qrEngine instanceof Worker;\n\n let promise = Promise.all([\n qrEngine || QrScanner.createQrEngine(),\n QrScanner._loadImage(imageOrFileOrUrl),\n ]).then(([engine, image]) => {\n qrEngine = engine;\n let canvasContext;\n [canvas, canvasContext] = this._drawToCanvas(image, scanRegion, canvas, disallowCanvasResizing);\n\n if (qrEngine instanceof Worker) {\n if (!gotExternalWorker) {\n // Enable scanning of inverted color qr codes. Not using _postWorkerMessage as it's async\n qrEngine.postMessage({ type: 'inversionMode', data: 'both' });\n }\n return new Promise((resolve, reject) => {\n let timeout, onMessage, onError;\n onMessage = event => {\n if (event.data.type !== 'qrResult') {\n return;\n }\n qrEngine.removeEventListener('message', onMessage);\n qrEngine.removeEventListener('error', onError);\n clearTimeout(timeout);\n if (event.data.data !== null) {\n resolve(event.data.data);\n } else {\n reject(QrScanner.NO_QR_CODE_FOUND);\n }\n };\n onError = (e) => {\n qrEngine.removeEventListener('message', onMessage);\n qrEngine.removeEventListener('error', onError);\n clearTimeout(timeout);\n const errorMessage = !e ? 'Unknown Error' : (e.message || e);\n reject('Scanner error: ' + errorMessage);\n };\n qrEngine.addEventListener('message', onMessage);\n qrEngine.addEventListener('error', onError);\n timeout = setTimeout(() => onError('timeout'), 10000);\n const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height);\n qrEngine.postMessage({\n type: 'decode',\n data: imageData\n }, [imageData.data.buffer]);\n });\n } else {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => reject('Scanner error: timeout'), 10000);\n qrEngine.detect(canvas).then(scanResults => {\n if (!scanResults.length) {\n reject(QrScanner.NO_QR_CODE_FOUND);\n } else {\n resolve(scanResults[0].rawValue);\n }\n }).catch((e) => reject('Scanner error: ' + (e.message || e))).finally(() => clearTimeout(timeout));\n });\n }\n });\n\n if (scanRegion && alsoTryWithoutScanRegion) {\n promise = promise.catch(() =>\n QrScanner.scanImage(imageOrFileOrUrl, null, qrEngine, canvas, disallowCanvasResizing));\n }\n\n promise = promise.finally(() => {\n if (gotExternalWorker) return;\n QrScanner._postWorkerMessage(qrEngine, 'close');\n });\n\n return promise;\n }\n\n setGrayscaleWeights(red, green, blue, useIntegerApproximation = true) {\n // Note that for the native BarcodeDecoder, this is a no-op. However, the native implementations work also\n // well with colored qr codes.\n QrScanner._postWorkerMessage(\n this._qrEnginePromise,\n 'grayscaleWeights',\n { red, green, blue, useIntegerApproximation }\n );\n }\n\n setInversionMode(inversionMode) {\n // Note that for the native BarcodeDecoder, this is a no-op. However, the native implementations scan normal\n // and inverted qr codes by default\n QrScanner._postWorkerMessage(this._qrEnginePromise, 'inversionMode', inversionMode);\n }\n\n /* async */\n static createQrEngine(workerPath = QrScanner.WORKER_PATH) {\n return ('BarcodeDetector' in window && BarcodeDetector.getSupportedFormats\n ? BarcodeDetector.getSupportedFormats()\n : Promise.resolve([])\n )\n .then((supportedFormats) => supportedFormats.indexOf('qr_code') !== -1\n ? new BarcodeDetector({ formats: ['qr_code'] })\n : new Worker(workerPath)\n );\n }\n\n _onPlay() {\n this._scanRegion = this._calculateScanRegion(this.$video);\n this._scanFrame();\n }\n\n _onLoadedMetaData() {\n this._scanRegion = this._calculateScanRegion(this.$video);\n }\n\n _onVisibilityChange() {\n if (document.hidden) {\n this.pause();\n } else if (this._active) {\n this.start();\n }\n }\n\n _calculateScanRegion(video) {\n // Default scan region calculation. Note that this can be overwritten in the constructor.\n const smallestDimension = Math.min(video.videoWidth, video.videoHeight);\n const scanRegionSize = Math.round(2 / 3 * smallestDimension);\n return {\n x: Math.round((video.videoWidth - scanRegionSize) / 2),\n y: Math.round((video.videoHeight - scanRegionSize) / 2),\n width: scanRegionSize,\n height: scanRegionSize,\n downScaledWidth: this._legacyCanvasSize,\n downScaledHeight: this._legacyCanvasSize,\n };\n }\n\n _scanFrame() {\n if (!this._active || this.$video.paused || this.$video.ended) return false;\n // using requestAnimationFrame to avoid scanning if tab is in background\n requestAnimationFrame(() => {\n if (this.$video.readyState <= 1) {\n // Skip scans until the video is ready as drawImage() only works correctly on a video with readyState\n // > 1, see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage#Notes.\n // This also avoids false positives for videos paused after a successful scan which remains visible on\n // the canvas until the video is started again and ready.\n this._scanFrame();\n return;\n }\n this._qrEnginePromise\n .then((qrEngine) => QrScanner.scanImage(this.$video, this._scanRegion, qrEngine, this.$canvas))\n .then(this._onDecode, (error) => {\n if (!this._active) return;\n const errorMessage = error.message || error;\n if (errorMessage.indexOf('service unavailable') !== -1) {\n // When the native BarcodeDetector crashed, create a new one\n this._qrEnginePromise = QrScanner.createQrEngine();\n }\n this._onDecodeError(error);\n })\n .then(() => this._scanFrame());\n });\n }\n\n _onDecodeError(error) {\n // default error handler; can be overwritten in the constructor\n if (error === QrScanner.NO_QR_CODE_FOUND) return;\n console.log(error);\n }\n\n /* async */\n _getCameraStream() {\n if (!navigator.mediaDevices) {\n return Promise.reject('Camera not found.');\n }\n\n const preferenceType = this._preferredCamera === 'environment' || this._preferredCamera === 'user'\n ? 'facingMode'\n : 'deviceId';\n const constraintsWithoutCamera = [{\n width: { min: 1024 }\n }, {\n width: { min: 768 }\n }, {}];\n const constraintsWithCamera = constraintsWithoutCamera.map((constraint) => Object.assign({}, constraint, {\n [preferenceType]: { exact: this._preferredCamera },\n }));\n\n // First try constraints with camera, then without camera. Using reduceRight as the Promise is build in a\n // bottom up fashion.\n return [...constraintsWithCamera, ...constraintsWithoutCamera].reduceRight((fallback, constraint) =>\n () => navigator.mediaDevices.getUserMedia({ video: constraint, audio: false })\n .then((stream) => ({\n stream,\n // Try to determine the facing mode from the stream, otherwise use a guess or 'environment' as\n // default. Note that the guess is not always accurate as Safari returns cameras of different facing\n // mode, even for exact facingMode constraints.\n facingMode: this._getFacingMode(stream)\n || (constraint.facingMode\n ? this._preferredCamera // _preferredCamera is a facing mode and we are able to fulfill it\n : (this._preferredCamera === 'environment'\n ? 'user' // switch as _preferredCamera was environment but we are not able to fulfill it\n : 'environment' // switch from unfulfilled user facingMode or default to environment\n )\n ),\n }))\n .catch(fallback),\n () => Promise.reject('Camera not found.')\n )();\n }\n\n /* async */\n _restartVideoStream() {\n // Note that we always pause the stream and not only if !this._paused as even if this._paused === true, the\n // stream might still be running, as it's by default only stopped after a delay of 300ms.\n const wasPaused = this._paused;\n return this.pause(true).then((paused) => {\n if (!paused || wasPaused || !this._active) return;\n return this.start();\n });\n }\n\n _setVideoMirror(facingMode) {\n // in user facing mode mirror the video to make it easier for the user to position the QR code\n const scaleFactor = facingMode==='user'? -1 : 1;\n this.$video.style.transform = 'scaleX(' + scaleFactor + ')';\n }\n\n _getFacingMode(videoStream) {\n const videoTrack = videoStream.getVideoTracks()[0];\n if (!videoTrack) return null; // unknown\n // inspired by https://github.com/JodusNodus/react-qr-reader/blob/master/src/getDeviceId.js#L13\n return /rear|back|environment/i.test(videoTrack.label)\n ? 'environment'\n : /front|user|face/i.test(videoTrack.label)\n ? 'user'\n : null; // unknown\n }\n\n static _drawToCanvas(image, scanRegion=null, canvas=null, disallowCanvasResizing=false) {\n canvas = canvas || document.createElement('canvas');\n const scanRegionX = scanRegion && scanRegion.x? scanRegion.x : 0;\n const scanRegionY = scanRegion && scanRegion.y? scanRegion.y : 0;\n const scanRegionWidth = scanRegion && scanRegion.width? scanRegion.width : image.width || image.videoWidth;\n const scanRegionHeight = scanRegion && scanRegion.height? scanRegion.height : image.height || image.videoHeight;\n\n if (!disallowCanvasResizing) {\n const canvasWidth = scanRegion && scanRegion.downScaledWidth\n ? scanRegion.downScaledWidth\n : scanRegionWidth;\n const canvasHeight = scanRegion && scanRegion.downScaledHeight\n ? scanRegion.downScaledHeight\n : scanRegionHeight;\n // Setting the canvas width or height clears the canvas, even if the values didn't change, therefore only\n // set them if they actually changed.\n if (canvas.width !== canvasWidth) {\n canvas.width = canvasWidth;\n }\n if (canvas.height !== canvasHeight) {\n canvas.height = canvasHeight;\n }\n }\n\n const context = canvas.getContext('2d', { alpha: false });\n context.imageSmoothingEnabled = false; // gives less blurry images\n context.drawImage(\n image,\n scanRegionX, scanRegionY, scanRegionWidth, scanRegionHeight,\n 0, 0, canvas.width, canvas.height\n );\n return [canvas, context];\n }\n\n /* async */\n static _loadImage(imageOrFileOrBlobOrUrl) {\n if (imageOrFileOrBlobOrUrl instanceof HTMLCanvasElement || imageOrFileOrBlobOrUrl instanceof HTMLVideoElement\n || window.ImageBitmap && imageOrFileOrBlobOrUrl instanceof window.ImageBitmap\n || window.OffscreenCanvas && imageOrFileOrBlobOrUrl instanceof window.OffscreenCanvas) {\n return Promise.resolve(imageOrFileOrBlobOrUrl);\n } else if (imageOrFileOrBlobOrUrl instanceof Image) {\n return QrScanner._awaitImageLoad(imageOrFileOrBlobOrUrl).then(() => imageOrFileOrBlobOrUrl);\n } else if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob\n || imageOrFileOrBlobOrUrl instanceof URL || typeof(imageOrFileOrBlobOrUrl)==='string') {\n const image = new Image();\n if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob) {\n image.src = URL.createObjectURL(imageOrFileOrBlobOrUrl);\n } else {\n image.src = imageOrFileOrBlobOrUrl;\n }\n return QrScanner._awaitImageLoad(image).then(() => {\n if (imageOrFileOrBlobOrUrl instanceof File || imageOrFileOrBlobOrUrl instanceof Blob) {\n URL.revokeObjectURL(image.src);\n }\n return image;\n });\n } else {\n return Promise.reject('Unsupported image type.');\n }\n }\n\n /* async */\n static _awaitImageLoad(image) {\n return new Promise((resolve, reject) => {\n if (image.complete && image.naturalWidth!==0) {\n // already loaded\n resolve();\n } else {\n let onLoad, onError;\n onLoad = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n resolve();\n };\n onError = () => {\n image.removeEventListener('load', onLoad);\n image.removeEventListener('error', onError);\n reject('Image load error');\n };\n image.addEventListener('load', onLoad);\n image.addEventListener('error', onError);\n }\n });\n }\n\n /* async */\n static _postWorkerMessage(qrEngineOrQrEnginePromise, type, data) {\n return Promise.resolve(qrEngineOrQrEnginePromise).then((qrEngine) => {\n if (!(qrEngine instanceof Worker)) return;\n qrEngine.postMessage({ type, data });\n });\n }\n}\nQrScanner.DEFAULT_CANVAS_SIZE = 400;\nQrScanner.NO_QR_CODE_FOUND = 'No QR code found';\nQrScanner.WORKER_PATH = 'qr-scanner-worker.min.js';\n"],"names":["QrScanner","listCameras","then","cameras","length","catch","requestLabels","navigator","mediaDevices","Promise","resolve","openedStream","getUserMedia","audio","video","stream","enumerateDevices","devices","filter","device","kind","map","i","id","deviceId","label","finally","track","stop","removeTrack","onDecode","canvasSizeOrOnDecodeError","_onDecodeError","canvasSizeOrCalculateScanRegion","_calculateScanRegion","preferredCamera","$video","$canvas","document","createElement","_onDecode","_legacyCanvasSize","DEFAULT_CANVAS_SIZE","_preferredCamera","_flashOn","_paused","_active","console","warn","_scanRegion","_onPlay","bind","_onLoadedMetaData","_onVisibilityChange","disablePictureInPicture","playsInline","muted","shouldHideVideo","hidden","body","contains","appendChild","requestAnimationFrame","computedStyle","display","style","setProperty","visibility","opacity","width","height","addEventListener","_qrEnginePromise","createQrEngine","srcObject","getVideoTracks","_getCameraStream","getSettings","turnFlashOff","turnFlashOn","hasFlash","applyConstraints","advanced","torch","reject","e","_restartVideoStream","removeEventListener","_postWorkerMessage","window","location","protocol","play","facingMode","_setVideoMirror","pause","stopStreamImmediately","tracks","getTracks","stopStream","setTimeout","facingModeOrDeviceId","imageOrFileOrUrl","scanRegion","qrEngine","canvas","disallowCanvasResizing","alsoTryWithoutScanRegion","promise","all","_loadImage","engine","image","canvasContext","_drawToCanvas","Worker","gotExternalWorker","postMessage","type","data","timeout","onMessage","onError","event","clearTimeout","NO_QR_CODE_FOUND","imageData","buffer","detect","scanResults","rawValue","message","scanImage","red","green","blue","useIntegerApproximation","inversionMode","workerPath","WORKER_PATH","BarcodeDetector","getSupportedFormats","supportedFormats","indexOf","formats","_scanFrame","start","videoHeight","x","Math","round","videoWidth","scanRegionSize","y","downScaledWidth","downScaledHeight","paused","ended","readyState","error","log","min","constraint","preferenceType","exact","constraintsWithoutCamera","reduceRight","fallback","_getFacingMode","wasPaused","transform","videoStream","test","videoTrack","scanRegionWidth","scanRegionHeight","canvasWidth","canvasHeight","alpha","context","imageSmoothingEnabled","drawImage","scanRegionX","scanRegionY","imageOrFileOrBlobOrUrl","HTMLCanvasElement","HTMLVideoElement","ImageBitmap","OffscreenCanvas","Image","_awaitImageLoad","File","Blob","URL","src","createObjectURL","revokeObjectURL","complete","naturalWidth","onLoad","qrEngineOrQrEnginePromise"],"mappings":"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"} \ No newline at end of file diff --git a/apps/snaky/README.md b/apps/snaky/README.md new file mode 100644 index 000000000..03ef3be2b --- /dev/null +++ b/apps/snaky/README.md @@ -0,0 +1,7 @@ +# Snaky + +Eat apples and don't bite your tail. + +## Controls +Use the touch screen, drag up, down, right or left. + diff --git a/apps/snaky/snaky-icon.js b/apps/snaky/snaky-icon.js new file mode 100644 index 000000000..85e81eadf --- /dev/null +++ b/apps/snaky/snaky-icon.js @@ -0,0 +1 @@ +E.toArrayBuffer(atob("MDCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7u7u7u7AAAJmZmZmZmZmZkAAAAAAAAAu7u7u7u7uwAJmZmZmZmZmZkAAAAAAAALuyu7u7u7uwAJmZmZmZmZmZkAAAAAAAALIiIru7IiKwAJmZmZmZmZmZkAAAAAAAALISIru7IiK7AJmZmZmZmZmZkAAAAAAAALsiK7u7IjK7AJmZmZmZmZmZkAAAAAAAALu7u7u7u7u7AJmZmZmZmZmZkAAAAAAAALu7u7u7u7u7AAAAAAAJmZmZkAAAAAAAALsru7u7siu7AAAAAAAAmZmZkAAAAAAAALuxEiIiIruwAAAAAAAJmZmZkAAAAAAAAAu7IiIiu7uwAAAAAAAJmZmZkAAAAAAAAAu7u7u7u7sAAAAAAAAJmZmZkAAAAAAAAAALuqqqqwAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAAmZmZkAAAAAAAAAAAmZmZmQAAAAAAAAAJmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAmZmZmZmZmZmZmZmZmZmZkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")) diff --git a/apps/snaky/snaky.js b/apps/snaky/snaky.js new file mode 100644 index 000000000..7ce032fcf --- /dev/null +++ b/apps/snaky/snaky.js @@ -0,0 +1,185 @@ +//Bangle.setLCDMode("176x176"); +Bangle.setLCDTimeout(0); + +const H = g.getWidth(); +const W = g.getHeight(); +let running = true; +let score = 0; +let d; +const gridSize = 29; +const tileSize = 6; +let nextX = 0; +let nextY = 0; +const defaultTailSize = 3; +let tailSize = defaultTailSize; +const snakeTrail = []; +const snake = { x: 10, y: 10 }; +const apple = { x: Math.floor(Math.random() * gridSize), y: Math.floor(Math.random() * gridSize) }; + +function drawBackground(){ + g.setColor("#000000"); + g.fillRect(0, 0, H, W); +} + +function drawBackgroundSuccess(){ + g.setColor("#00FFFF"); + g.fillRect(0, 0, H, W); +} + +function drawApple(){ + g.setColor("#FF0000"); + g.fillCircle((apple.x * tileSize) + tileSize/2, (apple.y * tileSize) + tileSize/2, tileSize/2); +} + +function drawSnake(){ + g.setColor("#008000"); + for (let i = 0; i < snakeTrail.length; i++) { + g.fillRect(snakeTrail[i].x * tileSize, snakeTrail[i].y * tileSize, snakeTrail[i].x * tileSize + tileSize, snakeTrail[i].y * tileSize + tileSize); + + //snake bites it's tail + if (snakeTrail[i].x === snake.x && snakeTrail[i].y === snake.y && tailSize > defaultTailSize) { + Bangle.buzz(1000); + gameOver(); + } + } + g.setColor("#FFFFFF"); + g.fillRect(snake.x*tileSize, snake.y*tileSize, snake.x*tileSize+ tileSize, snake.y*tileSize + tileSize); + + g.setColor("#0000ff"); + g.fillRect((snake.x*tileSize)+1, (snake.y*tileSize)+2, (snake.x*tileSize)+2, (snake.y*tileSize)+4); + + g.setColor("#0000ff"); + g.fillRect((snake.x*tileSize)+tileSize-1, (snake.y*tileSize)+2, (snake.x*tileSize)+tileSize-2, (snake.y*tileSize)+4); + +} + +function drawScore(){ + g.setColor("#555555"); + g.setFont("Vector20"); + g.setFontAlign(0, 0); + g.drawString("Score:" + score, W / 2, 10); +} + +function gameStart() { + running = true; + score = 0; +} + +function gameOver() { + g.clear(); + g.setColor("#000000"); + g.setFont("Vector12"); + g.drawString("GAME OVER!", W / 2, H / 2 - 20); + g.drawString("Score: " + score, W / 2, H / 2 - 10); + g.drawString("Tap to Restart", W / 2, H / 2 + 10); + running = false; + tailSize = defaultTailSize; +} + +function draw() { + if (!running) { + return; + } + + g.clear(); + + // move snake in next pos + snake.x += nextX; + snake.y += nextY; + + // snake over game world + if (snake.x < 0) { + snake.x = gridSize - 1; + } + if (snake.x > gridSize - 1) { + snake.x = 0; + } + + if (snake.y < 0) { + snake.y = gridSize - 1; + } + if (snake.y > gridSize - 1) { + snake.y = 0; + } + + //snake bite apple + if (snake.x === apple.x && snake.y === apple.y) { + Bangle.beep(20); + drawBackgroundSuccess(); + tailSize++; + score++; + + apple.x = Math.floor(Math.random() * gridSize); + apple.y = Math.floor(Math.random() * gridSize); + drawApple(); + } + + drawBackground(); + drawApple(); + drawSnake(); + drawScore(); + + //set snake trail + snakeTrail.push({ x: snake.x, y: snake.y }); + while (snakeTrail.length > tailSize) { + snakeTrail.shift(); + } + + g.flip(); +} + +let dDiff = 10; + +Bangle.on('drag', function(a) { + + if (a.dx > dDiff ) { // right + if (d !== 'l') + { + nextX = 1; + nextY = 0; + d = 'r'; + } + } + + if (a.dx < -dDiff ) { // left + if (d !== 'r') + { + nextX = -1; + nextY = 0; + d = 'l'; + } + } + + if (a.dy < -dDiff) { // Up + if (d !== 'd') { + nextX = 0; + nextY = -1; + d = 'u'; + } + } + + + if (a.dy > dDiff) { // Down + if (d !== 'u') + { + nextX = 0; + nextY = 1; + d = 'd'; + } + } + +}); + + + + +Bangle.on('touch', button => { + if (!running) { + gameStart(); + } +}); + + +// render X times per second +const x = 5; +setInterval(draw, 1000 / x); diff --git a/apps/snaky/snaky.png b/apps/snaky/snaky.png new file mode 100644 index 000000000..388c32126 Binary files /dev/null and b/apps/snaky/snaky.png differ diff --git a/apps/vectorclock/Changelog b/apps/vectorclock/Changelog index 43190331b..c2a6fbcf4 100644 --- a/apps/vectorclock/Changelog +++ b/apps/vectorclock/Changelog @@ -1,2 +1,3 @@ 0.1: New watch face 0.2: Use Bangle.setUI for button/launcher handling +0.3: Bangle.js 2 support \ No newline at end of file diff --git a/apps/vectorclock/app.js b/apps/vectorclock/app.js index a98c9f97b..78c17b3d4 100644 --- a/apps/vectorclock/app.js +++ b/apps/vectorclock/app.js @@ -5,9 +5,10 @@ function padNum(n, l) { return ("0".repeat(l)+n).substr(-l); } -let rects = {}; -let rectsToClear = {}; -let commands = []; +var rects = {}; +var rectsToClear = {}; +var commands = []; +var showSeconds = true; function pushCommand(command) { let hash = E.CRC32(E.toJS(arguments)); @@ -20,17 +21,20 @@ function executeCommands() { "ram"; for (let hash in rectsToClear) delete rects[hash]; for (let r of rectsToClear) if (r) g.clearRect(r.x1, r.y1, r.x2, r.y2); - g.getModified(true); - for (let c of commands) { - c.command(); - rects[c.hash] = g.getModified(true); - } + for (let c of commands) rects[c.hash] = c.command(); rectsToClear = Object.assign({}, rects); commands = []; } function drawVectorText(text, size, x, y, alignX, alignY) { g.setFont("Vector", size).setFontAlign(alignX, alignY).drawString(text, x, y); + var m = g.stringMetrics(text); + return { + x1: x - m.width * (alignX / 2 + 0.5), + y1: y - m.height * (alignY / 2 + 0.5), + x2: x - m.width * (alignX / 2 - 0.5), + y2: y - m.height * (alignY / 2 - 0.5) + }; } function draw() { @@ -43,11 +47,12 @@ function draw() { let secondsText = padNum(d.getSeconds(), 2); let dowText = locale.dow(d); let dateText = locale.date(d, true); + let width = g.getWidth() - 2; g.setFont("Vector", 256); - let timeFontSize = g.getWidth() / ((g.stringWidth(timeText) / 256) + (Math.max(g.stringWidth(meridian), g.stringWidth(secondsText)) / 512 * 9 / 10)); - let dowFontSize = g.getWidth() / (g.stringWidth(dowText) / 256); - let dateFontSize = g.getWidth() / (g.stringWidth(dateText) / 256); + let timeFontSize = width / ((g.stringWidth(timeText) / 256) + (Math.max(g.stringWidth(meridian), g.stringWidth(secondsText)) / 512 * 9 / 10)); + let dowFontSize = width / (g.stringWidth(dowText) / 256); + let dateFontSize = width / (g.stringWidth(dateText) / 256); let timeHeight = g.setFont("Vector", timeFontSize).getFontHeight() * 9 / 10; let dowHeight = g.setFont("Vector", dowFontSize).getFontHeight(); @@ -56,26 +61,28 @@ function draw() { let remainingHeight = g.getHeight() - 24 - timeHeight - dowHeight - dateHeight; let spacer = remainingHeight / 4; + let x = 2; let y = 24 + spacer; - pushCommand(drawVectorText, timeText, timeFontSize, 0, y, -1, -1); - pushCommand(drawVectorText, meridian, timeFontSize*9/20, g.getWidth(), y, 1, -1); - pushCommand(drawVectorText, secondsText, timeFontSize*9/20, g.getWidth(), y + timeHeight, 1, 1); + pushCommand(drawVectorText, timeText, timeFontSize, x, y, -1, -1); + pushCommand(drawVectorText, meridian, timeFontSize*9/20, x + width, y, 1, -1); + if (showSeconds) pushCommand(drawVectorText, secondsText, timeFontSize*9/20, x + width, y + timeHeight, 1, 1); y += timeHeight + spacer; - pushCommand(drawVectorText, dowText, dowFontSize, g.getWidth()/2, y, 0, -1); + pushCommand(drawVectorText, dowText, dowFontSize, x + width/2, y, 0, -1); y += dowHeight + spacer; - pushCommand(drawVectorText, dateText, dateFontSize, g.getWidth()/2, y, 0, -1); + pushCommand(drawVectorText, dateText, dateFontSize, x + width/2, y, 0, -1); executeCommands(); } -let timeout; +var timeout; function tick() { draw(); - timeout = setTimeout(tick, 1000 - getTime() % 1 * 1000); + var period = showSeconds ? 1000 : 60 * 1000; + timeout = setTimeout(tick, period - getTime() * 1000 % period); } Bangle.on('lcdPower', function(on) { @@ -84,6 +91,13 @@ Bangle.on('lcdPower', function(on) { if (on) tick(); }); +Bangle.on('lock', function(locked) { + if (timeout) clearTimeout(timeout); + timeout = null; + showSeconds = !locked; + tick(); +}); + g.clear(); tick(); Bangle.loadWidgets(); diff --git a/apps/vectorclock/bangle2-vector-clock-screenshot.png b/apps/vectorclock/bangle2-vector-clock-screenshot.png new file mode 100644 index 000000000..30d40c864 Binary files /dev/null and b/apps/vectorclock/bangle2-vector-clock-screenshot.png differ diff --git a/apps/weather/ChangeLog b/apps/weather/ChangeLog index 95f943e6d..fb6b28bf6 100644 --- a/apps/weather/ChangeLog +++ b/apps/weather/ChangeLog @@ -9,3 +9,4 @@ 0.10: Use new Layout library 0.11: Bangle.js 2 support 0.12: Allow hiding the widget +0.13: Tweak Bangle.js 2 light theme colors diff --git a/apps/weather/lib.js b/apps/weather/lib.js index 76ed2aaa4..7cb9a9f9b 100644 --- a/apps/weather/lib.js +++ b/apps/weather/lib.js @@ -54,14 +54,62 @@ exports.get = function() { scheduleExpiry(storage.readJSON('weather.json')||{}); exports.drawIcon = function(cond, x, y, r) { + var palette; + + if (B2) { + if (g.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 (g.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' + }; + } + } + function drawSun(x, y, r) { - g.setColor(B2 ? '#FF0' : (g.theme.dark ? "#FE0" : "#FC0")); + g.setColor(palette.sun); g.fillCircle(x, y, r); } function drawCloud(x, y, r, c) { const u = r/12; - if (c==null) c = B2 ? '#FFF': (g.theme.dark ? "#BBB" : "#AAA"); + if (c==null) c = palette.cloud; g.setColor(c); g.fillCircle(x-8*u, y+3*u, 4*u); g.fillCircle(x-4*u, y-2*u, 5*u); @@ -78,7 +126,7 @@ exports.drawIcon = function(cond, x, y, r) { } function drawBrokenClouds(x, y, r) { - drawCloud(x+1/8*r, y-1/8*r, 7/8*r, "#777"); // dithers on B2, but that's ok + drawCloud(x+1/8*r, y-1/8*r, 7/8*r, palette.bgCloud); drawCloud(x-1/8*r, y+1/8*r, 7/8*r); } @@ -88,7 +136,7 @@ exports.drawIcon = function(cond, x, y, r) { } function drawRainLines(x, y, r) { - g.setColor(B2 ? '#0FF' : (g.theme.dark ? "#0CF" : "#07F")); + g.setColor(palette.rain); const y1 = y+1/2*r; const y2 = y+1*r; const poly = g.fillPolyAA ? p => g.fillPolyAA(p) : p => g.fillPoly(p); @@ -124,7 +172,7 @@ exports.drawIcon = function(cond, x, y, r) { function drawThunderstorm(x, y, r) { function drawLightning(x, y, r) { - g.setColor(B2 ? '#FF0' : (g.theme.dark ? "#FE0" : "#FC0")); + g.setColor(palette.lightning); g.fillPoly([ x-2/6*r, y-r, x-4/6*r, y+1/6*r, @@ -152,7 +200,7 @@ exports.drawIcon = function(cond, x, y, r) { } } - g.setColor(B2 ? '#FFF' : (g.theme.dark ? "#FFF" : "#CCC")); + g.setColor(palette.snow); const w = 1/12*r; for(let i = 0; i<=6; ++i) { const points = [ @@ -187,7 +235,7 @@ exports.drawIcon = function(cond, x, y, r) { [-0.2, 0.3], ]; - g.setColor(B2 ? '#FFF' : (g.theme.dark ? "#FFF" : "#CCC")); + g.setColor(palette.mist); for(let i = 0; i<5; ++i) { g.fillRect(x+layers[i][0]*r, y+(0.4*i-0.9)*r, x+layers[i][1]*r, y+(0.4*i-0.7)*r-1); @@ -197,7 +245,7 @@ exports.drawIcon = function(cond, x, y, r) { } function drawUnknown(x, y, r) { - drawCloud(x, y, r, "#777"); // dithers on B2, but that's ok + drawCloud(x, y, r, palette.bgCloud); g.setColor(g.theme.fg).setFontAlign(0, 0).setFont('Vector', r*2).drawString("?", x+r/10, y+r/6); } diff --git a/apps/weatherClock/ChangeLog b/apps/weatherClock/ChangeLog index 600f93be2..72b53ebbf 100644 --- a/apps/weatherClock/ChangeLog +++ b/apps/weatherClock/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Minor layout format tweak so it uses less memory and draws ok on Bangle.js 1 (#1012) 0.03: Minor layout extra spaces. +0.04: Layout now compatible with Bangle.js 2 diff --git a/apps/weatherClock/app.js b/apps/weatherClock/app.js index 9dd49427f..799f9abc6 100644 --- a/apps/weatherClock/app.js +++ b/apps/weatherClock/app.js @@ -73,12 +73,10 @@ var clockLayout = new Layout( { {type: "img", filly: 1, id: "weatherIcon", src: sunIcon}, {type: "v", fillx:1, c: [ {type: "h", c: [ - {type: "txt", font: "10%", id: "temp", label: "000"}, - {type: "txt", font: "10%", id: "tempUnit", label: "°C"}, + {type: "txt", font: "10%", id: "temp", label: "000 °C"}, ]}, {type: "h", c: [ - {type: "txt", font: "10%", id: "wind", label: "00"}, - {type: "txt", font: "10%", id: "windUnit", label: "km/h"}, + {type: "txt", font: "10%", id: "wind", label: "00 km/h"}, ]} ] }, @@ -106,18 +104,14 @@ function draw() { if(weatherJson && weatherJson.weather){ var currentWeather = weatherJson.weather; const temp = locale.temp(currentWeather.temp-273.15).match(/^(\D*\d*)(.*)$/); - clockLayout.temp.label = temp[1]; - clockLayout.tempUnit.label = temp[2]; + clockLayout.temp.label = temp[1] + " " + temp[2]; clockLayout.weatherIcon.src = chooseIcon(currentWeather.txt); const wind = locale.speed(currentWeather.wind).match(/^(\D*\d*)(.*)$/); - clockLayout.wind.label = wind[1] + " ".repeat(wind[2].length-1); - clockLayout.windUnit.label = wind[2] + " " + (currentWeather.wrose||'').toUpperCase(); + clockLayout.wind.label = wind[1] + " " + wind[2] + " " + (currentWeather.wrose||'').toUpperCase(); } else{ clockLayout.temp.label = "Err"; - clockLayout.tempUnit.label = ""; clockLayout.wind.label = "No Data"; - clockLayout.windUnit.label = ""; clockLayout.weatherIcon.src = errIcon; } clockLayout.clear(); diff --git a/apps/wid_a_battery_widget/ChangeLog b/apps/wid_a_battery_widget/ChangeLog index 9b0649c27..b04824ae8 100644 --- a/apps/wid_a_battery_widget/ChangeLog +++ b/apps/wid_a_battery_widget/ChangeLog @@ -1,2 +1,3 @@ 1.00: Release for Bangle 2 (2021/11/18) 1.01: Internal id update to wid_* as per Gordon's request (2021/11/21) +1.02: Support dark themes \ No newline at end of file diff --git a/apps/wid_a_battery_widget/widget.js b/apps/wid_a_battery_widget/widget.js index 9fb06e320..8ab644ab3 100644 --- a/apps/wid_a_battery_widget/widget.js +++ b/apps/wid_a_battery_widget/widget.js @@ -1,9 +1,9 @@ (function(){ let COLORS = { - 'white': "#fff", - 'black': "#000", + 'white': g.theme.dark ? "#000" : "#fff", + 'black': g.theme.dark ? "#fff" : "#000", 'charging': "#08f", - 'high': "#000", + 'high': g.theme.dark ? "#fff" : "#000", 'low': "#f00", }; diff --git a/core b/core index 23854083e..b033af017 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 23854083e0c3f83c649073a2d85e8079efc471d3 +Subproject commit b033af017f6789a6a7777e6ef1428d94995a9b8b