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,24 +24,31 @@ export const home = async (req, res) => { ...@@ -23,24 +24,31 @@ 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;
32 let files = []; 34 let files = [];
33 try { 35 try {
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,426 +24,311 @@ function naiveLength () { return 1 } ...@@ -43,426 +24,311 @@ 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')
30 + options = { max: options }
31 +
32 + if (!options)
33 + options = {}
34 +
35 + if (options.max && (typeof options.max !== 'number' || options.max < 0))
36 + throw new TypeError('max must be a non-negative number')
37 + // Kind of weird to have a default max of Infinity, but oh well.
38 + const max = this[MAX] = options.max || Infinity
39 +
40 + const lc = options.length || naiveLength
41 + this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc
42 + this[ALLOW_STALE] = options.stale || false
43 + if (options.maxAge && typeof options.maxAge !== 'number')
44 + throw new TypeError('maxAge must be a number')
45 + this[MAX_AGE] = options.maxAge || 0
46 + this[DISPOSE] = options.dispose
47 + this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false
48 + this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false
49 + this.reset()
49 } 50 }
50 51
51 - if (typeof options === 'number') { 52 + // resize the cache when the max changes.
52 - options = { max: options } 53 + set max (mL) {
53 - } 54 + if (typeof mL !== 'number' || mL < 0)
55 + throw new TypeError('max must be a non-negative number')
54 56
55 - if (!options) { 57 + this[MAX] = mL || Infinity
56 - options = {} 58 + trim(this)
57 } 59 }
58 - 60 + get max () {
59 - var max = this[MAX] = options.max 61 + return this[MAX]
60 - // Kind of weird to have a default max of Infinity, but oh well.
61 - if (!max ||
62 - !(typeof max === 'number') ||
63 - max <= 0) {
64 - this[MAX] = Infinity
65 } 62 }
66 63
67 - var lc = options.length || naiveLength 64 + set allowStale (allowStale) {
68 - if (typeof lc !== 'function') { 65 + this[ALLOW_STALE] = !!allowStale
69 - lc = naiveLength 66 + }
67 + get allowStale () {
68 + return this[ALLOW_STALE]
70 } 69 }
71 - this[LENGTH_CALCULATOR] = lc
72 -
73 - this[ALLOW_STALE] = options.stale || false
74 - this[MAX_AGE] = options.maxAge || 0
75 - this[DISPOSE] = options.dispose
76 - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false
77 - this.reset()
78 -}
79 70
80 -// resize the cache when the max changes. 71 + set maxAge (mA) {
81 -Object.defineProperty(LRUCache.prototype, 'max', { 72 + if (typeof mA !== 'number')
82 - set: function (mL) { 73 + throw new TypeError('maxAge must be a non-negative number')
83 - if (!mL || !(typeof mL === 'number') || mL <= 0) {
84 - mL = Infinity
85 - }
86 - this[MAX] = mL
87 - trim(this)
88 - },
89 - get: function () {
90 - return this[MAX]
91 - },
92 - enumerable: true
93 -})
94 74
95 -Object.defineProperty(LRUCache.prototype, 'allowStale', {
96 - set: function (allowStale) {
97 - this[ALLOW_STALE] = !!allowStale
98 - },
99 - get: function () {
100 - 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 - }
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 - }, 80 + }
116 - enumerable: true 81 +
117 -}) 82 + // resize the cache when the lengthCalculator changes.
118 - 83 + set lengthCalculator (lC) {
119 -// resize the cache when the lengthCalculator changes. 84 + if (typeof lC !== 'function')
120 -Object.defineProperty(LRUCache.prototype, 'lengthCalculator', {
121 - set: function (lC) {
122 - if (typeof lC !== 'function') {
123 lC = naiveLength 85 lC = naiveLength
124 - } 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 - },
135 - get: function () { return this[LENGTH_CALCULATOR] },
136 - enumerable: true
137 -})
138 -
139 -Object.defineProperty(LRUCache.prototype, 'length', {
140 - get: function () { return this[LENGTH] },
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
151 - for (var walker = this[LRU_LIST].tail; walker !== null;) {
152 - var prev = walker.prev
153 - forEachStep(this, fn, walker, thisp)
154 - walker = prev
155 } 96 }
156 -} 97 + get lengthCalculator () { return this[LENGTH_CALCULATOR] }
157 98
158 -function forEachStep (self, fn, node, thisp) { 99 + get length () { return this[LENGTH] }
159 - var hit = node.value 100 + get itemCount () { return this[LRU_LIST].length }
160 - if (isStale(self, hit)) { 101 +
161 - del(self, node) 102 + rforEach (fn, thisp) {
162 - if (!self[ALLOW_STALE]) { 103 + thisp = thisp || this
163 - hit = undefined 104 + for (let walker = this[LRU_LIST].tail; walker !== null;) {
105 + const prev = walker.prev
106 + forEachStep(this, fn, walker, thisp)
107 + walker = prev
164 } 108 }
165 } 109 }
166 - if (hit) { 110 +
167 - fn.call(thisp, hit.value, hit.key, self) 111 + forEach (fn, thisp) {
112 + thisp = thisp || this
113 + for (let walker = this[LRU_LIST].head; walker !== null;) {
114 + const next = walker.next
115 + forEachStep(this, fn, walker, thisp)
116 + walker = next
117 + }
168 } 118 }
169 -}
170 119
171 -LRUCache.prototype.forEach = function (fn, thisp) { 120 + keys () {
172 - thisp = thisp || this 121 + return this[LRU_LIST].toArray().map(k => k.key)
173 - for (var walker = this[LRU_LIST].head; walker !== null;) {
174 - var next = walker.next
175 - forEachStep(this, fn, walker, thisp)
176 - walker = next
177 } 122 }
178 -}
179 123
180 -LRUCache.prototype.keys = function () { 124 + values () {
181 - return this[LRU_LIST].toArray().map(function (k) { 125 + return this[LRU_LIST].toArray().map(k => k.value)
182 - return k.key 126 + }
183 - }, this)
184 -}
185 127
186 -LRUCache.prototype.values = function () { 128 + reset () {
187 - return this[LRU_LIST].toArray().map(function (k) { 129 + if (this[DISPOSE] &&
188 - return k.value 130 + this[LRU_LIST] &&
189 - }, this) 131 + this[LRU_LIST].length) {
190 -} 132 + this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value))
133 + }
191 134
192 -LRUCache.prototype.reset = function () { 135 + this[CACHE] = new Map() // hash of items by key
193 - if (this[DISPOSE] && 136 + this[LRU_LIST] = new Yallist() // list of items in order of use recency
194 - this[LRU_LIST] && 137 + this[LENGTH] = 0 // length of items in the list
195 - this[LRU_LIST].length) {
196 - this[LRU_LIST].forEach(function (hit) {
197 - this[DISPOSE](hit.key, hit.value)
198 - }, this)
199 } 138 }
200 139
201 - this[CACHE] = new Map() // hash of items by key 140 + dump () {
202 - this[LRU_LIST] = new Yallist() // list of items in order of use recency 141 + return this[LRU_LIST].map(hit =>
203 - this[LENGTH] = 0 // length of items in the list 142 + isStale(this, hit) ? false : {
204 -}
205 -
206 -LRUCache.prototype.dump = function () {
207 - return this[LRU_LIST].map(function (hit) {
208 - if (!isStale(this, hit)) {
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)
213 - } 146 + }).toArray().filter(h => h)
214 - }
215 - }, this).toArray().filter(function (h) {
216 - return h
217 - })
218 -}
219 -
220 -LRUCache.prototype.dumpLru = function () {
221 - 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 } 147 }
234 148
235 - var max = this[MAX] 149 + dumpLru () {
236 - if (max && max !== Infinity) { 150 + return this[LRU_LIST]
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) { 154 + maxAge = maxAge || this[MAX_AGE]
246 - if (extras) {
247 - str += ','
248 - }
249 - str += '\n maxAge: ' + util.inspect(maxAge, opts)
250 - extras = true
251 - }
252 155
253 - var lc = this[LENGTH_CALCULATOR] 156 + if (maxAge && typeof maxAge !== 'number')
254 - if (lc && lc !== naiveLength) { 157 + throw new TypeError('maxAge must be a number')
255 - if (extras) {
256 - str += ','
257 - }
258 - str += '\n length: ' + util.inspect(this[LENGTH], opts)
259 - extras = true
260 - }
261 158
262 - var didFirst = false 159 + const now = maxAge ? Date.now() : 0
263 - this[LRU_LIST].forEach(function (item) { 160 + const len = this[LENGTH_CALCULATOR](value, key)
264 - if (didFirst) { 161 +
265 - str += ',\n ' 162 + if (this[CACHE].has(key)) {
266 - } else { 163 + if (len > this[MAX]) {
267 - if (extras) { 164 + del(this, this[CACHE].get(key))
268 - str += ',\n' 165 + return false
269 } 166 }
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 167
285 - val = util.inspect(val, opts).split('\n').join('\n ') 168 + const node = this[CACHE].get(key)
286 - str += key + ' => ' + val 169 + const item = node.value
287 - })
288 170
289 - if (didFirst || extras) { 171 + // dispose of the old one before overwriting
290 - str += '\n' 172 + // split out into 2 ifs for better coverage tracking
291 - } 173 + if (this[DISPOSE]) {
292 - str += '}' 174 + if (!this[NO_DISPOSE_ON_SET])
175 + this[DISPOSE](key, item.value)
176 + }
293 177
294 - return str 178 + item.now = now
295 -} 179 + item.maxAge = maxAge
180 + item.value = value
181 + this[LENGTH] += len - item.length
182 + item.length = len
183 + this.get(key)
184 + trim(this)
185 + return true
186 + }
296 187
297 -LRUCache.prototype.set = function (key, value, maxAge) { 188 + const hit = new Entry(key, value, len, now, maxAge)
298 - maxAge = maxAge || this[MAX_AGE]
299 189
300 - var now = maxAge ? Date.now() : 0 190 + // oversized objects fall out of cache automatically.
301 - var len = this[LENGTH_CALCULATOR](value, key) 191 + if (hit.length > this[MAX]) {
192 + if (this[DISPOSE])
193 + this[DISPOSE](key, value)
302 194
303 - if (this[CACHE].has(key)) {
304 - if (len > this[MAX]) {
305 - del(this, this[CACHE].get(key))
306 return false 195 return false
307 } 196 }
308 197
309 - var node = this[CACHE].get(key) 198 + this[LENGTH] += hit.length
310 - var item = node.value 199 + this[LRU_LIST].unshift(hit)
311 - 200 + this[CACHE].set(key, this[LRU_LIST].head)
312 - // dispose of the old one before overwriting
313 - // split out into 2 ifs for better coverage tracking
314 - if (this[DISPOSE]) {
315 - if (!this[NO_DISPOSE_ON_SET]) {
316 - this[DISPOSE](key, item.value)
317 - }
318 - }
319 -
320 - item.now = now
321 - item.maxAge = maxAge
322 - item.value = value
323 - this[LENGTH] += len - item.length
324 - item.length = len
325 - this.get(key)
326 trim(this) 201 trim(this)
327 return true 202 return true
328 } 203 }
329 204
330 - var hit = new Entry(key, value, len, now, maxAge) 205 + has (key) {
331 - 206 + if (!this[CACHE].has(key)) return false
332 - // oversized objects fall out of cache automatically. 207 + const hit = this[CACHE].get(key).value
333 - if (hit.length > this[MAX]) { 208 + return !isStale(this, hit)
334 - if (this[DISPOSE]) {
335 - this[DISPOSE](key, value)
336 - }
337 - return false
338 } 209 }
339 210
340 - this[LENGTH] += hit.length 211 + get (key) {
341 - this[LRU_LIST].unshift(hit) 212 + return get(this, key, true)
342 - this[CACHE].set(key, this[LRU_LIST].head)
343 - trim(this)
344 - return true
345 -}
346 -
347 -LRUCache.prototype.has = function (key) {
348 - if (!this[CACHE].has(key)) return false
349 - var hit = this[CACHE].get(key).value
350 - if (isStale(this, hit)) {
351 - return false
352 } 213 }
353 - return true
354 -}
355 214
356 -LRUCache.prototype.get = function (key) { 215 + peek (key) {
357 - return get(this, key, true) 216 + return get(this, key, false)
358 -} 217 + }
359 218
360 -LRUCache.prototype.peek = function (key) { 219 + pop () {
361 - return get(this, key, false) 220 + const node = this[LRU_LIST].tail
362 -} 221 + if (!node)
222 + return null
363 223
364 -LRUCache.prototype.pop = function () { 224 + del(this, node)
365 - var node = this[LRU_LIST].tail 225 + return node.value
366 - if (!node) return null 226 + }
367 - del(this, node)
368 - return node.value
369 -}
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)
249 + }
392 } 250 }
393 } 251 }
394 } 252 }
395 -}
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