From f47d8af9d30befbbd24435dadcc00bff45cc2c65 Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sun, 27 Oct 2019 12:18:35 +0100 Subject: [PATCH] first commit --- .gitignore | 4 + package-lock.json | 1573 +++++++++++++++++++++++++++++++++++ package.json | 21 + src/api/bike.js | 74 ++ src/api/program.js | 74 ++ src/api/workout.js | 178 ++++ src/drivers/index.js | 10 + src/drivers/mock.js | 103 +++ src/repositories/sqlite3.js | 227 +++++ src/server.js | 20 + src/systems/workout.js | 135 +++ stuff.db | Bin 0 -> 196608 bytes 12 files changed, 2419 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/api/bike.js create mode 100644 src/api/program.js create mode 100644 src/api/workout.js create mode 100644 src/drivers/index.js create mode 100644 src/drivers/mock.js create mode 100644 src/repositories/sqlite3.js create mode 100644 src/server.js create mode 100644 src/systems/workout.js create mode 100644 stuff.db diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fc22df9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/node_modules + +/.vscode +/.idea diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..25faebd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1573 @@ +{ + "name": "cyclefraud", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/body-parser": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", + "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", + "integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.10", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.10.tgz", + "integrity": "sha512-gM6evDj0OvTILTRKilh9T5dTaGpv1oYiFcJAfgSejuMJgGJUsD9hKEU2lB4aiTNy4WwChxRnjfYFuBQsULzsJw==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", + "dev": true + }, + "@types/node": { + "version": "12.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz", + "integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", + "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "optional": true, + "requires": { + "readable-stream": "^3.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "bluetooth-hci-socket": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/bluetooth-hci-socket/-/bluetooth-hci-socket-0.5.1.tgz", + "integrity": "sha1-774hUk/Bz10/rl1RNl1WHUq77Qs=", + "optional": true, + "requires": { + "debug": "^2.2.0", + "nan": "^2.0.5", + "usb": "^1.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "optional": true + } + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "bplist-parser": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.0.6.tgz", + "integrity": "sha1-ONo0cYF9+dRKs4kuJ3B7u9daEbk=", + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chownr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "requires": { + "mimic-response": "^2.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==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "optional": true + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "optional": true + }, + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconsole-bike-client": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/iconsole-bike-client/-/iconsole-bike-client-0.1.3.tgz", + "integrity": "sha512-07uemZKL6ul+d1LG4lE35Fh0bK5Bf8gWmaWjc+MEALq/bpCz8sD3TTcAj5jJn5R3zIb7eoIvwbEdehRB3tOdBA==", + "requires": { + "noble": "^1.9.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "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==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-response": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", + "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==", + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "napi-build-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", + "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==", + "optional": true + }, + "needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "noble": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/noble/-/noble-1.9.1.tgz", + "integrity": "sha1-LM0x6tjsktv/bxmkLkILJYvNzdA=", + "requires": { + "bluetooth-hci-socket": "^0.5.1", + "bplist-parser": "0.0.6", + "debug": "~2.2.0", + "xpc-connection": "~0.1.4" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "node-abi": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.12.0.tgz", + "integrity": "sha512-VhPBXCIcvmo/5K8HPmnWJyyhvgKxnHTUMXR/XwGHV68+wrgkzST4UmQrY/XszSWA5dtnXpNp528zkcyJ/pzVcw==", + "optional": true, + "requires": { + "semver": "^5.4.1" + } + }, + "node-pre-gyp": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", + "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "optional": true + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" + }, + "npm-packlist": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.6.tgz", + "integrity": "sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "prebuild-install": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.2.tgz", + "integrity": "sha512-INDfXzTPnhT+WYQemqnAXlP7SvfiFMopMozSgXCZ+RDLb279gKfIuLk4o7PgEawLp3WrMgIYGBpkxpraROHsSA==", + "optional": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "optional": true + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "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==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "optional": true + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "optional": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sqlite3": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.1.0.tgz", + "integrity": "sha512-RvqoKxq+8pDHsJo7aXxsFR18i+dU2Wp5o12qAJOV5LNcDt+fgJsc2QKKg3sIRfXrN9ZjzY1T7SNe/DFVqAXjaw==", + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.11.0", + "request": "^2.87.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", + "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "optional": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp": "^0.5.1", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", + "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "optional": true, + "requires": { + "bl": "^3.0.0", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "usb": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/usb/-/usb-1.6.0.tgz", + "integrity": "sha512-52DyWlCk9K+iw3LnvY95WXSnpHjxJoI++aGkV8HiMNPc4zmvDQlYvWAzrkbJ2JH3oUcx26XfU5sZcG4RAcVkMg==", + "optional": true, + "requires": { + "bindings": "^1.4.0", + "nan": "2.13.2", + "prebuild-install": "^5.2.4" + }, + "dependencies": { + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "optional": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xpc-connection": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/xpc-connection/-/xpc-connection-0.1.4.tgz", + "integrity": "sha1-3Nf6oq7Gt6bhjMXdrQQvejTHcVY=", + "optional": true, + "requires": { + "nan": "^2.0.5" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..915a3ef --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "ykonsole-server", + "private": true, + "version": "0.1.0", + "description": "Monitoring tool using the bluetooth client.", + "main": "./src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Gisle", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "iconsole-bike-client": "^0.1.3", + "sqlite3": "^4.1.0", + "underscore": "^1.9.1" + }, + "devDependencies": { + "@types/express": "^4.17.1" + } +} diff --git a/src/api/bike.js b/src/api/bike.js new file mode 100644 index 0000000..dd18a96 --- /dev/null +++ b/src/api/bike.js @@ -0,0 +1,74 @@ +const express = require("express"); + +/** + * @param {import("../repositories/sqlite3")} repo + */ +module.exports = function bikeRouter(repo) { + const router = express.Router({caseSensitive: false}); + + router.get("/", async(_, res) => { + try { + const bikes = await repo.listBikes(); + return res.status(200).json(bikes); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.get("/:id", async(req, res) => { + try { + const bike = await repo.findBike(req.params.id); + if (bike == null) { + return res.status(404).json({code: 404, message: "bike not found"}) + } + + return res.status(200).json(bike); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + router.post("/", async(req, res) => { + try { + const {name, driver, maxLevel, connect} = req.body; + const id = await repo.insertBike({name, driver, maxLevel, connect}) + + return res.status(200).json({id, name, driver, maxLevel, connect}); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.put("/:id", async(req, res) => { + try { + const bike = await repo.findBike(req.params.id); + if (bike == null) { + return res.status(404).json({code: 404, message: "bike not found"}) + } + + bike.name = req.body.name || ""; + await repo.updateBike(bike); + + return res.status(200).json(bike); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.delete("/:id", async(req, res) => { + try { + const bike = await repo.findBike(req.params.id); + if (bike == null) { + return res.status(404).json({code: 404, message: "bike not found"}) + } + + await repo.deleteBike(bike); + + return res.status(200).json(bike); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + return router; +} \ No newline at end of file diff --git a/src/api/program.js b/src/api/program.js new file mode 100644 index 0000000..e998f81 --- /dev/null +++ b/src/api/program.js @@ -0,0 +1,74 @@ +const express = require("express"); + +/** + * @param {import("../repositories/sqlite3")} repo + */ +module.exports = function programRouter(repo) { + const router = express.Router({caseSensitive: false}); + + router.get("/", async(_, res) => { + try { + const programs = await repo.listPrograms(); + return res.status(200).json(programs); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.get("/:id", async(req, res) => { + try { + const program = await repo.findProgram(req.params.id); + if (program == null) { + return res.status(404).json({code: 404, message: "program not found"}) + } + + return res.status(200).json(program); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + router.post("/", async(req, res) => { + try { + const {name, cpm, warmupMin, warmupCpm} = req.body; + const id = await repo.insertProgram({name, cpm, warmupMin, warmupCpm}) + + return res.status(200).json({id, name, cpm, warmupMin, warmupCpm}); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.put("/:id", async(req, res) => { + try { + const program = await repo.findProgram(req.params.id); + if (program == null) { + return res.status(404).json({code: 404, message: "program not found"}) + } + + program.name = req.body.name || ""; + await repo.updateProgram(program); + + return res.status(200).json(program); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.delete("/:id", async(req, res) => { + try { + const program = await repo.findProgram(req.params.id); + if (program == null) { + return res.status(404).json({code: 404, message: "program not found"}) + } + + await repo.deleteProgram(program); + + return res.status(200).json(program); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + return router; +} \ No newline at end of file diff --git a/src/api/workout.js b/src/api/workout.js new file mode 100644 index 0000000..c0a19ed --- /dev/null +++ b/src/api/workout.js @@ -0,0 +1,178 @@ +const express = require("express"); +const Workout = require("../systems/workout"); + +/** + * @param {import("../repositories/sqlite3")} repo + */ +module.exports = function workoutRouter(repo) { + const router = express.Router({caseSensitive: false}); + + /** @type {Workout[]} */ + let workouts = []; + + router.get("/", async(req, res) => { + if (req.query.active === "true") { + return res.status(200).json(workouts.map(w => ({ + id: w.id, + bike: w.bike, + program: w.program, + date: w.date, + active: true, + }))); + } + + try { + const dbWorkouts = await repo.listWorkouts(); + return res.status(200).json(dbWorkouts.map(w => ({ + ...w, + active: workouts.find(w2 => w2.id === w.id) != null, + }))); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.get("/:id", async(req, res) => { + let workout = workouts.find(w => w.id == req.params.id); + if (workout != null) { + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date, active: true}) + } + + try { + workout = await repo.findWorkout(req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "workout not found"}) + } + + return res.status(200).json({active: false, ...workout}); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + router.get("/:id/measurements/", async(req, res) => { + try { + const measurements = await repo.listMeasurements(req.params.id); + if (measurements == null) { + return res.status(404).json({code: 404, message: "measurements not found"}) + } + + return res.status(200).json(measurements); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + router.post("/", async(req, res) => { + try { + const {bikeId, programId} = req.body; + + const workout = await Workout.create(repo, bikeId, programId); + workouts.push(workout); + + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}); + } + }); + + router.post("/:id/continue", async(req, res) => { + let workout = workouts.find(w => w.id == req.params.id); + if (workout != null) { + return res.status(400).json({code: 400, message: "Workout already active."}) + } + + try { + workout = await Workout.continue(repo, req.params.id); + workouts.push(workout); + + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch (err) { + return res.status(400).json({code: 400, message: err.message || err}) + } + }); + + router.post("/:id/connect", async(req, res) => { + const workout = workouts.find(w => w.id == req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "Workout not found or inactive."}) + } + + try { + await workout.connect(); + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch(err) { + return res.status(500).json({code: 500, message: err.message || err}); + } + }); + + router.post("/:id/start", async(req, res) => { + const workout = workouts.find(w => w.id == req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "Workout not found or inactive."}) + } + + try { + await workout.start(); + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch(err) { + return res.status(500).json({code: 500, message: err.message || err}); + } + }); + + router.post("/:id/pause", async(req, res) => { + const workout = workouts.find(w => w.id == req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "Workout not found or inactive."}) + } + + try { + await workout.pause(); + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch(err) { + return res.status(500).json({code: 500, message: err.message || err}); + } + }); + + router.post("/:id/stop", async(req, res) => { + const workout = workouts.find(w => w.id == req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "Workout not found or inactive."}) + } + + try { + if (workout.driver != null) { + await workout.stop(); + } + + workouts = workouts.filter(w => w !== workout); + await workout.destroy(); + + return res.status(200).json({id: workout.id, bike: workout.bike, program: workout.program, date: workout.date}); + } catch(err) { + return res.status(500).json({code: 500, message: err.message || err}); + } + }); + + router.delete("/:id", async(req, res) => { + let workout = workouts.find(w => w.id == req.params.id); + if (workout != null) { + return res.status(400).json({code: 400, message: "Workout already active."}) + } + + try { + workout = await repo.findWorkout(req.params.id); + if (workout == null) { + return res.status(404).json({code: 404, message: "workout not found"}) + } + + await repo.deleteWorkout(workout); + + return res.status(200).json(workout); + } catch (err) { + return res.status(500).json({code: 500, message: err.message || err}) + } + }); + + return router; +} \ No newline at end of file diff --git a/src/drivers/index.js b/src/drivers/index.js new file mode 100644 index 0000000..9802cb6 --- /dev/null +++ b/src/drivers/index.js @@ -0,0 +1,10 @@ +const MockDriver = require("./mock"); + +module.exports = function createDriver(name) { + switch (name) { + case "mock": + return new MockDriver(); + default: + throw new Error(`Driver ${name} doesn't exist!`) + } +} \ No newline at end of file diff --git a/src/drivers/mock.js b/src/drivers/mock.js new file mode 100644 index 0000000..9ce2f81 --- /dev/null +++ b/src/drivers/mock.js @@ -0,0 +1,103 @@ +const EventEmitter = require("events"); +const _ = require("underscore"); + +class MockDriver { + constructor() { + this.started = false; + this.events = new EventEmitter(); + this.seconds = 0; + this.level = 1; + this.workoutState = { + minutes: 0, + seconds: 0, + speed: 0, + rpm: 0, + distance: 0, + calories: 0, + pulse: 0, + watt: 0, + level: 1, + }; + + this.interval = null; + } + + connect() { + return Promise.resolve(); + } + + start() { + if (this.started) { + return; + } + + this.started = true; + this.interval = setInterval(() => { + this.seconds++; + + this.workoutState.minutes = Math.floor(this.seconds / 60); + this.workoutState.seconds = this.seconds % 60; + this.workoutState.speed = Math.floor(300 + Math.random() * 200) / 10; + this.workoutState.rpm = Math.floor(57 + Math.random() * 5); + this.workoutState.distance += (this.seconds % 5 == 0) ? 0.1 : 0; + this.workoutState.calories += (this.seconds % 2 == 0) ? 1 : 0; + this.workoutState.pulse = null; + this.workoutState.watt = Math.floor(100 + Math.random() * 20); + this.workoutState.level = this.level; + + this.events.emit("workoutState", {...this.workoutState}); + }, 1000); + + this.workoutState.level = 1; + this.workoutState.speed = 0; + this.workoutState.rpm = 0; + this.workoutState.watt = 0; + + if (this.seconds === 0) { + this.events.emit("workoutState", {...this.workoutState}); + } + + return Promise.resolve(); + } + + setLevel(n) { + if (n < 0 || n > 32) { + return Promise.reject(new Error("Level is out of range (0..=32)")) + } + + this.level = n; + } + + pause() { + clearInterval(this.interval); + this.started = false; + + return Promise.resolve(); + } + + stop() { + this.pause(); + this.workoutState = { + minutes: 0, + seconds: 0, + speed: 0, + rpm: 0, + distance: 0, + calories: 0, + pulse: 0, + watt: 0, + level: 1, + }; + this.seconds = 0; + + return Promise.resolve(); + } + + destroy() { + this.stop(); + this.events.emit("destroy"); + this.events.removeAllListeners(); + } +} + +module.exports = MockDriver; \ No newline at end of file diff --git a/src/repositories/sqlite3.js b/src/repositories/sqlite3.js new file mode 100644 index 0000000..2f0b3d6 --- /dev/null +++ b/src/repositories/sqlite3.js @@ -0,0 +1,227 @@ +const sqlite3 = require("sqlite3").verbose(); + +class SQLite3Repository { + constructor(path) { + this.db = new sqlite3.Database(path); + } + + /** + * @returns {Promise} + */ + setup() { + return new Promise((resolve, reject) => { + this.db.run(SQL_TABLE_BIKE, (err) => { + if (err != null) { + reject(err); + } + + this.db.run(SQL_TABLE_PROGRAM, (err) => { + if (err != null) { + reject(err); + } + + this.db.run(SQL_TABLE_WORKOUT, (err) => { + if (err != null) { + reject(err); + } + + this.db.run(SQL_TABLE_MEASUREMENT, (err) => { + if (err != null) { + reject(err); + } + + resolve(); + }); + }); + }); + }); + }); + } + + insert(obj, table, params) { + return new Promise((resolve, reject) => { + const query = `INSERT INTO ${table} (${params.join(", ")}) VALUES (${params.map(p => ':'+p).join(", ")});`; + const values = params.map(p => obj[p]); + this.db.run(query, values, function(err) { + if (err != null) { + return reject(err); + } + + resolve(this.lastID); + }); + }); + } + + update(obj, table, key, keys) { + return new Promise((resolve, reject) => { + const query = `UPDATE ${table} SET ${keys.map(k => `${k}=:${k}`).join(" AND ")} WHERE ${key}=:${key}`; + const values = [ + ...keys.map(k => obj[k]), + obj[key], + ]; + + this.db.run(query, values, function(err) { + if (err != null) { + return reject(err); + } + + resolve(); + }); + }); + } + + delete(obj, table, key) { + return new Promise((resolve, reject) => { + const query = `DELETE FROM ${table} WHERE ${key}=:${key};` + this.db.run(query, [obj[key]], function(err) { + if (err != null) { + return reject(err); + } + + resolve(this.changes); + }); + }); + } + + findOne(table, match) { + return this.find(table, match).then(res => res[0] || null) + } + + find(table, match) { + return new Promise((resolve, reject) => { + const keys = Object.keys(match).filter(k => match[k] != null); + const params = keys.map(k => match[k]); + const query = `SELECT * FROM ${table}${keys.length > 0 ? ` WHERE ${keys.map(k => `${k}=:${k}`).join(" AND ")}` : ""};`; + this.db.all(query, params, function(err, rows) { + if (err != null) { + return reject(err); + } + + resolve(rows); + }); + }); + } + + findBike(id) { + return this.findOne("bike", {id}); + } + + listBikes() { + return this.find("bike", {}); + } + + insertBike(bike) { + return this.insert(bike, "bike", ["name", "driver", "connect", "maxLevel"]); + } + + updateBike(bike) { + return this.update(bike, "bike", "id", ["name"]); + } + + deleteBike(bike) { + return this.delete(bike, "bike", "id"); + } + + findProgram(id) { + return this.findOne("program", {id}); + } + + listPrograms() { + return this.find("program", {}); + } + + insertProgram(program) { + return this.insert(program, "program", ["name", "cpm", "warmupMin", "warmupCpm"]); + } + + updateProgram(program) { + return this.update(program, "program", "id", ["name"]); + } + + deleteProgram(program) { + return this.delete(program, "program", "id"); + } + + findWorkout(id) { + return this.findOne("workout", {id}).then(d => ({...d, date: new Date(d.date)})); + } + + listWorkouts({programId, bikeId} = {}) { + return this.find("workout", {programId, bikeId}).then(l => l.map(d => ({...d, date: new Date(d.date)}))); + } + + insertWorkout(workout) { + return this.insert(workout, "workout", ["bikeId","programId","date"]); + } + + deleteWorkout(workout) { + return this.delete(workout, "workout", "id"); + } + + findMeasurement(id) { + return this.findOne("measurement", {id}); + } + + listMeasurements(workoutId) { + return this.find("measurement", {workoutId}); + } + + insertMeasurement(measurement) { + return this.insert(measurement, "measurement", ["workoutId","minutes","seconds","speed","rpm","distance","calories","pulse","watt","level"]); + } + + deleteMeasurement(measurement) { + return this.delete(measurement, "measurement", "id"); + } + + deleteMeasurements({workoutId}) { + return this.delete({workoutId}, "measurement", "workoutId"); + } +} + +const SQL_TABLE_BIKE = ` + CREATE TABLE IF NOT EXISTS bike ( + id INTEGER PRIMARY KEY, + name VARCHAR(255) NOT NULL, + driver VARCHAR(255) NOT NULL, + connect VARCHAR(255) NOT NULL, + maxLevel INT + ); +`; + +const SQL_TABLE_PROGRAM = ` + CREATE TABLE IF NOT EXISTS program ( + id INTEGER PRIMARY KEY, + name VARCHAR(255) NOT NULL, + cpm INT NOT NULL, + warmupMin INT NOT NULL, + warmupCpm INT NOT NULL + ); +`; + +const SQL_TABLE_WORKOUT = ` + CREATE TABLE IF NOT EXISTS workout ( + id INTEGER PRIMARY KEY, + bikeId INT NOT NULL, + programId INT NOT NULL, + date DATETIME NOT NULL + ); +`; + +const SQL_TABLE_MEASUREMENT = ` + CREATE TABLE IF NOT EXISTS measurement ( + id INTEGER PRIMARY KEY, + workoutId INT NOT NULL, + minutes INT, + seconds INT, + speed REAL, + rpm REAL, + distance REAL, + calories REAL, + pulse INT, + watt REAL, + level INT + ); +`; + +module.exports = SQLite3Repository; diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..98c18a1 --- /dev/null +++ b/src/server.js @@ -0,0 +1,20 @@ +const express = require('express'); +const SQLite3Repository = require("./repositories/sqlite3"); + +const repo = new SQLite3Repository("stuff.db"); + +repo.setup().catch(err => { + console.error("Failed to setup db:", err); + process.exit(1); +}); + +const app = express(); + +app.use(express.json({strict: false})); + +app.use("/api/bike/", require("./api/bike")(repo)); +app.use("/api/program/", require("./api/program")(repo)); +app.use("/api/workout/", require("./api/workout")(repo)); + +app.listen(8780); + diff --git a/src/systems/workout.js b/src/systems/workout.js new file mode 100644 index 0000000..e88fd21 --- /dev/null +++ b/src/systems/workout.js @@ -0,0 +1,135 @@ +const EventEmitter = require("events"); +const createDriver = require("../drivers"); + +class Workout { + /** + * @param {import("../repositories/sqlite3")} repo + * @param {number} id + * @param {{ + * id: string, + * name: string, + * driver: string, + * connect: string, + * maxLevel: number, + * }} bike + * @param {{ + * id: number, + * name: string, + * cpm: number, + * warmupMin: number, + * warmupCpm: number, + * }} program + * @param {Date} date + */ + constructor(repo, id, bike, program, date) { + this.repo = repo; + this.id = id; + this.bike = bike; + this.program = program; + this.date = date; + this.driver = null; + + this.offsetSeconds = 0; + this.offsets = {}; + + this.events = new EventEmitter(); + } + + async connect() { + this.driver = createDriver(this.bike.driver); + this.driver.events.on("workoutState", ws => this.handleWorkoutState(ws)); + + return this.driver.connect(); + } + + start() { + return this.driver.start(); + } + + pause() { + return this.driver.pause(); + } + + stop() { + return this.driver.stop(); + } + + destroy() { + this.events.emit("destroy"); + this.events.removeAllListeners(); + + if (this.driver != null) { + this.driver.destroy(); + this.driver = null; + } + } + + listMeasurements() { + return this.repo.listMeasurements(this.id); + } + + handleWorkoutState(ws) { + if (this.offsetSeconds > 0) { + const seconds = (ws.minutes * 60) + ws.seconds + this.offsetSeconds; + ws.minutes = Math.floor(seconds / 60); + ws.seconds = seconds % 60; + + for (const key in this.offsets) { + if (!this.offsets.hasOwnProperty(key)) { + continue; + } + + ws[key] += this.offsets[key]; + } + } + + this.repo.insertMeasurement({...ws, workoutId: this.id}); + + this.events.emit("workoutState", ws); + } + + /** + * @param {import("../repositories/sqlite3")} repo + * @param {number} bikeId + * @param {number} programId + */ + static async create(repo, bikeId, programId) { + const bike = await repo.findBike(bikeId); + const program = await repo.findProgram(programId); + const date = new Date(); + const id = await repo.insertWorkout({ + bikeId: bike.id, + programId: program.id, + date: date, + }); + + return new Workout(repo, id, bike, program, date); + } + + /** + * @param {import("../repositories/sqlite3")} repo + * @param {number} id + */ + static async continue(repo, id) { + const data = await repo.findWorkout(id); + const bike = await repo.findBike(data.bikeId); + const program = await repo.findWorkout(data.workoutId); + + const workout = new Workout(repo, parseInt(id), bike, program, new Date(data.date)); + + const list = await repo.listMeasurements(id); + if (list.length > 0) { + const last = list[list.length - 1]; + + workout.offsetSeconds = (last.minutes * 60 + last.seconds); + workout.offsets = { + distance: last.distance, + calories: last.calories, + } + } + + return workout; + } +} + +module.exports = Workout; \ No newline at end of file diff --git a/stuff.db b/stuff.db new file mode 100644 index 0000000000000000000000000000000000000000..7cd2c4c14f8f3acc61266ac017a216b4b74855b7 GIT binary patch literal 196608 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 literal 0 HcmV?d00001