├── .gitignore
├── README.hbs
├── README.md
├── lib
├── peer.js
└── symple.js
├── package-lock.json
├── package.json
├── server.js
└── symple.json
/.gitignore:
--------------------------------------------------------------------------------
1 | ~*
2 | *~
3 | bak
4 | node_modules
5 |
--------------------------------------------------------------------------------
/README.hbs:
--------------------------------------------------------------------------------
1 | # Symple Server
2 |
3 | The Symple Node.js server is a real time messaging server built on top of `socket.io` and `redis` for creating blazing fast messaging applications quickly and easily. Use cases include chat, sms, media streaming, and games that run in the web browser, desktop, or on mobile devices.
4 |
5 | ## What is Symple?
6 |
7 | Symple is an unrestrictive real time messaging and presence protocol that implements the minimum number of features required to build full fledged messaging applications with security, flexibility, performance and scalability in mind. These features include:
8 |
9 | * Session sharing with any backend (via Redis)
10 | * User rostering and presence
11 | * Media streaming (via WebRTC, [see demo](http://symple.sourcey.com))
12 | * Scoped messaging ie. direct, user and group scope
13 | * Real-time commands and events
14 | * Real-time forms
15 |
16 | ## Installation
17 |
18 | [Install Redis](http://redis.io/download) Note that Redis is optional, but required if you want to share secure sessions. If you're using Ubuntu just type:
19 |
20 | ```
21 | sudo apt-get install redis-server
22 | ```
23 |
24 | Install Symple from npm:
25 |
26 | ```bash
27 | npm install symple
28 |
29 | # use the --save flag to automatically add Symple to your package.json dependencies
30 | # npm install symple --save
31 | ```
32 |
33 | Done.
34 |
35 | ## Usage
36 |
37 | To get started straight away fire up the default server by typing:
38 |
39 | ```bash
40 | node server
41 |
42 | # or using npm
43 | # npm start
44 | ```
45 |
46 | The `server.js` file in the root directory of the repo provides an example of how to include the Symple server in your own code:
47 |
48 | ```bash
49 | // include Symple
50 | var Symple = require('symple');
51 |
52 | // instantiate the Symple server
53 | var sy = new Symple();
54 |
55 | // load a config file
56 | sy.loadConfig(__dirname + "/symple.json");
57 |
58 | // initialize the server
59 | sy.init();
60 |
61 | // access socket.io instance methods if required
62 | // sy.io.use(function(socket, next) { });
63 |
64 | // access HTTP/S server instance methods if required
65 | // sy.http ...
66 |
67 | // access Redis publish/subscribe client instance methods
68 | // sy.pub ...
69 | // sy.sub ...
70 |
71 | console.log('Symple server listening on port ' + sy.config.port);
72 | ```
73 |
74 | See the [configuration options](#configuration) below for a list of available options.
75 |
76 | Once the server is up and running you need a client to connect to it. There are a number of options here in the following languages:
77 |
78 | * JavaScript: https://github.com/sourcey/symple-client
79 | * Ruby: https://github.com/sourcey/symple-client-ruby
80 | * C++: https://github.com/sourcey/libsourcey/tree/master/src/symple
81 |
82 | ## Configuration
83 |
84 | To configure the server just modify `symple.json` as needed:
85 |
86 | ```
87 | {
88 | /*
89 | The port to listen on (default: 4500).
90 | If `process.env.PORT` is set, the env value will be used instead.
91 | Port 443 should always be used for SSL.
92 | */
93 | "port" : 4500, /* 443 */
94 |
95 | /*
96 | Session time-to-live in minutes (default: 15 minutes)
97 | This is the duration of time before sessions expire after the client disconnects.
98 | If set to `-1` the session will never expire.
99 | */
100 | "sessionTTL" : 15,
101 |
102 | /* Enable or disable authentication */
103 | "authentication" : true,
104 |
105 | /*
106 | Redis configuration
107 | Redis must be available if using `authentication = true`
108 | */
109 | "redis" : {
110 | "host" : "localhost",
111 | "port" : 6379,
112 | "password" : "redispwd"
113 | },
114 |
115 | /* SSL configuration */
116 | "ssl" : {
117 | "enabled" : false,
118 | "key" : "ssl/symple.key",
119 | "cert" : "ssl/symple.crt"
120 | }
121 | }
122 | ```
123 |
124 | ## API Reference
125 |
126 | {{optionSet "example-lang" "js" ~}}
127 | {{>main}}
128 |
129 | ## Contributing
130 |
131 | Contributions are always welcome :)
132 |
133 | 1. Fork it
134 | 2. Create your feature branch (`git checkout -b my-new-feature`)
135 | 3. Commit your changes (`git commit -am 'Add some feature'`)
136 | 4. Push to the branch (`git push origin my-new-feature`)
137 | 5. Create new Pull Request
138 |
139 | ## Contact
140 |
141 | For more information check out the Symple homepage: http://sourcey.com/symple/
142 | For bugs or issues please use the Github issue tracker: https://github.com/sourcey/symple-server-node/issues
143 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Symple Server
2 |
3 | The Symple Node.js server is a real time messaging server built on top of `socket.io` and `redis` for creating blazing fast messaging applications quickly and easily. Use cases include chat, sms, media streaming, and games that run in the web browser, desktop, or on mobile devices.
4 |
5 | ## What is Symple?
6 |
7 | Symple is an unrestrictive real time messaging and presence protocol that implements the minimum number of features required to build full fledged messaging applications with security, flexibility, performance and scalability in mind. These features include:
8 |
9 | * Session sharing with any backend (via Redis)
10 | * User rostering and presence
11 | * Media streaming (via WebRTC, [see demo](http://symple.sourcey.com))
12 | * Scoped messaging ie. direct, user and group scope
13 | * Real-time commands and events
14 | * Real-time forms
15 |
16 | ## Installation
17 |
18 | [Install Redis](http://redis.io/download) Note that Redis is optional, but required if you want to share secure sessions. If you're using Ubuntu just type:
19 |
20 | ```
21 | sudo apt-get install redis-server
22 | ```
23 |
24 | Install Symple from npm:
25 |
26 | ```bash
27 | npm install symple
28 |
29 | # use the --save flag to automatically add Symple to your package.json dependencies
30 | # npm install symple --save
31 | ```
32 |
33 | Done.
34 |
35 | ## Usage
36 |
37 | To get started straight away fire up the default server by typing:
38 |
39 | ```bash
40 | node server
41 |
42 | # or using npm
43 | # npm start
44 | ```
45 |
46 | The `server.js` file in the root directory of the repo provides an example of how to include the Symple server in your own code:
47 |
48 | ```bash
49 | // include Symple
50 | var Symple = require('symple');
51 |
52 | // instantiate the Symple server
53 | var sy = new Symple();
54 |
55 | // load a config file
56 | sy.loadConfig(__dirname + "/symple.json");
57 |
58 | // initialize the server
59 | sy.init();
60 |
61 | // access socket.io instance methods if required
62 | // sy.io.use(function(socket, next) { });
63 |
64 | // access HTTP/S server instance methods if required
65 | // sy.http ...
66 |
67 | // access Redis publish/subscribe client instance methods
68 | // sy.pub ...
69 | // sy.sub ...
70 |
71 | console.log('Symple server listening on port ' + sy.config.port);
72 | ```
73 |
74 | See the [configuration options](#configuration) below for a list of available options.
75 |
76 | Once the server is up and running you need a client to connect to it. There are a number of options here in the following languages:
77 |
78 | * JavaScript: https://github.com/sourcey/symple-client
79 | * Ruby: https://github.com/sourcey/symple-client-ruby
80 | * C++: https://github.com/sourcey/libsourcey/tree/master/src/symple
81 |
82 | ## Configuration
83 |
84 | To configure the server just modify `symple.json` as needed:
85 |
86 | ```
87 | {
88 | /*
89 | The port to listen on (default: 4500).
90 | If `process.env.PORT` is set, the env value will be used instead.
91 | Port 443 should always be used for SSL.
92 | */
93 | "port" : 4500, /* 443 */
94 |
95 | /*
96 | Session time-to-live in minutes (default: 15 minutes)
97 | This is the duration of time before sessions expire after the client disconnects.
98 | If set to `-1` the session will never expire.
99 | */
100 | "sessionTTL" : 15,
101 |
102 | /* Enable or disable authentication */
103 | "authentication" : true,
104 |
105 | /*
106 | Redis configuration
107 | Redis must be available if using `authentication = true`
108 | */
109 | "redis" : {
110 | "host" : "localhost",
111 | "port" : 6379,
112 | "password" : "redispwd"
113 | },
114 |
115 | /* SSL configuration */
116 | "ssl" : {
117 | "enabled" : false,
118 | "key" : "ssl/symple.key",
119 | "cert" : "ssl/symple.crt"
120 | }
121 | }
122 | ```
123 |
124 | ## API Reference
125 |
126 |
127 | ## Symple
128 | Symple server class.
129 |
130 | **Kind**: global class
131 | **Access:** public
132 |
133 | * [Symple](#Symple)
134 | * [new Symple(config)](#new_Symple_new)
135 | * [.loadConfig(filepath)](#Symple+loadConfig)
136 | * [.init()](#Symple+init)
137 | * [.shutdown()](#Symple+shutdown)
138 | * [.broadcast(socket, message)](#Symple+broadcast)
139 | * [.getSession(token, fn)](#Symple+getSession)
140 | * [.touchSession(token, fn)](#Symple+touchSession)
141 | * [.parseAddress(str)](#Symple+parseAddress)
142 |
143 |
144 | ### new Symple(config)
145 |
146 | | Param | Type | Description |
147 | | --- | --- | --- |
148 | | config | Object
| optional confguration object (see config.json) |
149 | | config.port | string
| the port to listen on |
150 | | config.redis | Object
| redis configuration |
151 | | config.ssl | Object
| ssl configuration |
152 | | config.sessionTTL | number
| session timeout value |
153 | | config.authentication | boolean
| enable/disable authentication |
154 |
155 |
156 | ### symple.loadConfig(filepath)
157 | Load configuration from a file.
158 |
159 | **Kind**: instance method of [Symple](#Symple)
160 | **Access:** public
161 |
162 | | Param | Type | Description |
163 | | --- | --- | --- |
164 | | filepath | string
| absolute path to config.json |
165 |
166 |
167 | ### symple.init()
168 | Initialize the Symple server.
169 |
170 | **Kind**: instance method of [Symple](#Symple)
171 | **Access:** public
172 |
173 | ### symple.shutdown()
174 | Shutdown the Symple server.
175 |
176 | **Kind**: instance method of [Symple](#Symple)
177 | **Access:** public
178 |
179 | ### symple.broadcast(socket, message)
180 | Broadcast a message over the given socket.
181 |
182 | **Kind**: instance method of [Symple](#Symple)
183 | **Access:** public
184 |
185 | | Param | Type | Description |
186 | | --- | --- | --- |
187 | | socket | Socket
| client socket |
188 | | message | Object
| message to send |
189 |
190 |
191 | ### symple.getSession(token, fn)
192 | Get a peer session by it's token.
193 |
194 | **Kind**: instance method of [Symple](#Symple)
195 | **Access:** public
196 |
197 | | Param | Type | Description |
198 | | --- | --- | --- |
199 | | token | Object
| address string |
200 | | fn | function
| callback function |
201 |
202 |
203 | ### symple.touchSession(token, fn)
204 | Touch a peer session by it's token and extend
205 | it's lifetime by (config.sessionTTL) minutes.
206 |
207 | **Kind**: instance method of [Symple](#Symple)
208 | **Access:** public
209 |
210 | | Param | Type | Description |
211 | | --- | --- | --- |
212 | | token | Object
| address string |
213 | | fn | function
| callback function |
214 |
215 |
216 | ### symple.parseAddress(str)
217 | Parse a peer address with the format: user@group/id
218 |
219 | **Kind**: instance method of [Symple](#Symple)
220 | **Access:** public
221 |
222 | | Param | Type | Description |
223 | | --- | --- | --- |
224 | | str | Object
| address string |
225 |
226 |
227 | ## Contributing
228 |
229 | Contributions are always welcome :)
230 |
231 | 1. Fork it
232 | 2. Create your feature branch (`git checkout -b my-new-feature`)
233 | 3. Commit your changes (`git commit -am 'Add some feature'`)
234 | 4. Push to the branch (`git push origin my-new-feature`)
235 | 5. Create new Pull Request
236 |
237 | ## Contact
238 |
239 | For more information check out the Symple homepage: http://sourcey.com/symple/
240 | For bugs or issues please use the Github issue tracker: https://github.com/sourcey/symple-server-node/issues
241 |
--------------------------------------------------------------------------------
/lib/peer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @class Peer
3 | * The Peer model is an abritrary data store that generally consists of:
4 | * - id the peer session id
5 | * - online the peer online status
6 | * - group the peer group
7 | * - access the peer access level [1 - 10]
8 | * - user the peer user name
9 | * - user_id the peer user id
10 | *
11 | * @param {Object} args - peer data object
12 | */
13 |
14 | var Peer = function(args) {
15 | this.read(args);
16 | }
17 |
18 |
19 | Peer.prototype.read = function(from) {
20 | for (var key in from) {
21 | if (from.hasOwnProperty(key))
22 | this[key] = from[key];
23 | }
24 | }
25 |
26 |
27 | Peer.prototype.write = function(to) {
28 | for (var key in this) {
29 | if (this.hasOwnProperty(key))
30 | to[key] = this[key];
31 | }
32 | }
33 |
34 |
35 | Peer.prototype.toPresence = function(p) {
36 | if (typeof p !== 'object')
37 | p = {};
38 | p.type = 'presence';
39 | p.data = this.toPeer(p.data);
40 | if (!p.from)
41 | p.from = this.address();
42 |
43 | // Remove sensitive data
44 | if (typeof p.data.token === 'string')
45 | delete p.data.token;
46 |
47 | // Allow the peer to change name if the input
48 | // object name doesn't match the current name
49 | if (typeof p.name === 'string')
50 | this.name = p.name;
51 |
52 | return p;
53 | }
54 |
55 |
56 | Peer.prototype.toPeer = function(p) {
57 | if (typeof p !== 'object')
58 | p = {};
59 | this.write(p);
60 | return p;
61 | }
62 |
63 |
64 | Peer.prototype.address = function() {
65 | return this.user + "|" + this.id; // + "@" + this.group
66 | }
67 |
68 |
69 | Peer.prototype.valid = function() {
70 | return this.id && this.user; // && this.group;
71 | }
72 |
73 | /**
74 | * Module exports.
75 | */
76 |
77 | module.exports = Peer;
78 |
--------------------------------------------------------------------------------
/lib/symple.js:
--------------------------------------------------------------------------------
1 | const http = require('http')
2 | , https = require('https')
3 | , fs = require('fs')
4 | , Peer = require('./peer')
5 | , debug = require('debug')('symple:server')
6 | , { Server } = require('socket.io')
7 | , { createAdapter } = require('@socket.io/redis-adapter')
8 | , { createClient } = require('redis');
9 |
10 |
11 | /**
12 | * @class
13 | * Symple server class.
14 | *
15 | * @param {Object} config - optional confguration object (see config.json)
16 | * @param {string} config.port - the port to listen on
17 | * @param {Object} config.redis - redis configuration
18 | * @param {Object} config.ssl - ssl configuration
19 | * @param {number} config.sessionTTL - session timeout value
20 | * @param {boolean} config.authentication - enable/disable authentication
21 | * @public
22 | */
23 |
24 | function Symple(config) {
25 | this.config = config || {};
26 | // this.timer = undefined;
27 | }
28 |
29 |
30 | /**
31 | * Load configuration from a file.
32 | *
33 | * @param {string} filepath - absolute path to config.json
34 | * @public
35 | */
36 |
37 | Symple.prototype.loadConfig = function(filepath) {
38 | this.config = JSON.parse(
39 | fs.readFileSync(filepath).toString().replace( //
40 | new RegExp("\\/\\*(.|\\r|\\n)*?\\*\\/", "g"),
41 | "" // strip out comments
42 | )
43 | );
44 | }
45 |
46 |
47 | /**
48 | * Initialize the Symple server.
49 | *
50 | * @public
51 | */
52 |
53 | Symple.prototype.init = function() {
54 | this.initHTTP();
55 | this.initSocketIO();
56 | this.initRedis();
57 | }
58 |
59 |
60 | /**
61 | * Shutdown the Symple server.
62 | *
63 | * @public
64 | */
65 |
66 | Symple.prototype.shutdown = function() {
67 | // if (this.timer) {
68 | // clearInterval(this.timer);
69 | // }
70 | if (this.io)
71 | this.io.close();
72 | if (this.server)
73 | this.server.destroy();
74 | if (this.redis)
75 | this.redis.quit();
76 | if (this.pub)
77 | this.pub.quit();
78 | if (this.sub)
79 | this.sub.quit();
80 | }
81 |
82 |
83 | /**
84 | * Initialize HTTP server if required.
85 | *
86 | * @private
87 | */
88 |
89 | Symple.prototype.initHTTP = function() {
90 | // Create the HTTP/S server if the instance not already set
91 | if (!this.server) {
92 | this.server = (this.config.ssl && this.config.ssl.enabled ?
93 | // HTTPS
94 | https.createServer({
95 | key: fs.readFileSync(this.config.ssl.key)
96 | , cert: fs.readFileSync(this.config.ssl.cert)
97 | }) :
98 | // HTTP
99 | http.createServer());
100 |
101 | this.server.listen({
102 | port: process.env.PORT || this.config.port,
103 | // backlog: 511
104 | });
105 |
106 | // // AWS ALB keepAlive is set to 60 seconds, we need to increase the default KeepAlive timeout
107 | // // of our node server
108 | // this.server.keepAliveTimeout = 65000; // Ensure all inactive connections are terminated by the ALB, by setting this a few seconds higher than the ALB idle timeout
109 | // this.server.headersTimeout = 66000; // Ensure the headersTimeout is set higher than the keepAliveTimeout due to this nodejs regression bug: https://github.com/nodejs/node/issues/27363
110 | }
111 | }
112 |
113 |
114 | /**
115 | * Initialize the Socket.IO server.
116 | *
117 | * @private
118 | */
119 |
120 | Symple.prototype.initSocketIO = function() {
121 | const self = this;
122 |
123 | // Bind the Socket.IO server with the HTTP server
124 | const opts = {
125 | // allowEIO3: true
126 | };
127 | if (this.config.cors) {
128 | opts.cors = this.config.cors
129 | };
130 |
131 | this.io = new Server(this.server, opts);
132 |
133 | // Authentication middleware
134 | this.io.use((socket, next) => {
135 | self.authorize(socket, socket.handshake.auth, function(status, message) {
136 | if (status === 200) {
137 | next()
138 | } else {
139 | next(new Error(message));
140 | }
141 | })
142 | });
143 |
144 | // Handle socket connections
145 | this.io.on('connection', function(socket) {
146 | self.onConnection(socket);
147 | });
148 | }
149 |
150 |
151 | /**
152 | * Initialize the Redis adapter if required.
153 | *
154 | * @private
155 | */
156 |
157 | Symple.prototype.initRedis = function() {
158 | const self = this;
159 |
160 | if (this.config.redis && !this.redis) {
161 | this.redis = createClient({ url: this.config.redis });
162 | this.redis.on('error', this.onRedisError);
163 | this.redis.connect();
164 | }
165 |
166 | // if (this.config.redis && !this.pub && !this.sub) {
167 | if (this.config.redis) {
168 | this.initRedisAdapter();
169 |
170 | // Touch sessions every `sessionTTL / 0.8` minutes to prevent them from expiring.
171 | // if (this.config.sessionTTL > 0) {
172 | // this.timer = setInterval(function () {
173 | // debug('touching sessions');
174 | // for (const i = 0; i < self.io.sockets.sockets.length; i++) {
175 | // const socket = self.io.sockets.sockets[i];
176 | // self.touchSession(socket.token, function(err, res) {
177 | // debug(socket.id, 'touching session:', socket.token, !!res);
178 | // });
179 | // }
180 | // }, (this.config.sessionTTL / 0.8) * 60000);
181 | // }
182 | }
183 | }
184 |
185 | Symple.prototype.initRedisAdapter = function() {
186 | const self = this;
187 |
188 | this.pub = createClient({ url: this.config.redis });
189 | this.sub = this.pub.duplicate();
190 |
191 | this.pub.on('error', this.onRedisError);
192 | this.sub.on('error', this.onRedisError);
193 |
194 | Promise.all([this.pub.connect(), this.sub.connect()]).then(() => {
195 | self.io.adapter(createAdapter(self.pub, self.sub, { key: 'symple' }));
196 | });
197 | }
198 |
199 |
200 | /**
201 | * Called upon client socket connected.
202 | *
203 | * @param {Socket} socket - client socket
204 | * @private
205 | */
206 |
207 | Symple.prototype.onConnection = function(socket) {
208 | debug(socket.id, 'connection');
209 | const self = this;
210 |
211 | // Message
212 | socket.on('message', function(m, ack) {
213 | // debug('got message', m)
214 | if (m) {
215 | // Build presence from server side session data
216 | // if (m.type == 'presence')
217 | // socket.peer.toPresence(m);
218 | self.broadcast(socket, m);
219 | self.respond(ack, 200);
220 | }
221 | });
222 |
223 | // Dynmic rooms
224 | // TODO: Redis permission checking and Room validation
225 | if (self.config.dynamicRooms) {
226 |
227 | // Join Room
228 | socket.on('join', function(room, ack) {
229 | debug(socket.id, 'joining room', room);
230 | socket.join(room, function(err) {
231 | if (err) {
232 | debug(socket.id, 'cannot join room', err);
233 | self.respond(ack, 404, 'Cannot join room: ' + err);
234 | }
235 | else {
236 | self.respond(ack, 200, 'Joined room: ' + room);
237 | }
238 | });
239 | });
240 |
241 | // Leave Room
242 | socket.on('leave', function(room, ack) {
243 | debug(socket.id, 'leaving room', room);
244 | socket.leave(room, function(err) {
245 | if (err) {
246 | debug(socket.id, 'cannot leave room', err);
247 | self.respond(ack, 404, 'Cannot leave room: ' + err);
248 | }
249 | else {
250 | self.respond(ack, 200, 'Left room: ' + room);
251 | }
252 | });
253 | });
254 | }
255 |
256 | // Peers
257 | // socket.on('peers', function(ack) {
258 | // self.respond(ack, 200, '', self.peers(false));
259 | // });
260 |
261 | // Handle socket disconnection
262 | socket.on('disconnect', function() {
263 | self.onDisconnect(socket);
264 | });
265 | }
266 |
267 |
268 | /**
269 | * Called upon client socket disconnect.
270 | *
271 | * @param {Socket} socket - client socket
272 | * @private
273 | */
274 |
275 | Symple.prototype.onDisconnect = function(socket) {
276 | debug(socket.id, 'is disconnecting');
277 |
278 | if (socket.peer) {
279 |
280 | // Broadcast offline presence
281 | if (socket.peer.online) {
282 | socket.peer.online = false;
283 | this.broadcast(socket, socket.peer.toPresence());
284 | }
285 |
286 | // Leave rooms
287 | socket.leave(socket.peer.user); // leave user channel
288 | }
289 | }
290 |
291 |
292 | /**
293 | * Called to authorize a new connection.
294 | *
295 | * @param {Socket} socket - client socket
296 | * @param {Object} data - arbitrary peer object
297 | * @param {function} fn - callback function
298 | * @private
299 | */
300 |
301 | Symple.prototype.authorize = function(socket, auth, fn) {
302 | const self = this;
303 |
304 | // Authenticated access
305 | if (self.config.authentication) {
306 | if (!auth.user || !auth.token) {
307 | return fn(401, 'Authentication failed: Missing user or token param');
308 | }
309 |
310 | // Retreive the session from Redis
311 | debug(socket.id, 'authenticating', auth);
312 | self.getSession(auth.token, function(err, session) {
313 | if (err) {
314 | return fn(401, 'Authentication failed: ' + err);
315 | }
316 | else {
317 | debug(socket.id, 'authentication success');
318 | // socket.token = auth.token;
319 | self.authorizeValidPeer(socket, self.extend(auth, session), fn);
320 | }
321 | });
322 | }
323 |
324 | // Anonymous access
325 | else {
326 | if (!auth.user) {
327 | return fn(401, 'Authentication failed: Missing user param');
328 | }
329 |
330 | this.authorizeValidPeer(socket, auth, fn);
331 | }
332 | }
333 |
334 |
335 | /**
336 | * Create a valid peer object or return null.
337 | *
338 | * @param {Socket} socket - client socket
339 | * @param {Object} data - arbitrary peer object
340 | * @param {function} fn - callback function
341 | * @private
342 | */
343 |
344 | Symple.prototype.authorizeValidPeer = function(socket, data, fn) {
345 | const peer = new Peer(this.extend(data, {
346 | id: socket.id,
347 | online: true,
348 | name: (data.name || data.user),
349 | host: (socket.handshake.headers['x-real-ip']
350 | || socket.handshake.headers['x-forwarded-for']
351 | || socket.handshake.address)
352 | }));
353 |
354 | if (peer.valid()) {
355 | // This allows broadcasting to all connected clients at user scope
356 | socket.join(peer.user);
357 | // socket.join('group-' + peer.group); // Join group channel
358 | socket.peer = peer;
359 |
360 | debug(socket.id, 'authentication success', peer);
361 | this.onAuthorize(socket);
362 | return fn(200, 'Welcome ' + peer.name);
363 | }
364 | else {
365 | debug(socket.id, 'authentication failed: invalid peer object', peer);
366 | return fn(401, 'Invalid peer session');
367 | }
368 | }
369 |
370 |
371 | /**
372 | * Create a valid peer object or return null.
373 | *
374 | * @param {Socket} socket - client socket
375 | * @param {Peer} peer - arbitrary peer object
376 | * @private
377 | */
378 |
379 | Symple.prototype.onAuthorize = function(socket, peer) {
380 | // nothing to do
381 | }
382 |
383 |
384 | Symple.prototype.onRedisError = function(err) {
385 | console.log('Redis Client Error', err)
386 | }
387 |
388 |
389 | /**
390 | * Broadcast a message over the given socket.
391 | *
392 | * @param {Socket} socket - client socket
393 | * @param {Object} message - message to send
394 | * @public
395 | */
396 |
397 | Symple.prototype.broadcast = function(socket, message) {
398 | if (!message || typeof message !== 'object' || !message.from) {
399 | debug(socket.id, 'dropping invalid message:', message);
400 | return;
401 | }
402 |
403 | debug(socket.id, 'broadcasting message:', message);
404 |
405 | // Get an destination address object for routing
406 | const to = message.to;
407 | if (typeof to === 'undefined') {
408 | if (this.config.dynamicRooms) {
409 | // room scope
410 | socket.rooms.forEach(function(room) {
411 | if (room !== socket.id && room !== socket.peer.user) {
412 | socket.broadcast.to(room).emit('message', message);
413 | }
414 | });
415 | } else {
416 | // global scope
417 | socket.broadcast.emit('message', message);
418 | }
419 | }
420 | else if (typeof to === 'string') {
421 | const addr = this.parseAddress(to);
422 | socket.broadcast.to(addr.user || addr.id).emit('message', message); //.except(this.unauthorizedIDs())
423 | }
424 | else if (Array.isArray(to)) {
425 | // direct multi room scope
426 | for (let room in to) {
427 | socket.broadcast.to(to[room]).emit('message', message);
428 | };
429 | }
430 | else {
431 | debug(socket.id, 'cannot route message', message);
432 | }
433 | }
434 |
435 |
436 | Symple.prototype.respond = function(ack, status, message, data) {
437 | if (typeof ack !== 'function')
438 | return;
439 | const res = {}
440 | res.type = 'response';
441 | res.status = status;
442 | if (message)
443 | res.message = message;
444 | if (data)
445 | res.data = data.data || data;
446 | debug('responding', res);
447 | ack(res);
448 | }
449 |
450 |
451 | /**
452 | * Get a peer session by it's token.
453 | *
454 | * @param {Object} token - address string
455 | * @param {function} fn - callback function
456 | * @public
457 | */
458 |
459 | Symple.prototype.getSession = function(token, fn) {
460 | this.redis.get('symple:session:' + token).then((value) => {
461 | debug('symple session', token, value);
462 | if (value === null) {
463 | fn('No session', null);
464 | } else {
465 | const session = JSON.parse(value);
466 | if (typeof session !== 'object') {
467 | return fn('Session must be an object', null);
468 | } else {
469 | fn(null, session);
470 | }
471 | }
472 | }).catch((error) => {
473 | fn('Redis error: ' + error.message, null);
474 | });
475 | }
476 |
477 |
478 | /**
479 | * Touch a peer session by it's token and extend
480 | * it's lifetime by (config.sessionTTL) minutes.
481 | *
482 | * @param {Object} token - address string
483 | * @param {function} fn - callback function
484 | * @public
485 | */
486 |
487 | Symple.prototype.touchSession = function(token, fn) {
488 | if (this.config.sessionTTL == -1)
489 | return;
490 |
491 | const expiry = parseInt((+new Date)/1000) + (this.config.sessionTT * 60);
492 | this.pub.expireat('symple:session:' + token, expiry, fn);
493 | }
494 |
495 |
496 | /**
497 | * Parse a peer address with the format: user|id
498 | *
499 | * @param {Object} str - address string
500 | * @public
501 | */
502 |
503 | Symple.prototype.parseAddress = function(str) {
504 | const addr = {}
505 | arr = str.split('|')
506 |
507 | if (arr.length < 2) // no id
508 | addr.user = arr[0];
509 | else { // has id
510 | addr.user = arr[0];
511 | addr.id = arr[1];
512 | }
513 |
514 | return addr;
515 | }
516 |
517 |
518 | Symple.prototype.getSocketsByRoom = function(nsp, room) {
519 | const users = [];
520 | for (let id in this.io.of(nsp).adapter.rooms[room]) {
521 | users.push(this.io.of(nsp).adapter.nsp.connected[id]);
522 | };
523 | return users;
524 | };
525 |
526 |
527 | /**
528 | * Extend an object with another object.
529 | *
530 | * @param {Object} origin - target object
531 | * @param {Object} add - source object
532 | * @private
533 | */
534 |
535 | Symple.prototype.extend = function(origin, add) {
536 | // Don't do anything if add isn't an object
537 | if (!add || typeof add !== 'object') return origin;
538 |
539 | const keys = Object.keys(add);
540 | let i = keys.length;
541 | while (i--) {
542 | origin[keys[i]] = add[keys[i]];
543 | }
544 | return origin;
545 | }
546 |
547 |
548 | /**
549 | * Module exports.
550 | */
551 |
552 | module.exports = Symple;
553 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "symple",
3 | "version": "2.1.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "symple",
9 | "version": "2.1.1",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@socket.io/redis-adapter": "^8.3.0",
13 | "debug": "4.3.4",
14 | "notepack.io": "~2.2.0",
15 | "redis": "4.6.13",
16 | "socket.io": "^4.7.5",
17 | "socket.io-adapter": "~2.5.2",
18 | "uid2": "0.0.3"
19 | },
20 | "devDependencies": {
21 | "jsdoc-to-markdown": "^7.1.1"
22 | }
23 | },
24 | "node_modules/@babel/parser": {
25 | "version": "7.17.8",
26 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz",
27 | "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==",
28 | "dev": true,
29 | "bin": {
30 | "parser": "bin/babel-parser.js"
31 | },
32 | "engines": {
33 | "node": ">=6.0.0"
34 | }
35 | },
36 | "node_modules/@redis/bloom": {
37 | "version": "1.2.0",
38 | "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
39 | "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
40 | "peerDependencies": {
41 | "@redis/client": "^1.0.0"
42 | }
43 | },
44 | "node_modules/@redis/client": {
45 | "version": "1.5.14",
46 | "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
47 | "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
48 | "dependencies": {
49 | "cluster-key-slot": "1.1.2",
50 | "generic-pool": "3.9.0",
51 | "yallist": "4.0.0"
52 | },
53 | "engines": {
54 | "node": ">=14"
55 | }
56 | },
57 | "node_modules/@redis/graph": {
58 | "version": "1.1.1",
59 | "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
60 | "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
61 | "peerDependencies": {
62 | "@redis/client": "^1.0.0"
63 | }
64 | },
65 | "node_modules/@redis/json": {
66 | "version": "1.0.6",
67 | "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
68 | "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
69 | "peerDependencies": {
70 | "@redis/client": "^1.0.0"
71 | }
72 | },
73 | "node_modules/@redis/search": {
74 | "version": "1.1.6",
75 | "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
76 | "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
77 | "peerDependencies": {
78 | "@redis/client": "^1.0.0"
79 | }
80 | },
81 | "node_modules/@redis/time-series": {
82 | "version": "1.0.5",
83 | "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
84 | "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
85 | "peerDependencies": {
86 | "@redis/client": "^1.0.0"
87 | }
88 | },
89 | "node_modules/@socket.io/component-emitter": {
90 | "version": "3.1.2",
91 | "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
92 | "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
93 | },
94 | "node_modules/@socket.io/redis-adapter": {
95 | "version": "8.3.0",
96 | "resolved": "https://registry.npmjs.org/@socket.io/redis-adapter/-/redis-adapter-8.3.0.tgz",
97 | "integrity": "sha512-ly0cra+48hDmChxmIpnESKrc94LjRL80TEmZVscuQ/WWkRP81nNj8W8cCGMqbI4L6NCuAaPRSzZF1a9GlAxxnA==",
98 | "dependencies": {
99 | "debug": "~4.3.1",
100 | "notepack.io": "~3.0.1",
101 | "uid2": "1.0.0"
102 | },
103 | "engines": {
104 | "node": ">=10.0.0"
105 | },
106 | "peerDependencies": {
107 | "socket.io-adapter": "^2.5.4"
108 | }
109 | },
110 | "node_modules/@socket.io/redis-adapter/node_modules/notepack.io": {
111 | "version": "3.0.1",
112 | "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-3.0.1.tgz",
113 | "integrity": "sha512-TKC/8zH5pXIAMVQio2TvVDTtPRX+DJPHDqjRbxogtFiByHyzKmy96RA0JtCQJ+WouyyL4A10xomQzgbUT+1jCg=="
114 | },
115 | "node_modules/@socket.io/redis-adapter/node_modules/uid2": {
116 | "version": "1.0.0",
117 | "resolved": "https://registry.npmjs.org/uid2/-/uid2-1.0.0.tgz",
118 | "integrity": "sha512-+I6aJUv63YAcY9n4mQreLUt0d4lvwkkopDNmpomkAUz0fAkEMV9pRWxN0EjhW1YfRhcuyHg2v3mwddCDW1+LFQ==",
119 | "engines": {
120 | "node": ">= 4.0.0"
121 | }
122 | },
123 | "node_modules/@types/cookie": {
124 | "version": "0.4.1",
125 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
126 | "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
127 | },
128 | "node_modules/@types/cors": {
129 | "version": "2.8.17",
130 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
131 | "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
132 | "dependencies": {
133 | "@types/node": "*"
134 | }
135 | },
136 | "node_modules/@types/linkify-it": {
137 | "version": "3.0.2",
138 | "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
139 | "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
140 | "dev": true
141 | },
142 | "node_modules/@types/markdown-it": {
143 | "version": "12.2.3",
144 | "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
145 | "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
146 | "dev": true,
147 | "dependencies": {
148 | "@types/linkify-it": "*",
149 | "@types/mdurl": "*"
150 | }
151 | },
152 | "node_modules/@types/mdurl": {
153 | "version": "1.0.2",
154 | "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
155 | "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
156 | "dev": true
157 | },
158 | "node_modules/@types/node": {
159 | "version": "20.12.11",
160 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz",
161 | "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==",
162 | "dependencies": {
163 | "undici-types": "~5.26.4"
164 | }
165 | },
166 | "node_modules/accepts": {
167 | "version": "1.3.8",
168 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
169 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
170 | "dependencies": {
171 | "mime-types": "~2.1.34",
172 | "negotiator": "0.6.3"
173 | },
174 | "engines": {
175 | "node": ">= 0.6"
176 | }
177 | },
178 | "node_modules/ansi-escape-sequences": {
179 | "version": "4.1.0",
180 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
181 | "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
182 | "dev": true,
183 | "dependencies": {
184 | "array-back": "^3.0.1"
185 | },
186 | "engines": {
187 | "node": ">=8.0.0"
188 | }
189 | },
190 | "node_modules/ansi-escape-sequences/node_modules/array-back": {
191 | "version": "3.1.0",
192 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
193 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
194 | "dev": true,
195 | "engines": {
196 | "node": ">=6"
197 | }
198 | },
199 | "node_modules/argparse": {
200 | "version": "2.0.1",
201 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
202 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
203 | "dev": true
204 | },
205 | "node_modules/array-back": {
206 | "version": "6.2.2",
207 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
208 | "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
209 | "dev": true,
210 | "engines": {
211 | "node": ">=12.17"
212 | }
213 | },
214 | "node_modules/balanced-match": {
215 | "version": "1.0.2",
216 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
217 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
218 | "dev": true
219 | },
220 | "node_modules/base64id": {
221 | "version": "2.0.0",
222 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
223 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
224 | "engines": {
225 | "node": "^4.5.0 || >= 5.9"
226 | }
227 | },
228 | "node_modules/bluebird": {
229 | "version": "3.7.2",
230 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
231 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
232 | "dev": true
233 | },
234 | "node_modules/brace-expansion": {
235 | "version": "1.1.11",
236 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
237 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
238 | "dev": true,
239 | "dependencies": {
240 | "balanced-match": "^1.0.0",
241 | "concat-map": "0.0.1"
242 | }
243 | },
244 | "node_modules/cache-point": {
245 | "version": "2.0.0",
246 | "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz",
247 | "integrity": "sha512-4gkeHlFpSKgm3vm2gJN5sPqfmijYRFYCQ6tv5cLw0xVmT6r1z1vd4FNnpuOREco3cBs1G709sZ72LdgddKvL5w==",
248 | "dev": true,
249 | "dependencies": {
250 | "array-back": "^4.0.1",
251 | "fs-then-native": "^2.0.0",
252 | "mkdirp2": "^1.0.4"
253 | },
254 | "engines": {
255 | "node": ">=8"
256 | }
257 | },
258 | "node_modules/cache-point/node_modules/array-back": {
259 | "version": "4.0.2",
260 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
261 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
262 | "dev": true,
263 | "engines": {
264 | "node": ">=8"
265 | }
266 | },
267 | "node_modules/catharsis": {
268 | "version": "0.9.0",
269 | "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
270 | "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
271 | "dev": true,
272 | "dependencies": {
273 | "lodash": "^4.17.15"
274 | },
275 | "engines": {
276 | "node": ">= 10"
277 | }
278 | },
279 | "node_modules/cluster-key-slot": {
280 | "version": "1.1.2",
281 | "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
282 | "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
283 | "engines": {
284 | "node": ">=0.10.0"
285 | }
286 | },
287 | "node_modules/collect-all": {
288 | "version": "1.0.4",
289 | "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz",
290 | "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==",
291 | "dev": true,
292 | "dependencies": {
293 | "stream-connect": "^1.0.2",
294 | "stream-via": "^1.0.4"
295 | },
296 | "engines": {
297 | "node": ">=0.10.0"
298 | }
299 | },
300 | "node_modules/command-line-args": {
301 | "version": "5.2.1",
302 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
303 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
304 | "dev": true,
305 | "dependencies": {
306 | "array-back": "^3.1.0",
307 | "find-replace": "^3.0.0",
308 | "lodash.camelcase": "^4.3.0",
309 | "typical": "^4.0.0"
310 | },
311 | "engines": {
312 | "node": ">=4.0.0"
313 | }
314 | },
315 | "node_modules/command-line-args/node_modules/array-back": {
316 | "version": "3.1.0",
317 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
318 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
319 | "dev": true,
320 | "engines": {
321 | "node": ">=6"
322 | }
323 | },
324 | "node_modules/command-line-args/node_modules/typical": {
325 | "version": "4.0.0",
326 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
327 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
328 | "dev": true,
329 | "engines": {
330 | "node": ">=8"
331 | }
332 | },
333 | "node_modules/command-line-tool": {
334 | "version": "0.8.0",
335 | "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
336 | "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
337 | "dev": true,
338 | "dependencies": {
339 | "ansi-escape-sequences": "^4.0.0",
340 | "array-back": "^2.0.0",
341 | "command-line-args": "^5.0.0",
342 | "command-line-usage": "^4.1.0",
343 | "typical": "^2.6.1"
344 | },
345 | "engines": {
346 | "node": ">=4.0.0"
347 | }
348 | },
349 | "node_modules/command-line-tool/node_modules/array-back": {
350 | "version": "2.0.0",
351 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
352 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
353 | "dev": true,
354 | "dependencies": {
355 | "typical": "^2.6.1"
356 | },
357 | "engines": {
358 | "node": ">=4"
359 | }
360 | },
361 | "node_modules/command-line-usage": {
362 | "version": "4.1.0",
363 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
364 | "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
365 | "dev": true,
366 | "dependencies": {
367 | "ansi-escape-sequences": "^4.0.0",
368 | "array-back": "^2.0.0",
369 | "table-layout": "^0.4.2",
370 | "typical": "^2.6.1"
371 | },
372 | "engines": {
373 | "node": ">=4.0.0"
374 | }
375 | },
376 | "node_modules/command-line-usage/node_modules/array-back": {
377 | "version": "2.0.0",
378 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
379 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
380 | "dev": true,
381 | "dependencies": {
382 | "typical": "^2.6.1"
383 | },
384 | "engines": {
385 | "node": ">=4"
386 | }
387 | },
388 | "node_modules/common-sequence": {
389 | "version": "2.0.2",
390 | "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz",
391 | "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==",
392 | "dev": true,
393 | "engines": {
394 | "node": ">=8"
395 | }
396 | },
397 | "node_modules/concat-map": {
398 | "version": "0.0.1",
399 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
400 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
401 | "dev": true
402 | },
403 | "node_modules/config-master": {
404 | "version": "3.1.0",
405 | "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
406 | "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
407 | "dev": true,
408 | "dependencies": {
409 | "walk-back": "^2.0.1"
410 | }
411 | },
412 | "node_modules/config-master/node_modules/walk-back": {
413 | "version": "2.0.1",
414 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
415 | "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
416 | "dev": true,
417 | "engines": {
418 | "node": ">=0.10.0"
419 | }
420 | },
421 | "node_modules/cookie": {
422 | "version": "0.4.2",
423 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
424 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
425 | "engines": {
426 | "node": ">= 0.6"
427 | }
428 | },
429 | "node_modules/cors": {
430 | "version": "2.8.5",
431 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
432 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
433 | "dependencies": {
434 | "object-assign": "^4",
435 | "vary": "^1"
436 | },
437 | "engines": {
438 | "node": ">= 0.10"
439 | }
440 | },
441 | "node_modules/debug": {
442 | "version": "4.3.4",
443 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
444 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
445 | "dependencies": {
446 | "ms": "2.1.2"
447 | },
448 | "engines": {
449 | "node": ">=6.0"
450 | },
451 | "peerDependenciesMeta": {
452 | "supports-color": {
453 | "optional": true
454 | }
455 | }
456 | },
457 | "node_modules/deep-extend": {
458 | "version": "0.6.0",
459 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
460 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
461 | "dev": true,
462 | "engines": {
463 | "node": ">=4.0.0"
464 | }
465 | },
466 | "node_modules/dmd": {
467 | "version": "6.1.0",
468 | "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.1.0.tgz",
469 | "integrity": "sha512-0zQIJ873gay1scCTFZvHPWM9mVJBnaylB2NQDI8O9u8O32m00Jb6uxDKexZm8hjTRM7RiWe0FJ32pExHoXdwoQ==",
470 | "dev": true,
471 | "dependencies": {
472 | "array-back": "^6.2.2",
473 | "cache-point": "^2.0.0",
474 | "common-sequence": "^2.0.2",
475 | "file-set": "^4.0.2",
476 | "handlebars": "^4.7.7",
477 | "marked": "^4.0.12",
478 | "object-get": "^2.1.1",
479 | "reduce-flatten": "^3.0.1",
480 | "reduce-unique": "^2.0.1",
481 | "reduce-without": "^1.0.1",
482 | "test-value": "^3.0.0",
483 | "walk-back": "^5.1.0"
484 | },
485 | "engines": {
486 | "node": ">=12"
487 | }
488 | },
489 | "node_modules/dmd/node_modules/reduce-flatten": {
490 | "version": "3.0.1",
491 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz",
492 | "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==",
493 | "dev": true,
494 | "engines": {
495 | "node": ">=8"
496 | }
497 | },
498 | "node_modules/engine.io": {
499 | "version": "6.5.4",
500 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
501 | "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
502 | "dependencies": {
503 | "@types/cookie": "^0.4.1",
504 | "@types/cors": "^2.8.12",
505 | "@types/node": ">=10.0.0",
506 | "accepts": "~1.3.4",
507 | "base64id": "2.0.0",
508 | "cookie": "~0.4.1",
509 | "cors": "~2.8.5",
510 | "debug": "~4.3.1",
511 | "engine.io-parser": "~5.2.1",
512 | "ws": "~8.11.0"
513 | },
514 | "engines": {
515 | "node": ">=10.2.0"
516 | }
517 | },
518 | "node_modules/engine.io-parser": {
519 | "version": "5.2.2",
520 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz",
521 | "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==",
522 | "engines": {
523 | "node": ">=10.0.0"
524 | }
525 | },
526 | "node_modules/entities": {
527 | "version": "2.1.0",
528 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
529 | "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
530 | "dev": true,
531 | "funding": {
532 | "url": "https://github.com/fb55/entities?sponsor=1"
533 | }
534 | },
535 | "node_modules/escape-string-regexp": {
536 | "version": "2.0.0",
537 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
538 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
539 | "dev": true,
540 | "engines": {
541 | "node": ">=8"
542 | }
543 | },
544 | "node_modules/file-set": {
545 | "version": "4.0.2",
546 | "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz",
547 | "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==",
548 | "dev": true,
549 | "dependencies": {
550 | "array-back": "^5.0.0",
551 | "glob": "^7.1.6"
552 | },
553 | "engines": {
554 | "node": ">=10"
555 | }
556 | },
557 | "node_modules/file-set/node_modules/array-back": {
558 | "version": "5.0.0",
559 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz",
560 | "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==",
561 | "dev": true,
562 | "engines": {
563 | "node": ">=10"
564 | }
565 | },
566 | "node_modules/find-replace": {
567 | "version": "3.0.0",
568 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
569 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
570 | "dev": true,
571 | "dependencies": {
572 | "array-back": "^3.0.1"
573 | },
574 | "engines": {
575 | "node": ">=4.0.0"
576 | }
577 | },
578 | "node_modules/find-replace/node_modules/array-back": {
579 | "version": "3.1.0",
580 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
581 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
582 | "dev": true,
583 | "engines": {
584 | "node": ">=6"
585 | }
586 | },
587 | "node_modules/fs-then-native": {
588 | "version": "2.0.0",
589 | "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
590 | "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
591 | "dev": true,
592 | "engines": {
593 | "node": ">=4.0.0"
594 | }
595 | },
596 | "node_modules/fs.realpath": {
597 | "version": "1.0.0",
598 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
599 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
600 | "dev": true
601 | },
602 | "node_modules/generic-pool": {
603 | "version": "3.9.0",
604 | "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
605 | "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
606 | "engines": {
607 | "node": ">= 4"
608 | }
609 | },
610 | "node_modules/glob": {
611 | "version": "7.2.0",
612 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
613 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
614 | "dev": true,
615 | "dependencies": {
616 | "fs.realpath": "^1.0.0",
617 | "inflight": "^1.0.4",
618 | "inherits": "2",
619 | "minimatch": "^3.0.4",
620 | "once": "^1.3.0",
621 | "path-is-absolute": "^1.0.0"
622 | },
623 | "engines": {
624 | "node": "*"
625 | },
626 | "funding": {
627 | "url": "https://github.com/sponsors/isaacs"
628 | }
629 | },
630 | "node_modules/handlebars": {
631 | "version": "4.7.7",
632 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
633 | "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
634 | "dev": true,
635 | "dependencies": {
636 | "minimist": "^1.2.5",
637 | "neo-async": "^2.6.0",
638 | "source-map": "^0.6.1",
639 | "wordwrap": "^1.0.0"
640 | },
641 | "bin": {
642 | "handlebars": "bin/handlebars"
643 | },
644 | "engines": {
645 | "node": ">=0.4.7"
646 | },
647 | "optionalDependencies": {
648 | "uglify-js": "^3.1.4"
649 | }
650 | },
651 | "node_modules/inflight": {
652 | "version": "1.0.6",
653 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
654 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
655 | "dev": true,
656 | "dependencies": {
657 | "once": "^1.3.0",
658 | "wrappy": "1"
659 | }
660 | },
661 | "node_modules/inherits": {
662 | "version": "2.0.4",
663 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
664 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
665 | "dev": true
666 | },
667 | "node_modules/js2xmlparser": {
668 | "version": "4.0.2",
669 | "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
670 | "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
671 | "dev": true,
672 | "dependencies": {
673 | "xmlcreate": "^2.0.4"
674 | }
675 | },
676 | "node_modules/jsdoc": {
677 | "version": "3.6.10",
678 | "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
679 | "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
680 | "dev": true,
681 | "dependencies": {
682 | "@babel/parser": "^7.9.4",
683 | "@types/markdown-it": "^12.2.3",
684 | "bluebird": "^3.7.2",
685 | "catharsis": "^0.9.0",
686 | "escape-string-regexp": "^2.0.0",
687 | "js2xmlparser": "^4.0.2",
688 | "klaw": "^4.0.1",
689 | "markdown-it": "^12.3.2",
690 | "markdown-it-anchor": "^8.4.1",
691 | "marked": "^4.0.10",
692 | "mkdirp": "^1.0.4",
693 | "requizzle": "^0.2.3",
694 | "strip-json-comments": "^3.1.0",
695 | "taffydb": "2.6.2",
696 | "underscore": "~1.13.2"
697 | },
698 | "bin": {
699 | "jsdoc": "jsdoc.js"
700 | },
701 | "engines": {
702 | "node": ">=8.15.0"
703 | }
704 | },
705 | "node_modules/jsdoc-api": {
706 | "version": "7.1.1",
707 | "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.1.tgz",
708 | "integrity": "sha512-0pkuPCzVXiqsDAsVrNFXCkHzlyNepBIDVtwwehry4RJAnZmXtlAz7rh8F9FRz53u3NeynGbex+bpYWwi8lE66A==",
709 | "dev": true,
710 | "dependencies": {
711 | "array-back": "^6.2.2",
712 | "cache-point": "^2.0.0",
713 | "collect-all": "^1.0.4",
714 | "file-set": "^4.0.2",
715 | "fs-then-native": "^2.0.0",
716 | "jsdoc": "^3.6.10",
717 | "object-to-spawn-args": "^2.0.1",
718 | "temp-path": "^1.0.0",
719 | "walk-back": "^5.1.0"
720 | },
721 | "engines": {
722 | "node": ">=12.17"
723 | }
724 | },
725 | "node_modules/jsdoc-parse": {
726 | "version": "6.1.0",
727 | "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.1.0.tgz",
728 | "integrity": "sha512-n/hDGQJa69IBun1yZAjqzV4gVR41+flZ3bIlm9fKvNe2Xjsd1/+zCo2+R9ls8LxtePgIWbpA1jU7xkB2lRdLLg==",
729 | "dev": true,
730 | "dependencies": {
731 | "array-back": "^6.2.2",
732 | "lodash.omit": "^4.5.0",
733 | "lodash.pick": "^4.4.0",
734 | "reduce-extract": "^1.0.0",
735 | "sort-array": "^4.1.4",
736 | "test-value": "^3.0.0"
737 | },
738 | "engines": {
739 | "node": ">=12"
740 | }
741 | },
742 | "node_modules/jsdoc-to-markdown": {
743 | "version": "7.1.1",
744 | "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.1.tgz",
745 | "integrity": "sha512-CI86d63xAVNO+ENumWwmJ034lYe5iGU5GwjtTA11EuphP9tpnoi4hrKgR/J8uME0D+o4KUpVfwX1fjZhc8dEtg==",
746 | "dev": true,
747 | "dependencies": {
748 | "array-back": "^6.2.2",
749 | "command-line-tool": "^0.8.0",
750 | "config-master": "^3.1.0",
751 | "dmd": "^6.1.0",
752 | "jsdoc-api": "^7.1.1",
753 | "jsdoc-parse": "^6.1.0",
754 | "walk-back": "^5.1.0"
755 | },
756 | "bin": {
757 | "jsdoc2md": "bin/cli.js"
758 | },
759 | "engines": {
760 | "node": ">=12.17"
761 | }
762 | },
763 | "node_modules/klaw": {
764 | "version": "4.0.1",
765 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
766 | "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
767 | "dev": true,
768 | "engines": {
769 | "node": ">=14.14.0"
770 | }
771 | },
772 | "node_modules/linkify-it": {
773 | "version": "3.0.3",
774 | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
775 | "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
776 | "dev": true,
777 | "dependencies": {
778 | "uc.micro": "^1.0.1"
779 | }
780 | },
781 | "node_modules/lodash": {
782 | "version": "4.17.21",
783 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
784 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
785 | "dev": true
786 | },
787 | "node_modules/lodash.camelcase": {
788 | "version": "4.3.0",
789 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
790 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
791 | "dev": true
792 | },
793 | "node_modules/lodash.omit": {
794 | "version": "4.5.0",
795 | "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
796 | "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
797 | "dev": true
798 | },
799 | "node_modules/lodash.padend": {
800 | "version": "4.6.1",
801 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
802 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
803 | "dev": true
804 | },
805 | "node_modules/lodash.pick": {
806 | "version": "4.4.0",
807 | "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
808 | "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
809 | "dev": true
810 | },
811 | "node_modules/markdown-it": {
812 | "version": "12.3.2",
813 | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
814 | "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
815 | "dev": true,
816 | "dependencies": {
817 | "argparse": "^2.0.1",
818 | "entities": "~2.1.0",
819 | "linkify-it": "^3.0.1",
820 | "mdurl": "^1.0.1",
821 | "uc.micro": "^1.0.5"
822 | },
823 | "bin": {
824 | "markdown-it": "bin/markdown-it.js"
825 | }
826 | },
827 | "node_modules/markdown-it-anchor": {
828 | "version": "8.4.1",
829 | "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.4.1.tgz",
830 | "integrity": "sha512-sLODeRetZ/61KkKLJElaU3NuU2z7MhXf12Ml1WJMSdwpngeofneCRF+JBbat8HiSqhniOMuTemXMrsI7hA6XyA==",
831 | "dev": true,
832 | "peerDependencies": {
833 | "@types/markdown-it": "*",
834 | "markdown-it": "*"
835 | }
836 | },
837 | "node_modules/marked": {
838 | "version": "4.0.12",
839 | "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
840 | "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
841 | "dev": true,
842 | "bin": {
843 | "marked": "bin/marked.js"
844 | },
845 | "engines": {
846 | "node": ">= 12"
847 | }
848 | },
849 | "node_modules/mdurl": {
850 | "version": "1.0.1",
851 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
852 | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
853 | "dev": true
854 | },
855 | "node_modules/mime-db": {
856 | "version": "1.52.0",
857 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
858 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
859 | "engines": {
860 | "node": ">= 0.6"
861 | }
862 | },
863 | "node_modules/mime-types": {
864 | "version": "2.1.35",
865 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
866 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
867 | "dependencies": {
868 | "mime-db": "1.52.0"
869 | },
870 | "engines": {
871 | "node": ">= 0.6"
872 | }
873 | },
874 | "node_modules/minimatch": {
875 | "version": "3.1.2",
876 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
877 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
878 | "dev": true,
879 | "dependencies": {
880 | "brace-expansion": "^1.1.7"
881 | },
882 | "engines": {
883 | "node": "*"
884 | }
885 | },
886 | "node_modules/minimist": {
887 | "version": "1.2.5",
888 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
889 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
890 | "dev": true
891 | },
892 | "node_modules/mkdirp": {
893 | "version": "1.0.4",
894 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
895 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
896 | "dev": true,
897 | "bin": {
898 | "mkdirp": "bin/cmd.js"
899 | },
900 | "engines": {
901 | "node": ">=10"
902 | }
903 | },
904 | "node_modules/mkdirp2": {
905 | "version": "1.0.5",
906 | "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz",
907 | "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==",
908 | "dev": true
909 | },
910 | "node_modules/ms": {
911 | "version": "2.1.2",
912 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
913 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
914 | },
915 | "node_modules/negotiator": {
916 | "version": "0.6.3",
917 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
918 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
919 | "engines": {
920 | "node": ">= 0.6"
921 | }
922 | },
923 | "node_modules/neo-async": {
924 | "version": "2.6.2",
925 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
926 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
927 | "dev": true
928 | },
929 | "node_modules/notepack.io": {
930 | "version": "2.2.0",
931 | "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-2.2.0.tgz",
932 | "integrity": "sha512-9b5w3t5VSH6ZPosoYnyDONnUTF8o0UkBw7JLA6eBlYJWyGT1Q3vQa8Hmuj1/X6RYvHjjygBDgw6fJhe0JEojfw=="
933 | },
934 | "node_modules/object-assign": {
935 | "version": "4.1.1",
936 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
937 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
938 | "engines": {
939 | "node": ">=0.10.0"
940 | }
941 | },
942 | "node_modules/object-get": {
943 | "version": "2.1.1",
944 | "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz",
945 | "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==",
946 | "dev": true
947 | },
948 | "node_modules/object-to-spawn-args": {
949 | "version": "2.0.1",
950 | "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz",
951 | "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==",
952 | "dev": true,
953 | "engines": {
954 | "node": ">=8.0.0"
955 | }
956 | },
957 | "node_modules/once": {
958 | "version": "1.4.0",
959 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
960 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
961 | "dev": true,
962 | "dependencies": {
963 | "wrappy": "1"
964 | }
965 | },
966 | "node_modules/path-is-absolute": {
967 | "version": "1.0.1",
968 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
969 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
970 | "dev": true,
971 | "engines": {
972 | "node": ">=0.10.0"
973 | }
974 | },
975 | "node_modules/redis": {
976 | "version": "4.6.13",
977 | "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
978 | "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
979 | "dependencies": {
980 | "@redis/bloom": "1.2.0",
981 | "@redis/client": "1.5.14",
982 | "@redis/graph": "1.1.1",
983 | "@redis/json": "1.0.6",
984 | "@redis/search": "1.1.6",
985 | "@redis/time-series": "1.0.5"
986 | }
987 | },
988 | "node_modules/reduce-extract": {
989 | "version": "1.0.0",
990 | "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
991 | "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
992 | "dev": true,
993 | "dependencies": {
994 | "test-value": "^1.0.1"
995 | },
996 | "engines": {
997 | "node": ">=0.10.0"
998 | }
999 | },
1000 | "node_modules/reduce-extract/node_modules/array-back": {
1001 | "version": "1.0.4",
1002 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
1003 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
1004 | "dev": true,
1005 | "dependencies": {
1006 | "typical": "^2.6.0"
1007 | },
1008 | "engines": {
1009 | "node": ">=0.12.0"
1010 | }
1011 | },
1012 | "node_modules/reduce-extract/node_modules/test-value": {
1013 | "version": "1.1.0",
1014 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
1015 | "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
1016 | "dev": true,
1017 | "dependencies": {
1018 | "array-back": "^1.0.2",
1019 | "typical": "^2.4.2"
1020 | },
1021 | "engines": {
1022 | "node": ">=0.10.0"
1023 | }
1024 | },
1025 | "node_modules/reduce-flatten": {
1026 | "version": "1.0.1",
1027 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
1028 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
1029 | "dev": true,
1030 | "engines": {
1031 | "node": ">=0.10.0"
1032 | }
1033 | },
1034 | "node_modules/reduce-unique": {
1035 | "version": "2.0.1",
1036 | "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz",
1037 | "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==",
1038 | "dev": true,
1039 | "engines": {
1040 | "node": ">=6"
1041 | }
1042 | },
1043 | "node_modules/reduce-without": {
1044 | "version": "1.0.1",
1045 | "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
1046 | "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
1047 | "dev": true,
1048 | "dependencies": {
1049 | "test-value": "^2.0.0"
1050 | },
1051 | "engines": {
1052 | "node": ">=0.10.0"
1053 | }
1054 | },
1055 | "node_modules/reduce-without/node_modules/array-back": {
1056 | "version": "1.0.4",
1057 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
1058 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
1059 | "dev": true,
1060 | "dependencies": {
1061 | "typical": "^2.6.0"
1062 | },
1063 | "engines": {
1064 | "node": ">=0.12.0"
1065 | }
1066 | },
1067 | "node_modules/reduce-without/node_modules/test-value": {
1068 | "version": "2.1.0",
1069 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
1070 | "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
1071 | "dev": true,
1072 | "dependencies": {
1073 | "array-back": "^1.0.3",
1074 | "typical": "^2.6.0"
1075 | },
1076 | "engines": {
1077 | "node": ">=0.10.0"
1078 | }
1079 | },
1080 | "node_modules/requizzle": {
1081 | "version": "0.2.3",
1082 | "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
1083 | "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
1084 | "dev": true,
1085 | "dependencies": {
1086 | "lodash": "^4.17.14"
1087 | }
1088 | },
1089 | "node_modules/socket.io": {
1090 | "version": "4.7.5",
1091 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
1092 | "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
1093 | "dependencies": {
1094 | "accepts": "~1.3.4",
1095 | "base64id": "~2.0.0",
1096 | "cors": "~2.8.5",
1097 | "debug": "~4.3.2",
1098 | "engine.io": "~6.5.2",
1099 | "socket.io-adapter": "~2.5.2",
1100 | "socket.io-parser": "~4.2.4"
1101 | },
1102 | "engines": {
1103 | "node": ">=10.2.0"
1104 | }
1105 | },
1106 | "node_modules/socket.io-adapter": {
1107 | "version": "2.5.4",
1108 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz",
1109 | "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==",
1110 | "dependencies": {
1111 | "debug": "~4.3.4",
1112 | "ws": "~8.11.0"
1113 | }
1114 | },
1115 | "node_modules/socket.io-parser": {
1116 | "version": "4.2.4",
1117 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
1118 | "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
1119 | "dependencies": {
1120 | "@socket.io/component-emitter": "~3.1.0",
1121 | "debug": "~4.3.1"
1122 | },
1123 | "engines": {
1124 | "node": ">=10.0.0"
1125 | }
1126 | },
1127 | "node_modules/sort-array": {
1128 | "version": "4.1.5",
1129 | "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz",
1130 | "integrity": "sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==",
1131 | "dev": true,
1132 | "dependencies": {
1133 | "array-back": "^5.0.0",
1134 | "typical": "^6.0.1"
1135 | },
1136 | "engines": {
1137 | "node": ">=10"
1138 | }
1139 | },
1140 | "node_modules/sort-array/node_modules/array-back": {
1141 | "version": "5.0.0",
1142 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz",
1143 | "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==",
1144 | "dev": true,
1145 | "engines": {
1146 | "node": ">=10"
1147 | }
1148 | },
1149 | "node_modules/sort-array/node_modules/typical": {
1150 | "version": "6.0.1",
1151 | "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz",
1152 | "integrity": "sha512-+g3NEp7fJLe9DPa1TArHm9QAA7YciZmWnfAqEaFrBihQ7epOv9i99rjtgb6Iz0wh3WuQDjsCTDfgRoGnmHN81A==",
1153 | "dev": true,
1154 | "engines": {
1155 | "node": ">=10"
1156 | }
1157 | },
1158 | "node_modules/source-map": {
1159 | "version": "0.6.1",
1160 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1161 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1162 | "dev": true,
1163 | "engines": {
1164 | "node": ">=0.10.0"
1165 | }
1166 | },
1167 | "node_modules/stream-connect": {
1168 | "version": "1.0.2",
1169 | "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
1170 | "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
1171 | "dev": true,
1172 | "dependencies": {
1173 | "array-back": "^1.0.2"
1174 | },
1175 | "engines": {
1176 | "node": ">=0.10.0"
1177 | }
1178 | },
1179 | "node_modules/stream-connect/node_modules/array-back": {
1180 | "version": "1.0.4",
1181 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
1182 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
1183 | "dev": true,
1184 | "dependencies": {
1185 | "typical": "^2.6.0"
1186 | },
1187 | "engines": {
1188 | "node": ">=0.12.0"
1189 | }
1190 | },
1191 | "node_modules/stream-via": {
1192 | "version": "1.0.4",
1193 | "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
1194 | "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
1195 | "dev": true,
1196 | "engines": {
1197 | "node": ">=0.10.0"
1198 | }
1199 | },
1200 | "node_modules/strip-json-comments": {
1201 | "version": "3.1.1",
1202 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
1203 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
1204 | "dev": true,
1205 | "engines": {
1206 | "node": ">=8"
1207 | },
1208 | "funding": {
1209 | "url": "https://github.com/sponsors/sindresorhus"
1210 | }
1211 | },
1212 | "node_modules/table-layout": {
1213 | "version": "0.4.5",
1214 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
1215 | "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
1216 | "dev": true,
1217 | "dependencies": {
1218 | "array-back": "^2.0.0",
1219 | "deep-extend": "~0.6.0",
1220 | "lodash.padend": "^4.6.1",
1221 | "typical": "^2.6.1",
1222 | "wordwrapjs": "^3.0.0"
1223 | },
1224 | "engines": {
1225 | "node": ">=4.0.0"
1226 | }
1227 | },
1228 | "node_modules/table-layout/node_modules/array-back": {
1229 | "version": "2.0.0",
1230 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1231 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1232 | "dev": true,
1233 | "dependencies": {
1234 | "typical": "^2.6.1"
1235 | },
1236 | "engines": {
1237 | "node": ">=4"
1238 | }
1239 | },
1240 | "node_modules/taffydb": {
1241 | "version": "2.6.2",
1242 | "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
1243 | "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
1244 | "dev": true
1245 | },
1246 | "node_modules/temp-path": {
1247 | "version": "1.0.0",
1248 | "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
1249 | "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
1250 | "dev": true
1251 | },
1252 | "node_modules/test-value": {
1253 | "version": "3.0.0",
1254 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
1255 | "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
1256 | "dev": true,
1257 | "dependencies": {
1258 | "array-back": "^2.0.0",
1259 | "typical": "^2.6.1"
1260 | },
1261 | "engines": {
1262 | "node": ">=4.0.0"
1263 | }
1264 | },
1265 | "node_modules/test-value/node_modules/array-back": {
1266 | "version": "2.0.0",
1267 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1268 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1269 | "dev": true,
1270 | "dependencies": {
1271 | "typical": "^2.6.1"
1272 | },
1273 | "engines": {
1274 | "node": ">=4"
1275 | }
1276 | },
1277 | "node_modules/typical": {
1278 | "version": "2.6.1",
1279 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
1280 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
1281 | "dev": true
1282 | },
1283 | "node_modules/uc.micro": {
1284 | "version": "1.0.6",
1285 | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
1286 | "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
1287 | "dev": true
1288 | },
1289 | "node_modules/uglify-js": {
1290 | "version": "3.15.3",
1291 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz",
1292 | "integrity": "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==",
1293 | "dev": true,
1294 | "optional": true,
1295 | "bin": {
1296 | "uglifyjs": "bin/uglifyjs"
1297 | },
1298 | "engines": {
1299 | "node": ">=0.8.0"
1300 | }
1301 | },
1302 | "node_modules/uid2": {
1303 | "version": "0.0.3",
1304 | "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
1305 | "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
1306 | },
1307 | "node_modules/underscore": {
1308 | "version": "1.13.2",
1309 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz",
1310 | "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==",
1311 | "dev": true
1312 | },
1313 | "node_modules/undici-types": {
1314 | "version": "5.26.5",
1315 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
1316 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
1317 | },
1318 | "node_modules/vary": {
1319 | "version": "1.1.2",
1320 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1321 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
1322 | "engines": {
1323 | "node": ">= 0.8"
1324 | }
1325 | },
1326 | "node_modules/walk-back": {
1327 | "version": "5.1.0",
1328 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz",
1329 | "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==",
1330 | "dev": true,
1331 | "engines": {
1332 | "node": ">=12.17"
1333 | }
1334 | },
1335 | "node_modules/wordwrap": {
1336 | "version": "1.0.0",
1337 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1338 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
1339 | "dev": true
1340 | },
1341 | "node_modules/wordwrapjs": {
1342 | "version": "3.0.0",
1343 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
1344 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
1345 | "dev": true,
1346 | "dependencies": {
1347 | "reduce-flatten": "^1.0.1",
1348 | "typical": "^2.6.1"
1349 | },
1350 | "engines": {
1351 | "node": ">=4.0.0"
1352 | }
1353 | },
1354 | "node_modules/wrappy": {
1355 | "version": "1.0.2",
1356 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1357 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1358 | "dev": true
1359 | },
1360 | "node_modules/ws": {
1361 | "version": "8.11.0",
1362 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
1363 | "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
1364 | "engines": {
1365 | "node": ">=10.0.0"
1366 | },
1367 | "peerDependencies": {
1368 | "bufferutil": "^4.0.1",
1369 | "utf-8-validate": "^5.0.2"
1370 | },
1371 | "peerDependenciesMeta": {
1372 | "bufferutil": {
1373 | "optional": true
1374 | },
1375 | "utf-8-validate": {
1376 | "optional": true
1377 | }
1378 | }
1379 | },
1380 | "node_modules/xmlcreate": {
1381 | "version": "2.0.4",
1382 | "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
1383 | "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
1384 | "dev": true
1385 | },
1386 | "node_modules/yallist": {
1387 | "version": "4.0.0",
1388 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1389 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
1390 | }
1391 | },
1392 | "dependencies": {
1393 | "@babel/parser": {
1394 | "version": "7.17.8",
1395 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz",
1396 | "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==",
1397 | "dev": true
1398 | },
1399 | "@redis/bloom": {
1400 | "version": "1.2.0",
1401 | "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
1402 | "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
1403 | "requires": {}
1404 | },
1405 | "@redis/client": {
1406 | "version": "1.5.14",
1407 | "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
1408 | "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
1409 | "requires": {
1410 | "cluster-key-slot": "1.1.2",
1411 | "generic-pool": "3.9.0",
1412 | "yallist": "4.0.0"
1413 | }
1414 | },
1415 | "@redis/graph": {
1416 | "version": "1.1.1",
1417 | "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
1418 | "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
1419 | "requires": {}
1420 | },
1421 | "@redis/json": {
1422 | "version": "1.0.6",
1423 | "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
1424 | "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
1425 | "requires": {}
1426 | },
1427 | "@redis/search": {
1428 | "version": "1.1.6",
1429 | "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
1430 | "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
1431 | "requires": {}
1432 | },
1433 | "@redis/time-series": {
1434 | "version": "1.0.5",
1435 | "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
1436 | "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
1437 | "requires": {}
1438 | },
1439 | "@socket.io/component-emitter": {
1440 | "version": "3.1.2",
1441 | "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
1442 | "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
1443 | },
1444 | "@socket.io/redis-adapter": {
1445 | "version": "8.3.0",
1446 | "resolved": "https://registry.npmjs.org/@socket.io/redis-adapter/-/redis-adapter-8.3.0.tgz",
1447 | "integrity": "sha512-ly0cra+48hDmChxmIpnESKrc94LjRL80TEmZVscuQ/WWkRP81nNj8W8cCGMqbI4L6NCuAaPRSzZF1a9GlAxxnA==",
1448 | "requires": {
1449 | "debug": "~4.3.1",
1450 | "notepack.io": "~3.0.1",
1451 | "uid2": "1.0.0"
1452 | },
1453 | "dependencies": {
1454 | "notepack.io": {
1455 | "version": "3.0.1",
1456 | "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-3.0.1.tgz",
1457 | "integrity": "sha512-TKC/8zH5pXIAMVQio2TvVDTtPRX+DJPHDqjRbxogtFiByHyzKmy96RA0JtCQJ+WouyyL4A10xomQzgbUT+1jCg=="
1458 | },
1459 | "uid2": {
1460 | "version": "1.0.0",
1461 | "resolved": "https://registry.npmjs.org/uid2/-/uid2-1.0.0.tgz",
1462 | "integrity": "sha512-+I6aJUv63YAcY9n4mQreLUt0d4lvwkkopDNmpomkAUz0fAkEMV9pRWxN0EjhW1YfRhcuyHg2v3mwddCDW1+LFQ=="
1463 | }
1464 | }
1465 | },
1466 | "@types/cookie": {
1467 | "version": "0.4.1",
1468 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
1469 | "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
1470 | },
1471 | "@types/cors": {
1472 | "version": "2.8.17",
1473 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
1474 | "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
1475 | "requires": {
1476 | "@types/node": "*"
1477 | }
1478 | },
1479 | "@types/linkify-it": {
1480 | "version": "3.0.2",
1481 | "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
1482 | "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
1483 | "dev": true
1484 | },
1485 | "@types/markdown-it": {
1486 | "version": "12.2.3",
1487 | "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
1488 | "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
1489 | "dev": true,
1490 | "requires": {
1491 | "@types/linkify-it": "*",
1492 | "@types/mdurl": "*"
1493 | }
1494 | },
1495 | "@types/mdurl": {
1496 | "version": "1.0.2",
1497 | "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
1498 | "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
1499 | "dev": true
1500 | },
1501 | "@types/node": {
1502 | "version": "20.12.11",
1503 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz",
1504 | "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==",
1505 | "requires": {
1506 | "undici-types": "~5.26.4"
1507 | }
1508 | },
1509 | "accepts": {
1510 | "version": "1.3.8",
1511 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
1512 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
1513 | "requires": {
1514 | "mime-types": "~2.1.34",
1515 | "negotiator": "0.6.3"
1516 | }
1517 | },
1518 | "ansi-escape-sequences": {
1519 | "version": "4.1.0",
1520 | "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
1521 | "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
1522 | "dev": true,
1523 | "requires": {
1524 | "array-back": "^3.0.1"
1525 | },
1526 | "dependencies": {
1527 | "array-back": {
1528 | "version": "3.1.0",
1529 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
1530 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
1531 | "dev": true
1532 | }
1533 | }
1534 | },
1535 | "argparse": {
1536 | "version": "2.0.1",
1537 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1538 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1539 | "dev": true
1540 | },
1541 | "array-back": {
1542 | "version": "6.2.2",
1543 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
1544 | "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
1545 | "dev": true
1546 | },
1547 | "balanced-match": {
1548 | "version": "1.0.2",
1549 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1550 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1551 | "dev": true
1552 | },
1553 | "base64id": {
1554 | "version": "2.0.0",
1555 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
1556 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
1557 | },
1558 | "bluebird": {
1559 | "version": "3.7.2",
1560 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
1561 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
1562 | "dev": true
1563 | },
1564 | "brace-expansion": {
1565 | "version": "1.1.11",
1566 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1567 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1568 | "dev": true,
1569 | "requires": {
1570 | "balanced-match": "^1.0.0",
1571 | "concat-map": "0.0.1"
1572 | }
1573 | },
1574 | "cache-point": {
1575 | "version": "2.0.0",
1576 | "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz",
1577 | "integrity": "sha512-4gkeHlFpSKgm3vm2gJN5sPqfmijYRFYCQ6tv5cLw0xVmT6r1z1vd4FNnpuOREco3cBs1G709sZ72LdgddKvL5w==",
1578 | "dev": true,
1579 | "requires": {
1580 | "array-back": "^4.0.1",
1581 | "fs-then-native": "^2.0.0",
1582 | "mkdirp2": "^1.0.4"
1583 | },
1584 | "dependencies": {
1585 | "array-back": {
1586 | "version": "4.0.2",
1587 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
1588 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
1589 | "dev": true
1590 | }
1591 | }
1592 | },
1593 | "catharsis": {
1594 | "version": "0.9.0",
1595 | "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
1596 | "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
1597 | "dev": true,
1598 | "requires": {
1599 | "lodash": "^4.17.15"
1600 | }
1601 | },
1602 | "cluster-key-slot": {
1603 | "version": "1.1.2",
1604 | "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
1605 | "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="
1606 | },
1607 | "collect-all": {
1608 | "version": "1.0.4",
1609 | "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz",
1610 | "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==",
1611 | "dev": true,
1612 | "requires": {
1613 | "stream-connect": "^1.0.2",
1614 | "stream-via": "^1.0.4"
1615 | }
1616 | },
1617 | "command-line-args": {
1618 | "version": "5.2.1",
1619 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
1620 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
1621 | "dev": true,
1622 | "requires": {
1623 | "array-back": "^3.1.0",
1624 | "find-replace": "^3.0.0",
1625 | "lodash.camelcase": "^4.3.0",
1626 | "typical": "^4.0.0"
1627 | },
1628 | "dependencies": {
1629 | "array-back": {
1630 | "version": "3.1.0",
1631 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
1632 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
1633 | "dev": true
1634 | },
1635 | "typical": {
1636 | "version": "4.0.0",
1637 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
1638 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
1639 | "dev": true
1640 | }
1641 | }
1642 | },
1643 | "command-line-tool": {
1644 | "version": "0.8.0",
1645 | "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
1646 | "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
1647 | "dev": true,
1648 | "requires": {
1649 | "ansi-escape-sequences": "^4.0.0",
1650 | "array-back": "^2.0.0",
1651 | "command-line-args": "^5.0.0",
1652 | "command-line-usage": "^4.1.0",
1653 | "typical": "^2.6.1"
1654 | },
1655 | "dependencies": {
1656 | "array-back": {
1657 | "version": "2.0.0",
1658 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1659 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1660 | "dev": true,
1661 | "requires": {
1662 | "typical": "^2.6.1"
1663 | }
1664 | }
1665 | }
1666 | },
1667 | "command-line-usage": {
1668 | "version": "4.1.0",
1669 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
1670 | "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
1671 | "dev": true,
1672 | "requires": {
1673 | "ansi-escape-sequences": "^4.0.0",
1674 | "array-back": "^2.0.0",
1675 | "table-layout": "^0.4.2",
1676 | "typical": "^2.6.1"
1677 | },
1678 | "dependencies": {
1679 | "array-back": {
1680 | "version": "2.0.0",
1681 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
1682 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
1683 | "dev": true,
1684 | "requires": {
1685 | "typical": "^2.6.1"
1686 | }
1687 | }
1688 | }
1689 | },
1690 | "common-sequence": {
1691 | "version": "2.0.2",
1692 | "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz",
1693 | "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==",
1694 | "dev": true
1695 | },
1696 | "concat-map": {
1697 | "version": "0.0.1",
1698 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1699 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
1700 | "dev": true
1701 | },
1702 | "config-master": {
1703 | "version": "3.1.0",
1704 | "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
1705 | "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
1706 | "dev": true,
1707 | "requires": {
1708 | "walk-back": "^2.0.1"
1709 | },
1710 | "dependencies": {
1711 | "walk-back": {
1712 | "version": "2.0.1",
1713 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
1714 | "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
1715 | "dev": true
1716 | }
1717 | }
1718 | },
1719 | "cookie": {
1720 | "version": "0.4.2",
1721 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
1722 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="
1723 | },
1724 | "cors": {
1725 | "version": "2.8.5",
1726 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1727 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
1728 | "requires": {
1729 | "object-assign": "^4",
1730 | "vary": "^1"
1731 | }
1732 | },
1733 | "debug": {
1734 | "version": "4.3.4",
1735 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1736 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1737 | "requires": {
1738 | "ms": "2.1.2"
1739 | }
1740 | },
1741 | "deep-extend": {
1742 | "version": "0.6.0",
1743 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
1744 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
1745 | "dev": true
1746 | },
1747 | "dmd": {
1748 | "version": "6.1.0",
1749 | "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.1.0.tgz",
1750 | "integrity": "sha512-0zQIJ873gay1scCTFZvHPWM9mVJBnaylB2NQDI8O9u8O32m00Jb6uxDKexZm8hjTRM7RiWe0FJ32pExHoXdwoQ==",
1751 | "dev": true,
1752 | "requires": {
1753 | "array-back": "^6.2.2",
1754 | "cache-point": "^2.0.0",
1755 | "common-sequence": "^2.0.2",
1756 | "file-set": "^4.0.2",
1757 | "handlebars": "^4.7.7",
1758 | "marked": "^4.0.12",
1759 | "object-get": "^2.1.1",
1760 | "reduce-flatten": "^3.0.1",
1761 | "reduce-unique": "^2.0.1",
1762 | "reduce-without": "^1.0.1",
1763 | "test-value": "^3.0.0",
1764 | "walk-back": "^5.1.0"
1765 | },
1766 | "dependencies": {
1767 | "reduce-flatten": {
1768 | "version": "3.0.1",
1769 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz",
1770 | "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==",
1771 | "dev": true
1772 | }
1773 | }
1774 | },
1775 | "engine.io": {
1776 | "version": "6.5.4",
1777 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
1778 | "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
1779 | "requires": {
1780 | "@types/cookie": "^0.4.1",
1781 | "@types/cors": "^2.8.12",
1782 | "@types/node": ">=10.0.0",
1783 | "accepts": "~1.3.4",
1784 | "base64id": "2.0.0",
1785 | "cookie": "~0.4.1",
1786 | "cors": "~2.8.5",
1787 | "debug": "~4.3.1",
1788 | "engine.io-parser": "~5.2.1",
1789 | "ws": "~8.11.0"
1790 | }
1791 | },
1792 | "engine.io-parser": {
1793 | "version": "5.2.2",
1794 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz",
1795 | "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw=="
1796 | },
1797 | "entities": {
1798 | "version": "2.1.0",
1799 | "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
1800 | "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
1801 | "dev": true
1802 | },
1803 | "escape-string-regexp": {
1804 | "version": "2.0.0",
1805 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
1806 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
1807 | "dev": true
1808 | },
1809 | "file-set": {
1810 | "version": "4.0.2",
1811 | "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz",
1812 | "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==",
1813 | "dev": true,
1814 | "requires": {
1815 | "array-back": "^5.0.0",
1816 | "glob": "^7.1.6"
1817 | },
1818 | "dependencies": {
1819 | "array-back": {
1820 | "version": "5.0.0",
1821 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz",
1822 | "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==",
1823 | "dev": true
1824 | }
1825 | }
1826 | },
1827 | "find-replace": {
1828 | "version": "3.0.0",
1829 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
1830 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
1831 | "dev": true,
1832 | "requires": {
1833 | "array-back": "^3.0.1"
1834 | },
1835 | "dependencies": {
1836 | "array-back": {
1837 | "version": "3.1.0",
1838 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
1839 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
1840 | "dev": true
1841 | }
1842 | }
1843 | },
1844 | "fs-then-native": {
1845 | "version": "2.0.0",
1846 | "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
1847 | "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
1848 | "dev": true
1849 | },
1850 | "fs.realpath": {
1851 | "version": "1.0.0",
1852 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1853 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
1854 | "dev": true
1855 | },
1856 | "generic-pool": {
1857 | "version": "3.9.0",
1858 | "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
1859 | "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g=="
1860 | },
1861 | "glob": {
1862 | "version": "7.2.0",
1863 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
1864 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
1865 | "dev": true,
1866 | "requires": {
1867 | "fs.realpath": "^1.0.0",
1868 | "inflight": "^1.0.4",
1869 | "inherits": "2",
1870 | "minimatch": "^3.0.4",
1871 | "once": "^1.3.0",
1872 | "path-is-absolute": "^1.0.0"
1873 | }
1874 | },
1875 | "handlebars": {
1876 | "version": "4.7.7",
1877 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
1878 | "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
1879 | "dev": true,
1880 | "requires": {
1881 | "minimist": "^1.2.5",
1882 | "neo-async": "^2.6.0",
1883 | "source-map": "^0.6.1",
1884 | "uglify-js": "^3.1.4",
1885 | "wordwrap": "^1.0.0"
1886 | }
1887 | },
1888 | "inflight": {
1889 | "version": "1.0.6",
1890 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1891 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1892 | "dev": true,
1893 | "requires": {
1894 | "once": "^1.3.0",
1895 | "wrappy": "1"
1896 | }
1897 | },
1898 | "inherits": {
1899 | "version": "2.0.4",
1900 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1901 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1902 | "dev": true
1903 | },
1904 | "js2xmlparser": {
1905 | "version": "4.0.2",
1906 | "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
1907 | "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
1908 | "dev": true,
1909 | "requires": {
1910 | "xmlcreate": "^2.0.4"
1911 | }
1912 | },
1913 | "jsdoc": {
1914 | "version": "3.6.10",
1915 | "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
1916 | "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
1917 | "dev": true,
1918 | "requires": {
1919 | "@babel/parser": "^7.9.4",
1920 | "@types/markdown-it": "^12.2.3",
1921 | "bluebird": "^3.7.2",
1922 | "catharsis": "^0.9.0",
1923 | "escape-string-regexp": "^2.0.0",
1924 | "js2xmlparser": "^4.0.2",
1925 | "klaw": "^4.0.1",
1926 | "markdown-it": "^12.3.2",
1927 | "markdown-it-anchor": "^8.4.1",
1928 | "marked": "^4.0.10",
1929 | "mkdirp": "^1.0.4",
1930 | "requizzle": "^0.2.3",
1931 | "strip-json-comments": "^3.1.0",
1932 | "taffydb": "2.6.2",
1933 | "underscore": "~1.13.2"
1934 | }
1935 | },
1936 | "jsdoc-api": {
1937 | "version": "7.1.1",
1938 | "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.1.tgz",
1939 | "integrity": "sha512-0pkuPCzVXiqsDAsVrNFXCkHzlyNepBIDVtwwehry4RJAnZmXtlAz7rh8F9FRz53u3NeynGbex+bpYWwi8lE66A==",
1940 | "dev": true,
1941 | "requires": {
1942 | "array-back": "^6.2.2",
1943 | "cache-point": "^2.0.0",
1944 | "collect-all": "^1.0.4",
1945 | "file-set": "^4.0.2",
1946 | "fs-then-native": "^2.0.0",
1947 | "jsdoc": "^3.6.10",
1948 | "object-to-spawn-args": "^2.0.1",
1949 | "temp-path": "^1.0.0",
1950 | "walk-back": "^5.1.0"
1951 | }
1952 | },
1953 | "jsdoc-parse": {
1954 | "version": "6.1.0",
1955 | "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.1.0.tgz",
1956 | "integrity": "sha512-n/hDGQJa69IBun1yZAjqzV4gVR41+flZ3bIlm9fKvNe2Xjsd1/+zCo2+R9ls8LxtePgIWbpA1jU7xkB2lRdLLg==",
1957 | "dev": true,
1958 | "requires": {
1959 | "array-back": "^6.2.2",
1960 | "lodash.omit": "^4.5.0",
1961 | "lodash.pick": "^4.4.0",
1962 | "reduce-extract": "^1.0.0",
1963 | "sort-array": "^4.1.4",
1964 | "test-value": "^3.0.0"
1965 | }
1966 | },
1967 | "jsdoc-to-markdown": {
1968 | "version": "7.1.1",
1969 | "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.1.tgz",
1970 | "integrity": "sha512-CI86d63xAVNO+ENumWwmJ034lYe5iGU5GwjtTA11EuphP9tpnoi4hrKgR/J8uME0D+o4KUpVfwX1fjZhc8dEtg==",
1971 | "dev": true,
1972 | "requires": {
1973 | "array-back": "^6.2.2",
1974 | "command-line-tool": "^0.8.0",
1975 | "config-master": "^3.1.0",
1976 | "dmd": "^6.1.0",
1977 | "jsdoc-api": "^7.1.1",
1978 | "jsdoc-parse": "^6.1.0",
1979 | "walk-back": "^5.1.0"
1980 | }
1981 | },
1982 | "klaw": {
1983 | "version": "4.0.1",
1984 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
1985 | "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
1986 | "dev": true
1987 | },
1988 | "linkify-it": {
1989 | "version": "3.0.3",
1990 | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
1991 | "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
1992 | "dev": true,
1993 | "requires": {
1994 | "uc.micro": "^1.0.1"
1995 | }
1996 | },
1997 | "lodash": {
1998 | "version": "4.17.21",
1999 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
2000 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
2001 | "dev": true
2002 | },
2003 | "lodash.camelcase": {
2004 | "version": "4.3.0",
2005 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
2006 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
2007 | "dev": true
2008 | },
2009 | "lodash.omit": {
2010 | "version": "4.5.0",
2011 | "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
2012 | "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
2013 | "dev": true
2014 | },
2015 | "lodash.padend": {
2016 | "version": "4.6.1",
2017 | "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
2018 | "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
2019 | "dev": true
2020 | },
2021 | "lodash.pick": {
2022 | "version": "4.4.0",
2023 | "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
2024 | "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
2025 | "dev": true
2026 | },
2027 | "markdown-it": {
2028 | "version": "12.3.2",
2029 | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
2030 | "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
2031 | "dev": true,
2032 | "requires": {
2033 | "argparse": "^2.0.1",
2034 | "entities": "~2.1.0",
2035 | "linkify-it": "^3.0.1",
2036 | "mdurl": "^1.0.1",
2037 | "uc.micro": "^1.0.5"
2038 | }
2039 | },
2040 | "markdown-it-anchor": {
2041 | "version": "8.4.1",
2042 | "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.4.1.tgz",
2043 | "integrity": "sha512-sLODeRetZ/61KkKLJElaU3NuU2z7MhXf12Ml1WJMSdwpngeofneCRF+JBbat8HiSqhniOMuTemXMrsI7hA6XyA==",
2044 | "dev": true,
2045 | "requires": {}
2046 | },
2047 | "marked": {
2048 | "version": "4.0.12",
2049 | "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
2050 | "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
2051 | "dev": true
2052 | },
2053 | "mdurl": {
2054 | "version": "1.0.1",
2055 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
2056 | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
2057 | "dev": true
2058 | },
2059 | "mime-db": {
2060 | "version": "1.52.0",
2061 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
2062 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
2063 | },
2064 | "mime-types": {
2065 | "version": "2.1.35",
2066 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
2067 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
2068 | "requires": {
2069 | "mime-db": "1.52.0"
2070 | }
2071 | },
2072 | "minimatch": {
2073 | "version": "3.1.2",
2074 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2075 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2076 | "dev": true,
2077 | "requires": {
2078 | "brace-expansion": "^1.1.7"
2079 | }
2080 | },
2081 | "minimist": {
2082 | "version": "1.2.5",
2083 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
2084 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
2085 | "dev": true
2086 | },
2087 | "mkdirp": {
2088 | "version": "1.0.4",
2089 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
2090 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
2091 | "dev": true
2092 | },
2093 | "mkdirp2": {
2094 | "version": "1.0.5",
2095 | "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz",
2096 | "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==",
2097 | "dev": true
2098 | },
2099 | "ms": {
2100 | "version": "2.1.2",
2101 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2102 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
2103 | },
2104 | "negotiator": {
2105 | "version": "0.6.3",
2106 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
2107 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
2108 | },
2109 | "neo-async": {
2110 | "version": "2.6.2",
2111 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
2112 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
2113 | "dev": true
2114 | },
2115 | "notepack.io": {
2116 | "version": "2.2.0",
2117 | "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-2.2.0.tgz",
2118 | "integrity": "sha512-9b5w3t5VSH6ZPosoYnyDONnUTF8o0UkBw7JLA6eBlYJWyGT1Q3vQa8Hmuj1/X6RYvHjjygBDgw6fJhe0JEojfw=="
2119 | },
2120 | "object-assign": {
2121 | "version": "4.1.1",
2122 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
2123 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
2124 | },
2125 | "object-get": {
2126 | "version": "2.1.1",
2127 | "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz",
2128 | "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==",
2129 | "dev": true
2130 | },
2131 | "object-to-spawn-args": {
2132 | "version": "2.0.1",
2133 | "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz",
2134 | "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==",
2135 | "dev": true
2136 | },
2137 | "once": {
2138 | "version": "1.4.0",
2139 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
2140 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
2141 | "dev": true,
2142 | "requires": {
2143 | "wrappy": "1"
2144 | }
2145 | },
2146 | "path-is-absolute": {
2147 | "version": "1.0.1",
2148 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
2149 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
2150 | "dev": true
2151 | },
2152 | "redis": {
2153 | "version": "4.6.13",
2154 | "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
2155 | "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
2156 | "requires": {
2157 | "@redis/bloom": "1.2.0",
2158 | "@redis/client": "1.5.14",
2159 | "@redis/graph": "1.1.1",
2160 | "@redis/json": "1.0.6",
2161 | "@redis/search": "1.1.6",
2162 | "@redis/time-series": "1.0.5"
2163 | }
2164 | },
2165 | "reduce-extract": {
2166 | "version": "1.0.0",
2167 | "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
2168 | "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
2169 | "dev": true,
2170 | "requires": {
2171 | "test-value": "^1.0.1"
2172 | },
2173 | "dependencies": {
2174 | "array-back": {
2175 | "version": "1.0.4",
2176 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2177 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2178 | "dev": true,
2179 | "requires": {
2180 | "typical": "^2.6.0"
2181 | }
2182 | },
2183 | "test-value": {
2184 | "version": "1.1.0",
2185 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
2186 | "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
2187 | "dev": true,
2188 | "requires": {
2189 | "array-back": "^1.0.2",
2190 | "typical": "^2.4.2"
2191 | }
2192 | }
2193 | }
2194 | },
2195 | "reduce-flatten": {
2196 | "version": "1.0.1",
2197 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
2198 | "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
2199 | "dev": true
2200 | },
2201 | "reduce-unique": {
2202 | "version": "2.0.1",
2203 | "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz",
2204 | "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==",
2205 | "dev": true
2206 | },
2207 | "reduce-without": {
2208 | "version": "1.0.1",
2209 | "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
2210 | "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
2211 | "dev": true,
2212 | "requires": {
2213 | "test-value": "^2.0.0"
2214 | },
2215 | "dependencies": {
2216 | "array-back": {
2217 | "version": "1.0.4",
2218 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2219 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2220 | "dev": true,
2221 | "requires": {
2222 | "typical": "^2.6.0"
2223 | }
2224 | },
2225 | "test-value": {
2226 | "version": "2.1.0",
2227 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
2228 | "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
2229 | "dev": true,
2230 | "requires": {
2231 | "array-back": "^1.0.3",
2232 | "typical": "^2.6.0"
2233 | }
2234 | }
2235 | }
2236 | },
2237 | "requizzle": {
2238 | "version": "0.2.3",
2239 | "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
2240 | "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
2241 | "dev": true,
2242 | "requires": {
2243 | "lodash": "^4.17.14"
2244 | }
2245 | },
2246 | "socket.io": {
2247 | "version": "4.7.5",
2248 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
2249 | "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
2250 | "requires": {
2251 | "accepts": "~1.3.4",
2252 | "base64id": "~2.0.0",
2253 | "cors": "~2.8.5",
2254 | "debug": "~4.3.2",
2255 | "engine.io": "~6.5.2",
2256 | "socket.io-adapter": "~2.5.2",
2257 | "socket.io-parser": "~4.2.4"
2258 | }
2259 | },
2260 | "socket.io-adapter": {
2261 | "version": "2.5.4",
2262 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz",
2263 | "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==",
2264 | "requires": {
2265 | "debug": "~4.3.4",
2266 | "ws": "~8.11.0"
2267 | }
2268 | },
2269 | "socket.io-parser": {
2270 | "version": "4.2.4",
2271 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
2272 | "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
2273 | "requires": {
2274 | "@socket.io/component-emitter": "~3.1.0",
2275 | "debug": "~4.3.1"
2276 | }
2277 | },
2278 | "sort-array": {
2279 | "version": "4.1.5",
2280 | "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz",
2281 | "integrity": "sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==",
2282 | "dev": true,
2283 | "requires": {
2284 | "array-back": "^5.0.0",
2285 | "typical": "^6.0.1"
2286 | },
2287 | "dependencies": {
2288 | "array-back": {
2289 | "version": "5.0.0",
2290 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz",
2291 | "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==",
2292 | "dev": true
2293 | },
2294 | "typical": {
2295 | "version": "6.0.1",
2296 | "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz",
2297 | "integrity": "sha512-+g3NEp7fJLe9DPa1TArHm9QAA7YciZmWnfAqEaFrBihQ7epOv9i99rjtgb6Iz0wh3WuQDjsCTDfgRoGnmHN81A==",
2298 | "dev": true
2299 | }
2300 | }
2301 | },
2302 | "source-map": {
2303 | "version": "0.6.1",
2304 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2305 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
2306 | "dev": true
2307 | },
2308 | "stream-connect": {
2309 | "version": "1.0.2",
2310 | "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
2311 | "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
2312 | "dev": true,
2313 | "requires": {
2314 | "array-back": "^1.0.2"
2315 | },
2316 | "dependencies": {
2317 | "array-back": {
2318 | "version": "1.0.4",
2319 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
2320 | "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
2321 | "dev": true,
2322 | "requires": {
2323 | "typical": "^2.6.0"
2324 | }
2325 | }
2326 | }
2327 | },
2328 | "stream-via": {
2329 | "version": "1.0.4",
2330 | "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
2331 | "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
2332 | "dev": true
2333 | },
2334 | "strip-json-comments": {
2335 | "version": "3.1.1",
2336 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
2337 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
2338 | "dev": true
2339 | },
2340 | "table-layout": {
2341 | "version": "0.4.5",
2342 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
2343 | "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
2344 | "dev": true,
2345 | "requires": {
2346 | "array-back": "^2.0.0",
2347 | "deep-extend": "~0.6.0",
2348 | "lodash.padend": "^4.6.1",
2349 | "typical": "^2.6.1",
2350 | "wordwrapjs": "^3.0.0"
2351 | },
2352 | "dependencies": {
2353 | "array-back": {
2354 | "version": "2.0.0",
2355 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
2356 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
2357 | "dev": true,
2358 | "requires": {
2359 | "typical": "^2.6.1"
2360 | }
2361 | }
2362 | }
2363 | },
2364 | "taffydb": {
2365 | "version": "2.6.2",
2366 | "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
2367 | "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
2368 | "dev": true
2369 | },
2370 | "temp-path": {
2371 | "version": "1.0.0",
2372 | "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
2373 | "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
2374 | "dev": true
2375 | },
2376 | "test-value": {
2377 | "version": "3.0.0",
2378 | "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
2379 | "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
2380 | "dev": true,
2381 | "requires": {
2382 | "array-back": "^2.0.0",
2383 | "typical": "^2.6.1"
2384 | },
2385 | "dependencies": {
2386 | "array-back": {
2387 | "version": "2.0.0",
2388 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
2389 | "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
2390 | "dev": true,
2391 | "requires": {
2392 | "typical": "^2.6.1"
2393 | }
2394 | }
2395 | }
2396 | },
2397 | "typical": {
2398 | "version": "2.6.1",
2399 | "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
2400 | "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
2401 | "dev": true
2402 | },
2403 | "uc.micro": {
2404 | "version": "1.0.6",
2405 | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
2406 | "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
2407 | "dev": true
2408 | },
2409 | "uglify-js": {
2410 | "version": "3.15.3",
2411 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz",
2412 | "integrity": "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==",
2413 | "dev": true,
2414 | "optional": true
2415 | },
2416 | "uid2": {
2417 | "version": "0.0.3",
2418 | "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
2419 | "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
2420 | },
2421 | "underscore": {
2422 | "version": "1.13.2",
2423 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz",
2424 | "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==",
2425 | "dev": true
2426 | },
2427 | "undici-types": {
2428 | "version": "5.26.5",
2429 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
2430 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
2431 | },
2432 | "vary": {
2433 | "version": "1.1.2",
2434 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2435 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
2436 | },
2437 | "walk-back": {
2438 | "version": "5.1.0",
2439 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz",
2440 | "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==",
2441 | "dev": true
2442 | },
2443 | "wordwrap": {
2444 | "version": "1.0.0",
2445 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
2446 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
2447 | "dev": true
2448 | },
2449 | "wordwrapjs": {
2450 | "version": "3.0.0",
2451 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
2452 | "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
2453 | "dev": true,
2454 | "requires": {
2455 | "reduce-flatten": "^1.0.1",
2456 | "typical": "^2.6.1"
2457 | }
2458 | },
2459 | "wrappy": {
2460 | "version": "1.0.2",
2461 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2462 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
2463 | "dev": true
2464 | },
2465 | "ws": {
2466 | "version": "8.11.0",
2467 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
2468 | "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
2469 | "requires": {}
2470 | },
2471 | "xmlcreate": {
2472 | "version": "2.0.4",
2473 | "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
2474 | "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
2475 | "dev": true
2476 | },
2477 | "yallist": {
2478 | "version": "4.0.0",
2479 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2480 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
2481 | }
2482 | }
2483 | }
2484 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "symple",
3 | "version": "2.1.2",
4 | "description": "Realtime messaging and presence server",
5 | "main": "./lib/symple.js",
6 | "dependencies": {
7 | "@socket.io/redis-adapter": "^8.3.0",
8 | "debug": "4.3.4",
9 | "notepack.io": "~2.2.0",
10 | "socket.io-adapter": "~2.5.2",
11 | "uid2": "0.0.3",
12 | "redis": "4.6.13",
13 | "socket.io": "^4.7.5"
14 | },
15 | "devDependencies": {
16 | "jsdoc-to-markdown": "^7.1.1"
17 | },
18 | "scripts": {
19 | "test": "echo \"Error: no test specified\" && exit 1",
20 | "start": "node server.js",
21 | "docs": "jsdoc2md ./lib/symple.js --template README.hbs > README.md"
22 | },
23 | "repository": {
24 | "type": "git",
25 | "url": "git+https://github.com/sourcey/symple-server.git"
26 | },
27 | "keywords": [
28 | "symple",
29 | "server",
30 | "realtime",
31 | "messaging",
32 | "websocket",
33 | "streaming",
34 | "webrtc",
35 | "chat"
36 | ],
37 | "author": "Kam Low (http://sourcey.com)",
38 | "license": "MIT",
39 | "bugs": {
40 | "url": "https://github.com/sourcey/symple-server/issues"
41 | },
42 | "homepage": "http://sourcey.com/symple"
43 | }
44 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | // include Symple
2 | var Symple = require('./lib/symple');
3 |
4 | // instantiate the Symple server
5 | var sy = new Symple();
6 |
7 | // load a config file
8 | sy.loadConfig(__dirname + "/symple.json");
9 |
10 | // initialize the server
11 | sy.init();
12 |
13 | // access socket.io instance methods if required
14 | // sy.io.use(function(socket, next) { });
15 |
16 | // access HTTP/S server instance methods if required
17 | // sy.http ...
18 |
19 | // access Redis publish/subscribe client instance methods
20 | // sy.pub ...
21 | // sy.sub ...
22 |
23 | console.log('Symple server listening on port ' + sy.config.port);
24 |
--------------------------------------------------------------------------------
/symple.json:
--------------------------------------------------------------------------------
1 | {
2 | /*
3 | The port to listen on (default: 4500).
4 | If `process.env.PORT` is set, the env value will be used instead.
5 | Port 443 should always be used for SSL.
6 | */
7 | "port" : 4500, /* 443 */
8 |
9 | /*
10 | Session time-to-live in minutes (Redis required, default: 15 minutes)
11 | This is the duration of time before sessions expire after the client disconnects.
12 | If set to `-1` the session will never expire.
13 | */
14 | "sessionTTL" : 15,
15 |
16 | /* Enable or disable authentication (Redis required) */
17 | "authentication" : false,
18 |
19 | /* Enable users to dynamically join and leave rooms (Redis required) */
20 | "dynamicRooms" : true,
21 |
22 | /*
23 | Redis configuration
24 | */
25 | "redis" : "redis://localhost:6379",
26 |
27 | /* SSL configuration */
28 | "ssl" : {
29 | "enabled" : false,
30 | "key" : "ssl/symple.key",
31 | "cert" : "ssl/symple.crt"
32 | },
33 |
34 | /*
35 | CORS configuration. See https://socket.io/docs/v4/handling-cors/
36 | */
37 | "cors" : {
38 | "origin": true,
39 | "credentials": true
40 | }
41 | }
42 |
--------------------------------------------------------------------------------