├── .gitignore ├── .gitmodules ├── .travis.yml ├── README.md ├── addon.cpp ├── binding.gyp ├── index.d.ts ├── index.js ├── nodeimu.cpp ├── nodeimu.h ├── package-lock.json ├── package.json ├── test.js └── testSync.js /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | RTIMULib.ini 3 | node_modules 4 | npm-debug.log 5 | out/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "RTIMULib2"] 2 | path = RTIMULib2 3 | url = https://github.com/rupnikj/RTIMULib2.git 4 | ignore = dirty 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | sudo: false 4 | language: cpp 5 | addons: 6 | apt: 7 | sources: 8 | - ubuntu-toolchain-r-test 9 | packages: 10 | - g++-4.8 11 | env: 12 | matrix: 13 | - TRAVIS_NODE_VERSION="6" 14 | - TRAVIS_NODE_VERSION="8" 15 | - TRAVIS_NODE_VERSION="10" 16 | - TRAVIS_NODE_VERSION="12" 17 | install: 18 | - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION 19 | - if [[ $TRAVIS_NODE_VERSION == "0.8" ]]; then npm install npm@2 && node_modules/.bin/npm install npm; else npm install npm; fi 20 | - mv node_modules npm 21 | - npm/.bin/npm --version 22 | - if [[ $TRAVIS_OS_NAME == "linux" ]]; then export CXX=g++-4.8; fi 23 | - $CXX --version 24 | - npm/.bin/npm install 25 | - node_modules/.bin/node-gyp rebuild 26 | script: "true" 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nodeimu 2 | ========= 3 | 4 | [![NPM Version][npm-image]][npm-url] 5 | [![Linux Build][travis-linux-image]][travis-linux-url] 6 | 7 | 8 | Nodejs bindings for accessing IMU/pressure/humidity/temperature data using [RTIMULib2](https://github.com/richards-tech/RTIMULib2.git). The addon uses [nodejs/nan](https://github.com/nodejs/nan.git). It has been tested on [Sense HAT](https://www.raspberrypi.org/products/sense-hat/) and on [GrovePi+](http://www.dexterindustries.com/grovepi/) for Raspberry Pi. 9 | 10 | ## Install 11 | 12 | ``` 13 | git clone https://github.com/rupnikj/nodeimu --recursive && cd nodeimu 14 | npm install node-gyp -g 15 | npm install 16 | ``` 17 | 18 | ## Test 19 | 20 | ``` 21 | node test.js 22 | node testSync.js 23 | ``` 24 | 25 | [npm-image]: https://img.shields.io/npm/v/nodeimu.svg 26 | [npm-url]: https://npmjs.org/package/nodeimu 27 | [travis-linux-image]: https://img.shields.io/travis/rupnikj/nodeimu/master.svg?label=linux 28 | [travis-linux-url]: https://travis-ci.org/rupnikj/nodeimu 29 | -------------------------------------------------------------------------------- /addon.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "nodeimu.h" 3 | #include 4 | 5 | NAN_MODULE_INIT(Init) { 6 | NodeIMU::Init(target); 7 | } 8 | 9 | NODE_MODULE(NodeIMU, Init) 10 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'target_defaults': { 3 | 'default_configuration': 'Release', 4 | 'conditions': [ 5 | ['OS == "win"', { 6 | 'msbuild_toolset': 'v120', 7 | }], 8 | ], 9 | }, 10 | 'targets' : [ 11 | { 12 | 'target_name' : 'NodeIMU', 13 | 'sources' : [ 14 | './addon.cpp', 15 | './nodeimu.cpp', 16 | './RTIMULib2/RTIMULib/RTMath.cpp', 17 | './RTIMULib2/RTIMULib/RTIMUHal.cpp', 18 | './RTIMULib2/RTIMULib/RTFusion.cpp', 19 | './RTIMULib2/RTIMULib/RTFusionKalman4.cpp', 20 | './RTIMULib2/RTIMULib/RTFusionRTQF.cpp', 21 | './RTIMULib2/RTIMULib/RTIMUSettings.cpp', 22 | './RTIMULib2/RTIMULib/RTIMUAccelCal.cpp', 23 | './RTIMULib2/RTIMULib/RTIMUMagCal.cpp', 24 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMU.cpp', 25 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUNull.cpp', 26 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUMPU9150.cpp', 27 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUMPU9250.cpp', 28 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUGD20HM303D.cpp', 29 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUGD20M303DLHC.cpp', 30 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUGD20HM303DLHC.cpp', 31 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMULSM9DS0.cpp', 32 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMULSM9DS1.cpp', 33 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUBMX055.cpp', 34 | './RTIMULib2/RTIMULib/IMUDrivers/RTIMUBNO055.cpp', 35 | './RTIMULib2/RTIMULib/IMUDrivers/RTPressure.cpp', 36 | './RTIMULib2/RTIMULib/IMUDrivers/RTPressureBMP180.cpp', 37 | './RTIMULib2/RTIMULib/IMUDrivers/RTPressureLPS25H.cpp', 38 | './RTIMULib2/RTIMULib/IMUDrivers/RTPressureMS5611.cpp', 39 | './RTIMULib2/RTIMULib/IMUDrivers/RTPressureMS5637.cpp', 40 | './RTIMULib2/RTIMULib/IMUDrivers/RTHumidity.cpp', 41 | './RTIMULib2/RTIMULib/IMUDrivers/RTHumidityHTS221.cpp', 42 | './RTIMULib2/RTIMULib/IMUDrivers/RTHumidityHTU21D.cpp' 43 | ], 44 | 'include_dirs': [ 45 | './RTIMULib2/RTIMULib', 46 | " void; 22 | 23 | type CallbackFunction = (args: Callback) => void 24 | 25 | export class IMU { 26 | getValue: CallbackFunction; 27 | getValueSync: () => Data; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = exports = require('./out/NodeIMU'); 2 | -------------------------------------------------------------------------------- /nodeimu.cpp: -------------------------------------------------------------------------------- 1 | #include "nodeimu.h" 2 | #include 3 | 4 | using namespace v8; 5 | 6 | NodeIMU::NodeIMU() { 7 | settings = new RTIMUSettings("RTIMULib"); 8 | imu = RTIMU::createIMU(settings); 9 | pressure = RTPressure::createPressure(settings); 10 | humidity = RTHumidity::createHumidity(settings); 11 | 12 | if ((imu == NULL) || (imu->IMUType() == RTIMU_TYPE_NULL)) { 13 | printf("No IMU found\n"); 14 | exit(1); 15 | } 16 | 17 | imu->IMUInit(); 18 | if (pressure != NULL) { pressure->pressureInit(); } 19 | if (humidity != NULL) { humidity->humidityInit(); } 20 | 21 | imu->setSlerpPower((float)0.02); 22 | imu->setGyroEnable(true); 23 | imu->setAccelEnable(true); 24 | imu->setCompassEnable(true); 25 | } 26 | 27 | NodeIMU::~NodeIMU() { 28 | delete imu; 29 | delete settings; 30 | delete pressure; 31 | delete humidity; 32 | } 33 | 34 | NAN_METHOD(NodeIMU::New) { 35 | NodeIMU* obj = new NodeIMU(); 36 | obj->Wrap(info.This()); 37 | info.GetReturnValue().Set(info.This()); 38 | } 39 | 40 | void AddRTVector3ToResult(v8::Local& result, RTVector3 data, const char* name) { 41 | Nan::HandleScope(); 42 | 43 | v8::Local field = Nan::New(); 44 | Nan::Set(field, Nan::New("x").ToLocalChecked(), Nan::New(data.x())); 45 | Nan::Set(field, Nan::New("y").ToLocalChecked(), Nan::New(data.y())); 46 | Nan::Set(field, Nan::New("z").ToLocalChecked(), Nan::New(data.z())); 47 | 48 | Nan::Set(result, Nan::New(name).ToLocalChecked(), field); 49 | } 50 | 51 | void PutMeasurement(const RTIMU_DATA& imuData, const bool pressure, const bool humidity, v8::Local& result) { 52 | Nan::HandleScope(); 53 | 54 | Nan::Set(result, Nan::New("timestamp").ToLocalChecked(), Nan::New(0.001 * (double)imuData.timestamp).ToLocalChecked()); 55 | 56 | AddRTVector3ToResult(result, imuData.accel, "accel"); 57 | AddRTVector3ToResult(result, imuData.gyro, "gyro"); 58 | AddRTVector3ToResult(result, imuData.compass, "compass"); 59 | AddRTVector3ToResult(result, imuData.fusionPose, "fusionPose"); 60 | 61 | Nan::Set(result, Nan::New("tiltHeading").ToLocalChecked(), Nan::New(RTMath::poseFromAccelMag(imuData.accel, imuData.compass).z())); 62 | 63 | if (pressure) { 64 | Nan::Set(result, Nan::New("pressure").ToLocalChecked(), Nan::New(imuData.pressure)); 65 | Nan::Set(result, Nan::New("temperature").ToLocalChecked(), Nan::New(imuData.temperature)); 66 | } 67 | if (humidity) { 68 | Nan::Set(result, Nan::New("humidity").ToLocalChecked(), Nan::New(imuData.humidity)); 69 | } 70 | } 71 | 72 | class SensorWorker : public Nan::AsyncWorker { 73 | public: 74 | SensorWorker(Nan::Callback *callback, RTIMU* imu, RTPressure *pressure, RTHumidity *humidity) 75 | : AsyncWorker(callback), d_imu(imu), d_pressure(pressure), d_humidity(humidity) {} 76 | ~SensorWorker() {} 77 | 78 | // Executed inside the worker-thread. 79 | // It is not safe to access V8, or V8 data structures 80 | // here, so everything we need for input and output 81 | // should go on `this`. 82 | void Execute() { 83 | if (d_imu->IMURead()) { 84 | d_imuData = d_imu->getIMUData(); 85 | if (d_pressure != NULL) { d_pressure->pressureRead(d_imuData); } 86 | if (d_humidity != NULL) { d_humidity->humidityRead(d_imuData); } 87 | } 88 | } 89 | 90 | // Executed when the async work is complete 91 | // this function will be run inside the main event loop 92 | // so it is safe to use V8 again 93 | void HandleOKCallback() { 94 | Nan::HandleScope scope; 95 | 96 | v8::Local result = Nan::New(); 97 | PutMeasurement(d_imuData, d_pressure != NULL,d_humidity != NULL, result); 98 | 99 | v8::Local argv[] = { 100 | Nan::Null(), result 101 | }; 102 | 103 | callback->Call(2, argv); 104 | } 105 | 106 | private: 107 | RTIMU* d_imu; 108 | RTPressure *d_pressure; 109 | RTHumidity *d_humidity; 110 | 111 | RTIMU_DATA d_imuData; 112 | }; 113 | 114 | NAN_METHOD(NodeIMU::GetValue) { 115 | NodeIMU* obj = Nan::ObjectWrap::Unwrap(info.This()); 116 | Nan::Callback *callback = new Nan::Callback(info[0].As()); 117 | Nan::AsyncQueueWorker(new SensorWorker(callback, obj->imu, obj->pressure, obj->humidity)); 118 | } 119 | 120 | NAN_METHOD(NodeIMU::GetValueSync) { 121 | NodeIMU* obj = Nan::ObjectWrap::Unwrap(info.This()); 122 | if (obj->imu->IMURead()) { 123 | RTIMU_DATA imuData = obj->imu->getIMUData(); 124 | bool pressure = (obj->pressure != NULL); 125 | bool humidity = (obj->humidity != NULL); 126 | if (pressure) { obj->pressure->pressureRead(imuData); } 127 | if (humidity) { obj->humidity->humidityRead(imuData); } 128 | 129 | v8::Local result = Nan::New(); 130 | PutMeasurement(imuData, pressure, humidity, result); 131 | 132 | info.GetReturnValue().Set(result); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /nodeimu.h: -------------------------------------------------------------------------------- 1 | #ifndef NODEIMU_H 2 | #define NODEIMU_H 3 | 4 | #include "RTIMULib.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // tested on node 0.12.7 LSM9DS1 (IMU), LPS25H (pressure), HTS221 (humidity) 11 | 12 | class NodeIMU : public Nan::ObjectWrap { 13 | public: 14 | static NAN_MODULE_INIT(Init) { 15 | v8::Local tpl = Nan::New(New); 16 | tpl->SetClassName(Nan::New("IMU").ToLocalChecked()); 17 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 18 | 19 | Nan::SetPrototypeMethod(tpl, "getValue", GetValue); 20 | Nan::SetPrototypeMethod(tpl, "getValueSync", GetValueSync); 21 | 22 | Nan::Set(target, Nan::New("IMU").ToLocalChecked(), 23 | Nan::GetFunction(tpl).ToLocalChecked()); 24 | } 25 | 26 | 27 | private: 28 | explicit NodeIMU(); 29 | 30 | ~NodeIMU(); 31 | 32 | static NAN_METHOD(New); 33 | 34 | static NAN_METHOD(GetValue); 35 | 36 | static NAN_METHOD(GetValueSync); 37 | 38 | RTIMU *imu; 39 | RTIMUSettings *settings; 40 | RTPressure *pressure; 41 | RTHumidity *humidity; 42 | 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeimu", 3 | "version": "2.1.12", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 11 | }, 12 | "ajv": { 13 | "version": "6.12.0", 14 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", 15 | "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", 16 | "requires": { 17 | "fast-deep-equal": "^3.1.1", 18 | "fast-json-stable-stringify": "^2.0.0", 19 | "json-schema-traverse": "^0.4.1", 20 | "uri-js": "^4.2.2" 21 | } 22 | }, 23 | "ansi-regex": { 24 | "version": "2.1.1", 25 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 26 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 27 | }, 28 | "aproba": { 29 | "version": "1.2.0", 30 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 31 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 32 | }, 33 | "are-we-there-yet": { 34 | "version": "1.1.5", 35 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 36 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 37 | "requires": { 38 | "delegates": "^1.0.0", 39 | "readable-stream": "^2.0.6" 40 | } 41 | }, 42 | "asn1": { 43 | "version": "0.2.4", 44 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 45 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 46 | "requires": { 47 | "safer-buffer": "~2.1.0" 48 | } 49 | }, 50 | "assert-plus": { 51 | "version": "1.0.0", 52 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 53 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 54 | }, 55 | "asynckit": { 56 | "version": "0.4.0", 57 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 58 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 59 | }, 60 | "aws-sign2": { 61 | "version": "0.7.0", 62 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 63 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 64 | }, 65 | "aws4": { 66 | "version": "1.9.1", 67 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", 68 | "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" 69 | }, 70 | "balanced-match": { 71 | "version": "1.0.0", 72 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 73 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 74 | }, 75 | "bcrypt-pbkdf": { 76 | "version": "1.0.2", 77 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 78 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 79 | "requires": { 80 | "tweetnacl": "^0.14.3" 81 | } 82 | }, 83 | "brace-expansion": { 84 | "version": "1.1.11", 85 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 86 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 87 | "requires": { 88 | "balanced-match": "^1.0.0", 89 | "concat-map": "0.0.1" 90 | } 91 | }, 92 | "caseless": { 93 | "version": "0.12.0", 94 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 95 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 96 | }, 97 | "chownr": { 98 | "version": "1.1.4", 99 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 100 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" 101 | }, 102 | "code-point-at": { 103 | "version": "1.1.0", 104 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 105 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 106 | }, 107 | "combined-stream": { 108 | "version": "1.0.8", 109 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 110 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 111 | "requires": { 112 | "delayed-stream": "~1.0.0" 113 | } 114 | }, 115 | "concat-map": { 116 | "version": "0.0.1", 117 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 118 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 119 | }, 120 | "console-control-strings": { 121 | "version": "1.1.0", 122 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 123 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 124 | }, 125 | "core-util-is": { 126 | "version": "1.0.2", 127 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 128 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 129 | }, 130 | "dashdash": { 131 | "version": "1.14.1", 132 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 133 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 134 | "requires": { 135 | "assert-plus": "^1.0.0" 136 | } 137 | }, 138 | "delayed-stream": { 139 | "version": "1.0.0", 140 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 141 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 142 | }, 143 | "delegates": { 144 | "version": "1.0.0", 145 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 146 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 147 | }, 148 | "ecc-jsbn": { 149 | "version": "0.1.2", 150 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 151 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 152 | "requires": { 153 | "jsbn": "~0.1.0", 154 | "safer-buffer": "^2.1.0" 155 | } 156 | }, 157 | "env-paths": { 158 | "version": "2.2.0", 159 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", 160 | "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==" 161 | }, 162 | "extend": { 163 | "version": "3.0.2", 164 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 165 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 166 | }, 167 | "extsprintf": { 168 | "version": "1.3.0", 169 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 170 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 171 | }, 172 | "fast-deep-equal": { 173 | "version": "3.1.1", 174 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 175 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" 176 | }, 177 | "fast-json-stable-stringify": { 178 | "version": "2.1.0", 179 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 180 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 181 | }, 182 | "forever-agent": { 183 | "version": "0.6.1", 184 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 185 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 186 | }, 187 | "form-data": { 188 | "version": "2.3.3", 189 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 190 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 191 | "requires": { 192 | "asynckit": "^0.4.0", 193 | "combined-stream": "^1.0.6", 194 | "mime-types": "^2.1.12" 195 | } 196 | }, 197 | "fs-minipass": { 198 | "version": "1.2.7", 199 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", 200 | "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", 201 | "requires": { 202 | "minipass": "^2.6.0" 203 | } 204 | }, 205 | "fs.realpath": { 206 | "version": "1.0.0", 207 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 208 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 209 | }, 210 | "gauge": { 211 | "version": "2.7.4", 212 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 213 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 214 | "requires": { 215 | "aproba": "^1.0.3", 216 | "console-control-strings": "^1.0.0", 217 | "has-unicode": "^2.0.0", 218 | "object-assign": "^4.1.0", 219 | "signal-exit": "^3.0.0", 220 | "string-width": "^1.0.1", 221 | "strip-ansi": "^3.0.1", 222 | "wide-align": "^1.1.0" 223 | } 224 | }, 225 | "getpass": { 226 | "version": "0.1.7", 227 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 228 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 229 | "requires": { 230 | "assert-plus": "^1.0.0" 231 | } 232 | }, 233 | "glob": { 234 | "version": "7.1.6", 235 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 236 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 237 | "requires": { 238 | "fs.realpath": "^1.0.0", 239 | "inflight": "^1.0.4", 240 | "inherits": "2", 241 | "minimatch": "^3.0.4", 242 | "once": "^1.3.0", 243 | "path-is-absolute": "^1.0.0" 244 | } 245 | }, 246 | "graceful-fs": { 247 | "version": "4.2.3", 248 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 249 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" 250 | }, 251 | "har-schema": { 252 | "version": "2.0.0", 253 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 254 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 255 | }, 256 | "har-validator": { 257 | "version": "5.1.3", 258 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 259 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 260 | "requires": { 261 | "ajv": "^6.5.5", 262 | "har-schema": "^2.0.0" 263 | } 264 | }, 265 | "has-unicode": { 266 | "version": "2.0.1", 267 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 268 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 269 | }, 270 | "http-signature": { 271 | "version": "1.2.0", 272 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 273 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 274 | "requires": { 275 | "assert-plus": "^1.0.0", 276 | "jsprim": "^1.2.2", 277 | "sshpk": "^1.7.0" 278 | } 279 | }, 280 | "inflight": { 281 | "version": "1.0.6", 282 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 283 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 284 | "requires": { 285 | "once": "^1.3.0", 286 | "wrappy": "1" 287 | } 288 | }, 289 | "inherits": { 290 | "version": "2.0.4", 291 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 292 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 293 | }, 294 | "is-fullwidth-code-point": { 295 | "version": "1.0.0", 296 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 297 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 298 | "requires": { 299 | "number-is-nan": "^1.0.0" 300 | } 301 | }, 302 | "is-typedarray": { 303 | "version": "1.0.0", 304 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 305 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 306 | }, 307 | "isarray": { 308 | "version": "1.0.0", 309 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 310 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 311 | }, 312 | "isexe": { 313 | "version": "2.0.0", 314 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 315 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 316 | }, 317 | "isstream": { 318 | "version": "0.1.2", 319 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 320 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 321 | }, 322 | "jsbn": { 323 | "version": "0.1.1", 324 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 325 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 326 | }, 327 | "json-schema": { 328 | "version": "0.2.3", 329 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 330 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 331 | }, 332 | "json-schema-traverse": { 333 | "version": "0.4.1", 334 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 335 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 336 | }, 337 | "json-stringify-safe": { 338 | "version": "5.0.1", 339 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 340 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 341 | }, 342 | "jsprim": { 343 | "version": "1.4.1", 344 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 345 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 346 | "requires": { 347 | "assert-plus": "1.0.0", 348 | "extsprintf": "1.3.0", 349 | "json-schema": "0.2.3", 350 | "verror": "1.10.0" 351 | } 352 | }, 353 | "mime-db": { 354 | "version": "1.43.0", 355 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", 356 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" 357 | }, 358 | "mime-types": { 359 | "version": "2.1.26", 360 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", 361 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", 362 | "requires": { 363 | "mime-db": "1.43.0" 364 | } 365 | }, 366 | "minimatch": { 367 | "version": "3.0.4", 368 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 369 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 370 | "requires": { 371 | "brace-expansion": "^1.1.7" 372 | } 373 | }, 374 | "minimist": { 375 | "version": "0.0.8", 376 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 377 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 378 | }, 379 | "minipass": { 380 | "version": "2.9.0", 381 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", 382 | "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", 383 | "requires": { 384 | "safe-buffer": "^5.1.2", 385 | "yallist": "^3.0.0" 386 | } 387 | }, 388 | "minizlib": { 389 | "version": "1.3.3", 390 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", 391 | "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", 392 | "requires": { 393 | "minipass": "^2.9.0" 394 | } 395 | }, 396 | "mkdirp": { 397 | "version": "0.5.1", 398 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 399 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 400 | "requires": { 401 | "minimist": "0.0.8" 402 | } 403 | }, 404 | "nan": { 405 | "version": "2.14.0", 406 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", 407 | "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" 408 | }, 409 | "node-gyp": { 410 | "version": "6.1.0", 411 | "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz", 412 | "integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==", 413 | "requires": { 414 | "env-paths": "^2.2.0", 415 | "glob": "^7.1.4", 416 | "graceful-fs": "^4.2.2", 417 | "mkdirp": "^0.5.1", 418 | "nopt": "^4.0.1", 419 | "npmlog": "^4.1.2", 420 | "request": "^2.88.0", 421 | "rimraf": "^2.6.3", 422 | "semver": "^5.7.1", 423 | "tar": "^4.4.12", 424 | "which": "^1.3.1" 425 | } 426 | }, 427 | "nopt": { 428 | "version": "4.0.3", 429 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", 430 | "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", 431 | "requires": { 432 | "abbrev": "1", 433 | "osenv": "^0.1.4" 434 | } 435 | }, 436 | "npmlog": { 437 | "version": "4.1.2", 438 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 439 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 440 | "requires": { 441 | "are-we-there-yet": "~1.1.2", 442 | "console-control-strings": "~1.1.0", 443 | "gauge": "~2.7.3", 444 | "set-blocking": "~2.0.0" 445 | } 446 | }, 447 | "number-is-nan": { 448 | "version": "1.0.1", 449 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 450 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 451 | }, 452 | "oauth-sign": { 453 | "version": "0.9.0", 454 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 455 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 456 | }, 457 | "object-assign": { 458 | "version": "4.1.1", 459 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 460 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 461 | }, 462 | "once": { 463 | "version": "1.4.0", 464 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 465 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 466 | "requires": { 467 | "wrappy": "1" 468 | } 469 | }, 470 | "os-homedir": { 471 | "version": "1.0.2", 472 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 473 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" 474 | }, 475 | "os-tmpdir": { 476 | "version": "1.0.2", 477 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 478 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 479 | }, 480 | "osenv": { 481 | "version": "0.1.5", 482 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 483 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 484 | "requires": { 485 | "os-homedir": "^1.0.0", 486 | "os-tmpdir": "^1.0.0" 487 | } 488 | }, 489 | "path-is-absolute": { 490 | "version": "1.0.1", 491 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 492 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 493 | }, 494 | "performance-now": { 495 | "version": "2.1.0", 496 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 497 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 498 | }, 499 | "process-nextick-args": { 500 | "version": "2.0.1", 501 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 502 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 503 | }, 504 | "psl": { 505 | "version": "1.7.0", 506 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", 507 | "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" 508 | }, 509 | "punycode": { 510 | "version": "2.1.1", 511 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 512 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 513 | }, 514 | "qs": { 515 | "version": "6.5.2", 516 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 517 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 518 | }, 519 | "readable-stream": { 520 | "version": "2.3.7", 521 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 522 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 523 | "requires": { 524 | "core-util-is": "~1.0.0", 525 | "inherits": "~2.0.3", 526 | "isarray": "~1.0.0", 527 | "process-nextick-args": "~2.0.0", 528 | "safe-buffer": "~5.1.1", 529 | "string_decoder": "~1.1.1", 530 | "util-deprecate": "~1.0.1" 531 | } 532 | }, 533 | "request": { 534 | "version": "2.88.2", 535 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 536 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 537 | "requires": { 538 | "aws-sign2": "~0.7.0", 539 | "aws4": "^1.8.0", 540 | "caseless": "~0.12.0", 541 | "combined-stream": "~1.0.6", 542 | "extend": "~3.0.2", 543 | "forever-agent": "~0.6.1", 544 | "form-data": "~2.3.2", 545 | "har-validator": "~5.1.3", 546 | "http-signature": "~1.2.0", 547 | "is-typedarray": "~1.0.0", 548 | "isstream": "~0.1.2", 549 | "json-stringify-safe": "~5.0.1", 550 | "mime-types": "~2.1.19", 551 | "oauth-sign": "~0.9.0", 552 | "performance-now": "^2.1.0", 553 | "qs": "~6.5.2", 554 | "safe-buffer": "^5.1.2", 555 | "tough-cookie": "~2.5.0", 556 | "tunnel-agent": "^0.6.0", 557 | "uuid": "^3.3.2" 558 | } 559 | }, 560 | "rimraf": { 561 | "version": "2.7.1", 562 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 563 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 564 | "requires": { 565 | "glob": "^7.1.3" 566 | } 567 | }, 568 | "safe-buffer": { 569 | "version": "5.1.2", 570 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 571 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 572 | }, 573 | "safer-buffer": { 574 | "version": "2.1.2", 575 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 576 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 577 | }, 578 | "semver": { 579 | "version": "5.7.1", 580 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 581 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 582 | }, 583 | "set-blocking": { 584 | "version": "2.0.0", 585 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 586 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 587 | }, 588 | "signal-exit": { 589 | "version": "3.0.2", 590 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 591 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 592 | }, 593 | "sshpk": { 594 | "version": "1.16.1", 595 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 596 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 597 | "requires": { 598 | "asn1": "~0.2.3", 599 | "assert-plus": "^1.0.0", 600 | "bcrypt-pbkdf": "^1.0.0", 601 | "dashdash": "^1.12.0", 602 | "ecc-jsbn": "~0.1.1", 603 | "getpass": "^0.1.1", 604 | "jsbn": "~0.1.0", 605 | "safer-buffer": "^2.0.2", 606 | "tweetnacl": "~0.14.0" 607 | } 608 | }, 609 | "string-width": { 610 | "version": "1.0.2", 611 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 612 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 613 | "requires": { 614 | "code-point-at": "^1.0.0", 615 | "is-fullwidth-code-point": "^1.0.0", 616 | "strip-ansi": "^3.0.0" 617 | } 618 | }, 619 | "string_decoder": { 620 | "version": "1.1.1", 621 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 622 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 623 | "requires": { 624 | "safe-buffer": "~5.1.0" 625 | } 626 | }, 627 | "strip-ansi": { 628 | "version": "3.0.1", 629 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 630 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 631 | "requires": { 632 | "ansi-regex": "^2.0.0" 633 | } 634 | }, 635 | "tar": { 636 | "version": "4.4.13", 637 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", 638 | "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", 639 | "requires": { 640 | "chownr": "^1.1.1", 641 | "fs-minipass": "^1.2.5", 642 | "minipass": "^2.8.6", 643 | "minizlib": "^1.2.1", 644 | "mkdirp": "^0.5.0", 645 | "safe-buffer": "^5.1.2", 646 | "yallist": "^3.0.3" 647 | } 648 | }, 649 | "tough-cookie": { 650 | "version": "2.5.0", 651 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 652 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 653 | "requires": { 654 | "psl": "^1.1.28", 655 | "punycode": "^2.1.1" 656 | } 657 | }, 658 | "tunnel-agent": { 659 | "version": "0.6.0", 660 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 661 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 662 | "requires": { 663 | "safe-buffer": "^5.0.1" 664 | } 665 | }, 666 | "tweetnacl": { 667 | "version": "0.14.5", 668 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 669 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 670 | }, 671 | "uri-js": { 672 | "version": "4.2.2", 673 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 674 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 675 | "requires": { 676 | "punycode": "^2.1.0" 677 | } 678 | }, 679 | "util-deprecate": { 680 | "version": "1.0.2", 681 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 682 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 683 | }, 684 | "uuid": { 685 | "version": "3.4.0", 686 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 687 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 688 | }, 689 | "verror": { 690 | "version": "1.10.0", 691 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 692 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 693 | "requires": { 694 | "assert-plus": "^1.0.0", 695 | "core-util-is": "1.0.2", 696 | "extsprintf": "^1.2.0" 697 | } 698 | }, 699 | "which": { 700 | "version": "1.3.1", 701 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 702 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 703 | "requires": { 704 | "isexe": "^2.0.0" 705 | } 706 | }, 707 | "wide-align": { 708 | "version": "1.1.3", 709 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 710 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 711 | "requires": { 712 | "string-width": "^1.0.2 || 2" 713 | } 714 | }, 715 | "wrappy": { 716 | "version": "1.0.2", 717 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 718 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 719 | }, 720 | "yallist": { 721 | "version": "3.1.1", 722 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 723 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" 724 | } 725 | } 726 | } 727 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeimu", 3 | "version": "2.1.12", 4 | "description": "Native addon for accessing IMU/pressure/humidity/temperature sensors using RTIMULib2", 5 | "license": "BSD-2-Clause-FreeBSD", 6 | "author": "Jan Rupnik ", 7 | "contributors": [ 8 | { 9 | "name": "Jan Rupnik", 10 | "email": "jan.rupnik@ijs.si" 11 | }, 12 | { 13 | "name": "Stéphane Lavirotte", 14 | "email": "stephane@lavirotte.com" 15 | } 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/rupnikj/nodeimu" 20 | }, 21 | "main": "./index.js", 22 | "types": "./index.d.ts", 23 | "dependencies": { 24 | "nan": "^2.14.0", 25 | "node-gyp": "^6.1.0" 26 | }, 27 | "keywords": [ 28 | "raspberry", 29 | "pi", 30 | "sense", 31 | "hat", 32 | "RTIMULib", 33 | "IMU", 34 | "pressure", 35 | "humidity", 36 | "temperature" 37 | ], 38 | "readmeFilename": "README.md" 39 | } 40 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var util = require('util') 2 | var nodeimu = require('./index.js'); 3 | var IMU = new nodeimu.IMU(); 4 | 5 | var num = 0; 6 | var numStop = 100; 7 | 8 | console.time("async"); 9 | 10 | var print_vector3 = function(name, data) { 11 | var sx = data.x >= 0 ? ' ' : ''; 12 | var sy = data.y >= 0 ? ' ' : ''; 13 | var sz = data.z >= 0 ? ' ' : ''; 14 | return util.format('%s: %s%s %s%s %s%s ', name, sx, data.x.toFixed(4), sy, data.y.toFixed(4), sz, data.z.toFixed(4)); 15 | } 16 | 17 | var headingCorrection = function(heading, offset) { 18 | if (typeof offset ==='undefined') 19 | offset = 0; 20 | 21 | // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location. 22 | // Find yours here: http://www.magnetic-declination.com/ 23 | var declinationAngle = 0.03106686; 24 | 25 | heading += declinationAngle + offset; 26 | 27 | // Correct for when signs are reversed. 28 | if (heading < 0) 29 | heading += 2 * Math.PI; 30 | 31 | // Check for wrap due to addition of declination. 32 | if (heading > 2 * Math.PI) 33 | heading -= 2 * Math.PI; 34 | 35 | return heading; 36 | } 37 | 38 | var headingToDegree = function(heading) { 39 | // Convert radians to degrees for readability. 40 | return heading * 180 / Math.PI; 41 | } 42 | 43 | var tic = new Date(); 44 | var callb = function (e, data) { 45 | var toc = new Date(); 46 | 47 | if (e) { 48 | console.log(e); 49 | return; 50 | } 51 | 52 | var str = data.timestamp.toISOString() + " "; 53 | str += print_vector3('Accel', data.accel) 54 | // str += print_vector3('Gyro', data.gyro) 55 | // str += print_vector3('Compass', data.compass) 56 | // str += print_vector3('Fusion', data.fusionPose) 57 | str += util.format('TiltHeading: %s ', headingToDegree(headingCorrection(data.tiltHeading, Math.PI / 2)).toFixed(0)); 58 | 59 | var str2 = ""; 60 | if (data.temperature && data.pressure && data.humidity) { 61 | var str2 = util.format('%s %s %s', data.temperature.toFixed(4), data.pressure.toFixed(4), data.humidity.toFixed(4)); 62 | } 63 | if ((num % 10) == 0) { 64 | console.log(str + str2); 65 | } 66 | 67 | num++; 68 | if (num == numStop) { 69 | console.timeEnd("async"); 70 | } else { 71 | setTimeout(function() { tic = new Date(); IMU.getValue(callb); } , 20 - (toc - tic)); 72 | } 73 | } 74 | 75 | IMU.getValue(callb); 76 | -------------------------------------------------------------------------------- /testSync.js: -------------------------------------------------------------------------------- 1 | var util = require('util') 2 | var nodeimu = require('./index.js'); 3 | var IMU = new nodeimu.IMU(); 4 | 5 | var num = 0; 6 | var numStop = 100; 7 | 8 | console.time("sync"); 9 | 10 | var print_vector3 = function(name, data) { 11 | var sx = data.x >= 0 ? ' ' : ''; 12 | var sy = data.y >= 0 ? ' ' : ''; 13 | var sz = data.z >= 0 ? ' ' : ''; 14 | return util.format('%s: %s%s %s%s %s%s ', name, sx, data.x.toFixed(4), sy, data.y.toFixed(4), sz, data.z.toFixed(4)); 15 | } 16 | 17 | function dispAccel() { 18 | var tic = new Date(); 19 | var data = IMU.getValueSync(); 20 | var toc = new Date(); 21 | 22 | var str = data.timestamp.toISOString() + " "; 23 | str += print_vector3("Accel", data.accel) 24 | // str += print_vector3("Gyro", data.gyro) 25 | // str += print_vector3("Compass", data.compass) 26 | // str += print_vector3("Fusion", data.fusionPose) 27 | 28 | var str2 = ""; 29 | if (data.temperature && data.pressure && data.humidity) { 30 | var str2 = util.format(' %s %s %s', data.temperature.toFixed(4), data.pressure.toFixed(4), data.humidity.toFixed(4)); 31 | } 32 | console.log(str + str2); 33 | num++; 34 | if (num == numStop) { 35 | console.timeEnd("sync"); 36 | } else { 37 | setTimeout(dispAccel, 50 - (toc - tic)); 38 | } 39 | } 40 | 41 | dispAccel(); 42 | 43 | --------------------------------------------------------------------------------