├── .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 | --------------------------------------------------------------------------------