Flare-k

Modified Caculating Function Speed

1 +describe("Test suite", function () {
2 + it("should be ok", function () {
3 + assert.equal(true, false)
4 + })
5 +})
...\ No newline at end of file ...\ No newline at end of file
1 +class LRUCache{
2 + constructor(capacity){
3 + this.capacity = capacity;
4 + this.map = new Map();
5 + }
6 + get(key){
7 + const value = this.map.get(key);
8 + if(typeof value === "undefined"){
9 + return -1;
10 + }
11 + this.map.delete(key);
12 + this.map.set(key, value);
13 + return value;
14 + }
15 +
16 + put(key, value){
17 + let obj = {};
18 + if(this.map.has(key)){
19 + obj.key = key;
20 + obj.value = this.map.get(key);
21 + this.map.delete(key);
22 + }
23 + else{
24 + obj.key = key;
25 + obj.value = value;
26 + }
27 + this.map.set(key, value);
28 + const keys = this.map.keys();
29 + if(this.map.size > this.capacity){
30 + obj.key = keys.next().value;
31 + obj.value = this.map.get(obj.key);
32 + this.map.delete(obj.key);
33 + }
34 + return obj;
35 + }
36 +}
37 +
38 +module.exports = LRUCache;
...\ No newline at end of file ...\ No newline at end of file
...@@ -9,13 +9,16 @@ import mongoose from "mongoose"; ...@@ -9,13 +9,16 @@ import mongoose from "mongoose";
9 import session from "express-session"; 9 import session from "express-session";
10 import flash from "express-flash"; 10 import flash from "express-flash";
11 import MongoStore from "connect-mongo"; 11 import MongoStore from "connect-mongo";
12 -import { localsMiddleware } from "./middlewares"; 12 +import { localsMiddleware, uploadFile } from "./middlewares";
13 +import File from "./models/File";
13 import routes from "./routes"; 14 import routes from "./routes";
14 import globalRouter from "./routers/globalRouter"; 15 import globalRouter from "./routers/globalRouter";
15 import fileRouter from "./routers/fileRouter"; 16 import fileRouter from "./routers/fileRouter";
16 - 17 +import redis from 'redis';
18 +import JSON from 'JSON';
17 dotenv.config(); 19 dotenv.config();
18 const app = express(); 20 const app = express();
21 +const client = redis.createClient(6379,'127.0.0.1');
19 22
20 const CokieStore = MongoStore(session); 23 const CokieStore = MongoStore(session);
21 24
...@@ -39,6 +42,84 @@ app.use( ...@@ -39,6 +42,84 @@ app.use(
39 app.use(flash()); 42 app.use(flash());
40 app.use(localsMiddleware); 43 app.use(localsMiddleware);
41 app.use(routes.home, globalRouter); 44 app.use(routes.home, globalRouter);
42 -app.use(routes.files, fileRouter); 45 +//app.use(routes.files, fileRouter);
46 +app.use(function(req,res,next){
47 +
48 + req.cache = client;
49 +
50 + next();
51 +
52 +})
53 +
54 +// Caching
55 +app.use(function(req,res,next){
56 + req.cache = client;
57 + next();
58 +})
59 +
60 +app.get(`/files${routes.upload}`, (req, res) =>
61 + res.render("upload", { pageTitle: "Upload" }));
62 +
63 +app.post(`/files${routes.upload}`, uploadFile, (req, res) => {
64 + // multer를 해야 파일이 넘어가는 것이 나타난다.
65 + req.accepts('application/json');
66 + const key = req.body.title;
67 + const value = JSON.stringify(req.body);
68 +
69 + req.cache.set(key, value, (err, data) => {
70 + if(err){
71 + console.log(err);
72 + res.send("error"+err);
73 + return;
74 + }
75 + req.cache.expire(key, 10);
76 + console.log(value);
77 + res.send(value);
78 + });
79 +});
80 +app.get('/files/:title', (req, res, next) => {
81 + const key = req.params.title;
82 + console.log('title : ' + key);
83 +
84 + req.cache.get(key, (err, data) => {
85 + if(err){
86 + console.log(err);
87 + res.send("error : " + err);
88 + return;
89 + }
90 +
91 + const value = JSON.parse(data);
92 + res.json(value);
93 + });
94 +});
95 +
96 +app.get('/view_cache', (req, res) => {
97 + req.cache.get('/files/:title', async (err, data) => {
98 + if(err){
99 + console.log(err);
100 + res.send("error : " + err);
101 + return;
102 + }
103 + if(!data) {
104 + const allData = await File.find({}).sort({ _id: -1 });
105 + const dataArr = JSON.stringify(allData);
106 + req.cache.set('/files/:title', dataArr, (err, data) => {
107 + if(err){
108 + console.log(err);
109 + res.send("error :" + err);
110 + return;
111 + }
112 + req.cache.expire('/files/:title', 10);
113 + res.send(dataArr)
114 + })
115 + }
116 + else {
117 + res.send(data)
118 + }
119 + });
120 +});
121 +
122 +
123 +
43 124
44 export default app; // 파일을 불러올때 app object를 준다는 의미. 125 export default app; // 파일을 불러올때 app object를 준다는 의미.
......
1 /* eslint-disable no-console */ 1 /* eslint-disable no-console */
2 import routes from "../routes"; 2 import routes from "../routes";
3 import File from "../models/File"; 3 import File from "../models/File";
4 +
4 const createCsvWriter = require('csv-writer').createObjectCsvWriter; 5 const createCsvWriter = require('csv-writer').createObjectCsvWriter;
5 const csvInsertWriter = createCsvWriter({ 6 const csvInsertWriter = createCsvWriter({
6 path: 'insertOutput.csv', 7 path: 'insertOutput.csv',
...@@ -23,9 +24,10 @@ export const home = async (req, res) => { ...@@ -23,9 +24,10 @@ export const home = async (req, res) => {
23 res.render("home", { pageTitle: "Home", files: [] }); 24 res.render("home", { pageTitle: "Home", files: [] });
24 } 25 }
25 }; 26 };
26 -const searchTime = new Array(); 27 +// const searchTime = new Array();
27 export const search = async (req, res) => { 28 export const search = async (req, res) => {
28 - const startTime = new Date().getTime(); 29 + console.log(req);
30 + // const startTime = new Date().getTime();
29 const { 31 const {
30 query: { term: searchingBy }, 32 query: { term: searchingBy },
31 } = req; // == const searchingBy = req.query.term; 33 } = req; // == const searchingBy = req.query.term;
...@@ -34,13 +36,19 @@ export const search = async (req, res) => { ...@@ -34,13 +36,19 @@ export const search = async (req, res) => {
34 files = await File.find({ 36 files = await File.find({
35 title: { $regex: searchingBy, $options: "i" }, // i를 옵션으로 추가하면 insensitive.. 대소문자 구분 안함. 37 title: { $regex: searchingBy, $options: "i" }, // i를 옵션으로 추가하면 insensitive.. 대소문자 구분 안함.
36 }); 38 });
39 + /*
37 const endTime = new Date().getTime(); // SELECT의 경우 파일 시간 측정 40 const endTime = new Date().getTime(); // SELECT의 경우 파일 시간 측정
38 searchTime.push({ms: endTime - startTime}); 41 searchTime.push({ms: endTime - startTime});
39 - if (searchTime.length === 3){ 42 + if (searchTime.length === 50){
40 csvSelectWriter 43 csvSelectWriter
41 .writeRecords(searchTime) 44 .writeRecords(searchTime)
42 .then(() => console.log("The CSV file was written successfully~")); 45 .then(() => console.log("The CSV file was written successfully~"));
43 } 46 }
47 +
48 + for (var i = 0; i < searchTime.length; i++){
49 + console.log(i+1 + "번째 속도: " + Object.values(searchTime[i]) + "ms");
50 + }
51 + */
44 } catch (error) { 52 } catch (error) {
45 console.log(error); 53 console.log(error);
46 } 54 }
...@@ -54,7 +62,7 @@ export const getUpload = (req, res) => ...@@ -54,7 +62,7 @@ export const getUpload = (req, res) =>
54 62
55 const insertTime = new Array(); 63 const insertTime = new Array();
56 export const postUpload = async (req, res) => { 64 export const postUpload = async (req, res) => {
57 - const startTime = new Date().getTime(); 65 + // const startTime = new Date().getTime();
58 // multer를 해야 파일이 넘어가는 것이 나타난다. 66 // multer를 해야 파일이 넘어가는 것이 나타난다.
59 const { 67 const {
60 body: { title }, 68 body: { title },
...@@ -66,14 +74,20 @@ export const postUpload = async (req, res) => { ...@@ -66,14 +74,20 @@ export const postUpload = async (req, res) => {
66 title, 74 title,
67 // 여기있는 fileUrl, title은 fileDB의 속성이다. 75 // 여기있는 fileUrl, title은 fileDB의 속성이다.
68 }); 76 });
69 - console.log(newFile); 77 + // console.log(newFile);
78 + /*
70 const endTime = new Date().getTime(); // INSERT의 경우 파일 시간 측정 79 const endTime = new Date().getTime(); // INSERT의 경우 파일 시간 측정
71 insertTime.push({ms: endTime - startTime}); 80 insertTime.push({ms: endTime - startTime});
72 - if (insertTime.length === 3){ 81 + if (insertTime.length === 50){
73 csvInsertWriter 82 csvInsertWriter
74 .writeRecords(insertTime) 83 .writeRecords(insertTime)
75 .then(() => console.log("The CSV file was written successfully~")); 84 .then(() => console.log("The CSV file was written successfully~"));
76 } 85 }
86 +
87 + for (var i = 0; i < insertTime.length; i++){
88 + console.log(i+1 + "번째 속도: " + Object.values(insertTime[i]) + "ms");
89 + }
90 + */
77 res.redirect(routes.home); 91 res.redirect(routes.home);
78 }; 92 };
79 93
......
...@@ -2,6 +2,7 @@ dotenv.config(); ...@@ -2,6 +2,7 @@ dotenv.config();
2 import dotenv from "dotenv"; 2 import dotenv from "dotenv";
3 import app from "./app"; // app.js에서 export default app했기 때문에 불러올 수 있다. 3 import app from "./app"; // app.js에서 export default app했기 때문에 불러올 수 있다.
4 import "./db"; 4 import "./db";
5 +import "./test/lruCache.spec";
5 import "./models/File"; 6 import "./models/File";
6 7
7 const PORT = process.env.PORT || 80; 8 const PORT = process.env.PORT || 80;
......
1 +time
2 +146
3 +11
4 +5
5 +5
6 +8
7 +9
8 +79
9 +11
10 +2
11 +154
12 +27
13 +10
14 +9
15 +10
16 +53
17 +8
18 +9
19 +4
20 +8
21 +50
22 +5
23 +10
24 +10
25 +9
26 +9
27 +16
28 +3
29 +3
30 +31
31 +29
32 +4
33 +3
34 +3
35 +5
36 +3
37 +3
38 +3
39 +2
40 +12
41 +49
42 +3
43 +4
44 +3
45 +4
46 +60
47 +3
48 +3
49 +3
50 +4
51 +70
...@@ -18,8 +18,8 @@ var LRU = require("lru-cache") ...@@ -18,8 +18,8 @@ var LRU = require("lru-cache")
18 , length: function (n, key) { return n * 2 + key.length } 18 , length: function (n, key) { return n * 2 + key.length }
19 , dispose: function (key, n) { n.close() } 19 , dispose: function (key, n) { n.close() }
20 , maxAge: 1000 * 60 * 60 } 20 , maxAge: 1000 * 60 * 60 }
21 - , cache = LRU(options) 21 + , cache = new LRU(options)
22 - , otherCache = LRU(50) // sets just the max size 22 + , otherCache = new LRU(50) // sets just the max size
23 23
24 cache.set("key", "value") 24 cache.set("key", "value")
25 cache.get("key") // "value" 25 cache.get("key") // "value"
...@@ -49,10 +49,13 @@ away. ...@@ -49,10 +49,13 @@ away.
49 * `max` The maximum size of the cache, checked by applying the length 49 * `max` The maximum size of the cache, checked by applying the length
50 function to all values in the cache. Not setting this is kind of 50 function to all values in the cache. Not setting this is kind of
51 silly, since that's the whole purpose of this lib, but it defaults 51 silly, since that's the whole purpose of this lib, but it defaults
52 - to `Infinity`. 52 + to `Infinity`. Setting it to a non-number or negative number will
53 + throw a `TypeError`. Setting it to 0 makes it be `Infinity`.
53 * `maxAge` Maximum age in ms. Items are not pro-actively pruned out 54 * `maxAge` Maximum age in ms. Items are not pro-actively pruned out
54 as they age, but if you try to get an item that is too old, it'll 55 as they age, but if you try to get an item that is too old, it'll
55 drop it and return undefined instead of giving it to you. 56 drop it and return undefined instead of giving it to you.
57 + Setting this to a negative value will make everything seem old!
58 + Setting it to a non-number will throw a `TypeError`.
56 * `length` Function that is used to calculate the length of stored 59 * `length` Function that is used to calculate the length of stored
57 items. If you're storing strings or buffers, then you probably want 60 items. If you're storing strings or buffers, then you probably want
58 to do something like `function(n, key){return n.length}`. The default is 61 to do something like `function(n, key){return n.length}`. The default is
...@@ -76,6 +79,11 @@ away. ...@@ -76,6 +79,11 @@ away.
76 it'll be called whenever a `set()` operation overwrites an existing 79 it'll be called whenever a `set()` operation overwrites an existing
77 key. If you set this option, `dispose()` will only be called when a 80 key. If you set this option, `dispose()` will only be called when a
78 key falls out of the cache, not when it is overwritten. 81 key falls out of the cache, not when it is overwritten.
82 +* `updateAgeOnGet` When using time-expiring entries with `maxAge`,
83 + setting this to `true` will make each item's effective time update
84 + to the current time whenever it is retrieved from cache, causing it
85 + to not expire. (It can still fall out of cache based on recency of
86 + use, of course.)
79 87
80 ## API 88 ## API
81 89
......
1 'use strict' 1 'use strict'
2 2
3 -module.exports = LRUCache
4 -
5 -// This will be a proper iterable 'Map' in engines that support it,
6 -// or a fakey-fake PseudoMap in older versions.
7 -var Map = require('pseudomap')
8 -var util = require('util')
9 -
10 // A linked list to keep track of recently-used-ness 3 // A linked list to keep track of recently-used-ness
11 -var Yallist = require('yallist') 4 +const Yallist = require('yallist')
12 -
13 -// use symbols if possible, otherwise just _props
14 -var hasSymbol = typeof Symbol === 'function' && process.env._nodeLRUCacheForceNoSymbol !== '1'
15 -var makeSymbol
16 -if (hasSymbol) {
17 - makeSymbol = function (key) {
18 - return Symbol(key)
19 - }
20 -} else {
21 - makeSymbol = function (key) {
22 - return '_' + key
23 - }
24 -}
25 5
26 -var MAX = makeSymbol('max') 6 +const MAX = Symbol('max')
27 -var LENGTH = makeSymbol('length') 7 +const LENGTH = Symbol('length')
28 -var LENGTH_CALCULATOR = makeSymbol('lengthCalculator') 8 +const LENGTH_CALCULATOR = Symbol('lengthCalculator')
29 -var ALLOW_STALE = makeSymbol('allowStale') 9 +const ALLOW_STALE = Symbol('allowStale')
30 -var MAX_AGE = makeSymbol('maxAge') 10 +const MAX_AGE = Symbol('maxAge')
31 -var DISPOSE = makeSymbol('dispose') 11 +const DISPOSE = Symbol('dispose')
32 -var NO_DISPOSE_ON_SET = makeSymbol('noDisposeOnSet') 12 +const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet')
33 -var LRU_LIST = makeSymbol('lruList') 13 +const LRU_LIST = Symbol('lruList')
34 -var CACHE = makeSymbol('cache') 14 +const CACHE = Symbol('cache')
15 +const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet')
35 16
36 -function naiveLength () { return 1 } 17 +const naiveLength = () => 1
37 18
38 // lruList is a yallist where the head is the youngest 19 // lruList is a yallist where the head is the youngest
39 // item, and the tail is the oldest. the list contains the Hit 20 // item, and the tail is the oldest. the list contains the Hit
...@@ -43,262 +24,140 @@ function naiveLength () { return 1 } ...@@ -43,262 +24,140 @@ function naiveLength () { return 1 }
43 // 24 //
44 // cache is a Map (or PseudoMap) that matches the keys to 25 // cache is a Map (or PseudoMap) that matches the keys to
45 // the Yallist.Node object. 26 // the Yallist.Node object.
46 -function LRUCache (options) { 27 +class LRUCache {
47 - if (!(this instanceof LRUCache)) { 28 + constructor (options) {
48 - return new LRUCache(options) 29 + if (typeof options === 'number')
49 - }
50 -
51 - if (typeof options === 'number') {
52 options = { max: options } 30 options = { max: options }
53 - }
54 31
55 - if (!options) { 32 + if (!options)
56 options = {} 33 options = {}
57 - }
58 34
59 - var max = this[MAX] = options.max 35 + if (options.max && (typeof options.max !== 'number' || options.max < 0))
36 + throw new TypeError('max must be a non-negative number')
60 // Kind of weird to have a default max of Infinity, but oh well. 37 // Kind of weird to have a default max of Infinity, but oh well.
61 - if (!max || 38 + const max = this[MAX] = options.max || Infinity
62 - !(typeof max === 'number') ||
63 - max <= 0) {
64 - this[MAX] = Infinity
65 - }
66 -
67 - var lc = options.length || naiveLength
68 - if (typeof lc !== 'function') {
69 - lc = naiveLength
70 - }
71 - this[LENGTH_CALCULATOR] = lc
72 39
40 + const lc = options.length || naiveLength
41 + this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc
73 this[ALLOW_STALE] = options.stale || false 42 this[ALLOW_STALE] = options.stale || false
43 + if (options.maxAge && typeof options.maxAge !== 'number')
44 + throw new TypeError('maxAge must be a number')
74 this[MAX_AGE] = options.maxAge || 0 45 this[MAX_AGE] = options.maxAge || 0
75 this[DISPOSE] = options.dispose 46 this[DISPOSE] = options.dispose
76 this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false 47 this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false
48 + this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false
77 this.reset() 49 this.reset()
78 -}
79 -
80 -// resize the cache when the max changes.
81 -Object.defineProperty(LRUCache.prototype, 'max', {
82 - set: function (mL) {
83 - if (!mL || !(typeof mL === 'number') || mL <= 0) {
84 - mL = Infinity
85 } 50 }
86 - this[MAX] = mL 51 +
52 + // resize the cache when the max changes.
53 + set max (mL) {
54 + if (typeof mL !== 'number' || mL < 0)
55 + throw new TypeError('max must be a non-negative number')
56 +
57 + this[MAX] = mL || Infinity
87 trim(this) 58 trim(this)
88 - }, 59 + }
89 - get: function () { 60 + get max () {
90 return this[MAX] 61 return this[MAX]
91 - }, 62 + }
92 - enumerable: true
93 -})
94 63
95 -Object.defineProperty(LRUCache.prototype, 'allowStale', { 64 + set allowStale (allowStale) {
96 - set: function (allowStale) {
97 this[ALLOW_STALE] = !!allowStale 65 this[ALLOW_STALE] = !!allowStale
98 - }, 66 + }
99 - get: function () { 67 + get allowStale () {
100 return this[ALLOW_STALE] 68 return this[ALLOW_STALE]
101 - },
102 - enumerable: true
103 -})
104 -
105 -Object.defineProperty(LRUCache.prototype, 'maxAge', {
106 - set: function (mA) {
107 - if (!mA || !(typeof mA === 'number') || mA < 0) {
108 - mA = 0
109 } 69 }
70 +
71 + set maxAge (mA) {
72 + if (typeof mA !== 'number')
73 + throw new TypeError('maxAge must be a non-negative number')
74 +
110 this[MAX_AGE] = mA 75 this[MAX_AGE] = mA
111 trim(this) 76 trim(this)
112 - }, 77 + }
113 - get: function () { 78 + get maxAge () {
114 return this[MAX_AGE] 79 return this[MAX_AGE]
115 - },
116 - enumerable: true
117 -})
118 -
119 -// resize the cache when the lengthCalculator changes.
120 -Object.defineProperty(LRUCache.prototype, 'lengthCalculator', {
121 - set: function (lC) {
122 - if (typeof lC !== 'function') {
123 - lC = naiveLength
124 } 80 }
81 +
82 + // resize the cache when the lengthCalculator changes.
83 + set lengthCalculator (lC) {
84 + if (typeof lC !== 'function')
85 + lC = naiveLength
86 +
125 if (lC !== this[LENGTH_CALCULATOR]) { 87 if (lC !== this[LENGTH_CALCULATOR]) {
126 this[LENGTH_CALCULATOR] = lC 88 this[LENGTH_CALCULATOR] = lC
127 this[LENGTH] = 0 89 this[LENGTH] = 0
128 - this[LRU_LIST].forEach(function (hit) { 90 + this[LRU_LIST].forEach(hit => {
129 hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) 91 hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key)
130 this[LENGTH] += hit.length 92 this[LENGTH] += hit.length
131 - }, this) 93 + })
132 } 94 }
133 trim(this) 95 trim(this)
134 - }, 96 + }
135 - get: function () { return this[LENGTH_CALCULATOR] }, 97 + get lengthCalculator () { return this[LENGTH_CALCULATOR] }
136 - enumerable: true 98 +
137 -}) 99 + get length () { return this[LENGTH] }
138 - 100 + get itemCount () { return this[LRU_LIST].length }
139 -Object.defineProperty(LRUCache.prototype, 'length', { 101 +
140 - get: function () { return this[LENGTH] }, 102 + rforEach (fn, thisp) {
141 - enumerable: true
142 -})
143 -
144 -Object.defineProperty(LRUCache.prototype, 'itemCount', {
145 - get: function () { return this[LRU_LIST].length },
146 - enumerable: true
147 -})
148 -
149 -LRUCache.prototype.rforEach = function (fn, thisp) {
150 thisp = thisp || this 103 thisp = thisp || this
151 - for (var walker = this[LRU_LIST].tail; walker !== null;) { 104 + for (let walker = this[LRU_LIST].tail; walker !== null;) {
152 - var prev = walker.prev 105 + const prev = walker.prev
153 forEachStep(this, fn, walker, thisp) 106 forEachStep(this, fn, walker, thisp)
154 walker = prev 107 walker = prev
155 } 108 }
156 -}
157 -
158 -function forEachStep (self, fn, node, thisp) {
159 - var hit = node.value
160 - if (isStale(self, hit)) {
161 - del(self, node)
162 - if (!self[ALLOW_STALE]) {
163 - hit = undefined
164 } 109 }
165 - }
166 - if (hit) {
167 - fn.call(thisp, hit.value, hit.key, self)
168 - }
169 -}
170 110
171 -LRUCache.prototype.forEach = function (fn, thisp) { 111 + forEach (fn, thisp) {
172 thisp = thisp || this 112 thisp = thisp || this
173 - for (var walker = this[LRU_LIST].head; walker !== null;) { 113 + for (let walker = this[LRU_LIST].head; walker !== null;) {
174 - var next = walker.next 114 + const next = walker.next
175 forEachStep(this, fn, walker, thisp) 115 forEachStep(this, fn, walker, thisp)
176 walker = next 116 walker = next
177 } 117 }
178 -} 118 + }
179 119
180 -LRUCache.prototype.keys = function () { 120 + keys () {
181 - return this[LRU_LIST].toArray().map(function (k) { 121 + return this[LRU_LIST].toArray().map(k => k.key)
182 - return k.key 122 + }
183 - }, this)
184 -}
185 123
186 -LRUCache.prototype.values = function () { 124 + values () {
187 - return this[LRU_LIST].toArray().map(function (k) { 125 + return this[LRU_LIST].toArray().map(k => k.value)
188 - return k.value 126 + }
189 - }, this)
190 -}
191 127
192 -LRUCache.prototype.reset = function () { 128 + reset () {
193 if (this[DISPOSE] && 129 if (this[DISPOSE] &&
194 this[LRU_LIST] && 130 this[LRU_LIST] &&
195 this[LRU_LIST].length) { 131 this[LRU_LIST].length) {
196 - this[LRU_LIST].forEach(function (hit) { 132 + this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value))
197 - this[DISPOSE](hit.key, hit.value)
198 - }, this)
199 } 133 }
200 134
201 this[CACHE] = new Map() // hash of items by key 135 this[CACHE] = new Map() // hash of items by key
202 this[LRU_LIST] = new Yallist() // list of items in order of use recency 136 this[LRU_LIST] = new Yallist() // list of items in order of use recency
203 this[LENGTH] = 0 // length of items in the list 137 this[LENGTH] = 0 // length of items in the list
204 -} 138 + }
205 139
206 -LRUCache.prototype.dump = function () { 140 + dump () {
207 - return this[LRU_LIST].map(function (hit) { 141 + return this[LRU_LIST].map(hit =>
208 - if (!isStale(this, hit)) { 142 + isStale(this, hit) ? false : {
209 - return {
210 k: hit.key, 143 k: hit.key,
211 v: hit.value, 144 v: hit.value,
212 e: hit.now + (hit.maxAge || 0) 145 e: hit.now + (hit.maxAge || 0)
146 + }).toArray().filter(h => h)
213 } 147 }
214 - }
215 - }, this).toArray().filter(function (h) {
216 - return h
217 - })
218 -}
219 148
220 -LRUCache.prototype.dumpLru = function () { 149 + dumpLru () {
221 return this[LRU_LIST] 150 return this[LRU_LIST]
222 -}
223 -
224 -/* istanbul ignore next */
225 -LRUCache.prototype.inspect = function (n, opts) {
226 - var str = 'LRUCache {'
227 - var extras = false
228 -
229 - var as = this[ALLOW_STALE]
230 - if (as) {
231 - str += '\n allowStale: true'
232 - extras = true
233 - }
234 -
235 - var max = this[MAX]
236 - if (max && max !== Infinity) {
237 - if (extras) {
238 - str += ','
239 - }
240 - str += '\n max: ' + util.inspect(max, opts)
241 - extras = true
242 } 151 }
243 152
244 - var maxAge = this[MAX_AGE] 153 + set (key, value, maxAge) {
245 - if (maxAge) {
246 - if (extras) {
247 - str += ','
248 - }
249 - str += '\n maxAge: ' + util.inspect(maxAge, opts)
250 - extras = true
251 - }
252 -
253 - var lc = this[LENGTH_CALCULATOR]
254 - if (lc && lc !== naiveLength) {
255 - if (extras) {
256 - str += ','
257 - }
258 - str += '\n length: ' + util.inspect(this[LENGTH], opts)
259 - extras = true
260 - }
261 -
262 - var didFirst = false
263 - this[LRU_LIST].forEach(function (item) {
264 - if (didFirst) {
265 - str += ',\n '
266 - } else {
267 - if (extras) {
268 - str += ',\n'
269 - }
270 - didFirst = true
271 - str += '\n '
272 - }
273 - var key = util.inspect(item.key).split('\n').join('\n ')
274 - var val = { value: item.value }
275 - if (item.maxAge !== maxAge) {
276 - val.maxAge = item.maxAge
277 - }
278 - if (lc !== naiveLength) {
279 - val.length = item.length
280 - }
281 - if (isStale(this, item)) {
282 - val.stale = true
283 - }
284 -
285 - val = util.inspect(val, opts).split('\n').join('\n ')
286 - str += key + ' => ' + val
287 - })
288 -
289 - if (didFirst || extras) {
290 - str += '\n'
291 - }
292 - str += '}'
293 -
294 - return str
295 -}
296 -
297 -LRUCache.prototype.set = function (key, value, maxAge) {
298 maxAge = maxAge || this[MAX_AGE] 154 maxAge = maxAge || this[MAX_AGE]
299 155
300 - var now = maxAge ? Date.now() : 0 156 + if (maxAge && typeof maxAge !== 'number')
301 - var len = this[LENGTH_CALCULATOR](value, key) 157 + throw new TypeError('maxAge must be a number')
158 +
159 + const now = maxAge ? Date.now() : 0
160 + const len = this[LENGTH_CALCULATOR](value, key)
302 161
303 if (this[CACHE].has(key)) { 162 if (this[CACHE].has(key)) {
304 if (len > this[MAX]) { 163 if (len > this[MAX]) {
...@@ -306,16 +165,15 @@ LRUCache.prototype.set = function (key, value, maxAge) { ...@@ -306,16 +165,15 @@ LRUCache.prototype.set = function (key, value, maxAge) {
306 return false 165 return false
307 } 166 }
308 167
309 - var node = this[CACHE].get(key) 168 + const node = this[CACHE].get(key)
310 - var item = node.value 169 + const item = node.value
311 170
312 // dispose of the old one before overwriting 171 // dispose of the old one before overwriting
313 // split out into 2 ifs for better coverage tracking 172 // split out into 2 ifs for better coverage tracking
314 if (this[DISPOSE]) { 173 if (this[DISPOSE]) {
315 - if (!this[NO_DISPOSE_ON_SET]) { 174 + if (!this[NO_DISPOSE_ON_SET])
316 this[DISPOSE](key, item.value) 175 this[DISPOSE](key, item.value)
317 } 176 }
318 - }
319 177
320 item.now = now 178 item.now = now
321 item.maxAge = maxAge 179 item.maxAge = maxAge
...@@ -327,13 +185,13 @@ LRUCache.prototype.set = function (key, value, maxAge) { ...@@ -327,13 +185,13 @@ LRUCache.prototype.set = function (key, value, maxAge) {
327 return true 185 return true
328 } 186 }
329 187
330 - var hit = new Entry(key, value, len, now, maxAge) 188 + const hit = new Entry(key, value, len, now, maxAge)
331 189
332 // oversized objects fall out of cache automatically. 190 // oversized objects fall out of cache automatically.
333 if (hit.length > this[MAX]) { 191 if (hit.length > this[MAX]) {
334 - if (this[DISPOSE]) { 192 + if (this[DISPOSE])
335 this[DISPOSE](key, value) 193 this[DISPOSE](key, value)
336 - } 194 +
337 return false 195 return false
338 } 196 }
339 197
...@@ -342,127 +200,135 @@ LRUCache.prototype.set = function (key, value, maxAge) { ...@@ -342,127 +200,135 @@ LRUCache.prototype.set = function (key, value, maxAge) {
342 this[CACHE].set(key, this[LRU_LIST].head) 200 this[CACHE].set(key, this[LRU_LIST].head)
343 trim(this) 201 trim(this)
344 return true 202 return true
345 -} 203 + }
346 204
347 -LRUCache.prototype.has = function (key) { 205 + has (key) {
348 if (!this[CACHE].has(key)) return false 206 if (!this[CACHE].has(key)) return false
349 - var hit = this[CACHE].get(key).value 207 + const hit = this[CACHE].get(key).value
350 - if (isStale(this, hit)) { 208 + return !isStale(this, hit)
351 - return false
352 } 209 }
353 - return true
354 -}
355 210
356 -LRUCache.prototype.get = function (key) { 211 + get (key) {
357 return get(this, key, true) 212 return get(this, key, true)
358 -} 213 + }
359 214
360 -LRUCache.prototype.peek = function (key) { 215 + peek (key) {
361 return get(this, key, false) 216 return get(this, key, false)
362 -} 217 + }
218 +
219 + pop () {
220 + const node = this[LRU_LIST].tail
221 + if (!node)
222 + return null
363 223
364 -LRUCache.prototype.pop = function () {
365 - var node = this[LRU_LIST].tail
366 - if (!node) return null
367 del(this, node) 224 del(this, node)
368 return node.value 225 return node.value
369 -} 226 + }
370 227
371 -LRUCache.prototype.del = function (key) { 228 + del (key) {
372 del(this, this[CACHE].get(key)) 229 del(this, this[CACHE].get(key))
373 -} 230 + }
374 231
375 -LRUCache.prototype.load = function (arr) { 232 + load (arr) {
376 // reset the cache 233 // reset the cache
377 this.reset() 234 this.reset()
378 235
379 - var now = Date.now() 236 + const now = Date.now()
380 // A previous serialized cache has the most recent items first 237 // A previous serialized cache has the most recent items first
381 - for (var l = arr.length - 1; l >= 0; l--) { 238 + for (let l = arr.length - 1; l >= 0; l--) {
382 - var hit = arr[l] 239 + const hit = arr[l]
383 - var expiresAt = hit.e || 0 240 + const expiresAt = hit.e || 0
384 - if (expiresAt === 0) { 241 + if (expiresAt === 0)
385 // the item was created without expiration in a non aged cache 242 // the item was created without expiration in a non aged cache
386 this.set(hit.k, hit.v) 243 this.set(hit.k, hit.v)
387 - } else { 244 + else {
388 - var maxAge = expiresAt - now 245 + const maxAge = expiresAt - now
389 // dont add already expired items 246 // dont add already expired items
390 if (maxAge > 0) { 247 if (maxAge > 0) {
391 this.set(hit.k, hit.v, maxAge) 248 this.set(hit.k, hit.v, maxAge)
392 } 249 }
393 } 250 }
394 } 251 }
395 -} 252 + }
396 253
397 -LRUCache.prototype.prune = function () { 254 + prune () {
398 - var self = this 255 + this[CACHE].forEach((value, key) => get(this, key, false))
399 - this[CACHE].forEach(function (value, key) { 256 + }
400 - get(self, key, false)
401 - })
402 } 257 }
403 258
404 -function get (self, key, doUse) { 259 +const get = (self, key, doUse) => {
405 - var node = self[CACHE].get(key) 260 + const node = self[CACHE].get(key)
406 if (node) { 261 if (node) {
407 - var hit = node.value 262 + const hit = node.value
408 if (isStale(self, hit)) { 263 if (isStale(self, hit)) {
409 del(self, node) 264 del(self, node)
410 - if (!self[ALLOW_STALE]) hit = undefined 265 + if (!self[ALLOW_STALE])
266 + return undefined
411 } else { 267 } else {
412 if (doUse) { 268 if (doUse) {
269 + if (self[UPDATE_AGE_ON_GET])
270 + node.value.now = Date.now()
413 self[LRU_LIST].unshiftNode(node) 271 self[LRU_LIST].unshiftNode(node)
414 } 272 }
415 } 273 }
416 - if (hit) hit = hit.value 274 + return hit.value
417 } 275 }
418 - return hit
419 } 276 }
420 277
421 -function isStale (self, hit) { 278 +const isStale = (self, hit) => {
422 - if (!hit || (!hit.maxAge && !self[MAX_AGE])) { 279 + if (!hit || (!hit.maxAge && !self[MAX_AGE]))
423 return false 280 return false
424 - } 281 +
425 - var stale = false 282 + const diff = Date.now() - hit.now
426 - var diff = Date.now() - hit.now 283 + return hit.maxAge ? diff > hit.maxAge
427 - if (hit.maxAge) { 284 + : self[MAX_AGE] && (diff > self[MAX_AGE])
428 - stale = diff > hit.maxAge
429 - } else {
430 - stale = self[MAX_AGE] && (diff > self[MAX_AGE])
431 - }
432 - return stale
433 } 285 }
434 286
435 -function trim (self) { 287 +const trim = self => {
436 if (self[LENGTH] > self[MAX]) { 288 if (self[LENGTH] > self[MAX]) {
437 - for (var walker = self[LRU_LIST].tail; 289 + for (let walker = self[LRU_LIST].tail;
438 self[LENGTH] > self[MAX] && walker !== null;) { 290 self[LENGTH] > self[MAX] && walker !== null;) {
439 // We know that we're about to delete this one, and also 291 // We know that we're about to delete this one, and also
440 // what the next least recently used key will be, so just 292 // what the next least recently used key will be, so just
441 // go ahead and set it now. 293 // go ahead and set it now.
442 - var prev = walker.prev 294 + const prev = walker.prev
443 del(self, walker) 295 del(self, walker)
444 walker = prev 296 walker = prev
445 } 297 }
446 } 298 }
447 } 299 }
448 300
449 -function del (self, node) { 301 +const del = (self, node) => {
450 if (node) { 302 if (node) {
451 - var hit = node.value 303 + const hit = node.value
452 - if (self[DISPOSE]) { 304 + if (self[DISPOSE])
453 self[DISPOSE](hit.key, hit.value) 305 self[DISPOSE](hit.key, hit.value)
454 - } 306 +
455 self[LENGTH] -= hit.length 307 self[LENGTH] -= hit.length
456 self[CACHE].delete(hit.key) 308 self[CACHE].delete(hit.key)
457 self[LRU_LIST].removeNode(node) 309 self[LRU_LIST].removeNode(node)
458 } 310 }
459 } 311 }
460 312
461 -// classy, since V8 prefers predictable objects. 313 +class Entry {
462 -function Entry (key, value, length, now, maxAge) { 314 + constructor (key, value, length, now, maxAge) {
463 this.key = key 315 this.key = key
464 this.value = value 316 this.value = value
465 this.length = length 317 this.length = length
466 this.now = now 318 this.now = now
467 this.maxAge = maxAge || 0 319 this.maxAge = maxAge || 0
320 + }
321 +}
322 +
323 +const forEachStep = (self, fn, node, thisp) => {
324 + let hit = node.value
325 + if (isStale(self, hit)) {
326 + del(self, node)
327 + if (!self[ALLOW_STALE])
328 + hit = undefined
329 + }
330 + if (hit)
331 + fn.call(thisp, hit.value, hit.key, self)
468 } 332 }
333 +
334 +module.exports = LRUCache
......
1 { 1 {
2 - "_from": "lru-cache@^4.0.1", 2 + "_from": "lru-cache",
3 - "_id": "lru-cache@4.1.5", 3 + "_id": "lru-cache@6.0.0",
4 "_inBundle": false, 4 "_inBundle": false,
5 - "_integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 5 + "_integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
6 "_location": "/lru-cache", 6 "_location": "/lru-cache",
7 "_phantomChildren": {}, 7 "_phantomChildren": {},
8 "_requested": { 8 "_requested": {
9 - "type": "range", 9 + "type": "tag",
10 "registry": true, 10 "registry": true,
11 - "raw": "lru-cache@^4.0.1", 11 + "raw": "lru-cache",
12 "name": "lru-cache", 12 "name": "lru-cache",
13 "escapedName": "lru-cache", 13 "escapedName": "lru-cache",
14 - "rawSpec": "^4.0.1", 14 + "rawSpec": "",
15 "saveSpec": null, 15 "saveSpec": null,
16 - "fetchSpec": "^4.0.1" 16 + "fetchSpec": "latest"
17 }, 17 },
18 "_requiredBy": [ 18 "_requiredBy": [
19 - "/cross-spawn" 19 + "#USER",
20 + "/"
20 ], 21 ],
21 - "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 22 + "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
22 - "_shasum": "8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd", 23 + "_shasum": "6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94",
23 - "_spec": "lru-cache@^4.0.1", 24 + "_spec": "lru-cache",
24 - "_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project/node_modules/cross-spawn", 25 + "_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project",
25 "author": { 26 "author": {
26 "name": "Isaac Z. Schlueter", 27 "name": "Isaac Z. Schlueter",
27 "email": "i@izs.me" 28 "email": "i@izs.me"
...@@ -31,15 +32,16 @@ ...@@ -31,15 +32,16 @@
31 }, 32 },
32 "bundleDependencies": false, 33 "bundleDependencies": false,
33 "dependencies": { 34 "dependencies": {
34 - "pseudomap": "^1.0.2", 35 + "yallist": "^4.0.0"
35 - "yallist": "^2.1.2"
36 }, 36 },
37 "deprecated": false, 37 "deprecated": false,
38 "description": "A cache object that deletes the least-recently-used items.", 38 "description": "A cache object that deletes the least-recently-used items.",
39 "devDependencies": { 39 "devDependencies": {
40 "benchmark": "^2.1.4", 40 "benchmark": "^2.1.4",
41 - "standard": "^12.0.1", 41 + "tap": "^14.10.7"
42 - "tap": "^12.1.0" 42 + },
43 + "engines": {
44 + "node": ">=10"
43 }, 45 },
44 "files": [ 46 "files": [
45 "index.js" 47 "index.js"
...@@ -58,14 +60,11 @@ ...@@ -58,14 +60,11 @@
58 "url": "git://github.com/isaacs/node-lru-cache.git" 60 "url": "git://github.com/isaacs/node-lru-cache.git"
59 }, 61 },
60 "scripts": { 62 "scripts": {
61 - "coveragerport": "tap --coverage-report=html", 63 + "postversion": "npm publish",
62 - "lintfix": "standard --fix test/*.js index.js", 64 + "prepublishOnly": "git push origin --follow-tags",
63 - "postpublish": "git push origin --all; git push origin --tags",
64 - "posttest": "standard test/*.js index.js",
65 - "postversion": "npm publish --tag=legacy",
66 "preversion": "npm test", 65 "preversion": "npm test",
67 - "snap": "TAP_SNAPSHOT=1 tap test/*.js -J", 66 + "snap": "tap",
68 - "test": "tap test/*.js --100 -J" 67 + "test": "tap"
69 }, 68 },
70 - "version": "4.1.5" 69 + "version": "6.0.0"
71 } 70 }
......
1 -var Yallist = require('./yallist.js') 1 +'use strict'
2 - 2 +module.exports = function (Yallist) {
3 -Yallist.prototype[Symbol.iterator] = function* () { 3 + Yallist.prototype[Symbol.iterator] = function* () {
4 for (let walker = this.head; walker; walker = walker.next) { 4 for (let walker = this.head; walker; walker = walker.next) {
5 yield walker.value 5 yield walker.value
6 } 6 }
7 + }
7 } 8 }
......
1 { 1 {
2 - "_from": "yallist@^2.1.2", 2 + "_from": "yallist@^4.0.0",
3 - "_id": "yallist@2.1.2", 3 + "_id": "yallist@4.0.0",
4 "_inBundle": false, 4 "_inBundle": false,
5 - "_integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 5 + "_integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
6 "_location": "/yallist", 6 "_location": "/yallist",
7 "_phantomChildren": {}, 7 "_phantomChildren": {},
8 "_requested": { 8 "_requested": {
9 "type": "range", 9 "type": "range",
10 "registry": true, 10 "registry": true,
11 - "raw": "yallist@^2.1.2", 11 + "raw": "yallist@^4.0.0",
12 "name": "yallist", 12 "name": "yallist",
13 "escapedName": "yallist", 13 "escapedName": "yallist",
14 - "rawSpec": "^2.1.2", 14 + "rawSpec": "^4.0.0",
15 "saveSpec": null, 15 "saveSpec": null,
16 - "fetchSpec": "^2.1.2" 16 + "fetchSpec": "^4.0.0"
17 }, 17 },
18 "_requiredBy": [ 18 "_requiredBy": [
19 "/lru-cache" 19 "/lru-cache"
20 ], 20 ],
21 - "_resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 21 + "_resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
22 - "_shasum": "1c11f9218f076089a47dd512f93c6699a6a81d52", 22 + "_shasum": "9bb92790d9c0effec63be73519e11a35019a3a72",
23 - "_spec": "yallist@^2.1.2", 23 + "_spec": "yallist@^4.0.0",
24 "_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project/node_modules/lru-cache", 24 "_where": "/Users/noblyan/Desktop/4_2/캡스톤디자인II/2017110267/Project/node_modules/lru-cache",
25 "author": { 25 "author": {
26 "name": "Isaac Z. Schlueter", 26 "name": "Isaac Z. Schlueter",
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
35 "deprecated": false, 35 "deprecated": false,
36 "description": "Yet Another Linked List", 36 "description": "Yet Another Linked List",
37 "devDependencies": { 37 "devDependencies": {
38 - "tap": "^10.3.0" 38 + "tap": "^12.1.0"
39 }, 39 },
40 "directories": { 40 "directories": {
41 "test": "test" 41 "test": "test"
...@@ -58,5 +58,5 @@ ...@@ -58,5 +58,5 @@
58 "preversion": "npm test", 58 "preversion": "npm test",
59 "test": "tap test/*.js --100" 59 "test": "tap test/*.js --100"
60 }, 60 },
61 - "version": "2.1.2" 61 + "version": "4.0.0"
62 } 62 }
......
1 +'use strict'
1 module.exports = Yallist 2 module.exports = Yallist
2 3
3 Yallist.Node = Node 4 Yallist.Node = Node
...@@ -53,6 +54,8 @@ Yallist.prototype.removeNode = function (node) { ...@@ -53,6 +54,8 @@ Yallist.prototype.removeNode = function (node) {
53 node.next = null 54 node.next = null
54 node.prev = null 55 node.prev = null
55 node.list = null 56 node.list = null
57 +
58 + return next
56 } 59 }
57 60
58 Yallist.prototype.unshiftNode = function (node) { 61 Yallist.prototype.unshiftNode = function (node) {
...@@ -317,6 +320,37 @@ Yallist.prototype.sliceReverse = function (from, to) { ...@@ -317,6 +320,37 @@ Yallist.prototype.sliceReverse = function (from, to) {
317 return ret 320 return ret
318 } 321 }
319 322
323 +Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
324 + if (start > this.length) {
325 + start = this.length - 1
326 + }
327 + if (start < 0) {
328 + start = this.length + start;
329 + }
330 +
331 + for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
332 + walker = walker.next
333 + }
334 +
335 + var ret = []
336 + for (var i = 0; walker && i < deleteCount; i++) {
337 + ret.push(walker.value)
338 + walker = this.removeNode(walker)
339 + }
340 + if (walker === null) {
341 + walker = this.tail
342 + }
343 +
344 + if (walker !== this.head && walker !== this.tail) {
345 + walker = walker.prev
346 + }
347 +
348 + for (var i = 0; i < nodes.length; i++) {
349 + walker = insert(this, walker, nodes[i])
350 + }
351 + return ret;
352 +}
353 +
320 Yallist.prototype.reverse = function () { 354 Yallist.prototype.reverse = function () {
321 var head = this.head 355 var head = this.head
322 var tail = this.tail 356 var tail = this.tail
...@@ -330,6 +364,23 @@ Yallist.prototype.reverse = function () { ...@@ -330,6 +364,23 @@ Yallist.prototype.reverse = function () {
330 return this 364 return this
331 } 365 }
332 366
367 +function insert (self, node, value) {
368 + var inserted = node === self.head ?
369 + new Node(value, null, node, self) :
370 + new Node(value, node, node.next, self)
371 +
372 + if (inserted.next === null) {
373 + self.tail = inserted
374 + }
375 + if (inserted.prev === null) {
376 + self.head = inserted
377 + }
378 +
379 + self.length++
380 +
381 + return inserted
382 +}
383 +
333 function push (self, item) { 384 function push (self, item) {
334 self.tail = new Node(item, self.tail, null, self) 385 self.tail = new Node(item, self.tail, null, self)
335 if (!self.head) { 386 if (!self.head) {
...@@ -368,3 +419,8 @@ function Node (value, prev, next, list) { ...@@ -368,3 +419,8 @@ function Node (value, prev, next, list) {
368 this.next = null 419 this.next = null
369 } 420 }
370 } 421 }
422 +
423 +try {
424 + // add if support for Symbol.iterator is present
425 + require('./iterator.js')(Yallist)
426 +} catch (er) {}
......
...@@ -1074,6 +1074,12 @@ ...@@ -1074,6 +1074,12 @@
1074 "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", 1074 "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
1075 "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" 1075 "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A=="
1076 }, 1076 },
1077 + "@ungap/promise-all-settled": {
1078 + "version": "1.1.2",
1079 + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
1080 + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
1081 + "dev": true
1082 + },
1077 "@webassemblyjs/ast": { 1083 "@webassemblyjs/ast": {
1078 "version": "1.9.0", 1084 "version": "1.9.0",
1079 "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", 1085 "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
...@@ -1241,6 +1247,11 @@ ...@@ -1241,6 +1247,11 @@
1241 "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", 1247 "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
1242 "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" 1248 "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
1243 }, 1249 },
1250 + "JSON": {
1251 + "version": "1.0.0",
1252 + "resolved": "https://registry.npmjs.org/JSON/-/JSON-1.0.0.tgz",
1253 + "integrity": "sha1-hoFTHCj4Q4oHVYn/BySCRuqWDYw="
1254 + },
1244 "abbrev": { 1255 "abbrev": {
1245 "version": "1.1.1", 1256 "version": "1.1.1",
1246 "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 1257 "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
...@@ -1370,6 +1381,12 @@ ...@@ -1370,6 +1381,12 @@
1370 } 1381 }
1371 } 1382 }
1372 }, 1383 },
1384 + "ansi-colors": {
1385 + "version": "4.1.1",
1386 + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
1387 + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
1388 + "dev": true
1389 + },
1373 "ansi-escapes": { 1390 "ansi-escapes": {
1374 "version": "4.3.1", 1391 "version": "4.3.1",
1375 "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", 1392 "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
...@@ -1559,6 +1576,11 @@ ...@@ -1559,6 +1576,11 @@
1559 "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 1576 "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
1560 "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 1577 "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
1561 }, 1578 },
1579 + "assertion-error": {
1580 + "version": "1.1.0",
1581 + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
1582 + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="
1583 + },
1562 "assign-symbols": { 1584 "assign-symbols": {
1563 "version": "1.0.0", 1585 "version": "1.0.0",
1564 "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", 1586 "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
...@@ -2021,6 +2043,12 @@ ...@@ -2021,6 +2043,12 @@
2021 "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 2043 "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
2022 "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 2044 "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
2023 }, 2045 },
2046 + "browser-stdout": {
2047 + "version": "1.3.1",
2048 + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
2049 + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
2050 + "dev": true
2051 + },
2024 "browserify-aes": { 2052 "browserify-aes": {
2025 "version": "1.2.0", 2053 "version": "1.2.0",
2026 "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 2054 "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
...@@ -2356,6 +2384,19 @@ ...@@ -2356,6 +2384,19 @@
2356 "lazy-cache": "^1.0.3" 2384 "lazy-cache": "^1.0.3"
2357 } 2385 }
2358 }, 2386 },
2387 + "chai": {
2388 + "version": "4.2.0",
2389 + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
2390 + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
2391 + "requires": {
2392 + "assertion-error": "^1.1.0",
2393 + "check-error": "^1.0.2",
2394 + "deep-eql": "^3.0.1",
2395 + "get-func-name": "^2.0.0",
2396 + "pathval": "^1.1.0",
2397 + "type-detect": "^4.0.5"
2398 + }
2399 + },
2359 "chainsaw": { 2400 "chainsaw": {
2360 "version": "0.1.0", 2401 "version": "0.1.0",
2361 "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", 2402 "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
...@@ -2388,6 +2429,11 @@ ...@@ -2388,6 +2429,11 @@
2388 "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 2429 "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
2389 "dev": true 2430 "dev": true
2390 }, 2431 },
2432 + "check-error": {
2433 + "version": "1.0.2",
2434 + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
2435 + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
2436 + },
2391 "chokidar": { 2437 "chokidar": {
2392 "version": "2.1.8", 2438 "version": "2.1.8",
2393 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", 2439 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
...@@ -2750,6 +2796,12 @@ ...@@ -2750,6 +2796,12 @@
2750 "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 2796 "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
2751 "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 2797 "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
2752 }, 2798 },
2799 + "cookiejar": {
2800 + "version": "2.1.2",
2801 + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
2802 + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
2803 + "dev": true
2804 + },
2753 "copy-concurrently": { 2805 "copy-concurrently": {
2754 "version": "1.0.5", 2806 "version": "1.0.5",
2755 "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", 2807 "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
...@@ -2864,6 +2916,22 @@ ...@@ -2864,6 +2916,22 @@
2864 "requires": { 2916 "requires": {
2865 "lru-cache": "^4.0.1", 2917 "lru-cache": "^4.0.1",
2866 "which": "^1.2.9" 2918 "which": "^1.2.9"
2919 + },
2920 + "dependencies": {
2921 + "lru-cache": {
2922 + "version": "4.1.5",
2923 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
2924 + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
2925 + "requires": {
2926 + "pseudomap": "^1.0.2",
2927 + "yallist": "^2.1.2"
2928 + }
2929 + },
2930 + "yallist": {
2931 + "version": "2.1.2",
2932 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
2933 + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
2934 + }
2867 } 2935 }
2868 }, 2936 },
2869 "crypto-browserify": { 2937 "crypto-browserify": {
...@@ -3017,6 +3085,14 @@ ...@@ -3017,6 +3085,14 @@
3017 } 3085 }
3018 } 3086 }
3019 }, 3087 },
3088 + "deep-eql": {
3089 + "version": "3.0.1",
3090 + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
3091 + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
3092 + "requires": {
3093 + "type-detect": "^4.0.0"
3094 + }
3095 + },
3020 "deep-extend": { 3096 "deep-extend": {
3021 "version": "0.6.0", 3097 "version": "0.6.0",
3022 "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 3098 "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
...@@ -3151,6 +3227,12 @@ ...@@ -3151,6 +3227,12 @@
3151 } 3227 }
3152 } 3228 }
3153 }, 3229 },
3230 + "diff": {
3231 + "version": "4.0.2",
3232 + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
3233 + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
3234 + "dev": true
3235 + },
3154 "diffie-hellman": { 3236 "diffie-hellman": {
3155 "version": "5.0.3", 3237 "version": "5.0.3",
3156 "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", 3238 "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
...@@ -4125,6 +4207,12 @@ ...@@ -4125,6 +4207,12 @@
4125 "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 4207 "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
4126 "dev": true 4208 "dev": true
4127 }, 4209 },
4210 + "fast-safe-stringify": {
4211 + "version": "2.0.7",
4212 + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
4213 + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
4214 + "dev": true
4215 + },
4128 "feature-policy": { 4216 "feature-policy": {
4129 "version": "0.3.0", 4217 "version": "0.3.0",
4130 "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", 4218 "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
...@@ -4228,6 +4316,12 @@ ...@@ -4228,6 +4316,12 @@
4228 "resolve-dir": "^1.0.1" 4316 "resolve-dir": "^1.0.1"
4229 } 4317 }
4230 }, 4318 },
4319 + "flat": {
4320 + "version": "5.0.2",
4321 + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
4322 + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
4323 + "dev": true
4324 + },
4231 "flat-cache": { 4325 "flat-cache": {
4232 "version": "2.0.1", 4326 "version": "2.0.1",
4233 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 4327 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
...@@ -4303,6 +4397,12 @@ ...@@ -4303,6 +4397,12 @@
4303 "mime-types": "^2.1.12" 4397 "mime-types": "^2.1.12"
4304 } 4398 }
4305 }, 4399 },
4400 + "formidable": {
4401 + "version": "1.2.2",
4402 + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
4403 + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==",
4404 + "dev": true
4405 + },
4306 "forwarded": { 4406 "forwarded": {
4307 "version": "0.1.2", 4407 "version": "0.1.2",
4308 "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 4408 "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
...@@ -4426,6 +4526,11 @@ ...@@ -4426,6 +4526,11 @@
4426 "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 4526 "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
4427 "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 4527 "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
4428 }, 4528 },
4529 + "get-func-name": {
4530 + "version": "2.0.0",
4531 + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
4532 + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
4533 + },
4429 "get-stdin": { 4534 "get-stdin": {
4430 "version": "4.0.1", 4535 "version": "4.0.1",
4431 "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", 4536 "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
...@@ -4567,6 +4672,12 @@ ...@@ -4567,6 +4672,12 @@
4567 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 4672 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
4568 "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" 4673 "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
4569 }, 4674 },
4675 + "growl": {
4676 + "version": "1.10.5",
4677 + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
4678 + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
4679 + "dev": true
4680 + },
4570 "har-schema": { 4681 "har-schema": {
4571 "version": "2.0.0", 4682 "version": "2.0.0",
4572 "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 4683 "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
...@@ -4688,6 +4799,12 @@ ...@@ -4688,6 +4799,12 @@
4688 "minimalistic-assert": "^1.0.1" 4799 "minimalistic-assert": "^1.0.1"
4689 } 4800 }
4690 }, 4801 },
4802 + "he": {
4803 + "version": "1.2.0",
4804 + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
4805 + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
4806 + "dev": true
4807 + },
4691 "helmet": { 4808 "helmet": {
4692 "version": "3.23.3", 4809 "version": "3.23.3",
4693 "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz", 4810 "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz",
...@@ -5276,6 +5393,12 @@ ...@@ -5276,6 +5393,12 @@
5276 "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", 5393 "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
5277 "dev": true 5394 "dev": true
5278 }, 5395 },
5396 + "is-plain-obj": {
5397 + "version": "2.1.0",
5398 + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
5399 + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
5400 + "dev": true
5401 + },
5279 "is-plain-object": { 5402 "is-plain-object": {
5280 "version": "2.0.4", 5403 "version": "2.0.4",
5281 "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 5404 "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
...@@ -5578,6 +5701,66 @@ ...@@ -5578,6 +5701,66 @@
5578 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 5701 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
5579 "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" 5702 "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
5580 }, 5703 },
5704 + "log-symbols": {
5705 + "version": "4.0.0",
5706 + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
5707 + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
5708 + "dev": true,
5709 + "requires": {
5710 + "chalk": "^4.0.0"
5711 + },
5712 + "dependencies": {
5713 + "ansi-styles": {
5714 + "version": "4.3.0",
5715 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
5716 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
5717 + "dev": true,
5718 + "requires": {
5719 + "color-convert": "^2.0.1"
5720 + }
5721 + },
5722 + "chalk": {
5723 + "version": "4.1.0",
5724 + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
5725 + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
5726 + "dev": true,
5727 + "requires": {
5728 + "ansi-styles": "^4.1.0",
5729 + "supports-color": "^7.1.0"
5730 + }
5731 + },
5732 + "color-convert": {
5733 + "version": "2.0.1",
5734 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
5735 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
5736 + "dev": true,
5737 + "requires": {
5738 + "color-name": "~1.1.4"
5739 + }
5740 + },
5741 + "color-name": {
5742 + "version": "1.1.4",
5743 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
5744 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
5745 + "dev": true
5746 + },
5747 + "has-flag": {
5748 + "version": "4.0.0",
5749 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
5750 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
5751 + "dev": true
5752 + },
5753 + "supports-color": {
5754 + "version": "7.2.0",
5755 + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
5756 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
5757 + "dev": true,
5758 + "requires": {
5759 + "has-flag": "^4.0.0"
5760 + }
5761 + }
5762 + }
5763 + },
5581 "longest": { 5764 "longest": {
5582 "version": "1.0.1", 5765 "version": "1.0.1",
5583 "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 5766 "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
...@@ -5607,12 +5790,11 @@ ...@@ -5607,12 +5790,11 @@
5607 "dev": true 5790 "dev": true
5608 }, 5791 },
5609 "lru-cache": { 5792 "lru-cache": {
5610 - "version": "4.1.5", 5793 + "version": "6.0.0",
5611 - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 5794 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
5612 - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 5795 + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
5613 "requires": { 5796 "requires": {
5614 - "pseudomap": "^1.0.2", 5797 + "yallist": "^4.0.0"
5615 - "yallist": "^2.1.2"
5616 } 5798 }
5617 }, 5799 },
5618 "make-dir": { 5800 "make-dir": {
...@@ -5837,6 +6019,237 @@ ...@@ -5837,6 +6019,237 @@
5837 "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", 6019 "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz",
5838 "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" 6020 "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE="
5839 }, 6021 },
6022 + "mocha": {
6023 + "version": "8.2.1",
6024 + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz",
6025 + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==",
6026 + "dev": true,
6027 + "requires": {
6028 + "@ungap/promise-all-settled": "1.1.2",
6029 + "ansi-colors": "4.1.1",
6030 + "browser-stdout": "1.3.1",
6031 + "chokidar": "3.4.3",
6032 + "debug": "4.2.0",
6033 + "diff": "4.0.2",
6034 + "escape-string-regexp": "4.0.0",
6035 + "find-up": "5.0.0",
6036 + "glob": "7.1.6",
6037 + "growl": "1.10.5",
6038 + "he": "1.2.0",
6039 + "js-yaml": "3.14.0",
6040 + "log-symbols": "4.0.0",
6041 + "minimatch": "3.0.4",
6042 + "ms": "2.1.2",
6043 + "nanoid": "3.1.12",
6044 + "serialize-javascript": "5.0.1",
6045 + "strip-json-comments": "3.1.1",
6046 + "supports-color": "7.2.0",
6047 + "which": "2.0.2",
6048 + "wide-align": "1.1.3",
6049 + "workerpool": "6.0.2",
6050 + "yargs": "13.3.2",
6051 + "yargs-parser": "13.1.2",
6052 + "yargs-unparser": "2.0.0"
6053 + },
6054 + "dependencies": {
6055 + "anymatch": {
6056 + "version": "3.1.1",
6057 + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
6058 + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
6059 + "dev": true,
6060 + "requires": {
6061 + "normalize-path": "^3.0.0",
6062 + "picomatch": "^2.0.4"
6063 + }
6064 + },
6065 + "binary-extensions": {
6066 + "version": "2.1.0",
6067 + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
6068 + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
6069 + "dev": true
6070 + },
6071 + "braces": {
6072 + "version": "3.0.2",
6073 + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
6074 + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
6075 + "dev": true,
6076 + "requires": {
6077 + "fill-range": "^7.0.1"
6078 + }
6079 + },
6080 + "chokidar": {
6081 + "version": "3.4.3",
6082 + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
6083 + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
6084 + "dev": true,
6085 + "requires": {
6086 + "anymatch": "~3.1.1",
6087 + "braces": "~3.0.2",
6088 + "fsevents": "~2.1.2",
6089 + "glob-parent": "~5.1.0",
6090 + "is-binary-path": "~2.1.0",
6091 + "is-glob": "~4.0.1",
6092 + "normalize-path": "~3.0.0",
6093 + "readdirp": "~3.5.0"
6094 + }
6095 + },
6096 + "debug": {
6097 + "version": "4.2.0",
6098 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
6099 + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
6100 + "dev": true,
6101 + "requires": {
6102 + "ms": "2.1.2"
6103 + }
6104 + },
6105 + "escape-string-regexp": {
6106 + "version": "4.0.0",
6107 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
6108 + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
6109 + "dev": true
6110 + },
6111 + "fill-range": {
6112 + "version": "7.0.1",
6113 + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
6114 + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
6115 + "dev": true,
6116 + "requires": {
6117 + "to-regex-range": "^5.0.1"
6118 + }
6119 + },
6120 + "find-up": {
6121 + "version": "5.0.0",
6122 + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
6123 + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
6124 + "dev": true,
6125 + "requires": {
6126 + "locate-path": "^6.0.0",
6127 + "path-exists": "^4.0.0"
6128 + }
6129 + },
6130 + "fsevents": {
6131 + "version": "2.1.3",
6132 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
6133 + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
6134 + "dev": true,
6135 + "optional": true
6136 + },
6137 + "glob-parent": {
6138 + "version": "5.1.1",
6139 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
6140 + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
6141 + "dev": true,
6142 + "requires": {
6143 + "is-glob": "^4.0.1"
6144 + }
6145 + },
6146 + "has-flag": {
6147 + "version": "4.0.0",
6148 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
6149 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
6150 + "dev": true
6151 + },
6152 + "is-binary-path": {
6153 + "version": "2.1.0",
6154 + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
6155 + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
6156 + "dev": true,
6157 + "requires": {
6158 + "binary-extensions": "^2.0.0"
6159 + }
6160 + },
6161 + "is-number": {
6162 + "version": "7.0.0",
6163 + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
6164 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
6165 + "dev": true
6166 + },
6167 + "locate-path": {
6168 + "version": "6.0.0",
6169 + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
6170 + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
6171 + "dev": true,
6172 + "requires": {
6173 + "p-locate": "^5.0.0"
6174 + }
6175 + },
6176 + "ms": {
6177 + "version": "2.1.2",
6178 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
6179 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
6180 + "dev": true
6181 + },
6182 + "p-limit": {
6183 + "version": "3.0.2",
6184 + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
6185 + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==",
6186 + "dev": true,
6187 + "requires": {
6188 + "p-try": "^2.0.0"
6189 + }
6190 + },
6191 + "p-locate": {
6192 + "version": "5.0.0",
6193 + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
6194 + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
6195 + "dev": true,
6196 + "requires": {
6197 + "p-limit": "^3.0.2"
6198 + }
6199 + },
6200 + "path-exists": {
6201 + "version": "4.0.0",
6202 + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
6203 + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
6204 + "dev": true
6205 + },
6206 + "readdirp": {
6207 + "version": "3.5.0",
6208 + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
6209 + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
6210 + "dev": true,
6211 + "requires": {
6212 + "picomatch": "^2.2.1"
6213 + }
6214 + },
6215 + "serialize-javascript": {
6216 + "version": "5.0.1",
6217 + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
6218 + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
6219 + "dev": true,
6220 + "requires": {
6221 + "randombytes": "^2.1.0"
6222 + }
6223 + },
6224 + "supports-color": {
6225 + "version": "7.2.0",
6226 + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
6227 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
6228 + "dev": true,
6229 + "requires": {
6230 + "has-flag": "^4.0.0"
6231 + }
6232 + },
6233 + "to-regex-range": {
6234 + "version": "5.0.1",
6235 + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
6236 + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
6237 + "dev": true,
6238 + "requires": {
6239 + "is-number": "^7.0.0"
6240 + }
6241 + },
6242 + "which": {
6243 + "version": "2.0.2",
6244 + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
6245 + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
6246 + "dev": true,
6247 + "requires": {
6248 + "isexe": "^2.0.0"
6249 + }
6250 + }
6251 + }
6252 + },
5840 "mongodb": { 6253 "mongodb": {
5841 "version": "3.6.2", 6254 "version": "3.6.2",
5842 "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz", 6255 "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
...@@ -5996,6 +6409,12 @@ ...@@ -5996,6 +6409,12 @@
5996 "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", 6409 "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
5997 "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" 6410 "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
5998 }, 6411 },
6412 + "nanoid": {
6413 + "version": "3.1.12",
6414 + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz",
6415 + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==",
6416 + "dev": true
6417 + },
5999 "nanomatch": { 6418 "nanomatch": {
6000 "version": "1.2.13", 6419 "version": "1.2.13",
6001 "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", 6420 "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
...@@ -6836,6 +7255,11 @@ ...@@ -6836,6 +7255,11 @@
6836 } 7255 }
6837 } 7256 }
6838 }, 7257 },
7258 + "pathval": {
7259 + "version": "1.1.0",
7260 + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
7261 + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA="
7262 + },
6839 "pause": { 7263 "pause": {
6840 "version": "0.0.1", 7264 "version": "0.0.1",
6841 "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", 7265 "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
...@@ -7431,6 +7855,35 @@ ...@@ -7431,6 +7855,35 @@
7431 "strip-indent": "^1.0.1" 7855 "strip-indent": "^1.0.1"
7432 } 7856 }
7433 }, 7857 },
7858 + "redis": {
7859 + "version": "3.0.2",
7860 + "resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz",
7861 + "integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==",
7862 + "requires": {
7863 + "denque": "^1.4.1",
7864 + "redis-commands": "^1.5.0",
7865 + "redis-errors": "^1.2.0",
7866 + "redis-parser": "^3.0.0"
7867 + }
7868 + },
7869 + "redis-commands": {
7870 + "version": "1.6.0",
7871 + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz",
7872 + "integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ=="
7873 + },
7874 + "redis-errors": {
7875 + "version": "1.2.0",
7876 + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
7877 + "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60="
7878 + },
7879 + "redis-parser": {
7880 + "version": "3.0.0",
7881 + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
7882 + "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
7883 + "requires": {
7884 + "redis-errors": "^1.0.0"
7885 + }
7886 + },
7434 "referrer-policy": { 7887 "referrer-policy": {
7435 "version": "1.2.0", 7888 "version": "1.2.0",
7436 "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", 7889 "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
...@@ -8400,6 +8853,92 @@ ...@@ -8400,6 +8853,92 @@
8400 "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 8853 "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
8401 "dev": true 8854 "dev": true
8402 }, 8855 },
8856 + "superagent": {
8857 + "version": "6.1.0",
8858 + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz",
8859 + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==",
8860 + "dev": true,
8861 + "requires": {
8862 + "component-emitter": "^1.3.0",
8863 + "cookiejar": "^2.1.2",
8864 + "debug": "^4.1.1",
8865 + "fast-safe-stringify": "^2.0.7",
8866 + "form-data": "^3.0.0",
8867 + "formidable": "^1.2.2",
8868 + "methods": "^1.1.2",
8869 + "mime": "^2.4.6",
8870 + "qs": "^6.9.4",
8871 + "readable-stream": "^3.6.0",
8872 + "semver": "^7.3.2"
8873 + },
8874 + "dependencies": {
8875 + "debug": {
8876 + "version": "4.2.0",
8877 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
8878 + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
8879 + "dev": true,
8880 + "requires": {
8881 + "ms": "2.1.2"
8882 + }
8883 + },
8884 + "form-data": {
8885 + "version": "3.0.0",
8886 + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
8887 + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
8888 + "dev": true,
8889 + "requires": {
8890 + "asynckit": "^0.4.0",
8891 + "combined-stream": "^1.0.8",
8892 + "mime-types": "^2.1.12"
8893 + }
8894 + },
8895 + "mime": {
8896 + "version": "2.4.6",
8897 + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
8898 + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
8899 + "dev": true
8900 + },
8901 + "ms": {
8902 + "version": "2.1.2",
8903 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
8904 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
8905 + "dev": true
8906 + },
8907 + "qs": {
8908 + "version": "6.9.4",
8909 + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
8910 + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
8911 + "dev": true
8912 + },
8913 + "readable-stream": {
8914 + "version": "3.6.0",
8915 + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
8916 + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
8917 + "dev": true,
8918 + "requires": {
8919 + "inherits": "^2.0.3",
8920 + "string_decoder": "^1.1.1",
8921 + "util-deprecate": "^1.0.1"
8922 + }
8923 + },
8924 + "semver": {
8925 + "version": "7.3.2",
8926 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
8927 + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
8928 + "dev": true
8929 + }
8930 + }
8931 + },
8932 + "supertest": {
8933 + "version": "6.0.1",
8934 + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.0.1.tgz",
8935 + "integrity": "sha512-8yDNdm+bbAN/jeDdXsRipbq9qMpVF7wRsbwLgsANHqdjPsCoecmlTuqEcLQMGpmojFBhxayZ0ckXmLXYq7e+0g==",
8936 + "dev": true,
8937 + "requires": {
8938 + "methods": "1.1.2",
8939 + "superagent": "6.1.0"
8940 + }
8941 + },
8403 "supports-color": { 8942 "supports-color": {
8404 "version": "5.5.0", 8943 "version": "5.5.0",
8405 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 8944 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
...@@ -8745,6 +9284,11 @@ ...@@ -8745,6 +9284,11 @@
8745 "prelude-ls": "~1.1.2" 9284 "prelude-ls": "~1.1.2"
8746 } 9285 }
8747 }, 9286 },
9287 + "type-detect": {
9288 + "version": "4.0.8",
9289 + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
9290 + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
9291 + },
8748 "type-fest": { 9292 "type-fest": {
8749 "version": "0.8.1", 9293 "version": "0.8.1",
8750 "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 9294 "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
...@@ -9463,6 +10007,12 @@ ...@@ -9463,6 +10007,12 @@
9463 "errno": "~0.1.7" 10007 "errno": "~0.1.7"
9464 } 10008 }
9465 }, 10009 },
10010 + "workerpool": {
10011 + "version": "6.0.2",
10012 + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz",
10013 + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==",
10014 + "dev": true
10015 + },
9466 "wrap-ansi": { 10016 "wrap-ansi": {
9467 "version": "5.1.0", 10017 "version": "5.1.0",
9468 "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 10018 "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
...@@ -9565,9 +10115,9 @@ ...@@ -9565,9 +10115,9 @@
9565 "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" 10115 "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
9566 }, 10116 },
9567 "yallist": { 10117 "yallist": {
9568 - "version": "2.1.2", 10118 + "version": "4.0.0",
9569 - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 10119 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
9570 - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 10120 + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
9571 }, 10121 },
9572 "yargs": { 10122 "yargs": {
9573 "version": "13.3.2", 10123 "version": "13.3.2",
...@@ -9624,6 +10174,32 @@ ...@@ -9624,6 +10174,32 @@
9624 "camelcase": "^5.0.0", 10174 "camelcase": "^5.0.0",
9625 "decamelize": "^1.2.0" 10175 "decamelize": "^1.2.0"
9626 } 10176 }
10177 + },
10178 + "yargs-unparser": {
10179 + "version": "2.0.0",
10180 + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
10181 + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
10182 + "dev": true,
10183 + "requires": {
10184 + "camelcase": "^6.0.0",
10185 + "decamelize": "^4.0.0",
10186 + "flat": "^5.0.2",
10187 + "is-plain-obj": "^2.1.0"
10188 + },
10189 + "dependencies": {
10190 + "camelcase": {
10191 + "version": "6.2.0",
10192 + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
10193 + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
10194 + "dev": true
10195 + },
10196 + "decamelize": {
10197 + "version": "4.0.0",
10198 + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
10199 + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
10200 + "dev": true
10201 + }
10202 + }
9627 } 10203 }
9628 } 10204 }
9629 } 10205 }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 "dev:server": "nodemon --exec babel-node init.js --delay 2 --ignore '.scss' --ignore 'static'", 7 "dev:server": "nodemon --exec babel-node init.js --delay 2 --ignore '.scss' --ignore 'static'",
8 "dev:assets": "WEBPACK_ENV=development webpack -w", 8 "dev:assets": "WEBPACK_ENV=development webpack -w",
9 "build:assets": "WEBPACK_ENV=production webpack", 9 "build:assets": "WEBPACK_ENV=production webpack",
10 - "tunnel": "ngrok http 80" 10 + "test": "mocha"
11 }, 11 },
12 "repository": { 12 "repository": {
13 "type": "git", 13 "type": "git",
...@@ -21,11 +21,13 @@ ...@@ -21,11 +21,13 @@
21 "@babel/node": "^7.8.7", 21 "@babel/node": "^7.8.7",
22 "@babel/polyfill": "^7.10.1", 22 "@babel/polyfill": "^7.10.1",
23 "@babel/preset-env": "^7.9.6", 23 "@babel/preset-env": "^7.9.6",
24 + "JSON": "^1.0.0",
24 "autoprefixer": "^9.8.0", 25 "autoprefixer": "^9.8.0",
25 "aws-sdk": "^2.702.0", 26 "aws-sdk": "^2.702.0",
26 "axios": "^0.19.2", 27 "axios": "^0.19.2",
27 "babel-loader": "^8.1.0", 28 "babel-loader": "^8.1.0",
28 "body-parser": "^1.19.0", 29 "body-parser": "^1.19.0",
30 + "chai": "^4.2.0",
29 "connect-mongo": "^3.2.0", 31 "connect-mongo": "^3.2.0",
30 "cookie-parser": "^1.4.5", 32 "cookie-parser": "^1.4.5",
31 "css-loader": "^3.5.3", 33 "css-loader": "^3.5.3",
...@@ -37,6 +39,7 @@ ...@@ -37,6 +39,7 @@
37 "extract-text-webpack-plugin": "^4.0.0-beta.0", 39 "extract-text-webpack-plugin": "^4.0.0-beta.0",
38 "get-blob-duration": "^1.1.1", 40 "get-blob-duration": "^1.1.1",
39 "helmet": "^3.22.0", 41 "helmet": "^3.22.0",
42 + "lru-cache": "^6.0.0",
40 "mongoose": "^5.9.15", 43 "mongoose": "^5.9.15",
41 "morgan": "^1.10.0", 44 "morgan": "^1.10.0",
42 "multer": "^1.4.2", 45 "multer": "^1.4.2",
...@@ -52,6 +55,7 @@ ...@@ -52,6 +55,7 @@
52 "perf_hooks": "0.0.1", 55 "perf_hooks": "0.0.1",
53 "postcss-loader": "^3.0.0", 56 "postcss-loader": "^3.0.0",
54 "pug": "^2.0.4", 57 "pug": "^2.0.4",
58 + "redis": "^3.0.2",
55 "sass-loader": "^8.0.2", 59 "sass-loader": "^8.0.2",
56 "webpack": "^4.43.0", 60 "webpack": "^4.43.0",
57 "webpack-cli": "^3.3.11" 61 "webpack-cli": "^3.3.11"
...@@ -62,7 +66,10 @@ ...@@ -62,7 +66,10 @@
62 "eslint-config-prettier": "^6.11.0", 66 "eslint-config-prettier": "^6.11.0",
63 "eslint-plugin-import": "^2.21.1", 67 "eslint-plugin-import": "^2.21.1",
64 "eslint-plugin-prettier": "^3.1.3", 68 "eslint-plugin-prettier": "^3.1.3",
69 + "mocha": "^8.2.1",
70 + "loadtest": "*",
65 "nodemon": "^2.0.4", 71 "nodemon": "^2.0.4",
66 - "prettier": "^2.0.5" 72 + "prettier": "^2.0.5",
73 + "supertest": "^6.0.1"
67 } 74 }
68 } 75 }
......
1 +time
2 +24
3 +4
4 +6
5 +6
6 +3
7 +3
8 +3
9 +3
10 +3
11 +3
12 +2
13 +2
14 +3
15 +2
16 +3
17 +2
18 +2
19 +2
20 +2
21 +11
22 +7
23 +5
24 +3
25 +2
26 +2
27 +2
28 +2
29 +3
30 +2
31 +2
32 +2
33 +2
34 +2
35 +2
36 +2
37 +6
38 +3
39 +2
40 +13
41 +39
42 +3
43 +2
44 +2
45 +2
46 +2
47 +2
48 +3
49 +2
50 +1
51 +3
1 +/*
2 +const { expect } = require('chai');
3 +const LRU = require('lru-cache');
4 +
5 +const MAX = 3;
6 +
7 +const options = {
8 + max: MAX,
9 + maxAge: 1900,
10 + length(n, key) { return 1},
11 +};
12 +
13 +describe('LRU Cache Test', () => {
14 + before( () => {
15 + lruCache = new LRU(options);
16 + // 데이터들을 최대로 cache!
17 + lruCache.set(1, 'SampleData1');
18 + lruCache.set(2, 'SampleData2');
19 + lruCache.set(3, 'SampleData3');
20 + });
21 +
22 + it('LRU algorithm Test', () => {
23 + // Happy3을 key로 가지는 데이터를 가장 사용 안함
24 + lruCache.keys().forEach( k => {
25 + for(let i = 0; i <= MAX - k; i++) {
26 + console.log("########", k, lruCache.get(k));
27 + }
28 + });
29 +
30 + // 새로운 데이터 cache!
31 + lruCache.set(4, 'SampleData4');
32 +
33 + //LRU 알고리즘에 의해 key가 3인 데이터가 삭제되어야함
34 + expect(lruCache.has(1)).to.be.equal(true);
35 + expect(lruCache.has(2)).to.be.equal(true);
36 + expect(lruCache.has(3)).to.be.equal(false);
37 + expect(lruCache.has(4)).to.be.equal(true);
38 + });
39 +
40 + it('dump & load Test', () => {
41 + //dump
42 + let cacheEntriesArray = lruCache.dump();
43 + lruCache.reset();
44 + expect(lruCache.itemCount).to.be.equal(0);
45 +
46 + //load
47 + lruCache.load(cacheEntriesArray);
48 + expect(lruCache.itemCount).to.be.equal(3);
49 + });
50 +
51 +
52 + it('Expire time Test', done => {
53 + //maxAge 시간 후엔 데이터 모두 만료되어야함
54 + setTimeout(() => {
55 + cache.prune();
56 + expect(lruCache.itemCount).to.be.equal(0);
57 + done();
58 + }, 1900);
59 + });
60 +});*/
...\ No newline at end of file ...\ No newline at end of file
...@@ -7,4 +7,5 @@ block content ...@@ -7,4 +7,5 @@ block content
7 label(for="file") File 7 label(for="file") File
8 input(type="file", id="file", name="file", required=true) 8 input(type="file", id="file", name="file", required=true)
9 input(type="text", placeholder="Title", name="title", required=true) 9 input(type="text", placeholder="Title", name="title", required=true)
10 + input(type="text", placeholder="Description", name="description", required=true)
10 input(type="submit", value="Upload File") 11 input(type="submit", value="Upload File")
...\ No newline at end of file ...\ No newline at end of file
......
1 +time
2 +37
3 +11
4 +6
5 +13
6 +4
7 +9
8 +9
9 +11
10 +3
11 +3
12 +3
13 +9
14 +12
15 +9
16 +5
17 +3
18 +2
19 +3
20 +8
21 +4
22 +2
23 +2
24 +5
25 +4
26 +2
27 +3
28 +3
29 +3
30 +3
31 +3
32 +6
33 +2
34 +2
35 +3
36 +2
37 +2
38 +7
39 +3
40 +2
41 +3
42 +3
43 +2
44 +5
45 +8
46 +6
47 +3
48 +3
49 +2
50 +2
51 +6
1 +time
2 +18
3 +5
4 +3
5 +3
6 +4
7 +2
8 +3
9 +3
10 +2
11 +3
12 +2
13 +2
14 +2
15 +2
16 +3
17 +2
18 +2
19 +2
20 +3
21 +2
22 +2
23 +2
24 +2
25 +2
26 +2
27 +2
28 +3
29 +4
30 +2
31 +3
32 +2
33 +2
34 +3
35 +2
36 +3
37 +2
38 +2
39 +2
40 +1
41 +2
42 +2
43 +1
44 +2
45 +2
46 +2
47 +3
48 +2
49 +3
50 +3
51 +3
1 +time
2 +146
3 +11
4 +5
5 +5
6 +8
7 +9
8 +79
9 +11
10 +2
11 +154
12 +27
13 +10
14 +9
15 +10
16 +53
17 +8
18 +9
19 +4
20 +8
21 +50
22 +5
23 +10
24 +10
25 +9
26 +9
27 +16
28 +3
29 +3
30 +31
31 +29
32 +4
33 +3
34 +3
35 +5
36 +3
37 +3
38 +3
39 +2
40 +12
41 +49
42 +3
43 +4
44 +3
45 +4
46 +60
47 +3
48 +3
49 +3
50 +4
51 +70
1 +time
2 +24
3 +4
4 +6
5 +6
6 +3
7 +3
8 +3
9 +3
10 +3
11 +3
12 +2
13 +2
14 +3
15 +2
16 +3
17 +2
18 +2
19 +2
20 +2
21 +11
22 +7
23 +5
24 +3
25 +2
26 +2
27 +2
28 +2
29 +3
30 +2
31 +2
32 +2
33 +2
34 +2
35 +2
36 +2
37 +6
38 +3
39 +2
40 +13
41 +39
42 +3
43 +2
44 +2
45 +2
46 +2
47 +2
48 +3
49 +2
50 +1
51 +3