From c28d85ad1fc18f2a326858ddc5dfc0842d7b13e5 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 11 Jun 2022 09:00:47 +0200 Subject: [PATCH 01/19] sleepphasealarm: add settings file - Vibrate with configured pattern - Add setting to defer start of algorithm --- apps/sleepphasealarm/ChangeLog | 2 + apps/sleepphasealarm/README.md | 17 +++- apps/sleepphasealarm/app.js | 130 +++++++++++++++++----------- apps/sleepphasealarm/interface.html | 1 - apps/sleepphasealarm/metadata.json | 3 +- apps/sleepphasealarm/settings.js | 37 ++++++++ 6 files changed, 135 insertions(+), 55 deletions(-) create mode 100644 apps/sleepphasealarm/settings.js diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog index 208058472..4ca4fb723 100644 --- a/apps/sleepphasealarm/ChangeLog +++ b/apps/sleepphasealarm/ChangeLog @@ -7,3 +7,5 @@ use Layout library and display ETA 0.07: Add check for day of week 0.08: Update to new time_utils module +0.09: Vibrate with configured pattern + Add setting to defer start of algorithm diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md index c33c9c807..218ce5363 100644 --- a/apps/sleepphasealarm/README.md +++ b/apps/sleepphasealarm/README.md @@ -4,10 +4,19 @@ The alarm must be in the next 24h. The display shows: -- the current time -- time of the next alarm or timer -- time difference between current time and alarm time (ETA) -- current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging +- The current time. +- Time of the next alarm or timer. +- Time difference between current time and alarm time (ETA). +- Current state of the ESS algorithm, "Sleep" or "Awake", useful for debugging. State can also be "Deferred", see the "Run before alarm"-option. + +## Settings + +* **Keep alarm enabled** + - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00. + - No: No action at configured alarm time from scheduler. +* **Run before alarm** + - disabled: (default) The ESS algorithm starts immediately when the application starts. + - 1..23: The ESS algorithm starts the configured time before the alarm. E.g. when set to 1h for an alarm at 7:00 the ESS algorithm will start at 6:00. This improves battery life. ## Logging diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index febc8a259..23df53b22 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -1,9 +1,18 @@ const BANGLEJS2 = process.env.HWVERSION == 2; // check for bangle 2 +const CONFIGFILE = "sleepphasealarm.json"; const Layout = require("Layout"); const locale = require('locale'); const alarms = require("Storage").readJSON("sched.json",1) || []; -const config = require("Storage").readJSON("sleepphasealarm.json",1) || {logs: []}; +const config = Object.assign({ + logs: [], // array of length 31 with one entry for each day of month + settings: { + startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time + disableAlarm: false, + } +}, require("Storage").readJSON(CONFIGFILE,1) || {}); const active = alarms.filter(a=>a.on); +const schedSettings = require("sched").getSettings(); +let buzzCount = schedSettings.buzzCount; let logs = []; // Sleep/Wake detection with Estimation of Stationary Sleep-segments (ESS): @@ -43,7 +52,8 @@ function calc_ess(acc_magn) { } // locate next alarm -var nextAlarm; +var nextAlarmDate; +var nextAlarmConfig; active.forEach(alarm => { const now = new Date(); const time = require("time_utils").decodeTime(alarm.t); @@ -52,8 +62,9 @@ active.forEach(alarm => { dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000)); } if ((alarm.dow >> dateAlarm.getDay()) & 1) { // check valid day of week - if (nextAlarm === undefined || dateAlarm < nextAlarm) { - nextAlarm = dateAlarm; + if (nextAlarmDate === undefined || dateAlarm < nextAlarmDate) { + nextAlarmDate = dateAlarm; + nextAlarmConfig = alarm; } } }); @@ -69,8 +80,8 @@ var layout = new Layout({ }, {lazy:true}); function drawApp() { - var alarmHour = nextAlarm.getHours(); - var alarmMinute = nextAlarm.getMinutes(); + var alarmHour = nextAlarmDate.getHours(); + var alarmMinute = nextAlarmDate.getMinutes(); if (alarmHour < 10) alarmHour = "0" + alarmHour; if (alarmMinute < 10) alarmMinute = "0" + alarmMinute; layout.alarm_date.label = "Alarm at " + alarmHour + ":" + alarmMinute; @@ -80,7 +91,7 @@ function drawApp() { if (Bangle.isLCDOn()) { const now = new Date(); layout.date.label = locale.time(now, BANGLEJS2 && Bangle.isLocked() ? 1 : 0); // hide seconds on bangle 2 - const diff = nextAlarm - now; + const diff = nextAlarmDate - now; const diffHour = Math.floor((diff % 86400000) / 3600000).toString(); const diffMinutes = Math.floor(((diff % 86400000) % 3600000) / 60000).toString(); layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0'); @@ -92,70 +103,91 @@ function drawApp() { setInterval(drawTime, 500); // 2Hz } -var buzzCount = 19; function buzz() { if ((require('Storage').readJSON('setting.json',1)||{}).quiet>1) return; // total silence - Bangle.setLCDPower(1); - Bangle.buzz().then(()=>{ - if (buzzCount--) { - setTimeout(buzz, 500); - } else { - // back to main after finish - setTimeout(load, 1000); - } - }); + Bangle.setLCDPower(1); + require("buzz").pattern(nextAlarmConfig.vibrate || ";"); + if (buzzCount--) { + setTimeout(buzz, schedSettings.buzzIntervalMillis); + } else { + // back to main after finish + setTimeout(load, 1000); + } } function addLog(time, type) { logs.push({time: time, type: type}); - require("Storage").writeJSON("sleepphasealarm.json", config); + if (logs.length > 1) { // Do not write if there is only one state + require("Storage").writeJSON(CONFIGFILE, config); + } } // run var minAlarm = new Date(); var measure = true; -if (nextAlarm !== undefined) { - config.logs[nextAlarm.getDate()] = []; // overwrite log on each day of month - logs = config.logs[nextAlarm.getDate()]; +if (nextAlarmDate !== undefined) { + config.logs[nextAlarmDate.getDate()] = []; // overwrite log on each day of month + logs = config.logs[nextAlarmDate.getDate()]; g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); let swest_last; // minimum alert 30 minutes early - minAlarm.setTime(nextAlarm.getTime() - (30*60*1000)); - Bangle.on('accel', (accelData) => { // 12.5Hz - const now = new Date(); - const acc = accelData.mag; - const swest = calc_ess(acc); + minAlarm.setTime(nextAlarmDate.getTime() - (30*60*1000)); + run = () => { + layout.state.label = "Start"; + layout.render(); + Bangle.on('accel', (accelData) => { // 12.5Hz + const now = new Date(); + const acc = accelData.mag; + const swest = calc_ess(acc); - if (swest !== undefined) { - if (Bangle.isLCDOn()) { - layout.state.label = swest ? "Sleep" : "Awake"; - layout.render(); - } - // log - if (swest_last != swest) { - if (swest) { - addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz - } else { - addLog(now, "awake"); + if (swest !== undefined) { + if (Bangle.isLCDOn()) { + layout.state.label = swest ? "Sleep" : "Awake"; + layout.render(); + } + // log + if (swest_last != swest) { + if (swest) { + addLog(new Date(now - sleepthresh*13/12.5*1000), "sleep"); // calculate begin of no motion phase, 13 values/second at 12.5Hz + } else { + addLog(now, "awake"); + } + swest_last = swest; } - swest_last = swest; } - } - if (now >= nextAlarm) { - // The alarm widget should handle this one - addLog(now, "alarm"); - setTimeout(load, 1000); - } else if (measure && now >= minAlarm && swest === false) { - addLog(now, "alarm"); - buzz(); - measure = false; - } - }); + if (now >= nextAlarmDate) { + // The alarm widget should handle this one + addLog(now, "alarm"); + setTimeout(load, 1000); + } else if (measure && now >= minAlarm && swest_last === false) { + addLog(now, "alarm"); + buzz(); + measure = false; + if (config.settings.disableAlarm) { + // disable alarm for scheduler + nextAlarmConfig.last = now.getDate(); + require("Storage").writeJSON("sched.json", alarms); + } + } + }); + }; drawApp(); + if (config.settings.startBeforeAlarm === 0) { + // Start immediately + run(); + } else { + // defer start + layout.state.label = "Deferred"; + layout.render(); + const diff = nextAlarmDate - Date.now(); + let timeout = diff-config.settings.startBeforeAlarm*60*60*1000; + if (timeout < 0) timeout = 0; + setTimeout(run, timeout); + } } else { E.showMessage('No Alarm'); setTimeout(load, 1000); diff --git a/apps/sleepphasealarm/interface.html b/apps/sleepphasealarm/interface.html index 9a7cb0f93..f45c183e1 100644 --- a/apps/sleepphasealarm/interface.html +++ b/apps/sleepphasealarm/interface.html @@ -1,7 +1,6 @@ -

Please select a wakeup day:

diff --git a/apps/sleepphasealarm/metadata.json b/apps/sleepphasealarm/metadata.json index c74a617ab..6ec5f4180 100644 --- a/apps/sleepphasealarm/metadata.json +++ b/apps/sleepphasealarm/metadata.json @@ -2,7 +2,7 @@ "id": "sleepphasealarm", "name": "SleepPhaseAlarm", "shortName": "SleepPhaseAlarm", - "version": "0.08", + "version": "0.09", "description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.", "icon": "app.png", "tags": "alarm", @@ -11,6 +11,7 @@ "dependencies": {"scheduler":"type"}, "storage": [ {"name":"sleepphasealarm.app.js","url":"app.js"}, + {"name":"sleepphasealarm.settings.js","url":"settings.js"}, {"name":"sleepphasealarm.img","url":"app-icon.js","evaluate":true} ], "data": [{"name":"sleepphasealarm.json","storageFile":true}], diff --git a/apps/sleepphasealarm/settings.js b/apps/sleepphasealarm/settings.js new file mode 100644 index 000000000..a79abb598 --- /dev/null +++ b/apps/sleepphasealarm/settings.js @@ -0,0 +1,37 @@ +(function(back) { + const CONFIGFILE = "sleepphasealarm.json"; + // Load settings + const config = Object.assign({ + logs: [], // array of length 31 with one entry for each day of month + settings: { + startBeforeAlarm: 0, // 0 = start immediately, 1..23 = start 1h..23h before alarm time + disableAlarm: false, + } + }, require("Storage").readJSON(CONFIGFILE,1) || {}); + + function writeSettings() { + require('Storage').writeJSON(CONFIGFILE, config); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "SleepPhaseAlarm" }, + 'Keep alarm enabled': { + value: !!config.settings.disableAlarm, + format: v => v?"No":"Yes", + onchange: v => { + config.settings.disableAlarm = v; + writeSettings(); + } + }, "< Back" : () => back(), + 'Run before alarm': { + format: v => v === 0 ? 'disabled' : v+'h', + value: config.settings.startBeforeAlarm, + min: 0, max: 23, + onchange: v => { + config.settings.startBeforeAlarm = v; + writeSettings(); + } + }, + }); +}) From fd1cab5b96884de25435e7c633ffd257b4a3d2bf Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sat, 11 Jun 2022 09:05:31 +0200 Subject: [PATCH 02/19] sleepphasealarm. updated documentation --- apps/sleepphasealarm/ChangeLog | 2 ++ apps/sleepphasealarm/README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog index 4ca4fb723..6bf296342 100644 --- a/apps/sleepphasealarm/ChangeLog +++ b/apps/sleepphasealarm/ChangeLog @@ -9,3 +9,5 @@ 0.08: Update to new time_utils module 0.09: Vibrate with configured pattern Add setting to defer start of algorithm + Add setting to disable scheduler alarm + diff --git a/apps/sleepphasealarm/README.md b/apps/sleepphasealarm/README.md index 218ce5363..ecb3feb06 100644 --- a/apps/sleepphasealarm/README.md +++ b/apps/sleepphasealarm/README.md @@ -12,7 +12,7 @@ The display shows: ## Settings * **Keep alarm enabled** - - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at 6:45 (the calculated time from the ESS algorithm) and again at 7:00. + - Yes: (default) Alert will stay enabled, e.g. for an alarm at 7:00 the clock will buzz at the calculated time from the ESS algorithm (for example 6:45) and again at 7:00. - No: No action at configured alarm time from scheduler. * **Run before alarm** - disabled: (default) The ESS algorithm starts immediately when the application starts. From 7fcd86b4bca38585693ca66ac17876108b60f723 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sun, 12 Jun 2022 10:39:48 +0200 Subject: [PATCH 03/19] sleepphasealarm: Replace setInterval with setTimeout --- apps/sleepphasealarm/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 23df53b22..92f4b3dc7 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -97,10 +97,13 @@ function drawApp() { layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0'); layout.render(); } + + setTimeout(()=>{ + drawTime(); + }, 1000 - (Date.now() % 1000)); } drawTime(); - setInterval(drawTime, 500); // 2Hz } function buzz() { From 19c3e0e20eb347958e523bd2d96a23d7e07109ed Mon Sep 17 00:00:00 2001 From: Alessandro Cocco Date: Mon, 25 Apr 2022 20:54:52 +0200 Subject: [PATCH 04/19] [Scheduler] Remove custom boolean formatter The new menu system handles booleans by default --- apps/sched/settings.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/sched/settings.js b/apps/sched/settings.js index a2b3a5241..b73cd41d1 100644 --- a/apps/sched/settings.js +++ b/apps/sched/settings.js @@ -4,11 +4,10 @@ E.showMenu({ "": { "title": /*LANG*/"Scheduler" }, - /*LANG*/"< Back": () => back(), + "< Back": () => back(), /*LANG*/"Unlock at Buzz": { value: settings.unlockAtBuzz, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.unlockAtBuzz = v; require("sched").setSettings(settings); @@ -17,7 +16,6 @@ /*LANG*/"Default Auto Snooze": { value: settings.defaultAutoSnooze, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.defaultAutoSnooze = v; require("sched").setSettings(settings); @@ -38,7 +36,6 @@ /*LANG*/"Default Repeat": { value: settings.defaultRepeat, - format: v => v ? /*LANG*/"Yes" : /*LANG*/"No", onchange: v => { settings.defaultRepeat = v; require("sched").setSettings(settings); From fa2fa9e4a721145ceebd9536ca391f3bc1063472 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Tue, 14 Jun 2022 20:09:57 +0200 Subject: [PATCH 05/19] sleepphasealarm: set acc fixed intervall --- apps/sleepphasealarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 92f4b3dc7..9f2e6c3b4 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) { run = () => { layout.state.label = "Start"; layout.render(); - Bangle.on('accel', (accelData) => { // 12.5Hz + Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval + Bangle.on('accel', (accelData) => { const now = new Date(); const acc = accelData.mag; const swest = calc_ess(acc); From ee8f62d250b8c91732d5d21c5841b7ca31055295 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Tue, 14 Jun 2022 20:29:10 +0200 Subject: [PATCH 06/19] sleepphasealarm set powerSave=false do not dynamically change accelerometer poll interval --- apps/sleepphasealarm/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index 9f2e6c3b4..b19799c4b 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -141,7 +141,8 @@ if (nextAlarmDate !== undefined) { run = () => { layout.state.label = "Start"; layout.render(); - Bangle.setPollInterval(80); // 12.5Hz, do not dynamically change accelerometer poll interval + Bangle.setOptions({powerSave: false}); // do not dynamically change accelerometer poll interval + Bangle.setPollInterval(80); // 12.5Hz Bangle.on('accel', (accelData) => { const now = new Date(); const acc = accelData.mag; From 924ec23211092b304c135ff2b2e503c24f962b24 Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Wed, 15 Jun 2022 09:23:14 +0200 Subject: [PATCH 07/19] updates Github action and replaces TravisCI badge --- .github/workflows/nodejs.yml | 30 +- .gitignore | 1 - README.md | 2 +- package-lock.json | 2168 ++++++++++++++++++++++++++++++++++ 4 files changed, 2182 insertions(+), 19 deletions(-) create mode 100644 package-lock.json diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 1eb009153..a3469e7bb 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -1,4 +1,4 @@ -name: Node CI +name: build on: [push, pull_request] @@ -6,29 +6,25 @@ jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x] - steps: - name: Checkout repository and submodules - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - - name: install testing dependencies - run: npm i - - name: test all apps and widgets - run: npm run test - - name: install typescript dependencies + node-version: 16.x + - name: Install testing dependencies + run: npm ci + - name: Test all apps and widgets + run: npm test + - name: Install typescript dependencies working-directory: ./typescript run: npm ci - - name: build types + - name: Build types working-directory: ./typescript run: npm run build:types - - name: build all TS apps and widgets + - name: Build all TS apps and widgets working-directory: ./typescript - run: npm run build \ No newline at end of file + run: npm run build diff --git a/.gitignore b/.gitignore index 231851dd6..a9398e871 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .htaccess node_modules -package-lock.json .DS_Store *.js.bak appdates.csv diff --git a/README.md b/README.md index b3da9f685..e8d5579c0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Bangle.js App Loader (and Apps) ================================ -[![Build Status](https://app.travis-ci.com/espruino/BangleApps.svg?branch=master)](https://app.travis-ci.com/github/espruino/BangleApps) +[![Build Status](https://github.com/espruino/BangleApps/actions/workflows/nodejs.yml/badge.svg)](https://github.com/espruino/BangleApps/actions/workflows/nodejs.yml) * Try the **release version** at [banglejs.com/apps](https://banglejs.com/apps) * Try the **development version** at [espruino.github.io](https://espruino.github.io/BangleApps/) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..6872e616c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2168 @@ +{ + "name": "BangleApps", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@eslint/eslintrc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "requires": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "dev": true + } + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "global-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", + "dev": true, + "requires": { + "ini": "2.0.0" + } + }, + "globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-npm": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "nodemon": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.16.tgz", + "integrity": "sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "update-notifier": "^5.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "npm-watch": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/npm-watch/-/npm-watch-0.11.0.tgz", + "integrity": "sha512-wAOd0moNX2kSA2FNvt8+7ORwYaJpQ1ZoWjUYdb1bBCxq4nkWuU0IiJa9VpVxrj5Ks+FGXQd62OC/Bjk0aSr+dg==", + "dev": true, + "requires": { + "nodemon": "^2.0.7", + "through2": "^4.0.2" + } + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dev": true, + "requires": { + "escape-goat": "^2.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "update-notifier": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", + "dev": true, + "requires": { + "boxen": "^5.0.0", + "chalk": "^4.1.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} From 67e2fb24003b0d74c0100bef04e9b02fa5aaef37 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 15 Jun 2022 10:41:45 +0200 Subject: [PATCH 08/19] Add a simple watchface to learn Hiragana and Katakana --- apps/kanawatch/ChangeLog | 1 + apps/kanawatch/README.md | 12 + apps/kanawatch/app-icon.js | 1 + apps/kanawatch/app.js | 825 ++++++++++++++++++++++++++++++++++ apps/kanawatch/app.png | Bin 0 -> 15313 bytes apps/kanawatch/metadata.json | 31 ++ apps/kanawatch/screenshot.jpg | Bin 0 -> 21235 bytes 7 files changed, 870 insertions(+) create mode 100644 apps/kanawatch/ChangeLog create mode 100644 apps/kanawatch/README.md create mode 100644 apps/kanawatch/app-icon.js create mode 100644 apps/kanawatch/app.js create mode 100644 apps/kanawatch/app.png create mode 100644 apps/kanawatch/metadata.json create mode 100644 apps/kanawatch/screenshot.jpg diff --git a/apps/kanawatch/ChangeLog b/apps/kanawatch/ChangeLog new file mode 100644 index 000000000..7b83706bf --- /dev/null +++ b/apps/kanawatch/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/kanawatch/README.md b/apps/kanawatch/README.md new file mode 100644 index 000000000..1fdf1927c --- /dev/null +++ b/apps/kanawatch/README.md @@ -0,0 +1,12 @@ +# kanawatch + +A simple watchface design with hiragana and katakana +cards for learning. + +## Author + +Written by pancake in 2022, powered by insomnia + +## Screenshots + +![hiragana and katakana](screenshot.jpg) diff --git a/apps/kanawatch/app-icon.js b/apps/kanawatch/app-icon.js new file mode 100644 index 000000000..a17f21d56 --- /dev/null +++ b/apps/kanawatch/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxEBAH4A/AEn/AAgrrAA4ttGL4hF9fGsU1pMNmti43rGLwcD/3MxEAud413p6uuvFzgGI5n+GDQaD6F8i2p8KKH8Opi186AwYC4Xv08A0fnXhfn0cA0/vGCoVC7+ItHNE4vQ+oxH5toxHfGCYTC8t/xaKH5VY+CUIxd/8owSCIPxymB8wkH8UA2yTI82Byn4F6AXCwNH7YjI7UATAwAD7dHHgYuP4sAc5XLgHrBpXAjngGBwOCrmJ/whJ1syBgXw7v6Bov+xObF5rWDgHWKJWEt3l4mQjkAoHzBwvWgHhGBgMC1WIDQuw1/L427z8ygAABp+R3vqH4+I1QvO/1R5YZF+t1FINWuMAy/W+BuKZ4NRT4ReL7kc+waG/fy/n/9kA74tLAAP2jncAgPBF5W5yIeLZgPxEgf3CJOR3JTCF5WU3wvL6sA/YFC7e0CJO+ygDB94vKt3aF5fHoQDB+/dzdL4nb+YRG7VuAYP5F5VF9ovL3dP3t8pOKgFw0+CjmT84RE9tFAYP+F6/uwMm1Hd/vCk3oQYWGl3XF6aPK/e0oVwrohCmu9Bof5sVF+yPSd5PtuWA9m7o///uCwH9B4m9gHKd6W5yIuG9NV3v+//Gjn/2VA9wQF6UA2AFCyO5AYPcF5Xcjh1DAAPnp/SEYnJiy2EAAXTgGvAgP2jncAgPBF44wC/1R5a7EsZHCAAPegEA3afH4sA4wEB5dROgP/FxBgD1WIPgky/QGD5MAxYfCAAuGjnvAgNHuBLCF5nhgHWAoWvuwEC9mWLwN+Fw6aB1wEB60A44EB6ovJGAebxJSC1lF4/AyMNoXBzUN/IuF5kmyP8VgOJrgKCFxUB8QOB8Ec4CnCLIMAmWr+v/9Vy/otD+WWmu7BAXAjnFF5xgD21H7f//u+0vN/CKH9Ojse4+QHC7dH2wuPgPVCAP4yk98wqHAAf734OF82ByhCDF5pgD/9/xfhGBYAF8OLv/lFyIABU4XfxFo5ouP5toxHfFyZhE9+ngGj84tL8+jgGn94uVSQvQvkW1KUI8Opi186AIDFygwF/3MxEAuew6fp9PT2FzgGI5n+FzQwFAAPr42fu9JpN3z/G9YPFFzAxIABYtbGKItfGZYrlAH4A+A")) diff --git a/apps/kanawatch/app.js b/apps/kanawatch/app.js new file mode 100644 index 000000000..ada6aa6df --- /dev/null +++ b/apps/kanawatch/app.js @@ -0,0 +1,825 @@ +const stripe_width = 32; +const stripe_pos = 40; +const stripe2_pos = 110; +const h = g.getHeight(); +const w = g.getWidth(); + +/// ///////////////////////////////////////// +const katakana = {}; +const hiragana = {}; +katakana.A = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAjAEBfv4B/+yeAXwAOgBAAPAAAEHAAABzAAAAPgAAADgAAAAwAAAAMAAAAGAAAABgAAAAYAAAAMAAAADAAAABgAAAAYAAAAMAAAAGAAAADAAAABgAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.A = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAAAIAAAACAAAABgAAAAZ4AAGf4AAA/gAAAAQAAAAEAAAABBAAAAQwAAAN/wAADiGAADxAwABswEAAhYBgAQUAYAMHAEACBgDABh4AwAZ2AYAD4gcAAQAcAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.I = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAwAAAAGAAAADwAAAA0AAAAYAAAAUgAAAGAAAAFAAAADgAAAA8AAAA2AAAAZgAAAYYAAAMGAAAMFgAAGAYAAGAGAACABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.I = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAgAEAAEABAAAgAQAAMAGAABAAgAAYAIAAGACAAAwAQAAMAEAADABiAAQAIgAAADQAAAAcAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.U = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAQAAAAHAAAAAwAAAAICAAACIAAAAgIABQa3AAP7q4ADQANAAwADAAMABgADAAYAAwAGAAMADAADAAwAAwAYAAMAGAABADAAAABgAAAAwAAAAMAAAAGAAAACQAAADAAAABgAAAAwAAAAoAAAAAAAAAAAAAAAgAAA=') +}; +hiragana.U = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAIAAAABwAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAA4YAAA4CAAAAAgAAAAIAAAACAAAAAgAAAAYAAAAGAAAABAAAAAQAAAAIAAAACAAAABAAAAAQAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.E = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAJXAAe+20ADRQAAAAOAAAABgAAAAQAAAAMAAAABAAAAAwAAAAEAACABAEAgJbvgP9qSsByAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.E = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAADgAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAdwAAAcYAAB8MAAAIGAAAADAAAABgAAAAwAAAAYAAAAMAAAAGAAAADIAAAB4gAAA4EAAAMAgAACAOGAAAB/wAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.O = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAADwAAAAOAAAADAAAAAwAAAAMAAAAjAABAAydAbff/wH/XAUAwDwAAAB0AAAA7AAAAMwAAAHMAAADjAAABkwAAA4MAAAZDAAAMEwAAGEMAAGQzAADAHwABAA8AAAAHAAAABAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.O = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADACAAAwAYAAMADAADIAQAA/AGAF+AAAAyAAAAAgAAAAIAAAACAAAAAg/gAAJwOAADgBgABgAMAAoADAAyAAwAIgAMAEIAGABCADAAJgBgAD4AgAAMAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAcGAAADgwAAB4HAAA4A4AAMgHAAHAA4ADAAXAAwAA4AYAAHAMAABwGAAAMGAAACDAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAABAACAAYAAwAGAAMABgACAAYAAgAHwAIAD4AGAfYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAOGAAQEfgAFCA8ABggPwAYG+GAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAXAAAABwAAAAYAgAAGAMAABgDgABYD0AAWF4gABvwAAAfAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAgAAal8AAD//gAAJQAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAA8BAAB2AYAABACAAAwAQAAIAEAAGAJgABACIAAwAjAAIAIYACACGABABAwAQAQEAEAEAABADAAAAAgAAEAYAABAEAAAYDAAADDgAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAAALwAYt/vAD/0DwAcABwAACAcAAAAGAAAADIAAAAwAAAAYAAAAOAAAAGAAAADgAAAAwAAAA0AAAAaAAAAOAAAAHAAAAHAAAAHAAAAGgAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAACAAAAAQAAAACAgAAAgEAAAMBgAABAYAgAwDAMAMAgBgCAAAYHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAANwAAAGHAAADA4AABwDgAIwBOADcABwQeAAHgDAAA8AIAADwAAAAeAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAIMAAAMAgAAGAGAADAAwAAAADAAAAAYAAAADgAAAAMAAAABwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.HO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAEAAAADQAAAAYAAAASAAAABgAAAAIAACAGK4A273dAHoYAAAAGAAAAAgAAAIIQAAECGAABAgwAAgYGAAIGAwAGAgGADAIBwBiCAaAYRgDAMDIAgAAeAAAADgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.HO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAQB+AAEAgAABAAQAAQAGAAIABgACAAQAAgAHwAIAD4ACAfQABAAEAAQABAAEAAQABAAGAAQABgAEAAYABAAGAAQBdgAHAg4ABwAHgAIB+OACAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAUAAAADwAAAAcAAAAGAAAABgAAAAYFABAOvwAfv9eAD6wHAAQMBwAADAYAABwGAAAYBgAAGAYAADAOAAAwDAAAYgwAAMgcAADEmAAFgzgAAwHwAA4B4ABYAcAAMABAAEAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAAAIAAAACAAAABAAAAAQAgAAMAEAAD8AwAHggGAHQIBgAECAMADAgDAAgIAQAIGAEAEBAAABAwAAAwIAAAYGAAAGBgAAADwAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAACwAAAAeAAAADgAAAAYAAAATBgAAAz8AAAP5AAxfQAAH8YAAA4GAAAABgHAAAYf4AAD+pAAF8AAMPsAAC/hgAAPAYAABAGAAAABwAAAAYAAAAHAAAAAwAAAAOAAAADAAAAAYAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAAGAAAAAgAAAAIAAAADDAAAAfwAAAeAAAA4gAAAwIAAAABAAAAAZwAAADwAAAHwAAAOGAAAAAgAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAEAAAABgAAAAPmAAAAfwAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAAHAAAAA4AAAAMAAAAHBwAAB/+AAA0XAAAaBkAAGA4AADAOAABgHAAAwBwAAYA4AAMAMAAGAHAAAADgAAABwAAAA0AAAAaAAAAOAAAAHAAAADIAAADgAAACgAAABgAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAADAAAABgAAAAQAAAAIAAAAGAAAABAAAAAgAAAAQAAAAEAAAACAAAAAQAAAAEAAAAAgAAAAEAAAABgAAAAIAAAADAAAAAYAAAAGAAAAAwAAAAMAAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAABwAAAAOAAAADgAAABwAAAAYAQAAGAAgABgF8AA79/gAb7gAAGQcQADAHgABgBgAAYAwAAZAMAAMAHAADABgAAgAwAAAAMAAAAGAAAALAAAABwAAAAYAAAAYAAAAMgAAAGAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAABAAAAAYAAIAGAAGABgABgAYAAYAGAAEAB+ABAB/gAQHmAAEABgADAAYAAgAGAAIABgACAAYAAgAGAAIABAACAAQAAgAEAAKABAADgAwAAYAIAAGACAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.KO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwCtwAH//8AA+oGAAEABgAAAAYAAAAGAAAABgAAAAQAAAAsAAAADAAIAFwADv//AAf1CQACAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.KO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/8AAAADwAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAYAAAAD8EAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAFcAIG/3ga/0h4H6gA4AcAAcACAAOAAAAHAAAYDAAAFjgAAAPgAAAB4AAAAOAAAABwAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABBAAAAf8AAD+AAAOBAAAAAQAAAAGAAAABgAAAAZwAAAHwAAB/gAAAAYAAAAGAAAABgAAAAYAAAAGAAAARgAAAR4AAAIHgAACDPAAARg4AABAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAegAAAC+gAAAB8AAAAHgAAAAYAAAAQAAAAgAAAegAAAB+AAAAD4AAAAPAAAABwAAAAMAAAAAAAAAAAAAAAAAAAUAAAAF8AAAAHwAAAAPgAAAA8AAAAHwAAAAeAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAAA+YAAAEMAAAADAAAABgAAAAQAAAAMAAAACAAAABgAAAAQAAAAIAIAAGAGAADgBgAO/wQAEIH8ACEAH4AiABnAJgAQQBgAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAACgAAAAcAAAADgAAAA4AAAAcAAAAHAAAABkAAAAYAAAAMQAAADEAAABwwAAAYGAAAGAwAADAHAAAwA4AAIAOAAWBfwBBX9OAf/oDgH+gAYA6AAGAAEAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAYAAAACAAAAAgAwAAIAGAACIAwAA/gEAB+ABAB2AAAAAgAAAAYAAAAGAAAABgAAAAYAAAAGAEAABgBAAGQAQAA0AEAAFABAAAwAQAAEAMAARgCAAGWHgAA8fgAAGAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.ME = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAcAAAABgAAAAcAAAAHAAAADgAAAAwAAABcAABgGAAAfDgAAAewAAAB8AAAAPAAAAD8AAABzgAAA44AAAcHAAAGAwAADAAAACgAAABwAAAAoAAAAcAAAAMAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.ME = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABgAAAAYAABAGAAAIBAAACAwAAAgP4AAMeDgABZgMAAYQBgAOMAYAGiACADJgAgAjQAIAQcACAEGABgBBgAQARsAIAHwAEAAQAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.MO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAABAAUAASXfgAD7EQAAQwAAAAOAAAABAAAAAwAAAAEAUBADd/wNfaRID1EAAAIDAAAAAwAAAAEAAAADAAAAAQAAAAMAAAABiQAAAf+AAABKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.MO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAIAAAACAAAAB+AAAA/wAAB0AAAABAAAAAQAAAAEAAAABAAAAAQAAAAEYAAAf+AAABwAAAAMAAAACAIAAAgCAAAIAgAACAIAAAgCAAAEBAAABgwAAAP4AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAPAAAAA4AAAAOAAAADAAAAAwBAAAMQAAADAaBAT9/wf/vbcD6DAAAQAxAAAAMAAAADAAAAAwAAAAMAAAAGAAAABgAAAAYAAAAMAAAAGAAAABgAAAAwAAAAYAAAAMAAAAEAAAABAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAgAAAAJgAAAH4AAA/gAAAMQAIAAIABAACAAYABgACAAQAAAAMAAAACAIAAAgCAAAAAgAAAAIAAAACAAAAAgAAAPIAAAEOAAABB4AAAQTgAAD4MAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgALAANb/8AB/6pAAMAAAAAACAAAAAAAAAAAAAAAAAAAAAAABAAAIAAAJvAKN//4D/1EGAdAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAGAAAABgA/AAYBwAAEAAAABAAAAAQAAAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAAEAAAIAgAADAH/gAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFgAML38AB/9OAAOgHAAAQBgABAA4AAAAMAADoHAAAPRgAAAfYAAAB4gAAAPQAAADeAAABjwAABwcAAI4DgAA4AcAAcADAAcAAQAaAAAAWAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAABAwAAAIMAAACDf4AAg4DAAIYAYACeACAAZAAgAMQAIAFMACACSAAgBDgAIAwwOGAIMEbACHBDgAjYPsAPCABgBggAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAGAAAAA4AAAAHAAAAA4AAAAGAAAABgAAAAJYABAv/AAf+nwAD4DoAAQB4AAAA8AAAB8AAAAeAAAAPQAAAHzgAAHMeAAHDB4ADgwOAHgMBwHADAMKgAwAgAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAEAAAAAAAAAAAAA=') +}; +hiragana.NE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADAAAAAwAAAAIAAAADAHgAA8GIAA+CCAAzBAwAAhAMAAIgDAAGQAwABoAMAAsADAASAAwAFgAMAC4ACAAyAugAcgIYAGYCHABGAecABgABgAYAAIAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.NO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAABwAAAAeAAAAOAAAADgAAAAwAAAAcAAAANAAAADAAAABwAAAAYAAAAOAAAAHAAAABgAAAAwAAAAYAAAAMAAAAGAAAAGQAAADAAAADgAAAAkAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.NO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAD44AADEBAABBAIABgQBAAwMAYAICACAEBgAgAAQAIAgMACAICAAgCBgAYAwwAGAEIADABmAAgAPAAQADgAYAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAEAAQAIAANTvgAD/u0AAOAAAAAACAAAAAAABAACAAgAt4APf/vAB/UDQAIAJwAAAA4AAAAOAAAAHAAAABgAAAA4AAAAcAAAAOAAAAGgAAADQAAABoAAAA4AAAAcAAAAaAAAAMgAAAEIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAQAAAACAAAAAwAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAgAAAAYAAAAEAAAABAAAAAQAAAAEA+AADBwQAA3gCAAPgAgADAAIAAAAGAAAADAAAABgAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAQBwAAHgOAAAsDgAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAAGAwAABgMAAAYDAAACAwAAAAYAAAAGAAAADAAAAEwAAAA0AAAAcAAAAOAAAAOAAAAOAAAAGAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAABAAAAAYAAAAGAAAABAQAAAQGAAAEAgAABAIAAAwCAAAIAgAACAIAAAoCAAAOAgAADAIAAAQCAAAEAgAAAAYAAAAGAAAABAAAAAQAAAAEAAAACAAAAAgAAAAAAAAAEAAAACAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAeAAAADgAAAA4AAAcGAAADhgAAA4YAAAMGABAGDAAwBkYAYAYGAMAMDAOADAYHAAwGDgAYBjgAMgbwADAHyABgD4AAwA4AAYAEAAMAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAO4AAA8MAAAAGAAAADAAAAAgAAAAQAAAAIAAAAGAAAABAAAAAgAAAAQAAAAIYMAAE4BgAB4AIAA4ACAAMAAgAAAAYAAAAEAAATCAAAEZAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAACgAAAAeAAAADgAAAAwAAAAMAAAADAAAAAwAAYAMAAMADAAGAAwAGAAsADgADABgAAwBwAAMBwAADA4AAAw8AAAM8AAAD8AAAA+AAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAGAAAYDgAAfBIAANgiAAMQwgAAMYIAAHMCAAB2AgAAnAIAAJgCAAEwAgAAcAIAAvACAAewAggHMAIwBDADwAAwAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.RO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAYABk3/AAP/a4ADQAYAAwAGAAMABgABAAwAAwAMAAMADAABAAwAAQEMAAEASAADEt4AA/++QAGgAAADAAQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.RO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAF8wAAAwYAAAAMAAAACAAAABAAAAAwAAAAYAAAAEAAAACAAAABAAAAAg/gAARgGAAPgAgAHgAMADgADAAQAAwAAAAYAAAAOAAAAGAAAAGAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAFAAAAA4AABAHAAAdBgAABwYAAAYGAAAGBgAABgYABAYGrAYu//4H/aomA4YGAAAGBgAABgYAAAYGAAAGBgAABgwAAAYMAAACGAAAABgAAAAwAAAAYAAAAOAAAAGAAAADgAAABgAAAAgAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAGAAAABgAAAAIAAAADAAAAAQgAAAG8AAAB4AAAB8AAAPhgAAAAIAAAABAAAAAYAAAADAAAABwAAAAGAAAAAgAAAAAAAAAAAAAAAAAAAAAAAEAAAAAwAAAAH/AAAAHwAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAHgAAAAcAAAAjgAAAAYABAAAAAwEAAAYB4AAMAHgAGAA4ADAAWABgAAgAyAAAAYAAAAcAAAAOAAAAOAAAIHAAAUHgAABnwAAAPwAAAB4AAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAQAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAIAQAADA4AAAf4AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAEAAGC/gAE/9cAAOgOAAAgHAAAABwAAAA4AAAAcAAAAGAAAAHgAAAB2AAAA44AAAYHAAAcA4AAOAHAALAA4AHAAOAGgABgDAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAADAAAAAQAAAAEAAAABAAAAAQAAAAE/gAAf/4AH4QAAHAEAAAABAAAAAQAAAGkAAABFAAAARQAAAEcAAABDAAAAYwAAAB8AAAAGAAAABgAAAAQAAAAMAAAAGAAAABAAAABgAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAA4AAAAHgAAAA4AAAAMAAAADABAAAwG4CAN/vAw36DgH+wDgA6MBwACDA4AAAwZAAAMUAAADMAAAAyAAAAMAAAADAAAAAwAAAAMAAAADAGAAA//gAAL94AAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAgCAAAMAgAADAIAAAwCAAAMAgAADAf8AAx+AAAPhgAAPAQAA8wEAAMMBAAADAwAAAwcAAAEGAAABAAAAAQAAAACAAAAA8OAAAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.SO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAQAAAALAAIAA4ADAAeAAcAHAADIBwAAYA4AAHAOAAAwDAAAIBwAAAAYAAAAMgAAAHAAAADAAAABwAAAAYAAAAMAAAAOAAAAHAAAADgAAADgAAADgAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.SO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAYAAAAzAAAHxgAAAwwAAAAYAAAAEAAAACAAAABAAAAAgAAAAQDwAAIDwAAEGQAACOIAABeEAAAMCAAAAAAAAAAQAAAAEAAAABAAAAAYAAAADAAAAAYAAAADwAAAAMAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAOAAAABwAAAAcAAAAGBYAAB/fAAA1DgAAMA4AAGAcAABgHAAA4DAABdwwAAMPcAAGA+AADADkABgB8AAQAzAAAAMAAAAGAAAADAAAADgAAABwAAAA4AAAAYAAAAcAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAYAAAAEAAAADHgAAA/gAAH8AAAAmAAAABAAAAAQAAAAMAAAACAfgABg4AAAQAAAAEAAAADAAAAAgAAAAYAAAAEAAAADAAAAAwDjgAIAP8ACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAOAAAAH4AAAPwAAAvgAADe4AAL4OAABADAAABAwAQAAMV4ECv//B7/0IwPQmAAAgDAAAAQwAAAAMAAAADAAAABgAAAAYAAAAMAAAAGAAAACgAAAAwAAAAwAAAAsAAAAMAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAABAAAAAIAAAAGAAAABgAAAAQAAAAEAAAABHAAAB/AAAH4AAAACAAAAAgAAAAQAAAAEAAAABAAAAAQAAAAIPcAACMBgAAsAIAAcACAAGAAgAAAAIAAAAGAAAADAAAABgAAABgAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAACAAAAAyBgAgHAOAGA4DwAwOA8AGBgcABwYHAAcADgADAA4AAQAcAAAAGAAAALgAAABwAAAAYAAAAMAAAAOAAAADAAAADgAAABwAAABwAAABwAAADRAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/HAAB4AYADwACAPwAAwBgAAMAAAADAAAAAgAAAAYAAAAEAAAADAAAADAAAADgAAADAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAACAACAn4AC3/vAAHoAAACQAAAAAAIAAAIAAAgAFfQG3+/8B/YwBAGAOAAAADgAAABgAAAAcAAAAGAAAADAAAABQAAAAYAAAAOAAAADAAAABgAAAAwAAAAwAAAAYAAAAKAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.TE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAPAAAAbgAAA5gAABwgAADwYAAHgEAAAgCAAAABAAAAAQAAAAAAAAACAAAAAgAAAAIAAAACAAAAAQAAAAEAAAAAgAAAAOAAAABwAAAAHAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.TO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAA4AAAAHgAAAA4AAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAD6AAAAzwAAAMPAAADA4AAAwHAAAMAwAADAEAAAwAAAAMAAAADAAAAAwAAAAMAAAAGAAAABwAAAAMAAAAAAAAAAAAAAAIAAAAAAAA=') +}; +hiragana.TO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAGAAAAAgAAAAMAYAABAHAAAQHAAAGDAAAAhgAAAIwAAABwAAAAYAAAAMAAAAEAAAACAAAABAAAAAQAAAAAAAAACAAAAAAAAAAGAAAAAf/wAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAACAAANACsAB7//gAPtI4AJgAOAAYADAAMABwABgAYACYAGAAOABgABgA4AAwAcAAGAHAABADgAAAAwAAAAcAAAAOAAAAHAAAADgAAADgAAADgAAAFwAAACgAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAADAAAAAwAAAAMAAAADAAAAA8AAAAfAAAAfgAAAIwAAAAIDnAAGCAYACiACAArAAwATAAMAJgADAD4AAgByAAYARgAEAAYACAAGACAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WI = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAQAAAAPAAAAA4AAAAMAAAADAAAAAwAAAAsEABhLvgAP//cAB5MAAAGDAAADAwAAAQMAAAMDAAADAwcBg19/wf/7UsD1AwAAIAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WI = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAbAAAB4wAAAMIAAAACAAAABgAAAAQAAAAEAAAADAAAAA3+AAAeAwAAeAGAAZAAgAMQAMAEMADACCAAwBBgAMAwQACAIMDxgBCBGwARAQYADgCcAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WE = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAFBK4AB//+AAPUHgABADgAAARwAAAOwAAABwAAAAMAAAADAAAAAwAAAAMAAAALAAAgAyVgPv//+B/qIrgIAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WE = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAA8AAAB3AAAHhgAAAAwAAAAYAAAAMAAAAGAAAADAAAABhwAAAzDAAAaAYAAOAGAADADAAACRgAAANgAAAGAAAADAAAABgAAAAgAAAAwAcAAYAxwAfggGAOGwAwDA4AAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.WO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAABAAAgAAwAO37/AB//bwAMgAwAAABYAAgAHAAAABgAGFb4AA//uAAHQDAAAAQwAAAAYAAAAOAAAADAAAABgAAAAwAAAAsAAAAGAAAADAAAABgAAABoAAAAwAAAA4AAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.WO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAACOAAAB/AAAPwAAAAMAAAACAAAABAAAAAwAgAAIAcAAHMMAADBOAAAAeAAAAGAAAADgAAADIAAABCAAAAgAAAAIAAAACAAAAAgAAAAGBwAAAP8AAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YA = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAEAAAAD4AAAAOAAAADAAAAAwAIAAGADAABgX4AAa/fAAX6OAZfwHAD9MDgAcDBgAEAwwAAAmYAAABogAAAYAAAAGAAAABgAAAAcAAAADAAAAAwAAAAOAAAADgAAAA4AAAAGAAAABgAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YA = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAgAAAAGAAAAAgAAAAMAAAQAAAAEAAAABAHGAAQOAwAGcAEAA4ADAA4AAwA7AAYA4QA4AAEAAAAAgAAAAIAAAADAAAAAQAAAAGAAAAAgAAAAMAAAADAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YU = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAABAC4AAd//AAH2hoAAQAyAAAAMAAAALAAAAAwAAAAMAAAADAAABAwQEABe+Bt//9wP+kAIBwAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YU = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAgAAAAIAACADAAAwD3AAIDIIACBCDAAgggQAIwIGACICBgBkAgYASAIEAEACBABQBgwAcB4YAGAGcABgB8AAYAQAACAIAAAACAAAABAAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +katakana.YO = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAIAlgAD//8AAfUGAACABgAAAAYAAAAMAABABgABBLwAAf/8AAF0DAAAgAwAAAAMAAAADAAAQAwAAgAMAANN3AAD/3wAANAIAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.YO = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAEAAAABgAAAAMAAAACAAAAAgAAAAIAAAACDAAAA3wAAAOAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAPCAAAEPgAABA8AAAQHwAAADPAAA/g8AAAADgAAAAYAAAAAAAAAAAAAAAAA=') +}; +katakana.N = { + width: 32, + height: 32, + bpp: 1, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAEAAAABgAAAAOAAAABwAAIAMgAGADgADAAwABgAAAAwAAAAwAAABYAAABOAAAAHAAAAHAAAADgAAADkAAABwAACB4AAAx4AAAP4QAAB8AAAAOAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +hiragana.N = { + width: 32, + height: 32, + bpp: 1, + transparent: 0, + buffer: atob('AAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAACAAAABgAAAAQAAAAMAAAACAAAABAAAAAQAAAAIAAAAGAAAABAAAAAkAAAALgAAAFIAIADiAAAAwwBAAYMAQAEBAIADAQGAAgGDAAYAzgAEAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAA=') +}; +/// ///////////////////////////////////////// + +let kana = katakana.KI; +let scroll = 0; + +function drawWheel () { + if (scroll > 20 || scroll < -20) { + scroll = 0; + next(); + } +} +let hiramode = false; +let curkana = 'KA'; +function next () { + let found = false; + for (const k of Object.keys(katakana).sort()) { + if (found) { + kana = hiramode ? hiragana[k] : katakana[k]; + curkana = k; + return; + } + if (curkana === k) { + found = true; + } + } + curkana = 'KA'; + kana = hiramode ? hiragana[curkana] : katakana[curkana]; +} + +function prev () { + let oldk = ''; + let count = 0; + for (const k of Object.keys(katakana).sort()) { + if (curkana === k) { + if (count > 0) { + curkana = oldk; + kana = katakana[curkana]; + return; + } else { + } + } + oldk = k; + count++; + } + curkana = oldk; + kana = katakana[curkana]; +} + +const kanacolors = { + A: [] +}; + +const clocktop = false; + +function updateWatch (hhmm) { + if (!hhmm) { + hhmm = ohhmm; + } + g.setBgColor(0, 0, 0); + g.setColor(0, 0, 0); + if (false) { + g.fillRect(0, 0, g.getWidth(), g.getHeight()); + g.setColor(0.3, 0.3, 0.3); + g.setColor(1, 0, 0); + + g.fillRect(stripe_pos, 0, stripe_pos + stripe_width, h); + + g.fillRect(stripe2_pos, 0, stripe2_pos + stripe_width, h); + + for (i = 0; i < h; i += 8) { + g.setColor(0.15, 0.15, 0.15); + g.fillRect(0, i, g.getWidth(), i + 3); + g.setColor(0.4, 0.4, 0.4); + g.fillRect(stripe_pos, i, stripe_pos + stripe_width, i + 3); + g.fillRect(stripe2_pos, i, stripe2_pos + stripe_width, i + 3); + } + } else { + var whitecolor = false; + if (curkana.indexOf('A') != -1) { + g.setColor(1, 0, 0); + whitecolor = true; + } else if (curkana.indexOf('I') != -1) { + g.setColor(0, 1, 0); + } else if (curkana.indexOf('U') != -1) { + g.setColor(0, 0, 1); + whitecolor = true; + } else if (curkana.indexOf('E') != -1) { + g.setColor(1, 1, 0); + } else { + g.setColor(0, 1, 1); + } + g.fillRect(0, 0, w, h); + } + + // GOOD FONT SIZE g.setFont("Vector", 62); + g.setFont('Vector', 50); + const bignumbers = false; + if (bignumbers) { + g.setColor(1, 1, 1); + g.drawString(hhmm, 12, 12); + g.setColor(0, 0, 0); + g.drawString(hhmm, 10, 10); + } else { + if (whitecolor) { + g.setColor(0, 0, 0); + } else { + g.setColor(0.5, 0.5, 0.5); + } + if (clocktop) { + x = 26; y = 26; + } else { + x = 26; y = h - 42; + } + g.drawString(hhmm, x - 3, y - 3); + if (whitecolor) { + g.setColor(1, 1, 1); + } else { + g.setColor(0, 0, 0); + } + g.drawString(hhmm, x, y - 1); + } + // drawKana(hira_a, 0, 60); + drawKana(hiragana.KA, g.getWidth() / 6, 60); + Bangle.drawWidgets(); +} +function drawKana (img, x, y) { + g.setColor(0, 0, 0); + + // g.fillRect(0,0,g.getWidth(), h); + if (clocktop) { + g.fillRect(0, h / 2.5, g.getWidth(), h); + } else { + g.fillRect(0, 0, g.getWidth(), 6 * (h / 8) + 1); + } + + if (false) { + g.drawImage(hira_a, x, y); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, x + 32, y + 4); + } else { + if (clocktop) { + g.setColor(1, 1, 1); + g.drawImage(kana, x + 8, y + 12, { scale: 3.4 }); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, 0, y + 16); + g.drawString(hiramode ? 'H' : 'K', w - 20, y + 16); + } else { + g.setColor(1, 1, 1); + g.drawImage(kana, x + 8, 26, { scale: 3.4 }); + g.setColor(1, 1, 1); + g.setFont('Vector', 30); + g.drawString(curkana, 4, 32); + g.drawString(hiramode ? 'H' : 'K', w - 20, 32); + } + } +} + +var ohhmm = ''; + +function tickWatch () { + const now = Date(); + function zpad (n) { + return (n < 10) ? '0' + n : n; + } + const hhmm = zpad(now.getHours()) + ':' + zpad(now.getMinutes()); + if (hhmm !== ohhmm) { + updateWatch(hhmm); + } +} + +Bangle.on('touch', function (tap, top) { + if (top.y < h / 3) { + // clocktop = !clocktop; + return; + } + if (top.x < w / 4) { + prev(); + } else if (top.x > (w - (w / 4))) { + next(); + } else { + hiramode = !hiramode; + } + kana = hiramode ? hiragana[curkana] : katakana[curkana]; + tickWatch(); +}); + +Bangle.loadWidgets(); +tickWatch(); +setInterval(tickWatch, 1000); + diff --git a/apps/kanawatch/app.png b/apps/kanawatch/app.png new file mode 100644 index 0000000000000000000000000000000000000000..cf081937b94dda9444fca31c03baa89a8df61c70 GIT binary patch literal 15313 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 Dnfa#} literal 0 HcmV?d00001 From 433f8adc187849ccb9221d129ecb6ac3d4a6f9cb Mon Sep 17 00:00:00 2001 From: julowe Date: Wed, 15 Jun 2022 10:27:51 -0700 Subject: [PATCH 09/19] qrcode: add MeCard (contact info) creation add html elements and script for First & Last Names, Phone Number, Email, and Website elements of meCard format. Bump to v0.06 --- apps/qrcode/ChangeLog | 1 + apps/qrcode/custom.html | 60 +++++++++++++++++++++++++++++++++++++-- apps/qrcode/metadata.json | 2 +- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/apps/qrcode/ChangeLog b/apps/qrcode/ChangeLog index 6d9cc0569..52eadbcf9 100644 --- a/apps/qrcode/ChangeLog +++ b/apps/qrcode/ChangeLog @@ -3,3 +3,4 @@ 0.03: Forces integer scaling and adds more configuration (error correction, description, display) 0.04: Allow scanning of QR codes from camera or file 0.05: Change brightness on touch +0.06: Add ability to generate contact info (MeCard format) QR code diff --git a/apps/qrcode/custom.html b/apps/qrcode/custom.html index 7ae3eb3af..9955ea6c9 100644 --- a/apps/qrcode/custom.html +++ b/apps/qrcode/custom.html @@ -8,6 +8,8 @@

+ +

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

First Name:

+

Last Name:

+

Phone Number:

+

Email:

+

Website:

+
+

Try your QR Code:

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