박권수

feat. new DataTable :Bottle -> TakeMedicineHistory / BottleMedicine, API Change, Test

module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
}
};
{
"extends": "eslint:recommended",
"rules": {
// "semi": ["warn", "never"],
"quotes": ["warn", "single"],
"no-console": ["off"],
"no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
"no-constant-condition" : ["off"]
},
"parserOptions": {
"ecmaVersion": 9
},
"env": {
"es6": true,
"node": true,
"browser": true,
"amd": true
},
"globals": {
"$": true,
"require": true,
"process": true
},
"root": true
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ const updateMedicineInfo = require('./src/lib/UpdatingMedicineInfo');
const MqttServer = require('./src/util/MqttServer');
require('dotenv').config();
// eslint-disable-next-line no-undef
const { SERVER_PORT, MONGO_URL } = process.env;
const app = new Koa();
......@@ -21,7 +22,7 @@ Mongoose.connect(MONGO_URL, {
useCreateIndex : true
}).then(() => {
console.log('\x1b[1;32mMongo DB is connected : ', MONGO_URL, '\x1b[0m');
updateMedicineInfo.updateMedicineInfo();
// updateMedicineInfo.updateMedicineInfo();
}).catch(e => {
console.log(e);
})
......
This diff could not be displayed because it is too large.
......@@ -19,5 +19,8 @@
"dependencies": {
"moment": "^2.29.1",
"mqtt": "^4.2.6"
},
"devDependencies": {
"eslint": "^7.32.0"
}
}
......
......@@ -20,7 +20,10 @@ exports.register = async(ctx) => {
userId : Joi.string().email().max(50).required(),
password : Joi.string().required(),
passwordCheck : Joi.string().required(),
})
userNm : Joi.string().required(),
userAge : Joi.number().required(),
contact : Joi.string().required(),
});
const result = schema.validate(ctx.request.body);
if(result.error || password !== passwordCheck) {
......@@ -41,7 +44,6 @@ exports.register = async(ctx) => {
});
await user.setPassword(password);
await user.save();
const profile = new Profile({
userId,
......@@ -50,6 +52,7 @@ exports.register = async(ctx) => {
contact,
});
await user.save();
await profile.save();
ctx.status = 201;
......@@ -68,6 +71,7 @@ exports.doctorRegister = async ctx => {
userId : Joi.string().email().max(50).required(),
password : Joi.string().required(),
passwordCheck : Joi.string().required(),
info : Joi.object().required(),
})
const result = schema.validate(ctx.request.body);
......@@ -90,7 +94,6 @@ exports.doctorRegister = async ctx => {
});
await doctor.setPassword(password);
doctor.save();
const doctorInfo = new DoctorInfo({
doctorId : userId,
......@@ -98,6 +101,8 @@ exports.doctorRegister = async ctx => {
useYn : 'W',
});
doctor.save();
doctorInfo.save();
ctx.status = 201;
......
/* eslint-disable no-undef */
//어플에서 약병 등록 및, 약병에 관한 정보 조회 = 여기서 mqtt통신으로 broker에 데이터를 요청한다.
const Bottle = require('../../models/bottle');
const Hub = require('../../models/hub');
const Medicine = require('../../models/medicine');
const User = require('../../models/user');
const History = require('../../models/history');
const PatientInfo = require('../../models/patientInfo');
const TakeMedicineHist = require('../../models/takeMedicineHistory');
const BottleMedicine = require('../../models/bottleMedicine');
const Feedback = require('../../models/feedback');
const Mqtt = require('../../lib/MqttModule');
const jwt = require('jsonwebtoken');
......@@ -16,7 +20,7 @@ exports.bottleConnect = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -70,7 +74,7 @@ exports.bottleDisconnect = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -102,7 +106,7 @@ exports.bottleDisconnect = async(ctx) => {
};
//약병 정보를 조회 -> 약병에 현재 데이터를 요청한다. message : req
//약병 정보를 조회 -> 약병의 기록을 가져온다. message : req
exports.getBottleInfo = async(ctx) => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
......@@ -111,7 +115,7 @@ exports.getBottleInfo = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -126,41 +130,101 @@ exports.getBottleInfo = async(ctx) => {
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.getHub_UserId() !== userId || user.userTypeCd !== 'DOCTOR') {
if(hub.userId !== userId) {
ctx.status = 403;
return;
}
if(user.userTypeCd === 'NORMAL') {
const hosting = hub.getHubHost();
//서버에서 bottle로 데이터를 요청한다.
const client = await Mqtt.mqttOn(hosting);
const topic = 'bottle/' + bottleId + '/stb';
const message = 'req';
await Mqtt.mqttPublishMessage(client, { topic, message });
const bottle = await Bottle.findByBottleId(bottleId);
const hosting = hub.getHubHost();
//서버에서 bottle로 데이터를 요청한다.
const client = await Mqtt.mqttOn(hosting);
const topic = 'bottle/' + bottleId + '/stb';
const message = 'req';
await Mqtt.mqttPublishMessage(client, { topic, message });
const bottleMedicine = await BottleMedicine.find({ bottleId })
.sort({ regDtm : 'desc' })
.limit(1);
if(bottleMedicine.length) {
const takeMedicineHist = await TakeMedicineHist
.find({ bmId : bottleMedicine[0]._id })
.sort({ takeDate : 'desc' })
.populate('bmId');
ctx.status = 200;
ctx.body = bottle;
ctx.body = takeMedicineHist;
} else {
ctx.status = 404;
ctx.body = {
error : '정보가 등록되지 않은 약병'
}
}
}
//약병에 대한 피드백의 정보를 가져옴
exports.getBottleFeedback = async ctx => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
ctx.status = 401;
return;
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자'
}
return;
} else if (user.userTypeCd === 'DOCTOR') {
let result = {
bottle,
history : [],
};
}
result.historyList = History.findByBottleId(bottle.bottleId);
const { bottleId } = ctx.params;
ctx.status = 200;
ctx.body = result;
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병'
}
return;
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.userId !== userId) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음'
}
return;
}
}
//약병의 ID를 찾아서 약의 정보를 등록 : Post
const bottleMedicine = await BottleMedicine.find({ bottleId })
.sort({ regDtm : 'desc' })
.limit(1);
if(bottleMedicine.length) {
const feedbackList = await Feedback.find({ bmId : bottleMedicine[0]._id })
.sort({ fdbDtm : 'desc' })
.populate('bmId');
ctx.status = 200;
ctx.body = feedbackList;
} else {
ctx.status = 404;
ctx.body = {
error : '정보가 등록되지 않은 약병',
};
}
};
//약병의 ID를 찾아서 약의 정보와 처방의를 등록 : Post
exports.setMedicine = async(ctx) => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
......@@ -169,42 +233,103 @@ exports.setMedicine = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { bottleId } = ctx.params;
const { medicineId, dosage } = ctx.request.body;
const { medicineId, dosage, doctorId } = ctx.request.body;
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '약병 찾을 수 없음.',
}
return;
}
const hub = await Hub.findByHubId(bottle.getHubId());
if(hub.getHub_UserId() !== userId) {
ctx.status = 403;
ctx.body = {
error : '해당 허브 권한 없음',
}
return;
}
const medicine = await Medicine.findByMedicineId(medicineId);
if(!medicine) {
ctx.status = 404;
ctx.body = {
error : '해당 약 존재하지 않음',
}
return;
}
await Bottle.findOneAndUpdate({
bottleId
}, {
if(doctorId !== undefined && doctorId !== null && doctorId !== '') {
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
if(!patientInfo) {
ctx.status = 403;
ctx.body = {
error : '담당의가 아님',
};
return;
}
}
const bottleMedicine = new BottleMedicine({
bottleId,
medicineId,
dosage : parseInt(dosage)
});
doctorId,
dosage,
});
bottleMedicine.save();
ctx.status = 200;
}
};
// //비어있는 약병에 의사를 등록한다.
// exports.registerDoctorToBottle = async ctx => {
// const token = ctx.req.headers.authorization;
// if(!token || !token.length) {
// ctx.status = 401;
// return;
// }
// const { userId } = jwt.verify(token, process.env.JWT_SECRET);
// const user = await User.findByUserId(userId);
// if(!user || !user.userTypeCd || user.useYn !== 'Y') {
// ctx.status = 403;
// return;
// }
// const { bottleId } = ctx.params;
// const { doctorId } = ctx.request.body;
// const bottle = await Bottle.findByBottleId(bottleId);
// if(!bottle) {
// ctx.status = 404;
// return;
// }
// if(bottle.getDoctorId()) {
// ctx.status = 403;
// return;
// }
// const patinetInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
// if(!patinetInfo) {
// ctx.status = 404;
// return;
// }
// bottle.setDoctorId(doctorId);
// bottle.save();
// ctx.status = 200;
// };
//로그인한 유저의 약병 리스트 가져오기
exports.getBottleList = async(ctx) => {
......@@ -215,7 +340,7 @@ exports.getBottleList = async(ctx) => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -243,4 +368,4 @@ exports.getBottleList = async(ctx) => {
ctx.status = 200;
ctx.body = bottleList;
}
\ No newline at end of file
};
\ No newline at end of file
......
......@@ -28,6 +28,14 @@ bottle.delete('/:bottleId', bottleCtrl.bottleDisconnect);
bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
/**
* 약병에 대한 피드백 확인
* request parameter : bottleId
* url : http://localhost:4000/api/bottle/feedback/:bottleId
* return : feedback List
*/
bottle.get('/feedback/:bottleId', bottleCtrl.getBottleFeedback);
/**
* 약병에 약 등록 = 약 검색 후 약 ID(medicineId)와 복용 정보 보고 사용자가 약 복용량(dosage) 입력
* request parameter : medicineId, dosage
* url : http://localhost:4000/api/bottle/:bottleId
......@@ -36,6 +44,14 @@ bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
bottle.patch('/:bottleId', bottleCtrl.setMedicine);
/**
* 비어있는 약병에 전담의 등록
* request parameter : bottleId, doctorId
* url : http://localhost:4000/api/bottle/doctor/:bottleId
* return null;
*/
// bottle.patch('/doctor/:bottleId', bottleCtrl.registerDoctorToBottle);
/**
* 현재 로그인한 유저의 허브 중, 해당 허브에 등록된 약병 리스트를 가져옴
* request parameter : x
* url : http://localhost:4000/api/bottle/hub/:hubId
......
......@@ -3,7 +3,8 @@ const User = require('../../models/user');
const Profile = require('../../models/profile');
const Bottle = require('../../models/bottle');
const Medicine = require('../../models/medicine');
const History = require('../../models/history');
const BottleMedicine = require('../../models/bottleMedicine');
const TakeMedicineHist = require('../../models/takeMedicineHistory');
const Feedback = require('../../models/feedback');
const Hub = require('../../models/hub');
const PatientInfo = require('../../models/patientInfo');
......@@ -21,19 +22,21 @@ exports.getPatientList = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const managePatientIdList = await PatientInfo.findAllByDoctorId(userId);
const managePatientIdList = await PatientInfo.findAllByDoctorIdAndUseYn(userId, 'Y');
const result = managePatientIdList.map(async patientId => {
const patient = await User.findByUserId(patientId);
return patient;
});
const result = [];
await Promise.all(managePatientIdList.map(async patient => {
const patientProfile = await Profile.findByUserId(patient.patientId);
result.push(patientProfile);
}));
ctx.status = 200;
ctx.body = result;
......@@ -52,21 +55,22 @@ exports.getPatientDetail = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { patientId } = ctx.params;
const { patientId } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!isDoctorsPatient) {
ctx.status = 403;
return;
......@@ -78,12 +82,12 @@ exports.getPatientDetail = async ctx => {
const reqUserHubList = await Hub.findAllByUserId(patientId);
const reqUserBottleList = [];
await Promise.all(reqUserHubList.map(async hub => {
const bottleList = await Bottle.findAllByHubId(hub.hubId);
const bottleList = await Bottle.findAllByHubId(hub.hubId, userId);
reqUserBottleList.push(...bottleList);
}));
const result = {
...profile,
profile,
info : isDoctorsPatient.getInfo(),
bottleList : reqUserBottleList,
};
......@@ -105,10 +109,14 @@ exports.getBottleDetail = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자',
}
return;
}
......@@ -116,29 +124,29 @@ exports.getBottleDetail = async ctx => {
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병',
}
return;
}
if(bottle.getDoctorId() !== userId) {
const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId });
if(!bottleMedicine) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음',
}
return;
}
//약병에 들어있는 약 정보와 복용 내역을 가져온다.
const bottleInfo = {
temperature : bottle.temperature,
humidity : bottle.humidity,
dosage : bottle.dosage,
balance : bottle.balance,
};
const medicine = await Medicine.findByMedicineId(bottle.getMedicineId());
const takeHistory = await History.findByBottleIdAndMedicineId(bottleId, bottle.getMedicineId());
const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
const takeMedicineHist = await TakeMedicineHist.find({
bmId : bottleMedicine._id,
}).sort({ takeDate : 'desc' });
const result = {
bottleInfo,
medicine,
takeHistory,
takeMedicineHist,
};
ctx.status = 200;
......@@ -158,21 +166,22 @@ exports.writeReqPatientReport = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { reqUserId, info } = ctx.request.body;
const patient = await User.findByUserId(reqUserId);
const { patientId, info } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(reqUserId, userId);
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!patientInfo) {
ctx.status = 404;
return;
......@@ -197,10 +206,14 @@ exports.writeReqBottleFeedback = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 사용자',
}
return;
}
......@@ -208,17 +221,27 @@ exports.writeReqBottleFeedback = async ctx => {
const bottle = await Bottle.findByBottleId(bottleId);
if(!bottle) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약병'
}
return;
}
if(bottle.getDoctorId() !== userId) {
const bottleMedicine = await BottleMedicine.find({ bottleId, doctorId : userId })
.sort({ regDtm : 'desc' })
.limit(1);
if(!bottleMedicine.length) {
ctx.status = 403;
ctx.body = {
error : '약병에 대한 권한 없음'
}
return;
}
const newFeedback = new Feedback({
fdbDtm : new Date(),
fdbType,
bottleId,
bmId : bottleMedicine[0]._id,
doctorId : userId,
feedback,
});
......@@ -240,27 +263,35 @@ exports.registerNewPatient = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR') {
ctx.status = 403;
return;
}
const { reqUserId } = ctx.request.body;
const patient = await User.findByUserId(reqUserId);
const { patientId } = ctx.request.body;
const patient = await User.findByUserId(patientId);
if(!patient || patient.useYn !== 'Y') {
ctx.status = 404;
return;
}
const isExistPatientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
if(isExistPatientInfo) {
ctx.status = 403;
return;
}
const patientInfo = new PatientInfo({
patientId : reqUserId,
patientId,
doctorId : userId,
info : '',
useYn : 'W',
});
patientInfo.updateInfo('환자 등록');
patientInfo.updateInfo('환자 등록 요청');
patientInfo.save();
ctx.status = 200;
......@@ -279,8 +310,9 @@ exports.removeReqPatient = async ctx => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR') {
ctx.status = 403;
return;
......@@ -293,16 +325,14 @@ exports.removeReqPatient = async ctx => {
return;
}
const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
if(!patientInfo) {
ctx.status = 404;
return;
}
await PatientInfo.deleteOne({
patientId,
doctorId : userId,
});
await patientInfo.setUseYn('N')
patientInfo.save();
ctx.status = 200;
......
......@@ -17,7 +17,7 @@ doctor.get('/patient', doctorCtrl.getPatientList);
* url : http://localhost:4000/doctor/patient/:patientId
* return : patient Detail
*/
doctor.get('/patient/:patientId', doctorCtrl.getPatientDetail);
doctor.get('/patient/detail', doctorCtrl.getPatientDetail);
/**
* 현재 로그인한 유저(의사)의 관리 약병 상세 정보를 가져옴
......@@ -37,7 +37,7 @@ doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail);
doctor.patch('/patient', doctorCtrl.writeReqPatientReport);
/**
* 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 기록함
* 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 등록함.
* request parameter : bottleId, fdbType, feedback
* url : http://localhost:4000/doctor/bottle
* return : null
......
......@@ -12,8 +12,9 @@ exports.hubConnect = async (ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -53,8 +54,9 @@ exports.getHubList = async(ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -77,8 +79,9 @@ exports.hubDisconnect = async(ctx) => {
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findById(userId);
const user = await User.findByUserId(userId);
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......
const Router = require('koa-router')
const auth = require('./auth')
const user = require('./user')
const bottle = require('./bottle')
const hub = require('./hub')
const medicine = require('./medicine')
const Router = require('koa-router');
const auth = require('./auth');
const user = require('./user');
const bottle = require('./bottle');
const hub = require('./hub');
const medicine = require('./medicine');
const doctor = require('./doctor');
const manage = require('./manage');
const api = new Router();
api.use('/auth', auth.routes())
api.use('/user', user.routes())
api.use('/bottle', bottle.routes())
api.use('/hub', hub.routes())
api.use('/medicine', medicine.routes())
api.use('/auth', auth.routes());
api.use('/user', user.routes());
api.use('/bottle', bottle.routes());
api.use('/hub', hub.routes());
api.use('/medicine', medicine.routes());
api.use('/doctor', doctor.routes());
api.use('/manage', manage.routes());
module.exports = api;
\ No newline at end of file
......
const Router = require('koa-router');
const manage = new Router();
module.exports = manage;
\ No newline at end of file
......@@ -8,23 +8,9 @@ exports.medicineSearch = async(ctx) => {
return;
}
const { name, company, target } = ctx.request.body;
const { keyword } = ctx.request.body;
let result = [];
if (name && name !== '' && name !== undefined)
result = await medicineSearch_ByName(name);
else if (company && company !== '' && company !== undefined)
result = await medicineSearch_ByCompany(company);
else if (target && target !== '' && target !== undefined)
result = await medicineSearch_ByTarget(target);
if(!result.length) {
ctx.status = 404;
return;
}
const result = await Medicine.findByKeyword(keyword);
ctx.status = 200;
ctx.body = result;
......@@ -47,22 +33,4 @@ exports.medicineGet = async(ctx) => {
ctx.status = 200;
ctx.body = medicine;
}
//이름으로 약 검색
const medicineSearch_ByName = async(name) => {
const result = await Medicine.findByName(name);
return result;
}
//제조사명으로 약 검색
const medicineSearch_ByCompany = async(company) => {
const result = await Medicine.findByCompany(company);
return result;
}
//타겟 병명으로 약 검색
const medicineSearch_ByTarget = async(target) => {
const result = await Medicine.findByTarget(target);
return result;
}
\ No newline at end of file
......
......@@ -11,4 +11,22 @@ const user = new Router();
*/
user.get('/', userCtrl.getMyDetail);
/**
* 유저를 등록하려는 의사의 요청을 전부 보여준다
* request parameter : token,
* url : http://localhost:4000/api/user/doctorrequest
* return : List
*/
user.get('/doctorrequest', userCtrl.viewAllDoctorRegister);
/**
* 유저를 등록하려는 의사의 요청을 수락한다.
* request parameter : token, doctorId,
* url : http://localhost:4000/api/user/doctorrequest/:doctorId
* return : null
*/
user.post('/doctorrequest/accept', userCtrl.acceptDoctorRegister);
module.exports = user;
......
//유저에 관련된 Api
const User = require('../../models/user');
const Profile = require('../../models/profile');
const PatientInfo = require('../../models/patientInfo');
const jwt = require('jsonwebtoken');
/**
* 내 정보를 확인한다.
* @param {*} ctx
* http methods : get
*/
exports.getMyDetail = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
......@@ -12,7 +18,7 @@ exports.getMyDetail = async ctx => {
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findById(userId)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.useYn !== 'Y') {
ctx.status = 403;
return;
......@@ -25,7 +31,71 @@ exports.getMyDetail = async ctx => {
}
//toDo
/**
* 내 정보를 업데이트한다.
* @param {*} ctx
* http methods : post
*/
exports.updateMyInfo = async ctx => {
}
};
/**
* 의사가 요청한 환자 등록을 확인한다.
* @param {*} ctx
* http methods : get
*/
exports.viewAllDoctorRegister = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
ctx.status = 401
return
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const patientInfoList = await PatientInfo.findAllByPatientIdAndUseYn(userId, 'W');
ctx.status = 200;
ctx.body = patientInfoList;
};
/**
* 의사가 요청한 환자 등록을 수락한다/
* @param {*} ctx
* http methods : post
*/
exports.acceptDoctorRegister = async ctx => {
const token = ctx.req.headers.authorization
if (!token || !token.length) {
ctx.status = 401
return
}
const { userId } = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findByUserId(userId)
if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
ctx.status = 403;
return;
}
const { doctorId } = ctx.request.body;
const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'W');
if(!patientInfo) {
ctx.status = 404;
return;
}
patientInfo.updateInfo('환자 등록 요청 수락');
patientInfo.setUseYn('Y');
patientInfo.save();
ctx.status = 200;
};
......
const Bottle = require('../models/bottle');
const History = require('../models/history');
const BottleMedicine = require('../models/bottleMedicine');
const TakeMedicineHist = require('../models/takeMedicineHistory');
//message subscribe 후 message를 가공한 이후 해당 데이터를 보낼 topic과 message를 리턴하는 함수
exports.dataPublish = async (topic, message) => {
//client가 subscribe를 하면 메시지를 보낸 약병의 topic과 message를 가공 및 보낸 약병의 bottleId를 가져옴
const data = await factoring(topic, message);
const { bottleId } = data;
//가공된 데이터를 bottleId의 약병에 업데이트
await bottleInfoUpdate(data);
//가공된 데이터를 메시지로 만들어 topic과 message 리턴
const result = await transPublishingTopicAndMessage(bottleId);
const result = await transPublishingTopicAndMessage(data.bottleId);
return result;
......@@ -26,13 +25,11 @@ const factoring = async (topic, message) => {
if(isOpen === '0')
balance = await balanceFactoring(balance);
else balance = '-1';
const openDate = new Date();
return {
bottleId,
isOpen,
openDate,
openDate : new Date(),
temperature,
humidity,
balance
......@@ -66,39 +63,32 @@ const bottleInfoUpdate = async(data) => {
humidity = parseFloat(humidity);
balance = parseInt(balance);
const bottle = await Bottle.findByBottleId(bottleId);
const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
if(bottle) {
if(bottleMedicine) {
if(isOpen) {
const history = new History({
takeDate : new Date(openDate),
bottleId,
medicineId : bottle.getMedicineId(),
const takeMedicineHist = new TakeMedicineHist({
takeDate : openDate,
bmId : bottleMedicine._id,
temperature,
humidity,
balance,
});
history.save();
}
if(balance !== -1) {
await Bottle.findOneAndUpdate({
bottleId
}, { balance })
takeMedicineHist.save();
}
bottle.updateTemperature(temperature);
bottle.updateHumidity(humidity);
bottle.save();
}
}
//해당 MQTT Broker(client)에 bottleId의 정보에 관한 topic과 message를 리턴한다.
const transPublishingTopicAndMessage = async(bottleId) => {
const topic = 'bottle/' + bottleId + '/stb';
const bottle = await Bottle.findByBottleId(bottleId);
const recentOpen = bottle.getRecentOpenDate();
const dosage = bottle.getDosage();
const message = 'res/' + await transDate(recentOpen) + '/' + dosage;
const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
const takeMedicineHist = await TakeMedicineHist.find({
bmId : bottleMedicine._id
}).sort((a, b) => a.takeDate < b.takeDate)[0];
const message = 'res/' + await transDate(takeMedicineHist.takeDate) + '/' + bottleMedicine.dosage;
return {
topic,
......
const mqtt = require('mqtt')
const clientList = []
exports.mqttOn = async (hosting, func) => {
exports.mqttOn = async (hosting, foo) => {
const filterIndex = clientList.findIndex(client => {
return (client.options.clientId === hosting.clientId
&& client.options.host === hosting.host
......@@ -17,7 +17,7 @@ exports.mqttOn = async (hosting, func) => {
})
client.on('message', async (topic, message) => {
const result = await func(topic, message.toString())
const result = await foo(topic, message.toString())
console.log('\x1b[1;32msubscribe : topic', topic, 'message : ', message.toString(), '\x1b[0m')
this.mqttPublishMessage(client, result)
})
......
......@@ -15,7 +15,7 @@ const jwtMiddleware = async (ctx, next) => {
};
const now = Math.floor(Date.now() / 1000);
if (decoded.exp - now < 60 * 60 * 24 * 7) {
const user = await User.findById(decoded._id);
const user = await User.findByUserId(decoded._id);
const token = user.generateToken();
ctx.cookies.set('access_token', token, {
......
......@@ -4,13 +4,7 @@ const Schema = mongoose.Schema;
const BottleSchema = new Schema ({
bottleId : { type : Number, required : true, unique : true },
temperature : { type : Number, default : 0 },
humidity : { type : Number, default : 0 },
balance : { type : Number, default : 0 },
medicineId : { type : Number, },
dosage : { type : Number, default : 0 },
hubId : { type : Number, required : true, },
doctorId : { type : String, default : null, },
hubId : { type : Number, required : true, ref : 'Hub', },
});
BottleSchema.statics.findByBottleId = function(bottleId) {
......@@ -21,56 +15,13 @@ BottleSchema.statics.findAllByHubId = function(hubId) {
return this.find({ hubId });
};
BottleSchema.statics.findAllByDoctorId = function(doctorId) {
return this.find({ doctorId });
}
BottleSchema.methods.getBottleId = function() {
return this.bottleId;
};
BottleSchema.methods.getTemperature = function() {
return this.temperature;
};
BottleSchema.methods.getHumidity = function() {
return this.humidity;
};
BottleSchema.methods.getBalance = function() {
return this.balance;
};
BottleSchema.methods.getDosage = function() {
return this.dosage;
};
BottleSchema.methods.getMedicineId = function() {
return this.medicineId;
};
BottleSchema.methods.getHubId = function() {
return this.hubId;
};
BottleSchema.methods.getDoctorId = function() {
return this.doctorId;
};
BottleSchema.methods.setMedicineId = function(medicineId) {
this.medicineId = medicineId;
};
BottleSchema.methods.setDosage = function(dosage) {
this.dosage = dosage;
};
BottleSchema.methods.updateTemperature = function (temperature) {
this.temperature = temperature;
};
BottleSchema.methods.updateHumidity = function (humidity) {
this.humidity = humidity;
};
module.exports = mongoose.model('Bottle', BottleSchema);
\ No newline at end of file
......
......@@ -2,31 +2,33 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const TakeMedicineHistorySchema = new Schema ({
takeDate : {
type : Date,
const BottleMedicineSchema = new Schema({
bottleId : {
type : Number,
ref : 'Bottle',
required : true,
default : Date.now,
},
medicineId : {
type : Number,
ref : 'Medicine',
required : true,
},
doctorId : {
type : String,
ref : 'User',
required : true,
},
bottleId : {
dosage : {
type : Number,
ref : 'Bottle',
required : true,
default : 0,
},
regDtm : {
type : Date,
required : true,
default : Date.now,
}
});
TakeMedicineHistorySchema.statics.findByBottleId = async function(bottleId) {
return this.find({ bottleId });
};
TakeMedicineHistorySchema.statics.findByBottleIdAndMedicineId = async function(bottleId, medicineId) {
return this.find({ bottleId, medicineId });
};
module.export = mongoose.model("TakeMedicineHist", TakeMedicineHistorySchema);
\ No newline at end of file
module.exports = mongoose.model('BottleMedicine', BottleMedicineSchema);
\ No newline at end of file
......
......@@ -7,7 +7,7 @@ const DoctorInfoSchema = new Schema({
info : {
doctorLicense : { type : String, required : true, },
hospitalNm : { type : String, default : null, },
hosptialAddr : { type : String, default : null, },
hospitalAddr : { type : String, default : null, },
contact : { type : String, required : true, },
},
useYn : { type : String, default : 'W', required : true, },
......
......@@ -5,8 +5,12 @@ const Schema = mongoose.Schema;
const FeedbackSchema = new Schema({
fdbDtm : { type : Date, default : Date.now, required : true, },
fdbType : { type : String, required : true, },
bottleId : { type : Number, required : true, },
doctorId : { type : String, required : true, },
bmId : {
type : Schema.Types.ObjectId,
required : true,
ref : 'BottleMedicine',
},
doctorId : { type : String, required : true, ref : 'User', },
feedback : { type : String, required : true, },
});
......
......@@ -12,31 +12,14 @@ const MedicineSchema = new Schema ({
antiEffect : { type : String, required : true }
})
MedicineSchema.statics.findByName = async function(name) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.name.includes(name)
});
return result;
};
MedicineSchema.statics.findByCompany = async function(company) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.company.includes(company)
});
return result;
};
MedicineSchema.statics.findByTarget = async function(target) {
const all = await this.find().exec();
const result = all.filter(item => {
return item.target.includes(target)
});
return result;
MedicineSchema.statics.findByKeyword = function(keyword) {
return this.find({
$or : [
{ name : { $regex : keyword }},
{ company : { $regex : keyword }},
{ target : { $regex : keyword }},
]
})
};
MedicineSchema.statics.findByMedicineId = function(medicineId) {
......
......@@ -4,27 +4,36 @@ const moment = require('moment');
const Schema = mongoose.Schema;
const PatientInfoSchema = new Schema({
patientId : { type : String, required : true, },
doctorId : { type : String, required : true, },
patientId : { type : String, required : true, ref : 'User', },
doctorId : { type : String, required : true, ref : 'User', },
info : { type : String, required : true, },
useYn : { type : String, required : true, default : 'W', },
});
PatientInfoSchema.statics.findAllByPatientId = function(patientId) {
return this.find({ patientId });
PatientInfoSchema.statics.findAllByPatientIdAndUseYn = function(patientId, useYn) {
return this.find({ patientId, useYn });
};
PatientInfoSchema.statics.findAllByDoctorId = function(doctorId) {
return this.find({ doctorId });
PatientInfoSchema.statics.findAllByDoctorIdAndUseYn = function(doctorId, useYn) {
return this.find({ doctorId, useYn });
};
PatientInfoSchema.statics.findByPatientIdAndDoctorId = function(patientId, doctorId) {
return this.findOne({ patientId, doctorId });
};
PatientInfoSchema.statics.findByPatientIdAndDoctorIdAndUseYn = function(patientId, doctorId, useYn) {
return this.findOne({ patientId, doctorId, useYn });
};
PatientInfoSchema.methods.getInfo = function() {
return this.info;
};
PatientInfoSchema.methods.setUseYn = function(useYn) {
this.useYn = useYn;
};
PatientInfoSchema.methods.updateInfo = function(info) {
const date = moment(new Date()).format('YYYY-MM-DD hh:mm');
if(this.info.length)
......
......@@ -3,7 +3,7 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProfileSchema = new Schema({
userId : { type : String, required : true, },
userId : { type : String, required : true, ref : 'User', },
userNm : { type : String, required : true, },
userAge : { type : Number, required : true, },
contact : { type : String, required : true, },
......
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const TakeMedicineHistorySchema = new Schema ({
takeDate : {
type : Date,
required : true,
default : Date.now,
},
bmId : {
type : Schema.Types.ObjectId,
ref : 'BottleMedicine',
required : true,
},
temperature : { type : Number, default : 0 },
humidity : { type : Number, default : 0 },
balance : { type : Number, default : 0 },
});
module.exports = mongoose.model('TakeMedicineHist', TakeMedicineHistorySchema);
\ No newline at end of file
......@@ -5,7 +5,7 @@ const jwt = require('jsonwebtoken');
const Schema = mongoose.Schema;
const UserSchema = new Schema ({
userId : { type: String, required : true, unique : true, lowercase : true },
userId : { type: String, required : true, unique : true, lowercase : true, },
hashedPassword : { type : String, required : true },
userTypeCd : { type : String, required : true, default : 'NORMAL' },
useYn : { type : String, default : 'W', required : true, },
......@@ -39,6 +39,7 @@ UserSchema.methods.generateToken = function() {
_id : this._id,
userId : this.userId
},
// eslint-disable-next-line no-undef
process.env.JWT_SECRET,
{ expiresIn : '30d' }
);
......
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/code-frame@7.12.11":
"integrity" "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw=="
"resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz"
"version" "7.12.11"
dependencies:
"@babel/highlight" "^7.10.4"
"@babel/helper-validator-identifier@^7.14.5":
"integrity" "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g=="
"resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz"
"version" "7.14.9"
"@babel/highlight@^7.10.4":
"integrity" "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg=="
"resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz"
"version" "7.14.5"
dependencies:
"@babel/helper-validator-identifier" "^7.14.5"
"chalk" "^2.0.0"
"js-tokens" "^4.0.0"
"@eslint/eslintrc@^0.4.3":
"integrity" "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw=="
"resolved" "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz"
"version" "0.4.3"
dependencies:
"ajv" "^6.12.4"
"debug" "^4.1.1"
"espree" "^7.3.0"
"globals" "^13.9.0"
"ignore" "^4.0.6"
"import-fresh" "^3.2.1"
"js-yaml" "^3.13.1"
"minimatch" "^3.0.4"
"strip-json-comments" "^3.1.1"
"@humanwhocodes/config-array@^0.5.0":
"integrity" "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg=="
"resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz"
"version" "0.5.0"
dependencies:
"@humanwhocodes/object-schema" "^1.2.0"
"debug" "^4.1.1"
"minimatch" "^3.0.4"
"@humanwhocodes/object-schema@^1.2.0":
"integrity" "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w=="
"resolved" "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz"
"version" "1.2.0"
"acorn-jsx@^5.3.1":
"integrity" "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
"resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
"version" "5.3.2"
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^7.4.0":
"integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
"version" "7.4.1"
"ajv@^6.10.0", "ajv@^6.12.4":
"integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
"version" "6.12.6"
dependencies:
"fast-deep-equal" "^3.1.1"
"fast-json-stable-stringify" "^2.0.0"
"json-schema-traverse" "^0.4.1"
"uri-js" "^4.2.2"
"ajv@^8.0.1":
"integrity" "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz"
"version" "8.6.2"
dependencies:
"fast-deep-equal" "^3.1.1"
"json-schema-traverse" "^1.0.0"
"require-from-string" "^2.0.2"
"uri-js" "^4.2.2"
"ansi-colors@^4.1.1":
"integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
"resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz"
"version" "4.1.1"
"ansi-regex@^5.0.0":
"integrity" "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz"
"version" "5.0.0"
"ansi-styles@^3.2.1":
"integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="
"resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
"version" "3.2.1"
dependencies:
"color-convert" "^1.9.0"
"ansi-styles@^4.0.0", "ansi-styles@^4.1.0":
"integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="
"resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
"version" "4.3.0"
dependencies:
"color-convert" "^2.0.1"
"argparse@^1.0.7":
"integrity" "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="
"resolved" "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
"version" "1.0.10"
dependencies:
"sprintf-js" "~1.0.2"
"astral-regex@^2.0.0":
"integrity" "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
"resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
"version" "2.0.0"
"balanced-match@^1.0.0":
"integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
"version" "1.0.2"
"base64-js@^1.3.1":
"integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
"resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
"version" "1.5.1"
"bl@^4.0.2":
"integrity" "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="
"resolved" "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz"
"version" "4.1.0"
dependencies:
"buffer" "^5.5.0"
"inherits" "^2.0.4"
"readable-stream" "^3.4.0"
"brace-expansion@^1.1.7":
"integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="
"resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
"version" "1.1.11"
dependencies:
"balanced-match" "^1.0.0"
"concat-map" "0.0.1"
"buffer-from@^1.0.0":
"integrity" "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
"resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
"version" "1.1.1"
"buffer@^5.5.0":
"integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="
"resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
"version" "5.7.1"
dependencies:
"base64-js" "^1.3.1"
"ieee754" "^1.1.13"
"callback-stream@^1.0.2":
"integrity" "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg="
"resolved" "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz"
"version" "1.1.0"
dependencies:
"inherits" "^2.0.1"
"readable-stream" "> 1.0.0 < 3.0.0"
"callsites@^3.0.0":
"integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
"resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
"version" "3.1.0"
"chalk@^2.0.0":
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
"version" "2.4.2"
dependencies:
"ansi-styles" "^3.2.1"
"escape-string-regexp" "^1.0.5"
"supports-color" "^5.3.0"
"chalk@^4.0.0":
"integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
"resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
"version" "4.1.2"
dependencies:
"ansi-styles" "^4.1.0"
"supports-color" "^7.1.0"
"color-convert@^1.9.0":
"integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="
"resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
"version" "1.9.3"
dependencies:
"color-name" "1.1.3"
"color-convert@^2.0.1":
"integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
"resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
"version" "2.0.1"
dependencies:
"color-name" "~1.1.4"
"color-name@~1.1.4":
"integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
"resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
"version" "1.1.4"
"color-name@1.1.3":
"integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
"resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
"version" "1.1.3"
"commist@^1.0.0":
"integrity" "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg=="
"resolved" "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz"
"version" "1.1.0"
dependencies:
"leven" "^2.1.0"
"minimist" "^1.1.0"
"concat-map@0.0.1":
"integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
"version" "0.0.1"
"concat-stream@^2.0.0":
"integrity" "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="
"resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz"
"version" "2.0.0"
dependencies:
"buffer-from" "^1.0.0"
"inherits" "^2.0.3"
"readable-stream" "^3.0.2"
"typedarray" "^0.0.6"
"core-util-is@~1.0.0":
"integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
"resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
"version" "1.0.2"
"cross-spawn@^7.0.2":
"integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="
"resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
"version" "7.0.3"
dependencies:
"path-key" "^3.1.0"
"shebang-command" "^2.0.0"
"which" "^2.0.1"
"debug@^4.0.1", "debug@^4.1.1":
"integrity" "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ=="
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
"version" "4.3.1"
dependencies:
"ms" "2.1.2"
"deep-is@^0.1.3":
"integrity" "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
"resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
"version" "0.1.3"
"doctrine@^3.0.0":
"integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="
"resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
"version" "3.0.0"
dependencies:
"esutils" "^2.0.2"
"duplexify@^3.6.0":
"integrity" "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g=="
"resolved" "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz"
"version" "3.7.1"
dependencies:
"end-of-stream" "^1.0.0"
"inherits" "^2.0.1"
"readable-stream" "^2.0.0"
"stream-shift" "^1.0.0"
"emoji-regex@^8.0.0":
"integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
"version" "8.0.0"
"end-of-stream@^1.0.0", "end-of-stream@^1.1.0":
"integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="
"resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz"
"version" "1.4.4"
dependencies:
"once" "^1.4.0"
"enquirer@^2.3.5":
"integrity" "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="
"resolved" "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
"version" "2.3.6"
dependencies:
"ansi-colors" "^4.1.1"
"escape-string-regexp@^1.0.5":
"integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
"version" "1.0.5"
"escape-string-regexp@^4.0.0":
"integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
"version" "4.0.0"
"eslint-scope@^5.1.1":
"integrity" "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="
"resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
"version" "5.1.1"
dependencies:
"esrecurse" "^4.3.0"
"estraverse" "^4.1.1"
"eslint-utils@^2.1.0":
"integrity" "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg=="
"resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz"
"version" "2.1.0"
dependencies:
"eslint-visitor-keys" "^1.1.0"
"eslint-visitor-keys@^1.1.0":
"integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
"resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
"version" "1.3.0"
"eslint-visitor-keys@^1.3.0":
"integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
"resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
"version" "1.3.0"
"eslint-visitor-keys@^2.0.0":
"integrity" "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
"resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz"
"version" "2.1.0"
"eslint@^7.32.0":
"integrity" "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA=="
"resolved" "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz"
"version" "7.32.0"
dependencies:
"@babel/code-frame" "7.12.11"
"@eslint/eslintrc" "^0.4.3"
"@humanwhocodes/config-array" "^0.5.0"
"ajv" "^6.10.0"
"chalk" "^4.0.0"
"cross-spawn" "^7.0.2"
"debug" "^4.0.1"
"doctrine" "^3.0.0"
"enquirer" "^2.3.5"
"escape-string-regexp" "^4.0.0"
"eslint-scope" "^5.1.1"
"eslint-utils" "^2.1.0"
"eslint-visitor-keys" "^2.0.0"
"espree" "^7.3.1"
"esquery" "^1.4.0"
"esutils" "^2.0.2"
"fast-deep-equal" "^3.1.3"
"file-entry-cache" "^6.0.1"
"functional-red-black-tree" "^1.0.1"
"glob-parent" "^5.1.2"
"globals" "^13.6.0"
"ignore" "^4.0.6"
"import-fresh" "^3.0.0"
"imurmurhash" "^0.1.4"
"is-glob" "^4.0.0"
"js-yaml" "^3.13.1"
"json-stable-stringify-without-jsonify" "^1.0.1"
"levn" "^0.4.1"
"lodash.merge" "^4.6.2"
"minimatch" "^3.0.4"
"natural-compare" "^1.4.0"
"optionator" "^0.9.1"
"progress" "^2.0.0"
"regexpp" "^3.1.0"
"semver" "^7.2.1"
"strip-ansi" "^6.0.0"
"strip-json-comments" "^3.1.0"
"table" "^6.0.9"
"text-table" "^0.2.0"
"v8-compile-cache" "^2.0.3"
"espree@^7.3.0", "espree@^7.3.1":
"integrity" "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g=="
"resolved" "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz"
"version" "7.3.1"
dependencies:
"acorn" "^7.4.0"
"acorn-jsx" "^5.3.1"
"eslint-visitor-keys" "^1.3.0"
"esprima@^4.0.0":
"integrity" "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
"resolved" "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
"version" "4.0.1"
"esquery@^1.4.0":
"integrity" "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w=="
"resolved" "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz"
"version" "1.4.0"
dependencies:
"estraverse" "^5.1.0"
"esrecurse@^4.3.0":
"integrity" "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="
"resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
"version" "4.3.0"
dependencies:
"estraverse" "^5.2.0"
"estraverse@^4.1.1":
"integrity" "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
"version" "4.3.0"
"estraverse@^5.1.0":
"integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz"
"version" "5.2.0"
"estraverse@^5.2.0":
"integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
"resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz"
"version" "5.2.0"
"esutils@^2.0.2":
"integrity" "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
"resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
"version" "2.0.3"
"extend@^3.0.0":
"integrity" "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
"resolved" "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
"version" "3.0.2"
"fast-deep-equal@^3.1.1", "fast-deep-equal@^3.1.3":
"integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
"resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
"version" "3.1.3"
"fast-json-stable-stringify@^2.0.0":
"integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
"resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
"version" "2.1.0"
"fast-levenshtein@^2.0.6":
"integrity" "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
"resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
"version" "2.0.6"
"file-entry-cache@^6.0.1":
"integrity" "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="
"resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
"version" "6.0.1"
dependencies:
"flat-cache" "^3.0.4"
"flat-cache@^3.0.4":
"integrity" "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg=="
"resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
"version" "3.0.4"
dependencies:
"flatted" "^3.1.0"
"rimraf" "^3.0.2"
"flatted@^3.1.0":
"integrity" "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA=="
"resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz"
"version" "3.2.2"
"fs.realpath@^1.0.0":
"integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
"version" "1.0.0"
"functional-red-black-tree@^1.0.1":
"integrity" "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
"resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz"
"version" "1.0.1"
"glob-parent@^3.1.0":
"integrity" "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4="
"resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz"
"version" "3.1.0"
dependencies:
"is-glob" "^3.1.0"
"path-dirname" "^1.0.0"
"glob-parent@^5.1.2":
"integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
"resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
"version" "5.1.2"
dependencies:
"is-glob" "^4.0.1"
"glob-stream@^6.1.0":
"integrity" "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ="
"resolved" "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz"
"version" "6.1.0"
dependencies:
"extend" "^3.0.0"
"glob" "^7.1.1"
"glob-parent" "^3.1.0"
"is-negated-glob" "^1.0.0"
"ordered-read-streams" "^1.0.0"
"pumpify" "^1.3.5"
"readable-stream" "^2.1.5"
"remove-trailing-separator" "^1.0.1"
"to-absolute-glob" "^2.0.0"
"unique-stream" "^2.0.2"
"glob@^7.1.1", "glob@^7.1.3":
"integrity" "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA=="
"resolved" "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
"version" "7.1.6"
dependencies:
"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"
"globals@^13.6.0", "globals@^13.9.0":
"integrity" "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g=="
"resolved" "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz"
"version" "13.11.0"
dependencies:
"type-fest" "^0.20.2"
"has-flag@^3.0.0":
"integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
"resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
"version" "3.0.0"
"has-flag@^4.0.0":
"integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
"resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
"version" "4.0.0"
"help-me@^1.0.1":
"integrity" "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y="
"resolved" "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz"
"version" "1.1.0"
dependencies:
"callback-stream" "^1.0.2"
"glob-stream" "^6.1.0"
"through2" "^2.0.1"
"xtend" "^4.0.0"
"ieee754@^1.1.13":
"integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
"resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
"version" "1.2.1"
"ignore@^4.0.6":
"integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
"resolved" "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
"version" "4.0.6"
"import-fresh@^3.0.0", "import-fresh@^3.2.1":
"integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="
"resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
"version" "3.3.0"
dependencies:
"parent-module" "^1.0.0"
"resolve-from" "^4.0.0"
"imurmurhash@^0.1.4":
"integrity" "sha1-khi5srkoojixPcT7a21XbyMUU+o="
"resolved" "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
"version" "0.1.4"
"inflight@^1.0.4":
"integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
"resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
"version" "1.0.6"
dependencies:
"once" "^1.3.0"
"wrappy" "1"
"inherits@^2.0.1", "inherits@^2.0.3", "inherits@^2.0.4", "inherits@~2.0.3", "inherits@2":
"integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
"version" "2.0.4"
"is-absolute@^1.0.0":
"integrity" "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="
"resolved" "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz"
"version" "1.0.0"
dependencies:
"is-relative" "^1.0.0"
"is-windows" "^1.0.1"
"is-extglob@^2.1.0", "is-extglob@^2.1.1":
"integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
"resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
"version" "2.1.1"
"is-fullwidth-code-point@^3.0.0":
"integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
"resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
"version" "3.0.0"
"is-glob@^3.1.0":
"integrity" "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo="
"resolved" "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz"
"version" "3.1.0"
dependencies:
"is-extglob" "^2.1.0"
"is-glob@^4.0.0", "is-glob@^4.0.1":
"integrity" "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg=="
"resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz"
"version" "4.0.1"
dependencies:
"is-extglob" "^2.1.1"
"is-negated-glob@^1.0.0":
"integrity" "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI="
"resolved" "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz"
"version" "1.0.0"
"is-relative@^1.0.0":
"integrity" "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA=="
"resolved" "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz"
"version" "1.0.0"
dependencies:
"is-unc-path" "^1.0.0"
"is-unc-path@^1.0.0":
"integrity" "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ=="
"resolved" "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz"
"version" "1.0.0"
dependencies:
"unc-path-regex" "^0.1.2"
"is-windows@^1.0.1":
"integrity" "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
"resolved" "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
"version" "1.0.2"
"isarray@~1.0.0":
"integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
"version" "1.0.0"
"isexe@^2.0.0":
"integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
"resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
"version" "2.0.0"
"js-tokens@^4.0.0":
"integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
"resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
"version" "4.0.0"
"js-yaml@^3.13.1":
"integrity" "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="
"resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
"version" "3.14.1"
dependencies:
"argparse" "^1.0.7"
"esprima" "^4.0.0"
"json-schema-traverse@^0.4.1":
"integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
"resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
"version" "0.4.1"
"json-schema-traverse@^1.0.0":
"integrity" "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
"resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz"
"version" "1.0.0"
"json-stable-stringify-without-jsonify@^1.0.1":
"integrity" "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
"resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
"version" "1.0.1"
"leven@^2.1.0":
"integrity" "sha1-wuep93IJTe6dNCAq6KzORoeHVYA="
"resolved" "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz"
"version" "2.1.0"
"levn@^0.4.1":
"integrity" "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="
"resolved" "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
"version" "0.4.1"
dependencies:
"prelude-ls" "^1.2.1"
"type-check" "~0.4.0"
"lodash.clonedeep@^4.5.0":
"integrity" "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
"resolved" "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
"version" "4.5.0"
"lodash.merge@^4.6.2":
"integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
"resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
"version" "4.6.2"
"lodash.truncate@^4.4.2":
"integrity" "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM="
"resolved" "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz"
"version" "4.4.2"
"lru-cache@^6.0.0":
"integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="
"resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
"version" "6.0.0"
dependencies:
"yallist" "^4.0.0"
"minimatch@^3.0.4":
"integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA=="
"resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
"version" "3.0.4"
dependencies:
"brace-expansion" "^1.1.7"
"minimist@^1.1.0", "minimist@^1.2.5":
"integrity" "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
"version" "1.2.5"
"moment@^2.29.1":
"integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
"version" "2.29.1"
"mqtt-packet@^6.6.0":
"integrity" "sha512-0+u0ZoRj6H6AuzNY5d8qzXzyXmFI19gkdPRA14kGfKvbqYcpOL+HWUGHjtCxHqjm8CscwsH+dX0+Rxx4se5HSA=="
"resolved" "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.9.1.tgz"
"version" "6.9.1"
dependencies:
"bl" "^4.0.2"
"debug" "^4.1.1"
"process-nextick-args" "^2.0.1"
"mqtt@^4.2.6":
"integrity" "sha512-GpxVObyOzL0CGPBqo6B04GinN8JLk12NRYAIkYvARd9ZCoJKevvOyCaWK6bdK/kFSDj3LPDnCsJbezzNlsi87Q=="
"resolved" "https://registry.npmjs.org/mqtt/-/mqtt-4.2.6.tgz"
"version" "4.2.6"
dependencies:
"commist" "^1.0.0"
"concat-stream" "^2.0.0"
"debug" "^4.1.1"
"help-me" "^1.0.1"
"inherits" "^2.0.3"
"minimist" "^1.2.5"
"mqtt-packet" "^6.6.0"
"pump" "^3.0.0"
"readable-stream" "^3.6.0"
"reinterval" "^1.1.0"
"split2" "^3.1.0"
"ws" "^7.3.1"
"xtend" "^4.0.2"
"ms@2.1.2":
"integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
"version" "2.1.2"
"natural-compare@^1.4.0":
"integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
"resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
"version" "1.4.0"
"once@^1.3.0", "once@^1.3.1", "once@^1.4.0":
"integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
"resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
"version" "1.4.0"
dependencies:
"wrappy" "1"
"optionator@^0.9.1":
"integrity" "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw=="
"resolved" "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz"
"version" "0.9.1"
dependencies:
"deep-is" "^0.1.3"
"fast-levenshtein" "^2.0.6"
"levn" "^0.4.1"
"prelude-ls" "^1.2.1"
"type-check" "^0.4.0"
"word-wrap" "^1.2.3"
"ordered-read-streams@^1.0.0":
"integrity" "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4="
"resolved" "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz"
"version" "1.0.1"
dependencies:
"readable-stream" "^2.0.1"
"parent-module@^1.0.0":
"integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="
"resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
"version" "1.0.1"
dependencies:
"callsites" "^3.0.0"
"path-dirname@^1.0.0":
"integrity" "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
"resolved" "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz"
"version" "1.0.2"
"path-is-absolute@^1.0.0":
"integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
"resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
"version" "1.0.1"
"path-key@^3.1.0":
"integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
"resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
"version" "3.1.1"
"prelude-ls@^1.2.1":
"integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
"resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
"version" "1.2.1"
"process-nextick-args@^2.0.1", "process-nextick-args@~2.0.0":
"integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
"resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
"version" "2.0.1"
"progress@^2.0.0":
"integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
"resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
"version" "2.0.3"
"pump@^2.0.0":
"integrity" "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA=="
"resolved" "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz"
"version" "2.0.1"
dependencies:
"end-of-stream" "^1.1.0"
"once" "^1.3.1"
"pump@^3.0.0":
"integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="
"resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
"version" "3.0.0"
dependencies:
"end-of-stream" "^1.1.0"
"once" "^1.3.1"
"pumpify@^1.3.5":
"integrity" "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ=="
"resolved" "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz"
"version" "1.5.1"
dependencies:
"duplexify" "^3.6.0"
"inherits" "^2.0.3"
"pump" "^2.0.0"
"punycode@^2.1.0":
"integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
"resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
"version" "2.1.1"
"readable-stream@^2.0.0":
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
"version" "2.3.7"
dependencies:
"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"
"readable-stream@^2.0.1":
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
"version" "2.3.7"
dependencies:
"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"
"readable-stream@^2.1.5":
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
"version" "2.3.7"
dependencies:
"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"
"readable-stream@^3.0.0", "readable-stream@^3.0.2", "readable-stream@^3.4.0", "readable-stream@^3.6.0":
"integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
"version" "3.6.0"
dependencies:
"inherits" "^2.0.3"
"string_decoder" "^1.1.1"
"util-deprecate" "^1.0.1"
"readable-stream@> 1.0.0 < 3.0.0":
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
"version" "2.3.7"
dependencies:
"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"
"readable-stream@~2.3.6":
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
"version" "2.3.7"
dependencies:
"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"
"regexpp@^3.1.0":
"integrity" "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
"resolved" "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
"version" "3.2.0"
"reinterval@^1.1.0":
"integrity" "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc="
"resolved" "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz"
"version" "1.1.0"
"remove-trailing-separator@^1.0.1":
"integrity" "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
"resolved" "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"
"version" "1.1.0"
"require-from-string@^2.0.2":
"integrity" "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
"resolved" "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
"version" "2.0.2"
"resolve-from@^4.0.0":
"integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
"resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
"version" "4.0.0"
"rimraf@^3.0.2":
"integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="
"resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
"version" "3.0.2"
dependencies:
"glob" "^7.1.3"
"safe-buffer@~5.1.0", "safe-buffer@~5.1.1":
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
"version" "5.1.2"
"safe-buffer@~5.2.0":
"integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
"version" "5.2.1"
"semver@^7.2.1":
"integrity" "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ=="
"resolved" "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz"
"version" "7.3.5"
dependencies:
"lru-cache" "^6.0.0"
"shebang-command@^2.0.0":
"integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="
"resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
"version" "2.0.0"
dependencies:
"shebang-regex" "^3.0.0"
"shebang-regex@^3.0.0":
"integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
"resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
"version" "3.0.0"
"slice-ansi@^4.0.0":
"integrity" "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="
"resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz"
"version" "4.0.0"
dependencies:
"ansi-styles" "^4.0.0"
"astral-regex" "^2.0.0"
"is-fullwidth-code-point" "^3.0.0"
"split2@^3.1.0":
"integrity" "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg=="
"resolved" "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz"
"version" "3.2.2"
dependencies:
"readable-stream" "^3.0.0"
"sprintf-js@~1.0.2":
"integrity" "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
"resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
"version" "1.0.3"
"stream-shift@^1.0.0":
"integrity" "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
"resolved" "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz"
"version" "1.0.1"
"string_decoder@^1.1.1":
"integrity" "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="
"resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
"version" "1.3.0"
dependencies:
"safe-buffer" "~5.2.0"
"string_decoder@~1.1.1":
"integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="
"resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
"version" "1.1.1"
dependencies:
"safe-buffer" "~5.1.0"
"string-width@^4.2.0":
"integrity" "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA=="
"resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz"
"version" "4.2.2"
dependencies:
"emoji-regex" "^8.0.0"
"is-fullwidth-code-point" "^3.0.0"
"strip-ansi" "^6.0.0"
"strip-ansi@^6.0.0":
"integrity" "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w=="
"resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz"
"version" "6.0.0"
dependencies:
"ansi-regex" "^5.0.0"
"strip-json-comments@^3.1.0", "strip-json-comments@^3.1.1":
"integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
"resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
"version" "3.1.1"
"supports-color@^5.3.0":
"integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="
"resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
"version" "5.5.0"
dependencies:
"has-flag" "^3.0.0"
"supports-color@^7.1.0":
"integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
"resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
"version" "7.2.0"
dependencies:
"has-flag" "^4.0.0"
"table@^6.0.9":
"integrity" "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg=="
"resolved" "https://registry.npmjs.org/table/-/table-6.7.1.tgz"
"version" "6.7.1"
dependencies:
"ajv" "^8.0.1"
"lodash.clonedeep" "^4.5.0"
"lodash.truncate" "^4.4.2"
"slice-ansi" "^4.0.0"
"string-width" "^4.2.0"
"strip-ansi" "^6.0.0"
"text-table@^0.2.0":
"integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
"resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
"version" "0.2.0"
"through2-filter@^3.0.0":
"integrity" "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA=="
"resolved" "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz"
"version" "3.0.0"
dependencies:
"through2" "~2.0.0"
"xtend" "~4.0.0"
"through2@^2.0.1", "through2@~2.0.0":
"integrity" "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="
"resolved" "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
"version" "2.0.5"
dependencies:
"readable-stream" "~2.3.6"
"xtend" "~4.0.1"
"to-absolute-glob@^2.0.0":
"integrity" "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs="
"resolved" "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz"
"version" "2.0.2"
dependencies:
"is-absolute" "^1.0.0"
"is-negated-glob" "^1.0.0"
"type-check@^0.4.0", "type-check@~0.4.0":
"integrity" "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="
"resolved" "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
"version" "0.4.0"
dependencies:
"prelude-ls" "^1.2.1"
"type-fest@^0.20.2":
"integrity" "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
"version" "0.20.2"
"typedarray@^0.0.6":
"integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
"resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
"version" "0.0.6"
"unc-path-regex@^0.1.2":
"integrity" "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
"resolved" "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz"
"version" "0.1.2"
"unique-stream@^2.0.2":
"integrity" "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A=="
"resolved" "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz"
"version" "2.3.1"
dependencies:
"json-stable-stringify-without-jsonify" "^1.0.1"
"through2-filter" "^3.0.0"
"uri-js@^4.2.2":
"integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="
"resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
"version" "4.4.1"
dependencies:
"punycode" "^2.1.0"
"util-deprecate@^1.0.1", "util-deprecate@~1.0.1":
"integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
"version" "1.0.2"
"v8-compile-cache@^2.0.3":
"integrity" "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA=="
"resolved" "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"
"version" "2.3.0"
"which@^2.0.1":
"integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
"resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
"version" "2.0.2"
dependencies:
"isexe" "^2.0.0"
"word-wrap@^1.2.3":
"integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
"resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
"version" "1.2.3"
"wrappy@1":
"integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
"version" "1.0.2"
"ws@^7.3.1":
"integrity" "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
"resolved" "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz"
"version" "7.4.5"
"xtend@^4.0.0", "xtend@^4.0.2", "xtend@~4.0.0", "xtend@~4.0.1":
"integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
"resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
"version" "4.0.2"
"yallist@^4.0.0":
"integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
"resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
"version" "4.0.0"