박권수

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

1 +module.exports = {
2 + "env": {
3 + "browser": true,
4 + "commonjs": true,
5 + "es2021": true
6 + },
7 + "extends": "eslint:recommended",
8 + "parserOptions": {
9 + "ecmaVersion": 12
10 + },
11 + "rules": {
12 + "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
13 +
14 + }
15 +};
1 -{
2 - "extends": "eslint:recommended",
3 - "rules": {
4 - // "semi": ["warn", "never"],
5 - "quotes": ["warn", "single"],
6 - "no-console": ["off"],
7 - "no-unused-vars": ["warn", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
8 - "no-constant-condition" : ["off"]
9 - },
10 - "parserOptions": {
11 - "ecmaVersion": 9
12 - },
13 - "env": {
14 - "es6": true,
15 - "node": true,
16 - "browser": true,
17 - "amd": true
18 - },
19 - "globals": {
20 - "$": true,
21 - "require": true,
22 - "process": true
23 - },
24 - "root": true
25 -}
...\ No newline at end of file ...\ No newline at end of file
...@@ -8,6 +8,7 @@ const updateMedicineInfo = require('./src/lib/UpdatingMedicineInfo'); ...@@ -8,6 +8,7 @@ const updateMedicineInfo = require('./src/lib/UpdatingMedicineInfo');
8 const MqttServer = require('./src/util/MqttServer'); 8 const MqttServer = require('./src/util/MqttServer');
9 9
10 require('dotenv').config(); 10 require('dotenv').config();
11 +// eslint-disable-next-line no-undef
11 const { SERVER_PORT, MONGO_URL } = process.env; 12 const { SERVER_PORT, MONGO_URL } = process.env;
12 13
13 const app = new Koa(); 14 const app = new Koa();
...@@ -21,7 +22,7 @@ Mongoose.connect(MONGO_URL, { ...@@ -21,7 +22,7 @@ Mongoose.connect(MONGO_URL, {
21 useCreateIndex : true 22 useCreateIndex : true
22 }).then(() => { 23 }).then(() => {
23 console.log('\x1b[1;32mMongo DB is connected : ', MONGO_URL, '\x1b[0m'); 24 console.log('\x1b[1;32mMongo DB is connected : ', MONGO_URL, '\x1b[0m');
24 - updateMedicineInfo.updateMedicineInfo(); 25 + // updateMedicineInfo.updateMedicineInfo();
25 }).catch(e => { 26 }).catch(e => {
26 console.log(e); 27 console.log(e);
27 }) 28 })
......
This diff could not be displayed because it is too large.
...@@ -19,5 +19,8 @@ ...@@ -19,5 +19,8 @@
19 "dependencies": { 19 "dependencies": {
20 "moment": "^2.29.1", 20 "moment": "^2.29.1",
21 "mqtt": "^4.2.6" 21 "mqtt": "^4.2.6"
22 + },
23 + "devDependencies": {
24 + "eslint": "^7.32.0"
22 } 25 }
23 } 26 }
......
...@@ -20,7 +20,10 @@ exports.register = async(ctx) => { ...@@ -20,7 +20,10 @@ exports.register = async(ctx) => {
20 userId : Joi.string().email().max(50).required(), 20 userId : Joi.string().email().max(50).required(),
21 password : Joi.string().required(), 21 password : Joi.string().required(),
22 passwordCheck : Joi.string().required(), 22 passwordCheck : Joi.string().required(),
23 - }) 23 + userNm : Joi.string().required(),
24 + userAge : Joi.number().required(),
25 + contact : Joi.string().required(),
26 + });
24 27
25 const result = schema.validate(ctx.request.body); 28 const result = schema.validate(ctx.request.body);
26 if(result.error || password !== passwordCheck) { 29 if(result.error || password !== passwordCheck) {
...@@ -41,7 +44,6 @@ exports.register = async(ctx) => { ...@@ -41,7 +44,6 @@ exports.register = async(ctx) => {
41 }); 44 });
42 45
43 await user.setPassword(password); 46 await user.setPassword(password);
44 - await user.save();
45 47
46 const profile = new Profile({ 48 const profile = new Profile({
47 userId, 49 userId,
...@@ -50,6 +52,7 @@ exports.register = async(ctx) => { ...@@ -50,6 +52,7 @@ exports.register = async(ctx) => {
50 contact, 52 contact,
51 }); 53 });
52 54
55 + await user.save();
53 await profile.save(); 56 await profile.save();
54 57
55 ctx.status = 201; 58 ctx.status = 201;
...@@ -68,6 +71,7 @@ exports.doctorRegister = async ctx => { ...@@ -68,6 +71,7 @@ exports.doctorRegister = async ctx => {
68 userId : Joi.string().email().max(50).required(), 71 userId : Joi.string().email().max(50).required(),
69 password : Joi.string().required(), 72 password : Joi.string().required(),
70 passwordCheck : Joi.string().required(), 73 passwordCheck : Joi.string().required(),
74 + info : Joi.object().required(),
71 }) 75 })
72 76
73 const result = schema.validate(ctx.request.body); 77 const result = schema.validate(ctx.request.body);
...@@ -90,7 +94,6 @@ exports.doctorRegister = async ctx => { ...@@ -90,7 +94,6 @@ exports.doctorRegister = async ctx => {
90 }); 94 });
91 95
92 await doctor.setPassword(password); 96 await doctor.setPassword(password);
93 - doctor.save();
94 97
95 const doctorInfo = new DoctorInfo({ 98 const doctorInfo = new DoctorInfo({
96 doctorId : userId, 99 doctorId : userId,
...@@ -98,6 +101,8 @@ exports.doctorRegister = async ctx => { ...@@ -98,6 +101,8 @@ exports.doctorRegister = async ctx => {
98 useYn : 'W', 101 useYn : 'W',
99 }); 102 });
100 103
104 +
105 + doctor.save();
101 doctorInfo.save(); 106 doctorInfo.save();
102 107
103 ctx.status = 201; 108 ctx.status = 201;
......
1 +/* eslint-disable no-undef */
1 //어플에서 약병 등록 및, 약병에 관한 정보 조회 = 여기서 mqtt통신으로 broker에 데이터를 요청한다. 2 //어플에서 약병 등록 및, 약병에 관한 정보 조회 = 여기서 mqtt통신으로 broker에 데이터를 요청한다.
2 const Bottle = require('../../models/bottle'); 3 const Bottle = require('../../models/bottle');
3 const Hub = require('../../models/hub'); 4 const Hub = require('../../models/hub');
4 const Medicine = require('../../models/medicine'); 5 const Medicine = require('../../models/medicine');
5 const User = require('../../models/user'); 6 const User = require('../../models/user');
6 -const History = require('../../models/history'); 7 +const PatientInfo = require('../../models/patientInfo');
8 +const TakeMedicineHist = require('../../models/takeMedicineHistory');
9 +const BottleMedicine = require('../../models/bottleMedicine');
10 +const Feedback = require('../../models/feedback');
7 const Mqtt = require('../../lib/MqttModule'); 11 const Mqtt = require('../../lib/MqttModule');
8 const jwt = require('jsonwebtoken'); 12 const jwt = require('jsonwebtoken');
9 13
...@@ -16,7 +20,7 @@ exports.bottleConnect = async(ctx) => { ...@@ -16,7 +20,7 @@ exports.bottleConnect = async(ctx) => {
16 } 20 }
17 21
18 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 22 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
19 - const user = await User.findById(userId); 23 + const user = await User.findByUserId(userId);
20 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 24 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
21 ctx.status = 403; 25 ctx.status = 403;
22 return; 26 return;
...@@ -70,7 +74,7 @@ exports.bottleDisconnect = async(ctx) => { ...@@ -70,7 +74,7 @@ exports.bottleDisconnect = async(ctx) => {
70 } 74 }
71 75
72 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 76 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
73 - const user = await User.findById(userId); 77 + const user = await User.findByUserId(userId);
74 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 78 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
75 ctx.status = 403; 79 ctx.status = 403;
76 return; 80 return;
...@@ -102,7 +106,7 @@ exports.bottleDisconnect = async(ctx) => { ...@@ -102,7 +106,7 @@ exports.bottleDisconnect = async(ctx) => {
102 106
103 }; 107 };
104 108
105 -//약병 정보를 조회 -> 약병에 현재 데이터를 요청한다. message : req 109 +//약병 정보를 조회 -> 약병의 기록을 가져온다. message : req
106 exports.getBottleInfo = async(ctx) => { 110 exports.getBottleInfo = async(ctx) => {
107 const token = ctx.req.headers.authorization; 111 const token = ctx.req.headers.authorization;
108 if(!token || !token.length) { 112 if(!token || !token.length) {
...@@ -111,7 +115,7 @@ exports.getBottleInfo = async(ctx) => { ...@@ -111,7 +115,7 @@ exports.getBottleInfo = async(ctx) => {
111 } 115 }
112 116
113 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 117 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
114 - const user = await User.findById(userId); 118 + const user = await User.findByUserId(userId);
115 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 119 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
116 ctx.status = 403; 120 ctx.status = 403;
117 return; 121 return;
...@@ -126,12 +130,12 @@ exports.getBottleInfo = async(ctx) => { ...@@ -126,12 +130,12 @@ exports.getBottleInfo = async(ctx) => {
126 } 130 }
127 131
128 const hub = await Hub.findByHubId(bottle.getHubId()); 132 const hub = await Hub.findByHubId(bottle.getHubId());
129 - if(hub.getHub_UserId() !== userId || user.userTypeCd !== 'DOCTOR') { 133 + if(hub.userId !== userId) {
130 ctx.status = 403; 134 ctx.status = 403;
131 return; 135 return;
132 } 136 }
133 137
134 - if(user.userTypeCd === 'NORMAL') { 138 +
135 const hosting = hub.getHubHost(); 139 const hosting = hub.getHubHost();
136 //서버에서 bottle로 데이터를 요청한다. 140 //서버에서 bottle로 데이터를 요청한다.
137 const client = await Mqtt.mqttOn(hosting); 141 const client = await Mqtt.mqttOn(hosting);
...@@ -139,28 +143,88 @@ exports.getBottleInfo = async(ctx) => { ...@@ -139,28 +143,88 @@ exports.getBottleInfo = async(ctx) => {
139 const message = 'req'; 143 const message = 'req';
140 await Mqtt.mqttPublishMessage(client, { topic, message }); 144 await Mqtt.mqttPublishMessage(client, { topic, message });
141 145
142 - const bottle = await Bottle.findByBottleId(bottleId); 146 + const bottleMedicine = await BottleMedicine.find({ bottleId })
147 + .sort({ regDtm : 'desc' })
148 + .limit(1);
149 +
150 + if(bottleMedicine.length) {
151 +
152 + const takeMedicineHist = await TakeMedicineHist
153 + .find({ bmId : bottleMedicine[0]._id })
154 + .sort({ takeDate : 'desc' })
155 + .populate('bmId');
143 156
144 ctx.status = 200; 157 ctx.status = 200;
145 - ctx.body = bottle; 158 + ctx.body = takeMedicineHist;
159 +
160 + } else {
161 + ctx.status = 404;
162 + ctx.body = {
163 + error : '정보가 등록되지 않은 약병'
164 + }
165 + }
146 166
167 +}
168 +
169 +//약병에 대한 피드백의 정보를 가져옴
170 +exports.getBottleFeedback = async ctx => {
171 + const token = ctx.req.headers.authorization;
172 + if(!token || !token.length) {
173 + ctx.status = 401;
147 return; 174 return;
148 - } else if (user.userTypeCd === 'DOCTOR') { 175 + }
149 - let result = {
150 - bottle,
151 - history : [],
152 - };
153 176
154 - result.historyList = History.findByBottleId(bottle.bottleId); 177 + const { userId } = jwt.verify(token, process.env.JWT_SECRET);
178 + const user = await User.findByUserId(userId);
179 + if(!user || !user.userTypeCd || user.useYn !== 'Y') {
180 + ctx.status = 403;
181 + ctx.body = {
182 + error : '권한 없는 사용자'
183 + }
184 + return;
185 + }
155 186
156 - ctx.status = 200; 187 + const { bottleId } = ctx.params;
157 - ctx.body = result;
158 188
189 + const bottle = await Bottle.findByBottleId(bottleId);
190 + if(!bottle) {
191 + ctx.status = 404;
192 + ctx.body = {
193 + error : '존재하지 않는 약병'
194 + }
159 return; 195 return;
160 } 196 }
161 -}
162 197
163 -//약병의 ID를 찾아서 약의 정보를 등록 : Post 198 + const hub = await Hub.findByHubId(bottle.getHubId());
199 + if(hub.userId !== userId) {
200 + ctx.status = 403;
201 + ctx.body = {
202 + error : '약병에 대한 권한 없음'
203 + }
204 + return;
205 + }
206 +
207 + const bottleMedicine = await BottleMedicine.find({ bottleId })
208 + .sort({ regDtm : 'desc' })
209 + .limit(1);
210 +
211 + if(bottleMedicine.length) {
212 + const feedbackList = await Feedback.find({ bmId : bottleMedicine[0]._id })
213 + .sort({ fdbDtm : 'desc' })
214 + .populate('bmId');
215 +
216 + ctx.status = 200;
217 + ctx.body = feedbackList;
218 + } else {
219 + ctx.status = 404;
220 + ctx.body = {
221 + error : '정보가 등록되지 않은 약병',
222 + };
223 + }
224 +
225 +};
226 +
227 +//약병의 ID를 찾아서 약의 정보와 처방의를 등록 : Post
164 exports.setMedicine = async(ctx) => { 228 exports.setMedicine = async(ctx) => {
165 const token = ctx.req.headers.authorization; 229 const token = ctx.req.headers.authorization;
166 if(!token || !token.length) { 230 if(!token || !token.length) {
...@@ -169,42 +233,103 @@ exports.setMedicine = async(ctx) => { ...@@ -169,42 +233,103 @@ exports.setMedicine = async(ctx) => {
169 } 233 }
170 234
171 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 235 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
172 - const user = await User.findById(userId); 236 + const user = await User.findByUserId(userId);
173 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 237 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
174 ctx.status = 403; 238 ctx.status = 403;
175 return; 239 return;
176 } 240 }
177 241
178 const { bottleId } = ctx.params; 242 const { bottleId } = ctx.params;
179 - const { medicineId, dosage } = ctx.request.body; 243 + const { medicineId, dosage, doctorId } = ctx.request.body;
180 244
181 const bottle = await Bottle.findByBottleId(bottleId); 245 const bottle = await Bottle.findByBottleId(bottleId);
182 if(!bottle) { 246 if(!bottle) {
183 ctx.status = 404; 247 ctx.status = 404;
248 + ctx.body = {
249 + error : '약병 찾을 수 없음.',
250 + }
184 return; 251 return;
185 } 252 }
186 253
187 const hub = await Hub.findByHubId(bottle.getHubId()); 254 const hub = await Hub.findByHubId(bottle.getHubId());
188 if(hub.getHub_UserId() !== userId) { 255 if(hub.getHub_UserId() !== userId) {
189 ctx.status = 403; 256 ctx.status = 403;
257 + ctx.body = {
258 + error : '해당 허브 권한 없음',
259 + }
190 return; 260 return;
191 } 261 }
192 262
193 const medicine = await Medicine.findByMedicineId(medicineId); 263 const medicine = await Medicine.findByMedicineId(medicineId);
194 if(!medicine) { 264 if(!medicine) {
195 ctx.status = 404; 265 ctx.status = 404;
266 + ctx.body = {
267 + error : '해당 약 존재하지 않음',
268 + }
269 + return;
270 + }
271 +
272 + if(doctorId !== undefined && doctorId !== null && doctorId !== '') {
273 + const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
274 + if(!patientInfo) {
275 + ctx.status = 403;
276 + ctx.body = {
277 + error : '담당의가 아님',
278 + };
196 return; 279 return;
197 } 280 }
281 + }
198 282
199 - await Bottle.findOneAndUpdate({ 283 + const bottleMedicine = new BottleMedicine({
200 - bottleId 284 + bottleId,
201 - }, {
202 medicineId, 285 medicineId,
203 - dosage : parseInt(dosage) 286 + doctorId,
287 + dosage,
204 }); 288 });
289 + bottleMedicine.save();
205 290
206 ctx.status = 200; 291 ctx.status = 200;
207 -} 292 +};
293 +
294 +// //비어있는 약병에 의사를 등록한다.
295 +// exports.registerDoctorToBottle = async ctx => {
296 +// const token = ctx.req.headers.authorization;
297 +// if(!token || !token.length) {
298 +// ctx.status = 401;
299 +// return;
300 +// }
301 +
302 +// const { userId } = jwt.verify(token, process.env.JWT_SECRET);
303 +// const user = await User.findByUserId(userId);
304 +// if(!user || !user.userTypeCd || user.useYn !== 'Y') {
305 +// ctx.status = 403;
306 +// return;
307 +// }
308 +
309 +// const { bottleId } = ctx.params;
310 +// const { doctorId } = ctx.request.body;
311 +// const bottle = await Bottle.findByBottleId(bottleId);
312 +// if(!bottle) {
313 +// ctx.status = 404;
314 +// return;
315 +// }
316 +// if(bottle.getDoctorId()) {
317 +// ctx.status = 403;
318 +// return;
319 +// }
320 +
321 +// const patinetInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'Y');
322 +// if(!patinetInfo) {
323 +// ctx.status = 404;
324 +// return;
325 +// }
326 +
327 +// bottle.setDoctorId(doctorId);
328 +// bottle.save();
329 +
330 +// ctx.status = 200;
331 +
332 +// };
208 333
209 //로그인한 유저의 약병 리스트 가져오기 334 //로그인한 유저의 약병 리스트 가져오기
210 exports.getBottleList = async(ctx) => { 335 exports.getBottleList = async(ctx) => {
...@@ -215,7 +340,7 @@ exports.getBottleList = async(ctx) => { ...@@ -215,7 +340,7 @@ exports.getBottleList = async(ctx) => {
215 } 340 }
216 341
217 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 342 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
218 - const user = await User.findById(userId); 343 + const user = await User.findByUserId(userId);
219 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 344 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
220 ctx.status = 403; 345 ctx.status = 403;
221 return; 346 return;
...@@ -243,4 +368,4 @@ exports.getBottleList = async(ctx) => { ...@@ -243,4 +368,4 @@ exports.getBottleList = async(ctx) => {
243 ctx.status = 200; 368 ctx.status = 200;
244 ctx.body = bottleList; 369 ctx.body = bottleList;
245 370
246 -}
...\ No newline at end of file ...\ No newline at end of file
371 +};
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -28,6 +28,14 @@ bottle.delete('/:bottleId', bottleCtrl.bottleDisconnect); ...@@ -28,6 +28,14 @@ bottle.delete('/:bottleId', bottleCtrl.bottleDisconnect);
28 bottle.get('/:bottleId', bottleCtrl.getBottleInfo); 28 bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
29 29
30 /** 30 /**
31 + * 약병에 대한 피드백 확인
32 + * request parameter : bottleId
33 + * url : http://localhost:4000/api/bottle/feedback/:bottleId
34 + * return : feedback List
35 + */
36 +bottle.get('/feedback/:bottleId', bottleCtrl.getBottleFeedback);
37 +
38 +/**
31 * 약병에 약 등록 = 약 검색 후 약 ID(medicineId)와 복용 정보 보고 사용자가 약 복용량(dosage) 입력 39 * 약병에 약 등록 = 약 검색 후 약 ID(medicineId)와 복용 정보 보고 사용자가 약 복용량(dosage) 입력
32 * request parameter : medicineId, dosage 40 * request parameter : medicineId, dosage
33 * url : http://localhost:4000/api/bottle/:bottleId 41 * url : http://localhost:4000/api/bottle/:bottleId
...@@ -36,6 +44,14 @@ bottle.get('/:bottleId', bottleCtrl.getBottleInfo); ...@@ -36,6 +44,14 @@ bottle.get('/:bottleId', bottleCtrl.getBottleInfo);
36 bottle.patch('/:bottleId', bottleCtrl.setMedicine); 44 bottle.patch('/:bottleId', bottleCtrl.setMedicine);
37 45
38 /** 46 /**
47 + * 비어있는 약병에 전담의 등록
48 + * request parameter : bottleId, doctorId
49 + * url : http://localhost:4000/api/bottle/doctor/:bottleId
50 + * return null;
51 + */
52 +// bottle.patch('/doctor/:bottleId', bottleCtrl.registerDoctorToBottle);
53 +
54 +/**
39 * 현재 로그인한 유저의 허브 중, 해당 허브에 등록된 약병 리스트를 가져옴 55 * 현재 로그인한 유저의 허브 중, 해당 허브에 등록된 약병 리스트를 가져옴
40 * request parameter : x 56 * request parameter : x
41 * url : http://localhost:4000/api/bottle/hub/:hubId 57 * url : http://localhost:4000/api/bottle/hub/:hubId
......
...@@ -3,7 +3,8 @@ const User = require('../../models/user'); ...@@ -3,7 +3,8 @@ const User = require('../../models/user');
3 const Profile = require('../../models/profile'); 3 const Profile = require('../../models/profile');
4 const Bottle = require('../../models/bottle'); 4 const Bottle = require('../../models/bottle');
5 const Medicine = require('../../models/medicine'); 5 const Medicine = require('../../models/medicine');
6 -const History = require('../../models/history'); 6 +const BottleMedicine = require('../../models/bottleMedicine');
7 +const TakeMedicineHist = require('../../models/takeMedicineHistory');
7 const Feedback = require('../../models/feedback'); 8 const Feedback = require('../../models/feedback');
8 const Hub = require('../../models/hub'); 9 const Hub = require('../../models/hub');
9 const PatientInfo = require('../../models/patientInfo'); 10 const PatientInfo = require('../../models/patientInfo');
...@@ -21,19 +22,21 @@ exports.getPatientList = async ctx => { ...@@ -21,19 +22,21 @@ exports.getPatientList = async ctx => {
21 return; 22 return;
22 } 23 }
23 24
25 + // eslint-disable-next-line no-undef
24 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 26 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
25 - const user = await User.findById(userId); 27 + const user = await User.findByUserId(userId);
26 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') { 28 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
27 ctx.status = 403; 29 ctx.status = 403;
28 return; 30 return;
29 } 31 }
30 32
31 - const managePatientIdList = await PatientInfo.findAllByDoctorId(userId); 33 + const managePatientIdList = await PatientInfo.findAllByDoctorIdAndUseYn(userId, 'Y');
32 34
33 - const result = managePatientIdList.map(async patientId => { 35 + const result = [];
34 - const patient = await User.findByUserId(patientId); 36 + await Promise.all(managePatientIdList.map(async patient => {
35 - return patient; 37 + const patientProfile = await Profile.findByUserId(patient.patientId);
36 - }); 38 + result.push(patientProfile);
39 + }));
37 40
38 ctx.status = 200; 41 ctx.status = 200;
39 ctx.body = result; 42 ctx.body = result;
...@@ -52,21 +55,22 @@ exports.getPatientDetail = async ctx => { ...@@ -52,21 +55,22 @@ exports.getPatientDetail = async ctx => {
52 return; 55 return;
53 } 56 }
54 57
58 + // eslint-disable-next-line no-undef
55 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 59 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
56 - const user = await User.findById(userId); 60 + const user = await User.findByUserId(userId);
57 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') { 61 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
58 ctx.status = 403; 62 ctx.status = 403;
59 return; 63 return;
60 } 64 }
61 65
62 - const { patientId } = ctx.params; 66 + const { patientId } = ctx.request.body;
63 const patient = await User.findByUserId(patientId); 67 const patient = await User.findByUserId(patientId);
64 if(!patient || patient.useYn !== 'Y') { 68 if(!patient || patient.useYn !== 'Y') {
65 ctx.status = 404; 69 ctx.status = 404;
66 return; 70 return;
67 } 71 }
68 72
69 - const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId); 73 + const isDoctorsPatient = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
70 if(!isDoctorsPatient) { 74 if(!isDoctorsPatient) {
71 ctx.status = 403; 75 ctx.status = 403;
72 return; 76 return;
...@@ -78,12 +82,12 @@ exports.getPatientDetail = async ctx => { ...@@ -78,12 +82,12 @@ exports.getPatientDetail = async ctx => {
78 const reqUserHubList = await Hub.findAllByUserId(patientId); 82 const reqUserHubList = await Hub.findAllByUserId(patientId);
79 const reqUserBottleList = []; 83 const reqUserBottleList = [];
80 await Promise.all(reqUserHubList.map(async hub => { 84 await Promise.all(reqUserHubList.map(async hub => {
81 - const bottleList = await Bottle.findAllByHubId(hub.hubId); 85 + const bottleList = await Bottle.findAllByHubId(hub.hubId, userId);
82 reqUserBottleList.push(...bottleList); 86 reqUserBottleList.push(...bottleList);
83 })); 87 }));
84 88
85 const result = { 89 const result = {
86 - ...profile, 90 + profile,
87 info : isDoctorsPatient.getInfo(), 91 info : isDoctorsPatient.getInfo(),
88 bottleList : reqUserBottleList, 92 bottleList : reqUserBottleList,
89 }; 93 };
...@@ -105,10 +109,14 @@ exports.getBottleDetail = async ctx => { ...@@ -105,10 +109,14 @@ exports.getBottleDetail = async ctx => {
105 return; 109 return;
106 } 110 }
107 111
112 + // eslint-disable-next-line no-undef
108 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 113 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
109 - const user = await User.findById(userId); 114 + const user = await User.findByUserId(userId);
110 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') { 115 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
111 ctx.status = 403; 116 ctx.status = 403;
117 + ctx.body = {
118 + error : '권한 없는 사용자',
119 + }
112 return; 120 return;
113 } 121 }
114 122
...@@ -116,29 +124,29 @@ exports.getBottleDetail = async ctx => { ...@@ -116,29 +124,29 @@ exports.getBottleDetail = async ctx => {
116 const bottle = await Bottle.findByBottleId(bottleId); 124 const bottle = await Bottle.findByBottleId(bottleId);
117 if(!bottle) { 125 if(!bottle) {
118 ctx.status = 404; 126 ctx.status = 404;
127 + ctx.body = {
128 + error : '존재하지 않는 약병',
129 + }
119 return; 130 return;
120 } 131 }
121 - if(bottle.getDoctorId() !== userId) { 132 +
133 + const bottleMedicine = await BottleMedicine.findOne({ bottleId, doctorId : userId });
134 + if(!bottleMedicine) {
122 ctx.status = 403; 135 ctx.status = 403;
136 + ctx.body = {
137 + error : '약병에 대한 권한 없음',
138 + }
123 return; 139 return;
124 } 140 }
125 141
126 - 142 + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId });
127 - //약병에 들어있는 약 정보와 복용 내역을 가져온다. 143 + const takeMedicineHist = await TakeMedicineHist.find({
128 - const bottleInfo = { 144 + bmId : bottleMedicine._id,
129 - temperature : bottle.temperature, 145 + }).sort({ takeDate : 'desc' });
130 - humidity : bottle.humidity,
131 - dosage : bottle.dosage,
132 - balance : bottle.balance,
133 - };
134 -
135 - const medicine = await Medicine.findByMedicineId(bottle.getMedicineId());
136 - const takeHistory = await History.findByBottleIdAndMedicineId(bottleId, bottle.getMedicineId());
137 146
138 const result = { 147 const result = {
139 - bottleInfo,
140 medicine, 148 medicine,
141 - takeHistory, 149 + takeMedicineHist,
142 }; 150 };
143 151
144 ctx.status = 200; 152 ctx.status = 200;
...@@ -158,21 +166,22 @@ exports.writeReqPatientReport = async ctx => { ...@@ -158,21 +166,22 @@ exports.writeReqPatientReport = async ctx => {
158 return; 166 return;
159 } 167 }
160 168
169 + // eslint-disable-next-line no-undef
161 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 170 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
162 - const user = await User.findById(userId); 171 + const user = await User.findByUserId(userId);
163 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') { 172 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
164 ctx.status = 403; 173 ctx.status = 403;
165 return; 174 return;
166 } 175 }
167 176
168 - const { reqUserId, info } = ctx.request.body; 177 + const { patientId, info } = ctx.request.body;
169 - const patient = await User.findByUserId(reqUserId); 178 + const patient = await User.findByUserId(patientId);
170 if(!patient || patient.useYn !== 'Y') { 179 if(!patient || patient.useYn !== 'Y') {
171 ctx.status = 404; 180 ctx.status = 404;
172 return; 181 return;
173 } 182 }
174 183
175 - const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(reqUserId, userId); 184 + const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
176 if(!patientInfo) { 185 if(!patientInfo) {
177 ctx.status = 404; 186 ctx.status = 404;
178 return; 187 return;
...@@ -197,10 +206,14 @@ exports.writeReqBottleFeedback = async ctx => { ...@@ -197,10 +206,14 @@ exports.writeReqBottleFeedback = async ctx => {
197 return; 206 return;
198 } 207 }
199 208
209 + // eslint-disable-next-line no-undef
200 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 210 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
201 - const user = await User.findById(userId); 211 + const user = await User.findByUserId(userId);
202 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') { 212 if(!user || user.userTypeCd !== 'DOCTOR' || user.useYn !== 'Y') {
203 ctx.status = 403; 213 ctx.status = 403;
214 + ctx.body = {
215 + error : '권한 없는 사용자',
216 + }
204 return; 217 return;
205 } 218 }
206 219
...@@ -208,17 +221,27 @@ exports.writeReqBottleFeedback = async ctx => { ...@@ -208,17 +221,27 @@ exports.writeReqBottleFeedback = async ctx => {
208 const bottle = await Bottle.findByBottleId(bottleId); 221 const bottle = await Bottle.findByBottleId(bottleId);
209 if(!bottle) { 222 if(!bottle) {
210 ctx.status = 404; 223 ctx.status = 404;
224 + ctx.body = {
225 + error : '존재하지 않는 약병'
226 + }
211 return; 227 return;
212 } 228 }
213 - if(bottle.getDoctorId() !== userId) { 229 +
230 + const bottleMedicine = await BottleMedicine.find({ bottleId, doctorId : userId })
231 + .sort({ regDtm : 'desc' })
232 + .limit(1);
233 +
234 + if(!bottleMedicine.length) {
214 ctx.status = 403; 235 ctx.status = 403;
236 + ctx.body = {
237 + error : '약병에 대한 권한 없음'
238 + }
215 return; 239 return;
216 } 240 }
217 241
218 const newFeedback = new Feedback({ 242 const newFeedback = new Feedback({
219 - fdbDtm : new Date(),
220 fdbType, 243 fdbType,
221 - bottleId, 244 + bmId : bottleMedicine[0]._id,
222 doctorId : userId, 245 doctorId : userId,
223 feedback, 246 feedback,
224 }); 247 });
...@@ -240,27 +263,35 @@ exports.registerNewPatient = async ctx => { ...@@ -240,27 +263,35 @@ exports.registerNewPatient = async ctx => {
240 return; 263 return;
241 } 264 }
242 265
266 + // eslint-disable-next-line no-undef
243 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 267 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
244 - const user = await User.findById(userId); 268 + const user = await User.findByUserId(userId);
245 if(!user || user.userTypeCd !== 'DOCTOR') { 269 if(!user || user.userTypeCd !== 'DOCTOR') {
246 ctx.status = 403; 270 ctx.status = 403;
247 return; 271 return;
248 } 272 }
249 273
250 - const { reqUserId } = ctx.request.body; 274 + const { patientId } = ctx.request.body;
251 - const patient = await User.findByUserId(reqUserId); 275 + const patient = await User.findByUserId(patientId);
252 if(!patient || patient.useYn !== 'Y') { 276 if(!patient || patient.useYn !== 'Y') {
253 ctx.status = 404; 277 ctx.status = 404;
254 return; 278 return;
255 } 279 }
256 280
281 + const isExistPatientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId);
282 + if(isExistPatientInfo) {
283 + ctx.status = 403;
284 + return;
285 + }
286 +
257 const patientInfo = new PatientInfo({ 287 const patientInfo = new PatientInfo({
258 - patientId : reqUserId, 288 + patientId,
259 doctorId : userId, 289 doctorId : userId,
260 info : '', 290 info : '',
291 + useYn : 'W',
261 }); 292 });
262 293
263 - patientInfo.updateInfo('환자 등록'); 294 + patientInfo.updateInfo('환자 등록 요청');
264 patientInfo.save(); 295 patientInfo.save();
265 296
266 ctx.status = 200; 297 ctx.status = 200;
...@@ -279,8 +310,9 @@ exports.removeReqPatient = async ctx => { ...@@ -279,8 +310,9 @@ exports.removeReqPatient = async ctx => {
279 return; 310 return;
280 } 311 }
281 312
313 + // eslint-disable-next-line no-undef
282 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 314 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
283 - const user = await User.findById(userId); 315 + const user = await User.findByUserId(userId);
284 if(!user || user.userTypeCd !== 'DOCTOR') { 316 if(!user || user.userTypeCd !== 'DOCTOR') {
285 ctx.status = 403; 317 ctx.status = 403;
286 return; 318 return;
...@@ -293,16 +325,14 @@ exports.removeReqPatient = async ctx => { ...@@ -293,16 +325,14 @@ exports.removeReqPatient = async ctx => {
293 return; 325 return;
294 } 326 }
295 327
296 - const patientInfo = await PatientInfo.findByPatientIdAndDoctorId(patientId, userId); 328 + const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(patientId, userId, 'Y');
297 if(!patientInfo) { 329 if(!patientInfo) {
298 ctx.status = 404; 330 ctx.status = 404;
299 return; 331 return;
300 } 332 }
301 333
302 - await PatientInfo.deleteOne({ 334 + await patientInfo.setUseYn('N')
303 - patientId, 335 + patientInfo.save();
304 - doctorId : userId,
305 - });
306 336
307 ctx.status = 200; 337 ctx.status = 200;
308 338
......
...@@ -17,7 +17,7 @@ doctor.get('/patient', doctorCtrl.getPatientList); ...@@ -17,7 +17,7 @@ doctor.get('/patient', doctorCtrl.getPatientList);
17 * url : http://localhost:4000/doctor/patient/:patientId 17 * url : http://localhost:4000/doctor/patient/:patientId
18 * return : patient Detail 18 * return : patient Detail
19 */ 19 */
20 -doctor.get('/patient/:patientId', doctorCtrl.getPatientDetail); 20 +doctor.get('/patient/detail', doctorCtrl.getPatientDetail);
21 21
22 /** 22 /**
23 * 현재 로그인한 유저(의사)의 관리 약병 상세 정보를 가져옴 23 * 현재 로그인한 유저(의사)의 관리 약병 상세 정보를 가져옴
...@@ -37,7 +37,7 @@ doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail); ...@@ -37,7 +37,7 @@ doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail);
37 doctor.patch('/patient', doctorCtrl.writeReqPatientReport); 37 doctor.patch('/patient', doctorCtrl.writeReqPatientReport);
38 38
39 /** 39 /**
40 - * 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 기록함 40 + * 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 등록함.
41 * request parameter : bottleId, fdbType, feedback 41 * request parameter : bottleId, fdbType, feedback
42 * url : http://localhost:4000/doctor/bottle 42 * url : http://localhost:4000/doctor/bottle
43 * return : null 43 * return : null
......
...@@ -12,8 +12,9 @@ exports.hubConnect = async (ctx) => { ...@@ -12,8 +12,9 @@ exports.hubConnect = async (ctx) => {
12 return; 12 return;
13 } 13 }
14 14
15 + // eslint-disable-next-line no-undef
15 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 16 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
16 - const user = await User.findById(userId); 17 + const user = await User.findByUserId(userId);
17 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 18 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
18 ctx.status = 403; 19 ctx.status = 403;
19 return; 20 return;
...@@ -53,8 +54,9 @@ exports.getHubList = async(ctx) => { ...@@ -53,8 +54,9 @@ exports.getHubList = async(ctx) => {
53 return; 54 return;
54 } 55 }
55 56
57 + // eslint-disable-next-line no-undef
56 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 58 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
57 - const user = await User.findById(userId); 59 + const user = await User.findByUserId(userId);
58 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 60 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
59 ctx.status = 403; 61 ctx.status = 403;
60 return; 62 return;
...@@ -77,8 +79,9 @@ exports.hubDisconnect = async(ctx) => { ...@@ -77,8 +79,9 @@ exports.hubDisconnect = async(ctx) => {
77 return; 79 return;
78 } 80 }
79 81
82 + // eslint-disable-next-line no-undef
80 const { userId } = jwt.verify(token, process.env.JWT_SECRET); 83 const { userId } = jwt.verify(token, process.env.JWT_SECRET);
81 - const user = await User.findById(userId); 84 + const user = await User.findByUserId(userId);
82 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 85 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
83 ctx.status = 403; 86 ctx.status = 403;
84 return; 87 return;
......
1 -const Router = require('koa-router') 1 +const Router = require('koa-router');
2 -const auth = require('./auth') 2 +
3 -const user = require('./user') 3 +const auth = require('./auth');
4 -const bottle = require('./bottle') 4 +const user = require('./user');
5 -const hub = require('./hub') 5 +const bottle = require('./bottle');
6 -const medicine = require('./medicine') 6 +const hub = require('./hub');
7 +const medicine = require('./medicine');
7 const doctor = require('./doctor'); 8 const doctor = require('./doctor');
9 +const manage = require('./manage');
8 10
9 const api = new Router(); 11 const api = new Router();
10 12
11 -api.use('/auth', auth.routes()) 13 +api.use('/auth', auth.routes());
12 -api.use('/user', user.routes()) 14 +api.use('/user', user.routes());
13 -api.use('/bottle', bottle.routes()) 15 +api.use('/bottle', bottle.routes());
14 -api.use('/hub', hub.routes()) 16 +api.use('/hub', hub.routes());
15 -api.use('/medicine', medicine.routes()) 17 +api.use('/medicine', medicine.routes());
16 api.use('/doctor', doctor.routes()); 18 api.use('/doctor', doctor.routes());
19 +api.use('/manage', manage.routes());
17 20
18 module.exports = api; 21 module.exports = api;
...\ No newline at end of file ...\ No newline at end of file
......
1 +const Router = require('koa-router');
2 +
3 +const manage = new Router();
4 +
5 +
6 +module.exports = manage;
...\ No newline at end of file ...\ No newline at end of file
...@@ -8,23 +8,9 @@ exports.medicineSearch = async(ctx) => { ...@@ -8,23 +8,9 @@ exports.medicineSearch = async(ctx) => {
8 return; 8 return;
9 } 9 }
10 10
11 - const { name, company, target } = ctx.request.body; 11 + const { keyword } = ctx.request.body;
12 12
13 - let result = []; 13 + const result = await Medicine.findByKeyword(keyword);
14 -
15 - if (name && name !== '' && name !== undefined)
16 - result = await medicineSearch_ByName(name);
17 -
18 - else if (company && company !== '' && company !== undefined)
19 - result = await medicineSearch_ByCompany(company);
20 -
21 - else if (target && target !== '' && target !== undefined)
22 - result = await medicineSearch_ByTarget(target);
23 -
24 - if(!result.length) {
25 - ctx.status = 404;
26 - return;
27 - }
28 14
29 ctx.status = 200; 15 ctx.status = 200;
30 ctx.body = result; 16 ctx.body = result;
...@@ -48,21 +34,3 @@ exports.medicineGet = async(ctx) => { ...@@ -48,21 +34,3 @@ exports.medicineGet = async(ctx) => {
48 ctx.body = medicine; 34 ctx.body = medicine;
49 35
50 } 36 }
...\ No newline at end of file ...\ No newline at end of file
51 -
52 -//이름으로 약 검색
53 -const medicineSearch_ByName = async(name) => {
54 - const result = await Medicine.findByName(name);
55 - return result;
56 -}
57 -
58 -//제조사명으로 약 검색
59 -const medicineSearch_ByCompany = async(company) => {
60 - const result = await Medicine.findByCompany(company);
61 - return result;
62 -}
63 -
64 -//타겟 병명으로 약 검색
65 -const medicineSearch_ByTarget = async(target) => {
66 - const result = await Medicine.findByTarget(target);
67 - return result;
68 -}
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -11,4 +11,22 @@ const user = new Router(); ...@@ -11,4 +11,22 @@ const user = new Router();
11 */ 11 */
12 user.get('/', userCtrl.getMyDetail); 12 user.get('/', userCtrl.getMyDetail);
13 13
14 +/**
15 + * 유저를 등록하려는 의사의 요청을 전부 보여준다
16 + * request parameter : token,
17 + * url : http://localhost:4000/api/user/doctorrequest
18 + * return : List
19 + */
20 +user.get('/doctorrequest', userCtrl.viewAllDoctorRegister);
21 +
22 +
23 +/**
24 + * 유저를 등록하려는 의사의 요청을 수락한다.
25 + * request parameter : token, doctorId,
26 + * url : http://localhost:4000/api/user/doctorrequest/:doctorId
27 + * return : null
28 + */
29 +user.post('/doctorrequest/accept', userCtrl.acceptDoctorRegister);
30 +
31 +
14 module.exports = user; 32 module.exports = user;
......
1 //유저에 관련된 Api 1 //유저에 관련된 Api
2 const User = require('../../models/user'); 2 const User = require('../../models/user');
3 const Profile = require('../../models/profile'); 3 const Profile = require('../../models/profile');
4 +const PatientInfo = require('../../models/patientInfo');
4 const jwt = require('jsonwebtoken'); 5 const jwt = require('jsonwebtoken');
5 6
6 7
8 +/**
9 + * 내 정보를 확인한다.
10 + * @param {*} ctx
11 + * http methods : get
12 + */
7 exports.getMyDetail = async ctx => { 13 exports.getMyDetail = async ctx => {
8 const token = ctx.req.headers.authorization 14 const token = ctx.req.headers.authorization
9 if (!token || !token.length) { 15 if (!token || !token.length) {
...@@ -12,7 +18,7 @@ exports.getMyDetail = async ctx => { ...@@ -12,7 +18,7 @@ exports.getMyDetail = async ctx => {
12 } 18 }
13 19
14 const { userId } = jwt.verify(token, process.env.JWT_SECRET) 20 const { userId } = jwt.verify(token, process.env.JWT_SECRET)
15 - const user = await User.findById(userId) 21 + const user = await User.findByUserId(userId)
16 if(!user || !user.userTypeCd || user.useYn !== 'Y') { 22 if(!user || !user.userTypeCd || user.useYn !== 'Y') {
17 ctx.status = 403; 23 ctx.status = 403;
18 return; 24 return;
...@@ -25,7 +31,71 @@ exports.getMyDetail = async ctx => { ...@@ -25,7 +31,71 @@ exports.getMyDetail = async ctx => {
25 31
26 } 32 }
27 33
28 -//toDo 34 +/**
35 + * 내 정보를 업데이트한다.
36 + * @param {*} ctx
37 + * http methods : post
38 + */
29 exports.updateMyInfo = async ctx => { 39 exports.updateMyInfo = async ctx => {
30 40
31 -} 41 +};
42 +
43 +/**
44 + * 의사가 요청한 환자 등록을 확인한다.
45 + * @param {*} ctx
46 + * http methods : get
47 + */
48 +exports.viewAllDoctorRegister = async ctx => {
49 + const token = ctx.req.headers.authorization
50 + if (!token || !token.length) {
51 + ctx.status = 401
52 + return
53 + }
54 +
55 + const { userId } = jwt.verify(token, process.env.JWT_SECRET)
56 + const user = await User.findByUserId(userId)
57 + if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
58 + ctx.status = 403;
59 + return;
60 + }
61 +
62 + const patientInfoList = await PatientInfo.findAllByPatientIdAndUseYn(userId, 'W');
63 +
64 + ctx.status = 200;
65 + ctx.body = patientInfoList;
66 +
67 +};
68 +
69 +/**
70 + * 의사가 요청한 환자 등록을 수락한다/
71 + * @param {*} ctx
72 + * http methods : post
73 + */
74 +exports.acceptDoctorRegister = async ctx => {
75 + const token = ctx.req.headers.authorization
76 + if (!token || !token.length) {
77 + ctx.status = 401
78 + return
79 + }
80 +
81 + const { userId } = jwt.verify(token, process.env.JWT_SECRET)
82 + const user = await User.findByUserId(userId)
83 + if(!user || !user.userTypeCd || user.userTypeCd !== 'NORMAL' || user.useYn !== 'Y') {
84 + ctx.status = 403;
85 + return;
86 + }
87 +
88 + const { doctorId } = ctx.request.body;
89 + const patientInfo = await PatientInfo.findByPatientIdAndDoctorIdAndUseYn(userId, doctorId, 'W');
90 + if(!patientInfo) {
91 + ctx.status = 404;
92 + return;
93 + }
94 +
95 + patientInfo.updateInfo('환자 등록 요청 수락');
96 + patientInfo.setUseYn('Y');
97 + patientInfo.save();
98 +
99 + ctx.status = 200;
100 +
101 +};
......
1 const Bottle = require('../models/bottle'); 1 const Bottle = require('../models/bottle');
2 -const History = require('../models/history'); 2 +const BottleMedicine = require('../models/bottleMedicine');
3 +const TakeMedicineHist = require('../models/takeMedicineHistory');
3 4
4 //message subscribe 후 message를 가공한 이후 해당 데이터를 보낼 topic과 message를 리턴하는 함수 5 //message subscribe 후 message를 가공한 이후 해당 데이터를 보낼 topic과 message를 리턴하는 함수
5 exports.dataPublish = async (topic, message) => { 6 exports.dataPublish = async (topic, message) => {
6 //client가 subscribe를 하면 메시지를 보낸 약병의 topic과 message를 가공 및 보낸 약병의 bottleId를 가져옴 7 //client가 subscribe를 하면 메시지를 보낸 약병의 topic과 message를 가공 및 보낸 약병의 bottleId를 가져옴
7 const data = await factoring(topic, message); 8 const data = await factoring(topic, message);
8 - const { bottleId } = data;
9 -
10 //가공된 데이터를 bottleId의 약병에 업데이트 9 //가공된 데이터를 bottleId의 약병에 업데이트
11 await bottleInfoUpdate(data); 10 await bottleInfoUpdate(data);
12 //가공된 데이터를 메시지로 만들어 topic과 message 리턴 11 //가공된 데이터를 메시지로 만들어 topic과 message 리턴
13 - const result = await transPublishingTopicAndMessage(bottleId); 12 + const result = await transPublishingTopicAndMessage(data.bottleId);
14 13
15 return result; 14 return result;
16 15
...@@ -27,12 +26,10 @@ const factoring = async (topic, message) => { ...@@ -27,12 +26,10 @@ const factoring = async (topic, message) => {
27 balance = await balanceFactoring(balance); 26 balance = await balanceFactoring(balance);
28 else balance = '-1'; 27 else balance = '-1';
29 28
30 - const openDate = new Date();
31 -
32 return { 29 return {
33 bottleId, 30 bottleId,
34 isOpen, 31 isOpen,
35 - openDate, 32 + openDate : new Date(),
36 temperature, 33 temperature,
37 humidity, 34 humidity,
38 balance 35 balance
...@@ -66,27 +63,19 @@ const bottleInfoUpdate = async(data) => { ...@@ -66,27 +63,19 @@ const bottleInfoUpdate = async(data) => {
66 humidity = parseFloat(humidity); 63 humidity = parseFloat(humidity);
67 balance = parseInt(balance); 64 balance = parseInt(balance);
68 65
69 - const bottle = await Bottle.findByBottleId(bottleId); 66 + const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
70 67
71 - if(bottle) { 68 + if(bottleMedicine) {
72 if(isOpen) { 69 if(isOpen) {
73 - const history = new History({ 70 + const takeMedicineHist = new TakeMedicineHist({
74 - takeDate : new Date(openDate), 71 + takeDate : openDate,
75 - bottleId, 72 + bmId : bottleMedicine._id,
76 - medicineId : bottle.getMedicineId(), 73 + temperature,
74 + humidity,
75 + balance,
77 }); 76 });
78 - history.save(); 77 + takeMedicineHist.save();
79 - }
80 -
81 - if(balance !== -1) {
82 - await Bottle.findOneAndUpdate({
83 - bottleId
84 - }, { balance })
85 } 78 }
86 -
87 - bottle.updateTemperature(temperature);
88 - bottle.updateHumidity(humidity);
89 - bottle.save();
90 } 79 }
91 } 80 }
92 81
...@@ -94,11 +83,12 @@ const bottleInfoUpdate = async(data) => { ...@@ -94,11 +83,12 @@ const bottleInfoUpdate = async(data) => {
94 const transPublishingTopicAndMessage = async(bottleId) => { 83 const transPublishingTopicAndMessage = async(bottleId) => {
95 const topic = 'bottle/' + bottleId + '/stb'; 84 const topic = 'bottle/' + bottleId + '/stb';
96 85
97 - const bottle = await Bottle.findByBottleId(bottleId); 86 + const bottleMedicine = await BottleMedicine.find({ bottleId }).sort((a, b) => a.regDtm < b.regDtm)[0];
98 - const recentOpen = bottle.getRecentOpenDate(); 87 + const takeMedicineHist = await TakeMedicineHist.find({
99 - const dosage = bottle.getDosage(); 88 + bmId : bottleMedicine._id
89 + }).sort((a, b) => a.takeDate < b.takeDate)[0];
100 90
101 - const message = 'res/' + await transDate(recentOpen) + '/' + dosage; 91 + const message = 'res/' + await transDate(takeMedicineHist.takeDate) + '/' + bottleMedicine.dosage;
102 92
103 return { 93 return {
104 topic, 94 topic,
......
1 const mqtt = require('mqtt') 1 const mqtt = require('mqtt')
2 const clientList = [] 2 const clientList = []
3 3
4 -exports.mqttOn = async (hosting, func) => { 4 +exports.mqttOn = async (hosting, foo) => {
5 const filterIndex = clientList.findIndex(client => { 5 const filterIndex = clientList.findIndex(client => {
6 return (client.options.clientId === hosting.clientId 6 return (client.options.clientId === hosting.clientId
7 && client.options.host === hosting.host 7 && client.options.host === hosting.host
...@@ -17,7 +17,7 @@ exports.mqttOn = async (hosting, func) => { ...@@ -17,7 +17,7 @@ exports.mqttOn = async (hosting, func) => {
17 }) 17 })
18 18
19 client.on('message', async (topic, message) => { 19 client.on('message', async (topic, message) => {
20 - const result = await func(topic, message.toString()) 20 + const result = await foo(topic, message.toString())
21 console.log('\x1b[1;32msubscribe : topic', topic, 'message : ', message.toString(), '\x1b[0m') 21 console.log('\x1b[1;32msubscribe : topic', topic, 'message : ', message.toString(), '\x1b[0m')
22 this.mqttPublishMessage(client, result) 22 this.mqttPublishMessage(client, result)
23 }) 23 })
......
...@@ -15,7 +15,7 @@ const jwtMiddleware = async (ctx, next) => { ...@@ -15,7 +15,7 @@ const jwtMiddleware = async (ctx, next) => {
15 }; 15 };
16 const now = Math.floor(Date.now() / 1000); 16 const now = Math.floor(Date.now() / 1000);
17 if (decoded.exp - now < 60 * 60 * 24 * 7) { 17 if (decoded.exp - now < 60 * 60 * 24 * 7) {
18 - const user = await User.findById(decoded._id); 18 + const user = await User.findByUserId(decoded._id);
19 const token = user.generateToken(); 19 const token = user.generateToken();
20 20
21 ctx.cookies.set('access_token', token, { 21 ctx.cookies.set('access_token', token, {
......
...@@ -4,13 +4,7 @@ const Schema = mongoose.Schema; ...@@ -4,13 +4,7 @@ const Schema = mongoose.Schema;
4 4
5 const BottleSchema = new Schema ({ 5 const BottleSchema = new Schema ({
6 bottleId : { type : Number, required : true, unique : true }, 6 bottleId : { type : Number, required : true, unique : true },
7 - temperature : { type : Number, default : 0 }, 7 + hubId : { type : Number, required : true, ref : 'Hub', },
8 - humidity : { type : Number, default : 0 },
9 - balance : { type : Number, default : 0 },
10 - medicineId : { type : Number, },
11 - dosage : { type : Number, default : 0 },
12 - hubId : { type : Number, required : true, },
13 - doctorId : { type : String, default : null, },
14 }); 8 });
15 9
16 BottleSchema.statics.findByBottleId = function(bottleId) { 10 BottleSchema.statics.findByBottleId = function(bottleId) {
...@@ -21,56 +15,13 @@ BottleSchema.statics.findAllByHubId = function(hubId) { ...@@ -21,56 +15,13 @@ BottleSchema.statics.findAllByHubId = function(hubId) {
21 return this.find({ hubId }); 15 return this.find({ hubId });
22 }; 16 };
23 17
24 -BottleSchema.statics.findAllByDoctorId = function(doctorId) {
25 - return this.find({ doctorId });
26 -}
27 -
28 BottleSchema.methods.getBottleId = function() { 18 BottleSchema.methods.getBottleId = function() {
29 return this.bottleId; 19 return this.bottleId;
30 }; 20 };
31 21
32 -BottleSchema.methods.getTemperature = function() {
33 - return this.temperature;
34 -};
35 -
36 -BottleSchema.methods.getHumidity = function() {
37 - return this.humidity;
38 -};
39 -
40 -BottleSchema.methods.getBalance = function() {
41 - return this.balance;
42 -};
43 -
44 -BottleSchema.methods.getDosage = function() {
45 - return this.dosage;
46 -};
47 -
48 -BottleSchema.methods.getMedicineId = function() {
49 - return this.medicineId;
50 -};
51 -
52 BottleSchema.methods.getHubId = function() { 22 BottleSchema.methods.getHubId = function() {
53 return this.hubId; 23 return this.hubId;
54 }; 24 };
55 25
56 -BottleSchema.methods.getDoctorId = function() {
57 - return this.doctorId;
58 -};
59 -
60 -BottleSchema.methods.setMedicineId = function(medicineId) {
61 - this.medicineId = medicineId;
62 -};
63 -
64 -BottleSchema.methods.setDosage = function(dosage) {
65 - this.dosage = dosage;
66 -};
67 -
68 -BottleSchema.methods.updateTemperature = function (temperature) {
69 - this.temperature = temperature;
70 -};
71 -
72 -BottleSchema.methods.updateHumidity = function (humidity) {
73 - this.humidity = humidity;
74 -};
75 26
76 module.exports = mongoose.model('Bottle', BottleSchema); 27 module.exports = mongoose.model('Bottle', BottleSchema);
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,31 +2,33 @@ const mongoose = require('mongoose'); ...@@ -2,31 +2,33 @@ const mongoose = require('mongoose');
2 2
3 const Schema = mongoose.Schema; 3 const Schema = mongoose.Schema;
4 4
5 -const TakeMedicineHistorySchema = new Schema ({ 5 +const BottleMedicineSchema = new Schema({
6 - takeDate : { 6 + bottleId : {
7 - type : Date, 7 + type : Number,
8 + ref : 'Bottle',
8 required : true, 9 required : true,
9 - default : Date.now,
10 }, 10 },
11 medicineId : { 11 medicineId : {
12 type : Number, 12 type : Number,
13 ref : 'Medicine', 13 ref : 'Medicine',
14 required : true, 14 required : true,
15 }, 15 },
16 - bottleId : { 16 + doctorId : {
17 + type : String,
18 + ref : 'User',
19 + required : true,
20 + },
21 + dosage : {
17 type : Number, 22 type : Number,
18 - ref : 'Bottle',
19 required : true, 23 required : true,
24 + default : 0,
20 }, 25 },
26 + regDtm : {
27 + type : Date,
28 + required : true,
29 + default : Date.now,
30 + }
21 }); 31 });
22 32
23 -TakeMedicineHistorySchema.statics.findByBottleId = async function(bottleId) {
24 - return this.find({ bottleId });
25 -};
26 -
27 -TakeMedicineHistorySchema.statics.findByBottleIdAndMedicineId = async function(bottleId, medicineId) {
28 - return this.find({ bottleId, medicineId });
29 -};
30 -
31 33
32 -module.export = mongoose.model("TakeMedicineHist", TakeMedicineHistorySchema);
...\ No newline at end of file ...\ No newline at end of file
34 +module.exports = mongoose.model('BottleMedicine', BottleMedicineSchema);
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -7,7 +7,7 @@ const DoctorInfoSchema = new Schema({ ...@@ -7,7 +7,7 @@ const DoctorInfoSchema = new Schema({
7 info : { 7 info : {
8 doctorLicense : { type : String, required : true, }, 8 doctorLicense : { type : String, required : true, },
9 hospitalNm : { type : String, default : null, }, 9 hospitalNm : { type : String, default : null, },
10 - hosptialAddr : { type : String, default : null, }, 10 + hospitalAddr : { type : String, default : null, },
11 contact : { type : String, required : true, }, 11 contact : { type : String, required : true, },
12 }, 12 },
13 useYn : { type : String, default : 'W', required : true, }, 13 useYn : { type : String, default : 'W', required : true, },
......
...@@ -5,8 +5,12 @@ const Schema = mongoose.Schema; ...@@ -5,8 +5,12 @@ const Schema = mongoose.Schema;
5 const FeedbackSchema = new Schema({ 5 const FeedbackSchema = new Schema({
6 fdbDtm : { type : Date, default : Date.now, required : true, }, 6 fdbDtm : { type : Date, default : Date.now, required : true, },
7 fdbType : { type : String, required : true, }, 7 fdbType : { type : String, required : true, },
8 - bottleId : { type : Number, required : true, }, 8 + bmId : {
9 - doctorId : { type : String, required : true, }, 9 + type : Schema.Types.ObjectId,
10 + required : true,
11 + ref : 'BottleMedicine',
12 + },
13 + doctorId : { type : String, required : true, ref : 'User', },
10 feedback : { type : String, required : true, }, 14 feedback : { type : String, required : true, },
11 }); 15 });
12 16
......
...@@ -12,31 +12,14 @@ const MedicineSchema = new Schema ({ ...@@ -12,31 +12,14 @@ const MedicineSchema = new Schema ({
12 antiEffect : { type : String, required : true } 12 antiEffect : { type : String, required : true }
13 }) 13 })
14 14
15 -MedicineSchema.statics.findByName = async function(name) { 15 +MedicineSchema.statics.findByKeyword = function(keyword) {
16 - const all = await this.find().exec(); 16 + return this.find({
17 - const result = all.filter(item => { 17 + $or : [
18 - return item.name.includes(name) 18 + { name : { $regex : keyword }},
19 - }); 19 + { company : { $regex : keyword }},
20 - 20 + { target : { $regex : keyword }},
21 - return result; 21 + ]
22 -}; 22 + })
23 -
24 -MedicineSchema.statics.findByCompany = async function(company) {
25 - const all = await this.find().exec();
26 - const result = all.filter(item => {
27 - return item.company.includes(company)
28 - });
29 -
30 - return result;
31 -};
32 -
33 -MedicineSchema.statics.findByTarget = async function(target) {
34 - const all = await this.find().exec();
35 - const result = all.filter(item => {
36 - return item.target.includes(target)
37 - });
38 -
39 - return result;
40 }; 23 };
41 24
42 MedicineSchema.statics.findByMedicineId = function(medicineId) { 25 MedicineSchema.statics.findByMedicineId = function(medicineId) {
......
...@@ -4,27 +4,36 @@ const moment = require('moment'); ...@@ -4,27 +4,36 @@ const moment = require('moment');
4 const Schema = mongoose.Schema; 4 const Schema = mongoose.Schema;
5 5
6 const PatientInfoSchema = new Schema({ 6 const PatientInfoSchema = new Schema({
7 - patientId : { type : String, required : true, }, 7 + patientId : { type : String, required : true, ref : 'User', },
8 - doctorId : { type : String, required : true, }, 8 + doctorId : { type : String, required : true, ref : 'User', },
9 info : { type : String, required : true, }, 9 info : { type : String, required : true, },
10 + useYn : { type : String, required : true, default : 'W', },
10 }); 11 });
11 12
12 -PatientInfoSchema.statics.findAllByPatientId = function(patientId) { 13 +PatientInfoSchema.statics.findAllByPatientIdAndUseYn = function(patientId, useYn) {
13 - return this.find({ patientId }); 14 + return this.find({ patientId, useYn });
14 }; 15 };
15 16
16 -PatientInfoSchema.statics.findAllByDoctorId = function(doctorId) { 17 +PatientInfoSchema.statics.findAllByDoctorIdAndUseYn = function(doctorId, useYn) {
17 - return this.find({ doctorId }); 18 + return this.find({ doctorId, useYn });
18 }; 19 };
19 20
20 PatientInfoSchema.statics.findByPatientIdAndDoctorId = function(patientId, doctorId) { 21 PatientInfoSchema.statics.findByPatientIdAndDoctorId = function(patientId, doctorId) {
21 return this.findOne({ patientId, doctorId }); 22 return this.findOne({ patientId, doctorId });
22 }; 23 };
23 24
25 +PatientInfoSchema.statics.findByPatientIdAndDoctorIdAndUseYn = function(patientId, doctorId, useYn) {
26 + return this.findOne({ patientId, doctorId, useYn });
27 +};
28 +
24 PatientInfoSchema.methods.getInfo = function() { 29 PatientInfoSchema.methods.getInfo = function() {
25 return this.info; 30 return this.info;
26 }; 31 };
27 32
33 +PatientInfoSchema.methods.setUseYn = function(useYn) {
34 + this.useYn = useYn;
35 +};
36 +
28 PatientInfoSchema.methods.updateInfo = function(info) { 37 PatientInfoSchema.methods.updateInfo = function(info) {
29 const date = moment(new Date()).format('YYYY-MM-DD hh:mm'); 38 const date = moment(new Date()).format('YYYY-MM-DD hh:mm');
30 if(this.info.length) 39 if(this.info.length)
......
...@@ -3,7 +3,7 @@ const mongoose = require('mongoose'); ...@@ -3,7 +3,7 @@ const mongoose = require('mongoose');
3 const Schema = mongoose.Schema; 3 const Schema = mongoose.Schema;
4 4
5 const ProfileSchema = new Schema({ 5 const ProfileSchema = new Schema({
6 - userId : { type : String, required : true, }, 6 + userId : { type : String, required : true, ref : 'User', },
7 userNm : { type : String, required : true, }, 7 userNm : { type : String, required : true, },
8 userAge : { type : Number, required : true, }, 8 userAge : { type : Number, required : true, },
9 contact : { type : String, required : true, }, 9 contact : { type : String, required : true, },
......
1 +const mongoose = require('mongoose');
2 +
3 +const Schema = mongoose.Schema;
4 +
5 +const TakeMedicineHistorySchema = new Schema ({
6 + takeDate : {
7 + type : Date,
8 + required : true,
9 + default : Date.now,
10 + },
11 + bmId : {
12 + type : Schema.Types.ObjectId,
13 + ref : 'BottleMedicine',
14 + required : true,
15 + },
16 + temperature : { type : Number, default : 0 },
17 + humidity : { type : Number, default : 0 },
18 + balance : { type : Number, default : 0 },
19 +});
20 +
21 +
22 +module.exports = mongoose.model('TakeMedicineHist', TakeMedicineHistorySchema);
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,7 +5,7 @@ const jwt = require('jsonwebtoken'); ...@@ -5,7 +5,7 @@ const jwt = require('jsonwebtoken');
5 const Schema = mongoose.Schema; 5 const Schema = mongoose.Schema;
6 6
7 const UserSchema = new Schema ({ 7 const UserSchema = new Schema ({
8 - userId : { type: String, required : true, unique : true, lowercase : true }, 8 + userId : { type: String, required : true, unique : true, lowercase : true, },
9 hashedPassword : { type : String, required : true }, 9 hashedPassword : { type : String, required : true },
10 userTypeCd : { type : String, required : true, default : 'NORMAL' }, 10 userTypeCd : { type : String, required : true, default : 'NORMAL' },
11 useYn : { type : String, default : 'W', required : true, }, 11 useYn : { type : String, default : 'W', required : true, },
...@@ -39,6 +39,7 @@ UserSchema.methods.generateToken = function() { ...@@ -39,6 +39,7 @@ UserSchema.methods.generateToken = function() {
39 _id : this._id, 39 _id : this._id,
40 userId : this.userId 40 userId : this.userId
41 }, 41 },
42 + // eslint-disable-next-line no-undef
42 process.env.JWT_SECRET, 43 process.env.JWT_SECRET,
43 { expiresIn : '30d' } 44 { expiresIn : '30d' }
44 ); 45 );
......
1 +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 +# yarn lockfile v1
3 +
4 +
5 +"@babel/code-frame@7.12.11":
6 + "integrity" "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw=="
7 + "resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz"
8 + "version" "7.12.11"
9 + dependencies:
10 + "@babel/highlight" "^7.10.4"
11 +
12 +"@babel/helper-validator-identifier@^7.14.5":
13 + "integrity" "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g=="
14 + "resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz"
15 + "version" "7.14.9"
16 +
17 +"@babel/highlight@^7.10.4":
18 + "integrity" "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg=="
19 + "resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz"
20 + "version" "7.14.5"
21 + dependencies:
22 + "@babel/helper-validator-identifier" "^7.14.5"
23 + "chalk" "^2.0.0"
24 + "js-tokens" "^4.0.0"
25 +
26 +"@eslint/eslintrc@^0.4.3":
27 + "integrity" "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw=="
28 + "resolved" "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz"
29 + "version" "0.4.3"
30 + dependencies:
31 + "ajv" "^6.12.4"
32 + "debug" "^4.1.1"
33 + "espree" "^7.3.0"
34 + "globals" "^13.9.0"
35 + "ignore" "^4.0.6"
36 + "import-fresh" "^3.2.1"
37 + "js-yaml" "^3.13.1"
38 + "minimatch" "^3.0.4"
39 + "strip-json-comments" "^3.1.1"
40 +
41 +"@humanwhocodes/config-array@^0.5.0":
42 + "integrity" "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg=="
43 + "resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz"
44 + "version" "0.5.0"
45 + dependencies:
46 + "@humanwhocodes/object-schema" "^1.2.0"
47 + "debug" "^4.1.1"
48 + "minimatch" "^3.0.4"
49 +
50 +"@humanwhocodes/object-schema@^1.2.0":
51 + "integrity" "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w=="
52 + "resolved" "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz"
53 + "version" "1.2.0"
54 +
55 +"acorn-jsx@^5.3.1":
56 + "integrity" "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
57 + "resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
58 + "version" "5.3.2"
59 +
60 +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^7.4.0":
61 + "integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
62 + "resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
63 + "version" "7.4.1"
64 +
65 +"ajv@^6.10.0", "ajv@^6.12.4":
66 + "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
67 + "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
68 + "version" "6.12.6"
69 + dependencies:
70 + "fast-deep-equal" "^3.1.1"
71 + "fast-json-stable-stringify" "^2.0.0"
72 + "json-schema-traverse" "^0.4.1"
73 + "uri-js" "^4.2.2"
74 +
75 +"ajv@^8.0.1":
76 + "integrity" "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w=="
77 + "resolved" "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz"
78 + "version" "8.6.2"
79 + dependencies:
80 + "fast-deep-equal" "^3.1.1"
81 + "json-schema-traverse" "^1.0.0"
82 + "require-from-string" "^2.0.2"
83 + "uri-js" "^4.2.2"
84 +
85 +"ansi-colors@^4.1.1":
86 + "integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA=="
87 + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz"
88 + "version" "4.1.1"
89 +
90 +"ansi-regex@^5.0.0":
91 + "integrity" "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
92 + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz"
93 + "version" "5.0.0"
94 +
95 +"ansi-styles@^3.2.1":
96 + "integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="
97 + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
98 + "version" "3.2.1"
99 + dependencies:
100 + "color-convert" "^1.9.0"
101 +
102 +"ansi-styles@^4.0.0", "ansi-styles@^4.1.0":
103 + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="
104 + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
105 + "version" "4.3.0"
106 + dependencies:
107 + "color-convert" "^2.0.1"
108 +
109 +"argparse@^1.0.7":
110 + "integrity" "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="
111 + "resolved" "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
112 + "version" "1.0.10"
113 + dependencies:
114 + "sprintf-js" "~1.0.2"
115 +
116 +"astral-regex@^2.0.0":
117 + "integrity" "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
118 + "resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
119 + "version" "2.0.0"
120 +
121 +"balanced-match@^1.0.0":
122 + "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
123 + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
124 + "version" "1.0.2"
125 +
126 +"base64-js@^1.3.1":
127 + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
128 + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
129 + "version" "1.5.1"
130 +
131 +"bl@^4.0.2":
132 + "integrity" "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="
133 + "resolved" "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz"
134 + "version" "4.1.0"
135 + dependencies:
136 + "buffer" "^5.5.0"
137 + "inherits" "^2.0.4"
138 + "readable-stream" "^3.4.0"
139 +
140 +"brace-expansion@^1.1.7":
141 + "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="
142 + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
143 + "version" "1.1.11"
144 + dependencies:
145 + "balanced-match" "^1.0.0"
146 + "concat-map" "0.0.1"
147 +
148 +"buffer-from@^1.0.0":
149 + "integrity" "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
150 + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
151 + "version" "1.1.1"
152 +
153 +"buffer@^5.5.0":
154 + "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="
155 + "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
156 + "version" "5.7.1"
157 + dependencies:
158 + "base64-js" "^1.3.1"
159 + "ieee754" "^1.1.13"
160 +
161 +"callback-stream@^1.0.2":
162 + "integrity" "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg="
163 + "resolved" "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz"
164 + "version" "1.1.0"
165 + dependencies:
166 + "inherits" "^2.0.1"
167 + "readable-stream" "> 1.0.0 < 3.0.0"
168 +
169 +"callsites@^3.0.0":
170 + "integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
171 + "resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
172 + "version" "3.1.0"
173 +
174 +"chalk@^2.0.0":
175 + "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
176 + "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
177 + "version" "2.4.2"
178 + dependencies:
179 + "ansi-styles" "^3.2.1"
180 + "escape-string-regexp" "^1.0.5"
181 + "supports-color" "^5.3.0"
182 +
183 +"chalk@^4.0.0":
184 + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
185 + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
186 + "version" "4.1.2"
187 + dependencies:
188 + "ansi-styles" "^4.1.0"
189 + "supports-color" "^7.1.0"
190 +
191 +"color-convert@^1.9.0":
192 + "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="
193 + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
194 + "version" "1.9.3"
195 + dependencies:
196 + "color-name" "1.1.3"
197 +
198 +"color-convert@^2.0.1":
199 + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
200 + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
201 + "version" "2.0.1"
202 + dependencies:
203 + "color-name" "~1.1.4"
204 +
205 +"color-name@~1.1.4":
206 + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
207 + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
208 + "version" "1.1.4"
209 +
210 +"color-name@1.1.3":
211 + "integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
212 + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
213 + "version" "1.1.3"
214 +
215 +"commist@^1.0.0":
216 + "integrity" "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg=="
217 + "resolved" "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz"
218 + "version" "1.1.0"
219 + dependencies:
220 + "leven" "^2.1.0"
221 + "minimist" "^1.1.0"
222 +
223 +"concat-map@0.0.1":
224 + "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
225 + "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
226 + "version" "0.0.1"
227 +
228 +"concat-stream@^2.0.0":
229 + "integrity" "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="
230 + "resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz"
231 + "version" "2.0.0"
232 + dependencies:
233 + "buffer-from" "^1.0.0"
234 + "inherits" "^2.0.3"
235 + "readable-stream" "^3.0.2"
236 + "typedarray" "^0.0.6"
237 +
238 +"core-util-is@~1.0.0":
239 + "integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
240 + "resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
241 + "version" "1.0.2"
242 +
243 +"cross-spawn@^7.0.2":
244 + "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="
245 + "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
246 + "version" "7.0.3"
247 + dependencies:
248 + "path-key" "^3.1.0"
249 + "shebang-command" "^2.0.0"
250 + "which" "^2.0.1"
251 +
252 +"debug@^4.0.1", "debug@^4.1.1":
253 + "integrity" "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ=="
254 + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
255 + "version" "4.3.1"
256 + dependencies:
257 + "ms" "2.1.2"
258 +
259 +"deep-is@^0.1.3":
260 + "integrity" "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
261 + "resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
262 + "version" "0.1.3"
263 +
264 +"doctrine@^3.0.0":
265 + "integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="
266 + "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
267 + "version" "3.0.0"
268 + dependencies:
269 + "esutils" "^2.0.2"
270 +
271 +"duplexify@^3.6.0":
272 + "integrity" "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g=="
273 + "resolved" "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz"
274 + "version" "3.7.1"
275 + dependencies:
276 + "end-of-stream" "^1.0.0"
277 + "inherits" "^2.0.1"
278 + "readable-stream" "^2.0.0"
279 + "stream-shift" "^1.0.0"
280 +
281 +"emoji-regex@^8.0.0":
282 + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
283 + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
284 + "version" "8.0.0"
285 +
286 +"end-of-stream@^1.0.0", "end-of-stream@^1.1.0":
287 + "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="
288 + "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz"
289 + "version" "1.4.4"
290 + dependencies:
291 + "once" "^1.4.0"
292 +
293 +"enquirer@^2.3.5":
294 + "integrity" "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="
295 + "resolved" "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz"
296 + "version" "2.3.6"
297 + dependencies:
298 + "ansi-colors" "^4.1.1"
299 +
300 +"escape-string-regexp@^1.0.5":
301 + "integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
302 + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
303 + "version" "1.0.5"
304 +
305 +"escape-string-regexp@^4.0.0":
306 + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
307 + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
308 + "version" "4.0.0"
309 +
310 +"eslint-scope@^5.1.1":
311 + "integrity" "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="
312 + "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
313 + "version" "5.1.1"
314 + dependencies:
315 + "esrecurse" "^4.3.0"
316 + "estraverse" "^4.1.1"
317 +
318 +"eslint-utils@^2.1.0":
319 + "integrity" "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg=="
320 + "resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz"
321 + "version" "2.1.0"
322 + dependencies:
323 + "eslint-visitor-keys" "^1.1.0"
324 +
325 +"eslint-visitor-keys@^1.1.0":
326 + "integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
327 + "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
328 + "version" "1.3.0"
329 +
330 +"eslint-visitor-keys@^1.3.0":
331 + "integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
332 + "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
333 + "version" "1.3.0"
334 +
335 +"eslint-visitor-keys@^2.0.0":
336 + "integrity" "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
337 + "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz"
338 + "version" "2.1.0"
339 +
340 +"eslint@^7.32.0":
341 + "integrity" "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA=="
342 + "resolved" "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz"
343 + "version" "7.32.0"
344 + dependencies:
345 + "@babel/code-frame" "7.12.11"
346 + "@eslint/eslintrc" "^0.4.3"
347 + "@humanwhocodes/config-array" "^0.5.0"
348 + "ajv" "^6.10.0"
349 + "chalk" "^4.0.0"
350 + "cross-spawn" "^7.0.2"
351 + "debug" "^4.0.1"
352 + "doctrine" "^3.0.0"
353 + "enquirer" "^2.3.5"
354 + "escape-string-regexp" "^4.0.0"
355 + "eslint-scope" "^5.1.1"
356 + "eslint-utils" "^2.1.0"
357 + "eslint-visitor-keys" "^2.0.0"
358 + "espree" "^7.3.1"
359 + "esquery" "^1.4.0"
360 + "esutils" "^2.0.2"
361 + "fast-deep-equal" "^3.1.3"
362 + "file-entry-cache" "^6.0.1"
363 + "functional-red-black-tree" "^1.0.1"
364 + "glob-parent" "^5.1.2"
365 + "globals" "^13.6.0"
366 + "ignore" "^4.0.6"
367 + "import-fresh" "^3.0.0"
368 + "imurmurhash" "^0.1.4"
369 + "is-glob" "^4.0.0"
370 + "js-yaml" "^3.13.1"
371 + "json-stable-stringify-without-jsonify" "^1.0.1"
372 + "levn" "^0.4.1"
373 + "lodash.merge" "^4.6.2"
374 + "minimatch" "^3.0.4"
375 + "natural-compare" "^1.4.0"
376 + "optionator" "^0.9.1"
377 + "progress" "^2.0.0"
378 + "regexpp" "^3.1.0"
379 + "semver" "^7.2.1"
380 + "strip-ansi" "^6.0.0"
381 + "strip-json-comments" "^3.1.0"
382 + "table" "^6.0.9"
383 + "text-table" "^0.2.0"
384 + "v8-compile-cache" "^2.0.3"
385 +
386 +"espree@^7.3.0", "espree@^7.3.1":
387 + "integrity" "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g=="
388 + "resolved" "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz"
389 + "version" "7.3.1"
390 + dependencies:
391 + "acorn" "^7.4.0"
392 + "acorn-jsx" "^5.3.1"
393 + "eslint-visitor-keys" "^1.3.0"
394 +
395 +"esprima@^4.0.0":
396 + "integrity" "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
397 + "resolved" "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
398 + "version" "4.0.1"
399 +
400 +"esquery@^1.4.0":
401 + "integrity" "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w=="
402 + "resolved" "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz"
403 + "version" "1.4.0"
404 + dependencies:
405 + "estraverse" "^5.1.0"
406 +
407 +"esrecurse@^4.3.0":
408 + "integrity" "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="
409 + "resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
410 + "version" "4.3.0"
411 + dependencies:
412 + "estraverse" "^5.2.0"
413 +
414 +"estraverse@^4.1.1":
415 + "integrity" "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
416 + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
417 + "version" "4.3.0"
418 +
419 +"estraverse@^5.1.0":
420 + "integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
421 + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz"
422 + "version" "5.2.0"
423 +
424 +"estraverse@^5.2.0":
425 + "integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
426 + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz"
427 + "version" "5.2.0"
428 +
429 +"esutils@^2.0.2":
430 + "integrity" "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
431 + "resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
432 + "version" "2.0.3"
433 +
434 +"extend@^3.0.0":
435 + "integrity" "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
436 + "resolved" "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
437 + "version" "3.0.2"
438 +
439 +"fast-deep-equal@^3.1.1", "fast-deep-equal@^3.1.3":
440 + "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
441 + "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
442 + "version" "3.1.3"
443 +
444 +"fast-json-stable-stringify@^2.0.0":
445 + "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
446 + "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
447 + "version" "2.1.0"
448 +
449 +"fast-levenshtein@^2.0.6":
450 + "integrity" "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
451 + "resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
452 + "version" "2.0.6"
453 +
454 +"file-entry-cache@^6.0.1":
455 + "integrity" "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="
456 + "resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
457 + "version" "6.0.1"
458 + dependencies:
459 + "flat-cache" "^3.0.4"
460 +
461 +"flat-cache@^3.0.4":
462 + "integrity" "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg=="
463 + "resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
464 + "version" "3.0.4"
465 + dependencies:
466 + "flatted" "^3.1.0"
467 + "rimraf" "^3.0.2"
468 +
469 +"flatted@^3.1.0":
470 + "integrity" "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA=="
471 + "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz"
472 + "version" "3.2.2"
473 +
474 +"fs.realpath@^1.0.0":
475 + "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
476 + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
477 + "version" "1.0.0"
478 +
479 +"functional-red-black-tree@^1.0.1":
480 + "integrity" "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
481 + "resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz"
482 + "version" "1.0.1"
483 +
484 +"glob-parent@^3.1.0":
485 + "integrity" "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4="
486 + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz"
487 + "version" "3.1.0"
488 + dependencies:
489 + "is-glob" "^3.1.0"
490 + "path-dirname" "^1.0.0"
491 +
492 +"glob-parent@^5.1.2":
493 + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
494 + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
495 + "version" "5.1.2"
496 + dependencies:
497 + "is-glob" "^4.0.1"
498 +
499 +"glob-stream@^6.1.0":
500 + "integrity" "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ="
501 + "resolved" "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz"
502 + "version" "6.1.0"
503 + dependencies:
504 + "extend" "^3.0.0"
505 + "glob" "^7.1.1"
506 + "glob-parent" "^3.1.0"
507 + "is-negated-glob" "^1.0.0"
508 + "ordered-read-streams" "^1.0.0"
509 + "pumpify" "^1.3.5"
510 + "readable-stream" "^2.1.5"
511 + "remove-trailing-separator" "^1.0.1"
512 + "to-absolute-glob" "^2.0.0"
513 + "unique-stream" "^2.0.2"
514 +
515 +"glob@^7.1.1", "glob@^7.1.3":
516 + "integrity" "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA=="
517 + "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
518 + "version" "7.1.6"
519 + dependencies:
520 + "fs.realpath" "^1.0.0"
521 + "inflight" "^1.0.4"
522 + "inherits" "2"
523 + "minimatch" "^3.0.4"
524 + "once" "^1.3.0"
525 + "path-is-absolute" "^1.0.0"
526 +
527 +"globals@^13.6.0", "globals@^13.9.0":
528 + "integrity" "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g=="
529 + "resolved" "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz"
530 + "version" "13.11.0"
531 + dependencies:
532 + "type-fest" "^0.20.2"
533 +
534 +"has-flag@^3.0.0":
535 + "integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
536 + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
537 + "version" "3.0.0"
538 +
539 +"has-flag@^4.0.0":
540 + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
541 + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
542 + "version" "4.0.0"
543 +
544 +"help-me@^1.0.1":
545 + "integrity" "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y="
546 + "resolved" "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz"
547 + "version" "1.1.0"
548 + dependencies:
549 + "callback-stream" "^1.0.2"
550 + "glob-stream" "^6.1.0"
551 + "through2" "^2.0.1"
552 + "xtend" "^4.0.0"
553 +
554 +"ieee754@^1.1.13":
555 + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
556 + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
557 + "version" "1.2.1"
558 +
559 +"ignore@^4.0.6":
560 + "integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
561 + "resolved" "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
562 + "version" "4.0.6"
563 +
564 +"import-fresh@^3.0.0", "import-fresh@^3.2.1":
565 + "integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="
566 + "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
567 + "version" "3.3.0"
568 + dependencies:
569 + "parent-module" "^1.0.0"
570 + "resolve-from" "^4.0.0"
571 +
572 +"imurmurhash@^0.1.4":
573 + "integrity" "sha1-khi5srkoojixPcT7a21XbyMUU+o="
574 + "resolved" "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
575 + "version" "0.1.4"
576 +
577 +"inflight@^1.0.4":
578 + "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk="
579 + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
580 + "version" "1.0.6"
581 + dependencies:
582 + "once" "^1.3.0"
583 + "wrappy" "1"
584 +
585 +"inherits@^2.0.1", "inherits@^2.0.3", "inherits@^2.0.4", "inherits@~2.0.3", "inherits@2":
586 + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
587 + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
588 + "version" "2.0.4"
589 +
590 +"is-absolute@^1.0.0":
591 + "integrity" "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="
592 + "resolved" "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz"
593 + "version" "1.0.0"
594 + dependencies:
595 + "is-relative" "^1.0.0"
596 + "is-windows" "^1.0.1"
597 +
598 +"is-extglob@^2.1.0", "is-extglob@^2.1.1":
599 + "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
600 + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
601 + "version" "2.1.1"
602 +
603 +"is-fullwidth-code-point@^3.0.0":
604 + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
605 + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
606 + "version" "3.0.0"
607 +
608 +"is-glob@^3.1.0":
609 + "integrity" "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo="
610 + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz"
611 + "version" "3.1.0"
612 + dependencies:
613 + "is-extglob" "^2.1.0"
614 +
615 +"is-glob@^4.0.0", "is-glob@^4.0.1":
616 + "integrity" "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg=="
617 + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz"
618 + "version" "4.0.1"
619 + dependencies:
620 + "is-extglob" "^2.1.1"
621 +
622 +"is-negated-glob@^1.0.0":
623 + "integrity" "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI="
624 + "resolved" "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz"
625 + "version" "1.0.0"
626 +
627 +"is-relative@^1.0.0":
628 + "integrity" "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA=="
629 + "resolved" "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz"
630 + "version" "1.0.0"
631 + dependencies:
632 + "is-unc-path" "^1.0.0"
633 +
634 +"is-unc-path@^1.0.0":
635 + "integrity" "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ=="
636 + "resolved" "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz"
637 + "version" "1.0.0"
638 + dependencies:
639 + "unc-path-regex" "^0.1.2"
640 +
641 +"is-windows@^1.0.1":
642 + "integrity" "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
643 + "resolved" "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
644 + "version" "1.0.2"
645 +
646 +"isarray@~1.0.0":
647 + "integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
648 + "resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
649 + "version" "1.0.0"
650 +
651 +"isexe@^2.0.0":
652 + "integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
653 + "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
654 + "version" "2.0.0"
655 +
656 +"js-tokens@^4.0.0":
657 + "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
658 + "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
659 + "version" "4.0.0"
660 +
661 +"js-yaml@^3.13.1":
662 + "integrity" "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="
663 + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
664 + "version" "3.14.1"
665 + dependencies:
666 + "argparse" "^1.0.7"
667 + "esprima" "^4.0.0"
668 +
669 +"json-schema-traverse@^0.4.1":
670 + "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
671 + "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
672 + "version" "0.4.1"
673 +
674 +"json-schema-traverse@^1.0.0":
675 + "integrity" "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
676 + "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz"
677 + "version" "1.0.0"
678 +
679 +"json-stable-stringify-without-jsonify@^1.0.1":
680 + "integrity" "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
681 + "resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
682 + "version" "1.0.1"
683 +
684 +"leven@^2.1.0":
685 + "integrity" "sha1-wuep93IJTe6dNCAq6KzORoeHVYA="
686 + "resolved" "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz"
687 + "version" "2.1.0"
688 +
689 +"levn@^0.4.1":
690 + "integrity" "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="
691 + "resolved" "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
692 + "version" "0.4.1"
693 + dependencies:
694 + "prelude-ls" "^1.2.1"
695 + "type-check" "~0.4.0"
696 +
697 +"lodash.clonedeep@^4.5.0":
698 + "integrity" "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
699 + "resolved" "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
700 + "version" "4.5.0"
701 +
702 +"lodash.merge@^4.6.2":
703 + "integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
704 + "resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
705 + "version" "4.6.2"
706 +
707 +"lodash.truncate@^4.4.2":
708 + "integrity" "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM="
709 + "resolved" "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz"
710 + "version" "4.4.2"
711 +
712 +"lru-cache@^6.0.0":
713 + "integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="
714 + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
715 + "version" "6.0.0"
716 + dependencies:
717 + "yallist" "^4.0.0"
718 +
719 +"minimatch@^3.0.4":
720 + "integrity" "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA=="
721 + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
722 + "version" "3.0.4"
723 + dependencies:
724 + "brace-expansion" "^1.1.7"
725 +
726 +"minimist@^1.1.0", "minimist@^1.2.5":
727 + "integrity" "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
728 + "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
729 + "version" "1.2.5"
730 +
731 +"moment@^2.29.1":
732 + "integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
733 + "resolved" "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
734 + "version" "2.29.1"
735 +
736 +"mqtt-packet@^6.6.0":
737 + "integrity" "sha512-0+u0ZoRj6H6AuzNY5d8qzXzyXmFI19gkdPRA14kGfKvbqYcpOL+HWUGHjtCxHqjm8CscwsH+dX0+Rxx4se5HSA=="
738 + "resolved" "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.9.1.tgz"
739 + "version" "6.9.1"
740 + dependencies:
741 + "bl" "^4.0.2"
742 + "debug" "^4.1.1"
743 + "process-nextick-args" "^2.0.1"
744 +
745 +"mqtt@^4.2.6":
746 + "integrity" "sha512-GpxVObyOzL0CGPBqo6B04GinN8JLk12NRYAIkYvARd9ZCoJKevvOyCaWK6bdK/kFSDj3LPDnCsJbezzNlsi87Q=="
747 + "resolved" "https://registry.npmjs.org/mqtt/-/mqtt-4.2.6.tgz"
748 + "version" "4.2.6"
749 + dependencies:
750 + "commist" "^1.0.0"
751 + "concat-stream" "^2.0.0"
752 + "debug" "^4.1.1"
753 + "help-me" "^1.0.1"
754 + "inherits" "^2.0.3"
755 + "minimist" "^1.2.5"
756 + "mqtt-packet" "^6.6.0"
757 + "pump" "^3.0.0"
758 + "readable-stream" "^3.6.0"
759 + "reinterval" "^1.1.0"
760 + "split2" "^3.1.0"
761 + "ws" "^7.3.1"
762 + "xtend" "^4.0.2"
763 +
764 +"ms@2.1.2":
765 + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
766 + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
767 + "version" "2.1.2"
768 +
769 +"natural-compare@^1.4.0":
770 + "integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
771 + "resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
772 + "version" "1.4.0"
773 +
774 +"once@^1.3.0", "once@^1.3.1", "once@^1.4.0":
775 + "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
776 + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
777 + "version" "1.4.0"
778 + dependencies:
779 + "wrappy" "1"
780 +
781 +"optionator@^0.9.1":
782 + "integrity" "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw=="
783 + "resolved" "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz"
784 + "version" "0.9.1"
785 + dependencies:
786 + "deep-is" "^0.1.3"
787 + "fast-levenshtein" "^2.0.6"
788 + "levn" "^0.4.1"
789 + "prelude-ls" "^1.2.1"
790 + "type-check" "^0.4.0"
791 + "word-wrap" "^1.2.3"
792 +
793 +"ordered-read-streams@^1.0.0":
794 + "integrity" "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4="
795 + "resolved" "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz"
796 + "version" "1.0.1"
797 + dependencies:
798 + "readable-stream" "^2.0.1"
799 +
800 +"parent-module@^1.0.0":
801 + "integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="
802 + "resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
803 + "version" "1.0.1"
804 + dependencies:
805 + "callsites" "^3.0.0"
806 +
807 +"path-dirname@^1.0.0":
808 + "integrity" "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
809 + "resolved" "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz"
810 + "version" "1.0.2"
811 +
812 +"path-is-absolute@^1.0.0":
813 + "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
814 + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
815 + "version" "1.0.1"
816 +
817 +"path-key@^3.1.0":
818 + "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
819 + "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
820 + "version" "3.1.1"
821 +
822 +"prelude-ls@^1.2.1":
823 + "integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
824 + "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
825 + "version" "1.2.1"
826 +
827 +"process-nextick-args@^2.0.1", "process-nextick-args@~2.0.0":
828 + "integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
829 + "resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
830 + "version" "2.0.1"
831 +
832 +"progress@^2.0.0":
833 + "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
834 + "resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
835 + "version" "2.0.3"
836 +
837 +"pump@^2.0.0":
838 + "integrity" "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA=="
839 + "resolved" "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz"
840 + "version" "2.0.1"
841 + dependencies:
842 + "end-of-stream" "^1.1.0"
843 + "once" "^1.3.1"
844 +
845 +"pump@^3.0.0":
846 + "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="
847 + "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
848 + "version" "3.0.0"
849 + dependencies:
850 + "end-of-stream" "^1.1.0"
851 + "once" "^1.3.1"
852 +
853 +"pumpify@^1.3.5":
854 + "integrity" "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ=="
855 + "resolved" "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz"
856 + "version" "1.5.1"
857 + dependencies:
858 + "duplexify" "^3.6.0"
859 + "inherits" "^2.0.3"
860 + "pump" "^2.0.0"
861 +
862 +"punycode@^2.1.0":
863 + "integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
864 + "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
865 + "version" "2.1.1"
866 +
867 +"readable-stream@^2.0.0":
868 + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
869 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
870 + "version" "2.3.7"
871 + dependencies:
872 + "core-util-is" "~1.0.0"
873 + "inherits" "~2.0.3"
874 + "isarray" "~1.0.0"
875 + "process-nextick-args" "~2.0.0"
876 + "safe-buffer" "~5.1.1"
877 + "string_decoder" "~1.1.1"
878 + "util-deprecate" "~1.0.1"
879 +
880 +"readable-stream@^2.0.1":
881 + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
882 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
883 + "version" "2.3.7"
884 + dependencies:
885 + "core-util-is" "~1.0.0"
886 + "inherits" "~2.0.3"
887 + "isarray" "~1.0.0"
888 + "process-nextick-args" "~2.0.0"
889 + "safe-buffer" "~5.1.1"
890 + "string_decoder" "~1.1.1"
891 + "util-deprecate" "~1.0.1"
892 +
893 +"readable-stream@^2.1.5":
894 + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
895 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
896 + "version" "2.3.7"
897 + dependencies:
898 + "core-util-is" "~1.0.0"
899 + "inherits" "~2.0.3"
900 + "isarray" "~1.0.0"
901 + "process-nextick-args" "~2.0.0"
902 + "safe-buffer" "~5.1.1"
903 + "string_decoder" "~1.1.1"
904 + "util-deprecate" "~1.0.1"
905 +
906 +"readable-stream@^3.0.0", "readable-stream@^3.0.2", "readable-stream@^3.4.0", "readable-stream@^3.6.0":
907 + "integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
908 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
909 + "version" "3.6.0"
910 + dependencies:
911 + "inherits" "^2.0.3"
912 + "string_decoder" "^1.1.1"
913 + "util-deprecate" "^1.0.1"
914 +
915 +"readable-stream@> 1.0.0 < 3.0.0":
916 + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
917 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
918 + "version" "2.3.7"
919 + dependencies:
920 + "core-util-is" "~1.0.0"
921 + "inherits" "~2.0.3"
922 + "isarray" "~1.0.0"
923 + "process-nextick-args" "~2.0.0"
924 + "safe-buffer" "~5.1.1"
925 + "string_decoder" "~1.1.1"
926 + "util-deprecate" "~1.0.1"
927 +
928 +"readable-stream@~2.3.6":
929 + "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
930 + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
931 + "version" "2.3.7"
932 + dependencies:
933 + "core-util-is" "~1.0.0"
934 + "inherits" "~2.0.3"
935 + "isarray" "~1.0.0"
936 + "process-nextick-args" "~2.0.0"
937 + "safe-buffer" "~5.1.1"
938 + "string_decoder" "~1.1.1"
939 + "util-deprecate" "~1.0.1"
940 +
941 +"regexpp@^3.1.0":
942 + "integrity" "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
943 + "resolved" "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
944 + "version" "3.2.0"
945 +
946 +"reinterval@^1.1.0":
947 + "integrity" "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc="
948 + "resolved" "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz"
949 + "version" "1.1.0"
950 +
951 +"remove-trailing-separator@^1.0.1":
952 + "integrity" "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
953 + "resolved" "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"
954 + "version" "1.1.0"
955 +
956 +"require-from-string@^2.0.2":
957 + "integrity" "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
958 + "resolved" "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
959 + "version" "2.0.2"
960 +
961 +"resolve-from@^4.0.0":
962 + "integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
963 + "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
964 + "version" "4.0.0"
965 +
966 +"rimraf@^3.0.2":
967 + "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="
968 + "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
969 + "version" "3.0.2"
970 + dependencies:
971 + "glob" "^7.1.3"
972 +
973 +"safe-buffer@~5.1.0", "safe-buffer@~5.1.1":
974 + "integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
975 + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
976 + "version" "5.1.2"
977 +
978 +"safe-buffer@~5.2.0":
979 + "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
980 + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
981 + "version" "5.2.1"
982 +
983 +"semver@^7.2.1":
984 + "integrity" "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ=="
985 + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz"
986 + "version" "7.3.5"
987 + dependencies:
988 + "lru-cache" "^6.0.0"
989 +
990 +"shebang-command@^2.0.0":
991 + "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="
992 + "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
993 + "version" "2.0.0"
994 + dependencies:
995 + "shebang-regex" "^3.0.0"
996 +
997 +"shebang-regex@^3.0.0":
998 + "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
999 + "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
1000 + "version" "3.0.0"
1001 +
1002 +"slice-ansi@^4.0.0":
1003 + "integrity" "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="
1004 + "resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz"
1005 + "version" "4.0.0"
1006 + dependencies:
1007 + "ansi-styles" "^4.0.0"
1008 + "astral-regex" "^2.0.0"
1009 + "is-fullwidth-code-point" "^3.0.0"
1010 +
1011 +"split2@^3.1.0":
1012 + "integrity" "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg=="
1013 + "resolved" "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz"
1014 + "version" "3.2.2"
1015 + dependencies:
1016 + "readable-stream" "^3.0.0"
1017 +
1018 +"sprintf-js@~1.0.2":
1019 + "integrity" "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
1020 + "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
1021 + "version" "1.0.3"
1022 +
1023 +"stream-shift@^1.0.0":
1024 + "integrity" "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
1025 + "resolved" "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz"
1026 + "version" "1.0.1"
1027 +
1028 +"string_decoder@^1.1.1":
1029 + "integrity" "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="
1030 + "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
1031 + "version" "1.3.0"
1032 + dependencies:
1033 + "safe-buffer" "~5.2.0"
1034 +
1035 +"string_decoder@~1.1.1":
1036 + "integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="
1037 + "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
1038 + "version" "1.1.1"
1039 + dependencies:
1040 + "safe-buffer" "~5.1.0"
1041 +
1042 +"string-width@^4.2.0":
1043 + "integrity" "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA=="
1044 + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz"
1045 + "version" "4.2.2"
1046 + dependencies:
1047 + "emoji-regex" "^8.0.0"
1048 + "is-fullwidth-code-point" "^3.0.0"
1049 + "strip-ansi" "^6.0.0"
1050 +
1051 +"strip-ansi@^6.0.0":
1052 + "integrity" "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w=="
1053 + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz"
1054 + "version" "6.0.0"
1055 + dependencies:
1056 + "ansi-regex" "^5.0.0"
1057 +
1058 +"strip-json-comments@^3.1.0", "strip-json-comments@^3.1.1":
1059 + "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
1060 + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
1061 + "version" "3.1.1"
1062 +
1063 +"supports-color@^5.3.0":
1064 + "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="
1065 + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
1066 + "version" "5.5.0"
1067 + dependencies:
1068 + "has-flag" "^3.0.0"
1069 +
1070 +"supports-color@^7.1.0":
1071 + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
1072 + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
1073 + "version" "7.2.0"
1074 + dependencies:
1075 + "has-flag" "^4.0.0"
1076 +
1077 +"table@^6.0.9":
1078 + "integrity" "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg=="
1079 + "resolved" "https://registry.npmjs.org/table/-/table-6.7.1.tgz"
1080 + "version" "6.7.1"
1081 + dependencies:
1082 + "ajv" "^8.0.1"
1083 + "lodash.clonedeep" "^4.5.0"
1084 + "lodash.truncate" "^4.4.2"
1085 + "slice-ansi" "^4.0.0"
1086 + "string-width" "^4.2.0"
1087 + "strip-ansi" "^6.0.0"
1088 +
1089 +"text-table@^0.2.0":
1090 + "integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
1091 + "resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
1092 + "version" "0.2.0"
1093 +
1094 +"through2-filter@^3.0.0":
1095 + "integrity" "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA=="
1096 + "resolved" "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz"
1097 + "version" "3.0.0"
1098 + dependencies:
1099 + "through2" "~2.0.0"
1100 + "xtend" "~4.0.0"
1101 +
1102 +"through2@^2.0.1", "through2@~2.0.0":
1103 + "integrity" "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="
1104 + "resolved" "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
1105 + "version" "2.0.5"
1106 + dependencies:
1107 + "readable-stream" "~2.3.6"
1108 + "xtend" "~4.0.1"
1109 +
1110 +"to-absolute-glob@^2.0.0":
1111 + "integrity" "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs="
1112 + "resolved" "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz"
1113 + "version" "2.0.2"
1114 + dependencies:
1115 + "is-absolute" "^1.0.0"
1116 + "is-negated-glob" "^1.0.0"
1117 +
1118 +"type-check@^0.4.0", "type-check@~0.4.0":
1119 + "integrity" "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="
1120 + "resolved" "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
1121 + "version" "0.4.0"
1122 + dependencies:
1123 + "prelude-ls" "^1.2.1"
1124 +
1125 +"type-fest@^0.20.2":
1126 + "integrity" "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
1127 + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
1128 + "version" "0.20.2"
1129 +
1130 +"typedarray@^0.0.6":
1131 + "integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
1132 + "resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
1133 + "version" "0.0.6"
1134 +
1135 +"unc-path-regex@^0.1.2":
1136 + "integrity" "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
1137 + "resolved" "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz"
1138 + "version" "0.1.2"
1139 +
1140 +"unique-stream@^2.0.2":
1141 + "integrity" "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A=="
1142 + "resolved" "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz"
1143 + "version" "2.3.1"
1144 + dependencies:
1145 + "json-stable-stringify-without-jsonify" "^1.0.1"
1146 + "through2-filter" "^3.0.0"
1147 +
1148 +"uri-js@^4.2.2":
1149 + "integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="
1150 + "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
1151 + "version" "4.4.1"
1152 + dependencies:
1153 + "punycode" "^2.1.0"
1154 +
1155 +"util-deprecate@^1.0.1", "util-deprecate@~1.0.1":
1156 + "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
1157 + "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
1158 + "version" "1.0.2"
1159 +
1160 +"v8-compile-cache@^2.0.3":
1161 + "integrity" "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA=="
1162 + "resolved" "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"
1163 + "version" "2.3.0"
1164 +
1165 +"which@^2.0.1":
1166 + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
1167 + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
1168 + "version" "2.0.2"
1169 + dependencies:
1170 + "isexe" "^2.0.0"
1171 +
1172 +"word-wrap@^1.2.3":
1173 + "integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
1174 + "resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
1175 + "version" "1.2.3"
1176 +
1177 +"wrappy@1":
1178 + "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
1179 + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
1180 + "version" "1.0.2"
1181 +
1182 +"ws@^7.3.1":
1183 + "integrity" "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
1184 + "resolved" "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz"
1185 + "version" "7.4.5"
1186 +
1187 +"xtend@^4.0.0", "xtend@^4.0.2", "xtend@~4.0.0", "xtend@~4.0.1":
1188 + "integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
1189 + "resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
1190 + "version" "4.0.2"
1191 +
1192 +"yallist@^4.0.0":
1193 + "integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1194 + "resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
1195 + "version" "4.0.0"